8626 lines
312 KiB
Diff
8626 lines
312 KiB
Diff
From bfe57d20e9d39d52428e95e493d9af0bd034a82f Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 15 Jan 2018 14:44:07 +0900
|
|
Subject: [PATCH] Added DBus filtering against malware
|
|
|
|
The proposal prevents non-ower of the GDBusConnection from accessing
|
|
DBus methods against malicious usages.
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/1955
|
|
|
|
Review URL: https://codereview.appspot.com/335380043
|
|
---
|
|
bus/inputcontext.c | 24 +++++++++++++++++++++++-
|
|
src/ibusengine.c | 18 +++++++++++++++++-
|
|
src/ibuspanelservice.c | 14 +++++++++++++-
|
|
3 files changed, 53 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
|
|
index d8be9e3f..4f2ecafc 100644
|
|
--- a/bus/inputcontext.c
|
|
+++ b/bus/inputcontext.c
|
|
@@ -2,7 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2008-2016 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -1148,6 +1148,20 @@ _ic_set_surrounding_text (BusInputContext *context,
|
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
|
}
|
|
|
|
+/*
|
|
+ * Since IBusService is inherited by IBusImpl, this method cannot be
|
|
+ * applied to IBusServiceClass.method_call() directly but can be in
|
|
+ * each child class.method_call().
|
|
+ */
|
|
+static gboolean
|
|
+bus_input_context_service_authorized_method (IBusService *service,
|
|
+ GDBusConnection *connection)
|
|
+{
|
|
+ if (ibus_service_get_connection (service) == connection)
|
|
+ return TRUE;
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
/**
|
|
* bus_input_context_service_method_call:
|
|
*
|
|
@@ -1197,6 +1211,10 @@ bus_input_context_service_method_call (IBusService *service,
|
|
};
|
|
|
|
gint i;
|
|
+
|
|
+ if (!bus_input_context_service_authorized_method (service, connection))
|
|
+ return;
|
|
+
|
|
for (i = 0; i < G_N_ELEMENTS (methods); i++) {
|
|
if (g_strcmp0 (method_name, methods[i].method_name) == 0) {
|
|
methods[i].method_callback ((BusInputContext *)service, parameters, invocation);
|
|
@@ -1270,6 +1288,9 @@ bus_input_context_service_set_property (IBusService *service,
|
|
error);
|
|
}
|
|
|
|
+ if (!bus_input_context_service_authorized_method (service, connection))
|
|
+ return FALSE;
|
|
+
|
|
if (g_strcmp0 (property_name, "ContentType") == 0) {
|
|
BusInputContext *context = (BusInputContext *) service;
|
|
_ic_set_content_type (context, value);
|
|
@@ -1279,6 +1300,7 @@ bus_input_context_service_set_property (IBusService *service,
|
|
g_return_val_if_reached (FALSE);
|
|
}
|
|
|
|
+
|
|
gboolean
|
|
bus_input_context_has_focus (BusInputContext *context)
|
|
{
|
|
diff --git a/src/ibusengine.c b/src/ibusengine.c
|
|
index b2a8022a..da648d11 100644
|
|
--- a/src/ibusengine.c
|
|
+++ b/src/ibusengine.c
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2013 Red Hat, Inc.
|
|
+ * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -851,6 +852,15 @@ ibus_engine_get_property (IBusEngine *engine,
|
|
}
|
|
}
|
|
|
|
+static gboolean
|
|
+ibus_engine_service_authorized_method (IBusService *service,
|
|
+ GDBusConnection *connection)
|
|
+{
|
|
+ if (ibus_service_get_connection (service) == connection)
|
|
+ return TRUE;
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static void
|
|
ibus_engine_service_method_call (IBusService *service,
|
|
GDBusConnection *connection,
|
|
@@ -876,6 +886,9 @@ ibus_engine_service_method_call (IBusService *service,
|
|
return;
|
|
}
|
|
|
|
+ if (!ibus_engine_service_authorized_method (service, connection))
|
|
+ return;
|
|
+
|
|
if (g_strcmp0 (method_name, "ProcessKeyEvent") == 0) {
|
|
guint keyval, keycode, state;
|
|
gboolean retval = FALSE;
|
|
@@ -1085,6 +1098,9 @@ ibus_engine_service_set_property (IBusService *service,
|
|
error);
|
|
}
|
|
|
|
+ if (!ibus_engine_service_authorized_method (service, connection))
|
|
+ return FALSE;
|
|
+
|
|
if (g_strcmp0 (property_name, "ContentType") == 0) {
|
|
guint purpose = 0;
|
|
guint hints = 0;
|
|
diff --git a/src/ibuspanelservice.c b/src/ibuspanelservice.c
|
|
index 468aa324..33949fa1 100644
|
|
--- a/src/ibuspanelservice.c
|
|
+++ b/src/ibuspanelservice.c
|
|
@@ -3,7 +3,7 @@
|
|
/* ibus - The Input Bus
|
|
* Copyright (c) 2009-2014 Google Inc. All rights reserved.
|
|
* Copyright (C) 2010-2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2017-2018 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
|
|
@@ -936,6 +936,15 @@ _g_object_unref_if_floating (gpointer instance)
|
|
g_object_unref (instance);
|
|
}
|
|
|
|
+static gboolean
|
|
+ibus_panel_service_service_authorized_method (IBusService *service,
|
|
+ GDBusConnection *connection)
|
|
+{
|
|
+ if (ibus_service_get_connection (service) == connection)
|
|
+ return TRUE;
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static void
|
|
ibus_panel_service_service_method_call (IBusService *service,
|
|
GDBusConnection *connection,
|
|
@@ -961,6 +970,9 @@ ibus_panel_service_service_method_call (IBusService *service,
|
|
return;
|
|
}
|
|
|
|
+ if (!ibus_panel_service_service_authorized_method (service, connection))
|
|
+ return;
|
|
+
|
|
if (g_strcmp0 (method_name, "UpdatePreeditText") == 0) {
|
|
GVariant *variant = NULL;
|
|
guint cursor = 0;
|
|
--
|
|
2.14.3
|
|
|
|
From e17c99859d06ab75326730e45072e1061f7d87c7 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 29 Jan 2018 16:50:07 +0900
|
|
Subject: [PATCH] Implement Unicode choice on Emojier
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/1922
|
|
|
|
Review URL: https://codereview.appspot.com/340190043
|
|
---
|
|
configure.ac | 41 +-
|
|
po/POTFILES.in | 1 +
|
|
src/Makefile.am | 55 ++-
|
|
src/emoji-parser.c | 3 +-
|
|
src/ibus.h | 4 +-
|
|
src/ibusunicode.c | 1069 +++++++++++++++++++++++++++++++++++++++++
|
|
src/ibusunicode.h | 299 ++++++++++++
|
|
src/ibusunicodegen.h | 1151 +++++++++++++++++++++++++++++++++++++++++++++
|
|
src/unicode-parser.c | 502 ++++++++++++++++++++
|
|
ui/gtk3/emojier.vala | 550 +++++++++++++++++++---
|
|
ui/gtk3/emojierapp.vala | 2 +
|
|
ui/gtk3/ibusemojidialog.h | 9 +-
|
|
ui/gtk3/panel.vala | 3 +-
|
|
13 files changed, 3613 insertions(+), 76 deletions(-)
|
|
create mode 100644 src/ibusunicode.c
|
|
create mode 100644 src/ibusunicode.h
|
|
create mode 100644 src/ibusunicodegen.h
|
|
create mode 100644 src/unicode-parser.c
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 4789328e..bd41069b 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -3,8 +3,8 @@
|
|
# ibus - The Input Bus
|
|
#
|
|
# Copyright (c) 2007-2016 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
-# Copyright (c) 2007-2017 Red Hat, Inc.
|
|
+# Copyright (c) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2007-2018 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
|
|
@@ -653,6 +653,41 @@ https://github.com/fujiwarat/cldr-emoji-annotation)
|
|
enable_emoji_dict="yes (enabled, use --disable-emoji-dict to disable)"
|
|
fi
|
|
|
|
+# --disable-unicode-dict option.
|
|
+AC_ARG_ENABLE(unicode-dict,
|
|
+ AS_HELP_STRING([--disable-unicode-dict],
|
|
+ [Do not build Unicode dict files]),
|
|
+ [enable_unicode_dict=$enableval],
|
|
+ [enable_unicode_dict=yes]
|
|
+)
|
|
+AM_CONDITIONAL([ENABLE_UNICODE_DICT], [test x"$enable_unicode_dict" = x"yes"])
|
|
+
|
|
+AC_ARG_WITH(ucd-dir,
|
|
+ AS_HELP_STRING([--with-ucd-dir[=DIR]],
|
|
+ [Set the directory of UCD (Unicode Character Database) files.
|
|
+ (default: "/usr/share/unicode/ucd")]),
|
|
+ UCD_DIR=$with_emoji_annotation_dir,
|
|
+ UCD_DIR="/usr/share/unicode/ucd"
|
|
+)
|
|
+AC_SUBST(UCD_DIR)
|
|
+
|
|
+if test x"$enable_unicode_dict" = x"yes"; then
|
|
+ if test ! -f $UCD_DIR/NamesList.txt ; then
|
|
+ AC_MSG_ERROR(Not found $UCD_DIR/NamesList.txt. You can get \
|
|
+the UCD files from https://www.unicode.org/Public/UNIDATA/)
|
|
+ elif test ! -f $UCD_DIR/Blocks.txt ; then
|
|
+ AC_MSG_ERROR(Not found $UCD_DIR/Blocks.txt. You can get \
|
|
+the UCD files from https://www.unicode.org/Public/UNIDATA/)
|
|
+ else
|
|
+ # POSIX SHELL has no ${FOO:0:1}
|
|
+ head=`echo "$UCD_DIR" | cut -c1`;
|
|
+ if test $head != "/" ; then
|
|
+ UCD_DIR=`realpath "$UCD_DIR"`
|
|
+ fi
|
|
+ fi
|
|
+ enable_unicode_dict="yes (enabled, use --disable-unicode-dict to disable)"
|
|
+fi
|
|
+
|
|
# Check iso-codes.
|
|
PKG_CHECK_MODULES(ISOCODES, [
|
|
iso-codes
|
|
@@ -743,6 +778,8 @@ Build options:
|
|
Enable Emoji dict $enable_emoji_dict
|
|
Unicode Emoji directory $UNICODE_EMOJI_DIR
|
|
CLDR annotation directory $EMOJI_ANNOTATION_DIR
|
|
+ Enable Unicode dict $enable_unicode_dict
|
|
+ UCD directory $UCD_DIR
|
|
Run test cases $enable_tests
|
|
])
|
|
|
|
diff --git a/po/POTFILES.in b/po/POTFILES.in
|
|
index 00f7c7f6..58d1e39d 100644
|
|
--- a/po/POTFILES.in
|
|
+++ b/po/POTFILES.in
|
|
@@ -51,6 +51,7 @@ src/ibuspanelservice.c
|
|
src/ibusproxy.c
|
|
src/ibusregistry.c
|
|
src/ibusservice.c
|
|
+src/ibusunicodegen.h
|
|
src/ibusutil.c
|
|
src/keyname-table.h
|
|
tools/main.vala
|
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
index 303250f5..1ba418d8 100644
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -41,6 +41,7 @@ INTROSPECTION_COMPILER_ARGS = \
|
|
$(NULL)
|
|
INTROSPECTION_GIRS =
|
|
CLEANFILES =
|
|
+noinst_PROGRAMS =
|
|
|
|
# C preprocessor flags
|
|
AM_CPPFLAGS = \
|
|
@@ -100,6 +101,7 @@ ibus_sources = \
|
|
ibusservice.c \
|
|
ibusshare.c \
|
|
ibustext.c \
|
|
+ ibusunicode.c \
|
|
ibusutil.c \
|
|
ibusxml.c \
|
|
$(NULL)
|
|
@@ -151,6 +153,7 @@ ibus_headers = \
|
|
ibusshare.h \
|
|
ibustext.h \
|
|
ibustypes.h \
|
|
+ ibusunicode.h \
|
|
ibusutil.h \
|
|
ibusxml.h \
|
|
$(NULL)
|
|
@@ -169,6 +172,7 @@ ibus_private_headers = \
|
|
ibusemojigen.h \
|
|
ibusenginesimpleprivate.h \
|
|
ibusinternal.h \
|
|
+ ibusunicodegen.h \
|
|
keyname-table.h \
|
|
$(NULL)
|
|
noinst_HEADERS = \
|
|
@@ -241,7 +245,7 @@ dictdir = $(pkgdatadir)/dicts
|
|
dict_DATA = dicts/emoji-en.dict
|
|
LANG_FILES = $(basename $(notdir $(wildcard $(EMOJI_ANNOTATION_DIR)/*.xml)))
|
|
|
|
-noinst_PROGRAMS = emoji-parser
|
|
+noinst_PROGRAMS += emoji-parser
|
|
|
|
dicts/emoji-en.dict: emoji-parser
|
|
$(AM_V_at)if test x"$(LANG_FILES)" = x ; then \
|
|
@@ -325,12 +329,60 @@ clean-local:
|
|
$(NULL)
|
|
endif
|
|
|
|
+if ENABLE_UNICODE_DICT
|
|
+unicodedir = $(pkgdatadir)/dicts
|
|
+unicode_DATA = dicts/unicode-names.dict dicts/unicode-blocks.dict
|
|
+noinst_PROGRAMS += unicode-parser
|
|
+
|
|
+dicts/unicode-names.dict: unicode-parser
|
|
+ $(AM_V_at)input_file="$(UCD_DIR)/NamesList.txt"; \
|
|
+ if test ! -f "$$input_file" ; then \
|
|
+ echo "WARNING: Not found $$input_file" 1>&2; \
|
|
+ else \
|
|
+ $(builddir)/unicode-parser \
|
|
+ --input-names-list $$input_file \
|
|
+ --output-names-list $@; \
|
|
+ echo "Generated $@"; \
|
|
+ fi;
|
|
+
|
|
+dicts/unicode-blocks.dict: unicode-parser
|
|
+ $(AM_V_at)input_file="$(UCD_DIR)/Blocks.txt"; \
|
|
+ if test ! -f "$$input_file" ; then \
|
|
+ echo "WARNING: Not found $$input_file" 1>&2; \
|
|
+ else \
|
|
+ $(builddir)/unicode-parser \
|
|
+ --input-blocks $$input_file \
|
|
+ --output-blocks-trans ibusunicodegen.h \
|
|
+ --output-blocks $@; \
|
|
+ echo "Generated $@"; \
|
|
+ fi;
|
|
+
|
|
+ibusunicodegen.h: dicts/unicode-blocks.dict
|
|
+ $(NULL)
|
|
+
|
|
+unicode_parser_SOURCES = \
|
|
+ unicode-parser.c \
|
|
+ $(NULL)
|
|
+unicode_parser_CFLAGS = \
|
|
+ $(GLIB2_CFLAGS) \
|
|
+ $(NULL)
|
|
+unicode_parser_LDADD = \
|
|
+ $(GLIB2_LIBS) \
|
|
+ $(libibus) \
|
|
+ $(NULL)
|
|
+
|
|
+clean-local:
|
|
+ -rm -rf dicts
|
|
+ $(NULL)
|
|
+endif
|
|
+
|
|
EXTRA_DIST = \
|
|
emoji-parser.c \
|
|
ibusversion.h.in \
|
|
ibusmarshalers.list \
|
|
ibusenumtypes.h.template \
|
|
ibusenumtypes.c.template \
|
|
+ unicode-parser.c \
|
|
$(NULL)
|
|
|
|
CLEANFILES += \
|
|
@@ -341,6 +393,7 @@ CLEANFILES += \
|
|
|
|
DISTCLEANFILES = \
|
|
ibusemojigen.h \
|
|
+ ibusunicodegen.h \
|
|
ibusversion.h \
|
|
$(NULL)
|
|
|
|
diff --git a/src/emoji-parser.c b/src/emoji-parser.c
|
|
index fe3e4ef8..0f7c8cfb 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-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2016-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2016 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -1126,6 +1126,7 @@ category_file_save (const gchar *filename,
|
|
if (!g_file_get_contents (__FILE__, &content, &length, &error)) {
|
|
g_warning ("Failed to load %s: %s", __FILE__, error->message);
|
|
g_clear_pointer (&error, g_error_free);
|
|
+ return;
|
|
}
|
|
buff = g_string_new (NULL);
|
|
p = content;
|
|
diff --git a/src/ibus.h b/src/ibus.h
|
|
index c6cf58cf..8011729f 100644
|
|
--- a/src/ibus.h
|
|
+++ b/src/ibus.h
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2013 Red Hat, Inc.
|
|
+ * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -57,6 +58,7 @@
|
|
#include <ibusutil.h>
|
|
#include <ibusregistry.h>
|
|
#include <ibusemoji.h>
|
|
+#include <ibusunicode.h>
|
|
|
|
#ifndef IBUS_DISABLE_DEPRECATED
|
|
#include <ibuskeysyms-compat.h>
|
|
diff --git a/src/ibusunicode.c b/src/ibusunicode.c
|
|
new file mode 100644
|
|
index 00000000..8559819d
|
|
--- /dev/null
|
|
+++ b/src/ibusunicode.c
|
|
@@ -0,0 +1,1069 @@
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
+/* vim:set et sts=4: */
|
|
+/* bus - The Input Bus
|
|
+ * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2018 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
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+#ifdef HAVE_CONFIG_H
|
|
+#include <config.h>
|
|
+#endif
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib/gstdio.h>
|
|
+#include "ibusinternal.h"
|
|
+#include "ibuserror.h"
|
|
+#include "ibusunicode.h"
|
|
+
|
|
+#define IBUS_UNICODE_DATA_MAGIC "IBusUnicodeData"
|
|
+#define IBUS_UNICODE_BLOCK_MAGIC "IBusUnicodeBlock"
|
|
+#define IBUS_UNICODE_DATA_VERSION (1)
|
|
+#define IBUS_UNICODE_DESERIALIZE_SIGNALL_STR \
|
|
+ "deserialize-unicode"
|
|
+
|
|
+enum {
|
|
+ PROP_0 = 0,
|
|
+ PROP_CODE,
|
|
+ PROP_NAME,
|
|
+ PROP_ALIAS,
|
|
+ PROP_BLOCK_NAME,
|
|
+ PROP_START,
|
|
+ PROP_END
|
|
+};
|
|
+
|
|
+struct _IBusUnicodeDataPrivate {
|
|
+ gunichar code;
|
|
+ gchar *name;
|
|
+ gchar *alias;
|
|
+ gchar *block_name;
|
|
+};
|
|
+
|
|
+struct _IBusUnicodeBlockPrivate {
|
|
+ gunichar start;
|
|
+ gunichar end;
|
|
+ gchar *name;
|
|
+};
|
|
+
|
|
+typedef struct {
|
|
+ IBusUnicodeDataLoadAsyncFinish callback;
|
|
+ gpointer user_data;
|
|
+} IBusUnicodeDataLoadData;
|
|
+
|
|
+#define IBUS_UNICODE_DATA_GET_PRIVATE(o) \
|
|
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
|
+ IBUS_TYPE_UNICODE_DATA, \
|
|
+ IBusUnicodeDataPrivate))
|
|
+#define IBUS_UNICODE_BLOCK_GET_PRIVATE(o) \
|
|
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
|
+ IBUS_TYPE_UNICODE_BLOCK, \
|
|
+ IBusUnicodeBlockPrivate))
|
|
+
|
|
+/* functions prototype */
|
|
+static void ibus_unicode_data_set_property (IBusUnicodeData *unicode,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void ibus_unicode_data_get_property (IBusUnicodeData *unicode,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void ibus_unicode_data_destroy (IBusUnicodeData *unicode);
|
|
+static gboolean ibus_unicode_data_serialize (IBusUnicodeData *unicode,
|
|
+ GVariantBuilder *builder);
|
|
+static gint ibus_unicode_data_deserialize (IBusUnicodeData *unicode,
|
|
+ GVariant *variant);
|
|
+static gboolean ibus_unicode_data_copy (IBusUnicodeData *dest,
|
|
+ const IBusUnicodeData *src);
|
|
+static void ibus_unicode_block_set_property
|
|
+ (IBusUnicodeBlock *block,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void ibus_unicode_block_get_property
|
|
+ (IBusUnicodeBlock *block,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void ibus_unicode_block_destroy (IBusUnicodeBlock *block);
|
|
+static gboolean ibus_unicode_block_serialize (IBusUnicodeBlock *block,
|
|
+ GVariantBuilder *builder);
|
|
+static gint ibus_unicode_block_deserialize (IBusUnicodeBlock *block,
|
|
+ GVariant *variant);
|
|
+static gboolean ibus_unicode_block_copy (IBusUnicodeBlock *dest,
|
|
+ const IBusUnicodeBlock *src);
|
|
+
|
|
+G_DEFINE_TYPE (IBusUnicodeData, ibus_unicode_data, IBUS_TYPE_SERIALIZABLE)
|
|
+G_DEFINE_TYPE (IBusUnicodeBlock, ibus_unicode_block, IBUS_TYPE_SERIALIZABLE)
|
|
+
|
|
+static void
|
|
+ibus_unicode_data_class_init (IBusUnicodeDataClass *class)
|
|
+{
|
|
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
|
|
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
|
|
+
|
|
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_unicode_data_destroy;
|
|
+ gobject_class->set_property =
|
|
+ (GObjectSetPropertyFunc) ibus_unicode_data_set_property;
|
|
+ gobject_class->get_property =
|
|
+ (GObjectGetPropertyFunc) ibus_unicode_data_get_property;
|
|
+ serializable_class->serialize =
|
|
+ (IBusSerializableSerializeFunc) ibus_unicode_data_serialize;
|
|
+ serializable_class->deserialize =
|
|
+ (IBusSerializableDeserializeFunc) ibus_unicode_data_deserialize;
|
|
+ serializable_class->copy =
|
|
+ (IBusSerializableCopyFunc) ibus_unicode_data_copy;
|
|
+
|
|
+ g_type_class_add_private (class, sizeof (IBusUnicodeDataPrivate));
|
|
+
|
|
+ /* install properties */
|
|
+ /**
|
|
+ * IBusUnicodeData:code:
|
|
+ *
|
|
+ * The Uniode code point
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_CODE,
|
|
+ g_param_spec_unichar ("code",
|
|
+ "code point",
|
|
+ "The Unicode code point",
|
|
+ 0,
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+
|
|
+ /**
|
|
+ * IBusUnicodeData:name:
|
|
+ *
|
|
+ * The Uniode name
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_NAME,
|
|
+ g_param_spec_string ("name",
|
|
+ "name",
|
|
+ "The Unicode name",
|
|
+ "",
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
|
+
|
|
+ /**
|
|
+ * IBusUnicodeData:alias:
|
|
+ *
|
|
+ * The Uniode alias name
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_ALIAS,
|
|
+ g_param_spec_string ("alias",
|
|
+ "alias name",
|
|
+ "The Unicode alias name",
|
|
+ "",
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
|
+
|
|
+ /**
|
|
+ * IBusUnicodeData:block-name:
|
|
+ *
|
|
+ * The Uniode block name
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_BLOCK_NAME,
|
|
+ g_param_spec_string ("block-name",
|
|
+ "block name",
|
|
+ "The Unicode block name",
|
|
+ "",
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_data_init (IBusUnicodeData *unicode)
|
|
+{
|
|
+ unicode->priv = IBUS_UNICODE_DATA_GET_PRIVATE (unicode);
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_data_destroy (IBusUnicodeData *unicode)
|
|
+{
|
|
+ g_clear_pointer (&unicode->priv->name, g_free);
|
|
+ g_clear_pointer (&unicode->priv->alias, g_free);
|
|
+ g_clear_pointer (&unicode->priv->block_name, g_free);
|
|
+
|
|
+ IBUS_OBJECT_CLASS (ibus_unicode_data_parent_class)->
|
|
+ destroy (IBUS_OBJECT (unicode));
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_data_set_property (IBusUnicodeData *unicode,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ switch (prop_id) {
|
|
+ case PROP_CODE:
|
|
+ g_assert (unicode->priv->code == 0);
|
|
+ unicode->priv->code = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_NAME:
|
|
+ g_assert (unicode->priv->name == NULL);
|
|
+ unicode->priv->name = g_value_dup_string (value);
|
|
+ break;
|
|
+ case PROP_ALIAS:
|
|
+ g_assert (unicode->priv->alias == NULL);
|
|
+ unicode->priv->alias = g_value_dup_string (value);
|
|
+ break;
|
|
+ case PROP_BLOCK_NAME:
|
|
+ g_free (unicode->priv->block_name);
|
|
+ unicode->priv->block_name = g_value_dup_string (value);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (unicode, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_data_get_property (IBusUnicodeData *unicode,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ switch (prop_id) {
|
|
+ case PROP_CODE:
|
|
+ g_value_set_uint (value, ibus_unicode_data_get_code (unicode));
|
|
+ break;
|
|
+ case PROP_NAME:
|
|
+ g_value_set_string (value, ibus_unicode_data_get_name (unicode));
|
|
+ break;
|
|
+ case PROP_ALIAS:
|
|
+ g_value_set_string (value, ibus_unicode_data_get_alias (unicode));
|
|
+ break;
|
|
+ case PROP_BLOCK_NAME:
|
|
+ g_value_set_string (value, ibus_unicode_data_get_block_name (unicode));
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (unicode, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ibus_unicode_data_serialize (IBusUnicodeData *unicode,
|
|
+ GVariantBuilder *builder)
|
|
+{
|
|
+ gboolean retval = IBUS_SERIALIZABLE_CLASS (ibus_unicode_data_parent_class)->
|
|
+ serialize ((IBusSerializable *)unicode, builder);
|
|
+ g_return_val_if_fail (retval, FALSE);
|
|
+
|
|
+#define NOTNULL(s) ((s) != NULL ? (s) : "")
|
|
+ /* If you will add a new property, you can append it at the end and
|
|
+ * you should not change the serialized order of name, longname,
|
|
+ * description, ... because the order is also used in other applications
|
|
+ * likes ibus-qt. */
|
|
+ g_variant_builder_add (builder, "u", unicode->priv->code);
|
|
+ g_variant_builder_add (builder, "s", NOTNULL (unicode->priv->name));
|
|
+ g_variant_builder_add (builder, "s", NOTNULL (unicode->priv->alias));
|
|
+ /* Use IBusUnicodeBlock for memory usage.
|
|
+ g_variant_builder_add (builder, "s", NOTNULL (unicode->priv->block_name));
|
|
+ */
|
|
+#undef NOTNULL
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gint
|
|
+ibus_unicode_data_deserialize (IBusUnicodeData *unicode,
|
|
+ GVariant *variant)
|
|
+{
|
|
+ gint retval = IBUS_SERIALIZABLE_CLASS (ibus_unicode_data_parent_class)->
|
|
+ deserialize ((IBusSerializable *)unicode, variant);
|
|
+ g_return_val_if_fail (retval, 0);
|
|
+
|
|
+ /* If you will add a new property, you can append it at the end and
|
|
+ * you should not change the serialized order of name, longname,
|
|
+ * description, ... because the order is also used in other applications
|
|
+ * likes ibus-qt. */
|
|
+ g_variant_get_child (variant, retval++, "u", &unicode->priv->code);
|
|
+ ibus_g_variant_get_child_string (variant, retval++,
|
|
+ &unicode->priv->name);
|
|
+ ibus_g_variant_get_child_string (variant, retval++,
|
|
+ &unicode->priv->alias);
|
|
+ /* Use IBusUnicodeBlock for memory usage.
|
|
+ ibus_g_variant_get_child_string (variant, retval++,
|
|
+ &unicode->priv->block_name);
|
|
+ */
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ibus_unicode_data_copy (IBusUnicodeData *dest,
|
|
+ const IBusUnicodeData *src)
|
|
+{
|
|
+ gboolean retval = IBUS_SERIALIZABLE_CLASS (ibus_unicode_data_parent_class)->
|
|
+ copy ((IBusSerializable *)dest,
|
|
+ (IBusSerializable *)src);
|
|
+ g_return_val_if_fail (retval, FALSE);
|
|
+
|
|
+ dest->priv->code = src->priv->code;
|
|
+ dest->priv->name = g_strdup (src->priv->name);
|
|
+ dest->priv->alias = g_strdup (src->priv->alias);
|
|
+ dest->priv->block_name = g_strdup (src->priv->block_name);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+IBusUnicodeData *
|
|
+ibus_unicode_data_new (const gchar *first_property_name, ...)
|
|
+{
|
|
+ va_list var_args;
|
|
+ IBusUnicodeData *unicode;
|
|
+
|
|
+ g_assert (first_property_name != NULL);
|
|
+ va_start (var_args, first_property_name);
|
|
+ unicode = (IBusUnicodeData *) g_object_new_valist (IBUS_TYPE_UNICODE_DATA,
|
|
+ first_property_name,
|
|
+ var_args);
|
|
+ va_end (var_args);
|
|
+ /* code is required. Other properties are set in class_init by default. */
|
|
+ g_assert (unicode->priv->name != NULL);
|
|
+ g_assert (unicode->priv->alias != NULL);
|
|
+ g_assert (unicode->priv->block_name != NULL);
|
|
+ return unicode;
|
|
+}
|
|
+
|
|
+gunichar
|
|
+ibus_unicode_data_get_code (IBusUnicodeData *unicode)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_UNICODE_DATA (unicode), G_MAXUINT32);
|
|
+
|
|
+ return unicode->priv->code;
|
|
+}
|
|
+
|
|
+const gchar *
|
|
+ibus_unicode_data_get_name (IBusUnicodeData *unicode)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_UNICODE_DATA (unicode), "");
|
|
+
|
|
+ return unicode->priv->name;
|
|
+}
|
|
+
|
|
+const gchar *
|
|
+ibus_unicode_data_get_alias (IBusUnicodeData *unicode)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_UNICODE_DATA (unicode), "");
|
|
+
|
|
+ return unicode->priv->alias;
|
|
+}
|
|
+
|
|
+const gchar *
|
|
+ibus_unicode_data_get_block_name (IBusUnicodeData *unicode)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_UNICODE_DATA (unicode), "");
|
|
+
|
|
+ return unicode->priv->block_name;
|
|
+}
|
|
+
|
|
+void
|
|
+ibus_unicode_data_set_block_name (IBusUnicodeData *unicode,
|
|
+ const gchar *block_name)
|
|
+{
|
|
+ g_return_if_fail (IBUS_IS_UNICODE_DATA (unicode));
|
|
+
|
|
+ g_free (unicode->priv->block_name);
|
|
+ unicode->priv->block_name = g_strdup (block_name);
|
|
+}
|
|
+
|
|
+static void
|
|
+variant_foreach_add_unicode (IBusUnicodeData *unicode,
|
|
+ GVariantBuilder *builder)
|
|
+{
|
|
+ g_variant_builder_add (
|
|
+ builder, "v",
|
|
+ ibus_serializable_serialize (IBUS_SERIALIZABLE (unicode)));
|
|
+}
|
|
+
|
|
+static GVariant *
|
|
+ibus_unicode_data_list_serialize (GSList *list)
|
|
+{
|
|
+ GVariantBuilder builder;
|
|
+
|
|
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("av"));
|
|
+ g_slist_foreach (list, (GFunc) variant_foreach_add_unicode, &builder);
|
|
+ return g_variant_builder_end (&builder);
|
|
+}
|
|
+
|
|
+static GSList *
|
|
+ibus_unicode_data_list_deserialize (GVariant *variant,
|
|
+ GObject *source_object)
|
|
+{
|
|
+ GSList *list = NULL;
|
|
+ GVariantIter iter;
|
|
+ GVariant *unicode_variant = NULL;
|
|
+ gsize i, size;
|
|
+ gboolean has_signal = FALSE;
|
|
+
|
|
+ if (G_IS_OBJECT (source_object)) {
|
|
+ has_signal = g_signal_lookup (
|
|
+ IBUS_UNICODE_DESERIALIZE_SIGNALL_STR,
|
|
+ G_OBJECT_TYPE (source_object));
|
|
+ if (!has_signal) {
|
|
+ const gchar type_name = g_type_name (source_object);
|
|
+ g_warning ("GObject %s does not have the signal \"%s\"",
|
|
+ type_name ? type_name : "(null)",
|
|
+ IBUS_UNICODE_DESERIALIZE_SIGNALL_STR);
|
|
+ }
|
|
+ }
|
|
+ g_variant_iter_init (&iter, variant);
|
|
+ size = g_variant_iter_n_children (&iter);
|
|
+ i = 0;
|
|
+ while (g_variant_iter_loop (&iter, "v", &unicode_variant)) {
|
|
+ IBusUnicodeData *data =
|
|
+ IBUS_UNICODE_DATA (ibus_serializable_deserialize (
|
|
+ unicode_variant));
|
|
+ list = g_slist_append (list, data);
|
|
+ g_clear_pointer (&unicode_variant, g_variant_unref);
|
|
+ if (has_signal && (i == 0 || ((i + 1) % 100) == 0)) {
|
|
+ g_signal_emit_by_name (source_object,
|
|
+ IBUS_UNICODE_DESERIALIZE_SIGNALL_STR,
|
|
+ i + 1, size);
|
|
+ }
|
|
+ i++;
|
|
+ }
|
|
+ if (has_signal && (i != 1 && (i % 100) != 0)) {
|
|
+ g_signal_emit_by_name (source_object,
|
|
+ IBUS_UNICODE_DESERIALIZE_SIGNALL_STR,
|
|
+ i, size);
|
|
+ }
|
|
+
|
|
+ return list;
|
|
+}
|
|
+
|
|
+void
|
|
+ibus_unicode_data_save (const gchar *path,
|
|
+ GSList *list)
|
|
+{
|
|
+ GVariant *variant;
|
|
+ const gchar *header = IBUS_UNICODE_DATA_MAGIC;
|
|
+ const guint16 version = IBUS_UNICODE_DATA_VERSION;
|
|
+ const gchar *contents;
|
|
+ gsize length;
|
|
+ gchar *dir;
|
|
+ GStatBuf buf = { 0, };
|
|
+ GError *error = NULL;
|
|
+
|
|
+ g_return_if_fail (path != NULL);
|
|
+ g_return_if_fail (list != NULL);
|
|
+ if (list->data == NULL) {
|
|
+ g_warning ("Failed to save IBus Unicode data: Need a list data.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ variant = g_variant_new ("(sqv)",
|
|
+ header,
|
|
+ version,
|
|
+ ibus_unicode_data_list_serialize (list));
|
|
+
|
|
+ contents = g_variant_get_data (variant);
|
|
+ length = g_variant_get_size (variant);
|
|
+
|
|
+ dir = g_path_get_dirname (path);
|
|
+ if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) {
|
|
+ g_mkdir_with_parents (dir, 0777);
|
|
+ }
|
|
+ g_free (dir);
|
|
+ if (!g_file_set_contents (path, contents, length, &error)) {
|
|
+ g_warning ("Failed to save Unicode dict %s: %s", path, error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+
|
|
+ g_variant_unref (variant);
|
|
+}
|
|
+
|
|
+static GSList *
|
|
+ibus_unicode_data_load_with_error (const gchar *path,
|
|
+ GObject *source_object,
|
|
+ GError **error)
|
|
+{
|
|
+ gchar *contents = NULL;
|
|
+ gsize length = 0;
|
|
+ GVariant *variant_table = NULL;
|
|
+ GVariant *variant = NULL;
|
|
+ const gchar *header = NULL;
|
|
+ guint16 version = 0;
|
|
+ GSList *retval = NULL;
|
|
+
|
|
+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
|
|
+ g_set_error (error,
|
|
+ IBUS_ERROR,
|
|
+ IBUS_ERROR_FAILED,
|
|
+ "Unicode dict does not exist: %s", path);
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ if (!g_file_get_contents (path, &contents, &length, error)) {
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ variant_table = g_variant_new_from_data (G_VARIANT_TYPE ("(sq)"),
|
|
+ contents,
|
|
+ length,
|
|
+ FALSE,
|
|
+ NULL,
|
|
+ NULL);
|
|
+
|
|
+ if (variant_table == NULL) {
|
|
+ g_set_error (error,
|
|
+ IBUS_ERROR,
|
|
+ IBUS_ERROR_FAILED,
|
|
+ "cache table is broken.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ g_variant_get (variant_table, "(&sq)", &header, &version);
|
|
+
|
|
+ if (g_strcmp0 (header, IBUS_UNICODE_DATA_MAGIC) != 0) {
|
|
+ g_set_error (error,
|
|
+ IBUS_ERROR,
|
|
+ IBUS_ERROR_FAILED,
|
|
+ "cache is not IBusUnicodeData.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ if (version > IBUS_UNICODE_DATA_VERSION) {
|
|
+ g_set_error (error,
|
|
+ IBUS_ERROR,
|
|
+ IBUS_ERROR_FAILED,
|
|
+ "cache version is different: %u != %u",
|
|
+ version, IBUS_UNICODE_DATA_VERSION);
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ version = 0;
|
|
+ header = NULL;
|
|
+ g_variant_unref (variant_table);
|
|
+
|
|
+ variant_table = g_variant_new_from_data (G_VARIANT_TYPE ("(sqv)"),
|
|
+ contents,
|
|
+ length,
|
|
+ FALSE,
|
|
+ NULL,
|
|
+ NULL);
|
|
+
|
|
+ if (variant_table == NULL) {
|
|
+ g_set_error (error,
|
|
+ IBUS_ERROR,
|
|
+ IBUS_ERROR_FAILED,
|
|
+ "cache table is broken.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ g_variant_get (variant_table, "(&sqv)",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ &variant);
|
|
+
|
|
+ if (variant == NULL) {
|
|
+ g_set_error (error,
|
|
+ IBUS_ERROR,
|
|
+ IBUS_ERROR_FAILED,
|
|
+ "cache dict is broken.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ retval = ibus_unicode_data_list_deserialize (variant, source_object);
|
|
+
|
|
+out_load_cache:
|
|
+ if (variant)
|
|
+ g_variant_unref (variant);
|
|
+ if (variant_table)
|
|
+ g_variant_unref (variant_table);
|
|
+ g_free (contents);
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+GSList *
|
|
+ibus_unicode_data_load (const gchar *path,
|
|
+ GObject *source_object)
|
|
+{
|
|
+ GError *error = NULL;
|
|
+ GSList *retval = ibus_unicode_data_load_with_error (path,
|
|
+ source_object,
|
|
+ &error);
|
|
+
|
|
+ if (retval == NULL) {
|
|
+ g_warning ("%s", error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_data_load_async_thread (GTask *task,
|
|
+ gpointer source_object,
|
|
+ gpointer task_data,
|
|
+ GCancellable *cancellable)
|
|
+{
|
|
+ GSList *retval;
|
|
+ gchar *path = (gchar *)task_data;
|
|
+ GError *error = NULL;
|
|
+
|
|
+ g_assert (path != NULL);
|
|
+
|
|
+ retval = ibus_unicode_data_load_with_error (path, source_object, &error);
|
|
+ g_free (path);
|
|
+ if (retval == NULL)
|
|
+ g_task_return_error (task, error);
|
|
+ else
|
|
+ g_task_return_pointer (task, retval, NULL);
|
|
+ g_object_unref (task);
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_data_load_async_done (GObject *source_object,
|
|
+ GAsyncResult *res,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ IBusUnicodeDataLoadData *data = (IBusUnicodeDataLoadData*)user_data;
|
|
+ GSList *list;
|
|
+ GError *error = NULL;
|
|
+ g_assert (data != NULL);
|
|
+ list = g_task_propagate_pointer (G_TASK (res), &error);
|
|
+ if (error) {
|
|
+ g_warning ("%s", error->message);
|
|
+ g_error_free (error);
|
|
+ data->callback (NULL, data->user_data);
|
|
+ } else {
|
|
+ data->callback (list, data->user_data);
|
|
+ }
|
|
+ g_slice_free (IBusUnicodeDataLoadData, data);
|
|
+}
|
|
+
|
|
+void
|
|
+ibus_unicode_data_load_async (const gchar *path,
|
|
+ GObject *source_object,
|
|
+ GCancellable *cancellable,
|
|
+ IBusUnicodeDataLoadAsyncFinish
|
|
+ callback,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ GTask *task;
|
|
+ IBusUnicodeDataLoadData *data;
|
|
+
|
|
+ g_return_if_fail (path != NULL);
|
|
+
|
|
+ data = g_slice_new0 (IBusUnicodeDataLoadData);
|
|
+ data->callback = callback;
|
|
+ data->user_data = user_data;
|
|
+ task = g_task_new (source_object,
|
|
+ cancellable,
|
|
+ ibus_unicode_data_load_async_done,
|
|
+ data);
|
|
+ g_task_set_source_tag (task, ibus_unicode_data_load_async);
|
|
+ g_task_set_task_data (task, g_strdup (path), NULL);
|
|
+ g_task_run_in_thread (task, ibus_unicode_data_load_async_thread);
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_block_class_init (IBusUnicodeBlockClass *class)
|
|
+{
|
|
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
|
|
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
|
|
+
|
|
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_unicode_data_destroy;
|
|
+ gobject_class->set_property =
|
|
+ (GObjectSetPropertyFunc) ibus_unicode_block_set_property;
|
|
+ gobject_class->get_property =
|
|
+ (GObjectGetPropertyFunc) ibus_unicode_block_get_property;
|
|
+ serializable_class->serialize =
|
|
+ (IBusSerializableSerializeFunc) ibus_unicode_block_serialize;
|
|
+ serializable_class->deserialize =
|
|
+ (IBusSerializableDeserializeFunc) ibus_unicode_block_deserialize;
|
|
+ serializable_class->copy =
|
|
+ (IBusSerializableCopyFunc) ibus_unicode_block_copy;
|
|
+
|
|
+ g_type_class_add_private (class, sizeof (IBusUnicodeBlockPrivate));
|
|
+
|
|
+ /* install properties */
|
|
+ /**
|
|
+ * IBusUnicodeBlock:start:
|
|
+ *
|
|
+ * The Uniode start code point
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_START,
|
|
+ /* Cannot use g_param_spec_unichar() for the Unicode
|
|
+ * boundary values because the function checks
|
|
+ * if the value is a valid Unicode besides MAXUINT.
|
|
+ */
|
|
+ g_param_spec_uint ("start",
|
|
+ "start code point",
|
|
+ "The Unicode start code point",
|
|
+ 0,
|
|
+ G_MAXUINT,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+
|
|
+ /**
|
|
+ * IBusUnicodeBlock:end:
|
|
+ *
|
|
+ * The Uniode end code point
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_END,
|
|
+ /* Cannot use g_param_spec_unichar() for the Unicode
|
|
+ * boundary values because the function checks
|
|
+ * if the value is a valid Unicode besides MAXUINT.
|
|
+ */
|
|
+ g_param_spec_uint ("end",
|
|
+ "end code point",
|
|
+ "The Unicode end code point",
|
|
+ 0,
|
|
+ G_MAXUINT,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+
|
|
+ /**
|
|
+ * IBusUnicodeBlock:name:
|
|
+ *
|
|
+ * The Uniode block name
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_NAME,
|
|
+ g_param_spec_string ("name",
|
|
+ "name",
|
|
+ "The Unicode name",
|
|
+ "",
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_block_init (IBusUnicodeBlock *block)
|
|
+{
|
|
+ block->priv = IBUS_UNICODE_BLOCK_GET_PRIVATE (block);
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_block_destroy (IBusUnicodeBlock *block)
|
|
+{
|
|
+ g_clear_pointer (&block->priv->name, g_free);
|
|
+
|
|
+ IBUS_OBJECT_CLASS (ibus_unicode_data_parent_class)->
|
|
+ destroy (IBUS_OBJECT (block));
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_block_set_property (IBusUnicodeBlock *block,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ switch (prop_id) {
|
|
+ case PROP_START:
|
|
+ g_assert (block->priv->start == 0);
|
|
+ block->priv->start = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_END:
|
|
+ g_assert (block->priv->end == 0);
|
|
+ block->priv->end = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_NAME:
|
|
+ g_assert (block->priv->name == NULL);
|
|
+ block->priv->name = g_value_dup_string (value);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (block, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_unicode_block_get_property (IBusUnicodeBlock *block,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ switch (prop_id) {
|
|
+ case PROP_START:
|
|
+ g_value_set_uint (value, ibus_unicode_block_get_start (block));
|
|
+ break;
|
|
+ case PROP_END:
|
|
+ g_value_set_uint (value, ibus_unicode_block_get_end (block));
|
|
+ break;
|
|
+ case PROP_NAME:
|
|
+ g_value_set_string (value, ibus_unicode_block_get_name (block));
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (block, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ibus_unicode_block_serialize (IBusUnicodeBlock *block,
|
|
+ GVariantBuilder *builder)
|
|
+{
|
|
+ gboolean retval = IBUS_SERIALIZABLE_CLASS (ibus_unicode_block_parent_class)->
|
|
+ serialize ((IBusSerializable *)block, builder);
|
|
+ g_return_val_if_fail (retval, FALSE);
|
|
+
|
|
+#define NOTNULL(s) ((s) != NULL ? (s) : "")
|
|
+ /* If you will add a new property, you can append it at the end and
|
|
+ * you should not change the serialized order of name, longname,
|
|
+ * description, ... because the order is also used in other applications
|
|
+ * likes ibus-qt. */
|
|
+ g_variant_builder_add (builder, "u", block->priv->start);
|
|
+ g_variant_builder_add (builder, "u", block->priv->end);
|
|
+ g_variant_builder_add (builder, "s", NOTNULL (block->priv->name));
|
|
+#undef NOTNULL
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gint
|
|
+ibus_unicode_block_deserialize (IBusUnicodeBlock *block,
|
|
+ GVariant *variant)
|
|
+{
|
|
+ gint retval = IBUS_SERIALIZABLE_CLASS (ibus_unicode_block_parent_class)->
|
|
+ deserialize ((IBusSerializable *)block, variant);
|
|
+ g_return_val_if_fail (retval, 0);
|
|
+
|
|
+ /* If you will add a new property, you can append it at the end and
|
|
+ * you should not change the serialized order of name, longname,
|
|
+ * description, ... because the order is also used in other applications
|
|
+ * likes ibus-qt. */
|
|
+ g_variant_get_child (variant, retval++, "u", &block->priv->start);
|
|
+ g_variant_get_child (variant, retval++, "u", &block->priv->end);
|
|
+ ibus_g_variant_get_child_string (variant, retval++,
|
|
+ &block->priv->name);
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ibus_unicode_block_copy (IBusUnicodeBlock *dest,
|
|
+ const IBusUnicodeBlock *src)
|
|
+{
|
|
+ gboolean retval = IBUS_SERIALIZABLE_CLASS (ibus_unicode_block_parent_class)->
|
|
+ copy ((IBusSerializable *)dest,
|
|
+ (IBusSerializable *)src);
|
|
+ g_return_val_if_fail (retval, FALSE);
|
|
+
|
|
+ dest->priv->start = src->priv->start;
|
|
+ dest->priv->end = src->priv->end;
|
|
+ dest->priv->name = g_strdup (src->priv->name);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+IBusUnicodeBlock *
|
|
+ibus_unicode_block_new (const gchar *first_property_name, ...)
|
|
+{
|
|
+ va_list var_args;
|
|
+ IBusUnicodeBlock *block;
|
|
+
|
|
+ g_assert (first_property_name != NULL);
|
|
+ va_start (var_args, first_property_name);
|
|
+ block = (IBusUnicodeBlock *) g_object_new_valist (IBUS_TYPE_UNICODE_BLOCK,
|
|
+ first_property_name,
|
|
+ var_args);
|
|
+ va_end (var_args);
|
|
+ /* end is required. Other properties are set in class_init by default. */
|
|
+ g_assert (block->priv->start != block->priv->end);
|
|
+ g_assert (block->priv->name != NULL);
|
|
+ return block;
|
|
+}
|
|
+
|
|
+gunichar
|
|
+ibus_unicode_block_get_start (IBusUnicodeBlock *block)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_UNICODE_BLOCK (block), G_MAXUINT32);
|
|
+
|
|
+ return block->priv->start;
|
|
+}
|
|
+
|
|
+gunichar
|
|
+ibus_unicode_block_get_end (IBusUnicodeBlock *block)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_UNICODE_BLOCK (block), G_MAXUINT32);
|
|
+
|
|
+ return block->priv->end;
|
|
+}
|
|
+
|
|
+const gchar *
|
|
+ibus_unicode_block_get_name (IBusUnicodeBlock *block)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_UNICODE_BLOCK (block), "");
|
|
+
|
|
+ return block->priv->name;
|
|
+}
|
|
+
|
|
+static void
|
|
+variant_foreach_add_block (IBusUnicodeBlock *block,
|
|
+ GVariantBuilder *builder)
|
|
+{
|
|
+ g_variant_builder_add (
|
|
+ builder, "v",
|
|
+ ibus_serializable_serialize (IBUS_SERIALIZABLE (block)));
|
|
+}
|
|
+
|
|
+static GVariant *
|
|
+ibus_unicode_block_list_serialize (GSList *list)
|
|
+{
|
|
+ GVariantBuilder builder;
|
|
+
|
|
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("av"));
|
|
+ g_slist_foreach (list, (GFunc) variant_foreach_add_block, &builder);
|
|
+ return g_variant_builder_end (&builder);
|
|
+}
|
|
+
|
|
+static GSList *
|
|
+ibus_unicode_block_list_deserialize (GVariant *variant)
|
|
+{
|
|
+ GSList *list = NULL;
|
|
+ GVariantIter iter;
|
|
+ GVariant *unicode_variant = NULL;
|
|
+
|
|
+ g_variant_iter_init (&iter, variant);
|
|
+ while (g_variant_iter_loop (&iter, "v", &unicode_variant)) {
|
|
+ IBusUnicodeBlock *data =
|
|
+ IBUS_UNICODE_BLOCK (ibus_serializable_deserialize (
|
|
+ unicode_variant));
|
|
+ list = g_slist_append (list, data);
|
|
+ g_clear_pointer (&unicode_variant, g_variant_unref);
|
|
+ }
|
|
+
|
|
+ return list;
|
|
+}
|
|
+
|
|
+void
|
|
+ibus_unicode_block_save (const gchar *path,
|
|
+ GSList *list)
|
|
+{
|
|
+ GVariant *variant;
|
|
+ const gchar *header = IBUS_UNICODE_BLOCK_MAGIC;
|
|
+ const guint16 version = IBUS_UNICODE_DATA_VERSION;
|
|
+ const gchar *contents;
|
|
+ gsize length;
|
|
+ gchar *dir;
|
|
+ GStatBuf buf = { 0, };
|
|
+ GError *error = NULL;
|
|
+
|
|
+ g_return_if_fail (path != NULL);
|
|
+ g_return_if_fail (list != NULL);
|
|
+ if (list->data == NULL) {
|
|
+ g_warning ("Failed to save IBus Unicode block: Need a list data.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ variant = g_variant_new ("(sqv)",
|
|
+ header,
|
|
+ version,
|
|
+ ibus_unicode_block_list_serialize (list));
|
|
+
|
|
+ contents = g_variant_get_data (variant);
|
|
+ length = g_variant_get_size (variant);
|
|
+
|
|
+ dir = g_path_get_dirname (path);
|
|
+ if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) {
|
|
+ g_mkdir_with_parents (dir, 0777);
|
|
+ }
|
|
+ g_free (dir);
|
|
+ if (!g_file_set_contents (path, contents, length, &error)) {
|
|
+ g_warning ("Failed to save Unicode dict %s: %s", path, error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+
|
|
+ g_variant_unref (variant);
|
|
+}
|
|
+
|
|
+GSList *
|
|
+ibus_unicode_block_load (const gchar *path)
|
|
+{
|
|
+ gchar *contents = NULL;
|
|
+ gsize length = 0;
|
|
+ GError *error = NULL;
|
|
+ GVariant *variant_table = NULL;
|
|
+ GVariant *variant = NULL;
|
|
+ const gchar *header = NULL;
|
|
+ guint16 version = 0;
|
|
+ GSList *retval = NULL;
|
|
+
|
|
+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
|
|
+ g_warning ("Unicode dict does not exist: %s", path);
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ if (!g_file_get_contents (path, &contents, &length, &error)) {
|
|
+ g_warning ("Failed to get dict content %s: %s", path, error->message);
|
|
+ g_error_free (error);
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ variant_table = g_variant_new_from_data (G_VARIANT_TYPE ("(sq)"),
|
|
+ contents,
|
|
+ length,
|
|
+ FALSE,
|
|
+ NULL,
|
|
+ NULL);
|
|
+
|
|
+ if (variant_table == NULL) {
|
|
+ g_warning ("cache table is broken.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ g_variant_get (variant_table, "(&sq)", &header, &version);
|
|
+
|
|
+ if (g_strcmp0 (header, IBUS_UNICODE_BLOCK_MAGIC) != 0) {
|
|
+ g_warning ("cache is not IBusUnicodeBlock.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ if (version > IBUS_UNICODE_DATA_VERSION) {
|
|
+ g_warning ("cache version is different: %u != %u",
|
|
+ version, IBUS_UNICODE_DATA_VERSION);
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ version = 0;
|
|
+ header = NULL;
|
|
+ g_variant_unref (variant_table);
|
|
+
|
|
+ variant_table = g_variant_new_from_data (G_VARIANT_TYPE ("(sqv)"),
|
|
+ contents,
|
|
+ length,
|
|
+ FALSE,
|
|
+ NULL,
|
|
+ NULL);
|
|
+
|
|
+ if (variant_table == NULL) {
|
|
+ g_warning ("cache table is broken.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ g_variant_get (variant_table, "(&sqv)",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ &variant);
|
|
+
|
|
+ if (variant == NULL) {
|
|
+ g_warning ("cache dict is broken.");
|
|
+ goto out_load_cache;
|
|
+ }
|
|
+
|
|
+ retval = ibus_unicode_block_list_deserialize (variant);
|
|
+
|
|
+out_load_cache:
|
|
+ if (variant)
|
|
+ g_variant_unref (variant);
|
|
+ if (variant_table)
|
|
+ g_variant_unref (variant_table);
|
|
+ g_free (contents);
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
diff --git a/src/ibusunicode.h b/src/ibusunicode.h
|
|
new file mode 100644
|
|
index 00000000..99de9451
|
|
--- /dev/null
|
|
+++ b/src/ibusunicode.h
|
|
@@ -0,0 +1,299 @@
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
+/* vim:set et sts=4: */
|
|
+/* bus - The Input Bus
|
|
+ * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2018 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
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+#if !defined (__IBUS_H_INSIDE__) && !defined (IBUS_COMPILATION)
|
|
+#error "Only <ibus.h> can be included directly"
|
|
+#endif
|
|
+
|
|
+#ifndef __IBUS_UNICODE_H_
|
|
+#define __IBUS_UNICODE_H_
|
|
+
|
|
+/**
|
|
+ * SECTION: ibusunicode
|
|
+ * @short_description: unicode utility.
|
|
+ * @stability: Unstable
|
|
+ *
|
|
+ * miscellaneous unicode APIs.
|
|
+ */
|
|
+
|
|
+#include <gio/gio.h>
|
|
+#include "ibusserializable.h"
|
|
+
|
|
+/*
|
|
+ * Type macros.
|
|
+ */
|
|
+/* define GOBJECT macros */
|
|
+#define IBUS_TYPE_UNICODE_DATA (ibus_unicode_data_get_type ())
|
|
+#define IBUS_UNICODE_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
|
+ IBUS_TYPE_UNICODE_DATA, IBusUnicodeData))
|
|
+#define IBUS_UNICODE_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
|
|
+ IBUS_TYPE_UNICODE_DATA, \
|
|
+ IBusUnicodeDataClass))
|
|
+#define IBUS_IS_UNICODE_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
|
+ IBUS_TYPE_UNICODE_DATA))
|
|
+#define IBUS_TYPE_UNICODE_BLOCK (ibus_unicode_block_get_type ())
|
|
+#define IBUS_UNICODE_BLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
|
+ IBUS_TYPE_UNICODE_BLOCK, \
|
|
+ IBusUnicodeBlock))
|
|
+#define IBUS_UNICODE_BLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
|
|
+ IBUS_TYPE_UNICODE_BLOCK, \
|
|
+ IBusUnicodeBlockClass))
|
|
+#define IBUS_IS_UNICODE_BLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
|
+ IBUS_TYPE_UNICODE_BLOCK))
|
|
+
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+typedef struct _IBusUnicodeData IBusUnicodeData;
|
|
+typedef struct _IBusUnicodeDataPrivate IBusUnicodeDataPrivate;
|
|
+typedef struct _IBusUnicodeDataClass IBusUnicodeDataClass;
|
|
+typedef struct _IBusUnicodeBlock IBusUnicodeBlock;
|
|
+typedef struct _IBusUnicodeBlockPrivate IBusUnicodeBlockPrivate;
|
|
+typedef struct _IBusUnicodeBlockClass IBusUnicodeBlockClass;
|
|
+
|
|
+/**
|
|
+ * IBusUnicodeDataLoadAsyncFinish:
|
|
+ * @data_list: (transfer full) (element-type IBusUnicodeData):
|
|
+ *
|
|
+ * This callback can receive the list of #IBusUnicodeData.
|
|
+ */
|
|
+typedef void (*IBusUnicodeDataLoadAsyncFinish) (GSList *data_list,
|
|
+ gpointer user_data);
|
|
+
|
|
+/**
|
|
+ * IBusUnicodeData:
|
|
+ *
|
|
+ * Unicode data likes code, name, alias, block-name.
|
|
+ * You can get extended values with g_object_get_properties.
|
|
+ */
|
|
+struct _IBusUnicodeData {
|
|
+ IBusSerializable parent;
|
|
+ /* instance members */
|
|
+
|
|
+ /*< public >*/
|
|
+ /*< private >*/
|
|
+ IBusUnicodeDataPrivate *priv;
|
|
+};
|
|
+
|
|
+struct _IBusUnicodeDataClass {
|
|
+ IBusSerializableClass parent;
|
|
+ /* class members */
|
|
+};
|
|
+
|
|
+struct _IBusUnicodeBlock {
|
|
+ IBusSerializable parent;
|
|
+ /* instance members */
|
|
+
|
|
+ /*< public >*/
|
|
+ /*< private >*/
|
|
+ IBusUnicodeBlockPrivate *priv;
|
|
+};
|
|
+
|
|
+struct _IBusUnicodeBlockClass {
|
|
+ IBusSerializableClass parent;
|
|
+ /* class members */
|
|
+};
|
|
+
|
|
+GType ibus_unicode_data_get_type (void);
|
|
+GType ibus_unicode_block_get_type (void);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_new:
|
|
+ * @first_property_name: Name of the first property.
|
|
+ * @...: the NULL-terminated arguments of the properties and values.
|
|
+ *
|
|
+ * Creates a new #IBusUnicodeData.
|
|
+ * code property is required. e.g.
|
|
+ * ibus_unicode_data_new ("code", 0x3042, NULL)
|
|
+ *
|
|
+ * Returns: A newly allocated #IBusUnicodeData.
|
|
+ */
|
|
+IBusUnicodeData * ibus_unicode_data_new (const gchar *first_property_name,
|
|
+ ...);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_get_code:
|
|
+ * @unicode: An #IBusUnicodeData
|
|
+ *
|
|
+ * Gets the code point in #IBusUnicodeData.
|
|
+ *
|
|
+ * Returns: code property in #IBusUnicodeData
|
|
+ */
|
|
+gunichar ibus_unicode_data_get_code (IBusUnicodeData *unicode);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_get_name:
|
|
+ * @unicode: An #IBusUnicodeData
|
|
+ *
|
|
+ * Gets the name in #IBusUnicodeData. It should not be freed.
|
|
+ *
|
|
+ * Returns: name property in #IBusUnicodeData
|
|
+ */
|
|
+const gchar * ibus_unicode_data_get_name (IBusUnicodeData *unicode);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_get_alias:
|
|
+ * @unicode: An #IBusUnicodeData
|
|
+ *
|
|
+ * Gets the alias in #IBusUnicodeData. It should not be freed.
|
|
+ *
|
|
+ * Returns: alias property in #IBusUnicodeData
|
|
+ */
|
|
+const gchar * ibus_unicode_data_get_alias (IBusUnicodeData *unicode);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_get_block_name:
|
|
+ * @unicode: An #IBusUnicodeData
|
|
+ *
|
|
+ * Gets the block name in #IBusUnicodeData. It should not be freed.
|
|
+ *
|
|
+ * Returns: block-name property in #IBusUnicodeData
|
|
+ */
|
|
+const gchar * ibus_unicode_data_get_block_name
|
|
+ (IBusUnicodeData *unicode);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_set_block_name:
|
|
+ * @unicode: An #IBusUnicodeData
|
|
+ * @block_name: A block name
|
|
+ *
|
|
+ * Sets the block name in #IBusUnicodeData.
|
|
+ */
|
|
+void ibus_unicode_data_set_block_name
|
|
+ (IBusUnicodeData *unicode,
|
|
+ const gchar *block_name);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_save:
|
|
+ * @path: A path of the saved Unicode data.
|
|
+ * @list: (element-type IBusUnicodeData) (transfer none): A list of unicode
|
|
+ * data.
|
|
+ *
|
|
+ * Save the list of #IBusUnicodeData to the cache file.
|
|
+ */
|
|
+void ibus_unicode_data_save (const gchar *path,
|
|
+ GSList *list);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_load:
|
|
+ * @path: A path of the saved dictionary file.
|
|
+ * @object: (nullable): If the #GObject has "unicode-deserialize-progress"
|
|
+ * signal, this function will emit (the number of desrialized
|
|
+ * #IBusUnicodeData, * the total number of #IBusUnicodeData) of uint values
|
|
+ * with that signal by 100 times. Otherwise %NULL.
|
|
+ *
|
|
+ * Returns: (element-type IBusUnicodeData) (transfer container):
|
|
+ * An #IBusUnicodeData list loaded from the saved cache file.
|
|
+ */
|
|
+GSList * ibus_unicode_data_load (const gchar *path,
|
|
+ GObject *object);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_data_load_async:
|
|
+ * @path: A path of the saved dictionary file.
|
|
+ * @object: (nullable): If the #GObject has "unicode-deserialize-progress"
|
|
+ * signal, this function will emit (the number of desrialized
|
|
+ * #IBusUnicodeData, * the total number of #IBusUnicodeData) of uint values
|
|
+ * with that signal by 100 times. Otherwise %NULL.
|
|
+ * @cancellable: cancellable.
|
|
+ * @callback: (scope notified): IBusUnicodeDataLoadAsyncFinish.
|
|
+ * @user_data: User data.
|
|
+ *
|
|
+ * IBusUnicodeDataLoadAsyncFinish can receive the list of #IBusUnicodeData.
|
|
+ */
|
|
+void ibus_unicode_data_load_async
|
|
+ (const gchar *path,
|
|
+ GObject *object,
|
|
+ GCancellable *cancellable,
|
|
+ IBusUnicodeDataLoadAsyncFinish
|
|
+ callback,
|
|
+ gpointer user_data);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_block_new:
|
|
+ * @first_property_name: Name of the first property.
|
|
+ * @...: the NULL-terminated arguments of the properties and values.
|
|
+ *
|
|
+ * Creates a new #IBusUnicodeBlock.
|
|
+ * block property is required. e.g.
|
|
+ * ibus_unicode_block_new ("start", 0x0000, "end", "0x007f", "name", "basic",
|
|
+ * NULL)
|
|
+ *
|
|
+ * Returns: A newly allocated #IBusUnicodeBlock.
|
|
+ */
|
|
+IBusUnicodeBlock *ibus_unicode_block_new (const gchar *first_property_name,
|
|
+ ...);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_block_get_start:
|
|
+ * @block: An #IBusUnicodeData
|
|
+ *
|
|
+ * Gets the start code point in #IBusUnicodeBlock.
|
|
+ *
|
|
+ * Returns: start property in #IBusUnicodeBlock
|
|
+ */
|
|
+gunichar ibus_unicode_block_get_start
|
|
+ (IBusUnicodeBlock *block);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_block_get_end:
|
|
+ * @block: An #IBusUnicodeData
|
|
+ *
|
|
+ * Gets the end code point in #IBusUnicodeBlock.
|
|
+ *
|
|
+ * Returns: end property in #IBusUnicodeBlock
|
|
+ */
|
|
+gunichar ibus_unicode_block_get_end
|
|
+ (IBusUnicodeBlock *block);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_block_get_name:
|
|
+ * @block: An #IBusUnicodeBlock
|
|
+ *
|
|
+ * Gets the name in #IBusUnicodeBlock. It should not be freed.
|
|
+ *
|
|
+ * Returns: name property in #IBusUnicodeBlock
|
|
+ */
|
|
+const gchar * ibus_unicode_block_get_name (IBusUnicodeBlock *block);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_block_save:
|
|
+ * @path: A path of the saved Unicode block.
|
|
+ * @list: (element-type IBusUnicodeBlock) (transfer none): A list of unicode
|
|
+ * block.
|
|
+ *
|
|
+ * Save the list of #IBusUnicodeBlock to the cache file.
|
|
+ */
|
|
+void ibus_unicode_block_save (const gchar *path,
|
|
+ GSList *list);
|
|
+
|
|
+/**
|
|
+ * ibus_unicode_block_load:
|
|
+ * @path: A path of the saved dictionary file.
|
|
+ *
|
|
+ * Returns: (element-type IBusUnicodeBlock) (transfer container):
|
|
+ * An #IBusUnicodeBlock list loaded from the saved cache file.
|
|
+ */
|
|
+GSList * ibus_unicode_block_load (const gchar *path);
|
|
+
|
|
+G_END_DECLS
|
|
+#endif
|
|
diff --git a/src/ibusunicodegen.h b/src/ibusunicodegen.h
|
|
new file mode 100644
|
|
index 00000000..c613b81b
|
|
--- /dev/null
|
|
+++ b/src/ibusunicodegen.h
|
|
@@ -0,0 +1,1151 @@
|
|
+/* -*- 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.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+
|
|
+/* This file is generated by unicode-parser.c. */
|
|
+include <glib/gi18n.h>
|
|
+
|
|
+#ifndef __IBUS_UNICODE_GEN_H_
|
|
+#define __IBUS_UNICODE_GEN_H_
|
|
+const static char *unicode_blocks[] = {
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Basic Latin"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Latin-1 Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Latin Extended-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Latin Extended-B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("IPA Extensions"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Spacing Modifier Letters"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Combining Diacritical Marks"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Greek and Coptic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cyrillic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cyrillic Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Armenian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hebrew"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Arabic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Syriac"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Arabic Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Thaana"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("NKo"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Samaritan"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mandaic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Syriac Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Arabic Extended-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Devanagari"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Bengali"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Gurmukhi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Gujarati"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Oriya"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tamil"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Telugu"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kannada"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Malayalam"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Sinhala"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Thai"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Lao"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tibetan"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Myanmar"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Georgian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hangul Jamo"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ethiopic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ethiopic Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cherokee"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Unified Canadian Aboriginal Syllabics"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ogham"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Runic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tagalog"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hanunoo"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Buhid"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tagbanwa"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Khmer"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mongolian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Unified Canadian Aboriginal Syllabics Extended"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Limbu"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tai Le"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("New Tai Lue"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Khmer Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Buginese"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tai Tham"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Combining Diacritical Marks Extended"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Balinese"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Sundanese"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Batak"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Lepcha"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ol Chiki"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cyrillic Extended-C"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Sundanese Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Vedic Extensions"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Phonetic Extensions"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Phonetic Extensions Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Combining Diacritical Marks Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Latin Extended Additional"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Greek Extended"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("General Punctuation"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Superscripts and Subscripts"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Currency Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Combining Diacritical Marks for Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Letterlike Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Number Forms"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Arrows"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mathematical Operators"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Miscellaneous Technical"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Control Pictures"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Optical Character Recognition"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Enclosed Alphanumerics"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Box Drawing"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Block Elements"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Geometric Shapes"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Miscellaneous Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Dingbats"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Miscellaneous Mathematical Symbols-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplemental Arrows-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Braille Patterns"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplemental Arrows-B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Miscellaneous Mathematical Symbols-B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplemental Mathematical Operators"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Miscellaneous Symbols and Arrows"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Glagolitic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Latin Extended-C"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Coptic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Georgian Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tifinagh"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ethiopic Extended"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cyrillic Extended-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplemental Punctuation"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Radicals Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kangxi Radicals"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ideographic Description Characters"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Symbols and Punctuation"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hiragana"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Katakana"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Bopomofo"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hangul Compatibility Jamo"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kanbun"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Bopomofo Extended"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Strokes"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Katakana Phonetic Extensions"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Enclosed CJK Letters and Months"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Compatibility"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Unified Ideographs Extension A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Yijing Hexagram Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Unified Ideographs"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Yi Syllables"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Yi Radicals"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Lisu"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Vai"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cyrillic Extended-B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Bamum"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Modifier Tone Letters"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Latin Extended-D"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Syloti Nagri"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Common Indic Number Forms"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Phags-pa"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Saurashtra"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Devanagari Extended"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kayah Li"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Rejang"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hangul Jamo Extended-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Javanese"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Myanmar Extended-B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cham"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Myanmar Extended-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tai Viet"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Meetei Mayek Extensions"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ethiopic Extended-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Latin Extended-E"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cherokee Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Meetei Mayek"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hangul Syllables"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hangul Jamo Extended-B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("High Surrogates"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("High Private Use Surrogates"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Low Surrogates"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Private Use Area"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Compatibility Ideographs"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Alphabetic Presentation Forms"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Arabic Presentation Forms-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Variation Selectors"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Vertical Forms"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Combining Half Marks"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Compatibility Forms"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Small Form Variants"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Arabic Presentation Forms-B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Halfwidth and Fullwidth Forms"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Specials"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Linear B Syllabary"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Linear B Ideograms"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Aegean Numbers"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ancient Greek Numbers"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ancient Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Phaistos Disc"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Lycian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Carian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Coptic Epact Numbers"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Old Italic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Gothic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Old Permic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ugaritic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Old Persian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Deseret"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Shavian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Osmanya"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Osage"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Elbasan"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Caucasian Albanian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Linear A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cypriot Syllabary"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Imperial Aramaic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Palmyrene"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Nabataean"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Hatran"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Phoenician"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Lydian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Meroitic Hieroglyphs"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Meroitic Cursive"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kharoshthi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Old South Arabian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Old North Arabian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Manichaean"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Avestan"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Inscriptional Parthian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Inscriptional Pahlavi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Psalter Pahlavi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Old Turkic"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Old Hungarian"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Rumi Numeral Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Brahmi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kaithi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Sora Sompeng"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Chakma"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mahajani"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Sharada"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Sinhala Archaic Numbers"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Khojki"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Multani"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Khudawadi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Grantha"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Newa"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tirhuta"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Siddham"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Modi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mongolian Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Takri"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ahom"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Warang Citi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Zanabazar Square"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Soyombo"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Pau Cin Hau"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Bhaiksuki"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Marchen"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Masaram Gondi"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cuneiform"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Cuneiform Numbers and Punctuation"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Early Dynastic Cuneiform"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Egyptian Hieroglyphs"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Anatolian Hieroglyphs"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Bamum Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mro"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Bassa Vah"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Pahawh Hmong"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Miao"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ideographic Symbols and Punctuation"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tangut"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tangut Components"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kana Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Kana Extended-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Nushu"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Duployan"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Shorthand Format Controls"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Byzantine Musical Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Musical Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ancient Greek Musical Notation"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tai Xuan Jing Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Counting Rod Numerals"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mathematical Alphanumeric Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Sutton SignWriting"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Glagolitic Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mende Kikakui"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Adlam"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Arabic Mathematical Alphabetic Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Mahjong Tiles"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Domino Tiles"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Playing Cards"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Enclosed Alphanumeric Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Enclosed Ideographic Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Miscellaneous Symbols and Pictographs"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Emoticons"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Ornamental Dingbats"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Transport and Map Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Alchemical Symbols"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Geometric Shapes Extended"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplemental Arrows-C"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplemental Symbols and Pictographs"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Unified Ideographs Extension B"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Unified Ideographs Extension C"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Unified Ideographs Extension D"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Unified Ideographs Extension E"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Unified Ideographs Extension F"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("CJK Compatibility Ideographs Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Tags"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Variation Selectors Supplement"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplementary Private Use Area-A"),
|
|
+ /* TRANSLATORS: You might refer the translations from gucharmap with
|
|
+ the following command:
|
|
+ msgmerge -C gucharmap.po ibus.po ibus.pot */
|
|
+ N_("Supplementary Private Use Area-B"),
|
|
+};
|
|
+#endif
|
|
diff --git a/src/unicode-parser.c b/src/unicode-parser.c
|
|
new file mode 100644
|
|
index 00000000..e98c6d5f
|
|
--- /dev/null
|
|
+++ b/src/unicode-parser.c
|
|
@@ -0,0 +1,502 @@
|
|
+/* -*- 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.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+#ifdef HAVE_CONFIG_H
|
|
+#include <config.h>
|
|
+#endif
|
|
+
|
|
+#include <glib.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+
|
|
+#ifdef HAVE_LOCALE_H
|
|
+#include <locale.h>
|
|
+#endif
|
|
+
|
|
+#include "ibusunicode.h"
|
|
+
|
|
+#define NAMES_LIST_SUBJECT "The Unicode Standard"
|
|
+#define BLOCKS_SUBJECT "Blocks-"
|
|
+
|
|
+/* This file has 21 lines about the license at the top of the file. */
|
|
+#define LICENSE_LINES 21
|
|
+
|
|
+typedef enum
|
|
+{
|
|
+ UCD_NAMES_LIST,
|
|
+ UCD_BLOCKS
|
|
+} UCDType;
|
|
+
|
|
+typedef struct _UnicodeData UnicodeData;
|
|
+typedef struct _UnicodeDataIndex UnicodeDataIndex;
|
|
+
|
|
+struct _UnicodeData{
|
|
+ gunichar code;
|
|
+ gchar *name;
|
|
+ gchar *alias;
|
|
+ gunichar start;
|
|
+ gunichar end;
|
|
+ GSList *list;
|
|
+};
|
|
+
|
|
+struct _UnicodeDataIndex {
|
|
+ gchar *index;
|
|
+ UnicodeData *data_list;
|
|
+};
|
|
+
|
|
+static gchar *unicode_version;
|
|
+
|
|
+static void
|
|
+unicode_data_new_object (UnicodeData *data)
|
|
+{
|
|
+ g_return_if_fail (data != NULL);
|
|
+ if (!data->name) {
|
|
+ g_warning ("No name in U+%04X", data->code);
|
|
+ }
|
|
+ IBusUnicodeData *unicode =
|
|
+ ibus_unicode_data_new ("code",
|
|
+ data->code,
|
|
+ "name",
|
|
+ data->name ? g_strdup (data->name)
|
|
+ : g_strdup (""),
|
|
+ "alias",
|
|
+ data->alias ? g_strdup (data->alias)
|
|
+ : g_strdup (""),
|
|
+ NULL);
|
|
+ data->list = g_slist_append (data->list, unicode);
|
|
+}
|
|
+
|
|
+static void
|
|
+unicode_block_new_object (UnicodeData *data)
|
|
+{
|
|
+ g_return_if_fail (data != NULL);
|
|
+ if (!data->name) {
|
|
+ g_warning ("No name in U+%04X", data->start);
|
|
+ }
|
|
+ IBusUnicodeBlock *block =
|
|
+ ibus_unicode_block_new ("start",
|
|
+ data->start,
|
|
+ "end",
|
|
+ data->end,
|
|
+ "name",
|
|
+ data->name ? g_strdup (data->name)
|
|
+ : g_strdup (""),
|
|
+ NULL);
|
|
+ data->list = g_slist_append (data->list, block);
|
|
+}
|
|
+
|
|
+static void
|
|
+unicode_data_reset (UnicodeData *data)
|
|
+{
|
|
+ g_return_if_fail (data != NULL);
|
|
+ data->code = 0;
|
|
+ g_clear_pointer (&data->name, g_free);
|
|
+ g_clear_pointer (&data->alias, g_free);
|
|
+ data->start = 0;
|
|
+ data->end = 0;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ucd_names_list_parse_comment (const gchar *line)
|
|
+{
|
|
+ static gboolean has_version = FALSE;
|
|
+
|
|
+ if (has_version)
|
|
+ return TRUE;
|
|
+ if (strlen (line) > 4 && strncmp (line, "@@@", 3) == 0) {
|
|
+ gchar **elements = g_strsplit (line, "\t", -1);
|
|
+ if (strncmp (elements[1], NAMES_LIST_SUBJECT,
|
|
+ strlen (NAMES_LIST_SUBJECT)) == 0) {
|
|
+ unicode_version =
|
|
+ g_strdup (elements[1] + strlen (NAMES_LIST_SUBJECT) + 1);
|
|
+ has_version = TRUE;
|
|
+ }
|
|
+ g_strfreev (elements);
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ucd_names_list_parse_alias (const gchar *line,
|
|
+ UnicodeData *data)
|
|
+{
|
|
+ g_return_val_if_fail (line != NULL, FALSE);
|
|
+ g_return_val_if_fail (data != NULL, FALSE);
|
|
+
|
|
+ if (*line == '\0')
|
|
+ return FALSE;
|
|
+ data->alias = g_strdup (line);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ucd_names_list_parse_indent_line (const gchar *line,
|
|
+ UnicodeData *data)
|
|
+{
|
|
+ g_return_val_if_fail (line != NULL, FALSE);
|
|
+
|
|
+ switch (*line) {
|
|
+ case '\0':
|
|
+ return FALSE;
|
|
+ case '=':
|
|
+ line++;
|
|
+ while (*line == ' ') line++;
|
|
+ return ucd_names_list_parse_alias (line, data);
|
|
+ default:;
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ucd_names_list_parse_line (const gchar *line,
|
|
+ UnicodeData *data)
|
|
+{
|
|
+ g_return_val_if_fail (line != NULL, FALSE);
|
|
+
|
|
+ switch (*line) {
|
|
+ case '\0':
|
|
+ return TRUE;
|
|
+ case ';':
|
|
+ return TRUE;
|
|
+ case '@':
|
|
+ return ucd_names_list_parse_comment (line);
|
|
+ case '\t':
|
|
+ return ucd_names_list_parse_indent_line (line + 1, data);
|
|
+ default:;
|
|
+ }
|
|
+ if (g_ascii_isxdigit (*line)) {
|
|
+ gchar **elements = g_strsplit (line, "\t", -1);
|
|
+ gunichar code;
|
|
+ gchar *name;
|
|
+
|
|
+ if (g_strv_length (elements) < 2) {
|
|
+ g_strfreev (elements);
|
|
+ return FALSE;
|
|
+ }
|
|
+ code = g_ascii_strtoull (elements[0], NULL, 16);
|
|
+ name = g_strdup (elements[1]);
|
|
+ if (data->name) {
|
|
+ unicode_data_new_object (data);
|
|
+ unicode_data_reset (data);
|
|
+ }
|
|
+ data->code = code;
|
|
+ data->name = name;
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ucd_blocks_parse_comment (const gchar *line)
|
|
+{
|
|
+ static gboolean has_version = FALSE;
|
|
+
|
|
+ g_return_val_if_fail (line != NULL, FALSE);
|
|
+
|
|
+ if (has_version)
|
|
+ return TRUE;
|
|
+ while (*line == ' ') line++;
|
|
+ if (strlen (line) > strlen (BLOCKS_SUBJECT) &&
|
|
+ strncmp (line, BLOCKS_SUBJECT, strlen (BLOCKS_SUBJECT)) == 0) {
|
|
+ unicode_version = g_strdup (line + strlen (BLOCKS_SUBJECT) + 1);
|
|
+ has_version = TRUE;
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ucd_blocks_parse_line (const gchar *line,
|
|
+ UnicodeData *data)
|
|
+{
|
|
+ g_return_val_if_fail (line != NULL, FALSE);
|
|
+
|
|
+ switch (*line) {
|
|
+ case '\0':
|
|
+ return TRUE;
|
|
+ case '#':
|
|
+ return ucd_blocks_parse_comment (line + 1);
|
|
+ default:;
|
|
+ }
|
|
+ if (g_ascii_isxdigit (*line)) {
|
|
+ gchar *endptr = NULL;
|
|
+ gunichar start = g_ascii_strtoull (line, &endptr, 16);
|
|
+ gunichar end;
|
|
+ gchar *name = NULL;
|
|
+
|
|
+ if (endptr == NULL || *endptr == '\0')
|
|
+ return FALSE;
|
|
+ while (*endptr == '.') endptr++;
|
|
+ line = endptr;
|
|
+ endptr = NULL;
|
|
+ end = g_ascii_strtoull (line, &endptr, 16);
|
|
+ if (endptr == NULL || *endptr == '\0')
|
|
+ return FALSE;
|
|
+ while (*endptr == ';') endptr++;
|
|
+ while (*endptr == ' ') endptr++;
|
|
+ if (*endptr == '\0')
|
|
+ return FALSE;
|
|
+ name = g_strdup (endptr);
|
|
+ if (data->name) {
|
|
+ unicode_block_new_object (data);
|
|
+ unicode_data_reset (data);
|
|
+ }
|
|
+ data->start = start;
|
|
+ data->end = end;
|
|
+ data->name = name;
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ucd_parse_file (const gchar *filename,
|
|
+ GSList **list,
|
|
+ UCDType type)
|
|
+{
|
|
+ UnicodeData data = { 0, };
|
|
+ gchar *content = NULL;
|
|
+ gsize length = 0;
|
|
+ GError *error = NULL;
|
|
+ gchar *head, *end, *line;
|
|
+ int n = 1;
|
|
+
|
|
+ g_return_val_if_fail (filename != NULL, FALSE);
|
|
+ g_return_val_if_fail (list != NULL, FALSE);
|
|
+
|
|
+ if (!g_file_get_contents (filename, &content, &length, &error)) {
|
|
+ g_warning ("Failed to load %s: %s", filename, error->message);
|
|
+ goto failed_to_parse_ucd_names_list;
|
|
+ }
|
|
+ head = end = content;
|
|
+ while (*end == '\n' && end - content < length) {
|
|
+ end++;
|
|
+ n++;
|
|
+ }
|
|
+ head = end;
|
|
+ while (end - content < length) {
|
|
+ while (*end != '\n' && end - content < length)
|
|
+ end++;
|
|
+ if (end - content >= length)
|
|
+ break;
|
|
+ line = g_strndup (head, end - head);
|
|
+ switch (type) {
|
|
+ case UCD_NAMES_LIST:
|
|
+ if (!ucd_names_list_parse_line (line, &data)) {
|
|
+ g_warning ("parse error #%d in %s version %s: %s",
|
|
+ n, filename,
|
|
+ unicode_version ? unicode_version : "(null)",
|
|
+ line);
|
|
+ }
|
|
+ break;
|
|
+ case UCD_BLOCKS:
|
|
+ if (!ucd_blocks_parse_line (line, &data)) {
|
|
+ g_warning ("parse error #%d in %s version %s: %s",
|
|
+ n, filename,
|
|
+ unicode_version ? unicode_version : "(null)",
|
|
+ line);
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ g_abort ();
|
|
+ }
|
|
+ while (*end == '\n' && end - content < length) {
|
|
+ end++;
|
|
+ n++;
|
|
+ }
|
|
+ g_free (line);
|
|
+ head = end;
|
|
+ }
|
|
+ if (data.name != NULL) {
|
|
+ switch (type) {
|
|
+ case UCD_NAMES_LIST:
|
|
+ unicode_data_new_object (&data);
|
|
+ break;
|
|
+ case UCD_BLOCKS:
|
|
+ unicode_block_new_object (&data);
|
|
+ break;
|
|
+ default:;
|
|
+ }
|
|
+ unicode_data_reset (&data);
|
|
+ }
|
|
+ g_free (content);
|
|
+ *list = data.list;
|
|
+ return TRUE;
|
|
+
|
|
+failed_to_parse_ucd_names_list:
|
|
+ if (error)
|
|
+ g_error_free (error);
|
|
+ g_clear_pointer (&content, g_free);
|
|
+ *list = data.list;
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+block_list_dump (IBusUnicodeBlock *block,
|
|
+ GString *buff)
|
|
+{
|
|
+ g_return_if_fail (buff != NULL);
|
|
+
|
|
+ g_string_append (buff, " /* TRANSLATORS: You might refer the " \
|
|
+ "translations from gucharmap with\n" \
|
|
+ " 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));
|
|
+ g_string_append (buff, line);
|
|
+}
|
|
+
|
|
+static void
|
|
+ucd_block_translatable_save (const gchar *filename,
|
|
+ GSList *blocks_list)
|
|
+{
|
|
+ gchar *content = NULL;
|
|
+ gsize length = 0;
|
|
+ GError *error = NULL;
|
|
+ gchar *p;
|
|
+ GString *buff = NULL;
|
|
+ int i;
|
|
+ GSList *list = blocks_list;
|
|
+
|
|
+ g_return_if_fail (filename != NULL);
|
|
+ g_return_if_fail (list != NULL);
|
|
+
|
|
+ if (!g_file_get_contents (__FILE__, &content, &length, &error)) {
|
|
+ g_warning ("Failed to load %s: %s", __FILE__, error->message);
|
|
+ g_clear_pointer (&error, g_error_free);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ buff = g_string_new (NULL);
|
|
+ p = content;
|
|
+ for (i = 0; i < LICENSE_LINES; i++, p++) {
|
|
+ if ((p = strchr (p, '\n')) == NULL)
|
|
+ break;
|
|
+ }
|
|
+ if (p != NULL) {
|
|
+ g_string_append (buff, g_strndup (content, p - content));
|
|
+ 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_slist_foreach (list, (GFunc)block_list_dump, buff);
|
|
+ g_string_append (buff, g_strdup ("};\n"));
|
|
+ g_string_append (buff, g_strdup ("#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_error_free (error);
|
|
+ }
|
|
+
|
|
+ g_string_free (buff, TRUE);
|
|
+}
|
|
+
|
|
+int
|
|
+main (int argc, char *argv[])
|
|
+{
|
|
+ gchar *prgname;
|
|
+ gchar *input_names_list = NULL;
|
|
+ gchar *input_blocks = NULL;
|
|
+ gchar *output_names_list = NULL;
|
|
+ gchar *output_blocks = NULL;
|
|
+ gchar *output_blocks_trans = NULL;
|
|
+ GOptionEntry entries[] = {
|
|
+ { "input-names-list", 'n', 0, G_OPTION_ARG_STRING, &input_names_list,
|
|
+ "Parse NamesList.txt FILE in unicode.org ",
|
|
+ "FILE"
|
|
+ },
|
|
+ { "input-blocks", 'b', 0, G_OPTION_ARG_STRING, &input_blocks,
|
|
+ "Parse Blocks.txt FILE in unicode.org ",
|
|
+ "FILE"
|
|
+ },
|
|
+ { "output-names-list", 'o', 0, G_OPTION_ARG_STRING, &output_names_list,
|
|
+ "Save the Unicode data as FILE",
|
|
+ "FILE"
|
|
+ },
|
|
+ { "output-blocks", 'B', 0, G_OPTION_ARG_STRING, &output_blocks,
|
|
+ "Save the Unicode block list as FILE",
|
|
+ "FILE"
|
|
+ },
|
|
+ { "output-blocks-trans", 'C', 0, G_OPTION_ARG_STRING,
|
|
+ &output_blocks_trans,
|
|
+ "Save the translatable Unicode blocks as FILE",
|
|
+ "FILE"
|
|
+ },
|
|
+ { NULL }
|
|
+ };
|
|
+ GOptionContext *context;
|
|
+ GError *error = NULL;
|
|
+ GSList *names_list = NULL;
|
|
+ GSList *blocks_list = NULL;
|
|
+
|
|
+#ifdef HAVE_LOCALE_H
|
|
+ /* To output emoji warnings. */
|
|
+ setlocale (LC_ALL, "");
|
|
+#endif
|
|
+
|
|
+ prgname = g_path_get_basename (argv[0]);
|
|
+ g_set_prgname (prgname);
|
|
+ g_free (prgname);
|
|
+
|
|
+ context = g_option_context_new (NULL);
|
|
+ g_option_context_add_main_entries (context, entries, NULL);
|
|
+
|
|
+ if (argc < 3) {
|
|
+ g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
|
|
+ g_option_context_free (context);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
|
+ g_warning ("Failed options: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ return -1;
|
|
+ }
|
|
+ g_option_context_free (context);
|
|
+
|
|
+ if (input_names_list) {
|
|
+ ucd_parse_file (input_names_list, &names_list, UCD_NAMES_LIST);
|
|
+ g_free (input_names_list);
|
|
+ }
|
|
+ if (output_names_list && names_list)
|
|
+ ibus_unicode_data_save (output_names_list, names_list);
|
|
+ g_free (output_names_list);
|
|
+
|
|
+ if (input_blocks) {
|
|
+ ucd_parse_file (input_blocks, &blocks_list, UCD_BLOCKS);
|
|
+ g_free (input_blocks);
|
|
+ }
|
|
+ if (output_blocks && blocks_list)
|
|
+ ibus_unicode_block_save (output_blocks, blocks_list);
|
|
+ if (output_blocks_trans && blocks_list)
|
|
+ ucd_block_translatable_save (output_blocks_trans, blocks_list);
|
|
+ g_free (output_blocks);
|
|
+
|
|
+ g_free (unicode_version);
|
|
+ return 0;
|
|
+}
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index f3e9f15c..555ea68f 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -2,7 +2,7 @@
|
|
*
|
|
* ibus - The Input Bus
|
|
*
|
|
- * Copyright (c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (c) 2017-2018 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
|
|
@@ -20,7 +20,7 @@
|
|
* USA
|
|
*/
|
|
|
|
-class IBusEmojier : Gtk.ApplicationWindow {
|
|
+public class IBusEmojier : Gtk.ApplicationWindow {
|
|
private class EEntry : Gtk.SearchEntry {
|
|
public EEntry() {
|
|
GLib.Object(
|
|
@@ -99,15 +99,70 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
}
|
|
}
|
|
private class EWhiteLabel : Gtk.Label {
|
|
+ private int m_minimum_width = 0;
|
|
+ private int m_natural_width = 0;
|
|
+ private int m_minimum_height = 0;
|
|
+ private int m_natural_height = 0;
|
|
public EWhiteLabel(string text) {
|
|
GLib.Object(
|
|
name : "IBusEmojierWhiteLabel"
|
|
);
|
|
- if (text != "")
|
|
- set_label(text);
|
|
+ set_label(text);
|
|
+ }
|
|
+ public override void get_preferred_width(out int minimum_width,
|
|
+ out int natural_width) {
|
|
+ if (m_minimum_height == 0 && m_natural_height == 0) {
|
|
+ base.get_preferred_height(out m_minimum_height,
|
|
+ out m_natural_height);
|
|
+ }
|
|
+ var text = get_label();
|
|
+ var ch = text.get_char();
|
|
+ if (text.length == 1 && ch == '\t') {
|
|
+ m_minimum_width = minimum_width = m_minimum_height;
|
|
+ m_natural_width = natural_width = m_natural_height;
|
|
+ return;
|
|
+ }
|
|
+ base.get_preferred_width(out minimum_width, out natural_width);
|
|
+ if (text.length == 1 && (ch == '\n' || ch == '\r')) {
|
|
+ minimum_width /= 2;
|
|
+ natural_width /= 2;
|
|
+ m_minimum_width = minimum_width;
|
|
+ m_natural_width = natural_width;
|
|
+ return;
|
|
+ }
|
|
+ if (minimum_width < m_minimum_height)
|
|
+ minimum_width = m_minimum_height;
|
|
+ if (natural_width < m_natural_height)
|
|
+ natural_width = m_natural_height;
|
|
+ m_minimum_width = minimum_width;
|
|
+ m_natural_width = natural_width;
|
|
+ }
|
|
+ public override void get_preferred_height(out int minimum_height,
|
|
+ out int natural_height) {
|
|
+ if (m_minimum_width == 0 && m_natural_width == 0) {
|
|
+ base.get_preferred_width(out m_minimum_width,
|
|
+ out m_natural_width);
|
|
+ }
|
|
+ var text = get_label();
|
|
+ var ch = text.get_char();
|
|
+ if (text.length == 1 && ch == '\v') {
|
|
+ m_minimum_height = minimum_height = m_minimum_width;
|
|
+ m_natural_height = natural_height = m_natural_width;
|
|
+ return;
|
|
+ }
|
|
+ base.get_preferred_height(out minimum_height, out natural_height);
|
|
+ if (text.length == 1 && (ch == '\n' || ch == '\r')) {
|
|
+ minimum_height /= 2;
|
|
+ natural_height /= 2;
|
|
+ m_minimum_height = minimum_height;
|
|
+ m_natural_height = natural_height;
|
|
+ return;
|
|
+ }
|
|
+ m_minimum_height = minimum_height;
|
|
+ m_natural_height = natural_height;
|
|
}
|
|
}
|
|
- private class ESelectedLabel : Gtk.Label {
|
|
+ private class ESelectedLabel : EWhiteLabel {
|
|
public ESelectedLabel(string text) {
|
|
GLib.Object(
|
|
name : "IBusEmojierSelectedLabel"
|
|
@@ -116,7 +171,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
set_label(text);
|
|
}
|
|
}
|
|
- private class EGoldLabel : Gtk.Label {
|
|
+ private class EGoldLabel : EWhiteLabel {
|
|
public EGoldLabel(string text) {
|
|
GLib.Object(
|
|
name : "IBusEmojierGoldLabel"
|
|
@@ -167,6 +222,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
}
|
|
private class ETitleLabelBox : Gtk.HeaderBar {
|
|
private Gtk.Label m_lang_label;
|
|
+ private Gtk.Label m_title_label;
|
|
|
|
public ETitleLabelBox(string title) {
|
|
GLib.Object(
|
|
@@ -177,9 +233,9 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
);
|
|
var vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
|
|
set_custom_title(vbox);
|
|
- var label = new Gtk.Label(title);
|
|
- label.get_style_context().add_class(Gtk.STYLE_CLASS_TITLE);
|
|
- vbox.pack_start(label, true, false, 0);
|
|
+ m_title_label = new Gtk.Label(title);
|
|
+ m_title_label.get_style_context().add_class(Gtk.STYLE_CLASS_TITLE);
|
|
+ vbox.pack_start(m_title_label, true, false, 0);
|
|
m_lang_label = new Gtk.Label(null);
|
|
m_lang_label.get_style_context().add_class(
|
|
Gtk.STYLE_CLASS_SUBTITLE);
|
|
@@ -194,10 +250,19 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
menu_button.set_tooltip_text(_("Menu"));
|
|
pack_end(menu_button);
|
|
}
|
|
+ public new void set_title(string title) {
|
|
+ m_title_label.set_text(title);
|
|
+ }
|
|
public void set_lang_label(string str) {
|
|
m_lang_label.set_text(str);
|
|
}
|
|
}
|
|
+ private class LoadProgressObject : GLib.Object {
|
|
+ public LoadProgressObject() {
|
|
+ }
|
|
+ public signal void deserialize_unicode(uint done, uint total);
|
|
+ }
|
|
+
|
|
|
|
private enum TravelDirection {
|
|
NONE,
|
|
@@ -207,6 +272,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
private const uint EMOJI_GRID_PAGE = 10;
|
|
private const string EMOJI_CATEGORY_FAVORITES = N_("Favorites");
|
|
private const string EMOJI_CATEGORY_OTHERS = N_("Others");
|
|
+ private const string EMOJI_CATEGORY_UNICODE = N_("Open Unicode choice");
|
|
private const unichar[] EMOJI_VARIANT_LIST = {
|
|
0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff, 0x200d };
|
|
|
|
@@ -223,6 +289,8 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
private static uint m_partial_match_length;
|
|
private static uint m_partial_match_condition;
|
|
private static bool m_show_emoji_variant = false;
|
|
+ private static int m_default_window_width;
|
|
+ private static int m_default_window_height;
|
|
private static GLib.HashTable<string, GLib.SList<string>>?
|
|
m_annotation_to_emojis_dict;
|
|
private static GLib.HashTable<string, IBus.EmojiData>?
|
|
@@ -231,6 +299,14 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
m_category_to_emojis_dict;
|
|
private static GLib.HashTable<string, GLib.SList<string>>?
|
|
m_emoji_to_emoji_variants_dict;
|
|
+ private static GLib.HashTable<unichar, IBus.UnicodeData>?
|
|
+ m_unicode_to_data_dict;
|
|
+ private static GLib.HashTable<string, GLib.SList<unichar>>?
|
|
+ m_name_to_unicodes_dict;
|
|
+ private static GLib.SList<IBus.UnicodeBlock> m_unicode_block_list;
|
|
+ private static bool m_show_unicode = false;
|
|
+ private static LoadProgressObject m_unicode_progress_object;
|
|
+ private static bool m_loaded_unicode = false;
|
|
|
|
private ThemedRGBA m_rgba;
|
|
private Gtk.Box m_vbox;
|
|
@@ -246,7 +322,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
private string? m_result;
|
|
private string? m_unicode_point = null;
|
|
private bool m_candidate_panel_is_visible;
|
|
- private int m_category_active_index;
|
|
+ private int m_category_active_index = -1;
|
|
private IBus.LookupTable m_lookup_table;
|
|
private Gtk.Label[] m_candidates;
|
|
private bool m_enter_notify_enable = true;
|
|
@@ -254,6 +330,9 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
private uint m_entry_notify_disable_id;
|
|
protected static double m_mouse_x;
|
|
protected static double m_mouse_y;
|
|
+ private Gtk.ProgressBar m_unicode_progress_bar;
|
|
+ private Gtk.Label m_unicode_percent_label;
|
|
+ private double m_unicode_percent;
|
|
|
|
public signal void candidate_clicked(uint index, uint button, uint state);
|
|
|
|
@@ -402,6 +481,8 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
if (m_annotation_to_emojis_dict == null) {
|
|
reload_emoji_dict();
|
|
}
|
|
+
|
|
+ get_load_progress_object();
|
|
}
|
|
|
|
|
|
@@ -433,6 +514,13 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
m_emoji_to_emoji_variants_dict =
|
|
new GLib.HashTable<string, GLib.SList<string>>(GLib.str_hash,
|
|
GLib.str_equal);
|
|
+ m_unicode_to_data_dict =
|
|
+ new GLib.HashTable<unichar, IBus.UnicodeData>(
|
|
+ GLib.direct_hash,
|
|
+ GLib.direct_equal);
|
|
+ m_name_to_unicodes_dict =
|
|
+ new GLib.HashTable<string, GLib.SList<unichar>>(GLib.str_hash,
|
|
+ GLib.str_equal);
|
|
}
|
|
|
|
|
|
@@ -482,6 +570,10 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
private static string utf8_code_point(string str) {
|
|
var buff = new GLib.StringBuilder();
|
|
int length = str.char_count();
|
|
+ if (length == 0) {
|
|
+ buff.append("U+%04X".printf(0));
|
|
+ return buff.str;
|
|
+ }
|
|
for (int i = 0; i < length; i++) {
|
|
unichar ch = str.get_char(0);
|
|
if (i == 0)
|
|
@@ -644,6 +736,72 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
}
|
|
|
|
|
|
+ private static void make_unicode_block_dict() {
|
|
+ m_unicode_block_list = IBus.UnicodeBlock.load(
|
|
+ Config.PKGDATADIR + "/dicts/unicode-blocks.dict");
|
|
+ foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
+ unowned string name = block.get_name();
|
|
+ if (m_emoji_max_seq_len < name.length)
|
|
+ m_emoji_max_seq_len = name.length;
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ private static void make_unicode_name_dict(Object source_object) {
|
|
+ IBus.UnicodeData.load_async(
|
|
+ Config.PKGDATADIR + "/dicts/unicode-names.dict",
|
|
+ source_object,
|
|
+ null,
|
|
+ (IBus.UnicodeDataLoadAsyncFinish)make_unicode_name_dict_finish);
|
|
+ }
|
|
+
|
|
+ private static void
|
|
+ make_unicode_name_dict_finish(GLib.SList<IBus.UnicodeData> unicode_list) {
|
|
+ if (unicode_list == null)
|
|
+ return;
|
|
+ foreach (IBus.UnicodeData data in unicode_list) {
|
|
+ update_unicode_to_data_dict(data);
|
|
+ update_name_to_unicodes_dict(data);
|
|
+ }
|
|
+ GLib.List<unowned string> names =
|
|
+ m_name_to_unicodes_dict.get_keys();
|
|
+ foreach (unowned string name in names) {
|
|
+ if (m_emoji_max_seq_len < name.length)
|
|
+ m_emoji_max_seq_len = name.length;
|
|
+ }
|
|
+ m_loaded_unicode = true;
|
|
+ }
|
|
+
|
|
+
|
|
+ private static void update_unicode_to_data_dict(IBus.UnicodeData data) {
|
|
+ unichar code = data.get_code();
|
|
+ m_unicode_to_data_dict.replace(code, data);
|
|
+ }
|
|
+
|
|
+
|
|
+ private static void update_name_to_unicodes_dict(IBus.UnicodeData data) {
|
|
+ unichar code = data.get_code();
|
|
+ string[] names = {data.get_name().down(), data.get_alias().down()};
|
|
+ foreach (unowned string name in names) {
|
|
+ if (name == "")
|
|
+ continue;
|
|
+ bool has_code = false;
|
|
+ GLib.SList<unichar> hits =
|
|
+ m_name_to_unicodes_dict.lookup(name).copy();
|
|
+ foreach (unichar hit_code in hits) {
|
|
+ if (hit_code == code) {
|
|
+ has_code = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (!has_code) {
|
|
+ hits.append(code);
|
|
+ m_name_to_unicodes_dict.replace(name, hits.copy());
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
private void set_fixed_size() {
|
|
resize(20, 1);
|
|
}
|
|
@@ -665,6 +823,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
m_scrolled_window = new EScrolledWindow();
|
|
set_fixed_size();
|
|
|
|
+ m_title.set_title(_("Emoji Choice"));
|
|
string language =
|
|
IBus.get_language_name(m_current_lang_id);
|
|
m_title.set_lang_label(language);
|
|
@@ -677,12 +836,12 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
Gtk.Adjustment adjustment = m_scrolled_window.get_vadjustment();
|
|
m_list_box.set_adjustment(adjustment);
|
|
m_list_box.row_activated.connect((box, gtkrow) => {
|
|
- m_category_active_index = 0;
|
|
+ m_category_active_index = -1;
|
|
EBoxRow row = gtkrow as EBoxRow;
|
|
show_emoji_for_category(row.text);
|
|
});
|
|
|
|
- uint n = 1;
|
|
+ uint n = 0;
|
|
if (m_favorites.length > 0) {
|
|
EBoxRow row = new EBoxRow(EMOJI_CATEGORY_FAVORITES);
|
|
EPaddedLabelBox widget =
|
|
@@ -716,9 +875,19 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
if (n++ == m_category_active_index)
|
|
m_list_box.select_row(row);
|
|
}
|
|
+ if (m_unicode_block_list.length() > 0) {
|
|
+ EBoxRow row = new EBoxRow(EMOJI_CATEGORY_UNICODE);
|
|
+ EPaddedLabelBox widget =
|
|
+ new EPaddedLabelBox(_(EMOJI_CATEGORY_UNICODE),
|
|
+ Gtk.Align.CENTER);
|
|
+ row.add(widget);
|
|
+ m_list_box.add(row);
|
|
+ if (n++ == m_category_active_index)
|
|
+ m_list_box.select_row(row);
|
|
+ }
|
|
|
|
m_scrolled_window.show_all();
|
|
- if (m_category_active_index == 0)
|
|
+ if (m_category_active_index == -1)
|
|
m_list_box.unselect_all();
|
|
m_list_box.invalidate_filter();
|
|
m_list_box.set_selection_mode(Gtk.SelectionMode.SINGLE);
|
|
@@ -733,6 +902,11 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
m_lookup_table.append_candidate(text);
|
|
}
|
|
m_backward = category;
|
|
+ } else if (category == EMOJI_CATEGORY_UNICODE) {
|
|
+ m_category_active_index = -1;
|
|
+ m_show_unicode = true;
|
|
+ show_unicode_blocks();
|
|
+ return;
|
|
} else {
|
|
unowned GLib.SList<unowned string> emojis =
|
|
m_category_to_emojis_dict.lookup(category);
|
|
@@ -764,6 +938,126 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
}
|
|
|
|
|
|
+ private void show_unicode_blocks() {
|
|
+ m_show_unicode = true;
|
|
+ if (m_default_window_width == 0 && m_default_window_height == 0)
|
|
+ get_size(out m_default_window_width, out m_default_window_height);
|
|
+ remove_all_children();
|
|
+ set_fixed_size();
|
|
+
|
|
+ m_title.set_title(_("Unicode Choice"));
|
|
+ EPaddedLabelBox label =
|
|
+ new EPaddedLabelBox(_("Bring back emoji choice"),
|
|
+ Gtk.Align.CENTER,
|
|
+ TravelDirection.BACKWARD);
|
|
+ Gtk.Button button = new Gtk.Button();
|
|
+ button.add(label);
|
|
+ m_vbox.add(button);
|
|
+ button.show_all();
|
|
+ button.button_press_event.connect((w, e) => {
|
|
+ m_category_active_index = -1;
|
|
+ m_show_unicode = false;
|
|
+ hide_candidate_panel();
|
|
+ return true;
|
|
+ });
|
|
+ m_scrolled_window = new EScrolledWindow();
|
|
+ m_title.set_lang_label("");
|
|
+ m_vbox.add(m_scrolled_window);
|
|
+ Gtk.Viewport viewport = new Gtk.Viewport(null, null);
|
|
+ m_scrolled_window.add(viewport);
|
|
+
|
|
+ m_list_box = new EListBox();
|
|
+ viewport.add(m_list_box);
|
|
+ Gtk.Adjustment adjustment = m_scrolled_window.get_vadjustment();
|
|
+ m_list_box.set_adjustment(adjustment);
|
|
+ m_list_box.row_activated.connect((box, gtkrow) => {
|
|
+ m_category_active_index = -1;
|
|
+ EBoxRow row = gtkrow as EBoxRow;
|
|
+ show_unicode_for_block(row.text);
|
|
+ });
|
|
+
|
|
+ uint n = 0;
|
|
+ foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
+ string name = block.get_name();
|
|
+ EBoxRow row = new EBoxRow(name);
|
|
+ EPaddedLabelBox widget =
|
|
+ new EPaddedLabelBox(_(name), Gtk.Align.CENTER);
|
|
+ row.add(widget);
|
|
+ m_list_box.add(row);
|
|
+ if (n++ == m_category_active_index) {
|
|
+ m_list_box.select_row(row);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ set_size_request(-1, m_default_window_height + 100);
|
|
+ m_scrolled_window.set_policy(Gtk.PolicyType.NEVER,
|
|
+ Gtk.PolicyType.AUTOMATIC);
|
|
+ m_scrolled_window.show_all();
|
|
+ if (m_category_active_index == -1)
|
|
+ m_list_box.unselect_all();
|
|
+ m_list_box.invalidate_filter();
|
|
+ m_list_box.set_selection_mode(Gtk.SelectionMode.SINGLE);
|
|
+ }
|
|
+
|
|
+ private void show_unicode_for_block(string block_name) {
|
|
+ if (!m_loaded_unicode) {
|
|
+ remove_all_children();
|
|
+ set_fixed_size();
|
|
+ m_unicode_progress_bar = new Gtk.ProgressBar();
|
|
+ m_unicode_progress_bar.set_ellipsize(Pango.EllipsizeMode.MIDDLE);
|
|
+ m_unicode_progress_bar.set_halign(Gtk.Align.CENTER);
|
|
+ m_unicode_progress_bar.set_valign(Gtk.Align.CENTER);
|
|
+ m_vbox.add(m_unicode_progress_bar);
|
|
+ m_unicode_progress_bar.show();
|
|
+ var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
|
|
+ hbox.set_halign(Gtk.Align.CENTER);
|
|
+ hbox.set_valign(Gtk.Align.CENTER);
|
|
+ m_vbox.add(hbox);
|
|
+ var label = new Gtk.Label(_("Loading a Unicode dictionary:"));
|
|
+ hbox.pack_start(label, false, true, 0);
|
|
+ m_unicode_percent_label = new Gtk.Label("");
|
|
+ hbox.pack_start(m_unicode_percent_label, false, true, 0);
|
|
+ hbox.show_all();
|
|
+
|
|
+ m_unicode_progress_object.deserialize_unicode.connect((i, n) => {
|
|
+ m_unicode_percent = (double)i / n;
|
|
+ });
|
|
+ GLib.Timeout.add(100, () => {
|
|
+ m_unicode_progress_bar.set_fraction(m_unicode_percent);
|
|
+ m_unicode_percent_label.set_text(
|
|
+ "%.0f%%\n".printf(m_unicode_percent * 100));
|
|
+ m_unicode_progress_bar.show();
|
|
+ m_unicode_percent_label.show();
|
|
+ if (m_loaded_unicode) {
|
|
+ show_unicode_for_block(block_name);
|
|
+ }
|
|
+ return !m_loaded_unicode;
|
|
+ });
|
|
+ return;
|
|
+ }
|
|
+ unichar start = 0;
|
|
+ unichar end = 0;
|
|
+ foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
+ string name = block.get_name();
|
|
+ if (block_name == name) {
|
|
+ start = block.get_start();
|
|
+ end = block.get_end();
|
|
+ }
|
|
+ }
|
|
+ m_lookup_table.clear();
|
|
+ for (unichar ch = start; ch < end; ch++) {
|
|
+ unowned IBus.UnicodeData? data =
|
|
+ m_unicode_to_data_dict.lookup(ch);
|
|
+ if (data == null)
|
|
+ continue;
|
|
+ IBus.Text text = new IBus.Text.from_unichar(ch);
|
|
+ m_lookup_table.append_candidate(text);
|
|
+ }
|
|
+ m_backward = block_name;
|
|
+ show_candidate_panel();
|
|
+ }
|
|
+
|
|
+
|
|
private void show_arrow_buttons() {
|
|
Gtk.Button next_button = new Gtk.Button();
|
|
next_button.clicked.connect(() => {
|
|
@@ -840,6 +1134,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
lookup_emojis_from_annotation(string annotation) {
|
|
GLib.SList<string>? total_emojis = null;
|
|
unowned GLib.SList<string>? sub_emojis = null;
|
|
+ unowned GLib.SList<unichar>? sub_unicodes = null;
|
|
int length = annotation.length;
|
|
if (m_has_partial_match && length >= m_partial_match_length) {
|
|
foreach (unowned string key in
|
|
@@ -877,6 +1172,22 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
foreach (unowned string emoji in sub_emojis)
|
|
total_emojis.append(emoji);
|
|
}
|
|
+ if (length >= m_partial_match_length) {
|
|
+ foreach (unowned string key in m_name_to_unicodes_dict.get_keys()) {
|
|
+ bool matched = false;
|
|
+ if (key.index_of(annotation) >= 0)
|
|
+ matched = true;
|
|
+ if (!matched)
|
|
+ continue;
|
|
+ sub_unicodes = m_name_to_unicodes_dict.lookup(key);
|
|
+ foreach (unichar code in sub_unicodes) {
|
|
+ string ch = code.to_string();
|
|
+ if (total_emojis.find_custom(ch, GLib.strcmp) == null) {
|
|
+ total_emojis.append(ch);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
return total_emojis;
|
|
}
|
|
|
|
@@ -1049,58 +1360,99 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
grid.show_all();
|
|
string text = m_lookup_table.get_candidate(cursor).text;
|
|
unowned IBus.EmojiData? data = m_emoji_to_data_dict.lookup(text);
|
|
- if (data == null) {
|
|
- // TODO: Provide a custom description and annotation for
|
|
- // the favorite emojis.
|
|
- EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
- _("Description: %s").printf(_("None")),
|
|
- Gtk.Align.START);
|
|
- m_vbox.add(widget);
|
|
- widget.show_all();
|
|
- show_code_point_description(text);
|
|
+ if (data != null) {
|
|
+ show_emoji_description(data, text);
|
|
return;
|
|
- } else {
|
|
- unowned string description = data.get_description();
|
|
- EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
- _("Description: %s").printf(description),
|
|
- Gtk.Align.START);
|
|
- m_vbox.add(widget);
|
|
- widget.show_all();
|
|
}
|
|
- unowned GLib.SList<unowned string>? annotations =
|
|
- data.get_annotations();
|
|
- var buff = new GLib.StringBuilder();
|
|
- int i = 0;
|
|
- foreach (unowned string annotation in annotations) {
|
|
- if (i++ == 0)
|
|
- buff.append_printf(_("Annotations: %s"), annotation);
|
|
- else
|
|
- buff.append_printf(" | %s", annotation);
|
|
- if (buff.str.char_count() > 30) {
|
|
- EPaddedLabelBox widget =
|
|
- new EPaddedLabelBox(buff.str,
|
|
- Gtk.Align.START);
|
|
- m_vbox.add(widget);
|
|
- widget.show_all();
|
|
- buff.erase();
|
|
+ if (text.char_count() <= 1) {
|
|
+ unichar code = text.get_char();
|
|
+ unowned IBus.UnicodeData? udata =
|
|
+ m_unicode_to_data_dict.lookup(code);
|
|
+ if (udata != null) {
|
|
+ show_unicode_description(udata, text);
|
|
+ return;
|
|
}
|
|
}
|
|
- if (buff.str != "") {
|
|
- EPaddedLabelBox widget = new EPaddedLabelBox(buff.str,
|
|
- Gtk.Align.START);
|
|
+ // TODO: Provide a custom description and annotation for
|
|
+ // the favorite emojis.
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
+ _("Description: %s").printf(_("None")),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget);
|
|
+ widget.show_all();
|
|
+ show_code_point_description(text);
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ private void show_emoji_description(IBus.EmojiData data,
|
|
+ string text) {
|
|
+ unowned string description = data.get_description();
|
|
+ {
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
+ _("Description: %s").printf(description),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget);
|
|
+ widget.show_all();
|
|
+ }
|
|
+ unowned GLib.SList<unowned string>? annotations =
|
|
+ data.get_annotations();
|
|
+ var buff = new GLib.StringBuilder();
|
|
+ int i = 0;
|
|
+ foreach (unowned string annotation in annotations) {
|
|
+ if (i++ == 0)
|
|
+ buff.append_printf(_("Annotations: %s"), annotation);
|
|
+ else
|
|
+ buff.append_printf(" | %s", annotation);
|
|
+ if (buff.str.char_count() > 30) {
|
|
+ EPaddedLabelBox widget =
|
|
+ new EPaddedLabelBox(buff.str,
|
|
+ Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
widget.show_all();
|
|
+ buff.erase();
|
|
}
|
|
- show_code_point_description(text);
|
|
}
|
|
+ if (buff.str != "") {
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(buff.str,
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget);
|
|
+ widget.show_all();
|
|
+ }
|
|
+ show_code_point_description(text);
|
|
+ }
|
|
+
|
|
+ private void show_unicode_description(IBus.UnicodeData data,
|
|
+ string text) {
|
|
+ unowned string name = data.get_name();
|
|
+ {
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
+ _("Name: %s").printf(name),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget);
|
|
+ widget.show_all();
|
|
+ }
|
|
+ unowned string alias = data.get_alias();
|
|
+ {
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
+ _("Alias: %s").printf(alias),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget);
|
|
+ widget.show_all();
|
|
+ }
|
|
+ show_code_point_description(text);
|
|
}
|
|
|
|
|
|
private void hide_candidate_panel() {
|
|
m_enter_notify_enable = true;
|
|
m_candidate_panel_is_visible = false;
|
|
- if (m_loop.is_running())
|
|
- show_category_list();
|
|
+ if (m_loop.is_running()) {
|
|
+ if (m_show_unicode)
|
|
+ show_unicode_blocks();
|
|
+ else
|
|
+ show_category_list();
|
|
+ }
|
|
}
|
|
|
|
|
|
@@ -1165,19 +1517,41 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
}
|
|
|
|
|
|
- private void category_list_cursor_move(uint keyval) {
|
|
+ private bool category_list_cursor_move(uint keyval) {
|
|
GLib.List<weak Gtk.Widget> list = m_list_box.get_children();
|
|
- if (keyval == Gdk.Key.Down) {
|
|
- m_category_active_index =
|
|
- ++m_category_active_index % ((int)list.length() + 1);
|
|
- } else if (keyval == Gdk.Key.Up) {
|
|
+ int length = (int)list.length();
|
|
+ if (length == 0)
|
|
+ return false;
|
|
+ switch(keyval) {
|
|
+ case Gdk.Key.Down:
|
|
+ if (++m_category_active_index == length)
|
|
+ m_category_active_index = 0;
|
|
+ break;
|
|
+ case Gdk.Key.Up:
|
|
if (--m_category_active_index < 0)
|
|
- m_category_active_index = (int)list.length();
|
|
+ m_category_active_index = length - 1;
|
|
+ break;
|
|
+ case Gdk.Key.Home:
|
|
+ m_category_active_index = 0;
|
|
+ break;
|
|
+ case Gdk.Key.End:
|
|
+ m_category_active_index = length - 1;
|
|
+ break;
|
|
}
|
|
- Gtk.Adjustment adjustment = m_list_box.get_adjustment();
|
|
- m_scrolled_window.set_hadjustment(new Gtk.Adjustment(0, 0, 0, 0, 0, 0));
|
|
- m_scrolled_window.set_vadjustment(adjustment);
|
|
- show_category_list();
|
|
+ var row = m_list_box.get_selected_row();
|
|
+ if (row != null)
|
|
+ m_list_box.unselect_row(row);
|
|
+ if (m_category_active_index >= 0) {
|
|
+ row = m_list_box.get_row_at_index(m_category_active_index);
|
|
+ m_list_box.select_row(row);
|
|
+ } else {
|
|
+ row = m_list_box.get_row_at_index(0);
|
|
+ }
|
|
+ Gtk.Allocation alloc = { 0, 0, 0, 0 };
|
|
+ row.get_allocation(out alloc);
|
|
+ var adjustment = m_scrolled_window.get_vadjustment();
|
|
+ adjustment.clamp_page(alloc.y, alloc.y + alloc.height);
|
|
+ return true;
|
|
}
|
|
|
|
|
|
@@ -1211,7 +1585,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
keyval = Gdk.Key.Up;
|
|
else if (keyval == Gdk.Key.Right)
|
|
keyval = Gdk.Key.Down;
|
|
- category_list_cursor_move(keyval);
|
|
+ return category_list_cursor_move(keyval);
|
|
}
|
|
return true;
|
|
}
|
|
@@ -1227,7 +1601,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
else if (keyval == Gdk.Key.Up)
|
|
candidate_panel_cursor_up();
|
|
} else {
|
|
- category_list_cursor_move(keyval);
|
|
+ return category_list_cursor_move(keyval);
|
|
}
|
|
return true;
|
|
}
|
|
@@ -1262,12 +1636,25 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
? true : false);
|
|
return true;
|
|
}
|
|
+ if (!m_candidate_panel_is_visible)
|
|
+ return category_list_cursor_move(keyval);
|
|
return false;
|
|
}
|
|
|
|
|
|
private bool key_press_escape() {
|
|
- if (m_backward_index >= 0 && m_backward != null) {
|
|
+ if (m_show_unicode) {
|
|
+ if (m_candidate_panel_is_visible) {
|
|
+ m_candidate_panel_is_visible = false;
|
|
+ show_unicode_blocks();
|
|
+ return true;
|
|
+ } else {
|
|
+ m_show_unicode = false;
|
|
+ m_category_active_index = -1;
|
|
+ hide_candidate_panel();
|
|
+ return true;
|
|
+ }
|
|
+ } else if (m_backward_index >= 0 && m_backward != null) {
|
|
show_emoji_for_category(m_backward);
|
|
return true;
|
|
} else if (m_candidate_panel_is_visible) {
|
|
@@ -1287,10 +1674,13 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
if (m_candidate_panel_is_visible) {
|
|
uint index = m_lookup_table.get_cursor_pos();
|
|
candidate_panel_select_index(index);
|
|
- } else if (m_category_active_index > 0) {
|
|
+ } else if (m_category_active_index >= 0) {
|
|
Gtk.ListBoxRow gtkrow = m_list_box.get_selected_row();
|
|
EBoxRow row = gtkrow as EBoxRow;
|
|
- show_emoji_for_category(row.text);
|
|
+ if (m_show_unicode)
|
|
+ show_unicode_for_block(row.text);
|
|
+ else
|
|
+ show_emoji_for_category(row.text);
|
|
}
|
|
return true;
|
|
}
|
|
@@ -1380,6 +1770,7 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
m_candidate_panel_is_visible = false;
|
|
m_result = null;
|
|
m_enter_notify_enable = true;
|
|
+ m_show_unicode = false;
|
|
|
|
/* Let gtk recalculate the window size. */
|
|
resize(1, 1);
|
|
@@ -1399,8 +1790,9 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
* prevention logic:
|
|
* https://mail.gnome.org/archives/gtk-devel-list/2017-May/msg00026.html
|
|
*/
|
|
- uint32 timestamp = event.get_time();
|
|
- present_with_time(timestamp);
|
|
+ //uint32 timestamp = event.get_time();
|
|
+ //present_with_time(timestamp);
|
|
+ present_centralize(event);
|
|
|
|
Gdk.Device pointer;
|
|
#if VALA_0_34
|
|
@@ -1646,18 +2038,24 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
Gtk.Allocation allocation;
|
|
get_allocation(out allocation);
|
|
Gdk.Rectangle monitor_area;
|
|
+ Gdk.Rectangle work_area;
|
|
#if VALA_0_34
|
|
Gdk.Display display = Gdk.Display.get_default();
|
|
Gdk.Monitor monitor = display.get_monitor_at_window(this.get_window());
|
|
monitor_area = monitor.get_geometry();
|
|
+ work_area = monitor.get_workarea();
|
|
#else
|
|
Gdk.Screen screen = Gdk.Screen.get_default();
|
|
int monitor_num = screen.get_monitor_at_window(this.get_window());
|
|
screen.get_monitor_geometry(monitor_num, out monitor_area);
|
|
+ work_area = screen.get_monitor_workarea(monitor_num);
|
|
#endif
|
|
int x = (monitor_area.x + monitor_area.width - allocation.width)/2;
|
|
int y = (monitor_area.y + monitor_area.height
|
|
- allocation.height)/2;
|
|
+ // Do not hide a bottom panel in XFCE4
|
|
+ if (work_area.y < y)
|
|
+ y = work_area.y;
|
|
move(x, y);
|
|
|
|
uint32 timestamp = event.get_time();
|
|
@@ -1723,7 +2121,6 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
string? favorite = unowned_favorites[i];
|
|
// Avoid gsetting value error by manual setting
|
|
GLib.return_if_fail(favorite != null);
|
|
- GLib.return_if_fail(favorite != "");
|
|
m_favorites += favorite;
|
|
}
|
|
for(int i = 0; i < unowned_favorite_annotations.length; i++) {
|
|
@@ -1733,4 +2130,19 @@ class IBusEmojier : Gtk.ApplicationWindow {
|
|
}
|
|
update_favorite_emoji_dict();
|
|
}
|
|
+
|
|
+
|
|
+ private static GLib.Object get_load_progress_object() {
|
|
+ if (m_unicode_progress_object == null)
|
|
+ m_unicode_progress_object = new LoadProgressObject();
|
|
+ return m_unicode_progress_object as GLib.Object;
|
|
+ }
|
|
+
|
|
+
|
|
+ public static void load_unicode_dict() {
|
|
+ if (m_unicode_block_list.length() == 0)
|
|
+ make_unicode_block_dict();
|
|
+ if (m_name_to_unicodes_dict.size() == 0)
|
|
+ make_unicode_name_dict(IBusEmojier.get_load_progress_object());
|
|
+ }
|
|
}
|
|
diff --git a/ui/gtk3/emojierapp.vala b/ui/gtk3/emojierapp.vala
|
|
index 6615f22b..d816352e 100644
|
|
--- a/ui/gtk3/emojierapp.vala
|
|
+++ b/ui/gtk3/emojierapp.vala
|
|
@@ -176,6 +176,8 @@ public class EmojiApplication : Application {
|
|
m_settings_emoji.get_strv("favorites"),
|
|
m_settings_emoji.get_strv("favorite-annotations"));
|
|
|
|
+ IBusEmojier.load_unicode_dict();
|
|
+
|
|
activate_dialog(command_line);
|
|
|
|
return Posix.EXIT_SUCCESS;
|
|
diff --git a/ui/gtk3/ibusemojidialog.h b/ui/gtk3/ibusemojidialog.h
|
|
index ed8886a8..3b420b21 100644
|
|
--- a/ui/gtk3/ibusemojidialog.h
|
|
+++ b/ui/gtk3/ibusemojidialog.h
|
|
@@ -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 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2017-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2017 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -196,5 +196,12 @@ void ibus_emojier_set_partial_match_length
|
|
*/
|
|
void ibus_emojier_set_partial_match_condition
|
|
(gint condition);
|
|
+/**
|
|
+ * ibus_emojier_load_unicode_dict:
|
|
+ *
|
|
+ * Load the dictionary of #IBusUnicodeData.
|
|
+ */
|
|
+void ibus_emojier_load_unicode_dict (void);
|
|
+
|
|
G_END_DECLS
|
|
#endif
|
|
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
|
index 4f032f6f..bcb3ed75 100644
|
|
--- a/ui/gtk3/panel.vala
|
|
+++ b/ui/gtk3/panel.vala
|
|
@@ -3,7 +3,7 @@
|
|
* ibus - The Input Bus
|
|
*
|
|
* Copyright(c) 2011-2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright(c) 2015-2017 Takao Fujwiara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright(c) 2015-2018 Takao Fujwiara <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
|
|
@@ -871,6 +871,7 @@ class Panel : IBus.PanelService {
|
|
IBusEmojier.set_annotation_lang(
|
|
m_settings_emoji.get_string("lang"));
|
|
m_emojier_set_emoji_lang_id = 0;
|
|
+ IBusEmojier.load_unicode_dict();
|
|
return false;
|
|
});
|
|
}
|
|
--
|
|
2.14.3
|
|
|
|
From 4cfd5ad7c6d071cfef6c7d678cc027ea480b8fc9 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Tue, 6 Feb 2018 11:02:09 +0900
|
|
Subject: [PATCH] Fix typo in ibusunicode.c
|
|
|
|
Review URL: https://codereview.appspot.com/340740043
|
|
---
|
|
src/ibusunicode.c | 5 +++--
|
|
ui/gtk3/emojier.vala | 4 ----
|
|
2 files changed, 3 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/ibusunicode.c b/src/ibusunicode.c
|
|
index 8559819d..aac9c135 100644
|
|
--- a/src/ibusunicode.c
|
|
+++ b/src/ibusunicode.c
|
|
@@ -412,7 +412,8 @@ ibus_unicode_data_list_deserialize (GVariant *variant,
|
|
IBUS_UNICODE_DESERIALIZE_SIGNALL_STR,
|
|
G_OBJECT_TYPE (source_object));
|
|
if (!has_signal) {
|
|
- const gchar type_name = g_type_name (source_object);
|
|
+ const gchar *type_name =
|
|
+ g_type_name (G_OBJECT_TYPE (source_object));
|
|
g_warning ("GObject %s does not have the signal \"%s\"",
|
|
type_name ? type_name : "(null)",
|
|
IBUS_UNICODE_DESERIALIZE_SIGNALL_STR);
|
|
@@ -677,7 +678,7 @@ ibus_unicode_block_class_init (IBusUnicodeBlockClass *class)
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
|
|
|
|
- object_class->destroy = (IBusObjectDestroyFunc) ibus_unicode_data_destroy;
|
|
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_unicode_block_destroy;
|
|
gobject_class->set_property =
|
|
(GObjectSetPropertyFunc) ibus_unicode_block_set_property;
|
|
gobject_class->get_property =
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 555ea68f..0bf34da8 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -1373,8 +1373,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
|
|
return;
|
|
}
|
|
}
|
|
- // TODO: Provide a custom description and annotation for
|
|
- // the favorite emojis.
|
|
EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
_("Description: %s").printf(_("None")),
|
|
Gtk.Align.START);
|
|
@@ -1790,8 +1788,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
|
|
* prevention logic:
|
|
* https://mail.gnome.org/archives/gtk-devel-list/2017-May/msg00026.html
|
|
*/
|
|
- //uint32 timestamp = event.get_time();
|
|
- //present_with_time(timestamp);
|
|
present_centralize(event);
|
|
|
|
Gdk.Device pointer;
|
|
--
|
|
2.14.3
|
|
|
|
From fb07f64764f18f702221ff5574b2fd2193f051f0 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Tue, 20 Feb 2018 17:25:07 +0900
|
|
Subject: [PATCH] Implement ibus-extension-gtk3 for the global keybinding
|
|
|
|
Currently IBus panel (ibus-ui-gtk3) is not available in GNOME and Plasma
|
|
so the emoji and unicode point typings are not available in GNOME and Plasma.
|
|
The workaround `ibus emoji` command is available but it put the selected
|
|
character into the copy buffer and users have to paste the character.
|
|
|
|
Originaly the emoji feature was implemented in IBus GtkIMModule but
|
|
it had several problems; the first is the keybinding is hard-coded
|
|
and IBus GtkIMModule does not use GSettings for the customized settings.
|
|
The second is the feature was available for GTK applications.
|
|
The third is that XKB input sources uses gtk-im-context-simple
|
|
but not ibus in GNOME desktop so users have to add an IM input sources
|
|
to enable IBus for the XKB input sources. The fourth is the feature
|
|
was available for IBusEngineSimple only and other IBus IMEs need to
|
|
inherit that class to get the emoji feature. The fifth is that
|
|
emoji typing is available for English only since IBusEngineSimple
|
|
had the feature. The sixth is that the default one dimension lookup
|
|
window was not useful to choose an emoji and needed two dimensions
|
|
lookup window.
|
|
|
|
And the implementation was moved from IBus GtkIMModule to IBus panel
|
|
to fix above problems.
|
|
But users have to use `ibus emoji` at present if ibus-ui-gtk3
|
|
is not available.
|
|
|
|
Now I think to move the emoji feature from ibus-ui-gtk3 to another
|
|
IBus component; ibus-extension-gtk3 which manages the Ctrl-Shift-e.
|
|
GNOME and Plasma desktops still do not show the GUI menu but
|
|
the shortcut key is available in this implementation.
|
|
|
|
BUG=RHBZ#1430501
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/339300043
|
|
---
|
|
bindings/vala/IBus-1.0-custom.vala | 4 +
|
|
bus/Makefile.am | 7 +-
|
|
bus/ibusimpl.c | 82 ++-
|
|
bus/main.c | 25 +-
|
|
bus/marshalers.list | 1 +
|
|
bus/panelproxy.c | 57 +-
|
|
bus/panelproxy.h | 20 +-
|
|
src/Makefile.am | 4 +-
|
|
src/ibus.h | 1 +
|
|
src/ibusmarshalers.list | 1 +
|
|
src/ibuspanelservice.c | 81 ++-
|
|
src/ibuspanelservice.h | 15 +-
|
|
src/ibusserializable.c | 7 +-
|
|
src/ibusserializable.h | 18 +-
|
|
src/ibusshare.c | 4 +-
|
|
src/ibusshare.h | 17 +-
|
|
src/ibusxevent.c | 1004 ++++++++++++++++++++++++++++++++++++
|
|
src/ibusxevent.h | 294 +++++++++++
|
|
src/tests/runtest | 1 +
|
|
ui/gtk3/Makefile.am | 59 ++-
|
|
ui/gtk3/bindingcommon.vala | 215 ++++++++
|
|
ui/gtk3/candidatearea.vala | 102 ----
|
|
ui/gtk3/extension.vala | 124 +++++
|
|
ui/gtk3/gtkextension.xml.in | 12 +
|
|
ui/gtk3/iconwidget.vala | 103 ++++
|
|
ui/gtk3/panel.vala | 408 +++------------
|
|
ui/gtk3/panelbinding.vala | 335 ++++++++++++
|
|
27 files changed, 2506 insertions(+), 495 deletions(-)
|
|
create mode 100644 src/ibusxevent.c
|
|
create mode 100644 src/ibusxevent.h
|
|
create mode 100644 ui/gtk3/bindingcommon.vala
|
|
create mode 100644 ui/gtk3/extension.vala
|
|
create mode 100644 ui/gtk3/gtkextension.xml.in
|
|
create mode 100644 ui/gtk3/panelbinding.vala
|
|
|
|
diff --git a/bindings/vala/IBus-1.0-custom.vala b/bindings/vala/IBus-1.0-custom.vala
|
|
index 144d75e2..cf1fc3fa 100644
|
|
--- a/bindings/vala/IBus-1.0-custom.vala
|
|
+++ b/bindings/vala/IBus-1.0-custom.vala
|
|
@@ -6,4 +6,8 @@ namespace IBus {
|
|
[CCode (cname = "ibus_text_new_from_static_string", has_construct_function = false)]
|
|
public Text.from_static_string (string str);
|
|
}
|
|
+ public class XEvent : IBus.Serializable {
|
|
+ [CCode (cname = "ibus_x_event_new", has_construct_function = true)]
|
|
+ public XEvent (string first_property_name, ...);
|
|
+ }
|
|
}
|
|
diff --git a/bus/Makefile.am b/bus/Makefile.am
|
|
index 864ba923..8bcc8e16 100644
|
|
--- a/bus/Makefile.am
|
|
+++ b/bus/Makefile.am
|
|
@@ -3,7 +3,8 @@
|
|
# ibus - The Input Bus
|
|
#
|
|
# Copyright (c) 2007-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2007-2013 Red Hat, Inc.
|
|
+# Copyright (c) 2013-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2007-2018 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
|
|
@@ -105,6 +106,10 @@ marshalers.c: marshalers.h marshalers.list
|
|
$(GLIB_GENMARSHAL) --prefix=bus_marshal $(srcdir)/marshalers.list --body --internal) > $@.tmp && \
|
|
mv $@.tmp $@
|
|
|
|
+if ENABLE_EMOJI_DICT
|
|
+AM_CFLAGS += -DEMOJI_DICT
|
|
+endif
|
|
+
|
|
|
|
if ENABLE_TESTS
|
|
TESTS = \
|
|
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
|
|
index f99307ad..58d205cf 100644
|
|
--- a/bus/ibusimpl.c
|
|
+++ b/bus/ibusimpl.c
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2013 Red Hat, Inc.
|
|
+ * Copyright (C) 2011-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -73,6 +74,7 @@ struct _BusIBusImpl {
|
|
|
|
BusInputContext *focused_context;
|
|
BusPanelProxy *panel;
|
|
+ BusPanelProxy *extension;
|
|
|
|
/* a default keymap of ibus-daemon (usually "us") which is used only
|
|
* when use_sys_layout is FALSE. */
|
|
@@ -290,12 +292,37 @@ _panel_destroy_cb (BusPanelProxy *panel,
|
|
g_assert (BUS_IS_PANEL_PROXY (panel));
|
|
g_assert (BUS_IS_IBUS_IMPL (ibus));
|
|
|
|
- g_return_if_fail (ibus->panel == panel);
|
|
-
|
|
- ibus->panel = NULL;
|
|
+ if (ibus->panel == panel)
|
|
+ ibus->panel = NULL;
|
|
+ else if (ibus->extension == panel)
|
|
+ ibus->extension = NULL;
|
|
+ else
|
|
+ g_return_if_reached ();
|
|
g_object_unref (panel);
|
|
}
|
|
|
|
+static void
|
|
+_panel_panel_extension_cb (BusPanelProxy *panel,
|
|
+ GVariant *parameters,
|
|
+ BusIBusImpl *ibus)
|
|
+{
|
|
+ if (!ibus->extension) {
|
|
+ g_warning ("Panel extension is not running.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ g_return_if_fail (BUS_IS_IBUS_IMPL (ibus));
|
|
+ g_return_if_fail (BUS_IS_PANEL_PROXY (ibus->extension));
|
|
+
|
|
+ /* Use the DBus method because it seems any DBus signal,
|
|
+ * g_dbus_message_new_signal(), cannot be reached to the server. */
|
|
+ g_dbus_proxy_call (G_DBUS_PROXY (ibus->extension),
|
|
+ "PanelExtensionReceived",
|
|
+ parameters,
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1, NULL, NULL, NULL);
|
|
+}
|
|
+
|
|
static void
|
|
_registry_changed_cb (IBusRegistry *registry,
|
|
BusIBusImpl *ibus)
|
|
@@ -317,33 +344,47 @@ _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
|
|
const gchar *new_name,
|
|
BusIBusImpl *ibus)
|
|
{
|
|
+ PanelType panel_type = PANEL_TYPE_NONE;
|
|
+
|
|
g_assert (BUS_IS_DBUS_IMPL (dbus));
|
|
g_assert (name != NULL);
|
|
g_assert (old_name != NULL);
|
|
g_assert (new_name != NULL);
|
|
g_assert (BUS_IS_IBUS_IMPL (ibus));
|
|
|
|
- if (g_strcmp0 (name, IBUS_SERVICE_PANEL) == 0) {
|
|
+ if (!g_strcmp0 (name, IBUS_SERVICE_PANEL))
|
|
+ panel_type = PANEL_TYPE_PANEL;
|
|
+ else if (!g_strcmp0 (name, IBUS_SERVICE_PANEL_EXTENSION))
|
|
+ panel_type = PANEL_TYPE_EXTENSION;
|
|
+
|
|
+ if (panel_type != PANEL_TYPE_NONE) {
|
|
if (g_strcmp0 (new_name, "") != 0) {
|
|
/* a Panel process is started. */
|
|
BusConnection *connection;
|
|
BusInputContext *context = NULL;
|
|
-
|
|
- if (ibus->panel != NULL) {
|
|
- ibus_proxy_destroy ((IBusProxy *) ibus->panel);
|
|
- /* panel should be NULL after destroy. See _panel_destroy_cb for details. */
|
|
- g_assert (ibus->panel == NULL);
|
|
+ BusPanelProxy **panel = (panel_type == PANEL_TYPE_PANEL) ?
|
|
+ &ibus->panel : &ibus->extension;
|
|
+
|
|
+ if (*panel != NULL) {
|
|
+ ibus_proxy_destroy ((IBusProxy *)(*panel));
|
|
+ /* panel should be NULL after destroy. See _panel_destroy_cb
|
|
+ * for details. */
|
|
+ g_assert (*panel == NULL);
|
|
}
|
|
|
|
connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
|
|
g_return_if_fail (connection != NULL);
|
|
|
|
- ibus->panel = bus_panel_proxy_new (connection);
|
|
+ *panel = bus_panel_proxy_new (connection, panel_type);
|
|
|
|
- g_signal_connect (ibus->panel,
|
|
+ g_signal_connect (*panel,
|
|
"destroy",
|
|
G_CALLBACK (_panel_destroy_cb),
|
|
ibus);
|
|
+ g_signal_connect (*panel,
|
|
+ "panel-extension",
|
|
+ G_CALLBACK (_panel_panel_extension_cb),
|
|
+ ibus);
|
|
|
|
if (ibus->focused_context != NULL) {
|
|
context = ibus->focused_context;
|
|
@@ -355,14 +396,13 @@ _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
|
|
if (context != NULL) {
|
|
BusEngineProxy *engine;
|
|
|
|
- bus_panel_proxy_focus_in (ibus->panel, context);
|
|
+ bus_panel_proxy_focus_in (*panel, context);
|
|
|
|
engine = bus_input_context_get_engine (context);
|
|
if (engine != NULL) {
|
|
IBusPropList *prop_list =
|
|
bus_engine_proxy_get_properties (engine);
|
|
- bus_panel_proxy_register_properties (ibus->panel,
|
|
- prop_list);
|
|
+ bus_panel_proxy_register_properties (*panel, prop_list);
|
|
}
|
|
}
|
|
}
|
|
@@ -403,6 +443,7 @@ bus_ibus_impl_init (BusIBusImpl *ibus)
|
|
ibus->contexts = NULL;
|
|
ibus->focused_context = NULL;
|
|
ibus->panel = NULL;
|
|
+ ibus->extension = NULL;
|
|
|
|
ibus->keymap = ibus_keymap_get ("us");
|
|
|
|
@@ -635,6 +676,8 @@ bus_ibus_impl_set_focused_context (BusIBusImpl *ibus,
|
|
|
|
if (ibus->panel != NULL)
|
|
bus_panel_proxy_focus_out (ibus->panel, ibus->focused_context);
|
|
+ if (ibus->extension != NULL)
|
|
+ bus_panel_proxy_focus_out (ibus->extension, ibus->focused_context);
|
|
|
|
bus_input_context_get_content_type (ibus->focused_context,
|
|
&purpose, &hints);
|
|
@@ -658,6 +701,8 @@ bus_ibus_impl_set_focused_context (BusIBusImpl *ibus,
|
|
|
|
if (ibus->panel != NULL)
|
|
bus_panel_proxy_focus_in (ibus->panel, context);
|
|
+ if (ibus->extension != NULL)
|
|
+ bus_panel_proxy_focus_in (ibus->extension, context);
|
|
}
|
|
|
|
if (engine != NULL)
|
|
@@ -846,8 +891,13 @@ _context_destroy_cb (BusInputContext *context,
|
|
bus_ibus_impl_set_focused_context (ibus, NULL);
|
|
|
|
if (ibus->panel &&
|
|
- bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS)
|
|
+ bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) {
|
|
bus_panel_proxy_destroy_context (ibus->panel, context);
|
|
+ }
|
|
+ if (ibus->extension &&
|
|
+ bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) {
|
|
+ bus_panel_proxy_destroy_context (ibus->extension, context);
|
|
+ }
|
|
|
|
ibus->contexts = g_list_remove (ibus->contexts, context);
|
|
g_object_unref (context);
|
|
diff --git a/bus/main.c b/bus/main.c
|
|
index 6ad60179..5b2589b1 100644
|
|
--- a/bus/main.c
|
|
+++ b/bus/main.c
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2013 Red Hat, Inc.
|
|
+ * Copyright (C) 2013-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -42,6 +43,7 @@ static gboolean xim = FALSE;
|
|
static gboolean replace = FALSE;
|
|
static gboolean restart = FALSE;
|
|
static gchar *panel = "default";
|
|
+static gchar *panel_extension = "default";
|
|
static gchar *config = "default";
|
|
static gchar *desktop = "gnome";
|
|
|
|
@@ -60,6 +62,7 @@ static const GOptionEntry entries[] =
|
|
{ "xim", 'x', 0, G_OPTION_ARG_NONE, &xim, "execute ibus XIM server.", NULL },
|
|
{ "desktop", 'n', 0, G_OPTION_ARG_STRING, &desktop, "specify the name of desktop session. [default=gnome]", "name" },
|
|
{ "panel", 'p', 0, G_OPTION_ARG_STRING, &panel, "specify the cmdline of panel program. pass 'disable' not to start a panel program.", "cmdline" },
|
|
+ { "panel-extension", 'E', 0, G_OPTION_ARG_STRING, &panel_extension, "specify the cmdline of panel extension program. pass 'disable' not to start an extension program.", "cmdline" },
|
|
{ "config", 'c', 0, G_OPTION_ARG_STRING, &config, "specify the cmdline of config program. pass 'disable' not to start a config program.", "cmdline" },
|
|
{ "address", 'a', 0, G_OPTION_ARG_STRING, &g_address, "specify the address of ibus daemon.", "address" },
|
|
{ "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "if there is an old ibus-daemon is running, it will be replaced.", NULL },
|
|
@@ -268,7 +271,27 @@ main (gint argc, gchar **argv)
|
|
if (!execute_cmdline (panel))
|
|
exit (-1);
|
|
}
|
|
+
|
|
+#ifdef EMOJI_DICT
|
|
+ if (g_strcmp0 (panel_extension, "default") == 0) {
|
|
+ BusComponent *component;
|
|
+ component = bus_ibus_impl_lookup_component_by_name (
|
|
+ BUS_DEFAULT_IBUS, IBUS_SERVICE_PANEL_EXTENSION);
|
|
+ if (component) {
|
|
+ bus_component_set_restart (component, restart);
|
|
+ }
|
|
+ if (component == NULL ||
|
|
+ !bus_component_start (component, g_verbose)) {
|
|
+ g_printerr ("Can not execute default panel program\n");
|
|
+ exit (-1);
|
|
+ }
|
|
+ } else if (g_strcmp0 (panel_extension, "disable") != 0 &&
|
|
+ g_strcmp0 (panel_extension, "") != 0) {
|
|
+ if (!execute_cmdline (panel_extension))
|
|
+ exit (-1);
|
|
+ }
|
|
}
|
|
+#endif
|
|
|
|
/* execute ibus xim server */
|
|
if (xim) {
|
|
diff --git a/bus/marshalers.list b/bus/marshalers.list
|
|
index c032cdaa..437c6fee 100644
|
|
--- a/bus/marshalers.list
|
|
+++ b/bus/marshalers.list
|
|
@@ -12,4 +12,5 @@ VOID:STRING
|
|
VOID:STRING,INT
|
|
VOID:UINT,UINT
|
|
VOID:UINT,UINT,UINT
|
|
+VOID:VARIANT
|
|
VOID:VOID
|
|
diff --git a/bus/panelproxy.c b/bus/panelproxy.c
|
|
index 8381d7dc..c3908fcf 100644
|
|
--- a/bus/panelproxy.c
|
|
+++ b/bus/panelproxy.c
|
|
@@ -2,8 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
- * Copyright (C) 2008-2014 Red Hat, Inc.
|
|
+ * Copyright (C) 2017-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -51,6 +51,7 @@ enum {
|
|
PROPERTY_SHOW,
|
|
PROPERTY_HIDE,
|
|
COMMIT_TEXT,
|
|
+ PANEL_EXTENSION,
|
|
LAST_SIGNAL,
|
|
};
|
|
|
|
@@ -59,6 +60,7 @@ struct _BusPanelProxy {
|
|
|
|
/* instance members */
|
|
BusInputContext *focused_context;
|
|
+ PanelType panel_type;
|
|
};
|
|
|
|
struct _BusPanelProxyClass {
|
|
@@ -110,22 +112,39 @@ static void bus_panel_proxy_commit_text
|
|
G_DEFINE_TYPE(BusPanelProxy, bus_panel_proxy, IBUS_TYPE_PROXY)
|
|
|
|
BusPanelProxy *
|
|
-bus_panel_proxy_new (BusConnection *connection)
|
|
+bus_panel_proxy_new (BusConnection *connection,
|
|
+ PanelType panel_type)
|
|
{
|
|
+ const gchar *path = NULL;
|
|
+ GObject *obj;
|
|
+ BusPanelProxy *panel;
|
|
+
|
|
g_assert (BUS_IS_CONNECTION (connection));
|
|
|
|
- GObject *obj;
|
|
+ switch (panel_type) {
|
|
+ case PANEL_TYPE_PANEL:
|
|
+ path = IBUS_PATH_PANEL;
|
|
+ break;
|
|
+ case PANEL_TYPE_EXTENSION:
|
|
+ path = IBUS_PATH_PANEL_EXTENSION;
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (NULL);
|
|
+ }
|
|
+
|
|
obj = g_initable_new (BUS_TYPE_PANEL_PROXY,
|
|
NULL,
|
|
NULL,
|
|
- "g-object-path", IBUS_PATH_PANEL,
|
|
+ "g-object-path", path,
|
|
"g-interface-name", IBUS_INTERFACE_PANEL,
|
|
"g-connection", bus_connection_get_dbus_connection (connection),
|
|
"g-default-timeout", g_gdbus_timeout,
|
|
"g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
|
NULL);
|
|
|
|
- return BUS_PANEL_PROXY (obj);
|
|
+ panel = BUS_PANEL_PROXY (obj);
|
|
+ panel->panel_type = panel_type;
|
|
+ return panel;
|
|
}
|
|
|
|
static void
|
|
@@ -231,6 +250,16 @@ bus_panel_proxy_class_init (BusPanelProxyClass *class)
|
|
bus_marshal_VOID__OBJECT,
|
|
G_TYPE_NONE, 1,
|
|
IBUS_TYPE_TEXT);
|
|
+
|
|
+ panel_signals[PANEL_EXTENSION] =
|
|
+ g_signal_new (I_("panel-extension"),
|
|
+ G_TYPE_FROM_CLASS (class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ 0,
|
|
+ NULL, NULL,
|
|
+ bus_marshal_VOID__VARIANT,
|
|
+ G_TYPE_NONE, 1,
|
|
+ G_TYPE_VARIANT);
|
|
}
|
|
|
|
static void
|
|
@@ -337,6 +366,15 @@ bus_panel_proxy_g_signal (GDBusProxy *proxy,
|
|
return;
|
|
}
|
|
|
|
+ if (g_strcmp0 ("PanelExtension", signal_name) == 0) {
|
|
+ if (panel->panel_type != PANEL_TYPE_PANEL) {
|
|
+ g_warning ("Wrong signal");
|
|
+ return;
|
|
+ }
|
|
+ g_signal_emit (panel, panel_signals[PANEL_EXTENSION], 0, parameters);
|
|
+ return;
|
|
+ }
|
|
+
|
|
/* shound not be reached */
|
|
g_return_if_reached ();
|
|
}
|
|
@@ -832,3 +870,10 @@ bus_panel_proxy_destroy_context (BusPanelProxy *panel,
|
|
|
|
g_object_unref (context);
|
|
}
|
|
+
|
|
+PanelType
|
|
+bus_panel_proxy_get_panel_type (BusPanelProxy *panel)
|
|
+{
|
|
+ g_assert (BUS_IS_PANEL_PROXY (panel));
|
|
+ return panel->panel_type;
|
|
+}
|
|
diff --git a/bus/panelproxy.h b/bus/panelproxy.h
|
|
index 5002f86d..b5a7af17 100644
|
|
--- a/bus/panelproxy.h
|
|
+++ b/bus/panelproxy.h
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2014 Red Hat, Inc.
|
|
+ * Copyright (C) 2017-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -50,12 +51,25 @@
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
+typedef enum
|
|
+{
|
|
+ PANEL_TYPE_NONE,
|
|
+ PANEL_TYPE_PANEL,
|
|
+ PANEL_TYPE_EXTENSION
|
|
+} PanelType;
|
|
+
|
|
typedef struct _BusPanelProxy BusPanelProxy;
|
|
typedef struct _BusPanelProxyClass BusPanelProxyClass;
|
|
|
|
GType bus_panel_proxy_get_type (void);
|
|
-BusPanelProxy *bus_panel_proxy_new (BusConnection *connection);
|
|
+BusPanelProxy *bus_panel_proxy_new (BusConnection *connection,
|
|
+ PanelType panel_type);
|
|
|
|
+gboolean bus_panel_proxy_send_signal (BusPanelProxy *panel,
|
|
+ const gchar *interface_name,
|
|
+ const gchar *signal_name,
|
|
+ GVariant *parameters,
|
|
+ GError **error);
|
|
/* functions that invoke D-Bus methods of the panel component. */
|
|
void bus_panel_proxy_focus_in (BusPanelProxy *panel,
|
|
BusInputContext *context);
|
|
@@ -119,6 +133,8 @@ void bus_panel_proxy_set_content_type
|
|
(BusPanelProxy *panel,
|
|
guint purpose,
|
|
guint hints);
|
|
+PanelType bus_panel_proxy_get_panel_type
|
|
+ (BusPanelProxy *panel);
|
|
G_END_DECLS
|
|
#endif
|
|
|
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
index 1ba418d8..72ec05ab 100644
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -3,7 +3,7 @@
|
|
# ibus - The Input Bus
|
|
#
|
|
# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
# Copyright (c) 2007-2017 Red Hat, Inc.
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
@@ -103,6 +103,7 @@ ibus_sources = \
|
|
ibustext.c \
|
|
ibusunicode.c \
|
|
ibusutil.c \
|
|
+ ibusxevent.c \
|
|
ibusxml.c \
|
|
$(NULL)
|
|
libibus_1_0_la_SOURCES = \
|
|
@@ -155,6 +156,7 @@ ibus_headers = \
|
|
ibustypes.h \
|
|
ibusunicode.h \
|
|
ibusutil.h \
|
|
+ ibusxevent.h \
|
|
ibusxml.h \
|
|
$(NULL)
|
|
ibusincludedir = $(includedir)/ibus-@IBUS_API_VERSION@
|
|
diff --git a/src/ibus.h b/src/ibus.h
|
|
index 8011729f..b15dded9 100644
|
|
--- a/src/ibus.h
|
|
+++ b/src/ibus.h
|
|
@@ -59,6 +59,7 @@
|
|
#include <ibusregistry.h>
|
|
#include <ibusemoji.h>
|
|
#include <ibusunicode.h>
|
|
+#include <ibusxevent.h>
|
|
|
|
#ifndef IBUS_DISABLE_DEPRECATED
|
|
#include <ibuskeysyms-compat.h>
|
|
diff --git a/src/ibusmarshalers.list b/src/ibusmarshalers.list
|
|
index 918bc7f7..8d91937e 100644
|
|
--- a/src/ibusmarshalers.list
|
|
+++ b/src/ibusmarshalers.list
|
|
@@ -24,4 +24,5 @@ VOID:STRING,STRING,STRING
|
|
VOID:UINT
|
|
VOID:UINT,POINTER
|
|
VOID:POINTER,UINT
|
|
+VOID:VARIANT
|
|
OBJECT:STRING
|
|
diff --git a/src/ibuspanelservice.c b/src/ibuspanelservice.c
|
|
index 33949fa1..f37b91c3 100644
|
|
--- a/src/ibuspanelservice.c
|
|
+++ b/src/ibuspanelservice.c
|
|
@@ -25,6 +25,10 @@
|
|
#include "ibusmarshalers.h"
|
|
#include "ibusinternal.h"
|
|
|
|
+#define IBUS_PANEL_SERVICE_GET_PRIVATE(o) \
|
|
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_PANEL_SERVICE, \
|
|
+ IBusPanelServicePrivate))
|
|
+
|
|
enum {
|
|
UPDATE_PREEDIT_TEXT,
|
|
UPDATE_AUXILIARY_TEXT,
|
|
@@ -52,6 +56,7 @@ enum {
|
|
STATE_CHANGED,
|
|
DESTROY_CONTEXT,
|
|
SET_CONTENT_TYPE,
|
|
+ PANEL_EXTENSION_RECEIVED,
|
|
LAST_SIGNAL,
|
|
};
|
|
|
|
@@ -146,6 +151,9 @@ static void ibus_panel_service_set_content_type
|
|
(IBusPanelService *panel,
|
|
guint purpose,
|
|
guint hints);
|
|
+static void ibus_panel_service_panel_extension_received
|
|
+ (IBusPanelService *panel,
|
|
+ GVariant *data);
|
|
|
|
G_DEFINE_TYPE (IBusPanelService, ibus_panel_service, IBUS_TYPE_SERVICE)
|
|
|
|
@@ -212,6 +220,9 @@ static const gchar introspection_xml[] =
|
|
" <arg direction='in' type='u' name='purpose' />"
|
|
" <arg direction='in' type='u' name='hints' />"
|
|
" </method>"
|
|
+ " <method name='PanelExtensionReceived'>"
|
|
+ " <arg direction='in' type='v' name='data' />"
|
|
+ " </method>"
|
|
/* Signals */
|
|
" <signal name='CursorUp' />"
|
|
" <signal name='CursorDown' />"
|
|
@@ -235,6 +246,9 @@ static const gchar introspection_xml[] =
|
|
" <signal name='CommitText'>"
|
|
" <arg type='v' name='text' />"
|
|
" </signal>"
|
|
+ " <signal name='PanelExtension'>"
|
|
+ " <arg type='v' name='data' />"
|
|
+ " </signal>"
|
|
" </interface>"
|
|
"</node>";
|
|
|
|
@@ -274,6 +288,8 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
|
|
class->update_preedit_text = ibus_panel_service_update_preedit_text;
|
|
class->update_property = ibus_panel_service_update_property;
|
|
class->set_content_type = ibus_panel_service_set_content_type;
|
|
+ class->panel_extension_received =
|
|
+ ibus_panel_service_panel_extension_received;
|
|
|
|
class->cursor_down_lookup_table = ibus_panel_service_not_implemented;
|
|
class->cursor_up_lookup_table = ibus_panel_service_not_implemented;
|
|
@@ -891,6 +907,30 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class)
|
|
2,
|
|
G_TYPE_UINT,
|
|
G_TYPE_UINT);
|
|
+
|
|
+ /**
|
|
+ * IBusPanelService::panel-extension-received:
|
|
+ * @panel: An #IBusPanelService
|
|
+ * @data: A #GVariant
|
|
+ *
|
|
+ * Emitted when the client application get the ::panel-extension-received.
|
|
+ * Implement the member function
|
|
+ * IBusPanelServiceClass::panel_extension_received in extended class to
|
|
+ * receive this signal.
|
|
+ *
|
|
+ * <note><para>Argument @user_data is ignored in this function.</para>
|
|
+ * </note>
|
|
+ */
|
|
+ panel_signals[PANEL_EXTENSION_RECEIVED] =
|
|
+ g_signal_new (I_("panel-extension-received"),
|
|
+ G_TYPE_FROM_CLASS (gobject_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (IBusPanelServiceClass, panel_extension_received),
|
|
+ NULL, NULL,
|
|
+ _ibus_marshal_VOID__VARIANT,
|
|
+ G_TYPE_NONE,
|
|
+ 1,
|
|
+ G_TYPE_VARIANT);
|
|
}
|
|
|
|
static void
|
|
@@ -1088,6 +1128,24 @@ ibus_panel_service_service_method_call (IBusService *service,
|
|
return;
|
|
}
|
|
|
|
+ if (g_strcmp0 (method_name, "PanelExtensionReceived") == 0) {
|
|
+ GVariant *variant = NULL;
|
|
+ g_variant_get (parameters, "(v)", &variant);
|
|
+ if (variant == NULL) {
|
|
+ g_dbus_method_invocation_return_error (
|
|
+ invocation,
|
|
+ G_DBUS_ERROR,
|
|
+ G_DBUS_ERROR_FAILED,
|
|
+ "PanelExtensionReceived method gives NULL");
|
|
+ return;
|
|
+ }
|
|
+ g_signal_emit (panel, panel_signals[PANEL_EXTENSION_RECEIVED], 0,
|
|
+ variant);
|
|
+ g_variant_unref (variant);
|
|
+ g_dbus_method_invocation_return_value (invocation, NULL);
|
|
+ return;
|
|
+ }
|
|
+
|
|
const static struct {
|
|
const gchar *name;
|
|
const gint signal_id;
|
|
@@ -1259,6 +1317,13 @@ ibus_panel_service_set_content_type (IBusPanelService *panel,
|
|
ibus_panel_service_not_implemented(panel);
|
|
}
|
|
|
|
+static void
|
|
+ibus_panel_service_panel_extension_received (IBusPanelService *panel,
|
|
+ GVariant *data)
|
|
+{
|
|
+ ibus_panel_service_not_implemented(panel);
|
|
+}
|
|
+
|
|
IBusPanelService *
|
|
ibus_panel_service_new (GDBusConnection *connection)
|
|
{
|
|
@@ -1347,6 +1412,21 @@ ibus_panel_service_commit_text (IBusPanelService *panel,
|
|
}
|
|
}
|
|
|
|
+void
|
|
+ibus_panel_service_panel_extension (IBusPanelService *panel,
|
|
+ GVariant *variant)
|
|
+{
|
|
+ g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel));
|
|
+ g_return_if_fail (variant);
|
|
+
|
|
+ ibus_service_emit_signal ((IBusService *) panel,
|
|
+ NULL,
|
|
+ IBUS_INTERFACE_PANEL,
|
|
+ "PanelExtension",
|
|
+ g_variant_new ("(v)", variant),
|
|
+ NULL);
|
|
+}
|
|
+
|
|
#define DEFINE_FUNC(name, Name) \
|
|
void \
|
|
ibus_panel_service_##name (IBusPanelService *panel) \
|
|
@@ -1364,4 +1444,3 @@ DEFINE_FUNC (cursor_up, CursorUp)
|
|
DEFINE_FUNC (page_down, PageDown)
|
|
DEFINE_FUNC (page_up, PageUp)
|
|
#undef DEFINE_FUNC
|
|
-
|
|
diff --git a/src/ibuspanelservice.h b/src/ibuspanelservice.h
|
|
index a5b13c73..60ef842b 100644
|
|
--- a/src/ibuspanelservice.h
|
|
+++ b/src/ibuspanelservice.h
|
|
@@ -2,7 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (c) 2009-2014 Google Inc. All rights reserved.
|
|
- * Copyright (c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (c) 2017-2018 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
|
|
@@ -128,6 +128,9 @@ struct _IBusPanelServiceClass {
|
|
gint y,
|
|
gint w,
|
|
gint h);
|
|
+ void (* panel_extension_received)
|
|
+ (IBusPanelService *panel,
|
|
+ GVariant *data);
|
|
|
|
/*< private >*/
|
|
/* padding */
|
|
@@ -242,5 +245,15 @@ void ibus_panel_service_property_hide (IBusPanelService *panel,
|
|
void ibus_panel_service_commit_text (IBusPanelService *panel,
|
|
IBusText *text);
|
|
|
|
+/**
|
|
+ * ibus_panel_service_panel_extension:
|
|
+ * @panel: An #IBusPanelService
|
|
+ * @data: (transfer full): A #GVariant data which is sent to a panel extension.
|
|
+ *
|
|
+ * Notify that a data is sent
|
|
+ * by sending a "PanelExtension" message to IBus panel extension service.
|
|
+ */
|
|
+void ibus_panel_service_panel_extension (IBusPanelService *panel,
|
|
+ GVariant *data);
|
|
G_END_DECLS
|
|
#endif
|
|
diff --git a/src/ibusserializable.c b/src/ibusserializable.c
|
|
index d7f867f4..a377b613 100644
|
|
--- a/src/ibusserializable.c
|
|
+++ b/src/ibusserializable.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) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -251,7 +252,7 @@ ibus_serializable_copy (IBusSerializable *object)
|
|
}
|
|
|
|
GVariant *
|
|
-ibus_serializable_serialize (IBusSerializable *object)
|
|
+ibus_serializable_serialize_object (IBusSerializable *object)
|
|
{
|
|
g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), FALSE);
|
|
gboolean retval;
|
|
@@ -267,7 +268,7 @@ ibus_serializable_serialize (IBusSerializable *object)
|
|
}
|
|
|
|
IBusSerializable *
|
|
-ibus_serializable_deserialize (GVariant *variant)
|
|
+ibus_serializable_deserialize_object (GVariant *variant)
|
|
{
|
|
g_return_val_if_fail (variant != NULL, NULL);
|
|
|
|
diff --git a/src/ibusserializable.h b/src/ibusserializable.h
|
|
index 4327eaee..102de1bd 100644
|
|
--- a/src/ibusserializable.h
|
|
+++ b/src/ibusserializable.h
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2013 Red Hat, Inc.
|
|
+ * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -248,10 +249,10 @@ void ibus_serializable_remove_qattachment
|
|
*
|
|
* See also: IBusSerializableCopyFunc().
|
|
*/
|
|
-IBusSerializable *ibus_serializable_copy (IBusSerializable *serializable);
|
|
+IBusSerializable *ibus_serializable_copy (IBusSerializable *serializable);
|
|
|
|
/**
|
|
- * ibus_serializable_serialize:
|
|
+ * ibus_serializable_serialize_object:
|
|
* @serializable: An #IBusSerializable.
|
|
*
|
|
* Serialize an #IBusSerializable to a #GVariant.
|
|
@@ -261,10 +262,11 @@ IBusSerializable *ibus_serializable_copy (IBusSerializable *ser
|
|
*
|
|
* See also: IBusSerializableCopyFunc().
|
|
*/
|
|
-GVariant *ibus_serializable_serialize (IBusSerializable *serializable);
|
|
+GVariant *ibus_serializable_serialize_object
|
|
+ (IBusSerializable *serializable);
|
|
|
|
/**
|
|
- * ibus_serializable_deserialize:
|
|
+ * ibus_serializable_deserialize_object:
|
|
* @variant: A #GVariant.
|
|
*
|
|
* Deserialize a #GVariant to an #IBusSerializable/
|
|
@@ -274,7 +276,11 @@ GVariant *ibus_serializable_serialize (IBusSerializable *ser
|
|
*
|
|
* See also: IBusSerializableCopyFunc().
|
|
*/
|
|
-IBusSerializable *ibus_serializable_deserialize (GVariant *variant);
|
|
+IBusSerializable *ibus_serializable_deserialize_object
|
|
+ (GVariant *variant);
|
|
+
|
|
+#define ibus_serializable_serialize ibus_serializable_serialize_object
|
|
+#define ibus_serializable_deserialize ibus_serializable_deserialize_object
|
|
|
|
G_END_DECLS
|
|
#endif
|
|
diff --git a/src/ibusshare.c b/src/ibusshare.c
|
|
index b793a962..d7724a6b 100644
|
|
--- a/src/ibusshare.c
|
|
+++ b/src/ibusshare.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) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -287,6 +288,7 @@ ibus_init (void)
|
|
IBUS_TYPE_ENGINE_DESC;
|
|
IBUS_TYPE_OBSERVED_PATH;
|
|
IBUS_TYPE_REGISTRY;
|
|
+ IBUS_TYPE_X_EVENT;
|
|
}
|
|
|
|
static GMainLoop *main_loop = NULL;
|
|
diff --git a/src/ibusshare.h b/src/ibusshare.h
|
|
index f3e2011e..757d915b 100644
|
|
--- a/src/ibusshare.h
|
|
+++ b/src/ibusshare.h
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2013 Red Hat, Inc.
|
|
+ * Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2018 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
|
|
@@ -65,6 +66,13 @@
|
|
*/
|
|
#define IBUS_SERVICE_PANEL "org.freedesktop.IBus.Panel"
|
|
|
|
+/**
|
|
+ * IBUS_SERVICE_PANEL_EXTENSION:
|
|
+ *
|
|
+ * Address of IBus panel extension service.
|
|
+ */
|
|
+#define IBUS_SERVICE_PANEL_EXTENSION "org.freedesktop.IBus.Panel.Extension"
|
|
+
|
|
/**
|
|
* IBUS_SERVICE_CONFIG:
|
|
*
|
|
@@ -100,6 +108,13 @@
|
|
*/
|
|
#define IBUS_PATH_PANEL "/org/freedesktop/IBus/Panel"
|
|
|
|
+/**
|
|
+ * IBUS_PATH_PANEL_EXTENSION:
|
|
+ *
|
|
+ * D-Bus path for IBus panel.
|
|
+ */
|
|
+#define IBUS_PATH_PANEL_EXTENSION "/org/freedesktop/IBus/Panel/Extension"
|
|
+
|
|
/**
|
|
* IBUS_PATH_CONFIG:
|
|
*
|
|
diff --git a/src/ibusxevent.c b/src/ibusxevent.c
|
|
new file mode 100644
|
|
index 00000000..dea80272
|
|
--- /dev/null
|
|
+++ b/src/ibusxevent.c
|
|
@@ -0,0 +1,1004 @@
|
|
+/* -*- 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.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+#include "ibusinternal.h"
|
|
+#include "ibusxevent.h"
|
|
+
|
|
+#define IBUS_X_EVENT_VERSION 1
|
|
+#define IBUS_X_EVENT_GET_PRIVATE(o) \
|
|
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_X_EVENT, IBusXEventPrivate))
|
|
+
|
|
+enum {
|
|
+ PROP_0,
|
|
+ PROP_VERSION,
|
|
+ PROP_EVENT_TYPE,
|
|
+ PROP_WINDOW,
|
|
+ PROP_SEND_EVENT,
|
|
+ PROP_SERIAL,
|
|
+ PROP_TIME,
|
|
+ PROP_STATE,
|
|
+ PROP_KEYVAL,
|
|
+ PROP_LENGTH,
|
|
+ PROP_STRING,
|
|
+ PROP_HARDWARE_KEYCODE,
|
|
+ PROP_GROUP,
|
|
+ PROP_IS_MODIFIER,
|
|
+ PROP_ROOT,
|
|
+ PROP_SUBWINDOW,
|
|
+ PROP_X,
|
|
+ PROP_Y,
|
|
+ PROP_X_ROOT,
|
|
+ PROP_Y_ROOT,
|
|
+ PROP_SAME_SCREEN,
|
|
+ PROP_PURPOSE
|
|
+};
|
|
+
|
|
+
|
|
+struct _IBusXEventPrivate {
|
|
+ guint version;
|
|
+ guint32 time;
|
|
+ guint state;
|
|
+ guint keyval;
|
|
+ gint length;
|
|
+ gchar *string;
|
|
+ guint16 hardware_keycode;
|
|
+ guint8 group;
|
|
+ gboolean is_modifier;
|
|
+ guint root;
|
|
+ guint subwindow;
|
|
+ gint x;
|
|
+ gint y;
|
|
+ gint x_root;
|
|
+ gint y_root;
|
|
+ gboolean same_screen;
|
|
+ gchar *purpose;
|
|
+};
|
|
+
|
|
+/* functions prototype */
|
|
+static void ibus_x_event_destroy (IBusXEvent *event);
|
|
+static void ibus_x_event_set_property (IBusXEvent *event,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void ibus_x_event_get_property (IBusXEvent *event,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static gboolean ibus_x_event_serialize (IBusXEvent *event,
|
|
+ GVariantBuilder *builder);
|
|
+static gint ibus_x_event_deserialize (IBusXEvent *event,
|
|
+ GVariant *variant);
|
|
+static gboolean ibus_x_event_copy (IBusXEvent *dest,
|
|
+ const IBusXEvent *src);
|
|
+
|
|
+G_DEFINE_TYPE (IBusXEvent, ibus_x_event, IBUS_TYPE_SERIALIZABLE)
|
|
+
|
|
+static void
|
|
+ibus_x_event_class_init (IBusXEventClass *class)
|
|
+{
|
|
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
+ IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
|
|
+ IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
|
|
+
|
|
+ gobject_class->set_property =
|
|
+ (GObjectSetPropertyFunc) ibus_x_event_set_property;
|
|
+ gobject_class->get_property =
|
|
+ (GObjectGetPropertyFunc) ibus_x_event_get_property;
|
|
+
|
|
+ object_class->destroy = (IBusObjectDestroyFunc) ibus_x_event_destroy;
|
|
+
|
|
+ serializable_class->serialize =
|
|
+ (IBusSerializableSerializeFunc) ibus_x_event_serialize;
|
|
+ serializable_class->deserialize =
|
|
+ (IBusSerializableDeserializeFunc) ibus_x_event_deserialize;
|
|
+ serializable_class->copy =
|
|
+ (IBusSerializableCopyFunc) ibus_x_event_copy;
|
|
+
|
|
+ /* install properties */
|
|
+ /**
|
|
+ * IBusXEvent:version:
|
|
+ *
|
|
+ * Version of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_VERSION,
|
|
+ g_param_spec_uint ("version",
|
|
+ "version",
|
|
+ "version",
|
|
+ 0,
|
|
+ G_MAXUINT32,
|
|
+ IBUS_X_EVENT_VERSION,
|
|
+ G_PARAM_READABLE));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:event-type:
|
|
+ *
|
|
+ * IBusXEventType of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_EVENT_TYPE,
|
|
+ g_param_spec_int ("event-type",
|
|
+ "event type",
|
|
+ "event type",
|
|
+ -1,
|
|
+ G_MAXINT32,
|
|
+ -1,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:window:
|
|
+ *
|
|
+ * window of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_WINDOW,
|
|
+ g_param_spec_uint ("window",
|
|
+ "window",
|
|
+ "window",
|
|
+ 0,
|
|
+ G_MAXUINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:send-event:
|
|
+ *
|
|
+ * send_event of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_SEND_EVENT,
|
|
+ g_param_spec_int ("send-event",
|
|
+ "send event",
|
|
+ "send event",
|
|
+ 0,
|
|
+ G_MAXINT8,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:serial:
|
|
+ *
|
|
+ * serial of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_SERIAL,
|
|
+ g_param_spec_ulong ("serial",
|
|
+ "serial",
|
|
+ "serial",
|
|
+ 0,
|
|
+ G_MAXUINT64,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:time:
|
|
+ *
|
|
+ * time of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_TIME,
|
|
+ g_param_spec_uint ("time",
|
|
+ "time",
|
|
+ "time",
|
|
+ 0,
|
|
+ G_MAXUINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:state:
|
|
+ *
|
|
+ * state of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_STATE,
|
|
+ g_param_spec_uint ("state",
|
|
+ "state",
|
|
+ "state",
|
|
+ 0,
|
|
+ G_MAXUINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:keyval:
|
|
+ *
|
|
+ * keyval of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_KEYVAL,
|
|
+ g_param_spec_uint ("keyval",
|
|
+ "keyval",
|
|
+ "keyval",
|
|
+ 0,
|
|
+ G_MAXUINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:length:
|
|
+ *
|
|
+ * keyval of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_LENGTH,
|
|
+ g_param_spec_int ("length",
|
|
+ "length",
|
|
+ "length",
|
|
+ -1,
|
|
+ G_MAXINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:string:
|
|
+ *
|
|
+ * string of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_STRING,
|
|
+ g_param_spec_string ("string",
|
|
+ "string",
|
|
+ "string",
|
|
+ "",
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:hardware-keycode:
|
|
+ *
|
|
+ * hardware keycode of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_HARDWARE_KEYCODE,
|
|
+ g_param_spec_uint ("hardware-keycode",
|
|
+ "hardware keycode",
|
|
+ "hardware keycode",
|
|
+ 0,
|
|
+ G_MAXUINT16,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:group:
|
|
+ *
|
|
+ * group of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_GROUP,
|
|
+ g_param_spec_uint ("group",
|
|
+ "group",
|
|
+ "group",
|
|
+ 0,
|
|
+ G_MAXUINT8,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:is-modifier:
|
|
+ *
|
|
+ * is_modifier of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_IS_MODIFIER,
|
|
+ g_param_spec_boolean ("is-modifier",
|
|
+ "is modifier",
|
|
+ "is modifier",
|
|
+ FALSE,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:root:
|
|
+ *
|
|
+ * root window of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_ROOT,
|
|
+ g_param_spec_uint ("root",
|
|
+ "root",
|
|
+ "root",
|
|
+ 0,
|
|
+ G_MAXUINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:subwindow:
|
|
+ *
|
|
+ * subwindow of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_SUBWINDOW,
|
|
+ g_param_spec_uint ("subwindow",
|
|
+ "subwindow",
|
|
+ "subwindow",
|
|
+ 0,
|
|
+ G_MAXUINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:x:
|
|
+ *
|
|
+ * x of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_X,
|
|
+ g_param_spec_int ("x",
|
|
+ "x",
|
|
+ "x",
|
|
+ G_MININT32,
|
|
+ G_MAXINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:y:
|
|
+ *
|
|
+ * x of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_Y,
|
|
+ g_param_spec_int ("y",
|
|
+ "y",
|
|
+ "y",
|
|
+ G_MININT32,
|
|
+ G_MAXINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:x-root:
|
|
+ *
|
|
+ * root-x of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_X_ROOT,
|
|
+ g_param_spec_int ("x-root",
|
|
+ "x root",
|
|
+ "x root",
|
|
+ G_MININT32,
|
|
+ G_MAXINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:y-root:
|
|
+ *
|
|
+ * root-y of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_Y_ROOT,
|
|
+ g_param_spec_int ("y-root",
|
|
+ "y root",
|
|
+ "y root",
|
|
+ G_MININT32,
|
|
+ G_MAXINT32,
|
|
+ 0,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:same-screen:
|
|
+ *
|
|
+ * same_screen of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_SAME_SCREEN,
|
|
+ g_param_spec_boolean ("same-screen",
|
|
+ "same screen",
|
|
+ "same screen",
|
|
+ TRUE,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusXEvent:purpose:
|
|
+ *
|
|
+ * purpose of this IBusXEvent.
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_PURPOSE,
|
|
+ g_param_spec_string ("purpose",
|
|
+ "purpose",
|
|
+ "purpose",
|
|
+ "",
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ g_type_class_add_private (class, sizeof (IBusXEventPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_x_event_init (IBusXEvent *event)
|
|
+{
|
|
+ event->priv = IBUS_X_EVENT_GET_PRIVATE (event);
|
|
+ event->priv->version = IBUS_X_EVENT_VERSION;
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_x_event_destroy (IBusXEvent *event)
|
|
+{
|
|
+ g_clear_pointer (&event->priv->string, g_free);
|
|
+
|
|
+ IBUS_OBJECT_CLASS(ibus_x_event_parent_class)->destroy (IBUS_OBJECT (event));
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_x_event_set_property (IBusXEvent *event,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ IBusXEventPrivate *priv = event->priv;
|
|
+
|
|
+ switch (prop_id) {
|
|
+ case PROP_EVENT_TYPE:
|
|
+ event->event_type = g_value_get_int (value);
|
|
+ break;
|
|
+ case PROP_WINDOW:
|
|
+ event->window = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_SEND_EVENT:
|
|
+ event->send_event = g_value_get_int (value);
|
|
+ break;
|
|
+ case PROP_SERIAL:
|
|
+ event->serial = g_value_get_ulong (value);
|
|
+ break;
|
|
+ case PROP_TIME:
|
|
+ priv->time = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_STATE:
|
|
+ priv->state = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_KEYVAL:
|
|
+ priv->keyval = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_LENGTH:
|
|
+ priv->length = g_value_get_int (value);
|
|
+ break;
|
|
+ case PROP_STRING:
|
|
+ g_free (priv->string);
|
|
+ priv->string = g_value_dup_string (value);
|
|
+ break;
|
|
+ case PROP_HARDWARE_KEYCODE:
|
|
+ priv->hardware_keycode = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_GROUP:
|
|
+ priv->group = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_IS_MODIFIER:
|
|
+ priv->is_modifier = g_value_get_boolean (value);
|
|
+ break;
|
|
+ case PROP_ROOT:
|
|
+ priv->root = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_SUBWINDOW:
|
|
+ priv->subwindow = g_value_get_uint (value);
|
|
+ break;
|
|
+ case PROP_X:
|
|
+ priv->x = g_value_get_int (value);
|
|
+ break;
|
|
+ case PROP_Y:
|
|
+ priv->y = g_value_get_int (value);
|
|
+ break;
|
|
+ case PROP_X_ROOT:
|
|
+ priv->x_root = g_value_get_int (value);
|
|
+ break;
|
|
+ case PROP_Y_ROOT:
|
|
+ priv->y_root = g_value_get_int (value);
|
|
+ break;
|
|
+ case PROP_SAME_SCREEN:
|
|
+ priv->same_screen = g_value_get_boolean (value);
|
|
+ break;
|
|
+ case PROP_PURPOSE:
|
|
+ g_free (priv->purpose);
|
|
+ priv->purpose = g_value_dup_string (value);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (event, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_x_event_get_property (IBusXEvent *event,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ IBusXEventPrivate *priv = event->priv;
|
|
+ switch (prop_id) {
|
|
+ case PROP_VERSION:
|
|
+ g_value_set_uint (value, priv->version);
|
|
+ break;
|
|
+ case PROP_EVENT_TYPE:
|
|
+ g_value_set_int (value, event->event_type);
|
|
+ break;
|
|
+ case PROP_WINDOW:
|
|
+ g_value_set_uint (value, event->window);
|
|
+ break;
|
|
+ case PROP_SEND_EVENT:
|
|
+ g_value_set_int (value, event->send_event);
|
|
+ break;
|
|
+ case PROP_SERIAL:
|
|
+ g_value_set_ulong (value, event->serial);
|
|
+ break;
|
|
+ case PROP_TIME:
|
|
+ g_value_set_uint (value, priv->time);
|
|
+ break;
|
|
+ case PROP_STATE:
|
|
+ g_value_set_uint (value, priv->state);
|
|
+ break;
|
|
+ case PROP_KEYVAL:
|
|
+ g_value_set_uint (value, priv->keyval);
|
|
+ break;
|
|
+ case PROP_LENGTH:
|
|
+ g_value_set_int (value, priv->length);
|
|
+ break;
|
|
+ case PROP_STRING:
|
|
+ g_value_set_string (value, priv->string);
|
|
+ break;
|
|
+ case PROP_HARDWARE_KEYCODE:
|
|
+ g_value_set_uint (value, priv->hardware_keycode);
|
|
+ break;
|
|
+ case PROP_GROUP:
|
|
+ g_value_set_uint (value, priv->group);
|
|
+ break;
|
|
+ case PROP_IS_MODIFIER:
|
|
+ g_value_set_boolean (value, priv->is_modifier);
|
|
+ break;
|
|
+ case PROP_ROOT:
|
|
+ g_value_set_uint (value, priv->root);
|
|
+ break;
|
|
+ case PROP_SUBWINDOW:
|
|
+ g_value_set_uint (value, priv->subwindow);
|
|
+ break;
|
|
+ case PROP_X:
|
|
+ g_value_set_int (value, priv->x);
|
|
+ break;
|
|
+ case PROP_Y:
|
|
+ g_value_set_int (value, priv->y);
|
|
+ break;
|
|
+ case PROP_X_ROOT:
|
|
+ g_value_set_int (value, priv->x_root);
|
|
+ break;
|
|
+ case PROP_Y_ROOT:
|
|
+ g_value_set_int (value, priv->y_root);
|
|
+ break;
|
|
+ case PROP_SAME_SCREEN:
|
|
+ g_value_set_boolean (value, priv->same_screen);
|
|
+ break;
|
|
+ case PROP_PURPOSE:
|
|
+ g_value_set_string (value, priv->purpose);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (event, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ibus_x_event_serialize (IBusXEvent *event,
|
|
+ GVariantBuilder *builder)
|
|
+{
|
|
+ gboolean retval;
|
|
+ IBusXEventPrivate *priv;
|
|
+
|
|
+ retval = IBUS_SERIALIZABLE_CLASS (ibus_x_event_parent_class)->
|
|
+ serialize ((IBusSerializable *)event, builder);
|
|
+ g_return_val_if_fail (retval, FALSE);
|
|
+ /* End dict iter */
|
|
+
|
|
+ priv = event->priv;
|
|
+#define NOTNULL(s) ((s) != NULL ? (s) : "")
|
|
+ /* If you will add a new property, you can append it at the end and
|
|
+ * you should not change the serialized order of name, longname,
|
|
+ * description, ... because the order is also used in other applications
|
|
+ * likes ibus-qt. */
|
|
+ g_variant_builder_add (builder, "u", priv->version);
|
|
+ g_variant_builder_add (builder, "u", event->event_type);
|
|
+ g_variant_builder_add (builder, "u", event->window);
|
|
+ g_variant_builder_add (builder, "i", event->send_event);
|
|
+ g_variant_builder_add (builder, "t", event->serial);
|
|
+ g_variant_builder_add (builder, "u", priv->time);
|
|
+ g_variant_builder_add (builder, "u", priv->state);
|
|
+ g_variant_builder_add (builder, "u", priv->keyval);
|
|
+ g_variant_builder_add (builder, "i", priv->length);
|
|
+ g_variant_builder_add (builder, "s", NOTNULL (priv->string));
|
|
+ g_variant_builder_add (builder, "u", priv->hardware_keycode);
|
|
+ g_variant_builder_add (builder, "u", priv->group);
|
|
+ g_variant_builder_add (builder, "b", priv->is_modifier);
|
|
+ g_variant_builder_add (builder, "u", priv->root);
|
|
+ g_variant_builder_add (builder, "u", priv->subwindow);
|
|
+ g_variant_builder_add (builder, "i", priv->x);
|
|
+ g_variant_builder_add (builder, "i", priv->y);
|
|
+ g_variant_builder_add (builder, "i", priv->x_root);
|
|
+ g_variant_builder_add (builder, "i", priv->y_root);
|
|
+ g_variant_builder_add (builder, "b", priv->same_screen);
|
|
+ g_variant_builder_add (builder, "s", NOTNULL (priv->purpose));
|
|
+#undef NOTNULL
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gint
|
|
+ibus_x_event_deserialize (IBusXEvent *event,
|
|
+ GVariant *variant)
|
|
+{
|
|
+ gint retval;
|
|
+ IBusXEventPrivate *priv;
|
|
+
|
|
+ retval = IBUS_SERIALIZABLE_CLASS (ibus_x_event_parent_class)->
|
|
+ deserialize ((IBusSerializable *)event, variant);
|
|
+ g_return_val_if_fail (retval, 0);
|
|
+
|
|
+ priv = event->priv;
|
|
+ /* If you will add a new property, you can append it at the end and
|
|
+ * you should not change the serialized order of name, longname,
|
|
+ * description, ... because the order is also used in other applications
|
|
+ * likes ibus-qt. */
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->version);
|
|
+ g_variant_get_child (variant, retval++, "u", &event->event_type);
|
|
+ g_variant_get_child (variant, retval++, "u", &event->window);
|
|
+ g_variant_get_child (variant, retval++, "i", &event->send_event);
|
|
+ g_variant_get_child (variant, retval++, "t", &event->serial);
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->time);
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->state);
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->keyval);
|
|
+ g_variant_get_child (variant, retval++, "i", &priv->length);
|
|
+ ibus_g_variant_get_child_string (variant, retval++,
|
|
+ &priv->string);
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->hardware_keycode);
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->group);
|
|
+ g_variant_get_child (variant, retval++, "b", &priv->is_modifier);
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->root);
|
|
+ g_variant_get_child (variant, retval++, "u", &priv->subwindow);
|
|
+ g_variant_get_child (variant, retval++, "i", &priv->x);
|
|
+ g_variant_get_child (variant, retval++, "i", &priv->y);
|
|
+ g_variant_get_child (variant, retval++, "i", &priv->x_root);
|
|
+ g_variant_get_child (variant, retval++, "i", &priv->y_root);
|
|
+ g_variant_get_child (variant, retval++, "b", &priv->same_screen);
|
|
+ ibus_g_variant_get_child_string (variant, retval++,
|
|
+ &priv->purpose);
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+ibus_x_event_copy (IBusXEvent *dest,
|
|
+ const IBusXEvent *src)
|
|
+{
|
|
+ gboolean retval;
|
|
+ IBusXEventPrivate *dest_priv = dest->priv;
|
|
+ IBusXEventPrivate *src_priv = src->priv;
|
|
+
|
|
+ retval = IBUS_SERIALIZABLE_CLASS (ibus_x_event_parent_class)->
|
|
+ copy ((IBusSerializable *)dest, (IBusSerializable *)src);
|
|
+ g_return_val_if_fail (retval, FALSE);
|
|
+
|
|
+ dest_priv->version = src_priv->version;
|
|
+ dest->event_type = src->event_type;
|
|
+ dest->window = src->window;
|
|
+ dest->send_event = src->send_event;
|
|
+ dest->serial = src->serial;
|
|
+ dest_priv->time = src_priv->time;
|
|
+ dest_priv->state = src_priv->state;
|
|
+ dest_priv->keyval = src_priv->keyval;
|
|
+ dest_priv->length = src_priv->length;
|
|
+ dest_priv->string = g_strdup (src_priv->string);
|
|
+ dest_priv->hardware_keycode = src_priv->hardware_keycode;
|
|
+ dest_priv->group = src_priv->group;
|
|
+ dest_priv->is_modifier = src_priv->is_modifier;
|
|
+ dest_priv->root = src_priv->root;
|
|
+ dest_priv->subwindow = src_priv->subwindow;
|
|
+ dest_priv->x = src_priv->x;
|
|
+ dest_priv->y = src_priv->y;
|
|
+ dest_priv->x_root = src_priv->x_root;
|
|
+ dest_priv->y_root = src_priv->y_root;
|
|
+ dest_priv->same_screen = src_priv->same_screen;
|
|
+ dest_priv->purpose = g_strdup (src_priv->purpose);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+IBusXEvent *
|
|
+ibus_x_event_new (const gchar *first_property_name,
|
|
+ ...)
|
|
+{
|
|
+ va_list var_args;
|
|
+ IBusXEvent *event;
|
|
+
|
|
+ va_start (var_args, first_property_name);
|
|
+ event = (IBusXEvent *) g_object_new_valist (IBUS_TYPE_X_EVENT,
|
|
+ first_property_name,
|
|
+ var_args);
|
|
+ va_end (var_args);
|
|
+ g_assert (event->priv->version != 0);
|
|
+ g_assert (event->event_type != IBUS_X_EVENT_NOTHING);
|
|
+ return event;
|
|
+}
|
|
+
|
|
+guint
|
|
+ibus_x_event_get_version (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ return event->priv->version;
|
|
+}
|
|
+
|
|
+IBusXEventType
|
|
+ibus_x_event_get_event_type (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ return event->event_type;
|
|
+}
|
|
+
|
|
+guint32
|
|
+ibus_x_event_get_window (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ return event->window;
|
|
+}
|
|
+
|
|
+gint8
|
|
+ibus_x_event_get_send_event (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), -1);
|
|
+ return event->send_event;
|
|
+}
|
|
+
|
|
+gulong
|
|
+ibus_x_event_get_serial (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ return event->serial;
|
|
+}
|
|
+
|
|
+guint32
|
|
+ibus_x_event_get_time (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->time;
|
|
+}
|
|
+
|
|
+guint
|
|
+ibus_x_event_get_state (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->state;
|
|
+}
|
|
+
|
|
+guint
|
|
+ibus_x_event_get_keyval (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->keyval;
|
|
+}
|
|
+
|
|
+gint
|
|
+ibus_x_event_get_length (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), -1);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (-1);
|
|
+ }
|
|
+ return event->priv->length;
|
|
+}
|
|
+
|
|
+const gchar *
|
|
+ibus_x_event_get_string (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), "");
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached ("");
|
|
+ }
|
|
+ return event->priv->string;
|
|
+}
|
|
+
|
|
+guint16
|
|
+ibus_x_event_get_hardware_keycode (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->hardware_keycode;
|
|
+}
|
|
+
|
|
+guint8
|
|
+ibus_x_event_get_group (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->group;
|
|
+}
|
|
+
|
|
+gboolean
|
|
+ibus_x_event_get_is_modifier (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->is_modifier;
|
|
+}
|
|
+
|
|
+guint32
|
|
+ibus_x_event_get_root (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->root;
|
|
+}
|
|
+
|
|
+guint32
|
|
+ibus_x_event_get_subwindow (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->subwindow;
|
|
+}
|
|
+
|
|
+gint
|
|
+ibus_x_event_get_x (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->x;
|
|
+}
|
|
+
|
|
+gint
|
|
+ibus_x_event_get_y (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->y;
|
|
+}
|
|
+
|
|
+gint
|
|
+ibus_x_event_get_x_root (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->x_root;
|
|
+}
|
|
+
|
|
+gint
|
|
+ibus_x_event_get_y_root (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), 0);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (0);
|
|
+ }
|
|
+ return event->priv->y_root;
|
|
+}
|
|
+
|
|
+gboolean
|
|
+ibus_x_event_get_same_screen (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), TRUE);
|
|
+ switch (event->event_type) {
|
|
+ case IBUS_X_EVENT_KEY_PRESS:
|
|
+ case IBUS_X_EVENT_KEY_RELEASE:
|
|
+ break;
|
|
+ default:
|
|
+ g_return_val_if_reached (TRUE);
|
|
+ }
|
|
+ return event->priv->same_screen;
|
|
+}
|
|
+
|
|
+const gchar *
|
|
+ibus_x_event_get_purpose (IBusXEvent *event)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_X_EVENT (event), "");
|
|
+ return event->priv->purpose;
|
|
+}
|
|
diff --git a/src/ibusxevent.h b/src/ibusxevent.h
|
|
new file mode 100644
|
|
index 00000000..f35f14e4
|
|
--- /dev/null
|
|
+++ b/src/ibusxevent.h
|
|
@@ -0,0 +1,294 @@
|
|
+/* -*- 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.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+#if !defined (__IBUS_H_INSIDE__) && !defined (IBUS_COMPILATION)
|
|
+#error "Only <ibus.h> can be included directly"
|
|
+#endif
|
|
+
|
|
+#ifndef __IBUS_X_EVENT_H_
|
|
+#define __IBUS_X_EVENT_H_
|
|
+
|
|
+/**
|
|
+ * SECTION: ibusxevent
|
|
+ * @short_description: XEvent wrapper object
|
|
+ * @title: IBusXEvent
|
|
+ * @stability: Unstable
|
|
+ *
|
|
+ * An IBusXEvent provides a wrapper of XEvent.
|
|
+ *
|
|
+ * see_also: #IBusComponent, #IBusEngineDesc
|
|
+ */
|
|
+
|
|
+#include "ibusserializable.h"
|
|
+
|
|
+/*
|
|
+ * Type macros.
|
|
+ */
|
|
+
|
|
+/* define GOBJECT macros */
|
|
+#define IBUS_TYPE_X_EVENT \
|
|
+ (ibus_x_event_get_type ())
|
|
+#define IBUS_X_EVENT(obj) \
|
|
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_X_EVENT, IBusXEvent))
|
|
+#define IBUS_X_EVENT_CLASS(klass) \
|
|
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_X_EVENT, IBusXEventClass))
|
|
+#define IBUS_IS_X_EVENT(obj) \
|
|
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_X_EVENT))
|
|
+#define IBUS_IS_X_EVENT_CLASS(klass) \
|
|
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_X_EVENT))
|
|
+#define IBUS_X_EVENT_GET_CLASS(obj) \
|
|
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_X_EVENT, IBusXEventClass))
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+typedef struct _IBusXEvent IBusXEvent;
|
|
+typedef struct _IBusXEventClass IBusXEventClass;
|
|
+typedef struct _IBusXEventPrivate IBusXEventPrivate;
|
|
+
|
|
+typedef enum {
|
|
+ IBUS_X_EVENT_NOTHING = -1,
|
|
+ IBUS_X_EVENT_KEY_PRESS = 0,
|
|
+ IBUS_X_EVENT_KEY_RELEASE = 1,
|
|
+ IBUS_X_EVENT_OTHER = 2,
|
|
+ IBUS_X_EVENT_EVENT_LAST /* helper variable for decls */
|
|
+} IBusXEventType;
|
|
+
|
|
+/**
|
|
+ * IBusXEvent:
|
|
+ * @type: event type
|
|
+ *
|
|
+ * IBusEngine properties.
|
|
+ */
|
|
+struct _IBusXEvent {
|
|
+ /*< private >*/
|
|
+ IBusSerializable parent;
|
|
+ IBusXEventPrivate *priv;
|
|
+
|
|
+ /* instance members */
|
|
+ /*< public >*/
|
|
+ IBusXEventType event_type;
|
|
+ guint window;
|
|
+ gint8 send_event;
|
|
+ gulong serial;
|
|
+};
|
|
+
|
|
+struct _IBusXEventClass {
|
|
+ /*< private >*/
|
|
+ IBusSerializableClass parent;
|
|
+
|
|
+ /* class members */
|
|
+ /*< public >*/
|
|
+
|
|
+ /*< private >*/
|
|
+ /* padding */
|
|
+ gpointer pdummy[10];
|
|
+};
|
|
+
|
|
+GType ibus_x_event_get_type (void);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_new:
|
|
+ * @first_property_name: Name of the first property.
|
|
+ * @...: the NULL-terminated arguments of the properties and values.
|
|
+ *
|
|
+ * Create a new #IBusXEvent.
|
|
+ *
|
|
+ * Returns: A newly allocated #IBusXEvent. E.g.
|
|
+ * ibus_x_event_new ("event-type", IBUS_X_EVENT_KEY_PRESS, NULL);
|
|
+ */
|
|
+IBusXEvent * ibus_x_event_new (const gchar
|
|
+ *first_property_name,
|
|
+ ...);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_version:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: Version of #IBusXEvent
|
|
+ */
|
|
+guint ibus_x_event_get_version (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_event_type:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: IBusXEventType of #IBusXEvent
|
|
+ */
|
|
+IBusXEventType ibus_x_event_get_event_type (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_window:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: XID of #IBusXEvent
|
|
+ */
|
|
+guint32 ibus_x_event_get_window (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_send_event:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: send_event of #IBusXEvent
|
|
+ */
|
|
+gint8 ibus_x_event_get_send_event (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_serial:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: serial of #IBusXEvent
|
|
+ */
|
|
+gulong ibus_x_event_get_serial (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_time:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: time of #IBusXEvent
|
|
+ */
|
|
+guint32 ibus_x_event_get_time (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_state:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: state of #IBusXEvent
|
|
+ */
|
|
+guint ibus_x_event_get_state (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_keyval:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: keyval of #IBusXEvent
|
|
+ */
|
|
+guint ibus_x_event_get_keyval (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_length:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: length of #IBusXEvent
|
|
+ */
|
|
+gint ibus_x_event_get_length (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_string:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: string of #IBusXEvent
|
|
+ */
|
|
+const gchar * ibus_x_event_get_string (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_hardware_keycode:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: hardware keycode of #IBusXEvent
|
|
+ */
|
|
+guint16 ibus_x_event_get_hardware_keycode
|
|
+ (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_group:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: group of #IBusXEvent
|
|
+ */
|
|
+guint8 ibus_x_event_get_group (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_is_modifier:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: is_modifier of #IBusXEvent
|
|
+ */
|
|
+gboolean ibus_x_event_get_is_modifier
|
|
+ (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_subwindow:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: subwindow of #IBusXEvent
|
|
+ */
|
|
+guint32 ibus_x_event_get_subwindow (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_root:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: root window of #IBusXEvent
|
|
+ */
|
|
+guint32 ibus_x_event_get_root (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_x:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: x of #IBusXEvent
|
|
+ */
|
|
+gint ibus_x_event_get_x (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_y:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: y of #IBusXEvent
|
|
+ */
|
|
+gint ibus_x_event_get_y (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_x_root:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: x-root of #IBusXEvent
|
|
+ */
|
|
+gint ibus_x_event_get_x_root (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_y_root:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: y-root of #IBusXEvent
|
|
+ */
|
|
+gint ibus_x_event_get_y_root (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_same_screen:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: same_screen of #IBusXEvent
|
|
+ */
|
|
+gboolean ibus_x_event_get_same_screen
|
|
+ (IBusXEvent *event);
|
|
+
|
|
+/**
|
|
+ * ibus_x_event_get_purpose:
|
|
+ * @event: An #IBusXEvent.
|
|
+ *
|
|
+ * Returns: purpose of #IBusXEvent
|
|
+ */
|
|
+const gchar * ibus_x_event_get_purpose (IBusXEvent *event);
|
|
+
|
|
+G_END_DECLS
|
|
+#endif
|
|
diff --git a/src/tests/runtest b/src/tests/runtest
|
|
index 91c4e95f..0e43fee5 100755
|
|
--- a/src/tests/runtest
|
|
+++ b/src/tests/runtest
|
|
@@ -106,6 +106,7 @@ test -d $tstdir || mkdir $tstdir
|
|
--daemonize \
|
|
--cache=none \
|
|
--panel=disable \
|
|
+ --panel-extension=disable \
|
|
--config=default \
|
|
--verbose;
|
|
|
|
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
|
|
index 786b80e6..0a8f4200 100644
|
|
--- a/ui/gtk3/Makefile.am
|
|
+++ b/ui/gtk3/Makefile.am
|
|
@@ -3,8 +3,8 @@
|
|
# ibus - The Input Bus
|
|
#
|
|
# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2015-2017 Takao Fujwiara <takao.fujiwara1@gmail.com>
|
|
-# Copyright (c) 2007-2017 Red Hat, Inc.
|
|
+# Copyright (c) 2015-2018 Takao Fujwiara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2007-2018 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
|
|
@@ -30,7 +30,7 @@ component_DATA = \
|
|
$(NULL)
|
|
componentdir = $(pkgdatadir)/component
|
|
|
|
-gtkpanel.xml: gtkpanel.xml.in
|
|
+%.xml: %.xml.in
|
|
$(AM_V_GEN) sed \
|
|
-e 's|@VERSION[@]|$(VERSION)|g' \
|
|
-e 's|@libexecdir[@]|$(libexecdir)|g' $< > $@.tmp && \
|
|
@@ -108,6 +108,7 @@ libexec_PROGRAMS = ibus-ui-gtk3
|
|
|
|
ibus_ui_gtk3_SOURCES = \
|
|
application.vala \
|
|
+ bindingcommon.vala \
|
|
candidatearea.vala \
|
|
candidatepanel.vala \
|
|
emojier.vala \
|
|
@@ -155,9 +156,12 @@ EXTRA_DIST = \
|
|
$(emoji_headers) \
|
|
$(man_seven_in_files) \
|
|
emojierapp.vala \
|
|
+ extension.vala \
|
|
+ gtkextension.xml.in \
|
|
gtkpanel.xml.in \
|
|
notification-item.xml \
|
|
notification-watcher.xml \
|
|
+ panelbinding.vala \
|
|
$(NULL)
|
|
|
|
if ENABLE_EMOJI_DICT
|
|
@@ -167,10 +171,8 @@ libexec_PROGRAMS += ibus-ui-emojier
|
|
|
|
ibus_ui_emojier_VALASOURCES = \
|
|
emojierapp.vala \
|
|
- candidatearea.vala \
|
|
emojier.vala \
|
|
iconwidget.vala \
|
|
- pango.vala \
|
|
separator.vala \
|
|
$(NULL)
|
|
ibus_ui_emojier_SOURCES = \
|
|
@@ -198,6 +200,53 @@ emojierapp.o: $(srcdir)/emojierapp.c
|
|
$(AM_V_CC_no)$(COMPILE) -c -o $@ $<
|
|
$(NULL)
|
|
|
|
+component_DATA += gtkextension.xml
|
|
+CLEANFILES += gtkextension.xml
|
|
+libexec_PROGRAMS += ibus-extension-gtk3
|
|
+
|
|
+ibus_extension_gtk3_VALASOURCES = \
|
|
+ bindingcommon.vala \
|
|
+ emojier.vala \
|
|
+ extension.vala \
|
|
+ iconwidget.vala \
|
|
+ keybindingmanager.vala \
|
|
+ panelbinding.vala \
|
|
+ $(NULL)
|
|
+ibus_extension_gtk3_SOURCES = \
|
|
+ $(ibus_extension_gtk3_VALASOURCES:.vala=.c) \
|
|
+ $(NULL)
|
|
+
|
|
+ibus_extension_gtk3_LDADD = \
|
|
+ $(AM_LDADD) \
|
|
+ $(NULL)
|
|
+ibus_extension_gtk3_VALAFLAGS = \
|
|
+ $(AM_VALAFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+# This line and foo_VALASOURCES line can delete the duplicated entries
|
|
+# of emojier.c: emojier.vala
|
|
+extension.c: $(ibus_extension_gtk3_VALASOURCES)
|
|
+ $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) \
|
|
+$(VALAFLAGS) -C $(ibus_extension_gtk3_VALASOURCES)
|
|
+ $(NULL)
|
|
+# make dist creates .c files in a different srcdir
|
|
+extension.o: $(srcdir)/extension.c
|
|
+ $(AM_V_CC)source='$<' object='$@' libtool=no \
|
|
+ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
|
|
+ $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
|
|
+ $(NULL)
|
|
+# of emojier.c: emojier.vala
|
|
+panelbinding.c: $(ibus_extension_gtk3_VALASOURCES)
|
|
+ $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) \
|
|
+$(VALAFLAGS) -C $(ibus_extension_gtk3_VALASOURCES)
|
|
+ $(NULL)
|
|
+# make dist creates .c files in a different srcdir
|
|
+panelbinding.o: $(srcdir)/panelbinding.c
|
|
+ $(AM_V_CC)source='$<' object='$@' libtool=no \
|
|
+ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
|
|
+ $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
|
|
+ $(NULL)
|
|
+
|
|
man_seven_files = $(man_seven_in_files:.7.in=.7)
|
|
man_seven_DATA =$(man_seven_files:.7=.7.gz)
|
|
man_sevendir = $(mandir)/man7
|
|
diff --git a/ui/gtk3/bindingcommon.vala b/ui/gtk3/bindingcommon.vala
|
|
new file mode 100644
|
|
index 00000000..4171f29d
|
|
--- /dev/null
|
|
+++ b/ui/gtk3/bindingcommon.vala
|
|
@@ -0,0 +1,215 @@
|
|
+/* vim:set et sts=4 sw=4:
|
|
+ *
|
|
+ * ibus - The Input Bus
|
|
+ *
|
|
+ * Copyright(c) 2018 Peng Huang <shawn.p.huang@gmail.com>
|
|
+ * Copyright(c) 2018 Takao Fujwiara <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
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+/* This file depends on keybindingmanager.vala */
|
|
+
|
|
+class BindingCommon {
|
|
+ public enum KeyEventFuncType {
|
|
+ ANY,
|
|
+ IME_SWITCHER,
|
|
+ EMOJI_TYPING,
|
|
+ }
|
|
+
|
|
+ public class Keybinding : GLib.Object {
|
|
+ public Keybinding(uint keysym,
|
|
+ Gdk.ModifierType modifiers,
|
|
+ bool reverse,
|
|
+ KeyEventFuncType ftype) {
|
|
+ this.keysym = keysym;
|
|
+ this.modifiers = modifiers;
|
|
+ this.reverse = reverse;
|
|
+ this.ftype = ftype;
|
|
+ }
|
|
+
|
|
+ public uint keysym { get; set; }
|
|
+ public Gdk.ModifierType modifiers { get; set; }
|
|
+ public bool reverse { get; set; }
|
|
+ public KeyEventFuncType ftype { get; set; }
|
|
+ }
|
|
+
|
|
+ public delegate void KeybindingFuncHandlerFunc(Gdk.Event event);
|
|
+
|
|
+ public static void
|
|
+ keybinding_manager_bind(KeybindingManager keybinding_manager,
|
|
+ ref GLib.List<Keybinding> keybindings,
|
|
+ string? accelerator,
|
|
+ KeyEventFuncType ftype,
|
|
+ KeybindingManager.KeybindingHandlerFunc
|
|
+ handler_normal,
|
|
+ KeybindingManager.KeybindingHandlerFunc?
|
|
+ handler_reverse) {
|
|
+ uint switch_keysym = 0;
|
|
+ Gdk.ModifierType switch_modifiers = 0;
|
|
+ Gdk.ModifierType reverse_modifier = Gdk.ModifierType.SHIFT_MASK;
|
|
+ Keybinding keybinding;
|
|
+
|
|
+ Gtk.accelerator_parse(accelerator,
|
|
+ out switch_keysym, out switch_modifiers);
|
|
+
|
|
+ // Map virtual modifiers to (i.e. Mod2, Mod3, ...)
|
|
+ const Gdk.ModifierType VIRTUAL_MODIFIERS = (
|
|
+ Gdk.ModifierType.SUPER_MASK |
|
|
+ Gdk.ModifierType.HYPER_MASK |
|
|
+ Gdk.ModifierType.META_MASK);
|
|
+ if ((switch_modifiers & VIRTUAL_MODIFIERS) != 0) {
|
|
+ // workaround a bug in gdk vapi vala > 0.18
|
|
+ // https://bugzilla.gnome.org/show_bug.cgi?id=677559
|
|
+#if VALA_0_18
|
|
+ Gdk.Keymap.get_default().map_virtual_modifiers(
|
|
+ ref switch_modifiers);
|
|
+#else
|
|
+ if ((switch_modifiers & Gdk.ModifierType.SUPER_MASK) != 0)
|
|
+ switch_modifiers |= Gdk.ModifierType.MOD4_MASK;
|
|
+ if ((switch_modifiers & Gdk.ModifierType.HYPER_MASK) != 0)
|
|
+ switch_modifiers |= Gdk.ModifierType.MOD4_MASK;
|
|
+#endif
|
|
+ switch_modifiers &= ~VIRTUAL_MODIFIERS;
|
|
+ }
|
|
+
|
|
+ if (switch_keysym == 0 && switch_modifiers == 0) {
|
|
+ warning("Parse accelerator '%s' failed!", accelerator);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ keybinding = new Keybinding(switch_keysym,
|
|
+ switch_modifiers,
|
|
+ false,
|
|
+ ftype);
|
|
+ keybindings.append(keybinding);
|
|
+
|
|
+ keybinding_manager.bind(switch_keysym, switch_modifiers,
|
|
+ handler_normal);
|
|
+ if (ftype == KeyEventFuncType.EMOJI_TYPING) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // accelerator already has Shift mask
|
|
+ if ((switch_modifiers & reverse_modifier) != 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ switch_modifiers |= reverse_modifier;
|
|
+
|
|
+ keybinding = new Keybinding(switch_keysym,
|
|
+ switch_modifiers,
|
|
+ true,
|
|
+ ftype);
|
|
+ keybindings.append(keybinding);
|
|
+
|
|
+ if (ftype == KeyEventFuncType.IME_SWITCHER) {
|
|
+ keybinding_manager.bind(switch_keysym, switch_modifiers,
|
|
+ handler_reverse);
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ public static void
|
|
+ unbind_switch_shortcut(KeyEventFuncType ftype,
|
|
+ GLib.List<Keybinding> keybindings) {
|
|
+ var keybinding_manager = KeybindingManager.get_instance();
|
|
+
|
|
+ while (keybindings != null) {
|
|
+ Keybinding keybinding = keybindings.data;
|
|
+
|
|
+ if (ftype == KeyEventFuncType.ANY ||
|
|
+ ftype == keybinding.ftype) {
|
|
+ keybinding_manager.unbind(keybinding.keysym,
|
|
+ keybinding.modifiers);
|
|
+ }
|
|
+ keybindings = keybindings.next;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static void
|
|
+ set_custom_font(GLib.Settings? settings_panel,
|
|
+ GLib.Settings? settings_emoji,
|
|
+ ref Gtk.CssProvider? css_provider) {
|
|
+ Gdk.Display display = Gdk.Display.get_default();
|
|
+ Gdk.Screen screen = (display != null) ?
|
|
+ display.get_default_screen() : null;
|
|
+
|
|
+ if (screen == null) {
|
|
+ warning("Could not open display.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (settings_emoji != null) {
|
|
+ string emoji_font = settings_emoji.get_string("font");
|
|
+ if (emoji_font == null) {
|
|
+ warning("No config emoji:font.");
|
|
+ return;
|
|
+ }
|
|
+ IBusEmojier.set_emoji_font(emoji_font);
|
|
+ }
|
|
+
|
|
+ if (settings_panel == null)
|
|
+ return;
|
|
+
|
|
+ bool use_custom_font = settings_panel.get_boolean("use-custom-font");
|
|
+
|
|
+ if (css_provider != null) {
|
|
+ Gtk.StyleContext.remove_provider_for_screen(screen,
|
|
+ css_provider);
|
|
+ css_provider = null;
|
|
+ }
|
|
+
|
|
+ if (use_custom_font == false) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ string custom_font = settings_panel.get_string("custom-font");
|
|
+ if (custom_font == null) {
|
|
+ warning("No config panel:custom-font.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Pango.FontDescription font_desc =
|
|
+ Pango.FontDescription.from_string(custom_font);
|
|
+ string font_family = font_desc.get_family();
|
|
+ int font_size = font_desc.get_size() / Pango.SCALE;
|
|
+ string data;
|
|
+
|
|
+ if (Gtk.MAJOR_VERSION < 3 ||
|
|
+ (Gtk.MAJOR_VERSION == 3 && Gtk.MINOR_VERSION < 20)) {
|
|
+ data = "GtkLabel { font: %s; }".printf(custom_font);
|
|
+ } else {
|
|
+ data = "label { font-family: %s; font-size: %dpt; }"
|
|
+ .printf(font_family, font_size);
|
|
+ }
|
|
+
|
|
+ css_provider = new Gtk.CssProvider();
|
|
+
|
|
+ try {
|
|
+ css_provider.load_from_data(data, -1);
|
|
+ } catch (GLib.Error e) {
|
|
+ warning("Failed css_provider_from_data: %s: %s", custom_font,
|
|
+ e.message);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Gtk.StyleContext.add_provider_for_screen(
|
|
+ screen,
|
|
+ css_provider,
|
|
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
+ }
|
|
+}
|
|
diff --git a/ui/gtk3/candidatearea.vala b/ui/gtk3/candidatearea.vala
|
|
index e162a960..f590cf3a 100644
|
|
--- a/ui/gtk3/candidatearea.vala
|
|
+++ b/ui/gtk3/candidatearea.vala
|
|
@@ -21,108 +21,6 @@
|
|
* USA
|
|
*/
|
|
|
|
-class ThemedRGBA {
|
|
- public Gdk.RGBA *normal_fg { get; set; }
|
|
- public Gdk.RGBA *normal_bg { get; set; }
|
|
- public Gdk.RGBA *selected_fg { get; set; }
|
|
- public Gdk.RGBA *selected_bg { get; set; }
|
|
-
|
|
- private Gtk.StyleContext m_style_context;
|
|
-
|
|
- public ThemedRGBA(Gtk.Widget widget) {
|
|
- this.normal_fg = null;
|
|
- this.normal_bg = null;
|
|
- this.selected_fg = null;
|
|
- this.selected_bg = null;
|
|
-
|
|
- /* Use the color of Gtk.TextView instead of Gtk.Label
|
|
- * because the selected label "color" is not configured
|
|
- * in "Adwaita" theme and the selected label "background-color"
|
|
- * is not configured in "Maia" theme.
|
|
- * https://github.com/ibus/ibus/issues/1871
|
|
- */
|
|
- Gtk.WidgetPath widget_path = new Gtk.WidgetPath();
|
|
- widget_path.append_type(typeof(Gtk.TextView));
|
|
- m_style_context = new Gtk.StyleContext();
|
|
- m_style_context.set_path(widget_path);
|
|
- m_style_context.add_class(Gtk.STYLE_CLASS_VIEW);
|
|
-
|
|
- /* "-gtk-secondary-caret-color" value is different
|
|
- * if the parent widget is set in "Menta" theme.
|
|
- */
|
|
- m_style_context.set_parent(widget.get_style_context());
|
|
-
|
|
- get_rgba();
|
|
-
|
|
- m_style_context.changed.connect(() => { get_rgba(); });
|
|
- }
|
|
-
|
|
- ~ThemedRGBA() {
|
|
- reset_rgba();
|
|
- }
|
|
-
|
|
- private void reset_rgba() {
|
|
- if (this.normal_fg != null) {
|
|
- this.normal_fg.free();
|
|
- this.normal_fg = null;
|
|
- }
|
|
- if (this.normal_bg != null) {
|
|
- this.normal_bg.free();
|
|
- this.normal_bg = null;
|
|
- }
|
|
- if (this.selected_fg != null) {
|
|
- this.selected_fg.free();
|
|
- this.selected_fg = null;
|
|
- }
|
|
- if (this.selected_bg != null) {
|
|
- this.selected_bg.free();
|
|
- this.selected_bg = null;
|
|
- }
|
|
- }
|
|
-
|
|
- private void get_rgba() {
|
|
- reset_rgba();
|
|
- Gdk.RGBA *normal_fg = null;
|
|
- Gdk.RGBA *normal_bg = null;
|
|
- Gdk.RGBA *selected_fg = null;
|
|
- Gdk.RGBA *selected_bg = null;
|
|
- m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
- "color",
|
|
- out normal_fg);
|
|
- m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
- "color",
|
|
- out selected_fg);
|
|
-
|
|
- string bg_prop = "background-color";
|
|
- m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
- bg_prop,
|
|
- out normal_bg);
|
|
- m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
- bg_prop,
|
|
- out selected_bg);
|
|
- if (normal_bg.red == selected_bg.red &&
|
|
- normal_bg.green == selected_bg.green &&
|
|
- normal_bg.blue == selected_bg.blue &&
|
|
- normal_bg.alpha == selected_bg.alpha) {
|
|
- normal_bg.free();
|
|
- normal_bg = null;
|
|
- normal_bg.free();
|
|
- normal_bg = null;
|
|
- bg_prop = "-gtk-secondary-caret-color";
|
|
- m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
- bg_prop,
|
|
- out normal_bg);
|
|
- m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
- bg_prop,
|
|
- out selected_bg);
|
|
- }
|
|
- this.normal_fg = normal_fg;
|
|
- this.normal_bg = normal_bg;
|
|
- this.selected_fg = selected_fg;
|
|
- this.selected_bg = selected_bg;
|
|
- }
|
|
-}
|
|
-
|
|
class CandidateArea : Gtk.Box {
|
|
private bool m_vertical;
|
|
private Gtk.Label[] m_labels;
|
|
diff --git a/ui/gtk3/extension.vala b/ui/gtk3/extension.vala
|
|
new file mode 100644
|
|
index 00000000..a170280b
|
|
--- /dev/null
|
|
+++ b/ui/gtk3/extension.vala
|
|
@@ -0,0 +1,124 @@
|
|
+/* vim:set et sts=4 sw=4:
|
|
+ *
|
|
+ * ibus - The Input Bus
|
|
+ *
|
|
+ * Copyright(c) 2018 Peng Huang <shawn.p.huang@gmail.com>
|
|
+ * Copyright(c) 2018 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
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+class ExtensionGtk {
|
|
+ private IBus.Bus m_bus;
|
|
+ private PanelBinding m_panel;
|
|
+
|
|
+ public ExtensionGtk(string[] argv) {
|
|
+ GLib.Intl.bindtextdomain(Config.GETTEXT_PACKAGE,
|
|
+ Config.GLIB_LOCALE_DIR);
|
|
+ GLib.Intl.bind_textdomain_codeset(Config.GETTEXT_PACKAGE, "UTF-8");
|
|
+ IBus.init();
|
|
+ Gtk.init(ref argv);
|
|
+
|
|
+ m_bus = new IBus.Bus();
|
|
+
|
|
+ m_bus.connected.connect(bus_connected);
|
|
+ m_bus.disconnected.connect(bus_disconnected);
|
|
+
|
|
+ if (m_bus.is_connected()) {
|
|
+ init();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void init() {
|
|
+ DBusConnection connection = m_bus.get_connection();
|
|
+ connection.signal_subscribe("org.freedesktop.DBus",
|
|
+ "org.freedesktop.DBus",
|
|
+ "NameAcquired",
|
|
+ "/org/freedesktop/DBus",
|
|
+ IBus.SERVICE_PANEL_EXTENSION,
|
|
+ DBusSignalFlags.NONE,
|
|
+ bus_name_acquired_cb);
|
|
+ connection.signal_subscribe("org.freedesktop.DBus",
|
|
+ "org.freedesktop.DBus",
|
|
+ "NameLost",
|
|
+ "/org/freedesktop/DBus",
|
|
+ IBus.SERVICE_PANEL_EXTENSION,
|
|
+ DBusSignalFlags.NONE,
|
|
+ bus_name_lost_cb);
|
|
+ var flags =
|
|
+ IBus.BusNameFlag.ALLOW_REPLACEMENT |
|
|
+ IBus.BusNameFlag.REPLACE_EXISTING;
|
|
+ m_bus.request_name(IBus.SERVICE_PANEL_EXTENSION, flags);
|
|
+ }
|
|
+
|
|
+ public int run() {
|
|
+ Gtk.main();
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ private void bus_name_acquired_cb(DBusConnection connection,
|
|
+ string sender_name,
|
|
+ string object_path,
|
|
+ string interface_name,
|
|
+ string signal_name,
|
|
+ Variant parameters) {
|
|
+ debug("signal_name = %s", signal_name);
|
|
+ m_panel = new PanelBinding(m_bus);
|
|
+ m_panel.load_settings();
|
|
+ }
|
|
+
|
|
+ private void bus_name_lost_cb(DBusConnection connection,
|
|
+ string sender_name,
|
|
+ string object_path,
|
|
+ string interface_name,
|
|
+ string signal_name,
|
|
+ Variant parameters) {
|
|
+ // "Destroy" dbus method was called before this callback is called.
|
|
+ // "Destroy" dbus method -> ibus_service_destroy()
|
|
+ // -> g_dbus_connection_unregister_object()
|
|
+ // -> g_object_unref(m_panel) will be called later with an idle method,
|
|
+ // which was assigned in the arguments of
|
|
+ // g_dbus_connection_register_object()
|
|
+ debug("signal_name = %s", signal_name);
|
|
+
|
|
+ // unref m_panel
|
|
+ m_panel.disconnect_signals();
|
|
+ m_panel = null;
|
|
+ }
|
|
+
|
|
+ private void bus_disconnected(IBus.Bus bus) {
|
|
+ debug("connection is lost.");
|
|
+ Gtk.main_quit();
|
|
+ }
|
|
+
|
|
+ private void bus_connected(IBus.Bus bus) {
|
|
+ init();
|
|
+ }
|
|
+
|
|
+ public static void main(string[] argv) {
|
|
+ // https://bugzilla.redhat.com/show_bug.cgi?id=1226465#c20
|
|
+ // In /etc/xdg/plasma-workspace/env/gtk3_scrolling.sh
|
|
+ // Plasma deskop sets this variable and prevents Super-space,
|
|
+ // and Ctrl-Shift-e when ibus-ui-gtk3 runs after the
|
|
+ // desktop is launched.
|
|
+ GLib.Environment.unset_variable("GDK_CORE_DEVICE_EVENTS");
|
|
+ // for Gdk.X11.get_default_xdisplay()
|
|
+ Gdk.set_allowed_backends("x11");
|
|
+
|
|
+ ExtensionGtk extension = new ExtensionGtk(argv);
|
|
+ extension.run();
|
|
+ }
|
|
+}
|
|
diff --git a/ui/gtk3/gtkextension.xml.in b/ui/gtk3/gtkextension.xml.in
|
|
new file mode 100644
|
|
index 00000000..b8157c97
|
|
--- /dev/null
|
|
+++ b/ui/gtk3/gtkextension.xml.in
|
|
@@ -0,0 +1,12 @@
|
|
+<?xml version="1.0" encoding="utf-8"?>
|
|
+<!-- filename: gtkextension.xml -->
|
|
+<component>
|
|
+ <name>org.freedesktop.IBus.Panel.Extension</name>
|
|
+ <description>Gtk Panel Extension Component</description>
|
|
+ <exec>@libexecdir@/ibus-extension-gtk3</exec>
|
|
+ <version>@VERSION@</version>
|
|
+ <author>Takao Fujiwara <takao.fujiwara1@gmail.com></author>
|
|
+ <license>GPL</license>
|
|
+ <homepage>https://github.com/ibus/ibus/wiki</homepage>
|
|
+ <textdomain>ibus</textdomain>
|
|
+</component>
|
|
diff --git a/ui/gtk3/iconwidget.vala b/ui/gtk3/iconwidget.vala
|
|
index d322650c..36643c74 100644
|
|
--- a/ui/gtk3/iconwidget.vala
|
|
+++ b/ui/gtk3/iconwidget.vala
|
|
@@ -3,6 +3,7 @@
|
|
* ibus - The Input Bus
|
|
*
|
|
* Copyright(c) 2011-2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
+ * Copyright(c) 2018 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
|
|
@@ -20,6 +21,108 @@
|
|
* USA
|
|
*/
|
|
|
|
+class ThemedRGBA {
|
|
+ public Gdk.RGBA *normal_fg { get; set; }
|
|
+ public Gdk.RGBA *normal_bg { get; set; }
|
|
+ public Gdk.RGBA *selected_fg { get; set; }
|
|
+ public Gdk.RGBA *selected_bg { get; set; }
|
|
+
|
|
+ private Gtk.StyleContext m_style_context;
|
|
+
|
|
+ public ThemedRGBA(Gtk.Widget widget) {
|
|
+ this.normal_fg = null;
|
|
+ this.normal_bg = null;
|
|
+ this.selected_fg = null;
|
|
+ this.selected_bg = null;
|
|
+
|
|
+ /* Use the color of Gtk.TextView instead of Gtk.Label
|
|
+ * because the selected label "color" is not configured
|
|
+ * in "Adwaita" theme and the selected label "background-color"
|
|
+ * is not configured in "Maia" theme.
|
|
+ * https://github.com/ibus/ibus/issues/1871
|
|
+ */
|
|
+ Gtk.WidgetPath widget_path = new Gtk.WidgetPath();
|
|
+ widget_path.append_type(typeof(Gtk.TextView));
|
|
+ m_style_context = new Gtk.StyleContext();
|
|
+ m_style_context.set_path(widget_path);
|
|
+ m_style_context.add_class(Gtk.STYLE_CLASS_VIEW);
|
|
+
|
|
+ /* "-gtk-secondary-caret-color" value is different
|
|
+ * if the parent widget is set in "Menta" theme.
|
|
+ */
|
|
+ m_style_context.set_parent(widget.get_style_context());
|
|
+
|
|
+ get_rgba();
|
|
+
|
|
+ m_style_context.changed.connect(() => { get_rgba(); });
|
|
+ }
|
|
+
|
|
+ ~ThemedRGBA() {
|
|
+ reset_rgba();
|
|
+ }
|
|
+
|
|
+ private void reset_rgba() {
|
|
+ if (this.normal_fg != null) {
|
|
+ this.normal_fg.free();
|
|
+ this.normal_fg = null;
|
|
+ }
|
|
+ if (this.normal_bg != null) {
|
|
+ this.normal_bg.free();
|
|
+ this.normal_bg = null;
|
|
+ }
|
|
+ if (this.selected_fg != null) {
|
|
+ this.selected_fg.free();
|
|
+ this.selected_fg = null;
|
|
+ }
|
|
+ if (this.selected_bg != null) {
|
|
+ this.selected_bg.free();
|
|
+ this.selected_bg = null;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void get_rgba() {
|
|
+ reset_rgba();
|
|
+ Gdk.RGBA *normal_fg = null;
|
|
+ Gdk.RGBA *normal_bg = null;
|
|
+ Gdk.RGBA *selected_fg = null;
|
|
+ Gdk.RGBA *selected_bg = null;
|
|
+ m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
+ "color",
|
|
+ out normal_fg);
|
|
+ m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
+ "color",
|
|
+ out selected_fg);
|
|
+
|
|
+ string bg_prop = "background-color";
|
|
+ m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
+ bg_prop,
|
|
+ out normal_bg);
|
|
+ m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
+ bg_prop,
|
|
+ out selected_bg);
|
|
+ if (normal_bg.red == selected_bg.red &&
|
|
+ normal_bg.green == selected_bg.green &&
|
|
+ normal_bg.blue == selected_bg.blue &&
|
|
+ normal_bg.alpha == selected_bg.alpha) {
|
|
+ normal_bg.free();
|
|
+ normal_bg = null;
|
|
+ normal_bg.free();
|
|
+ normal_bg = null;
|
|
+ bg_prop = "-gtk-secondary-caret-color";
|
|
+ m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
+ bg_prop,
|
|
+ out normal_bg);
|
|
+ m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
+ bg_prop,
|
|
+ out selected_bg);
|
|
+ }
|
|
+ this.normal_fg = normal_fg;
|
|
+ this.normal_bg = normal_bg;
|
|
+ this.selected_fg = selected_fg;
|
|
+ this.selected_bg = selected_bg;
|
|
+ }
|
|
+}
|
|
+
|
|
class IconWidget: Gtk.Image {
|
|
/**
|
|
* IconWidget:
|
|
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
|
index bcb3ed75..d9238c89 100644
|
|
--- a/ui/gtk3/panel.vala
|
|
+++ b/ui/gtk3/panel.vala
|
|
@@ -22,39 +22,16 @@
|
|
*/
|
|
|
|
class Panel : IBus.PanelService {
|
|
- private class Keybinding {
|
|
- public Keybinding(uint keysym,
|
|
- Gdk.ModifierType modifiers,
|
|
- bool reverse,
|
|
- KeyEventFuncType ftype) {
|
|
- this.keysym = keysym;
|
|
- this.modifiers = modifiers;
|
|
- this.reverse = reverse;
|
|
- this.ftype = ftype;
|
|
- }
|
|
-
|
|
- public uint keysym { get; set; }
|
|
- public Gdk.ModifierType modifiers { get; set; }
|
|
- public bool reverse { get; set; }
|
|
- public KeyEventFuncType ftype { get; set; }
|
|
- }
|
|
|
|
private enum IconType {
|
|
STATUS_ICON,
|
|
INDICATOR,
|
|
}
|
|
|
|
- private enum KeyEventFuncType {
|
|
- ANY,
|
|
- IME_SWITCHER,
|
|
- EMOJI_TYPING,
|
|
- }
|
|
-
|
|
private IBus.Bus m_bus;
|
|
private GLib.Settings m_settings_general = null;
|
|
private GLib.Settings m_settings_hotkey = null;
|
|
private GLib.Settings m_settings_panel = null;
|
|
- private GLib.Settings m_settings_emoji = null;
|
|
private IconType m_icon_type = IconType.STATUS_ICON;
|
|
private Indicator m_indicator;
|
|
#if INDICATOR
|
|
@@ -73,10 +50,6 @@ class Panel : IBus.PanelService {
|
|
private CandidatePanel m_candidate_panel;
|
|
private Switcher m_switcher;
|
|
private uint m_switcher_focus_set_engine_id;
|
|
- private IBusEmojier? m_emojier;
|
|
- private uint m_emojier_set_emoji_lang_id;
|
|
- private uint m_emojier_focus_commit_text_id;
|
|
- private string[] m_emojier_favorites = {};
|
|
private PropertyManager m_property_manager;
|
|
private PropertyPanel m_property_panel;
|
|
private GLib.Pid m_setup_pid = 0;
|
|
@@ -108,7 +81,8 @@ class Panel : IBus.PanelService {
|
|
private ulong m_activate_id;
|
|
private ulong m_registered_status_notifier_item_id;
|
|
|
|
- private GLib.List<Keybinding> m_keybindings = new GLib.List<Keybinding>();
|
|
+ private GLib.List<BindingCommon.Keybinding> m_keybindings =
|
|
+ new GLib.List<BindingCommon.Keybinding>();
|
|
|
|
public Panel(IBus.Bus bus) {
|
|
GLib.assert(bus.is_connected());
|
|
@@ -147,8 +121,6 @@ class Panel : IBus.PanelService {
|
|
m_switcher.set_popup_delay_time((uint) m_switcher_delay_time);
|
|
}
|
|
|
|
- bind_emoji_shortcut();
|
|
-
|
|
m_property_manager = new PropertyManager();
|
|
m_property_manager.property_activate.connect((w, k, s) => {
|
|
property_activate(k, s);
|
|
@@ -168,7 +140,9 @@ class Panel : IBus.PanelService {
|
|
if (m_indicator != null)
|
|
m_indicator.unregister_connection();
|
|
#endif
|
|
- unbind_switch_shortcut(KeyEventFuncType.ANY);
|
|
+ BindingCommon.unbind_switch_shortcut(
|
|
+ BindingCommon.KeyEventFuncType.ANY, m_keybindings);
|
|
+ m_keybindings = null;
|
|
}
|
|
|
|
private void init_settings() {
|
|
@@ -176,7 +150,6 @@ class Panel : IBus.PanelService {
|
|
m_settings_hotkey =
|
|
new GLib.Settings("org.freedesktop.ibus.general.hotkey");
|
|
m_settings_panel = new GLib.Settings("org.freedesktop.ibus.panel");
|
|
- m_settings_emoji = new GLib.Settings("org.freedesktop.ibus.panel.emoji");
|
|
|
|
m_settings_general.changed["preload-engines"].connect((key) => {
|
|
update_engines(m_settings_general.get_strv(key),
|
|
@@ -205,16 +178,23 @@ class Panel : IBus.PanelService {
|
|
});
|
|
|
|
m_settings_hotkey.changed["triggers"].connect((key) => {
|
|
- unbind_switch_shortcut(KeyEventFuncType.IME_SWITCHER);
|
|
+ BindingCommon.unbind_switch_shortcut(
|
|
+ BindingCommon.KeyEventFuncType.IME_SWITCHER,
|
|
+ m_keybindings);
|
|
+ m_keybindings = null;
|
|
bind_switch_shortcut();
|
|
});
|
|
|
|
m_settings_panel.changed["custom-font"].connect((key) => {
|
|
- set_custom_font();
|
|
+ BindingCommon.set_custom_font(m_settings_panel,
|
|
+ null,
|
|
+ ref m_css_provider);
|
|
});
|
|
|
|
m_settings_panel.changed["use-custom-font"].connect((key) => {
|
|
- set_custom_font();
|
|
+ BindingCommon.set_custom_font(m_settings_panel,
|
|
+ null,
|
|
+ ref m_css_provider);
|
|
});
|
|
|
|
m_settings_panel.changed["show-icon-on-systray"].connect((key) => {
|
|
@@ -245,39 +225,6 @@ class Panel : IBus.PanelService {
|
|
m_settings_panel.changed["property-icon-delay-time"].connect((key) => {
|
|
set_property_icon_delay_time();
|
|
});
|
|
-
|
|
- m_settings_emoji.changed["hotkey"].connect((key) => {
|
|
- unbind_switch_shortcut(KeyEventFuncType.EMOJI_TYPING);
|
|
- bind_emoji_shortcut();
|
|
- });
|
|
-
|
|
- m_settings_emoji.changed["font"].connect((key) => {
|
|
- set_custom_font();
|
|
- });
|
|
-
|
|
- m_settings_emoji.changed["favorites"].connect((key) => {
|
|
- set_emoji_favorites();
|
|
- });
|
|
-
|
|
- m_settings_emoji.changed["favorite-annotations"].connect((key) => {
|
|
- set_emoji_favorites();
|
|
- });
|
|
-
|
|
- m_settings_emoji.changed["lang"].connect((key) => {
|
|
- set_emoji_lang();
|
|
- });
|
|
-
|
|
- m_settings_emoji.changed["has-partial-match"].connect((key) => {
|
|
- set_emoji_partial_match();
|
|
- });
|
|
-
|
|
- m_settings_emoji.changed["partial-match-length"].connect((key) => {
|
|
- set_emoji_partial_match();
|
|
- });
|
|
-
|
|
- m_settings_emoji.changed["partial-match-condition"].connect((key) => {
|
|
- set_emoji_partial_match();
|
|
- });
|
|
}
|
|
|
|
private void popup_menu_at_area_window(Gtk.Menu menu,
|
|
@@ -409,120 +356,40 @@ class Panel : IBus.PanelService {
|
|
m_status_icon.set_from_icon_name("ibus-keyboard");
|
|
}
|
|
|
|
- private void keybinding_manager_bind(KeybindingManager keybinding_manager,
|
|
- string? accelerator,
|
|
- KeyEventFuncType ftype) {
|
|
- uint switch_keysym = 0;
|
|
- Gdk.ModifierType switch_modifiers = 0;
|
|
- Gdk.ModifierType reverse_modifier = Gdk.ModifierType.SHIFT_MASK;
|
|
- Keybinding keybinding;
|
|
-
|
|
- Gtk.accelerator_parse(accelerator,
|
|
- out switch_keysym, out switch_modifiers);
|
|
-
|
|
- // Map virtual modifiers to (i.e. Mod2, Mod3, ...)
|
|
- const Gdk.ModifierType VIRTUAL_MODIFIERS = (
|
|
- Gdk.ModifierType.SUPER_MASK |
|
|
- Gdk.ModifierType.HYPER_MASK |
|
|
- Gdk.ModifierType.META_MASK);
|
|
- if ((switch_modifiers & VIRTUAL_MODIFIERS) != 0) {
|
|
- // workaround a bug in gdk vapi vala > 0.18
|
|
- // https://bugzilla.gnome.org/show_bug.cgi?id=677559
|
|
-#if VALA_0_18
|
|
- Gdk.Keymap.get_default().map_virtual_modifiers(
|
|
- ref switch_modifiers);
|
|
-#else
|
|
- if ((switch_modifiers & Gdk.ModifierType.SUPER_MASK) != 0)
|
|
- switch_modifiers |= Gdk.ModifierType.MOD4_MASK;
|
|
- if ((switch_modifiers & Gdk.ModifierType.HYPER_MASK) != 0)
|
|
- switch_modifiers |= Gdk.ModifierType.MOD4_MASK;
|
|
-#endif
|
|
- switch_modifiers &= ~VIRTUAL_MODIFIERS;
|
|
- }
|
|
-
|
|
- if (switch_keysym == 0 && switch_modifiers == 0) {
|
|
- warning("Parse accelerator '%s' failed!", accelerator);
|
|
- return;
|
|
- }
|
|
-
|
|
- keybinding = new Keybinding(switch_keysym,
|
|
- switch_modifiers,
|
|
- false,
|
|
- ftype);
|
|
- m_keybindings.append(keybinding);
|
|
-
|
|
- /* Workaround not to free the pointer of handle_engine_switch() */
|
|
- if (ftype == KeyEventFuncType.IME_SWITCHER) {
|
|
- keybinding_manager.bind(switch_keysym, switch_modifiers,
|
|
- (e) => handle_engine_switch(e, false));
|
|
- } else if (ftype == KeyEventFuncType.EMOJI_TYPING) {
|
|
- keybinding_manager.bind(switch_keysym, switch_modifiers,
|
|
- (e) => handle_emoji_typing(e));
|
|
- return;
|
|
- }
|
|
-
|
|
- // accelerator already has Shift mask
|
|
- if ((switch_modifiers & reverse_modifier) != 0) {
|
|
- return;
|
|
- }
|
|
-
|
|
- switch_modifiers |= reverse_modifier;
|
|
-
|
|
- keybinding = new Keybinding(switch_keysym,
|
|
- switch_modifiers,
|
|
- true,
|
|
- ftype);
|
|
- m_keybindings.append(keybinding);
|
|
-
|
|
- if (ftype == KeyEventFuncType.IME_SWITCHER) {
|
|
- keybinding_manager.bind(switch_keysym, switch_modifiers,
|
|
- (e) => handle_engine_switch(e, true));
|
|
- }
|
|
- }
|
|
-
|
|
private void bind_switch_shortcut() {
|
|
string[] accelerators = m_settings_hotkey.get_strv("triggers");
|
|
|
|
var keybinding_manager = KeybindingManager.get_instance();
|
|
|
|
foreach (var accelerator in accelerators) {
|
|
- keybinding_manager_bind(keybinding_manager,
|
|
- accelerator,
|
|
- KeyEventFuncType.IME_SWITCHER);
|
|
- }
|
|
- }
|
|
-
|
|
- private void bind_emoji_shortcut() {
|
|
-#if EMOJI_DICT
|
|
- string[] accelerators = m_settings_emoji.get_strv("hotkey");
|
|
-
|
|
- var keybinding_manager = KeybindingManager.get_instance();
|
|
-
|
|
- foreach (var accelerator in accelerators) {
|
|
- keybinding_manager_bind(keybinding_manager,
|
|
- accelerator,
|
|
- KeyEventFuncType.EMOJI_TYPING);
|
|
+ BindingCommon.keybinding_manager_bind(
|
|
+ keybinding_manager,
|
|
+ ref m_keybindings,
|
|
+ accelerator,
|
|
+ BindingCommon.KeyEventFuncType.IME_SWITCHER,
|
|
+ handle_engine_switch_normal,
|
|
+ handle_engine_switch_reverse);
|
|
}
|
|
-#endif
|
|
}
|
|
|
|
- private void unbind_switch_shortcut(KeyEventFuncType ftype) {
|
|
+/*
|
|
+ public static void
|
|
+ unbind_switch_shortcut(KeyEventFuncType ftype,
|
|
+ GLib.List<Keybinding> keybindings) {
|
|
var keybinding_manager = KeybindingManager.get_instance();
|
|
|
|
- unowned GLib.List<Keybinding> keybindings = m_keybindings;
|
|
-
|
|
while (keybindings != null) {
|
|
Keybinding keybinding = keybindings.data;
|
|
|
|
- if (ftype == KeyEventFuncType.ANY || ftype == keybinding.ftype) {
|
|
+ if (ftype == KeyEventFuncType.ANY ||
|
|
+ ftype == keybinding.ftype) {
|
|
keybinding_manager.unbind(keybinding.keysym,
|
|
keybinding.modifiers);
|
|
}
|
|
keybindings = keybindings.next;
|
|
}
|
|
-
|
|
- m_keybindings = null;
|
|
}
|
|
+*/
|
|
|
|
/**
|
|
* panel_get_engines_from_xkb:
|
|
@@ -670,69 +537,6 @@ class Panel : IBus.PanelService {
|
|
m_settings_general.set_strv("preload-engines", names);
|
|
}
|
|
|
|
- private void set_custom_font() {
|
|
- Gdk.Display display = Gdk.Display.get_default();
|
|
- Gdk.Screen screen = (display != null) ?
|
|
- display.get_default_screen() : null;
|
|
-
|
|
- if (screen == null) {
|
|
- warning("Could not open display.");
|
|
- return;
|
|
- }
|
|
-
|
|
- string emoji_font = m_settings_emoji.get_string("font");
|
|
- if (emoji_font == null) {
|
|
- warning("No config emoji:font.");
|
|
- return;
|
|
- }
|
|
- IBusEmojier.set_emoji_font(emoji_font);
|
|
-
|
|
- bool use_custom_font = m_settings_panel.get_boolean("use-custom-font");
|
|
-
|
|
- if (m_css_provider != null) {
|
|
- Gtk.StyleContext.remove_provider_for_screen(screen,
|
|
- m_css_provider);
|
|
- m_css_provider = null;
|
|
- }
|
|
-
|
|
- if (use_custom_font == false) {
|
|
- return;
|
|
- }
|
|
-
|
|
- string custom_font = m_settings_panel.get_string("custom-font");
|
|
- if (custom_font == null) {
|
|
- warning("No config panel:custom-font.");
|
|
- return;
|
|
- }
|
|
-
|
|
- Pango.FontDescription font_desc =
|
|
- Pango.FontDescription.from_string(custom_font);
|
|
- string font_family = font_desc.get_family();
|
|
- int font_size = font_desc.get_size() / Pango.SCALE;
|
|
- string data;
|
|
-
|
|
- if (Gtk.MAJOR_VERSION < 3 ||
|
|
- (Gtk.MAJOR_VERSION == 3 && Gtk.MINOR_VERSION < 20)) {
|
|
- data = "GtkLabel { font: %s; }".printf(custom_font);
|
|
- } else {
|
|
- data = "label { font-family: %s; font-size: %dpt; }"
|
|
- .printf(font_family, font_size);
|
|
- }
|
|
-
|
|
- m_css_provider = new Gtk.CssProvider();
|
|
-
|
|
- try {
|
|
- m_css_provider.load_from_data(data, -1);
|
|
- } catch (GLib.Error e) {
|
|
- warning("Failed css_provider_from_data: %s: %s", custom_font,
|
|
- e.message);
|
|
- return;
|
|
- }
|
|
-
|
|
- Gtk.StyleContext.add_provider_for_screen(screen,
|
|
- m_css_provider,
|
|
- Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
- }
|
|
|
|
private void set_switcher_delay_time() {
|
|
m_switcher_delay_time =
|
|
@@ -855,35 +659,6 @@ class Panel : IBus.PanelService {
|
|
m_settings_panel.get_int("property-icon-delay-time");
|
|
}
|
|
|
|
- private void set_emoji_favorites() {
|
|
- m_emojier_favorites = m_settings_emoji.get_strv("favorites");
|
|
- IBusEmojier.set_favorites(
|
|
- m_emojier_favorites,
|
|
- m_settings_emoji.get_strv("favorite-annotations"));
|
|
- }
|
|
-
|
|
- private void set_emoji_lang() {
|
|
- if (m_emojier_set_emoji_lang_id > 0) {
|
|
- GLib.Source.remove(m_emojier_set_emoji_lang_id);
|
|
- m_emojier_set_emoji_lang_id = 0;
|
|
- }
|
|
- m_emojier_set_emoji_lang_id = GLib.Idle.add(() => {
|
|
- IBusEmojier.set_annotation_lang(
|
|
- m_settings_emoji.get_string("lang"));
|
|
- m_emojier_set_emoji_lang_id = 0;
|
|
- IBusEmojier.load_unicode_dict();
|
|
- return false;
|
|
- });
|
|
- }
|
|
-
|
|
- private void set_emoji_partial_match() {
|
|
- IBusEmojier.set_partial_match(
|
|
- m_settings_emoji.get_boolean("has-partial-match"));
|
|
- IBusEmojier.set_partial_match_length(
|
|
- m_settings_emoji.get_int("partial-match-length"));
|
|
- IBusEmojier.set_partial_match_condition(
|
|
- m_settings_emoji.get_int("partial-match-condition"));
|
|
- }
|
|
|
|
private int compare_versions(string version1, string version2) {
|
|
string[] version1_list = version1.split(".");
|
|
@@ -985,12 +760,16 @@ class Panel : IBus.PanelService {
|
|
set_use_xmodmap();
|
|
update_engines(m_settings_general.get_strv("preload-engines"),
|
|
m_settings_general.get_strv("engines-order"));
|
|
- unbind_switch_shortcut(KeyEventFuncType.ANY);
|
|
+ BindingCommon.unbind_switch_shortcut(
|
|
+ BindingCommon.KeyEventFuncType.ANY,
|
|
+ m_keybindings);
|
|
+ m_keybindings = null;
|
|
bind_switch_shortcut();
|
|
- bind_emoji_shortcut();
|
|
set_switcher_delay_time();
|
|
set_embed_preedit_text();
|
|
- set_custom_font();
|
|
+ BindingCommon.set_custom_font(m_settings_panel,
|
|
+ null,
|
|
+ ref m_css_provider);
|
|
set_show_icon_on_systray();
|
|
set_lookup_table_orientation();
|
|
set_show_property_panel();
|
|
@@ -998,9 +777,6 @@ class Panel : IBus.PanelService {
|
|
set_follow_input_cursor_when_always_shown_property_panel();
|
|
set_xkb_icon_rgba();
|
|
set_property_icon_delay_time();
|
|
- set_emoji_favorites();
|
|
- set_emoji_lang();
|
|
- set_emoji_partial_match();
|
|
}
|
|
|
|
/**
|
|
@@ -1037,10 +813,6 @@ class Panel : IBus.PanelService {
|
|
GLib.Source.remove(m_preload_engines_id);
|
|
m_preload_engines_id = 0;
|
|
}
|
|
- if (m_emojier_set_emoji_lang_id > 0) {
|
|
- GLib.Source.remove(m_emojier_set_emoji_lang_id);
|
|
- m_emojier_set_emoji_lang_id = 0;
|
|
- }
|
|
}
|
|
|
|
private void engine_contexts_insert(IBus.EngineDesc engine) {
|
|
@@ -1091,7 +863,15 @@ class Panel : IBus.PanelService {
|
|
set_engine(engine);
|
|
}
|
|
|
|
- private void handle_engine_switch(Gdk.Event event, bool revert) {
|
|
+ private void handle_engine_switch_normal(Gdk.Event event) {
|
|
+ handle_engine_switch(event, false);
|
|
+ }
|
|
+
|
|
+ private void handle_engine_switch_reverse(Gdk.Event event) {
|
|
+ handle_engine_switch(event, true);
|
|
+ }
|
|
+
|
|
+ private void handle_engine_switch(Gdk.Event event, bool reverse) {
|
|
// Do not need switch IME
|
|
if (m_engines.length <= 1)
|
|
return;
|
|
@@ -1105,12 +885,12 @@ class Panel : IBus.PanelService {
|
|
bool pressed = KeybindingManager.primary_modifier_still_pressed(
|
|
event, primary_modifiers);
|
|
|
|
- if (revert) {
|
|
+ if (reverse) {
|
|
modifiers &= ~Gdk.ModifierType.SHIFT_MASK;
|
|
}
|
|
|
|
if (pressed && m_switcher_delay_time >= 0) {
|
|
- int i = revert ? m_engines.length - 1 : 1;
|
|
+ int i = reverse ? m_engines.length - 1 : 1;
|
|
|
|
/* The flag of m_switcher.is_running avoids the following problem:
|
|
*
|
|
@@ -1132,28 +912,11 @@ class Panel : IBus.PanelService {
|
|
this.switcher_focus_set_engine();
|
|
}
|
|
} else {
|
|
- int i = revert ? m_engines.length - 1 : 1;
|
|
+ int i = reverse ? m_engines.length - 1 : 1;
|
|
switch_engine(i);
|
|
}
|
|
}
|
|
|
|
- private void show_emojier(Gdk.Event event) {
|
|
- m_emojier = new IBusEmojier();
|
|
- string emoji = m_emojier.run(m_real_current_context_path, event);
|
|
- if (emoji == null) {
|
|
- m_emojier = null;
|
|
- return;
|
|
- }
|
|
- this.emojier_focus_commit();
|
|
- }
|
|
-
|
|
- private void handle_emoji_typing(Gdk.Event event) {
|
|
- if (m_emojier != null && m_emojier.is_running()) {
|
|
- m_emojier.present_centralize(event);
|
|
- return;
|
|
- }
|
|
- show_emojier(event);
|
|
- }
|
|
|
|
private void run_preload_engines(IBus.EngineDesc[] engines, int index) {
|
|
string[] names = {};
|
|
@@ -1393,7 +1156,18 @@ class Panel : IBus.PanelService {
|
|
event.key.window = Gdk.get_default_root_window();
|
|
event.key.window.ref();
|
|
}
|
|
- handle_emoji_typing(event);
|
|
+ IBus.XEvent xevent = new IBus.XEvent(
|
|
+ "event-type", IBus.XEventType.KEY_PRESS,
|
|
+ "window",
|
|
+ (event.key.window as Gdk.X11.Window).get_xid(),
|
|
+ "time", event.key.time,
|
|
+ "purpose", "emoji");
|
|
+ /* new GLib.Variant("(sv)", "emoji", xevent.serialize_object())
|
|
+ * will call g_variant_unref() for the child variant by vala.
|
|
+ * I have no idea not to unref the object so integrated
|
|
+ * the purpose to IBus.XEvent above.
|
|
+ */
|
|
+ panel_extension(xevent.serialize_object());
|
|
});
|
|
m_sys_menu.append(item);
|
|
#endif
|
|
@@ -1557,67 +1331,6 @@ class Panel : IBus.PanelService {
|
|
}
|
|
}
|
|
|
|
- private bool emojier_focus_commit_real() {
|
|
- if (m_emojier == null)
|
|
- return true;
|
|
- string selected_string = m_emojier.get_selected_string();
|
|
- string prev_context_path = m_emojier.get_input_context_path();
|
|
- if (selected_string != null &&
|
|
- prev_context_path != "" &&
|
|
- prev_context_path == m_current_context_path) {
|
|
- IBus.Text text = new IBus.Text.from_string(selected_string);
|
|
- commit_text(text);
|
|
- m_emojier = null;
|
|
- bool has_favorite = false;
|
|
- foreach (unowned string favorite in m_emojier_favorites) {
|
|
- if (favorite == selected_string) {
|
|
- has_favorite = true;
|
|
- break;
|
|
- }
|
|
- }
|
|
- if (!has_favorite) {
|
|
- m_emojier_favorites += selected_string;
|
|
- m_settings_emoji.set_strv("favorites", m_emojier_favorites);
|
|
- }
|
|
- return true;
|
|
- }
|
|
-
|
|
- return false;
|
|
- }
|
|
-
|
|
- private void emojier_focus_commit() {
|
|
- if (m_emojier == null)
|
|
- return;
|
|
- string selected_string = m_emojier.get_selected_string();
|
|
- string prev_context_path = m_emojier.get_input_context_path();
|
|
- if (selected_string == null &&
|
|
- prev_context_path != "" &&
|
|
- m_emojier.is_running()) {
|
|
- var context = GLib.MainContext.default();
|
|
- if (m_emojier_focus_commit_text_id > 0 &&
|
|
- context.find_source_by_id(m_emojier_focus_commit_text_id)
|
|
- != null) {
|
|
- GLib.Source.remove(m_emojier_focus_commit_text_id);
|
|
- }
|
|
- m_emojier_focus_commit_text_id = GLib.Timeout.add(100, () => {
|
|
- // focus_in is comming before switcher returns
|
|
- emojier_focus_commit_real();
|
|
- m_emojier_focus_commit_text_id = -1;
|
|
- return false;
|
|
- });
|
|
- } else {
|
|
- if (emojier_focus_commit_real()) {
|
|
- var context = GLib.MainContext.default();
|
|
- if (m_emojier_focus_commit_text_id > 0 &&
|
|
- context.find_source_by_id(m_emojier_focus_commit_text_id)
|
|
- != null) {
|
|
- GLib.Source.remove(m_emojier_focus_commit_text_id);
|
|
- }
|
|
- m_emojier_focus_commit_text_id = -1;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
public override void focus_in(string input_context_path) {
|
|
m_current_context_path = input_context_path;
|
|
|
|
@@ -1632,7 +1345,6 @@ class Panel : IBus.PanelService {
|
|
m_real_current_context_path = m_current_context_path;
|
|
m_property_panel.focus_in();
|
|
this.switcher_focus_set_engine();
|
|
- this.emojier_focus_commit();
|
|
}
|
|
|
|
if (m_use_global_engine)
|
|
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
|
|
new file mode 100644
|
|
index 00000000..50700121
|
|
--- /dev/null
|
|
+++ b/ui/gtk3/panelbinding.vala
|
|
@@ -0,0 +1,335 @@
|
|
+/* vim:set et sts=4 sw=4:
|
|
+ *
|
|
+ * ibus - The Input Bus
|
|
+ *
|
|
+ * Copyright(c) 2018 Peng Huang <shawn.p.huang@gmail.com>
|
|
+ * Copyright(c) 2018 Takao Fujwiara <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
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+class PanelBinding : IBus.PanelService {
|
|
+ private IBus.Bus m_bus;
|
|
+ private GLib.Settings m_settings_panel = null;
|
|
+ private GLib.Settings m_settings_emoji = null;
|
|
+ private string m_current_context_path = "";
|
|
+ private string m_real_current_context_path = "";
|
|
+ private IBusEmojier? m_emojier;
|
|
+ private uint m_emojier_set_emoji_lang_id;
|
|
+ private uint m_emojier_focus_commit_text_id;
|
|
+ private string[] m_emojier_favorites = {};
|
|
+ private Gtk.CssProvider m_css_provider;
|
|
+ private const uint PRELOAD_ENGINES_DELAY_TIME = 30000;
|
|
+ private GLib.List<BindingCommon.Keybinding> m_keybindings =
|
|
+ new GLib.List<BindingCommon.Keybinding>();
|
|
+
|
|
+ public PanelBinding(IBus.Bus bus) {
|
|
+ GLib.assert(bus.is_connected());
|
|
+ // Chain up base class constructor
|
|
+ GLib.Object(connection : bus.get_connection(),
|
|
+ object_path : IBus.PATH_PANEL_EXTENSION);
|
|
+
|
|
+ m_bus = bus;
|
|
+
|
|
+ init_settings();
|
|
+
|
|
+ bind_emoji_shortcut();
|
|
+ }
|
|
+
|
|
+
|
|
+ ~PanelBinding() {
|
|
+ BindingCommon.unbind_switch_shortcut(
|
|
+ BindingCommon.KeyEventFuncType.ANY,
|
|
+ m_keybindings);
|
|
+ }
|
|
+
|
|
+
|
|
+ private void init_settings() {
|
|
+ m_settings_panel = new GLib.Settings("org.freedesktop.ibus.panel");
|
|
+ m_settings_emoji = new GLib.Settings("org.freedesktop.ibus.panel.emoji");
|
|
+
|
|
+ m_settings_panel.changed["custom-font"].connect((key) => {
|
|
+ BindingCommon.set_custom_font(m_settings_panel,
|
|
+ m_settings_emoji,
|
|
+ ref m_css_provider);
|
|
+ });
|
|
+
|
|
+ m_settings_panel.changed["use-custom-font"].connect((key) => {
|
|
+ BindingCommon.set_custom_font(m_settings_panel,
|
|
+ m_settings_emoji,
|
|
+ ref m_css_provider);
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["hotkey"].connect((key) => {
|
|
+ BindingCommon.unbind_switch_shortcut(
|
|
+ BindingCommon.KeyEventFuncType.EMOJI_TYPING,
|
|
+ m_keybindings);
|
|
+ bind_emoji_shortcut();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["font"].connect((key) => {
|
|
+ BindingCommon.set_custom_font(m_settings_panel,
|
|
+ m_settings_emoji,
|
|
+ ref m_css_provider);
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["favorites"].connect((key) => {
|
|
+ set_emoji_favorites();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["favorite-annotations"].connect((key) => {
|
|
+ set_emoji_favorites();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["lang"].connect((key) => {
|
|
+ set_emoji_lang();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["has-partial-match"].connect((key) => {
|
|
+ set_emoji_partial_match();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["partial-match-length"].connect((key) => {
|
|
+ set_emoji_partial_match();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["partial-match-condition"].connect((key) => {
|
|
+ set_emoji_partial_match();
|
|
+ });
|
|
+ }
|
|
+
|
|
+
|
|
+ private void bind_emoji_shortcut() {
|
|
+#if EMOJI_DICT
|
|
+ string[] accelerators = m_settings_emoji.get_strv("hotkey");
|
|
+
|
|
+ var keybinding_manager = KeybindingManager.get_instance();
|
|
+
|
|
+ foreach (var accelerator in accelerators) {
|
|
+ BindingCommon.keybinding_manager_bind(
|
|
+ keybinding_manager,
|
|
+ ref m_keybindings,
|
|
+ accelerator,
|
|
+ BindingCommon.KeyEventFuncType.EMOJI_TYPING,
|
|
+ handle_emoji_typing,
|
|
+ null);
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+
|
|
+
|
|
+ private void set_emoji_favorites() {
|
|
+ m_emojier_favorites = m_settings_emoji.get_strv("favorites");
|
|
+ IBusEmojier.set_favorites(
|
|
+ m_emojier_favorites,
|
|
+ m_settings_emoji.get_strv("favorite-annotations"));
|
|
+ }
|
|
+
|
|
+
|
|
+ private void set_emoji_lang() {
|
|
+ if (m_emojier_set_emoji_lang_id > 0) {
|
|
+ GLib.Source.remove(m_emojier_set_emoji_lang_id);
|
|
+ m_emojier_set_emoji_lang_id = 0;
|
|
+ }
|
|
+ m_emojier_set_emoji_lang_id = GLib.Idle.add(() => {
|
|
+ IBusEmojier.set_annotation_lang(
|
|
+ m_settings_emoji.get_string("lang"));
|
|
+ m_emojier_set_emoji_lang_id = 0;
|
|
+ IBusEmojier.load_unicode_dict();
|
|
+ return false;
|
|
+ });
|
|
+ }
|
|
+
|
|
+
|
|
+ private void set_emoji_partial_match() {
|
|
+ IBusEmojier.set_partial_match(
|
|
+ m_settings_emoji.get_boolean("has-partial-match"));
|
|
+ IBusEmojier.set_partial_match_length(
|
|
+ m_settings_emoji.get_int("partial-match-length"));
|
|
+ IBusEmojier.set_partial_match_condition(
|
|
+ m_settings_emoji.get_int("partial-match-condition"));
|
|
+ }
|
|
+
|
|
+
|
|
+ public void load_settings() {
|
|
+ BindingCommon.unbind_switch_shortcut(BindingCommon.KeyEventFuncType.ANY,
|
|
+ m_keybindings);
|
|
+ bind_emoji_shortcut();
|
|
+ BindingCommon.set_custom_font(m_settings_panel,
|
|
+ m_settings_emoji,
|
|
+ ref m_css_provider);
|
|
+ set_emoji_favorites();
|
|
+ set_emoji_lang();
|
|
+ set_emoji_partial_match();
|
|
+ }
|
|
+
|
|
+
|
|
+ /**
|
|
+ * disconnect_signals:
|
|
+ *
|
|
+ * Call this API before m_panel = null so that the ref_count becomes 0
|
|
+ */
|
|
+ public void disconnect_signals() {
|
|
+ if (m_emojier_set_emoji_lang_id > 0) {
|
|
+ GLib.Source.remove(m_emojier_set_emoji_lang_id);
|
|
+ m_emojier_set_emoji_lang_id = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ private void show_emojier(Gdk.Event event) {
|
|
+ m_emojier = new IBusEmojier();
|
|
+ string emoji = m_emojier.run(m_real_current_context_path, event);
|
|
+ if (emoji == null) {
|
|
+ m_emojier = null;
|
|
+ return;
|
|
+ }
|
|
+ this.emojier_focus_commit();
|
|
+ }
|
|
+
|
|
+
|
|
+ private void handle_emoji_typing(Gdk.Event event) {
|
|
+ if (m_emojier != null && m_emojier.is_running()) {
|
|
+ m_emojier.present_centralize(event);
|
|
+ return;
|
|
+ }
|
|
+ show_emojier(event);
|
|
+ }
|
|
+
|
|
+
|
|
+ private bool emojier_focus_commit_real() {
|
|
+ if (m_emojier == null)
|
|
+ return true;
|
|
+ string selected_string = m_emojier.get_selected_string();
|
|
+ string prev_context_path = m_emojier.get_input_context_path();
|
|
+ if (selected_string != null &&
|
|
+ prev_context_path != "" &&
|
|
+ prev_context_path == m_current_context_path) {
|
|
+ IBus.Text text = new IBus.Text.from_string(selected_string);
|
|
+ commit_text(text);
|
|
+ m_emojier = null;
|
|
+ bool has_favorite = false;
|
|
+ foreach (unowned string favorite in m_emojier_favorites) {
|
|
+ if (favorite == selected_string) {
|
|
+ has_favorite = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (!has_favorite) {
|
|
+ m_emojier_favorites += selected_string;
|
|
+ m_settings_emoji.set_strv("favorites", m_emojier_favorites);
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+
|
|
+ private void emojier_focus_commit() {
|
|
+ if (m_emojier == null)
|
|
+ return;
|
|
+ string selected_string = m_emojier.get_selected_string();
|
|
+ string prev_context_path = m_emojier.get_input_context_path();
|
|
+ if (selected_string == null &&
|
|
+ prev_context_path != "" &&
|
|
+ m_emojier.is_running()) {
|
|
+ var context = GLib.MainContext.default();
|
|
+ if (m_emojier_focus_commit_text_id > 0 &&
|
|
+ context.find_source_by_id(m_emojier_focus_commit_text_id)
|
|
+ != null) {
|
|
+ GLib.Source.remove(m_emojier_focus_commit_text_id);
|
|
+ }
|
|
+ m_emojier_focus_commit_text_id = GLib.Timeout.add(100, () => {
|
|
+ // focus_in is comming before switcher returns
|
|
+ emojier_focus_commit_real();
|
|
+ m_emojier_focus_commit_text_id = -1;
|
|
+ return false;
|
|
+ });
|
|
+ } else {
|
|
+ if (emojier_focus_commit_real()) {
|
|
+ var context = GLib.MainContext.default();
|
|
+ if (m_emojier_focus_commit_text_id > 0 &&
|
|
+ context.find_source_by_id(m_emojier_focus_commit_text_id)
|
|
+ != null) {
|
|
+ GLib.Source.remove(m_emojier_focus_commit_text_id);
|
|
+ }
|
|
+ m_emojier_focus_commit_text_id = -1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ public override void focus_in(string input_context_path) {
|
|
+ m_current_context_path = input_context_path;
|
|
+
|
|
+ /* 'fake' input context is named as
|
|
+ * '/org/freedesktop/IBus/InputContext_1' and always send in
|
|
+ * focus-out events by ibus-daemon for the global engine mode.
|
|
+ * Now ibus-daemon assumes to always use the global engine.
|
|
+ * But this event should not be used for modal dialogs
|
|
+ * such as Switcher.
|
|
+ */
|
|
+ if (!input_context_path.has_suffix("InputContext_1")) {
|
|
+ m_real_current_context_path = m_current_context_path;
|
|
+ this.emojier_focus_commit();
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ public override void focus_out(string input_context_path) {
|
|
+ m_current_context_path = "";
|
|
+ }
|
|
+
|
|
+
|
|
+ public override void panel_extension_received(GLib.Variant data) {
|
|
+ IBus.XEvent? xevent = IBus.Serializable.deserialize_object(data)
|
|
+ as IBus.XEvent;
|
|
+ if (xevent == null) {
|
|
+ warning ("Failed to deserialize IBusXEvent");
|
|
+ return;
|
|
+ }
|
|
+ if (xevent.get_purpose() != "emoji") {
|
|
+ string format = "The purpose %s is not implemented in PanelExtension";
|
|
+ warning (format.printf(xevent.get_purpose()));
|
|
+ return;
|
|
+ }
|
|
+ Gdk.EventType event_type;
|
|
+ if (xevent.get_event_type() == IBus.XEventType.KEY_PRESS) {
|
|
+ event_type = Gdk.EventType.KEY_PRESS;
|
|
+ } else if (xevent.get_event_type() == IBus.XEventType.KEY_RELEASE) {
|
|
+ event_type = Gdk.EventType.KEY_RELEASE;
|
|
+ } else {
|
|
+ warning ("Not supported type %d".printf(xevent.get_event_type()));
|
|
+ return;
|
|
+ }
|
|
+ Gdk.Event event = new Gdk.Event(event_type);
|
|
+ event.key.time = xevent.get_time();
|
|
+ Gdk.Display? display = Gdk.Display.get_default();
|
|
+ X.Window xid = xevent.get_window();
|
|
+ Gdk.X11.Window window;
|
|
+ window = Gdk.X11.Window.lookup_for_display(
|
|
+ display as Gdk.X11.Display, xid);
|
|
+ if (window != null) {
|
|
+ event.key.window = window;
|
|
+ } else {
|
|
+ window = new Gdk.X11.Window.foreign_for_display(
|
|
+ display as Gdk.X11.Display, xid);
|
|
+ event.key.window = window;
|
|
+ }
|
|
+ handle_emoji_typing(event);
|
|
+ }
|
|
+}
|
|
--
|
|
2.14.3
|
|
|
|
From 366963d57d1468914611c71929cc64c83be9affd Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Piotr=20Dr=C4=85g?= <piotrdrag@gmail.com>
|
|
Date: Tue, 20 Feb 2018 18:57:32 +0900
|
|
Subject: [PATCH] Fix typos in translatable strings
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
BUG=https://github.com/ibus/ibus/pull/1983
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/333670043
|
|
|
|
Patch from Piotr Drąg <piotrdrag@gmail.com>.
|
|
---
|
|
data/ibus.schemas.in | 6 +++---
|
|
ui/gtk3/emojierapp.vala | 2 +-
|
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
|
|
index 278362d7..4523ccc4 100644
|
|
--- a/data/ibus.schemas.in
|
|
+++ b/data/ibus.schemas.in
|
|
@@ -64,7 +64,7 @@
|
|
<default>[ara,bg,cz,dev,gr,gur,in,jp(kana),mal,mkd,ru,ua]</default>
|
|
<locale name="C">
|
|
<short>Latin layouts which have no ASCII</short>
|
|
- <long>US layout is appended to the latin layouts. variant can be
|
|
+ <long>US layout is appended to the Latin layouts. variant can be
|
|
omitted.
|
|
</long>
|
|
</locale>
|
|
@@ -299,7 +299,7 @@
|
|
and blue, 3. a RGB color in form 'rgb(r,g,b)' or
|
|
4. a RGBA color in form 'rgba(r,g,b,a)' where 'r',
|
|
'g', and 'b' are either integers in the range 0 to 255
|
|
- or precentage values in the range 0% to 100%, and
|
|
+ or percentage values in the range 0% to 100%, and
|
|
'a' is a floating point value in the range 0 to 1
|
|
of the alpha.</long>
|
|
</locale>
|
|
@@ -373,7 +373,7 @@
|
|
<default>Monospace 16</default>
|
|
<locale name="C">
|
|
<short>Custom font</short>
|
|
- <long>Custom font name for emoji chracters on emoji dialog</long>
|
|
+ <long>Custom font name for emoji characters on emoji dialog</long>
|
|
</locale>
|
|
</schema>
|
|
<schema>
|
|
diff --git a/ui/gtk3/emojierapp.vala b/ui/gtk3/emojierapp.vala
|
|
index d816352e..efedf344 100644
|
|
--- a/ui/gtk3/emojierapp.vala
|
|
+++ b/ui/gtk3/emojierapp.vala
|
|
@@ -94,7 +94,7 @@ public class EmojiApplication : Application {
|
|
/* TRANSLATORS: "FONT" should be capital and translatable.
|
|
* It's used for an argument command --font=FONT
|
|
*/
|
|
- N_("\"FONT\" for emoji chracters on emoji dialog"),
|
|
+ N_("\"FONT\" for emoji characters on emoji dialog"),
|
|
N_("FONT") },
|
|
{ "lang", 0, 0, OptionArg.STRING, out annotation_lang,
|
|
/* TRANSLATORS: "LANG" should be capital and translatable.
|
|
--
|
|
2.14.3
|
|
|
|
From d1ebb3d77ebfe8f58188261c383d8122e2125fe6 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Wed, 21 Feb 2018 12:12:11 +0900
|
|
Subject: [PATCH] ui/gtk3: Show code points on Unicode name list dialog
|
|
|
|
The code points are useful since the list has many names.
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/340770043
|
|
---
|
|
ui/gtk3/emojier.vala | 14 ++++++++++++--
|
|
1 file changed, 12 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 0bf34da8..c85dfa86 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -198,7 +198,8 @@ public class IBusEmojier : Gtk.ApplicationWindow {
|
|
private class EPaddedLabelBox : Gtk.Box {
|
|
public EPaddedLabelBox(string text,
|
|
Gtk.Align align,
|
|
- TravelDirection direction=TravelDirection.NONE) {
|
|
+ TravelDirection direction=TravelDirection.NONE,
|
|
+ string? caption=null) {
|
|
GLib.Object(
|
|
name : "IBusEmojierPaddedLabelBox",
|
|
orientation : Gtk.Orientation.HORIZONTAL,
|
|
@@ -218,6 +219,11 @@ public class IBusEmojier : Gtk.ApplicationWindow {
|
|
}
|
|
EPaddedLabel label = new EPaddedLabel(text, align);
|
|
pack_start(label, true, true, 0);
|
|
+ if (caption != null) {
|
|
+ EPaddedLabel label_r = new EPaddedLabel(caption,
|
|
+ Gtk.Align.END);
|
|
+ pack_end(label_r, true, true, 0);
|
|
+ }
|
|
}
|
|
}
|
|
private class ETitleLabelBox : Gtk.HeaderBar {
|
|
@@ -979,9 +985,13 @@ public class IBusEmojier : Gtk.ApplicationWindow {
|
|
uint n = 0;
|
|
foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
string name = block.get_name();
|
|
+ string caption = "U+%08X".printf(block.get_start());
|
|
EBoxRow row = new EBoxRow(name);
|
|
EPaddedLabelBox widget =
|
|
- new EPaddedLabelBox(_(name), Gtk.Align.CENTER);
|
|
+ new EPaddedLabelBox(_(name),
|
|
+ Gtk.Align.CENTER,
|
|
+ TravelDirection.NONE,
|
|
+ caption);
|
|
row.add(widget);
|
|
m_list_box.add(row);
|
|
if (n++ == m_category_active_index) {
|
|
--
|
|
2.14.3
|
|
|
|
From fc54b0c051c2eb4a2c1f836b1415def00314cfc1 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Wed, 21 Feb 2018 12:17:31 +0900
|
|
Subject: [PATCH] ui/gtk3: Load Unicode data when open the dialog by
|
|
default
|
|
|
|
The emoji data requires about 10MB and the Unicode data requires about 15MB.
|
|
Now the emoji data is loaded at the time of startup and the Unicode data
|
|
is loaded if users open the dialog at the beginning.
|
|
The settings can be customized with gsettings command and the keys
|
|
of 'load-emoji-at-startup' and 'load-unicode-at-startup' in
|
|
'org.freedesktop.ibus.panel.emoji' schema.
|
|
|
|
Review URL: https://codereview.appspot.com/340780043
|
|
---
|
|
data/ibus.schemas.in | 32 ++++++++++++++++++++++++++++++++
|
|
ui/gtk3/panelbinding.vala | 41 +++++++++++++++++++++++++++++++++++++++--
|
|
2 files changed, 71 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
|
|
index 4523ccc4..3c6b6f69 100644
|
|
--- a/data/ibus.schemas.in
|
|
+++ b/data/ibus.schemas.in
|
|
@@ -455,6 +455,38 @@
|
|
</long>
|
|
</locale>
|
|
</schema>
|
|
+ <schema>
|
|
+ <key>/schemas/desktop/ibus/panel/emoji/load-emoji-at-startup</key>
|
|
+ <applyto>/desktop/ibus/panel/emoji/load-emoji-at-startup</applyto>
|
|
+ <owner>ibus</owner>
|
|
+ <type>bool</type>
|
|
+ <default>true</default>
|
|
+ <locale name="C">
|
|
+ <short>Load the emoji data at the time of startup</short>
|
|
+ <long>Load the emoji data at the time of startup if true.
|
|
+ About 10MB memory is needed to load the data.
|
|
+ Load the emoji data when open the emoji dialog at the
|
|
+ beginning if false.
|
|
+ </long>
|
|
+ </locale>
|
|
+ </schema>
|
|
+ <schema>
|
|
+ <key>/schemas/desktop/ibus/panel/emoji/load-unicode-at-startup</key>
|
|
+ <applyto>/desktop/ibus/panel/emoji/load-unicode-at-startup</applyto>
|
|
+ <owner>ibus</owner>
|
|
+ <type>bool</type>
|
|
+ <default>false</default>
|
|
+ <locale name="C">
|
|
+ <short>Load the Unicode data at the time of startup</short>
|
|
+ <long>Load the Unicode data at the time of startup if true.
|
|
+ About 15MB memory is needed to load the data.
|
|
+ Load the Unicode data when open the emoji dialog at the
|
|
+ beginning if false.
|
|
+ The Unicode data is always loaded after the emoji data
|
|
+ is loaded even if true.
|
|
+ </long>
|
|
+ </locale>
|
|
+ </schema>
|
|
<schema>
|
|
<key>/schemas/desktop/ibus/general/embed_preedit_text</key>
|
|
<applyto>/desktop/ibus/general/embed_preedit_text</applyto>
|
|
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
|
|
index 50700121..1fbf6cfc 100644
|
|
--- a/ui/gtk3/panelbinding.vala
|
|
+++ b/ui/gtk3/panelbinding.vala
|
|
@@ -35,6 +35,10 @@ class PanelBinding : IBus.PanelService {
|
|
private const uint PRELOAD_ENGINES_DELAY_TIME = 30000;
|
|
private GLib.List<BindingCommon.Keybinding> m_keybindings =
|
|
new GLib.List<BindingCommon.Keybinding>();
|
|
+ private bool m_load_emoji_at_startup;
|
|
+ private bool m_loaded_emoji = false;
|
|
+ private bool m_load_unicode_at_startup;
|
|
+ private bool m_loaded_unicode = false;
|
|
|
|
public PanelBinding(IBus.Bus bus) {
|
|
GLib.assert(bus.is_connected());
|
|
@@ -109,6 +113,14 @@ class PanelBinding : IBus.PanelService {
|
|
m_settings_emoji.changed["partial-match-condition"].connect((key) => {
|
|
set_emoji_partial_match();
|
|
});
|
|
+
|
|
+ m_settings_emoji.changed["load-emoji-at-startup"].connect((key) => {
|
|
+ set_load_emoji_at_startup();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["load-unicode-at-startup"].connect((key) => {
|
|
+ set_load_unicode_at_startup();
|
|
+ });
|
|
}
|
|
|
|
|
|
@@ -148,7 +160,11 @@ class PanelBinding : IBus.PanelService {
|
|
IBusEmojier.set_annotation_lang(
|
|
m_settings_emoji.get_string("lang"));
|
|
m_emojier_set_emoji_lang_id = 0;
|
|
- IBusEmojier.load_unicode_dict();
|
|
+ m_loaded_emoji = true;
|
|
+ if (m_load_unicode_at_startup && !m_loaded_unicode) {
|
|
+ IBusEmojier.load_unicode_dict();
|
|
+ m_loaded_unicode = true;
|
|
+ }
|
|
return false;
|
|
});
|
|
}
|
|
@@ -164,7 +180,21 @@ class PanelBinding : IBus.PanelService {
|
|
}
|
|
|
|
|
|
+ private void set_load_emoji_at_startup() {
|
|
+ m_load_emoji_at_startup =
|
|
+ m_settings_emoji.get_boolean("load-emoji-at-startup");
|
|
+ }
|
|
+
|
|
+
|
|
+ private void set_load_unicode_at_startup() {
|
|
+ m_load_unicode_at_startup =
|
|
+ m_settings_emoji.get_boolean("load-unicode-at-startup");
|
|
+ }
|
|
+
|
|
public void load_settings() {
|
|
+
|
|
+ set_load_emoji_at_startup();
|
|
+ set_load_unicode_at_startup();
|
|
BindingCommon.unbind_switch_shortcut(BindingCommon.KeyEventFuncType.ANY,
|
|
m_keybindings);
|
|
bind_emoji_shortcut();
|
|
@@ -172,7 +202,8 @@ class PanelBinding : IBus.PanelService {
|
|
m_settings_emoji,
|
|
ref m_css_provider);
|
|
set_emoji_favorites();
|
|
- set_emoji_lang();
|
|
+ if (m_load_emoji_at_startup && !m_loaded_emoji)
|
|
+ set_emoji_lang();
|
|
set_emoji_partial_match();
|
|
}
|
|
|
|
@@ -191,6 +222,12 @@ class PanelBinding : IBus.PanelService {
|
|
|
|
|
|
private void show_emojier(Gdk.Event event) {
|
|
+ if (!m_loaded_emoji)
|
|
+ set_emoji_lang();
|
|
+ if (!m_loaded_unicode && m_loaded_emoji) {
|
|
+ IBusEmojier.load_unicode_dict();
|
|
+ m_loaded_unicode = true;
|
|
+ }
|
|
m_emojier = new IBusEmojier();
|
|
string emoji = m_emojier.run(m_real_current_context_path, event);
|
|
if (emoji == null) {
|
|
--
|
|
2.14.3
|
|
|