Friday, May 15, 2009

Make your Apple Aluminium Keyboard really work under Linux, X.org

Like many others, I've bought an Aluminium Keyboard for its cool style the smooth typing experience it provides. Mine is a wired version, ISO variant (international, 110-keys). It's not working 100% out-of-the-box under Linux, so this post explains what I did to make it happen:

  • Supporting the additional keys (F13..F19) and geometry (physical layout) under X.org
  • Making the keyboard auto-configured at X.org startup. No need to mess with xorg.conf!

But wait, there's more. If you're accustomed to PC keyboards, you really need those ones too:

  • Making this fn key located on top of the delete key behave like a regular PC keyboard: Insert!
  • Making multimedia keys output Fxx symbols by default
  • Making F13..F15 behave like those charmingly obsolete Scroll Lock..Print Screen keys
  • Keeping the multimedia keys accessible when the fn key is remapped to Insert

Prerequisite

First, make sure you have installed all the packages below and that their versions are recent enough:

  • xserver-xorg v1.5.2, X.org's hotplug-aware X server
  • xserver-xorg-input-evdev v2.0.xx, evdev driver for input devices
  • HAL v0.5.xx, the hardware abstraction layer daemon which gives hotplug information to the X server

How the support works

Install

Go grab this patch and save it in your home directory; it contains the relevant XKB updates to support the keymap and the geometry of Apple Aluminium keyboard, ISO variant. It also defines two XKB options to make this keyboard behave more like a PC keyboard (more on that later). To install it, first pretend to apply the patch in the directory that holds the XKB data. On my Ubuntu, this gives:

sudo bash
cd /usr/share/X11/xkb
gunzip -cd $HOME/xkb-apple-aluminium-kdb-iso.patch.gz | patch -p1 --dry-run

If the patch applies successfuly, you can proceed and apply it for real:

gunzip -cd $HOME/xkb-apple-aluminium-kdb-iso.patch.gz | patch -p1

Once you have the relevant XKB definition for your keyboard, you need to tell X.org to apply these settings automatically when it detects your keyboard. The following HAL fdi file makes the necessary voodoo (read: XKB settings) for you. Note that these settings do not preclude your system-wide XKB options.

In order to install the fdi file I'm providing, just copy it in the HAL directory which holds user-defined policies for devices. On my Ubuntu, this directory is /usr/share/hal/fdi/policy/30user. You might need to create 30user if it doesn't exist.

Test

Now that you installed everything, restart HAL. For example, on a Debian-like distro:

sudo /etc/init.d/hal restart

Then log out from your current X session and start a new one. If everything went well, you should now be able to see the Aluminium Keyboard in your keyboard preferences application. The screenshots below show the result under GNOME:

Make it a PC keyboard!

The Insert key hack

The fn key is not seen by X because its keycode (464) is greater than 255, which is not allowed in X11 protocol. But there is a trick: under Linux, you can modify the kernel scancode→keycode mapping of your evdev device!

Just uncomment the two optional lines in the fdi file I'm providing to make the fn scancode (HID usage 0xff0003 on this keyboard) generate the Insert keycode (110) in userland and make Xorg happy :D

For curious people: Initially (funny how these names look familiar if you read p.g.o...), HAL's keycode remapping seems to have been designed with AT scancodes in mind, not HID usages. In order to override those ones, you must revert a special encoding performed for representing AT escape scancodes. In our case, you end up remapping usage 0xffdf83!

Fxx keys enabled by default

This one is not new. In order to boot with Fxx keys enabled, you must pass an option to the hid Linux module. On my Ubuntu, this can be done by updating modprobe options and rebuilding an initrd image.

sudo bash
echo "options hid pb_fnmode=2" >> /etc/modprobe.d/alukbd
echo "options hid_apple fnmode=2" >> /etc/modprobe.d/alukbd
update-initramfs -k `uname -r` -u

Additional PC-like XKB options

The XKB patch I'm providing defines two new XKB options:

apple:alupcfkeys
If you need to map F13..F15 to Scroll Lock..Print Screen keys (I won't judge you, I swear :P)
apple:alul3media
If you remap fn to Insert, this options allows you to access the multimedia keys is by typing 3rd-level chooser + Fxx key. I've mapped my 3rd-level chooser to the right Alt key (XKB option lv3:ralt_switch )

Naturally, the simplest way of using these XKB options is to enable them via your keyboard preferences application. For instance, GNOME users can find them in the Keyboard Layout Options:

Conclusion

My XKB and HAL settings provide complete support for your Aluminium Keyboard on Xorg Linux. However, the Insert key hack is probably not mainstream and ultimately should not land in a fdi file. It would be better to make a distro package such as “enable PC-support on Aluminium Keyboard”.

The XKB geometry implemented is for the ISO variant. if you have one of the other variant and like to throw it away, you know I'd be happy to add support for it, eheh :P

24 comments:

Gene said...

I appreciate this blog. I'm trying to install an Apple wired aluminum keyboard (the smallest one that has no number pad). I've gone to numerous forums, but no one has pointed out the necessity to remap the fn keycode.

Anyway, I downloaded the xkb-apple . . . patch but the dry run says "strip count l is not a number". Can I proceed, or is the error fatal? I'm running Ubuntu 8.1.

Dam said...

Hi Gene,

Thanks for the feedback :)
You simply made a typo when performing the patch -p command (letter l instead of number 1).

Copy-paste the lines in the blog and tell me if those patches work as expected for your Aluminium Keyboard :)

Cheers

Gene said...

I applied the patch typing 1 instead of l. It said hunk 5 failed, but went on to set up hunks 1 and 2.

Anyway, I ran the patch, loaded the fdi file, logged off and logged in. Sure enough, the apple aluminum keyboard showed up keyboard preferences, layouts. But when I tried to select it, I got error activating xkb.

I tried the keyboard, and it worked as before. No fn key. I have to have the fn key to page up and page down, or go to home or end. Well I looked at the fdi file you gave us, and as far as I could tell the two lines that map fn to ins were not commented at all. What is the symbol for a comment? Is it {less than symbol}!-- text --{greater than}? I'm not sure how to uncomment these two lines, because they are of the form {less than} statement {greater than}, with no suggestion that they are comments (i.e., no !-- as I surmise indicates a comment.)

So, where am I going wrong? I'm running Ubuntu 8.1 server to which I added the gnome desktop. Perhaps some xorg file didn't get added. Also, the keyboard I have is the smaller one. It has no number pad. I think it is the ANSI model. You say support pending for ANSI and JIS models.

Dam said...

Okay, I've reworked the patch.
Please download the file and apply it again (dry-run first is safer).

My last comment was too sketchy; actually the FDI file matches the USB ID of the keyboard in order to apply remapping.

the FDI won't work as is for your keyboard since it's not the same model.
You should replace the product_id written in the file (currently 0x0221) with the one for the mini Alu keyboard.
According to your comment above and to Linux source, the ID you should use is:
0x021d (for the mini ANSI)
or 0x021e (for the mini ISO)

You can type:
lsusb | grep '-i keyboard' | grep -i alu
To find out your model number

Last thing: you can ask HAL whether the fdi file was applied by typing:
lshal | grep -B10 -i keyboard
And look for the remapping line:
input.keymap.data = {'ffdf83:insert'} (string list)

Tell me if it helps!

Gene said...

Well I tried again, but no go. This time I reapplied the patch. A small problem there. It kept asking me if I wanted to use -R. I answered yes. It then said "continue anyway?". I answered yes.

Anway, it seemed to work. I changed the fdi file to reflect the ANSI mini keyboard. lsusb reported 05ac:021d. I restarted HAL, logged off, and logged back on. lshal | grep -B10 -i keyboard showed the remapping line.

I opened keyboard preferences and found the aluminum keyboard there.

So it all seems to be correct. The fn key produced the wide cursor to indicate it was in insert mode. But no forward delete (fn + delete). The third level key was set to the right option key. I pressed that and the fn key. the right option changed the fn cursor from wide to narrow, suggesting I was on the third level. But even so, alt-fn-delete yielded only a backspace.

In short, everything seems right, but I have no working function key.

I notice in the keyboard preferences that it selects the Apple Aluminum keyboard, but the layout is USA Macintosh. No other options are available.

I saw some posts on an Apple Forum that said the fn key wasn't working in Leopard, but it seems to work on my macbook pro.

So any more ideas. You have been very patient, Dam, and I am grateful for all the feedback you've given.

douggreen said...

Thanks for the blog post! I've been searching for the perfect keyboard, and the lack of Ubuntu support for the Mac keyboard has held me back.

I'm not very far along in getting this working yet, the first problem is that the patch looks for evdev files in /usr/share/X11/xkb/rules, and I have none. I do have server-xorg-input-evdev installed, I even re-installed it to be sure. Do I need to enable this somewhere?

I'm running Ubuntu 8.04.

douggreen said...

To enable the function keys, I put this in /etc/rc.local

# enable function keys on the mac keyboard.
lsusb | grep -i 'Apple Aluminum Keyboard' > /dev/null
if [ $? -eq 0 ]; then
echo -n 0x02 > /sys/module/hid/parameters/pb_fnmode
fi

Dam said...

Hi Gene,

[Sorry for this late answer. If you still have a bit of time...]

I though you were complaining about the lack of "Insert", but thx to your post I just understood the meaning of the symbol on the "delete" key, forward delete!

I have to modify my patch to take this symbol into account.

In the meantime, you may have applied the patch unsuccessfuly, that could be the reason why you don't see any fn symbol in action.

In order to sort this out, could you please ensure that you can see aluminium keyboard options in your keyboard properties (screenshot in my post)

If not, could you reinstall your XKB original file:
sudo apt-get install --reinstall xkb-data
and then reapply my latest patch?

