]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkimcontextsimple.c
ri Jun 14 10:00:29 2002 Owen Taylor <otaylor@redhat.com>
[~andy/gtk] / gtk / gtkimcontextsimple.c
index 0f3304ac483b6556393ad81df20fcb0f9d4f902d..99ea9d456805fcd47b6501ef618897e7ff331d74 100644 (file)
@@ -38,7 +38,7 @@ struct _GtkComposeTable
  * to obtain the relevant perl scripts.
  *
  * The following compose letter letter sequences confliced
- *   Dstroke/dstroke and ETH/eth; resolved to Dstroke (Croation, Vietnamese, Lappish), over 
+*   Dstroke/dstroke and ETH/eth; resolved to Dstroke (Croation, Vietnamese, Lappish), over 
  *                                ETH (Icelandic, Faroese, old English, IPA)   [ D- -D d- -d ]
  *   Amacron/amacron and ordfeminine; resolved to ordfeminine                  [ _A A_ a_ _a ]
  *   Amacron/amacron and Atilde/atilde; resolved to atilde                   [ -A A- a- -a ]
@@ -71,12 +71,14 @@ static guint16 gtk_compose_seqs[] = {
   GDK_dead_acute,      GDK_space,      0,      0,      0,      0x0027, /* APOSTROPHE */
   GDK_dead_acute,      GDK_apostrophe, 0,      0,      0,      0x00B4, /* ACUTE_ACCENT */
   GDK_dead_acute,      GDK_A,  0,      0,      0,      0x00C1, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
+  GDK_dead_acute,      GDK_C,  0,      0,      0,      0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
   GDK_dead_acute,      GDK_E,  0,      0,      0,      0x00C9, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
   GDK_dead_acute,      GDK_I,  0,      0,      0,      0x00CD, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
   GDK_dead_acute,      GDK_O,  0,      0,      0,      0x00D3, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
   GDK_dead_acute,      GDK_U,  0,      0,      0,      0x00DA, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
   GDK_dead_acute,      GDK_Y,  0,      0,      0,      0x00DD, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
   GDK_dead_acute,      GDK_a,  0,      0,      0,      0x00E1, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
+  GDK_dead_acute,      GDK_c,  0,      0,      0,      0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
   GDK_dead_acute,      GDK_e,  0,      0,      0,      0x00E9, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
   GDK_dead_acute,      GDK_i,  0,      0,      0,      0x00ED, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
   GDK_dead_acute,      GDK_o,  0,      0,      0,      0x00F3, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
@@ -817,6 +819,13 @@ gtk_im_context_simple_finalize (GObject *obj)
   parent_class->finalize (obj);
 }
 
+/** 
+ * gtk_im_context_simple_new:
+ * 
+ * Creates a new #GtkIMContextSimple.
+ *
+ * Returns: a new #GtkIMContextSimple.
+ **/
 GtkIMContext *
 gtk_im_context_simple_new (void)
 {
@@ -1034,7 +1043,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
       context_simple->compose_buffer[0] = 0;
       if (n_compose > 1)               /* Invalid sequence */
        {
-         gdk_beep();
+         gdk_display_beep (gdk_drawable_get_display (event->window));
          return TRUE;
        }
   
@@ -1060,6 +1069,7 @@ is_hex_keyval (guint keyval)
 static guint
 canonical_hex_keyval (GdkEventKey *event)
 {
+  GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_drawable_get_display (event->window));
   guint keyval;
   guint *keyvals = NULL;
   gint n_vals = 0;
@@ -1072,9 +1082,10 @@ canonical_hex_keyval (GdkEventKey *event)
   /* See if this key would have generated a hex keyval in
    * any other state, and return that hex keyval if so
    */
-  gdk_keymap_get_entries_for_keycode (NULL,
-                                      event->hardware_keycode, NULL,
-                                      &keyvals, &n_vals);
+  gdk_keymap_get_entries_for_keycode (keymap,
+                                     event->hardware_keycode,
+                                     NULL,
+                                     &keyvals, &n_vals);
 
   keyval = 0;
   i = 0;
@@ -1094,10 +1105,9 @@ canonical_hex_keyval (GdkEventKey *event)
   if (keyval)
     return keyval;
   else
-    /* just return the keyval unchanged, we couldn't figure
-     * out a way to make it a hex digit
+    /* No way to make it a hex digit
      */
-    return event->keyval;
+    return 0;
 }
 
 static gboolean
