I've just posted my first significant contribution to an existing open source project, rdesktop. I've completely re-written the way rdesktop handles keyboard input, in an effort to bring much better support for different keyboard types and layouts, using the XKB configuration database.Here is my email announcement in the rdesktop-devel mailing list.
I'm a bit excited and worried at the same time, I just want it to be accepted, I've put a lot of time so far in this. I want it to be perfect.
Here is a copy of the mail:
It has been a while since the discussion about rdesktop using XKB. I've
worked on it from time to time, and I finally got something which is usable
Download it here:
Unzip the contents of the archive over the latest sources, and then add
xkbkeymap.o to the following line in the Makefile:
X11OBJ = rdesktop.o xwin.o xkbkeymap.o xkeymap.o ewmhints.o xclip.o
And it should compile. For the moment, I expect it to work fine at least
under any system with XKB, but the magic of the thing is that it doesn't
depend on any pre-existing XKB installation.
The reason for this patch is that rdesktop currently has its down separate
keymap database that it keeps updating and fixing. The way the keymaps
currently works is that it maps keysyms (almost the resulting characters
you'd see on your screen corresponding to a keystroke) to scan codes used by
the remote desktop protocol. As there are tons of different keyboard
layouts, it means tons of possible keymaps we'd have to make so that we
correctly map everything for each keyboard layout. It also means that if on
the client side we change the keyboard layout while rdesktop is running, the
keymap will now be wrong (still mapping for the previous keyboard layout),
unless you restart rdesktop. I've been thinking about the problem and about
a "cleaner" way to solve it. I thought of the XKB configuration database,
which is separate from XKB itself and intends to be an up to date and
accurate keymap database usable for everyone. Could we ask for a better
thing? They're already supporting way much more keyboards than we do, so I
thought it would only be for the better.
Now, what part of XKB is the best to use. Considering that we're sending
scan codes through the remote desktop protocol, it makes sense to simply map
keycodes -> virtual key codes -> scan codes. Why not keycodes to scan codes
directly? Because they're not always the same for the same key, and that is
pretty much why Microsoft made virtual key codes for. So, keycodes ->
virtual key codes -> scan codes is the most efficient and accurate. It
doesn't even depend on the current keyboard layout, all we have to know is
the keyboard type (the default type just works fine with pretty much every
"common" keyboard, a significantly different one would be a japanese
keyboard). For systems with XKB, what I'm doing in the patch at the moment
is that I call setxkbmap -print and get the current XKB keyboard type out of
that. This requires no linkage with XKBlib, which is nice.
I said at the beginning that it doesn't require any pre-existing XKB
installation. The reason is that I've made a perl script which exports only
the part of the XKB configuration database that is needed, making a new one
out of it that maps only keycodes to virtual key codes. Maintaining
rdesktop's XKB configuration database is as simple as running the perl
script on newer versions of the XKB configuration database that contain
fixes. The mapping from virtual key codes to scan codes is made using an
array of structures containing the mapping, so that for instance:
gives you the scan code for VK_SPACE.
The new XKB configuration database that is exported by the perl script can
be located anywhere where the current keymap folder is. I've made rdesktop
search for the folder in the same places.
There is more. I've made a lot of work on finding the current possible
keyboard layout from the current locale. What I found is that in the current
rdesktop code, the locale of the system would be used to find a keymap of
the same name as the locale. The keymap would then contain the keyboard
layout code that is sent to the remote desktop server. I used the locale IDs
and default keyboard layouts from Microsoft, and made a table out of it. I
also make complete tables of all the keyboard layouts and the ID that should
be sent to announce to the remote desktop server what keyboard layout to
use. this is all in keyboard.h
Now, an overview of the files contained in the patch:
Macro definitions for all virtual key codes
Default built-in keymap
Virtual key code to scan code conversion map
Keyboard layout IDs + Name in an array of structures. Same for keyboard
layout variants and IMEs.
Macro definitions for all locales (with locale ID)
Locale country code + language code to locale ID map
Default keyboard layouts for each locale, in an array of structures
Functions to detect, initialize and load the keyboard layout
Functions equivalent to what you have in xkeymap.c, but for XKB
Folder containing all the keycode -> virtual key code maps.
Perl script to export the XKB configuration database to an easier to use
format for rdesktop.
What I plan to work on, next:
Keyboard layout detection on non-XKB systems. I own a SPARC system
running Solaris 10, and it doesn't have XKB. That would be my first target.
OpenSolaris comes with X.org and XKB, so it should be fine for that one. I
also have an old PowerPC mac that runs Mac OS X Tiger, I would eventually
take the time to write keyboard layout detection function that reads it from
the current Mac OS X configuration.
I would like to know your comments and advice for the work that would still
need to be done on this. If anybody is using a japanese keyboard I would
require his assistance in order to ensure that it works fine with those
keyboards. Weird sun keyboards should be working fine if XKB is correctly
set for that keyboard. In other words, whatever is supported by XKB should
be supported by rdesktop with that.
I encourage you to try my patch and give comments! I also need people to test it so that I can more easily find problems in it.