? Keyboard.kbd
? am
? ar
? automatic-scanning.xam
? az
? be
? ca
? cs
? cy
? da
? de
? direct-selection.xam
? dist-log
? dwell-selection.xam
? el
? es
? fr
? ga
? gok-0.9.6.tar.gz
? gok-docs-patch.diff
? gok-shift-patch.diff
? gok.desktop
? hi
? hr
? inverse-scanning.xam
? it
? ja
? ko
? lt
? mk
? ml
? mn
? ms
? nl
? no
? pl
? pt
? pt_BR
? singlekey-automatic-scanning.xam
? singlekey-inverse-scanning.xam
? sk
? sl
? sq
? sr
? sr@Latn
? sv
? ta
? tr
? uk
? vi
? zh_CN
? zh_TW
? docs/reference/gok-undocumented.txt
? docs/reference/xml
? docs/reference/tmpl/gok-file-util.sgml
? docs/reference/tmpl/gok-file-util.sgml.sgml
? gok/GNOME_Gok.server.in
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gok/ChangeLog,v
retrieving revision 1.388
diff -u -r1.388 ChangeLog
--- ChangeLog	10 Feb 2004 18:51:17 -0000	1.388
+++ ChangeLog	11 Feb 2004 10:49:15 -0000
@@ -1,3 +1,34 @@
+2004-02-11  Bill Haneman <billh@gnome.org>
+
+	Fix for bug 134040.
+	
+	* gok/gok-modifier-keymasks.c:
+	Added missing KEYMASK_MOD5 (AltGr on many keyboards).
+
+	* gok/gok-output.c:
+	(gok_output_send_to_system): Use XKB to
+	handle groups and levels correctly - allows
+	correct synthesis of keycodes with shift levels > 1.
+	Also handled some code to store deadkeys and pass their
+	postfix unicode equivalents with the next keystroke.
+	(gok_output_unichar_postfix_from_deadkey): New, 
+	support for above.
+	(gok_output_unichar_from_keysym): Correct and simplify
+	to use keysym2ucs.
+	
+	* gok/gok-spy.c:
+	Remove old #ifdef which was a hack for compat with 
+	very old versions of at-spi.
+
+	* gok/gok-word-complete.c:
+	(gok_wordcomplete_unichar_is_combine): Check for 
+	UNICODE_NON_SPACING_MARK as well as COMBINING_MARK.
+
+	* gok/gok-key.h:
+	(gok_key_get_xkb_type_index, gok_key_level_for_type):
+	Expose these methods since they are now needed by
+	gok-output.c.	
+	
 2004-02-10  Bill Haneman <billh@gnome.org>
 
 	* gok/gok-key.c:
Index: gok/gok-key.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-key.c,v
retrieving revision 1.86
diff -u -r1.86 gok-key.c
--- gok/gok-key.c	10 Feb 2004 18:29:55 -0000	1.86
+++ gok/gok-key.c	11 Feb 2004 10:49:24 -0000
@@ -263,7 +263,7 @@
 }
 
 
-static int
+int
 gok_key_get_xkb_type_index (XkbDescPtr xkb, KeyCode keycode, guint group)
 {
 	int num_groups = XkbKeyNumGroups (xkb, keycode);
@@ -275,7 +275,7 @@
 	return xkb->map->key_sym_map[keycode].kt_index[group];
 }
 
-static int
+int
 gok_key_level_for_type (Display *display, XkbDescRec *kbd,
 			int type, unsigned int *modmask)
 {
@@ -518,7 +518,7 @@
 	  is_modifier = TRUE;
 	  gok_modifier_add (pKey->ModifierName);
   }
-  if (is_modifier) { /* FIXME */
+  if (is_modifier) {
     pKey->Type = KEYTYPE_MODIFIER;
     pKey->pImage = gok_keyimage_new (pKey, NULL);
     pKey->pImage->type = IMAGE_TYPE_INDICATOR;
Index: gok/gok-key.h
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-key.h,v
retrieving revision 1.54
diff -u -r1.54 gok-key.h
--- gok/gok-key.h	4 Feb 2004 16:03:21 -0000	1.54
+++ gok/gok-key.h	11 Feb 2004 10:49:25 -0000
@@ -253,6 +253,8 @@
 gboolean gok_key_contains_point (GokKey *pKey, gint x, gint y);
 void gok_key_set_effective_group (gint group);
 gint gok_key_get_effective_group (void);
+int gok_key_get_xkb_type_index (XkbDescPtr xkb, KeyCode keycode, guint group);
+int gok_key_level_for_type (Display *display, XkbDescRec *kbd, int type, unsigned int *modmask);
 GokKeyImage* gok_keyimage_new (GokKey *pKey, gchar* Filename);
 void gok_keyimage_delete (GokKeyImage* pKeyImage);
 gboolean gok_key_isRepeatable(GokKey* pKey);
Index: gok/gok-modifier-keymasks.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-modifier-keymasks.c,v
retrieving revision 1.2
diff -u -r1.2 gok-modifier-keymasks.c
--- gok/gok-modifier-keymasks.c	14 Feb 2003 15:42:17 -0000	1.2
+++ gok/gok-modifier-keymasks.c	11 Feb 2004 10:49:25 -0000
@@ -34,5 +34,6 @@
 	{ "mod2",     SPI_KEYMASK_MOD2 },
 	{ "mod3",     SPI_KEYMASK_MOD3 },
 	{ "mod4",     SPI_KEYMASK_MOD4 },
+	{ "mod5",     SPI_KEYMASK_MOD5 },
 	{ NULL,       0 }
 };
Index: gok/gok-output.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-output.c,v
retrieving revision 1.23
diff -u -r1.23 gok-output.c
--- gok/gok-output.c	4 Feb 2004 16:03:21 -0000	1.23
+++ gok/gok-output.c	11 Feb 2004 10:49:26 -0000
@@ -93,26 +93,24 @@
 	}
 }
 
