1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* bus - The Input Bus
4 * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2019 Red Hat, Inc.
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.1 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 Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20 * USA
21 */
22 #include <stdlib.h>
23 #include "ibusenginedesc.h"
24 #include "ibusinternal.h"
25 #include "ibusxml.h"
26
27 enum {
28 LAST_SIGNAL,
29 };
30
31 enum {
32 PROP_0 = 0,
33 PROP_NAME,
34 PROP_LONGNAME,
35 PROP_DESCRIPTION,
36 PROP_LANGUAGE,
37 PROP_LICENSE,
38 PROP_AUTHOR,
39 PROP_ICON,
40 PROP_LAYOUT,
41 PROP_LAYOUT_VARIANT,
42 PROP_LAYOUT_OPTION,
43 PROP_RANK,
44 PROP_HOTKEYS,
45 PROP_SYMBOL,
46 PROP_SETUP,
47 PROP_VERSION,
48 PROP_TEXTDOMAIN,
49 PROP_ICON_PROP_KEY
50 };
51
52
53 /* IBusEngineDescPriv */
54 struct _IBusEngineDescPrivate {
55 gchar *name;
56 gchar *longname;
57 gchar *description;
58 gchar *language;
59 gchar *license;
60 gchar *author;
61 gchar *icon;
62 gchar *layout;
63 gchar *layout_variant;
64 gchar *layout_option;
65 guint rank;
66 gchar *hotkeys;
67 gchar *symbol;
68 gchar *setup;
69 gchar *version;
70 gchar *textdomain;
71 gchar *icon_prop_key;
72 };
73
74 #define IBUS_ENGINE_DESC_GET_PRIVATE(o) \
75 ((IBusEngineDescPrivate *)ibus_engine_desc_get_instance_private (o))
76
77 // static guint _signals[LAST_SIGNAL] = { 0 };
78
79 /* functions prototype */
80 static void ibus_engine_desc_set_property (IBusEngineDesc *desc,
81 guint prop_id,
82 const GValue *value,
83 GParamSpec *pspec);
84 static void ibus_engine_desc_get_property (IBusEngineDesc *desc,
85 guint prop_id,
86 GValue *value,
87 GParamSpec *pspec);
88 static void ibus_engine_desc_destroy (IBusEngineDesc *desc);
89 static gboolean ibus_engine_desc_serialize (IBusEngineDesc *desc,
90 GVariantBuilder *builder);
91 static gint ibus_engine_desc_deserialize (IBusEngineDesc *desc,
92 GVariant *variant);
93 static gboolean ibus_engine_desc_copy (IBusEngineDesc *dest,
94 const IBusEngineDesc *src);
95 static gboolean ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc,
96 XMLNode *node);
97
G_DEFINE_TYPE_WITH_PRIVATE(IBusEngineDesc,ibus_engine_desc,IBUS_TYPE_SERIALIZABLE)98 G_DEFINE_TYPE_WITH_PRIVATE (IBusEngineDesc,
99 ibus_engine_desc,
100 IBUS_TYPE_SERIALIZABLE)
101
102
103 static void
104 ibus_engine_desc_class_init (IBusEngineDescClass *class)
105 {
106 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
107 IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
108 IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
109
110 gobject_class->set_property = (GObjectSetPropertyFunc) ibus_engine_desc_set_property;
111 gobject_class->get_property = (GObjectGetPropertyFunc) ibus_engine_desc_get_property;
112 object_class->destroy = (IBusObjectDestroyFunc) ibus_engine_desc_destroy;
113
114 serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_engine_desc_serialize;
115 serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_engine_desc_deserialize;
116 serializable_class->copy = (IBusSerializableCopyFunc) ibus_engine_desc_copy;
117
118 /* install properties */
119 /**
120 * IBusEngineDesc:name:
121 *
122 * The name of engine description
123 */
124 g_object_class_install_property (gobject_class,
125 PROP_NAME,
126 g_param_spec_string ("name",
127 "description name",
128 "The name of engine description",
129 NULL,
130 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
131
132 /**
133 * IBusEngineDesc:longname:
134 *
135 * The longname of engine description
136 */
137 g_object_class_install_property (gobject_class,
138 PROP_LONGNAME,
139 g_param_spec_string ("longname",
140 "description longname",
141 "The longname of engine description",
142 "",
143 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
144
145 /**
146 * IBusEngineDesc:description:
147 *
148 * The description of engine description
149 */
150 g_object_class_install_property (gobject_class,
151 PROP_DESCRIPTION,
152 g_param_spec_string ("description",
153 "description description",
154 "The description of engine description",
155 "",
156 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
157
158 /**
159 * IBusEngineDesc:language:
160 *
161 * The language of engine description
162 */
163 g_object_class_install_property (gobject_class,
164 PROP_LANGUAGE,
165 g_param_spec_string ("language",
166 "description language",
167 "The language of engine description",
168 "",
169 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
170
171 /**
172 * IBusEngineDesc:license:
173 *
174 * The license of engine description
175 */
176 g_object_class_install_property (gobject_class,
177 PROP_LICENSE,
178 g_param_spec_string ("license",
179 "description license",
180 "The license of engine description",
181 "",
182 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
183
184 /**
185 * IBusEngineDesc:author:
186 *
187 * The author of engine description
188 */
189 g_object_class_install_property (gobject_class,
190 PROP_AUTHOR,
191 g_param_spec_string ("author",
192 "description author",
193 "The author of engine description",
194 "",
195 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
196
197 /**
198 * IBusEngineDesc:icon:
199 *
200 * The icon of engine description
201 */
202 g_object_class_install_property (gobject_class,
203 PROP_ICON,
204 g_param_spec_string ("icon",
205 "description icon",
206 "The icon of engine description",
207 "ibus-engine",
208 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
209
210 /**
211 * IBusEngineDesc:layout:
212 *
213 * The layout of engine description
214 */
215 g_object_class_install_property (gobject_class,
216 PROP_LAYOUT,
217 g_param_spec_string ("layout",
218 "description layout",
219 "The layout of engine description",
220 "us",
221 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
222
223 /**
224 * IBusEngineDesc:layout-variant:
225 *
226 * The keyboard variant of engine description
227 */
228 g_object_class_install_property (gobject_class,
229 PROP_LAYOUT_VARIANT,
230 g_param_spec_string ("layout-variant",
231 "description keyboard variant",
232 "The keyboard variant of engine description",
233 "",
234 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
235
236 /**
237 * IBusEngineDesc:layout-option:
238 *
239 * The keyboard option of engine description
240 */
241 g_object_class_install_property (gobject_class,
242 PROP_LAYOUT_OPTION,
243 g_param_spec_string ("layout-option",
244 "description keyboard option",
245 "The keyboard option of engine description",
246 "",
247 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
248
249 /**
250 * IBusEngineDesc:rank:
251 *
252 * The rank of engine description
253 */
254 g_object_class_install_property (gobject_class,
255 PROP_RANK,
256 g_param_spec_uint ("rank",
257 "description rank",
258 "The rank of engine description",
259 0,
260 G_MAXUINT,
261 0,
262 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
263
264 /**
265 * IBusEngineDesc:hotkeys:
266 *
267 * The hotkeys of engine description
268 */
269 g_object_class_install_property (gobject_class,
270 PROP_HOTKEYS,
271 g_param_spec_string ("hotkeys",
272 "description hotkeys",
273 "The hotkeys of engine description",
274 "",
275 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
276
277 /**
278 * IBusEngineDesc:symbol:
279 *
280 * The symbol chars of engine description instead of icon image
281 */
282 g_object_class_install_property (gobject_class,
283 PROP_SYMBOL,
284 g_param_spec_string ("symbol",
285 "description symbol",
286 "The icon symbol chars of engine description",
287 "",
288 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
289
290 /**
291 * IBusEngineDesc:setup:
292 *
293 * The exec lists of the engine setup command
294 */
295 g_object_class_install_property (gobject_class,
296 PROP_SETUP,
297 g_param_spec_string ("setup",
298 "setup args",
299 "The exec lists of the engine setup command",
300 "",
301 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
302
303 /**
304 * IBusEngineDesc:version:
305 *
306 * The version number of engine description
307 */
308 g_object_class_install_property (gobject_class,
309 PROP_VERSION,
310 g_param_spec_string ("version",
311 "version number",
312 "The version number of engine description",
313 "",
314 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
315
316 /**
317 * IBusEngineDesc:textdomain:
318 *
319 * The textdomain of engine description
320 */
321 g_object_class_install_property (gobject_class,
322 PROP_TEXTDOMAIN,
323 g_param_spec_string ("textdomain",
324 "textdomain",
325 "The textdomain of engine description",
326 "",
327 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
328
329 /**
330 * IBusEngineDesc:icon-prop-key:
331 *
332 * The key of IBusProperty to change panel icon dynamically.
333 */
334 g_object_class_install_property (gobject_class,
335 PROP_ICON_PROP_KEY,
336 g_param_spec_string ("icon-prop-key",
337 "icon property key",
338 "The key of IBusProperty for the dynamic panel icon",
339 "",
340 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
341 }
342
343 static void
ibus_engine_desc_init(IBusEngineDesc * desc)344 ibus_engine_desc_init (IBusEngineDesc *desc)
345 {
346 desc->priv = IBUS_ENGINE_DESC_GET_PRIVATE (desc);
347
348 desc->priv->name = NULL;
349 desc->priv->longname = NULL;
350 desc->priv->description = NULL;
351 desc->priv->language = NULL;
352 desc->priv->license = NULL;
353 desc->priv->author = NULL;
354 desc->priv->icon = NULL;
355 desc->priv->layout = NULL;
356 desc->priv->layout_variant = NULL;
357 desc->priv->layout_option = NULL;
358 desc->priv->rank = 0;
359 desc->priv->hotkeys = NULL;
360 desc->priv->symbol = NULL;
361 desc->priv->setup = NULL;
362 desc->priv->version = NULL;
363 desc->priv->textdomain = NULL;
364 desc->priv->icon_prop_key = NULL;
365 }
366
367 static void
ibus_engine_desc_destroy(IBusEngineDesc * desc)368 ibus_engine_desc_destroy (IBusEngineDesc *desc)
369 {
370 g_free (desc->priv->name);
371 g_free (desc->priv->longname);
372 g_free (desc->priv->description);
373 g_free (desc->priv->language);
374 g_free (desc->priv->license);
375 g_free (desc->priv->author);
376 g_free (desc->priv->icon);
377 g_free (desc->priv->layout);
378 g_free (desc->priv->layout_variant);
379 g_free (desc->priv->layout_option);
380 g_free (desc->priv->hotkeys);
381 g_free (desc->priv->symbol);
382 g_free (desc->priv->setup);
383 g_free (desc->priv->version);
384 g_free (desc->priv->textdomain);
385 g_free (desc->priv->icon_prop_key);
386
387 IBUS_OBJECT_CLASS (ibus_engine_desc_parent_class)->destroy (IBUS_OBJECT (desc));
388 }
389
390 static void
ibus_engine_desc_set_property(IBusEngineDesc * desc,guint prop_id,const GValue * value,GParamSpec * pspec)391 ibus_engine_desc_set_property (IBusEngineDesc *desc,
392 guint prop_id,
393 const GValue *value,
394 GParamSpec *pspec)
395 {
396 switch (prop_id) {
397 case PROP_NAME:
398 g_assert (desc->priv->name == NULL);
399 desc->priv->name = g_value_dup_string (value);
400 break;
401 case PROP_LONGNAME:
402 g_assert (desc->priv->longname == NULL);
403 desc->priv->longname = g_value_dup_string (value);
404 break;
405 case PROP_DESCRIPTION:
406 g_assert (desc->priv->description == NULL);
407 desc->priv->description = g_value_dup_string (value);
408 break;
409 case PROP_LANGUAGE:
410 g_assert (desc->priv->language == NULL);
411 desc->priv->language = g_value_dup_string (value);
412 break;
413 case PROP_LICENSE:
414 g_assert (desc->priv->license == NULL);
415 desc->priv->license = g_value_dup_string (value);
416 break;
417 case PROP_AUTHOR:
418 g_assert (desc->priv->author == NULL);
419 desc->priv->author = g_value_dup_string (value);
420 break;
421 case PROP_ICON:
422 g_assert (desc->priv->icon == NULL);
423 desc->priv->icon = g_value_dup_string (value);
424 break;
425 case PROP_LAYOUT:
426 g_assert (desc->priv->layout == NULL);
427 desc->priv->layout = g_value_dup_string (value);
428 break;
429 case PROP_LAYOUT_VARIANT:
430 g_assert (desc->priv->layout_variant == NULL);
431 desc->priv->layout_variant = g_value_dup_string (value);
432 break;
433 case PROP_LAYOUT_OPTION:
434 g_assert (desc->priv->layout_option == NULL);
435 desc->priv->layout_option = g_value_dup_string (value);
436 break;
437 case PROP_RANK:
438 desc->priv->rank = g_value_get_uint (value);
439 break;
440 case PROP_HOTKEYS:
441 g_assert (desc->priv->hotkeys == NULL);
442 desc->priv->hotkeys = g_value_dup_string (value);
443 break;
444 case PROP_SYMBOL:
445 g_assert (desc->priv->symbol == NULL);
446 desc->priv->symbol = g_value_dup_string (value);
447 break;
448 case PROP_SETUP:
449 g_assert (desc->priv->setup == NULL);
450 desc->priv->setup = g_value_dup_string (value);
451 break;
452 case PROP_VERSION:
453 g_assert (desc->priv->version == NULL);
454 desc->priv->version = g_value_dup_string (value);
455 break;
456 case PROP_TEXTDOMAIN:
457 g_assert (desc->priv->textdomain == NULL);
458 desc->priv->textdomain = g_value_dup_string (value);
459 break;
460 case PROP_ICON_PROP_KEY:
461 g_assert (desc->priv->icon_prop_key == NULL);
462 desc->priv->icon_prop_key = g_value_dup_string (value);
463 break;
464 default:
465 G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec);
466 }
467 }
468
469 static void
ibus_engine_desc_get_property(IBusEngineDesc * desc,guint prop_id,GValue * value,GParamSpec * pspec)470 ibus_engine_desc_get_property (IBusEngineDesc *desc,
471 guint prop_id,
472 GValue *value,
473 GParamSpec *pspec)
474 {
475 switch (prop_id) {
476 case PROP_NAME:
477 g_value_set_string (value, ibus_engine_desc_get_name (desc));
478 break;
479 case PROP_LONGNAME:
480 g_value_set_string (value, ibus_engine_desc_get_longname (desc));
481 break;
482 case PROP_DESCRIPTION:
483 g_value_set_string (value, ibus_engine_desc_get_description (desc));
484 break;
485 case PROP_LANGUAGE:
486 g_value_set_string (value, ibus_engine_desc_get_language (desc));
487 break;
488 case PROP_LICENSE:
489 g_value_set_string (value, ibus_engine_desc_get_license (desc));
490 break;
491 case PROP_AUTHOR:
492 g_value_set_string (value, ibus_engine_desc_get_author (desc));
493 break;
494 case PROP_ICON:
495 g_value_set_string (value, ibus_engine_desc_get_icon (desc));
496 break;
497 case PROP_LAYOUT:
498 g_value_set_string (value, ibus_engine_desc_get_layout (desc));
499 break;
500 case PROP_LAYOUT_VARIANT:
501 g_value_set_string (value, ibus_engine_desc_get_layout_variant (desc));
502 break;
503 case PROP_LAYOUT_OPTION:
504 g_value_set_string (value, ibus_engine_desc_get_layout_option (desc));
505 break;
506 case PROP_RANK:
507 g_value_set_uint (value, ibus_engine_desc_get_rank (desc));
508 break;
509 case PROP_HOTKEYS:
510 g_value_set_string (value, ibus_engine_desc_get_hotkeys (desc));
511 break;
512 case PROP_SYMBOL:
513 g_value_set_string (value, ibus_engine_desc_get_symbol (desc));
514 break;
515 case PROP_SETUP:
516 g_value_set_string (value, ibus_engine_desc_get_setup (desc));
517 break;
518 case PROP_VERSION:
519 g_value_set_string (value, ibus_engine_desc_get_version (desc));
520 break;
521 case PROP_TEXTDOMAIN:
522 g_value_set_string (value, ibus_engine_desc_get_textdomain (desc));
523 break;
524 case PROP_ICON_PROP_KEY:
525 g_value_set_string (value, ibus_engine_desc_get_icon_prop_key (desc));
526 break;
527 default:
528 G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec);
529 }
530 }
531
532 static gboolean
ibus_engine_desc_serialize(IBusEngineDesc * desc,GVariantBuilder * builder)533 ibus_engine_desc_serialize (IBusEngineDesc *desc,
534 GVariantBuilder *builder)
535 {
536 gboolean retval;
537
538 retval = IBUS_SERIALIZABLE_CLASS (ibus_engine_desc_parent_class)->serialize ((IBusSerializable *)desc, builder);
539 g_return_val_if_fail (retval, FALSE);
540 /* End dict iter */
541
542 #define NOTNULL(s) ((s) != NULL ? (s) : "")
543 /* If you will add a new property, you can append it at the end and
544 * you should not change the serialized order of name, longname,
545 * description, ... because the order is also used in other applications
546 * likes ibus-qt. */
547 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->name));
548 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->longname));
549 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->description));
550 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->language));
551 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->license));
552 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->author));
553 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->icon));
554 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->layout));
555 g_variant_builder_add (builder, "u", desc->priv->rank);
556 /* The serialized order should be kept. */
557 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->hotkeys));
558 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->symbol));
559 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->setup));
560 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->layout_variant));
561 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->layout_option));
562 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->version));
563 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->textdomain));
564 g_variant_builder_add (builder, "s", NOTNULL (desc->priv->icon_prop_key));
565 #undef NOTNULL
566
567 return TRUE;
568 }
569
570 static gint
ibus_engine_desc_deserialize(IBusEngineDesc * desc,GVariant * variant)571 ibus_engine_desc_deserialize (IBusEngineDesc *desc,
572 GVariant *variant)
573 {
574 gint retval;
575
576 retval = IBUS_SERIALIZABLE_CLASS (ibus_engine_desc_parent_class)->deserialize ((IBusSerializable *)desc, variant);
577 g_return_val_if_fail (retval, 0);
578
579 /* If you will add a new property, you can append it at the end and
580 * you should not change the serialized order of name, longname,
581 * description, ... because the order is also used in other applications
582 * likes ibus-qt. */
583 ibus_g_variant_get_child_string (variant, retval++,
584 &desc->priv->name);
585 ibus_g_variant_get_child_string (variant, retval++,
586 &desc->priv->longname);
587 ibus_g_variant_get_child_string (variant, retval++,
588 &desc->priv->description);
589 ibus_g_variant_get_child_string (variant, retval++,
590 &desc->priv->language);
591 ibus_g_variant_get_child_string (variant, retval++,
592 &desc->priv->license);
593 ibus_g_variant_get_child_string (variant, retval++,
594 &desc->priv->author);
595 ibus_g_variant_get_child_string (variant, retval++,
596 &desc->priv->icon);
597 ibus_g_variant_get_child_string (variant, retval++,
598 &desc->priv->layout);
599 g_variant_get_child (variant, retval++, "u", &desc->priv->rank);
600 /* The serialized order should be kept. */
601 ibus_g_variant_get_child_string (variant, retval++,
602 &desc->priv->hotkeys);
603 ibus_g_variant_get_child_string (variant, retval++,
604 &desc->priv->symbol);
605 ibus_g_variant_get_child_string (variant, retval++,
606 &desc->priv->setup);
607 if (g_variant_n_children (variant) < retval + 2)
608 return retval;
609 ibus_g_variant_get_child_string (variant, retval++,
610 &desc->priv->layout_variant);
611 ibus_g_variant_get_child_string (variant, retval++,
612 &desc->priv->layout_option);
613 if (g_variant_n_children (variant) < retval + 1)
614 return retval;
615 ibus_g_variant_get_child_string (variant, retval++,
616 &desc->priv->version);
617 if (g_variant_n_children (variant) < retval + 1)
618 return retval;
619 ibus_g_variant_get_child_string (variant, retval++,
620 &desc->priv->textdomain);
621 if (g_variant_n_children (variant) < retval + 1)
622 return retval;
623 ibus_g_variant_get_child_string (variant, retval++,
624 &desc->priv->icon_prop_key);
625
626 return retval;
627 }
628
629 static gboolean
ibus_engine_desc_copy(IBusEngineDesc * dest,const IBusEngineDesc * src)630 ibus_engine_desc_copy (IBusEngineDesc *dest,
631 const IBusEngineDesc *src)
632 {
633 gboolean retval;
634
635 retval = IBUS_SERIALIZABLE_CLASS (ibus_engine_desc_parent_class)->copy ((IBusSerializable *)dest,
636 (IBusSerializable *)src);
637 g_return_val_if_fail (retval, FALSE);
638
639 dest->priv->name = g_strdup (src->priv->name);
640 dest->priv->longname = g_strdup (src->priv->longname);
641 dest->priv->description = g_strdup (src->priv->description);
642 dest->priv->language = g_strdup (src->priv->language);
643 dest->priv->license = g_strdup (src->priv->license);
644 dest->priv->author = g_strdup (src->priv->author);
645 dest->priv->icon = g_strdup (src->priv->icon);
646 dest->priv->layout = g_strdup (src->priv->layout);
647 dest->priv->layout_variant = g_strdup (src->priv->layout_variant);
648 dest->priv->layout_option = g_strdup (src->priv->layout_option);
649 dest->priv->rank = src->priv->rank;
650 dest->priv->hotkeys = g_strdup (src->priv->hotkeys);
651 dest->priv->symbol = g_strdup (src->priv->symbol);
652 dest->priv->setup = g_strdup (src->priv->setup);
653 dest->priv->version = g_strdup (src->priv->version);
654 dest->priv->textdomain = g_strdup (src->priv->textdomain);
655 dest->priv->icon_prop_key = g_strdup (src->priv->icon_prop_key);
656 return TRUE;
657 }
658
659 #define g_string_append_indent(string, indent) \
660 { \
661 gint i; \
662 for (i = 0; i < (indent); i++) { \
663 g_string_append (string, " "); \
664 } \
665 }
666
667 void
ibus_engine_desc_output(IBusEngineDesc * desc,GString * output,gint indent)668 ibus_engine_desc_output (IBusEngineDesc *desc,
669 GString *output,
670 gint indent)
671 {
672 g_string_append_indent (output, indent);
673 g_string_append (output, "<engine>\n");
674 #define OUTPUT_ENTRY(field, element) \
675 { \
676 gchar *escape_text = g_markup_escape_text ( \
677 desc->priv->field ? desc->priv->field : "", -1); \
678 g_string_append_indent (output, indent + 1); \
679 g_string_append_printf (output, "<"element">%s</"element">\n", \
680 escape_text); \
681 g_free (escape_text); \
682 }
683 #define OUTPUT_ENTRY_1(name) OUTPUT_ENTRY(name, #name)
684 OUTPUT_ENTRY_1(name);
685 OUTPUT_ENTRY_1(longname);
686 OUTPUT_ENTRY_1(description);
687 OUTPUT_ENTRY_1(language);
688 OUTPUT_ENTRY_1(license);
689 OUTPUT_ENTRY_1(author);
690 OUTPUT_ENTRY_1(icon);
691 OUTPUT_ENTRY_1(layout);
692 OUTPUT_ENTRY_1(layout_variant);
693 OUTPUT_ENTRY_1(layout_option);
694 OUTPUT_ENTRY_1(hotkeys);
695 OUTPUT_ENTRY_1(symbol);
696 OUTPUT_ENTRY_1(setup);
697 OUTPUT_ENTRY_1(version);
698 OUTPUT_ENTRY_1(textdomain);
699 OUTPUT_ENTRY_1(icon_prop_key);
700 g_string_append_indent (output, indent + 1);
701 g_string_append_printf (output, "<rank>%u</rank>\n", desc->priv->rank);
702 #undef OUTPUT_ENTRY
703 #undef OUTPUT_ENTRY_1
704 g_string_append_indent (output, indent);
705 g_string_append (output, "</engine>\n");
706 }
707
708 static gboolean
ibus_engine_desc_parse_xml_node(IBusEngineDesc * desc,XMLNode * node)709 ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc,
710 XMLNode *node)
711 {
712 GList *p;
713
714 for (p = node->sub_nodes; p != NULL; p = p->next) {
715 XMLNode *sub_node = (XMLNode *) p->data;
716
717 #define PARSE_ENTRY(field_name, element_name) \
718 if (g_strcmp0 (sub_node->name, element_name) == 0) { \
719 g_free (desc->priv->field_name); \
720 desc->priv->field_name = g_strdup (sub_node->text); \
721 continue; \
722 }
723 #define PARSE_ENTRY_1(name) PARSE_ENTRY(name, #name)
724 PARSE_ENTRY_1(name);
725 PARSE_ENTRY_1(longname);
726 PARSE_ENTRY_1(description);
727 PARSE_ENTRY_1(language);
728 PARSE_ENTRY_1(license);
729 PARSE_ENTRY_1(author);
730 PARSE_ENTRY_1(icon);
731 PARSE_ENTRY_1(layout);
732 PARSE_ENTRY_1(layout_variant);
733 PARSE_ENTRY_1(layout_option);
734 PARSE_ENTRY_1(hotkeys);
735 PARSE_ENTRY_1(symbol);
736 PARSE_ENTRY_1(setup);
737 PARSE_ENTRY_1(version);
738 PARSE_ENTRY_1(textdomain);
739 PARSE_ENTRY_1(icon_prop_key);
740 #undef PARSE_ENTRY
741 #undef PARSE_ENTRY_1
742 if (g_strcmp0 (sub_node->name , "rank") == 0) {
743 desc->priv->rank = atoi (sub_node->text);
744 continue;
745 }
746 g_warning ("<engines> element contains invalidate element <%s>", sub_node->name);
747 }
748 return TRUE;
749 }
750
751 #define IBUS_ENGINE_DESC_GET_PROPERTY(property, return_type) \
752 return_type \
753 ibus_engine_desc_get_ ## property (IBusEngineDesc *desc) \
754 { \
755 return desc->priv->property; \
756 }
757
IBUS_ENGINE_DESC_GET_PROPERTY(name,const gchar *)758 IBUS_ENGINE_DESC_GET_PROPERTY (name, const gchar *)
759 IBUS_ENGINE_DESC_GET_PROPERTY (longname, const gchar *)
760 IBUS_ENGINE_DESC_GET_PROPERTY (description, const gchar *)
761 IBUS_ENGINE_DESC_GET_PROPERTY (language, const gchar *)
762 IBUS_ENGINE_DESC_GET_PROPERTY (license, const gchar *)
763 IBUS_ENGINE_DESC_GET_PROPERTY (author, const gchar *)
764 IBUS_ENGINE_DESC_GET_PROPERTY (icon, const gchar *)
765 IBUS_ENGINE_DESC_GET_PROPERTY (layout, const gchar *)
766 IBUS_ENGINE_DESC_GET_PROPERTY (layout_variant, const gchar *)
767 IBUS_ENGINE_DESC_GET_PROPERTY (layout_option, const gchar *)
768 IBUS_ENGINE_DESC_GET_PROPERTY (rank, guint)
769 IBUS_ENGINE_DESC_GET_PROPERTY (hotkeys, const gchar *)
770 IBUS_ENGINE_DESC_GET_PROPERTY (symbol, const gchar *)
771 IBUS_ENGINE_DESC_GET_PROPERTY (setup, const gchar *)
772 IBUS_ENGINE_DESC_GET_PROPERTY (version, const gchar *)
773 IBUS_ENGINE_DESC_GET_PROPERTY (textdomain, const gchar *)
774 IBUS_ENGINE_DESC_GET_PROPERTY (icon_prop_key, const gchar *)
775 #undef IBUS_ENGINE_DESC_GET_PROPERTY
776
777 IBusEngineDesc *
778 ibus_engine_desc_new (const gchar *name,
779 const gchar *longname,
780 const gchar *description,
781 const gchar *language,
782 const gchar *license,
783 const gchar *author,
784 const gchar *icon,
785 const gchar *layout)
786 {
787 return ibus_engine_desc_new_varargs ("name", name,
788 "longname", longname,
789 "description", description,
790 "language", language,
791 "license", license,
792 "author", author,
793 "icon", icon,
794 "layout", layout,
795 NULL);
796 }
797
798 IBusEngineDesc *
ibus_engine_desc_new_varargs(const gchar * first_property_name,...)799 ibus_engine_desc_new_varargs (const gchar *first_property_name, ...)
800 {
801 va_list var_args;
802 IBusEngineDesc *desc;
803
804 g_assert (first_property_name);
805
806 va_start (var_args, first_property_name);
807 desc = (IBusEngineDesc *) g_object_new_valist (IBUS_TYPE_ENGINE_DESC,
808 first_property_name,
809 var_args);
810 va_end (var_args);
811
812 /* name is required. Other properties are set in class_init by default. */
813 g_assert (desc->priv->name);
814 g_assert (desc->priv->longname);
815 g_assert (desc->priv->description);
816 g_assert (desc->priv->language);
817 g_assert (desc->priv->license);
818 g_assert (desc->priv->author);
819 g_assert (desc->priv->icon);
820 g_assert (desc->priv->layout);
821 g_assert (desc->priv->layout_variant);
822 g_assert (desc->priv->layout_option);
823 g_assert (desc->priv->hotkeys);
824 g_assert (desc->priv->symbol);
825 g_assert (desc->priv->setup);
826 g_assert (desc->priv->version);
827 g_assert (desc->priv->textdomain);
828 g_assert (desc->priv->icon_prop_key);
829
830 return desc;
831 }
832
833 IBusEngineDesc *
ibus_engine_desc_new_from_xml_node(XMLNode * node)834 ibus_engine_desc_new_from_xml_node (XMLNode *node)
835 {
836 g_assert (node);
837
838 IBusEngineDesc *desc;
839
840 if (G_UNLIKELY (g_strcmp0 (node->name, "engine") != 0)) {
841 return NULL;
842 }
843
844 desc = (IBusEngineDesc *)g_object_new (IBUS_TYPE_ENGINE_DESC, NULL);
845
846 if (!ibus_engine_desc_parse_xml_node (desc, node)) {
847 g_object_unref (desc);
848 desc = NULL;
849 }
850
851 return desc;
852 }
853