tchmdd.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,050 行 · 第 1/2 页

C
1,050
字号
    RegCloseKey(hKey);

    RETAILMSG(1, (TEXT("TOUCH:ThrdPrio = %d, ThrdHighPrio = %d\n"), *ThrdPrio, *ThrdHighPrio));
    
    return;
}   // TouchPanelpGetPriority


//**********************************************************************
// The following routines provide the exported DDI interface.
// @doc EX_TOUCH_DDI EXTERNAL DRIVERS MDD TOUCH_PANEL
//**********************************************************************



#ifdef DEBUG
PFN_TOUCH_PANEL_SET_CALIBRATION v_pfnSetCalibration = TouchPanelSetCalibration;
#endif

/*++
Autodoc Information:

    @func BOOL | TouchPanelDllEntry |
    Dll entry point.

    @rdesc
    TRUE if the function succeeds. Otherwise, FALSE.

--*/
BOOL
TouchPanelDllEntry(
    HANDLE  hinstDll,    //@parm Process handle.
    DWORD   fdwReason,   //@parm Reason for calling the function.
    LPVOID  lpvReserved  //@parm Reserved, not used.
    )
{
xxxxxxxx
    BOOL ReturnCode = TRUE;
    switch ( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
            DEBUGREGISTER(hinstDll);
            DEBUGMSG( ZONE_FUNCTION, (TEXT("Dll Process Attach\r\n")) );

             //
             // Process is attaching.  We allow only 1 process to be attached.
             // If our global counter (maintained by the PDD) is greater than 0,
             //   error.
             //

            if ( DdsiTouchPanelAttach() > 1 )
            {
                DEBUGMSG( ZONE_FUNCTION, (TEXT("DdsiTouchPanelAttach > 1\r\n")) );
                DdsiTouchPanelDetach(); // if a process attach fails, the detach is
                 // never called. So adjust the count here.
                ReturnCode = FALSE;
            }
            break;

        case DLL_THREAD_ATTACH:
            DEBUGMSG( ZONE_FUNCTION, (TEXT("Dll Thread Attach\r\n")) );

             //
             // Thread is attaching.  We allow only 1 thread to be attached.
             //

            if ( ++culReferenceCount > 1 )
                ReturnCode = FALSE;
            break;

        case DLL_THREAD_DETACH:
            DEBUGMSG( ZONE_FUNCTION, (TEXT("Dll Thread Detach\r\n")) );

             //
             // Thread is detaching. If the detaching thread is the thread that
             // was allowed to attach, we now have no one to process touch panel
             // points. In this case we clear the callback functions, disable the
             // touch panel hardware, and disconnect from the logical interrupt.
             //

            if ( --culReferenceCount == 0 )
            {
                v_pfnPointCallback = NULL;
                DdsiTouchPanelDisable();
                InterruptDisable( gIntrTouch );
                InterruptDisable( gIntrTouchChanged );
            }
            break;

        case DLL_PROCESS_DETACH:
            DEBUGMSG( ZONE_FUNCTION,
                      (TEXT("Dll Process Detach\r\n")) );

             //
             // Process is detaching.
             // If the detaching process is the process that was allowed
             // to attach, we reset the callback functions,
             // reference count, disable the touch panel, and disconnect from the
             // logical interrupt.
             //
             //
            DdsiTouchPanelDetach();
            break;
    }
    return ( ReturnCode );
}


/*++

 @func BOOL | TouchPanelGetDeviceCaps |
 Queries capabilities about the physical touch panel device.

 @parm ULONG | iIndex |
 Specifies the capability to query. They are one of the following:

 @flag DDI_TPDC_SAMPLERATE |
 The sample rate.
 @flag DDI_TPDC_CALIBRATIONPOINTS |
 The X and Y coordinates used for calibration.
 @flag DDI_TPDC_CALIBRATIONDATA |
 The X and Y coordinates used for calibration mapping.
 @flag DDI_TPDC_SAMPLERATE |
 Size of the digitizer panel (X, Y).

 @parm LPVOID | lpOutput |
 Points to the memory location(s) where the queried information
 will be placed. The format of the memory referenced depends on
 the setting of iIndex. If 0, returns the number of words
 required for the output data.

 @rdesc
 The return value is TRUE if the information was retrieved succesfully,
 and FALSE otherwise.
 

--*/
BOOL
TouchPanelGetDeviceCaps(
    INT		iIndex,
    LPVOID  lpOutput
    )
{
    struct TPDC_CALIBRATION_POINT *pTCP;
    BOOL fGotCaps = FALSE;
    

    EnterCriticalSection( &csMutex );

    if( lpOutput != NULL)
    {
        fGotCaps = DdsiTouchPanelGetDeviceCaps(iIndex, lpOutput);

         // We want to remember the screen size for later use.  Some day,
         // we might change this so that screen size is passed in as
         // part of setup.  But for now, it is part of getCalibrationPoint
        if( iIndex == TPDC_CALIBRATION_POINT_ID )
        {
            pTCP = (struct TPDC_CALIBRATION_POINT *)lpOutput;
            DisplayWidth  = pTCP -> cDisplayWidth;
            DisplayHeight = pTCP -> cDisplayHeight;
        }
    }
    
    LeaveCriticalSection( &csMutex );

    return ( fGotCaps );
}
				
