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-2013 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2013 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.1 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 Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
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;
690 initable = g_initable_new (IBUS_TYPE_INPUT_CONTEXT,
693 "g-connection", connection,
694 "g-name", IBUS_SERVICE_IBUS,
696 "g-interface-name", IBUS_INTERFACE_INPUT_CONTEXT,
697 "g-object-path", path,
698 "g-default-timeout", ibus_get_timeout (),
700 if (initable != NULL)
701 return IBUS_INPUT_CONTEXT (initable);
706 ibus_input_context_new_async (const gchar *path,
707 GDBusConnection *connection,
708 GCancellable *cancellable,
709 GAsyncReadyCallback callback,
712 g_assert (path != NULL);
713 g_assert (G_IS_DBUS_CONNECTION (connection));
714 g_assert (callback != NULL);
716 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
718 g_async_initable_new_async (IBUS_TYPE_INPUT_CONTEXT,
723 "g-connection", connection,
724 "g-name", IBUS_SERVICE_IBUS,
726 "g-interface-name", IBUS_INTERFACE_INPUT_CONTEXT,
727 "g-object-path", path,
728 "g-default-timeout", ibus_get_timeout (),
733 ibus_input_context_new_async_finish (GAsyncResult *res,
736 GObject *object = NULL;
737 GObject *source_object = NULL;
739 source_object = g_async_result_get_source_object (res);
740 g_assert (source_object != NULL);
742 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
745 g_object_unref (source_object);
747 if (object != NULL) {
748 return IBUS_INPUT_CONTEXT (object);
756 ibus_input_context_get_input_context (const gchar *path,
757 GDBusConnection *connection)
759 IBusInputContext *context = NULL;
760 GError *error = NULL;
762 context = ibus_input_context_new (path, connection, NULL, &error);
763 if (context == NULL) {
764 g_warning ("ibus_input_context_get_input_context: %s", error->message);
765 g_error_free (error);
769 /* Do not call "org.freedesktop.IBus.Service.Destroy" when the input
770 * context object is disposed. */
771 IBUS_PROXY (context)->own = FALSE;
776 ibus_input_context_get_input_context_async (const gchar *path,
777 GDBusConnection *connection,
778 GCancellable *cancellable,
779 GAsyncReadyCallback callback,
782 ibus_input_context_new_async (path,
790 ibus_input_context_get_input_context_async_finish (GAsyncResult *res,
793 IBusInputContext *context = NULL;
795 context = ibus_input_context_new_async_finish (res, error);
796 if (context == NULL) {
800 /* Do not call "org.freedesktop.IBus.Service.Destroy" when the input
801 * context object is disposed. */
802 IBUS_PROXY (context)->own = FALSE;
807 ibus_input_context_process_hand_writing_event (IBusInputContext *context,
808 const gdouble *coordinates,
809 guint coordinates_len)
811 g_assert (IBUS_IS_INPUT_CONTEXT (context));
812 g_return_if_fail (coordinates != NULL);
813 g_return_if_fail (coordinates_len >= 4); /* The array should contain at least one line. */
814 g_return_if_fail ((coordinates_len & 1) == 0);
817 GVariantBuilder builder;
818 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ad"));
819 for (i = 0; i < coordinates_len; i++) {
820 g_variant_builder_add (&builder, "d", coordinates[i]);
823 g_dbus_proxy_call ((GDBusProxy *) context,
824 "ProcessHandWritingEvent", /* method_name */
825 g_variant_new ("(ad)", &builder), /* parameters */
826 G_DBUS_CALL_FLAGS_NONE, /* flags */
828 NULL, /* cancellable */
835 ibus_input_context_cancel_hand_writing (IBusInputContext *context,
838 g_assert (IBUS_IS_INPUT_CONTEXT (context));
840 g_dbus_proxy_call ((GDBusProxy *) context,
841 "CancelHandWriting", /* method_name */
842 g_variant_new ("(u)", n_strokes), /* parameters */
843 G_DBUS_CALL_FLAGS_NONE, /* flags */
845 NULL, /* cancellable */
852 ibus_input_context_process_key_event_async (IBusInputContext *context,
857 GCancellable *cancellable,
858 GAsyncReadyCallback callback,
861 g_assert (IBUS_IS_INPUT_CONTEXT (context));
863 g_dbus_proxy_call ((GDBusProxy *) context,
864 "ProcessKeyEvent", /* method_name */
865 g_variant_new ("(uuu)",
866 keyval, keycode, state), /* parameters */
867 G_DBUS_CALL_FLAGS_NONE, /* flags */
868 timeout_msec, /* timeout */
869 cancellable, /* cancellable */
870 callback, /* callback */
871 user_data /* user_data */
876 ibus_input_context_process_key_event_async_finish (IBusInputContext *context,
880 g_assert (IBUS_IS_INPUT_CONTEXT (context));
881 g_assert (G_IS_ASYNC_RESULT (res));
882 g_assert (error == NULL || *error == NULL);
884 gboolean processed = FALSE;
886 GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
888 if (variant != NULL) {
889 g_variant_get (variant, "(b)", &processed);
890 g_variant_unref (variant);
897 ibus_input_context_process_key_event (IBusInputContext *context,
902 g_assert (IBUS_IS_INPUT_CONTEXT (context));
904 GVariant *result = g_dbus_proxy_call_sync ((GDBusProxy *) context,
905 "ProcessKeyEvent", /* method_name */
906 g_variant_new ("(uuu)",
907 keyval, keycode, state), /* parameters */
908 G_DBUS_CALL_FLAGS_NONE, /* flags */
910 NULL, /* cancellable */
913 if (result != NULL) {
914 gboolean processed = FALSE;
916 g_variant_get (result, "(b)", &processed);
917 g_variant_unref (result);
925 ibus_input_context_set_cursor_location (IBusInputContext *context,
931 g_assert (IBUS_IS_INPUT_CONTEXT (context));
933 g_dbus_proxy_call ((GDBusProxy *) context,
934 "SetCursorLocation", /* method_name */
935 g_variant_new ("(iiii)", x, y, w, h),/* parameters */
936 G_DBUS_CALL_FLAGS_NONE, /* flags */
938 NULL, /* cancellable */
945 ibus_input_context_set_capabilities (IBusInputContext *context,
948 g_assert (IBUS_IS_INPUT_CONTEXT (context));
949 g_dbus_proxy_call ((GDBusProxy *) context,
950 "SetCapabilities", /* method_name */
951 g_variant_new ("(u)", capabilites), /* parameters */
952 G_DBUS_CALL_FLAGS_NONE, /* flags */
954 NULL, /* cancellable */
961 ibus_input_context_property_activate (IBusInputContext *context,
962 const gchar *prop_name,
965 g_assert (IBUS_IS_INPUT_CONTEXT (context));
966 g_dbus_proxy_call ((GDBusProxy *) context,
967 "PropertyActivate", /* method_name */
968 g_variant_new ("(su)",
969 prop_name, state), /* parameters */
970 G_DBUS_CALL_FLAGS_NONE, /* flags */
972 NULL, /* cancellable */
979 ibus_input_context_property_show (IBusInputContext *context,
980 const gchar *prop_name)
982 g_assert (IBUS_IS_INPUT_CONTEXT (context));
983 g_dbus_proxy_call ((GDBusProxy *) context,
984 "PropertyShow", /* method_name */
985 g_variant_new ("(s)", prop_name), /* parameters */
986 G_DBUS_CALL_FLAGS_NONE, /* flags */
988 NULL, /* cancellable */
995 ibus_input_context_property_hide (IBusInputContext *context,
996 const gchar *prop_name)
998 g_assert (IBUS_IS_INPUT_CONTEXT (context));
999 g_dbus_proxy_call ((GDBusProxy *) context,
1000 "PropertyHide", /* method_name */
1001 g_variant_new ("(s)", prop_name), /* parameters */
1002 G_DBUS_CALL_FLAGS_NONE, /* flags */
1004 NULL, /* cancellable */
1005 NULL, /* callback */
1006 NULL /* user_data */
1011 ibus_input_context_set_surrounding_text (IBusInputContext *context,
1016 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1017 g_assert (IBUS_IS_TEXT (text));
1019 IBusInputContextPrivate *priv;
1020 priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
1022 if (cursor_pos != priv->surrounding_cursor_pos ||
1023 anchor_pos != priv->selection_anchor_pos ||
1024 priv->surrounding_text == NULL ||
1025 g_strcmp0 (text->text, priv->surrounding_text->text) != 0) {
1026 if (priv->surrounding_text)
1027 g_object_unref (priv->surrounding_text);
1028 priv->surrounding_text = (IBusText *) g_object_ref_sink (text);
1029 priv->surrounding_cursor_pos = cursor_pos;
1030 priv->selection_anchor_pos = anchor_pos;
1032 if (priv->needs_surrounding_text) {
1033 GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
1034 g_dbus_proxy_call ((GDBusProxy *) context,
1035 "SetSurroundingText", /* method_name */
1036 g_variant_new ("(vuu)",
1039 anchor_pos), /* parameters */
1040 G_DBUS_CALL_FLAGS_NONE, /* flags */
1042 NULL, /* cancellable */
1043 NULL, /* callback */
1044 NULL /* user_data */
1051 ibus_input_context_needs_surrounding_text (IBusInputContext *context)
1053 IBusInputContextPrivate *priv;
1054 priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
1055 return priv->needs_surrounding_text;
1059 ibus_input_context_set_content_type (IBusInputContext *context,
1063 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1065 GVariant *cached_content_type =
1066 g_dbus_proxy_get_cached_property ((GDBusProxy *) context,
1068 GVariant *content_type = g_variant_new ("(uu)", purpose, hints);
1070 g_variant_ref_sink (content_type);
1071 if (cached_content_type == NULL ||
1072 !g_variant_equal (content_type, cached_content_type)) {
1073 g_dbus_proxy_call ((GDBusProxy *) context,
1074 "org.freedesktop.DBus.Properties.Set",
1075 g_variant_new ("(ssv)",
1076 IBUS_INTERFACE_INPUT_CONTEXT,
1079 G_DBUS_CALL_FLAGS_NONE,
1081 NULL, /* cancellable */
1082 NULL, /* callback */
1083 NULL /* user_data */
1087 if (cached_content_type != NULL)
1088 g_variant_unref (cached_content_type);
1089 g_variant_unref (content_type);
1093 ibus_input_context_get_engine_async (IBusInputContext *context,
1095 GCancellable *cancellable,
1096 GAsyncReadyCallback callback,
1099 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1100 g_dbus_proxy_call ((GDBusProxy *) context,
1101 "GetEngine", /* method_name */
1102 NULL, /* parameters */
1103 G_DBUS_CALL_FLAGS_NONE, /* flags */
1111 ibus_input_context_get_engine_async_finish (IBusInputContext *context,
1115 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1116 g_assert (G_IS_ASYNC_RESULT (res));
1117 g_assert (error == NULL || *error == NULL);
1119 GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
1121 if (variant == NULL) {
1125 GVariant *engine_desc_variant = g_variant_get_child_value (variant, 0);
1126 IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
1127 g_variant_unref (engine_desc_variant);
1128 g_variant_unref (variant);
1134 ibus_input_context_get_engine (IBusInputContext *context)
1136 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1137 GVariant *result = NULL;
1138 GError *error = NULL;
1139 result = g_dbus_proxy_call_sync ((GDBusProxy *) context,
1140 "GetEngine", /* method_name */
1141 NULL, /* parameters */
1142 G_DBUS_CALL_FLAGS_NONE, /* flags */
1144 NULL, /* cancellable */
1147 if (result == NULL) {
1148 if (g_error_matches (error, IBUS_ERROR, IBUS_ERROR_NO_ENGINE)) {
1149 g_debug ("%s.GetEngine: %s",
1150 IBUS_INTERFACE_INPUT_CONTEXT,
1154 g_warning ("%s.GetEngine: %s",
1155 IBUS_INTERFACE_INPUT_CONTEXT,
1158 g_error_free (error);
1162 GVariant *engine_desc_variant = g_variant_get_child_value (result, 0);
1163 IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
1164 g_variant_unref (engine_desc_variant);
1165 g_variant_unref (result);
1171 ibus_input_context_set_engine (IBusInputContext *context,
1174 g_assert (IBUS_IS_INPUT_CONTEXT (context));
1176 g_dbus_proxy_call ((GDBusProxy *) context,
1177 "SetEngine", /* method_name */
1178 g_variant_new ("(s)", name), /* parameters */
1179 G_DBUS_CALL_FLAGS_NONE, /* flags */
1181 NULL, /* cancellable */
1182 NULL, /* callback */
1183 NULL /* user_data */
1187 #define DEFINE_FUNC(name, Name) \
1189 ibus_input_context_##name (IBusInputContext *context) \
1191 g_assert (IBUS_IS_INPUT_CONTEXT (context)); \
1192 g_dbus_proxy_call ((GDBusProxy *) context, \
1193 #Name, /* method_name */ \
1194 NULL, /* parameters */ \
1195 G_DBUS_CALL_FLAGS_NONE, /* flags */ \
1197 NULL, /* cancellable */ \
1198 NULL, /* callback */ \
1199 NULL /* user_data */ \
1203 DEFINE_FUNC(focus_in, FocusIn);
1204 DEFINE_FUNC(focus_out, FocusOut);
1205 DEFINE_FUNC(reset, Reset);
1206 DEFINE_FUNC(page_up, PageUp);
1207 DEFINE_FUNC(page_down, PageDown);
1208 DEFINE_FUNC(cursor_up, CursorUp);
1209 DEFINE_FUNC(cursor_down, CursorDown);