From 6786b0e985fe4ca78974218a58fb14785c175e00 Mon Sep 17 00:00:00 2001 From: glasseyes Date: Tue, 28 Aug 2018 14:37:17 +0700 Subject: [PATCH 1/9] WIP: ibus-kmfl and dbus --- linux/ibus-kmfl/src/Makefile.am | 2 + linux/ibus-kmfl/src/engine.c | 25 +- linux/ibus-kmfl/src/keyman-service.c | 379 +++++++++++++++++++++++++++ linux/ibus-kmfl/src/keyman-service.h | 69 +++++ linux/ibus-kmfl/src/main.c | 5 + 5 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 linux/ibus-kmfl/src/keyman-service.c create mode 100644 linux/ibus-kmfl/src/keyman-service.h diff --git a/linux/ibus-kmfl/src/Makefile.am b/linux/ibus-kmfl/src/Makefile.am index df1e959e8f..d52a1aae08 100644 --- a/linux/ibus-kmfl/src/Makefile.am +++ b/linux/ibus-kmfl/src/Makefile.am @@ -53,6 +53,8 @@ ibus_engine_kmfl_SOURCES = \ main.c \ engine.c \ engine.h \ + keyman-service.c \ + keyman-service.h \ $(NULL) ibus_engine_kmfl_CFLAGS = \ @IBUS_CFLAGS@ \ diff --git a/linux/ibus-kmfl/src/engine.c b/linux/ibus-kmfl/src/engine.c index 5b825359d7..59a24abb84 100644 --- a/linux/ibus-kmfl/src/engine.c +++ b/linux/ibus-kmfl/src/engine.c @@ -29,6 +29,7 @@ #include #include "kmflutil.h" +#include "keyman-service.h" #include "engine.h" typedef struct _IBusKMFLEngine IBusKMFLEngine; @@ -196,6 +197,7 @@ ibus_kmfl_engine_constructor (GType type, engine_name = ibus_engine_get_name ((IBusEngine *) kmfl); g_assert (engine_name); + g_message("DAR: ibus_kmfl_engine_constructor %s", engine_name); if (im_table == NULL) { im_table = g_hash_table_new_full (g_str_hash, @@ -231,10 +233,11 @@ static void ibus_kmfl_engine_destroy (IBusKMFLEngine *kmfl) { const gchar *engine_name; - g_debug("DAR: ibus_kmfl_engine_destroy"); + g_debug("DAR: ibus_kmfl_engine_destroy"); engine_name = ibus_engine_get_name ((IBusEngine *) kmfl); g_assert (engine_name); + g_message("DAR: ibus_kmfl_engine_destroy %s", engine_name); if (kmfl->prop_list) { g_debug("DAR: unref kmfl->prop_list"); @@ -402,17 +405,37 @@ ibus_kmfl_engine_reset (IBusEngine *engine) static void ibus_kmfl_engine_enable (IBusEngine *engine) { + const gchar *engine_name; IBusKMFLEngine *kmfl = (IBusKMFLEngine *) engine; + engine_name = ibus_engine_get_name (engine); + g_assert (engine_name); + g_message("WDG: ibus_kmfl_engine_enable %s", engine_name); + // own dbus name com.Keyman + // expose properties LDMLFile and Name + KeymanService *service = km_service_get_default(); + //const gchar *ldmlfile = ""; + km_service_set_ldmlfile (service, engine_name); + km_service_set_name (service, engine_name); parent_class->enable (engine); } static void ibus_kmfl_engine_disable (IBusEngine *engine) { + const gchar *engine_name; IBusKMFLEngine *kmfl = (IBusKMFLEngine *) engine; + engine_name = ibus_engine_get_name (engine); + g_assert (engine_name); + g_message("WDG: ibus_kmfl_engine_disable %s", engine_name); ibus_kmfl_engine_focus_out (engine); + // stop owning dbus name com.Keyman + KeymanService *service = km_service_get_default(); + km_service_set_ldmlfile (service, ""); + km_service_set_name (service, "None"); + // g_clear_object(&service); + parent_class->disable (engine); } diff --git a/linux/ibus-kmfl/src/keyman-service.c b/linux/ibus-kmfl/src/keyman-service.c new file mode 100644 index 0000000000..c768430677 --- /dev/null +++ b/linux/ibus-kmfl/src/keyman-service.c @@ -0,0 +1,379 @@ +/* vim:set et sts=4: */ + +/* + * KMFL Input Method for IBUS (The Input Bus) + * + * Copyright (C) 2018 SIL International + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 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 + * General Public License for more details. + * + * You should have received a copy of the GNU 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 based on work from Mousetweaks + Copyright © 2007-2010 Gerd Kohlberger +*/ + +#include + +#include "keyman-service.h" + +struct _KeymanServicePrivate +{ + guint owner_id; + GDBusNodeInfo *ispec; + + gchar * name; + gchar * ldmlfile; +}; + +enum +{ + PROP_0, + PROP_NAME, + PROP_LDMLFILE +}; + +static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + ""; + +static void km_service_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer data); + +G_DEFINE_TYPE (KeymanService, km_service, G_TYPE_OBJECT) + +static void +km_service_init (KeymanService *service) +{ + KeymanServicePrivate *priv; + GError *error = NULL; + + g_message("WDG: km_service_init"); + + service->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (service, + KM_TYPE_SERVICE, + KeymanServicePrivate); + + priv->name = g_strdup ("None"); + priv->ldmlfile = g_strdup (""); + priv->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + KEYMAN_DBUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + km_service_bus_acquired, + NULL, NULL, + service, NULL); + priv->ispec = g_dbus_node_info_new_for_xml (introspection_xml, &error); + if (error) + { + g_warning ("%s\n", error->message); + g_error_free (error); + } +} + +static void +km_service_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + KeymanService *service = KM_SERVICE (object); + + switch (prop_id) + { + case PROP_NAME: + if (service->priv->name) + { + g_free(service->priv->name); + } + service->priv->name = g_value_dup_string (value); + break; + case PROP_LDMLFILE: + if (service->priv->ldmlfile) + { + g_free(service->priv->ldmlfile); + } + service->priv->ldmlfile = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +km_service_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + KeymanService *service = KM_SERVICE (object); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, service->priv->name); + break; + case PROP_LDMLFILE: + g_value_set_string (value, service->priv->ldmlfile); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +km_service_dispose (GObject *object) +{ + g_message("WDG: km_service_dispose"); + KeymanServicePrivate *priv = KM_SERVICE (object)->priv; + + if (priv->owner_id) + { + g_bus_unown_name (priv->owner_id); + priv->owner_id = 0; + } + + if (priv->ispec) + { + g_dbus_node_info_unref (priv->ispec); + priv->ispec = NULL; + } + + if (priv->name) + { + g_free(priv->name); + } + + if (priv->ldmlfile) + { + g_free(priv->ldmlfile); + } + + G_OBJECT_CLASS (km_service_parent_class)->dispose (object); +} + +static void +km_service_class_init (KeymanServiceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = km_service_get_property; + object_class->set_property = km_service_set_property; + object_class->dispose = km_service_dispose; + + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "Name of the currently active Keyman keyboard", + "None", + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_LDMLFILE, + g_param_spec_string ("ldmlfile", + "LDML file", + "On screen keyboard file for the currently active Keyman keyboard", + "", + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private (klass, sizeof (KeymanServicePrivate)); +} + +static GVariant * +handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *path, + const gchar *interface_name, + const gchar *property, + GError **error, + KeymanService *service) +{ + GVariant *ret = NULL; + + if (g_strcmp0 (property, "Name") == 0) + { + ret = g_variant_new_string (service->priv->name); + } + else if (g_strcmp0 (property, "LDMLFile") == 0) + { + ret = g_variant_new_string (service->priv->ldmlfile); + } + return ret; +} + +static gboolean +handle_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *path, + const gchar *interface, + const gchar *property, + GVariant *value, + GError **error, + KeymanService *service) +{ + gsize sz; + if (g_strcmp0 (property, "Name") == 0) + { + km_service_set_name (service, g_variant_dup_string (value, &sz)); + } + else if (g_strcmp0 (property, "LDMLFile") == 0) + { + km_service_set_ldmlfile (service, g_variant_dup_string (value, &sz)); + } + return TRUE; +} + +static const GDBusInterfaceVTable interface_vtable = +{ + (GDBusInterfaceMethodCallFunc) NULL, + (GDBusInterfaceGetPropertyFunc) handle_get_property, + (GDBusInterfaceSetPropertyFunc) handle_set_property +}; + +static void +emit_property_changed (GObject *object, + GParamSpec *pspec, + GDBusConnection *connection) +{ + KeymanService *service = KM_SERVICE (object); + GError *error = NULL; + GVariantBuilder builder, inv_builder; + GVariant *prop_v; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_init (&inv_builder, G_VARIANT_TYPE ("as")); + + if (g_strcmp0 (pspec->name, "name") == 0) + { + g_variant_builder_add (&builder, "{sv}", "Name", + g_variant_new_string (service->priv->name)); + } + else if (g_strcmp0 (pspec->name, "ldmlfile") == 0) + { + g_variant_builder_add (&builder, "{sv}", "LDMLFile", + g_variant_new_string (service->priv->ldmlfile)); + } + + prop_v = g_variant_new ("(sa{sv}as)", + KEYMAN_DBUS_IFACE, + &builder, &inv_builder); + + if (!g_dbus_connection_emit_signal (connection, NULL, + KEYMAN_DBUS_PATH, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + prop_v, &error)) + { + g_warning ("%s\n", error->message); + g_error_free (error); + } +} + +static void +km_service_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer data) +{ + KeymanService *service = data; + + if (service->priv->ispec) + { + GError *error = NULL; + + g_dbus_connection_register_object (connection, + KEYMAN_DBUS_PATH, + service->priv->ispec->interfaces[0], + &interface_vtable, + service, NULL, &error); + if (error) + { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_signal_connect (service, "notify", + G_CALLBACK (emit_property_changed), connection); + } +} + +KeymanService * +km_service_get_default (void) +{ + static KeymanService *service = NULL; + + // if (service) + // { + // g_free(service); + // service = g_object_new (KM_TYPE_SERVICE, NULL); + // g_object_add_weak_pointer (G_OBJECT (service), (gpointer *) &service); + // } + if (!service) + { + service = g_object_new (KM_TYPE_SERVICE, NULL); + g_object_add_weak_pointer (G_OBJECT (service), (gpointer *) &service); + } + return service; +} + +void +km_service_set_name (KeymanService *service, + const gchar *name) +{ + g_return_if_fail (KM_IS_SERVICE (service)); + + if (g_strcmp0(name,service->priv->name) != 0) + { + g_free(service->priv->name); + service->priv->name = g_strdup(name); + g_object_notify (G_OBJECT (service), "name"); + } +} + +// const gchar * +// km_service_get_name (KeymanService *service) +// { +// g_return_val_if_fail (KM_IS_SERVICE (service), -1); + +// return service->priv->name; +// } + +void +km_service_set_ldmlfile (KeymanService *service, + const gchar *xml) +{ + g_return_if_fail (KM_IS_SERVICE (service)); + + if (g_strcmp0(xml,service->priv->ldmlfile) != 0) + { + g_free(service->priv->ldmlfile); + service->priv->ldmlfile = g_strdup(xml); + g_object_notify (G_OBJECT (service), "ldmlfile"); + } +} + +// const gchar * +// km_service_get_ldmlfile (KeymanService *service) +// { +// g_return_val_if_fail (KM_IS_SERVICE (service), -1); + +// return service->priv->ldmlfile; +// } diff --git a/linux/ibus-kmfl/src/keyman-service.h b/linux/ibus-kmfl/src/keyman-service.h new file mode 100644 index 0000000000..0ce5237b77 --- /dev/null +++ b/linux/ibus-kmfl/src/keyman-service.h @@ -0,0 +1,69 @@ +/* vim:set et sts=4: */ + +/* + * KMFL Input Method for IBUS (The Input Bus) + * + * Copyright (C) 2018 SIL International + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 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 + * General Public License for more details. + * + * You should have received a copy of the GNU 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 based on work from Mousetweaks + Copyright © 2007-2010 Gerd Kohlberger +*/ + +#ifndef __KM_SERVICE_H__ +#define __KM_SERVICE_H__ + +#include + +G_BEGIN_DECLS + +#define KEYMAN_DBUS_NAME "com.Keyman" +#define KEYMAN_DBUS_IFACE "com.Keyman" +#define KEYMAN_DBUS_PATH "/com/Keyman/IBus" + +#define KM_TYPE_SERVICE (km_service_get_type ()) +#define KM_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), KM_TYPE_SERVICE, KeymanService)) +#define KM_IS_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), KM_TYPE_SERVICE)) + +typedef GObjectClass KeymanServiceClass; +typedef struct _KeymanService KeymanService; +typedef struct _KeymanServicePrivate KeymanServicePrivate; + +struct _KeymanService +{ + GObject parent; + KeymanServicePrivate *priv; +}; + +GType km_service_get_type (void) G_GNUC_CONST; + +KeymanService * km_service_get_default (void); + +// const gchar * km_service_get_ldmlfile (KeymanService *service); +void km_service_set_ldmlfile (KeymanService *service, + const gchar *xml); + +// const gchar * km_service_get_name (KeymanService *service); +void km_service_set_name (KeymanService *service, + const gchar *name); + + +G_END_DECLS + +#endif /* __KM_SERVICE_H__ */ diff --git a/linux/ibus-kmfl/src/main.c b/linux/ibus-kmfl/src/main.c index 106ebe1f05..273423b825 100644 --- a/linux/ibus-kmfl/src/main.c +++ b/linux/ibus-kmfl/src/main.c @@ -27,6 +27,7 @@ #include #include "kmflutil.h" #include "engine.h" +#include "keyman-service.h" static IBusBus *bus = NULL; static IBusFactory *factory = NULL; @@ -50,6 +51,9 @@ ibus_disconnected_cb (IBusBus *bus, gpointer user_data) { g_debug ("bus disconnected"); + KeymanService *service = km_service_get_default(); + g_clear_object(&service); + ibus_quit (); } @@ -88,6 +92,7 @@ start_component (void) } g_object_unref (component); + km_service_get_default(); // initialise dbus service ibus_main (); } From a818621e9847f163a3782170a71ad4569e90a6a3 Mon Sep 17 00:00:00 2001 From: glasseyes Date: Tue, 28 Aug 2018 16:01:05 +0700 Subject: [PATCH 2/9] WIP: get visualkeyboard and keyboardversion WIP: set ldmlfilename --- linux/ibus-kmfl/src/engine.c | 6 ++++-- linux/ibus-kmfl/src/kmflutil.c | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/linux/ibus-kmfl/src/engine.c b/linux/ibus-kmfl/src/engine.c index 59a24abb84..f7e01b73a2 100644 --- a/linux/ibus-kmfl/src/engine.c +++ b/linux/ibus-kmfl/src/engine.c @@ -407,16 +407,18 @@ ibus_kmfl_engine_enable (IBusEngine *engine) { const gchar *engine_name; IBusKMFLEngine *kmfl = (IBusKMFLEngine *) engine; + KInputMethod *im; engine_name = ibus_engine_get_name (engine); g_assert (engine_name); g_message("WDG: ibus_kmfl_engine_enable %s", engine_name); + im = (KInputMethod *) g_hash_table_lookup (im_table, engine_name); // own dbus name com.Keyman // expose properties LDMLFile and Name KeymanService *service = km_service_get_default(); //const gchar *ldmlfile = ""; - km_service_set_ldmlfile (service, engine_name); - km_service_set_name (service, engine_name); + km_service_set_ldmlfile (service, im->keyboard_ldmlfile); + km_service_set_name (service, im->keyboard_name); parent_class->enable (engine); } diff --git a/linux/ibus-kmfl/src/kmflutil.c b/linux/ibus-kmfl/src/kmflutil.c index 9af72adef6..ce2e33622e 100644 --- a/linux/ibus-kmfl/src/kmflutil.c +++ b/linux/ibus-kmfl/src/kmflutil.c @@ -171,6 +171,14 @@ void kmfl_get_keyboard_info(KInputMethod * im) kmfl_get_header(p_kmsi,SS_MESSAGE,buf,sizeof(buf) - 1); im->keyboard_description=g_strdup(buf); + *buf='\0'; + kmfl_get_header(p_kmsi,SS_VISUALKEYBOARD,buf,sizeof(buf) - 1); + im->keyboard_visualkeyboard=g_strdup(buf); + + *buf='\0'; + kmfl_get_header(p_kmsi,SS_KEYBOARDVERSION,buf,sizeof(buf) - 1); + im->keyboard_keyboardversion=g_strdup(buf); + if (g_strrstr(buf, "license") || g_strrstr(buf, "License") || g_strrstr(buf, "LICENSE")) im->keyboard_license=g_strdup(buf); else @@ -200,6 +208,8 @@ void kmfl_free_keyboard_info(KInputMethod * im) g_free(im->keyboard_icon_filename); g_free(im->keyboard_layout); g_free(im->keyboard_license); + g_free(im->keyboard_visualkeyboard); + g_free(im->keyboard_keyboardversion); } From 1b08bf0e6a0eacd94b25f3f2373fec34a33d7b5e Mon Sep 17 00:00:00 2001 From: glasseyes Date: Tue, 28 Aug 2018 17:19:56 +0700 Subject: [PATCH 3/9] more WIP: visualkeyboard, keyboardversion, ldmlfile --- linux/ibus-kmfl/src/kmflutil.c | 1 + linux/ibus-kmfl/src/kmflutil.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/linux/ibus-kmfl/src/kmflutil.c b/linux/ibus-kmfl/src/kmflutil.c index ce2e33622e..62b5d9ad50 100644 --- a/linux/ibus-kmfl/src/kmflutil.c +++ b/linux/ibus-kmfl/src/kmflutil.c @@ -210,6 +210,7 @@ void kmfl_free_keyboard_info(KInputMethod * im) g_free(im->keyboard_license); g_free(im->keyboard_visualkeyboard); g_free(im->keyboard_keyboardversion); + g_free(im->keyboard_ldmlfile); } diff --git a/linux/ibus-kmfl/src/kmflutil.h b/linux/ibus-kmfl/src/kmflutil.h index 3937aa8aa2..1358d48b8e 100644 --- a/linux/ibus-kmfl/src/kmflutil.h +++ b/linux/ibus-kmfl/src/kmflutil.h @@ -83,6 +83,9 @@ typedef struct gchar * keyboard_description; gchar * keyboard_layout; gchar * keyboard_license; + gchar * keyboard_visualkeyboard; + gchar * keyboard_keyboardversion; + gchar * keyboard_ldmlfile; } KInputMethod; From 954b19636d897177e2d695609414fed4fcbe8cc4 Mon Sep 17 00:00:00 2001 From: glasseyes Date: Wed, 29 Aug 2018 09:06:29 +0700 Subject: [PATCH 4/9] test sending visualkeyboard --- linux/ibus-kmfl/src/engine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/ibus-kmfl/src/engine.c b/linux/ibus-kmfl/src/engine.c index f7e01b73a2..6eaf6bda1d 100644 --- a/linux/ibus-kmfl/src/engine.c +++ b/linux/ibus-kmfl/src/engine.c @@ -417,7 +417,7 @@ ibus_kmfl_engine_enable (IBusEngine *engine) // expose properties LDMLFile and Name KeymanService *service = km_service_get_default(); //const gchar *ldmlfile = ""; - km_service_set_ldmlfile (service, im->keyboard_ldmlfile); + km_service_set_ldmlfile (service, im->keyboard_visualkeyboard); km_service_set_name (service, im->keyboard_name); parent_class->enable (engine); } From 9240a8098b4d2b7e34891946c4aa3dc1e4e607f9 Mon Sep 17 00:00:00 2001 From: glasseyes Date: Wed, 29 Aug 2018 09:05:33 +0700 Subject: [PATCH 5/9] unused variables and pointer cast warnings --- linux/libkmfl/src/kmfl_interpreter.c | 5 ++--- linux/libkmfl/src/kmfl_load_keyboard.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/linux/libkmfl/src/kmfl_interpreter.c b/linux/libkmfl/src/kmfl_interpreter.c index 57e8aa69f0..e1c6f8f416 100644 --- a/linux/libkmfl/src/kmfl_interpreter.c +++ b/linux/libkmfl/src/kmfl_interpreter.c @@ -80,7 +80,6 @@ int kmfl_interpret(KMSI *p_kmsi, UINT key, UINT state) XKEYBOARD *p_kbd; XGROUP *p_group1; ITEM keysym; - int matched; p_kmsi->noutput_queue=0; @@ -250,7 +249,7 @@ int match_rule(KMSI *p_kmsi, XRULE *rp, ITEM *any_index, int usekeys) { UINT k, m, n, nmax, rulelen, nhistory, index; - ITEM *pr, *ph, *ps, mask; + ITEM *pr, *ph, *ps; rulelen = rp->ilen; pr = p_kmsi->strings+rp->lhs; @@ -351,7 +350,7 @@ int process_rule(KMSI *p_kmsi, XRULE *rp, ITEM *any_index, int usekeys) XGROUP *gp; UINT i, k, m, n, nout, itp, index; ITEM *p, *pr, *ps, output[MAX_OUTPUT+1], history[MAX_HISTORY], *it; - int erase, result, retCode=1, nhistory; + int erase, retCode=1, nhistory; DBGMSG(1, "DAR - libkmfl - process_rule\n"); pr = p_kmsi->strings+rp->rhs; // Pointer to start of output rule diff --git a/linux/libkmfl/src/kmfl_load_keyboard.c b/linux/libkmfl/src/kmfl_load_keyboard.c index 5656c573f6..0d29526677 100644 --- a/linux/libkmfl/src/kmfl_load_keyboard.c +++ b/linux/libkmfl/src/kmfl_load_keyboard.c @@ -461,7 +461,7 @@ const char *kmfl_icon_file(int keyboard_number) if(stores[SS_BITMAP].len >= 0) { p32 = strings + stores[SS_BITMAP].items; - p8 = icon_name; + p8 = (UTF8 *)icon_name; IConvertUTF32toUTF8((const UTF32**)&p32,p32+stores[SS_BITMAP].len,&p8,p8+255); *p8 = 0; } From 9ad10ae496a1db12d5b9738e6ec8196d98146104 Mon Sep 17 00:00:00 2001 From: glasseyes Date: Wed, 29 Aug 2018 09:04:12 +0700 Subject: [PATCH 6/9] some linux .gitignore --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index a418450415..440467d21a 100644 --- a/.gitignore +++ b/.gitignore @@ -226,6 +226,16 @@ # /test/wm_unichar/ +# linux +autom4te.cache +*.orig +config.h +Makefile +build-kmflcomp +build-libkmfl +build-ibus-kmfl +__pycache__ + # VS Code .vscode From cf5535a71393b93ec59695ea926d3c0c3cc33b71 Mon Sep 17 00:00:00 2001 From: glasseyes Date: Wed, 29 Aug 2018 16:02:52 +0700 Subject: [PATCH 7/9] get ldml file name make visualkeyboard and keyboardversion available --- linux/ibus-kmfl/src/engine.c | 2 +- linux/ibus-kmfl/src/kmflutil.c | 45 +++++++++++++++++++++++----- linux/libkmfl/src/kmfl_interpreter.c | 2 +- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/linux/ibus-kmfl/src/engine.c b/linux/ibus-kmfl/src/engine.c index 6eaf6bda1d..f7e01b73a2 100644 --- a/linux/ibus-kmfl/src/engine.c +++ b/linux/ibus-kmfl/src/engine.c @@ -417,7 +417,7 @@ ibus_kmfl_engine_enable (IBusEngine *engine) // expose properties LDMLFile and Name KeymanService *service = km_service_get_default(); //const gchar *ldmlfile = ""; - km_service_set_ldmlfile (service, im->keyboard_visualkeyboard); + km_service_set_ldmlfile (service, im->keyboard_ldmlfile); km_service_set_name (service, im->keyboard_name); parent_class->enable (engine); } diff --git a/linux/ibus-kmfl/src/kmflutil.c b/linux/ibus-kmfl/src/kmflutil.c index 62b5d9ad50..ceeb478e39 100644 --- a/linux/ibus-kmfl/src/kmflutil.c +++ b/linux/ibus-kmfl/src/kmflutil.c @@ -146,11 +146,41 @@ gchar * kmfl_get_icon_file(KInputMethod * im) return full_path_to_icon_file; } +gchar * kmfl_get_ldml_file(KInputMethod * im) +{ + gchar * full_path_to_ldml_file=NULL, *p, *filename; + struct stat filestat; + + p=rindex(im->keyboard_visualkeyboard,'.'); + if(g_strcmp0(im->keyboard_visualkeyboard, "") == 0) + { + g_debug("WDG: no kvk(s) so no ldml file"); + return g_strdup(""); + } + if (p==NULL) + { + g_debug("WDG: couldn't find . in vk filename %s", im->keyboard_visualkeyboard); + return g_strdup(""); + } + filename = g_strndup(im->keyboard_visualkeyboard, p-(im->keyboard_visualkeyboard)); + full_path_to_ldml_file=g_strdup_printf("%s/%s.ldml", get_dirname(im->keyboard_filename), filename); + g_free(filename); + // don't forget to stat for the file before returning + stat(full_path_to_ldml_file, &filestat); + + if (!S_ISREG(filestat.st_mode)) { + g_debug("WDG: couldn't find ldml file %s", full_path_to_ldml_file); + g_free(full_path_to_ldml_file); + full_path_to_ldml_file=g_strdup(""); + } + return full_path_to_ldml_file; +} + void kmfl_get_keyboard_info(KInputMethod * im) { char buf[1024]; KMSI * p_kmsi; - + im->keyboard_name = g_strdup(kmfl_keyboard_name(im->keyboard_number)); p_kmsi = kmfl_make_keyboard_instance(NULL); kmfl_attach_keyboard(p_kmsi, im->keyboard_number); @@ -171,6 +201,11 @@ void kmfl_get_keyboard_info(KInputMethod * im) kmfl_get_header(p_kmsi,SS_MESSAGE,buf,sizeof(buf) - 1); im->keyboard_description=g_strdup(buf); + if (g_strrstr(buf, "license") || g_strrstr(buf, "License") || g_strrstr(buf, "LICENSE")) + im->keyboard_license=g_strdup(buf); + else + im->keyboard_license=g_strdup(""); + *buf='\0'; kmfl_get_header(p_kmsi,SS_VISUALKEYBOARD,buf,sizeof(buf) - 1); im->keyboard_visualkeyboard=g_strdup(buf); @@ -179,21 +214,17 @@ void kmfl_get_keyboard_info(KInputMethod * im) kmfl_get_header(p_kmsi,SS_KEYBOARDVERSION,buf,sizeof(buf) - 1); im->keyboard_keyboardversion=g_strdup(buf); - if (g_strrstr(buf, "license") || g_strrstr(buf, "License") || g_strrstr(buf, "LICENSE")) - im->keyboard_license=g_strdup(buf); - else - im->keyboard_license=g_strdup(""); - *buf='\0'; kmfl_get_header(p_kmsi,SS_LAYOUT,buf,sizeof(buf) - 1); if (*buf != '\0') im->keyboard_layout=g_strdup(buf); else im->keyboard_layout=g_strdup("us"); - + kmfl_detach_keyboard(p_kmsi); kmfl_delete_keyboard_instance(p_kmsi); im->keyboard_icon_filename = kmfl_get_icon_file(im); + im->keyboard_ldmlfile = kmfl_get_ldml_file(im); } void kmfl_free_keyboard_info(KInputMethod * im) diff --git a/linux/libkmfl/src/kmfl_interpreter.c b/linux/libkmfl/src/kmfl_interpreter.c index e1c6f8f416..a881f90bec 100644 --- a/linux/libkmfl/src/kmfl_interpreter.c +++ b/linux/libkmfl/src/kmfl_interpreter.c @@ -738,7 +738,7 @@ int kmfl_get_header(KMSI *p_kmsi,int hdrID,char *buf,int buflen) if(!p_kmsi) return -1; - if(hdrID < 0 || hdrID > SS_AUTHOR) return -2; + if(hdrID < 0 || hdrID > SS_KEYBOARDVERSION) return -2; p32 = (UTF32 *)store_content(p_kmsi,hdrID); p8 = (UTF8 *)buf; From 9dd777c15522f951d5edc0d9fc856ffe4dab1b58 Mon Sep 17 00:00:00 2001 From: glasseyes Date: Thu, 13 Sep 2018 15:05:50 +0700 Subject: [PATCH 8/9] remove duplicated from merged .gitignore --- .gitignore | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 440467d21a..5f65b71a6c 100644 --- a/.gitignore +++ b/.gitignore @@ -226,16 +226,6 @@ # /test/wm_unichar/ -# linux -autom4te.cache -*.orig -config.h -Makefile -build-kmflcomp -build-libkmfl -build-ibus-kmfl -__pycache__ - # VS Code .vscode @@ -247,6 +237,7 @@ configure aclocal.m4 config.guess config.sub +config.h config.h.in config.h.in~ config.rpath From ca6bc9c03282c93fb083b82f1b1f76109bc4315a Mon Sep 17 00:00:00 2001 From: glasseyes Date: Fri, 21 Sep 2018 09:23:57 +0700 Subject: [PATCH 9/9] [linux] ibus-kmfl: PR1198 improve checks looking for ldml file --- linux/ibus-kmfl/src/kmflutil.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/linux/ibus-kmfl/src/kmflutil.c b/linux/ibus-kmfl/src/kmflutil.c index ceeb478e39..983ce98662 100644 --- a/linux/ibus-kmfl/src/kmflutil.c +++ b/linux/ibus-kmfl/src/kmflutil.c @@ -151,17 +151,22 @@ gchar * kmfl_get_ldml_file(KInputMethod * im) gchar * full_path_to_ldml_file=NULL, *p, *filename; struct stat filestat; - p=rindex(im->keyboard_visualkeyboard,'.'); if(g_strcmp0(im->keyboard_visualkeyboard, "") == 0) { g_debug("WDG: no kvk(s) so no ldml file"); return g_strdup(""); } + p=rindex(im->keyboard_visualkeyboard,'.'); if (p==NULL) { g_debug("WDG: couldn't find . in vk filename %s", im->keyboard_visualkeyboard); return g_strdup(""); } + if (strncmp(p, ".kvk", 4) != 0) // sometimes kmn have kvks as the "visual keyboard" + { + g_debug("WDG: visual keyboard is not a kvk. Filename: %s", im->keyboard_visualkeyboard); + return g_strdup(""); + } filename = g_strndup(im->keyboard_visualkeyboard, p-(im->keyboard_visualkeyboard)); full_path_to_ldml_file=g_strdup_printf("%s/%s.ldml", get_dirname(im->keyboard_filename), filename); g_free(filename);