? Keyboard.kbd
? am
? ar
? automatic-scanning.xam
? az
? be
? ca
? cs
? cy
? da
? de
? direct-selection.xam
? dwell-selection.xam
? el
? es
? foo
? fr
? ga
? gok-group-patch.diff
? gok-groups-patch.diff
? gok-thai-trouble.png
? gok-ui-grab-patch.diff
? gok.desktop
? hi
? hr
? inverse-scanning.xam
? it
? ja
? ko
? log
? lt
? mk
? ml
? mn
? ms
? nl
? no
? pl
? pt
? pt_BR
? screenshot-gb-shift.png
? screenshot-thai-null-probs.png
? 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-decl-list.txt
? docs/reference/gok-decl.txt
? docs/reference/gok-undocumented.txt
? docs/reference/gok-unused.txt
? docs/reference/gok.args
? docs/reference/gok.hierarchy
? docs/reference/gok.signals
? docs/reference/html
? docs/reference/html-build.stamp
? docs/reference/html.stamp
? docs/reference/scan-build.stamp
? docs/reference/sgml
? docs/reference/sgml-build.stamp
? docs/reference/sgml.stamp
? docs/reference/tmpl-build.stamp
? docs/reference/tmpl.stamp
? docs/reference/tmpl/gok-file-util.sgml
? docs/reference/tmpl/gok-file-util.sgml.sgml
? gok/gok-pango-test.c
? gok/keyboard-geometry
? gok/test-focus-reject
? gok/test-gok-wordcomplete
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gok/ChangeLog,v
retrieving revision 1.375
diff -u -r1.375 ChangeLog
--- ChangeLog	4 Feb 2004 14:42:46 -0000	1.375
+++ ChangeLog	4 Feb 2004 15:52:57 -0000
@@ -1,3 +1,64 @@
+<<<<<<< ChangeLog
+2004-02-04  Bill Haneman <billh@gnome.org>
+
+	* gok/gok-windowlister.c:
+	(gok_windowlister_show): Allow for possible failure of
+	wnck_window_get_name() call to return a non-NULL string.
+
+2004-02-03  Bill Haneman <billh@gnome.org>
+
+	* gok/gok-key.h:
+	(GokKeyLabel): Store level and group now, not modifiers and
+	mod_mask. For bug #132757.
+
+	* gok/gok-key.c:
+	Changed some char declarations to gchar, for consistency when
+	doing utf8/byte mixed operations.
+	(gok_key_print_utf8_debug): New, used only for debugging.
+	(gok_key_get_xkb_type_index): Reworked to work correctly with
+	multi-group keyboards, and to include a compensation for
+	alphabetic types to account for the 'preservation' of the
+	LockMask, which is accounted for by Xlib string conversion rather
+	than the XKB level calculation.
+	(gok_key_label_from_keycode):  Reworked to take a level/group
+	combination; it now works correctly for multi-group keyboards.
+	(gok_key_keycode_from_xkb_key): We now create the new keylabels
+	for four groups and up to four levels.  This is more
+	correct and more efficient.
+	(gok_key_initialize): Got rid of some leaks detected by valgrind,
+	in reading XML strings without freeing them.	Read in 
+	the 'level' and 'group' attributes of compose keyboard xml nodes.
+	(gok_keylabel_new): Pass in level and group instead of
+	modifiers and mod_mask.
+	(gok_key_add_label): Take level+group instead of mods and mask.
+	(gok_key_get_label): FIxed to work properly with multi-group keyboards.
+	
+	* qwerty.kbd:
+	Changed references to (deprecated) 'modifier' attribute to
+	'level' instead. (see below).
+
+	* gok/gok-editor.c:
+	(gok_editor_add_key):
+	Pass additional NULL parameter to gok_key_add_label().
+
+	* gok/gok-output.[ch]:
+	(gok_output_unichar_from_keysym): Correct this by using keysym2ucs.
+	(gok_output_get_keycode): New, used internally.
+	
+	* gok/gok-predictor.c:
+	(gok_predictor_predict): Pass additional parameter to
+	gok_key_add_label().
+
+	* gok/gok-windowlister.c:
+	(gok_windowlister_show): Pass additional parameter to
+	gok_key_add_label().
+
+	* gok/keysym2ucs.c:
+	Changed 'ucs' member of struct from short to long, to
+	handle guint32 unichars.  Added a typecast when returning the
+	keysym itself.
+	
+=======
 2004-02-04  David Bolter  <david.bolter@utoronto.ca>
 
 	* gok/gok-spy.c: 
@@ -5,6 +66,7 @@
 	(gok_spy_accessible_unref): added preprocessing to create empty
 	functions if logging is not enabled.
 
+>>>>>>> 1.375
 2004-01-29  Bill Haneman <billh@gnome.org>
 
 	* gok/gok-keyboard.c:
Index: gok-controls.kbd
===================================================================
RCS file: /cvs/gnome/gok/gok-controls.kbd,v
retrieving revision 1.10
diff -u -r1.10 gok-controls.kbd
--- gok-controls.kbd	29 Jan 2004 16:51:09 -0000	1.10
+++ gok-controls.kbd	4 Feb 2004 15:52:57 -0000
@@ -53,6 +53,9 @@
 		
 		
 		
+		
+		
+		
 	</GOK:key>
 	<GOK:key bottom="1" type="help" top="0" right="6" left="4">
 		<GOK:label>Help</GOK:label>
@@ -65,6 +68,9 @@
 		
 		
 		
+		
+		
+		
 	</GOK:key>
 	<GOK:key bottom="2" type="branchModal" top="1" right="2" target="move-resize" left="0">
 		<GOK:label>Window</GOK:label>
@@ -84,6 +90,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="2" type="branch" top="1" right="4" target="quit" left="2">
 		<GOK:label>Quit GOK</GOK:label>
@@ -96,6 +103,9 @@
 		
 		
 		
+		
+		
+		
 	</GOK:key>
 	<GOK:key bottom="2" type="settings" top="1" right="6" left="4">
 		<GOK:label>Preferences</GOK:label>
@@ -108,6 +118,9 @@
 		
 		
 		
+		
+		
+		
 	</GOK:key>
 </GOK:keyboard>
 </GOK:GokFile>
\ No newline at end of file
Index: hide.kbd
===================================================================
RCS file: /cvs/gnome/gok/hide.kbd,v
retrieving revision 1.6
diff -u -r1.6 hide.kbd
--- hide.kbd	29 Jan 2004 16:51:09 -0000	1.6
+++ hide.kbd	4 Feb 2004 15:52:57 -0000
@@ -20,6 +20,7 @@
 		
 		
 		
+		
 	</GOK:key>
 </GOK:keyboard>
 </GOK:GokFile>
\ No newline at end of file
Index: launcher.kbd
===================================================================
RCS file: /cvs/gnome/gok/launcher.kbd,v
retrieving revision 1.11
diff -u -r1.11 launcher.kbd
--- launcher.kbd	29 Jan 2004 16:51:09 -0000	1.11
+++ launcher.kbd	4 Feb 2004 15:52:57 -0000
@@ -59,6 +59,7 @@
 		
 		
 		
+		
 		 
 		<GOK:output type="exec">gnome-terminal</GOK:output>
 	</GOK:key> 
@@ -79,6 +80,7 @@
 		
 		
 		
+		
 		 
 		<GOK:output type="exec">mozilla</GOK:output>
 	</GOK:key> 
@@ -99,6 +101,7 @@
 		
 		
 		
+		
 		 
 		<GOK:output type="exec">gedit</GOK:output>
 	</GOK:key> 
@@ -119,6 +122,7 @@
 		
 		
 		
+		
 		 
 		<GOK:output type="exec">gnome-help</GOK:output>
 	</GOK:key> 
Index: main.kbd
===================================================================
RCS file: /cvs/gnome/gok/main.kbd,v
retrieving revision 1.24
diff -u -r1.24 main.kbd
--- main.kbd	29 Jan 2004 16:51:09 -0000	1.24
+++ main.kbd	4 Feb 2004 15:52:57 -0000
@@ -62,6 +62,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="1" type="branchModal" top="0" right="4" target="move-resize" left="2">
 		<GOK:label>Window</GOK:label>
@@ -81,6 +82,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="1" type="branch" top="0" right="6" target="mouse" left="4">
 		<GOK:label>Mouse</GOK:label>
@@ -100,6 +102,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="2" type="branchWindows" top="1" right="4" left="2">
 		<GOK:label>Activate</GOK:label>
@@ -118,6 +121,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="3" type="branchToolbars" top="2" right="4" left="2">
 		<GOK:label>Toolbars</GOK:label>
@@ -136,6 +140,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="2" type="branchSettings" top="1" right="6" target="gok-controls" left="4">
 		<GOK:label>GOK</GOK:label>
@@ -194,6 +199,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="2" type="branch" top="1" right="2" target="launcher" left="0">
 		<GOK:label>Launcher</GOK:label>
@@ -213,6 +219,7 @@
 		
 		
 		
+		
 	</GOK:key>
 </GOK:keyboard>
 </GOK:GokFile>
\ No newline at end of file
Index: mouse.kbd
===================================================================
RCS file: /cvs/gnome/gok/mouse.kbd,v
retrieving revision 1.8
diff -u -r1.8 mouse.kbd
--- mouse.kbd	29 Jan 2004 16:51:09 -0000	1.8
+++ mouse.kbd	4 Feb 2004 15:52:57 -0000
@@ -58,6 +58,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="1" type="pointer" top="0" right="4" left="2">
 		<GOK:label>Pointer</GOK:label>
@@ -77,6 +78,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="1" type="repeat-next" top="0" right="6" left="4">
 		<GOK:label>Repeat</GOK:label>
@@ -96,6 +98,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="northwest" bottom="2" type="mouse" top="1" right="1" left="0">
 		<GOK:label>NW</GOK:label>
@@ -115,6 +118,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="north" bottom="2" type="mouse" top="1" right="3" left="1">
 		<GOK:label>N</GOK:label>
@@ -134,6 +138,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="northeast" bottom="2" type="mouse" top="1" right="4" left="3">
 		<GOK:label>NE</GOK:label>
