[PATCH] keyboard.c

Andries.Brouwer@cwi.nl
Wed, 5 Aug 1998 17:07:47 +0200 (MET DST)


Below a patch for keyboard.c, allowing arbitrary non-nul bytes
to occur as dead keys, and allowing one character to be modified
by more than one diacritical. This is needed by Vietnamese and Greek.
The code is shorter than the old code, and much more powerful.

Andries

P.S. When I wrote this last week, I also did the changes for
a keycode that is an int instead of char. Unfortunately, that
change touches all of the about 20 files that handle the keyboard
for various architectures. As it turns out, these files are a mess,
so this conceptually small change gives a very large patch,
and I wanted to separate that from the present small and clean one.

[I am also not sure whether the linux-2.1.114 sources are the
latest in this respect. For example, the asm-arm/arch-*/keyboard.h
files are just nonsense, and can never work. Also, there are some
traces of a struct kbd_operations, precisely what I wanted to add
instead of all these #define's - perhaps someone did this already?]

-------------------------------------------------------------------
--- ../linux-2.1.114/linux/drivers/char/keyboard.c Tue Aug 4 20:51:31 1998
+++ linux/drivers/char/keyboard.c Wed Aug 5 15:20:19 1998
@@ -12,6 +12,7 @@
* Added decr/incr_console, dynamic keymaps, Unicode support,
* dynamic function/string keys, led setting, Sept 1994
* `Sticky' modifier keys, 951006.
+ *
* 11-11-96: SAK should now work in the raw mode (Martin Mares)
*
* Modified to provide 'generic' keyboard support by Hamish Macdonald
@@ -19,6 +20,8 @@
* parts by Geert Uytterhoeven, May 1997
*
* 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
+ *
+ * Dead keys redone, aeb@cwi.nl, 980730.
*/

#include <linux/config.h>
@@ -101,12 +104,13 @@

static k_handfn
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
- do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_ignore;
+ do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+ do_ignore;

static k_hand key_handler[16] = {
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
- do_meta, do_ascii, do_lock, do_lowercase, do_slock,
- do_ignore, do_ignore, do_ignore
+ do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+ do_ignore, do_ignore
};

/* Key types processed even in raw modes */
@@ -135,7 +139,7 @@
255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
255, NR_ASCII - 1, NR_LOCK - 1, 255,
- NR_LOCK - 1
+ NR_LOCK - 1, 255
};

const int NR_TYPES = SIZE(max_vals);
@@ -343,6 +347,10 @@

static void enter(void)
{
+ if (diacr) {
+ put_queue(diacr);
+ diacr = 0;
+ }
put_queue(13);
if (vc_kbd_mode(kbd,VC_CRLF))
put_queue(10);
@@ -539,26 +547,34 @@
static unsigned char ret_diacr[NR_DEAD] =
{A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };

-/* If a dead key pressed twice, output a character corresponding to it, */
-/* otherwise just remember the dead key. */
+/* Obsolete - for backwards compatibility only */

static void do_dead(unsigned char value, char up_flag)
{
+ value = ret_diacr[value];
+ do_dead2(value,up_flag);
+}
+
+/*
+ * Handle dead key. Note that we now may have several
+ * dead keys modifying the same character. Very useful
+ * for Vietnamese.
+ */
+static void do_dead2(unsigned char value, char up_flag)
+{
if (up_flag)
return;

- value = ret_diacr[value];
- if (diacr == value) { /* pressed twice */
- diacr = 0;
- put_queue(value);
- return;
- }
- diacr = value;
+ diacr = (diacr ? handle_diacr(value) : value);
}

-
-/* If space is pressed, return the character corresponding the pending */
-/* dead key, otherwise try to combine the two. */
+/*
+ * We have a combining character DIACR here, followed by the character CH.
+ * If the combination occurs in the table, return the corresponding value.
+ * Otherwise, if CH is a space or equals DIACR, return DIACR.
+ * Otherwise, conclude that DIACR was not combining after all,
+ * queue it and return CH.
+ */

unsigned char handle_diacr(unsigned char ch)
{
@@ -566,13 +582,14 @@
int i;

diacr = 0;
- if (ch == ' ')
- return d;

for (i = 0; i < accent_table_size; i++) {
if (accent_table[i].diacr == d && accent_table[i].base == ch)
return accent_table[i].result;
}
+
+ if (ch == ' ' || ch == d)
+ return d;

put_queue(d);
return ch;


-
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.altern.org/andrebalsa/doc/lkml-faq.html