1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2010 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
22 #include "ibusinputcontext.h"
24 #include "ibusshare.h"
25 #include "ibusinternal.h"
26 #include "ibusmarshalers.h"
27 #include "ibusattribute.h"
28 #include "ibuslookuptable.h"
29 #include "ibusproplist.h"
30 #include "ibuserror.h"
32 #define IBUS_INPUT_CONTEXT_GET_PRIVATE(o) \
33 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextPrivate))
40 DELETE_SURROUNDING_TEXT,
44 UPDATE_AUXILIARY_TEXT,
51 PAGE_DOWN_LOOKUP_TABLE,
52 CURSOR_UP_LOOKUP_TABLE,
53 CURSOR_DOWN_LOOKUP_TABLE,
59 /* IBusInputContextPrivate */
60 struct _IBusInputContextPrivate {
61 /* TRUE if the current engine needs surrounding text; FALSE otherwise */
62 gboolean needs_surrounding_text;
64 /* cached surrounding text (see also IBusEnginePrivate and
66 IBusText *surrounding_text;
67 guint surrounding_cursor_pos;
68 guint selection_anchor_pos;
71 typedef struct _IBusInputContextPrivate IBusInputContextPrivate;
73 static guint context_signals[LAST_SIGNAL] = { 0 };
75 static IBusText *text_empty = NULL;
77 /* functions prototype */
78 static void ibus_input_context_real_destroy (IBusProxy *context);
79 static void ibus_input_context_g_signal (GDBusProxy *proxy,
80 const gchar *sender_name,
81 const gchar *signal_name,
82 GVariant *parameters);
84 G_DEFINE_TYPE (IBusInputContext, ibus_input_context, IBUS_TYPE_PROXY)
87 ibus_input_context_class_init (IBusInputContextClass *class)
89 IBusProxyClass *ibus_proxy_class = IBUS_PROXY_CLASS (class);
90 GDBusProxyClass *g_dbus_proxy_class = G_DBUS_PROXY_CLASS (class);
92 g_type_class_add_private (class, sizeof (IBusInputContextPrivate));
94 ibus_proxy_class->destroy = ibus_input_context_real_destroy;
96 g_dbus_proxy_class->g_signal = ibus_input_context_g_signal;
100 * IBusInputContext::enabled:
101 * @context: An IBusInputContext.
103 * Emitted when an IME is enabled.
105 context_signals[ENABLED] =
106 g_signal_new (I_("enabled"),
107 G_TYPE_FROM_CLASS (class),
111 _ibus_marshal_VOID__VOID,
115 * IBusInputContext::disabled:
116 * @context: An IBusInputContext.
118 * Emitted when an IME is disabled.
120 context_signals[DISABLED] =
121 g_signal_new (I_("disabled"),
122 G_TYPE_FROM_CLASS (class),
126 _ibus_marshal_VOID__VOID,
130 * IBusInputContext::commit-text:
131 * @context: An IBusInputContext.
132 * @text: Text to be committed.
134 * Emitted when the text is going to be committed.
136 * (Note: The text object is floating, and it will be released after the signal.
137 * If singal handler want to keep the object, the handler should use g_object_ref_sink()
138 * to get the ownership of the object.)
140 context_signals[COMMIT_TEXT] =
141 g_signal_new (I_("commit-text"),
142 G_TYPE_FROM_CLASS (class),
146 _ibus_marshal_VOID__OBJECT,
152 * IBusInputContext::forward-key-event:
153 * @context: An IBusInputContext.
154 * @keyval: Key symbol of the keyboard event.
155 * @keycode: Key symbol of the keyboard event.
156 * @modifiers: Key modifier flags.
158 * Emitted to forward key event from IME to client of IME.
160 context_signals[FORWARD_KEY_EVENT] =
161 g_signal_new (I_("forward-key-event"),
162 G_TYPE_FROM_CLASS (class),
166 _ibus_marshal_VOID__UINT_UINT_UINT,
174 * IBusInputContext::delete-surrounding-text:
175 * @context: An IBusInputContext.
176 * @offset: the character offset from the cursor position of the text to be deleted.
177 * A negative value indicates a position before the cursor.
178 * @n_chars: the number of characters to be deleted.
180 * Emitted to delete surrounding text event from IME to client of IME.
182 context_signals[DELETE_SURROUNDING_TEXT] =
183 g_signal_new (I_("delete-surrounding-text"),
184 G_TYPE_FROM_CLASS (class),
188 _ibus_marshal_VOID__INT_UINT,
195 * IBusInputContext::update-preedit-text:
196 * @context: An IBusInputContext.
197 * @text: Text to be updated.
198 * @cursor_pos: Cursor position.
199 * @visible: Whether the update is visible.
201 * Emitted to update preedit text.
203 * (Note: The text object is floating, and it will be released after the signal.
204 * If singal handler want to keep the object, the handler should use g_object_ref_sink()
205 * to get the ownership of the object.)
207 context_signals[UPDATE_PREEDIT_TEXT] =
208 g_signal_new (I_("update-preedit-text"),
209 G_TYPE_FROM_CLASS (class),
213 _ibus_marshal_VOID__OBJECT_UINT_BOOLEAN,
221 * IBusInputContext::show-preedit-text:
222 * @context: An IBusInputContext.
224 * Emitted to show preedit text.
226 context_signals[SHOW_PREEDIT_TEXT] =
227 g_signal_new (I_("show-preedit-text"),
228 G_TYPE_FROM_CLASS (class),
232 _ibus_marshal_VOID__VOID,
236 * IBusInputContext::hide-preedit-text:
237 * @context: An IBusInputContext.
239 * Emitted to hide preedit text.
241 context_signals[HIDE_PREEDIT_TEXT] =
242 g_signal_new (I_("hide-preedit-text"),
243 G_TYPE_FROM_CLASS (class),
247 _ibus_marshal_VOID__VOID,
251 * IBusInputContext::update-auxiliary-text:
252 * @context: An IBusInputContext.
254 * Emitted to hide auxilary text.
256 * (Note: The text object is floating, and it will be released after the signal.
257 * If singal handler want to keep the object, the handler should use g_object_ref_sink()
258 * to get the ownership of the object.)
260 context_signals[UPDATE_AUXILIARY_TEXT] =
261 g_signal_new (I_("update-auxiliary-text"),
262 G_TYPE_FROM_CLASS (class),
266 _ibus_marshal_VOID__OBJECT_BOOLEAN,
272 * IBusInputContext::show-auxiliary-text:
273 * @context: An IBusInputContext.
275 * Emitted to show auxiliary text.
277 context_signals[SHOW_AUXILIARY_TEXT] =
278 g_signal_new (I_("show-auxiliary-text"),
279 G_TYPE_FROM_CLASS (class),
283 _ibus_marshal_VOID__VOID,
287 * IBusInputContext::hide-auxiliary-text:
288 * @context: An IBusInputContext.
290 * Emitted to hide auxiliary text.
292 context_signals[HIDE_AUXILIARY_TEXT] =
293 g_signal_new (I_("hide-auxiliary-text"),
294 G_TYPE_FROM_CLASS (class),
298 _ibus_marshal_VOID__VOID,
302 * IBusInputContext::update-lookup-table:
303 * @context: An IBusInputContext.
304 * @table: An IBusLookupTable to be updated.
305 * @visible: Whether the table should be visible.
307 * Emitted to update lookup table.
309 * (Note: The table object is floating, and it will be released after the signal.
310 * If singal handler want to keep the object, the handler should use g_object_ref_sink()
311 * to get the ownership of the object.)
313 context_signals[UPDATE_LOOKUP_TABLE] =
314 g_signal_new (I_("update-lookup-table"),
315 G_TYPE_FROM_CLASS (class),
319 _ibus_marshal_VOID__OBJECT_BOOLEAN,
321 IBUS_TYPE_LOOKUP_TABLE,
325 * IBusInputContext::show-lookup-table:
326 * @context: An IBusInputContext.
328 * Emitted to show lookup table.
330 context_signals[SHOW_LOOKUP_TABLE] =
331 g_signal_new (I_("show-lookup-table"),
332 G_TYPE_FROM_CLASS (class),
336 _ibus_marshal_VOID__VOID,
340 * IBusInputContext::hide-lookup-table:
341 * @context: An IBusInputContext.
343 * Emitted to hide lookup table.
345 context_signals[HIDE_LOOKUP_TABLE] =
346 g_signal_new (I_("hide-lookup-table"),
347 G_TYPE_FROM_CLASS (class),
351 _ibus_marshal_VOID__VOID,
355 * IBusInputContext::page-up-lookup-table:
356 * @context: An IBusInputContext.
358 * Emitted to view the previous page of lookup table.
360 context_signals[PAGE_UP_LOOKUP_TABLE] =
361 g_signal_new (I_("page-up-lookup-table"),
362 G_TYPE_FROM_CLASS (class),
366 _ibus_marshal_VOID__VOID,
370 * IBusInputContext::page-down-lookup-table:
371 * @context: An IBusInputContext.
373 * Emitted to view the next page of lookup table.
375 context_signals[PAGE_DOWN_LOOKUP_TABLE] =
376 g_signal_new (I_("page-down-lookup-table"),
377 G_TYPE_FROM_CLASS (class),
381 _ibus_marshal_VOID__VOID,
385 * IBusInputContext::cursor-up-lookup-table:
386 * @context: An IBusInputContext.
388 * Emitted to select previous candidate of lookup table.
390 context_signals[CURSOR_UP_LOOKUP_TABLE] =
391 g_signal_new (I_("cursor-up-lookup-table"),
392 G_TYPE_FROM_CLASS (class),
396 _ibus_marshal_VOID__VOID,
400 * IBusInputContext::cursor-down-lookup-table:
401 * @context: An IBusInputContext.
403 * Emitted to select next candidate of lookup table.
405 context_signals[CURSOR_DOWN_LOOKUP_TABLE] =
406 g_signal_new (I_("cursor-down-lookup-table"),
407 G_TYPE_FROM_CLASS (class),
411 _ibus_marshal_VOID__VOID,
416 * IBusInputContext::register-properties:
417 * @context: An IBusInputContext.
418 * @props: An IBusPropList that contains properties.
420 * Emitted to register the properties in @props.
422 * (Note: The props object is floating, and it will be released after the signal.
423 * If singal handler want to keep the object, the handler should use g_object_ref_sink()
424 * to get the ownership of the object.)
426 context_signals[REGISTER_PROPERTIES] =
427 g_signal_new (I_("register-properties"),
428 G_TYPE_FROM_CLASS (class),
432 _ibus_marshal_VOID__OBJECT,
435 IBUS_TYPE_PROP_LIST);
438 * IBusInputContext::update-property:
439 * @context: An IBusInputContext.
440 * @prop: The IBusProperty to be updated.
442 * Emitted to update the property @prop.
444 * (Note: The prop object is floating, and it will be released after the signal.
445 * If singal handler want to keep the object, the handler should use g_object_ref_sink()
446 * to get the ownership of the object.)
448 context_signals[UPDATE_PROPERTY] =
449 g_signal_new (I_("update-property"),
450 G_TYPE_FROM_CLASS (class),
454 _ibus_marshal_VOID__OBJECT,
459 text_empty = ibus_text_new_from_static_string ("");
460 g_object_ref_sink (text_empty);
464 ibus_input_context_init (IBusInputContext *context)
466 IBusInputContextPrivate *priv;
468 priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
469 priv->surrounding_text = g_object_ref_sink (text_empty);
473 ibus_input_context_real_destroy (IBusProxy *context)
475 IBusInputContextPrivate *priv;
476 priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
478 if (priv->surrounding_text) {
479 g_object_unref (priv->surrounding_text);
480 priv->surrounding_text = NULL;
483 IBUS_PROXY_CLASS(ibus_input_context_parent_class)->destroy (context);
487 ibus_input_context_g_signal (GDBusProxy *proxy,
488 const gchar *sender_name,
489 const gchar *signal_name,
490 GVariant *parameters)
492 g_assert (IBUS_IS_INPUT_CONTEXT (proxy));
494 IBusInputContext *context;
495 context = IBUS_INPUT_CONTEXT (proxy);
497 static const struct {
498 const gchar *signal_name;
501 { "ShowPreeditText", SHOW_PREEDIT_TEXT },
502 { "HidePreeditText", HIDE_PREEDIT_TEXT },
503 { "ShowAuxiliaryText", SHOW_AUXILIARY_TEXT },
504 { "HideAuxiliaryText", HIDE_AUXILIARY_TEXT },
505 { "ShowLookupTable", SHOW_LOOKUP_TABLE },
506 { "HideLookupTable", HIDE_LOOKUP_TABLE },
507 { "PageUpLookupTable", PAGE_UP_LOOKUP_TABLE },
508 { "PageDownLookupTable", PAGE_DOWN_LOOKUP_TABLE },
509 { "CursorUpLookupTable", CURSOR_UP_LOOKUP_TABLE },
510 { "CursorDownLookupTable", CURSOR_DOWN_LOOKUP_TABLE },
513 if (g_strcmp0 (signal_name, "CommitText") == 0) {
514 GVariant *variant = NULL;
515 g_variant_get (parameters, "(v)", &variant);
516 IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
517 g_variant_unref (variant);
518 g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
520 if (g_object_is_floating (text))
521 g_object_unref (text);
524 if (g_strcmp0 (signal_name, "UpdatePreeditText") == 0) {
525 GVariant *variant = NULL;
528 g_variant_get (parameters, "(vub)", &variant, &cursor_pos, &visible);
529 IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
530 g_variant_unref (variant);
532 g_signal_emit (context,
533 context_signals[UPDATE_PREEDIT_TEXT],
539 if (g_object_is_floating (text))
540 g_object_unref (text);
544 /* lookup signal in table */
547 i < G_N_ELEMENTS (signals) && g_strcmp0 (signal_name, signals[i].signal_name) != 0;
550 if (i < G_N_ELEMENTS (signals)) {
551 g_signal_emit (context, context_signals[signals[i].signal_id], 0);
555 if (g_strcmp0 (signal_name, "UpdateAuxiliaryText") == 0) {
556 GVariant *variant = NULL;
558 g_variant_get (parameters, "(vb)", &variant, &visible);
559 IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
560 g_variant_unref (variant);
562 g_signal_emit (context,
563 context_signals[UPDATE_AUXILIARY_TEXT],
567 if (g_object_is_floating (text))
568 g_object_unref (text);
572 if (g_strcmp0 (signal_name, "UpdateLookupTable") == 0) {
573 GVariant *variant = NULL;
575 g_variant_get (parameters, "(vb)", &variant, &visible);
577 IBusLookupTable *table = IBUS_LOOKUP_TABLE (ibus_serializable_deserialize (variant));
578 g_variant_unref (variant);
580 g_signal_emit (context,
581 context_signals[UPDATE_LOOKUP_TABLE],
585 if (g_object_is_floating (table))
586 g_object_unref (table);
591 if (g_strcmp0 (signal_name, "RegisterProperties") == 0) {
592 GVariant *variant = NULL;
593 g_variant_get (parameters, "(v)", &variant);
595 IBusPropList *prop_list = IBUS_PROP_LIST (ibus_serializable_deserialize (variant));
596 g_variant_unref (variant);
598 g_signal_emit (context,
599 context_signals[REGISTER_PROPERTIES],
603 if (g_object_is_floating (prop_list))
604 g_object_unref (prop_list);
608 if (g_strcmp0 (signal_name, "UpdateProperty") == 0) {
609 GVariant *variant = NULL;
610 g_variant_get (parameters, "(v)", &variant);
611 IBusProperty *prop = IBUS_PROPERTY (ibus_serializable_deserialize (variant));
612 g_variant_unref (variant);
614 g_signal_emit (context, context_signals[UPDATE_PROPERTY], 0, prop);
616 if (g_object_is_floating (prop))
617 g_object_unref (prop);
621 if (g_strcmp0 (signal_name, "ForwardKeyEvent") == 0) {
626 g_variant_get (parameters, "(uuu)", &keyval, &keycode, &state);
628 /* Forward key event back with IBUS_FORWARD_MASK. And process_key_event will
629 * not process key event with IBUS_FORWARD_MASK again. */
630 g_signal_emit (context,
631 context_signals[FORWARD_KEY_EVENT],
635 state | IBUS_FORWARD_MASK);
639 if (g_strcmp0 (signal_name, "DeleteSurroundingText") == 0) {
640 gint offset_from_cursor;
643 g_variant_get (parameters, "(iu)", &offset_from_cursor, &nchars);
645 g_signal_emit (context,
646 context_signals[DELETE_SURROUNDING_TEXT],
653 IBusInputContextPrivate *priv;
654 priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
656 if (g_strcmp0 (signal_name, "Enabled") == 0) {
657 priv->needs_surrounding_text = FALSE;
658 g_signal_emit (context, context_signals[ENABLED], 0);
662 if (g_strcmp0 (signal_name, "Disabled") == 0) {
663 priv->needs_surrounding_text = FALSE;
664 g_signal_emit (context, context_signals[DISABLED], 0);
668 if (g_strcmp0 (signal_name, "RequireSurroundingText") == 0) {
669 priv->needs_surrounding_text = TRUE;
673 G_DBUS_PROXY_CLASS (ibus_input_context_parent_class)->g_signal (
674 proxy, sender_name, signal_name, parameters);
678 ibus_input_context_new (const gchar *path,
679 GDBusConnection *connection,
680 GCancellable *cancellable,
683 g_assert (path != NULL);
684 g_assert (G_IS_DBUS_CONNECTION (connection));
688 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
689 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
691 initable = g_initable_new (IBUS_TYPE_INPUT_CONTEXT,
694 "g-connection", connection,
695 "g-name", IBUS_SERVICE_IBUS,
697 "g-interface-name", IBUS_INTERFACE_INPUT_CONTEXT,
698 "g-object-path", path,
699 "g-default-timeout", ibus_get_timeout (),
701 if (initable != NULL)
702 return IBUS_INPUT_CONTEXT (initable);
707 ibus_input_context_new_async (const gchar *path,
708 GDBusConnection *connection,
709 GCancellable *cancellable,
710 GAsyncReadyCallback callback,
713 g_assert (path != NULL);
714 g_assert (G_IS_DBUS_CONNECTION (connection));
715 g_assert (callback != NULL);
717 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
718 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
720 g_async_initable_new_async (IBUS_TYPE_INPUT_CONTEXT,
725 "g-connection", connection,
726 "g-name", IBUS_SERVICE_IBUS,
728 "g-interface-name", IBUS_INTERFACE_INPUT_CONTEXT,
729 "g-object-path", path,
730 "g-default-timeout", ibus_get_timeout (),
735 ibus_input_context_new_async_finish (GAsyncResult *res,
738 GObject *object = NULL;
739 GObject *source_object = NULL;
741 source_object = g_async_result_get_source_object (res);
742 g_assert (source_object != NULL);
744 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
747 g_object_unref (source_object);
749 if (object != NULL) {
750 return IBUS_INPUT_CONTEXT (object);
758 ibus_input_context_get_input_context (const gchar *path,
759 GDBusConnection *connection)
761 IBusInputContext *context = NULL;
762 GError *error = NULL;
764 context = ibus_input_context_new (path, connection, NULL, &error);
765 if (context == NULL) {
766 g_warning ("ibus_input_context_get_input_context: %s", error->message);
767 g_error_free (error);
771 /* Do not call "org.freedesktop.IBus.Service.Destroy" when the input
772 * context object is disposed. */
773 IBUS_PROXY (context)->own = FALSE;
778 ibus_input_context_get_input_context_async (const gchar *path,
779 GDBusConnection *connection,
780 GCancellable *cancellable,
781 GAsyncReadyCallback callback,
784 ibus_input_context_new_async (path,
792 ibus_input_context_get_input_context_async_finish (GAsyncResult *res,
795 IBusInputContext *context = NULL;
797 context = ibus_input_context_new_async_finish (res, error);
798 if (context == NULL) {
802 /* Do not call "org.freedesktop.IBus.Service.Destroy" when the input
803 * context object is disposed. */
804 IBUS_PROXY (context)->own = FALSE;
809 ibus_input_context_process_hand_writing_event (IBusInputContext *context,
810 const gdouble *coordinates,
811 guint coordinates_len)
813 g_assert (IBUS_IS_INPUT_CONTEXT (context));
814 g_return_if_fail (coordinates != NULL);
815 g_return_if_fail (coordinates_len >= 4); /* The array should contain at least one line. */
816 g_return_if_fail ((coordinates_len & 1) == 0);
819 GVariantBuilder builder;
820 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ad"));
821 for (i = 0; i < coordinates_len; i++) {
822 g_variant_builder_add (&builder, "d", coordinates[i]);
825 g_dbus_proxy_call ((GDBusProxy *) context,
826 "ProcessHandWritingEvent", /* method_name */
827 g_variant_new ("(ad)", &builder), /* parameters */
828 G_DBUS_CALL_FLAGS_NONE, /* flags */
830 NULL, /* cancellable */
837 ibus_input_context_cancel_hand_writing (IBusInputContext *context,
840 g_assert (IBUS_IS_INPUT_CONTEXT (context));
842 g_dbus_proxy_call ((GDBusProxy *) context,
843 "CancelHandWriting", /* method_name */
844 g_variant_new ("(u)", n_strokes), /* parameters */
845 G_DBUS_CALL_FLAGS_NONE, /* flags */
847 NULL, /* cancellable */
854 ibus_input_context_process_key_event_async (IBusInputContext *context,
859 GCancellable *cancellable,
860 GAsyncReadyCallback callback,
863 g_assert (IBUS_IS_INPUT_CONTEXT (context));
865 g_dbus_proxy_call ((GDBusProxy *) context,
866 "ProcessKeyEvent", /* method_name */
867 g_variant_new ("(uuu)",
868 keyval, keycode, state), /* parameters */
869 G_DBUS_CALL_FLAGS_NONE, /* flags */
870 timeout_msec, /* timeout */
871 cancellable, /* cancellable */
872 callback, /* callback */
873 user_data /* user_data */
878 ibus_input_context_process_key_event_async_finish (IBusInputContext *context,
882 g_assert (IBUS_IS_INPUT_CONTEXT (context));
883 g_assert (G_IS_ASYNC_RESULT (res));
884 g_assert (error == NULL || *error == NULL);
886 gboolean processed = FALSE;
888 GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
890 if (variant != NULL) {
891 g_variant_get (variant, "(b)", &processed);
892 g_variant_unref (variant);
899 ibus_input_context_process_key_event (IBusInputContext *context,
904 g_assert (IBUS_IS_INPUT_CONTEXT (context));
906 GVariant *result = g_dbus_proxy_call_sync ((GDBusProxy *) context,
907 "ProcessKeyEvent", /* method_name */
908 g_variant_new ("(uuu)",
909 keyval, keycode, state), /* parameters */
910 G_DBUS_CALL_FLAGS_NONE, /* flags */
912 NULL, /* cancellable */
915 if (result != NULL) {
916 gboolean processed = FALSE;
918 g_variant_get (result, "(b)", &processed);
919 g_variant_unref (result);
927 ibus_input_context_set_cursor_location (IBusInputContext *context,
933 g_assert (IBUS_IS_INPUT_CONTEXT (context));
935 g_dbus_proxy_call ((GDBusProxy *) context,
936 "SetCursorLocation", /* method_name */
937 g_variant_new ("(iiii)", x, y, w, h),/* parameters */
938 G_DBUS_CALL_FLAGS_NONE, /* flags */
940 NULL, /* cancellable */
947 ibus_input_context_set_capabilities (IBusInputContext *context,
950 g_assert (IBUS_IS_INPUT_CONTEXT (context));
951 g_dbus_proxy_call ((GDBusProxy *) context,
952 "SetCapabilities", /* method_name */
953 g_variant_new ("(u)", capabilites), /* parameters */
954 G_DBUS_CALL_FLAGS_NONE, /* flags */
956 NULL, /* cancellable */
963 ibus_input_context_property_activate (IBusInputContext *context,
964 const gchar *prop_name,
967 g_assert (IBUS_IS_INPUT_CONTEXT (context));
968 g_dbus_proxy_call ((GDBusProxy *) context,
969 "PropertyActivate", /* method_name */
970 g_variant_new ("(su)",
971 prop_name, state), /* parameters */
972 G_DBUS_CALL_FLAGS_NONE, /* flags */
974 NULL, /* cancellable */
981 ibus_input_context_property_show (IBusInputContext *context,
982 const gchar *prop_name)
984 g_assert (IBUS_IS_INPUT_CONTEXT (context));
985 g_dbus_proxy_call ((GDBusProxy *) context,
986 "PropertyShow", /* method_name */
987 g_variant_new ("(s)", prop_name), /* parameters */
988 G_DBUS_CALL_FLAGS_NONE, /* flags */
990 NULL, /* cancellable */
997 ibus_input_context_property_hide (IBusInputContext *context,
998 const gchar *prop_name)
1000 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1001 g_dbus_proxy_call ((GDBusProxy *) context,
1002 "PropertyHide", /* method_name */
1003 g_variant_new ("(s)", prop_name), /* parameters */
1004 G_DBUS_CALL_FLAGS_NONE, /* flags */
1006 NULL, /* cancellable */
1007 NULL, /* callback */
1008 NULL /* user_data */
1013 ibus_input_context_set_surrounding_text (IBusInputContext *context,
1018 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1019 g_assert (IBUS_IS_TEXT (text));
1021 IBusInputContextPrivate *priv;
1022 priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
1024 if (cursor_pos != priv->surrounding_cursor_pos ||
1025 anchor_pos != priv->selection_anchor_pos ||
1026 priv->surrounding_text == NULL ||
1027 g_strcmp0 (text->text, priv->surrounding_text->text) != 0) {
1028 if (priv->surrounding_text)
1029 g_object_unref (priv->surrounding_text);
1030 priv->surrounding_text = (IBusText *) g_object_ref_sink (text);
1031 priv->surrounding_cursor_pos = cursor_pos;
1032 priv->selection_anchor_pos = anchor_pos;
1034 if (priv->needs_surrounding_text) {
1035 GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
1036 g_dbus_proxy_call ((GDBusProxy *) context,
1037 "SetSurroundingText", /* method_name */
1038 g_variant_new ("(vuu)",
1041 anchor_pos), /* parameters */
1042 G_DBUS_CALL_FLAGS_NONE, /* flags */
1044 NULL, /* cancellable */
1045 NULL, /* callback */
1046 NULL /* user_data */
1053 ibus_input_context_needs_surrounding_text (IBusInputContext *context)
1055 IBusInputContextPrivate *priv;
1056 priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
1057 return priv->needs_surrounding_text;
1061 ibus_input_context_get_engine_async (IBusInputContext *context,
1063 GCancellable *cancellable,
1064 GAsyncReadyCallback callback,
1067 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1068 g_dbus_proxy_call ((GDBusProxy *) context,
1069 "GetEngine", /* method_name */
1070 NULL, /* parameters */
1071 G_DBUS_CALL_FLAGS_NONE, /* flags */
1079 ibus_input_context_get_engine_async_finish (IBusInputContext *context,
1083 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1084 g_assert (G_IS_ASYNC_RESULT (res));
1085 g_assert (error == NULL || *error == NULL);
1087 GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
1089 if (variant == NULL) {
1093 GVariant *engine_desc_variant = g_variant_get_child_value (variant, 0);
1094 IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
1095 g_variant_unref (engine_desc_variant);
1096 g_variant_unref (variant);
1102 ibus_input_context_get_engine (IBusInputContext *context)
1104 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1105 GVariant *result = NULL;
1106 GError *error = NULL;
1107 result = g_dbus_proxy_call_sync ((GDBusProxy *) context,
1108 "GetEngine", /* method_name */
1109 NULL, /* parameters */
1110 G_DBUS_CALL_FLAGS_NONE, /* flags */
1112 NULL, /* cancellable */
1115 if (result == NULL) {
1116 if (g_error_matches (error, IBUS_ERROR, IBUS_ERROR_NO_ENGINE)) {
1117 g_debug ("%s.GetEngine: %s",
1118 IBUS_INTERFACE_INPUT_CONTEXT,
1122 g_warning ("%s.GetEngine: %s",
1123 IBUS_INTERFACE_INPUT_CONTEXT,
1126 g_error_free (error);
1130 GVariant *engine_desc_variant = g_variant_get_child_value (result, 0);
1131 IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
1132 g_variant_unref (engine_desc_variant);
1133 g_variant_unref (result);
1139 ibus_input_context_set_engine (IBusInputContext *context,
1142 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1144 g_dbus_proxy_call ((GDBusProxy *) context,
1145 "SetEngine", /* method_name */
1146 g_variant_new ("(s)", name), /* parameters */
1147 G_DBUS_CALL_FLAGS_NONE, /* flags */
1149 NULL, /* cancellable */
1150 NULL, /* callback */
1151 NULL /* user_data */
1155 #define DEFINE_FUNC(name, Name) \
1157 ibus_input_context_##name (IBusInputContext *context) \
1159 g_assert (IBUS_IS_INPUT_CONTEXT (context)); \
1160 g_dbus_proxy_call ((GDBusProxy *) context, \
1161 #Name, /* method_name */ \
1162 NULL, /* parameters */ \
1163 G_DBUS_CALL_FLAGS_NONE, /* flags */ \
1165 NULL, /* cancellable */ \
1166 NULL, /* callback */ \
1167 NULL /* user_data */ \
1171 DEFINE_FUNC(focus_in, FocusIn);
1172 DEFINE_FUNC(focus_out, FocusOut);
1173 DEFINE_FUNC(reset, Reset);
1174 DEFINE_FUNC(page_up, PageUp);
1175 DEFINE_FUNC(page_down, PageDown);
1176 DEFINE_FUNC(cursor_up, CursorUp);
1177 DEFINE_FUNC(cursor_down, CursorDown);