58
/* BusInputContextPriv */
58
/* IBusInputContextPrivate */
59
59
struct _IBusInputContextPrivate {
60
/* TRUE if the current engine needs surrounding text; FALSE otherwise */
61
gboolean needs_surrounding_text;
63
/* cached surrounding text (see also IBusEnginePrivate and
65
IBusText *surrounding_text;
66
guint surrounding_cursor_pos;
62
69
typedef struct _IBusInputContextPrivate IBusInputContextPrivate;
64
71
static guint context_signals[LAST_SIGNAL] = { 0 };
65
// static guint context_signals[LAST_SIGNAL] = { 0 };
73
static IBusText *text_empty = NULL;
67
75
/* functions prototype */
68
static void ibus_input_context_real_destroy (IBusInputContext *context);
69
static gboolean ibus_input_context_ibus_signal (IBusProxy *proxy,
70
DBusMessage *message);
76
static void ibus_input_context_real_destroy (IBusProxy *context);
77
static void ibus_input_context_g_signal (GDBusProxy *proxy,
78
const gchar *sender_name,
79
const gchar *signal_name,
80
GVariant *parameters);
72
82
G_DEFINE_TYPE (IBusInputContext, ibus_input_context, IBUS_TYPE_PROXY)
75
ibus_input_context_new (const gchar *path,
76
IBusConnection *connection)
78
g_assert (path != NULL);
79
g_assert (IBUS_IS_CONNECTION (connection));
82
obj = g_object_new (IBUS_TYPE_INPUT_CONTEXT,
83
"name", IBUS_SERVICE_IBUS,
84
"interface", IBUS_INTERFACE_INPUT_CONTEXT,
86
"connection", connection,
89
return IBUS_INPUT_CONTEXT (obj);
93
ibus_input_context_get_input_context (const gchar *path,
94
IBusConnection *connection)
96
IBusInputContext *context = ibus_input_context_new (path, connection);
97
IBusInputContextPrivate *priv;
100
priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
106
ibus_input_context_class_init (IBusInputContextClass *klass)
85
ibus_input_context_class_init (IBusInputContextClass *class)
108
IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
109
IBusProxyClass *proxy_class = IBUS_PROXY_CLASS (klass);
111
g_type_class_add_private (klass, sizeof (IBusInputContextPrivate));
113
ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_input_context_real_destroy;
115
proxy_class->ibus_signal = ibus_input_context_ibus_signal;
87
IBusProxyClass *ibus_proxy_class = IBUS_PROXY_CLASS (class);
88
GDBusProxyClass *g_dbus_proxy_class = G_DBUS_PROXY_CLASS (class);
90
g_type_class_add_private (class, sizeof (IBusInputContextPrivate));
92
ibus_proxy_class->destroy = ibus_input_context_real_destroy;
94
g_dbus_proxy_class->g_signal = ibus_input_context_g_signal;
117
96
/* install signals */
533
509
{ "CursorDownLookupTable", CURSOR_DOWN_LOOKUP_TABLE },
537
interface = ibus_message_get_interface (message);
538
name = ibus_message_get_member (message);
540
if (interface != NULL && g_strcmp0 (interface, IBUS_INTERFACE_INPUT_CONTEXT) != 0) {
541
error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
542
"Signal %s.%s is not handled", interface, name);
546
if (g_strcmp0 (name, "CommitText") == 0) {
550
retval = ibus_message_get_args (message,
552
IBUS_TYPE_TEXT, &text,
555
g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
556
if (g_object_is_floating (text))
557
g_object_unref (text);
561
if (g_strcmp0 (name, "UpdatePreeditText") == 0) {
567
retval = ibus_message_get_args (message,
569
IBUS_TYPE_TEXT, &text,
570
G_TYPE_UINT, &cursor_pos,
571
G_TYPE_BOOLEAN, &visible,
575
g_signal_emit (context,
576
context_signals[UPDATE_PREEDIT_TEXT],
581
if (g_object_is_floating (text))
582
g_object_unref (text);
588
i < G_N_ELEMENTS (signals) && g_strcmp0 (name, signals[i].member) != 0;
591
if (i < G_N_ELEMENTS (signals)) {
592
g_signal_emit (context, context_signals[signals[i].signal_id], 0);
596
if (g_strcmp0 (name, "UpdateAuxiliaryText") == 0) {
601
retval = ibus_message_get_args (message,
603
IBUS_TYPE_TEXT, &text,
604
G_TYPE_BOOLEAN, &visible,
608
g_signal_emit (context,
609
context_signals[UPDATE_AUXILIARY_TEXT],
613
if (g_object_is_floating (text))
614
g_object_unref (text);
617
else if (g_strcmp0 (name, "UpdateLookupTable") == 0) {
618
IBusLookupTable *table;
622
retval = ibus_message_get_args (message,
624
IBUS_TYPE_LOOKUP_TABLE, &table,
625
G_TYPE_BOOLEAN, &visible,
629
g_signal_emit (context,
630
context_signals[UPDATE_LOOKUP_TABLE],
634
if (g_object_is_floating (table))
635
g_object_unref (table);
638
else if (g_strcmp0 (name, "RegisterProperties") == 0) {
639
IBusPropList *prop_list;
642
retval = ibus_message_get_args (message,
644
IBUS_TYPE_PROP_LIST, &prop_list,
648
g_signal_emit (context,
649
context_signals[REGISTER_PROPERTIES],
652
if (g_object_is_floating (prop_list))
653
g_object_unref (prop_list);
656
else if (g_strcmp0 (name, "UpdateProperty") == 0) {
660
retval = ibus_message_get_args (message,
662
IBUS_TYPE_PROPERTY, &prop,
665
g_signal_emit (context, context_signals[UPDATE_PROPERTY], 0, prop);
666
if (g_object_is_floating (prop))
667
g_object_unref (prop);
670
else if (g_strcmp0 (name, "ForwardKeyEvent") == 0) {
677
retval = ibus_message_get_args (message,
679
G_TYPE_UINT, &keyval,
680
G_TYPE_UINT, &keycode,
685
/* Forward key event back with IBUS_FORWARD_MASK. And process_key_event will
686
* not process key event with IBUS_FORWARD_MASK again. */
687
g_signal_emit (context,
688
context_signals[FORWARD_KEY_EVENT],
692
state | IBUS_FORWARD_MASK);
695
else if (g_strcmp0 (name, "DeleteSurroundingText") == 0) {
696
gint offset_from_cursor;
699
retval = ibus_message_get_args (message,
701
G_TYPE_INT, &offset_from_cursor,
702
G_TYPE_UINT, &nchars,
707
g_signal_emit (context,
708
context_signals[DELETE_SURROUNDING_TEXT],
715
error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
716
"Signal %s.%s is not handled", interface, name);
722
g_signal_stop_emission_by_name (context, "ibus-signal");
726
/* some error happens */
727
g_warning ("%s: %s", error->name, error->message);
728
ibus_error_free (error);
733
IBusInputContext *context;
740
_process_key_event_reply_cb (IBusPendingCall *pending,
743
IBusMessage *reply_message;
745
gboolean retval = FALSE;
747
reply_message = dbus_pending_call_steal_reply (pending);
749
if (reply_message == NULL) {
753
else if ((error = ibus_error_new_from_message (reply_message)) != NULL) {
754
/* some error happens */
755
g_warning ("%s: %s", error->name, error->message);
756
ibus_error_free (error);
759
else if (!ibus_message_get_args (reply_message,
761
G_TYPE_BOOLEAN, &retval,
763
/* can not get return value */
764
g_warning ("%s: %s", error->name, error->message);
765
ibus_error_free (error);
512
if (g_strcmp0 (signal_name, "CommitText") == 0) {
513
GVariant *variant = NULL;
514
g_variant_get (parameters, "(v)", &variant);
515
IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
516
g_variant_unref (variant);
517
g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
519
if (g_object_is_floating (text))
520
g_object_unref (text);
523
if (g_strcmp0 (signal_name, "UpdatePreeditText") == 0) {
524
GVariant *variant = NULL;
527
g_variant_get (parameters, "(vub)", &variant, &cursor_pos, &visible);
528
IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
529
g_variant_unref (variant);
531
g_signal_emit (context,
532
context_signals[UPDATE_PREEDIT_TEXT],
538
if (g_object_is_floating (text))
539
g_object_unref (text);
543
/* lookup signal in table */
546
i < G_N_ELEMENTS (signals) && g_strcmp0 (signal_name, signals[i].signal_name) != 0;
549
if (i < G_N_ELEMENTS (signals)) {
550
g_signal_emit (context, context_signals[signals[i].signal_id], 0);
554
if (g_strcmp0 (signal_name, "UpdateAuxiliaryText") == 0) {
555
GVariant *variant = NULL;
557
g_variant_get (parameters, "(vb)", &variant, &visible);
558
IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
559
g_variant_unref (variant);
561
g_signal_emit (context,
562
context_signals[UPDATE_AUXILIARY_TEXT],
566
if (g_object_is_floating (text))
567
g_object_unref (text);
571
if (g_strcmp0 (signal_name, "UpdateLookupTable") == 0) {
572
GVariant *variant = NULL;
574
g_variant_get (parameters, "(vb)", &variant, &visible);
576
IBusLookupTable *table = IBUS_LOOKUP_TABLE (ibus_serializable_deserialize (variant));
577
g_variant_unref (variant);
579
g_signal_emit (context,
580
context_signals[UPDATE_LOOKUP_TABLE],
584
if (g_object_is_floating (table))
585
g_object_unref (table);
590
if (g_strcmp0 (signal_name, "RegisterProperties") == 0) {
591
GVariant *variant = NULL;
592
g_variant_get (parameters, "(v)", &variant);
594
IBusPropList *prop_list = IBUS_PROP_LIST (ibus_serializable_deserialize (variant));
595
g_variant_unref (variant);
597
g_signal_emit (context,
598
context_signals[REGISTER_PROPERTIES],
602
if (g_object_is_floating (prop_list))
603
g_object_unref (prop_list);
607
if (g_strcmp0 (signal_name, "UpdateProperty") == 0) {
608
GVariant *variant = NULL;
609
g_variant_get (parameters, "(v)", &variant);
610
IBusProperty *prop = IBUS_PROPERTY (ibus_serializable_deserialize (variant));
611
g_variant_unref (variant);
613
g_signal_emit (context, context_signals[UPDATE_PROPERTY], 0, prop);
615
if (g_object_is_floating (prop))
616
g_object_unref (prop);
620
if (g_strcmp0 (signal_name, "ForwardKeyEvent") == 0) {
625
g_variant_get (parameters, "(uuu)", &keyval, &keycode, &state);
770
627
/* Forward key event back with IBUS_FORWARD_MASK. And process_key_event will
771
628
* not process key event with IBUS_FORWARD_MASK again. */
772
g_signal_emit (call_data->context,
629
g_signal_emit (context,
773
630
context_signals[FORWARD_KEY_EVENT],
777
call_data->state | IBUS_FORWARD_MASK);
780
if (reply_message != NULL) {
781
dbus_message_unref (reply_message);
786
_call_data_free (CallData *call_data)
788
g_object_unref (call_data->context);
789
g_slice_free (CallData, call_data);
634
state | IBUS_FORWARD_MASK);
638
if (g_strcmp0 (signal_name, "DeleteSurroundingText") == 0) {
639
gint offset_from_cursor;
642
g_variant_get (parameters, "(iu)", &offset_from_cursor, &nchars);
644
g_signal_emit (context,
645
context_signals[DELETE_SURROUNDING_TEXT],
652
IBusInputContextPrivate *priv;
653
priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
655
if (g_strcmp0 (signal_name, "Enabled") == 0) {
656
priv->needs_surrounding_text = FALSE;
657
g_signal_emit (context, context_signals[ENABLED], 0);
661
if (g_strcmp0 (signal_name, "Disabled") == 0) {
662
priv->needs_surrounding_text = FALSE;
663
g_signal_emit (context, context_signals[DISABLED], 0);
667
if (g_strcmp0 (signal_name, "RequireSurroundingText") == 0) {
668
priv->needs_surrounding_text = TRUE;
672
G_DBUS_PROXY_CLASS (ibus_input_context_parent_class)->g_signal (
673
proxy, sender_name, signal_name, parameters);
677
ibus_input_context_new (const gchar *path,
678
GDBusConnection *connection,
679
GCancellable *cancellable,
682
g_assert (path != NULL);
683
g_assert (G_IS_DBUS_CONNECTION (connection));
687
GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
688
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
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 |
717
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
719
g_async_initable_new_async (IBUS_TYPE_INPUT_CONTEXT,
724
"g-connection", connection,
725
"g-name", IBUS_SERVICE_IBUS,
727
"g-interface-name", IBUS_INTERFACE_INPUT_CONTEXT,
728
"g-object-path", path,
729
"g-default-timeout", ibus_get_timeout (),
734
ibus_input_context_new_async_finish (GAsyncResult *res,
737
GObject *object = NULL;
738
GObject *source_object = NULL;
740
source_object = g_async_result_get_source_object (res);
741
g_assert (source_object != NULL);
743
object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
746
g_object_unref (source_object);
748
if (object != NULL) {
749
return IBUS_INPUT_CONTEXT (object);
757
ibus_input_context_get_input_context (const gchar *path,
758
GDBusConnection *connection)
760
IBusInputContext *context = NULL;
761
GError *error = NULL;
763
context = ibus_input_context_new (path, connection, NULL, &error);
764
if (context == NULL) {
765
g_warning ("ibus_input_context_get_input_context: %s", error->message);
766
g_error_free (error);
770
/* Do not call "org.freedesktop.IBus.Service.Destroy" when the input
771
* context object is disposed. */
772
IBUS_PROXY (context)->own = FALSE;
777
ibus_input_context_get_input_context_async (const gchar *path,
778
GDBusConnection *connection,
779
GCancellable *cancellable,
780
GAsyncReadyCallback callback,
783
ibus_input_context_new_async (path,
791
ibus_input_context_get_input_context_async_finish (GAsyncResult *res,
794
IBusInputContext *context = NULL;
796
context = ibus_input_context_new_async_finish (res, error);
797
if (context == NULL) {
801
/* Do not call "org.freedesktop.IBus.Service.Destroy" when the input
802
* context object is disposed. */
803
IBUS_PROXY (context)->own = FALSE;
808
ibus_input_context_process_key_event_async (IBusInputContext *context,
813
GCancellable *cancellable,
814
GAsyncReadyCallback callback,
817
g_assert (IBUS_IS_INPUT_CONTEXT (context));
819
g_dbus_proxy_call ((GDBusProxy *) context,
820
"ProcessKeyEvent", /* method_name */
821
g_variant_new ("(uuu)",
822
keyval, keycode, state), /* parameters */
823
G_DBUS_CALL_FLAGS_NONE, /* flags */
824
timeout_msec, /* timeout */
825
cancellable, /* cancellable */
826
callback, /* callback */
827
user_data /* user_data */
833
ibus_input_context_process_key_event_async_finish (IBusInputContext *context,
838
g_assert (IBUS_IS_INPUT_CONTEXT (context));
839
g_assert (G_IS_ASYNC_RESULT (res));
840
g_assert (processed != NULL);
841
g_assert (error == NULL || *error == NULL);
843
GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
845
if (variant == NULL) {
851
g_variant_get (variant, "(b)", processed);
852
g_variant_unref (variant);
907
957
const gchar *prop_name)
909
959
g_assert (IBUS_IS_INPUT_CONTEXT (context));
911
ibus_proxy_call ((IBusProxy *) context,
913
G_TYPE_STRING, &prop_name,
960
g_dbus_proxy_call ((GDBusProxy *) context,
961
"PropertyHide", /* method_name */
962
g_variant_new ("(s)", prop_name), /* parameters */
963
G_DBUS_CALL_FLAGS_NONE, /* flags */
965
NULL, /* cancellable */
972
ibus_input_context_is_enabled_async (IBusInputContext *context,
974
GCancellable *cancellable,
975
GAsyncReadyCallback callback,
978
g_assert (IBUS_IS_INPUT_CONTEXT (context));
979
g_dbus_proxy_call ((GDBusProxy *) context,
980
"IsEnabled", /* method_name */
981
NULL, /* parameters */
982
G_DBUS_CALL_FLAGS_NONE, /* flags */
990
ibus_input_context_is_enabled_async_finish (IBusInputContext *context,
995
g_assert (IBUS_IS_INPUT_CONTEXT (context));
996
g_assert (G_IS_ASYNC_RESULT (res));
997
g_assert (retval != NULL);
998
g_assert (error == NULL || *error == NULL);
1000
GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
1002
if (variant == NULL) {
1005
g_variant_get (variant, "(b)", retval);
1006
g_variant_unref (variant);
1011
ibus_input_context_set_surrounding_text (IBusInputContext *context,
1015
g_assert (IBUS_IS_INPUT_CONTEXT (context));
1016
g_assert (IBUS_IS_TEXT (text));
1018
IBusInputContextPrivate *priv;
1019
priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
1021
if (priv->surrounding_text == NULL ||
1022
g_strcmp0 (text->text, priv->surrounding_text->text) != 0 ||
1023
cursor_pos != priv->surrounding_cursor_pos) {
1024
GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
1025
if (priv->surrounding_text)
1026
g_object_unref (priv->surrounding_text);
1027
priv->surrounding_text = (IBusText *) g_object_ref_sink (text);
1028
priv->surrounding_cursor_pos = cursor_pos;
1030
g_dbus_proxy_call ((GDBusProxy *) context,
1031
"SetSurroundingText", /* method_name */
1032
g_variant_new ("(vu)", variant, cursor_pos), /* parameters */
1033
G_DBUS_CALL_FLAGS_NONE, /* flags */
1035
NULL, /* cancellable */
1036
NULL, /* callback */
1037
NULL /* user_data */
1043
ibus_input_context_needs_surrounding_text (IBusInputContext *context)
1045
IBusInputContextPrivate *priv;
1046
priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
1047
return priv->needs_surrounding_text;
918
1051
ibus_input_context_is_enabled (IBusInputContext *context)
920
1053
g_assert (IBUS_IS_INPUT_CONTEXT (context));
1055
GError *error = NULL;
1056
result = g_dbus_proxy_call_sync ((GDBusProxy *) context,
1057
"IsEnabled", /* method_name */
1058
NULL, /* parameters */
1059
G_DBUS_CALL_FLAGS_NONE, /* flags */
1061
NULL, /* cancellable */
1065
if (result == NULL) {
1066
g_warning ("%s.IsEnabled: %s", IBUS_INTERFACE_INPUT_CONTEXT, error->message);
1067
g_error_free (error);
921
1071
gboolean retval = FALSE;
923
IBusMessage *reply_message;
924
IBusError *error = NULL;
926
reply_message = ibus_proxy_call_with_reply_and_block ((IBusProxy *) context,
931
if (!reply_message) {
932
g_debug ("%s: %s", error->name, error->message);
933
ibus_error_free (error);
937
if (!ibus_message_get_args (reply_message,
939
G_TYPE_BOOLEAN, &retval,
941
g_debug ("%s: %s", error->name, error->message);
942
ibus_error_free (error);
945
ibus_message_unref (reply_message);
1072
g_variant_get (result, "(b)", &retval);
1073
g_variant_unref (result);
1079
ibus_input_context_get_engine_async (IBusInputContext *context,
1081
GCancellable *cancellable,
1082
GAsyncReadyCallback callback,
1085
g_assert (IBUS_IS_INPUT_CONTEXT (context));
1086
g_dbus_proxy_call ((GDBusProxy *) context,
1087
"GetEngine", /* method_name */
1088
NULL, /* parameters */
1089
G_DBUS_CALL_FLAGS_NONE, /* flags */
1097
ibus_input_context_get_engine_async_finish (IBusInputContext *context,
1101
g_assert (IBUS_IS_INPUT_CONTEXT (context));
1102
g_assert (G_IS_ASYNC_RESULT (res));
1103
g_assert (error == NULL || *error == NULL);
1105
GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context,
1107
if (variant == NULL) {
1111
GVariant *engine_desc_variant = g_variant_get_child_value (variant, 0);
1112
IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
1113
g_variant_unref (engine_desc_variant);
1114
g_variant_unref (variant);
950
1119
IBusEngineDesc *
951
1120
ibus_input_context_get_engine (IBusInputContext *context)
953
1122
g_assert (IBUS_IS_INPUT_CONTEXT (context));
954
IBusMessage *reply_message;
955
IBusError *error = NULL;
956
IBusSerializable *object = NULL;
958
reply_message = ibus_proxy_call_with_reply_and_block ((IBusProxy *) context,
963
if (!reply_message) {
964
g_debug ("%s: %s", error->name, error->message);
965
ibus_error_free (error);
969
if (!ibus_message_get_args (reply_message,
971
IBUS_TYPE_ENGINE_DESC, &object,
973
g_debug ("%s: %s", error->name, error->message);
974
ibus_error_free (error);
975
ibus_message_unref (reply_message);
978
ibus_message_unref (reply_message);
980
return IBUS_ENGINE_DESC (object);
1124
GError *error = NULL;
1125
result = g_dbus_proxy_call_sync ((GDBusProxy *) context,
1126
"GetEngine", /* method_name */
1127
NULL, /* parameters */
1128
G_DBUS_CALL_FLAGS_NONE, /* flags */
1130
NULL, /* cancellable */
1134
if (result == NULL) {
1135
g_warning ("%s.GetEngine: %s", IBUS_INTERFACE_INPUT_CONTEXT, error->message);
1136
g_error_free (error);
1140
GVariant *engine_desc_variant = g_variant_get_child_value (result, 0);
1141
IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant));
1142
g_variant_unref (engine_desc_variant);
1143
g_variant_unref (result);