patch-2.1.115 linux/drivers/char/keyboard.c

Next file: linux/drivers/char/misc.c
Previous file: linux/drivers/char/cyclades.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.114/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c
@@ -11,6 +11,7 @@
  * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
  * 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)
  * 
@@ -19,6 +20,7 @@
  * parts by Geert Uytterhoeven, May 1997
  *
  * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
+ * 30-07-98: Dead keys redone, aeb@cwi.nl.
  */
 
 #include <linux/config.h>
@@ -101,12 +103,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,12 +138,13 @@
 	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);
 
-static void put_queue(int);
+/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */
+void put_queue(int);
 static unsigned char handle_diacr(unsigned char);
 
 /* kbd_pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
@@ -310,12 +314,12 @@
 }
 
 
-static void put_queue(int ch)
+void put_queue(int ch)
 {
 	wake_up(&keypress_wait);
 	if (tty) {
 		tty_insert_flip_char(tty, ch, 0);
-		tty_schedule_flip(tty);
+		con_schedule_flip(tty);
 	}
 }
 
@@ -329,7 +333,7 @@
 		tty_insert_flip_char(tty, *cp, 0);
 		cp++;
 	}
-	tty_schedule_flip(tty);
+	con_schedule_flip(tty);
 }
 
 static void applkey(int key, char mode)
@@ -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);
@@ -441,7 +449,7 @@
 	if (!tty)
 		return;
 	tty_insert_flip_char(tty, 0, TTY_BREAK);
-	tty_schedule_flip(tty);
+	con_schedule_flip(tty);
 }
 
 static void scroll_forw(void)
@@ -539,42 +547,49 @@
 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)
 {
 	int d = diacr;
 	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;
 	}
 
-	put_queue(d);
+	if (ch == ' ' || ch == d)
+		return d;
+
 	return ch;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov