📄 tchmain.c
字号:
/*++
@func VOID | TouchPanelPowerHandler |
System power state notification.
@parm BOOL | bOff | TRUE, the system is powering off; FALSE, the system is powering up.
@comm
This routine is called in a kernel context and may not make any system
calls whatsoever. It may read and write its own memory and that's about
it.
--*/
void
TouchPanelPowerHandler(
BOOL bOff
)
{
DdsiTouchPanelPowerHandler( bOff );
return;
}
#ifdef DEBUG
PFN_TOUCH_PANEL_POWER_HANDLER v_pfnPowerHandler = TouchPanelPowerHandler;
#endif
/*++
@func BOOL | TouchPanelEnable |
Powers up and initializes the touch panel for operation.
@rdesc
If the function succeeds, the return value is TRUE; otherwise, it is FALSE.
@comm
Following the call to this function the touch panel device generates
pen tip events and samples.
--*/
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.
//
InterruptDone( gIntrTouch );
InterruptDisable( gIntrTouch );
if( SYSINTR_NOP != gIntrTouchChanged ) {
InterruptDone( gIntrTouchChanged );
InterruptDisable( gIntrTouchChanged );
}
v_pfnCgrPointCallback = pfnCallback;
if (v_pfnCgrCallback != NULL)
v_pfnPointCallback = v_pfnCgrCallback;
else
v_pfnPointCallback = pfnCallback;
ghevCalibrationActivity = NULL;
ReturnValue = DdsiTouchPanelEnable();
if (ReturnValue && !InterruptInitialize(gIntrTouch, hTouchPanelEvent, NULL, 0)) {
DEBUGMSG(ZONE_ERROR, (TEXT("TouchPanelEnable: InterruptInitialize(gIntrTouch %d failed\r\n"),
gIntrTouch));
DdsiTouchPanelDisable();
ReturnValue = FALSE;
}
if ( ( SYSINTR_NOP != gIntrTouchChanged ) &&
ReturnValue && !InterruptInitialize( gIntrTouchChanged, hTouchPanelEvent, NULL, 0)) {
DEBUGMSG(ZONE_ERROR, (TEXT("TouchPanelEnable: InterruptInitialize(gIntrTouchChanged %d failed\r\n"),
gIntrTouchChanged));
InterruptDisable(gIntrTouch);
DdsiTouchPanelDisable();
ReturnValue = FALSE;
}
if (ReturnValue) {
// Create the ISR thread. If creation fails, perform cleanup and return failure.
//
bTerminate=FALSE;
if (!(hThread = CreateThread( NULL, 0, TouchPanelpISR, 0, 0, NULL))) {
TouchPanelpDetach();
InterruptDisable(gIntrTouch);
if( SYSINTR_NOP != gIntrTouchChanged )
InterruptDisable(gIntrTouchChanged);
DdsiTouchPanelDisable();
ReturnValue = FALSE;
} else {
// Get thread priority from registry
TouchPanelpGetPriority(&gThreadPriority, &gThreadHighPriority);
// Set our interrupt thread's priority
CeSetThreadPriority(hThread, gThreadPriority);
}
}
LeaveCriticalSection(&csMutex);
return(ReturnValue);
}
#ifdef DEBUG
PFN_TOUCH_PANEL_ENABLE v_pfnEnableTest = TouchPanelEnable;
#endif
/*++
@func BOOL | TouchPanelDisable |
Powers down the touch panel. Following the call to this function
the touch panel device no longer generates pen tip events or samples.
@rdesc
If the function succeeds, the return value is TRUE; otherwise, it is FALSE.
@comm
Following the call to this function the touch panel device no longer
generates pen tip events or samples.
--*/
VOID
TouchPanelDisable(
VOID
)
{
if ( hThread ) {
DWORD dwReturn=WAIT_TIMEOUT;
int count;
bTerminate=TRUE;
for (count=0;count<4;count++) {
SetEvent(hTouchPanelEvent);
if ((dwReturn=WaitForSingleObject(hThread,100))==WAIT_OBJECT_0)
break;
};
if (dwReturn!=WAIT_OBJECT_0) { // Can not kill normally. then force it
DEBUGCHK(FALSE);
#pragma prefast(suppress: 258, "Try to recover from a pathological failure")
TerminateThread(hThread,-1);
}
CloseHandle(hThread);
hThread=NULL;
}
EnterCriticalSection( &csMutex );
DdsiTouchPanelDisable(); // power off the panel.
InterruptDone( gIntrTouch ); // Unregister the logical interrupt.
InterruptDisable( gIntrTouch );
if( SYSINTR_NOP != gIntrTouchChanged ) {
InterruptDone( gIntrTouchChanged ); // Unregister the logical interrupt.
InterruptDisable( gIntrTouchChanged );
}
hThread = NULL;
ghevCalibrationActivity = NULL;
if ( hTouchPanelEvent )
{
//
// We created the touch panel event:
// close the event handle
// reset our bookkeeping information
//
CloseHandle( hTouchPanelEvent );
hTouchPanelEvent = NULL;
}
if ( hCalibrationSampleAvailable )
{
//
// We created the calibration sample available event:
// close the event handle
// reset our bookkeeping information
//
CloseHandle( hCalibrationSampleAvailable );
hCalibrationSampleAvailable = NULL;
}
LeaveCriticalSection( &csMutex );
DeleteCriticalSection( &csMutex );
}
#ifdef DEBUG
PFN_TOUCH_PANEL_DISABLE v_pfnDisableTest = TouchPanelDisable;
#endif
/*++
@func VOID | TouchPanelReadCalibrationPoint |
Initates the process of getting a calibration point. This function
causes the device driver to foward the last valid x and y coordinates
between the tip states of initial down and up to the calibration callback
function. The tip state of the forwarded coordinates is reported as
initial down.
@parm LONG | UcalX |
The uncalibrated X coordinate under calibration.
@parm LONG | UcalY |
The uncalibrated Y coordinate under calibration.
@rdesc
If the function succeeds, TRUE; otherwise FALSE. Extended error information
is available via the GetLastError function.
--*/
BOOL
TouchPanelReadCalibrationPoint(
INT *pRawX,
INT *pRawY
)
{
BOOL retval;
HANDLE hevActivity = NULL;
DWORD dwStatus;
HKEY hk;
if(!pRawX || !pRawY ) {
SetLastError(ERROR_INVALID_PARAMETER);
return ( FALSE ) ;
}
// Get a path to the GWES activity event. We need to set it ourselves
// because calibration is essentially a modal loop and doesn't put
// events onto the user input queue, which is where this event gets
// set inside GWES.
dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"System\\GWE", 0, 0, &hk);
if(dwStatus == ERROR_SUCCESS) {
WCHAR szEventPath[MAX_PATH];
DWORD dwSize = sizeof(szEventPath);
DWORD dwType;
// Read the path to the event and open it -- do this on every call
// to this API so that we're not forced to keep an event open that
// is almost never used.
dwStatus = RegQueryValueEx(hk, L"ActivityEvent", NULL, &dwType, (LPBYTE) szEventPath, &dwSize);
szEventPath[MAX_PATH - 1] = 0; // enforce null termination
if(dwStatus == ERROR_SUCCESS && dwType == REG_SZ) {
hevActivity = OpenEvent(EVENT_ALL_ACCESS, FALSE, szEventPath);
}
RegCloseKey(hk);
}
EnterCriticalSection( &csMutex );
//
// If a calibration is already active, error.
//
if ( CalibrationState )
{
SetLastError( ERROR_POSSIBLE_DEADLOCK );
LeaveCriticalSection( &csMutex );
if(hevActivity != NULL) {
CloseHandle(hevActivity);
}
return ( FALSE );
}
//
// Set sample count and active flag.
// Wait for calibration to happen.
// Update the memory with the x and y coordinates.
// Clear active flag.
// We be done.
CalibrationState = CalibrationWaiting;
// let the IST know about the event
ghevCalibrationActivity = hevActivity;
LeaveCriticalSection( &csMutex );
WaitForSingleObject( hCalibrationSampleAvailable, INFINITE );
EnterCriticalSection( &csMutex );
*pRawX = lCalibrationXCoord;
*pRawY = lCalibrationYCoord;
retval = ( CalibrationState == CalibrationValid );
CalibrationState = CalibrationInactive;
// done with the event
ghevCalibrationActivity = NULL;
LeaveCriticalSection( &csMutex );
// close the event handle
CloseHandle(hevActivity);
return retval;
}
#ifdef DEBUG
PFN_TOUCH_PANEL_READ_CALIBRATION_POINT v_pfnReadCalibrationPointTest = TouchPanelReadCalibrationPoint;
#endif
/*++
@func VOID | TouchPanelReadCalibrationAbort |
Aborts the currently active <f TouchPanelCalibratePoint>.
@rdesc
If the function succeeds, TRUE; FALSE is returned if there is no active
<f TouchPanelCalibrateAPoint> in progress.
--*/
VOID
TouchPanelReadCalibrationAbort(
VOID
)
{
EnterCriticalSection( &csMutex );
if ( ( CalibrationState == CalibrationValid ) ||
( CalibrationState == CalibrationInactive ) )
{
LeaveCriticalSection( &csMutex );
return;
}
CalibrationState = CalibrationAborted;
SetEvent( hCalibrationSampleAvailable );
LeaveCriticalSection( &csMutex );
return;
}
#ifdef DEBUG
PFN_TOUCH_PANEL_READ_CALIBRATION_ABORT v_pfnCalibrationPointAbortTest = TouchPanelReadCalibrationAbort;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -