summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2018-02-09 11:10:33 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2018-02-09 17:57:08 -0500
commitdfc9ea5316a48d02bbd0247728a2825b377ab463 (patch)
treedcbfd3eab0f1024fb7371f5a2488f0b4ec39f810
parent87ce1bc0de3bf1368f3160e0ca28bd282384e109 (diff)
initial commit of kbd-xmodmap
-rw-r--r--public/kbd-xmodmap.md129
1 files changed, 129 insertions, 0 deletions
diff --git a/public/kbd-xmodmap.md b/public/kbd-xmodmap.md
new file mode 100644
index 0000000..5dbccc1
--- /dev/null
+++ b/public/kbd-xmodmap.md
@@ -0,0 +1,129 @@
+GNU/Linux Keyboard Maps: xmodmap
+================================
+---
+date: "2017-10-01"
+---
+
+The modmap subsystem is part of the core [X11 protocol][xproto].
+However, it has been replaced by the [X Keyboard (XKB)
+Extension][kbproto] to the protocol, which defines a facade that
+emulates the legacy modmap subsystem so that old programs still
+work---including those that manipulate the modmap directly!
+
+[xproto]: https://www.x.org/releases/current/doc/xproto/x11protocol.html
+[kbproto]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html
+
+For people who like to Keep It Stupid Simple, the XKB extension looks
+horribly complicated and gross---even ignoring protocol details, the
+configuration syntax is a monstrosity! There's no way to say
+something like "I'd like to remap Caps-Lock to be Control", you have
+to copy and edit the entire keyboard definition, which includes
+mucking with vector graphics of the physical keyboard layout! So it's
+very tempting to pretend that XKB doesn't exist, and it's still using
+modmap.
+
+However, this is a leaky abstraction; for instance: when running the
+`xmodmap` command to manipulate the modmap, if you have multiple
+keyboards plugged in, the result can depend on which keyboard you used
+to press "enter" after typing the command!
+
+Despite only existing as a compatibility shim today, I think it is
+important to understand the modmap subsystem to understand modern XKB.
+
+Conceptual overview
+-------------------
+
+There are 3 fundamental tasks that the modmap subsystem performs:
+
+ 1. `keyboard: map keycode -> keysym`
+ 2. `keyboard: map keysym -> modifier bit` WAIT?
+ 3. `pointer: map physical button -> logical button`
+
+You're thinking: "Great, so the X server does these things for us!"
+Nope! It exposes those mappings, and leaves the actual
+transformations up to the client. Generally, the actual
+transformations are performed automatically inside of libX11/libxcb.
+
+Vocab:
+------
+
+ - keycode: A numeric ID for a hardware button; this is as close
+ the the hardware as X11 modmaps let us get. These are
+ conceptually identical to Linux kernel keycodes, but the numbers
+ don't match up. Xorg keycodes are typically linux_keycode+8.
+
+ - keysym: A 29-bit integer code that is meaningful to
+ applications. A mapping of these to symbolic names is defined
+ in <X11/keysymdef.h> and augmented by
+ </usr/share/X11/XKeysymDB>. See: XStringToKeysym() and
+ XKeysymToString(). We will generally use the symbolic name in
+ the modmap file. The symbolic names are case-sensitive.
+
+ - Modifier state: An 8-bit bitmask of modifier keys (names are
+ case-insensitive):
+
+ 1 << 0 : shift
+ 1 << 1 : lock
+ 1 << 2 : control
+ 1 << 3 : mod1
+ 1 << 4 : mod2
+ 1 << 5 : mod3
+ 1 << 6 : mod4
+ 1 << 7 : mod5
+
+Commands by task:
+-----------------
+
+The `xmodmap` command has its own little quirky syntax. There are 8
+commands that it recognizes. Let's look at those, grouped by the 3
+tasks that the modmap subsystem performs:
+
+ 1. `keyboard: map keycode -> keysym`
+
+ - `keycode KEYCODE = PLAIN [SHIFT [MODE_SWITCH [MODE_SWITCH+SHIFT ]]]`
+
+ Actually takes a list of up to 8 keysyms, but only the first
+ 4 have standard uses.
+
+ - `keysym OLD_KEYSYM = NEW_KEYSYMS...`
+
+ Takes the keycodes mapped to `OLD_KEYSYM` and maps them to
+ `NEW_KEYSYM`.
+
+ - `keysym any = KEYSYMS...`
+
+ Finds an otherwise unused keycode, and has it map to the
+ specified keysyms.
+
+ 2. `keyboard: map keysym -> modifier bit`
+
+ - `clear MODIFIER`
+ - `add MODIFIERNAME = KEYSYMS...`
+ - `remove MODIFIER = KEYSYMS...`
+
+ 3. `pointer: map physical button -> logical button`
+
+ - `pointer = default`
+
+ This is equivalent to `pointer = 1 2 3 4 5 6...` where the
+ list is as long as the number of buttons that there are.
+
+ - `pointer = NUMBERS...`
+
+ TODO
+
+Appendix:
+=========
+
+I use this snippet in my Emacs configuration to make editing xmodmap
+files nicer:
+
+ ;; http://www.emacswiki.org/emacs/XModMapMode
+ (when (not (fboundp 'xmodmap-mode))
+ (define-generic-mode 'xmodmap-mode
+ '(?!)
+ '("add" "clear" "keycode" "keysym" "pointer" "remove")
+ nil
+ '("[xX]modmap\\(rc\\)?\\'")
+ nil
+ "Simple mode for xmodmap files."))