Lately I’ve started a small collection of IBM Model-M keyboards. Well, two. And a modern Unicomp Model-M that I somehow managed to murder. The problem with the original ones is that they’re not the usual layout, for me. One is a Portuguese layout, and the other is a US layout. Both have the problem that one of the keys I need isn’t available. The key in question is the one I’d ordinarily get “\” and “|” from. This key is at the bottom left of the Irish keyboard layout (and the UK layout, which is very similar), next to Z. The key does not exist on US layout keyboards. There is a key with those two symbols on it, but that key serves the purpose of the Irish “#” and “~” key, both of which are found elsewhere on the US keyboard layout. In short, we have an extra key here that US keyboards simply do not have.
Sorry about the long pre-amble. Here’s the meat: on my main computer (a laptop that travels around with me from desk to desk, where I have my various Models-M), I run both Linux and Windows. And, being a bit of a techie, I need both “\” and “|” to work for me, so I put them under the key to the left of the digit “1”, the one that usually does “`” and “¬” and “¦“. Here’s how I did it.
xmodmap -e 'keycode 49 = grave bar grave bar backslash brokenbar'
Download and run the Microsoft Keyboard Layout Creator, and create a new Layout.
This should really be two blog posts, because most people will look for one or the other, but hey, I did them at the same time so you might too!
Linux: xev and xmodmap
First of all, I had to realise I had one fewer key than I needed. This hurt, on an emotional level. After much introspection and caffeine, I realised I had to repurpose an existing key, and re-reading the xmodmap man pages reminded me I had lots of room to play with. So, I used xev to find the correct key:
KeyPress event, serial 33, synthetic NO, window 0x5000001, root 0x109, subw 0x0, time 341821819, (713,297), root:(715,349), state 0x10, keycode 49 (keysym 0x60, grave), same_screen YES,
The third line is the important one. It’s got “keycode 49” and “keysym 0x60, grave”. That tells you that the keycode (physical key) is 49, and that it’s currently mapped to the keysym “grave”, that’s the symbol “`” associated with the key, and a symbol we sometimes call “backtick”.
Keysyms are found here on my machine:
$ locate keysymdef.h /usr/include/X11/keysymdef.h
Some of the keysyms look like this:
$ grep -C 2 0x0060 `locate keysymdef.h` #define XK_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */ #define XK_underscore 0x005f /* U+005F LOW LINE */ #define XK_grave 0x0060 /* U+0060 GRAVE ACCENT */ #define XK_quoteleft 0x0060 /* deprecated */ #define XK_a 0x0061 /* U+0061 LATIN SMALL LETTER A */ #define XK_b 0x0062 /* U+0062 LATIN SMALL LETTER B */
The “grave” symbol is 0x0060 (remember the 0x60 from the xev output?).
The current keyboard mapping shows the following keys have something with “grave” in:
$ xmodmap -pke | grep grave keycode 49 = grave notsign grave notsign brokenbar keycode 51 = numbersign asciitilde numbersign asciitilde guillemotleft guillemotright dead_grave dead_breve keycode 94 = backslash bar backslash bar dead_grave dead_acute bar brokenbar
There’s that keycode 49 (remember the xev output?). The other two have dead_grave, which I don’t really care about (although Windows has that as a default. More later.)
So, this is where the xmodmap docs go a bit wrong (more later: look for “Mode_switch“). They say the first four (represented above by “grave notsign grave notsign” are the only ones we care about… but a simple test:
$ xmodmap -e 'keycode 49 = 1 2 3 4 5 6 7 8'
…shows that combinations of that little key, alone, with shift, with other modifiers (particularly AltGr) result only in 1, 2, 5, 6 appearing. That matches what you’d expect when you type the key as is: you get grave with the key alone, notsign with shift, and brokenbar when using AltGr. So that means we’re looking at 1, 2, 5, 6.
Right, bearing that in mind, a quick look in keysymdef.h (along with some sneaky xev action with a different keyboard) shows that backslash “\” is called “backslash”, and the pipe symbol “|” is called “bar”. Next, bearing in mind that I never use notsign “¬” or brokenbar “¦”, I can ignore those. So, that’s how I came up with the following:
xmodmap -e 'keycode 49 = grave bar grave bar backslash brokenbar"
You can then save the current map to a file by doing something like this:
$ xmodmap -pke > ~/.xmodmaprc
…and then put it in a startup script (such as .bash_profile) as follows:
A brief aside: Mode_switch
The xmodmap man page threw me a curveball a bit, because it suggests that the first four keysyms are the relevant ones, and the latter four are ignored. This assumes that AltGr is set to something called “Mode_switch”, which it transpires has not been the default for quite some time.
Enter “ISO_Level3_Shift“. This is what kicks in the latter four elements of the xmodmap map, and is what AltGr normally does. That’s why “backslash” is the fifth element in the above xmodmap command.
During my investigations, I converted my “Menu” key (the one on the bottom right, beside the right Ctrl key) into another modifier, by doing the following:
- Firstly, use xev to get the keycode for the Menu key, which turns out to be 135.
- Run the following xmodmap commands to clear out Mode_switch from mod5 (AltGr) and add the Menu key as the Mode_switch modifier:
xmodmap -e 'clear mod5' xmodmap -e 'add mod5 = ISO_Level3_Shift' xmodmap -e 'keycode 135 = Mode_switch'
Now we can do fun stuff with a single key:
xmodmap -e 'keycode 49 = grave bar onequarter threequarters backslash brokenbar onehalf notsign'
The “notsign” can be seen by pressing shift, AltGr, our new “Menu” modifier (Mode_switch), and the “`” key. All eight symbols are available from that key by modifying it with combinations of shift, AltGr, and my new Menu modifier. Of course, my old Model-M keyboards predate Windows by quite some time, so the Menu key doesn’t exist. I use Oracle’s VirtualBox a lot, and it uses the right Ctrl key, so I can’t use that without tweaking VirtualBox. I was briefly considering making Scroll Lock into a modifier (keycode 78 if you’re interested), but fortunately I recovered from my madness before going any further in that direction. Who needs eight symbols per key anyway?
I did say it was a brief aside. Fear not, I’ve no intention of using this insanity. Yet, anyway.
Windows: Microsoft Keyboard Layout Creator
Next, Windows. I downloaded the KLC from the link shown above, and repeated here:
Once installed, you can open it up by running the MSKLC.exe file, and see a blank keyboard.
- First: File -> Load Existing Keyboard…
- Choose a layout that’s closest to the one you want. In my case, Irish.
- Next, click the key you want to change. In my case, it was the “`” key at the top left.
- Click “All…” to change the modified key settings.
- The shift-state of 0x0060 is fine (if you read the Linux section above you’ll recognise 0x0060 as the keysym for “grave”).
- To match my Linux configuration, I want to change the shift+ to “|”, which I could type in to the “Code Point(s)” box if I had that symbol on my keyboard, but I happen to know it’s U+007c, so I type that in. Similarly, I put “U+005c” into the box for ctrl+alt+, because I want “\” for that combination.
- One extra point: in Windows, the grave/backtick key is a “dead key” (I did say I’d come back to that), which means when you hit the key, nothing happens until you hit another key. If that key is a symbol for which a grave accent is appropriate, for example a vowel, such as à, è, ì, ò, ù, the symbol is accented as shown. For other symbols, such as space, you simply get a grave: `. I tend to dislike that setting, so I’ll take the tick out of “Dead Key?”, before clicking OK.
- Now you’ve set up the keyboard, so the next thing to do is set the properties and then build and install the custom layout. The “Project -> Properties” menu lets you name and describe your layout. I simply chose “Jeremy” as the name, and “Irish – Jeremy” as the Description.
- Finally, “Project -> Build DLL and Setup Package” creates a folder with an executable and supporting files to install your custom layout. Once you’ve done that, run the setup package, and then go into Control Panel’s Regional Settings to change your keyboard to your new layout.
Now the only thing to worry about is what happens when I use a normal keyboard…
Image courtesy of mattjb, licensed under the Creative Commons BY-NC-SA licence