From e12eb4be6d83cff082bdfa5fb22bf689db79c5d3 Mon Sep 17 00:00:00 2001 From: William Hua Date: Fri, 13 Jun 2014 09:50:24 -0400 Subject: Basic Fcitx support. --- configure.ac | 4 ++ debian/control | 1 + deps/Fcitx-1.0.metadata | 7 +++ deps/README | 4 ++ deps/fcitx.vapi | 97 ++++++++++++++++++++++++++++++++++ lib/Makefile.am | 3 ++ lib/source.vala | 136 ++++++++++++++++++++++++++++++++---------------- 7 files changed, 207 insertions(+), 45 deletions(-) create mode 100644 deps/Fcitx-1.0.metadata create mode 100644 deps/fcitx.vapi diff --git a/configure.ac b/configure.ac index dc2f0bae..38a445fd 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,10 @@ PKG_CHECK_MODULES([IBUS], [ibus-1.0]) AC_SUBST([IBUS_CFLAGS]) AC_SUBST([IBUS_LIBS]) +PKG_CHECK_MODULES([FCITX_GCLIENT], [fcitx-gclient]) +AC_SUBST([FCITX_GCLIENT_CFLAGS]) +AC_SUBST([FCITX_GCLIENT_LIBS]) + PKG_CHECK_MODULES([ACCOUNTSSERVICE], [accountsservice]) AC_SUBST([ACCOUNTSSERVICE_CFLAGS]) AC_SUBST([ACCOUNTSSERVICE_LIBS]) diff --git a/debian/control b/debian/control index 585af9c5..a359f3d9 100644 --- a/debian/control +++ b/debian/control @@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 9.0.0), dh-autoreconf, dh-translations, dbus, + fcitx-libs-dev (>= 1:4.2.8.3), libaccountsservice-dev, libgee-dev, libgirepository1.0-dev, diff --git a/deps/Fcitx-1.0.metadata b/deps/Fcitx-1.0.metadata new file mode 100644 index 00000000..81c20f3c --- /dev/null +++ b/deps/Fcitx-1.0.metadata @@ -0,0 +1,7 @@ +Client cheader_filename="fcitx-gclient/fcitxclient.h" +Connection cheader_filename="fcitx-gclient/fcitxconnection.h" +IMItem cheader_filename="fcitx-gclient/fcitxinputmethod.h" +InputMethod cheader_filename="fcitx-gclient/fcitxinputmethod.h" +Kbd cheader_filename="fcitx-gclient/fcitxkbd.h" +LayoutItem cheader_filename="fcitx-gclient/fcitxkbd.h" +PreeditItem cheader_filename="fcitx-gclient/fcitxclient.h" diff --git a/deps/README b/deps/README index 80ca5e0d..c3666140 100644 --- a/deps/README +++ b/deps/README @@ -38,6 +38,10 @@ To generate ibus-1.0.vapi docs: valadoc --vapidir /path/to/vapi/dir -o ibus-1.0 /path/to/ibus-1.0.vapi +To generate fcitx.vapi: + +vapigen --metadatadir . --pkg gio-2.0 --library fcitx /path/to/Fcitx-1.0.gir + To generate libbamf3.vapi: vapigen --library libbamf3 /path/to/Bamf-3.gir diff --git a/deps/fcitx.vapi b/deps/fcitx.vapi new file mode 100644 index 00000000..fbf5e925 --- /dev/null +++ b/deps/fcitx.vapi @@ -0,0 +1,97 @@ +/* fcitx.vapi generated by vapigen, do not modify. */ + +[CCode (cprefix = "Fcitx", gir_namespace = "Fcitx", gir_version = "1.0", lower_case_cprefix = "fcitx_")] +namespace Fcitx { + [CCode (cheader_filename = "fcitx-gclient/fcitxclient.h", type_id = "fcitx_client_get_type ()")] + public class Client : GLib.Object { + [CCode (has_construct_function = false)] + public Client (); + public void close_ic (); + public void enable_ic (); + public void focus_in (); + public void focus_out (); + public bool is_valid (); + [Deprecated] + public async int process_key (uint32 keyval, uint32 keycode, uint32 state, int type, uint32 t); + public async int process_key_async (uint32 keyval, uint32 keycode, uint32 state, int type, uint32 t, int timeout_msec, GLib.Cancellable? cancellable); + public int process_key_sync (uint32 keyval, uint32 keycode, uint32 state, int type, uint32 t); + public void reset (); + public void set_capacity (uint flags); + public void set_cursor_rect (int x, int y, int w, int h); + [Deprecated] + public void set_cusor_rect (int x, int y, int w, int h); + public void set_surrounding_text (string? text, uint cursor, uint anchor); + public signal void close_im (); + public signal void commit_string (string string); + public signal void connected (); + public signal void delete_surrounding_text (int cursor, uint len); + public signal void disconnected (); + public signal void enable_im (); + public signal void forward_key (uint keyval, int state, int type); + public signal void update_client_side_ui (string auxup, string auxdown, string preedit, string candidateword, string imname, int cursor_pos); + public signal void update_formatted_preedit (GLib.GenericArray preedit, int cursor); + } + [CCode (cheader_filename = "fcitx-gclient/fcitxconnection.h", type_id = "fcitx_connection_get_type ()")] + public class Connection : GLib.Object { + [CCode (has_construct_function = false)] + public Connection (); + public unowned GLib.DBusConnection get_g_dbus_connection (); + public bool is_valid (); + public signal void connected (); + public signal void disconnected (); + } + [CCode (cheader_filename = "fcitx-gclient/fcitxinputmethod.h", copy_function = "g_boxed_copy", free_function = "g_boxed_free", type_id = "fcitx_im_item_get_type ()")] + [Compact] + public class IMItem { + public bool enable; + public weak string langcode; + public weak string name; + public weak string unique_name; + [CCode (has_construct_function = false)] + public IMItem (string name, string unique_name, string langcode, bool enable); + } + [CCode (cheader_filename = "fcitx-gclient/fcitxinputmethod.h", type_id = "fcitx_input_method_get_type ()")] + public class InputMethod : GLib.DBusProxy, GLib.AsyncInitable, GLib.DBusInterface, GLib.Initable { + [CCode (has_construct_function = false)] + public InputMethod (GLib.BusType bus_type, GLib.DBusProxyFlags flags, int display_number, GLib.Cancellable? cancellable = null) throws GLib.Error; + public void activate (); + public void configure (); + public void configure_addon (string addon); + public void configure_im (string imname); + public void exit (); + public string get_current_im (); + public int get_current_state (); + public string get_current_ui (); + public string get_im_addon (string imname); + public GLib.GenericArray get_imlist_nofree (); + public void inactivate (); + public void reload_config (); + public void restart (); + public void set_current_im (string imname); + public void set_imlist (GLib.GenericArray array); + public void toggle (); + public signal void imlist_changed (); + } + [CCode (cheader_filename = "fcitx-gclient/fcitxkbd.h", type_id = "fcitx_kbd_get_type ()")] + public class Kbd : GLib.DBusProxy, GLib.AsyncInitable, GLib.DBusInterface, GLib.Initable { + [CCode (has_construct_function = false)] + public Kbd (GLib.BusType bus_type, GLib.DBusProxyFlags flags, int display_number, GLib.Cancellable? cancellable = null) throws GLib.Error; + public void get_layout_for_im (string imname, out string layout, out string variant); + public GLib.GenericArray get_layouts_nofree (); + public void set_default_layout (string layout, string variant); + public void set_layout_for_im (string imname, string layout, string variant); + } + [CCode (cheader_filename = "fcitx-gclient/fcitxkbd.h", copy_function = "g_boxed_copy", free_function = "g_boxed_free", type_id = "fcitx_layout_item_get_type ()")] + [Compact] + public class LayoutItem { + public weak string langcode; + public weak string layout; + public weak string name; + public weak string variant; + } + [CCode (cheader_filename = "fcitx-gclient/fcitxclient.h", has_type_id = false)] + public struct PreeditItem { + public weak global::string string; + public int32 type; + } +} diff --git a/lib/Makefile.am b/lib/Makefile.am index a19016d9..ae9dec00 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -26,6 +26,7 @@ indicator_keyboard_service_VALAFLAGS = $(AM_VALAFLAGS) \ --pkg Xkl-1.0 \ --pkg Gkbd-3.0 \ --pkg ibus-1.0 \ + --pkg fcitx \ --pkg accountsservice \ --pkg liblightdm-gobject-1 indicator_keyboard_service_CFLAGS = $(AM_CFLAGS) \ @@ -36,6 +37,7 @@ indicator_keyboard_service_CFLAGS = $(AM_CFLAGS) \ $(LIBXKLAVIER_CFLAGS) \ $(LIBGNOMEKBD_CFLAGS) \ $(IBUS_CFLAGS) \ + $(FCITX_GCLIENT_CFLAGS) \ $(ACCOUNTSSERVICE_CFLAGS) \ $(LIGHTDM_CFLAGS) \ $(COVERAGE_CFLAGS) @@ -47,6 +49,7 @@ indicator_keyboard_service_LDFLAGS = $(AM_LDFLAGS) \ $(LIBXKLAVIER_LIBS) \ $(LIBGNOMEKBD_LIBS) \ $(IBUS_LIBS) \ + $(FCITX_GCLIENT_LIBS) \ $(ACCOUNTSSERVICE_LIBS) \ $(LIGHTDM_LIBS) \ $(COVERAGE_LDFLAGS) diff --git a/lib/source.vala b/lib/source.vala index 5fe7157d..2777f521 100644 --- a/lib/source.vala +++ b/lib/source.vala @@ -19,10 +19,12 @@ public class Indicator.Keyboard.Source : Object { private static Gnome.XkbInfo? xkb_info; - private static IBus.Bus? bus; + private static IBus.Bus? ibus_bus; + private static Fcitx.InputMethod? fcitx_proxy; private string? xkb; private string? ibus; + private string? fcitx; private string? _name; private string? _short_name; @@ -77,6 +79,10 @@ public class Indicator.Keyboard.Source : Object { get { return ibus != null; } } + public bool is_fcitx { + get { return fcitx != null; } + } + public Source (Variant variant, bool use_gtk = false) { Object (use_gtk: use_gtk); @@ -90,6 +96,8 @@ public class Indicator.Keyboard.Source : Object { xkb = name; } else if (type == "ibus") { ibus = name; + } else if (type == "fcitx") { + fcitx = name; } } else if (variant.is_of_type (new VariantType ("a{ss}"))) { VariantIter iter; @@ -103,6 +111,8 @@ public class Indicator.Keyboard.Source : Object { xkb = value; } else if (key == "ibus") { ibus = value; + } else if (key == "fcitx") { + fcitx = value; } } } @@ -116,13 +126,21 @@ public class Indicator.Keyboard.Source : Object { return (!) xkb_info; } - private static IBus.Bus get_bus () { - if (bus == null) { + private static IBus.Bus get_ibus_bus () { + if (ibus_bus == null) { IBus.init (); - bus = new IBus.Bus (); + ibus_bus = new IBus.Bus (); } - return (!) bus; + return (!) ibus_bus; + } + + private static Fcitx.InputMethod get_fcitx_proxy () throws Error { + if (fcitx_proxy == null) { + fcitx_proxy = new Fcitx.InputMethod (GLib.BusType.SESSION, GLib.DBusProxyFlags.NONE, 0); + } + + return (!) fcitx_proxy; } private IBus.EngineDesc? get_engine () { @@ -132,7 +150,7 @@ public class Indicator.Keyboard.Source : Object { var names = new string[2]; names[0] = (!) ibus; - var engines = get_bus ().get_engines_by_names (names); + var engines = get_ibus_bus ().get_engines_by_names (names); if (engines.length > 0) { engine = engines[0]; @@ -145,31 +163,7 @@ public class Indicator.Keyboard.Source : Object { protected virtual string? _get_name () { string? name = null; - var engine = get_engine (); - - if (engine != null) { - string? language = ((!) engine).get_language (); - string? display_name = ((!) engine).get_longname (); - var has_language = language != null && ((!) language).get_char () != '\0'; - var has_display_name = display_name != null && ((!) display_name).get_char () != '\0'; - - if (has_language) { - language = Xkl.get_language_name ((!) language); - has_language = language != null && ((!) language).get_char () != '\0'; - } - - if (has_language && has_display_name) { - name = @"$((!) language) ($((!) display_name))"; - } else if (has_language) { - name = language; - } else if (has_display_name) { - name = display_name; - } - } - - var has_name = name != null && ((!) name).get_char () != '\0'; - - if (!has_name && xkb != null) { + if (xkb != null) { string? display_name = null; string? layout = null; @@ -194,14 +188,53 @@ public class Indicator.Keyboard.Source : Object { name = country; } } - } - if (name == null || ((!) name).get_char () == '\0') { - if (ibus != null) { - name = ibus; - } else if (xkb != null) { + if (name == null || ((!) name).get_char () == '\0') { name = xkb; } + } else if (ibus != null) { + var engine = get_engine (); + + if (engine != null) { + string? language = ((!) engine).get_language (); + string? display_name = ((!) engine).get_longname (); + var has_language = language != null && ((!) language).get_char () != '\0'; + var has_display_name = display_name != null && ((!) display_name).get_char () != '\0'; + + if (has_language) { + language = Xkl.get_language_name ((!) language); + has_language = language != null && ((!) language).get_char () != '\0'; + } + + if (has_language && has_display_name) { + name = @"$((!) language) ($((!) display_name))"; + } else if (has_language) { + name = language; + } else if (has_display_name) { + name = display_name; + } + } + + if (name == null || ((!) name).get_char () == '\0') { + name = ibus; + } + } else if (fcitx != null) { + try { + var input_methods = get_fcitx_proxy ().get_imlist_nofree (); + + for (var i = 0; i < input_methods.length; i++) { + if (input_methods.get (i).unique_name == (!) fcitx) { + name = input_methods.get (i).name; + break; + } + } + } catch (Error error) { + warning ("error: %s", error.message); + } + + if (name == null || ((!) name).get_char () == '\0') { + name = fcitx; + } } return name; @@ -212,23 +245,36 @@ public class Indicator.Keyboard.Source : Object { if (xkb != null) { get_xkb_info ().get_layout_info ((!) xkb, null, out short_name, null, null); - } - var has_short_name = short_name != null && ((!) short_name).get_char () != '\0'; - - if (!has_short_name) { + if (short_name == null || ((!) short_name).get_char () == '\0') { + short_name = xkb; + } + } else if (ibus != null) { var engine = get_engine (); if (engine != null) { short_name = ((!) engine).get_name (); } - } - if (short_name == null || ((!) short_name).get_char () == '\0') { - if (ibus != null) { + if (short_name == null || ((!) short_name).get_char () == '\0') { short_name = ibus; - } else if (xkb != null) { - short_name = xkb; + } + } else if (fcitx != null) { + try { + var input_methods = get_fcitx_proxy ().get_imlist_nofree (); + + for (var i = 0; i < input_methods.length; i++) { + if (input_methods.get (i).unique_name == (!) fcitx) { + short_name = input_methods.get (i).langcode; + break; + } + } + } catch (Error error) { + warning ("error: %s", error.message); + } + + if (short_name == null || ((!) short_name).get_char () == '\0') { + short_name = fcitx; } } -- cgit v1.2.3