Fix handling of backspace key press
[profile/ivi/weekeyboard.git] / src / wkb-ibus-config-eet.c
1 /*
2  * Copyright © 2013 Intel Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the eetific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21
22 #include <Eina.h>
23 #include <Eet.h>
24
25 #include "wkb-ibus-config-eet.h"
26
27 /*
28  * Base struct for all config types
29  */
30 struct _config_section
31 {
32    const char *id;
33
34    void (*free)(struct _config_section *);
35    void (*set_defaults)(struct _config_section *);
36    Eina_Bool (*set_value)(struct _config_section *, const char *, const char *, Eldbus_Message_Iter *);
37    void *(*get_value)(struct _config_section *, const char *, const char *);
38    void *(*get_values)(struct _config_section *, const char *);
39 };
40
41 static void
42 _config_section_free(struct _config_section *base)
43 {
44    eina_stringshare_del(base->id);
45    base->free(base);
46 }
47
48 static void
49 _config_section_set_defaults(struct _config_section *base)
50 {
51    base->set_defaults(base);
52 }
53
54 static Eina_Bool
55 _config_section_set_value(struct _config_section *base, const char *section, const char *name, Eldbus_Message_Iter *value)
56 {
57    return base->set_value(base, section, name, value);
58 }
59 static void *
60 _config_section_get_value(struct _config_section *base, const char *section, const char *name)
61 {
62    return base->get_value(base, section, name);
63 }
64
65 static void *
66 _config_section_get_values(struct _config_section *base, const char *section)
67 {
68    return base->get_values(base, section);
69 }
70
71 /*
72  * Helpers for manipulating list of strings
73  */
74 static void
75 _config_string_list_free(Eina_List *list)
76 {
77    const char *str;
78
79    EINA_LIST_FREE(list, str)
80       eina_stringshare_del(str);
81
82    eina_list_free(list);
83 }
84
85 static Eina_List *
86 _config_string_list_new(const char **strs)
87 {
88    Eina_List *list = NULL;
89    const char *str;
90
91    for (str = *strs; str != NULL; str = *++strs)
92       list = eina_list_append(list, eina_stringshare_add(str));
93
94    return list;
95 }
96
97 /*
98  * <schema path="/desktop/ibus/general/hotkey/" id="org.freedesktop.ibus.general.hotkey">
99  *   <key type="as" name="trigger">
100  *     <default>[ 'Control+space', 'Zenkaku_Hankaku', 'Alt+Kanji', 'Alt+grave', 'Hangul', 'Alt+Release+Alt_R' ]</default>
101  *     <summary>Trigger shortcut keys</summary>
102  *     <description>The shortcut keys for turning input method on or off</description>
103  *   </key>
104  *   <key type="as" name="triggers">
105  *     <default>[ '&lt;Super&gt;space' ]</default>
106  *     <summary>Trigger shortcut keys for gtk_accelerator_parse</summary>
107  *     <description>The shortcut keys for turning input method on or off</description>
108  *   </key>
109  *   <key type="as" name="enable-unconditional">
110  *     <default>[]</default>
111  *     <summary>Enable shortcut keys</summary>
112  *     <description>The shortcut keys for turning input method on</description>
113  *   </key>
114  *   <key type="as" name="disable-unconditional">
115  *     <default>[]</default>
116  *     <summary>Disable shortcut keys</summary>
117  *     <description>The shortcut keys for turning input method off</description>
118  *   </key>
119  *   <key type="as" name="next-engine">
120  *     <default>[ 'Alt+Shift_L' ]</default>
121  *     <summary>Next engine shortcut keys</summary>
122  *     <description>The shortcut keys for switching to the next input method in the list</description>
123  *   </key>
124  *   <key type="as" name="next-engine-in-menu">
125  *     <default>[ 'Alt+Shift_L' ]</default>
126  *     <summary>Next engine shortcut keys</summary>
127  *     <description>The shortcut keys for switching to the next input method in the list</description>
128  *   </key>
129  *   <key type="as" name="prev-engine">
130  *     <default>[]</default>
131  *     <summary>Prev engine shortcut keys</summary>
132  *     <description>The shortcut keys for switching to the previous input method</description>
133  *   </key>
134  *   <key type="as" name="previous-engine">
135  *     <default>[]</default>
136  *     <summary>Prev engine shortcut keys</summary>
137  *     <description>The shortcut keys for switching to the previous input method</description>
138  *   </key>
139  * </schema>
140  */
141 struct _config_hotkey
142 {
143    struct _config_section base;
144
145    Eina_List *trigger;
146    Eina_List *triggers;
147    Eina_List *enable_unconditional;
148    Eina_List *disable_unconditional;
149    Eina_List *next_engine;
150    Eina_List *next_engine_in_menu;
151    Eina_List *prev_engine;
152    Eina_List *previous_engine;
153 };
154
155 static Eet_Data_Descriptor *
156 _config_hotkey_edd_new(void)
157 {
158    Eet_Data_Descriptor *edd;
159    Eet_Data_Descriptor_Class eddc;
160
161    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, struct _config_hotkey);
162    edd = eet_data_descriptor_stream_new(&eddc);
163
164    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "trigger", trigger);
165    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "triggers", triggers);
166    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "enable-unconditional", enable_unconditional);
167    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "disable-unconditional", disable_unconditional);
168    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "next-engine", next_engine);
169    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "next-engine-in-menu", next_engine_in_menu);
170    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "prev-engine", prev_engine);
171    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hotkey, "previous-engine", previous_engine);
172
173    return edd;
174 }
175
176 static void
177 _config_hotkey_set_defaults(struct _config_section *base)
178 {
179    struct _config_hotkey *hotkey = (struct _config_hotkey *) base;
180
181    const char *trigger[] = { "Control+space", "Zenkaku_Hankaku", "Alt+Kanji", "Alt+grave", "Hangul", "Alt+Release+Alt_R", NULL };
182    const char *triggers[] = { "<Super>space", NULL };
183    const char *enable_unconditional[] = { NULL };
184    const char *disable_unconditional[] = { NULL };
185    const char *next_engine[] = { NULL };
186    const char *next_engine_in_menu[] = { NULL };
187    const char *prev_engine[] = { NULL };
188    const char *previous_engine[] = { NULL };
189
190    hotkey->trigger = _config_string_list_new(trigger);
191    hotkey->triggers = _config_string_list_new(triggers);
192    hotkey->enable_unconditional = _config_string_list_new(enable_unconditional);
193    hotkey->disable_unconditional = _config_string_list_new(disable_unconditional);
194    hotkey->next_engine = _config_string_list_new(next_engine);
195    hotkey->next_engine_in_menu = _config_string_list_new(next_engine_in_menu);
196    hotkey->prev_engine = _config_string_list_new(prev_engine);
197    hotkey->previous_engine = _config_string_list_new(previous_engine);
198 }
199
200 static void
201 _config_hotkey_free(struct _config_section *base)
202 {
203    struct _config_hotkey *hotkey = (struct _config_hotkey *) base;
204
205    _config_string_list_free(hotkey->trigger);
206    _config_string_list_free(hotkey->triggers);
207    _config_string_list_free(hotkey->enable_unconditional);
208    _config_string_list_free(hotkey->disable_unconditional);
209    _config_string_list_free(hotkey->next_engine);
210    _config_string_list_free(hotkey->next_engine_in_menu);
211    _config_string_list_free(hotkey->prev_engine);
212    _config_string_list_free(hotkey->previous_engine);
213
214    free(hotkey);
215 }
216
217 static Eina_Bool
218 _config_hotkey_set_value(struct _config_section *base, const char *section, const char *name, Eldbus_Message_Iter *value)
219 {
220    return EINA_FALSE;
221 }
222
223 static void *
224 _config_hotkey_get_value(struct _config_section *base, const char *section, const char *name)
225 {
226    return NULL;
227 }
228
229 static void *
230 _config_hotkey_get_values(struct _config_section *base, const char *section)
231 {
232    return NULL;
233 }
234
235 static void
236 _config_hotkey_section_init(struct _config_section *base)
237 {
238    base->id = eina_stringshare_add("hotkey");
239    base->free = _config_hotkey_free;
240    base->set_defaults = _config_hotkey_set_defaults;
241    base->set_value = _config_hotkey_set_value;
242    base->get_value = _config_hotkey_get_value;
243    base->get_values = _config_hotkey_get_values;
244 }
245
246 static struct _config_section *
247 _config_hotkey_new(void)
248 {
249    struct _config_hotkey *conf = calloc(1, sizeof(*conf));
250    _config_hotkey_section_init((struct _config_section *) conf);
251    return (struct _config_section *) conf;
252 }
253
254 /*
255  * <schema path="/desktop/ibus/general/" id="org.freedesktop.ibus.general">
256  *    <key type="as" name="preload-engines">
257  *      <default>[]</default>
258  *      <summary>Preload engines</summary>
259  *      <description>Preload engines during ibus starts up</description>
260  *    </key>
261  *    <key type="as" name="engines-order">
262  *      <default>[]</default>
263  *      <summary>Engines order</summary>
264  *      <description>Saved engines order in input method list</description>
265  *    </key>
266  *    <key type="i" name="switcher-delay-time">
267  *      <default>400</default>
268  *      <summary>Popup delay milliseconds for IME switcher window</summary>
269  *      <description>Set popup delay milliseconds to show IME switcher window. The default is 400. 0 = Show the window immediately. 0 &lt; Delay milliseconds. 0 &gt; Do not show the
270  *    </key>
271  *    <key type="s" name="version">
272  *      <default>''</default>
273  *      <summary>Saved version number</summary>
274  *      <description>The saved version number will be used to check the difference between the version of the previous installed ibus and one of the current ibus.</description>
275  *    </key>
276  *    <key type="b" name="use-system-keyboard-layout">
277  *      <default>false</default>
278  *      <summary>Use system keyboard layout</summary>
279  *      <description>Use system keyboard (XKB) layout</description>
280  *    </key>
281  *    <key type="b" name="embed-preedit-text">
282  *      <default>true</default>
283  *      <summary>Embed Preedit Text</summary>
284  *      <description>Embed Preedit Text in Application Window</description>
285  *    </key>
286  *    <key type="b" name="use-global-engine">
287  *      <default>false</default>
288  *      <summary>Use global input method</summary>
289  *     <description>Share the same input method among all applications</description>
290  *    </key>
291  *    <key type="b" name="enable-by-default">
292  *      <default>false</default>
293  *      <summary>Enable input method by default</summary>
294  *      <description>Enable input method by default when the application gets input focus</description>
295  *    </key>
296  *    <key type="as" name="dconf-preserve-name-prefixes">
297  *      <default>[ '/desktop/ibus/engine/pinyin', '/desktop/ibus/engine/bopomofo', '/desktop/ibus/engine/hangul' ]</default>
298  *      <summary>DConf preserve name prefixes</summary>
299  *      <description>Prefixes of DConf keys to stop name conversion</description>
300  *    </key>
301  *    <child schema="org.freedesktop.ibus.general.hotkey" name="hotkey"/>
302  * </schema>
303  */
304 struct _config_general
305 {
306    struct _config_section base;
307
308    struct _config_section *hotkey;
309
310    Eina_List *preload_engines;
311    Eina_List *engines_order;
312    Eina_List *dconf_preserve_name_prefixes;
313
314    const char *version;
315
316    int switcher_delay_time;
317
318    Eina_Bool use_system_keyboard_layout;
319    Eina_Bool embed_preedit_text;
320    Eina_Bool use_global_engine;
321    Eina_Bool enable_by_default;
322 };
323
324 static Eet_Data_Descriptor *
325 _config_general_edd_new(Eet_Data_Descriptor *hotkey_edd)
326 {
327    Eet_Data_Descriptor *edd;
328    Eet_Data_Descriptor_Class eddc;
329
330    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, struct _config_general);
331    edd = eet_data_descriptor_stream_new(&eddc);
332
333    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_general, "preload-engines", preload_engines);
334    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_general, "engines-order", engines_order);
335    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_general, "switcher-delay-time", switcher_delay_time, EET_T_INT);
336    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_general, "version", version, EET_T_STRING);
337    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_general, "use-system-keyboard-layout", use_system_keyboard_layout, EET_T_UCHAR);
338    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_general, "embed-preedit-text", embed_preedit_text, EET_T_UCHAR);
339    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_general, "use-global-engine", use_global_engine, EET_T_UCHAR);
340    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_general, "enable-by-default", enable_by_default, EET_T_UCHAR);
341    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_general, "dconf-preserve-name-prefixes", dconf_preserve_name_prefixes);
342    EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct _config_general, "hotkey", hotkey, hotkey_edd);
343
344    return edd;
345 }
346
347 static void
348 _config_general_set_defaults(struct _config_section *base)
349 {
350    struct _config_general *general = (struct _config_general *) base;
351
352    const char *preload_engines[] = { NULL };
353    const char *engines_order[] = { NULL };
354    const char *dconf_preserve_name_prefixes[] = { "/desktop/ibus/engine/pinyin", "/desktop/ibus/engine/bopomofo", "/desktop/ibus/engine/hangul", NULL };
355
356    _config_section_set_defaults(general->hotkey);
357
358    general->preload_engines = _config_string_list_new(preload_engines);
359    general->engines_order = _config_string_list_new(engines_order);
360    general->switcher_delay_time = 400;
361    general->version = eina_stringshare_add("");
362    general->use_system_keyboard_layout = EINA_FALSE;
363    general->embed_preedit_text = EINA_TRUE;
364    general->use_global_engine = EINA_FALSE;
365    general->enable_by_default = EINA_FALSE;
366    general->dconf_preserve_name_prefixes = _config_string_list_new(dconf_preserve_name_prefixes);
367
368 }
369
370 static void
371 _config_general_free(struct _config_section *base)
372 {
373    struct _config_general *general = (struct _config_general *) base;
374
375    _config_section_free(general->hotkey);
376
377    _config_string_list_free(general->preload_engines);
378    _config_string_list_free(general->engines_order);
379    _config_string_list_free(general->dconf_preserve_name_prefixes);
380
381    eina_stringshare_del(general->version);
382    free(general);
383 }
384
385 static Eina_Bool
386 _config_general_set_value(struct _config_section *base, const char *section, const char *name, Eldbus_Message_Iter *value)
387 {
388    return EINA_FALSE;
389 }
390
391 static void *
392 _config_general_get_value(struct _config_section *base, const char *section, const char *name)
393 {
394    return NULL;
395 }
396
397 static void *
398 _config_general_get_values(struct _config_section *base, const char *section)
399 {
400    return NULL;
401 }
402
403 static void
404 _config_general_section_init(struct _config_section *base)
405 {
406    struct _config_general *general = (struct _config_general *) base;
407
408    base->id = eina_stringshare_add("general");
409    base->free = _config_general_free;
410    base->set_defaults = _config_general_set_defaults;
411    base->set_value = _config_general_set_value;
412    base->get_value = _config_general_get_value;
413    base->get_values = _config_general_get_values;
414
415    if (general->hotkey)
416       _config_hotkey_section_init(general->hotkey);
417 }
418
419 static struct _config_section *
420 _config_general_new(void)
421 {
422    struct _config_general *conf = calloc(1, sizeof(*conf));
423    _config_general_section_init((struct _config_section *) conf);
424    conf->hotkey = _config_hotkey_new();
425    return (struct _config_section *) conf;
426 }
427
428 /*
429  * <schema path="/desktop/ibus/panel/" id="org.freedesktop.ibus.panel">
430  *    <key type="i" name="show">
431  *      <default>0</default>
432  *      <summary>Auto hide</summary>
433  *      <description>The behavior of language panel. 0 = Embedded in menu, 1 = Auto hide, 2 = Always show</description>
434  *    </key>
435  *    <key type="i" name="x">
436  *      <default>-1</default>
437  *      <summary>Language panel position</summary>
438  *    </key>
439  *    <key type="i" name="y">
440  *      <default>-1</default>
441  *      <summary>Language panel position</summary>
442  *    </key>
443  *    <key type="i" name="lookup-table-orientation">
444  *      <default>1</default>
445  *      <summary>Orientation of lookup table</summary>
446  *      <description>Orientation of lookup table. 0 = Horizontal, 1 = Vertical</description>
447  *    </key>
448  *    <key type="b" name="show-icon-on-systray">
449  *      <default>true</default>
450  *      <summary>Show icon on system tray</summary>
451  *      <description>Show icon on system tray</description>
452  *    </key>
453  *    <key type="b" name="show-im-name">
454  *      <default>false</default>
455  *      <summary>Show input method name</summary>
456  *      <description>Show input method name on language bar</description>
457  *    </key>
458  *    <key type="b" name="use-custom-font">
459  *      <default>false</default>
460  *      <summary>Use custom font</summary>
461  *      <description>Use custom font name for language panel</description>
462  *    </key>
463  *    <key type="s" name="custom-font">
464  *      <default>'Sans 10'</default>
465  *      <summary>Custom font</summary>
466  *      <description>Custom font name for language panel</description>
467  *    </key>
468  * </schema>
469  */
470 struct _config_panel
471 {
472    struct _config_section base;
473
474    const char *custom_font;
475    int show;
476    int x;
477    int y;
478    int lookup_table_orientation;
479    Eina_Bool show_icon_in_systray;
480    Eina_Bool show_im_name;
481    Eina_Bool use_custom_font;
482 };
483
484 static Eet_Data_Descriptor *
485 _config_panel_edd_new(void)
486 {
487    Eet_Data_Descriptor *edd;
488    Eet_Data_Descriptor_Class eddc;
489
490    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, struct _config_panel);
491    edd = eet_data_descriptor_stream_new(&eddc);
492
493    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "show", show, EET_T_INT);
494    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "x", x, EET_T_INT);
495    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "y", y, EET_T_INT);
496    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "lookup-table-orientation", lookup_table_orientation, EET_T_INT);
497    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "show-icon-in-systray", show_icon_in_systray, EET_T_UCHAR);
498    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "show-im-name", show_im_name, EET_T_UCHAR);
499    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "use-custom-font", use_custom_font, EET_T_UCHAR);
500    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_panel, "custom-font", custom_font, EET_T_STRING);
501
502    return edd;
503 }
504
505 static void
506 _config_panel_set_defaults(struct _config_section *base)
507 {
508    struct _config_panel *panel = (struct _config_panel *) base;
509
510    panel->show = 0;
511    panel->x = -1;
512    panel->y = -1;
513    panel->lookup_table_orientation = 1;
514    panel->show_icon_in_systray = EINA_TRUE;
515    panel->show_im_name = EINA_FALSE;
516    panel->use_custom_font = EINA_FALSE;
517    panel->custom_font = eina_stringshare_add("Sans 10");
518 }
519
520 static void
521 _config_panel_free(struct _config_section *base)
522 {
523    struct _config_panel *panel = (struct _config_panel *) base;
524
525    eina_stringshare_del(panel->custom_font);
526    free(panel);
527 }
528
529 static Eina_Bool
530 _config_panel_set_value(struct _config_section *base, const char *section, const char *name, Eldbus_Message_Iter *value)
531 {
532    return EINA_FALSE;
533 }
534
535 static void *
536 _config_panel_get_value(struct _config_section *base, const char *section, const char *name)
537 {
538    return NULL;
539 }
540
541 static void *
542 _config_panel_get_values(struct _config_section *base, const char *section)
543 {
544    return NULL;
545 }
546
547 static void
548 _config_panel_section_init(struct _config_section *base)
549 {
550    base->id = eina_stringshare_add("panel");
551    base->free = _config_panel_free;
552    base->set_defaults = _config_panel_set_defaults;
553    base->set_value = _config_panel_set_value;
554    base->get_value = _config_panel_get_value;
555    base->get_values = _config_panel_get_values;
556 }
557
558 static struct _config_section *
559 _config_panel_new(void)
560 {
561    struct _config_panel *conf = calloc(1, sizeof(*conf));
562    _config_panel_section_init((struct _config_section *) conf);
563    return (struct _config_section *) conf;
564 }
565
566 /*
567  * NO SCHEMA AVAILABLE. BASED ON THE SOURCE CODE
568  */
569 struct _config_hangul
570 {
571    struct _config_section base;
572
573    const char *hangul_keyboard;
574    Eina_List *hanja_keys;
575    Eina_Bool word_commit;
576    Eina_Bool auto_reorder;
577 };
578
579 static Eet_Data_Descriptor *
580 _config_hangul_edd_new(void)
581 {
582    Eet_Data_Descriptor *edd;
583    Eet_Data_Descriptor_Class eddc;
584
585    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, struct _config_hangul);
586    edd = eet_data_descriptor_stream_new(&eddc);
587
588    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_hangul, "HangulKeyboard", hangul_keyboard, EET_T_STRING);
589    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct _config_hangul, "HanjaKeys", hanja_keys);
590    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_hangul, "WordCommit", word_commit, EET_T_UCHAR);
591    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct _config_hangul, "AutoReorder", auto_reorder, EET_T_UCHAR);
592
593    return edd;
594 }
595
596 static void
597 _config_hangul_set_defaults(struct _config_section *base)
598 {
599    struct _config_hangul *hangul = (struct _config_hangul *) base;
600    const char *hanja_keys[] = { "Hangul_Hanja", "F9", NULL };
601
602    hangul->hangul_keyboard = eina_stringshare_add("2");
603    hangul->hanja_keys = _config_string_list_new(hanja_keys);
604    hangul->word_commit = EINA_FALSE;
605    hangul->auto_reorder = EINA_TRUE;
606 }
607
608 static void
609 _config_hangul_free(struct _config_section *base)
610 {
611    struct _config_hangul *hangul = (struct _config_hangul *) base;
612
613    eina_stringshare_del(hangul->hangul_keyboard);
614    _config_string_list_free(hangul->hanja_keys);
615    free(hangul);
616 }
617
618 static Eina_Bool
619 _config_hangul_set_value(struct _config_section *base, const char *section, const char *name, Eldbus_Message_Iter *value)
620 {
621    return EINA_FALSE;
622 }
623
624 static void *
625 _config_hangul_get_value(struct _config_section *base, const char *section, const char *name)
626 {
627    return NULL;
628 }
629
630 static void *
631 _config_hangul_get_values(struct _config_section *base, const char *section)
632 {
633    return NULL;
634 }
635
636 static void
637 _config_hangul_section_init(struct _config_section *base)
638 {
639    base->id = eina_stringshare_add("hangul");
640    base->free = _config_hangul_free;
641    base->set_defaults = _config_hangul_set_defaults;
642    base->set_value = _config_hangul_set_value;
643    base->get_value = _config_hangul_get_value;
644    base->get_values = _config_hangul_get_values;
645 }
646
647 static struct _config_section *
648 _config_hangul_new(void)
649 {
650    struct _config_hangul *conf = calloc(1, sizeof(*conf));
651    _config_hangul_section_init((struct _config_section *) conf);
652    return (struct _config_section *) conf;
653 }
654
655 /*
656  * NO SCHEMA AVAILABLE. BASED ON THE SOURCE CODE
657  */
658 struct _config_engine
659 {
660    struct _config_section base;
661
662    struct _config_section *hangul;
663 };
664
665 static Eet_Data_Descriptor *
666 _config_engine_edd_new(Eet_Data_Descriptor *hangul_edd)
667 {
668    Eet_Data_Descriptor *edd;
669    Eet_Data_Descriptor_Class eddc;
670
671    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, struct _config_engine);
672    edd = eet_data_descriptor_stream_new(&eddc);
673
674    EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct _config_engine, "Hangul", hangul, hangul_edd);
675
676    return edd;
677 }
678
679 static void
680 _config_engine_set_defaults(struct _config_section *base)
681 {
682    struct _config_engine *engine = (struct _config_engine *) base;
683
684    _config_section_set_defaults(engine->hangul);
685 }
686
687 static void
688 _config_engine_free(struct _config_section *base)
689 {
690    struct _config_engine *engine = (struct _config_engine *) base;
691
692    _config_section_free(engine->hangul);
693    free(engine);
694 }
695
696 static Eina_Bool
697 _config_engine_set_value(struct _config_section *base, const char *section, const char *name, Eldbus_Message_Iter *value)
698 {
699    return EINA_FALSE;
700 }
701
702 static void *
703 _config_engine_get_value(struct _config_section *base, const char *section, const char *name)
704 {
705    return NULL;
706 }
707
708 static void *
709 _config_engine_get_values(struct _config_section *base, const char *section)
710 {
711    return NULL;
712 }
713
714 static void
715 _config_engine_section_init(struct _config_section *base)
716 {
717    struct _config_engine *engine = (struct _config_engine *) base;
718
719    base->id = eina_stringshare_add("engine");
720    base->free = _config_engine_free;
721    base->set_defaults = _config_engine_set_defaults;
722    base->set_value = _config_engine_set_value;
723    base->get_value = _config_engine_get_value;
724    base->get_values = _config_engine_get_values;
725
726    if (engine->hangul)
727       _config_hangul_section_init(engine->hangul);
728 }
729
730 static struct _config_section *
731 _config_engine_new(void)
732 {
733    struct _config_engine *conf = calloc(1, sizeof(*conf));
734    _config_engine_section_init((struct _config_section *) conf);
735    conf->hangul = _config_hangul_new();
736    return (struct _config_section *) conf;
737 }
738
739 /*
740  * <schema path="/desktop/ibus/" id="org.freedesktop.ibus">
741  *    <child schema="org.freedesktop.ibus.general" name="general"/>
742  *    <child schema="org.freedesktop.ibus.panel" name="panel"/>
743  * </schema>
744  */
745 struct _config_ibus
746 {
747    struct _config_section base;
748
749    struct _config_section *general;
750    struct _config_section *panel;
751    struct _config_section *engine;
752 };
753
754 static Eet_Data_Descriptor *
755 _config_ibus_edd_new(Eet_Data_Descriptor *general_edd, Eet_Data_Descriptor *panel_edd, Eet_Data_Descriptor *engine_edd)
756 {
757    Eet_Data_Descriptor *edd;
758    Eet_Data_Descriptor_Class eddc;
759
760    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, struct _config_ibus);
761    edd = eet_data_descriptor_stream_new(&eddc);
762
763    EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct _config_ibus, "general", general, general_edd);
764    EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct _config_ibus, "panel", panel, panel_edd);
765    EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct _config_ibus, "engine", engine, engine_edd);
766
767    return edd;
768 }
769
770 static void
771 _config_ibus_set_defaults(struct _config_section *base)
772 {
773    struct _config_ibus *ibus = (struct _config_ibus *) base;
774
775    _config_section_set_defaults(ibus->general);
776    _config_section_set_defaults(ibus->panel);
777    _config_section_set_defaults(ibus->engine);
778 }
779
780 static void
781 _config_ibus_free(struct _config_section *base)
782 {
783    struct _config_ibus *ibus = (struct _config_ibus *) base;
784
785    _config_section_free(ibus->general);
786    _config_section_free(ibus->panel);
787    _config_section_free(ibus->engine);
788
789    free(ibus);
790 }
791
792 static Eina_Bool
793 _config_ibus_set_value(struct _config_section *base, const char *section, const char *name, Eldbus_Message_Iter *value)
794 {
795    return EINA_FALSE;
796 }
797
798 static void *
799 _config_ibus_get_value(struct _config_section *base, const char *section, const char *name)
800 {
801    return NULL;
802 }
803
804 static void *
805 _config_ibus_get_values(struct _config_section *base, const char *section)
806 {
807    return NULL;
808 }
809
810 static void
811 _config_ibus_section_init(struct _config_section *base)
812 {
813    struct _config_ibus *ibus = (struct _config_ibus *) base;
814    base->id = eina_stringshare_add("ibus");
815    base->free = _config_ibus_free;
816    base->set_defaults = _config_ibus_set_defaults;
817    base->set_value = _config_ibus_set_value;
818    base->get_value = _config_ibus_get_value;
819    base->get_values = _config_ibus_get_values;
820
821    if (ibus->general)
822       _config_general_section_init(ibus->general);
823
824    if (ibus->panel)
825       _config_panel_section_init(ibus->panel);
826
827    if (ibus->engine)
828       _config_engine_section_init(ibus->engine);
829 }
830
831 static struct _config_section *
832 _config_ibus_new(void)
833 {
834    struct _config_ibus *conf = calloc(1, sizeof(*conf));
835    _config_ibus_section_init((struct _config_section *) conf);
836    conf->general = _config_general_new();
837    conf->panel = _config_panel_new();
838    conf->engine = _config_engine_new();
839    return (struct _config_section *) conf;
840 }
841
842 /*
843  * MAIN
844  */
845 struct wkb_ibus_config_eet
846 {
847    const char *path;
848    struct _config_section *ibus_config;
849
850    Eet_Data_Descriptor *hotkey_edd;
851    Eet_Data_Descriptor *general_edd;
852    Eet_Data_Descriptor *panel_edd;
853    Eet_Data_Descriptor *hangul_edd;
854    Eet_Data_Descriptor *engine_edd;
855    Eet_Data_Descriptor *ibus_edd;
856 };
857
858 Eina_Bool
859 wkb_ibus_config_eet_set_value(struct wkb_ibus_config_eet *config_eet, const char *section, const char *name, Eldbus_Message_Iter *value)
860 {
861    return _config_section_set_value(config_eet->ibus_config, section, name, value);
862 }
863
864 void *
865 wkb_ibus_config_eet_get_value(struct wkb_ibus_config_eet *config_eet, const char *section, const char *name)
866 {
867    return _config_section_get_value(config_eet->ibus_config, section, name);
868 }
869
870 void *
871 wkb_ibus_config_eet_get_values(struct wkb_ibus_config_eet *config_eet, const char *section)
872 {
873    return _config_section_get_values(config_eet->ibus_config, section);
874 }
875
876 void
877 wkb_ibus_config_eet_set_defaults(struct wkb_ibus_config_eet *config_eet)
878 {
879
880    if (config_eet->ibus_config)
881       _config_section_free(config_eet->ibus_config);
882
883    config_eet->ibus_config = _config_ibus_new();
884    _config_ibus_set_defaults(config_eet->ibus_config);
885 }
886
887 static struct wkb_ibus_config_eet *
888 _config_eet_section_init(const char *path)
889 {
890    struct wkb_ibus_config_eet *eet = calloc(1, sizeof(*eet));
891    eet->path = eina_stringshare_add(path);
892
893    eet->hotkey_edd = _config_hotkey_edd_new();
894    eet->general_edd = _config_general_edd_new(eet->hotkey_edd);
895    eet->panel_edd = _config_panel_edd_new();
896    eet->hangul_edd = _config_hangul_edd_new();
897    eet->engine_edd = _config_engine_edd_new(eet->hangul_edd);
898    eet->ibus_edd = _config_ibus_edd_new(eet->general_edd, eet->panel_edd, eet->engine_edd);
899
900    return eet;
901 }
902
903 static Eina_Bool
904 _config_eet_exists(const char *path)
905 {
906    struct stat buf;
907    return stat(path, &buf) == 0;
908 }
909
910 struct wkb_ibus_config_eet *
911 wkb_ibus_config_eet_new(const char *path)
912 {
913    struct wkb_ibus_config_eet *eet = _config_eet_section_init(path);
914    Eet_File *ef = NULL;
915    Eet_File_Mode mode = EET_FILE_MODE_READ_WRITE;
916
917    if (_config_eet_exists(path))
918       mode = EET_FILE_MODE_READ;
919
920    if (!(ef = eet_open(path, mode)))
921      {
922         fprintf(stderr,"Error opening eet file '%s' for %s\n", path, mode == EET_FILE_MODE_READ ? "read" : "write");
923         wkb_ibus_config_eet_free(eet);
924         return NULL;
925      }
926
927    if (mode == EET_FILE_MODE_READ)
928      {
929         eet->ibus_config = eet_data_read(ef, eet->ibus_edd, "ibus");
930         _config_ibus_section_init(eet->ibus_config);
931         goto end;
932      }
933
934    wkb_ibus_config_eet_set_defaults(eet);
935    if (!eet_data_write(ef, eet->ibus_edd, "ibus", eet->ibus_config, EINA_TRUE))
936      {
937         fprintf(stderr,"Error creating eet file '%s'\n", path);
938         wkb_ibus_config_eet_free(eet);
939         eet = NULL;
940      }
941
942 end:
943    eet_close(ef);
944    return eet;
945 }
946
947 void
948 wkb_ibus_config_eet_free(struct wkb_ibus_config_eet *config_eet)
949 {
950    _config_ibus_free(config_eet->ibus_config);
951    eina_stringshare_del(config_eet->path);
952
953    eet_data_descriptor_free(config_eet->hotkey_edd);
954    eet_data_descriptor_free(config_eet->general_edd);
955    eet_data_descriptor_free(config_eet->panel_edd);
956    eet_data_descriptor_free(config_eet->hangul_edd);
957    eet_data_descriptor_free(config_eet->engine_edd);
958    eet_data_descriptor_free(config_eet->ibus_edd);
959
960    free(config_eet);
961 }