diff options
author | fujiwarat <takao.fujiwara1@gmail.com> | 2018-06-18 12:46:11 +0900 |
---|---|---|
committer | fujiwarat <takao.fujiwara1@gmail.com> | 2018-06-18 12:46:11 +0900 |
commit | 5ee3f48049ecf128391da6448ae7e74786bd171b (patch) | |
tree | aa24cd6a067812c0edc99d382d87c198e6fc7bc4 /src | |
parent | 37aa95f1adcdde82ef473936cadc0fa3fe8a4e44 (diff) | |
download | ibus-5ee3f48049ecf128391da6448ae7e74786bd171b.tar.gz |
Move input focus on Emojier to engines' preedit
Diffstat (limited to 'src')
-rw-r--r-- | src/ibusengine.c | 305 | ||||
-rw-r--r-- | src/ibuspanelservice.c | 318 | ||||
-rw-r--r-- | src/ibuspanelservice.h | 117 | ||||
-rw-r--r-- | src/ibusshare.h | 17 | ||||
-rw-r--r-- | src/ibusxevent.c | 375 | ||||
-rw-r--r-- | src/ibusxevent.h | 143 |
6 files changed, 1116 insertions, 159 deletions
diff --git a/src/ibusengine.c b/src/ibusengine.c index fd61102a..a3ccd7dd 100644 --- a/src/ibusengine.c +++ b/src/ibusengine.c @@ -64,8 +64,6 @@ enum { }; -typedef struct _IBusEngineKeybinding IBusEngineKeybinding; - /* IBusEnginePriv */ struct _IBusEnginePrivate { gchar *engine_name; @@ -81,14 +79,11 @@ struct _IBusEnginePrivate { guint content_purpose; guint content_hints; - GSettings *settings_emoji; - IBusEngineKeybinding **emoji_keybindings; + GHashTable *extension_keybindings; + gboolean enable_extension; + gchar *current_extension_name; }; -struct _IBusEngineKeybinding { - guint keyval; - IBusModifierType modifiers; -}; static guint engine_signals[LAST_SIGNAL] = { 0 }; @@ -191,10 +186,6 @@ static void ibus_engine_dbus_property_changed const gchar *property_name, GVariant *value); static void ibus_engine_keybinding_free (IBusEngine *engine); -static void settings_emoji_hotkey_changed_cb - (GSettings *settings, - const gchar *key, - gpointer data); G_DEFINE_TYPE (IBusEngine, ibus_engine, IBUS_TYPE_SERVICE) @@ -253,6 +244,12 @@ static const gchar introspection_xml[] = " <arg direction='in' type='u' name='cursor_pos' />" " <arg direction='in' type='u' name='anchor_pos' />" " </method>" + " <method name='PanelExtensionReceived'>" + " <arg direction='in' type='v' name='event' />" + " </method>" + " <method name='PanelExtensionRegisterKeys'>" + " <arg direction='in' type='v' name='data' />" + " </method>" /* FIXME signals */ " <signal name='CommitText'>" " <arg type='v' name='text' />" @@ -309,16 +306,22 @@ ibus_engine_class_init (IBusEngineClass *class) GObjectClass *gobject_class = G_OBJECT_CLASS (class); IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class); - gobject_class->set_property = (GObjectSetPropertyFunc) ibus_engine_set_property; - gobject_class->get_property = (GObjectGetPropertyFunc) ibus_engine_get_property; + gobject_class->set_property = + (GObjectSetPropertyFunc) ibus_engine_set_property; + gobject_class->get_property = + (GObjectGetPropertyFunc) ibus_engine_get_property; ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_engine_destroy; - IBUS_SERVICE_CLASS (class)->service_method_call = ibus_engine_service_method_call; - IBUS_SERVICE_CLASS (class)->service_get_property = ibus_engine_service_get_property; - IBUS_SERVICE_CLASS (class)->service_set_property = ibus_engine_service_set_property; + IBUS_SERVICE_CLASS (class)->service_method_call = + ibus_engine_service_method_call; + IBUS_SERVICE_CLASS (class)->service_get_property = + ibus_engine_service_get_property; + IBUS_SERVICE_CLASS (class)->service_set_property = + ibus_engine_service_set_property; - ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml); + ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), + introspection_xml); class->process_key_event = ibus_engine_process_key_event; class->focus_in = ibus_engine_focus_in; @@ -839,26 +842,25 @@ ibus_engine_init (IBusEngine *engine) { IBusEnginePrivate *priv; engine->priv = priv = IBUS_ENGINE_GET_PRIVATE (engine); - priv->surrounding_text = g_object_ref_sink (text_empty); - priv->settings_emoji = - g_settings_new ("org.freedesktop.ibus.panel.emoji"); - settings_emoji_hotkey_changed_cb (priv->settings_emoji, "hotkey", engine); - g_signal_connect (priv->settings_emoji, "changed::hotkey", - G_CALLBACK (settings_emoji_hotkey_changed_cb), engine); + priv->extension_keybindings = g_hash_table_new_full ( + g_str_hash, + g_str_equal, + g_free, + g_free); } static void ibus_engine_destroy (IBusEngine *engine) { - g_free (engine->priv->engine_name); - engine->priv->engine_name = NULL; + IBusEnginePrivate *priv = engine->priv; - if (engine->priv->surrounding_text) { - g_object_unref (engine->priv->surrounding_text); - engine->priv->surrounding_text = NULL; - } - ibus_engine_keybinding_free (engine); + g_clear_pointer (&priv->engine_name, g_free); + g_clear_pointer (&priv->current_extension_name, g_free); + if (priv->surrounding_text) + g_clear_object (&priv->surrounding_text); + if (priv->extension_keybindings) + g_clear_pointer (&priv->extension_keybindings, g_hash_table_destroy); IBUS_OBJECT_CLASS(ibus_engine_parent_class)->destroy (IBUS_OBJECT (engine)); } @@ -895,19 +897,38 @@ ibus_engine_get_property (IBusEngine *engine, } static void -ibus_engine_panel_extension (IBusEngine *engine) +ibus_engine_panel_extension (IBusEngine *engine, + const gchar *name) { - IBusXEvent *xevent = ibus_x_event_new ( - "event-type", IBUS_X_EVENT_KEY_PRESS, - "purpose", "emoji", + IBusEnginePrivate *priv; + IBusExtensionEvent *event; + GVariant *data; + + g_assert (IBUS_IS_ENGINE (engine)); + g_assert (name); + + priv = engine->priv; + if (!g_strcmp0 (name, priv->current_extension_name)) + priv->enable_extension = !priv->enable_extension; + else + priv->enable_extension = TRUE; + if (priv->enable_extension) { + g_free (priv->current_extension_name); + priv->current_extension_name = g_strdup (name); + } + event = ibus_extension_event_new ( + "name", name, + "is-enabled", priv->enable_extension, NULL); - GVariant *data = ibus_serializable_serialize_object ( - IBUS_SERIALIZABLE (xevent)); + g_assert (IBUS_IS_EXTENSION_EVENT (event)); + data = ibus_serializable_serialize_object ( + IBUS_SERIALIZABLE (event)); g_assert (data != NULL); ibus_engine_emit_signal (engine, "PanelExtension", g_variant_new ("(v)", data)); + g_object_unref (event); } static gboolean @@ -917,7 +938,8 @@ ibus_engine_filter_key_event (IBusEngine *engine, guint state) { IBusEnginePrivate *priv; - int i; + GList *names, *n; + IBusProcessKeyEventData *keys; guint modifiers; if ((state & IBUS_RELEASE_MASK) != 0) @@ -925,22 +947,29 @@ ibus_engine_filter_key_event (IBusEngine *engine, g_return_val_if_fail (IBUS_IS_ENGINE (engine), FALSE); priv = engine->priv; - if (!priv->emoji_keybindings) - return FALSE; - modifiers = state & IBUS_MODIFIER_FILTER; if (keyval >= IBUS_KEY_A && keyval <= IBUS_KEY_Z && (modifiers & IBUS_SHIFT_MASK) != 0) { keyval = keyval - IBUS_KEY_A + IBUS_KEY_a; } - for (i = 0; priv->emoji_keybindings[i]; i++) { - IBusEngineKeybinding *binding = priv->emoji_keybindings[i]; - if (binding->keyval == keyval && - binding->modifiers == modifiers) { - ibus_engine_panel_extension (engine); - return TRUE; + names = g_hash_table_get_keys (priv->extension_keybindings); + if (!names) + return FALSE; + for (n = names; n; n = n->next) { + const gchar *name = (const gchar *)n->data; + keys = g_hash_table_lookup (priv->extension_keybindings, name); + for (; keys; keys++) { + if (keys->keyval == 0 && keys->keycode == 0 && keys->state == 0) + break; + if (keys->keyval == keyval && + keys->state == modifiers && + (keys->keycode == 0 || keys->keycode == keycode)) { + ibus_engine_panel_extension (engine, name); + return TRUE; + } } } + g_list_free (names); return FALSE; } @@ -954,6 +983,97 @@ ibus_engine_service_authorized_method (IBusService *service, } static void +ibus_engine_service_panel_extension_register_keys (IBusEngine *engine, + GVariant *parameters, + GDBusMethodInvocation + *invocation) +{ + IBusEnginePrivate *priv = engine->priv; + GVariant *v1 = NULL; + GVariant *v2 = NULL; + GVariant *v3 = NULL; + GVariant *vkeys = NULL; + GVariantIter *iter1 = NULL; + GVariantIter *iter2 = NULL; + const gchar *name = NULL; + guint failure_id = 0; + + g_variant_get (parameters, "(v)", &v1); + if (v1) + g_variant_get (v1, "(v)", &v2); + else + failure_id = 1; + if (v2) + g_variant_get (v2, "a{sv}", &iter1); + else + failure_id = 2; + if (iter1) { + while (g_variant_iter_loop (iter1, "{&sv}", &name, &vkeys)) { + if (vkeys) + g_variant_get (vkeys, "av", &iter2); + if (name && iter2) { + IBusProcessKeyEventData *keys = NULL; + gint num = 0; + while (g_variant_iter_loop (iter2, "v", &v3)) { + if (v3) { + guint keyval = 0; + guint keycode = 0; + guint state = 0; + g_variant_get (v3, "(iii)", + &keyval, &keycode, &state); + if (!keys) + keys = g_new0 (IBusProcessKeyEventData, 2); + else + keys = g_renew (IBusProcessKeyEventData, + keys, + num + 2); + keys[num].keyval = keyval; + keys[num].keycode = keycode; + keys[num].state = state; + keys[num + 1].keyval = 0; + keys[num + 1].keycode = 0; + keys[num + 1].state = 0; + g_clear_pointer (&v3, g_variant_unref); + num++; + } else { + failure_id = 5; + } + } + if (num > 0) { + g_hash_table_replace (priv->extension_keybindings, + g_strdup (name), + keys); + } else { + g_hash_table_remove (priv->extension_keybindings, name); + } + g_clear_pointer (&iter2, g_variant_iter_free); + } else { + failure_id = 4; + } + g_clear_pointer (&vkeys, g_variant_unref); + name = NULL; + } + g_variant_iter_free (iter1); + } else { + failure_id = 3; + } + if (failure_id == 0) { + g_dbus_method_invocation_return_value (invocation, NULL); + } else { + g_dbus_method_invocation_return_error ( + invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "PanelExtensionRegisterKeys method gives NULL: %d", + failure_id); + } + if (v2) + g_variant_unref (v2); + if (v1) + g_variant_unref (v1); +} + +static void ibus_engine_service_method_call (IBusService *service, GDBusConnection *connection, const gchar *sender, @@ -964,6 +1084,7 @@ ibus_engine_service_method_call (IBusService *service, GDBusMethodInvocation *invocation) { IBusEngine *engine = IBUS_ENGINE (service); + IBusEnginePrivate *priv = engine->priv; if (g_strcmp0 (interface_name, IBUS_INTERFACE_ENGINE) != 0) { IBUS_SERVICE_CLASS (ibus_engine_parent_class)-> @@ -1002,6 +1123,33 @@ ibus_engine_service_method_call (IBusService *service, g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", retval)); return; } + if (g_strcmp0 (method_name, "PanelExtensionReceived") == 0) { + GVariant *arg0 = NULL; + IBusExtensionEvent *event = NULL; + + g_variant_get (parameters, "(v)", &arg0); + if (arg0) { + event = (IBusExtensionEvent *)ibus_serializable_deserialize_object ( + arg0); + } + if (!event) { + g_dbus_method_invocation_return_error ( + invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "PanelExtensionReceived method gives NULL"); + return; + } + priv->enable_extension = ibus_extension_event_is_enabled (event); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + if (g_strcmp0 (method_name, "PanelExtensionRegisterKeys") == 0) { + ibus_engine_service_panel_extension_register_keys (engine, + parameters, + invocation); + return; + } static const struct { gchar *member; @@ -1441,73 +1589,10 @@ static void ibus_engine_keybinding_free (IBusEngine *engine) { IBusEnginePrivate *priv; - int i; g_return_if_fail (IBUS_IS_ENGINE (engine)); priv = engine->priv; - if (priv->emoji_keybindings) { - for (i = 0; priv->emoji_keybindings[i]; i++) - g_slice_free (IBusEngineKeybinding, priv->emoji_keybindings[i]); - g_clear_pointer (&priv->emoji_keybindings, g_free); - } -} - -static IBusEngineKeybinding * -ibus_engine_keybinding_new (IBusEngine *engine, - const gchar *accelerator) -{ - guint keyval = 0U; - IBusModifierType modifiers = 0; - IBusEngineKeybinding *binding = NULL; - - ibus_accelerator_parse (accelerator, &keyval, &modifiers); - if (keyval == 0U && modifiers == 0) { - g_warning ("Failed to parse shortcut key '%s'", accelerator); - return NULL; - } - if (modifiers & IBUS_SUPER_MASK) { - modifiers^=IBUS_SUPER_MASK; - modifiers|=IBUS_MOD4_MASK; - } - - binding = g_slice_new0 (IBusEngineKeybinding); - binding->keyval = keyval; - binding->modifiers = modifiers; - return binding; -} - -static void -settings_emoji_hotkey_changed_cb (GSettings *settings, - const gchar *key, - gpointer data) -{ - IBusEngine *engine; - IBusEnginePrivate *priv; - gchar **accelerators; - int i, j, length; - g_return_if_fail (IBUS_IS_ENGINE (data)); - engine = IBUS_ENGINE (data); - priv = engine->priv; - - if (g_strcmp0 (key, "hotkey") != 0) - return; - accelerators = g_settings_get_strv (settings, key); - length = g_strv_length (accelerators); - ibus_engine_keybinding_free (engine); - if (length == 0) { - g_strfreev (accelerators); - return; - } - priv->emoji_keybindings = g_new0 (IBusEngineKeybinding*, length + 1); - for (i = 0, j = 0; i < length; i++) { - IBusEngineKeybinding *binding = - ibus_engine_keybinding_new (engine, accelerators[i]); - if (!binding) - continue; - priv->emoji_keybindings[j++] = binding; - } - g_strfreev (accelerators); } IBusEngine * diff --git a/src/ibuspanelservice.c b/src/ibuspanelservice.c index f37b91c3..71028ebf 100644 --- a/src/ibuspanelservice.c +++ b/src/ibuspanelservice.c @@ -57,6 +57,9 @@ enum { DESTROY_CONTEXT, SET_CONTENT_TYPE, PANEL_EXTENSION_RECEIVED, + PROCESS_KEY_EVENT, + COMMIT_TEXT_RECEIVED, + CANDIDATE_CLICKED_LOOKUP_TABLE, LAST_SIGNAL, }; @@ -153,7 +156,7 @@ static void ibus_panel_service_set_content_type guint hints); static void ibus_panel_service_panel_extension_received (IBusPanelService *panel, - GVariant *data); + IBusExtensionEvent *event); G_DEFINE_TYPE (IBusPanelService, ibus_panel_service, IBUS_TYPE_SERVICE) @@ -184,6 +187,11 @@ static const gchar introspection_xml[] = " <method name='CursorDownLookupTable' />" " <method name='PageUpLookupTable' />" " <method name='PageDownLookupTable' />" + " <method name='CandidateClickedLookupTable'>" + " <arg direction='in' type='u' name='index' />" + " <arg direction='in' type='u' name='button' />" + " <arg direction='in' type='u' name='state' />" + " </method>" " <method name='RegisterProperties'>" " <arg direction='in' type='v' name='props' />" " </method>" @@ -221,7 +229,16 @@ static const gchar introspection_xml[] = " <arg direction='in' type='u' name='hints' />" " </method>" " <method name='PanelExtensionReceived'>" - " <arg direction='in' type='v' name='data' />" + " <arg direction='in' type='v' name='event' />" + " </method>" + " <method name='ProcessKeyEvent'>" + " <arg direction='in' type='u' name='keyval' />" + " <arg direction='in' type='u' name='keycode' />" + " <arg direction='in' type='u' name='state' />" + " <arg direction='out' type='b' />" + " </method>" + " <method name='CommitTextReceived'>" + " <arg direction='in' type='v' name='text' />" " </method>" /* Signals */ " <signal name='CursorUp' />" @@ -247,7 +264,23 @@ static const gchar introspection_xml[] = " <arg type='v' name='text' />" " </signal>" " <signal name='PanelExtension'>" + " <arg type='v' name='event' />" + " </signal>" + " <method name='PanelExtensionRegisterKeys'>" " <arg type='v' name='data' />" + " </method>" + " <signal name='UpdatePreeditTextReceived'>" + " <arg type='v' name='text' />" + " <arg type='u' name='cursor_pos' />" + " <arg type='b' name='visible' />" + " </signal>" + " <signal name='UpdateAuxiliaryTextReceived'>" + " <arg type='v' name='text' />" + " <arg type='b' name='visible' />" + " </signal>" + " <signal name='UpdateLookupTableReceived'>" + " <arg type='v' name='table' />" + " <arg type='b' name='visible' />" " </signal>" " </interface>" "</node>"; @@ -927,10 +960,81 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusPanelServiceClass, panel_extension_received), NULL, NULL, - _ibus_marshal_VOID__VARIANT, + _ibus_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + IBUS_TYPE_EXTENSION_EVENT); + + /** + * IBusPanelService::process-key-event: + * @panel: An #IBusPanelService + * @keyval: Key symbol of the key press. + * @keycode: KeyCode of the key press. + * @state: Key modifier flags. + * + * Emitted when a key event is received. + * Implement the member function IBusPanelServiceClass::process_key_event + * in extended class to receive this signal. + * Both the key symbol and keycode are passed to the member function. + * See ibus_input_context_process_key_event() for further explanation of + * key symbol, keycode and which to use. + * + * Returns: %TRUE for successfully process the key; %FALSE otherwise. + * See also: ibus_input_context_process_key_event(). + * + * <note><para>Argument @user_data is ignored in this function.</para> + * </note> + */ + panel_signals[PROCESS_KEY_EVENT] = + g_signal_new (I_("process-key-event"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IBusPanelServiceClass, process_key_event), + g_signal_accumulator_true_handled, NULL, + _ibus_marshal_BOOL__UINT_UINT_UINT, + G_TYPE_BOOLEAN, + 3, + G_TYPE_UINT, + G_TYPE_UINT, + G_TYPE_UINT); + + /** + * IBusPanelService::commit-text-received: + * @panel: An #IBusPanelService + * @text: A #IBusText + * + * Emitted when the client application get the ::commit-text-received. + * Implement the member function + * IBusPanelServiceClass::commit_text_received in extended class to + * receive this signal. + * + * <note><para>Argument @user_data is ignored in this function.</para> + * </note> + */ + panel_signals[COMMIT_TEXT_RECEIVED] = + g_signal_new (I_("commit-text-received"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IBusPanelServiceClass, commit_text_received), + NULL, NULL, + _ibus_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - G_TYPE_VARIANT); + IBUS_TYPE_TEXT); + + panel_signals[CANDIDATE_CLICKED_LOOKUP_TABLE] = + g_signal_new (I_("candidate-clicked-lookup-table"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IBusPanelServiceClass, + candidate_clicked_lookup_table), + NULL, NULL, + _ibus_marshal_VOID__UINT_UINT_UINT, + G_TYPE_NONE, + 3, + G_TYPE_UINT, + G_TYPE_UINT, + G_TYPE_UINT); } static void @@ -1129,9 +1233,14 @@ ibus_panel_service_service_method_call (IBusService *service, } if (g_strcmp0 (method_name, "PanelExtensionReceived") == 0) { - GVariant *variant = NULL; - g_variant_get (parameters, "(v)", &variant); - if (variant == NULL) { + GVariant *arg0 = NULL; + IBusExtensionEvent *event = NULL; + g_variant_get (parameters, "(v)", &arg0); + if (arg0) { + event = IBUS_EXTENSION_EVENT (ibus_serializable_deserialize (arg0)); + g_variant_unref (arg0); + } + if (!event) { g_dbus_method_invocation_return_error ( invocation, G_DBUS_ERROR, @@ -1140,11 +1249,63 @@ ibus_panel_service_service_method_call (IBusService *service, return; } g_signal_emit (panel, panel_signals[PANEL_EXTENSION_RECEIVED], 0, - variant); - g_variant_unref (variant); + event); + _g_object_unref_if_floating (event); g_dbus_method_invocation_return_value (invocation, NULL); return; } + if (g_strcmp0 (method_name, "ProcessKeyEvent") == 0) { + guint keyval, keycode, state; + gboolean retval = FALSE; + + g_variant_get (parameters, "(uuu)", &keyval, &keycode, &state); + g_signal_emit (panel, + panel_signals[PROCESS_KEY_EVENT], + 0, + keyval, + keycode, + state, + &retval); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(b)", retval)); + return; + } + if (g_strcmp0 (method_name, "CommitTextReceived") == 0) { + GVariant *arg0 = NULL; + IBusText *text = NULL; + + g_variant_get (parameters, "(v)", &arg0); + if (arg0) { + text = (IBusText *) ibus_serializable_deserialize (arg0); + g_variant_unref (arg0); + } + if (!text) { + g_dbus_method_invocation_return_error ( + invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "CommitTextReceived method gives NULL"); + return; + } + g_signal_emit (panel, + panel_signals[COMMIT_TEXT_RECEIVED], + 0, + text); + _g_object_unref_if_floating (text); + return; + } + if (g_strcmp0 (method_name, "CandidateClickedLookupTable") == 0) { + guint index = 0; + guint button = 0; + guint state = 0; + g_variant_get (parameters, "(uuu)", &index, &button, &state); + g_signal_emit (panel, + panel_signals[CANDIDATE_CLICKED_LOOKUP_TABLE], + 0, + index, button, state); + return; + } + const static struct { const gchar *name; @@ -1318,8 +1479,8 @@ ibus_panel_service_set_content_type (IBusPanelService *panel, } static void -ibus_panel_service_panel_extension_received (IBusPanelService *panel, - GVariant *data) +ibus_panel_service_panel_extension_received (IBusPanelService *panel, + IBusExtensionEvent *event) { ibus_panel_service_not_implemented(panel); } @@ -1396,10 +1557,11 @@ void ibus_panel_service_commit_text (IBusPanelService *panel, IBusText *text) { + GVariant *variant; g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel)); g_return_if_fail (IBUS_IS_TEXT (text)); - GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text); + variant = ibus_serializable_serialize ((IBusSerializable *)text); ibus_service_emit_signal ((IBusService *) panel, NULL, IBUS_INTERFACE_PANEL, @@ -1413,18 +1575,144 @@ ibus_panel_service_commit_text (IBusPanelService *panel, } void -ibus_panel_service_panel_extension (IBusPanelService *panel, - GVariant *variant) +ibus_panel_service_panel_extension (IBusPanelService *panel, + IBusExtensionEvent *event) { + GVariant *variant; g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel)); - g_return_if_fail (variant); + g_return_if_fail (IBUS_IS_EXTENSION_EVENT (event)); + variant = ibus_serializable_serialize ((IBusSerializable *)event); ibus_service_emit_signal ((IBusService *) panel, NULL, IBUS_INTERFACE_PANEL, "PanelExtension", g_variant_new ("(v)", variant), NULL); + + if (g_object_is_floating (event)) { + g_object_unref (event); + } +} + +void +ibus_panel_service_panel_extension_register_keys (IBusPanelService *panel, + const gchar + *first_property_name, + ...) +{ + GVariantBuilder builder; + GVariantBuilder child; + const gchar *name; + va_list var_args; + IBusProcessKeyEventData *keys; + + g_return_if_fail (first_property_name); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + name = first_property_name; + + va_start (var_args, first_property_name); + do { + keys = va_arg (var_args, IBusProcessKeyEventData *); + g_return_if_fail (keys != NULL); + g_variant_builder_init (&child, G_VARIANT_TYPE ("av")); + for (; keys; keys++) { + if (keys->keyval == 0 && keys->keycode == 0 && keys->state == 0) + break; + g_variant_builder_add (&child, "v", + g_variant_new ("(iii)", + keys->keyval, + keys->keycode, + keys->state)); + } + g_variant_builder_add (&builder, "{sv}", + g_strdup (name), g_variant_builder_end (&child)); + } while ((name = va_arg (var_args, const gchar *))); + va_end (var_args); + + ibus_service_emit_signal ((IBusService *) panel, + NULL, + IBUS_INTERFACE_PANEL, + "PanelExtensionRegisterKeys", + g_variant_new ("(v)", + g_variant_builder_end (&builder)), + NULL); +} + +void +ibus_panel_service_update_preedit_text_received (IBusPanelService *panel, + IBusText *text, + guint cursor_pos, + gboolean visible) +{ + GVariant *variant; + + g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel)); + g_return_if_fail (IBUS_IS_TEXT (text)); + + variant = ibus_serializable_serialize ((IBusSerializable *)text); + g_return_if_fail (variant); + ibus_service_emit_signal ((IBusService *) panel, + NULL, + IBUS_INTERFACE_PANEL, + "UpdatePreeditTextReceived", + g_variant_new ("(vub)", + variant, cursor_pos, visible), + NULL); + + if (g_object_is_floating (text)) { + g_object_unref (text); + } +} + +void +ibus_panel_service_update_auxiliary_text_received (IBusPanelService *panel, + IBusText *text, + gboolean visible) +{ + GVariant *variant; + g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel)); + g_return_if_fail (IBUS_IS_TEXT (text)); + + variant = ibus_serializable_serialize ((IBusSerializable *)text); + g_return_if_fail (variant); + ibus_service_emit_signal ((IBusService *) panel, + NULL, + IBUS_INTERFACE_PANEL, + "UpdateAuxiliaryTextReceived", + g_variant_new ("(vb)", + variant, visible), + NULL); + + if (g_object_is_floating (text)) { + g_object_unref (text); + } +} + +void +ibus_panel_service_update_lookup_table_received (IBusPanelService *panel, + IBusLookupTable *table, + gboolean visible) +{ + GVariant *variant; + + g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel)); + g_return_if_fail (IBUS_IS_LOOKUP_TABLE (table)); + + variant = ibus_serializable_serialize ((IBusSerializable *)table); + g_return_if_fail (variant); + ibus_service_emit_signal ((IBusService *) panel, + NULL, + IBUS_INTERFACE_PANEL, + "UpdateLookupTableReceived", + g_variant_new ("(vb)", + variant, visible), + NULL); + + if (g_object_is_floating (table)) { + g_object_unref (table); + } } #define DEFINE_FUNC(name, Name) \ diff --git a/src/ibuspanelservice.h b/src/ibuspanelservice.h index 60ef842b..d91f2309 100644 --- a/src/ibuspanelservice.h +++ b/src/ibuspanelservice.h @@ -38,6 +38,7 @@ #include "ibuslookuptable.h" #include "ibusservice.h" #include "ibusproplist.h" +#include "ibusxevent.h" /* * Type macros. @@ -130,11 +131,24 @@ struct _IBusPanelServiceClass { gint h); void (* panel_extension_received) (IBusPanelService *panel, - GVariant *data); + IBusExtensionEvent *event); + gboolean (* process_key_event) + (IBusPanelService *panel, + guint keyval, + guint keycode, + guint state); + void (* commit_text_received) + (IBusPanelService *panel, + IBusText *text); + void (* candidate_clicked_lookup_table) + (IBusPanelService *panel, + guint index, + guint button, + guint state); /*< private >*/ /* padding */ - gpointer pdummy[5]; // We can add 8 pointers without breaking the ABI. + gpointer pdummy[2]; // We can add 8 pointers without breaking the ABI. }; GType ibus_panel_service_get_type (void); @@ -248,12 +262,105 @@ void ibus_panel_service_commit_text (IBusPanelService *panel, /** * ibus_panel_service_panel_extension: * @panel: An #IBusPanelService - * @data: (transfer full): A #GVariant data which is sent to a panel extension. + * @event: (transfer full): A #PanelExtensionEvent which is sent to a + * panel extension. * + * Enable or disable a panel extension with #IBusExtensionEvent. * 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); +void ibus_panel_service_panel_extension (IBusPanelService *panel, + IBusExtensionEvent *event); + +/** + * ibus_panel_service_panel_extension_register_keys: + * @panel: An #IBusPanelService + * @first_property_name: the first name of the shortcut keys. This is %NULL + " terminated. + * + * Register shortcut keys to enable panel extensions with #IBusExtensionEvent. + * Notify that a data is sent + * by sending a "PanelExtensionRegisterKeys" message to IBus panel extension + * service. Seems Vala does not support uint[][3] and use + * IBusProcessKeyEventData[]. E.g. + * IBusProcessKeyEventData[] keys = {{ + * IBUS_KEY_e, 0, IBUS_SHIFT_MASK | IBUS_SUPER_MASK }}; + * ibus_panel_service_panel_extension_register_keys(panel, "emoji", keys, NULL); + */ +void ibus_panel_service_panel_extension_register_keys + (IBusPanelService *panel, + const gchar *first_property_name, + ...); + +/** + * ibus_panel_service_update_preedit_text_received: + * @panel: An #IBusPanelService + * @text: Update content. + * @cursor_pos: Current position of cursor + * @visible: Whether the pre-edit buffer is visible. + * + * Notify that the preedit is updated by the panel extension + * + * (Note: The table object will be released, if it is floating. + * If caller want to keep the object, caller should make the object + * sink by g_object_ref_sink.) + */ +void ibus_panel_service_update_preedit_text_received + (IBusPanelService *panel, + IBusText *text, + guint cursor_pos, + gboolean visible); + +/** + * ibus_panel_service_show_preedit_text_received: + * @panel: An IBusPanelService + * + * Notify that the preedit is shown by the panel extension + */ +void ibus_panel_service_show_preedit_text_received + (IBusPanelService *panel); + +/** + * ibus_panel_service_hide_preedit_text_received: + * @panel: An IBusPanelService + * + * Notify that the preedit is hidden by the panel extension + */ +void ibus_panel_service_hide_preedit_text_received + (IBusPanelService *panel); + +/** + * ibus_panel_service_update_auxiliary_text_received: + * @panel: An #IBusPanelService + * @text: An #IBusText + * @visible: Whether the auxilirary text is visible. + * + * Notify that the auxilirary is updated by the panel extension. + * + * (Note: The table object will be released, if it is floating. + * If caller want to keep the object, caller should make the object + * sink by g_object_ref_sink.) + */ +void ibus_panel_service_update_auxiliary_text_received + (IBusPanelService *panel, + IBusText *text, + gboolean visible); + +/** + * ibus_panel_service_update_lookup_table_received: + * @panel: An #IBusPanelService + * @table: An #IBusLookupTable + * @visible: Whether the lookup table is visible. + * + * Notify that the lookup table is updated by the panel extension. + * + * (Note: The table object will be released, if it is floating. + * If caller want to keep the object, caller should make the object + * sink by g_object_ref_sink.) + */ +void ibus_panel_service_update_lookup_table_received + (IBusPanelService *panel, + IBusLookupTable *table, + gboolean visible); G_END_DECLS #endif diff --git a/src/ibusshare.h b/src/ibusshare.h index 757d915b..4f5a306b 100644 --- a/src/ibusshare.h +++ b/src/ibusshare.h @@ -74,6 +74,15 @@ #define IBUS_SERVICE_PANEL_EXTENSION "org.freedesktop.IBus.Panel.Extension" /** + * IBUS_SERVICE_PANEL_EXTENSION_EMOJI: + * + * Address of IBus panel extension service for emoji. + * This service provides emoji, Unicode code point, Unicode name features. + */ +#define IBUS_SERVICE_PANEL_EXTENSION_EMOJI \ + "org.freedesktop.IBus.Panel.Extension.Emoji" + +/** * IBUS_SERVICE_CONFIG: * * Address of IBus config service. @@ -109,11 +118,13 @@ #define IBUS_PATH_PANEL "/org/freedesktop/IBus/Panel" /** - * IBUS_PATH_PANEL_EXTENSION: + * IBUS_PATH_PANEL_EXTENSION_EMOJI: * - * D-Bus path for IBus panel. + * D-Bus path for IBus extension panel for emoji. + * This service provides emoji, Unicode code point, Unicode name features. */ -#define IBUS_PATH_PANEL_EXTENSION "/org/freedesktop/IBus/Panel/Extension" +#define IBUS_PATH_PANEL_EXTENSION_EMOJI \ + "/org/freedesktop/IBus/Panel/Extension/Emoji" /** * IBUS_PATH_CONFIG: diff --git a/src/ibusxevent.c b/src/ibusxevent.c index dea80272..287bb99b 100644 --- a/src/ibusxevent.c +++ b/src/ibusxevent.c @@ -22,13 +22,23 @@ #include "ibusinternal.h" #include "ibusxevent.h" +#define IBUS_EXTENSION_EVENT_VERSION 1 +#define IBUS_EXTENSION_EVENT_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + IBUS_TYPE_EXTENSION_EVENT, \ + IBusExtensionEventPrivate)) + #define IBUS_X_EVENT_VERSION 1 -#define IBUS_X_EVENT_GET_PRIVATE(o) \ +#define IBUS_X_EVENT_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_X_EVENT, IBusXEventPrivate)) enum { PROP_0, PROP_VERSION, + PROP_NAME, + PROP_IS_ENABLED, + PROP_IS_EXTENSION, + PROP_PARAMS, PROP_EVENT_TYPE, PROP_WINDOW, PROP_SEND_EVENT, @@ -52,6 +62,14 @@ enum { }; +struct _IBusExtensionEventPrivate { + guint version; + gchar *name; + gboolean is_enabled; + gboolean is_extension; + gchar *params; +}; + struct _IBusXEventPrivate { guint version; guint32 time; @@ -73,25 +91,347 @@ struct _IBusXEventPrivate { }; /* 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); - +static void ibus_extension_event_destroy (IBusExtensionEvent *event); +static void ibus_extension_event_set_property (IBusExtensionEvent *event, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void ibus_extension_event_get_property (IBusExtensionEvent *event, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static gboolean ibus_extension_event_serialize (IBusExtensionEvent *event, + GVariantBuilder + *builder); +static gint ibus_extension_event_deserialize (IBusExtensionEvent *event, + GVariant + *variant); +static gboolean ibus_extension_event_copy (IBusExtensionEvent + *dest, + const IBusExtensionEvent + *src); +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 (IBusExtensionEvent, ibus_extension_event, IBUS_TYPE_SERIALIZABLE) G_DEFINE_TYPE (IBusXEvent, ibus_x_event, IBUS_TYPE_SERIALIZABLE) static void +ibus_extension_event_class_init (IBusExtensionEventClass *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_extension_event_set_property; + gobject_class->get_property = + (GObjectGetPropertyFunc) ibus_extension_event_get_property; + + object_class->destroy = + (IBusObjectDestroyFunc) ibus_extension_event_destroy; + + serializable_class->serialize = + (IBusSerializableSerializeFunc) ibus_extension_event_serialize; + serializable_class->deserialize = + (IBusSerializableDeserializeFunc) ibus_extension_event_deserialize; + serializable_class->copy = + (IBusSerializableCopyFunc) ibus_extension_event_copy; + + /* install properties */ + /** + * IBusExtensionEvent:version: + * + * Version of the #IBusExtensionEvent. + */ + g_object_class_install_property (gobject_class, + PROP_VERSION, + g_param_spec_uint ("version", + "version", + "version", + 0, + G_MAXUINT32, + IBUS_EXTENSION_EVENT_VERSION, + G_PARAM_READABLE)); + + /** + * IBusExtensionEvent:name: + * + * Name of the extension in the #IBusExtensionEvent. + */ + g_object_class_install_property (gobject_class, + PROP_NAME, + g_param_spec_string ("name", + "name", + "name of the extension", + "", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + /** + * IBusExtensionEvent:is-enabled: + * + * %TRUE if the extension is enabled in the #IBusExtensionEvent. + */ + g_object_class_install_property (gobject_class, + PROP_IS_ENABLED, + g_param_spec_boolean ("is-enabled", + "is enabled", + "if the extension is enabled", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + /** + * IBusExtensionEvent:is-extension: + * + * %TRUE if the #IBusExtensionEvent is called by an extension. + * %FALSE if the #IBusExtensionEvent is called by an active engine or + * panel. + * If this value is %TRUE, the event is send to ibus-daemon, an active + * engine. If it's %FALSE, the event is sned to ibus-daemon, panels. + */ + g_object_class_install_property (gobject_class, + PROP_IS_EXTENSION, + g_param_spec_boolean ("is-extension", + "is extension", + "if the event is called by an extension", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + /** + * IBusExtensionEvent:params: + * + * Parameters to enable the extension in the #IBusExtensionEvent. + */ + g_object_class_install_property (gobject_class, + PROP_PARAMS, + g_param_spec_string ("params", + "params", + "Parameters to enable the extension", + "", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (class, sizeof (IBusExtensionEventPrivate)); +} + +static void +ibus_extension_event_init (IBusExtensionEvent *event) +{ + event->priv = IBUS_EXTENSION_EVENT_GET_PRIVATE (event); + event->priv->version = IBUS_EXTENSION_EVENT_VERSION; +} + +static void +ibus_extension_event_destroy (IBusExtensionEvent *event) +{ + g_clear_pointer (&event->priv->name, g_free); + + IBUS_OBJECT_CLASS(ibus_extension_event_parent_class)-> + destroy (IBUS_OBJECT (event)); +} + +static void +ibus_extension_event_set_property (IBusExtensionEvent *event, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + IBusExtensionEventPrivate *priv = event->priv; + + switch (prop_id) { + case PROP_NAME: + g_free (priv->name); + priv->name = g_value_dup_string (value); + break; + case PROP_IS_ENABLED: + priv->is_enabled = g_value_get_boolean (value); + break; + case PROP_IS_EXTENSION: + priv->is_extension = g_value_get_boolean (value); + break; + case PROP_PARAMS: + priv->params = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (event, prop_id, pspec); + } +} + +static void +ibus_extension_event_get_property (IBusExtensionEvent *event, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + IBusExtensionEventPrivate *priv = event->priv; + switch (prop_id) { + case PROP_VERSION: + g_value_set_uint (value, priv->version); + break; + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + case PROP_IS_ENABLED: + g_value_set_boolean (value, priv->is_enabled); + break; + case PROP_IS_EXTENSION: + g_value_set_boolean (value, priv->is_extension); + break; + case PROP_PARAMS: + g_value_set_string (value, priv->params); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (event, prop_id, pspec); + } +} + +static gboolean +ibus_extension_event_serialize (IBusExtensionEvent *event, + GVariantBuilder *builder) +{ + gboolean retval; + IBusExtensionEventPrivate *priv; + + retval = IBUS_SERIALIZABLE_CLASS (ibus_extension_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, "s", NOTNULL (priv->name)); + g_variant_builder_add (builder, "b", priv->is_enabled); + g_variant_builder_add (builder, "b", priv->is_extension); + g_variant_builder_add (builder, "s", NOTNULL (priv->params)); +#undef NOTNULL + + return TRUE; +} + +static gint +ibus_extension_event_deserialize (IBusExtensionEvent *event, + GVariant *variant) +{ + gint retval; + IBusExtensionEventPrivate *priv; + + retval = IBUS_SERIALIZABLE_CLASS (ibus_extension_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); + ibus_g_variant_get_child_string (variant, retval++, + &priv->name); + g_variant_get_child (variant, retval++, "b", &priv->is_enabled); + g_variant_get_child (variant, retval++, "b", &priv->is_extension); + ibus_g_variant_get_child_string (variant, retval++, + &priv->params); + + return retval; +} + +static gboolean +ibus_extension_event_copy (IBusExtensionEvent *dest, + const IBusExtensionEvent *src) +{ + gboolean retval; + IBusExtensionEventPrivate *dest_priv = dest->priv; + IBusExtensionEventPrivate *src_priv = src->priv; + + retval = IBUS_SERIALIZABLE_CLASS (ibus_extension_event_parent_class)-> + copy ((IBusSerializable *)dest, (IBusSerializable *)src); + g_return_val_if_fail (retval, FALSE); + + dest_priv->version = src_priv->version; + dest_priv->name = g_strdup (src_priv->name); + dest_priv->is_enabled = src_priv->is_enabled; + dest_priv->is_extension = src_priv->is_extension; + dest_priv->params = g_strdup (src_priv->params); + return TRUE; +} + +IBusExtensionEvent * +ibus_extension_event_new (const gchar *first_property_name, + ...) +{ + va_list var_args; + IBusExtensionEvent *event; + + va_start (var_args, first_property_name); + event = (IBusExtensionEvent *) g_object_new_valist ( + IBUS_TYPE_EXTENSION_EVENT, + first_property_name, + var_args); + va_end (var_args); + g_assert (event->priv->version != 0); + return event; +} + +guint +ibus_extension_event_get_version (IBusExtensionEvent *event) +{ + g_return_val_if_fail (IBUS_IS_EXTENSION_EVENT (event), 0); + return event->priv->version; +} + +const gchar * +ibus_extension_event_get_name (IBusExtensionEvent *event) +{ + g_return_val_if_fail (IBUS_IS_EXTENSION_EVENT (event), ""); + return event->priv->name; +} + +gboolean +ibus_extension_event_is_enabled (IBusExtensionEvent *event) +{ + g_return_val_if_fail (IBUS_IS_EXTENSION_EVENT (event), FALSE); + return event->priv->is_enabled; +} + +gboolean +ibus_extension_event_is_extension (IBusExtensionEvent *event) +{ + g_return_val_if_fail (IBUS_IS_EXTENSION_EVENT (event), FALSE); + return event->priv->is_extension; +} + +const gchar * +ibus_extension_event_get_params (IBusExtensionEvent *event) +{ + g_return_val_if_fail (IBUS_IS_EXTENSION_EVENT (event), ""); + return event->priv->params; +} + + +static void ibus_x_event_class_init (IBusXEventClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); @@ -454,6 +794,7 @@ static void ibus_x_event_destroy (IBusXEvent *event) { g_clear_pointer (&event->priv->string, g_free); + g_clear_pointer (&event->priv->purpose, g_free); IBUS_OBJECT_CLASS(ibus_x_event_parent_class)->destroy (IBUS_OBJECT (event)); } diff --git a/src/ibusxevent.h b/src/ibusxevent.h index f35f14e4..d44cc8f4 100644 --- a/src/ibusxevent.h +++ b/src/ibusxevent.h @@ -29,8 +29,8 @@ /** * SECTION: ibusxevent - * @short_description: XEvent wrapper object - * @title: IBusXEvent + * @short_description: Extension Event wrapper object + * @title: IBusExtensionEvent * @stability: Unstable * * An IBusXEvent provides a wrapper of XEvent. @@ -45,25 +45,150 @@ */ /* define GOBJECT macros */ -#define IBUS_TYPE_X_EVENT \ +#define IBUS_TYPE_EXTENSION_EVENT \ + (ibus_extension_event_get_type ()) +#define IBUS_EXTENSION_EVENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + IBUS_TYPE_EXTENSION_EVENT, \ + IBusExtensionEvent)) +#define IBUS_EXTENSION_EVENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + IBUS_TYPE_EXTENSION_EVENT, \ + IBusExtensionEventClass)) +#define IBUS_IS_EXTENSION_EVENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_EXTENSION_EVENT)) +#define IBUS_IS_EXTENSION_EVENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_EXTENSION_EVENT)) +#define IBUS_EXTENSION_EVENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + IBUS_TYPE_EXTENSION_EVENT, \ + IBusExtensionEventClass)) + +#define IBUS_TYPE_X_EVENT \ (ibus_x_event_get_type ()) -#define IBUS_X_EVENT(obj) \ +#define IBUS_X_EVENT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_X_EVENT, IBusXEvent)) -#define IBUS_X_EVENT_CLASS(klass) \ +#define IBUS_X_EVENT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_X_EVENT, IBusXEventClass)) -#define IBUS_IS_X_EVENT(obj) \ +#define IBUS_IS_X_EVENT(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_X_EVENT)) -#define IBUS_IS_X_EVENT_CLASS(klass) \ +#define IBUS_IS_X_EVENT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_X_EVENT)) -#define IBUS_X_EVENT_GET_CLASS(obj) \ +#define IBUS_X_EVENT_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_X_EVENT, IBusXEventClass)) G_BEGIN_DECLS +typedef struct _IBusProcessKeyEventData IBusProcessKeyEventData; +typedef struct _IBusExtensionEvent IBusExtensionEvent; +typedef struct _IBusExtensionEventClass IBusExtensionEventClass; +typedef struct _IBusExtensionEventPrivate IBusExtensionEventPrivate; typedef struct _IBusXEvent IBusXEvent; typedef struct _IBusXEventClass IBusXEventClass; typedef struct _IBusXEventPrivate IBusXEventPrivate; +/** + * IBusProcessKeyEventData: + * + * IBuProcessKeyEventData properties. + */ +struct _IBusProcessKeyEventData { + /*< public >*/ + guint keyval; + guint keycode; + guint state; +}; + +/** + * IBusExtensionEvent: + * + * IBusExtensionEvent properties. + */ +struct _IBusExtensionEvent { + /*< private >*/ + IBusSerializable parent; + IBusExtensionEventPrivate *priv; + + /* instance members */ + /*< public >*/ +}; + +struct _IBusExtensionEventClass { + /*< private >*/ + IBusSerializableClass parent; + + /* class members */ + /*< public >*/ + + /*< private >*/ + /* padding */ + gpointer pdummy[10]; +}; + + +GType ibus_extension_event_get_type (void); + +/** + * ibus_extension_event_new: + * @first_property_name: Name of the first property. + * @...: the NULL-terminated arguments of the properties and values. + * + * Create a new #IBusExtensionEvent. + * + * Returns: A newly allocated #IBusExtensionEvent. E.g. + * ibus_extension_event_new ("name", "emoji", "is-enabled", TRUE, NULL); + */ +IBusExtensionEvent *ibus_extension_event_new (const gchar + *first_property_name, + ...); + +/** + * ibus_extension_event_get_version: + * @event: An #IBusExtensionEvent. + * + * Returns: Version of #IBusExtensionEvent + */ +guint ibus_extension_event_get_version (IBusExtensionEvent *event); + +/** + * ibus_extension_event_get_purpose: + * @event: An #IBusExtensionEvent. + * + * Returns: name of the extension for #IBusXEvent + */ +const gchar * ibus_extension_event_get_name (IBusExtensionEvent *event); + +/** + * ibus_extension_event_is_enabled: + * @event: An #IBusExtensionEvent. + * + * Returns: %TRUE if the extension is enabled for #IBusExtensionEvent + */ +gboolean ibus_extension_event_is_enabled (IBusExtensionEvent *event); + +/** + * ibus_extension_event_is_extension: + * @event: An #IBusExtensionEvent. + * + * Returns: %TRUE if the #IBusExtensionEvent is called by an extension. + * %FALSE if the #IBusExtensionEvent is called by an active engine or + * panel. + * If this value is %TRUE, the event is send to ibus-daemon, an active + * engine. If it's %FALSE, the event is sned to ibus-daemon, panels. + */ +gboolean ibus_extension_event_is_extension + (IBusExtensionEvent *event); + +/** + * ibus_extension_event_get_params: + * @event: An #IBusExtensionEvent. + * + * Returns: Parameters to enable the extension for #IBusXEvent + */ +const gchar * ibus_extension_event_get_params (IBusExtensionEvent *event); + + + typedef enum { IBUS_X_EVENT_NOTHING = -1, IBUS_X_EVENT_KEY_PRESS = 0, @@ -76,7 +201,7 @@ typedef enum { * IBusXEvent: * @type: event type * - * IBusEngine properties. + * IBusXEvent properties. */ struct _IBusXEvent { /*< private >*/ |