Index: gtk/gtkimcontextsimple.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimcontextsimple.c,v
retrieving revision 1.48
diff -u -r1.48 gtkimcontextsimple.c
--- gtk/gtkimcontextsimple.c	1 Sep 2005 05:11:41 -0000	1.48
+++ gtk/gtkimcontextsimple.c	1 Sep 2005 20:41:43 -0000
@@ -1142,6 +1142,7 @@
  */
 
 #define ISO_14755_MOD_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK)
+#define HEX_START GDK_U
 
 static gboolean
 check_hex (GtkIMContextSimple *context_simple,
@@ -1153,7 +1154,13 @@
   gulong n;
   gchar *nptr = NULL;
   gchar buf[7];
-  
+
+  if (n_compose > 6)
+    {
+      context_simple->tentative_match = 0;
+      return FALSE;
+    }
+
   str = g_string_new (NULL);
   
   i = 0;
@@ -1189,10 +1196,6 @@
   else
     g_string_free (str, TRUE);
 
-  /* don't allow invalid Unicode or nul bytes */
-  if (n == 0 || !g_unichar_validate (n))
-    return FALSE;
-  
   context_simple->tentative_match = n;
   context_simple->tentative_match_len = n_compose;
   
@@ -1313,24 +1316,41 @@
   GSList *tmp_list;  
   int n_compose = 0;
   gboolean have_hex_mods;
+  gboolean is_hex_start;
+  gboolean is_space;
   guint hex_keyval;
   int i;
 
+  while (context_simple->compose_buffer[n_compose] != 0)
+    n_compose++;
+
   if (event->type == GDK_KEY_RELEASE)
     {
       if (context_simple->in_hex_sequence &&
 	  (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R ||
 	   event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R))
 	{
-	  if (context_simple->tentative_match)
+	  if (context_simple->tentative_match &&
+	      g_unichar_validate (context_simple->tentative_match))
 	    {
 	      gtk_im_context_simple_commit_char (context, context_simple->tentative_match);
 	      context_simple->compose_buffer[0] = 0;
+
+	      return TRUE;
 	    }
 	  else
-	    context_simple->in_hex_sequence = 0;
+	    {
+	      if (n_compose > 1)		/* Invalid sequence */
+		gdk_display_beep (gdk_drawable_get_display (event->window));
 
-	  return TRUE;
+	      context_simple->tentative_match = 0;
+	      context_simple->in_hex_sequence = 0;
+	      context_simple->compose_buffer[0] = 0;
+
+	      g_signal_emit_by_name (context_simple, "preedit_changed");
+
+	      return TRUE;
+	    }
 	}
       else
 	return FALSE;
@@ -1343,16 +1363,18 @@
       return FALSE;
 
   have_hex_mods = (event->state & (ISO_14755_MOD_MASK)) == ISO_14755_MOD_MASK;
+  is_hex_start = event->keyval == HEX_START;
+  is_space = event->keyval == GDK_space || event->keyval == GDK_KP_Space;
   hex_keyval = canonical_hex_keyval (event);
 
-  while (context_simple->compose_buffer[n_compose] != 0)
-    n_compose++;
-
   /* If we are already in a non-hex sequence, or
    * this keystroke is not 14755 modifiers + hex digit, don't filter 
    * key events with accelerator modifiers held down.
    */
-  if ((n_compose > 0 && !context_simple->in_hex_sequence) || !have_hex_mods || !hex_keyval)
+  if (!have_hex_mods ||
+      (n_compose > 0 && !context_simple->in_hex_sequence) || 
+      (n_compose == 0 && !context_simple->in_hex_sequence && !is_hex_start) ||
+      (n_compose > 0 && context_simple->in_hex_sequence && !hex_keyval && !is_space))
     {
       if (event->state &
           (gtk_accelerator_get_default_mod_mask () & ~GDK_SHIFT_MASK))
@@ -1360,8 +1382,16 @@
     }
   
   /* First key in sequence; decide if it's a 14755 hex sequence */
-  if (n_compose == 0)
-    context_simple->in_hex_sequence = have_hex_mods;
+  if (n_compose == 0 && !context_simple->in_hex_sequence && have_hex_mods && is_hex_start)
+    {
+      context_simple->compose_buffer[0] = 0;
+      context_simple->in_hex_sequence = TRUE;
+      context_simple->tentative_match = 0;
+
+      g_signal_emit_by_name (context_simple, "preedit_changed");
+  
+      return TRUE;
+    }
   
   /* Then, check for compose sequences
    */
@@ -1378,12 +1408,17 @@
       if (have_hex_mods)
         {
           /* space ends the sequence, and we eat the space */
-          if (n_compose > 1 &&
-              (event->keyval == GDK_space ||
-               event->keyval == GDK_KP_Space))
+          if (n_compose > 0 && is_space)
             {
-              gtk_im_context_simple_commit_char (context, context_simple->tentative_match);
-              context_simple->compose_buffer[0] = 0;
+	      if (g_unichar_validate (context_simple->tentative_match))
+		gtk_im_context_simple_commit_char (context, context_simple->tentative_match);
+
+	      context_simple->tentative_match = 0;
+	      context_simple->in_hex_sequence = 0;
+	      context_simple->compose_buffer[0] = 0;
+
+	      g_signal_emit_by_name (context_simple, "preedit_changed");
+
               return TRUE;
             }
           else if (check_hex (context_simple, n_compose))
@@ -1432,10 +1467,13 @@
   
   GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
 
-  if (context_simple->tentative_match)
+  if (context_simple->in_hex_sequence)
     {
-      if (context_simple->in_hex_sequence)
-        {
+      len += g_unichar_to_utf8 (g_unichar_tolower (gdk_keyval_to_unicode (HEX_START)),
+				outbuf + len);
+
+      if (context_simple->tentative_match)
+	{
           int hexchars = 0;
           
           while (context_simple->compose_buffer[hexchars] != 0)
@@ -1445,19 +1483,19 @@
               ++hexchars;
             }
         }
-      else
-        {
-          len = g_unichar_to_utf8 (context_simple->tentative_match, outbuf);
-        }
-      
+
       g_assert (len < 25);
       outbuf[len] = '\0';      
     }
+  else if (context_simple->tentative_match)
+    {
+      len = g_unichar_to_utf8 (context_simple->tentative_match, outbuf);
+    }
   else
     {
       outbuf[0] = '\0';
     }
-  
+      
   if (str)
     *str = g_strdup (outbuf);
 
@@ -1475,7 +1513,7 @@
     }
 
   if (cursor_pos)
-    *cursor_pos = (context_simple->tentative_match ? len : 0);
+    *cursor_pos = len;
 }
 
 /**
