[PATCH] keyboard driver improvement for Unicode mode

Bruno Haible (haible@ilog.fr)
Sun, 8 Aug 1999 17:29:22 +0200 (MET DST)


For inclusion in the development kernel:

The patch below improves the behaviour of the keyboard input method in
Unicode mode:

1. It permits to use the CapsLock behaviour (denotes by a '+' sign in
the keymaps file) for Unicode values (for example German umlauts -
they cannot use the normal KT_LATIN/KT_LETTER mechanism in Unicode
mode).

2. It avoids buggy behaviour when CapsLock is active and a key is
pressed whose standard mapping is KT_LATIN but whose Shift mapping
is Unicode.

3. It permits Unicode keymaps to access the U+f800..U+ffff Unicode range
which was previously inaccessible due to the way keysyms are
represented in the kernel.

4. It resets the kbd->slockstate when a Unicode key was hit, just the
same as is done for KT_LATIN mapped keys.

The patch is backward compatible with existing keymaps and existing
kbd/console-tools programs. New releases of the "loadkeys" programs will
be able to make use of the new features.

Bruno

*** linux-2.3.12/drivers/char/keyboard.c.bak Sat May 22 21:57:24 1999
--- linux-2.3.12/drivers/char/keyboard.c Sun Aug 8 15:06:53 1999
***************
*** 21,26 ****
--- 21,27 ----
*
* 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
* 30-07-98: Dead keys redone, aeb@cwi.nl.
+ * 08-08-99: Make CapsLock work in Unicode mode as well (Bruno Haible)
*/

#include <linux/config.h>
***************
*** 197,203 ****
{
unsigned char keycode;
char up_flag = down ? 0 : 0200;
! char raw_mode;

do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
--- 198,204 ----
{
unsigned char keycode;
char up_flag = down ? 0 : 0200;
! char raw_mode, see_capslock;

do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
***************
*** 287,313 ****
if (key_map != NULL) {
keysym = key_map[keycode];
type = KTYP(keysym);

! if (type >= 0xf0) {
! type -= 0xf0;
! if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type)))
return;
! if (type == KT_LETTER) {
! type = KT_LATIN;
! if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
! key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
! if (key_map)
! keysym = key_map[keycode];
! }
! }
! (*key_handler[type])(keysym & 0xff, up_flag);
! if (type != KT_SLOCK)
! kbd->slockstate = 0;
} else {
! /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
! if (!up_flag && !raw_mode)
! to_utf8(keysym);
}
} else {
/* maybe beep? */
/* we have at least to update shift_state */
--- 288,333 ----
if (key_map != NULL) {
keysym = key_map[keycode];
type = KTYP(keysym);
+ /* type >= 0xf0 refers to key_handler[type-0xf0] */
+ /* type < 0xf0 is a Unicode value, mapped as follows. */
+ /* keysym = 0x0000..0xdfff -> U+0000..U+dfff */
+ /* keysym = 0xe000..0xe7ff -> U+f800..U+ffff */
+ /* keysym = 0xe800..0xefff -> U+0000..U+7fff, CapsLock */

! /* raw mode treatment */
! if (raw_mode && ! (type >= 0xf0 && (TYPES_ALLOWED_IN_RAW_MODE & (1 << (type - 0xf0)))))
return;
! /* CapsLock treatment */
! see_capslock = 0;
! if (type >= 0xf0) {
! if (type == 0xf0 + KT_LETTER)
! see_capslock = 1;
} else {
! if (keysym >= 0xe800)
! see_capslock = 1;
}
+ if (see_capslock && vc_kbd_led(kbd, VC_CAPSLOCK)) {
+ key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
+ if (key_map) {
+ keysym = key_map[keycode];
+ type = KTYP(keysym);
+ }
+ }
+ /* now handle keysym and type */
+ if (type >= 0xf0) {
+ if (type == 0xf0 + KT_LETTER)
+ type = 0xf0 + KT_LATIN; /* strip CapsLock marker */
+ (*key_handler[type-0xf0])(keysym & 0xff, up_flag);
+ } else
+ if (!up_flag) {
+ if (keysym >= 0xe800)
+ keysym -= 0xe800; /* strip CapsLock marker */
+ if (keysym >= 0xe000)
+ keysym += 0x1800;
+ to_utf8(keysym);
+ }
+ if (type != 0xf0 + KT_SLOCK)
+ kbd->slockstate = 0;
} else {
/* maybe beep? */
/* we have at least to update shift_state */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/