Keyboard Driver Development Concepts
Other versions of this page are also available for the following:
8/28/2008
Keyboard drivers are divided into components. This facilitates developing keyboard drivers for any keyboard layout. A keyboard layout is the key arrangement used for a particular keyboard, including such factors as the number of keys and the configuration of the keys. Some proprietary keyboards use custom layouts, and many keyboards allow a user to map keys to characters according to personal preference.
For All Platforms
Some keyboard drivers must handle keys that generate multiple virtual keys. This is useful on smaller hardware platforms that do not have all of the physical keys normally present on keyboards used with desktop workstations. Some of the keys have multiple functions, modified functions, or both. The driver generates virtual keys based on the state of particular physical keys and modifier keys, such as SHIFT and ALT.
Generally, you should implement the keyboard driver as a layered driver. The upper layer, or model device driver (MDD), maps scan codes to virtual-key codes, generates character data associated with virtual-key codes, and then packages keyboard messages and puts them in a system-wide message queue. The lower layer, or platform-dependent driver (PDD), retrieves scan codes from hardware.
The following illustration shows a keyboard driver stack that is hardware-platform independent.
The keyboard driver is different from other device drivers because it is language dependent. The scan code to virtual-key code and virtual-key code to Unicode character translations are both dependent only on the keyboard layout for the language. The PFN_KEYBD_DRIVER_VKEY_TO_UNICODE function is responsible for generating the correct Unicode character based on the state of the virtual keys. This function is dependent only on the keyboard layout for the language. Both of these conversions are based on translation tables; also known as, keyboard mappings, which you can customize for different languages. You can create your own keyboard mappings or customize the existing keyboard mappings, if necessary.
The Graphics, Windowing, and Events Subsystem (GWES) loads the keyboard driver at boot time. When GWES starts, it retrieves the name of the keyboard driver dynamic-link library (DLL) from the HKEY_LOCAL_MACHINE\Hardware\DeviceMap\KEYBD\Drivername registry key. If no entry is found, GWES uses the default name, Keybddr.dll. It then loads the DLL and verifies that all required entry points exist. Then, GWES calls the PFN_KEYBD_DRIVER_INITIALIZE function to perform a one-time initialization. In this function, the driver saves a local copy of the GWES callback function and initializes the hardware and interrupt service thread (IST) to handle keyboard interrupts. When an interrupt is signaled, the keyboard driver is responsible for converting the hardware scan code into a virtual-key code and passing both to GWES through either the callback passed to PFN_KEYBD_DRIVER_INITIALIZE_EX or the keybd_event API. Later, GWES pulls the keyboard event from the queue and calls back to the driver's PFN_KEYBD_DRIVER_VKEY_TO_UNICODE routine. The driver analyzes the specified key event and the virtual-key state and generates the corresponding characters. GWES then sends the virtual-key code and the characters to the appropriate application. The keyboard driver must add the flags KEYBD_DEVICE_SILENT or KEYBD_DEVICE_SILENT_REPEAT to the virtual-key codes or pass KEYEVENTF_SILENT to keybd_event in order to suppress audible key clicks.
The PFN_KEYBD_DRIVER_GET_INFO and PFN_KEYBD_DRIVER_SET_MODE functions get and set information about the keyboard. When the main input thread processes a keyboard-connection event through the callback function passed to PFN_KEYBD_DRIVER_INITIALIZE_EX, the thread calls the PFN_KEYBD_DRIVER_GET_INFO function to get the virtual-key code to Unicode data supplied by the driver. The thread also allocates the required memory for the virtual-key state data and any extra data required by the driver.
The PFN_KEYBD_DRIVER_INITIALIZE_EX and PFN_KEYBD_EVENT_CALLBACK_EX functions replace the non-Ex versions of these functions. The Ex functions provide support for Terminal Server Client by handling extra scan code information that the Terminal Server Protocol requires. The sample keyboard drivers on all hardware platforms use the Ex versions.
Required and Optional Keyboard Driver Functionality
Keyboard drivers must call keybd_event to notify GWES of any keyboard activity.
The following list shows the optional keyboard driver functionality:
- Updating keyboard drivers to work with Layout Manager. For more information, see Layout Manager.
- Implementing MapVirtualKey(uCode, 0) to enable Remote Desktop Protocol (RDP). MapVirtualKey(uCode, 0) must perform virtual key code to XT scan code conversions. For more information, see Remote Desktop Protocol Support.
- Implementing MapVirtualKey(uCode, 3) to enable USB keyboards. MapVirtualKey(x, 3) must perform AT scan code to virtual key code conversions.
- Enabling USB keyboard LEDs
For Windows Embedded CE, for more information, see Adding Keyboard LED Support to the HID Keyboard Driver.
Remarks
It is recommended that the backlight driver does not forward softkey presses to the OS when the backlight is off.
For Windows Mobile
Remarks
**Device drivers that launch applications should use the State and Notifications Broker to check the device lock state prior to launching applications that present a User Interface to the user. This action will prevent applications from coming up over the lock screen and potentially exposing sensitive information.
To check the locked state the following code may be used.
DWORD dwLockState = 0;
RegistryGetDWORD(SN_LOCK_ROOT, SN_LOCK_PATH, SN_LOCK_VALUE, &dwLockState);
if(dwLockState & SN_LOCK_BITMASK_DEVICELOCKED){
//device is locked
}
if(dwLockState & SN_LOCK_BITMASK_KEYLOCKED){
//device is key locked
}
if(dwLockState & SN_LOCK_BITMASK_SIMLOCKED){
//device is SIM locked
}
The SN_LOCK_* values are defined in the snapi.h header file and the function RegistryGetDWORD is defined in the regext.h header file.**
See Also
Concepts
Layout Manager
Keyboard Driver Samples
Keyboard Driver Registry Settings
Device Layouts
Input Languages
Translating Scan Codes to Virtual-Key Codes
External Keyboard Driver Support