jsnorman Tux's lil' helper
Joined: 24 Feb 2005 Posts: 131
|
Posted: Tue Sep 12, 2006 1:59 am Post subject: Mutlimedia Keyboards and Xorg 7.1 |
|
|
After spending a full day in terminal/text mode, I have finally got my new mouse and keyboard working, so I thought I would post to save time of anyone else trying the same trick. To udev and evdev guru's, please note that I could use some (a lot really) help in figuring out how to use the evBits and keyBits option fields!!!! and of course if I messed anything up please let me know!!!
NOTES:
I have xorg 7.1 - this post is not relevant (or may be wrong!) for earlier versions.
Also, my input devices are:
Logitech Elite Keyboard (wired, usb)
Logitech G5 mouse (wired, usb)
The method below should work with just about ANY keyboard/mouse combo however (with different values of course).
I tried using the Ps2 adapter that came with the keyboard, but immediately had problems even in text mode so that had to be discarded and I had to use a USB port. Also, I believe the wireless versions of the keyboard and mouse should work identically.
Initial package requirements: you must have xf86-input-evdev, xorg 7.1, and udev (plus the usual stuff).
First Problem. Using keyboard driver in x11, many media keys do not seem to give signals. However, using evdev as drivers, the keyboard works in terminal, but not in X11. Solution: see if you might have TWO keyboards in one. udev seems to recognize certain keyboards as two keyboards, and gives each an interface. You can find this out by doing:
Code: | cat /proc/bus/input/devices |
You will see something like this if you have this dual keyboard interface issue:
Code: | I: Bus=0003 Vendor=046d Product=c30f Version=2300
N: Name="Logitech Logitech USB Keyboard"
P: Phys=usb-0000:00:02.0-2/input0
S: Sysfs=/class/input/input1
H: Handlers=kbd event1
B: EV=120003
B: KEY=1000000000007 ff800000000007ff febeffdfffefffff fffffffffffffffe
B: LED=1f
I: Bus=0003 Vendor=046d Product=c30f Version=2300
N: Name="Logitech Logitech USB Keyboard"
P: Phys=usb-0000:00:02.0-2/input1
S: Sysfs=/class/input/input2
H: Handlers=kbd event2
B: EV=3
B: KEY=8f00 40000050000 401978d800d508 1e000000000000 0
|
Note that one is event1 and the other is event2! You will see corresponding event entries in /dev/input/eventN
To fix this, you need to create two keyboard defs in your /etc/X11/xorg.conf file (ignore for now the vendor, product, evBits, and keyBits fields):
Code: | Section "ServerLayout"
Identifier "X.org Configured"
Screen 0 "Screen0" 0 0
InputDevice "LogitechG5" "CorePointer"
InputDevice "Keyboard0" "CoreKeyboard"
InputDevice "KeyboardExtra" "AlwaysCore"
EndSection
#snip
Section "InputDevice"
Identifier "Keyboard0"
Driver "evdev"
Option "vendor" "046d"
Option "product" "c30f"
Option "evBits" "+1"
Option "keyBits" "~1-255 ~352-511"
Option "device" "/dev/input/event1"
EndSection
Section "InputDevice"
Identifier "KeyboardExtra"
Driver "evdev"
Option "vendor" "046d"
Option "product" "c30f"
Option "device" "/dev/input/event2"
EndSection
|
You may need to swap event1/event2 (and of course if your mouse is not event0, your eventN's will be different!). It is possible some keyboards or mice could have even more interfaces, in which case you would create additional keyboard/mice per the above method.
Second Problem. Xorg will not start after modifying my xorg.conf file to use evdev instead of keyboard or mouse drivers. The problem is an esoteric limitation in evdev that is apparant only if you read the man page for evdev (and do not follow instructions elsewhere!). From man evdev:
Code: | Option "Device" "string"
Specifies the device note through which the device can be
accessed. At this time ONLY /dev/input/event<N>, where <N> is
an integer, are matched against this this field.
This option uses globbing.
Please note that use of this option is strongly discouraged.
|
The evdev folks would have you use "globbing" to specify the name, physdev, etc. of your keyboard/mouse/device instead of the more traditional (and effective) reference to the device note in /dev/input/****. Most unfortunately, however, if you have symlinked or udev'd your mouse/keyboard (e.g. created a rule for keyboard so that it is created as /dev/input/logitechkeyboard or /dev/input/g5) as recommended on a couple of wiki pages, evdev will FAIL and you will lose your corepointer, and therefore X will not start! More unfortunately, you cannot use NAME= at least for a keyboard like the Logitech because as you can see above in the /proc/bus/input/devices output, the NAME is the SAME for both event1 and event2!! Solution: use Option "Device" "/dev/input/eventN" but hard code it for the correct eventN. See above for my example. If you look in /dev/input/ and see nothing that is eventN, you may also need to "fix" any udev rule that may be preventing the creation of the "default" kernel links for the event interface:
/etc/udev/rules.d/10-mouse.rules:
Code: | KERNEL=="event[0-9]*",SYSFS{../name}=="Logitech USB Gaming Mouse",NAME="%k",SYMLINK="input/logitechg5mouse"
|
and /etc/udev/rules.d/10-keyboard.rules:
Code: |
KERNEL=="event[0-9]*",SYSFS{../name}=="Logitech Logitech USB Keyboard",NAME="%k",SYMLINK="input/logitechkeyboard%n"
|
Note that I created symlinks with readable names, but retained kernel naming for the primary node. This allow me to easily fix things if I accidentally plug in a new USB device or plug in my mouse/keyboard into a diff port (creating new eventN ordering) simply by doing an ls -l /dev/input
After creating the udev rules you will need to restart udev with udevstart
Third Problem: My mouse wheel does not work, and I cannot figure out the right xmodmap! Solution: delete any and all xmodmap pointer = statements in your Autostart or Xsession, or in .Xmodmap in your user account. Your mouse will be automagically configured with all (?) buttons working!!!! Out of the box, xorg 7.1 got my mouse scrolling, left/right wheel motion, wheel click, and of course left/right click working! Kudos to the developers on that one, but of course xmodmap will mess up the correct out of the box ordering!
Fourth Problem: My mouse and/or keyboard still do not work, or behave irratically. Solution (kind of): You need to set the appropriate evBits and keyBits for your mouse and keyboard. Here is what the man page has to say and it is what I followed:
Code: |
Most users of this driver will probably be quite happy with the following for all QWERTY keyboards:
Section "InputDevice"
Identifier "keyboard"
Driver "evdev"
Option "evBits" "+1"
Option "keyBits" "~1-255 ~352-511"
Option "Pass" "3"
...
EndSection
And the following for all mice:
Section "InputDevice"
Identifier "mouse"
Driver "evdev"
Option "evBits" "+1-2"
Option "keyBits" "~272-287"
Option "relBits" "~0-2 ~6 ~8"
Option "Pass" "3"
...
EndSection
|
Note I deleted the Option "Pass" "3" because that causes the evdev driver to wait until the third interface is loaded before attaching - my CorePointer keyboard interface was however the first interface of the keyboard or second of all input devices, and so Pass 3 would force attachment to event2 and make my keyboard mostly inoperable. I deleted it also from the mouse device statement for no good reason.
Also note (from my xorg.conf file above) that my event2 keyboard definition does not include the xxBits - that is because it is purely a button interface, and I could not figure out the correct bit masks (still seems to mostly work, but a few keys will not pass to X and I suspect this is the problem).
Mapping Keys. This is covered elsewhere, but I am including it here for completeness. To map out keys, run xev as root, move the cursor to the box (using mouse, click), and then tap each multimedia key. In the xev window, you will see a bunch of info for each key press and relase - you just need the keycode. Using keycode/key mapping, create .Xmodmap as follows (using your keycodes not mine!):
Code: |
keycode 179 = XF86Music
keycode 121 = XF86AudioMute
keycode 122 = XF86AudioLowerVolume
keycode 123 = XF86AudioRaiseVolume
keycode 172 = XF86AudioPlay
keycode 174 = XF86AudioStop
keycode 173 = XF86AudioPrev
keycode 171 = XF86AudioNext
keycode 163 = XF86Mail
keycode 180 = XF86HomePage
keycode 150 = XF86Sleep
keycode 148 = XF86Calculator
keycode 146 = XF86Support
keycode 139 = XF86RotationPB
keycode 190 = XF86RotationKB
keycode 242 = XF86Save
keycode 164 = XF86Favorites
keycode 133 = XF86Start
|
Note that (contrary to wiki based instructions) the available key mappings are located at /usr/share/X11/XKeysymDB
Last Problem. I would like to use all of the event features of my keyboard, including buttons that do not map to a keycode, but I cannot figure out how to do it. You SHOULD be able to modify the xxBits lines in xorg.conf. However, documentation is ... sparse. Here is man evdev again:
Code: |
Option "<map>Bits" "bit specifier"
Specifies device capability bits which must be set, possibly
set, or unset.
<map>Bits: Where map is one of ev, key, rel, abs, msc, led, snd,
or ff.
The bit specifier format is a string consisting of +<n>, -<n>,
and ~<n> space sepirated specifiers, where <n> is a positive
integer or integer range. (The latter given in the format of
2-6.)
+ specifies bits which must be set.
- specifies bits which must not be set.
~ is a little more complex, it specifies that at least one of
the bits given with ~ for the field in question must be set, but
it doesn't matter how many or which of the bits. (It is actually
the most useful of the 3 specifiers.)
As an example '+0 +3 -1-2 ~5-10', requires bits 0 and 3 be set,
bits 1 and 2 to not be set, and at least one bit in the range of
5 to 10 be set.
An annoyingly formatted set of bitmasks for your devices can be
obtained by typing "cat /proc/bus/input/devices", and
/usr/include/linux/input.h should contain the defines which
declare what bits are what for each field.
|
Unfortunately, this does not tell us how to translate the "annoyingly formatted" mask from /proc/bus/input/devices into useful information!!! I have banged my head against the wall without answers. And "input.h" just contains defines for keycodes - not much help without more information. That seems to exhaust documentation - anyone know more? |
|