{"id":2660,"date":"2013-01-11T19:57:33","date_gmt":"2013-01-11T19:57:33","guid":{"rendered":"http:\/\/really.zonky.org\/?p=2660"},"modified":"2013-01-11T19:57:33","modified_gmt":"2013-01-11T19:57:33","slug":"modern-low-level-keyboard-mapping-for-linux","status":"publish","type":"post","link":"https:\/\/really.zonky.org\/?p=2660","title":{"rendered":"Modern Low-Level Keyboard Mapping for Linux"},"content":{"rendered":"<p>Customising keyboard maps in Linux is somewhat &#8230; confused with lots of different tools and layers to perform the same task. There are a number of tools for performing some form of keyboard mapping, but the most common ones have some disadvantages :-<\/p>\n<ul>\n<li>\u00a0<em>xkb<\/em> (which is the modern X way), and\u00a0<em>xmodmap<\/em> (which is deprecated but conveniently has a very simple syntax for dealing with a single key) both work fine for ordinary keys but cannot do anything with &#8220;unusual&#8221; keys not passed into X. Just look online for just how many people have trouble with multimedia keys not being recognised.<\/li>\n<li>The PS\/2-specific tools of\u00a0<em>dumpkeys, loadkeys,\u00a0<\/em>and\u00a0<em>setkeycodes\u00a0<\/em>which work fine, but are somewhat reluctant to help out with USB keyboards.<\/li>\n<li>Plus the desktop environment you are using may well have its own idea of how the keyboard will be used (GNOME has a nasty tendency to grab the menu key away from me).<\/li>\n<\/ul>\n<p>There is fortunately another way which is rather difficult to find information about. Which is the reason behind this posting of course.<\/p>\n<p>This &#8220;other method&#8221; is to use the generic input system to perform the keyboard mapping which has certain advantages over other methods. Most of the information to do this came from a README file contained within the <a href=\"http:\/\/bazaar.launchpad.net\/~vcs-imports\/udev\/trunk\/view\/head:\/src\/keymap\/README.keymap.txt\">source code<\/a>.<\/p>\n<h2>The Example Keyboard<\/h2>\n<p>To demonstrate keyboard mapping, it is helpful to have an example keyboard with custom mappings to play with. Many of the keyboards I use this for are rather complex with\u00a0<em>many<\/em> mappings, but I also have a mini keyboard with relatively few mappings :-<\/p>\n<table align=\"centre\">\n<tbody>\n<tr>\n<th>Original Key<\/th>\n<th>new function<\/th>\n<\/tr>\n<tr>\n<td>Esc<\/td>\n<td>Lock screen<\/td>\n<\/tr>\n<tr>\n<td>`\/~<\/td>\n<td>Esc<\/td>\n<\/tr>\n<tr>\n<td>Caps Lock<\/td>\n<td>Control<\/td>\n<\/tr>\n<tr>\n<td>Insert<\/td>\n<td>Delete<\/td>\n<\/tr>\n<tr>\n<td>Delete<\/td>\n<td>`\/~<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>No great mystery as to why I want my keyboard mapped this way &#8211; I&#8217;m just fussy about keyboards.<\/p>\n<h2>The Basic &#8220;Tool&#8221;<\/h2>\n<p>In fact there is just one tool &#8211;\u00a0<em>\/lib\/udev\/keymap<\/em> &#8211; which performs all of the relevant tasks. Before it can do anything, it needs to be provided with the path of the relevant input device. This is easiest done from the console (rather than in X) as root. The easiest way of identifying the device is to unplug the keyboard, reboot the machine, and :-<\/p>\n<pre># ls \/dev\/input\/e* &gt; \/var\/tmp\/old.list\r\n[Plug in keyboard]\r\n# ls \/dev\/input\/e* &gt; \/var\/tmp\/new.list\r\n# diff \/var\/tmp\/old.list \/var\/tmp\/old.list\r\n&gt; \/dev\/input\/event13\r\n&gt; \/dev\/input\/event14<\/pre>\n<p>If you are lucky, there will be just one new input device. If not, you will have to try each one in turn. The first job is to record the keycode of each key to be customised in turn. To do this, it is necessary to run <em>keymap<\/em> with the input device and the &#8220;-i&#8221; option, and each keystroke will result in some output :-<\/p>\n<pre># \/lib\/udev\/keymap \/dev\/input\/event13 -i\r\nPress ESC to finish, or Control-C if this device is not your primary keyboard\r\nscan code: 0x70029   key code: esc\r\n# \/lib\/udev\/keymap \/dev\/input\/event13 -i\r\nPress ESC to finish, or Control-C if this device is not your primary keyboard\r\nscan code: 0x70035   key code: grave\r\nscan code: 0x70039   key code: capslock\r\nscan code: 0x70049   key code: insert\r\nscan code: 0x7004C   key code: delete<\/pre>\n<p>A key <em>can<\/em> be mapped temporarily using keymap. But before that a list of possible key names is useful to have; there is one to be found in \/usr\/include\/ :-<\/p>\n<pre># grep KEY_ \/usr\/include\/linux\/input.h | less<\/pre>\n<p>The relevant name would be the part that follows the &#8220;KEY_&#8221; converted to lower-case.<\/p>\n<pre># \/lib\/udev\/keymap \/dev\/input\/event13 0x70035 esc<\/pre>\n<p>But that is rather a temporary solution; it is better by far to create a file containing the necessary mappings to be automatically applied :-<\/p>\n<pre># cat \/tmp\/custom-filco.map\r\n0x70029 screenlock\r\n#\tOriginal: key code: esc\r\n0x70035 esc\r\n#\tOriginal: key code: grave\r\n0x70039 leftctrl\r\n#\tOriginal: key code: capslock\r\n0x70049 delete\r\n#\tOriginal: key code: insert\r\n0x7004C insert\r\n#\tOriginal: key code: delete<\/pre>\n<h2>Making The Mappings Permanent<\/h2>\n<p>The first step is to obtain some details to uniquely (or as much as possible) identify the keyboard. Run :-<\/p>\n<pre># udevadm info --export-db &gt; \/tmp\/udev-db.txt<\/pre>\n<p>And look through the output for the input device you previously used. Look for a <em>ID_VENDOR_ID<\/em> and <em>ID_MODEL_ID<\/em> that you can use.<\/p>\n<p>Next add a rule to <em>\/lib\/udev\/rules.d\/95-keymap.rules<\/em> along the lines of :-<\/p>\n<pre>ENV{ID_VENDOR_ID}==\"04d9\", ENV{ID_MODEL_ID}==\"2011\", RUN+=\"keymap $name custom-filco.map\"<\/pre>\n<p>Once this is working you may want to add it to your version of <em>custom-filco.map<\/em> as a comment to preserve it for use after upgrades; alternatively you may wish to create a new file that will not get overwritten.<\/p>\n<p>Before activating the new rule, remember to copy <em>\/tmp\/custom-filco.map<\/em> into <em>\/lib\/keymaps\/custom-filco.map<\/em>. And again keep another copy in a safe place to preserve.<\/p>\n<p>As to how to activate, a reboot is probably the simplest way.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Customising keyboard maps in Linux is somewhat &#8230; confused with lots of different tools and layers to perform the same task. There are a number of tools for performing some form of keyboard mapping, but the most common ones have some disadvantages :- \u00a0xkb (which is the modern X way), and\u00a0xmodmap (which is deprecated but <a href='https:\/\/really.zonky.org\/?p=2660' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_share_on_mastodon":"0"},"categories":[209],"tags":[1050,109,1051],"class_list":["post-2660","post","type-post","status-publish","format-standard","hentry","category-linux-it","tag-key-mapping","tag-keyboards","tag-udev","category-209-id","post-seq-1","post-parity-odd","meta-position-corners","fix"],"share_on_mastodon":{"url":"","error":""},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1f2KI-GU","_links":{"self":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/2660","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2660"}],"version-history":[{"count":9,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/2660\/revisions"}],"predecessor-version":[{"id":2669,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/2660\/revisions\/2669"}],"wp:attachment":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2660"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2660"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2660"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}