Touch Driver介绍
一.相关知识介绍
1.Touch Driver的加载过程
GWES到[HKEY_LOCAL_MACHINE/HARDWARE/DEVICEMAP/TOUCH]的“Driver name”获取Driver DLL的名字,如果没有找到该键值,则使用默认名字Touch.dll。
Touch Driver的加载内容非常简单,就是调用一下导出函数TouchPanelEnable()。
2.导出函数介绍
与其它很多Driver类似,Touch Driver采用PDD+MDD双层架构,如下图所示:
OEM厂商只需要修改微软PDD层的代码,实现PDD层的API即可,必须实现的PDD层的API包括:
Programming element |
Description |
This function executes when the MDD's DLL entry point receives a DLL_PROCESS_ATTACH message. |
|
This function executes when the MDD's DLL entry point receives a DLL_PROCESS_DETACH message. |
|
This function disables the touch screen device. |
|
This function applies power to the touch screen device and initializes it for operation. |
|
This function queries capabilities of the touch screen device. |
|
This function returns the most recently acquired point and its associated tip state information. |
|
This function indicates to the driver that the system is entering or leaving the suspend state. |
|
This function sets information about the touch screen device. |
由于PDD层的代码非常简单,所以这里不做讨论。
下面对MDD层的API,同时也是Touch Panel Driver必须的导出的一些接口,做一些简单分析,很多东西是我个人理解,有可能是错误的。
1> TouchPanelGetDeviceCaps
获取Touch Driver的一些参数,根据GWES传入的Code不同,返回不同的信息给GWES。
>> TPDC_SAMPLE_RATE_ID
返回Touch Driver的采样速率给上层,包括当前速率,高速和慢速。
struct TPDC_SAMPLE_RATE {
INT SamplesPerSecondLow;
INT SamplesPerSecondHigh;
INT CurrentSampleRateSetting;
};
>> TPDC_CALIBRATION_POINT_COUNT_ID
告诉上层进行屏幕校准的时候采样点是多少。
struct TPDC_CALIBRATION_POINT_COUNT {
DDI_TOUCH_PANEL_CALIBRATION_FLAGS flags;
INT cCalibrationPoints;
};
>> TPDC_CALIBRATION_POINT_ID
告诉上层采样点总共有多少个,及其坐标位置。
struct TPDC_CALIBRATION_POINT {
INT PointNumber;
INT cDisplayWidth;
INT cDisplayHeight;
INT CalibrationX;
INT CalibrationY;
};
2> TouchPanelEnable
初始化Touch Driver,所有相关硬件有关的初始化以及数据采集中断线程的创建都是在这里完成。
值得一提的是其传入参数是一个处理Event的Callback函数,在数据采集中断线程中需要通过该Callback反馈给GWES坐标信息。所以这里需要将这个Callback函数指针给保存下来以供后续使用。
另外,该函数除了在初始化的时候调用,按照帮助文档的解释,在系统运行的某个时间还会再次调用,所以该函数中有一些中断处理的操作。小弟一介菜鸟,不知道啥时候会再次调用,呵呵。
3> TouchPanelDisable
无语了。
4> TouchPanelSetMode
根据Code的不同配置Touch Panel的不同工作状态,MDD层代码中主要有下面的一些分支:
>> TPSM_PRIORITY_HIGH_ID
重新配置IST优先级为高优先级。
>> TPSM_PRIORITY_NORMAL_ID
重新配置IST的优先级为正常优先级。
该线程的默认优先级是109,可以在注册表//Drivers//BuiltIn//Touch下的"Priority256"及"HighPriority256"进行配置
5> TouchPanelReadCalibrationPoint
由GWES直接调用,在校准屏幕的时候使用,后面会对该函数详细的讲述。
6> TouchPanelReadCalibrationAbort
终止校准屏幕的过程,方法是直接给校准屏幕的函数TouchPanelReadCalibrationPoint发送一个hCalibrationSampleAvailable Event,并由函数TouchPanelReadCalibrationPoint通知GWES里面的校准线程(是否有该线程,我不太确定,我是推测的)校准失败。
在GWES看来,它只通过TouchPanelReadCalibrationPoint的返回值来判断校准的正确与否,无论任何原因引起的校准没有完成,它都认为是失败,包括用户的Abort。
7> TouchPanelCalibrateAPoint
Touch Driver通过中断数据采集线程IST告诉GWES当前触摸点的坐标,方式是调用Callback函数,然后GWES再通过调用TouchPanelCalibrateAPoint()对坐标位置进行校准,是由TouchPanelpISR直接调用,不是由GWES直接调用。校准公式如下:
校准的公式如下:
Sx = A1*Tx + B1*Ty + C1
Sy = A2*Tx + B2*Ty + C2
其中,Tx和Ty是触摸屏坐标,而Sx和Sy是显示设备坐标,其中A1/B1/C1/A2/B2/C2是校准参数,在屏幕进行校准的时候计算出来,在GWES调用TouchPanelSetCalibration()的时候会使用到。
该函数的声明如下:
VOID TouchPanelCalibrateAPoint( INT32 UncalX, INT32 UncalY, INT32* pCalX, INT32* pCalY ); Parameters UncalX [in] Noncalibrated x-coordinate. UncalY [in] Noncalibrated y-coordinate. pCalX [out] Pointer to the returned calibrated x-coordinate. pCalY [out] Pointer to the returned calibrated y-coordinate. |
8> TouchPanelSetCalibration
该函数利用Touch Panel的采样点坐标和屏幕的显示坐标来计算Touch Panel Driver的校正参数。
Microsoft通过下列的方式来计算坐标点:
Sx = A1*Tx + B1*Ty + C1
Sy = A2*Tx + B2*Ty + C2
其中,Tx和Ty是触摸屏坐标,而Sx和Sy是显示设备坐标。
该函数的功能就是根据采样点和屏幕上的十字号的值计算出A1,B1,C1和A2,B2,C2。
9> TouchPanelPowerHandler
这个函数虽然简单,但是在设备电源管理中有用处。与其它Driver中的PowerHandle作用类似。
二.Touch Driver和GWES的交互
1.Touch Driver中的 Callback 函数
GWES调用TouchPanelEnable()初始化Touch Driver,并传入Callback函数指针pfnCallback作为实参。在TouchPanelEnable()中将会保存该Callback函数的指针,并在数据采集中断线程IST中调用该Callback函数,以通知GWES目前的坐标点。
函数TouchPanelEnable()中对该Callback函数的处理如下:
BOOL TouchPanelEnable( PFN_TOUCH_PANEL_CALLBACK pfnCallback ) { BOOL ReturnValue;
// // Do the 'attach' code. Normally, this would have been // done in the ThreadAttach block, but this driver is set // up to be statically linked to GWE, in which case none of // the DLL related calls would even be invoked. // TouchPanelpAttach();
EnterCriticalSection( &csMutex );
// // Insure the device is disabled and no one is attached to the logical // interrupt. // Power on the device. // Connect the logical interrupt to the device. |