diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-08-02 18:07:46 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-08-02 18:07:46 +0000 |
commit | f59d2ae89de7da0e7fc37117be2592bfb2b78f34 (patch) | |
tree | f44a3821589a476a3f16a6777938a400e4aa3688 | |
parent | 7c3a53a1715f08b3587c655be50a0bec996134b7 (diff) | |
parent | c4dbb8f01ebab1b94adbbcd771642ce4013c22ec (diff) | |
download | gtk+-f59d2ae89de7da0e7fc37117be2592bfb2b78f34.tar.gz |
Merge branch 'input-tweaks' into 'master'4149-imcontext-handle-16bit-keysyms
imcontext: Tweak Compose sequence preedit
Closes #10, #4127, and #4124
See merge request GNOME/gtk!3799
-rw-r--r-- | gtk/compose/chars | bin | 1573 -> 1242 bytes | |||
-rw-r--r-- | gtk/compose/gtkcomposedata.h | 4 | ||||
-rw-r--r-- | gtk/compose/sequences | bin | 33042 -> 32894 bytes | |||
-rw-r--r-- | gtk/gtkcomposetable.c | 213 | ||||
-rw-r--r-- | gtk/gtkcomposetable.h | 7 | ||||
-rw-r--r-- | gtk/gtkimcontextsimple.c | 120 | ||||
-rw-r--r-- | testsuite/gtk/compose/system.expected | 185 | ||||
-rw-r--r-- | testsuite/gtk/composetable.c | 49 |
8 files changed, 272 insertions, 306 deletions
diff --git a/gtk/compose/chars b/gtk/compose/chars Binary files differindex 9f9b15314f..f3897230ea 100644 --- a/gtk/compose/chars +++ b/gtk/compose/chars diff --git a/gtk/compose/gtkcomposedata.h b/gtk/compose/gtkcomposedata.h index 057347a36b..442696218c 100644 --- a/gtk/compose/gtkcomposedata.h +++ b/gtk/compose/gtkcomposedata.h @@ -3,7 +3,7 @@ #define MAX_SEQ_LEN 5 #define N_INDEX_SIZE 30 -#define DATA_SIZE 16521 -#define N_CHARS 1572 +#define DATA_SIZE 16447 +#define N_CHARS 1241 #endif diff --git a/gtk/compose/sequences b/gtk/compose/sequences Binary files differindex 1db7a6cddb..39984d4125 100644 --- a/gtk/compose/sequences +++ b/gtk/compose/sequences diff --git a/gtk/gtkcomposetable.c b/gtk/gtkcomposetable.c index c95b153e6f..464bf1876a 100644 --- a/gtk/gtkcomposetable.c +++ b/gtk/gtkcomposetable.c @@ -486,6 +486,9 @@ parser_remove_duplicates (GtkComposeParser *parser) GHashTableIter iter; gunichar *sequence; char *value; + GString *output; + + output = g_string_new (""); g_hash_table_iter_init (&iter, parser->sequences); while (g_hash_table_iter_next (&iter, (gpointer *)&sequence, (gpointer *)&value)) @@ -493,8 +496,6 @@ parser_remove_duplicates (GtkComposeParser *parser) static guint16 keysyms[MAX_COMPOSE_LEN + 1]; int i; int n_compose = 0; - gunichar output_char; - char buf[8] = { 0, }; gboolean remove_sequence = FALSE; if (value[0] == '\0') @@ -529,10 +530,9 @@ parser_remove_duplicates (GtkComposeParser *parser) n_compose++; } - if (gtk_check_algorithmically (keysyms, n_compose, &output_char)) + if (gtk_check_algorithmically (keysyms, n_compose, output)) { - g_unichar_to_utf8 (output_char, buf); - if (strcmp (value, buf) == 0) + if (strcmp (value, output->str) == 0) remove_sequence = TRUE; } @@ -540,6 +540,8 @@ next: if (remove_sequence) g_hash_table_iter_remove (&iter); } + + g_string_free (output, TRUE); } static void @@ -1069,22 +1071,22 @@ gtk_compose_table_parse (const char *compose_file, return compose_table; } -static const char *prefix = - "# GTK has rewritten this file to add the line:\n" - "\n" - "include \"%L\"\n" - "\n" - "# This is necessary to add your own Compose sequences\n" - "# in addition to the builtin sequences of GTK. If this\n" - "# is not what you want, just remove that line.\n" - "#\n" - "# A backup of the previous file contents has been made.\n" - "\n" - "\n"; - static gboolean rewrite_compose_file (const char *compose_file) { + static const char *prefix = + "# GTK has rewritten this file to add the line:\n" + "\n" + "include \"%L\"\n" + "\n" + "# This is necessary to add your own Compose sequences\n" + "# in addition to the builtin sequences of GTK. If this\n" + "# is not what you want, just remove that line.\n" + "#\n" + "# A backup of the previous file contents has been made.\n" + "\n" + "\n"; + char *path = NULL; char *content = NULL; gsize content_len; @@ -1353,6 +1355,47 @@ gtk_compose_table_check (const GtkComposeTable *table, } void +gtk_compose_table_get_prefix (const GtkComposeTable *table, + const guint16 *compose_buffer, + int n_compose, + int *prefix) +{ + int index_stride = table->max_seq_len + 1; + int p = 0; + + for (int idx = 0; idx < table->n_index_size; idx++) + { + const guint16 *seq_index = table->data + (idx * index_stride); + + if (seq_index[0] == compose_buffer[0]) + { + p = 1; + + for (int i = 1; i < table->max_seq_len; i++) + { + int len = i + 1; + + for (int j = seq_index[i]; j < seq_index[i + 1]; j += len) + { + int k; + + for (k = 0; k < MIN (len, n_compose) - 1; k++) + { + if (compose_buffer[k + 1] != (gunichar) table->data[j + k]) + break; + } + p = MAX (p, k + 1); + } + } + + break; + } + } + + *prefix = p; +} + +void gtk_compose_table_foreach (const GtkComposeTable *table, GtkComposeSequenceCallback callback, gpointer data) @@ -1419,119 +1462,56 @@ gtk_compose_table_foreach (const GtkComposeTable *table, #define IS_DEAD_KEY(k) \ ((k) >= GDK_KEY_dead_grave && (k) <= GDK_KEY_dead_greek) -/* This function receives a sequence of Unicode characters and tries to - * 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. - * If they belong to the same canonical combining class, we produce all - * permutations of the diacritic marks, then attempt to normalize. - */ -static gboolean -check_normalize_nfc (gunichar *combination_buffer, - int n_compose) -{ - gunichar *combination_buffer_temp; - char *combination_utf8_temp = NULL; - char *nfc_temp = NULL; - int n_combinations; - gunichar temp_swap; - int i; - - combination_buffer_temp = g_alloca (n_compose * sizeof (gunichar)); - - n_combinations = 1; - - for (i = 1; i < n_compose; i++) - n_combinations *= i; - - /* 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. - */ - if (combination_buffer[0] >= 0x390 && combination_buffer[0] <= 0x3FF) - { - for (i = 1; i < n_compose; i++ ) - if (combination_buffer[i] == 0x303) - combination_buffer[i] = 0x342; - } - - memcpy (combination_buffer_temp, combination_buffer, n_compose * sizeof (gunichar) ); - - for (i = 0; i < n_combinations; i++) - { - g_unicode_canonical_ordering (combination_buffer_temp, n_compose); - combination_utf8_temp = g_ucs4_to_utf8 (combination_buffer_temp, n_compose, NULL, NULL, NULL); - nfc_temp = g_utf8_normalize (combination_utf8_temp, -1, G_NORMALIZE_NFC); - - if (g_utf8_strlen (nfc_temp, -1) == 1) - { - memcpy (combination_buffer, combination_buffer_temp, n_compose * sizeof (gunichar) ); - - g_free (combination_utf8_temp); - g_free (nfc_temp); - - return TRUE; - } - - g_free (combination_utf8_temp); - g_free (nfc_temp); - - if (n_compose > 2) - { - temp_swap = combination_buffer_temp[i % (n_compose - 1) + 1]; - combination_buffer_temp[i % (n_compose - 1) + 1] = combination_buffer_temp[(i+1) % (n_compose - 1) + 1]; - combination_buffer_temp[(i+1) % (n_compose - 1) + 1] = temp_swap; - } - else - break; - } - - return FALSE; -} - gboolean gtk_check_algorithmically (const guint16 *compose_buffer, int n_compose, - gunichar *output_char) + GString *output) { int i; - gunichar *combination_buffer; - char *combination_utf8, *nfc; - - combination_buffer = alloca (sizeof (gunichar) * (n_compose + 1)); - if (output_char) - *output_char = 0; + g_string_set_size (output, 0); for (i = 0; i < n_compose && IS_DEAD_KEY (compose_buffer[i]); i++) ; - /* Allow at most 2 dead keys */ - if (i > 2) - return FALSE; - - /* Can't combine if there's no base character */ + /* Can't combine if there's no base character: incomplete sequence */ if (i == n_compose) return TRUE; if (i > 0 && i == n_compose - 1) { - combination_buffer[0] = gdk_keyval_to_unicode (compose_buffer[i]); - combination_buffer[n_compose] = 0; + GString *input; + char *nfc; + gunichar ch; + + ch = gdk_keyval_to_unicode (compose_buffer[i]); + + /* We don't allow combining with non-letters */ + if (!g_unichar_isalpha (ch)) + return FALSE; + + input = g_string_sized_new (4 * n_compose); + + g_string_append_unichar (input, ch); + i--; while (i >= 0) { switch (compose_buffer[i]) { #define CASE(keysym, unicode) \ - case GDK_KEY_dead_##keysym: combination_buffer[i+1] = unicode; break + case GDK_KEY_dead_##keysym: g_string_append_unichar (input, unicode); break CASE (grave, 0x0300); CASE (acute, 0x0301); CASE (circumflex, 0x0302); - CASE (tilde, 0x0303); /* Also used with perispomeni, 0x342. */ + case GDK_KEY_dead_tilde: + if (g_unichar_get_script (ch) == G_UNICODE_SCRIPT_GREEK) + g_string_append_unichar (input, 0x342); /* combining perispomeni */ + else + g_string_append_unichar (input, 0x303); /* combining tilde */ + break; CASE (macron, 0x0304); CASE (breve, 0x0306); CASE (abovedot, 0x0307); @@ -1549,7 +1529,7 @@ gtk_check_algorithmically (const guint16 *compose_buffer, CASE (horn, 0x031B); /* Legacy use for psili, 0x313 (or 0x343). */ CASE (stroke, 0x335); CASE (abovecomma, 0x0313); /* Equivalent to psili */ - CASE (abovereversedcomma, 0x0314); /* Equivalent to dasia */ + CASE (abovereversedcomma, 0x0314); /* Equivalent to dasia */ CASE (doublegrave, 0x30F); CASE (belowring, 0x325); CASE (belowmacron, 0x331); @@ -1577,27 +1557,20 @@ gtk_check_algorithmically (const guint16 *compose_buffer, CASE (capital_schwa, 0x1DEA); #undef CASE default: - combination_buffer[i+1] = gdk_keyval_to_unicode (compose_buffer[i]); + g_string_append_unichar (input, gdk_keyval_to_unicode (compose_buffer[i])); } i--; } - /* 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)) - { - combination_utf8 = g_ucs4_to_utf8 (combination_buffer, -1, NULL, NULL, NULL); - nfc = g_utf8_normalize (combination_utf8, -1, G_NORMALIZE_NFC); + nfc = g_utf8_normalize (input->str, input->len, G_NORMALIZE_NFC); - if (output_char) - *output_char = g_utf8_get_char (nfc); + g_string_assign (output, nfc); - g_free (combination_utf8); - g_free (nfc); + g_free (nfc); - return TRUE; - } + g_string_free (input, TRUE); + + return TRUE; } return FALSE; diff --git a/gtk/gtkcomposetable.h b/gtk/gtkcomposetable.h index 1398559a66..584849f747 100644 --- a/gtk/gtkcomposetable.h +++ b/gtk/gtkcomposetable.h @@ -80,9 +80,14 @@ gboolean gtk_compose_table_check (const GtkComposeTable *table, gboolean *compose_match, GString *output); +void gtk_compose_table_get_prefix (const GtkComposeTable *table, + const guint16 *compose_buffer, + int n_compose, + int *prefix); + gboolean gtk_check_algorithmically (const guint16 *compose_buffer, int n_compose, - gunichar *output); + GString *output); guint32 gtk_compose_table_data_hash (const guint16 *data, int max_seq_len, diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c index 7183205646..cdba288c0b 100644 --- a/gtk/gtkimcontextsimple.c +++ b/gtk/gtkimcontextsimple.c @@ -544,18 +544,22 @@ is_dead_key (guint keysym) return GDK_KEY_dead_grave <= keysym && keysym <= GDK_KEY_dead_greek; } -static gunichar -dead_key_to_unicode (guint keysym, - gboolean *need_space) +static void +append_dead_key (GString *string, + guint keysym) { /* Sadly, not all the dead keysyms have spacing mark equivalents - * in Unicode. For those that don't, we use space + the non-spacing - * mark as an approximation + * in Unicode. For those that don't, we use NBSP + the non-spacing + * mark as an approximation. */ switch (keysym) { -#define CASE(keysym, unicode, sp) \ - case GDK_KEY_dead_##keysym: *need_space = sp; return unicode; +#define CASE(keysym, unicode, sp) \ + case GDK_KEY_dead_##keysym: \ + if (sp) \ + g_string_append_unichar (string, 0xA0); \ + g_string_append_unichar (string, unicode); \ + break; CASE (grave, 0x60, 0); CASE (acute, 0xb4, 0); @@ -606,8 +610,7 @@ dead_key_to_unicode (guint keysym, CASE (capital_schwa, 0x1dea, 1); #undef CASE default: - *need_space = FALSE; - return gdk_keyval_to_unicode (keysym); + g_string_append_unichar (string, gdk_keyval_to_unicode (keysym)); } } @@ -622,7 +625,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple, guint keyval; context = GTK_IM_CONTEXT (context_simple); - + priv->in_compose_sequence = FALSE; /* No compose sequences found, check first if we have a partial @@ -675,7 +678,6 @@ no_sequence_matches (GtkIMContextSimple *context_simple, if (n_compose > 1 && i >= n_compose - 1) { - gboolean need_space; GString *s; s = g_string_new (""); @@ -684,15 +686,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple, { /* dead keys are never *really* dead */ for (int j = 0; j < i; j++) - { - ch = dead_key_to_unicode (priv->compose_buffer[j], &need_space); - if (ch) - { - if (need_space) - g_string_append_c (s, ' '); - g_string_append_unichar (s, ch); - } - } + append_dead_key (s, priv->compose_buffer[j]); ch = gdk_keyval_to_unicode (priv->compose_buffer[i]); if (ch != 0 && ch != ' ' && !g_unichar_iscntrl (ch)) @@ -702,14 +696,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple, } else { - ch = dead_key_to_unicode (priv->compose_buffer[0], &need_space); - if (ch) - { - if (need_space) - g_string_append_c (s, ' '); - g_string_append_unichar (s, ch); - } - + append_dead_key (s, priv->compose_buffer[0]); gtk_im_context_simple_commit_string (context_simple, s->str); for (i = 1; i < n_compose; i++) @@ -821,7 +808,6 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context, int i; gboolean compose_finish; gboolean compose_match; - gunichar output_char; guint keyval, state; while (priv->compose_buffer[n_compose] != 0 && n_compose < priv->compose_buffer_len) @@ -1001,16 +987,22 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context, return TRUE; } - + + if (is_escape) + { + if (priv->in_hex_sequence || priv->in_compose_sequence) + { + gtk_im_context_simple_reset (context); + return TRUE; + } + + return FALSE; + } + if (priv->in_hex_sequence) { if (hex_keyval && n_compose < 6) priv->compose_buffer[n_compose++] = hex_keyval; - else if (is_escape) - { - gtk_im_context_simple_reset (context); - return TRUE; - } else if (!is_hex_end) { /* non-hex character in hex sequence, or sequence too long */ @@ -1071,6 +1063,7 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context, else /* Then, check for compose sequences */ { gboolean success = FALSE; + int prefix = 0; GString *output; output = g_string_new (""); @@ -1109,18 +1102,29 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context, success = TRUE; break; } + else + { + int table_prefix; + + gtk_compose_table_get_prefix ((GtkComposeTable *)tmp_list->data, + priv->compose_buffer, n_compose, + &table_prefix); + + prefix = MAX (prefix, table_prefix); + } tmp_list = tmp_list->next; } G_UNLOCK (global_tables); - g_string_free (output, TRUE); - if (success) - return TRUE; + { + g_string_free (output, TRUE); + return TRUE; + } - if (gtk_check_algorithmically (priv->compose_buffer, n_compose, &output_char)) + if (gtk_check_algorithmically (priv->compose_buffer, n_compose, output)) { if (!priv->in_compose_sequence) { @@ -1128,11 +1132,30 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context, g_signal_emit_by_name (context_simple, "preedit-start"); } - if (output_char) - gtk_im_context_simple_commit_char (context_simple, output_char); + if (output->len > 0) + gtk_im_context_simple_commit_string (context_simple, output->str); else g_signal_emit_by_name (context_simple, "preedit-changed"); + g_string_free (output, TRUE); + + return TRUE; + } + + g_string_free (output, TRUE); + + /* If we get here, no Compose sequence matched. + * Only beep if we were in a sequence before. + */ + if (prefix > 0) + { + for (i = prefix; i < n_compose; i++) + priv->compose_buffer[i] = 0; + + beep_surface (gdk_event_get_surface (event)); + + g_signal_emit_by_name (context_simple, "preedit-changed"); + return TRUE; } } @@ -1195,28 +1218,23 @@ gtk_im_context_simple_get_preedit_string (GtkIMContext *context, if (priv->compose_buffer[i] == GDK_KEY_Multi_key) { /* We only show the Compose key visibly when it is the - * only glyph in the preedit, or when it occurs in the + * only glyph in the preedit, or when the sequence contains + * multiple Compose keys, or when it occurs in the * middle of the sequence. Sadly, the official character, * U+2384, COMPOSITION SYMBOL, is bit too distracting, so * we use U+00B7, MIDDLE DOT. */ - if (priv->compose_buffer[1] == 0 || i > 0) + if (priv->compose_buffer[1] == 0 || i > 0 || + priv->compose_buffer[i + 1] == GDK_KEY_Multi_key) g_string_append (s, "·"); } else { gunichar ch; - gboolean need_space; if (is_dead_key (priv->compose_buffer[i])) { - ch = dead_key_to_unicode (priv->compose_buffer[i], &need_space); - if (ch) - { - if (need_space) - g_string_append_c (s, ' '); - g_string_append_unichar (s, ch); - } + append_dead_key (s, priv->compose_buffer[i]); } else { diff --git a/testsuite/gtk/compose/system.expected b/testsuite/gtk/compose/system.expected index aac5ac82ea..c807827bbf 100644 --- a/testsuite/gtk/compose/system.expected +++ b/testsuite/gtk/compose/system.expected @@ -1,14 +1,12 @@ -# n_sequences: 4909 +# n_sequences: 4874 # max_seq_len: 5 # n_index_size: 30 -# data_size: 16521 -# n_chars: 1572 +# data_size: 16447 +# n_chars: 1241 <U7ae> <U7e9> : "ΐ" # U390 <U7ae> <U7f5> : "ΰ" # U3b0 <Ufe50> <U20> : "`" # U60 -<Ufe50> <U4d> : "M̀" <Ufe50> <U56> : "Ǜ" # U1db -<Ufe50> <U6d> : "m̀" <Ufe50> <U76> : "ǜ" # U1dc <Ufe50> <Ua0> : "̀" # U300 <Ufe50> <U186> : "Ɔ̀" @@ -23,16 +21,6 @@ <Ufe50> <U269> : "ɩ̀" <Ufe50> <U28a> : "ʊ̀" <Ufe50> <U28b> : "ʋ̀" -<Ufe50> <U3bd> : "Ŋ̀" -<Ufe50> <U3bf> : "ŋ̀" -<Ufe50> <U6c1> : "а̀" -<Ufe50> <U6cf> : "о̀" -<Ufe50> <U6d2> : "р̀" -<Ufe50> <U6d5> : "у̀" -<Ufe50> <U6e1> : "А̀" -<Ufe50> <U6ef> : "О̀" -<Ufe50> <U6f2> : "Р̀" -<Ufe50> <U6f5> : "У̀" <Ufe50> <U1f00> : "ἂ" # U1f02 <Ufe50> <U1f01> : "ἃ" # U1f03 <Ufe50> <U1f08> : "Ἂ" # U1f0a @@ -131,9 +119,7 @@ <Ufe50> <Uff20> <Uaf> <U65> : "ḕ" # U1e15 <Ufe50> <Uff20> <Uaf> <U6f> : "ṑ" # U1e51 <Ufe51> <U20> : "'" # U27 -<Ufe51> <U4a> : "J́" <Ufe51> <U56> : "Ǘ" # U1d7 -<Ufe51> <U6a> : "j́" <Ufe51> <U76> : "ǘ" # U1d8 <Ufe51> <Ua0> : "́" # U301 <Ufe51> <U186> : "Ɔ́" @@ -148,28 +134,7 @@ <Ufe51> <U269> : "ɩ́" <Ufe51> <U28a> : "ʊ́" <Ufe51> <U28b> : "ʋ́" -<Ufe51> <U3bd> : "Ŋ́" -<Ufe51> <U3bf> : "ŋ́" -<Ufe51> <U6c0> : "ю́" -<Ufe51> <U6c1> : "а́" -<Ufe51> <U6c5> : "е́" -<Ufe51> <U6c9> : "и́" -<Ufe51> <U6cf> : "о́" -<Ufe51> <U6d1> : "я́" -<Ufe51> <U6d2> : "р́" -<Ufe51> <U6d5> : "у́" -<Ufe51> <U6d9> : "ы́" -<Ufe51> <U6dc> : "э́" <Ufe51> <U6e0> : "Ю́́" -<Ufe51> <U6e1> : "А́" -<Ufe51> <U6e5> : "Е́" -<Ufe51> <U6e9> : "И́" -<Ufe51> <U6ef> : "О́" -<Ufe51> <U6f1> : "Я́" -<Ufe51> <U6f2> : "Р́" -<Ufe51> <U6f5> : "У́" -<Ufe51> <U6f9> : "Ы́" -<Ufe51> <U6fc> : "Э́" <Ufe51> <U1f00> : "ἄ" # U1f04 <Ufe51> <U1f01> : "ἅ" # U1f05 <Ufe51> <U1f08> : "Ἄ" # U1f0c @@ -210,6 +175,8 @@ <Ufe51> <Ufe53> <U1dd> : "ǝ̃́" <Ufe51> <Ufe53> <U254> : "ɔ̃́" <Ufe51> <Ufe53> <U25b> : "ɛ̃́" +<Ufe51> <Ufe56> <U53> : "Ṥ" # U1e64 +<Ufe51> <Ufe56> <U73> : "ṥ" # U1e65 <Ufe51> <Ufe57> <U20> : "΅" # U385 <Ufe51> <Ufe63> <U4f> : "Ǿ" # U1fe <Ufe51> <Ufe63> <U6f> : "ǿ" # U1ff @@ -327,18 +294,6 @@ <Ufe52> <U269> : "ɩ̂" <Ufe52> <U28a> : "ʊ̂" <Ufe52> <U28b> : "ʋ̂" -<Ufe52> <U6c1> : "а̂" -<Ufe52> <U6c5> : "е̂" -<Ufe52> <U6c9> : "и̂" -<Ufe52> <U6cf> : "о̂" -<Ufe52> <U6d2> : "р̂" -<Ufe52> <U6d5> : "у̂" -<Ufe52> <U6e1> : "А̂" -<Ufe52> <U6e5> : "Е̂" -<Ufe52> <U6e9> : "И̂" -<Ufe52> <U6ef> : "О̂" -<Ufe52> <U6f2> : "Р̂" -<Ufe52> <U6f5> : "У̂" <Ufe52> <U1ea0> : "Ậ" # U1eac <Ufe52> <U1ea1> : "ậ" # U1ead <Ufe52> <U1eb8> : "Ệ" # U1ec6 @@ -374,6 +329,30 @@ <Ufe52> <Uffb8> : "⁸" # U2078 <Ufe52> <Uffb9> : "⁹" # U2079 <Ufe52> <Uffbd> : "⁼" # U207c +<Ufe52> <Ufe50> <U41> : "Ầ" # U1ea6 +<Ufe52> <Ufe50> <U45> : "Ề" # U1ec0 +<Ufe52> <Ufe50> <U4f> : "Ồ" # U1ed2 +<Ufe52> <Ufe50> <U61> : "ầ" # U1ea7 +<Ufe52> <Ufe50> <U65> : "ề" # U1ec1 +<Ufe52> <Ufe50> <U6f> : "ồ" # U1ed3 +<Ufe52> <Ufe51> <U41> : "Ấ" # U1ea4 +<Ufe52> <Ufe51> <U45> : "Ế" # U1ebe +<Ufe52> <Ufe51> <U4f> : "Ố" # U1ed0 +<Ufe52> <Ufe51> <U61> : "ấ" # U1ea5 +<Ufe52> <Ufe51> <U65> : "ế" # U1ebf +<Ufe52> <Ufe51> <U6f> : "ố" # U1ed1 +<Ufe52> <Ufe53> <U41> : "Ẫ" # U1eaa +<Ufe52> <Ufe53> <U45> : "Ễ" # U1ec4 +<Ufe52> <Ufe53> <U4f> : "Ỗ" # U1ed6 +<Ufe52> <Ufe53> <U61> : "ẫ" # U1eab +<Ufe52> <Ufe53> <U65> : "ễ" # U1ec5 +<Ufe52> <Ufe53> <U6f> : "ỗ" # U1ed7 +<Ufe52> <Ufe61> <U41> : "Ẩ" # U1ea8 +<Ufe52> <Ufe61> <U45> : "Ể" # U1ec2 +<Ufe52> <Ufe61> <U4f> : "Ổ" # U1ed4 +<Ufe52> <Ufe61> <U61> : "ẩ" # U1ea9 +<Ufe52> <Ufe61> <U65> : "ể" # U1ec3 +<Ufe52> <Ufe61> <U6f> : "ổ" # U1ed5 <Ufe52> <Uff20> <U21> <U41> : "Ậ" # U1eac <Ufe52> <Uff20> <U21> <U45> : "Ệ" # U1ec6 <Ufe52> <Uff20> <U21> <U4f> : "Ộ" # U1ed8 @@ -463,6 +442,14 @@ <Ufe53> <U1f68> : "Ὦ" # U1f6e <Ufe53> <U1f69> : "Ὧ" # U1f6f <Ufe53> <Ufe53> : "~" # U7e +<Ufe53> <Ufe51> <U4f> : "Ṍ" # U1e4c +<Ufe53> <Ufe51> <U55> : "Ṹ" # U1e78 +<Ufe53> <Ufe51> <U6f> : "ṍ" # U1e4d +<Ufe53> <Ufe51> <U75> : "ṹ" # U1e79 +<Ufe53> <Ufe54> <U4f> : "Ȭ" # U22c +<Ufe53> <Ufe54> <U6f> : "ȭ" # U22d +<Ufe53> <Ufe57> <U4f> : "Ṏ" # U1e4e +<Ufe53> <Ufe57> <U6f> : "ṏ" # U1e4f <Ufe53> <Uff20> <U22> <U7e9> : "ῗ" # U1fd7 <Ufe53> <Uff20> <U22> <U7f5> : "ῧ" # U1fe7 <Ufe53> <Uff20> <U28> <U7c1> : "Ἇ" # U1f0f @@ -528,21 +515,19 @@ <Ufe54> <U269> : "ɩ̄" <Ufe54> <U28a> : "ʊ̄" <Ufe54> <U28b> : "ʋ̄" -<Ufe54> <U6c1> : "а̄" -<Ufe54> <U6c5> : "е̄" -<Ufe54> <U6cf> : "о̄" -<Ufe54> <U6d2> : "р̄" -<Ufe54> <U6e1> : "А̄" -<Ufe54> <U6e5> : "Е̄" -<Ufe54> <U6ef> : "О̄" -<Ufe54> <U6f2> : "Р̄" <Ufe54> <U1e36> : "Ḹ" # U1e38 <Ufe54> <U1e37> : "ḹ" # U1e39 <Ufe54> <U1e5a> : "Ṝ" # U1e5c <Ufe54> <U1e5b> : "ṝ" # U1e5d <Ufe54> <Ufe54> : "¯" # Uaf -<Ufe54> <Ufe57> <U55> : "Ǖ" # U1d5 -<Ufe54> <Ufe57> <U75> : "ǖ" # U1d6 +<Ufe54> <Ufe50> <U45> : "Ḕ" # U1e14 +<Ufe54> <Ufe50> <U4f> : "Ṑ" # U1e50 +<Ufe54> <Ufe50> <U65> : "ḕ" # U1e15 +<Ufe54> <Ufe50> <U6f> : "ṑ" # U1e51 +<Ufe54> <Ufe51> <U45> : "Ḗ" # U1e16 +<Ufe54> <Ufe51> <U4f> : "Ṓ" # U1e52 +<Ufe54> <Ufe51> <U65> : "ḗ" # U1e17 +<Ufe54> <Ufe51> <U6f> : "ṓ" # U1e53 <Ufe54> <Ufe8c> <U41> : "Ᾱ" # U1fb9 <Ufe54> <Ufe8c> <U49> : "Ῑ" # U1fd9 <Ufe54> <Ufe8c> <U55> : "Ῡ" # U1fe9 @@ -580,6 +565,14 @@ <Ufe55> <U1ea0> : "Ặ" # U1eb6 <Ufe55> <U1ea1> : "ặ" # U1eb7 <Ufe55> <Ufe55> : "˘" # U2d8 +<Ufe55> <Ufe50> <U41> : "Ằ" # U1eb0 +<Ufe55> <Ufe50> <U61> : "ằ" # U1eb1 +<Ufe55> <Ufe51> <U41> : "Ắ" # U1eae +<Ufe55> <Ufe51> <U61> : "ắ" # U1eaf +<Ufe55> <Ufe53> <U41> : "Ẵ" # U1eb4 +<Ufe55> <Ufe53> <U61> : "ẵ" # U1eb5 +<Ufe55> <Ufe61> <U41> : "Ẳ" # U1eb2 +<Ufe55> <Ufe61> <U61> : "ẳ" # U1eb3 <Ufe55> <Uff20> <U21> <U41> : "Ặ" # U1eb6 <Ufe55> <Uff20> <U21> <U61> : "ặ" # U1eb7 <Ufe55> <Uff20> <U2c> <U45> : "Ḝ" # U1e1c @@ -600,6 +593,10 @@ <Ufe56> <U1e62> : "Ṩ" # U1e68 <Ufe56> <U1e63> : "ṩ" # U1e69 <Ufe56> <Ufe56> : "˙" # U2d9 +<Ufe56> <Ufe54> <U41> : "Ǡ" # U1e0 +<Ufe56> <Ufe54> <U4f> : "Ȱ" # U230 +<Ufe56> <Ufe54> <U61> : "ǡ" # U1e1 +<Ufe56> <Ufe54> <U6f> : "ȱ" # U231 <Ufe56> <Ufe63> <U6a> : "ɟ" # U25f <Ufe56> <Uff20> <U21> <U53> : "Ṩ" # U1e68 <Ufe56> <Uff20> <U21> <U73> : "ṩ" # U1e69 @@ -631,9 +628,21 @@ <Ufe57> <U4e8> : "Ӫ" # U4ea <Ufe57> <U4e9> : "ӫ" # U4eb <Ufe57> <Ufe57> : "¨" # Ua8 +<Ufe57> <Ufe50> <U55> : "Ǜ" # U1db +<Ufe57> <Ufe50> <U75> : "ǜ" # U1dc <Ufe57> <Ufe51> <U20> : "΅" # U385 -<Ufe57> <Ufe54> <U55> : "Ṻ" # U1e7a -<Ufe57> <Ufe54> <U75> : "ṻ" # U1e7b +<Ufe57> <Ufe51> <U49> : "Ḯ" # U1e2e +<Ufe57> <Ufe51> <U55> : "Ǘ" # U1d7 +<Ufe57> <Ufe51> <U69> : "ḯ" # U1e2f +<Ufe57> <Ufe51> <U75> : "ǘ" # U1d8 +<Ufe57> <Ufe51> <U7e9> : "ΐ" # U390 +<Ufe57> <Ufe51> <U7f5> : "ΰ" # U3b0 +<Ufe57> <Ufe54> <U41> : "Ǟ" # U1de +<Ufe57> <Ufe54> <U4f> : "Ȫ" # U22a +<Ufe57> <Ufe54> <U61> : "ǟ" # U1df +<Ufe57> <Ufe54> <U6f> : "ȫ" # U22b +<Ufe57> <Ufe5a> <U55> : "Ǚ" # U1d9 +<Ufe57> <Ufe5a> <U75> : "ǚ" # U1da <Ufe57> <Ufe6c> <U3d> : "⩷" # U2a77 <Ufe57> <Uff20> <U5f> <U55> : "Ṻ" # U1e7a <Ufe57> <Uff20> <U5f> <U75> : "ṻ" # U1e7b @@ -646,6 +655,8 @@ <Ufe58> <Uc1> : "Ǻ" # U1fa <Ufe58> <Ue1> : "ǻ" # U1fb <Ufe58> <Ufe58> : "°" # Ub0 +<Ufe58> <Ufe51> <U41> : "Ǻ" # U1fa +<Ufe58> <Ufe51> <U61> : "ǻ" # U1fb <Ufe59> <U20> : "˝" # U2dd <Ufe59> <Ua0> : "̋" # U30b <Ufe59> <Ufe59> : "˝" # U2dd @@ -682,6 +693,8 @@ <Ufe5a> <U28a> : "ʊ̌" <Ufe5a> <U28b> : "ʋ̌" <Ufe5a> <Ufe5a> : "ˇ" # U2c7 +<Ufe5a> <Ufe56> <U53> : "Ṧ" # U1e66 +<Ufe5a> <Ufe56> <U73> : "ṧ" # U1e67 <Ufe5a> <Uff20> <U22> <U55> : "Ǚ" # U1d9 <Ufe5a> <Uff20> <U22> <U75> : "ǚ" # U1da <Ufe5b> <U20> : "¸" # Ub8 @@ -787,42 +800,6 @@ <Ufe5d> <Ufe53> <U1f61> : "ᾧ" # U1fa7 <Ufe5d> <Ufe53> <U1f68> : "ᾮ" # U1fae <Ufe5d> <Ufe53> <U1f69> : "ᾯ" # U1faf -<Ufe5d> <Ufe50> <Ufe64> <U7c1> : "ᾊ" # U1f8a -<Ufe5d> <Ufe50> <Ufe64> <U7c7> : "ᾚ" # U1f9a -<Ufe5d> <Ufe50> <Ufe64> <U7d9> : "ᾪ" # U1faa -<Ufe5d> <Ufe50> <Ufe64> <U7e1> : "ᾂ" # U1f82 -<Ufe5d> <Ufe50> <Ufe64> <U7e7> : "ᾒ" # U1f92 -<Ufe5d> <Ufe50> <Ufe64> <U7f9> : "ᾢ" # U1fa2 -<Ufe5d> <Ufe50> <Ufe65> <U7c1> : "ᾋ" # U1f8b -<Ufe5d> <Ufe50> <Ufe65> <U7c7> : "ᾛ" # U1f9b -<Ufe5d> <Ufe50> <Ufe65> <U7d9> : "ᾫ" # U1fab -<Ufe5d> <Ufe50> <Ufe65> <U7e1> : "ᾃ" # U1f83 -<Ufe5d> <Ufe50> <Ufe65> <U7e7> : "ᾓ" # U1f93 -<Ufe5d> <Ufe50> <Ufe65> <U7f9> : "ᾣ" # U1fa3 -<Ufe5d> <Ufe51> <Ufe64> <U7c1> : "ᾌ" # U1f8c -<Ufe5d> <Ufe51> <Ufe64> <U7c7> : "ᾜ" # U1f9c -<Ufe5d> <Ufe51> <Ufe64> <U7d9> : "ᾬ" # U1fac -<Ufe5d> <Ufe51> <Ufe64> <U7e1> : "ᾄ" # U1f84 -<Ufe5d> <Ufe51> <Ufe64> <U7e7> : "ᾔ" # U1f94 -<Ufe5d> <Ufe51> <Ufe64> <U7f9> : "ᾤ" # U1fa4 -<Ufe5d> <Ufe51> <Ufe65> <U7c1> : "ᾍ" # U1f8d -<Ufe5d> <Ufe51> <Ufe65> <U7c7> : "ᾝ" # U1f9d -<Ufe5d> <Ufe51> <Ufe65> <U7d9> : "ᾭ" # U1fad -<Ufe5d> <Ufe51> <Ufe65> <U7e1> : "ᾅ" # U1f85 -<Ufe5d> <Ufe51> <Ufe65> <U7e7> : "ᾕ" # U1f95 -<Ufe5d> <Ufe51> <Ufe65> <U7f9> : "ᾥ" # U1fa5 -<Ufe5d> <Ufe53> <Ufe64> <U7c1> : "ᾎ" # U1f8e -<Ufe5d> <Ufe53> <Ufe64> <U7c7> : "ᾞ" # U1f9e -<Ufe5d> <Ufe53> <Ufe64> <U7d9> : "ᾮ" # U1fae -<Ufe5d> <Ufe53> <Ufe64> <U7e1> : "ᾆ" # U1f86 -<Ufe5d> <Ufe53> <Ufe64> <U7e7> : "ᾖ" # U1f96 -<Ufe5d> <Ufe53> <Ufe64> <U7f9> : "ᾦ" # U1fa6 -<Ufe5d> <Ufe53> <Ufe65> <U7c1> : "ᾏ" # U1f8f -<Ufe5d> <Ufe53> <Ufe65> <U7c7> : "ᾟ" # U1f9f -<Ufe5d> <Ufe53> <Ufe65> <U7d9> : "ᾯ" # U1faf -<Ufe5d> <Ufe53> <Ufe65> <U7e1> : "ᾇ" # U1f87 -<Ufe5d> <Ufe53> <Ufe65> <U7e7> : "ᾗ" # U1f97 -<Ufe5d> <Ufe53> <Ufe65> <U7f9> : "ᾧ" # U1fa7 <Ufe5d> <Uff20> <U27> <U7e1> : "ᾴ" # U1fb4 <Ufe5d> <Uff20> <U27> <U7e7> : "ῄ" # U1fc4 <Ufe5d> <Uff20> <U27> <U7f9> : "ῴ" # U1ff4 @@ -1175,18 +1152,6 @@ <Ufe63> <Ufe8c> <U72> : "ϼ" # U3fc <Ufe66> <U474> : "Ѷ" # U476 <Ufe66> <U475> : "ѷ" # U477 -<Ufe66> <U6c1> : "а̏" -<Ufe66> <U6c5> : "е̏" -<Ufe66> <U6c9> : "и̏" -<Ufe66> <U6cf> : "о̏" -<Ufe66> <U6d2> : "р̏" -<Ufe66> <U6d5> : "у̏" -<Ufe66> <U6e1> : "А̏" -<Ufe66> <U6e5> : "Е̏" -<Ufe66> <U6e9> : "И̏" -<Ufe66> <U6ef> : "О̏" -<Ufe66> <U6f2> : "Р̏" -<Ufe66> <U6f5> : "У̏" <Ufe67> <U7c> : "⫰" # U2af0 <Ufe6a> <U2b> : "⨦" # U2a26 <Ufe6c> <Ufe57> <U3d> : "⩷" # U2a77 diff --git a/testsuite/gtk/composetable.c b/testsuite/gtk/composetable.c index 1a77e5bc93..dec41af467 100644 --- a/testsuite/gtk/composetable.c +++ b/testsuite/gtk/composetable.c @@ -310,81 +310,86 @@ match_algorithmic (void) { guint16 buffer[8] = { 0, }; gboolean ret; - gunichar ch; + GString *output; + + output = g_string_new (""); buffer[0] = GDK_KEY_a; buffer[1] = GDK_KEY_b; - ret = gtk_check_algorithmically (buffer, 2, &ch); + ret = gtk_check_algorithmically (buffer, 2, output); g_assert_false (ret); - g_assert_true (ch == 0); + g_assert_cmpstr (output->str, ==, ""); buffer[0] = GDK_KEY_dead_abovering; buffer[1] = GDK_KEY_A; - ret = gtk_check_algorithmically (buffer, 2, &ch); + ret = gtk_check_algorithmically (buffer, 2, output); g_assert_true (ret); - g_assert_true (ch == 0xc5); + g_assert_cmpstr (output->str, ==, "Å"); buffer[0] = GDK_KEY_A; buffer[1] = GDK_KEY_dead_abovering; - ret = gtk_check_algorithmically (buffer, 2, &ch); + ret = gtk_check_algorithmically (buffer, 2, output); g_assert_false (ret); - g_assert_true (ch == 0); + g_assert_cmpstr (output->str, ==, ""); buffer[0] = GDK_KEY_dead_dasia; buffer[1] = GDK_KEY_dead_perispomeni; buffer[2] = GDK_KEY_Greek_alpha; - ret = gtk_check_algorithmically (buffer, 3, &ch); + ret = gtk_check_algorithmically (buffer, 3, output); g_assert_true (ret); - g_assert_true (ch == 0x1f07); + g_assert_cmpstr (output->str, ==, "ᾶ\xcc\x94"); buffer[0] = GDK_KEY_dead_perispomeni; buffer[1] = GDK_KEY_dead_dasia; buffer[2] = GDK_KEY_Greek_alpha; - ret = gtk_check_algorithmically (buffer, 3, &ch); + ret = gtk_check_algorithmically (buffer, 3, output); g_assert_true (ret); - g_assert_true (ch == 0x1f07); + g_assert_cmpstr (output->str, ==, "ἇ"); buffer[0] = GDK_KEY_dead_acute; buffer[1] = GDK_KEY_dead_cedilla; buffer[2] = GDK_KEY_c; - ret = gtk_check_algorithmically (buffer, 2, &ch); + ret = gtk_check_algorithmically (buffer, 2, output); g_assert_true (ret); - g_assert_cmphex (ch, ==, 0); + g_assert_cmpstr (output->str, ==, ""); - ret = gtk_check_algorithmically (buffer, 3, &ch); + ret = gtk_check_algorithmically (buffer, 3, output); g_assert_true (ret); - g_assert_cmphex (ch, ==, 0x1e09); + g_assert_cmpstr (output->str, ==, "ḉ"); buffer[0] = GDK_KEY_dead_cedilla; buffer[1] = GDK_KEY_dead_acute; buffer[2] = GDK_KEY_c; - ret = gtk_check_algorithmically (buffer, 3, &ch); + ret = gtk_check_algorithmically (buffer, 3, output); g_assert_true (ret); - g_assert_cmphex (ch, ==, 0x1e09); + g_assert_cmpstr (output->str, ==, "ḉ"); - ret = gtk_check_algorithmically (buffer, 2, &ch); + ret = gtk_check_algorithmically (buffer, 2, output); g_assert_true (ret); buffer[0] = GDK_KEY_dead_acute; buffer[1] = GDK_KEY_dead_cedilla; buffer[2] = GDK_KEY_dead_grave; - ret = gtk_check_algorithmically (buffer, 3, &ch); - g_assert_false (ret); + ret = gtk_check_algorithmically (buffer, 3, output); + g_assert_true (ret); + g_assert_cmpstr (output->str, ==, ""); buffer[0] = GDK_KEY_dead_diaeresis; buffer[1] = GDK_KEY_a; - ret = gtk_check_algorithmically (buffer, 2, &ch); + ret = gtk_check_algorithmically (buffer, 2, output); g_assert_true (ret); - g_assert_cmphex (ch, ==, 0xe4); + g_assert_cmpstr (output->str, ==, "ä"); + + g_string_free (output, TRUE); } int |