When I press a keyboard's key on some GTK application under Linux, what happens exactly? How does a key get received (from which device), interpreted, passed to the program, and then handled?
+5
A:
It's actually rather a complex process...
- The keyboard has a 2D matrix of key connections and its own microprocessor or gate array containing a microprocessor. It is constantly scanning the matrix to find out if any keys are pressed. (To save pins, the keys are not individually tested.) The keyboard micro speaks a protocol with the keyboard controller in your CPU and transmits a message indicating a keypress.
- The keyboard controller notes the code and interrupts the CPU.
- The keyboard driver receives an interrupt, reads the keycode out of a controller register, and places the keycode in a buffer that links the interrupt side of the kernel to the per-process threads. It marks the thread waiting for keyboard input as "runnable"
- This thread wakes up. It turns out, this is the X server. The X server reads the keycode from the kernel.
- The server will will check to see which window has keyboard focus. The window will be connected to one of various clients.
- The server sends an event to the client that displayed that specific window. (Note that to the server, every textbox and such is a "window", not just entire applications.)
- The event loop in the client is waiting for the next server event message. This connection could be via TCP or it could be a local Unix feature. It uses read(2) or a socket op to actually get the next event message.
- The low-level xlib routine passes the keypress up to higher level widgets, eventually getting to a GTK function of some kind.
- The GTK API element hands the character to your program.
I glossed over language mappings, console multiplexing, and a few other things...
Update: So, /dev/input/*
and in fact all of the /dev/*
things are things called block or character special files. The important thing is that they have no stored data in the filesystem, just a major and minor device number that serve to look up a driver in the kernel in a table. It's almost that simple. If you ls -l
/dev/input you will see a major and minor device number instead of a file size. The major number identifies the device driver and the minor number is a sort of instance-number that is passed (within the kernel) as a parameter to the driver.
DigitalRoss
2010-09-25 06:47:29
Wow, I'm amazed by the depth of your understanding on the flow. I'm still unclear on real device to `/dev/input/*` association though.
OTZ
2010-09-25 07:02:20