thx for your help! I'll let you know when I'll add the forward delete fn key

Dam said...

Hi douggreen!

First of all thx for your interest and sorry for this late answer.

So... on my patch targets a file which wasn't present in package xkb-data before Intrepid.

But you can patch my patch with sed as follows to make it work on Hardy:
gunzip -cd $HOME/xkb-apple-aluminium-kdb-iso.patch.gz | sed 's%/rules/evdev%/rules/base%g' | patch -p1 --dry-run

You should remove --dry-run to apply the patch for real.

Tell me if it works for you (tm)!

Cheers

Dam said...

Doug,

The solution in your last post cannot work for Gene because as soon as the fn key is remapped to insert, you loose other fn-combinated keys.

That's why my patch re-enables them with the 3rd-level chooser (AltGr in my case), and that's why I have to re-make my patch to enable forward delete too....

Dam said...

Hi Gene,

I've updated the patch to add support for forward delete!

first reinstall your package xkb-data.
then download the patch and apply it again.
at last in your keyboard preference application select "make BackSpace emit Delete at 3rd level"

Tell me if it works :)

Cheers

Gene said...

Hi Dam,
I followed your instructions. I reinstalled xkb-data. I downloaded the patch and applied it. No errors this time. I went to keyboard preferences and checked "make BackSpace emit Delete at 3rd level". I logged out and logged back in.

When I logged back in I got the error message, some sort of failure. I tested and tested, but no go.The fn key gave me the wide cursor. The 3rd level chooser cut in, but no effect when pressing the delete key.

Then I noticed that in keyboard preferences I selected Apple Aluminum keyboard, but under it was a keyboard model called Apple. That was interesting, because when I do lsusb, I find that my mini keyboard identifies itself as Apple, not as Apple Aluminum keyboard. So I selected Apple, and voi la, forward delete works.

I'm very happy about that, but page up and page down don't work. Nor do home and end. These keys should work with the fn key and the cursor keys.

So thanks much. Now if we can only get the 3rd level chooser to make the cursor keys do page up, page down, home, and end.

Gene

catbee said...

according to

http://support.apple.com/kb/HT1216

you can use "fn + enter." that doesn't work for me, but "fn + return" does.

Dam said...

Wow catbee, impressive :)

I didn't knew those shortcuts, thanks for the link. I must confess I find some of them a bit overkill :P

BTW, have you tried the updated support for apple keyboards?

Linux User #330250 said...

Hello!

I used your hack since the day I got my Alu keyboard.

Recently, since X.org server 1.9, HAL is no longer the default and has been dropped in favor of udev.

So far, I haven't found a way to make it work again.

Since you made it work the first time, maybe you are able to help to adapt your hack to work with udev instead of HAL.
See http://forums.gentoo.org/viewtopic-t-857617.html for details.

Thanks!

Linux User #330250 said...

http://forums.gentoo.org/viewtopic-t-857617.html

Linux User #330250 said...

The link is always truncated on my comments page. So here in two lines (to be combined to get there):
http://forums.gentoo.org/ viewtopic-t-857617.html

Hope it works this time...

Dam said...

Hi Atha, you're right HAL support was really meant to be replaced at some point, as I explain in a more recent post.

In my latest .fdi file, the remapping is performed by a script called by HAL when it discovers the keyboard.

I should provide a udev rule to perform the equivalent remapping trick, should be a matter of days :)

Thanks for the feedback and stay tuned, cheers!

Dam said...

There, the support for udev is ready to be published. Blog post on its way...

Anonymous said...

Thanks for the thorough post, Dam.

I have a question though - do I need to apply your patch even if I have the Apple Aluminium Keyboard (ISO) in the list of available keyboards already? (I'm on Lucid Lynx)

I tried to apply the fix for Fn key which supposed to turn it into the Insert key, but it disabled my mouse and external keyboard as well.

Thanks!

Dam said...

Hi OpenID :)

No you don't need to apply.

Here is the trouble: my XKB patches were accepted in xkeyboard-config 1.9. Ubuntu version is 1.8 + some patches including my support.

Problem is Ubuntu maintainers only picked 6 patches out of 7, so the support doesn't work right now (I'm running version 1.8-1ubuntu8).

I need to find out why the support has been partially integrated. More on that soon.

As for the Fn->Insert key, with Lucid Lynx you should have a fairly recent udev, so you could type:
/lib/udev/findkeyboards
to find your keyboard device name, then:
/lib/udev/keymap /dev/input/eventX 0xff0003 insert
with the relevant X, this should remap your key.

Tell me if it works, in any case I'll update the support very soon with udev support.

Artem said...

You are legend!!!

Thank you so much!!!

Art

Artem said...

I also meant to say that yes, it works, would be nice to get it included into the default Ubuntu layout I guess.

Art

Dam said...

I just published the new support for udev and Xorg server 1.9, along with a blog post for the explanations.

Cheers!