HOWTO_Microsoft_Natural_Ergonomic_Keyboard_4000
Contents |
Introduction
The Microsoft Natural Ergonomic Keyboard 4000 is one of several similar computer keyboards that tilts the keys to make typing more comfortable. Some non-standard keys have been added. Also, an F-lock key toggles the function keys (F1, F2, F3, etc.) between standard functions and "enhanced" functions (i.e., the F-Lock key changes the key codes that are generated when the function keys are pressed).
This HOWTO attempts to provide a working configuration for the Microsoft Natural Ergonomic Keyboard 4000 under linux, from the console to X, enabling all the non-standard keys which it features.
Kernel Configuration
Enabling all the functionalities of this extended keyboard requires patches to the kernel in order to encompass the totality of its capabilities. Thankfully such code has been provided and posted to the linux-usb-devel list [1] by liyu[2], as you can see from this list[3]. (As you can see from the list there is also a different patch from John Zaitseff, which I haven't tried and cannot comment upon). A simpler approach is found in these patches from powerman [4], possibly derived from the one just mentioned above, which unfortunately remove the non-F-locked versions of the Function keys. This behaviour can be reproduced, in what I believe to a far more flexible way, binding, for each of those keys, the same keysym to both the Function key and its non-F-locked correspondent, as we describe later for the console and X.
- Patches for 2.6.22 are available here[5]
- The 2.6.24 kernel has support for all buttons except Zoom and Spell (F10 without F-Lock), without needing any patches.
If you don't know how to apply the patches refer to Kernel/Patching.
The following are the required options to enable in the kernel, namely the evdev input module, the USB HID and what provived by the aforementioned patches.
| Linux Kernel Configuration: Kernel Configuration (2.6.18 Example) |
Device Drivers --->
Input Device Support --->
<M> Event Interface
USB Support --->
<M> USB Human Interface Device (full HID) support
[*] HID input layer support
[*] HID simple driver interface
<M> Microsoft Natural Ergonomic Keyboard 4000 Driver
|
Device Interface
The unusual phenomenon one can notice upon plugging in the keyboard is the creation of not one but two /dev/input/event* devices associated with it.
See the following extracts:
| File: /var/log/messages |
input: Microsoft Natural Ergonomic Keyboard 4000 as /class/input/input29 input: USB HID v1.11 Keyboard [Microsoft Natural Ergonomic Keyboard 4000] on usb-0000:00:1d.7-3.2 input: Microsoft Natural Ergonomic Keyboard 4000 as /class/input/input30 input: USB HID v1.11 Device [Microsoft Natural Ergonomic Keyboard 4000] on usb-0000:00:1d.7-3.2 The simple HID driver 'Microsoft Natural Ergonomic Keyboard 4000' register. The simple HID driver 'Microsoft Natural Ergonomic Keyboard 4000' attach on'Microsoft Natural Ergonomic Keyboard 4000' The simple HID driver 'Microsoft Natural Ergonomic Keyboard 4000' attach on'Microsoft Natural Ergonomic Keyboard 4000' |
rmmod usbnek4kand plug it back in.
A practical way to do it is something like this:
sleep 15s && rmmod usbnek4k
| File: /proc/bus/input/devices |
I: Bus=0003 Vendor=045e Product=00db Version=0173 N: Name="Microsoft Natural Ergonomic Keyboard 4000" P: Phys=usb-0000:00:1d.7-3.2/input0 S: Sysfs=/class/input/input29 H: Handlers=kbd event20 B: EV=120003 B: KEY=10000 7 ff800000 7ff febeffdf f3cfffff ffffffff fffffffe B: LED=7 I: Bus=0003 Vendor=045e Product=00db Version=0173 N: Name="Microsoft Natural Ergonomic Keyboard 4000" P: Phys=usb-0000:00:1d.7-3.2/input1 S: Sysfs=/class/input/input30 H: Handlers=kbd event21 B: EV=10000f B: KEY=7c0000 0 c0002 1400 0 0 1 10f80 287c407 ffff39fa d97157ff febeffdf ffefffff ffffffff fffffffe B: REL=40 B: ABS=1 0 |
| File: /proc/bus/usb/devices |
T: Bus=01 Lev=02 Prnt=08 Port=01 Cnt=02 Dev#= 20 Spd=1.5 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=045e ProdID=00db Rev= 1.73 S: Manufacturer=Microsoft S: Product=Natural Ergonomic Keyboard 4000 C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms I: If#= 1 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=10ms |
The reason for that is that the keyboard splits its functionalities in two different sections, so to speak (I lack a deep knowledge of USB terminology and technology, so forgive my imprecisions and correct them if possible).
The first device, which is the one listed first in each of the above files, and recognized as a "USB HID v1.11 Keyboard", is the device responsible for the standard keys events, with (parameters coming from the USB HID 1.11 specification) Interface Subclass having 1 as value (identifying it as a device implementing a Boot Protocol and therefore able to communicate with the BIOS at boot), and Interface Protocol set to 1 (identifying as a keyboard).
The second device, recognized as a "USB HID v1.11 Device", and with both Subclass and Protocol set to 0 (default values for every HID device not implementing any Boot Protocol, namely every device but keyboards and mice), is responsible for the "multimedia" keys events.
In fact, using evtest with the two /dev/input/event* related to the two devices, you will see how the events related to standard and "multimedia" keys are differentiated at the device level.
Console Configuration
The kernel driver provides keycodes for all the keys, (which can be discovered, as well as with evtest, as I said above, with the more traditional showkey -k), which are all below 256, apart from six of the multimedia keys:
- Favorites: 364
- One: 466
- Two: 467
- Three: 468
- Four: 469
- Five: 470
As far as I know, and as far as the ouput of dumpkeys suggests to me, only keycodes up to 255 can actually be employed.
man 5 keymaps explains the syntax of the files under /usr/share/keymaps, allowing to bind these keycodes to keysyms, strings, etc...
X.org configuration
When it comes to X configuration of the keyboard we must differentiate among:
- the configuration of the InputDevice section of /etc/X11/xorg.conf
- the configuration of various XKB files which constitute the description of the keyboard layout and its functions
- the configuration of programs such as xbindkeys or xvkbd or of the various Window Managers you might employ, which allow to bind a key to an action, program, or command
Device Configuration
The first thing about configuring the keyboard in X is choosing which devices have to manage the keyboard. The choice is between 'keyboard' (or its replacement 'kbd') or 'evdev'.
Initially I employed the first alternative, but unfortunately it suffers from the same shortcomings affecting the console, namely the lack of recognition for the six keys mentioned above. Actually xev doesn't even report their keycodes, making them utterly invisible to X.
As far as I could see around the net that's pretty much the situation everyone is in. Fortunately, there is a remedy, which ensues from the considerations made above about the existance of TWO devices associated with the keyboard.
The solution is, quite simply, to create two InputDevice sections, each using the 'evdev' driver to read the events respectively from one of the two event devices present.
That said we need a means to distinguish the two devices we need. The contents of /proc/bus/input/devices give us what we need. You can see in the box above how the event devices names are listed at the "Handlers:" line.
We need now to make those device names permanent, thus they'll remain the same even if you reboot and regardless of the order in which you might plug in your input peripherals.
In order to obtain that we will create two custom udev rules.
In case you never remove your keyboard from the usual usb socket (not even to move it to an external usb hub) you can use a simpler method I'll explain below.
First we'll use udevinfo on each of the two devices /dev/input/event* reported in /proc/bus/input/devices to discover the modalias string that's unique to those devices.
# udevinfo -a -p `udevinfo -q path -n /dev/input/event20`|grep modalias|grep usb
SYSFS{modalias}=="usb:v045Ep00DBd0173dc00dsc00dp00ic03isc00ip00"
# udevinfo -a -p `udevinfo -q path -n /dev/input/event21`|grep modalias|grep usb
SYSFS{modalias}=="usb:v045Ep00DBd0173dc00dsc00dp00ic03isc01ip01"
As you can see the strings differ only for the values of the USB HID Interface Subclass (isc) and Interface Protocol (ip) aforementioned.
Now we can create our custom rules:
| File: /etc/udev/rules.d/10-nek4k.rules |
KERNEL=="event*",SYSFS{modalias}=="usb:v045Ep00DBd0173dc00dsc00dp00ic03isc00ip00", MODE="0644", NAME="input/event20"
KERNEL=="event*",SYSFS{modalias}=="usb:v045Ep00DBd0173dc00dsc00dp00ic03isc01ip01", MODE="0644", NAME="input/event21"
|
We could not use different custom names than event* because of restrictions of the X evdev driver, therefore a good solution is, as you can see above, to set the names to eventXX, where XX is a number high enough not to conflict with other already connected input devices.
Here is an example of xorg.conf configuration.
| File: /etc/X11/xorg.conf |
Section "InputDevice"
Identifier "Keyboard1"
Driver "evdev"
Option "Protocol" "evdev"
Option "Device" "/dev/input/event20"
Option "XkbModel" "evdev"
...
EndSection
Section "InputDevice"
Identifier "Keyboard2"
Driver "evdev"
Option "Protocol" "evdev"
Option "Device" "/dev/input/event21"
Option "XkbModel" "evdev"
...
EndSection
...
Section "ServerLayout"
...
InputDevice "Keyboard1" "CoreKeyboard"
InputDevice "Keyboard2" "SendCoreEvents"
...
EndSection
|
The Option "Device" "..." is discouraged by the man page of the evdev driver ( man 4x evdev ), but the only other way to distinguish between the devices is to use the Option "Phys" "string", where "string" is found again in the contents of /proc/bus/input/devices, as the value of the corresponding field. Unfortunately that value is "connected" to the usb port the keyboard is plugged into, therefore it changes if the keyboard is plugged in elsewhere and thus not consistent in such cases.
Evdev more in depth
We have stated before,talking about the console, that six keys yield keycodes higher than 255, causing problems because in both console and X, 255 is the maximum allowed keycode. The kernel evdev driver assigns as keycodes values from 1 up, but X allows only keycodes in the range 9-255, therefore the X evdev driver first add 8 to every received keycode before parsing them, then truncate the keycode to an 8 bits value. In brief:
X keycode = ((kernel keycode + 8) mod 256)
That may, and with liyu's implementation does, cause some keys to have different kernel keycodes and same X keycodes. For example the Down Arrow key has the kernel keycode 108, while the Favorites key 364 (108+256), and under X with the evdev driver they both have keycode 116. A dirty workaround to this problem (caused, in my opinion, by the use of single-byte keycodes in X rather than by the the implementation of the kernel driver) is to replace the strings KEY_FAVORITES and KEY_FN_F1 in /usr/src/linux/drivers/usb/input/usbnek4k.c with others from /usr/include/linux/input.h so that eventually their X keycodes do not overlap ones associated with other keys.
Replacing those two strings along with the other KEY_FN_F* with others whose keycodes are below 256 (and of course not already generated by other keys) also allow us to have the keyboard completely mapped also using the console.
Further considerations and workarounds here. Talk:HOWTO Microsoft Natural Ergonomic Keyboard 4000
XKB Configuration
In order to map the supplementary keys we need to alter some of the xkb files under /usr/share/X11/xkb tree (it could also be /usr/lib/X11/xkb).
# ls -1 /usr/share/X11/xkb/ compat/ compat.dir compiled@ geometry/ geometry.dir keycodes/ keycodes.dir keymap/ keymap.dir rules/ semantics/ semantics.dir symbols/ symbols.dir types/ types.dir
The compat and types files are advanced configurations whose purposes are outside the scope of this howto; semantics files are collections of the previous two, while keymap files are deprecated. Our interest is the remaining four categories: rules, geometry, symbols, keycodes.
keycodes files map numeric keycodes to symbolic names.
symbols files map those symbolic names to keysyms, which are what we all use, from the alphanumeric characters to control characters, etc...
geometry files create descriptions of the physical layout of the keys, which can then be used to create a graphical representation of the keyboard with xkbcomp and xkbprint.
rules files define combinations of all the other types of files.
All the *.dir files list all the items within the files of the corresponding type, along with some flags.
Now we can begin:
- We add a nek4k specific geometry into geometry/microsoft :
| File: geometry/microsoft |
....
}; // End of "Keypad" section
alias <AC00> = <CAPS>;
alias <AA00> = <LCTL>;
};
// The following is the section to add
xkb_geometry "nek4k" {
// Approximate layout for a Microsoft Natural Keyboard
description= "Microsoft Natural Ergonomic Keyboard 4000";
width= 500;
height= 260;
shape.cornerRadius= 1;
shape "ZOOM" { { [ 16,15] } };
shape "MUL1" { { [ 22,10] } };
shape "MUL2" { { [ 20,10] } };
shape "MUL3" { { [ 26,10] } };
shape "DIR" { { [ 17,15] } };
shape "LDEF" { { [ 18,18] }, { [2,1], [15,16] } };
shape "FUNC" { { [ 18,15] }, { [3,1], [15,10] } };
shape "TABK" { { [ 36,18] }, { [3,1], [34,16] } };
shape "CAPS" { { [ 37,18] }, { [3,1], [33,16] } };
shape "LFSH" { { [ 23,18] }, { [3,1], [21,16] } };
shape "KEY~" { { [ 28,18] }, { [3,1], [25,15] } };
shape "KEY6" { { [ 20,18] }, { [2,1], [16,16] } };
shape "KEYB" { { [ 19,18] }, { [2,1], [15,16] } };
shape "KEYT" { { [ 30,18] }, { [2,1], [26,16] } };
shape "KEYG" { { [ 26,18] }, { [2,1], [22,16] } };
shape "LCTL" {
approx= { [ 33, 21 ] },
{ [ 0, 0], [ 33, 0 ], [ 33, 25 ], [ 0, 18 ] },
{ [ 2, 1], [ 30, 1 ], [ 30, 20 ], [ 2, 15 ] }
};
shape "LWIN" {
approx= { [ 26, 26 ] },
{ [ 0, 0], [ 26, 0 ], [ 26, 28 ], [ 0, 25 ] },
{ [ 2, 1], [ 23, 1 ], [ 23, 23 ], [ 2, 21 ] }
};
shape "LALT" {
approx= { [ 27, 29 ] },
{ [ 0, 0], [ 27, 0 ], [ 27, 30 ], [ 0, 28 ] },
{ [ 2, 1], [ 24, 1 ], [ 24, 26 ], [ 2, 24 ] }
};
shape "RDEF" { { [ 18,18 ] }, { [3,1], [15,16] } };
shape "KEY7" { { [ 30,18 ] }, { [4,1], [27,16] } };
shape "KEYY" { { [ 21,18 ] }, { [4,1], [18,16] } };
shape "KEYH" { { [ 27,18 ] }, { [4,1], [24,16] } };
shape "KEYN" { { [ 37,18 ] }, { [4,1], [34,16] } };
shape "BKSP" { { [ 37,18 ] }, { [3,1], [34,16] } };
shape "BKSL" { { [ 16,18 ] }, { [3,1], [13,16] } };
shape "RTRN" { { [ 0,0 ], [ 23,0 ], [ 23,37], [ 7,37 ], [ 7,18 ], [ 0, 18 ] }, { [ 3,1 ], [ 20,1 ], [ 20,34 ], [ 10,34 ], [ 10,15], [3,15] } };
shape "RTSH" { { [ 40,18 ] }, { [ 3, 1], [37, 16] } };
shape "RALT" {
approx= { [ 35, 30 ] },
{ [ 0, 0], [ 35, 0 ], [ 35, 28 ], [ 0, 31 ] },
{ [ 3, 1], [ 32, 1 ], [ 32, 25 ], [ 3, 27 ] }
};
shape "MENU" {
approx= { [ 35, 27 ] },
{ [ 0, 0], [ 35, 0 ], [ 35, 25 ], [ 0, 28 ] },
{ [ 3, 1], [ 32, 1 ], [ 32, 22 ], [ 3, 24 ] }
};
shape "RCTL" {
approx= { [ 34, 24 ] },
{ [ 0, 0], [ 34, 0 ], [ 34, 20 ], [ 0, 25 ] },
{ [ 3, 1], [ 31, 1 ], [ 31, 17 ], [ 3, 21 ] }
};
shape "KPAD" { { [ 18, 37 ] }, { [ 3, 1 ], [ 16, 34 ] } };
shape "KP0" { { [ 37, 18 ] }, { [ 3, 1 ], [ 35, 15 ] } };
shape "SPCE" {
{ [ 14, 2.5], [57,10], [60, 15], [86, 15], [89,9.5], [133, 1.5],
[138.5,32.5], [94,38], [52,38], [ 8.5,32.5] },
{ [ 16, 3.5], [52,10], [58, 20], [88, 20], [94,9.5], [131, 2.5],
[135.5,29.5], [94,35], [52,35], [ 11.5,29.5] }
};
shape "EDGE" {
cornerRadius= 2,
{ [ 25, 0 ], [ 500, 0 ],
[ 500, 220 ], [ 390, 225 ], [ 170, 260 ], [ 0, 230 ] }
};
outline "Edges" {
top= 0;
left= 0;
shape= "EDGE";
};
row.left= 1;
key.gap= 1;
key.shape= "FUNC";
section "LeftFunction" {
top= 25;
left= 30;
angle= 10;
row {
top= 1;
keys { <ESC>, { <FK01>, 15 }, <FK02>, <FK03>, <FK04>, <FK05> };
};
}; // End of "LeftFunction" section
key.shape= "LDEF";
section "LeftAlpha" {
top= 47;
left= 30;
angle= 10;
row {
top= 1;
left= -5;
keys { { <AE00>, "KEY~" }, <AE01>, <AE02>, <AE03>, <AE04>,
<AE05>, { <AE06>, "KEY6" }
};
};
row {
top= 20;
left= -4;
keys { { <TAB>, "TABK" },
<AD01>, <AD02>, <AD03>, <AD04>, { <AD05>, "KEYT" }
};
};
row {
top= 39;
left= -1;
keys { { <CAPS>, "CAPS" },
<AC01>, <AC02>, <AC03>, <AC04>, { <AC05>, "KEYG" }
};
};
row {
top= 58;
keys { { <LFSH>, "LFSH" },
<AB01>, <AB02>, <AB03>, <AB04>, <AB05>, { <AB06>, "KEYB" }
};
};
row {
top= 77;
left= 7;
keys { { <LCTL>, "LCTL" }, { <LWIN>, "LWIN" }, { <LALT>, "LALT" } };
};
}; // End of "LeftAlpha" section
key.shape= "FUNC";
section "RightFunction" {
top= 47;
left= 185;
angle= -10;
row {
top= 1;
left= 1;
keys { <FK06>, <FK07>, <FK08>, <FK09>, <FK10>, <FK11>, <FK12>, <FLCK> };
};
}; // End of "RightFunction" section
key.shape= "RDEF";
section "RightAlpha" {
top= 71;
left= 172;
angle= -10;
row.left= 1;
row {
top= 1;
keys { { <AE07>, "KEY7" },
<AE08>, <AE09>, <AE10>, <AE11>, <AE12>,
{ <BKSP>, "BKSP" }
};
};
row {
top= 20;
keys {
{ <AD06>, "KEYY" }, <AD07>, <AD08>, <AD09>, <AD10>, <AD11>, <AD12>,
{ <RTRN>, "RTRN" }
};
};
row {
top= 39;
keys { { <AC06>, "KEYH" },
<AC07>, <AC08>, <AC09>, <AC10>, <AC11>,{ <BKSL>, "BKSL" }
};
};
row {
top= 58;
keys { { <AB07>, "KEYN" },
<AB08>, <AB09>, <AB10>, <AB11>,
{ <RTSH>, "RTSH" }
};
};
row {
top= 77;
left= 46;
keys { { <RALT>, "RALT" }, { <MENU>, "MENU" }, { <RCTL>, "RCTL" }
};
};
}; // End of "RightAlpha" section
section "SpaceBar" {
top= 137;
left= 96;
key.shape= "SPCE";
row { keys { <SPCE> }; };
};
section "Editing" {
top= 20;
left= 350;
row {
top= 1;
key.shape= "FUNC";
keys { <PRSC>, <SCLK>, <PAUS> };
};
row {
top= 22;
keys { <INS>, <HOME>, <PGUP> };
};
row {
top= 42;
keys { <DELE>, <END>, <PGDN> };
};
row {
top= 80;
left= 20;
keys { <UP> };
};
row {
top= 99;
keys { <LEFT>, <DOWN>, <RGHT> };
};
}; // End of "Editing" section
shape "LED" {
cornerRadius= 0,
{ [ 3, 1 ] }
};
indicator.onColor= "green";
indicator.offColor= "green30";
indicator.left= 170;
indicator.shape= "LED";
indicator "Num Lock" { top= 215; };
indicator "Caps Lock" { top= 225; };
indicator "Scroll Lock" { top= 235; };
indicator "Function Lock" { top= 245; };
section "Keypad" {
top= 42;
left= 414;
row {
top= 1;
keys { <NMLK>, <KPDV>, <KPMU>, <KPSU> };
};
row {
top= 20;
keys { <KP7>, <KP8>, <KP9>, { <KPAD>, "KPAD" } };
};
row {
top= 39;
keys { <KP4>, <KP5>, <KP6> };
};
row {
top= 58;
keys { <KP1>, <KP2>, <KP3>, { <KPEN>, "KPAD" } };
};
row {
top= 77;
keys { { <KP0>, "KP0" }, <KPDL> };
};
}; // End of "Keypad" section
section "ExtKeypad" {
top= 20;
left= 414;
key.shape= "FUNC";
row {
top= 1;
keys { <EQUL>, <PARO>, <PARC>, <BKSP> };
};
}; // End of "ExtKeypad" section
section "Multimedia1" {
top= 4;
left= 30;
row {
top= 1;
key.shape= "MUL1";
key.gap=0;
keys { <WEB>, <FIND>, <MAIL>,{ <VOLD>, 175 }, <VOLU> };
};
};
section "Multimedia2" {
top= 4;
left= 35;
row {
top= 1;
key.shape= "MUL2";
key.gap=0;
keys { { <MUTE>, 210}, { <PLAY>, 55}, { <CALC>, 29 } };
};
row {
top= 26;
key.shape= "MUL2";
keys { { <BKMK>, 125} };
};
};
section "Multimedia3" {
top= 4;
left= 105;
row {
key.gap=0;
top= 1;
key.shape= "MUL3";
keys { <ONE>, <TWO>, <THRE>, <FOUR>, <FIVE> };
};
};
section "Zoom" {
top= 111;
left= 162;
row {
top= 1;
key.gap=0;
key.shape= "ZOOM";
keys { <ZMUP> };
};
row {
top= 17;
key.gap=0;
key.shape= "ZOOM";
keys { <ZMDN> };
};
};
section "Navigation" {
top= 190;
left= 153;
row {
key.gap=0;
top= 1;
key.shape= "DIR";
keys { <PREV>, <SUCC> };
};
};
alias <AC00> = <CAPS>;
alias <AA00> = <LCTL>;
};
|
- We insert the entry into geometry.dir :
| File: geometry.dir |
... -d------ -------- northgate(omnikey101) -d------ -------- microsoft(natural) // Insert the following line and not this one -d------ -------- microsoft(nek4k) -d------ -------- hp(pc101) ... |
- We proceed to create the file keycodes/nek4k :
| File: keycodes/nek4k |
default xkb_keycodes "nek4k" {
<WEB> = 180;
<FIND> = 225;
<MAIL> = 223;
<ZMUP> = 191;
<ZMDN> = 192;
<PREV> = 166;
<SUCC> = 167;
<EQUL> = 125;
<PARO> = 187;
<PARC> = 188;
<MUTE> = 121;
<VOLD> = 122;
<VOLU> = 123;
<PLAY> = 172;
<CALC> = 148;
alias <BKMK> = <DOWN>;
<ONE> = 218;
<TWO> = 219;
<THRE> = 220;
<FOUR> = 221;
<FIVE> = 222;
<HELP> = 146;
<UNDO> = 139;
<REDO> = 190;
<NEW> = 189;
<OPEN> = 142;
<CLOS> = 214;
<REPL> = 240;
<FWD> = 241;
<SEND> = 239;
<SPLL> = 193;
<SAVE> = 242;
alias <PRNT> = <ONE>;
};
|
- We add the entry to keycodes.dir :
| File: keycodes.dir |
... -d------ -------- nek4k(nek4k) |
- Another entry inserted into symbols/inet :
| File: symbols/inet |
...
// Control Section -- Far Right
// F-Locked Function keys
// Internet Section -- Right Side
// Multimedia Section -- Centre
// My Computer Section -- Left Side
};
//Insert the following section
// Microsoft Natural Ergonomic Keyboard 4000
partial alphanumeric_keys
xkb_symbols "microsoftnek4k" {
key <WEB> { [ XF86WWW ] };
key <FIND> { [ XF86Documents ] };
key <MAIL> { [ XF86Documents ] };
key <ZMUP> { [ XF86Documents ] };
key <ZMDN> { [ XF86Documents ] };
key <PREV> { [ XF86Documents ] };
key <SUCC> { [ XF86Documents ] };
key <EQUL> { [ XF86Documents ] };
key <PARO> { [ XF86Documents ] };
key <PARC> { [ XF86Documents ] };
key <MUTE> { [ XF86Documents ] };
key <VOLU> { [ XF86Documents ] };
key <VOLD> { [ XF86Documents ] };
key <PLAY> { [ XF86Documents ] };
key <CALC> { [ XF86Documents ] };
key <ONE> { [ XF86Documents ] };
key <TWO> { [ XF86Documents ] };
key <THRE> { [ XF86Documents ] };
key <FOUR> { [ XF86Documents ] };
key <FIVE> { [ XF86Documents ] };
key <HELP> { [ XF86Documents ] };
key <UNDO> { [ XF86Documents ] };
key <REDO> { [ XF86Documents ] };
key <NEW> { [ XF86Documents ] };
key <OPEN> { [ XF86Documents ] };
key <CLOS> { [ XF86Documents ] };
key <REPL> { [ XF86Documents ] };
key <FWD> { [ XF86Documents ] };
key <SEND> { [ XF86Documents ] };
key <SPLL> { [ XF86Documents ] };
key <SAVE> { [ XF86Documents ] };
};
// Oretec
// Oretec MCK-800 MM/Internet keyboard
...
|
The sample XF86* Keys can be substituted with others of your liking from /usr/share/X11/XKeysymDB. The various keysyms X uses are listed in /usr/include/X11/keysymdef.h , without the leading XK_.
- The following entry goes into symbols.dir :
| File: symbols.dir |
... --p----- a------- inet(microsoftoffice) --p----- a------- inet(microsoftmult) //Insert only the following line --p----- a------- inet(microsoftnek4k) --p----- a------- inet(oretec) --p----- a------- inet(propeller) ... |
The position where we inserted our additions in the previous files is, of course, of no consequence.
- The last file to be altered is rules/base :
| File: rules/base |
...
! $inetkbds = a4techKB21 a4techKBS8 acer_tm_800 acpi airkey azonaRF2300 \
...
microsoftoffice microsoftmult \
//Insert the following line
microsoftnek4k \
oretec \
...
! model = keycodes
...
evdev = evdev
//Insert the following line
microsoftnek4k = evdev+nek4k(nek4k)
* = xfree86
...
! model = geometry
...
microsoftprose = microsoft(natural)
//Insert the following line
microsoftnek4k = microsoft(nek4k)
dell101 = dell(dell101)
...
|
Then we alter again /etc/X11/xorg.conf
| File: /etc/X11/xorg.conf |
Section "InputDevice"
Identifier "Keyboard1"
Driver "evdev"
Option "Protocol" "evdev"
Option "Device" "/dev/input/event20"
# Remove the following line
# Option "XkbModel" "evdev"
Option "XkbModel" "microsoftnek4k"
Option "XkbLayout" "us"
Option "XkbRules" "xorg"
EndSection
Section "InputDevice"
Identifier "Keyboard2"
Driver "evdev"
Option "Protocol" "evdev"
Option "Device" "/dev/input/event21"
# Remove the following line
# Option "XkbModel" "evdev"
Option "XkbModel" "microsoftnek4k"
Option "XkbLayout" "us"
Option "XkbRules" "xorg"
EndSection
...
Section "ServerLayout"
...
InputDevice "Keyboard1" "CoreKeyboard"
InputDevice "Keyboard2" "SendCoreEvents"
...
EndSection
|
Action Bindings
TODO
Here's a relatively easy way to bind your special keys to certain actions/commands in KDE: http://dev-loki.blogspot.com/2006/04/mapping-unsupported-keys-with-xmodmap.html
< Perhaps the steps in this blog post should be detailed here with due credit given? >
Modern Way of doing things
Recent (2.6.24) versions of Linux have fully functional Microsoft Natural 4000 support. You do not need to patch kernel really much now.
Kernel
| Code: Get a bleeding edge version of Linux kernel |
emerge git-sources |
Due to limitations of X11 protocol (no keycodes outside 9—255 range are allowed), some kernel keycode bindings should be fixed in order to make zoom throttle and «Spellcheck» key work under X. Apply the following patch to include/linux/input.h file of kernel sources (only 3 lines are changed):
| File: |
--- /usr/src/linux/include/linux/input.h.orig 2007-12-31 12:36:02.000000000 +0300 +++ /usr/src/linux/include/linux/input.h 2007-12-30 18:37:19.000000000 +0300 @@ -510,8 +510,8 @@ #define KEY_TWEN 0x19f #define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */ #define KEY_GAMES 0x1a1 /* Media Select Games */ -#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */ -#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */ +#define KEY_ZOOMIN 246 /* AC Zoom In */ +#define KEY_ZOOMOUT 247 /* AC Zoom Out */ #define KEY_ZOOMRESET 0x1a4 /* AC Zoom */ #define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */ #define KEY_EDITOR 0x1a6 /* AL Text Editor */ @@ -524,7 +524,7 @@ #define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */ #define KEY_MESSENGER 0x1ae /* AL Instant Messaging */ #define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */ -#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */ +#define KEY_SPELLCHECK 235 /* AL Spell Check */ #define KEY_LOGOFF 0x1b1 /* AL Logoff */ #define KEY_DOLLAR 0x1b2 |
In kernel config, make sure the following options are enabled:
| Linux Kernel Configuration: 2.6.24-rc6 |
Device Drivers --->
HID Devices --->
<*> USB Human Interface Device (full HID) support
Input Device Support --->
<*> Event interface
|
Compile and install the new kernel. Reboot your system.
By now, showkey should react to all keys on your keyboard, including zoom!
X
If you're using an old version of X Window System and are not willing to change the existing configuration, you may skip this section; xev should react to all keys on your keyboard by now, so using xmodmap and any keybinding utility like xbindkeys you may make use of all keys on your fancy Microsoft keyboard!
The followiing configuration method requires at least hal-0.5.9.1 and xorg-server-1.4.0.9:
| Code: Unmask recent version of driver |
echo "=x11-drivers/xf86-input-evdev-1.2.0 **" >> /etc/portage/package.keywords |
| Code: Get X server and event driver |
INPUT_DEVICES="evdev" USE="hal" emerge xorg-server xf86-input-evdev |
Modern X (X11R7.3) versions allow input device hotplugging using HAL. Now you may wipe InputDevice sections away from your /etc/xorg.conf file, as well as references to them in ServerLayout section, example:
| File: /etc/xorg.conf |
Section "ServerLayout"
Identifier "Main Layout"
Screen "Screen1"
EndSection
|
Add AllowEmptyInput option to ServerFlags section, example:
| File: /etc/xorg.conf |
Section "ServerFlags"
Option "blank time" "10"
Option "standby time" "20"
Option "suspend time" "30"
Option "off time" "60"
Option "AllowEmptyInput"
EndSection
|
Now make HAL assign special properties to your input devices to make them discoverable by X server. Create the following file:
| File: /etc/hal/fdi/policy/x11-input.fdi |
<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
<device>
<match key="info.capabilities" contains="input.mouse">
<merge key="input.x11_driver" type="string">evdev</merge>
</match>
<match key="info.product" contains="Microsoft Natural">
<merge key="input.x11_driver" type="string">evdev</merge>
<merge key="input.xkb.model" type="string">evdev</merge>
<merge key="input.xkb.variant" type="string">,winkeys</merge>
<merge key="input.xkb.layout" type="string">us,ru</merge>
<merge key="input.xkb.options" type="strlist">grp:caps_toggle</merge>
<append key="input.xkb.options" type="strlist">grp_led:caps</append>
<append key="input.xkb.options" type="strlist">compose:ralt</append>
</match>
</device>
</deviceinfo> |
Make sure hald and dbus-daemon scripts get loaded. Add them to an appropriate runlevel otherwise:
| Code: |
rc-update add hald default rc-update add dbus default |
Feel free to reboot X server with /etc/init.d/xdm restart now. Your keyboard and mouse should work. In case of glitches see /var/log/Xorg.0.log for relevant error messages.
Now you can use xev to test your keyboard. All keys should generate an X event. Now you may wish to bind lots of additional keys on this keyboard using xbindkeys or similar tool provided by your desktop environment.
Links
TODO
For now these about the configuration:
Gentoo Forums:
Thread with contributions by powerman: [6]
Thread with contributions by truc: [7]
Ubuntu Forums:
Thread with contributions by liyu: [8]
Recent Updates:
Recent updates of the patches by liyu: [9]
Created by NickStallman.net, Luxury Homes Australia
Real estate agents should list their apartments, townhouses and units in Australia.