+static KeySym last_dead_key = 0;
+
 gunichar gok_output_unichar_from_keysym (KeySym keysym, guint mods)
 {
 	char *charstring;
 	if ((keysym >= 0xFF08) && (keysym < 0xFF20)) { /* X11 control codes, etc. */
+		last_dead_key = 0;
 		return (gunichar) keysym & 0x00FF; /* mask out the high bits */
 	}
+	else if ((keysym >= 0xFE50) && (keysym <= 0xFE62)) { /* deadkey: save to apply later */
+		last_dead_key = keysym;
+		return 0;
+	}
 	else {
-		char buf[20];
-		int nbytes, extra_rtn;
-		Display *display;
-		if (gok_main_get_main_window ()) 
+		long ucs;
+		if ((ucs = keysym2ucs (keysym)) > 0) 
 		{
-		        long ucs;
-			display = GDK_WINDOW_XDISPLAY (gok_main_get_main_window ()->window);
-			nbytes = MIN (XkbTranslateKeySym (display,
-							  &keysym, mods, buf, 19, &extra_rtn), 19); 
-			if ((ucs = keysym2ucs (keysym)) > 0) 
-			{
-			    return (gunichar) ucs;
-			}
+			return (gunichar) ucs;
 		}
 		return 0;
 	}
@@ -245,6 +243,55 @@
 	return gok_output_new (typeOutput, g_strstrip (xmlNodeGetContent (pNode)), flagOutput);
 }
 
