summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ibusengine.c305
-rw-r--r--src/ibuspanelservice.c318
-rw-r--r--src/ibuspanelservice.h117
-rw-r--r--src/ibusshare.h17
-rw-r--r--src/ibusxevent.c375
-rw-r--r--src/ibusxevent.h143
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 >*/