/* * Copyright (C) 2010 Daiki Ueno * Copyright (C) 2010 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #include "eek-simple-key.h" #include "eek-keysym.h" #include #define DEBUG 0 #if DEBUG #include #endif enum { PROP_0, PROP_NAME, PROP_KEYCODE, PROP_KEYSYMS, PROP_COLUMN, PROP_ROW, PROP_OUTLINE, PROP_BOUNDS, PROP_GROUP, PROP_LEVEL, PROP_LAST }; static void eek_key_iface_init (EekKeyIface *iface); G_DEFINE_TYPE_WITH_CODE (EekSimpleKey, eek_simple_key, G_TYPE_INITIALLY_UNOWNED, G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY, eek_key_iface_init)); #define EEK_SIMPLE_KEY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyPrivate)) struct _EekSimpleKeyPrivate { gchar *name; guint keycode; guint *keysyms; gint num_levels; gint num_groups; gint column; gint row; EekOutline *outline; EekBounds bounds; gint group; gint level; }; static guint eek_simple_key_real_get_keycode (EekKey *self) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_val_if_fail (priv, EEK_INVALID_KEYCODE); return priv->keycode; } static void eek_simple_key_real_set_keysyms (EekKey *self, guint *keysyms, gint groups, gint levels) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); if (priv->keysyms) g_slice_free (guint, priv->keysyms); priv->keysyms = g_slice_alloc (groups * levels * sizeof(guint)); memcpy (priv->keysyms, keysyms, groups * levels * sizeof(guint)); priv->num_groups = groups; priv->num_levels = levels; #if DEBUG { gint i; fprintf (stderr, "%s: ", priv->name); for (i = 0; i < groups * levels; i++) fprintf (stderr, "\"%s\" ", eek_keysym_to_string (keysyms[i])); fprintf (stderr, "\n"); } #endif } static void eek_simple_key_real_get_keysyms (EekKey *self, guint **keysyms, gint *groups, gint *levels) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (groups); g_return_if_fail (levels); g_return_if_fail (keysyms); *groups = priv->num_groups; *levels = priv->num_levels; if (priv->keysyms) { *keysyms = g_slice_alloc (*groups * *levels * sizeof(guint)); memcpy (*keysyms, priv->keysyms, *groups * *levels * sizeof(guint)); } else *keysyms = NULL; } static gint eek_simple_key_real_get_groups (EekKey *self) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_val_if_fail (priv, -1); return priv->num_groups; } static guint eek_simple_key_real_get_keysym (EekKey *self) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_val_if_fail (priv, EEK_INVALID_KEYSYM); if (priv->num_groups * priv->num_levels == 0) return EEK_INVALID_KEYSYM; return priv->keysyms[priv->group * priv->num_levels + priv->level]; } static void eek_simple_key_real_set_index (EekKey *self, gint column, gint row) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); g_return_if_fail (column < 0); g_return_if_fail (row < 0); priv->column = column; priv->row = row; } static void eek_simple_key_real_get_index (EekKey *self, gint *column, gint *row) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); g_return_if_fail (column); g_return_if_fail (row); *column = priv->column; *row = priv->row; } static void eek_simple_key_real_set_outline (EekKey *self, EekOutline *outline) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); priv->outline = outline; } static EekOutline * eek_simple_key_real_get_outline (EekKey *self) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_val_if_fail (priv, NULL); return priv->outline; } static void eek_simple_key_real_set_bounds (EekKey *self, EekBounds *bounds) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); priv->bounds = *bounds; } static void eek_simple_key_real_get_bounds (EekKey *self, EekBounds *bounds) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); g_return_if_fail (bounds); *bounds = priv->bounds; } static void eek_simple_key_real_set_keysym_index (EekKey *self, gint group, gint level) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); g_return_if_fail (group < priv->num_groups); g_return_if_fail (level < priv->num_levels); priv->group = group; priv->level = level; } static void eek_simple_key_real_get_keysym_index (EekKey *self, gint *group, gint *level) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); g_return_if_fail (priv); g_return_if_fail (group); g_return_if_fail (level); *group = priv->group; *level = priv->level; } static void eek_key_iface_init (EekKeyIface *iface) { iface->get_keycode = eek_simple_key_real_get_keycode; iface->set_keysyms = eek_simple_key_real_set_keysyms; iface->get_keysyms = eek_simple_key_real_get_keysyms; iface->get_groups = eek_simple_key_real_get_groups; iface->get_keysym = eek_simple_key_real_get_keysym; iface->set_index = eek_simple_key_real_set_index; iface->get_index = eek_simple_key_real_get_index; iface->set_outline = eek_simple_key_real_set_outline; iface->get_outline = eek_simple_key_real_get_outline; iface->set_bounds = eek_simple_key_real_set_bounds; iface->get_bounds = eek_simple_key_real_get_bounds; iface->set_keysym_index = eek_simple_key_real_set_keysym_index; iface->get_keysym_index = eek_simple_key_real_get_keysym_index; } static void eek_simple_key_dispose (GObject *object) { G_OBJECT_CLASS (eek_simple_key_parent_class)->dispose (object); } static void eek_simple_key_finalize (GObject *object) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); g_free (priv->name); g_slice_free (guint, priv->keysyms); G_OBJECT_CLASS (eek_simple_key_parent_class)->finalize (object); } static void eek_simple_key_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); EekKeysymMatrix *matrix; g_return_if_fail (priv); switch (prop_id) { case PROP_NAME: g_free (priv->name); priv->name = g_strdup (g_value_get_string (value)); break; case PROP_KEYCODE: priv->keycode = g_value_get_uint (value); break; case PROP_KEYSYMS: matrix = g_value_get_boxed (value); eek_key_set_keysyms (EEK_KEY(object), matrix->data, matrix->num_groups, matrix->num_levels); break; case PROP_COLUMN: priv->column = g_value_get_int (value); break; case PROP_ROW: priv->row = g_value_get_int (value); break; case PROP_OUTLINE: priv->outline = g_value_get_pointer (value); break; case PROP_BOUNDS: priv->bounds = *(EekBounds *)g_value_get_boxed (value); break; case PROP_GROUP: priv->group = g_value_get_int (value); break; case PROP_LEVEL: priv->level = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); g_object_set_property (object, g_param_spec_get_name (pspec), value); break; } } static void eek_simple_key_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); EekKeysymMatrix matrix; g_return_if_fail (priv); switch (prop_id) { case PROP_NAME: g_value_set_string (value, priv->name); break; case PROP_KEYCODE: g_value_set_uint (value, priv->keycode); break; case PROP_KEYSYMS: matrix.data = priv->keysyms; matrix.num_groups = priv->num_groups; matrix.num_levels = priv->num_levels; g_value_set_boxed (value, &matrix); break; case PROP_COLUMN: g_value_set_int (value, priv->column); break; case PROP_ROW: g_value_set_int (value, priv->row); break; case PROP_OUTLINE: g_value_set_pointer (value, priv->outline); break; case PROP_BOUNDS: g_value_set_boxed (value, &priv->bounds); break; case PROP_GROUP: g_value_set_int (value, priv->group); break; case PROP_LEVEL: g_value_set_int (value, priv->level); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); g_object_get_property (object, g_param_spec_get_name (pspec), value); break; } } static void eek_simple_key_class_init (EekSimpleKeyClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; g_type_class_add_private (gobject_class, sizeof (EekSimpleKeyPrivate)); gobject_class->set_property = eek_simple_key_set_property; gobject_class->get_property = eek_simple_key_get_property; gobject_class->finalize = eek_simple_key_finalize; gobject_class->dispose = eek_simple_key_dispose; g_object_class_override_property (gobject_class, PROP_NAME, "name"); g_object_class_override_property (gobject_class, PROP_KEYCODE, "keycode"); g_object_class_override_property (gobject_class, PROP_KEYSYMS, "keysyms"); g_object_class_override_property (gobject_class, PROP_COLUMN, "column"); g_object_class_override_property (gobject_class, PROP_ROW, "row"); g_object_class_override_property (gobject_class, PROP_OUTLINE, "outline"); g_object_class_override_property (gobject_class, PROP_BOUNDS, "bounds"); g_object_class_override_property (gobject_class, PROP_GROUP, "group"); g_object_class_override_property (gobject_class, PROP_LEVEL, "level"); } static void eek_simple_key_init (EekSimpleKey *self) { EekSimpleKeyPrivate *priv; priv = self->priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); priv->keysyms = NULL; priv->keycode = 0; priv->num_groups = 0; priv->num_levels = 0; priv->column = 0; priv->row = 0; priv->outline = NULL; memset (&priv->bounds, 0, sizeof priv->bounds); }