1 /* vim:set et sts=4: */
2 /* ibus - The Input Bus
3 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
4 * Copyright (C) 2008-2010 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #include "ibusengine.h"
24 #include "ibusinternal.h"
25 #include "ibusshare.h"
27 #define IBUS_ENGINE_GET_PRIVATE(o) \
28 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_ENGINE, IBusEnginePrivate))
58 struct _IBusEnginePrivate {
60 IBusConnection *connection;
62 typedef struct _IBusEnginePrivate IBusEnginePrivate;
64 static guint engine_signals[LAST_SIGNAL] = { 0 };
66 /* functions prototype */
67 static void ibus_engine_destroy (IBusEngine *engine);
68 static void ibus_engine_set_property (IBusEngine *engine,
72 static void ibus_engine_get_property (IBusEngine *engine,
76 static gboolean ibus_engine_ibus_message (IBusEngine *engine,
77 IBusConnection *connection,
78 IBusMessage *message);
79 static gboolean ibus_engine_process_key_event
84 static void ibus_engine_focus_in (IBusEngine *engine);
85 static void ibus_engine_focus_out (IBusEngine *engine);
86 static void ibus_engine_reset (IBusEngine *engine);
87 static void ibus_engine_enable (IBusEngine *engine);
88 static void ibus_engine_disable (IBusEngine *engine);
89 static void ibus_engine_set_cursor_location
95 static void ibus_engine_set_capabilities
98 static void ibus_engine_page_up (IBusEngine *engine);
99 static void ibus_engine_page_down (IBusEngine *engine);
100 static void ibus_engine_cursor_up (IBusEngine *engine);
101 static void ibus_engine_cursor_down (IBusEngine *engine);
102 static void ibus_engine_candidate_clicked
107 static void ibus_engine_property_activate
109 const gchar *prop_name,
111 static void ibus_engine_property_show (IBusEngine *engine,
112 const gchar *prop_name);
113 static void ibus_engine_property_hide (IBusEngine *engine,
114 const gchar *prop_name);
117 G_DEFINE_TYPE (IBusEngine, ibus_engine, IBUS_TYPE_SERVICE)
120 ibus_engine_new (const gchar *name,
122 IBusConnection *connection)
125 g_assert (IBUS_IS_CONNECTION (connection));
129 engine = (IBusEngine *) g_object_new (IBUS_TYPE_ENGINE,
132 "connection", connection,
139 ibus_engine_class_init (IBusEngineClass *klass)
141 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
142 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
144 g_type_class_add_private (klass, sizeof (IBusEnginePrivate));
146 gobject_class->set_property = (GObjectSetPropertyFunc) ibus_engine_set_property;
147 gobject_class->get_property = (GObjectGetPropertyFunc) ibus_engine_get_property;
149 ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_engine_destroy;
151 IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_engine_ibus_message;
153 klass->process_key_event = ibus_engine_process_key_event;
154 klass->focus_in = ibus_engine_focus_in;
155 klass->focus_out = ibus_engine_focus_out;
156 klass->reset = ibus_engine_reset;
157 klass->enable = ibus_engine_enable;
158 klass->disable = ibus_engine_disable;
159 klass->page_up = ibus_engine_page_up;
160 klass->page_down = ibus_engine_page_down;
161 klass->cursor_up = ibus_engine_cursor_up;
162 klass->cursor_down = ibus_engine_cursor_down;
163 klass->candidate_clicked = ibus_engine_candidate_clicked;
164 klass->property_activate = ibus_engine_property_activate;
165 klass->property_show = ibus_engine_property_show;
166 klass->property_hide = ibus_engine_property_hide;
167 klass->set_cursor_location = ibus_engine_set_cursor_location;
168 klass->set_capabilities = ibus_engine_set_capabilities;
171 /* install properties */
175 * Name of this IBusEngine.
177 g_object_class_install_property (gobject_class,
179 g_param_spec_string ("name",
183 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
186 * IBusEngine:connection:
188 * Connection of this IBusEngine.
190 g_object_class_install_property (gobject_class,
192 g_param_spec_object ("connection",
194 "The connection of engine object",
195 IBUS_TYPE_CONNECTION,
196 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
198 /* install signals */
200 * IBusEngine::process-key-event:
201 * @engine: An IBusEngine.
202 * @keyval: Key symbol of the key press.
203 * @keycode: KeyCode of the key press.
204 * @state: Key modifier flags.
206 * Emitted when a key event is received.
207 * Implement the member function process_key_event() in extended class to receive this signal.
208 * Both the key symbol and keycode are passed to the member function.
209 * See ibus_input_context_process_key_event() for further explanation of
210 * key symbol, keycode and which to use.
212 * Returns: TRUE for successfully process the key; FALSE otherwise.
213 * See also: ibus_input_context_process_key_event().
215 * <note><para>Argument @user_data is ignored in this function.</para></note>
217 engine_signals[PROCESS_KEY_EVENT] =
218 g_signal_new (I_("process-key-event"),
219 G_TYPE_FROM_CLASS (gobject_class),
221 G_STRUCT_OFFSET (IBusEngineClass, process_key_event),
223 ibus_marshal_BOOL__UINT_UINT_UINT,
231 * IBusEngine::focus-in:
232 * @engine: An IBusEngine.
234 * Emitted when the client application get the focus.
235 * Implement the member function focus_in() in extended class to receive this signal.
237 * See also: ibus_input_context_focus_in()
238 * <note><para>Argument @user_data is ignored in this function.</para></note>
240 engine_signals[FOCUS_IN] =
241 g_signal_new (I_("focus-in"),
242 G_TYPE_FROM_CLASS (gobject_class),
244 G_STRUCT_OFFSET (IBusEngineClass, focus_in),
246 ibus_marshal_VOID__VOID,
251 * IBusEngine::focus-out:
252 * @engine: An IBusEngine.
254 * Emitted when the client application lost the focus.
255 * Implement the member function focus_out() in extended class to receive this signal.
257 * See also: ibus_input_context_focus_out()
258 * <note><para>Argument @user_data is ignored in this function.</para></note>
260 engine_signals[FOCUS_OUT] =
261 g_signal_new (I_("focus-out"),
262 G_TYPE_FROM_CLASS (gobject_class),
264 G_STRUCT_OFFSET (IBusEngineClass, focus_out),
266 ibus_marshal_VOID__VOID,
272 * @engine: An IBusEngine.
274 * Emitted when the IME is reset.
275 * Implement the member function reset() in extended class to receive this signal.
277 * See also: ibus_input_context_reset().
278 * <note><para>Argument @user_data is ignored in this function.</para></note>
280 engine_signals[RESET] =
281 g_signal_new (I_("reset"),
282 G_TYPE_FROM_CLASS (gobject_class),
284 G_STRUCT_OFFSET (IBusEngineClass, reset),
286 ibus_marshal_VOID__VOID,
291 * IBusEngine::enable:
292 * @engine: An IBusEngine.
294 * Emitted when the IME is enabled.
295 * Implement the member function set_enable() in extended class to receive this signal.
297 * See also: ibus_input_context_enable().
298 * <note><para>Argument @user_data is ignored in this function.</para></note>
300 engine_signals[ENABLE] =
301 g_signal_new (I_("enable"),
302 G_TYPE_FROM_CLASS (gobject_class),
304 G_STRUCT_OFFSET (IBusEngineClass, enable),
306 ibus_marshal_VOID__VOID,
311 * IBusEngine::disable:
312 * @engine: An IBusEngine.
314 * Emitted when the IME is disabled.
315 * Implement the member function set_disable() in extended class to receive this signal.
317 * See also: ibus_input_context_disable().
318 * <note><para>Argument @user_data is ignored in this function.</para></note>
320 engine_signals[DISABLE] =
321 g_signal_new (I_("disable"),
322 G_TYPE_FROM_CLASS (gobject_class),
324 G_STRUCT_OFFSET (IBusEngineClass, disable),
326 ibus_marshal_VOID__VOID,
331 * IBusEngine::set-cursor-location:
332 * @engine: An IBusEngine.
333 * @x: X coordinate of the cursor.
334 * @y: Y coordinate of the cursor.
335 * @w: Width of the cursor.
336 * @h: Height of the cursor.
338 * Emitted when the location of IME is set.
339 * Implement the member function set_cursor_location() in extended class to receive this signal.
341 * See also: ibus_input_context_set_cursor_location().
342 * <note><para>Argument @user_data is ignored in this function.</para></note>
344 engine_signals[SET_CURSOR_LOCATION] =
345 g_signal_new (I_("set-cursor-location"),
346 G_TYPE_FROM_CLASS (gobject_class),
348 G_STRUCT_OFFSET (IBusEngineClass, set_cursor_location),
350 ibus_marshal_VOID__INT_INT_INT_INT,
359 * IBusEngine::set-capabilities:
360 * @engine: An IBusEngine.
361 * @caps: Capabilities flags of IBusEngine, see #IBusCapabilite
363 * Emitted when the client application capabilities is set.
364 * Implement the member function set_capabilities() in extended class to receive this signal.
366 * See also: ibus_input_context_set_capabilities().
367 * <note><para>Argument @user_data is ignored in this function.</para></note>
369 engine_signals[SET_CAPABILITIES] =
370 g_signal_new (I_("set-capabilities"),
371 G_TYPE_FROM_CLASS (gobject_class),
373 G_STRUCT_OFFSET (IBusEngineClass, set_capabilities),
375 ibus_marshal_VOID__UINT,
381 * IBusEngine::page-up:
382 * @engine: An IBusEngine.
384 * Emitted when the page-up button is pressed.
385 * Implement the member function page_up() in extended class to receive this signal.
387 * <note><para>Argument @user_data is ignored in this function.</para></note>
389 engine_signals[PAGE_UP] =
390 g_signal_new (I_("page-up"),
391 G_TYPE_FROM_CLASS (gobject_class),
393 G_STRUCT_OFFSET (IBusEngineClass, page_up),
395 ibus_marshal_VOID__VOID,
400 * IBusEngine::page-down:
401 * @engine: An IBusEngine.
403 * Emitted when the page-down button is pressed.
404 * Implement the member function page_down() in extended class to receive this signal.
406 * <note><para>Argument @user_data is ignored in this function.</para></note>
408 engine_signals[PAGE_DOWN] =
409 g_signal_new (I_("page-down"),
410 G_TYPE_FROM_CLASS (gobject_class),
412 G_STRUCT_OFFSET (IBusEngineClass, page_down),
414 ibus_marshal_VOID__VOID,
419 * IBusEngine::cursor-up:
420 * @engine: An IBusEngine.
422 * Emitted when the up cursor button is pressed.
423 * Implement the member function cursor_up() in extended class to receive this signal.
425 * <note><para>Argument @user_data is ignored in this function.</para></note>
427 engine_signals[CURSOR_UP] =
428 g_signal_new (I_("cursor-up"),
429 G_TYPE_FROM_CLASS (gobject_class),
431 G_STRUCT_OFFSET (IBusEngineClass, cursor_up),
433 ibus_marshal_VOID__VOID,
438 * IBusEngine::cursor-down:
439 * @engine: An IBusEngine.
441 * Emitted when the down cursor button is pressed.
442 * Implement the member function cursor_down() in extended class to receive this signal.
444 * <note><para>Argument @user_data is ignored in this function.</para></note>
446 engine_signals[CURSOR_DOWN] =
447 g_signal_new (I_("cursor-down"),
448 G_TYPE_FROM_CLASS (gobject_class),
450 G_STRUCT_OFFSET (IBusEngineClass, cursor_down),
452 ibus_marshal_VOID__VOID,
457 * IBusEngine::candidate-clicked:
458 * @engine: An IBusEngine.
460 * Emitted when candidate on lookup table is clicked.
461 * Implement the member function candidate_clicked() in extended class to receive this signal.
463 * <note><para>Argument @user_data is ignored in this function.</para></note>
465 engine_signals[CANDIDATE_CLICKED] =
466 g_signal_new (I_("candidate-clicked"),
467 G_TYPE_FROM_CLASS (gobject_class),
469 G_STRUCT_OFFSET (IBusEngineClass, candidate_clicked),
471 ibus_marshal_VOID__UINT_UINT_UINT,
479 * IBusEngine::property-activate:
480 * @engine: An IBusEngine.
482 * Emitted when a property is activated or change changed.
483 * Implement the member function property_activate() in extended class to receive this signal.
485 * <note><para>Argument @user_data is ignored in this function.</para></note>
487 engine_signals[PROPERTY_ACTIVATE] =
488 g_signal_new (I_("property-activate"),
489 G_TYPE_FROM_CLASS (gobject_class),
491 G_STRUCT_OFFSET (IBusEngineClass, property_activate),
493 ibus_marshal_VOID__STRING_UINT,
500 * IBusEngine::property-show:
501 * @engine: An IBusEngine.
503 * Emitted when a property is shown.
504 * Implement the member function property_side() in extended class to receive this signal.
506 * <note><para>Argument @user_data is ignored in this function.</para></note>
508 engine_signals[PROPERTY_SHOW] =
509 g_signal_new (I_("property-show"),
510 G_TYPE_FROM_CLASS (gobject_class),
512 G_STRUCT_OFFSET (IBusEngineClass, property_show),
514 ibus_marshal_VOID__STRING,
520 * IBusEngine::property-hide:
521 * @engine: An IBusEngine.
523 * Emitted when a property is hidden.
524 * Implement the member function property_hide() in extended class to receive this signal.
526 * <note><para>Argument @user_data is ignored in this function.</para></note>
528 engine_signals[PROPERTY_HIDE] =
529 g_signal_new (I_("property-hide"),
530 G_TYPE_FROM_CLASS (gobject_class),
532 G_STRUCT_OFFSET (IBusEngineClass, property_hide),
534 ibus_marshal_VOID__STRING,
542 ibus_engine_init (IBusEngine *engine)
544 IBusEnginePrivate *priv;
545 priv = IBUS_ENGINE_GET_PRIVATE (engine);
548 priv->connection = NULL;
552 ibus_engine_destroy (IBusEngine *engine)
554 IBusEnginePrivate *priv;
555 priv = IBUS_ENGINE_GET_PRIVATE (engine);
559 if (priv->connection) {
560 g_object_unref (priv->connection);
561 priv->connection = NULL;
564 IBUS_OBJECT_CLASS(ibus_engine_parent_class)->destroy (IBUS_OBJECT (engine));
568 ibus_engine_set_property (IBusEngine *engine,
573 IBusEnginePrivate *priv;
574 priv = IBUS_ENGINE_GET_PRIVATE (engine);
578 priv->name = g_strdup (g_value_dup_string (value));
581 case PROP_CONNECTION:
582 priv->connection = g_value_get_object (value);
583 g_object_ref_sink (priv->connection);
584 ibus_service_add_to_connection ((IBusService *) engine,
589 G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec);
594 ibus_engine_get_property (IBusEngine *engine,
595 guint prop_id, GValue *value, GParamSpec *pspec)
597 IBusEnginePrivate *priv;
598 priv = IBUS_ENGINE_GET_PRIVATE (engine);
602 g_value_set_string (value, priv->name);
605 case PROP_CONNECTION:
606 g_value_set_object (value, priv->connection);
610 G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec);
615 ibus_engine_ibus_message (IBusEngine *engine,
616 IBusConnection *connection,
617 IBusMessage *message)
619 g_assert (IBUS_IS_ENGINE (engine));
620 g_assert (IBUS_IS_CONNECTION (connection));
621 g_assert (message != NULL);
622 g_assert (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL);
624 IBusEnginePrivate *priv;
625 priv = IBUS_ENGINE_GET_PRIVATE (engine);
627 g_assert (priv->connection == connection);
629 IBusMessage *reply = NULL;
630 IBusError *error = NULL;
634 const gchar *interface;
637 static const struct {
640 } no_arg_methods[] = {
641 { "FocusIn", FOCUS_IN },
642 { "FocusOut", FOCUS_OUT },
644 { "Enable", ENABLE },
645 { "Disable", DISABLE },
646 { "PageUp", PAGE_UP },
647 { "PageDown", PAGE_DOWN },
648 { "CursorUp", CURSOR_UP },
649 { "CursorDown", CURSOR_DOWN },
652 interface = ibus_message_get_interface (message);
653 name = ibus_message_get_member (message);
655 if (interface != NULL && g_strcmp0 (interface, IBUS_INTERFACE_ENGINE) != 0)
656 return IBUS_SERVICE_CLASS (ibus_engine_parent_class)->ibus_message (
657 (IBusService *) engine, connection, message);
660 if (g_strcmp0 (name, "ProcessKeyEvent") == 0) {
661 guint keyval, keycode, state;
663 retval = ibus_message_get_args (message,
665 G_TYPE_UINT, &keyval,
666 G_TYPE_UINT, &keycode,
671 reply = ibus_message_new_error_printf (message,
672 DBUS_ERROR_INVALID_ARGS,
673 "%s.%s: Can not match signature (uuu) of method",
674 IBUS_INTERFACE_ENGINE, "ProcessKeyEvent");
675 ibus_error_free (error);
679 g_signal_emit (engine,
680 engine_signals[PROCESS_KEY_EVENT],
687 reply = ibus_message_new_method_return (message);
688 ibus_message_append_args (reply,
689 G_TYPE_BOOLEAN, &retval,
696 i < G_N_ELEMENTS (no_arg_methods) && g_strcmp0 (name, no_arg_methods[i].member) != 0;
699 if (i < G_N_ELEMENTS (no_arg_methods)) {
700 IBusMessageIter iter;
701 ibus_message_iter_init (message, &iter);
702 if (ibus_message_iter_has_next (&iter)) {
703 reply = ibus_message_new_error_printf (message,
704 DBUS_ERROR_INVALID_ARGS,
705 "%s.%s: Method does not have arguments",
706 IBUS_INTERFACE_ENGINE, no_arg_methods[i].member);
709 g_signal_emit (engine, engine_signals[no_arg_methods[i].signal_id], 0);
710 reply = ibus_message_new_method_return (message);
715 if (g_strcmp0 (name, "CandidateClicked") == 0) {
716 guint index, button, state;
718 retval = ibus_message_get_args (message,
721 G_TYPE_UINT, &button,
726 reply = ibus_message_new_error_printf (message,
727 DBUS_ERROR_INVALID_ARGS,
728 "%s.%s: Can not match signature (uuu) of method",
729 IBUS_INTERFACE_ENGINE, "CandidateClicked");
730 ibus_error_free (error);
733 g_signal_emit (engine,
734 engine_signals[CANDIDATE_CLICKED],
739 reply = ibus_message_new_method_return (message);
742 else if (g_strcmp0 (name, "PropertyActivate") == 0) {
746 retval = ibus_message_get_args (message,
748 G_TYPE_STRING, &name,
753 reply = ibus_message_new_error_printf (message,
754 DBUS_ERROR_INVALID_ARGS,
755 "%s.%s: Can not match signature (si) of method",
756 IBUS_INTERFACE_ENGINE,
758 ibus_error_free (error);
761 g_signal_emit (engine,
762 engine_signals[PROPERTY_ACTIVATE],
767 reply = ibus_message_new_method_return (message);
770 else if (g_strcmp0 (name, "PropertyShow") == 0) {
773 retval = ibus_message_get_args (message,
775 G_TYPE_STRING, &name,
779 reply = ibus_message_new_error_printf (message,
780 DBUS_ERROR_INVALID_ARGS,
781 "%s.%s: Can not match signature (s) of method",
782 IBUS_INTERFACE_ENGINE,
784 ibus_error_free (error);
787 g_signal_emit (engine,
788 engine_signals[PROPERTY_SHOW],
792 reply = ibus_message_new_method_return (message);
795 else if (g_strcmp0 (name, "PropertyHide") == 0) {
798 retval = ibus_message_get_args (message,
800 G_TYPE_STRING, &name,
803 reply = ibus_message_new_error_printf (message,
804 DBUS_ERROR_INVALID_ARGS,
805 "%s.%s: Can not match signature (s) of method",
806 IBUS_INTERFACE_ENGINE, "PropertyHide");
807 ibus_error_free (error);
810 g_signal_emit (engine, engine_signals[PROPERTY_HIDE], 0, name);
811 reply = ibus_message_new_method_return (message);
814 else if (g_strcmp0 (name, "SetCursorLocation") == 0) {
817 retval = ibus_message_get_args (message,
825 reply = ibus_message_new_error_printf (message,
826 DBUS_ERROR_INVALID_ARGS,
827 "%s.%s: Can not match signature (iiii) of method",
828 IBUS_INTERFACE_ENGINE,
829 "SetCursorLocation");
830 ibus_error_free (error);
833 engine->cursor_area.x = x;
834 engine->cursor_area.y = y;
835 engine->cursor_area.width = w;
836 engine->cursor_area.height = h;
838 g_signal_emit (engine,
839 engine_signals[SET_CURSOR_LOCATION],
843 reply = ibus_message_new_method_return (message);
846 else if (g_strcmp0 (name, "SetCapabilities") == 0) {
849 retval = ibus_message_get_args (message,
855 reply = ibus_message_new_error_printf (message,
856 DBUS_ERROR_INVALID_ARGS,
857 "%s.%s: Can not match signature (u) of method",
858 IBUS_INTERFACE_ENGINE, "SetCapabilities");
859 ibus_error_free (error);
862 engine->client_capabilities = caps;
863 g_signal_emit (engine, engine_signals[SET_CAPABILITIES], 0, caps);
864 reply = ibus_message_new_method_return (message);
867 else if (g_strcmp0 (name, "Destroy") == 0) {
868 reply = ibus_message_new_method_return (message);
869 ibus_connection_send (connection, reply);
870 ibus_message_unref (reply);
871 ibus_object_destroy ((IBusObject *) engine);
875 reply = ibus_message_new_error_printf (message,
876 DBUS_ERROR_UNKNOWN_METHOD,
878 IBUS_INTERFACE_ENGINE, name);
879 g_warn_if_reached ();
883 ibus_connection_send (connection, reply);
884 ibus_message_unref (reply);
889 ibus_engine_process_key_event (IBusEngine *engine,
898 ibus_engine_focus_in (IBusEngine *engine)
900 // g_debug ("focus-in");
904 ibus_engine_focus_out (IBusEngine *engine)
906 // g_debug ("focus-out");
910 ibus_engine_reset (IBusEngine *engine)
912 // g_debug ("reset");
916 ibus_engine_enable (IBusEngine *engine)
918 // g_debug ("enable");
922 ibus_engine_disable (IBusEngine *engine)
924 // g_debug ("disable");
928 ibus_engine_set_cursor_location (IBusEngine *engine,
934 // g_debug ("set-cursor-location (%d, %d, %d, %d)", x, y, w, h);
938 ibus_engine_set_capabilities (IBusEngine *engine,
941 // g_debug ("set-capabilities (0x%04x)", caps);
945 ibus_engine_page_up (IBusEngine *engine)
947 // g_debug ("page-up");
951 ibus_engine_page_down (IBusEngine *engine)
953 // g_debug ("page-down");
957 ibus_engine_cursor_up (IBusEngine *engine)
959 // g_debug ("cursor-up");
963 ibus_engine_cursor_down (IBusEngine *engine)
965 // g_debug ("cursor-down");
969 ibus_engine_candidate_clicked (IBusEngine *engine,
974 // g_debug ("candidate-clicked");
978 ibus_engine_property_activate (IBusEngine *engine,
979 const gchar *prop_name,
982 // g_debug ("property-activate ('%s', %d)", prop_name, prop_state);
986 ibus_engine_property_show (IBusEngine *engine, const gchar *prop_name)
988 // g_debug ("property-show ('%s')", prop_name);
992 ibus_engine_property_hide (IBusEngine *engine, const gchar *prop_name)
994 // g_debug ("property-hide ('%s')", prop_name);
998 _send_signal (IBusEngine *engine,
1000 GType first_arg_type,
1003 g_assert (IBUS_IS_ENGINE (engine));
1004 g_assert (name != NULL);
1008 IBusEnginePrivate *priv;
1010 priv = IBUS_ENGINE_GET_PRIVATE (engine);
1012 path = ibus_service_get_path ((IBusService *)engine);
1014 va_start (args, first_arg_type);
1015 ibus_connection_send_signal_valist (priv->connection,
1017 IBUS_INTERFACE_ENGINE,
1025 ibus_engine_commit_text (IBusEngine *engine,
1028 _send_signal (engine,
1030 IBUS_TYPE_TEXT, &text,
1033 if (g_object_is_floating (text)) {
1034 g_object_unref (text);
1039 ibus_engine_update_preedit_text (IBusEngine *engine,
1044 ibus_engine_update_preedit_text_with_mode (engine,
1045 text, cursor_pos, visible, IBUS_ENGINE_PREEDIT_CLEAR);
1049 ibus_engine_update_preedit_text_with_mode (IBusEngine *engine,
1053 IBusPreeditFocusMode mode)
1055 _send_signal (engine,
1056 "UpdatePreeditText",
1057 IBUS_TYPE_TEXT, &text,
1058 G_TYPE_UINT, &cursor_pos,
1059 G_TYPE_BOOLEAN, &visible,
1063 if (g_object_is_floating (text)) {
1064 g_object_unref (text);
1069 ibus_engine_show_preedit_text (IBusEngine *engine)
1071 _send_signal (engine,
1076 void ibus_engine_hide_preedit_text (IBusEngine *engine)
1078 _send_signal (engine,
1083 void ibus_engine_update_auxiliary_text (IBusEngine *engine,
1087 _send_signal (engine,
1088 "UpdateAuxiliaryText",
1089 IBUS_TYPE_TEXT, &text,
1090 G_TYPE_BOOLEAN, &visible,
1093 if (g_object_is_floating (text)) {
1094 g_object_unref (text);
1099 ibus_engine_show_auxiliary_text (IBusEngine *engine)
1101 _send_signal (engine,
1102 "ShowAuxiliaryText",
1107 ibus_engine_hide_auxiliary_text (IBusEngine *engine)
1109 _send_signal (engine,
1110 "HideAuxiliaryText",
1115 ibus_engine_update_lookup_table (IBusEngine *engine,
1116 IBusLookupTable *table,
1119 _send_signal (engine,
1120 "UpdateLookupTable",
1121 IBUS_TYPE_LOOKUP_TABLE, &table,
1122 G_TYPE_BOOLEAN, &visible,
1125 if (g_object_is_floating (table)) {
1126 g_object_unref (table);
1131 ibus_engine_update_lookup_table_fast (IBusEngine *engine,
1132 IBusLookupTable *table,
1135 IBusLookupTable *new_table;
1139 if (table->candidates->len < table->page_size << 2) {
1140 ibus_engine_update_lookup_table (engine, table, visible);
1144 page_begin = (table->cursor_pos / table->page_size) * table->page_size;
1146 new_table = ibus_lookup_table_new (table->page_size, 0, table->cursor_visible, table->round);
1148 for (i = page_begin; i < page_begin + table->page_size && i < table->candidates->len; i++) {
1149 ibus_lookup_table_append_candidate (new_table, ibus_lookup_table_get_candidate (table, i));
1152 ibus_lookup_table_set_cursor_pos (new_table, ibus_lookup_table_get_cursor_in_page (table));
1153 ibus_lookup_table_set_orientation (new_table, ibus_lookup_table_get_orientation (table));
1155 ibus_engine_update_lookup_table (engine, new_table, visible);
1157 if (g_object_is_floating (table)) {
1158 g_object_unref (table);
1162 void ibus_engine_show_lookup_table (IBusEngine *engine)
1164 _send_signal (engine,
1169 void ibus_engine_hide_lookup_table (IBusEngine *engine)
1171 _send_signal (engine,
1176 void ibus_engine_forward_key_event (IBusEngine *engine,
1181 _send_signal (engine,
1183 G_TYPE_UINT, &keyval,
1184 G_TYPE_UINT, &keycode,
1185 G_TYPE_UINT, &state,
1189 void ibus_engine_delete_surrounding_text (IBusEngine *engine,
1190 gint offset_from_cursor,
1193 _send_signal (engine,
1194 "DeleteSurroundingText",
1195 G_TYPE_INT, &offset_from_cursor,
1196 G_TYPE_UINT, &nchars,
1201 ibus_engine_register_properties (IBusEngine *engine,
1202 IBusPropList *prop_list)
1204 _send_signal (engine,
1205 "RegisterProperties",
1206 IBUS_TYPE_PROP_LIST, &prop_list,
1209 if (g_object_is_floating (prop_list)) {
1210 g_object_unref (prop_list);
1215 ibus_engine_update_property (IBusEngine *engine,
1218 _send_signal (engine,
1220 IBUS_TYPE_PROPERTY, &prop,
1223 if (g_object_is_floating (prop)) {
1224 g_object_unref (prop);
1229 ibus_engine_get_name (IBusEngine *engine)
1231 g_assert (IBUS_IS_ENGINE (engine));
1233 IBusEnginePrivate *priv;
1234 priv = IBUS_ENGINE_GET_PRIVATE (engine);