]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkimcontextsimple.c
filechooserbutton: whitespace fixes
[~andy/gtk] / gtk / gtkimcontextsimple.c
index ebbbd08d6bce01513e35b14aa189b1e3231a16bd..87debf226b9baaaeb4f3c3729aa6b25b79933e0b 100644 (file)
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
+
 #include <stdlib.h>
 #include <string.h>
 
-#include <gdk/gdkkeysyms-compat.h>
 #include "gtkprivate.h"
 #include "gtkaccelgroup.h"
 #include "gtkimcontextsimple.h"
 #include "gtksettings.h"
 #include "gtkwidget.h"
+#include "gtkdebug.h"
 #include "gtkintl.h"
 
 
@@ -67,14 +66,14 @@ struct _GtkComposeTableCompact
   gint n_index_stride;
 };
 
-/* This file contains the table of the compose sequences, 
+/* This file contains the table of the compose sequences,
  * static const guint16 gtk_compose_seqs_compact[] = {}
- * IT is generated from the compose-parse.py script.
+ * It is generated from the compose-parse.py script.
  */
 #include "gtkimcontextsimpleseqs.h"
 
-/* From the values below, the value 23 means the number of different first keysyms 
- * that exist in the Compose file (from Xorg). When running compose-parse.py without 
+/* From the values below, the value 24 means the number of different first keysyms
+ * that exist in the Compose file (from Xorg). When running compose-parse.py without
  * parameters, you get the count that you can put here. Needed when updating the
  * gtkimcontextsimpleseqs.h header file (contains the compose sequences).
  */
@@ -86,22 +85,22 @@ static const GtkComposeTableCompact gtk_compose_table_compact = {
 };
 
 static const guint16 gtk_compose_ignore[] = {
-  GDK_Shift_L,
-  GDK_Shift_R,
-  GDK_Control_L,
-  GDK_Control_R,
-  GDK_Caps_Lock,
-  GDK_Shift_Lock,
-  GDK_Meta_L,
-  GDK_Meta_R,
-  GDK_Alt_L,
-  GDK_Alt_R,
-  GDK_Super_L,
-  GDK_Super_R,
-  GDK_Hyper_L,
-  GDK_Hyper_R,
-  GDK_Mode_switch,
-  GDK_ISO_Level3_Shift
+  GDK_KEY_Shift_L,
+  GDK_KEY_Shift_R,
+  GDK_KEY_Control_L,
+  GDK_KEY_Control_R,
+  GDK_KEY_Caps_Lock,
+  GDK_KEY_Shift_Lock,
+  GDK_KEY_Meta_L,
+  GDK_KEY_Meta_R,
+  GDK_KEY_Alt_L,
+  GDK_KEY_Alt_R,
+  GDK_KEY_Super_L,
+  GDK_KEY_Super_R,
+  GDK_KEY_Hyper_L,
+  GDK_KEY_Hyper_R,
+  GDK_KEY_Mode_switch,
+  GDK_KEY_ISO_Level3_Shift
 };
 
 static void     gtk_im_context_simple_finalize           (GObject                  *obj);
@@ -154,7 +153,7 @@ gtk_im_context_simple_finalize (GObject *obj)
   G_OBJECT_CLASS (gtk_im_context_simple_parent_class)->finalize (obj);
 }
 
