Developing the Keyboard PDD Entry Point (Windows CE 5.0)

Send Feedback

In Windows CE .NET 4.1 or earlier operating systems (OSs), keyboard drivers used the DllMain function as the platform-dependent driver (PDD) entry point to initialize the keyboard hardware and to start the keyboard driver interrupt service thread (IST). In Windows CE .NET 4.2 or later, implement this new entry point to initialize the keyboard hardware and start the keyboard driver IST.

Perform all of the following steps in the file that contains the Windows CE .NET 4.1 or earlier implementation of the DllMain entry point.

The name of the file representing the PDD for each hardware platform can vary; usually the name is Kbdmouse.cpp. The PDD is not contained in the PDDList directory.

The keyboard driver directory, which is immediately subordinate to the Drivers directory, contains the dirs file that the build system uses to build the entire keyboard driver.

To develop the keyboard PDD entry point

  1. Rename DllMain to conform to the PFN_KEYBD_PDD_ENTRY function typedef.

    You can use any name, as long as it is globally unique in the Kbdmouse.dll that you will link. Microsoft recommends using a name based on your hardware platform.

    The following code example shows the PFN_KEYBD_PDD_ENTRYtypedef from Keybdpdd.h.

    typedef BOOL (*PFN_KEYBD_PDD_ENTRY)(UINT uiPddId, PFN_KEYBD_EVENT pfnKeybdEvent, PKEYBD_PDD *ppKeybdPdd);
    
  2. From the function definition, remove the line with the switch statement, the line with the case statement, and the brackets associated with the switch and case statements. (Do not remove the code within the switch and case statements.)

    The following code example shows an updated function definition, which was renamed TGTPLAT_Entry.

    BOOL
    WINAPI
    TGTPLAT_Entry(
        UINT uiPddId,
        PFN_KEYBD_EVENT pfnKeybdEvent,
        PKEYBD_PDD *ppKeybdPdd
        )
    {
    
        BOOL  bRet = FALSE;
    
        if (v_pp2p) {
          bRet = TRUE;
          goto leave;
        }
        v_pp2p = new Ps2Port;
        if (!v_pp2p->Initialize()) {
          ERRORMSG(1,(TEXT("Could not initialize ps2 port.\r\n")));
          goto leave;
        }
        //  We always assume that there is a keyboard.
        v_pp2k = new Ps2Keybd;
        if (v_pp2k->Initialize(v_pp2p)) {
          v_pp2k ->IsrThreadStart();
        } else {
          ERRORMSG(1,(TEXT("Could not initialize ps2 keyboard.\r\n")));
          delete v_pp2k;
          v_pp2k = NULL;
        }
        if (v_pp2p->MOUSE_PRESENT()) {
          v_pp2m = new Ps2Mouse;
          if ( v_pp2m -> Initialize(v_pp2p) ) {
            v_pp2m -> IsrThreadStart();
          } else {
            ERRORMSG(1,(TEXT("Could not initialize ps2 mouse\r\n")));
            delete v_pp2m;
            v_pp2m = NULL;
          }
        }
        bRet = TRUE;
    
        leave:
          return bRet;
    }
    
  3. Add the Keybdpdd.h file and the LayMgr.h file to the list of #include files.

  4. Add a PowerHandler function, which must adhere to the PFN_KEYBD_PDD_POWER_HANDLER function pointer. The Layout Manager calls the PowerHandler function when the hardware is powered up and powered down, if you want to support power handling in the PDD and decoupling the power state of a device from suspend or resume states of the system.

    To do this, in the PowerHandler function, call the KeybdPdd_PowerHandler function.

    The following code example shows an example PowerHandler function. In the file representing the PDD, place this function before the entry point.

    static
    void
    TGTPLAT_PowerHandler(
      UINT uiPddId,
      BOOL fTurnOff
      )
    {
      KeybdPdd_PowerHandler(fTurnOff);
    }
    

    For more information about the keyboard driver power handler function pointers, see PFN_KEYBD_DRIVER_POWER_HANDLER and PFN_KEYBD_PDD_POWER_HANDLER.

  5. If your keyboard has CAPS LOCK, NUM LOCK, and SCROLL LOCK LEDs, and you want to support those LEDs, create a function that adheres to the PFN_KEYBD_PDD_TOGGLE_LIGHTS function pointer. The Layout Manager calls the ToggleLights function when the user presses or releases these keys.

    To do this, in the PFN_KEYBD_PDD_TOGGLE_LIGHTS function, call the KeybdPdd_ToggleKeyNotification function. You can optimize the ToggleLights function by calling KeybdPdd_ToggleKeyNotification only when the state of the LEDs changes.

    The following code example shows an example PFN_KEYBD_PDD_TOGGLE_LIGHTS function with this optimization. In the file representing the PDD, place this function before the entry point.

    static
    void
    TGTPLAT_ToggleLights(
      UINT uiPddId,
      KEY_STATE_FLAGS KeyStateFlags
      )
    {
      static const KEY_STATE_FLAGS ksfLightMask = KeyShiftCapitalFlag | 
    KeyShiftNumLockFlag | KeyShiftScrollLockFlag; 
      static KEY_STATE_FLAGS ksfCurr;
    
      SETFNAME(_T("PS2_ToggleLights"));
    
      KEY_STATE_FLAGS ksfNewState = (ksfLightMask & KeyStateFlags);
    
      if (ksfNewState != ksfCurr) 
      {
        DEBUGMSG(ZONE_PDD, (_T("%s: PDD %u: Changing light state\r\n"), pszFname, uiPddId));
        KeybdPdd_ToggleKeyNotification(ksfNewState);
        ksfCurr = ksfNewState;
      }
    
      return;
    }
    
  6. Create a KEYBD_PDD structure to describe the PDD.

    This is a parameter in the Layout Manager's entry point. Place this structure after the PowerHandler and ToggleLights function definitions, but before the TGTPLAT_Entry function.

    The following code example shows a KEYBD_PDD structure.

    static KEYBD_PDD PS28042Pdd = {
      PS2_AT_PDD,
      _T("PS/2 TGTPLAT"),
      TGTPLAT_PowerHandler,
      TGTPLAT_ToggleLights
    };
    

    The following table shows the members of this structure.

    Member Description
    wPddMask Bit value or combination of bit values that describe the device layouts that work with this PDD.

    The device layout is the grouping of PDD-specific scan-code-to-virtual-key tables and a mapping function that are specific to that PDD, but change based on the input locale.

    If the PDD is an OEM-specific matrix keyboard, it could use an OEM-defined bit mask.

    The SA11X1 driver uses AT keyboard scan codes, so it uses the PS2_AT_PDD mask value.

    pszName Description of the PDD.
    pfnPowerHandler Pointer to the PowerHandler function.

    If your PDD does not support the PowerHandler function, set this member to NULL.

    For more information about this function pointer, see PFN_KEYBD_PDD_POWER_HANDLER.

    pfnToggleLights Pointer to the ToggleLights function.

    If your PDD does not support the ToggleLights function, set this member to NULL.

    For more information about this function pointer, see PFN_KEYBD_PDD_TOGGLE_LIGHTS.

  7. Declare two global variables to save the identifier and callback function parameters.

    The following code example shows a way to declare these global variables.

    UINT            v_uiPddId;
    PFN_KEYBD_EVENT v_pfnKeybdEvent;
    
  8. In the entry function, which a previous code sample renamed TGTPLAT_Entry, save the identifier and callback function parameters into the global variables.

    The following code example shows a way to save the identifier and callback function parameters into global variables.

    v_uiPddId = uiPddId;
    v_pfnKeybdEvent = pfnKeybdEvent;
    
  9. In the entry function, which you previously renamed TGTPLAT_Entry, save the address of the KEYBD_PDD structure to the ppKeybdPdd parameter.

    The following code example shows how to save the address of the KEYBD_PDD structure to the ppKeybdPdd parameter.

    *ppKeybdPdd = &PS28042Pdd;
    
  10. Save your progress.

See Also

Layout Manager

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.