From 7916930160f85a17ea8e55dcb91d255370db5e9e Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Mon, 14 Feb 2011 14:13:02 +0900 Subject: [PATCH] Implement serialization to GVariant. --- eek/eek-container.c | 19 +++- eek/eek-container.h | 16 +-- eek/eek-element.c | 2 +- eek/eek-key.c | 110 +++++++++++-------- eek/eek-key.h | 18 ++-- eek/eek-keyboard.c | 209 ++++++++++++++++++++++++++++++++++-- eek/eek-keyboard.h | 12 +++ eek/eek-keysym.c | 235 +++++++++++++++++++++++------------------ eek/eek-renderer.c | 43 ++++++-- eek/eek-section.c | 106 ++++++++++++++++++- eek/eek-serializable.c | 16 +-- eek/eek-symbol.c | 168 ++++++++++++++++------------- eek/eek-symbol.h | 18 ---- eek/eek-types.c | 15 ++- eek/eek-types.h | 4 +- eek/eek-xkb-layout.c | 41 +++---- eek/eek-xml-layout.c | 61 +++++------ eek/eek-xml.c | 38 ++++--- eek/eek.h | 1 + src/client-main.c | 1 + src/proxy.c | 12 +-- src/server-main.c | 8 ++ src/server.c | 17 ++- 23 files changed, 774 insertions(+), 396 deletions(-) diff --git a/eek/eek-container.c b/eek/eek-container.c index 331ace45..6d0a3976 100644 --- a/eek/eek-container.c +++ b/eek/eek-container.c @@ -82,7 +82,6 @@ eek_container_real_deserialize (EekSerializable *self, GVariant *variant, gsize index) { - EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self); GVariant *array, *child; GVariantIter iter; @@ -94,9 +93,9 @@ eek_container_real_deserialize (EekSerializable *self, g_variant_iter_init (&iter, array); while (g_variant_iter_next (&iter, "v", &child)) { EekSerializable *serializable = eek_serializable_deserialize (child); - priv->children = g_slist_prepend (priv->children, serializable); + eek_container_add_child (EEK_CONTAINER(self), + EEK_ELEMENT(serializable)); } - priv->children = g_slist_reverse (priv->children); return index; } @@ -122,6 +121,7 @@ eek_container_real_add_child (EekContainer *self, priv->children = g_slist_prepend (priv->children, child); eek_element_set_parent (child, EEK_ELEMENT(self)); + g_signal_emit_by_name (self, "child-added", child); } static void @@ -137,6 +137,7 @@ eek_container_real_remove_child (EekContainer *self, g_object_unref (child); priv->children = g_slist_remove_link (priv->children, head); eek_element_set_parent (child, NULL); + g_signal_emit_by_name (self, "child-removed", child); } static void @@ -202,6 +203,10 @@ eek_container_class_init (EekContainerClass *klass) klass->foreach_child = eek_container_real_foreach_child; klass->find = eek_container_real_find; + /* signals */ + klass->child_added = NULL; + klass->child_removed = NULL; + gobject_class->finalize = eek_container_finalize; gobject_class->dispose = eek_container_dispose; @@ -290,3 +295,11 @@ eek_container_find (EekContainer *container, func, user_data); } + +void +eek_container_add_child (EekContainer *container, EekElement *element) +{ + g_return_if_fail (EEK_IS_CONTAINER(container)); + g_return_if_fail (EEK_IS_ELEMENT(element)); + return EEK_CONTAINER_GET_CLASS(container)->add_child (container, element); +} diff --git a/eek/eek-container.h b/eek/eek-container.h index 6a7bda87..4d83dfd0 100644 --- a/eek/eek-container.h +++ b/eek/eek-container.h @@ -81,14 +81,16 @@ struct _EekContainerClass gpointer pdummy[24]; }; -GType eek_container_get_type (void) G_GNUC_CONST; +GType eek_container_get_type (void) G_GNUC_CONST; -void eek_container_foreach_child (EekContainer *container, - EekCallback callback, - gpointer user_data); -EekElement *eek_container_find (EekContainer *container, - EekCompareFunc func, - gpointer user_data); +void eek_container_foreach_child (EekContainer *container, + EekCallback callback, + gpointer user_data); +EekElement *eek_container_find (EekContainer *container, + EekCompareFunc func, + gpointer user_data); +void eek_container_add_child (EekContainer *container, + EekElement *element); G_END_DECLS #endif /* EEK_CONTAINER_H */ diff --git a/eek/eek-element.c b/eek/eek-element.c index d82f2cf8..ad588812 100644 --- a/eek/eek-element.c +++ b/eek/eek-element.c @@ -89,7 +89,7 @@ eek_element_real_serialize (EekSerializable *self, { EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self); - g_variant_builder_add (builder, "s", priv->name); + g_variant_builder_add (builder, "s", priv->name == NULL ? "" : priv->name); g_variant_builder_add (builder, "v", _g_variant_new_bounds (&priv->bounds)); } diff --git a/eek/eek-key.c b/eek/eek-key.c index 77ee5fd5..dc30981c 100644 --- a/eek/eek-key.c +++ b/eek/eek-key.c @@ -46,7 +46,7 @@ enum { PROP_SYMBOL_MATRIX, PROP_COLUMN, PROP_ROW, - PROP_OUTLINE, + PROP_OREF, PROP_LAST }; @@ -74,7 +74,7 @@ struct _EekKeyPrivate EekSymbolMatrix *symbol_matrix; gint column; gint row; - EekOutline *outline; + gulong oref; gboolean is_pressed; }; @@ -86,23 +86,45 @@ _g_variant_new_symbol_matrix (EekSymbolMatrix *symbol_matrix) GVariantBuilder builder, array; gint i, num_symbols = symbol_matrix->num_groups * symbol_matrix->num_levels; - g_variant_builder_init (&builder, G_VARIANT_TYPE ("iiav")); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iiv)")); g_variant_builder_add (&builder, "i", symbol_matrix->num_groups); g_variant_builder_add (&builder, "i", symbol_matrix->num_levels); g_variant_builder_init (&array, G_VARIANT_TYPE ("av")); for (i = 0; i < num_symbols; i++) { GVariant *symbol = eek_serializable_serialize (EEK_SERIALIZABLE(symbol_matrix->data[i])); - g_variant_builder_add (&builder, "v", symbol); + g_variant_builder_add (&array, "v", symbol); } - g_variant_builder_add (&builder, "av", g_variant_builder_end (&array)); + g_variant_builder_add (&builder, "v", g_variant_builder_end (&array)); return g_variant_builder_end (&builder); } static EekSymbolMatrix * _g_variant_get_symbol_matrix (GVariant *variant) { - g_return_val_if_reached (NULL); /* TODO */ + gint num_groups, num_levels, i; + EekSymbolMatrix *symbol_matrix; + GVariant *array, *child; + GVariantIter iter; + + g_variant_get_child (variant, 0, "i", &num_groups); + g_variant_get_child (variant, 1, "i", &num_levels); + symbol_matrix = eek_symbol_matrix_new (num_groups, num_levels); + + g_variant_get_child (variant, 2, "v", &array); + g_variant_iter_init (&iter, array); + for (i = 0; i < num_groups * num_levels; i++) { + EekSerializable *serializable; + + if (!g_variant_iter_next (&iter, "v", &child)) { + eek_symbol_matrix_free (symbol_matrix); + g_return_val_if_reached (NULL); + } + + serializable = eek_serializable_deserialize (child); + symbol_matrix->data[i] = EEK_SYMBOL(serializable); + } + return symbol_matrix; } static void @@ -118,6 +140,7 @@ eek_key_real_serialize (EekSerializable *self, _g_variant_new_symbol_matrix (priv->symbol_matrix)); g_variant_builder_add (builder, "i", priv->column); g_variant_builder_add (builder, "i", priv->row); + g_variant_builder_add (builder, "u", priv->oref); } static gsize @@ -137,6 +160,7 @@ eek_key_real_deserialize (EekSerializable *self, priv->symbol_matrix = _g_variant_get_symbol_matrix (symbol_matrix); g_variant_get_child (variant, index++, "i", &priv->column); g_variant_get_child (variant, index++, "i", &priv->row); + g_variant_get_child (variant, index++, "u", &priv->oref); return index; } @@ -208,17 +232,17 @@ eek_key_real_get_index (EekKey *self, } static void -eek_key_real_set_outline (EekKey *self, EekOutline *outline) +eek_key_real_set_oref (EekKey *self, gulong oref) { EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); - priv->outline = outline; + priv->oref = oref; } -static EekOutline * -eek_key_real_get_outline (EekKey *self) +static gulong +eek_key_real_get_oref (EekKey *self) { EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self); - return priv->outline; + return priv->oref; } static gboolean @@ -283,8 +307,8 @@ eek_key_set_property (GObject *object, eek_key_get_index (EEK_KEY(object), &column, &row); eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value)); break; - case PROP_OUTLINE: - eek_key_set_outline (EEK_KEY(object), g_value_get_pointer (value)); + case PROP_OREF: + eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value)); break; default: g_object_set_property (object, @@ -319,8 +343,8 @@ eek_key_get_property (GObject *object, eek_key_get_index (EEK_KEY(object), &column, &row); g_value_set_int (value, row); break; - case PROP_OUTLINE: - g_value_set_pointer (value, eek_key_get_outline (EEK_KEY(object))); + case PROP_OREF: + g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object))); break; default: g_object_get_property (object, @@ -345,8 +369,8 @@ eek_key_class_init (EekKeyClass *klass) klass->get_symbol_matrix = eek_key_real_get_symbol_matrix; klass->set_index = eek_key_real_set_index; klass->get_index = eek_key_real_get_index; - klass->set_outline = eek_key_real_set_outline; - klass->get_outline = eek_key_real_get_outline; + klass->set_oref = eek_key_real_set_oref; + klass->get_oref = eek_key_real_get_oref; klass->is_pressed = eek_key_real_is_pressed; gobject_class->set_property = eek_key_set_property; @@ -406,18 +430,16 @@ eek_key_class_init (EekKeyClass *klass) g_object_class_install_property (gobject_class, PROP_ROW, pspec); /** - * EekKey:outline: + * EekKey:oref: * - * The pointer to the outline shape of #EekKey. + * The outline id of #EekKey. */ - /* Use pointer instead of boxed to avoid copy, since we can - assume that only a few outline shapes are used in a whole - keyboard (unlike symbol matrix and bounds). */ - pspec = g_param_spec_pointer ("outline", - "Outline", - "Pointer to outline shape of the key", - G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_OUTLINE, pspec); + pspec = g_param_spec_ulong ("oref", + "Oref", + "Outline id of the key", + 0, G_MAXULONG, 0, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_OREF, pspec); /** * EekKey::pressed: @@ -463,7 +485,7 @@ eek_key_init (EekKey *self) priv->keycode = 0; priv->symbol_matrix = eek_symbol_matrix_new (0, 0); priv->column = priv->row = 0; - priv->outline = NULL; + priv->oref = 0; } /** @@ -639,8 +661,7 @@ eek_key_get_symbol_at_index (EekKey *key, * @column: column index of @key in #EekSection * @row: row index of @key in #EekSection * - * Set the index of @key (i.e. logical location of @key in - * #EekSection) to @column and @row. + * Set the location of @key in #EekSection with @column and @row. */ void eek_key_set_index (EekKey *key, @@ -657,8 +678,7 @@ eek_key_set_index (EekKey *key, * @column: pointer where the column index of @key in #EekSection will be stored * @row: pointer where the row index of @key in #EekSection will be stored * - * Get the index of @key (i.e. logical location of @key in - * #EekSection). + * Get the location of @key in #EekSection. */ void eek_key_get_index (EekKey *key, @@ -670,32 +690,32 @@ eek_key_get_index (EekKey *key, } /** - * eek_key_set_outline: + * eek_key_set_oref: * @key: an #EekKey - * @outline: outline of @key + * @oref: outline id of @key * - * Set the outline shape of @key to @outline. + * Set the outline id of @key to @oref. */ void -eek_key_set_outline (EekKey *key, - EekOutline *outline) +eek_key_set_oref (EekKey *key, + gulong oref) { g_return_if_fail (EEK_IS_KEY(key)); - EEK_KEY_GET_CLASS(key)->set_outline (key, outline); + EEK_KEY_GET_CLASS(key)->set_oref (key, oref); } /** - * eek_key_get_outline: + * eek_key_get_oref: * @key: an #EekKey * - * Get the outline shape of @key. - * Returns: an #EekOutline pointer or NULL on failure + * Get the outline id of @key. + * Returns: a non-zero unsigned integer on success, 0 if the id is not set */ -EekOutline * -eek_key_get_outline (EekKey *key) +gulong +eek_key_get_oref (EekKey *key) { - g_return_val_if_fail (EEK_IS_KEY (key), NULL); - return EEK_KEY_GET_CLASS(key)->get_outline (key); + g_return_val_if_fail (EEK_IS_KEY (key), 0); + return EEK_KEY_GET_CLASS(key)->get_oref (key); } /** diff --git a/eek/eek-key.h b/eek/eek-key.h index 38cb6b55..94d03a4f 100644 --- a/eek/eek-key.h +++ b/eek/eek-key.h @@ -54,8 +54,8 @@ struct _EekKey * section * @get_index: virtual function for getting position of the key in the * section - * @set_outline: virtual function for setting outline shape of the key - * @get_outline: virtual function for getting outline shape of the key + * @set_oref: virtual function for setting outline id of the key + * @get_oref: virtual function for getting outline id of the key * @pressed: class handler for #EekKey::pressed signal * @released: class handler for #EekKey::released signal * @is_pressed: virtual function for getting whether the key is pressed @@ -80,9 +80,9 @@ struct _EekKeyClass gint *column, gint *row); - void (* set_outline) (EekKey *self, - EekOutline *outline); - EekOutline *(* get_outline) (EekKey *self); + void (* set_oref) (EekKey *self, + gulong oref); + gulong (* get_oref) (EekKey *self); gboolean (* is_pressed) (EekKey *self); @@ -104,7 +104,7 @@ void eek_key_set_symbol_matrix (EekKey *key, EekSymbolMatrix *matrix); EekSymbolMatrix *eek_key_get_symbol_matrix (EekKey *key); EekSymbol *eek_key_get_symbol (EekKey *key); -EekSymbol * eek_key_get_symbol_with_fallback +EekSymbol *eek_key_get_symbol_with_fallback (EekKey *key, gint fallback_group, gint fallback_level); @@ -121,9 +121,9 @@ void eek_key_get_index (EekKey *key, gint *column, gint *row); -void eek_key_set_outline (EekKey *key, - EekOutline *outline); -EekOutline *eek_key_get_outline (EekKey *key); +void eek_key_set_oref (EekKey *key, + gulong oref); +gulong eek_key_get_oref (EekKey *key); gboolean eek_key_is_pressed (EekKey *key); diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index 5d7780ce..596833cf 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -36,6 +36,7 @@ #include "eek-key.h" #include "eek-symbol.h" #include "eek-marshalers.h" +#include "eek-serializable.h" enum { PROP_0, @@ -55,7 +56,11 @@ enum { static guint signals[LAST_SIGNAL] = { 0, }; -G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER); +static void eek_serializable_iface_init (EekSerializableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER, + G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE, + eek_serializable_iface_init)); #define EEK_KEYBOARD_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate)) @@ -68,8 +73,117 @@ struct _EekKeyboardPrivate EekLayout *layout; EekModifierBehavior modifier_behavior; EekModifierType modifiers; + GArray *outline_array; }; +static EekSerializableIface *eek_keyboard_parent_serializable_iface; + +static GVariant *_g_variant_new_outline (EekOutline *outline); +static EekOutline *_g_variant_get_outline (GVariant *variant); + +static GVariant * +_g_variant_new_outline (EekOutline *outline) +{ + GVariantBuilder builder, array; + gint i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(div)")); + g_variant_builder_add (&builder, "d", outline->corner_radius); + g_variant_builder_add (&builder, "i", outline->num_points); + g_variant_builder_init (&array, G_VARIANT_TYPE ("a(dd)")); + for (i = 0; i < outline->num_points; i++) + g_variant_builder_add (&array, + "(dd)", + outline->points[i].x, + outline->points[i].y); + g_variant_builder_add (&builder, "v", g_variant_builder_end (&array)); + return g_variant_builder_end (&builder); +} + +static EekOutline * +_g_variant_get_outline (GVariant *variant) +{ + EekOutline *outline; + GVariant *array; + GVariantIter iter; + gdouble x, y; + gint i; + + outline = g_slice_new0 (EekOutline); + + g_variant_get_child (variant, 0, "d", &outline->corner_radius); + g_variant_get_child (variant, 1, "i", &outline->num_points); + + outline->points = g_slice_alloc0 (sizeof (EekPoint) * outline->num_points); + + g_variant_get_child (variant, 2, "v", &array); + g_variant_iter_init (&iter, array); + for (i = 0; i < outline->num_points; i++) { + if (!g_variant_iter_next (&iter, "(dd)", &x, &y)) { + eek_outline_free (outline); + g_return_val_if_reached (NULL); + } + outline->points[i].x = x; + outline->points[i].y = y; + } + + return outline; +} + +static void +eek_keyboard_real_serialize (EekSerializable *self, + GVariantBuilder *builder) +{ + EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); + GVariantBuilder array; + guint i; + + eek_keyboard_parent_serializable_iface->serialize (self, builder); + + g_variant_builder_init (&array, G_VARIANT_TYPE ("av")); + for (i = 0; i < priv->outline_array->len; i++) { + EekOutline *outline = + eek_keyboard_get_outline (EEK_KEYBOARD(self), i + 1); + g_variant_builder_add (&array, "v", + _g_variant_new_outline (outline)); + } + g_variant_builder_add (builder, "v", g_variant_builder_end (&array)); +} + +static gsize +eek_keyboard_real_deserialize (EekSerializable *self, + GVariant *variant, + gsize index) +{ + EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); + GVariant *array, *outline; + GVariantIter iter; + + index = eek_keyboard_parent_serializable_iface->deserialize (self, + variant, + index); + + g_variant_get_child (variant, index++, "v", &array); + + g_variant_iter_init (&iter, array); + while (g_variant_iter_next (&iter, "v", &outline)) { + EekOutline *_outline = _g_variant_get_outline (outline); + g_array_append_val (priv->outline_array, *_outline); + } + + return index; +} + +static void +eek_serializable_iface_init (EekSerializableIface *iface) +{ + eek_keyboard_parent_serializable_iface = + g_type_interface_peek_parent (iface); + + iface->serialize = eek_keyboard_real_serialize; + iface->deserialize = eek_keyboard_real_deserialize; +} + static void eek_keyboard_real_set_symbol_index (EekKeyboard *self, gint group, @@ -123,11 +237,6 @@ eek_keyboard_real_create_section (EekKeyboard *self) section = g_object_new (EEK_TYPE_SECTION, NULL); g_return_val_if_fail (section, NULL); - g_signal_connect (section, "key-pressed", - G_CALLBACK(on_key_pressed), self); - g_signal_connect (section, "key-released", - G_CALLBACK(on_key_released), self); - EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), EEK_ELEMENT(section)); return section; @@ -318,9 +427,46 @@ eek_keyboard_dispose (GObject *object) G_OBJECT_CLASS (eek_keyboard_parent_class)->dispose (object); } +static void +eek_keyboard_finalize (GObject *object) +{ + EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object); + gint i; + + for (i = 0; i < priv->outline_array->len; i++) { + EekOutline *outline = &g_array_index (priv->outline_array, + EekOutline, + i); + g_slice_free1 (sizeof (EekPoint) * outline->num_points, + outline->points); + } + g_array_free (priv->outline_array, TRUE); + + G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object); +} + +static void +eek_keyboard_real_child_added (EekContainer *self, + EekElement *element) +{ + g_signal_connect (element, "key-pressed", + G_CALLBACK(on_key_pressed), self); + g_signal_connect (element, "key-released", + G_CALLBACK(on_key_released), self); +} + +static void +eek_keyboard_real_child_removed (EekContainer *self, + EekElement *element) +{ + g_signal_handlers_disconnect_by_func (element, on_key_pressed, self); + g_signal_handlers_disconnect_by_func (element, on_key_released, self); +} + static void eek_keyboard_class_init (EekKeyboardClass *klass) { + EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; @@ -337,9 +483,13 @@ eek_keyboard_class_init (EekKeyboardClass *klass) klass->key_released = eek_keyboard_real_key_released; klass->symbol_index_changed = eek_keyboard_real_symbol_index_changed; + container_class->child_added = eek_keyboard_real_child_added; + container_class->child_removed = eek_keyboard_real_child_removed; + gobject_class->get_property = eek_keyboard_get_property; gobject_class->set_property = eek_keyboard_set_property; gobject_class->dispose = eek_keyboard_dispose; + gobject_class->finalize = eek_keyboard_finalize; /** * EekKeyboard:group: @@ -470,6 +620,7 @@ eek_keyboard_init (EekKeyboard *self) priv->layout = NULL; priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE; priv->modifiers = 0; + priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline)); } /** @@ -692,3 +843,49 @@ eek_keyboard_get_modifiers (EekKeyboard *keyboard) return priv->modifiers; } + +/** + * eek_keyboard_add_outline: + * @keyboard: an #EekKeyboard + * @outline: an #EekOutline + * + * Register an outline of @keyboard. + * Returns: an unsigned long id of the registered outline, for later reference + */ +gulong +eek_keyboard_add_outline (EekKeyboard *keyboard, + EekOutline *outline) +{ + EekKeyboardPrivate *priv; + EekOutline *_outline; + + g_assert (EEK_IS_KEYBOARD(keyboard)); + priv = EEK_KEYBOARD_GET_PRIVATE(keyboard); + + _outline = eek_outline_copy (outline); + g_array_append_val (priv->outline_array, *_outline); + return priv->outline_array->len; +} + +/** + * eek_keyboard_get_outline: + * @keyboard: an #EekKeyboard + * @oref: an unsigned long id + * + * Get an outline associated with @oref in @keyboard. + * Returns: an #EekOutline, which should not be released + */ +EekOutline * +eek_keyboard_get_outline (EekKeyboard *keyboard, + gulong oref) +{ + EekKeyboardPrivate *priv; + + g_assert (EEK_IS_KEYBOARD(keyboard)); + priv = EEK_KEYBOARD_GET_PRIVATE(keyboard); + + if (oref > priv->outline_array->len) + return NULL; + + return &g_array_index (priv->outline_array, EekOutline, oref - 1); +} diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h index c603d256..6124e504 100644 --- a/eek/eek-keyboard.h +++ b/eek/eek-keyboard.h @@ -102,6 +102,10 @@ void eek_keyboard_get_size (EekKeyboard *keyboard, gdouble *width, gdouble *height); +void eek_keyboard_set_size + (EekKeyboard *keyboard, + gdouble width, + gdouble height); void eek_keyboard_set_symbol_index (EekKeyboard *keyboard, gint group, @@ -137,5 +141,13 @@ EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, guint keycode); +gulong eek_keyboard_add_outline + (EekKeyboard *keyboard, + EekOutline *outline); + +EekOutline *eek_keyboard_get_outline + (EekKeyboard *keyboard, + gulong oref); + G_END_DECLS #endif /* EEK_KEYBOARD_H */ diff --git a/eek/eek-keysym.c b/eek/eek-keysym.c index 959e0325..fd808128 100644 --- a/eek/eek-keysym.c +++ b/eek/eek-keysym.c @@ -31,6 +31,7 @@ #endif /* HAVE_CONFIG_H */ #include "eek-keysym.h" +#include "eek-serializable.h" /* modifier keys */ #define EEK_KEYSYM_Shift_L 0xffe1 @@ -51,27 +52,68 @@ struct _EekKeysymPrivate { guint xkeysym; +}; + +struct _EekKeysymEntry { + guint xkeysym; const gchar *name; EekSymbolCategory category; }; -typedef EekKeysymPrivate EekKeysymEntry; +typedef struct _EekKeysymEntry EekKeysymEntry; #include "eek-special-keysym-entries.h" #include "eek-unicode-keysym-entries.h" #include "eek-xkeysym-keysym-entries.h" -static const EekKeysymEntry invalid_keysym_entry = { - EEK_INVALID_KEYSYM, - "\0", - EEK_SYMBOL_CATEGORY_UNKNOWN, -}; +static void eek_serializable_iface_init (EekSerializableIface *iface); -G_DEFINE_TYPE (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL); +G_DEFINE_TYPE_WITH_CODE (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL, + G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE, + eek_serializable_iface_init)); #define EEK_KEYSYM_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYSYM, EekKeysymPrivate)) +static EekSerializableIface *eek_keysym_parent_serializable_iface; + +static void +eek_keysym_real_serialize (EekSerializable *self, + GVariantBuilder *builder) +{ + EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self); + + eek_keysym_parent_serializable_iface->serialize (self, builder); + + g_variant_builder_add (builder, "u", priv->xkeysym); +} + +static gsize +eek_keysym_real_deserialize (EekSerializable *self, + GVariant *variant, + gsize index) +{ + EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self); + + index = eek_keysym_parent_serializable_iface->deserialize (self, + variant, + index); + + g_variant_get_child (variant, index++, "u", &priv->xkeysym); + + return index; +} + +static void +eek_serializable_iface_init (EekSerializableIface *iface) +{ + eek_keysym_parent_serializable_iface = + g_type_interface_peek_parent (iface); + + iface->serialize = eek_keysym_real_serialize; + iface->deserialize = eek_keysym_real_deserialize; +} + static gchar * unichar_to_utf8 (gunichar uc) { @@ -91,7 +133,7 @@ static int keysym_entry_compare_by_xkeysym (const void *key0, const void *key1) { const EekKeysymEntry *entry0 = key0, *entry1 = key1; - return (gint)entry0->xkeysym - (gint)entry1->xkeysym; + return (gint) (entry0->xkeysym - entry1->xkeysym); } static EekKeysymEntry * @@ -103,14 +145,7 @@ find_keysym_entry_by_xkeysym (guint xkeysym, key.xkeysym = xkeysym; return bsearch (&key, entries, num_entries, sizeof (EekKeysymEntry), - keysym_entry_compare_by_xkeysym); -} - -static G_CONST_RETURN gchar * -eek_keysym_real_get_name (EekSymbol *self) -{ - EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self); - return priv->name; + keysym_entry_compare_by_xkeysym); } static gboolean @@ -132,46 +167,10 @@ get_unichar (guint xkeysym, gunichar *uc) { return FALSE; } -static gchar * -eek_keysym_real_get_label (EekSymbol *self) +G_INLINE_FUNC EekModifierType +get_modifier_mask (guint xkeysym) { - EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self); - EekKeysymEntry *entry; - gunichar uc; - - /* First, search special keysyms. */ - entry = find_keysym_entry_by_xkeysym (priv->xkeysym, - special_keysym_entries, - G_N_ELEMENTS(special_keysym_entries)); - if (entry) - return g_strdup (entry->name); - - if (get_unichar (priv->xkeysym, &uc)) - return unichar_to_utf8 (uc); - - /* Search known unicode keysyms. */ - entry = find_keysym_entry_by_xkeysym (priv->xkeysym, - unicode_keysym_entries, - G_N_ELEMENTS(unicode_keysym_entries)); - if (entry) - return g_strdup (entry->name); - - return g_strdup (eek_symbol_get_name (self)); -} - -EekSymbolCategory -eek_keysym_real_get_category (EekSymbol *self) -{ - EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self); - return priv->category; -} - -EekModifierType -eek_keysym_real_get_modifier_mask (EekSymbol *self) -{ - EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self); - - switch (priv->xkeysym) { + switch (xkeysym) { case EEK_KEYSYM_Shift_L: case EEK_KEYSYM_Shift_R: case EEK_KEYSYM_Caps_Lock: @@ -201,15 +200,9 @@ eek_keysym_real_get_modifier_mask (EekSymbol *self) static void eek_keysym_class_init (EekKeysymClass *klass) { - EekSymbolClass *symbol_class = EEK_SYMBOL_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (gobject_class, sizeof (EekKeysymPrivate)); - - symbol_class->get_name = eek_keysym_real_get_name; - symbol_class->get_label = eek_keysym_real_get_label; - symbol_class->get_category = eek_keysym_real_get_category; - symbol_class->get_modifier_mask = eek_keysym_real_get_modifier_mask; } static void @@ -218,7 +211,7 @@ eek_keysym_init (EekKeysym *self) EekKeysymPrivate *priv; priv = self->priv = EEK_KEYSYM_GET_PRIVATE(self); - memcpy (priv, &invalid_keysym_entry, sizeof (EekKeysymEntry)); + priv->xkeysym = EEK_INVALID_KEYSYM; } EekKeysym * @@ -226,33 +219,77 @@ eek_keysym_new (guint xkeysym) { EekKeysym *keysym; EekKeysymPrivate *priv; - EekKeysymEntry *entry; + EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry, + *unichar_entry; + gchar *name, *label; + EekSymbolCategory category; + EekModifierType modifier_mask; + gunichar uc; - keysym = g_object_new (EEK_TYPE_KEYSYM, NULL); - priv = EEK_KEYSYM_GET_PRIVATE(keysym); - priv->xkeysym = xkeysym; - - /* First check the X standard keysyms */ - entry = find_keysym_entry_by_xkeysym (xkeysym, - xkeysym_keysym_entries, - G_N_ELEMENTS(xkeysym_keysym_entries)); - if (!entry) { - gunichar uc; - - /* Check the special unicode mappings */ - if (get_unichar (priv->xkeysym, &uc)) { - priv->category = EEK_SYMBOL_CATEGORY_LETTER; - return keysym; - } - - entry = find_keysym_entry_by_xkeysym - (priv->xkeysym, - unicode_keysym_entries, - G_N_ELEMENTS(unicode_keysym_entries)); + special_entry = + find_keysym_entry_by_xkeysym (xkeysym, + special_keysym_entries, + G_N_ELEMENTS(special_keysym_entries)); + xkeysym_entry = + find_keysym_entry_by_xkeysym (xkeysym, + xkeysym_keysym_entries, + G_N_ELEMENTS(xkeysym_keysym_entries)); + unicode_entry = + find_keysym_entry_by_xkeysym (xkeysym, + unicode_keysym_entries, + G_N_ELEMENTS(unicode_keysym_entries)); + unichar_entry = NULL; + if (get_unichar (xkeysym, &uc)) { + unichar_entry = g_slice_new (EekKeysymEntry); + unichar_entry->xkeysym = xkeysym; + unichar_entry->name = unichar_to_utf8 (uc); + unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER; } - if (entry) - memcpy (priv, entry, sizeof (EekKeysymEntry)); + /* name and category */ + name = NULL; + if (xkeysym_entry) { + name = g_strdup (xkeysym_entry->name); + category = xkeysym_entry->category; + } else if (unichar_entry) { + name = g_strdup (unichar_entry->name); + category = unichar_entry->category; + } else if (unicode_entry) { + name = g_strdup (unicode_entry->name); + category = unicode_entry->category; + } else { + name = g_strdup (""); + category = EEK_SYMBOL_CATEGORY_UNKNOWN; + } + + /* label */ + if (special_entry) + label = g_strdup (special_entry->name); + else if (unichar_entry) + label = g_strdup (unichar_entry->name); + else if (unicode_entry) + label = g_strdup (unicode_entry->name); + else + label = g_strdup (name); + + modifier_mask = get_modifier_mask (xkeysym); + + keysym = g_object_new (EEK_TYPE_KEYSYM, + "name", name, + "label", label, + "category", category, + "modifier-mask", modifier_mask, + NULL); + g_free (name); + g_free (label); + + if (unichar_entry) { + g_free ((gpointer) unichar_entry->name); + g_slice_free (EekKeysymEntry, unichar_entry); + } + + priv = EEK_KEYSYM_GET_PRIVATE(keysym); + priv->xkeysym = xkeysym; return keysym; } @@ -260,25 +297,19 @@ eek_keysym_new (guint xkeysym) EekKeysym * eek_keysym_new_from_name (const gchar *name) { - EekKeysym *keysym; - EekKeysymPrivate *priv; gint i; - for (i = 0; - i < G_N_ELEMENTS(xkeysym_keysym_entries) && - g_strcmp0 (xkeysym_keysym_entries[i].name, name) != 0; i++) - ; + for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++) + if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) + return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym); - keysym = g_object_new (EEK_TYPE_KEYSYM, NULL); - priv = EEK_KEYSYM_GET_PRIVATE(keysym); - - if (i < G_N_ELEMENTS(xkeysym_keysym_entries)) - memcpy (priv, &xkeysym_keysym_entries[i], sizeof (EekKeysymEntry)); - else { - // g_warning ("can't find keysym entry for %s", name); - memcpy (priv, &invalid_keysym_entry, sizeof (EekKeysymEntry)); - } - return keysym; + // g_warning ("can't find keysym entry for %s", name); + return g_object_new (EEK_TYPE_KEYSYM, + "name", name, + "label", name, + "category", EEK_SYMBOL_CATEGORY_UNKNOWN, + "modifier-mask", 0, + NULL); } guint diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index cfab8a39..a8e82015 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -184,9 +184,9 @@ render_key_outline (EekRenderer *renderer, EekOutline *outline; EekBounds bounds; cairo_pattern_t *pat; - EekPoint *points; gdouble scale; gint i; + gulong oref; /* need to rescale so that the border fit inside the clipping region */ @@ -194,12 +194,15 @@ render_key_outline (EekRenderer *renderer, scale = MIN((bounds.width - priv->border_width) / bounds.width, (bounds.height - priv->border_width) / bounds.height); - outline = eek_key_get_outline (key); - points = g_slice_copy (sizeof (EekPoint) * outline->num_points, - outline->points); + oref = eek_key_get_oref (key); + if (oref == 0) + return; + + outline = eek_keyboard_get_outline (priv->keyboard, oref); + outline = eek_outline_copy (outline); for (i = 0; i < outline->num_points; i++) { - points[i].x *= priv->scale * scale; - points[i].y *= priv->scale * scale; + outline->points[i].x *= priv->scale * scale; + outline->points[i].y *= priv->scale * scale; } cairo_translate (cr, @@ -227,7 +230,7 @@ render_key_outline (EekRenderer *renderer, cairo_set_source (cr, pat); _eek_rounded_polygon (cr, outline->corner_radius, - points, + outline->points, outline->num_points); cairo_fill (cr); @@ -246,11 +249,11 @@ render_key_outline (EekRenderer *renderer, _eek_rounded_polygon (cr, outline->corner_radius, - points, + outline->points, outline->num_points); cairo_stroke (cr); - g_slice_free1 (sizeof (EekPoint) * outline->num_points, points); + eek_outline_free (outline); } struct _CalculateFontSizeCallbackData { @@ -338,6 +341,20 @@ calculate_font_size (EekRenderer *renderer) return data.size > 0 ? data.size : data.em_size; } +static EekKeyboard * +get_keyboard (EekKey *key) +{ + EekElement *parent; + + parent = eek_element_get_parent (EEK_ELEMENT(key)); + g_return_val_if_fail (EEK_IS_SECTION(parent), NULL); + + parent = eek_element_get_parent (parent); + g_return_val_if_fail (EEK_IS_KEYBOARD(parent), NULL); + + return EEK_KEYBOARD(parent); +} + static void render_key (EekRenderer *self, cairo_t *cr, @@ -349,10 +366,16 @@ render_key (EekRenderer *self, EekBounds bounds; PangoLayout *layout; PangoRectangle extents = { 0, }; + gulong oref; + EekKeyboard *keyboard; eek_element_get_bounds (EEK_ELEMENT(key), &bounds); - outline = eek_key_get_outline (key); + oref = eek_key_get_oref (key); + if (oref == 0) + return; + keyboard = get_keyboard (key); + outline = eek_keyboard_get_outline (keyboard, oref); outline_surface = g_hash_table_lookup (priv->outline_surface_cache, outline); if (!outline_surface) { diff --git a/eek/eek-section.c b/eek/eek-section.c index 0a617d0b..3982670b 100644 --- a/eek/eek-section.c +++ b/eek/eek-section.c @@ -34,6 +34,7 @@ #endif /* HAVE_CONFIG_H */ #include "eek-section.h" #include "eek-key.h" +#include "eek-serializable.h" enum { PROP_0, @@ -49,7 +50,11 @@ enum { static guint signals[LAST_SIGNAL] = { 0, }; -G_DEFINE_TYPE (EekSection, eek_section, EEK_TYPE_CONTAINER); +static void eek_serializable_iface_init (EekSerializableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekSection, eek_section, EEK_TYPE_CONTAINER, + G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE, + eek_serializable_iface_init)); #define EEK_SECTION_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SECTION, EekSectionPrivate)) @@ -66,9 +71,82 @@ struct _EekSectionPrivate { gint angle; GSList *rows; - GSList *keys; }; +static EekSerializableIface *eek_section_parent_serializable_iface; + +static GVariant * +_g_variant_new_row (EekRow *row) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iu)")); + g_variant_builder_add (&builder, "i", row->num_columns); + g_variant_builder_add (&builder, "u", row->orientation); + + return g_variant_builder_end (&builder); +} + +static EekRow * +_g_variant_get_row (GVariant *variant) +{ + EekRow *row = g_slice_new (EekRow); + g_variant_get_child (variant, 0, "i", &row->num_columns); + g_variant_get_child (variant, 1, "u", &row->orientation); + return row; +} + +static void +eek_section_real_serialize (EekSerializable *self, + GVariantBuilder *builder) +{ + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self); + GSList *head; + GVariantBuilder array; + + eek_section_parent_serializable_iface->serialize (self, builder); + + g_variant_builder_add (builder, "i", priv->angle); + + g_variant_builder_init (&array, G_VARIANT_TYPE("av")); + for (head = priv->rows; head; head = g_slist_next (head)) + g_variant_builder_add (&array, "v", _g_variant_new_row (head->data)); + g_variant_builder_add (builder, "v", g_variant_builder_end (&array)); +} + +static gsize +eek_section_real_deserialize (EekSerializable *self, + GVariant *variant, + gsize index) +{ + EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self); + GVariant *array, *child; + GVariantIter iter; + + index = eek_section_parent_serializable_iface->deserialize (self, + variant, + index); + + g_variant_get_child (variant, index++, "i", &priv->angle); + g_variant_get_child (variant, index++, "v", &array); + g_variant_iter_init (&iter, array); + while (g_variant_iter_next (&iter, "v", &child)) + priv->rows = g_slist_prepend (priv->rows, _g_variant_get_row (child)); + priv->rows = g_slist_reverse (priv->rows); + + return index; +} + +static void +eek_serializable_iface_init (EekSerializableIface *iface) +{ + eek_section_parent_serializable_iface = + g_type_interface_peek_parent (iface); + + iface->serialize = eek_section_real_serialize; + iface->deserialize = eek_section_real_deserialize; +} + static void eek_section_real_set_angle (EekSection *self, gint angle) @@ -161,9 +239,6 @@ eek_section_real_create_key (EekSection *self, NULL); g_return_val_if_fail (key, NULL); - g_signal_connect (key, "pressed", G_CALLBACK(on_pressed), self); - g_signal_connect (key, "released", G_CALLBACK(on_released), self); - EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), EEK_ELEMENT(key)); @@ -237,9 +312,26 @@ eek_section_get_property (GObject *object, } } +static void +eek_section_real_child_added (EekContainer *self, + EekElement *element) +{ + g_signal_connect (element, "pressed", G_CALLBACK(on_pressed), self); + g_signal_connect (element, "released", G_CALLBACK(on_released), self); +} + +static void +eek_section_real_child_removed (EekContainer *self, + EekElement *element) +{ + g_signal_handlers_disconnect_by_func (element, on_pressed, self); + g_signal_handlers_disconnect_by_func (element, on_released, self); +} + static void eek_section_class_init (EekSectionClass *klass) { + EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; @@ -253,6 +345,10 @@ eek_section_class_init (EekSectionClass *klass) klass->create_key = eek_section_real_create_key; klass->find_key_by_keycode = eek_section_real_find_key_by_keycode; + /* signals */ + container_class->child_added = eek_section_real_child_added; + container_class->child_removed = eek_section_real_child_removed; + gobject_class->set_property = eek_section_set_property; gobject_class->get_property = eek_section_get_property; gobject_class->finalize = eek_section_finalize; diff --git a/eek/eek-serializable.c b/eek/eek-serializable.c index e6baec64..14397df2 100644 --- a/eek/eek-serializable.c +++ b/eek/eek-serializable.c @@ -53,23 +53,27 @@ eek_serializable_serialize (EekSerializable *object) EekSerializable * eek_serializable_deserialize (GVariant *variant) { - GVariant *var = NULL; gchar *type_name = NULL; GType type; EekSerializable *object; + gsize index = 0; g_return_val_if_fail (variant != NULL, NULL); - g_variant_get_child (var, 0, "&s", &type_name); + g_variant_get_child (variant, index++, "&s", &type_name); type = g_type_from_name (type_name); g_return_val_if_fail (g_type_is_a (type, EEK_TYPE_SERIALIZABLE), NULL); object = g_object_new (type, NULL); - EEK_SERIALIZABLE_GET_IFACE (object)->deserialize (object, var, 1); - g_variant_unref (var); + index = EEK_SERIALIZABLE_GET_IFACE (object)->deserialize (object, + variant, + index); + if (index < 0) { + g_object_unref (object); + g_return_val_if_reached (NULL); + } - g_object_unref (object); - g_return_val_if_reached (NULL); + return object; } diff --git a/eek/eek-symbol.c b/eek/eek-symbol.c index 6a4953dc..d19c80ac 100644 --- a/eek/eek-symbol.c +++ b/eek/eek-symbol.c @@ -23,6 +23,7 @@ #endif /* HAVE_CONFIG_H */ #include "eek-symbol.h" +#include "eek-serializable.h" enum { PROP_0, @@ -40,71 +41,47 @@ struct _EekSymbolPrivate { EekModifierType modifier_mask; }; -G_DEFINE_TYPE (EekSymbol, eek_symbol, G_TYPE_OBJECT); +static void eek_serializable_iface_init (EekSerializableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekSymbol, eek_symbol, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE, + eek_serializable_iface_init)); #define EEK_SYMBOL_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SYMBOL, EekSymbolPrivate)) static void -eek_symbol_real_set_name (EekSymbol *self, - const gchar *name) +eek_symbol_real_serialize (EekSerializable *self, + GVariantBuilder *builder) { EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - g_free (priv->name); - priv->name = g_strdup (name); + + g_variant_builder_add (builder, "s", priv->name); + g_variant_builder_add (builder, "s", priv->label); + g_variant_builder_add (builder, "u", priv->category); + g_variant_builder_add (builder, "u", priv->modifier_mask); } -G_CONST_RETURN gchar * -eek_symbol_real_get_name (EekSymbol *self) +static gsize +eek_symbol_real_deserialize (EekSerializable *self, + GVariant *variant, + gsize index) { EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - return priv->name; + + g_variant_get_child (variant, index++, "s", &priv->name); + g_variant_get_child (variant, index++, "s", &priv->label); + g_variant_get_child (variant, index++, "u", &priv->category); + g_variant_get_child (variant, index++, "u", &priv->modifier_mask); + + return index; } static void -eek_symbol_real_set_label (EekSymbol *self, - const gchar *label) +eek_serializable_iface_init (EekSerializableIface *iface) { - EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - g_free (priv->label); - priv->label = g_strdup (label); -} - -gchar * -eek_symbol_real_get_label (EekSymbol *self) -{ - EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - return priv->label; -} - -static void -eek_symbol_real_set_category (EekSymbol *self, - EekSymbolCategory category) -{ - EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - priv->category = category; -} - -EekSymbolCategory -eek_symbol_real_get_category (EekSymbol *self) -{ - EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - return priv->category; -} - -static void -eek_symbol_real_set_modifier_mask (EekSymbol *self, - EekModifierType mask) -{ - EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - priv->modifier_mask = mask; -} - -EekModifierType -eek_symbol_real_get_modifier_mask (EekSymbol *self) -{ - EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self); - return priv->modifier_mask; + iface->serialize = eek_symbol_real_serialize; + iface->deserialize = eek_symbol_real_deserialize; } static void @@ -121,11 +98,11 @@ eek_symbol_set_property (GObject *object, eek_symbol_set_label (EEK_SYMBOL(object), g_value_get_string (value)); break; case PROP_CATEGORY: - eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_int (value)); + eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_uint (value)); break; case PROP_MODIFIER_MASK: eek_symbol_set_modifier_mask (EEK_SYMBOL(object), - g_value_get_int (value)); + g_value_get_uint (value)); break; default: g_object_set_property (object, @@ -149,11 +126,11 @@ eek_symbol_get_property (GObject *object, g_value_set_string (value, eek_symbol_get_label (EEK_SYMBOL(object))); break; case PROP_CATEGORY: - g_value_set_int (value, eek_symbol_get_category (EEK_SYMBOL(object))); + g_value_set_uint (value, eek_symbol_get_category (EEK_SYMBOL(object))); break; case PROP_MODIFIER_MASK: - g_value_set_int (value, - eek_symbol_get_modifier_mask (EEK_SYMBOL(object))); + g_value_set_uint (value, + eek_symbol_get_modifier_mask (EEK_SYMBOL(object))); break; default: g_object_get_property (object, @@ -180,32 +157,37 @@ eek_symbol_class_init (EekSymbolClass *klass) g_type_class_add_private (gobject_class, sizeof (EekSymbolPrivate)); - klass->set_name = eek_symbol_real_set_name; - klass->get_name = eek_symbol_real_get_name; - klass->set_label = eek_symbol_real_set_label; - klass->get_label = eek_symbol_real_get_label; - klass->set_category = eek_symbol_real_set_category; - klass->get_category = eek_symbol_real_get_category; - klass->set_modifier_mask = eek_symbol_real_set_modifier_mask; - klass->get_modifier_mask = eek_symbol_real_get_modifier_mask; - gobject_class->set_property = eek_symbol_set_property; gobject_class->get_property = eek_symbol_get_property; gobject_class->finalize = eek_symbol_finalize; pspec = g_param_spec_string ("name", "Name", - "Canonical name of the keysym", + "Canonical name of the symbol", NULL, - G_PARAM_READWRITE); + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_NAME, pspec); pspec = g_param_spec_string ("label", "Label", - "Text used to display the keysym", + "Text used to display the symbol", NULL, - G_PARAM_READWRITE); + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_LABEL, pspec); + + pspec = g_param_spec_uint ("category", + "Category", + "Category of the symbol", + 0, G_MAXUINT, 0, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_CATEGORY, pspec); + + pspec = g_param_spec_uint ("modifier-mask", + "Modifier mask", + "Modifier mask of the symbol", + 0, G_MAXUINT, 0, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec); } static void @@ -230,58 +212,92 @@ void eek_symbol_set_name (EekSymbol *symbol, const gchar *name) { + EekSymbolPrivate *priv; + g_return_if_fail (EEK_IS_SYMBOL(symbol)); - EEK_SYMBOL_GET_CLASS(symbol)->set_name (symbol, name); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + g_free (priv->name); + priv->name = g_strdup (name); } G_CONST_RETURN gchar * eek_symbol_get_name (EekSymbol *symbol) { + EekSymbolPrivate *priv; + g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL); - return EEK_SYMBOL_GET_CLASS(symbol)->get_name (symbol); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + return priv->name; } void eek_symbol_set_label (EekSymbol *symbol, const gchar *label) { + EekSymbolPrivate *priv; + g_return_if_fail (EEK_IS_SYMBOL(symbol)); - return EEK_SYMBOL_GET_CLASS(symbol)->set_label (symbol, label); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + g_free (priv->label); + priv->label = g_strdup (label); } gchar * eek_symbol_get_label (EekSymbol *symbol) { + EekSymbolPrivate *priv; + g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL); - return EEK_SYMBOL_GET_CLASS(symbol)->get_label (symbol); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + return g_strdup (priv->label); } void eek_symbol_set_category (EekSymbol *symbol, EekSymbolCategory category) { + EekSymbolPrivate *priv; + g_return_if_fail (EEK_IS_SYMBOL(symbol)); - return EEK_SYMBOL_GET_CLASS(symbol)->set_category (symbol, category); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + priv->category = category; } EekSymbolCategory eek_symbol_get_category (EekSymbol *symbol) { + EekSymbolPrivate *priv; + g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN); - return EEK_SYMBOL_GET_CLASS(symbol)->get_category (symbol); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + return priv->category; } void eek_symbol_set_modifier_mask (EekSymbol *symbol, EekModifierType mask) { + EekSymbolPrivate *priv; + g_return_if_fail (EEK_IS_SYMBOL(symbol)); - return EEK_SYMBOL_GET_CLASS(symbol)->set_modifier_mask (symbol, mask); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + priv->modifier_mask = mask; } EekModifierType eek_symbol_get_modifier_mask (EekSymbol *symbol) { + EekSymbolPrivate *priv; + g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0); - return EEK_SYMBOL_GET_CLASS(symbol)->get_modifier_mask (symbol); + + priv = EEK_SYMBOL_GET_PRIVATE(symbol); + return priv->modifier_mask; } diff --git a/eek/eek-symbol.h b/eek/eek-symbol.h index 3fcd434e..6342a0bc 100644 --- a/eek/eek-symbol.h +++ b/eek/eek-symbol.h @@ -69,24 +69,6 @@ struct _EekSymbol { struct _EekSymbolClass { /*< private >*/ GObjectClass parent_class; - - /*< public >*/ - void (* set_name) (EekSymbol *self, - const gchar *name); - G_CONST_RETURN gchar *(* get_name) (EekSymbol *self); - void (* set_label) (EekSymbol *self, - const gchar *label); - gchar *(* get_label) (EekSymbol *self); - void (* set_category) (EekSymbol *self, - EekSymbolCategory category); - EekSymbolCategory (* get_category) (EekSymbol *self); - void (* set_modifier_mask) (EekSymbol *self, - EekModifierType mask); - EekModifierType (* get_modifier_mask) (EekSymbol *self); - - /*< private >*/ - /* padding */ - gpointer pdummy[24]; }; GType eek_symbol_get_type (void) G_GNUC_CONST; diff --git a/eek/eek-types.c b/eek/eek-types.c index 659b232a..a38826ac 100644 --- a/eek/eek-types.c +++ b/eek/eek-types.c @@ -27,9 +27,11 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#include "eek-types.h" +#include #include +#include "eek-types.h" + /* EekSymbolMatrix */ EekSymbolMatrix * eek_symbol_matrix_new (gint num_groups, gint num_levels) @@ -147,15 +149,20 @@ eek_bounds_get_type (void) } /* EekOutline */ -static EekOutline * +EekOutline * eek_outline_copy (const EekOutline *outline) { - return g_slice_dup (EekOutline, outline); + EekOutline *_outline = g_slice_dup (EekOutline, outline); + _outline->num_points = outline->num_points; + _outline->points = g_slice_alloc0 (sizeof (EekPoint) * outline->num_points); + memcpy (_outline->points, outline->points, sizeof (EekPoint) * outline->num_points); + return _outline; } -static void +void eek_outline_free (EekOutline *outline) { + g_slice_free1 (sizeof (EekPoint) * outline->num_points, outline->points); g_slice_free (EekOutline, outline); } diff --git a/eek/eek-types.h b/eek/eek-types.h index 0186298f..2bfb35a8 100644 --- a/eek/eek-types.h +++ b/eek/eek-types.h @@ -192,7 +192,9 @@ struct _EekOutline gint num_points; }; -GType eek_outline_get_type (void) G_GNUC_CONST; +GType eek_outline_get_type (void) G_GNUC_CONST; +EekOutline *eek_outline_copy (const EekOutline *outline); +void eek_outline_free (EekOutline *outline); /** * EekColor: diff --git a/eek/eek-xkb-layout.c b/eek/eek-xkb-layout.c index 40c28a6d..a76e69a5 100644 --- a/eek/eek-xkb-layout.c +++ b/eek/eek-xkb-layout.c @@ -70,8 +70,8 @@ struct _EekXkbLayoutPrivate /* Actual XKB configuration of DISPLAY. */ XkbDescRec *xkb; - /* Hash table to cache outlines by shape address. */ - GHashTable *outline_hash; + /* Hash table to cache orefs by shape address. */ + GHashTable *shape_oref_hash; gint scale_numerator; gint scale_denominator; @@ -109,6 +109,7 @@ xkb_to_pixmap_double (EekXkbLayout *layout, static void create_key (EekXkbLayout *layout, + EekKeyboard *keyboard, EekSection *section, gint column, gint row, @@ -125,14 +126,16 @@ create_key (EekXkbLayout *layout, EekBounds bounds; EekSymbolMatrix *matrix = NULL; gchar name[XkbKeyNameLength + 1]; - EekOutline *outline; KeyCode keycode; gint num_groups, num_levels, num_symbols; + gulong oref; xkbgeometry = priv->xkb->geom; xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx]; - outline = g_hash_table_lookup (priv->outline_hash, xkbshape); - if (outline == NULL) { + oref = (gulong)g_hash_table_lookup (priv->shape_oref_hash, xkbshape); + if (oref == 0) { + EekOutline *outline; + xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] : xkbshape->primary; @@ -172,7 +175,8 @@ create_key (EekXkbLayout *layout, xkb_to_pixmap_coord(layout, xkboutline->points[i].y); } } - g_hash_table_insert (priv->outline_hash, xkbshape, outline); + oref = eek_keyboard_add_outline (keyboard, outline); + g_hash_table_insert (priv->shape_oref_hash, xkbshape, (gpointer)oref); } memset (name, 0, sizeof name); @@ -210,7 +214,7 @@ create_key (EekXkbLayout *layout, eek_key_set_keycode (key, keycode); eek_key_set_symbol_matrix (key, matrix); eek_symbol_matrix_free (matrix); - eek_key_set_outline (key, outline); + eek_key_set_oref (key, oref); } static void @@ -262,7 +266,7 @@ create_section (EekXkbLayout *layout, top += xkbkey->gap; else left += xkbkey->gap; - create_key (layout, section, j, i, left, top, xkbkey); + create_key (layout, keyboard, section, j, i, left, top, xkbkey); xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds; if (xkbrow->vertical) top += xkbbounds->y2 - xkbbounds->y1; @@ -301,14 +305,6 @@ create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard) eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds); } -static void -outline_free (gpointer data) -{ - EekOutline *outline = data; - g_slice_free1 (sizeof (EekPoint) * outline->num_points, outline->points); - g_boxed_free (EEK_TYPE_OUTLINE, outline); -} - static EekKeyboard * eek_xkb_layout_real_create_keyboard (EekLayout *self, gdouble initial_width, @@ -324,15 +320,12 @@ eek_xkb_layout_real_create_keyboard (EekLayout *self, bounds.height = initial_height; eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds); - if (priv->outline_hash) - g_hash_table_unref (priv->outline_hash); - - priv->outline_hash = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - outline_free); + if (priv->shape_oref_hash) + g_hash_table_destroy (priv->shape_oref_hash); + priv->shape_oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal); create_keyboard (EEK_XKB_LAYOUT(self), keyboard); + g_hash_table_destroy (priv->shape_oref_hash); return keyboard; } @@ -345,8 +338,6 @@ eek_xkb_layout_finalize (GObject *object) g_free (priv->names.keycodes); g_free (priv->names.geometry); g_free (priv->names.symbols); - if (priv->outline_hash) - g_hash_table_unref (priv->outline_hash); XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */ G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object); } diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c index 2262dc67..70336f18 100644 --- a/eek/eek-xml-layout.c +++ b/eek/eek-xml-layout.c @@ -48,7 +48,6 @@ G_DEFINE_TYPE (EekXmlLayout, eek_xml_layout, EEK_TYPE_LAYOUT); struct _EekXmlLayoutPrivate { GInputStream *source; - GHashTable *outline_hash; }; #define BUFSIZE 8192 @@ -86,7 +85,7 @@ static const gchar *valid_path_list[] = { "orientation/row/section/keyboard", "key/section/keyboard", "bounds/key/section/keyboard", - "outline-ref/key/section/keyboard", + "oref/key/section/keyboard", "symbols/key/section/keyboard", "groups/symbols/key/section/keyboard", "levels/symbols/key/section/keyboard", @@ -293,7 +292,7 @@ end_element_callback (GMarkupParseContext *pcontext, outline->points = g_slice_alloc0 (sizeof (EekPoint) * outline->num_points); for (head = data->points = g_slist_reverse (data->points), i = 0; - head; + head && i < outline->num_points; head = g_slist_next (head), i++) { memcpy (&outline->points[i], head->data, sizeof (EekPoint)); g_slice_free1 (sizeof (EekPoint), head->data); @@ -406,7 +405,7 @@ end_element_callback (GMarkupParseContext *pcontext, goto out; } - if (g_strcmp0 (element_name, "outline-ref") == 0) { + if (g_strcmp0 (element_name, "oref") == 0) { g_hash_table_insert (data->key_oref_hash, data->key, g_strdup (text)); goto out; } @@ -434,14 +433,6 @@ static const GMarkupParser parser = { 0 }; -static void -outline_free (gpointer data) -{ - EekOutline *outline = data; - g_slice_free1 (sizeof (EekPoint) * outline->num_points, outline->points); - g_boxed_free (EEK_TYPE_OUTLINE, outline); -} - static void scale_bounds_callback (EekElement *element, gpointer user_data); @@ -485,6 +476,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self, gdouble scale; GHashTableIter iter; gpointer k, v; + GHashTable *oref_hash; g_return_val_if_fail (priv->source, NULL); @@ -495,10 +487,11 @@ eek_xml_layout_real_create_keyboard (EekLayout *self, g_direct_equal, NULL, g_free); - data.oref_outline_hash = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - outline_free); + data.oref_outline_hash = + g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify)eek_outline_free); pcontext = g_markup_parse_context_new (&parser, 0, &data, NULL); while (1) { @@ -528,36 +521,44 @@ eek_xml_layout_real_create_keyboard (EekLayout *self, if (!data.keyboard) goto out; - g_hash_table_iter_init (&iter, data.key_oref_hash); - while (g_hash_table_iter_next (&iter, &k, &v)) { - EekOutline *outline = g_hash_table_lookup (data.oref_outline_hash, v); - g_assert (outline); - eek_key_set_outline (EEK_KEY(k), outline); - } - eek_element_get_bounds (EEK_ELEMENT(data.keyboard), &bounds); scale = initial_width * bounds.height < initial_height * bounds.width ? initial_width / bounds.width : initial_height / bounds.height; + oref_hash = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_iter_init (&iter, data.oref_outline_hash); while (g_hash_table_iter_next (&iter, &k, &v)) { EekOutline *outline = v; + gulong oref; gint i; for (i = 0; i < outline->num_points; i++) { outline->points[i].x *= scale; outline->points[i].y *= scale; } + + oref = eek_keyboard_add_outline (data.keyboard, outline); + g_hash_table_insert (oref_hash, k, (gpointer) oref); } + g_hash_table_iter_init (&iter, data.key_oref_hash); + while (g_hash_table_iter_next (&iter, &k, &v)) { + gulong oref; + + oref = (gulong) g_hash_table_lookup (oref_hash, v); + eek_key_set_oref (EEK_KEY(k), oref); + } + g_hash_table_destroy (oref_hash); + scale_bounds (EEK_ELEMENT(data.keyboard), scale); out: g_string_free (data.text, TRUE); if (data.key_oref_hash) g_hash_table_destroy (data.key_oref_hash); - priv->outline_hash = data.oref_outline_hash; + if (data.oref_outline_hash) + g_hash_table_destroy (data.oref_outline_hash); return data.keyboard; } @@ -612,17 +613,6 @@ eek_xml_layout_dispose (GObject *object) G_OBJECT_CLASS (eek_xml_layout_parent_class)->dispose (object); } -static void -eek_xml_layout_finalize (GObject *object) -{ - EekXmlLayoutPrivate *priv = EEK_XML_LAYOUT_GET_PRIVATE (object); - - if (priv->outline_hash) - g_hash_table_unref (priv->outline_hash); - - G_OBJECT_CLASS (eek_xml_layout_parent_class)->finalize (object); -} - static void eek_xml_layout_class_init (EekXmlLayoutClass *klass) { @@ -637,7 +627,6 @@ eek_xml_layout_class_init (EekXmlLayoutClass *klass) gobject_class->set_property = eek_xml_layout_set_property; gobject_class->get_property = eek_xml_layout_get_property; gobject_class->dispose = eek_xml_layout_dispose; - gobject_class->finalize = eek_xml_layout_finalize; pspec = g_param_spec_object ("source", "Source", diff --git a/eek/eek-xml.c b/eek/eek-xml.c index e8164547..a558a3dc 100644 --- a/eek/eek-xml.c +++ b/eek/eek-xml.c @@ -54,7 +54,7 @@ g_string_markup_printf (GString *output, const gchar *format, ...) struct _OutputCallbackData { GString *output; gint indent; - GArray *outline_array; + GHashTable *oref_hash; gint key_serial; }; typedef struct _OutputCallbackData OutputCallbackData; @@ -75,12 +75,12 @@ output_key_callback (EekElement *element, gpointer user_data) { OutputCallbackData *data = user_data; EekBounds bounds; - EekOutline *outline; gint i, num_symbols; EekSymbolMatrix *matrix; gint column, row; guint keycode; gchar *id; + gulong oref; keycode = eek_key_get_keycode (EEK_KEY(element)); if (keycode == EEK_INVALID_KEYCODE) @@ -112,19 +112,16 @@ output_key_callback (EekElement *element, gpointer user_data) g_string_append_indent (data->output, data->indent + 1); output_bounds (data->output, &bounds); - outline = eek_key_get_outline (EEK_KEY(element)); - if (outline) { - for (i = 0; - i < data->outline_array->len && - g_array_index (data->outline_array, gpointer, i) != outline; - i++) - ; - if (i == data->outline_array->len) - g_array_append_val (data->outline_array, outline); + oref = eek_key_get_oref (EEK_KEY(element)); + if (oref != 0) { g_string_append_indent (data->output, data->indent + 1); g_string_markup_printf (data->output, - "outline%d\n", - i); + "outline%u\n", + oref); + if (!g_hash_table_lookup (data->oref_hash, (gpointer)oref)) + g_hash_table_insert (data->oref_hash, + (gpointer)oref, + (gpointer)TRUE); } matrix = eek_key_get_symbol_matrix (EEK_KEY(element)); @@ -224,7 +221,8 @@ eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent) { OutputCallbackData data; EekBounds bounds; - gint i; + gulong oref; + GHashTableIter iter; g_assert (EEK_IS_KEYBOARD(keyboard)); @@ -245,7 +243,7 @@ eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent) data.output = output; data.indent = indent; - data.outline_array = g_array_new (FALSE, FALSE, sizeof (gpointer)); + data.oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal); data.key_serial = 0; data.indent++; @@ -254,14 +252,14 @@ eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent) &data); data.indent--; - for (i = 0; i < data.outline_array->len; i++) { + g_hash_table_iter_init (&iter, data.oref_hash); + while (g_hash_table_iter_next (&iter, (gpointer *)&oref, NULL)) { EekOutline *outline; gint j; + outline = eek_keyboard_get_outline (keyboard, oref); g_string_append_indent (output, indent + 1); - g_string_markup_printf (output, "\n", i); - - outline = g_array_index (data.outline_array, gpointer, i); + g_string_markup_printf (output, "\n", oref); for (j = 0; j < outline->num_points; j++) { g_string_append_indent (output, indent + 2); g_string_markup_printf (output, "%lf,%lf\n", @@ -272,7 +270,7 @@ eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent) g_string_append_indent (output, indent + 1); g_string_markup_printf (output, "\n"); } - g_array_free (data.outline_array, TRUE); + g_hash_table_destroy (data.oref_hash); g_string_append_indent (output, indent); g_string_markup_printf (output, "\n"); diff --git a/eek/eek.h b/eek/eek.h index 073cba3b..6a768c82 100644 --- a/eek/eek.h +++ b/eek/eek.h @@ -27,5 +27,6 @@ #include "eek-symbol.h" #include "eek-keysym.h" #include "eek-xml.h" +#include "eek-serializable.h" #endif /* EEK_H */ diff --git a/src/client-main.c b/src/client-main.c index 9bb06f7e..21ed6650 100644 --- a/src/client-main.c +++ b/src/client-main.c @@ -70,6 +70,7 @@ main (int argc, char **argv) gint retval = 0; g_type_init (); + g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); context = g_option_context_new ("eekboard-client"); g_option_context_add_main_entries (context, options, NULL); diff --git a/src/proxy.c b/src/proxy.c index bb3a1824..e1cbfbca 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -21,8 +21,6 @@ #include "proxy.h" -#define BUFSIZE 8192 - enum { KEY_PRESSED, KEY_RELEASED, @@ -150,17 +148,9 @@ proxy_call_async_ready_cb (GObject *source_object, void eekboard_proxy_set_keyboard (EekboardProxy *proxy, EekKeyboard *keyboard) { - GString *output; GVariant *variant; - gchar *data; - - output = g_string_sized_new (BUFSIZE); - eek_keyboard_output (keyboard, output, 0); - - data = g_string_free (output, FALSE); - variant = g_variant_new ("(s)", data); - g_free (data); + variant = eek_serializable_serialize (EEK_SERIALIZABLE(keyboard)); g_dbus_proxy_call (G_DBUS_PROXY(proxy), "SetKeyboard", g_variant_new ("(v)", variant), diff --git a/src/server-main.c b/src/server-main.c index aab08940..e30bfa88 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -50,6 +50,14 @@ main (int argc, char **argv) } #endif + g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); + + g_type_class_ref (EEK_TYPE_KEYBOARD); + g_type_class_ref (EEK_TYPE_SECTION); + g_type_class_ref (EEK_TYPE_KEY); + g_type_class_ref (EEK_TYPE_SYMBOL); + g_type_class_ref (EEK_TYPE_KEYSYM); + error = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (error) { diff --git a/src/server.c b/src/server.c index d53acf02..a57f8205 100644 --- a/src/server.c +++ b/src/server.c @@ -310,26 +310,21 @@ handle_method_call (GDBusConnection *connection, // g_debug ("%s", method_name); if (g_strcmp0 (method_name, "SetKeyboard") == 0) { + EekSerializable *serializable; GVariant *variant; gchar *data; - GInputStream *input; - EekLayout *layout; g_variant_get (parameters, "(v)", &variant); - g_variant_get (variant, "(&s)", &data); - input = g_memory_input_stream_new_from_data (data, -1, NULL); - g_variant_unref (variant); - - layout = eek_xml_layout_new (input); - if (!layout) { + serializable = eek_serializable_deserialize (variant); + if (!EEK_IS_KEYBOARD(serializable)) { g_dbus_method_invocation_return_error (invocation, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED, - "can't create layout"); + "not a keyboard"); return; } - - server->keyboard = eek_keyboard_new (layout, CSW, CSH); + + server->keyboard = EEK_KEYBOARD(serializable); disconnect_keyboard_signals (server); server->key_pressed_handler = g_signal_connect (server->keyboard, "key-pressed",