-/** 
+/**
  * gtk_im_context_simple_new:
  * 
  * Creates a new #GtkIMContextSimple.
@@ -252,7 +251,7 @@ check_table (GtkIMContextSimple    *context_simple,
       guint16 *prev_seq;
 
       /* Back up to the first sequence that matches to make sure
-       * we find the exact match if their is one.
+       * we find the exact match if there is one.
        */
       while (seq > table->data)
        {
@@ -269,7 +268,6 @@ check_table (GtkIMContextSimple    *context_simple,
          gunichar value = 
            0x10000 * seq[table->max_seq_len] + seq[table->max_seq_len + 1];
 
-         
          /* We found a tentative match. See if there are any longer
           * sequences containing this subsequence
           */
@@ -280,7 +278,7 @@ check_table (GtkIMContextSimple    *context_simple,
                {
                  priv->tentative_match = value;
                  priv->tentative_match_len = n_compose;
-               
+
                  g_signal_emit_by_name (context_simple, "preedit-changed");
 
                  return TRUE;
@@ -298,14 +296,14 @@ check_table (GtkIMContextSimple    *context_simple,
 }
 
 /* Checks if a keysym is a dead key. Dead key keysym values are defined in
- * ../gdk/gdkkeysyms.h and the first is GDK_dead_grave. As X.Org is updated,
+ * ../gdk/gdkkeysyms.h and the first is GDK_KEY_dead_grave. As X.Org is updated,
  * more dead keys are added and we need to update the upper limit.
- * Currently, the upper limit is GDK_dead_dasia+1. The +1 has to do with 
- * a temporary issue in the X.Org header files. 
+ * Currently, the upper limit is GDK_KEY_dead_dasia+1. The +1 has to do with
+ * a temporary issue in the X.Org header files.
  * In future versions it will be just the keysym (no +1).
  */
 #define IS_DEAD_KEY(k) \
-    ((k) >= GDK_dead_grave && (k) <= (GDK_dead_dasia+1))
+    ((k) >= GDK_KEY_dead_grave && (k) <= (GDK_KEY_dead_dasia+1))
 
 #ifdef GDK_WINDOWING_WIN32
 
@@ -322,15 +320,15 @@ check_win32_special_cases (GtkIMContextSimple    *context_simple,
 {
   GtkIMContextSimplePrivate *priv = context_simple->priv;
   if (n_compose == 2 &&
-      priv->compose_buffer[1] == GDK_space)
+      priv->compose_buffer[1] == GDK_KEY_space)
     {
       gunichar value = 0;
 
       switch (priv->compose_buffer[0])
        {
-       case GDK_dead_acute:
+       case GDK_KEY_dead_acute:
          value = 0x00B4; break;
-       case GDK_dead_diaeresis:
+       case GDK_KEY_dead_diaeresis:
          value = 0x00A8; break;
        }
       if (value > 0)
@@ -366,27 +364,91 @@ check_win32_special_case_after_compact_match (GtkIMContextSimple    *context_sim
 
 #endif
 
+#ifdef GDK_WINDOWING_QUARTZ
+
 static gboolean
-check_compact_table (GtkIMContextSimple    *context_simple,
-            const GtkComposeTableCompact *table,
-            gint                   n_compose)
+check_quartz_special_cases (GtkIMContextSimple *context_simple,
+                            gint                n_compose)
+{
+  GtkIMContextSimplePrivate *priv = context_simple->priv;
+  guint value = 0;
+
+  if (n_compose == 2)
+    {
+      switch (priv->compose_buffer[0])
+        {
+        case GDK_KEY_dead_doubleacute:
+          switch (priv->compose_buffer[1])
+            {
+            case GDK_KEY_dead_doubleacute:
+            case GDK_KEY_space:
+              value = GDK_KEY_quotedbl; break;
+
+            case 'a': value = GDK_KEY_adiaeresis; break;
+            case 'A': value = GDK_KEY_Adiaeresis; break;
+            case 'e': value = GDK_KEY_ediaeresis; break;
+            case 'E': value = GDK_KEY_Ediaeresis; break;
+            case 'i': value = GDK_KEY_idiaeresis; break;
+            case 'I': value = GDK_KEY_Idiaeresis; break;
+            case 'o': value = GDK_KEY_odiaeresis; break;
+            case 'O': value = GDK_KEY_Odiaeresis; break;
+            case 'u': value = GDK_KEY_udiaeresis; break;
+            case 'U': value = GDK_KEY_Udiaeresis; break;
+            case 'y': value = GDK_KEY_ydiaeresis; break;
+            case 'Y': value = GDK_KEY_Ydiaeresis; break;
+            }
+          break;
+
+        case GDK_KEY_dead_acute:
+          switch (priv->compose_buffer[1])
+            {
+            case 'c': value = GDK_KEY_ccedilla; break;
+            case 'C': value = GDK_KEY_Ccedilla; break;
+            }
+          break;
+        }
+    }
+
+  if (value > 0)
+    {
+      gtk_im_context_simple_commit_char (GTK_IM_CONTEXT (context_simple),
+                                         gdk_keyval_to_unicode (value));
+      priv->compose_buffer[0] = 0;
+
+      GTK_NOTE (MISC, g_print ("quartz: U+%04X\n", value));
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+#endif
+
+static gboolean
+check_compact_table (GtkIMContextSimple           *context_simple,
+                     const GtkComposeTableCompact *table,
+                     gint                          n_compose)
 {
   GtkIMContextSimplePrivate *priv = context_simple->priv;
   gint row_stride;
   guint16 *seq_index;
-  guint16 *seq; 
+  guint16 *seq;
   gint i;
+  gboolean match;
+  gunichar value;
 
   /* Will never match, if the sequence in the compose buffer is longer
    * than the sequences in the table.  Further, compare_seq (key, val)
-   * will overrun val if key is longer than val. */
+   * will overrun val if key is longer than val.
+   */
   if (n_compose > table->max_seq_len)
     return FALSE;
 
   seq_index = bsearch (priv->compose_buffer,
-                table->data, table->n_index_size,
-                sizeof (guint16) *  table->n_index_stride, 
-                compare_seq_index);
+                       table->data,
+                       table->n_index_size,
+                       sizeof (guint16) * table->n_index_stride,
+                       compare_seq_index);
 
   if (!seq_index)
     {
@@ -402,44 +464,47 @@ check_compact_table (GtkIMContextSimple    *context_simple,
 
   GTK_NOTE (MISC, g_print ("compact: %d ", *seq_index));
   seq = NULL;
+  match = FALSE;
 
-  for (i = n_compose-1; i < table->max_seq_len; i++)
+  for (i = n_compose - 1; i < table->max_seq_len; i++)
     {
       row_stride = i + 1;
 
-      if (seq_index[i+1] - seq_index[i] > 0)
+      if (seq_index[i + 1] - seq_index[i] > 0)
         {
-         seq = bsearch (priv->compose_buffer + 1,
-                table->data + seq_index[i], (seq_index[i+1] - seq_index[i]) / row_stride,
-                sizeof (guint16) *  row_stride, 
-                compare_seq);
+          seq = bsearch (priv->compose_buffer + 1,
+                         table->data + seq_index[i],
+                         (seq_index[i + 1] - seq_index[i]) / row_stride,
+                         sizeof (guint16) *  row_stride,
+                         compare_seq);
 
-         if (seq)
+          if (seq)
             {
               if (i == n_compose - 1)
-                break;
+                {
+                  value = seq[row_stride - 1];
+                  match = TRUE;
+                }
               else
                 {
+                  if (match)
+                    {
+                      GTK_NOTE (MISC, g_print ("tentative match U+%04X ", value));
+                      priv->tentative_match = value;
+                      priv->tentative_match_len = n_compose;
+                    }
+
                   g_signal_emit_by_name (context_simple, "preedit-changed");
 
-                 GTK_NOTE (MISC, g_print ("yes\n"));
-                 return TRUE;
+                  GTK_NOTE (MISC, g_print ("yes\n"));
+                  return TRUE;
                 }
              }
         }
     }
 
-  if (!seq)
-    {
-      GTK_NOTE (MISC, g_print ("no\n"));
-      return FALSE;
-    }
-  else
+  if (match)
     {
-      gunichar value;
-
-      value = seq[row_stride - 1];
-
       gtk_im_context_simple_commit_char (GTK_IM_CONTEXT (context_simple), value);
 #ifdef G_OS_WIN32
       check_win32_special_case_after_compact_match (context_simple, n_compose, value);
@@ -455,7 +520,7 @@ check_compact_table (GtkIMContextSimple    *context_simple,
 }
 
 /* This function receives a sequence of Unicode characters and tries to
- * normalize it (NFC). We check for the case the the resulting string
+ * normalize it (NFC). We check for the case where the resulting string
  * has length 1 (single character).
  * NFC normalisation normally rearranges diacritic marks, unless these
  * belong to the same Canonical Combining Class.
@@ -479,7 +544,8 @@ check_normalize_nfc (gunichar* combination_buffer, gint n_compose)
 
   /* Xorg reuses dead_tilde for the perispomeni diacritic mark.
    * We check if base character belongs to Greek Unicode block,
-   * and if so, we replace tilde with perispomeni. */
+   * and if so, we replace tilde with perispomeni.
+   */
   if (combination_buffer[0] >= 0x390 && combination_buffer[0] <= 0x3FF)
     {
       for (i = 1; i < n_compose; i++ )
@@ -493,7 +559,7 @@ check_normalize_nfc (gunichar* combination_buffer, gint n_compose)
     {
       g_unicode_canonical_ordering (combination_buffer_temp, n_compose);
       combination_utf8_temp = g_ucs4_to_utf8 (combination_buffer_temp, -1, NULL, NULL, NULL);
-      nfc_temp = g_utf8_normalize (combination_utf8_temp, -1, G_NORMALIZE_NFC);                
+      nfc_temp = g_utf8_normalize (combination_utf8_temp, -1, G_NORMALIZE_NFC);
 
       if (g_utf8_strlen (nfc_temp, -1) == 1)
         {
@@ -522,8 +588,8 @@ check_normalize_nfc (gunichar* combination_buffer, gint n_compose)
 }
 
 static gboolean
-check_algorithmically (GtkIMContextSimple    *context_simple,
-                      gint                   n_compose)
+check_algorithmically (GtkIMContextSimple *context_simple,
+                       gint                n_compose)
 
 {
   GtkIMContextSimplePrivate *priv = context_simple->priv;
@@ -549,7 +615,7 @@ check_algorithmically (GtkIMContextSimple    *context_simple,
          switch (priv->compose_buffer[i])
            {
 #define CASE(keysym, unicode) \
-           case GDK_dead_##keysym: combination_buffer[i+1] = unicode; break
+           case GDK_KEY_dead_##keysym: combination_buffer[i+1] = unicode; break
 
            CASE (grave, 0x0300);
            CASE (acute, 0x0301);
@@ -588,9 +654,8 @@ check_algorithmically (GtkIMContextSimple    *context_simple,
          i--;
        }
       
-      /* If the buffer normalizes to a single character, 
-       * then modify the order of combination_buffer accordingly, if necessary,
-       * and return TRUE. 
+      /* If the buffer normalizes to a single character, then modify the order
+       * of combination_buffer accordingly, if necessary, and return TRUE.
        */
       if (check_normalize_nfc (combination_buffer, n_compose))
         {
@@ -615,8 +680,8 @@ check_algorithmically (GtkIMContextSimple    *context_simple,
 /* In addition to the table-driven sequences, we allow Unicode hex
  * codes to be entered. The method chosen here is similar to the
  * one recommended in ISO 14755, but not exactly the same, since we
- * don't want to steal 16 valuable key combinations. 
- * 
+ * don't want to steal 16 valuable key combinations.
+ *
  * A hex Unicode sequence must be started with Ctrl-Shift-U, followed
  * by a sequence of hex digits entered with Ctrl-Shift still held.
  * Releasing one of the modifiers or pressing space while the modifiers
@@ -627,7 +692,6 @@ check_algorithmically (GtkIMContextSimple    *context_simple,
  * with Ctrl-Shift-U, then release the modifiers before typing any
  * digits, and enter the digits without modifiers.
  */
-#define HEX_MOD_MASK (GTK_DEFAULT_ACCEL_MOD_MASK | GDK_SHIFT_MASK)
 
 static gboolean
 check_hex (GtkIMContextSimple *context_simple,
@@ -668,7 +732,7 @@ check_hex (GtkIMContextSimple *context_simple,
 
   n = strtoul (str->str, &nptr, 16);
 
-  /* if strtoul fails it probably means non-latin digits were used;
+  /* If strtoul fails it probably means non-latin digits were used;
    * we should in principle handle that, but we probably don't.
    */
   if (nptr - str->str < str->len)
@@ -691,26 +755,15 @@ check_hex (GtkIMContextSimple *context_simple,
 static void
 beep_window (GdkWindow *window)
 {
-  GtkWidget *widget;
-
-  gdk_window_get_user_data (window, (gpointer) &widget);
-
-  if (GTK_IS_WIDGET (widget))
-    {
-      gtk_widget_error_bell (widget);
-    }
-  else
-    {
-      GdkScreen *screen = gdk_window_get_screen (GDK_DRAWABLE (window));
-      gboolean   beep;
+  GdkScreen *screen = gdk_window_get_screen (window);
+  gboolean   beep;
 
-      g_object_get (gtk_settings_get_for_screen (screen),
-                    "gtk-error-bell", &beep,
-                    NULL);
+  g_object_get (gtk_settings_get_for_screen (screen),
+                "gtk-error-bell", &beep,
+                NULL);
 
-      if (beep)
-        gdk_window_beep (window);
-    }
+  if (beep)
+    gdk_window_beep (window);
 }
 
 static gboolean
@@ -756,7 +809,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
        }
   
       ch = gdk_keyval_to_unicode (event->keyval);
-      if (ch != 0)
+      if (ch != 0 && !g_unichar_iscntrl (ch))
        {
          gtk_im_context_simple_commit_char (context, ch);
          return TRUE;
@@ -777,7 +830,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));
+  GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_window_get_display (event->window));
   guint keyval;
   guint *keyvals = NULL;
   gint n_vals = 0;
@@ -824,8 +877,10 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
 {
   GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
   GtkIMContextSimplePrivate *priv = context_simple->priv;
+  GdkDisplay *display = gdk_window_get_display (event->window);
   GSList *tmp_list;  
   int n_compose = 0;
+  GdkModifierType hex_mod_mask;
   gboolean have_hex_mods;
   gboolean is_hex_start;
   gboolean is_hex_end;
@@ -840,8 +895,8 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
   if (event->type == GDK_KEY_RELEASE)
     {
       if (priv->in_hex_sequence &&
-         (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R ||
-          event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R))
+         (event->keyval == GDK_KEY_Control_L || event->keyval == GDK_KEY_Control_R ||
+          event->keyval == GDK_KEY_Shift_L || event->keyval == GDK_KEY_Shift_R))
        {
          if (priv->tentative_match &&
              g_unichar_validate (priv->tentative_match))
@@ -878,18 +933,22 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
     if (event->keyval == gtk_compose_ignore[i])
       return FALSE;
 
+  hex_mod_mask = gdk_keymap_get_modifier_mask (gdk_keymap_get_for_display (display),
+                                               GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR);
+  hex_mod_mask |= GDK_SHIFT_MASK;
+
   if (priv->in_hex_sequence && priv->modifiers_dropped)
     have_hex_mods = TRUE;
   else
-    have_hex_mods = (event->state & (HEX_MOD_MASK)) == HEX_MOD_MASK;
-  is_hex_start = event->keyval == GDK_U;
-  is_hex_end = (event->keyval == GDK_space || 
-               event->keyval == GDK_KP_Space ||
-               event->keyval == GDK_Return || 
-               event->keyval == GDK_ISO_Enter ||
-               event->keyval == GDK_KP_Enter);
-  is_backspace = event->keyval == GDK_BackSpace;
-  is_escape = event->keyval == GDK_Escape;
+    have_hex_mods = (event->state & (hex_mod_mask)) == hex_mod_mask;
+  is_hex_start = event->keyval == GDK_KEY_U;
+  is_hex_end = (event->keyval == GDK_KEY_space ||
+               event->keyval == GDK_KEY_KP_Space ||
+               event->keyval == GDK_KEY_Return ||
+               event->keyval == GDK_KEY_ISO_Enter ||
+               event->keyval == GDK_KEY_KP_Enter);
+  is_backspace = event->keyval == GDK_KEY_BackSpace;
+  is_escape = event->keyval == GDK_KEY_Escape;
   hex_keyval = canonical_hex_keyval (event);
 
   /* If we are already in a non-hex sequence, or
@@ -905,11 +964,20 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
       (priv->in_hex_sequence && !hex_keyval &&
        !is_hex_start && !is_hex_end && !is_escape && !is_backspace))
     {
-      if (event->state & (GDK_MOD1_MASK | GDK_CONTROL_MASK) ||
+      GdkDisplay *display;
+      GdkModifierType no_text_input_mask;
+
+      display = gdk_window_get_display (event->window);
+
+      no_text_input_mask =
+        gdk_keymap_get_modifier_mask (gdk_keymap_get_for_display (display),
+                                      GDK_MODIFIER_INTENT_NO_TEXT_INPUT);
+
+      if (event->state & no_text_input_mask ||
          (priv->in_hex_sequence && priv->modifiers_dropped &&
-          (event->keyval == GDK_Return || 
-           event->keyval == GDK_ISO_Enter ||
-           event->keyval == GDK_KP_Enter)))
+          (event->keyval == GDK_KEY_Return ||
+           event->keyval == GDK_KEY_ISO_Enter ||
+           event->keyval == GDK_KEY_KP_Enter)))
        {
          return FALSE;
        }
@@ -1060,6 +1128,11 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
        return TRUE;
 #endif
 
+#ifdef GDK_WINDOWING_QUARTZ
+      if (check_quartz_special_cases (context_simple, n_compose))
+        return TRUE;
+#endif
+
       if (check_compact_table (context_simple, &gtk_compose_table_compact, n_compose))
         return TRUE;
   
@@ -1142,7 +1215,7 @@ gtk_im_context_simple_get_preedit_string (GtkIMContext   *context,
 }
 
 /**
- * gtk_im_context_simple_add_table:
+ * gtk_im_context_simple_add_table: (skip)
  * @context_simple: A #GtkIMContextSimple
  * @data: the table 
  * @max_seq_len: Maximum length of a sequence in the table