diff --git a/client/gtk2/ibusim.c b/client/gtk2/ibusim.c index 55609ce73..e196d5360 100644 --- a/client/gtk2/ibusim.c +++ b/client/gtk2/ibusim.c @@ -77,3 +77,23 @@ im_module_list (const GtkIMContextInfo ***contexts, *n_contexts = G_N_ELEMENTS (info_list); } +G_MODULE_EXPORT const char * +im_get_context_id (int *argc, + char ***argv) +{ + GtkIMContext *context; + char *preedit_string = NULL; + PangoAttrList *preedit_attrs = NULL; + const char *context_id; + + gtk_init (argc, argv); + context = gtk_im_multicontext_new (); + gtk_im_context_get_preedit_string (context, + &preedit_string, + &preedit_attrs, + 0); + context_id = gtk_im_multicontext_get_context_id ( + GTK_IM_MULTICONTEXT (context)); + return context_id; +} + diff --git a/client/gtk4/ibusim.c b/client/gtk4/ibusim.c index 5ecf9778c..562bdf2d9 100644 --- a/client/gtk4/ibusim.c +++ b/client/gtk4/ibusim.c @@ -50,3 +50,23 @@ g_io_im_ibus_unload (GTypeModule *type_module) g_type_module_unuse (type_module); } +G_MODULE_EXPORT const char * +im_get_context_id (int *argc, + char ***argv) +{ + GtkIMContext *context; + char *preedit_string = NULL; + PangoAttrList *preedit_attrs = NULL; + const char *context_id; + + gtk_init (); + context = gtk_im_multicontext_new (); + gtk_im_context_get_preedit_string (context, + &preedit_string, + &preedit_attrs, + 0); + context_id = gtk_im_multicontext_get_context_id ( + GTK_IM_MULTICONTEXT (context)); + return context_id; +} + diff --git a/po/ibus10.pot b/po/ibus10.pot index 09c09be76..1937f76ef 100644 --- a/po/ibus10.pot +++ b/po/ibus10.pot @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ibus 1.5.26\n" "Report-Msgid-Bugs-To: https://github.com/ibus/ibus/issues\n" -"POT-Creation-Date: 2022-07-06 22:08+0900\n" -"PO-Revision-Date: 2022-07-06 22:08+0900\n" +"POT-Creation-Date: 2022-07-07 00:32+0900\n" +"PO-Revision-Date: 2022-07-07 00:32+0900\n" "Last-Translator: Takao Fujiwara \n" "Language-Team: Source\n" "Language: \n" @@ -3099,6 +3099,11 @@ msgstr "" msgid "Supplementary Private Use Area-B" msgstr "" +#: tools/ibusimmodule.c:10 +msgid "" +"Type im-module TYPE = \"gtk2\", \"gtk3\", \"gtk4\". Default is \"gtk3\"." +msgstr "" + #: tools/main.vala:182 msgid "List engine name only" msgstr "" @@ -3170,74 +3175,78 @@ msgstr "" msgid "Done" msgstr "" -#: tools/main.vala:691 +#: tools/main.vala:700 msgid "Set or get engine" msgstr "" -#: tools/main.vala:692 +#: tools/main.vala:701 msgid "Exit ibus-daemon" msgstr "" -#: tools/main.vala:693 +#: tools/main.vala:702 msgid "Show available engines" msgstr "" -#: tools/main.vala:694 +#: tools/main.vala:703 msgid "(Not implemented)" msgstr "" -#: tools/main.vala:695 +#: tools/main.vala:704 msgid "Restart ibus-daemon" msgstr "" -#: tools/main.vala:696 +#: tools/main.vala:705 msgid "Start ibus-daemon" msgstr "" -#: tools/main.vala:697 +#: tools/main.vala:706 msgid "Show version" msgstr "" -#: tools/main.vala:698 +#: tools/main.vala:707 msgid "Show the content of registry cache" msgstr "" -#: tools/main.vala:699 +#: tools/main.vala:708 msgid "Create registry cache" msgstr "" -#: tools/main.vala:700 +#: tools/main.vala:709 msgid "Print the D-Bus address of ibus-daemon" msgstr "" -#: tools/main.vala:701 +#: tools/main.vala:710 msgid "Show the configuration values" msgstr "" -#: tools/main.vala:702 +#: tools/main.vala:711 msgid "Reset the configuration values" msgstr "" -#: tools/main.vala:704 +#: tools/main.vala:713 msgid "Save emoji on dialog to clipboard" msgstr "" -#: tools/main.vala:706 +#: tools/main.vala:715 +msgid "Retrieve im-module value from GTK instance" +msgstr "" + +#: tools/main.vala:717 msgid "Show this information" msgstr "" -#: tools/main.vala:713 +#: tools/main.vala:724 #, c-format msgid "" "Usage: %s COMMAND [OPTION...]\n" "\n" msgstr "" -#: tools/main.vala:714 +#: tools/main.vala:725 msgid "Commands:\n" msgstr "" -#: tools/main.vala:744 +#: tools/main.vala:755 #, c-format msgid "%s is unknown command!\n" msgstr "" diff --git a/tools/IBusIMModule-1.0.metadata b/tools/IBusIMModule-1.0.metadata new file mode 100644 index 000000000..14adc9ee8 --- /dev/null +++ b/tools/IBusIMModule-1.0.metadata @@ -0,0 +1 @@ +IBusIMModule cheader_filename="ibusimmodule.h" name="IBusIMModule" diff --git a/tools/Makefile.am b/tools/Makefile.am index e380a9aa9..a9262ee04 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -24,9 +24,19 @@ NULL = libibus = $(top_builddir)/src/libibus-@IBUS_API_VERSION@.la +libibusimmodule = libibusimmodule.la +ibusimmodule_gir = IBusIMModule-1.0.gir +ibus_immodule_vapi = ibus-immodule-1.0.vapi libibus_emoji_dialog = \ $(top_builddir)/ui/gtk3/libibus-emoji-dialog-@IBUS_API_VERSION@.la +noinst_LTLIBRARIES = $(libibusimmodule) +noinst_DATA = +INTROSPECTION_GIRS = +MAINTAINERCLEANFILES = +DISTCLEANFILES = +VAPIGEN_VAPIS = + # force include config.h before gi18n.h. AM_CPPFLAGS = \ -I$(top_srcdir)/src \ @@ -47,22 +57,26 @@ AM_CFLAGS = \ $(NULL) AM_LDADD = \ - @GOBJECT2_LIBS@ \ - @GLIB2_LIBS@ \ - @GIO2_LIBS@ \ - @GTHREAD2_LIBS@ \ - $(libibus) \ - $(NULL) + @GOBJECT2_LIBS@ \ + @GLIB2_LIBS@ \ + @GIO2_LIBS@ \ + @GTHREAD2_LIBS@ \ + $(libibus) \ + $(libibusimmodule) \ + $(NULL) AM_VALAFLAGS = \ - --vapidir=$(top_builddir)/bindings/vala \ - --vapidir=$(top_srcdir)/bindings/vala \ - --pkg=gio-2.0 \ - --pkg=ibus-1.0 \ - --pkg=posix \ - --pkg=config \ - --target-glib="$(VALA_TARGET_GLIB_VERSION)" \ - $(NULL) + --vapidir=$(top_builddir)/bindings/vala \ + --vapidir=$(top_srcdir)/bindings/vala \ + --vapidir=$(builddir) \ + --vapidir=$(srcdir) \ + --pkg=gio-2.0 \ + --pkg=ibus-1.0 \ + --pkg=ibus-immodule-1.0 \ + --pkg=posix \ + --pkg=config \ + --target-glib="$(VALA_TARGET_GLIB_VERSION)" \ + $(NULL) bin_PROGRAMS = ibus @@ -79,9 +93,27 @@ bash_completion_DATA= \ $(NULL) bash_completiondir=@datadir@/bash-completion/completions +libibusimmodule_la_SOURCES = \ + ibusimmodule.c \ + ibusimmodule.h \ + $(NULL) +libibusimmodule_la_CFLAGS = \ + @GLIB2_CFLAGS@ \ + -DGTK2_IM_MODULEDIR=\"$(GTK2_IM_MODULEDIR)\" \ + -DGTK3_IM_MODULEDIR=\"$(GTK3_IM_MODULEDIR)\" \ + -DGTK4_IM_MODULEDIR=\"$(GTK4_IM_MODULEDIR)\" \ + $(NULL) +libibusimmodule_la_LIBADD = \ + @GLIB2_LIBS@ \ + $(NULL) +libibusimmodule_la_LDFLAGS = \ + -no-undefined \ + -export-symbols-regex "ibus_.*" \ + $(NULL) + man_one_in_files = ibus.1.in man_one_files = $(man_one_in_files:.1.in=.1) -man_one_DATA =$(man_one_files:.1=.1.gz) +man_one_DATA =$(man_one_files:.1=.1.gz) man_onedir = $(mandir)/man1 %.1: %.1.in $(AM_V_GEN) sed \ @@ -91,14 +123,17 @@ man_onedir = $(mandir)/man1 $(AM_V_GEN) gzip -c $< > $@.tmp && mv $@.tmp $@ EXTRA_DIST = \ - $(man_one_in_files) \ - ibus.bash \ - $(NULL) + $(ibus_immodule_vapi) \ + $(ibusimmodule_gir) \ + $(man_one_in_files) \ + ibus.bash \ + IBusIMModule-1.0.metadata \ + $(NULL) CLEANFILES = \ - $(man_one_DATA) \ - $(man_one_files) \ - $(NULL) + $(man_one_DATA) \ + $(man_one_files) \ + $(NULL) if ENABLE_EMOJI_DICT if ENABLE_UI @@ -108,4 +143,43 @@ AM_VALAFLAGS += \ endif endif +if HAVE_INTROSPECTION +BUILT_SOURCES = $(INTROSPECTION_GIRS) $(VAPIGEN_VAPIS) + +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_SCANNER_ARGS = +INTROSPECTION_COMPILER_ARGS = \ + --includedir=$(srcdir) \ + --includedir=. \ + $(NULL) + +IBusIMModule-1.0.gir: $(libibusimmodule) Makefile +IBusIMModule_1_0_gir_SCANNERFLAGS = \ + --pkg=glib-2.0 \ + $(IBUS_GIR_SCANNERFLAGS) \ + $(NULL) +IBusIMModule_1_0_gir_INCLUDES = GLib-2.0 +IBusIMModule_1_0_gir_LIBS = $(libibusimmodule) +IBusIMModule_1_0_gir_FILES = ibusimmodule.h +IBusIMModule_1_0_gir_CFLAGS = \ + -I$(srcdir) \ + -I$(builddir) \ + $(NULL) + +INTROSPECTION_GIRS += $(ibusimmodule_gir) +noinst_DATA += $(ibusimmodule_gir) +MAINTAINERCLEANFILES += $(ibusimmodule_gir) +DISTCLEANFILES += $(ibusimmodule_gir) + +-include $(VAPIGEN_MAKEFILE) +ibus-immodule-1.0.vapi: $(ibusimmodule_gir) IBusIMModule-1.0.metadata +ibus_immodule_1_0_vapi_DEPS = glib-2.0 +ibus_immodule_1_0_vapi_METADATADIRS = $(srcdir) +ibus_immodule_1_0_vapi_FILES = IBusIMModule-1.0.gir +VAPIGEN_VAPIS += $(ibus_immodule_vapi) +noinst_DATA += $(ibus_immodule_vapi) +MAINTAINERCLEANFILES += $(ibus_immodule_vapi) +DISTCLEANFILES += $(ibus_immodule_vapi) +endif + -include $(top_srcdir)/git.mk diff --git a/tools/ibus.1.in b/tools/ibus.1.in index fe1b71573..84ef5fff4 100644 --- a/tools/ibus.1.in +++ b/tools/ibus.1.in @@ -128,6 +128,16 @@ option enables to match annotations with a partial string. These settings are available with .B ibus\-setup (1) utility. +.TP +\fBim-module\fR [\fB\-\-type=TYPE|\-\-help\fR] +Show an internal im-module value in a virtual GTK application. If IBus is +installed and configured properly, the output is "ibus". This sub-command +is useful for some users who build IBus from the source codes and check +the configurations. Currently the sub-command supports GTK applications only +and the default is GTK3. If you wish to check a GTK4 application, you can +specify +.B \-\-type=gtk4 +option and you can choose one of "gtk2", "gtk3" and "gtk4". .SH BUGS If you find a bug, please report it at https://github.com/ibus/ibus/issues diff --git a/tools/ibusimmodule.c b/tools/ibusimmodule.c new file mode 100644 index 000000000..20ccc7480 --- /dev/null +++ b/tools/ibusimmodule.c @@ -0,0 +1,87 @@ +#include +#include +#include + +#ifndef DEFAULT_IM_MODULE_TYPE +#define DEFAULT_IM_MODULE_TYPE "gtk3" +#endif + +#define OPTION_TYPE_MESSAGE \ + N_("Type im-module TYPE = \"gtk2\", \"gtk3\", \"gtk4\". Default is " \ + "\"gtk3\".") + +typedef const char * (* IBusIMGetContextIdFunc) (int *argc, char ***argv); + +static char *im_module_type; + + +char * +ibus_im_module_get_id (int argc, char *argv[]) +{ + static const GOptionEntry options[3] = { + { "type", (char)0, (int)0, G_OPTION_ARG_STRING, &im_module_type, + OPTION_TYPE_MESSAGE, + "TYPE"}, + { NULL } + }; + GOptionContext *option; + GError *error = NULL; + void *module; + char *im_context_id; + IBusIMGetContextIdFunc im_get_context_id; + + if (!(option = g_option_context_new (NULL))) { + g_critical ("malloc GOptionContext is failed."); + return NULL; + } + g_option_context_add_main_entries (option, options, GETTEXT_PACKAGE); + g_option_context_parse (option, &argc, &argv, &error); + if (error) { + g_critical ("%s", error->message); + g_clear_error (&error); + return NULL; + } + g_option_context_free (option); + if (!im_module_type) + im_module_type = g_strdup (DEFAULT_IM_MODULE_TYPE); + + if (G_LIKELY (!g_strcmp0 (im_module_type, "gtk3"))) { + module = dlopen (GTK3_IM_MODULEDIR "/im-ibus.so", + RTLD_LAZY); + } else if (!g_strcmp0 (im_module_type, "gtk4")) { + const char *module_path_env = g_getenv ("GTK_PATH"); + char *module_path; + if (module_path_env) { + module_path = g_build_filename (module_path_env, + GTK4_IM_MODULEDIR "/libim-ibus.so", + NULL); + } else { + module_path = g_strdup (GTK4_IM_MODULEDIR "/libim-ibus.so"); + } + module = dlopen (module_path, RTLD_LAZY); + g_free (module_path); + } else if (!g_strcmp0 (im_module_type, "gtk2")) { + module = dlopen (GTK2_IM_MODULEDIR "/im-ibus.so", + RTLD_LAZY); + } else { + module = dlopen (im_module_type, RTLD_LAZY); + } + if (!module) { + g_warning ("Not found module: %s", dlerror ()); + return NULL; + } + + im_get_context_id = dlsym (module, "im_get_context_id"); + if (!im_get_context_id) { + g_warning ("Not found im_get_context_id: %s", dlerror ()); + dlclose (module); + return NULL; + } + + im_context_id = strdup (im_get_context_id (&argc, &argv)); + dlclose (module); + return im_context_id; +} + +#undef DEFAULT_IM_MODULE_TYPE + diff --git a/tools/ibusimmodule.h b/tools/ibusimmodule.h new file mode 100644 index 000000000..e762a7472 --- /dev/null +++ b/tools/ibusimmodule.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* ibus - The Input Bus + * Copyright (C) 2022 Takao Fujiwara + * + * 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 + */ + +#ifndef __IBUS_IM_MODULE_CONTEXT_H_ +#define __IBUS_IM_MODULE_CONTEXT_H_ + +/** + * ibus_im_module_get_id: + * @argc: The length of argv + * @argv: (array length=argc) (element-type utf8): argv from main() + * + * Retrieve im-module value from GTK instance. + * + * Returns: (nullable): im-module value. + */ +char * ibus_im_module_get_id (int argc, char *argv[]); + +#endif diff --git a/tools/main.vala b/tools/main.vala index 407eaf74b..1fed24408 100644 --- a/tools/main.vala +++ b/tools/main.vala @@ -671,6 +671,15 @@ int emoji_dialog(string[] argv) { #endif +int read_im_module(string[] argv) { + string? im_module = IBusIMModule.im_module_get_id(argv); + if (im_module == null) + return Posix.EXIT_FAILURE; + print("%s\n".printf(im_module)); + return Posix.EXIT_SUCCESS; +} + + int print_help(string[] argv) { print_usage(stdout); return Posix.EXIT_SUCCESS; @@ -702,6 +711,8 @@ const CommandEntry commands[] = { #if EMOJI_DICT { "emoji", N_("Save emoji on dialog to clipboard"), emoji_dialog }, #endif + { "im-module", N_("Retrieve im-module value from GTK instance"), + read_im_module }, { "help", N_("Show this information"), print_help } };