public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Takao Fujiwara <tfujiwar@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/ibus] autotool: Delete upstreamed patches
Date: Sun, 31 May 2026 02:07:40 GMT	[thread overview]
Message-ID: <178019326059.1.17452965003865725176.rpms-ibus-9fc0c9da0a16@fedoraproject.org> (raw)

A new commit has been pushed.

Repo   : rpms/ibus
Branch : autotool
Commit : 9fc0c9da0a16d5b6fdac3d8d78741c4336c9f76d
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date   : 2021-08-20T15:55:45+09:00
Stats  : +0/-6201 in 1 file(s)
URL    : https://src.fedoraproject.org/rpms/ibus/c/9fc0c9da0a16d5b6fdac3d8d78741c4336c9f76d?branch=autotool

Log:
Delete upstreamed patches

---
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
index 0b56af7..05c3c97 100644
--- a/ibus-HEAD.patch
+++ b/ibus-HEAD.patch
@@ -1,6204 +1,3 @@
-From 214b60a3af67b6e8dafdb8edba666a369f18be12 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 26 Mar 2021 22:48:08 +0900
-Subject: [PATCH] src/tests: Run gnome-session with no-overview mode
-
-gnome-shell 40 now shows the overview mode by login and
-gnome-desktop-testing-runner cannot get the input focus.
-Running gnome-session with no-overview shell extension can
-get the input focus or mutter is another option.
-The default may be changed to twm if mutter also will be changed
-not to accept the application focus in the future.
-
-Disable Tour dialog which prevent test application from getting the
-input focus.
-
-Don't output FAIL if the actual failure is 0 for Fedora CI.
-
-BUG=https://discourse.gnome.org/t/focus-on-autostart-application-by-login/5863
----
- src/tests/ibus-desktop-testing-runner.in | 69 ++++++++++++++++++++----
- 1 file changed, 60 insertions(+), 9 deletions(-)
-
-diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in
-index 4232c549..15b2369d 100755
---- a/src/tests/ibus-desktop-testing-runner.in
-+++ b/src/tests/ibus-desktop-testing-runner.in
-@@ -4,7 +4,7 @@
- #
- # ibus - The Input Bus
- #
--# Copyright (c) 2018-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+# Copyright (c) 2018-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
- # Copyright (c) 2018 Red Hat, Inc.
- #
- # This program is free software; you can redistribute it and/or modify
-@@ -36,7 +36,7 @@
- 
- 
- PROGNAME=`basename $0`
--VERSION=0.1
-+VERSION=0.2
- DISPLAY=:99.0
- BUILDDIR="."
- SRCDIR="."
-@@ -80,7 +80,9 @@ usage()
- "-b, --builddir=BUILDDIR          Set the BUILDDIR\n"                          \
- "-s, --srcdir=SOURCEDIR           Set the SOURCEDIR\n"                         \
- "-c, --no-graphics                Use Xvfb instead of Xorg\n"                  \
--"-d, --desktop=DESKTOP            Run DESTKTOP. The default is gnome-session\n" \
-+"-d, --desktop=DESKTOP            Run DESTKTOP. The default is gnome-session.\n" \
-+"                                 Suffix '-with-dbus' can run DESKTOP with dbus session." \
-+"                                 E.g. --desktop=mutter-with-dbus"             \
- "-t, --tests=\"TESTS...\"           Run TESTS programs which is separated by space\n" \
- "-r, --runner=RUNNER              Run TESTS programs with a test RUNNER.\n"    \
- "                                 RUNNDER = gnome or default.\n"               \
-@@ -115,6 +117,13 @@ parse_args()
-         * )                  usage; exit 1;;
-         esac
-     done
-+    DL='$'
-+    echo "$DESKTOP_COMMAND" | grep "\-with\-dbus$DL" > /dev/null
-+    HAS_DBUS_SUFFIX=$?
-+    if [ $HAS_DBUS_SUFFIX -eq 0 ] ; then
-+        DESKTOP_COMMAND=`echo "$DESKTOP_COMMAND" | sed -e 's/-with-dbus$//'`
-+        DESKTOP_COMMAND="dbus-launch --exit-with-session $DESKTOP_COMMAND"
-+    fi
- }
- 
- init_desktop()
-@@ -124,8 +133,9 @@ init_desktop()
-             rm $RESULT_LOG
-         fi
-     fi
--    HAS_STDOUT=`echo "$TEST_LOG" | grep ':stdout'`
--    if [ x"$HAS_STDOUT" != x ] ; then
-+    echo "$TEST_LOG" | grep ':stdout' > /dev/null
-+    HAS_STDOUT=$?
-+    if [ $HAS_STDOUT -eq 0 ] ; then
-         TEST_LOG=`echo "$TEST_LOG" | sed -e 's|:stdout||'`
-         TEST_LOG_STDOUT=1
-     fi
-@@ -203,6 +213,39 @@ run_dbus_daemon()
-     export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus"
- }
- 
-+init_gnome()
-+{
-+    # Disable Tour dialog to get focus
-+    V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version`
-+    if [ x"$V" = x ] ; then
-+        gsettings set org.gnome.shell welcome-dialog-last-shown-version '100'
-+    fi
-+    # gnome-shell now starts overview mode by login.
-+    # https://extensions.gnome.org/extension/4099/no-overview/
-+    NO_SYS_DIR=/usr/share/gnome-shell/extensions/no-overview@fthx
-+    NO_USER_DIR=$HOME/.local/share/gnome-shell/extensions/no-overview@fthx
-+    if [ ! -d $NO_SYS_DIR ] && [ ! -d $NO_USER_DIR ] ; then
-+        mkdir -p `dirname $NO_USER_DIR`
-+        cp -R no-overview@fthx `dirname $NO_USER_DIR`
-+    fi
-+    V=`gsettings get org.gnome.shell disable-user-extensions`
-+    if [ x"$V" = x"true" ] ; then
-+        gsettings set org.gnome.shell disable-user-extensions false
-+    fi
-+    V=`gsettings get org.gnome.shell enabled-extensions`
-+    echo "$V" | grep "no-overview" > /dev/null
-+    V2=$?
-+    if [ $V2 -ne 0 ] ; then
-+        V3=`echo "$V" | sed -e 's/\[//' -e 's/\]//'`
-+        if [ x"$V3" = x ] ; then
-+            V4="['no-overview@fthx']"
-+        else
-+            V4="[$V3, 'no-overview@fthx']"
-+        fi
-+        gsettings set org.gnome.shell enabled-extensions "$V4"
-+    fi
-+}
-+
- run_desktop()
- {
-     if test $HAVE_GRAPHICS -eq 1 ; then
-@@ -217,8 +260,11 @@ run_desktop()
-     $DESKTOP_COMMAND &
-     PID_GNOME_SESSION=$!
-     sleep 30
--    HAS_GNOME=`echo $DESKTOP_COMMAND | grep gnome-session`
--    if [ x"$HAS_GNOME" = x ] ; then
-+    echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null
-+    HAS_GNOME=$?
-+    if [  $HAS_GNOME -eq 0 ] ; then
-+        init_gnome
-+    else
-         ibus-daemon --daemonize --verbose
-         sleep 3
-     fi
-@@ -360,8 +406,13 @@ EOF_RUNNER
-         ;;
-     esac
-     echo ""
--    print_log -e "${GREEN}PASS${NC}: $pass"
--    print_log -e "${RED}FAIL${NC}: $fail"
-+    # Fedora CI assumes the test is failed even if $fail is 0.
-+    if [ $pass -ne 0 ] ; then
-+        print_log -e "${GREEN}PASS${NC}: $pass"
-+    fi
-+    if [ $fail -ne 0 ] ; then
-+        print_log -e "${RED}FAIL${NC}: $fail"
-+    fi
-     echo ""
-     if [ $TEST_LOG_STDOUT -eq 1 ] ; then
-         cat $TEST_LOG
--- 
-2.28.0
-
-From d105a3941aad53b0c7470a1e9c1033987b029fb8 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 12 May 2021 18:54:30 +0900
-Subject: [PATCH] client/gtk2: Implement
- ibus_im_context_set_surrounding_with_selection()
-
-Selection bounds need to be re-calculated when pre-edit text is
-inserted and the selection position is changed.
-GTK4 has a new API GtkIMContext.set_surrounding_with_selection()
-to fix this issue and now IBus GTK module inherits the API.
-
-BUG=https://github.com/ibus/ibus/issues/2013
----
- client/gtk2/ibusimcontext.c | 53 ++++++++++++++++++++++++++++++-------
- 1 file changed, 44 insertions(+), 9 deletions(-)
-
-diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
-index e153081d..61194816 100644
---- a/client/gtk2/ibusimcontext.c
-+++ b/client/gtk2/ibusimcontext.c
-@@ -2,8 +2,8 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
-- * Copyright (C) 2008-2020 Red Hat, Inc.
-+ * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2008-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -165,11 +165,19 @@ static void     ibus_im_context_set_cursor_location
- static void     ibus_im_context_set_use_preedit
-                                             (GtkIMContext           *context,
-                                              gboolean               use_preedit);
-+#if !GTK_CHECK_VERSION (4, 1, 2)
- static void     ibus_im_context_set_surrounding
-                                             (GtkIMContext  *slave,
-                                              const gchar   *text,
--                                             gint           len,
--                                             gint           cursor_index);
-+                                             int            len,
-+                                             int            cursor_index);
-+#endif
-+static void     ibus_im_context_set_surrounding_with_selection
-+                                            (GtkIMContext  *slave,
-+                                             const gchar   *text,
-+                                             int            len,
-+                                             int            cursor_index,
-+                                             int            anchor_index);
- 
- /* static methods*/
- static void     _ibus_context_update_preedit_text_cb
-@@ -724,7 +732,12 @@ ibus_im_context_class_init (IBusIMContextClass *class)
- #endif
-     im_context_class->set_cursor_location = ibus_im_context_set_cursor_location;
-     im_context_class->set_use_preedit = ibus_im_context_set_use_preedit;
-+#if GTK_CHECK_VERSION (4, 1, 2)
-+    im_context_class->set_surrounding_with_selection
-+            = ibus_im_context_set_surrounding_with_selection;
-+#else
-     im_context_class->set_surrounding = ibus_im_context_set_surrounding;
-+#endif
-     gobject_class->notify = ibus_im_context_notify;
-     gobject_class->finalize = ibus_im_context_finalize;
- 
-@@ -1624,8 +1637,22 @@ get_selection_anchor_point (IBusIMContext *ibusimcontext,
- static void
- ibus_im_context_set_surrounding (GtkIMContext  *context,
-                                  const gchar   *text,
--                                 gint           len,
--                                 gint           cursor_index)
-+                                 int            len,
-+                                 int            cursor_index)
-+{
-+    ibus_im_context_set_surrounding_with_selection (context,
-+                                                    text,
-+                                                    len,
-+                                                    cursor_index,
-+                                                    cursor_index);
-+}
-+
-+static void
-+ibus_im_context_set_surrounding_with_selection (GtkIMContext  *context,
-+                                                const gchar   *text,
-+                                                int            len,
-+                                                int            cursor_index,
-+                                                int            anchor_index)
- {
-     g_return_if_fail (context != NULL);
-     g_return_if_fail (IBUS_IS_IM_CONTEXT (context));
-@@ -1647,18 +1674,26 @@ ibus_im_context_set_surrounding (GtkIMContext  *context,
-         ibustext = ibus_text_new_from_string (p);
-         g_free (p);
- 
--        guint anchor_pos = get_selection_anchor_point (ibusimcontext,
--                                                       cursor_pos,
--                                                       utf8_len);
-+        gint anchor_pos = get_selection_anchor_point (ibusimcontext,
-+                                                      cursor_pos,
-+                                                      utf8_len);
-         ibus_input_context_set_surrounding_text (ibusimcontext->ibuscontext,
-                                                  ibustext,
-                                                  cursor_pos,
-                                                  anchor_pos);
-     }
-+#if GTK_CHECK_VERSION (4, 1, 2)
-+    gtk_im_context_set_surrounding_with_selection (ibusimcontext->slave,
-+                                                   text,
-+                                                   len,
-+                                                   cursor_index,
-+                                                   anchor_index);
-+#else
-     gtk_im_context_set_surrounding (ibusimcontext->slave,
-                                     text,
-                                     len,
-                                     cursor_index);
-+#endif
- }
- 
- static void
--- 
-2.28.0
-
-From e9e1642870994abfdbd06b0138524ac231c159b8 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 16 Jun 2021 18:00:31 +0900
-Subject: [PATCH] Fix code reviews
-
----
- bus/ibusimpl.c                |  23 ++++--
- bus/server.c                  |  10 +--
- client/gtk2/ibusimcontext.c   |   8 ++
- client/wayland/main.c         |   9 ++-
- client/x11/main.c             |  22 +++--
- conf/dconf/main.c             |   7 +-
- portal/portal.c               |   7 +-
- setup/ibus-setup.in           |   2 +-
- src/emoji-parser.c            |  46 ++++++-----
- src/ibusaccelgroup.c          |   2 +-
- src/ibusbus.c                 |  10 ++-
- src/ibuscomposetable.c        |  91 ++++++++++++++++++---
- src/ibusemoji.c               |   8 +-
- src/ibusenginesimple.c        |  21 +++--
- src/ibushotkey.c              |   4 +-
- src/ibusregistry.c            |   9 ++-
- src/ibusshare.c               |  36 +++++----
- src/ibustext.c                |   5 +-
- src/ibusunicode.c             |  17 +++-
- src/tests/ibus-compose.c      |   6 +-
- src/tests/ibus-keypress.c     |   3 +-
- src/unicode-parser.c          |  52 ++++++------
- util/IMdkit/FrameMgr.c        |  34 +++++++-
- util/IMdkit/i18nIc.c          |  41 ++++++++--
- util/IMdkit/i18nMethod.c      |  24 +++++-
- util/IMdkit/i18nOffsetCache.c |   2 +-
- util/IMdkit/i18nPtHdr.c       | 148 ++++++++++++++++++++++++++++------
- util/IMdkit/i18nUtil.c        |  20 +++++
- util/IMdkit/i18nX.c           |  29 ++++---
- 29 files changed, 524 insertions(+), 172 deletions(-)
-
-diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
-index e432e849..49a138fe 100644
---- a/bus/ibusimpl.c
-+++ b/bus/ibusimpl.c
-@@ -2,8 +2,8 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2011-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
-- * Copyright (C) 2008-2020 Red Hat, Inc.
-+ * Copyright (C) 2011-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2008-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -624,7 +624,6 @@ bus_ibus_impl_destroy (BusIBusImpl *ibus)
- 
-     g_list_foreach (ibus->components, (GFunc) bus_component_stop, NULL);
- 
--    pid = 0;
-     timeout = 0;
-     flag = FALSE;
-     while (1) {
-@@ -1190,6 +1189,7 @@ _ibus_get_current_input_context (BusIBusImpl     *ibus,
-                                  GDBusConnection *connection,
-                                  GError         **error)
- {
-+    GVariant *retval = NULL;
-     if (error) {
-         *error = NULL;
-     }
-@@ -1204,8 +1204,14 @@ _ibus_get_current_input_context (BusIBusImpl     *ibus,
-         const gchar *path = ibus_service_get_object_path (
-                 (IBusService *) ibus->focused_context);
-         /* the format-string 'o' is for a D-Bus object path. */
--        return g_variant_new_object_path (path);
-+        retval = g_variant_new_object_path (path);
-+        if (!retval) {
-+            g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
-+                         "Could not get object path from %s",
-+                         path ? path : "(null)");
-+        }
-     }
-+    return retval;
- }
- 
- static void
-@@ -1572,6 +1578,7 @@ _ibus_get_global_engine (BusIBusImpl     *ibus,
-                          GError         **error)
- {
-     IBusEngineDesc *desc = NULL;
-+    GVariant *retval = NULL;
- 
-     if (error) {
-         *error = NULL;
-@@ -1592,7 +1599,13 @@ _ibus_get_global_engine (BusIBusImpl     *ibus,
-         GVariant *variant = ibus_serializable_serialize (
-                 (IBusSerializable *) desc);
-         // Set type "v" for introspection_xml.
--        return g_variant_new_variant (variant);
-+        retval = g_variant_new_variant (variant);
-+        if (!retval) {
-+            g_set_error (error,
-+                         G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
-+                         "Failed to serialize engine desc.");
-+        }
-+        return retval;
-     } while (0);
- 
-     g_set_error (error,
-diff --git a/bus/server.c b/bus/server.c
-index 6c9e2c02..e8d0ce2b 100644
---- a/bus/server.c
-+++ b/bus/server.c
-@@ -2,8 +2,8 @@
- /* vim:set et sts=4: */
- /* bus - The Input Bus
-  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2011-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-- * Copyright (C) 2008-2019 Red Hat, Inc.
-+ * Copyright (C) 2011-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2008-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -22,12 +22,11 @@
-  */
- #include "server.h"
- 
--#include <errno.h>
- #include <glib/gstdio.h>
- #include <gio/gio.h>
--#include <stdlib.h>
--#include <fcntl.h>
- #include <errno.h>
-+#include <fcntl.h>
-+#include <stdlib.h>
- #include <string.h>
- 
- #include "dbusimpl.h"
-@@ -282,6 +281,7 @@ bus_server_init (void)
-          * `chmod` runs for the last directory only not to change the modes
-          * of the parent directories. E.g. "/tmp/ibus".
-          */
-+        errno = 0;
-         if (g_mkdir_with_parents (unix_dir, 0700) != 0) {
-             g_error ("mkdir is failed in: %s: %s",
-                      unix_dir, g_strerror (errno));
-diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
-index 61194816..e7ce5363 100644
---- a/client/gtk2/ibusimcontext.c
-+++ b/client/gtk2/ibusimcontext.c
-@@ -385,7 +385,9 @@ _process_key_event_done (GObject      *object,
- 
-     ProcessKeyEventData *data = (ProcessKeyEventData *)user_data;
-     GdkEvent *event = data->event;
-+#if GTK_CHECK_VERSION (3, 98, 4)
-     IBusIMContext *ibusimcontext = data->ibusimcontext;
-+#endif
-     GError *error = NULL;
- 
-     g_slice_free (ProcessKeyEventData, data);
-@@ -1634,6 +1636,7 @@ get_selection_anchor_point (IBusIMContext *ibusimcontext,
-     return anchor;
- }
- 
-+#if !GTK_CHECK_VERSION (4, 1, 2)
- static void
- ibus_im_context_set_surrounding (GtkIMContext  *context,
-                                  const gchar   *text,
-@@ -1646,6 +1649,7 @@ ibus_im_context_set_surrounding (GtkIMContext  *context,
-                                                     cursor_index,
-                                                     cursor_index);
- }
-+#endif
- 
- static void
- ibus_im_context_set_surrounding_with_selection (GtkIMContext  *context,
-@@ -1851,7 +1855,11 @@ _create_gdk_event (IBusIMContext *ibusimcontext,
-         if (event->state & GDK_CONTROL_MASK) {
-             if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
-             else if (c == '2') {
-+#if GLIB_CHECK_VERSION (2, 68, 0)
-+                event->string = g_memdup2 ("\0\0", 2);
-+#else
-                 event->string = g_memdup ("\0\0", 2);
-+#endif
-                 event->length = 1;
-                 buf[0] = '\0';
-                 goto out;
-diff --git a/client/wayland/main.c b/client/wayland/main.c
-index d86bab9e..1f99c804 100644
---- a/client/wayland/main.c
-+++ b/client/wayland/main.c
-@@ -1,7 +1,7 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-- * Copyright (C) 2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2019-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2013 Intel Corporation
-  * Copyright (C) 2013-2019 Red Hat, Inc.
-  *
-@@ -339,16 +339,19 @@ input_method_keyboard_keymap (void               *data,
- {
-     IBusWaylandIM *wlim = data;
-     GMappedFile *map;
--    GError *error;
-+    GError *error = NULL;
- 
-     if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
-         close(fd);
-         return;
-     }
- 
--    error = NULL;
-     map = g_mapped_file_new_from_fd (fd, FALSE, &error);
-     if (map == NULL) {
-+        if (error) {
-+            g_warning ("Failed to map file fd %s", error->message);
-+            g_error_free (error);
-+        }
-         close (fd);
-         return;
-     }
-diff --git a/client/x11/main.c b/client/x11/main.c
-index c9ee174d..ffd776fd 100644
---- a/client/x11/main.c
-+++ b/client/x11/main.c
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* ibus
-  * Copyright (C) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2007-2015 Red Hat, Inc.
-  *
-  * main.c:
-@@ -229,12 +229,13 @@ _xim_preedit_callback_draw (XIMS xims, X11IC *x11ic, const gchar *preedit_string
-         }
-     }
- 
--    for (i = 0; i < len; i++) {
-+    for (i = 0; feedback && i < len; i++) {
-         if (feedback[i] == 0) {
-             feedback[i] = XIMUnderline;
-         }
-     }
--    feedback[len] = 0;
-+    if (feedback)
-+        feedback[len] = 0;
- 
-     pcb.major_code = XIM_PREEDIT_DRAW;
-     pcb.connect_id = x11ic->connect_id;
-@@ -736,9 +737,20 @@ xim_get_ic_values (XIMS xims, IMChangeICStruct *call_data)
- 
-     for (i = 0; i < (int) call_data->ic_attr_num; ++i, ++ic_attr) {
-         if (g_strcmp0 (XNFilterEvents, ic_attr->name) == 0) {
-+            /* ic_attr->value will be freed in server side and ignore
-+             * leak of malloc with -Wanalyzer-malloc-leak flags in gcc 11.0.1
-+             */
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
-             ic_attr->value = (void *) malloc (sizeof (CARD32));
--            *(CARD32 *) ic_attr->value = KeyPressMask | KeyReleaseMask;
--            ic_attr->value_length = sizeof (CARD32);
-+            if (ic_attr->value) {
-+                *(CARD32 *) ic_attr->value = KeyPressMask | KeyReleaseMask;
-+                ic_attr->value_length = sizeof (CARD32);
-+            } else {
-+                g_warning ("Failed to malloc");
-+                ic_attr->value_length = 0;
-+            }
-+#pragma GCC diagnostic pop
-         }
-     }
- 
-diff --git a/conf/dconf/main.c b/conf/dconf/main.c
-index e6878424..c8250f68 100644
---- a/conf/dconf/main.c
-+++ b/conf/dconf/main.c
-@@ -2,7 +2,8 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2008-2010 Red Hat, Inc.
-+ * Copyright (C) 2012-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2008-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -70,7 +71,9 @@ main (gint argc, gchar **argv)
-     GOptionContext *context;
- 
-     setlocale (LC_ALL, "");
--    g_setenv ("DCONF_PROFILE", "ibus", FALSE);
-+    errno = 0;
-+    if (!g_setenv ("DCONF_PROFILE", "ibus", FALSE))
-+        g_warning ("Failed setenv %s", strerror (errno));
- 
-     context = g_option_context_new ("- ibus dconf component");
- 
-diff --git a/portal/portal.c b/portal/portal.c
-index e78bc92f..c2e4fc7f 100644
---- a/portal/portal.c
-+++ b/portal/portal.c
-@@ -1,7 +1,7 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-- * Copyright (C) 2017-2019 Red Hat, Inc.
-+ * Copyright (C) 2017-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -508,7 +508,6 @@ create_input_context_done (IBusBus               *bus,
-     if (portal_context == NULL) {
-         g_dbus_method_invocation_return_gerror (invocation, error);
-         g_error_free (error);
--        g_object_unref (portal_context);
-         return;
-     }
- 
-@@ -656,8 +655,10 @@ main (gint argc, gchar **argv)
-         exit (-1);
-     }
- 
-+     errno = 0;
-     /* Avoid even loading gvfs to avoid accidental confusion */
--    g_setenv ("GIO_USE_VFS", "local", TRUE);
-+    if (!g_setenv ("GIO_USE_VFS", "local", TRUE))
-+        g_warning ("Failed setenv %s", strerror (errno));
- 
-     ibus_init ();
- 
-diff --git a/setup/ibus-setup.in b/setup/ibus-setup.in
-index 4a6830af..474ce8a8 100644
---- a/setup/ibus-setup.in
-+++ b/setup/ibus-setup.in
-@@ -27,5 +27,5 @@ export IBUS_PREFIX=@prefix@
- export IBUS_DATAROOTDIR=@datarootdir@
- export IBUS_LOCALEDIR=@localedir@
- export IBUS_LIBEXECDIR=${libexecdir}
--exec ${PYTHON:-@PYTHON@} @prefix@/share/ibus/setup/main.py $@
-+exec ${PYTHON:-@PYTHON@} @prefix@/share/ibus/setup/main.py "$@"
- 
-diff --git a/src/emoji-parser.c b/src/emoji-parser.c
-index b117b1b4..36d36e05 100644
---- a/src/emoji-parser.c
-+++ b/src/emoji-parser.c
-@@ -1,7 +1,7 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-- * Copyright (C) 2016-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2016-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2016 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -291,11 +291,9 @@ emoji_data_new_object (EmojiData *data)
-                                  "annotations",
-                                  data->annotations,
-                                  "description",
--                                 data->description ? data->description
--                                         : g_strdup (""),
-+                                 data->description ? data->description : "",
-                                  "category",
--                                 data->category ? data->category
--                                         : g_strdup (""),
-+                                 data->category ? data->category : "",
-                                  NULL);
-     data->list = g_slist_append (data->list, emoji);
- }
-@@ -608,7 +606,7 @@ unicode_emoji_test_parse_line (const gchar *line,
-         return FALSE;
-     }
-     unicode_emoji_test_parse_description (segments[1], data);
--    g_strfreev (segments);
-+    g_clear_pointer (&segments, g_strfreev);
-     if (data->annotations == NULL) {
-         if (data->subcategory) {
-             int i;
-@@ -631,7 +629,7 @@ unicode_emoji_test_parse_line (const gchar *line,
-                 data->annotations = g_slist_append (data->annotations,
-                                                     g_strdup (segments[i]));
-             }
--            g_strfreev (segments);
-+            g_clear_pointer (&segments, g_strfreev);
-         } else {
-             g_warning ("No subcategory line\n");
-             goto failed_to_parse_unicode_emoji_test_line;
-@@ -672,7 +670,7 @@ unicode_emoji_test_parse_file (const gchar *filename,
-                    filename, error ? error->message : "");
-         goto failed_to_parse_unicode_emoji_test;
-     }
--    head = end = content;
-+    end = content;
-     while (*end == '\n' && end - content < length) {
-         end++;
-         n++;
-@@ -1100,10 +1098,12 @@ static void
- category_list_dump (const gchar *category,
-                     GString     *buff)
- {
-+    gchar *line;
-     g_return_if_fail (buff != NULL);
- 
--    const gchar *line = g_strdup_printf ("    N_(\"%s\"),\n", category);
-+    line = g_strdup_printf ("    N_(\"%s\"),\n", category);
-     g_string_append (buff, line);
-+    g_free (line);
- }
- 
- static void
-@@ -1113,7 +1113,7 @@ category_file_save (const gchar *filename,
-     gchar *content = NULL;
-     gsize length = 0;
-     GError *error = NULL;
--    gchar *p;
-+    gchar *p, *substr;
-     GString *buff = NULL;
-     int i;
-     GSList *list_categories = NULL;
-@@ -1139,24 +1139,28 @@ category_file_save (const gchar *filename,
-             break;
-     }
-     if (p != NULL) {
--        g_string_append (buff, g_strndup (content, p - content));
-+        substr = g_strndup (content, p - content);
-+        g_string_append (buff, substr);
-+        g_free (substr);
-         g_string_append_c (buff, '\n');
-     }
-     g_clear_pointer (&content, g_free);
- 
--    g_string_append (buff, g_strdup ("\n"));
--    g_string_append (buff, g_strdup_printf ("/* This file is generated by %s. */", __FILE__));
--    g_string_append (buff, g_strdup ("\n"));
--    g_string_append (buff, g_strdup ("include <glib/gi18n.h>\n"));
--    g_string_append (buff, g_strdup ("\n"));
--    g_string_append (buff, g_strdup ("#ifndef __IBUS_EMOJI_GEN_H_\n"));
--    g_string_append (buff, g_strdup ("#define __IBUS_EMOJI_GEN_H_\n"));
--    g_string_append (buff, g_strdup ("const static char *unicode_emoji_categories[] = {\n"));
-+    g_string_append (buff, "\n");
-+    substr = g_strdup_printf ("/* This file is generated by %s. */", __FILE__);
-+    g_string_append (buff, substr);
-+    g_free (substr);
-+    g_string_append (buff, "\n");
-+    g_string_append (buff, "include <glib/gi18n.h>\n");
-+    g_string_append (buff, "\n");
-+    g_string_append (buff, "#ifndef __IBUS_EMOJI_GEN_H_\n");
-+    g_string_append (buff, "#define __IBUS_EMOJI_GEN_H_\n");
-+    g_string_append (buff, "const static char *unicode_emoji_categories[] = {\n");
-     list_categories = g_slist_sort (list_categories, (GCompareFunc)g_strcmp0);
-     g_slist_foreach (list_categories, (GFunc)category_list_dump, buff);
-     g_slist_free (list_categories);
--    g_string_append (buff, g_strdup ("};\n"));
--    g_string_append (buff, g_strdup ("#endif\n"));
-+    g_string_append (buff, "};\n");
-+    g_string_append (buff, "#endif\n");
- 
-     if (!g_file_set_contents (filename, buff->str, -1, &error)) {
-         g_warning ("Failed to save emoji category file %s: %s", filename, error->message);
-diff --git a/src/ibusaccelgroup.c b/src/ibusaccelgroup.c
-index 8a81597e..ef2d3976 100644
---- a/src/ibusaccelgroup.c
-+++ b/src/ibusaccelgroup.c
-@@ -468,7 +468,7 @@ ibus_accelerator_name (guint            accelerator_key,
-     if (accelerator_mods & IBUS_SUPER_MASK)
-         l += sizeof (text_super) - 1;
- 
--    accelerator = g_new (gchar, l + 1);
-+    g_return_val_if_fail ((accelerator = g_new (gchar, l + 1)), NULL);
- 
-     accelerator_mods = saved_mods;
-     l = 0;
-diff --git a/src/ibusbus.c b/src/ibusbus.c
-index b7ffbb47..e9b0bcbb 100644
---- a/src/ibusbus.c
-+++ b/src/ibusbus.c
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2008-2016 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -555,12 +555,18 @@ ibus_bus_init (IBusBus *bus)
- 
-     path = g_path_get_dirname (ibus_get_socket_path ());
- 
--    g_mkdir_with_parents (path, 0700);
-+    errno = 0;
-+    if (g_mkdir_with_parents (path, 0700)) {
-+        g_warning ("Failed to mkdir %s: %s", path, g_strerror (errno));
-+        g_free (path);
-+        return;
-+    }
- 
-     if (stat (path, &buf) == 0) {
-         if (buf.st_uid != getuid ()) {
-             g_warning ("The owner of %s is not %s!",
-                        path, ibus_get_user_name ());
-+            g_free (path);
-             return;
-         }
-         if (buf.st_mode != (S_IFDIR | S_IRWXU)) {
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index ef20469c..685ac717 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -1,7 +1,7 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- /* ibus - The Input Bus
-  * Copyright (C) 2013-2014 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2013-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2013-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -108,6 +108,7 @@ parse_compose_value (IBusComposeData  *compose_data,
-     }
-     ++head;
-     p = head;
-+    end = NULL;
-     while ((*p != '\0') && (end = strchr (p, '\"'))) {
-         if (*(end - 1) == '\\' && *(end - 2) == '\\')
-             break;
-@@ -516,10 +517,10 @@ ibus_compose_hash_get_cache_path (guint32 hash)
-                                 "ibus", "compose", NULL);
-     }
-     path = g_build_filename (dir, basename, NULL);
--    if (g_mkdir_with_parents (dir, 0755) != 0) {
--        g_warning ("Failed to mkdir %s", dir);
--        g_free (path);
--        path = NULL;
-+    errno = 0;
-+    if (g_mkdir_with_parents (dir, 0755)) {
-+        g_warning ("Failed to mkdir %s: %s", dir, g_strerror (errno));
-+        g_clear_pointer (&path, g_free);
-     }
- 
-     g_free (dir);
-@@ -812,10 +813,14 @@ ibus_compose_table_deserialize (const gchar *contents,
-         }
-     }
-     if (data_length) {
--        retval->priv->data_second = g_new (guint32, data_length);
--        memcpy (retval->priv->data_second,
--                data_32bit_second, data_length * sizeof (guint32));
--        retval->priv->second_size = second_size;
-+        if ((retval->priv->data_second = g_new (guint32, data_length))) {
-+            memcpy (retval->priv->data_second,
-+                    data_32bit_second, data_length * sizeof (guint32));
-+            retval->priv->second_size = second_size;
-+        } else {
-+            g_warning ("Failed g_new");
-+            retval->priv->second_size = 0;
-+        }
-     }
- 
- 
-@@ -910,6 +915,43 @@ ibus_compose_table_new_with_list (GList   *compose_list,
-                                   int      n_index_stride,
-                                   guint32  hash)
- {
-+    /* @ibus_compose_seqs: Include both compose sequence and the value(compose
-+     *     output) as the tradition GTK. The value is one character only
-+     *     and within 16bit. I.e. All compose sequences and the values
-+     *     are 16bit.
-+     * @ibus_compose_seqs_32bit_second: Include the compose values only.
-+     *     The length of values by compose sequence is more than one characster
-+     *     or one of the values is outside 16bit but within 32bit.
-+     *     Some values could be more than one character and Emoji character
-+     *     could be outside 16bit.
-+     *     See also ibus/src/tests/ibus-compose.emoji file for e.g.
-+     * @ibus_compose_seqs_32bit_first: Include the compose sequence only in
-+     *     case the value is included in @ibus_compose_seqs_32bit_second.
-+     * @s_size_total: The number of compose sequences.
-+     * @s_size_16bit: The number of compose sequences whose value is one
-+     *     character only and within 16bit. I.e. the number of the compose
-+     *     sequence in @ibus_compose_seqs is @@s_size_16bit. And
-+     *     @s_size_total - @s_size_16bit is the number of the compose sequence
-+     *     in @ibus_compose_seqs_32bit_first.
-+     * @v_size_32bit: The total number of compose values. Each length of the
-+     *     values is more than one character or one of the value is
-+     *     outside 16bit but within 32bit. I.e. The size of
-+     *     @ibus_compose_seqs_32bit_second is @v_size_32bit.
-+     * @v_index_32bit: Each index of the compose values in
-+     *     @ibus_compose_seqs_32bit_second and this is not a fixed value in
-+     *     this API. If a compose sequence is found in
-+     *     @ibus_compose_seqs_32bit_first and the next value is 0, 0 is lined
-+     *     in @ibus_compose_seqs_32bit_first until @max_compose_len after
-+     *     the found compose sequence. And the next value is the length of
-+     *     the compose values and the next value is the @v_index_32bit, i.e.
-+     *     the index of @ibus_compose_seqs_32bit_second.
-+     *     E.g. the following line could be found in
-+     *     @ibus_compose_seqs_32bit_first:
-+     *         ..., "U17ff", "0", "0", "0", "0", 2, 100, ...
-+     *     @ibus_compose_seqs_32bit_second[100] is "ាំ"  and the character
-+     *     length is 2.
-+     *     @max_compose_len is 5 and @n_index_stride is 7.
-+     */
-     gsize s_size_total, s_size_16bit, v_size_32bit, v_index_32bit;
-     guint n = 0, m = 0;
-     int i, j;
-@@ -935,13 +977,25 @@ ibus_compose_table_new_with_list (GList   *compose_list,
-         }
-     }
- 
--    if (s_size_16bit)
-+    if (s_size_16bit) {
-         ibus_compose_seqs = g_new (guint16, s_size_16bit * n_index_stride);
-+        if (!ibus_compose_seqs) {
-+            g_warning ("Failed g_new");
-+            return NULL;
-+        }
-+    }
-     if (s_size_total > s_size_16bit) {
-         ibus_compose_seqs_32bit_first =
-                 g_new (guint16,
-                        (s_size_total - s_size_16bit) * n_index_stride);
-         ibus_compose_seqs_32bit_second = g_new (guint32, v_size_32bit);
-+        if (!ibus_compose_seqs_32bit_first || !ibus_compose_seqs_32bit_second) {
-+            g_warning ("Failed g_new");
-+            g_free (ibus_compose_seqs);
-+            g_free (ibus_compose_seqs_32bit_first);
-+            g_free (ibus_compose_seqs_32bit_second);
-+            return NULL;
-+        }
-     }
- 
-     v_index_32bit = 0;
-@@ -951,32 +1005,45 @@ ibus_compose_table_new_with_list (GList   *compose_list,
- 
-         is_32bit = unichar_length (compose_data->values) > 1 ? TRUE :
-                 compose_data->values[0] >= 0xFFFF ? TRUE : FALSE;
-+        if (is_32bit) {
-+            g_assert (ibus_compose_seqs_32bit_first);
-+            g_assert (ibus_compose_seqs_32bit_second);
-+        }
-         for (i = 0; i < max_compose_len; i++) {
-             if (compose_data->sequence[i] == 0) {
-                 for (j = i; j < max_compose_len; j++) {
--                    if (is_32bit)
-+                    if (is_32bit) {
-+                        g_assert (m < (s_size_total - s_size_16bit)
-+                                  * n_index_stride);
-                         ibus_compose_seqs_32bit_first[m++] = 0;
--                    else
-+                    } else {
-+                        g_assert (n < s_size_16bit * n_index_stride);
-                         ibus_compose_seqs[n++] = 0;
-+                    }
-                 }
-                 break;
-             }
-             if (is_32bit) {
-+                g_assert (m < (s_size_total - s_size_16bit) * n_index_stride);
-                 ibus_compose_seqs_32bit_first[m++] =
-                         (guint16) compose_data->sequence[i];
-             } else {
-+                g_assert (n < s_size_16bit * n_index_stride);
-                 ibus_compose_seqs[n++] = (guint16) compose_data->sequence[i];
-             }
-         }
-         if (is_32bit) {
-             for (j = 0; compose_data->values[j]; j++) {
-+                g_assert (v_index_32bit + j <  v_size_32bit);
-                 ibus_compose_seqs_32bit_second[v_index_32bit + j] =
-                         compose_data->values[j];
-             }
-+            g_assert (m + 1 < (s_size_total - s_size_16bit) * n_index_stride);
-             ibus_compose_seqs_32bit_first[m++] = j;
-             ibus_compose_seqs_32bit_first[m++] = v_index_32bit;
-             v_index_32bit += j;
-         } else {
-+            g_assert (n + 1 < s_size_16bit * n_index_stride);
-             ibus_compose_seqs[n++] = (guint16) compose_data->values[0];
-             ibus_compose_seqs[n++] = 0;
-         }
-diff --git a/src/ibusemoji.c b/src/ibusemoji.c
-index ae8907a2..df97264b 100644
---- a/src/ibusemoji.c
-+++ b/src/ibusemoji.c
-@@ -1,7 +1,7 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- /* vim:set et sts=4: */
- /* bus - The Input Bus
-- * Copyright (C) 2017-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2017-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2017-2019 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -497,7 +497,11 @@ ibus_emoji_data_save (const gchar *path,
- 
-     dir = g_path_get_dirname (path);
-     if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) {
--        g_mkdir_with_parents (dir, 0777);
-+        errno = 0;
-+        if (g_mkdir_with_parents (dir, 0777)) {
-+            g_warning ("Failed mkdir %s: %s", dir, g_strerror (errno));
-+            return;
-+        }
-     }
-     g_free (dir);
-     if (!g_file_set_contents (path, contents, length, &error)) {
-diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
-index 43bd5283..6dbc39c7 100644
---- a/src/ibusenginesimple.c
-+++ b/src/ibusenginesimple.c
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2014 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2014-2017 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -466,11 +466,15 @@ check_hex (IBusEngineSimple *simple,
- 
-         ch = ibus_keyval_to_unicode (priv->compose_buffer[i]);
- 
--        if (ch == 0)
-+        if (ch == 0) {
-+            g_string_free (str, TRUE);
-             return FALSE;
-+        }
- 
--        if (!g_unichar_isxdigit (ch))
-+        if (!g_unichar_isxdigit (ch)) {
-+            g_string_free (str, TRUE);
-             return FALSE;
-+        }
- 
-         buf[g_unichar_to_utf8 (ch, buf)] = '\0';
- 
-@@ -487,8 +491,9 @@ check_hex (IBusEngineSimple *simple,
-     if (nptr - str->str < str->len) {
-         g_string_free (str, TRUE);
-         return FALSE;
--    } else
-+    } else {
-         g_string_free (str, TRUE);
-+    }
- 
-     if (g_unichar_validate (n)) {
-         priv->tentative_match = n;
-@@ -559,11 +564,15 @@ check_emoji_table (IBusEngineSimple       *simple,
- 
-         ch = ibus_keyval_to_unicode (priv->compose_buffer[i]);
- 
--        if (ch == 0)
-+        if (ch == 0) {
-+            g_string_free (str, TRUE);
-             return FALSE;
-+        }
- 
--        if (!g_unichar_isprint (ch))
-+        if (!g_unichar_isprint (ch)) {
-+            g_string_free (str, TRUE);
-             return FALSE;
-+        }
- 
-         buf[g_unichar_to_utf8 (ch, buf)] = '\0';
- 
-diff --git a/src/ibushotkey.c b/src/ibushotkey.c
-index d4ab7c23..e72b8305 100644
---- a/src/ibushotkey.c
-+++ b/src/ibushotkey.c
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* IBus - The Input Bus
-  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2018-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2018-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2008-2019 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -373,6 +373,8 @@ ibus_hotkey_profile_add_hotkey (IBusHotkeyProfile *profile,
-         p->event = event;
-     }
- 
-+    if (!p)
-+        return FALSE;
-     p->hotkeys = g_list_append (p->hotkeys, hotkey);
- 
-     return TRUE;
-diff --git a/src/ibusregistry.c b/src/ibusregistry.c
-index 3386a5d1..23c5ca1b 100644
---- a/src/ibusregistry.c
-+++ b/src/ibusregistry.c
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* bus - The Input Bus
-  * Copyright (C) 2015 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2015-2020 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -438,7 +438,12 @@ ibus_registry_save_cache_file (IBusRegistry *registry,
-     g_assert (filename != NULL);
- 
-     cachedir = g_path_get_dirname (filename);
--    g_mkdir_with_parents (cachedir, 0775);
-+    errno = 0;
-+    if (g_mkdir_with_parents (cachedir, 0775)) {
-+        g_warning ("Failed to mkdir %s: %s", cachedir, g_strerror (errno));
-+        g_free (cachedir);
-+        return FALSE;
-+    }
-     g_free (cachedir);
- 
-     variant = ibus_serializable_serialize (IBUS_SERIALIZABLE (registry));
-diff --git a/src/ibusshare.c b/src/ibusshare.c
-index e0ef2ce0..8974511a 100644
---- a/src/ibusshare.c
-+++ b/src/ibusshare.c
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2008-2018 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -197,22 +197,17 @@ ibus_get_address (void)
-     FILE *pf;
- 
-     /* free address */
--    if (address != NULL) {
--        g_free (address);
--        address = NULL;
--    }
-+    g_clear_pointer (&address, g_free);
- 
-     /* get address from env variable */
-     address = g_strdup (g_getenv ("IBUS_ADDRESS"));
--    if (address) {
-+    if (address)
-         return address;
--    }
- 
-     /* read address from ~/.config/ibus/bus/soketfile */
-     pf = fopen (ibus_get_socket_path (), "r");
--    if (pf == NULL) {
-+    if (pf == NULL)
-         return NULL;
--    }
- 
-     while (!feof (pf)) {
-         gchar *p = buffer;
-@@ -224,11 +219,12 @@ ibus_get_address (void)
-             continue;
-         /* parse IBUS_ADDRESS */
-         if (strncmp (p, "IBUS_ADDRESS=", sizeof ("IBUS_ADDRESS=") - 1) == 0) {
--            address = p + sizeof ("IBUS_ADDRESS=") - 1;
--            for (p = (gchar *)address; *p != '\n' && *p != '\0'; p++);
-+            gchar *head = p + sizeof ("IBUS_ADDRESS=") - 1;
-+            for (p = head; *p != '\n' && *p != '\0'; p++);
-             if (*p == '\n')
-                 *p = '\0';
--            address = g_strdup (address);
-+            g_free (address);
-+            address = g_strdup (head);
-             continue;
-         }
- 
-@@ -241,9 +237,8 @@ ibus_get_address (void)
-     }
-     fclose (pf);
- 
--    if (pid == -1 || kill (pid, 0) != 0) {
-+    if (pid == -1 || kill (pid, 0) != 0)
-         return NULL;
--    }
- 
-     return address;
- }
-@@ -256,10 +251,19 @@ ibus_write_address (const gchar *address)
-     g_return_if_fail (address != NULL);
- 
-     path = g_path_get_dirname (ibus_get_socket_path ());
--    g_mkdir_with_parents (path, 0700);
-+    errno = 0;
-+    if (g_mkdir_with_parents (path, 0700)) {
-+        g_warning ("Failed to mkdir %s: %s", path, g_strerror (errno));
-+        g_free (path);
-+        return;
-+    }
-     g_free (path);
- 
--    g_unlink (ibus_get_socket_path ());
-+    errno = 0;
-+    if (g_unlink (ibus_get_socket_path ())) {
-+        g_warning ("Failed to unlink %s: %s",
-+                   ibus_get_socket_path (), g_strerror (errno));
-+    }
-     pf = fopen (ibus_get_socket_path (), "w");
-     g_return_if_fail (pf != NULL);
- 
-diff --git a/src/ibustext.c b/src/ibustext.c
-index a5e3c43b..ed0fe666 100644
---- a/src/ibustext.c
-+++ b/src/ibustext.c
-@@ -2,7 +2,8 @@
- /* vim:set et sts=4: */
- /* IBus - The Input Bus
-  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2008-2010 Red Hat, Inc.
-+ * Copyright (C) 2011-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2008-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -220,7 +221,7 @@ ibus_text_new_from_unichar (gunichar c)
-     text= g_object_new (IBUS_TYPE_TEXT, NULL);
- 
-     text->is_static = FALSE;
--    text->text = (gchar *)g_malloc (12);
-+    g_return_val_if_fail ((text->text = (gchar *)g_malloc (12)), NULL);
-     len = g_unichar_to_utf8 (c, text->text);
-     text->text[len] =  0;
- 
-diff --git a/src/ibusunicode.c b/src/ibusunicode.c
-index 9e6f6b2b..f7a897d1 100644
---- a/src/ibusunicode.c
-+++ b/src/ibusunicode.c
-@@ -1,8 +1,8 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- /* vim:set et sts=4: */
- /* bus - The Input Bus
-- * Copyright (C) 2018-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-- * Copyright (C) 2018-2019 Red Hat, Inc.
-+ * Copyright (C) 2018-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2018-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -472,7 +472,12 @@ ibus_unicode_data_save (const gchar *path,
- 
-     dir = g_path_get_dirname (path);
-     if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) {
--        g_mkdir_with_parents (dir, 0777);
-+        errno = 0;
-+        if (g_mkdir_with_parents (dir, 0777)) {
-+            g_warning ("Failed to mkdir %s: %s", dir, g_strerror (errno));
-+            return;
-+        }
-+
-     }
-     g_free (dir);
-     if (!g_file_set_contents (path, contents, length, &error)) {
-@@ -967,7 +972,11 @@ ibus_unicode_block_save (const gchar *path,
- 
-     dir = g_path_get_dirname (path);
-     if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) {
--        g_mkdir_with_parents (dir, 0777);
-+        errno = 0;
-+        if (g_mkdir_with_parents (dir, 0777)) {
-+            g_warning ("Failed to mkdir %s: %s", dir, g_strerror (errno));
-+            return;
-+        }
-     }
-     g_free (dir);
-     if (!g_file_set_contents (path, contents, length, &error)) {
-diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
-index 4b4c56e7..81bfc69b 100644
---- a/src/tests/ibus-compose.c
-+++ b/src/tests/ibus-compose.c
-@@ -360,11 +360,13 @@ main (int argc, char *argv[])
-     /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name"
-      * with gtk_main().
-      */
--    g_setenv ("NO_AT_BRIDGE", "1", TRUE);
-+    if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE))
-+        g_message ("Failed setenv NO_AT_BRIDGE\n");
-     g_test_init (&argc, &argv, NULL);
-     gtk_init (&argc, &argv);
- 
--    m_srcdir = argc > 1 ? g_strdup (argv[1]) : g_strdup (".");
-+    m_srcdir = (argc > 1 && strlen (argv[1]) < FILENAME_MAX)
-+            ? g_strdup (argv[1]) : g_strdup (".");
-     m_compose_file = g_strdup (g_getenv ("COMPOSE_FILE"));
- #if GLIB_CHECK_VERSION (2, 58, 0)
-     test_name = g_get_language_names_with_category ("LC_CTYPE")[0];
-diff --git a/src/tests/ibus-keypress.c b/src/tests/ibus-keypress.c
-index dd1b0042..bab05398 100644
---- a/src/tests/ibus-keypress.c
-+++ b/src/tests/ibus-keypress.c
-@@ -291,7 +291,8 @@ main (int argc, char *argv[])
-     /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name"
-      * with gtk_main().
-      */
--    g_setenv ("NO_AT_BRIDGE", "1", TRUE);
-+    if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE))
-+        g_message ("Failed setenv NO_AT_BRIDGE\n");
-     g_test_init (&argc, &argv, NULL);
-     gtk_init (&argc, &argv);
- 
-diff --git a/src/unicode-parser.c b/src/unicode-parser.c
-index b4303ea8..2c4eb677 100644
---- a/src/unicode-parser.c
-+++ b/src/unicode-parser.c
-@@ -1,8 +1,8 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-- * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
-- * Copyright (C) 2018 Red Hat, Inc.
-+ * Copyright (C) 2018-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2018-2021 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public
-@@ -76,11 +76,9 @@ unicode_data_new_object (UnicodeData *data)
-             ibus_unicode_data_new ("code",
-                                    data->code,
-                                    "name",
--                                   data->name ? g_strdup (data->name)
--                                           : g_strdup (""),
-+                                   data->name ? data->name : "",
-                                    "alias",
--                                   data->alias ? g_strdup (data->alias)
--                                           : g_strdup (""),
-+                                   data->alias ? data->alias : "",
-                                    NULL);
-     data->list = g_slist_append (data->list, unicode);
- }
-@@ -98,8 +96,7 @@ unicode_block_new_object (UnicodeData *data)
-                                     "end",
-                                     data->end,
-                                     "name",
--                                    data->name ? g_strdup (data->name)
--                                           : g_strdup (""),
-+                                    data->name ? data->name : "",
-                                    NULL);
-     data->list = g_slist_append (data->list, block);
- }
-@@ -285,7 +282,7 @@ ucd_parse_file (const gchar *filename,
-                    filename, error ? error->message : "");
-         goto failed_to_parse_ucd_names_list;
-     }
--    head = end = content;
-+    end = content;
-     while (*end == '\n' && end - content < length) {
-         end++;
-         n++;
-@@ -352,6 +349,7 @@ static void
- block_list_dump (IBusUnicodeBlock *block,
-                  GString          *buff)
- {
-+    gchar *line;
-     g_return_if_fail (buff != NULL);
- 
-     g_string_append (buff, "    /* TRANSLATORS: You might refer the "         \
-@@ -359,9 +357,10 @@ block_list_dump (IBusUnicodeBlock *block,
-                            "                    the following command:\n"     \
-                            "       msgmerge -C gucharmap.po ibus.po "         \
-                            "ibus.pot */\n");
--    gchar *line = g_strdup_printf ("    N_(\"%s\"),\n",
--                                   ibus_unicode_block_get_name (block));
-+    line = g_strdup_printf ("    N_(\"%s\"),\n",
-+                            ibus_unicode_block_get_name (block));
-     g_string_append (buff, line);
-+    g_free (line);
- }
- 
- static void
-@@ -371,7 +370,7 @@ ucd_block_translatable_save (const gchar *filename,
-     gchar *content = NULL;
-     gsize length = 0;
-     GError *error = NULL;
--    gchar *p;
-+    gchar *p, *substr;
-     GString *buff = NULL;
-     int i;
-     GSList *list = blocks_list;
-@@ -392,25 +391,30 @@ ucd_block_translatable_save (const gchar *filename,
-             break;
-     }
-     if (p != NULL) {
--        g_string_append (buff, g_strndup (content, p - content));
-+        substr = g_strndup (content, p - content);
-+        g_string_append (buff, substr);
-+        g_free (substr);
-         g_string_append_c (buff, '\n');
-     }
-     g_clear_pointer (&content, g_free);
- 
--    g_string_append (buff, g_strdup ("\n"));
--    g_string_append (buff, g_strdup_printf ("/* This file is generated by %s. */", __FILE__));
--    g_string_append (buff, g_strdup ("\n"));
--    g_string_append (buff, g_strdup ("include <glib/gi18n.h>\n"));
--    g_string_append (buff, g_strdup ("\n"));
--    g_string_append (buff, g_strdup ("#ifndef __IBUS_UNICODE_GEN_H_\n"));
--    g_string_append (buff, g_strdup ("#define __IBUS_UNICODE_GEN_H_\n"));
--    g_string_append (buff, g_strdup ("const static char *unicode_blocks[] = {\n"));
-+    g_string_append (buff, "\n");
-+    substr = g_strdup_printf ("/* This file is generated by %s. */", __FILE__);
-+    g_string_append (buff, substr);
-+    g_free (substr);
-+    g_string_append (buff, "\n");
-+    g_string_append (buff, "include <glib/gi18n.h>\n");
-+    g_string_append (buff, "\n");
-+    g_string_append (buff, "#ifndef __IBUS_UNICODE_GEN_H_\n");
-+    g_string_append (buff, "#define __IBUS_UNICODE_GEN_H_\n");
-+    g_string_append (buff, "const static char *unicode_blocks[] = {\n");
-     g_slist_foreach (list, (GFunc)block_list_dump, buff);
--    g_string_append (buff, g_strdup ("};\n"));
--    g_string_append (buff, g_strdup ("#endif\n"));
-+    g_string_append (buff, "};\n");
-+    g_string_append (buff, "#endif\n");
- 
-     if (!g_file_set_contents (filename, buff->str, -1, &error)) {
--        g_warning ("Failed to save emoji category file %s: %s", filename, error->message);
-+        g_warning ("Failed to save emoji category file %s: %s",
-+                   filename, error->message);
-         g_error_free (error);
-     }
- 
-diff --git a/util/IMdkit/FrameMgr.c b/util/IMdkit/FrameMgr.c
-index 0e91b78e..80d019a0 100644
---- a/util/IMdkit/FrameMgr.c
-+++ b/util/IMdkit/FrameMgr.c
-@@ -851,7 +851,7 @@ static Bool _FrameMgrProcessPadding (FrameMgr fm, FmStatus* status)
-             return True;
-         }
-         /*endif*/
--        next_type = FrameInstGetNextType (fm->fi, &info);
-+        FrameInstGetNextType (fm->fi, &info);
-         fm->idx += info.num;
-         if ((fitr = _FrameIterCounterIncr (fm->iters, info.num)))
-             _FrameMgrRemoveIter (fm, fitr);
-@@ -1525,6 +1525,11 @@ static Iter IterInit (XimFrame frame, int count)
-     register XimFrameType type;
- 
-     it = (Iter) Xmalloc (sizeof (IterRec));
-+    if (!it) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        return NULL;
-+    }
-     it->template = frame;
-     it->max_count = (count == NO_VALUE)  ?  0  :  count;
-     it->allow_expansion = (count == NO_VALUE);
-@@ -1669,8 +1674,15 @@ static Bool IterIsLoopEnd (Iter it, Bool *myself)
- 
- static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info)
- {
--    XimFrameType type = it->template->type;
-+    XimFrameType type;
-+
-+    if (!it || !it->template) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+	return (XimFrameType) NULL;
-+    }
- 
-+    type = it->template->type;
-     if (it->start_counter)
-     {
-         (*it->start_watch_proc) (it, it->client_data);
-@@ -1766,7 +1778,15 @@ static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info)
- 
- static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info)
- {
--    XimFrameType type = it->template->type;
-+    XimFrameType type;
-+
-+    if (!it->template) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: dereference pointer %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        return (XimFrameType) NULL;
-+    }
-+
-+    type = it->template->type;
- 
-     if (!it->allow_expansion  &&  it->cur_no >= it->max_count)
-         return (EOL);
-@@ -1866,6 +1886,9 @@ static FmStatus IterSetSize (Iter it, int num)
-                     dr.num = NO_VALUE;
-                     d = ChainMgrSetData (&it->cm, i, dr);
-                 }
-+                if (!d) {
-+                    return FmNoMoreData;
-+                }
-                 /*endif*/
-                 if (d->num == NO_VALUE)
-                 {
-@@ -2254,6 +2277,11 @@ static ExtraData ChainMgrSetData (ChainMgr cm,
-                                   ExtraDataRec data)
- {
-     Chain cur = (Chain) Xmalloc (sizeof (ChainRec));
-+    if (!cur) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        return NULL;
-+    }
- 
-     cur->frame_no = frame_no;
-     cur->d = data;
-diff --git a/util/IMdkit/i18nIc.c b/util/IMdkit/i18nIc.c
-index 289837a6..14a3dc51 100644
---- a/util/IMdkit/i18nIc.c
-+++ b/util/IMdkit/i18nIc.c
-@@ -470,13 +470,16 @@ static XICAttribute *CreateNestedList (CARD16 attr_id,
-     /*endfor*/
-     
-     nest_list = (XICAttribute *) malloc (sizeof (XICAttribute));
--    if (nest_list == NULL)
-+    if (nest_list == NULL) {
-+        XFree (values);
-         return NULL;
-+    }
-     /*endif*/
-     memset (nest_list, 0, sizeof (XICAttribute));
-     nest_list->value = (void *) malloc (value_length);
-     if (nest_list->value == NULL) {
-         XFree (nest_list);
-+        XFree (values);
-         return NULL;
-     }
-     /*endif*/
-@@ -539,7 +542,13 @@ static int GetICValue (Xi18n i18n_core,
-                     attr_ret[n].attribute_id = xic_attr[j].attribute_id;
-                     attr_ret[n].name_length = xic_attr[j].length;
-                     attr_ret[n].name = malloc (xic_attr[j].length + 1);
--		    strcpy(attr_ret[n].name, xic_attr[j].name);
-+                    if (!attr_ret[n].name) {
-+                        fprintf (stderr,
-+                                 "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                                 __FILE__, __LINE__);
-+                    } else {
-+                        strcpy(attr_ret[n].name, xic_attr[j].name);
-+                    }
-                     attr_ret[n].type = xic_attr[j].type;
-                     n++;
-                     i++;
-@@ -560,7 +569,13 @@ static int GetICValue (Xi18n i18n_core,
-                 attr_ret[n].attribute_id = xic_attr[j].attribute_id;
-                 attr_ret[n].name_length = xic_attr[j].length;
-                 attr_ret[n].name = malloc (xic_attr[j].length + 1);
--		strcpy(attr_ret[n].name, xic_attr[j].name);
-+                if (!attr_ret[n].name) {
-+                    fprintf (stderr,
-+                             "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                             __FILE__, __LINE__);
-+                } else {
-+		    strcpy(attr_ret[n].name, xic_attr[j].name);
-+                }
-                 attr_ret[n].type = xic_attr[j].type;
-                 n++;
-                 break;
-@@ -700,10 +715,15 @@ void _Xi18nChangeIC (XIMS ims,
-         attrib_list[attrib_num].value_length = value_length;
-         FrameMgrGetToken (fm, value);
-         attrib_list[attrib_num].value = (void *) malloc (value_length + 1);
--        memmove (attrib_list[attrib_num].value, value, value_length);
--	((char *)attrib_list[attrib_num].value)[value_length] = '\0';
-+        if (!attrib_list[attrib_num].value) {
-+            fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                     __FILE__, __LINE__);
-+        } else {
-+            memmove (attrib_list[attrib_num].value, value, value_length);
-+            ((char *)attrib_list[attrib_num].value)[value_length] = '\0';
-+            total_value_length += (value_length + 1);
-+        }
-         attrib_num++;
--        total_value_length += (value_length + 1);
-     }
-     /*endwhile*/
- 
-@@ -917,6 +937,12 @@ void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p)
-     FrameMgrGetToken (fm, byte_length);
- 
-     attrID_list = (CARD16 *) malloc (sizeof (CARD16)*IC_SIZE);  /* bogus */
-+    if (!attrID_list) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        FrameMgrFree (fm);
-+        return;
-+    }
-     memset (attrID_list, 0, sizeof (CARD16)*IC_SIZE);
- 
-     number = 0;
-@@ -1026,7 +1052,7 @@ void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p)
-     {
-         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
-         XFree (attrID_list);
--        FrameMgrFree (fm);
-+        goto _Xi18nGetIC_finit;
-         return;
-     }
-     /*endif*/
-@@ -1097,6 +1123,7 @@ void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p)
-     }
-     /*endfor*/
-     
-+_Xi18nGetIC_finit:
-     if (preedit_ret)
-     {
-         XFree (preedit_ret->value);
-diff --git a/util/IMdkit/i18nMethod.c b/util/IMdkit/i18nMethod.c
-index 36dd28ac..9c44e7fe 100644
---- a/util/IMdkit/i18nMethod.c
-+++ b/util/IMdkit/i18nMethod.c
-@@ -166,8 +166,14 @@ static Bool GetEncodings(Xi18n i18n_core, XIMEncodings **p_encoding)
-     {
-         (*p_encoding)->supported_encodings[i]
-             = (char *) malloc (strlen (p->supported_encodings[i]) + 1);
--        strcpy ((*p_encoding)->supported_encodings[i],
--                p->supported_encodings[i]);
-+        if (!((*p_encoding)->supported_encodings[i])) {
-+            fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                     __FILE__, __LINE__);
-+
-+        } else {
-+            strcpy ((*p_encoding)->supported_encodings[i],
-+                    p->supported_encodings[i]);
-+        }
-     }
-     /*endif*/
-     return True;
-@@ -187,11 +193,17 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
-                 if (address->imvalue_mask & I18N_IM_LOCALE)
-                     return IMLocale;
-                 /*endif*/
-+                /* address->im_locale will be released later and don't need
-+                 * -Wanalyzer-malloc-leak flag in gcc 11.0.1.
-+                 */
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
-                 address->im_locale = (char *) malloc (strlen (p->value) + 1);
-                 if (!address->im_locale)
-                     return IMLocale;
-                 /*endif*/
-                 strcpy (address->im_locale, p->value);
-+#pragma GCC diagnostic pop
-                 address->imvalue_mask |= I18N_IM_LOCALE;
-             }
-             else if (strcmp (p->name, IMServerTransport) == 0)
-@@ -199,11 +211,14 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
-                 if (address->imvalue_mask & I18N_IM_ADDRESS)
-                     return IMServerTransport;
-                 /*endif*/
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
-                 address->im_addr = (char *) malloc (strlen (p->value) + 1);
-                 if (!address->im_addr)
-                     return IMServerTransport;
-                 /*endif*/
-                 strcpy(address->im_addr, p->value);
-+#pragma GCC diagnostic pop
-                 address->imvalue_mask |= I18N_IM_ADDRESS;
-             }
-             else if (strcmp (p->name, IMServerName) == 0)
-@@ -211,11 +226,14 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
-                 if (address->imvalue_mask & I18N_IM_NAME)
-                     return IMServerName;
-                 /*endif*/
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
-                 address->im_name = (char *) malloc (strlen (p->value) + 1);
-                 if (!address->im_name)
-                     return IMServerName;
-                 /*endif*/
-                 strcpy (address->im_name, p->value);
-+#pragma GCC diagnostic pop
-                 address->imvalue_mask |= I18N_IM_NAME;
-             }
-             else if (strcmp (p->name, IMServerWindow) == 0)
-@@ -698,7 +716,7 @@ static void ReturnSelectionNotify (Xi18n i18n_core, XSelectionRequestEvent *ev)
- {
-     XEvent event;
-     Display *dpy = i18n_core->address.dpy;
--    char buf[4096];
-+    char buf[4096] = { '\0', };
- 
-     event.type = SelectionNotify;
-     event.xselection.requestor = ev->requestor;
-diff --git a/util/IMdkit/i18nOffsetCache.c b/util/IMdkit/i18nOffsetCache.c
-index d5379051..e2fe8c6b 100644
---- a/util/IMdkit/i18nOffsetCache.c
-+++ b/util/IMdkit/i18nOffsetCache.c
-@@ -94,7 +94,7 @@ void _Xi18nSetPropertyOffset (Xi18nOffsetCache *offset_cache, Atom key,
-     }
- 
-     assert (data != NULL);
--    if (offset_cache->size > 0) {
-+    if (offset_cache->size > 0 && i < offset_cache->capacity) {
-         data[i].key = key;
-         data[i].offset = offset;
-     }
-diff --git a/util/IMdkit/i18nPtHdr.c b/util/IMdkit/i18nPtHdr.c
-index eaeeee1c..8dc52714 100644
---- a/util/IMdkit/i18nPtHdr.c
-+++ b/util/IMdkit/i18nPtHdr.c
-@@ -181,8 +181,13 @@ static void OpenMessageProc(XIMS ims, IMProtocol *call_data, unsigned char *p)
-     FrameMgrGetToken (fm, name);
-     imopen->lang.length = str_length;
-     imopen->lang.name = malloc (str_length + 1);
--    strncpy (imopen->lang.name, name, str_length);
--    imopen->lang.name[str_length] = (char) 0;
-+    if (!imopen->lang.name) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+    } else {
-+        strncpy (imopen->lang.name, name, str_length);
-+        imopen->lang.name[str_length] = (char) 0;
-+    }
- 
-     FrameMgrFree (fm);
- 
-@@ -339,7 +344,7 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core,
-                                   int number,
-                                   int *reply_number)
- {
--    XIMExt *ext_list;
-+    XIMExt *ext_list = NULL;
-     XIMExt *im_ext = (XIMExt *) i18n_core->address.extension;
-     int im_ext_len = i18n_core->address.ext_num;
-     int i;
-@@ -358,7 +363,8 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core,
-         {
-             for (j = 0;  j < (int) number;  j++)
-             {
--                if (strcmp (lib_extension[j].name, im_ext[i].name) == 0)
-+                if (lib_extension[j].name
-+                    && strcmp (lib_extension[j].name, im_ext[i].name) == 0)
-                 {
-                     (*reply_number)++;
-                     break;
-@@ -389,7 +395,13 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core,
-             ext_list[i].minor_opcode = im_ext[i].minor_opcode;
-             ext_list[i].length = im_ext[i].length;
-             ext_list[i].name = malloc (im_ext[i].length + 1);
--            strcpy (ext_list[i].name, im_ext[i].name);
-+            if (!ext_list[i].name) {
-+                fprintf (stderr,
-+                         "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                         __FILE__, __LINE__);
-+            } else {
-+                strcpy (ext_list[i].name, im_ext[i].name);
-+            }
-         }
-         /*endfor*/
-     }
-@@ -401,13 +413,20 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core,
-         {
-             for (j = 0;  j < (int)number;  j++)
-             {
--                if (strcmp (lib_extension[j].name, im_ext[i].name) == 0)
-+                if (lib_extension[j].name
-+                    && strcmp (lib_extension[j].name, im_ext[i].name) == 0)
-                 {
-                     ext_list[n].major_opcode = im_ext[i].major_opcode;
-                     ext_list[n].minor_opcode = im_ext[i].minor_opcode;
-                     ext_list[n].length = im_ext[i].length;
-                     ext_list[n].name = malloc (im_ext[i].length + 1);
--                    strcpy (ext_list[n].name, im_ext[i].name);
-+                    if (!ext_list[n].name) {
-+                        fprintf (stderr,
-+                                 "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                                 __FILE__, __LINE__);
-+                    } else {
-+                        strcpy (ext_list[n].name, im_ext[i].name);
-+                    }
-                     n++;
-                     break;
-                 }
-@@ -450,6 +469,11 @@ static void QueryExtensionMessageProc (XIMS ims,
-     FrameMgrGetToken (fm, input_method_ID);
-     FrameMgrGetToken (fm, byte_length);
-     query_ext->extension = (XIMStr *) malloc (sizeof (XIMStr)*10);
-+    if (!query_ext->extension) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        return;
-+    }
-     memset (query_ext->extension, 0, sizeof (XIMStr)*10);
-     number = 0;
-     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
-@@ -461,9 +485,20 @@ static void QueryExtensionMessageProc (XIMS ims,
-         FrameMgrSetSize (fm, str_length);
-         query_ext->extension[number].length = str_length;
-         FrameMgrGetToken (fm, name);
-+        /* I don't know why extension[number].name is detected as leak
-+         * with -Wanalyzer-malloc-leak option in gcc 11.0.1.
-+         */
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
-         query_ext->extension[number].name = malloc (str_length + 1);
--        strncpy (query_ext->extension[number].name, name, str_length);
--        query_ext->extension[number].name[str_length] = (char) 0;
-+        if (!query_ext->extension[number].name) {
-+            fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                     __FILE__, __LINE__);
-+        } else {
-+            strncpy (query_ext->extension[number].name, name, str_length);
-+            query_ext->extension[number].name[str_length] = (char) 0;
-+        }
-+#pragma GCC diagnostic pop
-         number++;
-     }
-     /*endwhile*/
-@@ -490,6 +525,8 @@ static void QueryExtensionMessageProc (XIMS ims,
-         XFree (query_ext->extension[i].name);
-     /*endfor*/
-     XFree (query_ext->extension);
-+    if (!ext_list)
-+        return;
- 
-     fm = FrameMgrInit (query_extension_reply_fr,
-                        NULL,
-@@ -501,7 +538,10 @@ static void QueryExtensionMessageProc (XIMS ims,
-     /* set length of BARRAY item in ext_fr */
-     for (i = 0;  i < reply_number;  i++)
-     {
--        str_size = strlen (ext_list[i].name);
-+        if (ext_list[i].name)
-+            str_size = strlen (ext_list[i].name);
-+        else
-+            str_size = 0;
-         FrameMgrSetSize (fm, str_size);
-     }
-     /*endfor*/
-@@ -700,7 +740,13 @@ static XIMAttribute *MakeIMAttributeList (Xi18n i18n_core,
-                                     &value_length);
-                 attrib_list[list_num].value_length = value_length;
-                 attrib_list[list_num].value = (void *) malloc (value_length);
--                memset(attrib_list[list_num].value, 0, value_length);
-+                if (attrib_list[list_num].value) {
-+                    memset(attrib_list[list_num].value, 0, value_length);
-+                } else {
-+                    fprintf (stderr,
-+                             "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                             __FILE__, __LINE__);
-+                }
-                 GetIMValueFromName (i18n_core,
-                                     connect_id,
-                                     attrib_list[list_num].value,
-@@ -737,10 +783,10 @@ static void GetIMValuesMessageProc (XIMS ims,
-     register int i;
-     register int j;
-     int number;
--    CARD16 *im_attrID_list;
--    char **name_list;
-+    CARD16 *im_attrID_list = NULL;
-+    char **name_list = NULL;
-     CARD16 name_number;
--    XIMAttribute *im_attribute_list;
-+    XIMAttribute *im_attribute_list = NULL;
-     IMGetIMValuesStruct *getim = (IMGetIMValuesStruct *)&call_data->getim;
-     CARD16 connect_id = call_data->any.connect_id;
-     CARD16 input_method_ID;
-@@ -753,8 +799,18 @@ static void GetIMValuesMessageProc (XIMS ims,
-     FrameMgrGetToken (fm, input_method_ID);
-     FrameMgrGetToken (fm, byte_length);
-     im_attrID_list = (CARD16 *) malloc (sizeof (CARD16)*20);
-+    if (!im_attrID_list) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        goto GetIMValuesMessageProc_finit;
-+    }
-     memset (im_attrID_list, 0, sizeof (CARD16)*20);
-     name_list = (char **)malloc(sizeof(char *) * 20);
-+    if (!name_list) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        goto GetIMValuesMessageProc_finit;
-+    }
-     memset(name_list, 0, sizeof(char *) * 20);
-     number = 0;
-     while (FrameMgrIsIterLoopEnd (fm, &status) == False)
-@@ -792,8 +848,11 @@ static void GetIMValuesMessageProc (XIMS ims,
-                                              im_attrID_list,
-                                              &number,
-                                              &list_len);
--    if (im_attrID_list)
--        XFree (im_attrID_list);
-+    if (!im_attribute_list) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        goto GetIMValuesMessageProc_finit2;
-+    }
-     /*endif*/
- 
-     fm = FrameMgrInit (get_im_values_reply_fr,
-@@ -815,11 +874,7 @@ static void GetIMValuesMessageProc (XIMS ims,
-     if (!reply)
-     {
-         _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
--        FrameMgrFree (fm);
--        for (i = 0; i < iter_count; i++)
--            XFree(im_attribute_list[i].value);
--        XFree (im_attribute_list);
--        return;
-+        goto GetIMValuesMessageProc_finit;
-     }
-     /*endif*/
-     memset (reply, 0, total_size);
-@@ -840,12 +895,18 @@ static void GetIMValuesMessageProc (XIMS ims,
-                        0,
-                        reply,
-                        total_size);
--    FrameMgrFree (fm);
-     XFree (reply);
- 
--    for (i = 0; i < iter_count; i++)
--        XFree(im_attribute_list[i].value);
--    XFree (im_attribute_list);
-+GetIMValuesMessageProc_finit:
-+    FrameMgrFree (fm);
-+GetIMValuesMessageProc_finit2:
-+    if (im_attrID_list)
-+        XFree (im_attrID_list);
-+    if (im_attribute_list) {
-+        for (i = 0; i < iter_count; i++)
-+            XFree(im_attribute_list[i].value);
-+        XFree (im_attribute_list);
-+    }
- }
- 
- static void CreateICMessageProc (XIMS ims,
-@@ -1435,6 +1496,11 @@ static void EncodingNegotiatonMessageProc (XIMS ims,
-     if (byte_length > 0)
-     {
-         enc_nego->encoding = (XIMStr *) malloc (sizeof (XIMStr)*10);
-+        if (!enc_nego->encoding) {
-+            fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                     __FILE__, __LINE__);
-+            goto EncodingNegotiatonMessageProc_finit;
-+        }
-         memset (enc_nego->encoding, 0, sizeof (XIMStr)*10);
-         i = 0;
-         while (FrameMgrIsIterLoopEnd (fm, &status) == False)
-@@ -1446,9 +1512,21 @@ static void EncodingNegotiatonMessageProc (XIMS ims,
-             FrameMgrSetSize (fm, str_length);
-             enc_nego->encoding[i].length = str_length;
-             FrameMgrGetToken (fm, name);
-+            /* I don't know why encoding[i].name is detected as leak
-+             * with -Wanalyzer-malloc-leak option in gcc 11.0.1.
-+             */
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
-             enc_nego->encoding[i].name = malloc (str_length + 1);
-+            if (!(enc_nego->encoding[i].name)) {
-+                fprintf (stderr,
-+                         "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                         __FILE__, __LINE__);
-+                goto EncodingNegotiatonMessageProc_finit;
-+            }
-             strncpy (enc_nego->encoding[i].name, name, str_length);
-             enc_nego->encoding[i].name[str_length] = '\0';
-+#pragma GCC diagnostic pop
-             i++;
-         }
-         /*endwhile*/
-@@ -1460,20 +1538,37 @@ static void EncodingNegotiatonMessageProc (XIMS ims,
-     if (byte_length > 0)
-     {
-         enc_nego->encodinginfo = (XIMStr *) malloc (sizeof (XIMStr)*10);
-+        if (!enc_nego->encodinginfo) {
-+            fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                     __FILE__, __LINE__);
-+            goto EncodingNegotiatonMessageProc_finit;
-+        }
-         memset (enc_nego->encodinginfo, 0, sizeof (XIMStr)*10);
-         i = 0;
-         while (FrameMgrIsIterLoopEnd (fm, &status) == False)
-         {
-             char *name;
-             int str_length;
--            
-+
-             FrameMgrGetToken (fm, str_length);
-             FrameMgrSetSize (fm, str_length);
-             enc_nego->encodinginfo[i].length = str_length;
-             FrameMgrGetToken (fm, name);
-+            /* I don't know why encodinginfo[i].name is detected as leak
-+             * with -Wanalyzer-malloc-leak option in gcc 11.0.1.
-+             */
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
-             enc_nego->encodinginfo[i].name = malloc (str_length + 1);
-+            if (!enc_nego->encodinginfo[i].name) {
-+                fprintf (stderr,
-+                         "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                         __FILE__, __LINE__);
-+                goto EncodingNegotiatonMessageProc_finit;
-+            }
-             strncpy (enc_nego->encodinginfo[i].name, name, str_length);
-             enc_nego->encodinginfo[i].name[str_length] = '\0';
-+#pragma GCC diagnostic pop
-             i++;
-         }
-         /*endwhile*/
-@@ -1524,6 +1619,7 @@ static void EncodingNegotiatonMessageProc (XIMS ims,
-                        total_size);
-     XFree (reply);
- 
-+EncodingNegotiatonMessageProc_finit:
-     /* free data for encoding list */
-     if (enc_nego->encoding)
-     {
-diff --git a/util/IMdkit/i18nUtil.c b/util/IMdkit/i18nUtil.c
-index 109dcdf9..c62154e7 100644
---- a/util/IMdkit/i18nUtil.c
-+++ b/util/IMdkit/i18nUtil.c
-@@ -46,6 +46,8 @@ _Xi18nNeedSwap (Xi18n i18n_core, CARD16 connect_id)
-     CARD8 im_byteOrder = i18n_core->address.im_byteOrder;
-     Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
- 
-+    if (!client)
-+        return True;
-     return (client->byte_order != im_byteOrder);
- }
- 
-@@ -67,6 +69,11 @@ Xi18nClient *_Xi18nNewClient(Xi18n i18n_core)
- 	new_connect_id = ++connect_id;
-     }
-     /*endif*/
-+    if (!client) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+        return NULL;
-+    }
-     memset (client, 0, sizeof (Xi18nClient));
-     client->connect_id = new_connect_id;
-     client->pending = (XIMPending *) NULL;
-@@ -113,7 +120,14 @@ void _Xi18nDeleteClient (Xi18n i18n_core, CARD16 connect_id)
-                 ccp0->next = ccp->next;
-             /*endif*/
-             /* put it back to free list */
-+            /* gcc 11.0.1 warns dereference of NULL with
-+             * -Wanalyzer-null-dereference option
-+             * but target should not be NULL.
-+             */
-+#pragma GCC diagnostic push
-+#pragma GCC diagnostic ignored "-Wanalyzer-null-dereference"
-             target->next = i18n_core->address.free_clients;
-+#pragma GCC diagnostic pop
-             i18n_core->address.free_clients = target;
-             return;
-         }
-@@ -161,6 +175,12 @@ void _Xi18nSendMessage (XIMS ims,
- 
-     reply_length = header_size + length;
-     reply = (unsigned char *) malloc (reply_length);
-+    if (!reply) {
-+        _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
-+        XFree (reply_hdr);
-+        FrameMgrFree (fm);
-+        return;
-+    }
-     replyp = reply;
-     memmove (reply, reply_hdr, header_size);
-     replyp += header_size;
-diff --git a/util/IMdkit/i18nX.c b/util/IMdkit/i18nX.c
-index 5e5c15fa..152fc4e8 100644
---- a/util/IMdkit/i18nX.c
-+++ b/util/IMdkit/i18nX.c
-@@ -58,16 +58,21 @@ static XClient *NewXClient (Xi18n i18n_core, Window new_client)
-     XClient *x_client;
- 
-     x_client = (XClient *) malloc (sizeof (XClient));
--    x_client->client_win = new_client;
--    x_client->accept_win = XCreateSimpleWindow (dpy,
--                                                DefaultRootWindow(dpy),
--                                                0,
--                                                0,
--                                                1,
--                                                1,
--                                                1,
--                                                0,
--                                                0);
-+    if (!x_client) {
-+        fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
-+                 __FILE__, __LINE__);
-+    } else {
-+        x_client->client_win = new_client;
-+        x_client->accept_win = XCreateSimpleWindow (dpy,
-+                                                    DefaultRootWindow(dpy),
-+                                                    0,
-+                                                    0,
-+                                                    1,
-+                                                    1,
-+                                                    1,
-+                                                    0,
-+                                                    0);
-+    }
-     client->trans_rec = x_client;
-     return ((XClient *) x_client);
- }
-@@ -219,7 +224,7 @@ static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev)
-     }
-     /*endif*/
-     _XRegisterFilterByType (dpy,
--                            x_client->accept_win,
-+                            x_client ? x_client->accept_win : 0,
-                             ClientMessage,
-                             ClientMessage,
-                             WaitXIMProtocol,
-@@ -229,7 +234,7 @@ static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev)
-     event.xclient.window = new_client;
-     event.xclient.message_type = spec->connect_request;
-     event.xclient.format = 32;
--    event.xclient.data.l[0] = x_client->accept_win;
-+    event.xclient.data.l[0] = x_client ? x_client->accept_win : 0;
-     event.xclient.data.l[1] = major_version;
-     event.xclient.data.l[2] = minor_version;
-     event.xclient.data.l[3] = XCM_DATA_LIMIT;
--- 
-2.28.0
-
-From bc7811c6247b7bb8eba2f9f80c4f9f1510cd6b65 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 16 Jun 2021 20:39:35 +0900
-Subject: [PATCH] src/tests: Fix ibus-desktop-testing-runner to get gsettings result
-
-gsettings null string is '' and the quote mark needs to be parsed.
-Also no-overview gsetting should be changed before run gnome-session.
----
- src/tests/ibus-desktop-testing-runner.in | 18 +++++++++++-------
- 1 file changed, 11 insertions(+), 7 deletions(-)
-
-diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in
-index 15b2369d..54b7e0d7 100755
---- a/src/tests/ibus-desktop-testing-runner.in
-+++ b/src/tests/ibus-desktop-testing-runner.in
-@@ -215,9 +215,11 @@ run_dbus_daemon()
- 
- init_gnome()
- {
-+    # gsettings set command needs dconf-service with the same $DISPLAY
-+    pkill dconf-service
-     # Disable Tour dialog to get focus
-     V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version`
--    if [ x"$V" = x ] ; then
-+    if [ x"$V" = x"''" ] ; then
-         gsettings set org.gnome.shell welcome-dialog-last-shown-version '100'
-     fi
-     # gnome-shell now starts overview mode by login.
-@@ -237,7 +239,7 @@ init_gnome()
-     V2=$?
-     if [ $V2 -ne 0 ] ; then
-         V3=`echo "$V" | sed -e 's/\[//' -e 's/\]//'`
--        if [ x"$V3" = x ] ; then
-+        if [ x"$V3" = x"''" ] ; then
-             V4="['no-overview@fthx']"
-         else
-             V4="[$V3, 'no-overview@fthx']"
-@@ -248,6 +250,8 @@ init_gnome()
- 
- run_desktop()
- {
-+    echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null
-+    HAS_GNOME=$?
-     if test $HAVE_GRAPHICS -eq 1 ; then
-         /usr/libexec/Xorg.wrap -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . $DISPLAY &
-     else
-@@ -256,15 +260,15 @@ run_desktop()
-     PID_XORG=$!
-     sleep 1
-     export DISPLAY=$DISPLAY
-+    # init_gnome need to be called with $DISPLAY before gnome-session is called
-+    if [  $HAS_GNOME -eq 0 ] ; then
-+        init_gnome
-+    fi
-     echo "Running $DESKTOP_COMMAND with $USER in `tty`"
-     $DESKTOP_COMMAND &
-     PID_GNOME_SESSION=$!
-     sleep 30
--    echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null
--    HAS_GNOME=$?
--    if [  $HAS_GNOME -eq 0 ] ; then
--        init_gnome
--    else
-+    if [  $HAS_GNOME -ne 0 ] ; then
-         ibus-daemon --daemonize --verbose
-         sleep 3
-     fi
--- 
-2.28.0
-
-From 9f9c88be46436b0a7aa8e09e044a2223356b46dc Mon Sep 17 00:00:00 2001
-From: lf- <software@lfcode.ca>
-Date: Fri, 18 Jun 2021 15:39:19 +0900
-Subject: [PATCH] src/ibuscomposetable: Add support for the include
- directive
-
-We also fix an issue with excess space at the start of lines stopping
-comments being recognized.
-
-BUG=https://github.com/ibus/ibus/pull/2296
----
- src/ibuscomposetable.c | 100 ++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 95 insertions(+), 5 deletions(-)
-
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index 685ac717..66a5dfa7 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -21,7 +21,6 @@
- 
- #include <glib.h>
- #include <glib/gstdio.h>
--#include <locale.h>
- #include <stdlib.h>
- #include <string.h>
- 
-@@ -36,6 +35,7 @@
- 
- #define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable"
- #define IBUS_COMPOSE_TABLE_VERSION (3)
-+#define PATHLEN_MAX 256
- 
- typedef struct {
-   gunichar     *sequence;
-@@ -181,7 +181,8 @@ parse_compose_sequence (IBusComposeData *compose_data,
-     int n = 0;
- 
-     if (g_strv_length (words) < 2) {
--        g_warning ("key sequence format is <a> <b>...: %s", line);
-+        g_warning ("too few words; key sequence format is <a> <b>...: %s",
-+                   line);
-         goto fail;
-     }
- 
-@@ -244,10 +245,68 @@ fail:
- }
- 
- 
-+static gchar *
-+expand_include_path (const gchar *include_path) {
-+    gchar *out = g_malloc0 (PATHLEN_MAX);
-+    gchar *out_lastchar = out + PATHLEN_MAX - 2;
-+    const gchar *i = include_path;
-+    gchar *o = out;
-+
-+    while (*i && o < out_lastchar) {
-+        // expand sequence
-+        if (*i == '%') {
-+            switch (*(i+1)) {
-+            // $HOME
-+            case 'H': {
-+                const gchar *home = getenv ("HOME");
-+                if (!home) {
-+                    g_warning ("while parsing XCompose include target %s, "
-+                               "%%H replacement failed because HOME is not "
-+                               "defined; the include has been ignored",
-+                               include_path);
-+                    goto fail;
-+                }
-+                o = out + g_strlcat (out, home, PATHLEN_MAX);
-+                break;
-+            }
-+            // locale compose file
-+            case 'L':
-+                g_warning ("while handling XCompose include target %s, found "
-+                          "redundant %%L include; the include has been "
-+                          "ignored", include_path);
-+                goto fail;
-+            // system compose dir
-+            case 'S':
-+                o = out + g_strlcat (out, "/usr/share/X11/locale",
-+                                     PATHLEN_MAX);
-+                break;
-+            // escaped %
-+            case '%':
-+                *o++ = '%';
-+                break;
-+            default:
-+                g_warning ("while parsing XCompose include target %s, found "
-+                           "unknown substitution character '%c'; the include "
-+                           "has been ignored", include_path, *(i+1));
-+                goto fail;
-+            }
-+            i += 2;
-+        } else {
-+            *o++ = *i++;
-+        }
-+    }
-+    return out;
-+fail:
-+    g_free (out);
-+    return NULL;
-+}
-+
-+
- static void
- parse_compose_line (GList       **compose_list,
-                     const gchar  *line,
--                    int          *compose_len)
-+                    int          *compose_len,
-+                    gchar        **include)
- {
-     gchar **components = NULL;
-     IBusComposeData *compose_data = NULL;
-@@ -256,11 +315,32 @@ parse_compose_line (GList       **compose_list,
-     g_assert (compose_len);
-     *compose_len = 0;
- 
-+    // eat spaces at the start of the line
-+    while (*line && (*line == ' ' || *line == '\t')) line++;
-+
-     if (line[0] == '\0' || line[0] == '#')
-         return;
- 
--    if (g_str_has_prefix (line, "include "))
-+    if (g_str_has_prefix (line, "include ")) {
-+        const char *rest = line + sizeof ("include ") - 1;
-+        while (*rest && *rest == ' ') rest++;
-+
-+        // grabbed the path part of the line
-+        char *rest2;
-+        if (*rest == '"') {
-+            rest++;
-+            rest2 = g_strdup (rest);
-+            // eat the closing quote
-+            char *i = rest2;
-+            while (*i && *i != '"') i++;
-+            *i = '\0';
-+        } else {
-+            rest2 = g_strdup (rest);
-+        }
-+        *include = expand_include_path (rest2);
-+        g_free (rest2);
-         return;
-+    }
- 
-     components = g_strsplit (line, ":", 2);
- 
-@@ -316,8 +396,18 @@ ibus_compose_list_parse_file (const gchar *compose_file,
- 
-     lines = g_strsplit (contents, "\n", -1);
-     g_free (contents);
-+    gchar *include = NULL;
-     for (i = 0; lines[i] != NULL; i++) {
--        parse_compose_line (&compose_list, lines[i], &compose_len);
-+        parse_compose_line (&compose_list, lines[i], &compose_len, &include);
-+        if (include && *include) {
-+            GList *rest = ibus_compose_list_parse_file (include,
-+                    max_compose_len);
-+            if (rest) {
-+                compose_list = g_list_concat (compose_list, rest);
-+            }
-+        }
-+
-+        g_clear_pointer (&include, g_free);
-         if (*max_compose_len < compose_len)
-             *max_compose_len = compose_len;
-     }
--- 
-2.28.0
-
-From a755d1601a730b5fa0d463e7820311c12b1f1661 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 18 Jun 2021 15:39:50 +0900
-Subject: [PATCH] src/ibuscomposetable: Do not include the same compose
- file
-
-BUG=https://github.com/ibus/ibus/pull/2296
----
- src/ibuscomposetable.c | 130 +++++++++++++++++++++++++++++++----------
- 1 file changed, 100 insertions(+), 30 deletions(-)
-
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index 66a5dfa7..916fcae3 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -34,8 +34,8 @@
- #include "ibusenginesimpleprivate.h"
- 
- #define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable"
--#define IBUS_COMPOSE_TABLE_VERSION (3)
--#define PATHLEN_MAX 256
-+#define IBUS_COMPOSE_TABLE_VERSION (4)
-+#define X11_DATADIR X11_DATA_PREFIX "/share/X11/locale"
- 
- typedef struct {
-   gunichar     *sequence;
-@@ -247,17 +247,15 @@ fail:
- 
- static gchar *
- expand_include_path (const gchar *include_path) {
--    gchar *out = g_malloc0 (PATHLEN_MAX);
--    gchar *out_lastchar = out + PATHLEN_MAX - 2;
--    const gchar *i = include_path;
--    gchar *o = out;
-+    gchar *out = strdup ("");
-+    const gchar *head, *i;
-+    gchar *former, *o;
- 
--    while (*i && o < out_lastchar) {
--        // expand sequence
-+    for (head = i = include_path; *i; ++i) {
-+        /* expand sequence */
-         if (*i == '%') {
--            switch (*(i+1)) {
--            // $HOME
--            case 'H': {
-+            switch (*(i + 1)) {
-+            case 'H': { /* $HOME */
-                 const gchar *home = getenv ("HOME");
-                 if (!home) {
-                     g_warning ("while parsing XCompose include target %s, "
-@@ -266,23 +264,34 @@ expand_include_path (const gchar *include_path) {
-                                include_path);
-                     goto fail;
-                 }
--                o = out + g_strlcat (out, home, PATHLEN_MAX);
-+                o = out;
-+                former = g_strndup (head, i - head);
-+                out = g_strdup_printf ("%s%s%s", o, former, home);
-+                head = i + 2;
-+                g_free (o);
-+                g_free (former);
-                 break;
-             }
--            // locale compose file
--            case 'L':
-+            case 'L': /* locale compose file */
-                 g_warning ("while handling XCompose include target %s, found "
-                           "redundant %%L include; the include has been "
-                           "ignored", include_path);
-                 goto fail;
--            // system compose dir
--            case 'S':
--                o = out + g_strlcat (out, "/usr/share/X11/locale",
--                                     PATHLEN_MAX);
-+            case 'S': /* system compose dir */
-+                o = out;
-+                former = g_strndup (head, i - head);
-+                out = g_strdup_printf ("%s%s%s", o, former, X11_DATADIR);
-+                head = i + 2;
-+                g_free (o);
-+                g_free (former);
-                 break;
--            // escaped %
--            case '%':
--                *o++ = '%';
-+            case '%': /* escaped % */
-+                o = out;
-+                former = g_strndup (head, i - head);
-+                out = g_strdup_printf ("%s%s%s", o, former, "%");
-+                head = i + 2;
-+                g_free (o);
-+                g_free (former);
-                 break;
-             default:
-                 g_warning ("while parsing XCompose include target %s, found "
-@@ -290,11 +299,12 @@ expand_include_path (const gchar *include_path) {
-                            "has been ignored", include_path, *(i+1));
-                 goto fail;
-             }
--            i += 2;
--        } else {
--            *o++ = *i++;
-+            ++i;
-         }
-     }
-+    o = out;
-+    out = g_strdup_printf ("%s%s", o, head);
-+    g_free (o);
-     return out;
- fail:
-     g_free (out);
-@@ -315,7 +325,7 @@ parse_compose_line (GList       **compose_list,
-     g_assert (compose_len);
-     *compose_len = 0;
- 
--    // eat spaces at the start of the line
-+    /* eat spaces at the start of the line */
-     while (*line && (*line == ' ' || *line == '\t')) line++;
- 
-     if (line[0] == '\0' || line[0] == '#')
-@@ -325,12 +335,12 @@ parse_compose_line (GList       **compose_list,
-         const char *rest = line + sizeof ("include ") - 1;
-         while (*rest && *rest == ' ') rest++;
- 
--        // grabbed the path part of the line
-+        /* grabbed the path part of the line */
-         char *rest2;
-         if (*rest == '"') {
-             rest++;
-             rest2 = g_strdup (rest);
--            // eat the closing quote
-+            /* eat the closing quote */
-             char *i = rest2;
-             while (*i && *i != '"') i++;
-             *i = '\0';
-@@ -374,6 +384,23 @@ fail:
- }
- 
- 
-+static gchar *
-+get_en_compose_file (void)
-+{
-+    gchar * const sys_langs[] = { "en_US.UTF-8", "en_US", "en.UTF-8",
-+                                  "en", NULL };
-+    gchar * const *sys_lang = NULL;
-+    gchar *path = NULL;
-+    for (sys_lang = sys_langs; *sys_lang; sys_lang++) {
-+        path = g_build_filename (X11_DATADIR, *sys_lang, "Compose", NULL);
-+        if (g_file_test (path, G_FILE_TEST_EXISTS))
-+            break;
-+        g_free (path);
-+    }
-+    return path;
-+}
-+
-+
- static GList *
- ibus_compose_list_parse_file (const gchar *compose_file,
-                               int         *max_compose_len)
-@@ -399,6 +426,52 @@ ibus_compose_list_parse_file (const gchar *compose_file,
-     gchar *include = NULL;
-     for (i = 0; lines[i] != NULL; i++) {
-         parse_compose_line (&compose_list, lines[i], &compose_len, &include);
-+        if (*max_compose_len < compose_len)
-+            *max_compose_len = compose_len;
-+        if (include && *include) {
-+            GStatBuf buf_include = { 0, };
-+            GStatBuf buf_parent = { 0, };
-+            gchar *en_compose;
-+            errno = 0;
-+            if (g_stat (include,  &buf_include)) {
-+                g_warning ("Cannot access %s: %s",
-+                           include,
-+                           g_strerror (errno));
-+                g_clear_pointer (&include, g_free);
-+                continue;
-+            }
-+            errno = 0;
-+            if (g_stat (compose_file,  &buf_parent)) {
-+                g_warning ("Cannot access %s: %s",
-+                           compose_file,
-+                           g_strerror (errno));
-+                g_clear_pointer (&include, g_free);
-+                continue;
-+            }
-+            if (buf_include.st_ino == buf_parent.st_ino) {
-+                g_warning ("Found recursive nest same file %s", include);
-+                g_clear_pointer (&include, g_free);
-+                continue;
-+            }
-+            en_compose = get_en_compose_file ();
-+            if (en_compose) {
-+                errno = 0;
-+                if (g_stat (en_compose,  &buf_parent)) {
-+                    g_warning ("Cannot access %s: %s",
-+                               compose_file,
-+                               g_strerror (errno));
-+                    g_clear_pointer (&include, g_free);
-+                    g_free (en_compose);
-+                    continue;
-+                }
-+            }
-+            g_free (en_compose);
-+            if (buf_include.st_ino == buf_parent.st_ino) {
-+                g_log ("System en_US Compose is already loaded %s\n", include);
-+                g_clear_pointer (&include, g_free);
-+                continue;
-+            }
-+        }
-         if (include && *include) {
-             GList *rest = ibus_compose_list_parse_file (include,
-                     max_compose_len);
-@@ -406,10 +479,7 @@ ibus_compose_list_parse_file (const gchar *compose_file,
-                 compose_list = g_list_concat (compose_list, rest);
-             }
-         }
--
-         g_clear_pointer (&include, g_free);
--        if (*max_compose_len < compose_len)
--            *max_compose_len = compose_len;
-     }
-     g_strfreev (lines);
- 
--- 
-2.28.0
-
-From 7f09379b3cb69c7de6d8d667ce398dcfc0000433 Mon Sep 17 00:00:00 2001
-From: lf- <software@lfcode.ca>
-Date: Thu, 24 Jun 2021 16:10:12 +0900
-Subject: [PATCH] src/ibuscomposetable: Fix a buffer overflow in compose
- handling
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-I believe this has no security impact but it is making my Valgrind sad.
-
-Thanks to Omni for the help in finding the root cause of this.
-
-~/.XCompose is:
-```
-<Multi_key> <g> <h> : "η"
-<Multi_key> <g> <v> <t> <h> : "ϑ"
-<Multi_key> <g> <h>     : "ɣ"
-```
-
-BUG=https://github.com/ibus/ibus/pull/2297
----
- src/ibuscomposetable.c | 15 ++++++++++++---
- 1 file changed, 12 insertions(+), 3 deletions(-)
-
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index 916fcae3..dd7cbf83 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -410,7 +410,6 @@ ibus_compose_list_parse_file (const gchar *compose_file,
-     gsize length = 0;
-     GError *error = NULL;
-     GList *compose_list = NULL;
--    int compose_len = 0;
-     int i;
- 
-     g_assert (max_compose_len);
-@@ -423,8 +422,9 @@ ibus_compose_list_parse_file (const gchar *compose_file,
- 
-     lines = g_strsplit (contents, "\n", -1);
-     g_free (contents);
--    gchar *include = NULL;
-     for (i = 0; lines[i] != NULL; i++) {
-+        int compose_len = 0;
-+        gchar *include = NULL;
-         parse_compose_line (&compose_list, lines[i], &compose_len, &include);
-         if (*max_compose_len < compose_len)
-             *max_compose_len = compose_len;
-@@ -467,7 +467,8 @@ ibus_compose_list_parse_file (const gchar *compose_file,
-             }
-             g_free (en_compose);
-             if (buf_include.st_ino == buf_parent.st_ino) {
--                g_log ("System en_US Compose is already loaded %s\n", include);
-+                g_message ("System en_US Compose is already loaded %s\n",
-+                           include);
-                 g_clear_pointer (&include, g_free);
-                 continue;
-             }
-@@ -583,12 +584,20 @@ ibus_compose_data_compare (gpointer a,
-     IBusComposeData *compose_data_b = b;
-     int max_compose_len = GPOINTER_TO_INT (data);
-     int i;
-+    /* The allocation length of compose_data_a->sequence[] is different from
-+     * one of compose_data_b->sequence[] and max_compose_len indicates
-+     * the sequence length only but not include the compose value length.
-+     * So max_compose_len is greater than any allocation lengths of sequence[]
-+     * and this API should return if code_a or code_b is 0.
-+     */
-     for (i = 0; i < max_compose_len; i++) {
-         gunichar code_a = compose_data_a->sequence[i];
-         gunichar code_b = compose_data_b->sequence[i];
- 
-         if (code_a != code_b)
-             return code_a - code_b;
-+        if (code_a == 0 && code_b == 0)
-+            return 0;
-     }
-     return 0;
- }
--- 
-2.28.0
-
-From ab6b9587a497e9662a2936df3dabed4582eeabdb Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Tue, 29 Jun 2021 12:40:20 +0900
-Subject: [PATCH] src/tests: Delete G_MESSAGES_DEBUG in desktop-testing for
- gsettings
-
-G_MESSAGES_DEBUG message could be appended to the output of gsettings
-command and it's not useful to check the output.
----
- src/tests/ibus-desktop-testing-runner.in | 11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
-diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in
-index 54b7e0d7..0ef72c03 100755
---- a/src/tests/ibus-desktop-testing-runner.in
-+++ b/src/tests/ibus-desktop-testing-runner.in
-@@ -217,6 +217,10 @@ init_gnome()
- {
-     # gsettings set command needs dconf-service with the same $DISPLAY
-     pkill dconf-service
-+    # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append
-+    # debug messages to gsettings output and could not get the result correctly.
-+    backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG"
-+    export -n G_MESSAGES_DEBUG=''
-     # Disable Tour dialog to get focus
-     V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version`
-     if [ x"$V" = x"''" ] ; then
-@@ -238,14 +242,17 @@ init_gnome()
-     echo "$V" | grep "no-overview" > /dev/null
-     V2=$?
-     if [ $V2 -ne 0 ] ; then
--        V3=`echo "$V" | sed -e 's/\[//' -e 's/\]//'`
--        if [ x"$V3" = x"''" ] ; then
-+        V3=`echo "$V" | sed -e 's/@as //' -e 's/\[//' -e 's/\]//'`
-+        if [ x"$V3" = x"''" ] || [ x"$V3" = x"" ]; then
-             V4="['no-overview@fthx']"
-         else
-             V4="[$V3, 'no-overview@fthx']"
-         fi
-         gsettings set org.gnome.shell enabled-extensions "$V4"
-     fi
-+    if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then
-+        export G_MESSAGES_DEBUG="$backup_G_MESSAGES_DEBUG"
-+    fi
- }
- 
- run_desktop()
--- 
-2.28.0
-
-From b952d30a1b7c741052c168fe1081ecb4d4b1c034 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 14 Jul 2021 22:31:47 +0900
-Subject: [PATCH] Change default Emoji shortcut key
-
-The shortcut key was Ctrl-Shit-e to follow Unicode code point
-shortcut key but now the shorcut key is changed to Ctrl-period
-to follow GTK.
-
-BUG=https://github.com/ibus/ibus/issues/2325
----
- data/dconf/org.freedesktop.ibus.gschema.xml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml
-index a79e9296..099b9c60 100644
---- a/data/dconf/org.freedesktop.ibus.gschema.xml
-+++ b/data/dconf/org.freedesktop.ibus.gschema.xml
-@@ -183,7 +183,7 @@
-       <description>The shortcut keys for turning Unicode typing on or off</description>
-     </key>
-     <key name="hotkey" type="as">
--      <default>[ '&lt;Control&gt;&lt;Shift&gt;e' ]</default>
-+      <default>[ '&lt;Control&gt;period' ]</default>
-       <summary>Emoji shortcut keys for gtk_accelerator_parse</summary>
-       <description>The shortcut keys for turning emoji typing on or off</description>
-     </key>
--- 
-2.28.0
-
-From a4939f67f9de8275219e2cfcd3873e0fbe59058f Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 16 Jul 2021 13:08:02 +0900
-Subject: [PATCH] setup: Enhance engine search function
-
-ibus-setup can search both the language names and input method names
-in the top language list but when you search a language keyword
-in the language list and move to the input method list after click
-the hit language name, any input methods could not be shown because
-the language didn't hit in any input method names.
-
-In this enhancement, ibus-setup can show the input methods to hit
-the language names.
----
- setup/enginedialog.py | 26 ++++++++++++++++++++------
- 1 file changed, 20 insertions(+), 6 deletions(-)
-
-diff --git a/setup/enginedialog.py b/setup/enginedialog.py
-index e1c322bf..470f801c 100644
---- a/setup/enginedialog.py
-+++ b/setup/enginedialog.py
-@@ -120,12 +120,26 @@ class EngineDialog(Gtk.Dialog):
-             return True
-         if word in row.untrans.lower():
-             return True
--        if row.lang_info and row.name in self.__engines_for_lang:
--            for row_e in self.__engines_for_lang[row.name]:
--                if word in row_e.name.lower():
--                    return True
--                if word in row_e.untrans.lower():
--                    return True
-+        # Search engine name in language list
-+        if row.lang_info:
-+            if row.name in self.__engines_for_lang.keys():
-+                for row_l in self.__engines_for_lang[row.name]:
-+                    if word in row_l.name.lower():
-+                        return True
-+                    if word in row_l.untrans.lower():
-+                        return True
-+        # Search language name in engine list
-+        if not row.lang_info:
-+            for l in self.__engines_for_lang.keys():
-+                if word in l.lower():
-+                    for row_l in self.__engines_for_lang[l]:
-+                        if row.name == row_l.name:
-+                            return True
-+            for (trans, untrans) in self.__untrans_for_lang.items():
-+                if word in untrans.lower():
-+                    for row_l in self.__engines_for_lang[trans]:
-+                        if row.name == row_l.name:
-+                            return True
-         return False
- 
- 
--- 
-2.28.0
-
-From 7e12d589ee4979fdd0f0b08f1bac9049741ec628 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 26 Jul 2021 22:52:12 +0900
-Subject: [PATCH 1/6] src/ibuscomposetable: Move ibus_compose_table_check
-
-- Move ibus_compose_table_check and ibus_compose_table_compact_check
-  from ibusenginesimple.c to ibuscomposetable.c
-- Fix src/tests/ibus-compose.c to read compose sequences correctly.
----
- src/ibuscomposetable.c        | 519 +++++++++++++++++++++++++++++-
- src/ibusenginesimple.c        | 583 ++++------------------------------
- src/ibusenginesimpleprivate.h |  17 +-
- src/tests/Makefile.am         |   3 +-
- src/tests/ibus-compose.c      |   7 +-
- 5 files changed, 601 insertions(+), 528 deletions(-)
-
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index dd7cbf83..f85177a6 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -33,6 +33,13 @@
- 
- #include "ibusenginesimpleprivate.h"
- 
-+/* 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.
-+ */
-+#include "gtkimcontextsimpleseqs.h"
-+
-+
- #define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable"
- #define IBUS_COMPOSE_TABLE_VERSION (4)
- #define X11_DATADIR X11_DATA_PREFIX "/share/X11/locale"
-@@ -44,6 +51,10 @@ typedef struct {
- } IBusComposeData;
- 
- 
-+extern const IBusComposeTableCompactEx ibus_compose_table_compact;
-+extern const IBusComposeTableCompactEx ibus_compose_table_compact_32bit;
-+
-+
- static void
- ibus_compose_data_free (IBusComposeData *compose_data)
- {
-@@ -527,20 +538,22 @@ ibus_compose_list_check_duplicated (GList *compose_list,
-         is_32bit = (n_outputs > 1) ? TRUE :
-                 (compose_data->values[0] >= 0xFFFF) ? TRUE : FALSE;
-         if (!is_32bit &&
--            ibus_check_compact_table (&ibus_compose_table_compact,
--                                      keysyms,
--                                      n_compose,
--                                      &compose_finish,
--                                      &output_chars) && compose_finish) {
-+            ibus_compose_table_compact_check (&ibus_compose_table_compact,
-+                                              keysyms,
-+                                              n_compose,
-+                                              &compose_finish,
-+                                              &output_chars) &&
-+            compose_finish) {
-             if (compose_data->values[0] == *output_chars)
-                 removed_list = g_list_append (removed_list, compose_data);
-             g_free (output_chars);
-         } else if (is_32bit &&
--                   ibus_check_compact_table (&ibus_compose_table_compact_32bit,
--                                             keysyms,
--                                             n_compose,
--                                             &compose_finish,
--                                             &output_chars) && compose_finish) {
-+                   ibus_compose_table_compact_check (
-+                          &ibus_compose_table_compact_32bit,
-+                          keysyms,
-+                          n_compose,
-+                          &compose_finish,
-+                          &output_chars) && compose_finish) {
-             
-             if (n_outputs == unichar_length (output_chars)) {
-                 int j = 0;
-@@ -1354,3 +1367,489 @@ ibus_compose_table_list_add_file (GSList      *compose_tables,
-     ibus_compose_table_save_cache (compose_table);
-     return g_slist_prepend (compose_tables, compose_table);
- }
-+
-+
-+static int
-+compare_seq (const void *key, const void *value)
-+{
-+    int i = 0;
-+    const guint16 *keysyms = key;
-+    const guint16 *seq = value;
-+
-+    while (keysyms[i]) {
-+        if (keysyms[i] < seq[i])
-+            return -1;
-+        else if (keysyms[i] > seq[i])
-+            return 1;
-+
-+        i++;
-+    }
-+
-+    return 0;
-+}
-+
-+
-+gboolean
-+ibus_compose_table_check (const IBusComposeTableEx *table,
-+                          guint16                  *compose_buffer,
-+                          gint                      n_compose,
-+                          gboolean                 *compose_finish,
-+                          gboolean                 *compose_match,
-+                          GString                  *output,
-+                          gboolean                  is_32bit)
-+{
-+    gint row_stride = table->max_seq_len + 2;
-+    guint16 *data_first;
-+    int n_seqs;
-+    guint16 *seq;
-+
-+    if (compose_finish)
-+        *compose_finish = FALSE;
-+    if (compose_match)
-+        *compose_match = FALSE;
-+    if (output)
-+        g_string_set_size (output, 0);
-+
-+    if (n_compose > table->max_seq_len)
-+        return FALSE;
-+
-+    if (is_32bit) {
-+        if (!table->priv)
-+            return FALSE;
-+        data_first = table->priv->data_first;
-+        n_seqs = table->priv->first_n_seqs;
-+    } else {
-+        data_first = table->data;
-+        n_seqs = table->n_seqs;
-+    }
-+    seq = bsearch (compose_buffer,
-+                   data_first, n_seqs,
-+                   sizeof (guint16) * row_stride,
-+                   compare_seq);
-+
-+    if (seq == NULL)
-+        return FALSE;
-+
-+    guint16 *prev_seq;
-+
-+    /* Back up to the first sequence that matches to make sure
-+     * we find the exact match if their is one.
-+     */
-+    while (seq > data_first) {
-+        prev_seq = seq - row_stride;
-+        if (compare_seq (compose_buffer, prev_seq) != 0)
-+            break;
-+        seq = prev_seq;
-+    }
-+
-+    /* complete sequence */
-+    if (n_compose == table->max_seq_len || seq[n_compose] == 0) {
-+        guint16 *next_seq;
-+        gunichar value = 0;
-+        int num = 0;
-+        int index = 0;
-+        gchar *output_str = NULL;
-+        GError *error = NULL;
-+
-+        if (is_32bit) {
-+            num = seq[table->max_seq_len];
-+            index = seq[table->max_seq_len + 1];
-+            value =  table->priv->data_second[index];
-+        } else {
-+            value = seq[table->max_seq_len];
-+        }
-+
-+        if (is_32bit) {
-+            output_str = g_ucs4_to_utf8 (table->priv->data_second + index,
-+                                         num, NULL, NULL, &error);
-+            if (output_str) {
-+                if (output)
-+                    g_string_append (output, output_str);
-+                g_free (output_str);
-+                if (compose_match)
-+                    *compose_match = TRUE;
-+            } else {
-+                g_warning ("Failed to output multiple characters: %s",
-+                           error->message);
-+                g_error_free (error);
-+            }
-+        } else {
-+            if (output)
-+                g_string_append_unichar (output, value);
-+            if (compose_match)
-+                *compose_match = TRUE;
-+        }
-+
-+        /* We found a tentative match. See if there are any longer
-+         * sequences containing this subsequence
-+         */
-+        next_seq = seq + row_stride;
-+        if (next_seq < data_first + row_stride * n_seqs) {
-+            if (compare_seq (compose_buffer, next_seq) == 0)
-+                return TRUE;
-+        }
-+
-+        if (compose_finish)
-+            *compose_finish = TRUE;
-+        compose_buffer[0] = 0;
-+    }
-+    return TRUE;
-+}
-+
-+
-+static int
-+compare_seq_index (const void *key, const void *value)
-+{
-+    const guint16 *keysyms = key;
-+    const guint16 *seq = value;
-+
-+    if (keysyms[0] < seq[0])
-+        return -1;
-+    else if (keysyms[0] > seq[0])
-+        return 1;
-+    return 0;
-+}
-+
-+
-+/**
-+ * ibus_compose_table_compact_check:
-+ * @table: A const `IBusComposeTableCompactEx`
-+ * @compose_buffer: Typed compose sequence buffer
-+ * @n_compose: The length of `compose_buffer`
-+ * @compose_finish: If %TRUE, `output_chars` should be committed
-+ * @output_chars: An array of gunichar of output compose characters
-+ *
-+ * output_chars is better to use gunichar instead of GString because
-+ * IBusComposeData->values[] is the gunichar array.
-+ */
-+gboolean
-+ibus_compose_table_compact_check (const IBusComposeTableCompactEx *table,
-+                                  guint16
-+                                                               *compose_buffer,
-+                                  gint                             n_compose,
-+                                  gboolean
-+                                                               *compose_finish,
-+                                  gunichar                       **output_chars)
-+{
-+    gint row_stride;
-+    guint16 *seq_index;
-+    guint16 *seq;
-+    gint i;
-+
-+    if (compose_finish)
-+        *compose_finish = FALSE;
-+    if (output_chars)
-+        *output_chars = NULL;
-+
-+    /* 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. */
-+    if (n_compose > table->max_seq_len)
-+        return FALSE;
-+
-+    seq_index = bsearch (compose_buffer,
-+                         table->data,
-+                         table->n_index_size,
-+                         sizeof (guint16) *  table->n_index_stride,
-+                         compare_seq_index);
-+
-+    if (seq_index == NULL)
-+        return FALSE;
-+
-+    if (n_compose == 1)
-+        return TRUE;
-+
-+    seq = NULL;
-+
-+    if (table->priv) {
-+        for (i = n_compose - 1; i < table->max_seq_len; i++) {
-+            row_stride = i + 2;
-+
-+            if (seq_index[i + 1] - seq_index[i] > 0) {
-+                seq = bsearch (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 (i == n_compose - 1)
-+                        break;
-+                    else
-+                        return TRUE;
-+                }
-+            }
-+        }
-+        if (!seq) {
-+            return FALSE;
-+        } else {
-+            int index = seq[row_stride - 2];
-+            int length = seq[row_stride - 1];
-+            int j;
-+            if (compose_finish)
-+                *compose_finish = TRUE;
-+            if (output_chars) {
-+                *output_chars = g_new (gunichar, length + 1);
-+                for (j = 0; j < length; j++) {
-+                    (*output_chars)[j] = table->priv->data2[index + j];
-+                }
-+                (*output_chars)[length] = 0;
-+            }
-+
-+            return TRUE;
-+        }
-+    } else {
-+        for (i = n_compose - 1; i < table->max_seq_len; i++) {
-+            row_stride = i + 1;
-+
-+            if (seq_index[i + 1] - seq_index[i] > 0) {
-+                seq = bsearch (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 (i == n_compose - 1)
-+                        break;
-+                    else
-+                        return TRUE;
-+                }
-+            }
-+        }
-+        if (!seq) {
-+            return FALSE;
-+        } else {
-+            if (compose_finish)
-+                *compose_finish = TRUE;
-+            if (output_chars) {
-+                *output_chars = g_new (gunichar, 2);
-+                (*output_chars)[0] = seq[row_stride - 1];
-+                (*output_chars)[1] = 0;
-+            }
-+
-+            return TRUE;
-+        }
-+    }
-+
-+    g_assert_not_reached ();
-+}
-+
-+
-+/* Checks if a keysym is a dead key. Dead key keysym values are defined in
-+ * ../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_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) >= IBUS_KEY_dead_grave && (k) <= IBUS_KEY_dead_greek)
-+
-+/* This function receives a sequence of Unicode characters and tries to
-+ * normalize it (NFC). We check for the case the 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, gint n_compose)
-+{
-+    gunichar combination_buffer_temp[IBUS_MAX_COMPOSE_LEN];
-+    gchar *combination_utf8_temp = NULL;
-+    gchar *nfc_temp = NULL;
-+    gint n_combinations;
-+    gunichar temp_swap;
-+    gint i;
-+
-+    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,
-+            IBUS_MAX_COMPOSE_LEN * 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, -1,
-+                                                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,
-+                    IBUS_MAX_COMPOSE_LEN * 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) {
-+            gint j = i % (n_compose - 1) + 1;
-+            gint k = (i+1) % (n_compose - 1) + 1;
-+            if (j >= IBUS_MAX_COMPOSE_LEN) {
-+                g_warning ("j >= IBUS_MAX_COMPOSE_LEN for " \
-+                           "combination_buffer_temp");
-+                break;
-+            }
-+            if (k >= IBUS_MAX_COMPOSE_LEN) {
-+                g_warning ("k >= IBUS_MAX_COMPOSE_LEN for " \
-+                           "combination_buffer_temp");
-+                break;
-+            }
-+            temp_swap = combination_buffer_temp[j];
-+            combination_buffer_temp[j] = combination_buffer_temp[k];
-+            combination_buffer_temp[k] = temp_swap;
-+        } else {
-+            break;
-+        }
-+    }
-+
-+    return FALSE;
-+}
-+
-+
-+gboolean
-+ibus_check_algorithmically (const guint16 *compose_buffer,
-+                            gint           n_compose,
-+                            gunichar      *output_char)
-+
-+{
-+    gint i;
-+    gunichar combination_buffer[IBUS_MAX_COMPOSE_LEN];
-+    gchar *combination_utf8, *nfc;
-+
-+    if (output_char)
-+        *output_char = 0;
-+
-+    if (n_compose >= IBUS_MAX_COMPOSE_LEN)
-+        return FALSE;
-+
-+    for (i = 0; i < n_compose && IS_DEAD_KEY (compose_buffer[i]); i++)
-+        ;
-+    if (i == n_compose)
-+        return TRUE;
-+
-+    if (i > 0 && i == n_compose - 1) {
-+        combination_buffer[0] = ibus_keyval_to_unicode (compose_buffer[i]);
-+        combination_buffer[n_compose] = 0;
-+        i--;
-+        while (i >= 0) {
-+            combination_buffer[i+1] = ibus_keysym_to_unicode (compose_buffer[i],
-+                                                              TRUE);
-+            if (!combination_buffer[i+1]) {
-+                combination_buffer[i+1] =
-+                        ibus_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);
-+
-+            if (output_char)
-+                *output_char = g_utf8_get_char (nfc);
-+
-+            g_free (combination_utf8);
-+            g_free (nfc);
-+
-+            return TRUE;
-+        }
-+    }
-+
-+    return FALSE;
-+}
-+
-+
-+gunichar
-+ibus_keysym_to_unicode (guint16  keysym,
-+                        gboolean combining) {
-+#define CASE(keysym_suffix, unicode)                                    \
-+        case IBUS_KEY_dead_##keysym_suffix: return unicode
-+#define CASE_COMBINE(keysym_suffix, combined_unicode, isolated_unicode) \
-+        case IBUS_KEY_dead_##keysym_suffix:                             \
-+            if (combining)                                              \
-+                return combined_unicode;                                \
-+            else                                                        \
-+                return isolated_unicode
-+    switch (keysym) {
-+    CASE (a, 0x03041);
-+    CASE (A, 0x03042);
-+    CASE (i, 0x03043);
-+    CASE (I, 0x03044);
-+    CASE (u, 0x03045);
-+    CASE (U, 0x03046);
-+    CASE (e, 0x03047);
-+    CASE (E, 0x03048);
-+    CASE (o, 0x03049);
-+    CASE (O, 0x0304A);
-+    CASE         (abovecomma,                   0x0313);
-+    CASE_COMBINE (abovedot,                     0x0307, 0x02D9);
-+    CASE         (abovereversedcomma,           0x0314);
-+    CASE_COMBINE (abovering,                    0x030A, 0x02DA);
-+    CASE_COMBINE (acute,                        0x0301, 0x00B4);
-+    CASE         (belowbreve,                   0x032E);
-+    CASE_COMBINE (belowcircumflex,              0x032D, 0xA788);
-+    CASE_COMBINE (belowcomma,                   0x0326, 0x002C);
-+    CASE         (belowdiaeresis,               0x0324);
-+    CASE_COMBINE (belowdot,                     0x0323, 0x002E);
-+    CASE_COMBINE (belowmacron,                  0x0331, 0x02CD);
-+    CASE_COMBINE (belowring,                    0x030A, 0x02F3);
-+    CASE_COMBINE (belowtilde,                   0x0330, 0x02F7);
-+    CASE_COMBINE (breve,                        0x0306, 0x02D8);
-+    CASE_COMBINE (capital_schwa,                0x018F, 0x04D8);
-+    CASE_COMBINE (caron,                        0x030C, 0x02C7);
-+    CASE_COMBINE (cedilla,                      0x0327, 0x00B8);
-+    CASE_COMBINE (circumflex,                   0x0302, 0x005E);
-+    CASE         (currency,                     0x00A4);
-+    // IBUS_KEY_dead_dasia == IBUS_KEY_dead_abovereversedcomma
-+    CASE_COMBINE (diaeresis,                    0x0308, 0x00A8);
-+    CASE_COMBINE (doubleacute,                  0x030B, 0x02DD);
-+    CASE_COMBINE (doublegrave,                  0x030F, 0x02F5);
-+    CASE_COMBINE (grave,                        0x0300, 0x0060);
-+    CASE         (greek,                        0x03BC);
-+    CASE         (hook,                         0x0309);
-+    CASE         (horn,                         0x031B);
-+    CASE         (invertedbreve,                0x032F);
-+    CASE_COMBINE (iota,                         0x0345, 0x037A);
-+    CASE_COMBINE (macron,                       0x0304, 0x00AF);
-+    CASE_COMBINE (ogonek,                       0x0328, 0x02DB);
-+    // IBUS_KEY_dead_perispomeni == IBUS_KEY_dead_tilde
-+    // IBUS_KEY_dead_psili == IBUS_KEY_dead_abovecomma
-+    CASE_COMBINE (semivoiced_sound,             0x309A, 0x309C);
-+    CASE_COMBINE (small_schwa,                  0x1D4A, 0x04D9);
-+    CASE         (stroke,                       0x002F);
-+    CASE_COMBINE (tilde,                        0x0303, 0x007E);
-+    CASE_COMBINE (voiced_sound,                 0x3099, 0x309B);
-+    case IBUS_KEY_Multi_key:
-+        return 0x2384;
-+    default:;
-+    }
-+    return 0x0;
-+#undef CASE
-+#undef CASE_COMBINE
-+}
-diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
-index 6dbc39c7..4644620b 100644
---- a/src/ibusenginesimple.c
-+++ b/src/ibusenginesimple.c
-@@ -91,11 +91,6 @@ struct _IBusEngineSimplePrivate {
-     gboolean            lookup_table_visible;
- };
- 
--struct _IBusComposeTableCompactPrivate
--{
--    const guint32 *data2;
--};
--
- /* From the values below, the value 30 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
-@@ -124,6 +119,7 @@ const IBusComposeTableCompactEx ibus_compose_table_compact_32bit = {
- };
- 
- guint COMPOSE_BUFFER_SIZE = 20;
-+G_LOCK_DEFINE_STATIC (global_tables);
- static GSList *global_tables;
- 
- /* functions prototype */
-@@ -261,74 +257,6 @@ ibus_engine_simple_commit_char (IBusEngineSimple *simple,
-             ibus_text_new_from_unichar (ch));
- }
- 
--static gunichar
--ibus_keysym_to_unicode (guint16  keysym,
--                        gboolean combining) {
--#define CASE(keysym_suffix, unicode)                                    \
--        case IBUS_KEY_dead_##keysym_suffix: return unicode
--#define CASE_COMBINE(keysym_suffix, combined_unicode, isolated_unicode) \
--        case IBUS_KEY_dead_##keysym_suffix:                             \
--            if (combining)                                              \
--                return combined_unicode;                                \
--            else                                                        \
--                return isolated_unicode
--    switch (keysym) {
--    CASE (a, 0x03041);
--    CASE (A, 0x03042);
--    CASE (i, 0x03043);
--    CASE (I, 0x03044);
--    CASE (u, 0x03045);
--    CASE (U, 0x03046);
--    CASE (e, 0x03047);
--    CASE (E, 0x03048);
--    CASE (o, 0x03049);
--    CASE (O, 0x0304A);
--    CASE         (abovecomma,                   0x0313);
--    CASE_COMBINE (abovedot,                     0x0307, 0x02D9);
--    CASE         (abovereversedcomma,           0x0314);
--    CASE_COMBINE (abovering,                    0x030A, 0x02DA);
--    CASE_COMBINE (acute,                        0x0301, 0x00B4);
--    CASE         (belowbreve,                   0x032E);
--    CASE_COMBINE (belowcircumflex,              0x032D, 0xA788);
--    CASE_COMBINE (belowcomma,                   0x0326, 0x002C);
--    CASE         (belowdiaeresis,               0x0324);
--    CASE_COMBINE (belowdot,                     0x0323, 0x002E);
--    CASE_COMBINE (belowmacron,                  0x0331, 0x02CD);
--    CASE_COMBINE (belowring,                    0x030A, 0x02F3);
--    CASE_COMBINE (belowtilde,                   0x0330, 0x02F7);
--    CASE_COMBINE (breve,                        0x0306, 0x02D8);
--    CASE_COMBINE (capital_schwa,                0x018F, 0x04D8);
--    CASE_COMBINE (caron,                        0x030C, 0x02C7);
--    CASE_COMBINE (cedilla,                      0x0327, 0x00B8);
--    CASE_COMBINE (circumflex,                   0x0302, 0x005E);
--    CASE         (currency,                     0x00A4);
--    // IBUS_KEY_dead_dasia == IBUS_KEY_dead_abovereversedcomma
--    CASE_COMBINE (diaeresis,                    0x0308, 0x00A8);
--    CASE_COMBINE (doubleacute,                  0x030B, 0x02DD);
--    CASE_COMBINE (doublegrave,                  0x030F, 0x02F5);
--    CASE_COMBINE (grave,                        0x0300, 0x0060);
--    CASE         (greek,                        0x03BC);
--    CASE         (hook,                         0x0309);
--    CASE         (horn,                         0x031B);
--    CASE         (invertedbreve,                0x032F);
--    CASE_COMBINE (iota,                         0x0345, 0x037A);
--    CASE_COMBINE (macron,                       0x0304, 0x00AF);
--    CASE_COMBINE (ogonek,                       0x0328, 0x02DB);
--    // IBUS_KEY_dead_perispomeni == IBUS_KEY_dead_tilde
--    // IBUS_KEY_dead_psili == IBUS_KEY_dead_abovecomma
--    CASE_COMBINE (semivoiced_sound,             0x309A, 0x309C);
--    CASE_COMBINE (small_schwa,                  0x1D4A, 0x04D9);
--    CASE         (stroke,                       0x002F);
--    CASE_COMBINE (tilde,                        0x0303, 0x007E);
--    CASE_COMBINE (voiced_sound,                 0x3099, 0x309B);
--    case IBUS_KEY_Multi_key:
--        return 0x2384;
--    default:;
--    }
--    return 0x0;
--#undef CASE
--#undef CASE_COMBINE
--}
- 
- static void
- ibus_engine_simple_commit_str (IBusEngineSimple *simple,
-@@ -607,415 +535,6 @@ check_emoji_table (IBusEngineSimple       *simple,
-     return FALSE;
- }
- 
--static int
--compare_seq_index (const void *key, const void *value)
--{
--    const guint16 *keysyms = key;
--    const guint16 *seq = value;
--
--    if (keysyms[0] < seq[0])
--        return -1;
--    else if (keysyms[0] > seq[0])
--        return 1;
--    return 0;
--}
--
--static int
--compare_seq (const void *key, const void *value)
--{
--    int i = 0;
--    const guint16 *keysyms = key;
--    const guint16 *seq = value;
--
--    while (keysyms[i]) {
--        if (keysyms[i] < seq[i])
--            return -1;
--        else if (keysyms[i] > seq[i])
--            return 1;
--
--        i++;
--    }
--
--    return 0;
--}
--
--
--static gboolean
--check_table (IBusEngineSimple         *simple,
--             const IBusComposeTableEx *table,
--             gint                      n_compose,
--             gboolean                  is_32bit)
--{
--    IBusEngineSimplePrivate *priv = simple->priv;
--    gint row_stride = table->max_seq_len + 2;
--    guint16 *data_first;
--    int n_seqs;
--    guint16 *seq;
--
--    g_assert (IBUS_IS_ENGINE_SIMPLE (simple));
--    CHECK_COMPOSE_BUFFER_LENGTH (n_compose);
--
--    if (n_compose > table->max_seq_len)
--        return FALSE;
--
--    if (is_32bit) {
--        if (!table->priv)
--            return FALSE;
--        data_first = table->priv->data_first;
--        n_seqs = table->priv->first_n_seqs;
--    } else {
--        data_first = table->data;
--        n_seqs = table->n_seqs;
--    }
--    seq = bsearch (priv->compose_buffer,
--                   data_first, n_seqs,
--                   sizeof (guint16) * row_stride,
--                   compare_seq);
--
--    if (seq == NULL)
--        return FALSE;
--
--    guint16 *prev_seq;
--
--    priv->tentative_match = 0;
--    priv->tentative_match_len = 0;
--    /* Back up to the first sequence that matches to make sure
--     * we find the exact match if their is one.
--     */
--    while (seq > data_first) {
--        prev_seq = seq - row_stride;
--        if (compare_seq (priv->compose_buffer, prev_seq) != 0) {
--            break;
--        }
--        seq = prev_seq;
--    }
--
--    /* complete sequence */
--    if (n_compose == table->max_seq_len || seq[n_compose] == 0) {
--        guint16 *next_seq;
--        gunichar value = 0;
--        int num = 0;
--        int index = 0;
--        gchar *output_str = NULL;
--        GError *error = NULL;
--
--        if (is_32bit) {
--            num = seq[table->max_seq_len];
--            index = seq[table->max_seq_len + 1];
--            value =  table->priv->data_second[index];
--        } else {
--            value = seq[table->max_seq_len];
--        }
--
--        /* We found a tentative match. See if there are any longer
--         * sequences containing this subsequence
--         */
--        next_seq = seq + row_stride;
--        if (next_seq < data_first + row_stride * n_seqs) {
--            if (compare_seq (priv->compose_buffer, next_seq) == 0) {
--                priv->tentative_match = value;
--                priv->tentative_match_len = n_compose;
--
--                ibus_engine_simple_update_preedit_text (simple);
--
--                return TRUE;
--            }
--        }
--
--        if (is_32bit) {
--            output_str = g_ucs4_to_utf8 (table->priv->data_second + index,
--                                         num, NULL, NULL, &error);
--            if (output_str) {
--                ibus_engine_simple_commit_str(simple, output_str);
--                g_free (output_str);
--            } else {
--                g_warning ("Failed to output multiple characters: %s",
--                           error->message);
--                g_error_free (error);
--            }
--        } else {
--            ibus_engine_simple_commit_char (simple, value);
--        }
--        priv->compose_buffer[0] = 0;
--    }
--    ibus_engine_simple_update_preedit_text (simple);
--    return TRUE;
--}
--
--gboolean
--ibus_check_compact_table (const IBusComposeTableCompactEx *table,
--                          guint16                         *compose_buffer,
--                          gint                             n_compose,
--                          gboolean                        *compose_finish,
--                          gunichar                       **output_chars)
--{
--    gint row_stride;
--    guint16 *seq_index;
--    guint16 *seq;
--    gint i;
--
--    if (compose_finish)
--        *compose_finish = FALSE;
--    if (output_chars)
--        *output_chars = NULL;
--
--    CHECK_COMPOSE_BUFFER_LENGTH (n_compose);
--
--    /* 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. */
--    if (n_compose > table->max_seq_len)
--        return FALSE;
--
--    // g_debug ("check_compact_table(n_compose=%d) [%04x, %04x, %04x, %04x]",
--    //          n_compose,
--    //          compose_buffer[0],
--    //          compose_buffer[1],
--    //          compose_buffer[2],
--    //          compose_buffer[3]);
--
--    seq_index = bsearch (compose_buffer,
--                         table->data,
--                         table->n_index_size,
--                         sizeof (guint16) *  table->n_index_stride,
--                         compare_seq_index);
--
--    if (seq_index == NULL) {
--        // g_debug ("compact: no\n");
--        return FALSE;
--    }
--
--    if (n_compose == 1) {
--        // g_debug ("compact: yes\n");
--        return TRUE;
--    }
--
--    // g_debug ("compact: %04x ", *seq_index);
--    seq = NULL;
--
--    if (table->priv) {
--        for (i = n_compose - 1; i < table->max_seq_len; i++) {
--            row_stride = i + 2;
--
--            if (seq_index[i + 1] - seq_index[i] > 0) {
--                seq = bsearch (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 (i == n_compose - 1)
--                        break;
--                    else
--                        return TRUE;
--                }
--            }
--        }
--        if (!seq) {
--            return FALSE;
--        } else {
--            int index = seq[row_stride - 2];
--            int length = seq[row_stride - 1];
--            int j;
--            if (compose_finish)
--                *compose_finish = TRUE;
--            if (output_chars) {
--                *output_chars = g_new (gunichar, length + 1);
--                for (j = 0; j < length; j++)
--                    (*output_chars)[j] = table->priv->data2[index + j];
--                (*output_chars)[length] = 0;
--            }
--
--            // g_debug ("U+%04X\n", value);
--            return TRUE;
--        }
--    } else {
--        for (i = n_compose - 1; i < table->max_seq_len; i++) {
--            row_stride = i + 1;
--
--            if (seq_index[i + 1] - seq_index[i] > 0) {
--                seq = bsearch (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 (i == n_compose - 1)
--                        break;
--                    else
--                        return TRUE;
--                }
--            }
--        }
--        if (!seq) {
--            return FALSE;
--        } else {
--            if (compose_finish)
--                *compose_finish = TRUE;
--            if (output_chars) {
--                *output_chars = g_new (gunichar, 2);
--                (*output_chars)[0] = seq[row_stride - 1];
--                (*output_chars)[1] = 0;
--            }
--
--            // g_debug ("U+%04X\n", value);
--            return TRUE;
--        }
--    }
--
--    g_assert_not_reached ();
--}
--
--
--/* Checks if a keysym is a dead key. Dead key keysym values are defined in
-- * ../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_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) >= IBUS_KEY_dead_grave && (k) <= (IBUS_KEY_dead_dasia + 1))
--
--/* This function receives a sequence of Unicode characters and tries to
-- * normalize it (NFC). We check for the case the 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, gint n_compose)
--{
--    gunichar combination_buffer_temp[IBUS_MAX_COMPOSE_LEN];
--    gchar *combination_utf8_temp = NULL;
--    gchar *nfc_temp = NULL;
--    gint n_combinations;
--    gunichar temp_swap;
--    gint i;
--
--    n_combinations = 1;
--
--    CHECK_COMPOSE_BUFFER_LENGTH (n_compose);
--
--    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,
--            IBUS_MAX_COMPOSE_LEN * 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, -1, 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,
--                    IBUS_MAX_COMPOSE_LEN * 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) {
--            gint j = i % (n_compose - 1) + 1;
--            gint k = (i+1) % (n_compose - 1) + 1;
--            if (j >= IBUS_MAX_COMPOSE_LEN) {
--                g_warning ("j >= IBUS_MAX_COMPOSE_LEN for " \
--                           "combination_buffer_temp");
--                break;
--            }
--            if (k >= IBUS_MAX_COMPOSE_LEN) {
--                g_warning ("k >= IBUS_MAX_COMPOSE_LEN for " \
--                           "combination_buffer_temp");
--                break;
--            }
--            temp_swap = combination_buffer_temp[j];
--            combination_buffer_temp[j] = combination_buffer_temp[k];
--            combination_buffer_temp[k] = temp_swap;
--        }
--        else
--            break;
--    }
--
--    return FALSE;
--}
--
--gboolean
--ibus_check_algorithmically (const guint16 *compose_buffer,
--                            gint           n_compose,
--                            gunichar      *output_char)
--
--{
--    gint i;
--    gunichar combination_buffer[IBUS_MAX_COMPOSE_LEN];
--    gchar *combination_utf8, *nfc;
--
--    if (output_char)
--        *output_char = 0;
--
--    CHECK_COMPOSE_BUFFER_LENGTH (n_compose);
--
--    if (n_compose >= IBUS_MAX_COMPOSE_LEN)
--        return FALSE;
--
--    for (i = 0; i < n_compose && IS_DEAD_KEY (compose_buffer[i]); i++)
--        ;
--    if (i == n_compose)
--        return TRUE;
--
--    if (i > 0 && i == n_compose - 1) {
--        combination_buffer[0] = ibus_keyval_to_unicode (compose_buffer[i]);
--        combination_buffer[n_compose] = 0;
--        i--;
--        while (i >= 0) {
--            combination_buffer[i+1] = ibus_keysym_to_unicode (compose_buffer[i],
--                                                              TRUE);
--            if (!combination_buffer[i+1]) {
--                combination_buffer[i+1] =
--                        ibus_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);
--
--            if (output_char)
--                *output_char = g_utf8_get_char (nfc);
--
--            g_free (combination_utf8);
--            g_free (nfc);
--
--            return TRUE;
--        }
--    }
--
--    return FALSE;
--}
- 
- static gboolean
- no_sequence_matches (IBusEngineSimple *simple,
-@@ -1184,34 +703,71 @@ ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
-                                             gint              n_compose)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
--    gboolean compose_finish;
--    gunichar output_char;
-+    gboolean compose_finish = FALSE;
-+    gboolean compose_match = FALSE;
-+    GString *output = g_string_new ("");
-+    gboolean does_hit = FALSE;
-+    gboolean is_32bit = FALSE;
-+    GSList *tmp_list;
-     gunichar *output_chars = NULL;
--    gchar *output_str = NULL;
--    GError *error = NULL;
--    GSList *list = global_tables;
-+    gunichar output_char;
- 
--    while (list) {
--        if (check_table (simple,
--            (IBusComposeTableEx *)list->data,
-+    G_LOCK (global_tables);
-+    tmp_list = global_tables;
-+    while (tmp_list) {
-+        is_32bit = FALSE;
-+        if (ibus_compose_table_check (
-+            (IBusComposeTableEx *)tmp_list->data,
-+            priv->compose_buffer,
-             n_compose,
--            FALSE)) {
--            return TRUE;
-+            &compose_finish,
-+            &compose_match,
-+            output,
-+            is_32bit)) {
-+            does_hit = TRUE;
-+            break;
-         }
--        if (check_table (simple,
--            (IBusComposeTableEx *)list->data,
-+        is_32bit = TRUE;
-+        if (ibus_compose_table_check (
-+            (IBusComposeTableEx *)tmp_list->data,
-+            priv->compose_buffer,
-             n_compose,
--            TRUE)) {
--            return TRUE;
-+            &compose_finish,
-+            &compose_match,
-+            output,
-+            is_32bit)) {
-+            does_hit = TRUE;
-+            break;
-         }
--        list = list->next;
-+        tmp_list = tmp_list->next;
-     }
-+    G_UNLOCK (global_tables);
- 
--    if (ibus_check_compact_table (&ibus_compose_table_compact,
--                                  priv->compose_buffer,
--                                  n_compose,
--                                  &compose_finish,
--                                  &output_chars)) {
-+    if (does_hit) {
-+        if (compose_finish) {
-+            if (compose_match) {
-+                if (is_32bit) {
-+                    ibus_engine_simple_commit_str (simple, output->str);
-+                } else {
-+                    ibus_engine_simple_commit_char (simple,
-+                                                    g_utf8_get_char (output->str));
-+                }
-+            }
-+        } else if (compose_match) {
-+            priv->tentative_match = g_utf8_get_char (output->str);
-+            priv->tentative_match_len = n_compose;
-+        }
-+        ibus_engine_simple_update_preedit_text (simple);
-+        g_string_free (output, TRUE);
-+        return TRUE;
-+    }
-+    g_string_free (output, TRUE);
-+
-+    if (ibus_compose_table_compact_check (&ibus_compose_table_compact,
-+                                          priv->compose_buffer,
-+                                          n_compose,
-+                                          &compose_finish,
-+                                          &output_chars)) {
-         if (compose_finish) {
-             ibus_engine_simple_commit_char (simple, *output_chars);
-             g_free (output_chars);
-@@ -1220,28 +776,29 @@ ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
-         ibus_engine_simple_update_preedit_text (simple);
-         return TRUE;
-     }
--    if (ibus_check_compact_table (&ibus_compose_table_compact_32bit,
--                                  priv->compose_buffer,
--                                  n_compose,
--                                  &compose_finish,
--                                  &output_chars)) {
-+    if (ibus_compose_table_compact_check (&ibus_compose_table_compact_32bit,
-+                                          priv->compose_buffer,
-+                                          n_compose,
-+                                          &compose_finish,
-+                                          &output_chars)) {
-         if (compose_finish) {
--            output_str = g_ucs4_to_utf8 (output_chars, -1, NULL, NULL, &error);
--            if (output_str) {
--                ibus_engine_simple_commit_str (simple, output_str);
--                g_free (output_str);
-+            GError *error = NULL;
-+            char *str = g_ucs4_to_utf8 (output_chars, -1, NULL, NULL, &error);
-+            if (str) {
-+                ibus_engine_simple_commit_str (simple, str);
-+                g_free (str);
-             } else {
-                 g_warning ("Failed to output multiple characters: %s",
-                            error->message);
-                 g_error_free (error);
-             }
--            g_free (output_chars);
-             priv->compose_buffer[0] = 0;
-         }
--        
-+        g_free (output_chars);
-         ibus_engine_simple_update_preedit_text (simple);
-         return TRUE;
-     }
-+    g_assert (!output_chars);
-     if (ibus_check_algorithmically (priv->compose_buffer,
-                                     n_compose,
-                                     &output_char)) {
-diff --git a/src/ibusenginesimpleprivate.h b/src/ibusenginesimpleprivate.h
-index 508d9344..47f2a3d4 100644
---- a/src/ibusenginesimpleprivate.h
-+++ b/src/ibusenginesimpleprivate.h
-@@ -37,15 +37,30 @@ struct _IBusComposeTablePrivate
-     gsize second_size;
- };
- 
-+struct _IBusComposeTableCompactPrivate
-+{
-+    const guint32 *data2;
-+};
-+
- gboolean ibus_check_algorithmically (const guint16              *compose_buffer,
-                                      gint                        n_compose,
-                                      gunichar                   *output);
--gboolean ibus_check_compact_table   (const IBusComposeTableCompactEx
-+gboolean ibus_compose_table_check   (const IBusComposeTableEx   *table,
-+                                     guint16                    *compose_buffer,
-+                                     gint                        n_compose,
-+                                     gboolean                   *compose_finish,
-+                                     gboolean                   *compose_match,
-+                                     GString                    *output,
-+                                     gboolean                    is_32bit);
-+gboolean ibus_compose_table_compact_check
-+                                    (const IBusComposeTableCompactEx
-                                                                 *table,
-                                      guint16                    *compose_buffer,
-                                      gint                        n_compose,
-                                      gboolean                   *compose_finish,
-                                      gunichar                  **output_chars);
-+gunichar ibus_keysym_to_unicode     (guint16                     keysym,
-+                                     gboolean                    combining);
- 
- G_END_DECLS
- 
-diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
-index 0a2e523c..13c06eb4 100644
---- a/src/tests/Makefile.am
-+++ b/src/tests/Makefile.am
-@@ -3,7 +3,7 @@
- # ibus - The Input Bus
- #
- # Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
--# Copyright (c) 2015-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+# Copyright (c) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
- # Copyright (c) 2007-2018 Red Hat, Inc.
- #
- # This library is free software; you can redistribute it and/or
-@@ -30,6 +30,7 @@ AM_CPPFLAGS = \
-     @GLIB2_CFLAGS@                          \
-     @GIO2_CFLAGS@                           \
-     -DIBUS_DISABLE_DEPRECATION_WARNINGS     \
-+    -DX11_DATA_PREFIX=\"$(X11_PREFIX)\"     \
-     -I$(top_srcdir)/src                     \
-     -I$(top_builddir)/src                   \
-     $(NULL)
-diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
-index 81bfc69b..0be01d27 100644
---- a/src/tests/ibus-compose.c
-+++ b/src/tests/ibus-compose.c
-@@ -6,6 +6,7 @@
- #define GREEN "\033[0;32m"
- #define RED   "\033[0;31m"
- #define NC    "\033[0m"
-+#define X11_DATADIR X11_DATA_PREFIX "/share/X11/locale"
- 
- IBusBus *m_bus;
- gchar *m_compose_file;
-@@ -35,7 +36,7 @@ get_compose_path ()
-             break;
-         if (g_strcmp0 (*l, "C") == 0)
-             break;
--        compose_path = g_build_filename ("/usr/share/X11/locale",
-+        compose_path = g_build_filename (X11_DATADIR,
-                                          *l,
-                                          "Compose",
-                                          NULL);
-@@ -155,7 +156,7 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
-     for (i = 0;
-          i < (m_compose_table->n_seqs * index_stride);
-          i += index_stride) {
--        for (j = i; j < i + (index_stride - 1); j++) {
-+        for (j = i; j < i + (index_stride - 2); j++) {
-             guint keyval = m_compose_table->data[j];
-             guint keycode = 0;
-             guint modifiers = 0;
-@@ -175,7 +176,7 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
-         for (i = 0;
-              i < (priv->first_n_seqs * index_stride);
-              i += index_stride) {
--            for (j = i; j < i + (index_stride - 1); j++) {
-+            for (j = i; j < i + (index_stride - 2); j++) {
-                 guint keyval = priv->data_first[j];
-                 guint keycode = 0;
-                 guint modifiers = 0;
--- 
-2.28.0
-
-From 2fc1a028aa697f1320d85a76548cde12894bf9ab Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 26 Jul 2021 22:52:18 +0900
-Subject: [PATCH 2/6] src/ibusenginesimple: Multi_key to 0xB7
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use · instead of ⎄ to display Multi_key in pre-edit.
-
-BUG=https://gitlab.gnome.org/GNOME/gtk/-/issues/3669
-BUG=https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3220
----
- src/ibuscomposetable.c |  8 ++++++-
- src/ibusenginesimple.c | 49 ++++++++++++++++++++----------------------
- 2 files changed, 30 insertions(+), 27 deletions(-)
-
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index f85177a6..4ebf119b 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -1846,7 +1846,13 @@ ibus_keysym_to_unicode (guint16  keysym,
-     CASE_COMBINE (tilde,                        0x0303, 0x007E);
-     CASE_COMBINE (voiced_sound,                 0x3099, 0x309B);
-     case IBUS_KEY_Multi_key:
--        return 0x2384;
-+        /* We only show the Compose key visibly when it is the
-+         * only glyph in the preedit, 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.
-+         */
-+        return 0x00B7;
-     default:;
-     }
-     return 0x0;
-diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
-index 4644620b..57ca10c4 100644
---- a/src/ibusenginesimple.c
-+++ b/src/ibusenginesimple.c
-@@ -289,32 +289,27 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
- 
--    gunichar outbuf[COMPOSE_BUFFER_SIZE + 1];
--    int len = 0;
-+    GString *s = g_string_new ("");
- 
-     if (priv->in_hex_sequence || priv->in_emoji_sequence) {
-         int hexchars = 0;
- 
-         if (priv->in_hex_sequence)
--            outbuf[0] = L'u';
-+            g_string_append_c (s, 'u');
-         else
--            outbuf[0] = L'@';
--
--        len = 1;
-+            g_string_append_c (s, '@');
- 
-         while (priv->compose_buffer[hexchars] != 0) {
--            outbuf[len] = ibus_keyval_to_unicode (
--                priv->compose_buffer[hexchars]);
--            ++len;
--            ++hexchars;
-+            g_string_append_unichar(
-+                    s,
-+                    ibus_keyval_to_unicode (priv->compose_buffer[hexchars++])
-+            );
-         }
--
--        g_assert (len <= COMPOSE_BUFFER_SIZE);
-     } else if (priv->tentative_match) {
--        outbuf[len++] = priv->tentative_match;
-+        g_string_append_unichar(s, priv->tentative_match);
-     } else if (priv->tentative_emoji && *priv->tentative_emoji) {
-         IBusText *text = ibus_text_new_from_string (priv->tentative_emoji);
--        len = strlen (priv->tentative_emoji);
-+        int len = strlen (priv->tentative_emoji);
-         ibus_text_append_attribute (text,
-                 IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, len);
-         ibus_engine_update_preedit_text ((IBusEngine *)simple, text, len, TRUE);
-@@ -324,31 +319,33 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
-         while (priv->compose_buffer[hexchars] != 0) {
-             guint16 keysym = priv->compose_buffer[hexchars];
-             gunichar unichar = ibus_keysym_to_unicode (keysym, FALSE);
--            if (unichar > 0)
--                outbuf[len] = unichar;
--            else
--                outbuf[len] = ibus_keyval_to_unicode (keysym);
--            if (!outbuf[len]) {
-+            if (unichar > 0) {
-+                g_string_append_unichar(s, unichar);
-+            } else {
-+                unichar = ibus_keyval_to_unicode (keysym);
-+                g_string_append_unichar(s, unichar);
-+            }
-+            if (!unichar) {
-                 g_warning (
-                         "Not found alternative character of compose key 0x%X",
-                         priv->compose_buffer[hexchars]);
-             }
--            ++len;
-             ++hexchars;
-         }
--        g_assert (len <= IBUS_MAX_COMPOSE_LEN);
-     }
- 
--    outbuf[len] = L'\0';
--    if (len == 0) {
-+    if (s->len == 0) {
-         ibus_engine_hide_preedit_text ((IBusEngine *)simple);
--    }
--    else {
--        IBusText *text = ibus_text_new_from_ucs4 (outbuf);
-+    } else if (s->len >= G_MAXINT) {
-+        g_warning ("%s is too long compose length: %lu", s->str, s->len);
-+    } else {
-+        int len = (int)s->len;
-+        IBusText *text = ibus_text_new_from_string (s->str);
-         ibus_text_append_attribute (text,
-                 IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, len);
-         ibus_engine_update_preedit_text ((IBusEngine *)simple, text, len, TRUE);
-     }
-+    g_string_free (s, TRUE);
- }
- 
- 
--- 
-2.28.0
-
-From 3e2609e68c9107ce7c65e2d5876bfdc9f0f8c854 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 26 Jul 2021 22:52:21 +0900
-Subject: [PATCH 3/6] src: Update ibuskeysyms.h for latest dead keys
-
----
- src/ibuskeysyms.h | 186 +++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 185 insertions(+), 1 deletion(-)
-
-diff --git a/src/ibuskeysyms.h b/src/ibuskeysyms.h
-index d35eb4a7..2fb2ea19 100644
---- a/src/ibuskeysyms.h
-+++ b/src/ibuskeysyms.h
-@@ -274,6 +274,10 @@
- #define IBUS_KEY_dead_invertedbreve 0xfe6d
- #define IBUS_KEY_dead_belowcomma 0xfe6e
- #define IBUS_KEY_dead_currency 0xfe6f
-+#define IBUS_KEY_dead_lowline 0xfe90
-+#define IBUS_KEY_dead_aboveverticalline 0xfe91
-+#define IBUS_KEY_dead_belowverticalline 0xfe92
-+#define IBUS_KEY_dead_longsolidusoverlay 0xfe93
- #define IBUS_KEY_dead_a 0xfe80
- #define IBUS_KEY_dead_A 0xfe81
- #define IBUS_KEY_dead_e 0xfe82
-@@ -1201,6 +1205,7 @@
- #define IBUS_KEY_leftdoublequotemark 0xad2
- #define IBUS_KEY_rightdoublequotemark 0xad3
- #define IBUS_KEY_prescription 0xad4
-+#define IBUS_KEY_permille 0xad5
- #define IBUS_KEY_minutes 0xad6
- #define IBUS_KEY_seconds 0xad7
- #define IBUS_KEY_latincross 0xad9
-@@ -1633,8 +1638,8 @@
- #define IBUS_KEY_ocaron 0x10001d2
- #define IBUS_KEY_obarred 0x1000275
- #define IBUS_KEY_SCHWA 0x100018f
--#define IBUS_KEY_EZH 0x10001b7
- #define IBUS_KEY_schwa 0x1000259
-+#define IBUS_KEY_EZH 0x10001b7
- #define IBUS_KEY_ezh 0x1000292
- #define IBUS_KEY_Lbelowdot 0x1001e36
- #define IBUS_KEY_lbelowdot 0x1001e37
-@@ -2121,5 +2126,184 @@
- #define IBUS_KEY_Sinh_ruu2 0x1000df2
- #define IBUS_KEY_Sinh_luu2 0x1000df3
- #define IBUS_KEY_Sinh_kunddaliya 0x1000df4
-+#define IBUS_KEY_ModeLock 0x1008ff01
-+#define IBUS_KEY_MonBrightnessUp 0x1008ff02
-+#define IBUS_KEY_MonBrightnessDown 0x1008ff03
-+#define IBUS_KEY_KbdLightOnOff 0x1008ff04
-+#define IBUS_KEY_KbdBrightnessUp 0x1008ff05
-+#define IBUS_KEY_KbdBrightnessDown 0x1008ff06
-+#define IBUS_KEY_Standby 0x1008ff10
-+#define IBUS_KEY_AudioLowerVolume 0x1008ff11
-+#define IBUS_KEY_AudioMute 0x1008ff12
-+#define IBUS_KEY_AudioRaiseVolume 0x1008ff13
-+#define IBUS_KEY_AudioPlay 0x1008ff14
-+#define IBUS_KEY_AudioStop 0x1008ff15
-+#define IBUS_KEY_AudioPrev 0x1008ff16
-+#define IBUS_KEY_AudioNext 0x1008ff17
-+#define IBUS_KEY_HomePage 0x1008ff18
-+#define IBUS_KEY_Mail 0x1008ff19
-+#define IBUS_KEY_Start 0x1008ff1a
-+#define IBUS_KEY_Search 0x1008ff1b
-+#define IBUS_KEY_AudioRecord 0x1008ff1c
-+#define IBUS_KEY_Calculator 0x1008ff1d
-+#define IBUS_KEY_Memo 0x1008ff1e
-+#define IBUS_KEY_ToDoList 0x1008ff1f
-+#define IBUS_KEY_Calendar 0x1008ff20
-+#define IBUS_KEY_PowerDown 0x1008ff21
-+#define IBUS_KEY_ContrastAdjust 0x1008ff22
-+#define IBUS_KEY_RockerUp 0x1008ff23
-+#define IBUS_KEY_RockerDown 0x1008ff24
-+#define IBUS_KEY_RockerEnter 0x1008ff25
-+#define IBUS_KEY_Back 0x1008ff26
-+#define IBUS_KEY_Forward 0x1008ff27
-+#define IBUS_KEY_Stop 0x1008ff28
-+#define IBUS_KEY_Refresh 0x1008ff29
-+#define IBUS_KEY_PowerOff 0x1008ff2a
-+#define IBUS_KEY_WakeUp 0x1008ff2b
-+#define IBUS_KEY_Eject 0x1008ff2c
-+#define IBUS_KEY_ScreenSaver 0x1008ff2d
-+#define IBUS_KEY_WWW 0x1008ff2e
-+#define IBUS_KEY_Sleep 0x1008ff2f
-+#define IBUS_KEY_Favorites 0x1008ff30
-+#define IBUS_KEY_AudioPause 0x1008ff31
-+#define IBUS_KEY_AudioMedia 0x1008ff32
-+#define IBUS_KEY_MyComputer 0x1008ff33
-+#define IBUS_KEY_VendorHome 0x1008ff34
-+#define IBUS_KEY_LightBulb 0x1008ff35
-+#define IBUS_KEY_Shop 0x1008ff36
-+#define IBUS_KEY_History 0x1008ff37
-+#define IBUS_KEY_OpenURL 0x1008ff38
-+#define IBUS_KEY_AddFavorite 0x1008ff39
-+#define IBUS_KEY_HotLinks 0x1008ff3a
-+#define IBUS_KEY_BrightnessAdjust 0x1008ff3b
-+#define IBUS_KEY_Finance 0x1008ff3c
-+#define IBUS_KEY_Community 0x1008ff3d
-+#define IBUS_KEY_AudioRewind 0x1008ff3e
-+#define IBUS_KEY_BackForward 0x1008ff3f
-+#define IBUS_KEY_Launch0 0x1008ff40
-+#define IBUS_KEY_Launch1 0x1008ff41
-+#define IBUS_KEY_Launch2 0x1008ff42
-+#define IBUS_KEY_Launch3 0x1008ff43
-+#define IBUS_KEY_Launch4 0x1008ff44
-+#define IBUS_KEY_Launch5 0x1008ff45
-+#define IBUS_KEY_Launch6 0x1008ff46
-+#define IBUS_KEY_Launch7 0x1008ff47
-+#define IBUS_KEY_Launch8 0x1008ff48
-+#define IBUS_KEY_Launch9 0x1008ff49
-+#define IBUS_KEY_LaunchA 0x1008ff4a
-+#define IBUS_KEY_LaunchB 0x1008ff4b
-+#define IBUS_KEY_LaunchC 0x1008ff4c
-+#define IBUS_KEY_LaunchD 0x1008ff4d
-+#define IBUS_KEY_LaunchE 0x1008ff4e
-+#define IBUS_KEY_LaunchF 0x1008ff4f
-+#define IBUS_KEY_ApplicationLeft 0x1008ff50
-+#define IBUS_KEY_ApplicationRight 0x1008ff51
-+#define IBUS_KEY_Book 0x1008ff52
-+#define IBUS_KEY_CD 0x1008ff53
-+#define IBUS_KEY_WindowClear 0x1008ff55
-+#define IBUS_KEY_Close 0x1008ff56
-+#define IBUS_KEY_Copy 0x1008ff57
-+#define IBUS_KEY_Cut 0x1008ff58
-+#define IBUS_KEY_Display 0x1008ff59
-+#define IBUS_KEY_DOS 0x1008ff5a
-+#define IBUS_KEY_Documents 0x1008ff5b
-+#define IBUS_KEY_Excel 0x1008ff5c
-+#define IBUS_KEY_Explorer 0x1008ff5d
-+#define IBUS_KEY_Game 0x1008ff5e
-+#define IBUS_KEY_Go 0x1008ff5f
-+#define IBUS_KEY_iTouch 0x1008ff60
-+#define IBUS_KEY_LogOff 0x1008ff61
-+#define IBUS_KEY_Market 0x1008ff62
-+#define IBUS_KEY_Meeting 0x1008ff63
-+#define IBUS_KEY_MenuKB 0x1008ff65
-+#define IBUS_KEY_MenuPB 0x1008ff66
-+#define IBUS_KEY_MySites 0x1008ff67
-+#define IBUS_KEY_New 0x1008ff68
-+#define IBUS_KEY_News 0x1008ff69
-+#define IBUS_KEY_OfficeHome 0x1008ff6a
-+#define IBUS_KEY_Open 0x1008ff6b
-+#define IBUS_KEY_Option 0x1008ff6c
-+#define IBUS_KEY_Paste 0x1008ff6d
-+#define IBUS_KEY_Phone 0x1008ff6e
-+#define IBUS_KEY_Reply 0x1008ff72
-+#define IBUS_KEY_Reload 0x1008ff73
-+#define IBUS_KEY_RotateWindows 0x1008ff74
-+#define IBUS_KEY_RotationPB 0x1008ff75
-+#define IBUS_KEY_RotationKB 0x1008ff76
-+#define IBUS_KEY_Save 0x1008ff77
-+#define IBUS_KEY_ScrollUp 0x1008ff78
-+#define IBUS_KEY_ScrollDown 0x1008ff79
-+#define IBUS_KEY_ScrollClick 0x1008ff7a
-+#define IBUS_KEY_Send 0x1008ff7b
-+#define IBUS_KEY_Spell 0x1008ff7c
-+#define IBUS_KEY_SplitScreen 0x1008ff7d
-+#define IBUS_KEY_Support 0x1008ff7e
-+#define IBUS_KEY_TaskPane 0x1008ff7f
-+#define IBUS_KEY_Terminal 0x1008ff80
-+#define IBUS_KEY_Tools 0x1008ff81
-+#define IBUS_KEY_Travel 0x1008ff82
-+#define IBUS_KEY_UserPB 0x1008ff84
-+#define IBUS_KEY_User1KB 0x1008ff85
-+#define IBUS_KEY_User2KB 0x1008ff86
-+#define IBUS_KEY_Video 0x1008ff87
-+#define IBUS_KEY_WheelButton 0x1008ff88
-+#define IBUS_KEY_Word 0x1008ff89
-+#define IBUS_KEY_Xfer 0x1008ff8a
-+#define IBUS_KEY_ZoomIn 0x1008ff8b
-+#define IBUS_KEY_ZoomOut 0x1008ff8c
-+#define IBUS_KEY_Away 0x1008ff8d
-+#define IBUS_KEY_Messenger 0x1008ff8e
-+#define IBUS_KEY_WebCam 0x1008ff8f
-+#define IBUS_KEY_MailForward 0x1008ff90
-+#define IBUS_KEY_Pictures 0x1008ff91
-+#define IBUS_KEY_Music 0x1008ff92
-+#define IBUS_KEY_Battery 0x1008ff93
-+#define IBUS_KEY_Bluetooth 0x1008ff94
-+#define IBUS_KEY_WLAN 0x1008ff95
-+#define IBUS_KEY_UWB 0x1008ff96
-+#define IBUS_KEY_AudioForward 0x1008ff97
-+#define IBUS_KEY_AudioRepeat 0x1008ff98
-+#define IBUS_KEY_AudioRandomPlay 0x1008ff99
-+#define IBUS_KEY_Subtitle 0x1008ff9a
-+#define IBUS_KEY_AudioCycleTrack 0x1008ff9b
-+#define IBUS_KEY_CycleAngle 0x1008ff9c
-+#define IBUS_KEY_FrameBack 0x1008ff9d
-+#define IBUS_KEY_FrameForward 0x1008ff9e
-+#define IBUS_KEY_Time 0x1008ff9f
-+#define IBUS_KEY_SelectButton 0x1008ffa0
-+#define IBUS_KEY_View 0x1008ffa1
-+#define IBUS_KEY_TopMenu 0x1008ffa2
-+#define IBUS_KEY_Red 0x1008ffa3
-+#define IBUS_KEY_Green 0x1008ffa4
-+#define IBUS_KEY_Yellow 0x1008ffa5
-+#define IBUS_KEY_Blue 0x1008ffa6
-+#define IBUS_KEY_Suspend 0x1008ffa7
-+#define IBUS_KEY_Hibernate 0x1008ffa8
-+#define IBUS_KEY_TouchpadToggle 0x1008ffa9
-+#define IBUS_KEY_TouchpadOn 0x1008ffb0
-+#define IBUS_KEY_TouchpadOff 0x1008ffb1
-+#define IBUS_KEY_AudioMicMute 0x1008ffb2
-+#define IBUS_KEY_Keyboard 0x1008ffb3
-+#define IBUS_KEY_WWAN 0x1008ffb4
-+#define IBUS_KEY_RFKill 0x1008ffb5
-+#define IBUS_KEY_AudioPreset 0x1008ffb6
-+#define IBUS_KEY_Switch_VT_1 0x1008fe01
-+#define IBUS_KEY_Switch_VT_2 0x1008fe02
-+#define IBUS_KEY_Switch_VT_3 0x1008fe03
-+#define IBUS_KEY_Switch_VT_4 0x1008fe04
-+#define IBUS_KEY_Switch_VT_5 0x1008fe05
-+#define IBUS_KEY_Switch_VT_6 0x1008fe06
-+#define IBUS_KEY_Switch_VT_7 0x1008fe07
-+#define IBUS_KEY_Switch_VT_8 0x1008fe08
-+#define IBUS_KEY_Switch_VT_9 0x1008fe09
-+#define IBUS_KEY_Switch_VT_10 0x1008fe0a
-+#define IBUS_KEY_Switch_VT_11 0x1008fe0b
-+#define IBUS_KEY_Switch_VT_12 0x1008fe0c
-+#define IBUS_KEY_Ungrab 0x1008fe20
-+#define IBUS_KEY_ClearGrab 0x1008fe21
-+#define IBUS_KEY_Next_VMode 0x1008fe22
-+#define IBUS_KEY_Prev_VMode 0x1008fe23
-+#define IBUS_KEY_LogWindowTree 0x1008fe24
-+#define IBUS_KEY_LogGrabInfo 0x1008fe25
- 
- #endif /* __IBUS_KEYSYMS_H__ */
--- 
-2.28.0
-
-From df495660a6da492fe0cac8f7fe748f25a1c3217c Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 26 Jul 2021 22:52:23 +0900
-Subject: [PATCH 4/6] src/ibusenginesimple: Change gint to int
-
----
- src/ibuscomposetable.c        | 128 +++++++++++++++++-----------------
- src/ibusenginesimple.c        |  58 +++++++--------
- src/ibusenginesimpleprivate.h |   6 +-
- 3 files changed, 96 insertions(+), 96 deletions(-)
-
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index 4ebf119b..aa58f136 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -47,7 +47,7 @@
- typedef struct {
-   gunichar     *sequence;
-   gunichar     *values;
--  gchar        *comment;
-+  char         *comment;
- } IBusComposeData;
- 
- 
-@@ -85,7 +85,7 @@ unichar_length (gunichar *uni_array)
- 
- 
- static gboolean
--is_codepoint (const gchar *str)
-+is_codepoint (const char *str)
- {
-     int i;
- 
-@@ -104,11 +104,11 @@ is_codepoint (const gchar *str)
- 
- static gboolean
- parse_compose_value (IBusComposeData  *compose_data,
--                     const gchar      *val,
--                     const gchar      *line)
-+                     const char       *val,
-+                     const char       *line)
- {
--    gchar *head, *end, *p;
--    gchar *ustr = NULL;
-+    char *head, *end, *p;
-+    char *ustr = NULL;
-     gunichar *uchars = NULL, *up;
-     GError *error = NULL;
-     int n_uchars = 0;
-@@ -184,10 +184,10 @@ fail:
- 
- static int
- parse_compose_sequence (IBusComposeData *compose_data,
--                        const gchar     *seq,
--                        const gchar     *line)
-+                        const char      *seq,
-+                        const char      *line)
- {
--    gchar **words = g_strsplit (seq, "<", -1);
-+    char **words = g_strsplit (seq, "<", -1);
-     int i;
-     int n = 0;
- 
-@@ -198,9 +198,9 @@ parse_compose_sequence (IBusComposeData *compose_data,
-     }
- 
-     for (i = 1; words[i] != NULL; i++) {
--        gchar *start = words[i];
--        gchar *end = index (words[i], '>');
--        gchar *match;
-+        char *start = words[i];
-+        char *end = index (words[i], '>');
-+        char *match;
-         gunichar codepoint;
- 
-         if (words[i][0] == '\0')
-@@ -256,18 +256,18 @@ fail:
- }
- 
- 
--static gchar *
--expand_include_path (const gchar *include_path) {
--    gchar *out = strdup ("");
--    const gchar *head, *i;
--    gchar *former, *o;
-+static char *
-+expand_include_path (const char *include_path) {
-+    char *out = strdup ("");
-+    const char *head, *i;
-+    char *former, *o;
- 
-     for (head = i = include_path; *i; ++i) {
-         /* expand sequence */
-         if (*i == '%') {
-             switch (*(i + 1)) {
-             case 'H': { /* $HOME */
--                const gchar *home = getenv ("HOME");
-+                const char *home = getenv ("HOME");
-                 if (!home) {
-                     g_warning ("while parsing XCompose include target %s, "
-                                "%%H replacement failed because HOME is not "
-@@ -325,11 +325,11 @@ fail:
- 
- static void
- parse_compose_line (GList       **compose_list,
--                    const gchar  *line,
-+                    const char   *line,
-                     int          *compose_len,
--                    gchar        **include)
-+                    char        **include)
- {
--    gchar **components = NULL;
-+    char **components = NULL;
-     IBusComposeData *compose_data = NULL;
-     int l;
- 
-@@ -395,13 +395,13 @@ fail:
- }
- 
- 
--static gchar *
-+static char *
- get_en_compose_file (void)
- {
--    gchar * const sys_langs[] = { "en_US.UTF-8", "en_US", "en.UTF-8",
--                                  "en", NULL };
--    gchar * const *sys_lang = NULL;
--    gchar *path = NULL;
-+    char * const sys_langs[] = { "en_US.UTF-8", "en_US", "en.UTF-8",
-+                                 "en", NULL };
-+    char * const *sys_lang = NULL;
-+    char *path = NULL;
-     for (sys_lang = sys_langs; *sys_lang; sys_lang++) {
-         path = g_build_filename (X11_DATADIR, *sys_lang, "Compose", NULL);
-         if (g_file_test (path, G_FILE_TEST_EXISTS))
-@@ -413,11 +413,11 @@ get_en_compose_file (void)
- 
- 
- static GList *
--ibus_compose_list_parse_file (const gchar *compose_file,
--                              int         *max_compose_len)
-+ibus_compose_list_parse_file (const char *compose_file,
-+                              int        *max_compose_len)
- {
--    gchar *contents = NULL;
--    gchar **lines = NULL;
-+    char *contents = NULL;
-+    char **lines = NULL;
-     gsize length = 0;
-     GError *error = NULL;
-     GList *compose_list = NULL;
-@@ -435,14 +435,14 @@ ibus_compose_list_parse_file (const gchar *compose_file,
-     g_free (contents);
-     for (i = 0; lines[i] != NULL; i++) {
-         int compose_len = 0;
--        gchar *include = NULL;
-+        char *include = NULL;
-         parse_compose_line (&compose_list, lines[i], &compose_len, &include);
-         if (*max_compose_len < compose_len)
-             *max_compose_len = compose_len;
-         if (include && *include) {
-             GStatBuf buf_include = { 0, };
-             GStatBuf buf_parent = { 0, };
--            gchar *en_compose;
-+            char *en_compose;
-             errno = 0;
-             if (g_stat (include,  &buf_include)) {
-                 g_warning ("Cannot access %s: %s",
-@@ -588,7 +588,7 @@ ibus_compose_list_check_duplicated (GList *compose_list,
- }
- 
- 
--static gint
-+static int
- ibus_compose_data_compare (gpointer a,
-                            gpointer b,
-                            gpointer data)
-@@ -625,7 +625,7 @@ ibus_compose_list_print (GList *compose_list,
-     int i, j;
-     IBusComposeData *compose_data;
-     int total_size = 0;
--    const gchar *keyval;
-+    const char *keyval;
- 
-     for (list = compose_list; list != NULL; list = list->next) {
-         compose_data = list->data;
-@@ -682,13 +682,13 @@ ibus_compose_table_data_hash (gconstpointer v,
- }
- 
- 
--static gchar *
-+static char *
- ibus_compose_hash_get_cache_path (guint32 hash)
- {
--    gchar *basename = NULL;
--    const gchar *cache_dir;
--    gchar *dir = NULL;
--    gchar *path = NULL;
-+    char *basename = NULL;
-+    const char *cache_dir;
-+    char *dir = NULL;
-+    char *path = NULL;
- 
-     basename = g_strdup_printf ("%08x.cache", hash);
- 
-@@ -715,7 +715,7 @@ ibus_compose_hash_get_cache_path (guint32 hash)
- static GVariant *
- ibus_compose_table_serialize (IBusComposeTableEx *compose_table)
- {
--    const gchar *header = IBUS_COMPOSE_TABLE_MAGIC;
-+    const char *header = IBUS_COMPOSE_TABLE_MAGIC;
-     const guint16 version = IBUS_COMPOSE_TABLE_VERSION;
-     guint16 max_seq_len;
-     guint16 index_stride;
-@@ -825,7 +825,7 @@ out_serialize:
- }
- 
- 
--static gint
-+static int
- ibus_compose_table_find (gconstpointer data1,
-                          gconstpointer data2)
- {
-@@ -837,8 +837,8 @@ ibus_compose_table_find (gconstpointer data1,
- 
- 
- static IBusComposeTableEx *
--ibus_compose_table_deserialize (const gchar *contents,
--                                gsize        length)
-+ibus_compose_table_deserialize (const char *contents,
-+                                gsize       length)
- {
-     IBusComposeTableEx *retval = NULL;
-     GVariantType *type;
-@@ -846,7 +846,7 @@ ibus_compose_table_deserialize (const gchar *contents,
-     GVariant *variant_data_32bit_first = NULL;
-     GVariant *variant_data_32bit_second = NULL;
-     GVariant *variant_table = NULL;
--    const gchar *header = NULL;
-+    const char *header = NULL;
-     guint16 version = 0;
-     guint16 max_seq_len = 0;
-     guint16 n_seqs = 0;
-@@ -1020,8 +1020,8 @@ ibus_compose_table_load_cache (const gchar *compose_file)
- {
-     IBusComposeTableEx *retval = NULL;
-     guint32 hash;
--    gchar *path = NULL;
--    gchar *contents = NULL;
-+    char *path = NULL;
-+    char *contents = NULL;
-     GStatBuf original_buf;
-     GStatBuf cache_buf;
-     gsize length = 0;
-@@ -1063,9 +1063,9 @@ ibus_compose_table_load_cache (const gchar *compose_file)
- void
- ibus_compose_table_save_cache (IBusComposeTableEx *compose_table)
- {
--    gchar *path = NULL;
-+    char *path = NULL;
-     GVariant *variant_table = NULL;
--    const gchar *contents = NULL;
-+    const char *contents = NULL;
-     GError *error = NULL;
-     gsize length = 0;
- 
-@@ -1392,13 +1392,13 @@ compare_seq (const void *key, const void *value)
- gboolean
- ibus_compose_table_check (const IBusComposeTableEx *table,
-                           guint16                  *compose_buffer,
--                          gint                      n_compose,
-+                          int                       n_compose,
-                           gboolean                 *compose_finish,
-                           gboolean                 *compose_match,
-                           GString                  *output,
-                           gboolean                  is_32bit)
- {
--    gint row_stride = table->max_seq_len + 2;
-+    int row_stride = table->max_seq_len + 2;
-     guint16 *data_first;
-     int n_seqs;
-     guint16 *seq;
-@@ -1448,7 +1448,7 @@ ibus_compose_table_check (const IBusComposeTableEx *table,
-         gunichar value = 0;
-         int num = 0;
-         int index = 0;
--        gchar *output_str = NULL;
-+        char *output_str = NULL;
-         GError *error = NULL;
- 
-         if (is_32bit) {
-@@ -1526,15 +1526,15 @@ gboolean
- ibus_compose_table_compact_check (const IBusComposeTableCompactEx *table,
-                                   guint16
-                                                                *compose_buffer,
--                                  gint                             n_compose,
-+                                  int                              n_compose,
-                                   gboolean
-                                                                *compose_finish,
-                                   gunichar                       **output_chars)
- {
--    gint row_stride;
-+    int row_stride;
-     guint16 *seq_index;
-     guint16 *seq;
--    gint i;
-+    int i;
- 
-     if (compose_finish)
-         *compose_finish = FALSE;
-@@ -1654,14 +1654,14 @@ ibus_compose_table_compact_check (const IBusComposeTableCompactEx *table,
-  * permutations of the diacritic marks, then attempt to normalize.
-  */
- static gboolean
--check_normalize_nfc (gunichar* combination_buffer, gint n_compose)
-+check_normalize_nfc (gunichar* combination_buffer, int n_compose)
- {
-     gunichar combination_buffer_temp[IBUS_MAX_COMPOSE_LEN];
--    gchar *combination_utf8_temp = NULL;
--    gchar *nfc_temp = NULL;
--    gint n_combinations;
-+    char *combination_utf8_temp = NULL;
-+    char *nfc_temp = NULL;
-+    int n_combinations;
-     gunichar temp_swap;
--    gint i;
-+    int i;
- 
-     n_combinations = 1;
- 
-@@ -1703,8 +1703,8 @@ check_normalize_nfc (gunichar* combination_buffer, gint n_compose)
-         g_free (nfc_temp);
- 
-         if (n_compose > 2) {
--            gint j = i % (n_compose - 1) + 1;
--            gint k = (i+1) % (n_compose - 1) + 1;
-+            int j = i % (n_compose - 1) + 1;
-+            int k = (i+1) % (n_compose - 1) + 1;
-             if (j >= IBUS_MAX_COMPOSE_LEN) {
-                 g_warning ("j >= IBUS_MAX_COMPOSE_LEN for " \
-                            "combination_buffer_temp");
-@@ -1729,13 +1729,13 @@ check_normalize_nfc (gunichar* combination_buffer, gint n_compose)
- 
- gboolean
- ibus_check_algorithmically (const guint16 *compose_buffer,
--                            gint           n_compose,
-+                            int            n_compose,
-                             gunichar      *output_char)
- 
- {
--    gint i;
-+    int i;
-     gunichar combination_buffer[IBUS_MAX_COMPOSE_LEN];
--    gchar *combination_utf8, *nfc;
-+    char *combination_utf8, *nfc;
- 
-     if (output_char)
-         *output_char = 0;
-diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
-index 57ca10c4..699cf0d4 100644
---- a/src/ibusenginesimple.c
-+++ b/src/ibusenginesimple.c
-@@ -79,8 +79,8 @@ typedef struct {
- struct _IBusEngineSimplePrivate {
-     guint16            *compose_buffer;
-     gunichar            tentative_match;
--    gchar              *tentative_emoji;
--    gint                tentative_match_len;
-+    char               *tentative_emoji;
-+    int                 tentative_match_len;
- 
-     guint               hex_mode_enabled : 1;
-     guint               in_hex_sequence : 1;
-@@ -142,7 +142,7 @@ static void     ibus_engine_simple_candidate_clicked
- static void     ibus_engine_simple_commit_char (IBusEngineSimple    *simple,
-                                                 gunichar             ch);
- static void     ibus_engine_simple_commit_str  (IBusEngineSimple    *simple,
--                                                const gchar         *str);
-+                                                const char          *str);
- static void     ibus_engine_simple_update_preedit_text
-                                                (IBusEngineSimple    *simple);
- 
-@@ -260,10 +260,10 @@ ibus_engine_simple_commit_char (IBusEngineSimple *simple,
- 
- static void
- ibus_engine_simple_commit_str (IBusEngineSimple *simple,
--                               const gchar      *str)
-+                               const char       *str)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
--    gchar *backup_str;
-+    char *backup_str;
- 
-     g_return_if_fail (str && *str);
- 
-@@ -368,15 +368,15 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
- 
- static gboolean
- check_hex (IBusEngineSimple *simple,
--           gint              n_compose)
-+           int               n_compose)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
- 
--    gint i;
-+    int i;
-     GString *str;
-     gulong n;
--    gchar *nptr = NULL;
--    gchar buf[7];
-+    char *nptr = NULL;
-+    char buf[7];
- 
-     CHECK_COMPOSE_BUFFER_LENGTH (n_compose);
- 
-@@ -453,14 +453,14 @@ load_emoji_dict ()
- 
- static gboolean
- check_emoji_table (IBusEngineSimple       *simple,
--                   gint                    n_compose,
--                   gint                    index)
-+                   int                     n_compose,
-+                   int                     index)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
-     IBusEngineDict *emoji_dict = priv->emoji_dict;
-     GString *str = NULL;
--    gint i;
--    gchar buf[7];
-+    int i;
-+    char buf[7];
-     GSList *words = NULL;
- 
-     g_assert (IBUS_IS_ENGINE_SIMPLE (simple));
-@@ -535,7 +535,7 @@ check_emoji_table (IBusEngineSimple       *simple,
- 
- static gboolean
- no_sequence_matches (IBusEngineSimple *simple,
--                     gint              n_compose,
-+                     int               n_compose,
-                      guint             keyval,
-                      guint             keycode,
-                      guint             modifiers)
-@@ -550,7 +550,7 @@ no_sequence_matches (IBusEngineSimple *simple,
-      * match pending.
-      */
-     if (priv->tentative_match) {
--        gint len = priv->tentative_match_len;
-+        int len = priv->tentative_match_len;
-         int i;
- 
-         ibus_engine_simple_commit_char (simple, priv->tentative_match);
-@@ -615,7 +615,7 @@ ibus_engine_simple_update_lookup_and_aux_table (IBusEngineSimple *simple)
- {
-     IBusEngineSimplePrivate *priv;
-     guint index, candidates;
--    gchar *aux_label = NULL;
-+    char *aux_label = NULL;
-     IBusText *text = NULL;
- 
-     g_return_if_fail (IBUS_IS_ENGINE_SIMPLE (simple));
-@@ -697,7 +697,7 @@ ibus_engine_simple_set_number_on_lookup_table (IBusEngineSimple *simple,
- 
- static gboolean
- ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
--                                            gint              n_compose)
-+                                            int               n_compose)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
-     gboolean compose_finish = FALSE;
-@@ -818,7 +818,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
- {
-     IBusEngineSimple *simple = (IBusEngineSimple *)engine;
-     IBusEngineSimplePrivate *priv = simple->priv;
--    gint n_compose = 0;
-+    int n_compose = 0;
-     gboolean have_hex_mods;
-     gboolean is_hex_start = FALSE;
-     gboolean is_emoji_start = FALSE;
-@@ -828,7 +828,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-     gboolean is_escape;
-     guint hex_keyval;
-     guint printable_keyval;
--    gint i;
-+    int i;
- 
-     while (n_compose <= COMPOSE_BUFFER_SIZE && priv->compose_buffer[n_compose] != 0)
-         n_compose++;
-@@ -1274,7 +1274,7 @@ ibus_engine_simple_candidate_clicked (IBusEngine *engine,
-     IBusEngineSimple *simple = (IBusEngineSimple *)engine;
-     IBusEngineSimplePrivate *priv = simple->priv;
-     guint keyval;
--    gint n_compose = 0;
-+    int n_compose = 0;
- 
-     if (priv->lookup_table == NULL || !priv->lookup_table_visible)
-         return;
-@@ -1308,18 +1308,18 @@ ibus_engine_simple_add_table_by_locale (IBusEngineSimple *simple,
- {
-     /* Now ibus_engine_simple_add_compose_file() always returns TRUE. */
-     gboolean retval = TRUE;
--    gchar *path = NULL;
--    const gchar *home;
-+    char *path = NULL;
-+    const char *home;
- #if GLIB_CHECK_VERSION (2, 58, 0)
--    const gchar * const *langs;
--    const gchar * const *lang = NULL;
-+    const char * const *langs;
-+    const char * const *lang = NULL;
- #else
--    const gchar *_locale;
--    gchar **langs = NULL;
--    gchar **lang = NULL;
-+    const char *_locale;
-+    char **langs = NULL;
-+    char **lang = NULL;
- #endif
--    gchar * const sys_langs[] = { "el_gr", "fi_fi", "pt_br", NULL };
--    gchar * const *sys_lang = NULL;
-+    char * const sys_langs[] = { "el_gr", "fi_fi", "pt_br", NULL };
-+    char * const *sys_lang = NULL;
- 
-     if (locale == NULL) {
-         path = g_build_filename (g_get_user_config_dir (),
-diff --git a/src/ibusenginesimpleprivate.h b/src/ibusenginesimpleprivate.h
-index 47f2a3d4..5479e553 100644
---- a/src/ibusenginesimpleprivate.h
-+++ b/src/ibusenginesimpleprivate.h
-@@ -43,11 +43,11 @@ struct _IBusComposeTableCompactPrivate
- };
- 
- gboolean ibus_check_algorithmically (const guint16              *compose_buffer,
--                                     gint                        n_compose,
-+                                     int                         n_compose,
-                                      gunichar                   *output);
- gboolean ibus_compose_table_check   (const IBusComposeTableEx   *table,
-                                      guint16                    *compose_buffer,
--                                     gint                        n_compose,
-+                                     int                         n_compose,
-                                      gboolean                   *compose_finish,
-                                      gboolean                   *compose_match,
-                                      GString                    *output,
-@@ -56,7 +56,7 @@ gboolean ibus_compose_table_compact_check
-                                     (const IBusComposeTableCompactEx
-                                                                 *table,
-                                      guint16                    *compose_buffer,
--                                     gint                        n_compose,
-+                                     int                         n_compose,
-                                      gboolean                   *compose_finish,
-                                      gunichar                  **output_chars);
- gunichar ibus_keysym_to_unicode     (guint16                     keysym,
--- 
-2.28.0
-
-From 4259f16324d578aa2505cf50f2f23923d8d87e76 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 26 Jul 2021 22:53:19 +0900
-Subject: [PATCH 5/6] src/ibusenginesimple: Make Compose preedit less intrusive
-
-Tweak the preedit display for Compose sequences to
-be not so distracting. We only show the Compose key
-when it occurs in the middle of the sequence or is
-the only key so far.
-
-BUG=https://gitlab.gnome.org/GNOME/gtk/-/issues/3669
-BUG=https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3220
-BUG=https://blog.gtk.org/2021/03/24/input-revisited/
----
- src/ibuscomposetable.c        | 175 +++++++++++---------
- src/ibusenginesimple.c        | 301 +++++++++++++++++++++++++---------
- src/ibusenginesimpleprivate.h |   9 +-
- 3 files changed, 325 insertions(+), 160 deletions(-)
-
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index aa58f136..2ad21551 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -1523,23 +1523,22 @@ compare_seq_index (const void *key, const void *value)
-  * IBusComposeData->values[] is the gunichar array.
-  */
- gboolean
--ibus_compose_table_compact_check (const IBusComposeTableCompactEx *table,
--                                  guint16
--                                                               *compose_buffer,
--                                  int                              n_compose,
--                                  gboolean
--                                                               *compose_finish,
--                                  gunichar                       **output_chars)
-+ibus_compose_table_compact_check (const IBusComposeTableCompactEx
-+                                                                *table,
-+                                  guint16                       *compose_buffer,
-+                                  int                            n_compose,
-+                                  gboolean                      *compose_finish,
-+                                  gunichar                     **output_chars)
- {
-     int row_stride;
-     guint16 *seq_index;
-     guint16 *seq;
-     int i;
- 
--    if (compose_finish)
--        *compose_finish = FALSE;
--    if (output_chars)
--        *output_chars = NULL;
-+    /* compose_finish and output_chars should not be initialized because
-+     * ibus_compose_table_check() is called at first and
-+     * engine->priv->tentative_match will be preedit after this is called.
-+     */
- 
-     /* Will never match, if the sequence in the compose buffer is longer
-      * than the sequences in the table.  Further, compare_seq (key, val)
-@@ -1588,7 +1587,8 @@ ibus_compose_table_compact_check (const IBusComposeTableCompactEx *table,
-             if (compose_finish)
-                 *compose_finish = TRUE;
-             if (output_chars) {
--                *output_chars = g_new (gunichar, length + 1);
-+                if (!(*output_chars))
-+                    *output_chars = g_new (gunichar, length + 1);
-                 for (j = 0; j < length; j++) {
-                     (*output_chars)[j] = table->priv->data2[index + j];
-                 }
-@@ -1622,7 +1622,8 @@ ibus_compose_table_compact_check (const IBusComposeTableCompactEx *table,
-             if (compose_finish)
-                 *compose_finish = TRUE;
-             if (output_chars) {
--                *output_chars = g_new (gunichar, 2);
-+                if (!(*output_chars))
-+                    *output_chars = g_new (gunichar, 2);
-                 (*output_chars)[0] = seq[row_stride - 1];
-                 (*output_chars)[1] = 0;
-             }
-@@ -1635,16 +1636,6 @@ ibus_compose_table_compact_check (const IBusComposeTableCompactEx *table,
- }
- 
- 
--/* Checks if a keysym is a dead key. Dead key keysym values are defined in
-- * ../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_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) >= IBUS_KEY_dead_grave && (k) <= IBUS_KEY_dead_greek)
--
- /* This function receives a sequence of Unicode characters and tries to
-  * normalize it (NFC). We check for the case the the resulting string
-  * has length 1 (single character).
-@@ -1754,7 +1745,8 @@ ibus_check_algorithmically (const guint16 *compose_buffer,
-         i--;
-         while (i >= 0) {
-             combination_buffer[i+1] = ibus_keysym_to_unicode (compose_buffer[i],
--                                                              TRUE);
-+                                                              TRUE,
-+                                                              NULL);
-             if (!combination_buffer[i+1]) {
-                 combination_buffer[i+1] =
-                         ibus_keyval_to_unicode (compose_buffer[i]);
-@@ -1786,66 +1778,91 @@ ibus_check_algorithmically (const guint16 *compose_buffer,
- 
- 
- gunichar
--ibus_keysym_to_unicode (guint16  keysym,
--                        gboolean combining) {
--#define CASE(keysym_suffix, unicode)                                    \
--        case IBUS_KEY_dead_##keysym_suffix: return unicode
--#define CASE_COMBINE(keysym_suffix, combined_unicode, isolated_unicode) \
--        case IBUS_KEY_dead_##keysym_suffix:                             \
--            if (combining)                                              \
--                return combined_unicode;                                \
--            else                                                        \
-+ibus_keysym_to_unicode (guint16   keysym,
-+                        gboolean  combining,
-+                        gboolean *need_space) {
-+#define CASE(keysym_suffix, unicode, sp)                                      \
-+        case IBUS_KEY_dead_##keysym_suffix:                                   \
-+            if (need_space)                                                   \
-+                *need_space = sp;                                             \
-+            return unicode
-+#define CASE_COMBINE(keysym_suffix, combined_unicode, isolated_unicode, sp)   \
-+        case IBUS_KEY_dead_##keysym_suffix:                                   \
-+            if (need_space)                                                   \
-+                *need_space = sp;                                             \
-+            if (combining)                                                    \
-+                return combined_unicode;                                      \
-+            else                                                              \
-                 return isolated_unicode
-     switch (keysym) {
--    CASE (a, 0x03041);
--    CASE (A, 0x03042);
--    CASE (i, 0x03043);
--    CASE (I, 0x03044);
--    CASE (u, 0x03045);
--    CASE (U, 0x03046);
--    CASE (e, 0x03047);
--    CASE (E, 0x03048);
--    CASE (o, 0x03049);
--    CASE (O, 0x0304A);
--    CASE         (abovecomma,                   0x0313);
--    CASE_COMBINE (abovedot,                     0x0307, 0x02D9);
--    CASE         (abovereversedcomma,           0x0314);
--    CASE_COMBINE (abovering,                    0x030A, 0x02DA);
--    CASE_COMBINE (acute,                        0x0301, 0x00B4);
--    CASE         (belowbreve,                   0x032E);
--    CASE_COMBINE (belowcircumflex,              0x032D, 0xA788);
--    CASE_COMBINE (belowcomma,                   0x0326, 0x002C);
--    CASE         (belowdiaeresis,               0x0324);
--    CASE_COMBINE (belowdot,                     0x0323, 0x002E);
--    CASE_COMBINE (belowmacron,                  0x0331, 0x02CD);
--    CASE_COMBINE (belowring,                    0x030A, 0x02F3);
--    CASE_COMBINE (belowtilde,                   0x0330, 0x02F7);
--    CASE_COMBINE (breve,                        0x0306, 0x02D8);
--    CASE_COMBINE (capital_schwa,                0x018F, 0x04D8);
--    CASE_COMBINE (caron,                        0x030C, 0x02C7);
--    CASE_COMBINE (cedilla,                      0x0327, 0x00B8);
--    CASE_COMBINE (circumflex,                   0x0302, 0x005E);
--    CASE         (currency,                     0x00A4);
-+#ifdef IBUS_ENGLISH_DEAD_KEY
-+    CASE (a, 0x0363, 1);
-+    CASE (A, 0x0363, 1);
-+    CASE (i, 0x0365, 1);
-+    CASE (I, 0x0365, 1);
-+    CASE (u, 0x0367, 1);
-+    CASE (U, 0x0367, 1);
-+    CASE (e, 0x0364, 1);
-+    CASE (E, 0x0364, 1);
-+    CASE (o, 0x0366, 1);
-+    CASE (O, 0x0366, 1);
-+#else
-+    CASE (a, 0x3041, 0);
-+    CASE (A, 0x3042, 0);
-+    CASE (i, 0x3043, 0);
-+    CASE (I, 0x3044, 0);
-+    CASE (u, 0x3045, 0);
-+    CASE (U, 0x3046, 0);
-+    CASE (e, 0x3047, 0);
-+    CASE (E, 0x3048, 0);
-+    CASE (o, 0x3049, 0);
-+    CASE (O, 0x304A, 0);
-+#endif
-+    CASE_COMBINE (abovecomma,                   0x0313, 0x02BC, 0);
-+    CASE_COMBINE (abovedot,                     0x0307, 0x02D9, 0);
-+    CASE_COMBINE (abovereversedcomma,           0x0314, 0x02BD, 0);
-+    CASE_COMBINE (abovering,                    0x030A, 0x02DA, 0);
-+    CASE_COMBINE (aboveverticalline,            0x030D, 0x02C8, 0);
-+    CASE_COMBINE (acute,                        0x0301, 0x00B4, 0);
-+    CASE         (belowbreve,                   0x032E, 1);
-+    CASE_COMBINE (belowcircumflex,              0x032D, 0xA788, 0);
-+    CASE_COMBINE (belowcomma,                   0x0326, 0x002C, 0);
-+    CASE         (belowdiaeresis,               0x0324, 1);
-+    CASE_COMBINE (belowdot,                     0x0323, 0x002E, 0);
-+    CASE_COMBINE (belowmacron,                  0x0331, 0x02CD, 0);
-+    CASE_COMBINE (belowring,                    0x030A, 0x02F3, 0);
-+    CASE_COMBINE (belowtilde,                   0x0330, 0x02F7, 0);
-+    CASE_COMBINE (belowverticalline,            0x0329, 0x02CC, 0);
-+    CASE_COMBINE (breve,                        0x0306, 0x02D8, 0);
-+    CASE_COMBINE (capital_schwa,                0x1DEA, 0x1D4A, 0);
-+    CASE_COMBINE (caron,                        0x030C, 0x02C7, 0);
-+    CASE_COMBINE (cedilla,                      0x0327, 0x00B8, 0);
-+    CASE_COMBINE (circumflex,                   0x0302, 0x005E, 0);
-+    CASE         (currency,                     0x00A4, 0);
-     // IBUS_KEY_dead_dasia == IBUS_KEY_dead_abovereversedcomma
--    CASE_COMBINE (diaeresis,                    0x0308, 0x00A8);
--    CASE_COMBINE (doubleacute,                  0x030B, 0x02DD);
--    CASE_COMBINE (doublegrave,                  0x030F, 0x02F5);
--    CASE_COMBINE (grave,                        0x0300, 0x0060);
--    CASE         (greek,                        0x03BC);
--    CASE         (hook,                         0x0309);
--    CASE         (horn,                         0x031B);
--    CASE         (invertedbreve,                0x032F);
--    CASE_COMBINE (iota,                         0x0345, 0x037A);
--    CASE_COMBINE (macron,                       0x0304, 0x00AF);
--    CASE_COMBINE (ogonek,                       0x0328, 0x02DB);
-+    CASE_COMBINE (diaeresis,                    0x0308, 0x00A8, 0);
-+    CASE_COMBINE (doubleacute,                  0x030B, 0x02DD, 0);
-+    CASE_COMBINE (doublegrave,                  0x030F, 0x02F5, 0);
-+    CASE_COMBINE (grave,                        0x0300, 0x0060, 0);
-+    CASE         (greek,                        0x03BC, 0);
-+    CASE_COMBINE (hook,                         0x0309, 0x02C0, 0);
-+    CASE         (horn,                         0x031B, 1);
-+    CASE         (invertedbreve,                0x032F, 1);
-+    CASE_COMBINE (iota,                         0x0345, 0x037A, 0);
-+    CASE         (longsolidusoverlay,           0x0338, 1);
-+    CASE_COMBINE (lowline,                      0x0332, 0x005F, 0);
-+    CASE_COMBINE (macron,                       0x0304, 0x00AF, 0);
-+    CASE_COMBINE (ogonek,                       0x0328, 0x02DB, 0);
-     // IBUS_KEY_dead_perispomeni == IBUS_KEY_dead_tilde
-     // IBUS_KEY_dead_psili == IBUS_KEY_dead_abovecomma
--    CASE_COMBINE (semivoiced_sound,             0x309A, 0x309C);
--    CASE_COMBINE (small_schwa,                  0x1D4A, 0x04D9);
--    CASE         (stroke,                       0x002F);
--    CASE_COMBINE (tilde,                        0x0303, 0x007E);
--    CASE_COMBINE (voiced_sound,                 0x3099, 0x309B);
-+    CASE_COMBINE (semivoiced_sound,             0x309A, 0x309C, 0);
-+    CASE_COMBINE (small_schwa,                  0x1DEA, 0x1D4A, 0);
-+    CASE         (stroke,                       0x0335, 1);
-+    CASE_COMBINE (tilde,                        0x0303, 0x007E, 0);
-+    CASE_COMBINE (voiced_sound,                 0x3099, 0x309B, 0);
-     case IBUS_KEY_Multi_key:
-+        if (need_space)
-+            *need_space = FALSE;
-         /* We only show the Compose key visibly when it is the
-          * only glyph in the preedit, or when it occurs in the
-          * middle of the sequence. Sadly, the official character,
-@@ -1854,6 +1871,8 @@ ibus_keysym_to_unicode (guint16  keysym,
-          */
-         return 0x00B7;
-     default:;
-+        if (need_space)
-+            *need_space = FALSE;
-     }
-     return 0x0;
- #undef CASE
-diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
-index 699cf0d4..acfc0264 100644
---- a/src/ibusenginesimple.c
-+++ b/src/ibusenginesimple.c
-@@ -78,13 +78,14 @@ typedef struct {
- 
- struct _IBusEngineSimplePrivate {
-     guint16            *compose_buffer;
--    gunichar            tentative_match;
--    char               *tentative_emoji;
-+    GString            *tentative_match;
-     int                 tentative_match_len;
-+    char               *tentative_emoji;
- 
-     guint               hex_mode_enabled : 1;
-     guint               in_hex_sequence : 1;
-     guint               in_emoji_sequence : 1;
-+    guint               in_compose_sequence : 1;
-     guint               modifiers_dropped : 1;
-     IBusEngineDict     *emoji_dict;
-     IBusLookupTable    *lookup_table;
-@@ -178,6 +179,8 @@ ibus_engine_simple_init (IBusEngineSimple *simple)
-     simple->priv->hex_mode_enabled =
-         g_getenv("IBUS_ENABLE_CTRL_SHIFT_U") != NULL ||
-         g_getenv("IBUS_ENABLE_CONTROL_SHIFT_U") != NULL;
-+    simple->priv->tentative_match = g_string_new ("");
-+    simple->priv->tentative_match_len = 0;
- }
- 
- 
-@@ -196,6 +199,9 @@ ibus_engine_simple_destroy (IBusEngineSimple *simple)
-     g_clear_object (&priv->lookup_table);
-     g_clear_pointer (&priv->compose_buffer, g_free);
-     g_clear_pointer (&priv->tentative_emoji, g_free);
-+    g_string_free (priv->tentative_match, TRUE);
-+    priv->tentative_match = NULL;
-+    priv->tentative_match_len = 0;
- 
-     IBUS_OBJECT_CLASS(ibus_engine_simple_parent_class)->destroy (
-         IBUS_OBJECT (simple));
-@@ -222,15 +228,15 @@ ibus_engine_simple_reset (IBusEngine *engine)
- 
-     priv->compose_buffer[0] = 0;
- 
--    if (priv->tentative_match || priv->in_hex_sequence) {
-+    if (priv->tentative_match->len > 0 || priv->in_hex_sequence) {
-         priv->in_hex_sequence = FALSE;
--        priv->tentative_match = 0;
-+        g_string_set_size (priv->tentative_match, 0);
-         priv->tentative_match_len = 0;
-     } else if (priv->tentative_emoji || priv->in_emoji_sequence) {
-         priv->in_emoji_sequence = FALSE;
-         g_clear_pointer (&priv->tentative_emoji, g_free);
-     } else if (!priv->in_hex_sequence && !priv->in_emoji_sequence) {
--        priv->tentative_match = 0;
-+        g_string_set_size (priv->tentative_match, 0);
-         priv->tentative_match_len = 0;
-     }
-     ibus_engine_hide_preedit_text ((IBusEngine *)simple);
-@@ -244,10 +250,17 @@ ibus_engine_simple_commit_char (IBusEngineSimple *simple,
- 
-     IBusEngineSimplePrivate *priv = simple->priv;
- 
--    if (priv->tentative_match || priv->in_hex_sequence) {
--        priv->in_hex_sequence = FALSE;
--        priv->tentative_match = 0;
-+    if (priv->in_hex_sequence ||
-+        priv->tentative_match_len > 0 ||
-+        priv->compose_buffer[0] != 0) {
-+        g_string_set_size (priv->tentative_match, 0);
-         priv->tentative_match_len = 0;
-+        priv->in_hex_sequence = FALSE;
-+        priv->in_compose_sequence = FALSE;
-+        priv->compose_buffer[0] = 0;
-+        /* Don't call ibus_engine_simple_update_preedit_text() inside
-+         * not to call it as duplilcated.
-+         */
-     }
-     if (priv->tentative_emoji || priv->in_emoji_sequence) {
-         priv->in_emoji_sequence = FALSE;
-@@ -269,10 +282,17 @@ ibus_engine_simple_commit_str (IBusEngineSimple *simple,
- 
-     backup_str = g_strdup (str);
- 
--    if (priv->tentative_match || priv->in_hex_sequence) {
--        priv->in_hex_sequence = FALSE;
--        priv->tentative_match = 0;
-+    if (priv->in_hex_sequence ||
-+        priv->tentative_match_len > 0 ||
-+        priv->compose_buffer[0] != 0) {
-+        g_string_set_size (priv->tentative_match, 0);
-         priv->tentative_match_len = 0;
-+        priv->in_hex_sequence = FALSE;
-+        priv->in_compose_sequence = FALSE;
-+        priv->compose_buffer[0] = 0;
-+        /* Don't call ibus_engine_simple_update_preedit_text() inside
-+         * not to call it as duplilcated.
-+         */
-     }
-     if (priv->tentative_emoji || priv->in_emoji_sequence) {
-         priv->in_emoji_sequence = FALSE;
-@@ -288,8 +308,8 @@ static void
- ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
--
-     GString *s = g_string_new ("");
-+    int i, j;
- 
-     if (priv->in_hex_sequence || priv->in_emoji_sequence) {
-         int hexchars = 0;
-@@ -305,32 +325,59 @@ ibus_engine_simple_update_preedit_text (IBusEngineSimple *simple)
-                     ibus_keyval_to_unicode (priv->compose_buffer[hexchars++])
-             );
-         }
--    } else if (priv->tentative_match) {
--        g_string_append_unichar(s, priv->tentative_match);
-     } else if (priv->tentative_emoji && *priv->tentative_emoji) {
-         IBusText *text = ibus_text_new_from_string (priv->tentative_emoji);
-         int len = strlen (priv->tentative_emoji);
-         ibus_text_append_attribute (text,
-                 IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, len);
-         ibus_engine_update_preedit_text ((IBusEngine *)simple, text, len, TRUE);
-+        g_string_free (s, TRUE);
-         return;
--    } else {
--        int hexchars = 0;
--        while (priv->compose_buffer[hexchars] != 0) {
--            guint16 keysym = priv->compose_buffer[hexchars];
--            gunichar unichar = ibus_keysym_to_unicode (keysym, FALSE);
--            if (unichar > 0) {
--                g_string_append_unichar(s, unichar);
--            } else {
--                unichar = ibus_keyval_to_unicode (keysym);
--                g_string_append_unichar(s, unichar);
--            }
--            if (!unichar) {
--                g_warning (
-+    } else if (priv->in_compose_sequence) {
-+        if (priv->tentative_match->len > 0 && priv->compose_buffer[0] != 0) {
-+            g_string_append (s, priv->tentative_match->str);
-+        } else {
-+            for (i = 0; priv->compose_buffer[i]; ++i) {
-+                guint16 keysym = priv->compose_buffer[i];
-+                gboolean show_keysym = TRUE;
-+                gboolean need_space = FALSE;
-+                gunichar ch;
-+
-+                if (keysym == IBUS_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
-+                     * middle of the sequence. Sadly, the official character,
-+                     * U+2384, COMPOSITION SYMBOL, is bit too distracting, so
-+                     * we use U+00B7, MIDDLE DOT.
-+                     */
-+                    for (j = i + 1; priv->compose_buffer[j]; j++) {
-+                        if (priv->compose_buffer[j] != IBUS_KEY_Multi_key) {
-+                            show_keysym = FALSE;
-+                            break;
-+                        }
-+                    }
-+                    if (!show_keysym)
-+                        continue;
-+                    ch = ibus_keysym_to_unicode (keysym, FALSE, NULL);
-+                    g_string_append_unichar (s, ch);
-+                } else if (IS_DEAD_KEY (keysym)) {
-+                    ch = ibus_keysym_to_unicode (keysym, FALSE, &need_space);
-+                    if (ch) {
-+                        if (need_space)
-+                            g_string_append_c (s, ' ');
-+                        g_string_append_unichar (s, ch);
-+                    }
-+                } else {
-+                    ch = ibus_keyval_to_unicode (keysym);
-+                    if (ch)
-+                        g_string_append_unichar(s, ch);
-+                }
-+                if (!ch) {
-+                    g_warning (
-                         "Not found alternative character of compose key 0x%X",
--                        priv->compose_buffer[hexchars]);
-+                        priv->compose_buffer[i]);
-+                }
-             }
--            ++hexchars;
-         }
-     }
- 
-@@ -380,7 +427,7 @@ check_hex (IBusEngineSimple *simple,
- 
-     CHECK_COMPOSE_BUFFER_LENGTH (n_compose);
- 
--    priv->tentative_match = 0;
-+    g_string_set_size (priv->tentative_match, 0);
-     priv->tentative_match_len = 0;
- 
-     str = g_string_new (NULL);
-@@ -421,7 +468,8 @@ check_hex (IBusEngineSimple *simple,
-     }
- 
-     if (g_unichar_validate (n)) {
--        priv->tentative_match = n;
-+        g_string_set_size (priv->tentative_match, 0);
-+        g_string_append_unichar (priv->tentative_match, n);
-         priv->tentative_match_len = n_compose;
-     }
- 
-@@ -546,21 +594,31 @@ no_sequence_matches (IBusEngineSimple *simple,
- 
-     CHECK_COMPOSE_BUFFER_LENGTH (n_compose);
- 
-+    priv->in_compose_sequence = FALSE;
-+
-     /* No compose sequences found, check first if we have a partial
-      * match pending.
-      */
--    if (priv->tentative_match) {
-+    if (priv->tentative_match_len > 0) {
-+        guint16 *compose_buffer;
-         int len = priv->tentative_match_len;
-         int i;
-+        char *str;
- 
--        ibus_engine_simple_commit_char (simple, priv->tentative_match);
--        priv->compose_buffer[0] = 0;
-+        compose_buffer = alloca (sizeof (guint16) * COMPOSE_BUFFER_SIZE);
-+        memcpy (compose_buffer,
-+                priv->compose_buffer,
-+                sizeof (guint16) * COMPOSE_BUFFER_SIZE);
-+
-+        str = g_strdup (priv->tentative_match->str);
-+        ibus_engine_simple_commit_str (simple, str);
-+        g_free (str);
-         ibus_engine_simple_update_preedit_text (simple);
- 
-         for (i=0; i < n_compose - len - 1; i++) {
-             ibus_engine_simple_process_key_event (
-                     (IBusEngine *)simple,
--                    priv->compose_buffer[len + i],
-+                    compose_buffer[len + i],
-                     0, 0);
-         }
- 
-@@ -571,6 +629,26 @@ no_sequence_matches (IBusEngineSimple *simple,
-         priv->compose_buffer[0] = 0;
-         ibus_engine_simple_update_preedit_text (simple);
-     } else {
-+        if (n_compose == 2 && IS_DEAD_KEY (priv->compose_buffer[0])) {
-+            gboolean need_space = FALSE;
-+            GString *s = g_string_new ("");
-+            /* dead keys are never *really* dead */
-+            ch = ibus_keysym_to_unicode (priv->compose_buffer[0],
-+                                         FALSE, &need_space);
-+            if (ch) {
-+                if (need_space)
-+                    g_string_append_c (s, ' ');
-+                g_string_append_unichar (s, ch);
-+            }
-+            ch = ibus_keyval_to_unicode (priv->compose_buffer[1]);
-+            if (ch != 0 && !g_unichar_iscntrl (ch))
-+                g_string_append_unichar (s, ch);
-+            ibus_engine_simple_commit_str (simple, s->str);
-+            g_string_free (s, TRUE);
-+            ibus_engine_simple_update_preedit_text (simple);
-+            return TRUE;
-+        }
-+
-         priv->compose_buffer[0] = 0;
-         if (n_compose > 1) {
-             /* Invalid sequence */
-@@ -695,19 +773,46 @@ ibus_engine_simple_set_number_on_lookup_table (IBusEngineSimple *simple,
-     ibus_engine_simple_update_preedit_text (simple);
- }
- 
-+
- static gboolean
- ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
-                                             int               n_compose)
- {
-     IBusEngineSimplePrivate *priv = simple->priv;
-+    GSList *tmp_list;
-     gboolean compose_finish = FALSE;
-     gboolean compose_match = FALSE;
-     GString *output = g_string_new ("");
--    gboolean does_hit = FALSE;
-+    gboolean success = FALSE;
-     gboolean is_32bit = FALSE;
--    GSList *tmp_list;
-     gunichar *output_chars = NULL;
--    gunichar output_char;
-+    gunichar output_char = '\0';
-+
-+    if (n_compose == 2) {
-+        /* Special-case deadkey-deadkey sequences.
-+         * We are not doing chained deadkeys, so we
-+         * want to commit the first key, and contine
-+         * preediting with second.
-+         */
-+        if (IS_DEAD_KEY (priv->compose_buffer[0]) &&
-+            IS_DEAD_KEY (priv->compose_buffer[1])) {
-+            gboolean need_space = FALSE;
-+            gunichar ch = ibus_keysym_to_unicode (priv->compose_buffer[0],
-+                                                  FALSE, &need_space);
-+            guint16 next = priv->compose_buffer[1];
-+            if (ch) {
-+                if (need_space)
-+                    g_string_append_c (output, ' ');
-+                g_string_append_unichar (output, ch);
-+                ibus_engine_simple_commit_str (simple, output->str);
-+                g_string_set_size (output, 0);
-+
-+                priv->compose_buffer[0] = next;
-+                priv->compose_buffer[1] = 0;
-+                n_compose = 1;
-+            }
-+        }
-+    }
- 
-     G_LOCK (global_tables);
-     tmp_list = global_tables;
-@@ -721,7 +826,7 @@ ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
-             &compose_match,
-             output,
-             is_32bit)) {
--            does_hit = TRUE;
-+            success = TRUE;
-             break;
-         }
-         is_32bit = TRUE;
-@@ -733,14 +838,15 @@ ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
-             &compose_match,
-             output,
-             is_32bit)) {
--            does_hit = TRUE;
-+            success = TRUE;
-             break;
-         }
-         tmp_list = tmp_list->next;
-     }
-     G_UNLOCK (global_tables);
- 
--    if (does_hit) {
-+    if (success) {
-+        priv->in_compose_sequence = TRUE;
-         if (compose_finish) {
-             if (compose_match) {
-                 if (is_32bit) {
-@@ -750,59 +856,89 @@ ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
-                                                     g_utf8_get_char (output->str));
-                 }
-             }
-+            ibus_engine_simple_update_preedit_text (simple);
-+            g_string_free (output, TRUE);
-+            return TRUE;
-         } else if (compose_match) {
--            priv->tentative_match = g_utf8_get_char (output->str);
-+            g_string_assign (priv->tentative_match, output->str);
-             priv->tentative_match_len = n_compose;
-+            ibus_engine_simple_update_preedit_text (simple);
-+            g_string_free (output, TRUE);
-+            return TRUE;
-         }
--        ibus_engine_simple_update_preedit_text (simple);
--        g_string_free (output, TRUE);
--        return TRUE;
-     }
-     g_string_free (output, TRUE);
-+    output = NULL;
- 
-     if (ibus_compose_table_compact_check (&ibus_compose_table_compact,
-                                           priv->compose_buffer,
-                                           n_compose,
-                                           &compose_finish,
-                                           &output_chars)) {
-+        priv->in_compose_sequence = TRUE;
-         if (compose_finish) {
--            ibus_engine_simple_commit_char (simple, *output_chars);
-+            if (success) {
-+                g_string_append_unichar (priv->tentative_match, *output_chars);
-+                priv->tentative_match_len = n_compose;
-+            } else {
-+                ibus_engine_simple_commit_char (simple, *output_chars);
-+                priv->compose_buffer[0] = 0;
-+            }
-             g_free (output_chars);
--            priv->compose_buffer[0] = 0;
-+            ibus_engine_simple_update_preedit_text (simple);
-+            return TRUE;
-         }
--        ibus_engine_simple_update_preedit_text (simple);
--        return TRUE;
-+        success = TRUE;
-     }
-+    g_free (output_chars);
-+    output_chars = NULL;
-     if (ibus_compose_table_compact_check (&ibus_compose_table_compact_32bit,
-                                           priv->compose_buffer,
-                                           n_compose,
-                                           &compose_finish,
-                                           &output_chars)) {
-+        priv->in_compose_sequence = TRUE;
-         if (compose_finish) {
-             GError *error = NULL;
-             char *str = g_ucs4_to_utf8 (output_chars, -1, NULL, NULL, &error);
--            if (str) {
--                ibus_engine_simple_commit_str (simple, str);
--                g_free (str);
--            } else {
-+            if (!str) {
-                 g_warning ("Failed to output multiple characters: %s",
-                            error->message);
-                 g_error_free (error);
-+            } else if (success) {
-+                g_string_append (priv->tentative_match, str);
-+                priv->tentative_match_len = n_compose;
-+            } else {
-+                ibus_engine_simple_commit_str (simple, str);
-+                priv->compose_buffer[0] = 0;
-             }
--            priv->compose_buffer[0] = 0;
-+            g_free (str);
-+            g_free (output_chars);
-+            ibus_engine_simple_update_preedit_text (simple);
-+            return TRUE;
-         }
--        g_free (output_chars);
--        ibus_engine_simple_update_preedit_text (simple);
--        return TRUE;
-+        success = TRUE;
-     }
--    g_assert (!output_chars);
-+    g_free (output_chars);
-+    output_chars = NULL;
-     if (ibus_check_algorithmically (priv->compose_buffer,
-                                     n_compose,
-                                     &output_char)) {
-+        priv->in_compose_sequence = TRUE;
-         if (output_char) {
--            ibus_engine_simple_commit_char (simple, output_char);
--            priv->compose_buffer[0] = 0;
-+            if (success) {
-+                g_string_append_unichar (priv->tentative_match, output_char);
-+                priv->tentative_match_len = n_compose;
-+            } else  {
-+                ibus_engine_simple_commit_char (simple, output_char);
-+                priv->compose_buffer[0] = 0;
-+            }
-+            ibus_engine_simple_update_preedit_text (simple);
-+            return TRUE;
-         }
-+        success = TRUE;
-+    }
-+    if (success) {
-         ibus_engine_simple_update_preedit_text (simple);
-         return TRUE;
-     }
-@@ -810,6 +946,7 @@ ibus_engine_simple_check_all_compose_table (IBusEngineSimple *simple,
-     return FALSE;
- }
- 
-+
- static gboolean
- ibus_engine_simple_process_key_event (IBusEngine *engine,
-                                       guint       keyval,
-@@ -841,16 +978,17 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-         if (priv->in_hex_sequence &&
-             (keyval == IBUS_KEY_Control_L || keyval == IBUS_KEY_Control_R ||
-              keyval == IBUS_KEY_Shift_L || keyval == IBUS_KEY_Shift_R)) {
--            if (priv->tentative_match &&
--                g_unichar_validate (priv->tentative_match)) {
--                ibus_engine_simple_commit_char (simple, priv->tentative_match);
-+            if (priv->tentative_match->len > 0) {
-+                char *str = g_strdup (priv->tentative_match->str);
-+                ibus_engine_simple_commit_str (simple, str);
-+                g_free (str);
-                 ibus_engine_simple_update_preedit_text (simple);
-             } else if (n_compose == 0) {
-                 priv->modifiers_dropped = TRUE;
-             } else {
-                 /* invalid hex sequence */
-                 /* FIXME beep_window (event->window); */
--                priv->tentative_match = 0;
-+                g_string_set_size (priv->tentative_match, 0);
-                 g_clear_pointer (&priv->tentative_emoji, g_free);
-                 priv->in_hex_sequence = FALSE;
-                 priv->in_emoji_sequence = FALSE;
-@@ -873,7 +1011,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-             } else {
-                 /* invalid hex sequence */
-                 /* FIXME beep_window (event->window); */
--                priv->tentative_match = 0;
-+                g_string_set_size (priv->tentative_match, 0);
-                 g_clear_pointer (&priv->tentative_emoji, g_free);
-                 priv->in_hex_sequence = FALSE;
-                 priv->in_emoji_sequence = FALSE;
-@@ -921,7 +1059,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-         else if (is_hex_end) {
-             /* invalid hex sequence */
-             // beep_window (event->window);
--            priv->tentative_match = 0;
-+            g_string_set_size (priv->tentative_match, 0);
-             g_clear_pointer (&priv->tentative_emoji, g_free);
-             priv->in_hex_sequence = FALSE;
-             priv->in_emoji_sequence = FALSE;
-@@ -999,7 +1137,8 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-         if (n_compose > 0) {
-             n_compose--;
-             priv->compose_buffer[n_compose] = 0;
--            priv->tentative_match = 0;
-+            g_string_set_size (priv->tentative_match, 0);
-+            priv->tentative_match_len = 0;
-             ibus_engine_simple_check_all_compose_table (simple, n_compose);
-             return TRUE;
-         }
-@@ -1007,16 +1146,17 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
- 
-     /* Check for hex sequence restart */
-     if (priv->in_hex_sequence && have_hex_mods && is_hex_start) {
--        if (priv->tentative_match &&
--            g_unichar_validate (priv->tentative_match)) {
--            ibus_engine_simple_commit_char (simple, priv->tentative_match);
-+        if (priv->tentative_match->len > 0 ) {
-+            char *str = g_strdup (priv->tentative_match->str);
-+            ibus_engine_simple_commit_str (simple, str);
-+            g_free (str);
-             ibus_engine_simple_update_preedit_text (simple);
-         }
-         else {
-             /* invalid hex sequence */
-             if (n_compose > 0) {
-                 // FIXME beep_window (event->window);
--                priv->tentative_match = 0;
-+                g_string_set_size (priv->tentative_match, 0);
-                 priv->in_hex_sequence = FALSE;
-                 priv->compose_buffer[0] = 0;
-             }
-@@ -1044,7 +1184,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-         priv->in_hex_sequence = TRUE;
-         priv->in_emoji_sequence = FALSE;
-         priv->modifiers_dropped = FALSE;
--        priv->tentative_match = 0;
-+        g_string_set_size (priv->tentative_match, 0);
-         g_clear_pointer (&priv->tentative_emoji, g_free);
- 
-         // g_debug ("Start HEX MODE");
-@@ -1058,7 +1198,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-         priv->in_hex_sequence = FALSE;
-         priv->in_emoji_sequence = TRUE;
-         priv->modifiers_dropped = FALSE;
--        priv->tentative_match = 0;
-+        g_string_set_size (priv->tentative_match, 0);
-         g_clear_pointer (&priv->tentative_emoji, g_free);
- 
-         // g_debug ("Start HEX MODE");
-@@ -1068,7 +1208,6 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-         return TRUE;
-     }
- 
--    /* Then, check for compose sequences */
-     if (priv->in_hex_sequence) {
-         if (hex_keyval) {
-             SET_COMPOSE_BUFFER_ELEMENT_NEXT (priv->compose_buffer,
-@@ -1133,17 +1272,17 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
-         if (have_hex_mods) {
-             /* space or return ends the sequence, and we eat the key */
-             if (n_compose > 0 && is_hex_end) {
--                if (priv->tentative_match &&
--                    g_unichar_validate (priv->tentative_match)) {
--                    ibus_engine_simple_commit_char (simple,
--                            priv->tentative_match);
--                    priv->compose_buffer[0] = 0;
-+                if (priv->tentative_match->len > 0) {
-+                    char *str = g_strdup (priv->tentative_match->str);
-+                    ibus_engine_simple_commit_str (simple, str);
-+                    g_free (str);
-                     ibus_engine_simple_update_preedit_text (simple);
-+                    return TRUE;
-                 } else {
-                     // FIXME
-                     /* invalid hex sequence */
-                     // beep_window (event->window);
--                    priv->tentative_match = 0;
-+                    g_string_set_size (priv->tentative_match, 0);
-                     priv->in_hex_sequence = FALSE;
-                     priv->compose_buffer[0] = 0;
-                 }
-@@ -1234,7 +1373,7 @@ ibus_engine_simple_process_key_event (IBusEngine *engine,
- 
-             return TRUE;
-         }
--    } else {
-+    } else { /* Then, check for compose sequences */
-         if (ibus_engine_simple_check_all_compose_table (simple, n_compose))
-             return TRUE;
-     }
-diff --git a/src/ibusenginesimpleprivate.h b/src/ibusenginesimpleprivate.h
-index 5479e553..ad93d2d2 100644
---- a/src/ibusenginesimpleprivate.h
-+++ b/src/ibusenginesimpleprivate.h
-@@ -26,6 +26,12 @@
- 
- G_BEGIN_DECLS
- 
-+/* Checks if a keysym is a dead key. Dead key keysym values are defined in
-+ * ibuskeysyms.h and the first is GDK_KEY_dead_grave.
-+ */
-+#define IS_DEAD_KEY(k) \
-+      ((k) >= IBUS_KEY_dead_grave && (k) <= IBUS_KEY_dead_greek)
-+
- extern const IBusComposeTableCompactEx ibus_compose_table_compact;
- extern const IBusComposeTableCompactEx ibus_compose_table_compact_32bit;
- 
-@@ -60,7 +66,8 @@ gboolean ibus_compose_table_compact_check
-                                      gboolean                   *compose_finish,
-                                      gunichar                  **output_chars);
- gunichar ibus_keysym_to_unicode     (guint16                     keysym,
--                                     gboolean                    combining);
-+                                     gboolean                    combining,
-+                                     gboolean                   *need_space);
- 
- G_END_DECLS
- 
--- 
-2.28.0
-
-From 17ae266cade41e795534532acefc85716bb309ef Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 26 Jul 2021 22:53:34 +0900
-Subject: [PATCH 6/6] Code reviews
-
-- Use fstat() and fchmod() but not stat() and chmod() to
-  fix race conditions
-- Avoid to use after free
-- Fix dereference of IBusComposeTable->priv
-- Fix to divide by zero
----
- src/ibusbus.c                            | 23 ++++++++++++++++++-----
- src/ibuscomposetable.c                   |  8 ++++++--
- src/tests/ibus-desktop-testing-runner.in |  6 +++---
- 3 files changed, 27 insertions(+), 10 deletions(-)
-
-diff --git a/src/ibusbus.c b/src/ibusbus.c
-index e9b0bcbb..47400cb8 100644
---- a/src/ibusbus.c
-+++ b/src/ibusbus.c
-@@ -21,13 +21,14 @@
-  * USA
-  */
- 
--#include "ibusbus.h"
- #include <errno.h>
-+#include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <glib/gstdio.h>
- #include <gio/gio.h>
-+#include "ibusbus.h"
- #include "ibusmarshalers.h"
- #include "ibusinternal.h"
- #include "ibusshare.h"
-@@ -537,7 +538,8 @@ static void
- ibus_bus_init (IBusBus *bus)
- {
-     struct stat buf;
--    gchar *path;
-+    char *path;
-+    int fd;
- 
-     bus->priv = IBUS_BUS_GET_PRIVATE (bus);
- 
-@@ -562,20 +564,31 @@ ibus_bus_init (IBusBus *bus)
-         return;
-     }
- 
--    if (stat (path, &buf) == 0) {
-+    errno = 0;
-+    if ((fd = open (path, O_RDONLY | O_DIRECTORY, S_IRWXU)) == -1) {
-+        g_warning ("open %s failed: %s", path, g_strerror (errno));
-+        g_free (path);
-+        return;
-+    }
-+    /* TOCTOU: Use fstat() and fchmod() but not stat() and chmod().
-+     * because it can cause a time-of-check, time-of-use race condition.
-+     */
-+    if (fstat (fd, &buf) == 0) {
-         if (buf.st_uid != getuid ()) {
-             g_warning ("The owner of %s is not %s!",
-                        path, ibus_get_user_name ());
-+            close (fd);
-             g_free (path);
-             return;
-         }
-         if (buf.st_mode != (S_IFDIR | S_IRWXU)) {
-             errno = 0;
--            if (g_chmod (path, 0700))
--                g_warning ("chmod failed: %s", errno ? g_strerror (errno) : "");
-+            if (fchmod (fd, S_IRWXU))
-+                g_warning ("chmod failed: %s", g_strerror (errno));
-         }
-     }
- 
-+    close (fd);
-     g_free (path);
- }
- 
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index 2ad21551..a0b0befc 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -406,7 +406,7 @@ get_en_compose_file (void)
-         path = g_build_filename (X11_DATADIR, *sys_lang, "Compose", NULL);
-         if (g_file_test (path, G_FILE_TEST_EXISTS))
-             break;
--        g_free (path);
-+        g_clear_pointer (&path, g_free);
-     }
-     return path;
- }
-@@ -975,7 +975,10 @@ ibus_compose_table_deserialize (const char *contents,
-         goto out_load_cache;
-     }
-     if (data_length) {
--        retval->priv = g_new0 (IBusComposeTablePrivate, 1);
-+        if (!(retval->priv = g_new0 (IBusComposeTablePrivate, 1))) {
-+            g_warning ("Failed g_new");
-+            goto out_load_cache;
-+        }
-         retval->priv->data_first = g_new (guint16, data_length);
-         memcpy (retval->priv->data_first,
-                 data_32bit_first, data_length * sizeof (guint16));
-@@ -1565,6 +1568,7 @@ ibus_compose_table_compact_check (const IBusComposeTableCompactEx
-             row_stride = i + 2;
- 
-             if (seq_index[i + 1] - seq_index[i] > 0) {
-+                g_assert (row_stride);
-                 seq = bsearch (compose_buffer + 1,
-                                table->data + seq_index[i],
-                                (seq_index[i + 1] - seq_index[i]) / row_stride,
-diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in
-index 0ef72c03..c1016703 100755
---- a/src/tests/ibus-desktop-testing-runner.in
-+++ b/src/tests/ibus-desktop-testing-runner.in
-@@ -220,7 +220,7 @@ init_gnome()
-     # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append
-     # debug messages to gsettings output and could not get the result correctly.
-     backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG"
--    export -n G_MESSAGES_DEBUG=''
-+    unset G_MESSAGES_DEBUG
-     # Disable Tour dialog to get focus
-     V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version`
-     if [ x"$V" = x"''" ] ; then
-@@ -231,8 +231,8 @@ init_gnome()
-     NO_SYS_DIR=/usr/share/gnome-shell/extensions/no-overview@fthx
-     NO_USER_DIR=$HOME/.local/share/gnome-shell/extensions/no-overview@fthx
-     if [ ! -d $NO_SYS_DIR ] && [ ! -d $NO_USER_DIR ] ; then
--        mkdir -p `dirname $NO_USER_DIR`
--        cp -R no-overview@fthx `dirname $NO_USER_DIR`
-+        mkdir -p "`dirname $NO_USER_DIR`"
-+        cp -R "no-overview@fthx" "`dirname $NO_USER_DIR`"
-     fi
-     V=`gsettings get org.gnome.shell disable-user-extensions`
-     if [ x"$V" = x"true" ] ; then
--- 
-2.28.0
-
-From a823161768c8f6916dbdebe73842a9fc04521369 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 9 Aug 2021 12:36:40 +0900
-Subject: [PATCH] client/gtk2/ibusimcontext: Enable sync process in GTK4
-
-gtk_im_context_filter_key() does not forward control keys likes
-BackSpace, Return and change the process mode to the synchronization.
-
-BUG=https://gitlab.gnome.org/GNOME/gtk/-/issues/3465
----
- client/gtk2/ibusimcontext.c | 65 +++++++++++++++++++++++--------------
- 1 file changed, 41 insertions(+), 24 deletions(-)
-
-diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
-index e7ce5363..da9a402f 100644
---- a/client/gtk2/ibusimcontext.c
-+++ b/client/gtk2/ibusimcontext.c
-@@ -110,13 +110,15 @@ static guint    _signal_preedit_end_id = 0;
- static guint    _signal_delete_surrounding_id = 0;
- static guint    _signal_retrieve_surrounding_id = 0;
- 
--#if !GTK_CHECK_VERSION (3, 98, 4)
-+#if GTK_CHECK_VERSION (3, 98, 4)
-+static gboolean _use_sync_mode = TRUE;
-+#else
- static const gchar *_no_snooper_apps = NO_SNOOPER_APPS;
- static gboolean _use_key_snooper = ENABLE_SNOOPER;
- static guint    _key_snooper_id = 0;
--#endif
- 
- static gboolean _use_sync_mode = FALSE;
-+#endif
- 
- static const gchar *_discard_password_apps  = "";
- static gboolean _use_discard_password = FALSE;
-@@ -767,11 +769,13 @@ ibus_im_context_class_init (IBusIMContextClass *class)
-         g_signal_lookup ("retrieve-surrounding", G_TYPE_FROM_CLASS (class));
-     g_assert (_signal_retrieve_surrounding_id != 0);
- 
--#if !GTK_CHECK_VERSION (3, 98, 4)
-+#if GTK_CHECK_VERSION (3, 98, 4)
-+    _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", TRUE);
-+#else
-     _use_key_snooper = !_get_boolean_env ("IBUS_DISABLE_SNOOPER",
-                                           !(ENABLE_SNOOPER));
--#endif
-     _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", FALSE);
-+#endif
-     _use_discard_password = _get_boolean_env ("IBUS_DISCARD_PASSWORD", FALSE);
- 
- #define CHECK_APP_IN_CSV_ENV_VARIABLES(retval,                          \
-@@ -1434,6 +1438,9 @@ static gboolean
- _set_cursor_location_internal (IBusIMContext *ibusimcontext)
- {
-     GdkRectangle area;
-+#if GTK_CHECK_VERSION (3, 98, 4)
-+    GtkWidget *root;
-+#endif
- 
-     if(ibusimcontext->client_window == NULL ||
-        ibusimcontext->ibuscontext == NULL) {
-@@ -1442,8 +1449,27 @@ _set_cursor_location_internal (IBusIMContext *ibusimcontext)
- 
-     area = ibusimcontext->cursor_area;
- 
--#if !GTK_CHECK_VERSION (3, 98, 4)
- #ifdef GDK_WINDOWING_WAYLAND
-+#if GTK_CHECK_VERSION (3, 98, 4)
-+    root = GTK_WIDGET (gtk_widget_get_root (ibusimcontext->client_window));
-+     /* FIXME: GTK_STYLE_CLASS_TITLEBAR is available in GTK3 but not GTK4.
-+      * gtk_css_boxes_get_content_rect() is available in GTK4 but it's an
-+      * internal API and calculate the window edge 32 in GTK3.
-+      */
-+    area.y += 32;
-+    area.width = 50; /* FIXME: Why 50 meets the cursor position? */
-+    area.height = gtk_widget_get_height (root);
-+    area.height += 32;
-+    if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) {
-+        ibus_input_context_set_cursor_location_relative (
-+            ibusimcontext->ibuscontext,
-+            area.x,
-+            area.y,
-+            area.width,
-+            area.height);
-+        return FALSE;
-+    }
-+#else
-     if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) {
-         gdouble px, py;
-         GdkWindow *parent;
-@@ -1469,23 +1495,20 @@ _set_cursor_location_internal (IBusIMContext *ibusimcontext)
- #endif
- #endif
- 
--    if (area.x == -1 && area.y == -1 && area.width == 0 && area.height == 0) {
- #if GTK_CHECK_VERSION (3, 98, 4)
--        area.x = 0;
--        area.y += gtk_widget_get_height (ibusimcontext->client_window);
- #elif GTK_CHECK_VERSION (2, 91, 0)
--        area.x = 0;
--        area.y += gdk_window_get_height (ibusimcontext->client_window);
-+    area.y += gdk_window_get_height (ibusimcontext->client_window);
- #else
-+    if (area.x == -1 && area.y == -1 && area.width == 0 && area.height == 0) {
-         gint w, h;
-         gdk_drawable_get_size (ibusimcontext->client_window, &w, &h);
-         area.y += h;
-         area.x = 0;
--#endif
-     }
-+#endif
- 
- #if GTK_CHECK_VERSION (3, 98, 4)
--#ifdef GDK_WINDOWING_X11
-+#if defined(GDK_WINDOWING_X11)
-     GdkDisplay *display = gtk_widget_get_display (ibusimcontext->client_window);
-     if (GDK_IS_X11_DISPLAY (display)) {
-         Display *xdisplay = gdk_x11_display_get_xdisplay (display);
-@@ -1505,21 +1528,10 @@ _set_cursor_location_internal (IBusIMContext *ibusimcontext)
-         XGetWindowAttributes (xdisplay, window, &xwa);
-         area.x = x - xwa.x + area.x;
-         area.y = y - xwa.y + area.y;
--        area.width = xwa.width;
-+        area.width = 50; /* FIXME: Why 50 meets the cursor position? */
-         area.height = xwa.height;
-     }
- #endif
--#elif GTK_CHECK_VERSION (3, 93, 0)
--    {
--        GtkNative *native = gtk_widget_get_native (
--                ibusimcontext->client_window);
--        GdkSurface *surface = gtk_native_get_surface (native);
--        int root_x = 0;
--        int root_y = 0;
--        gdk_surface_get_position (surface, &root_x, &root_y);
--        area.x += root_x;
--        area.y += root_y;
--    }
- #else
-     gdk_window_get_root_coords (ibusimcontext->client_window,
-                                 area.x, area.y,
-@@ -1541,12 +1553,17 @@ ibus_im_context_set_cursor_location (GtkIMContext *context, GdkRectangle *area)
- 
-     IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
- 
-+#if !GTK_CHECK_VERSION (3, 93, 0)
-+    /* The area is the relative coordinates and this has to get the absolute
-+     * ones in _set_cursor_location_internal() since GTK 4.0.
-+     */
-     if (ibusimcontext->cursor_area.x == area->x &&
-         ibusimcontext->cursor_area.y == area->y &&
-         ibusimcontext->cursor_area.width == area->width &&
-         ibusimcontext->cursor_area.height == area->height) {
-         return;
-     }
-+#endif
-     ibusimcontext->cursor_area = *area;
-     _set_cursor_location_internal (ibusimcontext);
-     gtk_im_context_set_cursor_location (ibusimcontext->slave, area);
--- 
-2.28.0
-
 From 943d37444d9cc0881cb5fff87bdd4b9efd5abdb4 Mon Sep 17 00:00:00 2001
 From: fujiwarat <takao.fujiwara1@gmail.com>
 Date: Mon, 9 Aug 2021 12:49:15 +0900

             reply	other threads:[~2026-05-31  2:07 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-31  2:07 Takao Fujiwara [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-05-31  2:09 [rpms/ibus] autotool: Delete upstreamed patches Takao Fujiwara
2026-05-31  2:09 Takao Fujiwara
2026-05-31  2:09 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:08 [rpms/ibus] autotool: Delete Upstreamed patches Takao Fujiwara
2026-05-31  2:08 [rpms/ibus] autotool: Delete upstreamed patches Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:07 Takao Fujiwara
2026-05-31  2:07 Takao Fujiwara
2026-05-31  2:07 Takao Fujiwara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178019326059.1.17452965003865725176.rpms-ibus-9fc0c9da0a16@fedoraproject.org \
    --to=tfujiwar@redhat.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox