# Mutlimedia Keyboards and Xorg 7.1

## jsnorman

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:

```
cat /proc/bus/input/devices
```

You will see something like this if you have this dual keyboard interface issue:

```
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):

```
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:

```
  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:

```
KERNEL=="event[0-9]*",SYSFS{../name}=="Logitech USB Gaming Mouse",NAME="%k",SYMLINK="input/logitechg5mouse"

```

and /etc/udev/rules.d/10-keyboard.rules:

```

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:

```

 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!):

```

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:

```

      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?

----------

## faceman

I'm wondering if your undetected keycodes are in the range above what you've defined for your evdev keyboard:

```
Option "keyBits" "~1-255 ~352-511" 
```

Maybe change that 511 to something bigger?

Just a guess.  I'm having the same problem, and wondering if that might help.

----------

