clone 401296 -1 reassign -1 kbd-chooser retitle -1 kbd-chooser: do not properly load unicode keymaps in g-i reassign 401296 libdirectfb-1.0-0 tags 401296 + d-i patch thanks
On Mon, Dec 04, 2006 at 03:10:33PM +0100, Attilio Fiandrotti wrote: > * Test results for bug #401296 (wrong encoding) > > - There were no differences between gtk-demo and df_input test results: > both failed, as described by Eddy Petrisor for ro keymap and Miroslav > Kure for cz-[lat2 | us-qwerty], to display some accented letters. > > -> I believe this bug is related to DFB or a lower lever component This issue is actually the result of two problems related to the way the Linux kernel handle unicode keymaps. First issue is in kbd-chooser: when run from the graphical installer, the keymap was not loaded using unicode symbols. This is due to the usage of the K_MEDIUMRAW keyboard mode by DirectFB, as pointed by Davide [1]. To get an unicode keymap loaded by loadkeys the keyboard must be in K_UNICODE mode ; so a temporary switch has to be done. [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=35;bug=401296 The second issue is in DirectFB itself and is solved in this patch. One aspect is pretty similar: when the library asks the kernel for the key symbols, the result are truncated for unicode symbols if the keyboard is not in K_UNICODE mode. So, a temporary switch is needed, as well as applying the right bitmask in order to retrieve the full unicode symbol. The attached patch fixes the issue in both the "keyboard" and "linux_input" input drivers. Both were displaying correct mapping on "dfbinput -k". It's really late now, and I might have made a mistake with my test setup, but I needed to disable the "keyboard" driver was needed to get the symbols properly showed in the GTK+ frontend of the debian-installer. Waow… this one really took some time to figure out… (and thanks free software for being able to track a code path in 5 different projects, from the debian-installer to the kernel itself!) Cheers, -- Jérémy Bobbio .''`. [EMAIL PROTECTED] : :Ⓐ : # apt-get install anarchism `. `'` `-
diff --git a/inputdrivers/keyboard/keyboard.c b/inputdrivers/keyboard/keyboard.c index 26dbad9..1f9b986 100644 --- a/inputdrivers/keyboard/keyboard.c +++ b/inputdrivers/keyboard/keyboard.c @@ -85,6 +85,10 @@ keyboard_get_symbol( int code, unsigned char index = KVAL(value); int base = (level == DIKSI_BASE); + /* Handle unicode characters directly */ + if (type >= 0x0f) { + return DFB_KEY( UNICODE, value ^ 0xf000 ); + } switch (type) { case KT_FN: if (index < 20) @@ -413,10 +417,17 @@ driver_get_keymap_entry( CoreInputDevice *device, void *driver_data, DFBInputDeviceKeymapEntry *entry ) { + KeyboardData *data = (KeyboardData*) driver_data; int code = entry->code; unsigned short value; DFBInputDeviceKeyIdentifier identifier; + /* switch to unicode mode to get the full keymap */ + if (ioctl( data->vt->fd, KDSKBMODE, K_UNICODE ) < 0) { + D_PERROR( "DirectFB/Keyboard: K_UNICODE failed!\n" ); + return DFB_INIT; + } + /* fetch the base level */ value = keyboard_read_value( driver_data, K_NORMTAB, code ); @@ -460,6 +471,12 @@ driver_get_keymap_entry( CoreInputDevice *device, entry->symbols[DIKSI_ALT_SHIFT] = keyboard_get_symbol( code, value, DIKSI_ALT_SHIFT ); + /* switch back to medium raw mode */ + if (ioctl( data->vt->fd, KDSKBMODE, K_MEDIUMRAW ) < 0) { + D_PERROR( "DirectFB/Keyboard: K_MEDIUMRAW failed!\n" ); + return DFB_INIT; + } + return DFB_OK; } diff --git a/inputdrivers/linux_input/linux_input.c b/inputdrivers/linux_input/linux_input.c index a4fd232..655fffc 100644 --- a/inputdrivers/linux_input/linux_input.c +++ b/inputdrivers/linux_input/linux_input.c @@ -374,6 +374,10 @@ keyboard_get_symbol( int code, unsigned char index = KVAL(value); int base = (level == DIKSI_BASE); + /* Handle unicode characters directly */ + if (type >= 0x0f) { + return DFB_KEY( UNICODE, value ^ 0xf000 ); + } switch (type) { case KT_FN: if (index < 20) @@ -1201,10 +1205,23 @@ driver_get_keymap_entry( CoreInputDevice *device, int code = entry->code; unsigned short value; DFBInputDeviceKeyIdentifier identifier; + int orig_mode; if (!data->vt) return DFB_UNSUPPORTED; + /* save keyboard mode in order to restore it later */ + if (ioctl( data->vt->fd, KDGKBMODE, &orig_mode ) < 0) { + D_PERROR( "DirectFB/Keyboard: KDGKBMODE failed!\n" ); + return DFB_INIT; + } + + /* switch to unicode mode to get the full keymap */ + if (ioctl( data->vt->fd, KDSKBMODE, K_UNICODE ) < 0) { + D_PERROR( "DirectFB/Keyboard: K_UNICODE failed!\n" ); + return DFB_INIT; + } + /* fetch the base level */ value = keyboard_read_value( driver_data, K_NORMTAB, code ); @@ -1248,6 +1265,12 @@ driver_get_keymap_entry( CoreInputDevice *device, entry->symbols[DIKSI_ALT_SHIFT] = keyboard_get_symbol( code, value, DIKSI_ALT_SHIFT ); + /* switch back to original mode */ + if (ioctl( data->vt->fd, KDSKBMODE, orig_mode ) < 0) { + D_PERROR( "DirectFB/Keyboard: KDSKBMODE failed!\n" ); + return DFB_INIT; + } + return DFB_OK; #else return DFB_UNSUPPORTED;
signature.asc
Description: Digital signature