The Big Picture: Follow One Key Press
You press A in Notepad. A fraction of a second later the letter appears. This section follows that one press through every layer, from your finger to the pixels. Driver names below are the usual ones on Windows 10/11; exact names can differ by device and version.
┌──────────────────────────────────────────────────────────────┐
│ 1. KEY + MATRIX SCAN switch closes, chip finds it │
│ 2. HID REPORT BUILT "Key 04 is down" (8 bytes) │
└──────────────────────────────┬───────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ 3. USB / BLUETOOTH xHCI polls; report arrives in RAM │
│ 4. HID CLASS DRIVERS hidusb, hidclass, kbdhid, kbdclass │
└──────────────────────────────┬───────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ 5. WINDOWS INPUT SYSTEM raw input thread (win32k) │
│ 6. LAYOUT TRANSLATION scan code -> virtual key -> char │
│ 7. MESSAGE TO WINDOW WM_KEYDOWN, WM_CHAR -> Notepad │
│ 8. APP DRAWS THE LETTER Notepad paints "a" │
└──────────────────────────────────────────────────────────────┘
3.1 Keyboard → USB/Bluetooth Transport
What it is: Everything in Section 1 and Section 2 happens first.
- Your finger closes the switch. The microcontroller's matrix scan notices it and debounces it.
- The firmware turns "key at row 3, column 5" into a HID usage (code 04 for A) and puts it into the next HID report.
- When the host controller (xHCI) next polls the keyboard (for example within 8 ms), the keyboard answers with the report.
- The controller writes the report into RAM by DMA (Chapter 4, Section 4), without the CPU copying it, and then signals the CPU with a normal hardware interrupt that "a transfer finished".
For a Bluetooth or 2.4 GHz keyboard the same report arrives over the radio and is delivered through the Bluetooth stack (or the dongle's USB path).
| Step | Who | Time scale |
|---|---|---|
| Scan + debounce | Keyboard chip | Around a few milliseconds |
| Wait for poll | USB host | Up to the polling interval (1 to 8 ms typical) |
| Transfer + interrupt | xHCI, CPU | Microseconds |
So a key press adds a delay of a few to about ten milliseconds before the PC even knows. This is far below what humans notice, but is the reason competitive gamers like fast polling.
3.2 HID Class Driver Receives the Report
What it is: The report is a pile of bytes. A stack of drivers (see Chapter 13) passes it upward. Each driver does one job. A common stack for a USB keyboard looks like this:
USB keyboard hardware
▲
USB bus drivers (the hub / host controller drivers) ← Chapter 13, Section 16
▲
hidusb.sys "Carries HID reports over USB"
▲
hidclass.sys "General HID rules; reads the report descriptor"
▲
kbdhid.sys "Turns a keyboard HID report into key events"
▲
kbdclass.sys "The common keyboard driver every keyboard feeds into"
▲
Windows input system (win32k)
| Driver (usual name) | Job in one sentence |
|---|---|
| hidusb.sys | Moves HID data between the USB bus and the HID layer |
| hidclass.sys | The HID "manager": it reads the descriptor and creates a device for each keyboard or mouse |
| kbdhid.sys | Converts keyboard HID reports into scan codes plus up / down |
| kbdclass.sys | The keyboard "class driver": gathers input from any keyboard (USB, PS/2, Bluetooth) and passes it on |
| i8042prt.sys | For PS/2 keyboards, takes the place of the HID drivers |
Here is where the difference in Section 1.2 and 2.1 gets solved. HID gives "what is down right now"; Windows wants "key down / key up events". The keyboard driver compares each report with the previous one. A key that appeared is a key-down event. A key that vanished is a key-up event. The USB HID code (04) is converted to a Windows-style scan code.
3.3 Driver Generates Interrupt / Event
What it is: The driver works in two quick parts, like the ISR and DPC you met in Chapter 4, Section 3:
- Interrupt (urgent): the host controller raises its interrupt. The CPU stops its work for a moment and runs the controller's urgent code, which only notes that a transfer is complete.
- Deferred work (a little later): the rest of the processing happens a moment after, with interrupts allowed again. The HID drivers read the report, find the changes, and prepare key events.
The key events are placed in a queue by kbdclass.sys. A queue is a waiting line; the Windows input system takes events out of it in order. The queue protects you if the PC is briefly busy: your keystrokes line up instead of vanishing.
Two kinds of interrupt. With PS/2, each key triggers the keyboard's own interrupt (IRQ 1). With USB, there is no interrupt per key. The interrupt belongs to the USB controller ("a transfer is done"). The keyboard driver then finds the key inside the report.
3.4 Windows Input Subsystem (Raw Input) Processes It
What it is: The Windows desktop (Chapter 30) has a part of the kernel, win32k, that handles windows and input. A special thread there, often called the raw input thread, takes the key events from the class driver. "Raw" means before any meaning has been added: just "this key, up or down, from this device".
The raw input thread does three jobs:
- Handles system-wide keys first. For example, Ctrl+Alt+Del is treated specially, and some hotkeys (Win+L to lock the PC, Alt+Tab) are caught here before any application sees them.
- Offers the input to applications that asked for it raw. Programs such as games can register to receive WM_INPUT messages and know which device the input came from (the Raw Input API).
- Sends the rest on for translation (3.5) and delivery (3.6).
| Level | Who sees it | What they get |
|---|---|---|
| Driver level | Drivers | Scan code + up/down |
| Raw input | Programs that register for raw input | The device and the raw data |
| Normal input | Almost every program | Messages like WM_KEYDOWN, WM_CHAR |
3.5 Keyboard Layout Translation (Scan Code → Virtual Key → Character)
What it is: Now the PC applies the layout that Section 1.2 promised. Windows keeps a keyboard layout file for each layout you have installed, a small DLL in the system folder (for example KBDUS.DLL for US English; each layout has its own, and the names differ). It holds the tables for translation, in two steps:
scan code virtual key character
(physical place) (what the key "means") (what is typed)
0x1E ──► VK_A (0x41) ──► "a" (no Shift)
"A" (Shift or Caps Lock)
"Ä" (on some layouts, with AltGr)
| Step | Table | Why a middle step? |
|---|---|---|
| Scan code → virtual key (VK) | Layout file | Programs want to know "the A key" without worrying about where it sits |
| Virtual key + Shift/Ctrl/Alt/Caps state → character | Layout file + current key states | The same key gives different characters when Shift is down |
A virtual key code is a number that names a key's function, such as VK_A, VK_RETURN, VK_SHIFT or VK_F5. It is the same for every keyboard in the world. On the French layout, the physical key that has a scan code 0x1E gives a different virtual key than on a US layout, but the application only ever sees "the virtual key and the character".
The system also keeps state: it knows Shift is held, Caps Lock is on, and whether a dead key (an accent key that waits for the next letter, like the ^ before e to give ê) was pressed before. If you switch layouts (Win+Space), Windows simply uses another translation table. No hardware change is needed.
3.6 Message Routed to the Focused Application's Window Procedure
What it is: Windows (Chapter 30) knows which window has the keyboard focus: the one you are typing into, which is usually the active window. The input system puts a message into that window's thread's message queue. A message is a small package: "this event happened, with these details".
For our A key, there are usually three messages:
| Message | Meaning | Carries |
|---|---|---|
| WM_KEYDOWN | A key went down | Virtual key (VK_A), and in its extra data the scan code, repeat count and whether the key was already down |
| WM_CHAR | A character was typed | The character code (for example "a") |
| WM_KEYUP | The key went up | Virtual key and scan code |
The program's message loop (Chapter 23, Chapter 30) takes each message from its queue and calls a TranslateMessage step, which makes the WM_CHAR from the WM_KEYDOWN using the layout. Then DispatchMessage calls the window's window procedure ("window proc"): the function that decides what to do. Keys that do not make characters (arrow keys, F5, Shift) produce no WM_CHAR. Combination keys such as Ctrl+C reach the window as keystrokes and the program decides what they mean (copy).
Notice the focus point: only the focused window gets the keys. That is why a background program does not receive your typing, and why a "key logger" has to do something special to see it. It is also why Windows protects the focus (a background window can't easily steal it).
3.7 Application Updates the UI
What it is: The last step belongs to the program, not Windows.
- Notepad's window procedure receives WM_CHAR with "a".
- The text control adds "a" to its text in RAM (the document).
- It marks the changed area as needing a repaint.
- Windows sends a paint request, and Notepad draws the letter with the font engine (shapes of letters turned into pixels).
- The desktop compositor (Chapter 30) combines Notepad's picture with everything else, and the graphics card sends the new frame to the screen (Chapter 32, Display and GPU).
Key down → ... → WM_KEYDOWN → WM_CHAR "a" → text added → repaint → compositor → GPU → "a" on screen
The whole path usually takes a few tens of milliseconds, which feels instant.
3.8 Why the Chain Matters
| Symptom | Which layer to suspect |
|---|---|
| Wrong letters appear (Z and Y swapped, symbols wrong) | Layout (3.5): the wrong keyboard layout is active |
| One key does nothing, everything else works | Hardware (Section 1): dead switch, or a broken matrix line |
| The whole keyboard is dead after a driver update | Driver layer (3.2) |
| Keyboard works in BIOS but not in Windows | Windows drivers (3.2), because BIOS uses the simple boot-protocol report |
| Keystrokes lag when the PC is busy | The message queue of the one app, or a slow driver (Chapter 4, Section 3) |
| Wireless keyboard misses keys | Radio (Section 2.2): range, battery, interference |
Summary
| Step | What happens | Main player |
|---|---|---|
| 1 | Key, matrix scan, debounce | Keyboard chip |
| 2 | Build HID report | Keyboard chip |
| 3 | Host polls, report copied to RAM | xHCI, DMA |
| 4 | Report decoded into key down / up | hidusb, hidclass, kbdhid, kbdclass |
| 5 | Event taken by input system | win32k raw input thread |
| 6 | Scan code to virtual key to character | Keyboard layout DLL |
| 7 | Message sent to focused window | WM_KEYDOWN, WM_CHAR |
| 8 | App updates text and repaints | The application, compositor, GPU |