Implement serialization to GVariant.

This commit is contained in:
Daiki Ueno
2011-02-14 14:13:02 +09:00
parent 11026923bd
commit 7916930160
23 changed files with 774 additions and 396 deletions

View File

@ -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);
}

View File

@ -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 */

View File

@ -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));
}

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -27,9 +27,11 @@
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-types.h"
#include <string.h>
#include <math.h>
#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);
}

View File

@ -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:

View File

@ -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);
}

View File

@ -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",

View File

@ -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-ref>outline%d</outline-ref>\n",
i);
"<oref>outline%u</oref>\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, "<outline id=\"outline%d\">\n", i);
outline = g_array_index (data.outline_array, gpointer, i);
g_string_markup_printf (output, "<outline id=\"outline%u\">\n", oref);
for (j = 0; j < outline->num_points; j++) {
g_string_append_indent (output, indent + 2);
g_string_markup_printf (output, "<point>%lf,%lf</point>\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, "</outline>\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, "</keyboard>\n");

View File

@ -27,5 +27,6 @@
#include "eek-symbol.h"
#include "eek-keysym.h"
#include "eek-xml.h"
#include "eek-serializable.h"
#endif /* EEK_H */

View File

@ -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);

View File

@ -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),

View File

@ -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) {

View File

@ -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",