Fix make rpm errors due to ibus-dconf and pygobject override
[platform/upstream/ibus.git] / src / ibuspanelservice.c
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) 2009, Google Inc. All rights reserved.
5  * Copyright (C) 2010 Peng Huang <shawn.p.huang@gmail.com>
6  *
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.
11  *
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.
16  *
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.
21  */
22 #include "ibusshare.h"
23 #include "ibuspanelservice.h"
24 #include "ibusmarshalers.h"
25 #include "ibusinternal.h"
26
27 enum {
28     UPDATE_PREEDIT_TEXT,
29     UPDATE_AUXILIARY_TEXT,
30     UPDATE_LOOKUP_TABLE,
31     FOCUS_IN,
32     FOCUS_OUT,
33     REGISTER_PROPERTIES,
34     UPDATE_PROPERTY,
35     SET_CURSOR_LOCATION,
36     CURSOR_UP_LOOKUP_TABLE,
37     CURSOR_DOWN_LOOKUP_TABLE,
38     HIDE_AUXILIARY_TEXT,
39     HIDE_LANGUAGE_BAR,
40     HIDE_LOOKUP_TABLE,
41     HIDE_PREEDIT_TEXT,
42     PAGE_UP_LOOKUP_TABLE,
43     PAGE_DOWN_LOOKUP_TABLE,
44     RESET,
45     SHOW_AUXILIARY_TEXT,
46     SHOW_LANGUAGE_BAR,
47     SHOW_LOOKUP_TABLE,
48     SHOW_PREEDIT_TEXT,
49     START_SETUP,
50     STATE_CHANGED,
51     LAST_SIGNAL,
52 };
53
54 enum {
55     PROP_0,
56 };
57
58 static guint            panel_signals[LAST_SIGNAL] = { 0 };
59
60 /* functions prototype */
61 static void      ibus_panel_service_set_property          (IBusPanelService       *panel,
62                                                            guint                   prop_id,
63                                                            const GValue           *value,
64                                                            GParamSpec             *pspec);
65 static void      ibus_panel_service_get_property          (IBusPanelService       *panel,
66                                                            guint                   prop_id,
67                                                            GValue                 *value,
68                                                            GParamSpec             *pspec);
69 static void      ibus_panel_service_real_destroy          (IBusPanelService       *panel);
70 static void      ibus_panel_service_service_method_call   (IBusService            *service,
71                                                            GDBusConnection        *connection,
72                                                            const gchar            *sender,
73                                                            const gchar            *object_path,
74                                                            const gchar            *interface_name,
75                                                            const gchar            *method_name,
76                                                            GVariant               *parameters,
77                                                            GDBusMethodInvocation  *invocation);
78 static GVariant *ibus_panel_service_service_get_property  (IBusService            *service,
79                                                            GDBusConnection        *connection,
80                                                            const gchar            *sender,
81                                                            const gchar            *object_path,
82                                                            const gchar            *interface_name,
83                                                            const gchar            *property_name,
84                                                            GError                **error);
85 static gboolean  ibus_panel_service_service_set_property  (IBusService            *service,
86                                                            GDBusConnection        *connection,
87                                                            const gchar            *sender,
88                                                            const gchar            *object_path,
89                                                            const gchar            *interface_name,
90                                                            const gchar            *property_name,
91                                                            GVariant               *value,
92                                                            GError                **error);
93 static void      ibus_panel_service_not_implemented       (IBusPanelService      *panel);
94 static void      ibus_panel_service_focus_in              (IBusPanelService      *panel,
95                                                            const gchar           *input_context_path);
96 static void      ibus_panel_service_focus_out             (IBusPanelService      *panel,
97                                                            const gchar           *input_context_path);
98 static void      ibus_panel_service_register_properties   (IBusPanelService      *panel,
99                                                            IBusPropList          *prop_list);
100 static void      ibus_panel_service_set_cursor_location   (IBusPanelService      *panel,
101                                                            gint                   x,
102                                                            gint                   y,
103                                                            gint                   w,
104                                                            gint                   h);
105 static void      ibus_panel_service_update_auxiliary_text (IBusPanelService      *panel,
106                                                            IBusText              *text,
107                                                            gboolean               visible);
108 static void      ibus_panel_service_update_lookup_table   (IBusPanelService      *panel,
109                                                            IBusLookupTable       *lookup_table,
110                                                            gboolean               visible);
111 static void      ibus_panel_service_update_preedit_text   (IBusPanelService      *panel,
112                                                            IBusText              *text,
113                                                            guint                  cursor_pos,
114                                                            gboolean               visible);
115 static void      ibus_panel_service_update_property       (IBusPanelService      *panel,
116                                                            IBusProperty          *prop);
117
118 G_DEFINE_TYPE (IBusPanelService, ibus_panel_service, IBUS_TYPE_SERVICE)
119
120 static const gchar introspection_xml[] =
121     "<node>"
122     "  <interface name='org.freedesktop.IBus.Panel'>"
123     /* Methods */
124     "    <method name='UpdatePreeditText'>"
125     "      <arg direction='in'  type='v' name='text' />"
126     "      <arg direction='in'  type='u' name='cursor_pos' />"
127     "      <arg direction='in'  type='b' name='visible' />"
128     "    </method>"
129     "    <method name='ShowPreeditText' />"
130     "    <method name='HidePreeditText' />"
131     "    <method name='UpdateAuxiliaryText'>"
132     "      <arg direction='in'  type='v' name='text' />"
133     "      <arg direction='in'  type='b' name='visible' />"
134     "    </method>"
135     "    <method name='ShowAuxiliaryText' />"
136     "    <method name='HideAuxiliaryText' />"
137     "    <method name='UpdateLookupTable'>"
138     "      <arg direction='in' type='v' name='table' />"
139     "      <arg direction='in' type='b' name='visible' />"
140     "    </method>"
141     "    <method name='ShowLookupTable' />"
142     "    <method name='HideLookupTable' />"
143     "    <method name='CursorUpLookupTable' />"
144     "    <method name='CursorDownLookupTable' />"
145     "    <method name='PageUpLookupTable' />"
146     "    <method name='PageDownLookupTable' />"
147     "    <method name='RegisterProperties'>"
148     "      <arg direction='in'  type='v' name='props' />"
149     "    </method>"
150     "    <method name='UpdateProperty'>"
151     "      <arg direction='in'  type='v' name='prop' />"
152     "    </method>"
153     "    <method name='FocusIn'>"
154     "      <arg direction='in'  type='o' name='ic' />"
155     "    </method>"
156     "    <method name='FocusOut'>"
157     "      <arg direction='in'  type='o' name='ic' />"
158     "    </method>"
159     "    <method name='SetCursorLocation'>"
160     "      <arg direction='in' type='i' name='x' />"
161     "      <arg direction='in' type='i' name='y' />"
162     "      <arg direction='in' type='i' name='w' />"
163     "      <arg direction='in' type='i' name='h' />"
164     "    </method>"
165     "    <method name='Reset' />"
166     "    <method name='StartSetup' />"
167     "    <method name='StateChanged' />"
168     "    <method name='HideLanguageBar' />"
169     "    <method name='ShowLanguageBar' />"
170     /* Signals */
171     "    <signal name='CursorUp' />"
172     "    <signal name='CursorDown' />"
173     "    <signal name='PageUp' />"
174     "    <signal name='PageDown' />"
175     "    <signal name='PropertyActivate'>"
176     "      <arg type='s' name='prop_name' />"
177     "      <arg type='i' name='prop_state' />"
178     "    </signal>"
179     "    <signal name='PropertyShow'>"
180     "      <arg type='s' name='prop_name' />"
181     "    </signal>"
182     "    <signal name='PropertyHide'>"
183     "      <arg type='s' name='prop_name' />"
184     "    </signal>"
185     "    <signal name='CandidateClicked'>"
186     "      <arg type='u' name='index' />"
187     "      <arg type='u' name='button' />"
188     "      <arg type='u' name='state' />"
189     "    </signal>"
190     "  </interface>"
191     "</node>";
192
193 static void
194 ibus_panel_service_class_init (IBusPanelServiceClass *class)
195 {
196     GObjectClass *gobject_class = G_OBJECT_CLASS (class);
197     ibus_panel_service_parent_class = IBUS_SERVICE_CLASS (g_type_class_peek_parent (class));
198
199     gobject_class->set_property = (GObjectSetPropertyFunc) ibus_panel_service_set_property;
200     gobject_class->get_property = (GObjectGetPropertyFunc) ibus_panel_service_get_property;
201
202     IBUS_OBJECT_CLASS (gobject_class)->destroy = (IBusObjectDestroyFunc) ibus_panel_service_real_destroy;
203
204     IBUS_SERVICE_CLASS (class)->service_method_call  = ibus_panel_service_service_method_call;
205     IBUS_SERVICE_CLASS (class)->service_get_property = ibus_panel_service_service_get_property;
206     IBUS_SERVICE_CLASS (class)->service_set_property = ibus_panel_service_service_set_property;
207
208     ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml);
209
210     class->focus_in              = ibus_panel_service_focus_in;
211     class->focus_out             = ibus_panel_service_focus_out;
212     class->register_properties   = ibus_panel_service_register_properties;
213     class->set_cursor_location   = ibus_panel_service_set_cursor_location;
214     class->update_lookup_table   = ibus_panel_service_update_lookup_table;
215     class->update_auxiliary_text = ibus_panel_service_update_auxiliary_text;
216     class->update_preedit_text   = ibus_panel_service_update_preedit_text;
217     class->update_property       = ibus_panel_service_update_property;
218
219     class->cursor_down_lookup_table = ibus_panel_service_not_implemented;
220     class->cursor_up_lookup_table   = ibus_panel_service_not_implemented;
221     class->hide_auxiliary_text      = ibus_panel_service_not_implemented;
222     class->hide_language_bar        = ibus_panel_service_not_implemented;
223     class->hide_lookup_table        = ibus_panel_service_not_implemented;
224     class->hide_preedit_text        = ibus_panel_service_not_implemented;
225     class->page_down_lookup_table   = ibus_panel_service_not_implemented;
226     class->page_up_lookup_table     = ibus_panel_service_not_implemented;
227     class->reset                    = ibus_panel_service_not_implemented;
228     class->show_auxiliary_text      = ibus_panel_service_not_implemented;
229     class->show_language_bar        = ibus_panel_service_not_implemented;
230     class->show_lookup_table        = ibus_panel_service_not_implemented;
231     class->show_preedit_text        = ibus_panel_service_not_implemented;
232     class->start_setup              = ibus_panel_service_not_implemented;
233     class->state_changed            = ibus_panel_service_not_implemented;
234
235     /* install signals */
236     /**
237      * IBusPanelService::update-preedit-text:
238      * @text: A preedit text to be updated.
239      * @cursor_pos: The cursor position of the text.
240      * @visible: Whether the update is visible.
241      *
242      * Emitted when the client application get the update-preedit-text.
243      * Implement the member function update_preedit_text() in extended class to receive this signal.
244      *
245      * <note><para>Argument @user_data is ignored in this function.</para></note>
246      */
247     panel_signals[UPDATE_PREEDIT_TEXT] =
248         g_signal_new (I_("update-preedit-text"),
249             G_TYPE_FROM_CLASS (gobject_class),
250             G_SIGNAL_RUN_LAST,
251             G_STRUCT_OFFSET (IBusPanelServiceClass, update_preedit_text),
252             NULL, NULL,
253             _ibus_marshal_VOID__OBJECT_UINT_BOOLEAN,
254             G_TYPE_NONE,
255             3,
256             IBUS_TYPE_TEXT,
257             G_TYPE_UINT,
258             G_TYPE_BOOLEAN);
259
260     /**
261      * IBusPanelService::update-auxiliary-text:
262      * @text: A preedit text to be updated.
263      * @visible: Whether the update is visible.
264      *
265      * Emitted when the client application get the update-auxiliary-text.
266      * Implement the member function update_auxiliary_text() in extended class to receive this signal.
267      *
268      * <note><para>Argument @user_data is ignored in this function.</para></note>
269      */
270     panel_signals[UPDATE_AUXILIARY_TEXT] =
271         g_signal_new (I_("update-auxiliary-text"),
272             G_TYPE_FROM_CLASS (gobject_class),
273             G_SIGNAL_RUN_LAST,
274             G_STRUCT_OFFSET (IBusPanelServiceClass, update_auxiliary_text),
275             NULL, NULL,
276             _ibus_marshal_VOID__OBJECT_BOOLEAN,
277             G_TYPE_NONE,
278             2,
279             IBUS_TYPE_TEXT,
280             G_TYPE_BOOLEAN);
281
282     /**
283      * IBusPanelService::update-lookup-table:
284      * @lookup_table: A lookup table to be updated.
285      * @visible: Whether the update is visible.
286      *
287      * Emitted when the client application get the update-lookup-table.
288      * Implement the member function update_lookup_table() in extended class to receive this signal.
289      *
290      * <note><para>Argument @user_data is ignored in this function.</para></note>
291      */
292     panel_signals[UPDATE_LOOKUP_TABLE] =
293         g_signal_new (I_("update-lookup-table"),
294             G_TYPE_FROM_CLASS (gobject_class),
295             G_SIGNAL_RUN_LAST,
296             G_STRUCT_OFFSET (IBusPanelServiceClass, update_lookup_table),
297             NULL, NULL,
298             _ibus_marshal_VOID__OBJECT_BOOLEAN,
299             G_TYPE_NONE,
300             2,
301             IBUS_TYPE_LOOKUP_TABLE,
302             G_TYPE_BOOLEAN);
303
304     /**
305      * IBusPanelService::focus-in:
306      * @input_context_path: Object path of InputContext.
307      *
308      * Emitted when the client application get the focus-in.
309      * Implement the member function focus_in() in extended class to receive this signal.
310      *
311      * <note><para>Argument @user_data is ignored in this function.</para></note>
312      */
313     panel_signals[FOCUS_IN] =
314         g_signal_new (I_("focus-in"),
315             G_TYPE_FROM_CLASS (gobject_class),
316             G_SIGNAL_RUN_LAST,
317             G_STRUCT_OFFSET (IBusPanelServiceClass, focus_in),
318             NULL, NULL,
319             _ibus_marshal_VOID__STRING,
320             G_TYPE_NONE,
321             1,
322             G_TYPE_STRING);
323
324     /**
325      * IBusPanelService::focus-out:
326      * @input_context_path: Object path of InputContext.
327      *
328      * Emitted when the client application get the focus-out.
329      * Implement the member function focus_out() in extended class to receive this signal.
330      *
331      * <note><para>Argument @user_data is ignored in this function.</para></note>
332      */
333     panel_signals[FOCUS_OUT] =
334         g_signal_new (I_("focus-out"),
335             G_TYPE_FROM_CLASS (gobject_class),
336             G_SIGNAL_RUN_LAST,
337             G_STRUCT_OFFSET (IBusPanelServiceClass, focus_out),
338             NULL, NULL,
339             _ibus_marshal_VOID__STRING,
340             G_TYPE_NONE,
341             1,
342             G_TYPE_STRING);
343
344     /**
345      * IBusPanelService::register-properties:
346      * @prop_list: An IBusPropList that contains properties.
347      *
348      * Emitted when the client application get the register-properties.
349      * Implement the member function register_properties() in extended class to receive this signal.
350      *
351      * <note><para>Argument @user_data is ignored in this function.</para></note>
352      */
353     panel_signals[REGISTER_PROPERTIES] =
354         g_signal_new (I_("register-properties"),
355             G_TYPE_FROM_CLASS (gobject_class),
356             G_SIGNAL_RUN_LAST,
357             G_STRUCT_OFFSET (IBusPanelServiceClass, register_properties),
358             NULL, NULL,
359             _ibus_marshal_VOID__OBJECT,
360             G_TYPE_NONE,
361             1,
362             IBUS_TYPE_PROP_LIST);
363
364     /**
365      * IBusPanelService::update-property:
366      * @prop: The IBusProperty to be updated.
367      *
368      * Emitted when the client application get the update-property.
369      * Implement the member function update_property() in extended class to receive this signal.
370      *
371      * <note><para>Argument @user_data is ignored in this function.</para></note>
372      */
373     panel_signals[UPDATE_PROPERTY] =
374         g_signal_new (I_("update-property"),
375             G_TYPE_FROM_CLASS (gobject_class),
376             G_SIGNAL_RUN_LAST,
377             G_STRUCT_OFFSET (IBusPanelServiceClass, update_property),
378             NULL, NULL,
379             _ibus_marshal_VOID__OBJECT,
380             G_TYPE_NONE,
381             1,
382             IBUS_TYPE_PROPERTY);
383
384     /**
385      * IBusPanelService::set-cursor-location:
386      * @x: X coordinate of the cursor.
387      * @y: Y coordinate of the cursor.
388      * @w: Width of the cursor.
389      * @h: Height of the cursor.
390      *
391      * Emitted when the client application get the set-cursor-location.
392      * Implement the member function set_cursor_location() in extended class to receive this signal.
393      *
394      * <note><para>Argument @user_data is ignored in this function.</para></note>
395      */
396     panel_signals[SET_CURSOR_LOCATION] =
397         g_signal_new (I_("set-cursor-location"),
398             G_TYPE_FROM_CLASS (gobject_class),
399             G_SIGNAL_RUN_LAST,
400             G_STRUCT_OFFSET (IBusPanelServiceClass, set_cursor_location),
401             NULL, NULL,
402             _ibus_marshal_VOID__INT_INT_INT_INT,
403             G_TYPE_NONE,
404             4,
405             G_TYPE_INT,
406             G_TYPE_INT,
407             G_TYPE_INT,
408             G_TYPE_INT);
409
410     /**
411      * IBusPanelService::cursor-up-lookup-table:
412      *
413      * Emitted when the client application get the cursor-up-lookup-table.
414      * Implement the member function cursor_up_lookup_table() in extended class to receive this signal.
415      *
416      * <note><para>Argument @user_data is ignored in this function.</para></note>
417      */
418     panel_signals[CURSOR_UP_LOOKUP_TABLE] =
419         g_signal_new (I_("cursor-up-lookup-table"),
420             G_TYPE_FROM_CLASS (gobject_class),
421             G_SIGNAL_RUN_LAST,
422             G_STRUCT_OFFSET (IBusPanelServiceClass, cursor_up_lookup_table),
423             NULL, NULL,
424             _ibus_marshal_VOID__VOID,
425             G_TYPE_NONE, 0);
426
427     /**
428      * IBusPanelService::cursor-down-lookup-table:
429      *
430      * Emitted when the client application get the cursor-down-lookup-table.
431      * Implement the member function cursor_down_lookup_table() in extended class to receive this signal.
432      *
433      * <note><para>Argument @user_data is ignored in this function.</para></note>
434      */
435     panel_signals[CURSOR_DOWN_LOOKUP_TABLE] =
436         g_signal_new (I_("cursor-down-lookup-table"),
437             G_TYPE_FROM_CLASS (gobject_class),
438             G_SIGNAL_RUN_LAST,
439             G_STRUCT_OFFSET (IBusPanelServiceClass, cursor_down_lookup_table),
440             NULL, NULL,
441             _ibus_marshal_VOID__VOID,
442             G_TYPE_NONE, 0);
443
444     /**
445      * IBusPanelService::hide-auxiliary-text:
446      *
447      * Emitted when the client application get the hide-auxiliary-text.
448      * Implement the member function hide_auxiliary_text() in extended class to receive this signal.
449      *
450      * <note><para>Argument @user_data is ignored in this function.</para></note>
451      */
452     panel_signals[HIDE_AUXILIARY_TEXT] =
453         g_signal_new (I_("hide-auxiliary-text"),
454             G_TYPE_FROM_CLASS (gobject_class),
455             G_SIGNAL_RUN_LAST,
456             G_STRUCT_OFFSET (IBusPanelServiceClass, hide_auxiliary_text),
457             NULL, NULL,
458             _ibus_marshal_VOID__VOID,
459             G_TYPE_NONE, 0);
460
461     /**
462      * IBusPanelService::hide-language-bar:
463      *
464      * Emitted when the client application get the hide-language-bar.
465      * Implement the member function hide_language_bar() in extended class to receive this signal.
466      *
467      * <note><para>Argument @user_data is ignored in this function.</para></note>
468      */
469     panel_signals[HIDE_LANGUAGE_BAR] =
470         g_signal_new (I_("hide-language-bar"),
471             G_TYPE_FROM_CLASS (gobject_class),
472             G_SIGNAL_RUN_LAST,
473             G_STRUCT_OFFSET (IBusPanelServiceClass, hide_language_bar),
474             NULL, NULL,
475             _ibus_marshal_VOID__VOID,
476             G_TYPE_NONE, 0);
477
478     /**
479      * IBusPanelService::hide-lookup-table:
480      *
481      * Emitted when the client application get the hide-lookup-table.
482      * Implement the member function hide_lookup_table() in extended class to receive this signal.
483      *
484      * <note><para>Argument @user_data is ignored in this function.</para></note>
485      */
486     panel_signals[HIDE_LOOKUP_TABLE] =
487         g_signal_new (I_("hide-lookup-table"),
488             G_TYPE_FROM_CLASS (gobject_class),
489             G_SIGNAL_RUN_LAST,
490             G_STRUCT_OFFSET (IBusPanelServiceClass, hide_lookup_table),
491             NULL, NULL,
492             _ibus_marshal_VOID__VOID,
493             G_TYPE_NONE, 0);
494
495     /**
496      * IBusPanelService::hide-preedit-text:
497      *
498      * Emitted when the client application get the hide-preedit-text.
499      * Implement the member function hide_preedit_text() in extended class to receive this signal.
500      *
501      * <note><para>Argument @user_data is ignored in this function.</para></note>
502      */
503     panel_signals[HIDE_PREEDIT_TEXT] =
504         g_signal_new (I_("hide-preedit-text"),
505             G_TYPE_FROM_CLASS (gobject_class),
506             G_SIGNAL_RUN_LAST,
507             G_STRUCT_OFFSET (IBusPanelServiceClass, hide_preedit_text),
508             NULL, NULL,
509             _ibus_marshal_VOID__VOID,
510             G_TYPE_NONE, 0);
511
512     /**
513      * IBusPanelService::page-up-lookup-table:
514      *
515      * Emitted when the client application get the page-up-lookup-table.
516      * Implement the member function page_up_lookup_table() in extended class to receive this signal.
517      *
518      * <note><para>Argument @user_data is ignored in this function.</para></note>
519      */
520     panel_signals[PAGE_UP_LOOKUP_TABLE] =
521         g_signal_new (I_("page-up-lookup-table"),
522             G_TYPE_FROM_CLASS (gobject_class),
523             G_SIGNAL_RUN_LAST,
524             G_STRUCT_OFFSET (IBusPanelServiceClass, page_up_lookup_table),
525             NULL, NULL,
526             _ibus_marshal_VOID__VOID,
527             G_TYPE_NONE, 0);
528
529     /**
530      * IBusPanelService::page-down-lookup-table:
531      *
532      * Emitted when the client application get the page-down-lookup-table.
533      * Implement the member function page_down_lookup_table() in extended class to receive this signal.
534      *
535      * <note><para>Argument @user_data is ignored in this function.</para></note>
536      */
537     panel_signals[PAGE_DOWN_LOOKUP_TABLE] =
538         g_signal_new (I_("page-down-lookup-table"),
539             G_TYPE_FROM_CLASS (gobject_class),
540             G_SIGNAL_RUN_LAST,
541             G_STRUCT_OFFSET (IBusPanelServiceClass, page_down_lookup_table),
542             NULL, NULL,
543             _ibus_marshal_VOID__VOID,
544             G_TYPE_NONE, 0);
545
546     /**
547      * IBusPanelService::reset:
548      *
549      * Emitted when the client application get the reset.
550      * Implement the member function reset() in extended class to receive this signal.
551      *
552      * <note><para>Argument @user_data is ignored in this function.</para></note>
553      */
554     panel_signals[RESET] =
555         g_signal_new (I_("reset"),
556             G_TYPE_FROM_CLASS (gobject_class),
557             G_SIGNAL_RUN_LAST,
558             G_STRUCT_OFFSET (IBusPanelServiceClass, reset),
559             NULL, NULL,
560             _ibus_marshal_VOID__VOID,
561             G_TYPE_NONE, 0);
562
563     /**
564      * IBusPanelService::show-auxiliary-text:
565      *
566      * Emitted when the client application get the show-auxiliary-text.
567      * Implement the member function show_auxiliary_text() in extended class to receive this signal.
568      *
569      * <note><para>Argument @user_data is ignored in this function.</para></note>
570      */
571     panel_signals[SHOW_AUXILIARY_TEXT] =
572         g_signal_new (I_("show-auxiliary-text"),
573             G_TYPE_FROM_CLASS (gobject_class),
574             G_SIGNAL_RUN_LAST,
575             G_STRUCT_OFFSET (IBusPanelServiceClass, show_auxiliary_text),
576             NULL, NULL,
577             _ibus_marshal_VOID__VOID,
578             G_TYPE_NONE, 0);
579
580     /**
581      * IBusPanelService::show-language-bar:
582      *
583      * Emitted when the client application get the show-language-bar.
584      * Implement the member function show_language_bar() in extended class to receive this signal.
585      *
586      * <note><para>Argument @user_data is ignored in this function.</para></note>
587      */
588     panel_signals[SHOW_LANGUAGE_BAR] =
589         g_signal_new (I_("show-language-bar"),
590             G_TYPE_FROM_CLASS (gobject_class),
591             G_SIGNAL_RUN_LAST,
592             G_STRUCT_OFFSET (IBusPanelServiceClass, show_language_bar),
593             NULL, NULL,
594             _ibus_marshal_VOID__VOID,
595             G_TYPE_NONE, 0);
596
597     /**
598      * IBusPanelService::show-lookup-table:
599      *
600      * Emitted when the client application get the show-lookup-table.
601      * Implement the member function show_lookup_table() in extended class to receive this signal.
602      *
603      * <note><para>Argument @user_data is ignored in this function.</para></note>
604      */
605     panel_signals[SHOW_LOOKUP_TABLE] =
606         g_signal_new (I_("show-lookup-table"),
607             G_TYPE_FROM_CLASS (gobject_class),
608             G_SIGNAL_RUN_LAST,
609             G_STRUCT_OFFSET (IBusPanelServiceClass, show_lookup_table),
610             NULL, NULL,
611             _ibus_marshal_VOID__VOID,
612             G_TYPE_NONE, 0);
613
614     /**
615      * IBusPanelService::show-preedit-text:
616      *
617      * Emitted when the client application get the show-preedit-text.
618      * Implement the member function show_preedit_text() in extended class to receive this signal.
619      *
620      * <note><para>Argument @user_data is ignored in this function.</para></note>
621      */
622     panel_signals[SHOW_PREEDIT_TEXT] =
623         g_signal_new (I_("show-preedit-text"),
624             G_TYPE_FROM_CLASS (gobject_class),
625             G_SIGNAL_RUN_LAST,
626             G_STRUCT_OFFSET (IBusPanelServiceClass, show_preedit_text),
627             NULL, NULL,
628             _ibus_marshal_VOID__VOID,
629             G_TYPE_NONE, 0);
630
631     /**
632      * IBusPanelService::start-setup:
633      *
634      * Emitted when the client application get the start-setup.
635      * Implement the member function start_setup() in extended class to receive this signal.
636      *
637      * <note><para>Argument @user_data is ignored in this function.</para></note>
638      */
639     panel_signals[START_SETUP] =
640         g_signal_new (I_("start-setup"),
641             G_TYPE_FROM_CLASS (gobject_class),
642             G_SIGNAL_RUN_LAST,
643             G_STRUCT_OFFSET (IBusPanelServiceClass, start_setup),
644             NULL, NULL,
645             _ibus_marshal_VOID__VOID,
646             G_TYPE_NONE, 0);
647
648     /**
649      * IBusPanelService::state-changed:
650      *
651      * Emitted when the client application get the state-changed.
652      * Implement the member function state_changed() in extended class to receive this signal.
653      *
654      * <note><para>Argument @user_data is ignored in this function.</para></note>
655      */
656     panel_signals[STATE_CHANGED] =
657         g_signal_new (I_("state-changed"),
658             G_TYPE_FROM_CLASS (gobject_class),
659             G_SIGNAL_RUN_LAST,
660             G_STRUCT_OFFSET (IBusPanelServiceClass, state_changed),
661             NULL, NULL,
662             _ibus_marshal_VOID__VOID,
663             G_TYPE_NONE, 0);
664 }
665
666 static void
667 ibus_panel_service_init (IBusPanelService *panel)
668 {
669 }
670
671 static void
672 ibus_panel_service_set_property (IBusPanelService *panel,
673                                  guint             prop_id,
674                                  const GValue     *value,
675                                  GParamSpec       *pspec)
676 {
677     switch (prop_id) {
678     default:
679         G_OBJECT_WARN_INVALID_PROPERTY_ID (panel, prop_id, pspec);
680     }
681 }
682
683 static void
684 ibus_panel_service_get_property (IBusPanelService *panel,
685                                  guint             prop_id,
686                                  GValue           *value,
687                                  GParamSpec       *pspec)
688 {
689     switch (prop_id) {
690     default:
691         G_OBJECT_WARN_INVALID_PROPERTY_ID (panel, prop_id, pspec);
692     }
693 }
694
695 static void
696 ibus_panel_service_real_destroy (IBusPanelService *panel)
697 {
698     IBUS_OBJECT_CLASS(ibus_panel_service_parent_class)->destroy (IBUS_OBJECT (panel));
699 }
700
701
702 static void
703 _g_object_unref_if_floating (gpointer instance)
704 {
705     if (g_object_is_floating (instance))
706         g_object_unref (instance);
707 }
708
709 static void
710 ibus_panel_service_service_method_call (IBusService           *service,
711                                         GDBusConnection       *connection,
712                                         const gchar           *sender,
713                                         const gchar           *object_path,
714                                         const gchar           *interface_name,
715                                         const gchar           *method_name,
716                                         GVariant              *parameters,
717                                         GDBusMethodInvocation *invocation)
718 {
719     IBusPanelService *panel = IBUS_PANEL_SERVICE (service);
720
721     if (g_strcmp0 (interface_name, IBUS_INTERFACE_PANEL) != 0) {
722         IBUS_SERVICE_CLASS (ibus_panel_service_parent_class)->
723                 service_method_call (service,
724                                      connection,
725                                      sender,
726                                      object_path,
727                                      interface_name,
728                                      method_name,
729                                      parameters,
730                                      invocation);
731         return;
732     }
733
734     if (g_strcmp0 (method_name, "UpdatePreeditText") == 0) {
735         GVariant *variant = NULL;
736         guint cursor = 0;
737         gboolean visible = FALSE;
738
739         g_variant_get (parameters, "(vub)", &variant, &cursor, &visible);
740         IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
741         g_variant_unref (variant);
742
743         g_signal_emit (panel, panel_signals[UPDATE_PREEDIT_TEXT], 0, text, cursor, visible);
744         _g_object_unref_if_floating (text);
745         g_dbus_method_invocation_return_value (invocation, NULL);
746         return;
747     }
748
749     if (g_strcmp0 (method_name, "UpdateAuxiliaryText") == 0) {
750         GVariant *variant = NULL;
751         gboolean visible = FALSE;
752
753         g_variant_get (parameters, "(vb)", &variant, &visible);
754         IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant));
755         g_variant_unref (variant);
756
757         g_signal_emit (panel, panel_signals[UPDATE_AUXILIARY_TEXT], 0, text, visible);
758         _g_object_unref_if_floating (text);
759         g_dbus_method_invocation_return_value (invocation, NULL);
760         return;
761     }
762
763     if (g_strcmp0 (method_name, "UpdateLookupTable") == 0) {
764         GVariant *variant = NULL;
765         gboolean visible = FALSE;
766
767         g_variant_get (parameters, "(vb)", &variant, &visible);
768         IBusLookupTable *table = IBUS_LOOKUP_TABLE (ibus_serializable_deserialize (variant));
769         g_variant_unref (variant);
770
771         g_signal_emit (panel, panel_signals[UPDATE_LOOKUP_TABLE], 0, table, visible);
772         _g_object_unref_if_floating (table);
773         g_dbus_method_invocation_return_value (invocation, NULL);
774         return;
775     }
776
777     if (g_strcmp0 (method_name, "FocusIn") == 0) {
778         const gchar *path;
779         g_variant_get (parameters, "(&o)", &path);
780         g_signal_emit (panel, panel_signals[FOCUS_IN], 0, path);
781         g_dbus_method_invocation_return_value (invocation, NULL);
782         return;
783     }
784
785     if (g_strcmp0 (method_name, "FocusOut") == 0) {
786         const gchar *path;
787         g_variant_get (parameters, "(&o)", &path);
788         g_signal_emit (panel, panel_signals[FOCUS_OUT], 0, path);
789         g_dbus_method_invocation_return_value (invocation, NULL);
790         return;
791     }
792
793     if (g_strcmp0 (method_name, "RegisterProperties") == 0) {
794         GVariant *variant = g_variant_get_child_value (parameters, 0);
795         IBusPropList *prop_list = IBUS_PROP_LIST (ibus_serializable_deserialize (variant));
796         g_variant_unref (variant);
797
798         g_signal_emit (panel, panel_signals[REGISTER_PROPERTIES], 0, prop_list);
799         _g_object_unref_if_floating (prop_list);
800         g_dbus_method_invocation_return_value (invocation, NULL);
801         return;
802     }
803
804     if (g_strcmp0 (method_name, "UpdateProperty") == 0) {
805         GVariant *variant = g_variant_get_child_value (parameters, 0);
806         IBusProperty *property = IBUS_PROPERTY (ibus_serializable_deserialize (variant));
807         g_variant_unref (variant);
808
809         g_signal_emit (panel, panel_signals[UPDATE_PROPERTY], 0, property);
810         _g_object_unref_if_floating (property);
811         g_dbus_method_invocation_return_value (invocation, NULL);
812         return;
813     }
814
815     if (g_strcmp0 (method_name, "SetCursorLocation") == 0) {
816         gint x, y, w, h;
817         g_variant_get (parameters, "(iiii)", &x, &y, &w, &h);
818         g_signal_emit (panel, panel_signals[SET_CURSOR_LOCATION], 0, x, y, w, h);
819         g_dbus_method_invocation_return_value (invocation, NULL);
820         return;
821     }
822
823     const static struct {
824         const gchar *name;
825         const gint signal_id;
826     } no_arg_methods [] = {
827         { "CursorUpLookupTable",   CURSOR_UP_LOOKUP_TABLE },
828         { "CursorDownLookupTable", CURSOR_DOWN_LOOKUP_TABLE },
829         { "HideAuxiliaryText",     HIDE_AUXILIARY_TEXT },
830         { "HideLanguageBar",       HIDE_LANGUAGE_BAR },
831         { "HideLookupTable",       HIDE_LOOKUP_TABLE },
832         { "HidePreeditText",       HIDE_PREEDIT_TEXT },
833         { "PageUpLookupTable",     PAGE_UP_LOOKUP_TABLE },
834         { "PageDownLookupTable",   PAGE_DOWN_LOOKUP_TABLE },
835         { "Reset",                 RESET },
836         { "ShowAuxiliaryText",     SHOW_AUXILIARY_TEXT },
837         { "ShowLanguageBar",       SHOW_LANGUAGE_BAR },
838         { "ShowLookupTable",       SHOW_LOOKUP_TABLE },
839         { "ShowPreeditText",       SHOW_PREEDIT_TEXT },
840         { "StartSetup",            START_SETUP },
841         { "StateChanged",          STATE_CHANGED },
842     };
843
844     gint i;
845     for (i = 0; i < G_N_ELEMENTS (no_arg_methods); i++) {
846         if (g_strcmp0 (method_name, no_arg_methods[i].name) == 0) {
847             if (no_arg_methods[i].signal_id >= 0) {
848                 g_signal_emit (panel, panel_signals[no_arg_methods[i].signal_id], 0);
849             }
850             g_dbus_method_invocation_return_value (invocation, NULL);
851             return;
852         }
853     }
854
855     /* should not be reached */
856     g_return_if_reached ();
857 }
858
859 static GVariant *
860 ibus_panel_service_service_get_property (IBusService        *service,
861                                          GDBusConnection    *connection,
862                                          const gchar        *sender,
863                                          const gchar        *object_path,
864                                          const gchar        *interface_name,
865                                          const gchar        *property_name,
866                                          GError            **error)
867 {
868     return IBUS_SERVICE_CLASS (ibus_panel_service_parent_class)->
869                 service_get_property (service,
870                                       connection,
871                                       sender,
872                                       object_path,
873                                       interface_name,
874                                       property_name,
875                                       error);
876 }
877
878 static gboolean
879 ibus_panel_service_service_set_property (IBusService        *service,
880                                          GDBusConnection    *connection,
881                                          const gchar        *sender,
882                                          const gchar        *object_path,
883                                          const gchar        *interface_name,
884                                          const gchar        *property_name,
885                                          GVariant           *value,
886                                          GError            **error)
887 {
888     return IBUS_SERVICE_CLASS (ibus_panel_service_parent_class)->
889                 service_set_property (service,
890                                       connection,
891                                       sender,
892                                       object_path,
893                                       interface_name,
894                                       property_name,
895                                       value,
896                                       error);
897 }
898
899
900 static void
901 ibus_panel_service_not_implemented (IBusPanelService *panel)
902 {
903     /* g_debug ("not implemented"); */
904 }
905
906 static void
907 ibus_panel_service_focus_in (IBusPanelService    *panel,
908                              const gchar         *input_context_path)
909 {
910     ibus_panel_service_not_implemented(panel);
911 }
912
913 static void
914 ibus_panel_service_focus_out (IBusPanelService    *panel,
915                               const gchar         *input_context_path)
916 {
917     ibus_panel_service_not_implemented(panel);
918 }
919
920 static void
921 ibus_panel_service_register_properties (IBusPanelService *panel,
922                                         IBusPropList     *prop_list)
923 {
924     ibus_panel_service_not_implemented(panel);
925 }
926
927 static void
928 ibus_panel_service_set_cursor_location (IBusPanelService *panel,
929                                         gint              x,
930                                         gint              y,
931                                         gint              w,
932                                         gint              h)
933 {
934     ibus_panel_service_not_implemented(panel);
935 }
936
937 static void
938 ibus_panel_service_update_auxiliary_text (IBusPanelService *panel,
939                                           IBusText         *text,
940                                           gboolean          visible)
941 {
942     ibus_panel_service_not_implemented(panel);
943 }
944
945 static void
946 ibus_panel_service_update_lookup_table (IBusPanelService *panel,
947                                         IBusLookupTable  *lookup_table,
948                                         gboolean          visible)
949 {
950     ibus_panel_service_not_implemented(panel);
951 }
952
953 static void
954 ibus_panel_service_update_preedit_text (IBusPanelService *panel,
955                                         IBusText         *text,
956                                         guint             cursor_pos,
957                                         gboolean          visible)
958 {
959     ibus_panel_service_not_implemented(panel);
960 }
961
962 static void
963 ibus_panel_service_update_property (IBusPanelService *panel,
964                                     IBusProperty     *prop)
965 {
966     ibus_panel_service_not_implemented(panel);
967 }
968
969 IBusPanelService *
970 ibus_panel_service_new (GDBusConnection *connection)
971 {
972     g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
973
974     GObject *object = g_object_new (IBUS_TYPE_PANEL_SERVICE,
975                                     "object-path", IBUS_PATH_PANEL,
976                                     "connection", connection,
977                                     NULL);
978
979     return IBUS_PANEL_SERVICE (object);
980 }
981
982 void
983 ibus_panel_service_candidate_clicked (IBusPanelService *panel,
984                                       guint             index,
985                                       guint             button,
986                                       guint             state)
987 {
988     g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel));
989     ibus_service_emit_signal ((IBusService *) panel,
990                               NULL,
991                               IBUS_INTERFACE_PANEL,
992                               "CandidateClicked",
993                               g_variant_new ("(uuu)", index, button, state),
994                               NULL);
995 }
996
997 void
998 ibus_panel_service_property_activate (IBusPanelService *panel,
999                                       const gchar      *prop_name,
1000                                       guint             prop_state)
1001 {
1002     g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel));
1003     ibus_service_emit_signal ((IBusService *) panel,
1004                               NULL,
1005                               IBUS_INTERFACE_PANEL,
1006                               "PropertyActivate",
1007                               g_variant_new ("(su)", prop_name, prop_state),
1008                               NULL);
1009 }
1010
1011 void
1012 ibus_panel_service_property_show (IBusPanelService *panel,
1013                                   const gchar      *prop_name)
1014 {
1015     g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel));
1016     ibus_service_emit_signal ((IBusService *) panel,
1017                               NULL,
1018                               IBUS_INTERFACE_PANEL,
1019                               "PropertyShow",
1020                               g_variant_new ("(s)", prop_name),
1021                               NULL);
1022 }
1023
1024 void
1025 ibus_panel_service_property_hide (IBusPanelService *panel,
1026                                   const gchar      *prop_name)
1027 {
1028     g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel));
1029     ibus_service_emit_signal ((IBusService *) panel,
1030                               NULL,
1031                               IBUS_INTERFACE_PANEL,
1032                               "PropertyHide",
1033                               g_variant_new ("(s)", prop_name),
1034                               NULL);
1035 }
1036
1037 #define DEFINE_FUNC(name, Name)                             \
1038     void                                                    \
1039     ibus_panel_service_##name (IBusPanelService *panel)     \
1040     {                                                       \
1041         g_return_if_fail (IBUS_IS_PANEL_SERVICE (panel));   \
1042         ibus_service_emit_signal ((IBusService *) panel,    \
1043                                   NULL,                     \
1044                                   IBUS_INTERFACE_PANEL,     \
1045                                   #Name,                    \
1046                                   NULL,                     \
1047                                   NULL);                    \
1048     }
1049 DEFINE_FUNC (cursor_down, CursorDown)
1050 DEFINE_FUNC (cursor_up, CursorUp)
1051 DEFINE_FUNC (page_down, PageDown)
1052 DEFINE_FUNC (page_up, PageUp)
1053 #undef DEFINE_FUNC
1054