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

Monday, February 23, 2009

Toolchain.sh is amazing!

A few weeks ago, I finally upgraded my iPhone to firwmare 2.2.1. It was actually an utterly painless operation, thanks to the amazing toolchain.sh by the guys from iphonedevlinux.

I remember in the 1.1.4 days, I had a hard time extracting the MacOS 10.5 SDK on Linux and compiling the openSDK on my Core2 Quad by following saurik's great instructions.

It turns out that building an open SDK for firmware 2.2.1 is actually very simple: getting a copy of the phone's sysroot, building GCC, importing headers from the official iphone SDK, classdumping private frameworks... all these operations are now almost automatic thanks to toolchain.sh.

The icing on the cake: those smart people from iphonedevlinux are friendly and reactive! Another good reason for sending them patches and using their script :)

Saturday, July 5, 2008

Hello MikMod!

As promised earlier, I've packaged an obligatory example of how to use the iPhone port of libmikmod which I've talked about recently. Go grab this tarball which implements a very simple "Hello World!":
  • It shows how to play a module within a UIKit application. This is an adaptation of the skeleton program found in MikMod Documentation.
  • It shows how to use the higher level sound API Celestial to control mikmod output. For instance, how to react to volume change events when iPhone buttons are pressed.
What to do with this archive once you've extracted it?
  tar -zxf HelloMikMod.tar.gz
  cd HelloMikMod
Simple! Modify the Makefile to set the location of the AudioQueue.h header, as well as the location where you've installed libmikmod. Once you're done, the makefile should look like:
  # directory where AudioQueue.h is located
  AQDIR=$(HOME)/local/audioqueue
  # directory where MikMod is located
  MMDIR=$(HOME)/local/mikmod-iphone
  # comment the following line when the previous settings are OK for you
  #$(error configure AudioQueue and Mikmod location in the Makefile first)
Then, just build and install the app by typing:
  make
  scp -r HelloMikMod.app root@iphone:/Applications
Where iphone stands for the hostname or the IP of your iPhone. Note that you will need either curl or wget installed or your machine so that the build process is able to download the module played in this example app (fortunately, one of those should always be available on MacOS X or on your favorite Linux distro). For your convenience, the HelloMikMod.app directory is standalone: it contains the app itself linked statically to libmikmod, a launcher descriptor for Springboard and the module to play. For my own pleasure, the mod played is Stardust Memories by Jester / Sanity, my all time favorite Amiga mod (see the compo World of Commodore). This is only a simple example of how to use MikMod on iPhone. I've started implementing a more complex app that mimics the iPod interface for playing mods (Module DB, Screenshot of associated demos...). Now if only I could use Nectarine or Pouet.net DB to make some kind of systematic indexing available!! (sigh....)

Friday, June 27, 2008

MikMod library ported to iPhone

I've always been a big fan of old skool computer music, like chiptunes or demoscene music. Perhaps because they remind me the Good Old Days (tm) of my Amiga. Or perhaps for the same reason I like demoscene: real-time computer art! Because it's definitely cool, I've decided to port MikMod to the iPhone! We'll see later if it might be useful to someone else :) Compiling libmikmod Here are the steps to follow to build libmikmod for your iPhone or iPod Touch. First of all, make sure that you have the necessary header file from Apple, namely AudioQueue.h. This file is part of the AudioQueue framework, which is available in the MacOS X 10.5 SDK. This means that the official iPhone SDK is not required. Then, download the latest libmikmod-3.2.0-beta2 available on the MikMod homepage, as well as this patch for iPhone support. For simplicity, let's consider that both files will be downloaded in the same directory. Once you have them, extract the archive and apply the patch:
tar -zxf libmikmod-3.2.0-beta2.tar.gz
cd libmikmod-3.2.0-beta2
gunzip -cd ../iphone-drv-mikmod-3.2.0-beta2.patch.gz | patch -p1
Among other things, the patch modifies various Makefiles and the configure script, so we have to cleanly regenerate all the autotool-related files:
aclocal
automake
autoconf
Now let's set up the necessary environment variables to configure and build libmikmod. First, where to find the AudioQueue header and where to install libmikmod:
export AQDIR=$HOME/local/audioqueue
export MMDIR=$HOME/local/mikmod-iphone
Make sure you are using absolute paths for the variables above. Then, let's set up some compilation flags and name the tools we'll use from the iPhone toolchain:
export CFLAGS="-I$AQDIR -DAVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER="
export CPPFLAGS="$CFLAGS"
export LDFLAGS="-framework AudioToolbox"
export CC=arm-apple-darwin-gcc
export RANLIB=arm-apple-darwin-ranlib
Okay, now it's time to let configure do its job:
./configure --enable-iphone --host=arm-apple-darwin --disable-oss --disable-esd --prefix=$MMDIR
We're almost done! But there's still a little quirk that must be addressed. The project is configured to build shared libraries, which for some reason refuse to link with the version of the open-source iPhone toolchain I use. To overcome this problem, you just need to patch the generated libtool configuration. Knowing no clever means to do so, I propose something like:
sed -r -i 's/^(allow_undefined_flag.*)"/\1 -Wl,-read_only_relocs,suppress"/' libtool
Phew, now we're done! Just type:
make CFLAGS="$CFLAGS"
make install
And voila! a fresh libmikmod with support for your beloved iPhone or iPod Touch! Oh, by the way: the library comes in both static and dynamic flavor, so it should be pretty usable. Of course, the obligatory example will follow soon :P EDIT: the link to the patch was pointing to a plain file instead of a gzip one, fixed!

Thursday, June 19, 2008

Hello World!

I'm opening this blog to share my bits of code, hacks or thoughts I have during the time I spend in front of my computer. That will be a great occasion for me to retrieve all the goodies laying in my attic and that I should take the time to package cleanly! Moreover, that will be a good way of talking about the cool things I work on nowadays... Okay, I know... it sounds so vague... but hey, it's only a Hello World after all :)