#ifdef DEBUG
PFN_TOUCH_PANEL_GET_DEVICE_CAPS v_pfnGetDeviceCaps = TouchPanelGetDeviceCaps;
#endif



/*++

Autodoc Information:

 @func BOOL | TouchPanelSetMode |
 Sets information about the abstract touch panel device.

 @parm ULONG | iIndex |
 Specifies the mode to set. They are one of the following:

 @flag DDI_TPSM_SAMPLERATE_HIGH |
 Set the sample rate to the high rate.

 @flag DDI_TPSM_SAMPLERATE_LOW |
 Set the sample rate to the low rate.

 @parm LPVOID | lpInput |
 Points to the memory location(s) where the update information
 resides. The format of the memory referenced depends on the
 mode.
 
 @rdesc
 If the function succeeds the return value is TRUE, otherwise, it is FALSE.
 Extended error information is available via the GetLastError function.

--*/
BOOL
TouchPanelSetMode(
	INT		iIndex,
	LPVOID	lpInput
    )
{
	BOOL	ReturnValue = TRUE;  // Assume it worked until someone says othewise

    EnterCriticalSection( &csMutex );
    switch( iIndex )
    {
        // The thread priority functions were provided so that OOM could
        // raise our priority as needed.
        case TPSM_PRIORITY_HIGH_ID:
            CeSetThreadPriority (hThread, gThreadHighPriority);
            break;
            
        case TPSM_PRIORITY_NORMAL_ID:
            CeSetThreadPriority (hThread, gThreadPriority);
            break;
            
        default:
            // If we can't handle it, give the PDD a chance
            ReturnValue = DdsiTouchPanelSetMode(iIndex, lpInput);
            break;
    }
    LeaveCriticalSection( &csMutex );
    
    return ( ReturnValue );
}


#ifdef DEBUG
PFN_TOUCH_PANEL_SET_MODE v_pfnSetMode = TouchPanelSetMode;
#endif



/*++

 @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 );
    InterruptDone( gIntrTouchChanged );
    InterruptDisable( gIntrTouchChanged );

	v_pfnPointCallback = pfnCallback;

    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 (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.
	    //
		if (!(hThread = CreateThread( NULL, 0, TouchPanelpISR, 0, 0, NULL))) {
	        TouchPanelpDetach();
	        InterruptDisable(gIntrTouch);
	        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
    )
{
    EnterCriticalSection( &csMutex );

    DdsiTouchPanelDisable();                // power off the panel.
    InterruptDone( gIntrTouch );         // Unregister the logical interrupt.
    InterruptDone( gIntrTouchChanged ); // Unregister the logical interrupt.
    InterruptDisable( gIntrTouch );
    InterruptDisable( gIntrTouchChanged );

    hThread = 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;

    EnterCriticalSection( &csMutex );

    //
    // If a calibration is already active, error.
    //

    if ( CalibrationState )
    {
        SetLastError( ERROR_POSSIBLE_DEADLOCK );
    	LeaveCriticalSection( &csMutex );
        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;

    LeaveCriticalSection( &csMutex );

    WaitForSingleObject( hCalibrationSampleAvailable, INFINITE );
    EnterCriticalSection( &csMutex );

	*pRawX = lCalibrationXCoord;
	*pRawY = lCalibrationYCoord;

	retval = ( CalibrationState == CalibrationValid );
    CalibrationState = CalibrationInactive;

    LeaveCriticalSection( &csMutex );

    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;
	
	RETAILMSG(1, (TEXT("CVAL ABORT")));

    SetEvent( hCalibrationSampleAvailable );

	LeaveCriticalSection( &csMutex );

	return;
}
#ifdef DEBUG
PFN_TOUCH_PANEL_READ_CALIBRATION_ABORT v_pfnCalibrationPointAbortTest = TouchPanelReadCalibrationAbort;
#endif


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?