@@ -1107,42 +1117,61 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
   GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
   GSList *tmp_list;  
   int n_compose = 0;
+  gboolean have_hex_mods;
+  guint hex_keyval;
   int i;
 
-  /* FIXME? 14755 says you have to commit the char on release of the shift/control
-   * keys. But instead we wait for the user to type another char, or to lose focus.
-   */
-  
+  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)
+           {
+             gtk_im_context_simple_commit_char (context, context_simple->tentative_match);
+             context_simple->compose_buffer[0] = 0;
+           }
+         else
+           context_simple->in_hex_sequence = 0;
+
+         return TRUE;
+       }
+      else
+       return FALSE;
+    }
+
   /* Ignore modifier key presses
    */
   for (i=0; i < G_N_ELEMENTS (gtk_compose_ignore); i++)
     if (event->keyval == gtk_compose_ignore[i])
       return FALSE;
 
+  have_hex_mods = (event->state & (ISO_14755_MOD_MASK)) == ISO_14755_MOD_MASK;
+  hex_keyval = canonical_hex_keyval (event);
+
   while (context_simple->compose_buffer[n_compose] != 0)
     n_compose++;
 
-  /* First key in sequence; decide if it's a 14755 hex sequence */
-  if (n_compose == 0)
-    context_simple->in_hex_sequence =
-      ((event->state & (ISO_14755_MOD_MASK)) == ISO_14755_MOD_MASK);
-  
   /* If we are already in a non-hex sequence, or
-   * the 14755 modifiers are not held down, filter all
+   * this keystroke is not 14755 modifiers + hex digit, don't filter 
    * key events with accelerator modifiers held down.
    */
-  if (!context_simple->in_hex_sequence ||
-      ((event->state & (ISO_14755_MOD_MASK)) != ISO_14755_MOD_MASK))
+  if ((n_compose > 0 && !context_simple->in_hex_sequence) || !have_hex_mods || !hex_keyval)
     {
       if (event->state &
           (gtk_accelerator_get_default_mod_mask () & ~GDK_SHIFT_MASK))
         return FALSE;
     }
   
+  /* First key in sequence; decide if it's a 14755 hex sequence */
+  if (n_compose == 0)
+    context_simple->in_hex_sequence = have_hex_mods;
+  
   /* Then, check for compose sequences
    */
   if (context_simple->in_hex_sequence)
-    context_simple->compose_buffer[n_compose++] = canonical_hex_keyval (event);
+    context_simple->compose_buffer[n_compose++] = hex_keyval ? hex_keyval : event->keyval;
   else
     context_simple->compose_buffer[n_compose++] = event->keyval;
 
@@ -1151,7 +1180,7 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
   if (context_simple->in_hex_sequence)
     {
       /* If the modifiers are still held down, consider the sequence again */
-      if ((event->state & (ISO_14755_MOD_MASK)) == ISO_14755_MOD_MASK)
+      if (have_hex_mods)
         {
           /* space ends the sequence, and we eat the space */
           if (n_compose > 1 &&
@@ -1203,7 +1232,7 @@ gtk_im_context_simple_get_preedit_string (GtkIMContext   *context,
                                          PangoAttrList **attrs,
                                          gint           *cursor_pos)
 {
-  char outbuf[25]; /* up to 4 hex digits */
+  char outbuf[37]; /* up to 6 hex digits */
   int len = 0;
   
   GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
@@ -1259,17 +1288,17 @@ gtk_im_context_simple_get_preedit_string (GtkIMContext   *context,
  * @context_simple: A #GtkIMContextSimple
  * @data: the table 
  * @max_seq_len: Maximum length of a sequence in the table
- *               (cannot be greater than 7)
+ *               (cannot be greater than #GTK_MAX_COMPOSE_LEN)
  * @n_seqs: number of sequences in the table
  * 
- * Add an additional table to search to the input context.
- * Each row of the table consists of max_seq_len key symbols
- * followed by two guint16 interpreted as the high and low
- * words of a gunicode value. Tables are searched starting
+ * Adds an additional table to search to the input context.
+ * Each row of the table consists of @max_seq_len key symbols
+ * followed by two #guint16 interpreted as the high and low
+ * words of a #gunicode value. Tables are searched starting
  * from the last added.
  *
  * The table must be sorted in dictionary order on the
- * by numeric value of the key symbol fields. (Values beyond
+ * numeric value of the key symbol fields. (Values beyond
  * the length of the sequence should be zero.)
  **/
 void