+static gunichar
+gok_output_unichar_postfix_from_deadkey (KeySym deadkey)
+{
+	switch (deadkey) 
+	{
+	case XK_dead_grave:
+		return 0x0300;
+	case XK_dead_acute:
+		return 0x0301;
+	case XK_dead_circumflex:
+		return 0x0302;
+	case XK_dead_tilde:
+		return 0x0303;
+	case XK_dead_macron:
+		return 0x0304;
+	case XK_dead_breve:
+		return 0x0306;
+	case XK_dead_abovedot:
+		return 0x0307;
+	case XK_dead_diaeresis:
+		return 0x0308;
+	case XK_dead_abovering:
+		return 0x030a;
+	case XK_dead_doubleacute:
+		return 0x030b;
+	case XK_dead_caron:
+		return 0x030c;
+	case XK_dead_cedilla:
+		return 0x0327;
+	case XK_dead_ogonek:
+		return 0x0328;
+	case XK_dead_iota:
+		return 0x0345;
+	case XK_dead_voiced_sound:
+		return 0x032c;
+	case XK_dead_semivoiced_sound:
+		return 0x0324;
+	case XK_dead_belowdot:
+		return 0x0323;
+	case XK_dead_hook:
+		return 0x0309;
+	case XK_dead_horn:
+		return 0x031b;
+	default:
+		return 0;
+	}
+}
+
+
 /**
 * gok_output_send_to_system
 * @pOutput: Pointer to a GokOutput that will be sent to the system.
@@ -256,6 +303,7 @@
 {
 	long keysym;
 	long keycode;
+	gunichar unichar;
 
 	gok_log_enter();
 	while (pOutput != NULL)
@@ -263,7 +311,7 @@
 		if (pOutput->Type == OUTPUT_KEYSYM)
 		{
 			keysym = XStringToKeysym (pOutput->Name);
-
+			
 			gok_log ("Sending a keysym");
 			gok_log ("pOutput->Name = %s", pOutput->Name);
 			gok_log ("SPI_KEY_SYM = %d", (int) SPI_KEY_SYM);
@@ -272,13 +320,24 @@
 
 			/* update the word prediction keys with the new output */
 			if (bWordCompletion && gok_output_can_predict ()) {
-				gok_output_update_predictions (pOutput,
-							       (gpointer) gok_output_unichar_from_keysym (keysym,
-													  gok_spy_get_modmask ()));
+				unichar = gok_output_unichar_from_keysym (keysym, 
+									  gok_spy_get_modmask ());
+				if (last_dead_key && unichar) {
+					gchar *s;
+					s = gok_wordcomplete_process_unichar (gok_wordcomplete_get_default (), unichar);
+					gok_output_update_predictions (pOutput, 
+								       (gpointer) gok_output_unichar_postfix_from_deadkey (last_dead_key));
+					last_dead_key = 0;
+				}
+				else if (unichar) {
+					gok_output_update_predictions (pOutput, 
+								       (gpointer) unichar);
+				}
 			}
 		}
 		else if (pOutput->Type == OUTPUT_KEYCODE)
 		{
+			XkbDescRec *xkb = gok_keyboard_get_xkb_desc ();
 			keycode = strtol (pOutput->Name, NULL, 0);
 
 			gok_log ("Sending a keycode");
@@ -291,22 +350,32 @@
 			if (bWordCompletion && gok_output_can_predict () &&
 			    !gok_key_modifier_for_keycode (
 				    gok_main_display (),
-				    gok_keyboard_get_xkb_desc (),
+				    xkb,
 				    keycode)) 
 			{
-			        /* FIXME this hack only works for Xlib core keymaps, not xkb-enhanced ones */
-				gulong mask = gok_spy_get_modmask ();
+				guint mask = gok_spy_get_modmask ();
 				gint group = gok_key_get_effective_group ();
-			        int index = (mask & ShiftMask) ?
-					((group > 0) ? (group + 2) : (mask & LockMask) ? 0 : 1) : 
-					((group > 0) ? (group + 1) : (mask & LockMask) ? 1 : 0);
-
-				/* TODO: get the correct index from XKB, that would be the right thing to do ;-) */
-			        keysym = XKeycodeToKeysym (gok_main_display (), 
-							   keycode, index);
-				gok_output_update_predictions (pOutput,
-							       (gpointer) gok_output_unichar_from_keysym (keysym,
-													  gok_spy_get_modmask ()));
+				int type = gok_key_get_xkb_type_index (xkb, keycode, group);
+			        int level = gok_key_level_for_type (gok_keyboard_get_display (),
+								    xkb, 
+								    type, &mask);
+
+			        keysym = XkbKeycodeToKeysym (gok_main_display (), 
+							   keycode, group, level);
+				
+				unichar = gok_output_unichar_from_keysym (keysym, 
+									  gok_spy_get_modmask ());
+				if (last_dead_key && unichar) {
+					gchar *s;
+					s = gok_wordcomplete_process_unichar (gok_wordcomplete_get_default (), unichar);
+					gok_output_update_predictions (pOutput, 
+								       (gpointer) gok_output_unichar_postfix_from_deadkey (last_dead_key));
+					last_dead_key = 0;
+				}
+				else if (unichar) {
+					gok_output_update_predictions (pOutput, 
+								       (gpointer) unichar);
+				}
 			}
 		}
 		else if (pOutput->Type == OUTPUT_KEYSTRING)
Index: gok/gok-spy.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-spy.c,v
retrieving revision 1.115
diff -u -r1.115 gok-spy.c
--- gok/gok-spy.c	5 Feb 2004 12:07:30 -0000	1.115
+++ gok/gok-spy.c	11 Feb 2004 10:49:28 -0000
@@ -32,9 +32,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include <libspi/keymasks.h>
-#ifndef  SPI_KEYMASK_MOD4
-  #define  SPI_KEYMASK_MOD4 Mod4Mask
-#endif
 #include "main.h"
 #include "gok-spy.h"
 #include "gok-log.h"
Index: gok/gok-word-complete.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-word-complete.c,v
retrieving revision 1.27
diff -u -r1.27 gok-word-complete.c
--- gok/gok-word-complete.c	20 Jan 2004 00:20:17 -0000	1.27
+++ gok/gok-word-complete.c	11 Feb 2004 10:49:29 -0000
@@ -367,7 +367,8 @@
 static gboolean
 gok_wordcomplete_unichar_is_combine (GokWordComplete *complete, gunichar letter)
 {
-	return (g_unichar_type (letter) == G_UNICODE_COMBINING_MARK);
+	GUnicodeType utype = g_unichar_type (letter);
+	return (utype == G_UNICODE_COMBINING_MARK || utype == G_UNICODE_NON_SPACING_MARK);
 }
 
 static gboolean 
@@ -504,7 +505,7 @@
 		gchar utf8char[7];
 		gchar *tmp, *tmp2;
 		utf8char[g_unichar_to_utf8 (combining_letter, utf8char)] = '\0'; /* null terminate utf8 string */
-		tmp = g_strconcat (word, utf8char);
+		tmp = g_strconcat (word, utf8char, NULL);
 		if (tmp)
 		{
 			gint len;
@@ -620,6 +621,7 @@
 		prefix = gok_wordcomplete_unichar_push (complete, letter);
 		break;
 	}
+
 	return prefix;
 }
 
