[gtk/single-key-compose: 2/5] input: Accept short compose sequences




commit a00db0f8c4da3b5316357304a4cd0dac271dcb8b
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Sep 12 21:45:49 2022 -0400

    input: Accept short compose sequences
    
    Some of the X keyboard layouts use compose
    sequences of length one to make individual
    keys generate multiple Unicode characters.
    
    To support this use case, change the index
    part of the table format to also include
    an offset for length 1. Bump the table
    version to indicate this change.
    
    Fixes: #5172

 gtk/gtkcomposetable.c | 56 ++++++++++++++++++++++-----------------------------
 gtk/gtkcomposetable.h |  3 +++
 2 files changed, 27 insertions(+), 32 deletions(-)
---
diff --git a/gtk/gtkcomposetable.c b/gtk/gtkcomposetable.c
index eda1e5ad5b..5e9b2065fc 100644
--- a/gtk/gtkcomposetable.c
+++ b/gtk/gtkcomposetable.c
@@ -28,7 +28,7 @@
 
 
 #define GTK_COMPOSE_TABLE_MAGIC "GtkComposeTable"
-#define GTK_COMPOSE_TABLE_VERSION (3)
+#define GTK_COMPOSE_TABLE_VERSION (4)
 
 extern const GtkComposeTable builtin_compose_table;
 
@@ -504,12 +504,6 @@ parser_remove_duplicates (GtkComposeParser *parser)
           goto next;
         }
 
-      if (sequence[1] == 0)
-        {
-          remove_sequence = TRUE;
-          goto next;
-        }
-
       for (i = 0; i < MAX_COMPOSE_LEN + 1; i++)
         keysyms[i] = 0;
 
@@ -671,7 +665,7 @@ gtk_compose_hash_get_cache_path (guint32 hash)
   return path;
 }
 
-static char *
+char *
 gtk_compose_table_serialize (GtkComposeTable *compose_table,
                              gsize           *count)
 {
@@ -907,7 +901,7 @@ parser_get_compose_table (GtkComposeParser *parser)
                                      (GCompareDataFunc) sequence_compare,
                                      NULL);
 
-  index_rowstride = max_compose_len + 1;
+  index_rowstride = max_compose_len + 2;
   data = g_new0 (guint16, n_first * index_rowstride + size);
 
   char_data = g_string_new ("");
@@ -923,7 +917,7 @@ parser_get_compose_table (GtkComposeParser *parser)
       char *value = g_hash_table_lookup (parser->sequences, sequence);
       int len = sequence_length (sequence);
 
-      g_assert (2 <= len && len <= max_compose_len);
+      g_assert (1 <= len && len <= max_compose_len);
 
       /* Encode the value. If the value is a single
        * character with a value smaller than 1 << 15,
@@ -944,7 +938,7 @@ parser_get_compose_table (GtkComposeParser *parser)
 
           if (char_data->len >= 0x8000)
             {
-              g_warning ("GTK can't handle compose tables this large (%s)", parser->compose_file ? 
parser->compose_file : "");
+              g_warning ("GTK can't handle compose tables this large (%s, %ld)", parser->compose_file ? 
parser->compose_file : "", char_data->len);
               g_string_free (char_data, TRUE);
               return NULL;
             }
@@ -979,10 +973,10 @@ parser_get_compose_table (GtkComposeParser *parser)
 
       rest_pos += len;
 
-      for (i = len; i <= max_compose_len; i++)
+      for (i = len + 1; i < index_rowstride; i++)
         data[first_pos + i] = rest_pos;
 
-      for (i = 1; i < max_compose_len; i++)
+      for (i = 1; i + 1 < index_rowstride; i++)
         g_assert (data[first_pos + i] <= data[first_pos + i + 1]);
     }
 
@@ -1275,7 +1269,7 @@ gtk_compose_table_check (const GtkComposeTable *table,
                          gboolean              *compose_match,
                          GString               *output)
 {
-  int row_stride;
+  int len;
   guint16 *seq_index;
   guint16 *seq;
   int i;
@@ -1297,7 +1291,7 @@ gtk_compose_table_check (const GtkComposeTable *table,
   seq_index = bsearch (compose_buffer,
                        table->data,
                        table->n_index_size,
-                       sizeof (guint16) * (table->max_seq_len + 1),
+                       sizeof (guint16) * (table->max_seq_len + 2),
                        compare_seq_index);
 
   if (!seq_index)
@@ -1312,21 +1306,21 @@ gtk_compose_table_check (const GtkComposeTable *table,
 
   for (i = n_compose - 1; i < table->max_seq_len; i++)
     {
-      row_stride = i + 1;
+      len = i + 1;
 
-      if (seq_index[i + 1] - seq_index[i] > 0)
+      if (seq_index[len + 1] - seq_index[len] > 0)
         {
           seq = bsearch (compose_buffer + 1,
-                         table->data + seq_index[i],
-                         (seq_index[i + 1] - seq_index[i]) / row_stride,
-                         sizeof (guint16) * row_stride,
+                         table->data + seq_index[len],
+                         (seq_index[len + 1] - seq_index[len]) / len,
+                         sizeof (guint16) * len,
                          compare_seq);
 
           if (seq)
             {
               if (i == n_compose - 1)
                 {
-                  value = seq[row_stride - 1];
+                  value = seq[len - 1];
 
                   if ((value & (1 << 15)) != 0)
                     g_string_append (output, &table->char_data[value & ~(1 << 15)]);
@@ -1367,7 +1361,7 @@ gtk_compose_table_get_prefix (const GtkComposeTable *table,
                               int                    n_compose,
                               int                   *prefix)
 {
-  int index_stride = table->max_seq_len + 1;
+  int index_stride = table->max_seq_len + 2;
   int p = 0;
 
   for (int idx = 0; idx < table->n_index_size; idx++)
@@ -1378,9 +1372,9 @@ gtk_compose_table_get_prefix (const GtkComposeTable *table,
         {
           p = 1;
 
-          for (int i = 1; i < table->max_seq_len; i++)
+          for (int i = 1; i < table->max_seq_len + 1; i++)
             {
-              int len = i + 1;
+              int len = i;
 
               for (int j = seq_index[i]; j < seq_index[i + 1]; j += len)
                 {
@@ -1407,20 +1401,20 @@ gtk_compose_table_foreach (const GtkComposeTable      *table,
                            GtkComposeSequenceCallback  callback,
                            gpointer                    data)
 {
-  int index_stride = table->max_seq_len + 1;
+  int index_stride = table->max_seq_len + 2;
   gunichar *sequence;
   int seqno;
 
-  sequence = g_new0 (gunichar, table->max_seq_len + 1);
+  sequence = g_newa (gunichar, table->max_seq_len + 1);
 
   seqno = 0;
   for (int idx = 0; idx < table->n_index_size; idx++)
     {
       const guint16 *seq_index = table->data + (idx * index_stride);
 
-      for (int i = 1; i < table->max_seq_len; i++)
+      for (int i = 1; i <= table->max_seq_len; i++)
         {
-          int len = i + 1;
+          int len = i;
 
           g_assert (seq_index[i] <= seq_index[i + 1]);
           g_assert (seq_index[i + 1] <= table->data_size);
@@ -1433,8 +1427,8 @@ gtk_compose_table_foreach (const GtkComposeTable      *table,
               char *value;
 
               sequence[0] = seq_index[0];
-              for (int k = 0; k < len - 1; k++)
-                sequence[k + 1] = (gunichar) table->data[j + k];
+              for (int k = 1; k < len; k++)
+                sequence[k] = (gunichar) table->data[j + k - 1];
               sequence[len] = 0;
 
               encoded_value = table->data[j + len - 1];
@@ -1456,8 +1450,6 @@ gtk_compose_table_foreach (const GtkComposeTable      *table,
             }
         }
     }
-
-  g_free (sequence);
 }
 
 /* Checks if a keysym is a dead key.
diff --git a/gtk/gtkcomposetable.h b/gtk/gtkcomposetable.h
index 72c0ed8d15..136091993d 100644
--- a/gtk/gtkcomposetable.h
+++ b/gtk/gtkcomposetable.h
@@ -64,6 +64,9 @@ GtkComposeTable * gtk_compose_table_new_with_data (const guint16 *data,
                                                    int            max_seq_len,
                                                    int            n_seqs);
 
+char *            gtk_compose_table_serialize     (GtkComposeTable *compose_table,
+                                                   gsize           *count);
+
 typedef void (* GtkComposeSequenceCallback) (gunichar   *sequence,
                                              int         len,
                                              const char *value,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]