@@ -153,6 +158,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="2" type="mousebutton" action="button1" top="1" right="6" left="4">
 		<GOK:label>Button 1</GOK:label>
@@ -172,6 +178,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="west" bottom="3" type="mouse" top="2" right="1" left="0">
 		<GOK:label>W</GOK:label>
@@ -191,6 +198,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="3" type="mousebutton" action="double1" top="2" right="3" left="1">
 		<GOK:label>Dbl Click</GOK:label>
@@ -210,6 +218,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="east" bottom="3" type="mouse" top="2" right="4" left="3">
 		<GOK:label>E</GOK:label>
@@ -229,6 +238,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="3" type="mousebutton" action="button2" top="2" right="6" left="4">
 		<GOK:label>Button 2</GOK:label>
@@ -248,6 +258,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="southwest" bottom="4" type="mouse" top="3" right="1" left="0">
 		<GOK:label>SW</GOK:label>
@@ -267,6 +278,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="south" bottom="4" type="mouse" top="3" right="3" left="1">
 		<GOK:label>S</GOK:label>
@@ -286,6 +298,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="southeast" bottom="4" type="mouse" top="3" right="4" left="3">
 		<GOK:label>SE</GOK:label>
@@ -304,6 +317,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key bottom="4" type="mousebutton" action="button3" top="3" right="6" left="4">
 		<GOK:label>Button 3</GOK:label>
@@ -323,6 +337,7 @@
 		
 		
 		
+		
 	</GOK:key>
 </GOK:keyboard>
 </GOK:GokFile>
\ No newline at end of file
Index: move-resize.kbd
===================================================================
RCS file: /cvs/gnome/gok/move-resize.kbd,v
retrieving revision 1.14
diff -u -r1.14 move-resize.kbd
--- move-resize.kbd	29 Jan 2004 16:51:09 -0000	1.14
+++ move-resize.kbd	4 Feb 2004 15:52:58 -0000
@@ -60,6 +60,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="south" bottom="1" type="dock" top="0" right="5" left="3">
 		<GOK:label>Dock Bottom</GOK:label>
@@ -79,6 +80,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="fillwidth" bottom="1" type="move-resize" top="0" right="6" left="5">
 		<GOK:label>Fill</GOK:label>
@@ -98,6 +100,7 @@
 		
 		
 		
+		
 	</GOK:key>
 
 	<GOK:key dir="northwest" bottom="2" type="move-resize" top="1" right="1" left="0">
@@ -121,6 +124,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="northeast" bottom="2" type="move-resize" top="1" right="4" left="3">
 		<GOK:image type="fixed:20,20" align="right" source="NE.png" />
@@ -143,6 +147,7 @@
 		
 		
 		
+		
 	</GOK:key>
 
 	<GOK:key dir="west" bottom="3" type="move-resize" top="2" right="1" left="0">
@@ -163,6 +168,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="none" bottom="3" type="dock" top="2" right="3" left="1">
 		<GOK:label>Float</GOK:label>
@@ -182,6 +188,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="east" bottom="3" type="move-resize" top="2" right="4" left="3">
 		<GOK:label>Right</GOK:label>
@@ -201,6 +208,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="wider" bottom="3" type="move-resize" top="2" right="6" left="4">
 		<GOK:label>Wider</GOK:label>
@@ -220,6 +228,7 @@
 		
 		
 		
+		
 	</GOK:key>
 
 	<GOK:key dir="southwest" bottom="4" type="move-resize" top="3" right="1" left="0">
@@ -243,6 +252,7 @@
 		
 		
 		
+		
 	</GOK:key>
 	<GOK:key dir="southeast" bottom="4" type="move-resize" top="3" right="4" left="3">
 		<GOK:image type="fixed:20,20" align="right" source="SE.png" />
@@ -265,6 +275,7 @@
 		
 		
 		
+		
 	</GOK:key>
 
 	<GOK:key bottom="5" type="branch" top="4" right="1" target="hide" left="0">
@@ -285,6 +296,7 @@
 		
 		
 		
+		
 	</GOK:key>
         <GOK:key bottom="5" type="repeat-next" top="4" right="4" left="1">
                 <GOK:label>Repeat Next Key</GOK:label>
@@ -338,6 +350,7 @@
 		
 		
 		
+		
 	</GOK:key>
 </GOK:keyboard>
 </GOK:GokFile>
\ No newline at end of file
Index: quit.kbd
===================================================================
RCS file: /cvs/gnome/gok/quit.kbd,v
retrieving revision 1.7
diff -u -r1.7 quit.kbd
--- quit.kbd	29 Jan 2004 16:51:09 -0000	1.7
+++ quit.kbd	4 Feb 2004 15:52:58 -0000
@@ -61,6 +61,7 @@
 		
 		
 		
+		
 		<GOK:image type="stock" source="gtk-quit" />
 	</GOK:key>
 </GOK:keyboard>
Index: qwerty.kbd
===================================================================
RCS file: /cvs/gnome/gok/qwerty.kbd,v
retrieving revision 1.19
diff -u -r1.19 qwerty.kbd
--- qwerty.kbd	11 Dec 2002 20:38:38 -0000	1.19
+++ qwerty.kbd	4 Feb 2004 15:52:58 -0000
@@ -71,67 +71,67 @@
 	</GOK:key> 
 	<GOK:key left="0" right="1" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>`</GOK:label> 
-		<GOK:label modifier="shift">~</GOK:label>
+		<GOK:label level="2">~</GOK:label>
 		<GOK:output type="keysym">asciitilde</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="1" right="2" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>1</GOK:label> 
-		<GOK:label modifier="shift">!</GOK:label>
+		<GOK:label level="2">!</GOK:label>
 		<GOK:output type="keysym">1</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="2" right="3" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>2</GOK:label> 
-		<GOK:label modifier="shift">@</GOK:label>
+		<GOK:label level="2">@</GOK:label>
 		<GOK:output type="keysym">2</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="3" right="4" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>3</GOK:label> 
-		<GOK:label modifier="shift">#</GOK:label>
+		<GOK:label level="2">#</GOK:label>
 		<GOK:output type="keysym">3</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="4" right="5" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>4</GOK:label> 
-		<GOK:label modifier="shift">$</GOK:label>
+		<GOK:label level="2">$</GOK:label>
 		<GOK:output type="keysym">4</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="5" right="6" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>5</GOK:label> 
-		<GOK:label modifier="shift">%</GOK:label>
+		<GOK:label level="2">%</GOK:label>
 		<GOK:output type="keysym">5</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="6" right="7" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>6</GOK:label> 
-		<GOK:label modifier="shift">^</GOK:label>
+		<GOK:label level="2">^</GOK:label>
 		<GOK:output type="keysym">6</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="7" right="8" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>7</GOK:label> 
-		<GOK:label modifier="shift">&amp;</GOK:label>
+		<GOK:label level="2">&amp;</GOK:label>
 		<GOK:output type="keysym">7</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="8" right="9" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>8</GOK:label> 
-		<GOK:label modifier="shift">*</GOK:label>
+		<GOK:label level="2">*</GOK:label>
 		<GOK:output type="keysym">8</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="9" right="10" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>9</GOK:label> 
-		<GOK:label modifier="shift">(</GOK:label>
+		<GOK:label level="2">(</GOK:label>
 		<GOK:output type="keysym">9</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="10" right="11" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>0</GOK:label> 
-		<GOK:label modifier="shift">)</GOK:label>
+		<GOK:label level="2">)</GOK:label>
 		<GOK:output type="keysym">0</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="11" right="12" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>-</GOK:label> 
-		<GOK:label modifier="shift">_</GOK:label>
+		<GOK:label level="2">_</GOK:label>
 		<GOK:output type="keysym">minus</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="12" right="13" top="1" bottom="2" type="normal" fontsizegroup="1"> 
 		<GOK:label>=</GOK:label> 
-		<GOK:label modifier="shift">+</GOK:label>
+		<GOK:label level="2">+</GOK:label>
 		<GOK:output type="keysym">equal</GOK:output>
 	</GOK:key> 
 	<GOK:key left="13" right="15" top="1" bottom="2" type="normal"> 
@@ -156,80 +156,67 @@
 	</GOK:key> 
 	<GOK:key left="1" right="2" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>q</GOK:label> 
-		<GOK:label modifier="shift">Q</GOK:label>
-		<GOK:label modifier="capslock">Q</GOK:label>
+		<GOK:label level="2">Q</GOK:label>
 		<GOK:output type="keysym">q</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="2" right="3" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>w</GOK:label> 
-		<GOK:label modifier="shift">W</GOK:label>
-		<GOK:label modifier="capslock">W</GOK:label>
+		<GOK:label level="2">W</GOK:label>
 		<GOK:output type="keysym">w</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="3" right="4" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>e</GOK:label> 
-		<GOK:label modifier="shift">E</GOK:label>
-		<GOK:label modifier="capslock">E</GOK:label>
+		<GOK:label level="2">E</GOK:label>
 		<GOK:output type="keysym">e</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="4" right="5" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>r</GOK:label> 
-		<GOK:label modifier="shift">R</GOK:label>
-		<GOK:label modifier="capslock">R</GOK:label>
+		<GOK:label level="2">R</GOK:label>
 		<GOK:output type="keysym">r</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="5" right="6" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>t</GOK:label> 
-		<GOK:label modifier="shift">T</GOK:label>
-		<GOK:label modifier="capslock">T</GOK:label>
+		<GOK:label level="2">T</GOK:label>
 		<GOK:output type="keysym">t</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="6" right="7" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>y</GOK:label> 
-		<GOK:label modifier="shift">Y</GOK:label>
-		<GOK:label modifier="capslock">Y</GOK:label>
+		<GOK:label level="2">Y</GOK:label>
 		<GOK:output type="keysym">y</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="7" right="8" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>u</GOK:label> 
-		<GOK:label modifier="shift">U</GOK:label>
-		<GOK:label modifier="capslock">U</GOK:label>
+		<GOK:label level="2">U</GOK:label>
 		<GOK:output type="keysym">u</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="8" right="9" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>i</GOK:label> 
-		<GOK:label modifier="shift">I</GOK:label>
-		<GOK:label modifier="capslock">I</GOK:label>
+		<GOK:label level="2">I</GOK:label>
 		<GOK:output type="keysym">i</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="9" right="10" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>o</GOK:label> 
-		<GOK:label modifier="shift">O</GOK:label>
-		<GOK:label modifier="capslock">O</GOK:label>
+		<GOK:label level="2">O</GOK:label>
 		<GOK:output type="keysym">o</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="10" right="11" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>p</GOK:label> 
-		<GOK:label modifier="shift">P</GOK:label>
-		<GOK:label modifier="capslock">P</GOK:label>
+		<GOK:label level="2">P</GOK:label>
 		<GOK:output type="keysym">p</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="11" right="12" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>[</GOK:label> 
-		<GOK:label modifier="shift">{</GOK:label>
-		<GOK:label modifier="capslock">[</GOK:label>
+		<GOK:label level="2">{</GOK:label>
 		<GOK:output type="keysym">bracketleft</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="12" right="13" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>]</GOK:label> 
-		<GOK:label modifier="shift">}</GOK:label>
-		<GOK:label modifier="capslock">]</GOK:label>
+		<GOK:label level="2">}</GOK:label>
 		<GOK:output type="keysym">bracketright</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="13" right="14" top="2" bottom="3" type="normal" fontsizegroup="1"> 
 		<GOK:label>\</GOK:label> 
-		<GOK:label modifier="shift">|</GOK:label>
-		<GOK:label modifier="capslock">\</GOK:label>
+		<GOK:label level="2">|</GOK:label>
 		<GOK:output type="keysym">backslash</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="14" right="15" top="0" bottom="1" type="normal"> 
@@ -250,131 +237,115 @@
 	</GOK:key> 
 	<GOK:key left="1" right="2" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>a</GOK:label> 
-		<GOK:label modifier="shift">A</GOK:label>
-		<GOK:label modifier="capslock">A</GOK:label>
+		<GOK:label level="2">A</GOK:label>
 		<GOK:output type="keysym">a</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="2" right="3" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>s</GOK:label> 
-		<GOK:label modifier="shift">S</GOK:label>
-		<GOK:label modifier="capslock">S</GOK:label>
+		<GOK:label level="2">S</GOK:label>
 		<GOK:output type="keysym">s</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="3" right="4" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>d</GOK:label> 
-		<GOK:label modifier="shift">D</GOK:label>
-		<GOK:label modifier="capslock">D</GOK:label>
+		<GOK:label level="2">D</GOK:label>
 		<GOK:output type="keysym">d</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="4" right="5" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>f</GOK:label> 
-		<GOK:label modifier="shift">F</GOK:label>
-		<GOK:label modifier="capslock">F</GOK:label>
+		<GOK:label level="2">F</GOK:label>
 		<GOK:output type="keysym">f</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="5" right="6" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>g</GOK:label> 
-		<GOK:label modifier="shift">G</GOK:label>
-		<GOK:label modifier="capslock">G</GOK:label>
+		<GOK:label level="2">G</GOK:label>
 		<GOK:output type="keysym">g</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="6" right="7" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>h</GOK:label> 
-		<GOK:label modifier="shift">H</GOK:label>
-		<GOK:label modifier="capslock">H</GOK:label>
+		<GOK:label level="2">H</GOK:label>
 		<GOK:output type="keysym">h</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="7" right="8" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>j</GOK:label> 
-		<GOK:label modifier="shift">J</GOK:label>
-		<GOK:label modifier="capslock">J</GOK:label>
+		<GOK:label level="2">J</GOK:label>
 		<GOK:output type="keysym">j</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="8" right="9" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>k</GOK:label> 
-		<GOK:label modifier="shift">K</GOK:label>
-		<GOK:label modifier="capslock">K</GOK:label>
+		<GOK:label level="2">K</GOK:label>
 		<GOK:output type="keysym">k</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="9" right="10" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>l</GOK:label> 
-		<GOK:label modifier="shift">L</GOK:label>
-		<GOK:label modifier="capslock">L</GOK:label>
+		<GOK:label level="2">L</GOK:label>
 		<GOK:output type="keysym">l</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="10" right="11" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>;</GOK:label> 
-		<GOK:label modifier="shift">:</GOK:label>
+		<GOK:label level="2">:</GOK:label>
 		<GOK:output type="keysym">semicolon</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="11" right="12" top="3" bottom="4" type="normal" fontsizegroup="1"> 
 		<GOK:label>'</GOK:label> 
-		<GOK:label modifier="shift">&quot;</GOK:label>
+		<GOK:label level="2">&quot;</GOK:label>
 		<GOK:output type="keysym">apostrophe</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="12" right="15" top="3" bottom="4" type="normal"> 
 		<GOK:label>Enter</GOK:label> 
 		<GOK:output type="keysym">Return</GOK:output> 
 	</GOK:key> 
-	<GOK:key left="0" right="1" top="4" bottom="5" type="modifier" modifier="shift">
+	<GOK:key left="0" right="1" top="4" bottom="5" type="modifier" level="2">
 		<GOK:label>Shift</GOK:label> 
 		<GOK:output type="keysym">Shift_L</GOK:output>
 	</GOK:key> 
 	<GOK:key left="1" right="2" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>z</GOK:label> 
-		<GOK:label modifier="shift">Z</GOK:label>
-		<GOK:label modifier="capslock">Z</GOK:label>
+		<GOK:label level="2">Z</GOK:label>
 		<GOK:output type="keysym">z</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="2" right="3" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>x</GOK:label> 
-		<GOK:label modifier="shift">X</GOK:label>
-		<GOK:label modifier="capslock">X</GOK:label>
+		<GOK:label level="2">X</GOK:label>
 		<GOK:output type="keysym">x</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="3" right="4" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>c</GOK:label> 
-		<GOK:label modifier="shift">C</GOK:label>
-		<GOK:label modifier="capslock">C</GOK:label>
+		<GOK:label level="2">C</GOK:label>
 		<GOK:output type="keysym">c</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="4" right="5" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>v</GOK:label> 
-		<GOK:label modifier="shift">V</GOK:label>
-		<GOK:label modifier="capslock">V</GOK:label>
+		<GOK:label level="2">V</GOK:label>
 		<GOK:output type="keysym">v</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="5" right="6" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>b</GOK:label> 
-		<GOK:label modifier="shift">B</GOK:label>
-		<GOK:label modifier="capslock">B</GOK:label>
+		<GOK:label level="2">B</GOK:label>
 		<GOK:output type="keysym">b</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="6" right="7" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>n</GOK:label> 
-		<GOK:label modifier="shift">N</GOK:label>
-		<GOK:label modifier="capslock">N</GOK:label>
+		<GOK:label level="2">N</GOK:label>
 		<GOK:output type="keysym">n</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="7" right="8" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>m</GOK:label> 
-		<GOK:label modifier="shift">M</GOK:label>
-		<GOK:label modifier="capslock">M</GOK:label>
+		<GOK:label level="2">M</GOK:label>
 		<GOK:output type="keysym">m</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="8" right="9" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>,</GOK:label> 
-		<GOK:label modifier="shift">&lt;</GOK:label>
+		<GOK:label level="2">&lt;</GOK:label>
 		<GOK:output type="keysym">comma</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="9" right="10" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>.</GOK:label> 
-		<GOK:label modifier="shift">&gt;</GOK:label>
+		<GOK:label level="2">&gt;</GOK:label>
 		<GOK:output type="keysym">period</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="10" right="11" top="4" bottom="5" type="normal" fontsizegroup="1"> 
 		<GOK:label>/</GOK:label> 
-		<GOK:label modifier="shift">?</GOK:label>
+		<GOK:label level="2">?</GOK:label>
 		<GOK:output type="keysym">slash</GOK:output> 
 	</GOK:key> 
 	<GOK:key left="11" right="13" top="4" bottom="5" type="modifier" modifier="shift">
Index: gok/gok-button.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-button.c,v
retrieving revision 1.26
diff -u -r1.26 gok-button.c
--- gok/gok-button.c	30 Jun 2003 12:43:22 -0000	1.26
+++ gok/gok-button.c	4 Feb 2004 15:52:59 -0000
@@ -310,7 +310,6 @@
  	gboolean retval = 
 		(* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
 	
-
 	if (GTK_WIDGET_DRAWABLE (widget) && GOK_BUTTON (widget)->pImage) {
 		if (GOK_BUTTON (widget)->indicator_type != NULL) {
 			GtkWidget *image = GOK_BUTTON (widget)->pImage;
Index: gok/gok-editor.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-editor.c,v
retrieving revision 1.12
diff -u -r1.12 gok-editor.c
--- gok/gok-editor.c	11 Dec 2003 20:08:33 -0000	1.12
+++ gok/gok-editor.c	4 Feb 2004 15:53:00 -0000
@@ -535,7 +535,7 @@
 		pNewKey->Left = col;
 		pNewKey->Right = col + 1;
 		gok_log("adding key {top [%d] bottom [%d] left [%d] right [%d]}",pNewKey->Top,pNewKey->Bottom,pNewKey->Left,pNewKey->Right);
-		gok_key_add_label (pNewKey, _("label"), 0, 0);
+		gok_key_add_label (pNewKey, _("label"), 0, 0, NULL);
 		
 		gok_editor_touch_file(TRUE);
 		gok_editor_update_keyboard(m_pKeyboard);
@@ -808,10 +808,9 @@
 		while (pLabel != NULL)
 		{
 			fputs ("\t\t<GOK:label", pFile);
-			if (pLabel->modifiers != 0)
-			{
-				fprintf (pFile, " modifier=\"%s\"", 
-					 gok_modifier_first_name_from_mask (pLabel->modifiers));
+			if (pLabel->level != 0)			{
+				fprintf (pFile, " level=\"%d\"", 
+					 pLabel->level);
 			}
 			fprintf (pFile, ">%s</GOK:label>\n", pLabel->Text);
 			
Index: gok/gok-key.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-key.c,v
retrieving revision 1.82
diff -u -r1.82 gok-key.c
--- gok/gok-key.c	28 Jan 2004 14:29:30 -0000	1.82
+++ gok/gok-key.c	4 Feb 2004 15:53:03 -0000
@@ -50,16 +50,45 @@
 
 gchar m_TextEmpty[]="";
 
-char m_label[XkbKeyNameLength + 1];
+gchar m_label[XkbKeyNameLength + 1];
 
 gint m_Group = 0; /* FIXME: statics are bad */
 
+#undef GOK_UTF8_DEBUG
+
+static void 
+gok_key_print_utf8_debug (gchar *buf)
+{
+      gchar *cp = buf;
+      gunichar next_char;
+      while ((next_char = g_utf8_get_char_validated (cp, -1)) >= 0) 
+      {
+	  fprintf (stderr, "[%x]", (unsigned long) next_char);
+	  if (next_char == 0) 
+	  {
+	      fprintf (stderr, "\t");
+	      break;
+	  }
+	  cp = g_utf8_next_char (cp);
+      }
+      cp = buf;
+      while (*cp)
+      {
+	  guchar c = *cp;
+	  fprintf (stderr, "0x%x ", (unsigned) c);
+	  ++cp;
+      }
+      fprintf (stderr, "\n");
+}
+
 /* returned string must be freed */
-static char *
-gok_key_lookup_shorter_label (char *str)
+static guchar *
+gok_key_lookup_shorter_label (guchar *str)
 {
 	gint i;
-	gchar *xstr = NULL;
+	guchar *xstr = NULL;
+
+	/* handle deadkeys gracefully */
 
 	if (!strcmp (str, "Delete")) {
 		xstr = "Del";
@@ -102,7 +131,7 @@
 	else {
 		gint len;
 		gboolean prev_is_lower, is_upper;
-		gchar *s1, *st2, *st1;
+		guchar *s1, *st2, *st1;
 		
 		if (!strncmp (str, "Sun", 3)) {
 			s1 = g_strdup (str + 3);
@@ -130,13 +159,15 @@
 	return str;
 }
 
-static char *	
-gok_key_label_from_keysym_string (const char *str)
+static guchar *	
+gok_key_label_from_keysym_string (const guchar *str)
 {
-	char *cp;
+	guchar *cp;
 	size_t strl;
+
 	if (!str) return g_strdup ("<nil>");
 	strl = strlen(str);
+
 	if (strncmp(str, "KP_", 3) == 0) {
 	        cp = g_strdup (str + 3);
 	}
@@ -154,6 +185,7 @@
 	}
 	if (strlen (cp) > 4)
 		cp = gok_key_lookup_shorter_label (cp);
+
 	return cp;
 }
 
@@ -172,7 +204,7 @@
 
 
 static int
-gok_key_get_xkb_type_index (XkbDescPtr xkb, KeyCode keycode, int group)
+gok_key_get_xkb_type_index (XkbDescPtr xkb, KeyCode keycode, guint group)
 {
 	int num_groups = XkbKeyNumGroups (xkb, keycode);
 	int index;
@@ -188,30 +220,64 @@
 			int type, unsigned int *modmask)
 {
 	int i, level = 0;
+	gboolean level_set = FALSE;
 	XkbKeyTypeRec *key_type = &kbd->map->types[type];
+
 	/* compare against each map entry in the XkbKeyType */
-	for (i = 0; i < key_type->map_count; ++i)
+	for (i = 0; i < key_type->map_count && !level_set; ++i)
 	{
-		unsigned int vmods_equiv = 0, level_mask = 0;
+		unsigned int vmods_equiv = 0, level_mods = 0;
 		unsigned int mods_mask;
+		unsigned int mods = *modmask;
 		XkbVirtualModsToReal (kbd, key_type->map[i].mods.vmods,
 				      &vmods_equiv);
 		XkbVirtualModsToReal (kbd, key_type->mods.vmods,
 				      &mods_mask);
-		mods_mask = key_type->mods.mask | mods_mask;
+		mods_mask = key_type->mods.mask;
+		level_mods = key_type->map[i].mods.real_mods | vmods_equiv;
 #ifdef GOK_DEBUG
-		if (type == 3) fprintf (stderr, "keypad [%d], level %d, realmods = %x, vmods = %x, preserve %x; mods_mask %x\n",
-					i, key_type->map[i].level,
-					key_type->map[i].mods.real_mods,
-					vmods_equiv,
+		fprintf (stderr, "key type %d [map %d], level %d, preserve %x; mods_mask %x; level_mods %x; modmask %x\n",
+					type, i, key_type->map[i].level,
 					key_type->preserve ? key_type->preserve[i].mask : 0,
-					mods_mask);
+					mods_mask,
+			                level_mods,
+			                *modmask);
 #endif
-		level_mask = key_type->map[i].mods.mask | vmods_equiv;
 		if ((key_type->map[i].active) && 
-		    ((*modmask & mods_mask) == level_mask))
+		    ((mods & mods_mask) == level_mods))
 		{	
 			level = key_type->map[i].level;
+			level_set = TRUE;
+			/** 
+			 *  Special hack for alpha types: see section 15.2.1 of XKBlib spec. 
+			 *  We'd restrict this to the canonical types, but XFree's maps tend to use 
+			 *  non-canonical types for the primary alphanumeric keycodes, in order
+			 *  to support more shift levels (AltGr, Shift-AltGr, etc.)
+			 *  If we reported the Xkb 'level' here, the keycap strings would not get
+			 *  'shifted' in our compose keyboard when CapsLock is active, since the 
+			 *  capitalization in that case is deferred to the Xlib lookup stage.
+			 **/
+			if (key_type->preserve && (key_type->preserve[i].mask == LockMask))
+			{
+			    /* Lock is preserved for Xlib, but we want to report 'equivalent' level */
+			    if ((mods & LockMask) && !(mods & ShiftMask))
+			    {
+				int j;
+				/* find the map matching the 'Shift' equivalent */
+				guint equiv_mods = (mods & ~LockMask) | ShiftMask; 
+				for (j = 0; j < key_type->map_count; ++j)
+				{
+				    if (key_type->map[j].active && 
+					(key_type->map[j].mods.real_mods == equiv_mods)) 
+				    {
+					level = key_type->map[j].level;
+					level_set = TRUE;
+					break;
+				    }
+				}
+			    }
+			}
+
 			/* preserve what needs preserving */
 			if (key_type->preserve) 
 				*modmask = *modmask & key_type->preserve[i].mask;
@@ -226,41 +292,31 @@
 	return level;
 }
 
-static char *
-gok_key_label_from_keycode (KeyCode keycode, Display *display, unsigned int modmask, gint group)
+static gchar *
+gok_key_label_from_keycode (KeyCode keycode, Display *display, guint level, guint group)
 {
   char buf[20];
   int extra_rtn, nbytes, state = 0;
   KeySym keysym;
   XkbStateRec xkb_state;
-  int level;
-  int type;
   long ucs;
+  gunichar unichar;
 
-  if (modmask == GOK_MODMASK_CURRENT) {
-          XkbGetState (display, XkbUseCoreKbd, &xkb_state);
-          modmask = xkb_state.compat_state;
-  }
-  type =  gok_key_get_xkb_type_index (gok_keyboard_get_xkb_desc (), keycode, group);
-  level = gok_key_level_for_type (display, gok_keyboard_get_xkb_desc(), type, &modmask);
   keysym = XkbKeycodeToKeysym (display, keycode, group, level);
   if ((ucs = keysym2ucs (keysym)) <= 0) 
   {
       /* workaround; XSun gets nbytes wrong, so we truncate to the largest legal value */  
-      nbytes = MIN (XkbTranslateKeySym (display, &keysym, modmask, buf, 19, &extra_rtn), 19); 
-      if (nbytes && g_unichar_isgraph (g_utf8_get_char_validated (buf, nbytes))) {
-	  return g_strndup (buf, nbytes);
-      }
-      else {  /* try again, without modifiers...*/
-	  nbytes = MIN (XkbTranslateKeySym (display, &keysym, 0, buf, 19, &extra_rtn), 19);
-	  return gok_key_label_from_keysym_string (
-	      (nbytes && g_unichar_isgraph (g_utf8_get_char_validated (buf, nbytes))) ? buf : XKeysymToString (keysym));
-      }
+      nbytes = MIN (XkbTranslateKeySym (display, &keysym, 0, buf, 19, &extra_rtn), 19);
+      buf[nbytes] = '\0';
+      return gok_key_label_from_keysym_string (XKeysymToString (keysym));
   }
   else
   {
-      buf[g_unichar_to_utf8 (ucs, buf)] = '\0';
-      return gok_key_label_from_keysym_string (buf);
+      unichar = (gunichar) ucs;
+      gchar cbuf[10];
+      cbuf[g_unichar_to_utf8 (unichar, cbuf)] = '\0';
+
+      return gok_key_label_from_keysym_string (cbuf);
   }
 }
 
@@ -268,7 +324,7 @@
 gok_key_keycode_from_xkb_key (XkbKeyPtr keyp, XkbDescPtr kbd)
 {
   int k;
-  char *name = keyp->name.name;
+  gchar *name = keyp->name.name;
   if (kbd) {
     for (k = kbd->min_key_code; k < kbd->max_key_code; ++k) 
       {
@@ -317,7 +373,7 @@
 gchar *
 gok_key_modifier_for_keycode (Display *display, XkbDescPtr xkb, int keycode)
 {
-	gint group = gok_key_get_effective_group ();
+	guint group = gok_key_get_effective_group ();
 	gint type = gok_key_get_xkb_type_index (xkb, keycode, group);
 	guint modmask = 0;	
 	GokModifier *modifier;
@@ -375,21 +431,17 @@
 gok_key_from_xkb_key (GokKey *prevKey, GokKeyboard *pKeyboard, Display *display, XkbGeometryPtr pGeom, XkbRowPtr pRow, XkbSectionPtr pXkbSection, XkbKeyPtr keyp, int section, int row, int col)
 {
   GokKey *pKey;
-  char *label;
-  char name[XkbKeyNameLength + 1];
-  char keycode_name[8];
+  gchar *label;
+  gchar name[XkbKeyNameLength + 1];
+  gchar keycode_name[8];
   int keycode;
   XkbBoundsRec *pBounds;
   int width, height, len;
   gboolean is_modifier = FALSE;
   unsigned int numlock_mask;
-  guint modmask = SPI_KEYMASK_SHIFT | SPI_KEYMASK_SHIFTLOCK | SPI_KEYMASK_ALT | 
-	  SPI_KEYMASK_CONTROL | SPI_KEYMASK_MOD1 | SPI_KEYMASK_MOD2 | SPI_KEYMASK_MOD3 | SPI_KEYMASK_MOD4 |
-	  SPI_KEYMASK_MOD5; 
+  int group, level;
 
   pKey = gok_key_new (prevKey, NULL, pKeyboard);
-  numlock_mask = gok_key_get_numlock_mask (display);
-  modmask |= numlock_mask;
   is_modifier = FALSE;
   pKey->has_text = TRUE; /* TODO: handle non-textual keyboard key caps! */
   pKey->Top = row;
@@ -416,55 +468,33 @@
 	  pKey->is_repeatable = TRUE;
   }
   pKey->Style = KEYSTYLE_NORMAL;
-  label = gok_key_label_from_keycode (keycode, display, 0, 0);
+
   pKey->FontSize = -1;
-  len = g_utf8_strlen (label, -1);
-  if (len > 1) {
-          if (len < 4) 
-                  pKey->FontSizeGroup = 3;
-	  else
-	          pKey->FontSizeGroup = FONT_SIZE_GROUP_UNIQUE;  
-  }
-  else {
-          pKey->FontSizeGroup = FONT_SIZE_GROUP_GLYPH;
-  }
+
   /* TODO: figure out how to specify smaller modmasks */
-  gok_keylabel_new (pKey, label, 0, modmask);
-  label = gok_key_label_from_keycode (keycode, display, ShiftMask, 0);
-  gok_keylabel_new (pKey, label, ShiftMask, modmask);
-  label = gok_key_label_from_keycode (keycode, display, LockMask | ShiftMask, 0);
-  gok_keylabel_new (pKey, label, LockMask | ShiftMask, modmask);
-  label = gok_key_label_from_keycode (keycode, display, LockMask, 0);
-  gok_keylabel_new (pKey, label, LockMask, modmask);
-  label = gok_key_label_from_keycode (keycode, display, Mod1Mask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_ALT, modmask);
-  label = gok_key_label_from_keycode (keycode, display, ControlMask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_CONTROL, modmask);
-  label = gok_key_label_from_keycode (keycode, display, numlock_mask, 0);
-  gok_keylabel_new (pKey, label, numlock_mask, modmask);
-  label = gok_key_label_from_keycode (keycode, display, numlock_mask | ShiftMask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_SHIFT | numlock_mask, 
-		    modmask);
-  label = gok_key_label_from_keycode (keycode, display, numlock_mask | LockMask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_SHIFTLOCK | numlock_mask, 
-		    modmask);
-  label = gok_key_label_from_keycode (keycode, display, 
-				      numlock_mask | LockMask | ShiftMask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_SHIFTLOCK | SPI_KEYMASK_SHIFT | numlock_mask, 
-		    modmask);
-  label = gok_key_label_from_keycode (keycode, display, Mod3Mask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_MOD2, modmask);
-  label = gok_key_label_from_keycode (keycode, display, Mod3Mask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_MOD3, modmask);
-  label = gok_key_label_from_keycode (keycode, display, Mod4Mask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_MOD4, modmask);
-  label = gok_key_label_from_keycode (keycode, display, Mod5Mask, 0);
-  gok_keylabel_new (pKey, label, SPI_KEYMASK_MOD5, modmask);
-  /*  label = gok_key_label_from_keycode (keycode, display, 0, 1);
-  gok_keylabel_new (pKey, label, group1_mask, group1_mask);
-  label = gok_key_label_from_keycode (keycode, display, ShiftMask, 1);
-  gok_keylabel_new (pKey, label, "shift+group1");*/
-  g_free(label);
+  for (group = 0; group < 4; ++group) 
+  {
+	  for (level = 0; level < 4; ++level) 
+	  {
+		  /* this API is a little weird, gok_keylabel_new adds the label to the key */
+		  label = gok_key_label_from_keycode (keycode, display, level, group);
+		  if (!level && !group) /* bogus but we only have one group per key, not per label */
+		  {
+			  len = g_utf8_strlen (label, -1);
+			  if (len > 1) {
+				  if (len < 4) 
+					  pKey->FontSizeGroup = 3;
+				  else
+					  pKey->FontSizeGroup = FONT_SIZE_GROUP_UNIQUE;  
+			  }
+			  else {
+				  pKey->FontSizeGroup = FONT_SIZE_GROUP_GLYPH;
+			  }
+		  }
+		  gok_keylabel_new (pKey, label, level, group, NULL);
+	  }
+  }
+  /* XXX do we need to g_free (label)  ?? */
   snprintf (keycode_name, 8, "%d", keycode);
   pKey->pOutput = gok_output_new (OUTPUT_KEYCODE, keycode_name, SPI_KEY_PRESSRELEASE);
   return pKey;
@@ -649,6 +679,8 @@
 	gok_feedback_drop_refs (pKey);
 	gok_scanner_drop_refs (pKey);
 	gok_repeat_drop_refs (pKey);
+
+	g_free (pKey->pGeneral);
 }
 
 /**
@@ -660,7 +692,7 @@
 **/ 
 gboolean gok_key_initialize (GokKey* pKey, xmlNode* pNode)
 {
-	xmlChar* pStringAttributeValue;
+	xmlChar* pStringAttributeValue, *pStringSubAttributeValue;
 	xmlNode* pNodeKeyChild;
 	xmlNode* pNodeWrapperChild;
 	GokOutput* pNewOutput;
@@ -765,13 +797,13 @@
 		pKey->Type = KEYTYPE_DOCK;
 		pKey->Style = KEYSTYLE_DOCK;
 		pKey->pGeneral = g_new0 (GokKeyboardDirection, 1);
-		pStringAttributeValue = 
+		pStringSubAttributeValue = 
 			xmlGetProp (pNode, (const xmlChar *) "dir");
-		if (pStringAttributeValue != NULL) 
+		if (pStringSubAttributeValue != NULL) 
 		{
 			* (GokKeyboardDirection *) pKey->pGeneral = 
-				gok_keyboard_parse_direction (pStringAttributeValue);
-			g_free (pStringAttributeValue);
+				gok_keyboard_parse_direction (pStringSubAttributeValue);
+			g_free (pStringSubAttributeValue);
 		}
 	}
 	else if (xmlStrcmp (pStringAttributeValue, (const xmlChar *)"move-resize") == 0)
@@ -779,13 +811,13 @@
 		pKey->Type = KEYTYPE_MOVERESIZE;
 		pKey->Style = KEYSTYLE_NORMAL;
 		pKey->pGeneral = g_new0 (GokKeyboardDirection, 1);
-		pStringAttributeValue = 
+		pStringSubAttributeValue = 
 			xmlGetProp (pNode, (const xmlChar *) "dir");
-		if (pStringAttributeValue != NULL) 
+		if (pStringSubAttributeValue != NULL) 
 		{
 			* (GokKeyboardDirection *) pKey->pGeneral = 
-				gok_keyboard_parse_direction (pStringAttributeValue);
-			g_free (pStringAttributeValue);
+				gok_keyboard_parse_direction (pStringSubAttributeValue);
+			g_free (pStringSubAttributeValue);
 		}
 		pKey->is_repeatable = TRUE;
 	}
@@ -853,15 +885,17 @@
 			pKey->Style = KEYSTYLE_INSENSITIVE;
 		gok_mouse_control_init (pKey, pNode);
 	}
+	xmlFree (pStringAttributeValue);
 
 	/* branch target */
 	pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "target");
 	{
 		if (pStringAttributeValue != NULL)
 		{
-			pKey->Target = (char *) pStringAttributeValue;
+			pKey->Target = (char *) g_strdup (pStringAttributeValue);
 		}
 	}
+	xmlFree (pStringAttributeValue);
 
 	/* font size group*/
 	pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "fontsizegroup");
@@ -874,6 +908,7 @@
 		else
 			pKey->FontSizeGroup = atoi ((char *)pStringAttributeValue);
 	}
+	xmlFree (pStringAttributeValue);
 
 	/* location of key (top, bottom, left & right) */
 	pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "top");
@@ -886,6 +921,7 @@
 		gok_log_x ("Can't find 'top' attribute in gok_key_initialize!\n");
 		return FALSE;
 	}
+	xmlFree (pStringAttributeValue);
 
 	pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "bottom");
 	if (pStringAttributeValue != NULL)
@@ -897,6 +933,7 @@
 		gok_log_x ("Warning: Can't find 'bottom' attribute in gok_key_initialize!\n");
 		return FALSE;
 	}
+	xmlFree (pStringAttributeValue);
 
 	pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "left");
 	if (pStringAttributeValue != NULL)
@@ -908,6 +945,7 @@
 		gok_log_x ("Warning: Can't find 'left' attribute in gok_key_initialize!\n");
 		return FALSE;
 	}
+	xmlFree (pStringAttributeValue);
 
 	pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "right");
 	if (pStringAttributeValue != NULL)
@@ -919,29 +957,31 @@
 		gok_log_x ("Warning: Can't find 'right' attribute in gok_key_initialize!\n");
 		return FALSE;
 	}
+	xmlFree (pStringAttributeValue);
 
 	/* is this a 'modifier' key? */
 	pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "modifier");
 	if (pStringAttributeValue != NULL)
 	{
 		/* add the modifier to the list of modifiers */
-		gok_modifier_add ((char *)pStringAttributeValue);
+		gok_modifier_add ((char *)g_strdup (pStringAttributeValue));
 		
 		/* store the name of the modifier on the key */
 		pKey->ModifierName = (gchar*)g_malloc (strlen ((char *)pStringAttributeValue) + 1);
 		strcpy (pKey->ModifierName, (char *)pStringAttributeValue);
 
 		/* what type of modifier is this? */
-		pStringAttributeValue = xmlGetProp (pNode, (const xmlChar *) "modifiertype");
-		if (pStringAttributeValue != NULL)
+		pStringSubAttributeValue = xmlGetProp (pNode, (const xmlChar *) "modifiertype");
+		if (pStringSubAttributeValue != NULL)
 		{
-	
-if (strcmp ((char *)pStringAttributeValue, "toggle") == 0)
-			{
-				gok_modifier_set_type (pKey->ModifierName, MODIFIER_TYPE_TOGGLE);
-			}
+		    if (strcmp ((char *)pStringSubAttributeValue, "toggle") == 0)
+		    {
+			gok_modifier_set_type (pKey->ModifierName, MODIFIER_TYPE_TOGGLE);
+		    }
+		    xmlFree (pStringSubAttributeValue);
 		}
 	}
+	xmlFree (pStringAttributeValue);
 
 	/* get child elements of the key */
 	pNodeKeyChild = pNode->xmlChildrenNode;
@@ -950,22 +990,24 @@
 		/* key label */
 		if (xmlStrcmp (pNodeKeyChild->name, (const xmlChar *)"label") == 0)
 		{
-			guint modifier = 0;
-			gchar *modifier_list = (gchar *) xmlGetProp (pNodeKeyChild, (const xmlChar *) "modifier");
-			gchar **tokens;
-			if (modifier_list) 
-			{
-				gint i = 0;
-				tokens = g_strsplit (modifier_list, "+", 16);
-				while (tokens[i]) {
-					modifier |= gok_modifier_mask_for_name (gok_main_display (),
-										tokens[i]);
-					++i;
-				}
-				g_strfreev (tokens);
+			guint level = 0, group = 0;
+			gchar *levelname = (gchar *) xmlGetProp (pNodeKeyChild, (const xmlChar *) "level");
+			gchar *groupname = (gchar *) xmlGetProp (pNodeKeyChild, (const xmlChar *) "group");
+			gchar *vmodname = (gchar *) xmlGetProp (pNodeKeyChild, (const xmlChar *) "modifier");
+			gchar *content = xmlNodeGetContent (pNodeKeyChild);
+
+			if (levelname) 
+			{
+			    level = atoi ((char *) levelname);
 			}
-			gok_keylabel_new (pKey, g_strstrip (xmlNodeGetContent (pNodeKeyChild)),
-					  modifier, modmask);
+			if (groupname) 
+			{
+			    group = atoi ((char *) groupname);
+			}
+			
+			gok_keylabel_new (pKey, g_strstrip (content),
+					  level, group, vmodname);
+			g_free (content);
 			pKey->has_text = TRUE;
 		}
 
@@ -1069,7 +1111,7 @@
 *
 * returns: A pointer to the new key label, NULL if it wasn't created.
 **/
-GokKeyLabel* gok_keylabel_new (GokKey* pKey, gchar* pLabelText, guint modifiers, guint mod_mask)
+GokKeyLabel* gok_keylabel_new (GokKey* pKey, gchar* pLabelText, guint level, guint group, const gchar *vmods)
 {
 	GokKeyLabel* pNewLabel;
 	GokKeyLabel* pKeyLabel;
@@ -1078,14 +1120,15 @@
 	pNewLabel = (GokKeyLabel*) g_malloc(sizeof(GokKeyLabel));
 	
 	pNewLabel->Text = m_TextEmpty;
-	pNewLabel->modifiers = modifiers;
-	pNewLabel->mod_mask = mod_mask;
+	pNewLabel->level = level;
+	pNewLabel->group = group;
+	pNewLabel->vmods = g_strdup (vmods);
 	pNewLabel->pLabelNext = NULL;
 
 	if (pLabelText != NULL)
 	{
-		pNewLabel->Text = (gchar*)g_malloc (strlen(pLabelText) + 1);
-		strcpy (pNewLabel->Text, pLabelText);
+	        int len = strlen (pLabelText);
+		pNewLabel->Text = g_strdup (pLabelText);
 	}
 	
 	if (pKey != NULL)
@@ -1120,6 +1163,10 @@
 		{
 			g_free (pKeyLabel->Text);
 		}
+		if (pKeyLabel->vmods)
+		{
+			g_free (pKeyLabel->vmods);
+		}
 		g_free (pKeyLabel);
 	}
 }
@@ -1135,7 +1182,7 @@
 *
 * returns: TRUE if the key was initialized, FALSE if not.
 **/ 
-gboolean gok_key_add_label (GokKey* pKey, gchar* pLabelText, guint modifiers, guint mod_mask)
+gboolean gok_key_add_label (GokKey* pKey, gchar* pLabelText, guint level, guint group, const gchar *vmods)
 {
 	GokKeyLabel* pKeyLabel;
 		
@@ -1144,7 +1191,7 @@
 	
 	if (pKey->pLabel == NULL)
 	{
-		gok_keylabel_new (pKey, pLabelText, modifiers, mod_mask);
+		gok_keylabel_new (pKey, pLabelText, level, group, vmods);
 	}
 	else
 	{
@@ -1152,7 +1199,7 @@
 		pKeyLabel = pKey->pLabel;
 		while (pKeyLabel != NULL)
 		{
-			if ((pKeyLabel->modifiers == modifiers) && (pKeyLabel->mod_mask == mod_mask))
+			if ((pKeyLabel->level == level) && (pKeyLabel->group == group))
 			{
 				g_free (pKeyLabel->Text);
 				pKeyLabel->Text = (gchar*)g_malloc (strlen(pLabelText) + 1);
@@ -1165,7 +1212,7 @@
 		
 		if (pKeyLabel == NULL)
 		{
-			gok_keylabel_new (pKey, pLabelText, modifiers, mod_mask);
+			gok_keylabel_new (pKey, pLabelText, level, group, vmods);
 		}
 	}
 		
@@ -1184,7 +1231,7 @@
 	g_assert (pKey != NULL);
 	g_assert (LabelText != NULL);
 	
-	gok_key_add_label (pKey, LabelText, 0, 0);
+	gok_key_add_label (pKey, LabelText, 0, 0, NULL);
 	
 	/* change the label text */
 	gok_key_set_button_label (pKey, LabelText);
@@ -1275,6 +1322,12 @@
 	/* if the new text is different from the old text then change it */
 	if (strcmp (pNewLabelText, pOldLabelText) != 0)
 	{
+#ifdef GOK_UTF8_DEBUG	    
+	    if (!g_utf8_validate (pNewLabelText, -1, NULL))
+		fprintf (stderr, "INVALID UTF8 : %s\n", pNewLabelText);
+	    fprintf (stderr, "setting button label: %s", pNewLabelText);
+	    gok_key_print_utf8_debug (pNewLabelText);
+#endif
 		gtk_label_set_text (GTK_LABEL(pButtonLabel), pNewLabelText);
 	}
 
@@ -1405,14 +1458,34 @@
 **/
 gchar* gok_key_get_label (GokKey* pKey)
 {
-	/* FIXME: make this work properly with multi-group keyboards! */
 	gchar* pTextReturned;
 	gchar* pToken;
 	gchar buffer[150];
 	GokKeyLabel* pKeyLabel;
 	gboolean bFoundLabel;
+	int  type, keycode;
+	guint level;
+	guint group = gok_key_get_effective_group ();
 	guint mods = gok_spy_get_modmask ();
-	
+	XkbDescRec *xkb;
+
+	xkb = gok_keyboard_get_xkb_desc (),
+	keycode = gok_output_get_keycode (pKey->pOutput);
+	type = gok_key_get_xkb_type_index (xkb, keycode, group);
+
+#ifdef GOK_DEBUG
+	char *typename = XGetAtomName (gok_keyboard_get_display (), xkb->map->types[type].name);
+	fprintf (stderr, "keycode %d, group %d, type=%d [%s]\n", keycode, group, type, typename);
+#endif
+	level = gok_key_level_for_type (gok_keyboard_get_display (), 
+					xkb,
+					type, &mods);
+
+#ifdef GOK_DEBUG
+	if (pKey->pLabel) fprintf (stderr, "Key %s: type %d, level %d [mods %x, preserved %x]\n", 
+				pKey->pLabel->Text,
+				type, level, gok_spy_get_modmask (), mods);
+#endif
 	g_assert (pKey != NULL);
 	
 	pTextReturned = m_TextEmpty;
@@ -1421,7 +1494,7 @@
 	pKeyLabel = pKey->pLabel;
 	while (pKeyLabel != NULL)
 	{
-		if (pKeyLabel->modifiers == 0)
+		if ((pKeyLabel->level == 0) && (pKeyLabel->group == 0))
 		{
 			pTextReturned = pKeyLabel->Text;
 			break;
@@ -1437,26 +1510,15 @@
 		return pTextReturned;
 	}
 	
-	/* find the correct label text for the current modifiers */
-	/* look through all the labels for one that best matches the modifiers */
+	/* find the correct label text for the current level and group */
 	bFoundLabel = FALSE;
 	pKeyLabel = pKey->pLabel;
 	while (pKeyLabel != NULL)
 	{
-		if ((pKeyLabel->modifiers) == (mods & pKeyLabel->mod_mask)) 
+		if (pKeyLabel->level == level && pKeyLabel->group == group) 
 		{
 			return pKeyLabel->Text;
 		}
-		else if ((bFoundLabel == FALSE) &&
-				(pKeyLabel->modifiers != 0))
-		{
-			/* the first modifier state that matches will be used */
-			if (pKeyLabel->modifiers & mods & pKeyLabel->mod_mask)
-			{
-				pTextReturned = pKeyLabel->Text;
-				bFoundLabel = TRUE;
-			}
-		}
 		pKeyLabel = pKeyLabel->pLabelNext;
 	}
 	
Index: gok/gok-key.h
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-key.h,v
retrieving revision 1.53
diff -u -r1.53 gok-key.h
--- gok/gok-key.h	28 Jan 2004 13:34:41 -0000	1.53
+++ gok/gok-key.h	4 Feb 2004 15:53:04 -0000
@@ -134,8 +134,9 @@
 /* if you add data members to this structure, initialize them in gok_keylabel_new */
 typedef struct GokKeyLabel{
 	gchar* Text;
-        guint  modifiers;
-	guint  mod_mask;
+        guint  level;
+        guint  group;
+	gchar* vmods; /* currently unused; see bug # */
 	struct GokKeyLabel* pLabelNext;	
 } GokKeyLabel;
 
@@ -226,7 +227,7 @@
 } GokKey;
 
 gboolean gok_key_initialize (GokKey* pKey, xmlNode* pNode);
-gboolean gok_key_add_label (GokKey* pKey, gchar* pLabelText, guint modifiers, guint mod_mask);
+gboolean gok_key_add_label (GokKey* pKey, gchar* pLabelText, guint level, guint group, const gchar *vmods);
 void gok_key_set_output (GokKey* pKey, gint Type, gchar* pName, AccessibleKeySynthType Flag);
 void gok_key_add_output (GokKey* pKey, gint Type, gchar* pName, AccessibleKeySynthType Flag);
 void gok_key_change_label (GokKey* pKey, gchar* LabelText);
@@ -242,7 +243,7 @@
 GokKeyImage* gok_key_get_image (GokKey* pKey);
 gchar* gok_key_get_image_filename (GokKey* pKey);
 gchar* gok_key_get_label (GokKey* pKey);
-GokKeyLabel* gok_keylabel_new (GokKey* pKey, gchar* pLabelText, guint modifiers, guint mod_mask);
+GokKeyLabel* gok_keylabel_new (GokKey* pKey, gchar* pLabelText, guint level, guint group, const gchar *vmods);
 void gok_keylabel_delete (GokKeyLabel* pKeyLabel);
 void gok_key_update_toggle_state (GokKey *pKey);
 void gok_key_set_cells(GokKey* pKey, gint top, gint bottom, gint left, gint right);
Index: gok/gok-keyboard.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-keyboard.c,v
retrieving revision 1.125
diff -u -r1.125 gok-keyboard.c
--- gok/gok-keyboard.c	4 Feb 2004 13:35:14 -0000	1.125
+++ gok/gok-keyboard.c	4 Feb 2004 15:53:09 -0000
@@ -54,6 +54,8 @@
 #define NUM_INTERESTING_ROLES 5
 #define GOK_KEYBOARD_MAX_ROWS 24
 
+#define BUG_133323_LIVES
+
 /* TODO: i18n */
 #define CORE_KEYBOARD "Keyboard"
 /*#define ALPHA_KEYBOARD "Keyboard" testing hack */
@@ -210,8 +212,6 @@
 	if (event->any.xkb_type == XkbStateNotify) {
 		XkbStateNotifyEvent *sevent = &event->state;
 		if (sevent->changed & XkbGroupStateMask) {
-			fprintf (stderr, "Group changed to %d\n",
-				 sevent->group);
 			gok_key_set_effective_group (sevent->group);
 		}
 		else
@@ -469,7 +469,7 @@
 		pKey->Bottom = row + 2;
 		pKey->Left = 0;
 		pKey->Right = 3;
-		gok_key_add_label (pKey, _("Repeat Next Key"), 0, 0);
+		gok_key_add_label (pKey, _("Repeat Next Key"), 0, 0, NULL);
 		
 		/* add a branch key for special text edit functions */
 		pKey = gok_key_new (pKey, NULL, pKeyboard);
@@ -481,7 +481,7 @@
 		pKey->Bottom = row + 2;
 		pKey->Left = 3;
 		pKey->Right = rightmost;
-		gok_key_add_label (pKey, _("Text Manipulation"), 0, 0);
+		gok_key_add_label (pKey, _("Text Manipulation"), 0, 0, NULL);
 	}
 
 	return TRUE;
@@ -503,7 +503,7 @@
 		if (pKey->Type == KEYTYPE_WORDCOMPLETE)
 		{
 			gok_key_set_button_label (pKey, "");
-			gok_key_add_label (pKey, "", 0, 0);
+			gok_key_add_label (pKey, "", 0, 0, NULL);
 			gok_key_set_output (pKey, 0, NULL, 0);
 		}
 		pKey = pKey->pKeyNext;
@@ -572,27 +572,27 @@
 		pKey->FontSize = -1;
 		pKey->FontSizeGroup = FONT_SIZE_GROUP_GLYPH;
 		utf8_char [g_unichar_to_utf8 (g_utf8_get_char (level0_string), utf8_char)] = '\0';
-		gok_keylabel_new (pKey, utf8_char, 0, 0);
+		gok_keylabel_new (pKey, utf8_char, 0, 0, NULL);
 		pKey->pOutput = gok_output_new (OUTPUT_KEYSTRING, utf8_char, SPI_KEY_STRING);
 		/* FIXME: need this to work for other levels too! */
 		level0_string = g_utf8_find_next_char (level0_string, NULL);
 		if (*level1_string)
 		{
 			utf8_char [g_unichar_to_utf8 (g_utf8_get_char (level1_string), utf8_char)] = '\0';
-			gok_keylabel_new (pKey, utf8_char, SPI_KEYMASK_SHIFT, SPI_KEYMASK_SHIFT);
+			gok_keylabel_new (pKey, utf8_char, 1, 1, NULL);
 			level1_string = g_utf8_find_next_char (level1_string, NULL);
 		}
 		if (*level2_string)
 		{
 		  /* FIXME: get the appropriate modifiers and mod masks! */
 			utf8_char [g_unichar_to_utf8 (g_utf8_get_char (level2_string), utf8_char)] = '\0';
-			gok_keylabel_new (pKey, utf8_char, SPI_KEYMASK_MOD4, SPI_KEYMASK_MOD4);
+			gok_keylabel_new (pKey, utf8_char, 2, 2, NULL);
 			level2_string = g_utf8_find_next_char (level2_string, NULL);
 		}
 		if (*level3_string)
 		{
 			utf8_char [g_unichar_to_utf8 (g_utf8_get_char (level3_string), utf8_char)] = '\0';
-			gok_keylabel_new (pKey, utf8_char, SPI_KEYMASK_MOD5, SPI_KEYMASK_MOD5);
+			gok_keylabel_new (pKey, utf8_char, 3, 3, NULL);
 			level3_string = g_utf8_find_next_char (level3_string, NULL);
 		}
 	}
@@ -630,7 +630,7 @@
 		pKey->Bottom = 1;
 		pKey->Left = 0;
 		pKey->Right = 1;
-		gok_keylabel_new (pKey, _("Back"), 0, 0);
+		gok_keylabel_new (pKey, _("Back"), 0, 0, NULL);
 		if (acc_with_text && 
 		    (Accessible_getRole (acc_with_text) == SPI_ROLE_PASSWORD_TEXT))
 		{
@@ -649,7 +649,7 @@
 		pKey->Bottom = 1;
 		pKey->Left = 0;
 		pKey->Right = 1;
-		gok_keylabel_new (pKey, _("Menus"), 0, 0); 
+		gok_keylabel_new (pKey, _("Menus"), 0, 0, NULL); 
 	}
 		
 	return pKeyboard;
@@ -1129,7 +1129,8 @@
 	pGokKeyboardNew->bWordCompletionKeysAdded = FALSE;
 	pGokKeyboardNew->bCommandPredictionKeysAdded = FALSE;
 	pGokKeyboardNew->expand = GOK_EXPAND_SOMETIMES;
-	pGokKeyboardNew->pAccessible = NULL;	
+	pGokKeyboardNew->pAccessible = NULL;
+	pGokKeyboardNew->flags.value = 0;
 	
 	m_NumberOfKeyboards++;
 	
@@ -2178,7 +2179,7 @@
 	pKey->Left = 0;
 	pKey->Right = 1;
 	/* "back" means go to previous keyboard */
-	gok_key_add_label (pKey, _("back"), 0, 0);
+	gok_key_add_label (pKey, _("back"), 0, 0, NULL);
 
 	pKeyPrevious = pKey;
 		
@@ -2338,7 +2339,7 @@
 			pKey->accessible_node = pNodeAccessible;
 			
 			gok_log("adding label %s to dynamic key",pNodeAccessible->pname);
-			gok_key_add_label (pKey, pNodeAccessible->pname, 0, 0);
+			gok_key_add_label (pKey, pNodeAccessible->pname, 0, 0, NULL);
 			
 			column++;
 		}
@@ -2555,7 +2556,7 @@
 *
 * returns: TRUE if the keyboard was displayed, FALSE if not.
 **/
-static gboolean 
+gboolean 
 gok_keyboard_branch_gui_valuator (AccessibleNode* node)
 {
 	AccessibleValue* value;
@@ -3722,14 +3723,17 @@
 	/* compare the size of the window to the size we made the window */
 	gdk_window_get_size (pWindow->window, &widthWindow, &heightWindow);
 	gok_main_get_our_window_size (&widthWindowPrevious, &heightWindowPrevious);
-	
-	/* if the size has not changed then don't do anything */
+
+#ifndef BUG_133323_LIVES
+	/* FIXME: see bug 133323 - we need to forcibly resize to work around this */
+        /* if the size has not changed then don't do anything */
 	if ((widthWindow == widthWindowPrevious) &&
 		(heightWindow == heightWindowPrevious))
 	{
 		return;
 	}
-		
+#endif	
+	
 	/* change the key size */
 	widthKey = gok_keyboard_get_keywidth_for_window (widthWindow, pKeyboard);
 	if (widthKey < MIN_KEY_WIDTH)
@@ -3947,7 +3951,7 @@
 			if (pKey->Type == KEYTYPE_WORDCOMPLETE)
 			{
 				gok_key_set_button_label (pKey, list[i]);
-				gok_key_add_label (pKey, list[i], 0, 0);
+				gok_key_add_label (pKey, list[i], 0, 0, NULL);
 								
 				pKey = pKey->pKeyNext;
 				break;
Index: gok/gok-output.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-output.c,v
retrieving revision 1.22
diff -u -r1.22 gok-output.c
--- gok/gok-output.c	17 Nov 2003 17:35:00 -0000	1.22
+++ gok/gok-output.c	4 Feb 2004 15:53:10 -0000
@@ -105,13 +105,13 @@
 		Display *display;
 		if (gok_main_get_main_window ()) 
 		{
+		        long ucs;
 			display = GDK_WINDOW_XDISPLAY (gok_main_get_main_window ()->window);
-			/* hmm, how do we know XkbTranslateKeySym will use UTF-8 ? */
 			nbytes = MIN (XkbTranslateKeySym (display,
 							  &keysym, mods, buf, 19, &extra_rtn), 19); 
-			if (nbytes) {
-			  fprintf (stderr, "unichar is [%s]\n", buf);
-				return g_utf8_get_char_validated (buf, nbytes);
+			if ((ucs = keysym2ucs (keysym)) > 0) 
+			{
+			    return (gunichar) ucs;
 			}
 		}
 		return 0;
@@ -344,6 +344,21 @@
 	gok_log_leave();
 }
 
+/**
+ *
+ * Returns keycode for OUTPUT_KEYCODE keys, or -1.
+ **/
+int 
+gok_output_get_keycode (GokOutput *output)
+{
+    int keycode = -1;
+    if (output && output->Type == OUTPUT_KEYCODE)
+	keycode = atoi (output->Name);
+
+    return keycode;
+}
+
+
 void
 gok_output_internal (gchar* action)
 {
Index: gok/gok-output.h
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-output.h,v
retrieving revision 1.7
diff -u -r1.7 gok-output.h
--- gok/gok-output.h	17 Jul 2003 20:20:25 -0000	1.7
+++ gok/gok-output.h	4 Feb 2004 15:53:10 -0000
@@ -51,6 +51,7 @@
 GokOutput* gok_output_new (gint Type, gchar* Name, AccessibleKeySynthType Flag);
 GokOutput* gok_output_new_from_xml (xmlNode* pNode);
 void gok_output_send_to_system (GokOutput* pOutput, gboolean bNoWordCompletion);
+int gok_output_get_keycode (GokOutput* output);
 void gok_output_internal (gchar* action);
 
 #ifdef __cplusplus
Index: gok/gok-predictor.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-predictor.c,v
retrieving revision 1.7
diff -u -r1.7 gok-predictor.c
--- gok/gok-predictor.c	4 Nov 2003 13:40:12 -0000	1.7
+++ gok/gok-predictor.c	4 Feb 2004 15:53:11 -0000
@@ -271,7 +271,7 @@
 					gok_key_set_button_name(pKey); /* update style info */
 					/*gtk_widget_set_style(pKey->pButton, pKey->Style);*/
 					gok_key_set_button_label (pKey, keyID);
-					gok_key_add_label (pKey, keyID, 0, 0);
+					gok_key_add_label (pKey, keyID, 0, 0, NULL);
 									
 					pKey = pKey->pKeyNext;
 					pRealKey = NULL;
Index: gok/gok-spy.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-spy.c,v
retrieving revision 1.113
diff -u -r1.113 gok-spy.c
--- gok/gok-spy.c	4 Feb 2004 14:42:47 -0000	1.113
+++ gok/gok-spy.c	4 Feb 2004 15:53:13 -0000
@@ -134,12 +134,14 @@
 static gulong keyboardmods;
 static gboolean spyshutdown = FALSE;/* this global could be removed if we have a
 						way of removing our idle handler in gok_spy_stop */
+
+#define MAX_CHILD_COUNT 100
+
 /* 
  * for debugging
  */
 void gok_spy_accessible_ref(Accessible* accessible)
 {
-#if defined(ENABLE_LOGGING_NORMAL)
 	char *s;
 
 	gok_log_enter ();
@@ -148,6 +150,7 @@
 	{
 		explicitrefs++;
 		Accessible_ref (accessible);
+#if defined(ENABLE_LOGGING_NORMAL)
 		s = Accessible_getName (accessible);
 		if (s == NULL)
 		{
@@ -158,6 +161,7 @@
 			gok_log ("%#x %s", accessible, s);
 			SPI_freeString (s);
 		}
+#endif
 	}
 	else
 	{
@@ -165,11 +169,10 @@
 	}
 
 	gok_log_leave ();
-#endif
 }
+
 void gok_spy_accessible_implicit_ref(Accessible* accessible)
 {
-#if defined(ENABLE_LOGGING_NORMAL)
 	char *s;
 
 	gok_log_enter ();
@@ -177,6 +180,7 @@
 	if (accessible != NULL)
 	{
 		implicitrefs++;
+#if defined(ENABLE_LOGGING_NORMAL)
 		s = Accessible_getName (accessible);
 		if (s == NULL)
 		{
@@ -187,6 +191,7 @@
 			gok_log ("%#x %s", accessible, s);
 			SPI_freeString (s);
 		}
+#endif
 	}
 	else
 	{
@@ -194,17 +199,17 @@
 	}
 
 	gok_log_leave ();
-#endif
 }
+
 void gok_spy_accessible_unref(Accessible* accessible)
 {
-#if defined(ENABLE_LOGGING_NORMAL)
 	char *s;
 
 	gok_log_enter ();
 
 	if (accessible != NULL)
 	{
+#if defined(ENABLE_LOGGING_NORMAL)
 		s = Accessible_getName (accessible);
 		if (s == NULL)
 		{
@@ -215,6 +220,7 @@
 			gok_log ("%#x %s", accessible, s);
 			SPI_freeString (s);
 		}
+#endif
 		explicitunrefs++;
 		Accessible_unref (accessible);
 	}
@@ -224,7 +230,6 @@
 	}
 
 	gok_log_leave ();
-#endif
 }
 
 gboolean gok_spy_accessible_is_okay(Accessible* accessible)
@@ -894,15 +899,15 @@
 		{
 			gchar *name = Accessible_getName (accessible);
 			gchar *role_name = Accessible_getRoleName (accessible);
-			/* TODO: determine whether we can safely bypass manages-descendants objects */
-			/* it's not safe to exhaustviely search them */
-			if (AccessibleStateSet_contains( ass, SPI_STATE_MANAGES_DESCENDANTS ))
-			{
-				gok_log_x ("Manages-descandants state found on %s [%s]", name, role_name);
-			}
 			gok_log ("%s %s is not worth searching", role_name, name);
 			worthiness = FALSE;
 		}
+		/* TODO: determine whether we can safely bypass manages-descendants objects */
+		/* it's not safe to exhaustviely search them */
+		if (AccessibleStateSet_contains( ass, SPI_STATE_MANAGES_DESCENDANTS ))
+		{
+			gok_log_x ("Manages-descendants state found on %s [%s]", name, role_name);
+		}
 		AccessibleStateSet_unref(ass);
 	}
 	gok_log_leave();
@@ -1827,7 +1832,8 @@
 	}	
 	parent_role = Accessible_getRole (parent);
 	child_count = Accessible_getChildCount (parent);
-	for (i = 0; i < child_count; ++i)
+	/* MAX_CHILD_COUNT is a bit of a kludge and will cause certain table items to be unreachable via UI Grab */
+	for (i = 0; i < child_count && i < MAX_CHILD_COUNT; ++i)
 	{
 		AccessibleNodeFlags flags;
 		flags.value = 0;
Index: gok/gok-windowlister.c
===================================================================
RCS file: /cvs/gnome/gok/gok/gok-windowlister.c,v
retrieving revision 1.7
diff -u -r1.7 gok-windowlister.c
--- gok/gok-windowlister.c	4 Nov 2003 13:40:12 -0000	1.7
+++ gok/gok-windowlister.c	4 Feb 2004 15:53:14 -0000
@@ -56,6 +56,7 @@
 	GokKey* pKey;
 	GokKey* pKeyPrevious;
 	int column;
+	gchar *window_name = NULL;
     GList *window_list_entry;
 
 /*    GType window_type; */
@@ -126,7 +127,7 @@
 	pKey->Bottom = 1;
 	pKey->Left = 0;
 	pKey->Right = 1;
-	gok_key_add_label (pKey, _("back"), 0, 0);
+	gok_key_add_label (pKey, _("back"), 0, 0, NULL);
 	pKeyPrevious = pKey;
 
 	/* build window keys */
@@ -148,8 +149,9 @@
 			pKey->Bottom = 1;
 			pKey->Left = column;
 			pKey->Right = column + 1;
-			
-			gok_key_add_label (pKey, (char*)(wnck_window_get_name (window_list_entry->data)), 0, 0);
+			window_name = wnck_window_get_name (window_list_entry->data);
+			if (!window_name) window_name = g_strdup ("");
+			gok_key_add_label (pKey, window_name, 0, 0, NULL);
 			
 			pKey->pGeneral = window_list_entry->data;  
 	
Index: gok/keysym2ucs.c
===================================================================
RCS file: /cvs/gnome/gok/gok/keysym2ucs.c,v
retrieving revision 1.1
diff -u -r1.1 keysym2ucs.c
--- gok/keysym2ucs.c	8 Dec 2003 14:43:43 -0000	1.1
+++ gok/keysym2ucs.c	4 Feb 2004 15:53:17 -0000
@@ -38,7 +38,7 @@
 
 struct codepair {
   unsigned short keysym;
-  unsigned short ucs;
+  unsigned long ucs;
 } keysymtab[] = {
   { 0x01a1, 0x0104 }, /*                     Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */
   { 0x01a2, 0x02d8 }, /*                       breve ˘ BREVE */
@@ -824,7 +824,7 @@
     /* first check for Latin-1 characters (1:1 mapping) */
     if ((keysym >= 0x0020 && keysym <= 0x007e) ||
         (keysym >= 0x00a0 && keysym <= 0x00ff))
-        return keysym;
+        return (long) keysym;
 
     /* also check for directly encoded 24-bit UCS characters */
     if ((keysym & 0xff000000) == 0x01000000)
