Fix object finalization.
Add XKL wrapper (not ready).
This commit is contained in:
@ -35,9 +35,11 @@ PKG_CHECK_MODULES([PANGO], [pango], ,
|
||||
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], ,
|
||||
[AC_MSG_ERROR([Clutter not found])])
|
||||
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 gdk-2.0], ,
|
||||
[AC_MSG_ERROR([GTK2 support not found])])
|
||||
[AC_MSG_ERROR([GTK2 not found])])
|
||||
PKG_CHECK_MODULES([XKB], [x11], ,
|
||||
[AC_MSG_ERROR([XKB support not found])])
|
||||
PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], ,
|
||||
[AC_MSG_ERROR([Libxklavier not found])])
|
||||
|
||||
GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
|
||||
|
||||
@ -56,5 +58,6 @@ docs/reference/Makefile
|
||||
docs/reference/eek/Makefile
|
||||
eek/eek.pc
|
||||
eek/eek-clutter.pc
|
||||
eek/eek-xkb.pc])
|
||||
eek/eek-xkb.pc
|
||||
eek/eek-xkl.pc])
|
||||
AC_OUTPUT
|
||||
|
||||
@ -32,6 +32,10 @@
|
||||
<title>XKB layout engine</title>
|
||||
<xi:include href="xml/eek-xkb-layout.xml"/>
|
||||
</chapter>
|
||||
<chapter>
|
||||
<title>Libxklavier layout engine</title>
|
||||
<xi:include href="xml/eek-xkl-layout.xml"/>
|
||||
</chapter>
|
||||
<chapter id="object-tree">
|
||||
<title>Object Hierarchy</title>
|
||||
<xi:include href="xml/tree_index.sgml"/>
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301 USA
|
||||
|
||||
lib_LTLIBRARIES = libeek.la libeek-clutter.la libeek-xkb.la
|
||||
lib_LTLIBRARIES = libeek.la libeek-clutter.la libeek-xkb.la libeek-xkl.la
|
||||
|
||||
libeek_la_SOURCES = \
|
||||
eek-layout.c \
|
||||
@ -66,6 +66,14 @@ libeek_xkb_la_SOURCES = \
|
||||
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS)
|
||||
libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS)
|
||||
|
||||
libeek_xkl_la_SOURCES = \
|
||||
eek-xkl-layout.h \
|
||||
eek-xkl-layout.c \
|
||||
$(NULL)
|
||||
|
||||
libeek_xkl_la_CFLAGS = $(GTK2_CFLAGS) $(LIBXKLAVIER_CFLAGS)
|
||||
libeek_xkl_la_LIBADD = libeek-xkb.la $(GTK2_LIBS) $(LIBXKLAVIER_LIBS)
|
||||
|
||||
eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
|
||||
eek_HEADERS = \
|
||||
$(top_srcdir)/eek/eek-element.h \
|
||||
@ -80,9 +88,11 @@ eek_HEADERS = \
|
||||
$(top_srcdir)/eek/eek-clutter-section.h \
|
||||
$(top_srcdir)/eek/eek-clutter-key.h \
|
||||
$(top_srcdir)/eek/eek-xkb-layout.h \
|
||||
$(top_srcdir)/eek/eek-xkl-layout.h \
|
||||
$(top_srcdir)/eek/eek.h \
|
||||
$(top_srcdir)/eek/eek-clutter.h \
|
||||
$(top_srcdir)/eek/eek-xkb.h
|
||||
$(top_srcdir)/eek/eek-xkb.h \
|
||||
$(top_srcdir)/eek/eek-xkl.h
|
||||
|
||||
eek-keysym.c: eek-special-keysym-labels.h eek-unicode-keysym-labels.h eek-keyname-keysym-labels.h
|
||||
|
||||
@ -94,7 +104,7 @@ eek-keyname-keysym-labels.h: keyname-keysym-labels.txt
|
||||
$(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = eek.pc eek-clutter.pc eek-xkb.pc
|
||||
pkgconfig_DATA = eek.pc eek-clutter.pc eek-xkb.pc eek-xkl.pc
|
||||
|
||||
DISTCLEANFILES = \
|
||||
eek-special-keysym-labels.h \
|
||||
|
||||
@ -35,6 +35,14 @@
|
||||
|
||||
#define noKBDRAW_DEBUG
|
||||
|
||||
enum {
|
||||
PRESSED,
|
||||
RELEASED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE (EekClutterKeyActor, eek_clutter_key_actor,
|
||||
CLUTTER_TYPE_GROUP);
|
||||
|
||||
@ -47,12 +55,20 @@ struct _EekClutterKeyActorPrivate
|
||||
ClutterActor *texture;
|
||||
};
|
||||
|
||||
static struct {
|
||||
/* outline pointer -> ClutterTexture */
|
||||
GHashTable *outline_textures;
|
||||
gint outline_textures_ref_count;
|
||||
} texture_cache;
|
||||
|
||||
static gboolean on_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data);
|
||||
static ClutterActor *get_texture (EekClutterKeyActor *actor);
|
||||
static void draw_key_on_layout (EekKey *key,
|
||||
PangoLayout *layout);
|
||||
static void key_enlarge (ClutterActor *actor);
|
||||
static void key_shrink (ClutterActor *actor);
|
||||
|
||||
static void
|
||||
eek_clutter_key_actor_real_paint (ClutterActor *self)
|
||||
@ -119,11 +135,46 @@ eek_clutter_key_actor_real_get_preferred_width (ClutterActor *self,
|
||||
get_preferred_width (self, for_height, min_width_p, natural_width_p);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_key_actor_real_pressed (EekClutterKeyActor *self)
|
||||
{
|
||||
ClutterActor *actor, *section;
|
||||
|
||||
actor = CLUTTER_ACTOR(self);
|
||||
|
||||
/* Make sure the enlarged key show up on the keys which belong
|
||||
to other sections. */
|
||||
section = clutter_actor_get_parent (actor);
|
||||
clutter_actor_raise_top (section);
|
||||
clutter_actor_raise_top (actor);
|
||||
key_enlarge (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_key_actor_real_released (EekClutterKeyActor *self)
|
||||
{
|
||||
ClutterActor *actor, *section;
|
||||
|
||||
actor = CLUTTER_ACTOR(self);
|
||||
|
||||
/* Make sure the enlarged key show up on the keys which belong
|
||||
to other sections. */
|
||||
section = clutter_actor_get_parent (actor);
|
||||
clutter_actor_raise_top (section);
|
||||
clutter_actor_raise_top (actor);
|
||||
key_shrink (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_key_actor_finalize (GObject *object)
|
||||
{
|
||||
EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(object);
|
||||
|
||||
g_object_unref (priv->key);
|
||||
if (priv->texture && --texture_cache.outline_textures_ref_count <= 0) {
|
||||
g_hash_table_unref (texture_cache.outline_textures);
|
||||
texture_cache.outline_textures = NULL;
|
||||
}
|
||||
G_OBJECT_CLASS (eek_clutter_key_actor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -145,6 +196,54 @@ eek_clutter_key_actor_class_init (EekClutterKeyActorClass *klass)
|
||||
eek_clutter_key_actor_real_get_preferred_width;
|
||||
|
||||
gobject_class->finalize = eek_clutter_key_actor_finalize;
|
||||
|
||||
/* signals */
|
||||
klass->pressed = eek_clutter_key_actor_real_pressed;
|
||||
klass->released = eek_clutter_key_actor_real_released;
|
||||
|
||||
signals[PRESSED] =
|
||||
g_signal_new ("pressed",
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET(EekClutterKeyActorClass, pressed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[RELEASED] =
|
||||
g_signal_new ("released",
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET(EekClutterKeyActorClass, released),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_button_press_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekClutterKeyActorPrivate *priv =
|
||||
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
|
||||
|
||||
/* priv->key will send back PRESSED event of actor. */
|
||||
g_signal_emit_by_name (priv->key, "pressed");
|
||||
}
|
||||
|
||||
static void
|
||||
on_button_release_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekClutterKeyActorPrivate *priv =
|
||||
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
|
||||
|
||||
/* priv->key will send back RELEASED event of actor. */
|
||||
g_signal_emit_by_name (priv->key, "released");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -156,7 +255,10 @@ eek_clutter_key_actor_init (EekClutterKeyActor *self)
|
||||
priv->key = NULL;
|
||||
priv->texture = NULL;
|
||||
clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE);
|
||||
g_signal_connect (self, "event", G_CALLBACK (on_event), NULL);
|
||||
g_signal_connect (self, "button-press-event",
|
||||
G_CALLBACK (on_button_press_event), NULL);
|
||||
g_signal_connect (self, "button-release-event",
|
||||
G_CALLBACK (on_button_release_event), NULL);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
@ -166,7 +268,7 @@ eek_clutter_key_actor_new (EekKey *key)
|
||||
|
||||
actor = g_object_new (EEK_TYPE_CLUTTER_KEY_ACTOR, NULL);
|
||||
actor->priv->key = key;
|
||||
g_object_ref (actor->priv->key);
|
||||
g_object_ref_sink (actor->priv->key);
|
||||
return CLUTTER_ACTOR(actor);
|
||||
}
|
||||
|
||||
@ -479,23 +581,22 @@ create_texture_for_key (EekKey *key)
|
||||
static ClutterActor *
|
||||
get_texture (EekClutterKeyActor *actor)
|
||||
{
|
||||
EekClutterKeyActorClass *actor_class =
|
||||
EEK_CLUTTER_KEY_ACTOR_GET_CLASS(actor);
|
||||
ClutterActor *texture;
|
||||
EekOutline *outline;
|
||||
|
||||
if (!actor_class->outline_textures)
|
||||
actor_class->outline_textures = g_hash_table_new_full (g_direct_hash,
|
||||
if (!texture_cache.outline_textures)
|
||||
texture_cache.outline_textures = g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
g_free);
|
||||
outline = eek_key_get_outline (actor->priv->key);
|
||||
texture = g_hash_table_lookup (actor_class->outline_textures, outline);
|
||||
texture = g_hash_table_lookup (texture_cache.outline_textures, outline);
|
||||
if (texture == NULL) {
|
||||
texture = create_texture_for_key (actor->priv->key);
|
||||
g_hash_table_insert (actor_class->outline_textures, outline, texture);
|
||||
g_hash_table_insert (texture_cache.outline_textures, outline, texture);
|
||||
} else
|
||||
texture = clutter_clone_new (texture);
|
||||
texture_cache.outline_textures_ref_count++;
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
@ -49,8 +49,9 @@ struct _EekClutterKeyActorClass
|
||||
/*< private >*/
|
||||
ClutterGroupClass parent_class;
|
||||
|
||||
/* outline pointer -> ClutterTexture */
|
||||
GHashTable *outline_textures;
|
||||
/* signals */
|
||||
void (* pressed) (EekClutterKeyActor *self);
|
||||
void (* released) (EekClutterKeyActor *self);
|
||||
};
|
||||
|
||||
GType eek_clutter_key_actor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
@ -68,13 +68,29 @@ eek_clutter_key_real_set_bounds (EekElement *self,
|
||||
clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_key_real_pressed (EekKey *key)
|
||||
{
|
||||
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key);
|
||||
|
||||
if (priv->actor)
|
||||
g_signal_emit_by_name (priv->actor, "pressed");
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_key_real_released (EekKey *key)
|
||||
{
|
||||
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key);
|
||||
|
||||
if (priv->actor)
|
||||
g_signal_emit_by_name (priv->actor, "released");
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_key_finalize (GObject *object)
|
||||
{
|
||||
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
|
||||
|
||||
/* No need for clutter_group_remove_all() since
|
||||
ClutterGroup#dispose() unrefs all the children. */
|
||||
if (priv->actor)
|
||||
g_object_unref (priv->actor);
|
||||
G_OBJECT_CLASS (eek_clutter_key_parent_class)->finalize (object);
|
||||
@ -85,6 +101,7 @@ eek_clutter_key_class_init (EekClutterKeyClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
EekElementClass *element_class = EEK_ELEMENT_CLASS (klass);
|
||||
EekKeyClass *key_class = EEK_KEY_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekClutterKeyPrivate));
|
||||
@ -92,6 +109,10 @@ eek_clutter_key_class_init (EekClutterKeyClass *klass)
|
||||
element_class->set_name = eek_clutter_key_real_set_name;
|
||||
element_class->set_bounds = eek_clutter_key_real_set_bounds;
|
||||
gobject_class->finalize = eek_clutter_key_finalize;
|
||||
|
||||
/* signals */
|
||||
key_class->pressed = eek_clutter_key_real_pressed;
|
||||
key_class->released = eek_clutter_key_real_released;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -106,7 +127,9 @@ ClutterActor *
|
||||
eek_clutter_key_get_actor (EekClutterKey *key)
|
||||
{
|
||||
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key);
|
||||
if (!priv->actor)
|
||||
if (!priv->actor) {
|
||||
priv->actor = eek_clutter_key_actor_new (EEK_KEY(key));
|
||||
g_object_ref_sink (priv->actor);
|
||||
}
|
||||
return priv->actor;
|
||||
}
|
||||
|
||||
@ -40,7 +40,6 @@ G_DEFINE_TYPE (EekClutterKeyboard, eek_clutter_keyboard, EEK_TYPE_KEYBOARD);
|
||||
struct _EekClutterKeyboardPrivate
|
||||
{
|
||||
ClutterActor *actor;
|
||||
EekLayout *layout;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -96,7 +95,6 @@ eek_clutter_keyboard_real_create_section (EekKeyboard *self)
|
||||
|
||||
section = g_object_new (EEK_TYPE_CLUTTER_SECTION, NULL);
|
||||
g_return_val_if_fail (section, NULL);
|
||||
g_object_ref_sink (section);
|
||||
|
||||
g_signal_connect (section, "key-pressed",
|
||||
G_CALLBACK(key_pressed_event), self);
|
||||
@ -114,31 +112,13 @@ eek_clutter_keyboard_real_create_section (EekKeyboard *self)
|
||||
return section;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_keyboard_real_set_layout (EekKeyboard *self,
|
||||
EekLayout *layout)
|
||||
{
|
||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
g_return_if_fail (EEK_IS_LAYOUT(layout));
|
||||
|
||||
/* Don't apply the layout to keyboard right now, so to delay
|
||||
drawing until eek_clutter_keyboard_get_actor. */
|
||||
priv->layout = layout;
|
||||
g_object_ref_sink (priv->layout);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_clutter_keyboard_finalize (GObject *object)
|
||||
{
|
||||
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object);
|
||||
|
||||
/* No need for clutter_group_remove_all() since
|
||||
ClutterGroup#dispose() unrefs all the children. */
|
||||
if (priv->actor)
|
||||
g_object_unref (priv->actor);
|
||||
if (priv->layout)
|
||||
g_object_unref (priv->layout);
|
||||
G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -165,7 +145,6 @@ eek_clutter_keyboard_init (EekClutterKeyboard *self)
|
||||
|
||||
priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
|
||||
priv->actor = NULL;
|
||||
priv->layout = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,14 +174,67 @@ eek_clutter_keyboard_new (gfloat width,
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_clutter_key_press_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint keycode;
|
||||
EekKey *key;
|
||||
|
||||
keycode = clutter_event_get_key_code (event);
|
||||
key = eek_keyboard_find_key_by_keycode (user_data, keycode);
|
||||
if (key) {
|
||||
g_signal_emit_by_name (key, "pressed", NULL);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_clutter_key_release_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint keycode;
|
||||
EekKey *key;
|
||||
|
||||
keycode = clutter_event_get_key_code (event);
|
||||
key = eek_keyboard_find_key_by_keycode (user_data, keycode);
|
||||
if (key) {
|
||||
g_signal_emit_by_name (key, "released", NULL);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_clutter_realize (ClutterActor *actor, gpointer user_data)
|
||||
{
|
||||
EekClutterKeyboard *keyboard = user_data;
|
||||
EekClutterKeyboardPrivate *priv =
|
||||
EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard);
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = clutter_actor_get_stage (priv->actor);
|
||||
g_signal_connect (stage, "key-press-event",
|
||||
G_CALLBACK (on_clutter_key_press_event), keyboard);
|
||||
g_signal_connect (stage, "key-release-event",
|
||||
G_CALLBACK (on_clutter_key_release_event), keyboard);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard)
|
||||
{
|
||||
EekClutterKeyboardPrivate *priv =
|
||||
EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard);
|
||||
if (!priv->actor)
|
||||
if (!priv->actor) {
|
||||
priv->actor = clutter_group_new ();
|
||||
if (priv->layout)
|
||||
eek_layout_apply (priv->layout, EEK_KEYBOARD(keyboard));
|
||||
g_object_ref_sink (priv->actor);
|
||||
g_signal_connect (priv->actor, "realize",
|
||||
G_CALLBACK (on_clutter_realize), keyboard);
|
||||
g_return_val_if_fail (priv->actor, NULL);
|
||||
eek_keyboard_realize (EEK_KEYBOARD(keyboard));
|
||||
}
|
||||
return priv->actor;
|
||||
}
|
||||
|
||||
@ -116,7 +116,6 @@ eek_clutter_section_real_create_key (EekSection *self,
|
||||
"row", row,
|
||||
NULL);
|
||||
g_return_val_if_fail (key, NULL);
|
||||
g_object_ref_sink (key);
|
||||
|
||||
g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self);
|
||||
g_signal_connect (key, "released", G_CALLBACK(released_event), self);
|
||||
@ -137,8 +136,6 @@ eek_clutter_section_finalize (GObject *object)
|
||||
{
|
||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object);
|
||||
|
||||
/* No need for clutter_group_remove_all() since
|
||||
ClutterGroup#dispose() unrefs all the children. */
|
||||
if (priv->actor)
|
||||
g_object_unref (priv->actor);
|
||||
G_OBJECT_CLASS (eek_clutter_section_parent_class)->finalize (object);
|
||||
@ -172,7 +169,9 @@ ClutterActor *
|
||||
eek_clutter_section_get_actor (EekClutterSection *section)
|
||||
{
|
||||
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(section);
|
||||
if (!priv->actor)
|
||||
if (!priv->actor) {
|
||||
priv->actor = clutter_group_new ();
|
||||
g_object_ref_sink (priv->actor);
|
||||
}
|
||||
return priv->actor;
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ eek_container_real_add_child (EekContainer *self,
|
||||
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
|
||||
|
||||
g_return_if_fail (EEK_IS_ELEMENT(child));
|
||||
g_object_ref (child);
|
||||
g_object_ref_sink (child);
|
||||
priv->children = g_slist_prepend (priv->children, child);
|
||||
}
|
||||
|
||||
@ -88,6 +88,20 @@ eek_container_real_foreach_child (EekContainer *self,
|
||||
(*callback) (EEK_ELEMENT(head->data), user_data);
|
||||
}
|
||||
|
||||
static EekElement *
|
||||
eek_container_real_find (EekContainer *self,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
|
||||
GSList *head;
|
||||
|
||||
head = g_slist_find_custom (priv->children, user_data, (GCompareFunc)func);
|
||||
if (head)
|
||||
return head->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_container_finalize (GObject *object)
|
||||
{
|
||||
@ -111,6 +125,7 @@ eek_container_class_init (EekContainerClass *klass)
|
||||
klass->add_child = eek_container_real_add_child;
|
||||
klass->remove_child = eek_container_real_remove_child;
|
||||
klass->foreach_child = eek_container_real_foreach_child;
|
||||
klass->find = eek_container_real_find;
|
||||
|
||||
gobject_class->finalize = eek_container_finalize;
|
||||
|
||||
@ -155,3 +170,14 @@ eek_container_foreach_child (EekContainer *container,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
EekElement *
|
||||
eek_container_find (EekContainer *container,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
|
||||
return EEK_CONTAINER_GET_CLASS(container)->find (container,
|
||||
func,
|
||||
user_data);
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ typedef struct _EekContainerClass EekContainerClass;
|
||||
typedef struct _EekContainerPrivate EekContainerPrivate;
|
||||
|
||||
typedef void (*EekCallback) (EekElement *element, gpointer user_data);
|
||||
typedef gint (*EekCompareFunc) (EekElement *element, gpointer user_data);
|
||||
|
||||
struct _EekContainer
|
||||
{
|
||||
@ -61,6 +62,9 @@ struct _EekContainerClass
|
||||
void (* foreach_child) (EekContainer *self,
|
||||
EekCallback callback,
|
||||
gpointer user_data);
|
||||
EekElement *(* find) (EekContainer *self,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
/* signals */
|
||||
void (* child_added) (EekContainer *self,
|
||||
@ -74,6 +78,9 @@ GType eek_container_get_type (void) G_GNUC_CONST;
|
||||
void eek_container_foreach_child (EekContainer *self,
|
||||
EekCallback callback,
|
||||
gpointer user_data);
|
||||
EekElement *eek_container_find (EekContainer *container,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_CONTAINER_H */
|
||||
|
||||
@ -221,6 +221,18 @@ eek_key_real_get_keysym_index (EekKey *self,
|
||||
*level = priv->level;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_real_pressed (EekKey *key)
|
||||
{
|
||||
g_debug ("pressed %X", eek_key_get_keycode (key));
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_real_released (EekKey *key)
|
||||
{
|
||||
g_debug ("released %X", eek_key_get_keycode (key));
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_finalize (GObject *object)
|
||||
{
|
||||
@ -354,6 +366,10 @@ eek_key_class_init (EekKeyClass *klass)
|
||||
gobject_class->get_property = eek_key_get_property;
|
||||
gobject_class->finalize = eek_key_finalize;
|
||||
|
||||
/* signals */
|
||||
klass->pressed = eek_key_real_pressed;
|
||||
klass->released = eek_key_real_released;
|
||||
|
||||
/**
|
||||
* EekKey:keycode:
|
||||
*
|
||||
@ -444,7 +460,7 @@ eek_key_class_init (EekKeyClass *klass)
|
||||
g_signal_new ("pressed",
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
G_STRUCT_OFFSET(EekKeyClass, pressed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
@ -454,7 +470,7 @@ eek_key_class_init (EekKeyClass *klass)
|
||||
g_signal_new ("released",
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
G_STRUCT_OFFSET(EekKeyClass, released),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
|
||||
@ -80,6 +80,10 @@ struct _EekKeyClass
|
||||
void (* get_keysym_index) (EekKey *self,
|
||||
gint *group,
|
||||
gint *level);
|
||||
|
||||
/* signals */
|
||||
void (* pressed) (EekKey *key);
|
||||
void (* released) (EekKey *key);
|
||||
};
|
||||
|
||||
GType eek_key_get_type (void) G_GNUC_CONST;
|
||||
|
||||
@ -60,6 +60,8 @@ struct _EekKeyboardPrivate
|
||||
{
|
||||
gint group;
|
||||
gint level;
|
||||
EekLayout *layout;
|
||||
gboolean is_realized;
|
||||
};
|
||||
|
||||
struct keysym_index {
|
||||
@ -141,7 +143,6 @@ eek_keyboard_real_create_section (EekKeyboard *self)
|
||||
|
||||
section = g_object_new (EEK_TYPE_SECTION, NULL);
|
||||
g_return_val_if_fail (section, NULL);
|
||||
g_object_ref_sink (section);
|
||||
|
||||
g_signal_connect (section, "key-pressed",
|
||||
G_CALLBACK(key_pressed_event), self);
|
||||
@ -157,12 +158,64 @@ static void
|
||||
eek_keyboard_real_set_layout (EekKeyboard *self,
|
||||
EekLayout *layout)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
g_return_if_fail (EEK_IS_LAYOUT(layout));
|
||||
priv->layout = layout;
|
||||
g_object_ref_sink (priv->layout);
|
||||
}
|
||||
|
||||
EEK_LAYOUT_GET_IFACE(layout)->apply (layout, self);
|
||||
static void
|
||||
eek_keyboard_real_realize (EekKeyboard *self)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
if (g_object_is_floating (layout))
|
||||
g_object_unref (layout);
|
||||
g_return_if_fail (priv->layout);
|
||||
g_return_if_fail (!priv->is_realized);
|
||||
EEK_LAYOUT_GET_IFACE(priv->layout)->apply (priv->layout, self);
|
||||
priv->is_realized = TRUE;
|
||||
}
|
||||
|
||||
struct find_key_by_keycode_data {
|
||||
EekKey *key;
|
||||
guint keycode;
|
||||
};
|
||||
|
||||
static gint
|
||||
compare_section_by_keycode (EekElement *element, gpointer user_data)
|
||||
{
|
||||
struct find_key_by_keycode_data *data = user_data;
|
||||
|
||||
data->key = eek_section_find_key_by_keycode (EEK_SECTION(element),
|
||||
data->keycode);
|
||||
if (data->key)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static EekKey *
|
||||
eek_keyboard_real_find_key_by_keycode (EekKeyboard *self,
|
||||
guint keycode)
|
||||
{
|
||||
struct find_key_by_keycode_data data;
|
||||
|
||||
data.keycode = keycode;
|
||||
if (eek_container_find (EEK_CONTAINER(self),
|
||||
compare_section_by_keycode,
|
||||
&data))
|
||||
return data.key;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_finalize (GObject *object)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
|
||||
|
||||
if (priv->layout)
|
||||
g_object_unref (priv->layout);
|
||||
|
||||
G_OBJECT_CLASS(eek_keyboard_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -234,9 +287,12 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
||||
klass->get_keysym_index = eek_keyboard_real_get_keysym_index;
|
||||
klass->create_section = eek_keyboard_real_create_section;
|
||||
klass->set_layout = eek_keyboard_real_set_layout;
|
||||
klass->realize = eek_keyboard_real_realize;
|
||||
klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode;
|
||||
|
||||
gobject_class->get_property = eek_keyboard_get_property;
|
||||
gobject_class->set_property = eek_keyboard_set_property;
|
||||
gobject_class->finalize = eek_keyboard_finalize;
|
||||
|
||||
/**
|
||||
* EekKeyboard:group:
|
||||
@ -298,6 +354,8 @@ eek_keyboard_init (EekKeyboard *self)
|
||||
|
||||
priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
priv->group = priv->level = 0;
|
||||
priv->layout = NULL;
|
||||
priv->is_realized = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -368,3 +426,19 @@ eek_keyboard_set_layout (EekKeyboard *keyboard,
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
EEK_KEYBOARD_GET_CLASS(keyboard)->set_layout (keyboard, layout);
|
||||
}
|
||||
|
||||
void
|
||||
eek_keyboard_realize (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
EEK_KEYBOARD_GET_CLASS(keyboard)->realize (keyboard);
|
||||
}
|
||||
|
||||
EekKey *
|
||||
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
|
||||
guint keycode)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
return EEK_KEYBOARD_GET_CLASS(keyboard)->find_key_by_keycode (keyboard,
|
||||
keycode);
|
||||
}
|
||||
|
||||
@ -62,6 +62,9 @@ struct _EekKeyboardClass
|
||||
|
||||
void (* set_layout) (EekKeyboard *self,
|
||||
EekLayout *layout);
|
||||
EekKey *(* find_key_by_keycode) (EekKeyboard *self,
|
||||
guint keycode);
|
||||
void (* realize) (EekKeyboard *self);
|
||||
};
|
||||
|
||||
GType eek_keyboard_get_type (void) G_GNUC_CONST;
|
||||
@ -77,6 +80,9 @@ EekSection *eek_keyboard_create_section (EekKeyboard *keyboard);
|
||||
|
||||
void eek_keyboard_set_layout (EekKeyboard *keyboard,
|
||||
EekLayout *layout);
|
||||
void eek_keyboard_realize (EekKeyboard *keyboard);
|
||||
EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
|
||||
guint keycode);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_KEYBOARD_H */
|
||||
|
||||
@ -158,7 +158,6 @@ eek_section_real_create_key (EekSection *self,
|
||||
"row", row,
|
||||
NULL);
|
||||
g_return_val_if_fail (key, NULL);
|
||||
g_object_ref_sink (key);
|
||||
|
||||
g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self);
|
||||
g_signal_connect (key, "released", G_CALLBACK(released_event), self);
|
||||
@ -169,6 +168,23 @@ eek_section_real_create_key (EekSection *self,
|
||||
return key;
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_key_by_keycode (EekElement *element, gpointer user_data)
|
||||
{
|
||||
if (eek_key_get_keycode (EEK_KEY(element)) == (guint)(long)user_data)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static EekKey *
|
||||
eek_section_real_find_key_by_keycode (EekSection *self,
|
||||
guint keycode)
|
||||
{
|
||||
return (EekKey *)eek_container_find (EEK_CONTAINER(self),
|
||||
compare_key_by_keycode,
|
||||
(gpointer)(long)keycode);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_finalize (GObject *object)
|
||||
{
|
||||
@ -179,10 +195,6 @@ eek_section_finalize (GObject *object)
|
||||
g_slice_free (EekRow, head->data);
|
||||
g_slist_free (priv->rows);
|
||||
|
||||
for (head = priv->keys; head; head = g_slist_next (head))
|
||||
g_object_unref (head->data);
|
||||
g_slist_free (priv->keys);
|
||||
|
||||
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -237,6 +249,7 @@ eek_section_class_init (EekSectionClass *klass)
|
||||
klass->add_row = eek_section_real_add_row;
|
||||
klass->get_row = eek_section_real_get_row;
|
||||
klass->create_key = eek_section_real_create_key;
|
||||
klass->find_key_by_keycode = eek_section_real_find_key_by_keycode;
|
||||
|
||||
gobject_class->set_property = eek_section_set_property;
|
||||
gobject_class->get_property = eek_section_get_property;
|
||||
@ -289,7 +302,6 @@ eek_section_init (EekSection *self)
|
||||
priv = self->priv = EEK_SECTION_GET_PRIVATE (self);
|
||||
priv->angle = 0;
|
||||
priv->rows = NULL;
|
||||
priv->keys = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -346,3 +358,12 @@ eek_section_create_key (EekSection *section,
|
||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||
return EEK_SECTION_GET_CLASS(section)->create_key (section, column, row);
|
||||
}
|
||||
|
||||
EekKey *
|
||||
eek_section_find_key_by_keycode (EekSection *section,
|
||||
guint keycode)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||
return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section,
|
||||
keycode);
|
||||
}
|
||||
|
||||
@ -66,6 +66,9 @@ struct _EekSectionClass
|
||||
EekKey *(* create_key) (EekSection *self,
|
||||
gint row,
|
||||
gint column);
|
||||
|
||||
EekKey *(* find_key_by_keycode) (EekSection *self,
|
||||
guint keycode);
|
||||
};
|
||||
|
||||
GType eek_section_get_type (void) G_GNUC_CONST;
|
||||
@ -87,5 +90,8 @@ EekKey *eek_section_create_key (EekSection *section,
|
||||
gint column,
|
||||
gint row);
|
||||
|
||||
EekKey *eek_section_find_key_by_keycode (EekSection *self,
|
||||
guint keycode);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_SECTION_H */
|
||||
|
||||
@ -145,7 +145,8 @@ create_key (EekXkbLayout *layout,
|
||||
gdouble x1, y1, x2, y2;
|
||||
|
||||
outline->num_points = 4;
|
||||
outline->points = g_new0 (EekPoint, outline->num_points);
|
||||
outline->points = g_slice_alloc0 (sizeof (EekPoint) *
|
||||
outline->num_points);
|
||||
if (xkboutline->num_points == 1) {
|
||||
x1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.x1);
|
||||
y1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.y1);
|
||||
@ -232,9 +233,10 @@ create_section (EekXkbLayout *layout,
|
||||
|
||||
priv = layout->priv;
|
||||
xkbgeometry = priv->xkb->geom;
|
||||
name = XGetAtomName (priv->display, xkbsection->name);
|
||||
section = eek_keyboard_create_section (keyboard);
|
||||
name = XGetAtomName (priv->display, xkbsection->name);
|
||||
eek_element_set_name (EEK_ELEMENT(section), name);
|
||||
XFree (name);
|
||||
eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
|
||||
eek_section_set_angle (section,
|
||||
/* angle is in tenth of degree */
|
||||
@ -303,11 +305,22 @@ static void
|
||||
eek_xkb_layout_real_apply (EekLayout *layout, EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
|
||||
create_keyboard (EEK_XKB_LAYOUT(layout), keyboard);
|
||||
}
|
||||
|
||||
if (g_object_is_floating (keyboard))
|
||||
g_object_unref (keyboard);
|
||||
static void
|
||||
eek_xkb_layout_real_set_names (EekXkbLayout *self, XkbComponentNamesRec *names)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
g_free (priv->names.keycodes);
|
||||
priv->names.keycodes = g_strdup (names->keycodes);
|
||||
g_free (priv->names.geometry);
|
||||
priv->names.geometry = g_strdup (names->geometry);
|
||||
g_free (priv->names.symbols);
|
||||
priv->names.symbols = g_strdup (names->symbols);
|
||||
get_keyboard (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -318,6 +331,7 @@ 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);
|
||||
@ -397,6 +411,7 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
|
||||
|
||||
klass->set_names = eek_xkb_layout_real_set_names;
|
||||
gobject_class->finalize = eek_xkb_layout_finalize;
|
||||
gobject_class->set_property = eek_xkb_layout_set_property;
|
||||
gobject_class->get_property = eek_xkb_layout_get_property;
|
||||
@ -426,7 +441,9 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
|
||||
static void
|
||||
outline_free (gpointer data)
|
||||
{
|
||||
g_slice_free (EekOutline, data);
|
||||
EekOutline *outline = data;
|
||||
g_slice_free1 (sizeof (EekPoint) * outline->num_points, outline->points);
|
||||
g_boxed_free (EEK_TYPE_OUTLINE, outline);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -435,9 +452,10 @@ eek_xkb_layout_init (EekXkbLayout *self)
|
||||
EekXkbLayoutPrivate *priv;
|
||||
|
||||
priv = self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
|
||||
|
||||
memset (&priv->names, 0, sizeof priv->names);
|
||||
|
||||
priv->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
g_return_if_fail (priv->display);
|
||||
|
||||
/* XXX: XkbClientMapMask | XkbIndicatorMapMask | XkbNamesMask |
|
||||
XkbGeometryMask */
|
||||
@ -555,8 +573,9 @@ eek_xkb_layout_new (const gchar *keycodes,
|
||||
void
|
||||
eek_xkb_layout_set_keycodes (EekXkbLayout *layout, const gchar *keycodes)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
g_free (priv->names.keycodes);
|
||||
priv->names.keycodes = g_strdup (keycodes);
|
||||
get_keyboard (layout);
|
||||
@ -572,8 +591,9 @@ eek_xkb_layout_set_keycodes (EekXkbLayout *layout, const gchar *keycodes)
|
||||
void
|
||||
eek_xkb_layout_set_geometry (EekXkbLayout *layout, const gchar *geometry)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
g_free (priv->names.geometry);
|
||||
priv->names.geometry = g_strdup (geometry);
|
||||
get_keyboard (layout);
|
||||
@ -589,8 +609,9 @@ eek_xkb_layout_set_geometry (EekXkbLayout *layout, const gchar *geometry)
|
||||
void
|
||||
eek_xkb_layout_set_symbols (EekXkbLayout *layout, const gchar *symbols)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
g_free (priv->names.symbols);
|
||||
priv->names.symbols = g_strdup (symbols);
|
||||
get_keyboard (layout);
|
||||
@ -605,8 +626,9 @@ eek_xkb_layout_set_symbols (EekXkbLayout *layout, const gchar *symbols)
|
||||
G_CONST_RETURN gchar *
|
||||
eek_xkb_layout_get_keycodes (EekXkbLayout *layout)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return priv->names.keycodes;
|
||||
}
|
||||
|
||||
@ -619,7 +641,9 @@ eek_xkb_layout_get_keycodes (EekXkbLayout *layout)
|
||||
G_CONST_RETURN gchar *
|
||||
eek_xkb_layout_get_geometry (EekXkbLayout *layout)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return priv->names.geometry;
|
||||
}
|
||||
|
||||
@ -632,8 +656,9 @@ eek_xkb_layout_get_geometry (EekXkbLayout *layout)
|
||||
G_CONST_RETURN gchar *
|
||||
eek_xkb_layout_get_symbols (EekXkbLayout *layout)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return priv->names.symbols;
|
||||
}
|
||||
|
||||
|
||||
@ -50,16 +50,8 @@ struct _EekXkbLayoutClass
|
||||
/*< private >*/
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
void (* set_keycodes) (EekXkbLayout *self,
|
||||
const gchar *keycodes);
|
||||
void (* set_geometry) (EekXkbLayout *self,
|
||||
const gchar *geometry);
|
||||
void (* set_symbols) (EekXkbLayout *self,
|
||||
const gchar *symbols);
|
||||
|
||||
G_CONST_RETURN gchar *(* get_keycodes) (EekXkbLayout *self);
|
||||
G_CONST_RETURN gchar *(* get_geometry) (EekXkbLayout *self);
|
||||
G_CONST_RETURN gchar *(* get_symbols) (EekXkbLayout *self);
|
||||
void (* set_names) (EekXkbLayout *self,
|
||||
XkbComponentNamesRec *names);
|
||||
};
|
||||
|
||||
GType eek_xkb_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
272
eek/eek-xkl-layout.c
Normal file
272
eek/eek-xkl-layout.c
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-xkl-layout
|
||||
* @short_description: Layout engine using Libxklavier configuration
|
||||
*
|
||||
* The #EekXklLayout is a simple wrapper around #EekXkbLayout class
|
||||
* to use Libxklavier configuration.
|
||||
*/
|
||||
|
||||
#include <libxklavier/xklavier.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-xkl-layout.h"
|
||||
|
||||
#define noKBDRAW_DEBUG
|
||||
|
||||
G_DEFINE_TYPE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT);
|
||||
|
||||
#define EEK_XKL_LAYOUT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_LAYOUTS,
|
||||
PROP_VARIANTS,
|
||||
PROP_OPTIONS,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
struct _EekXklLayoutPrivate
|
||||
{
|
||||
XklEngine *engine;
|
||||
XklConfigRec config;
|
||||
};
|
||||
|
||||
/* from gnome-keyboard-properties-xkbpv.c:
|
||||
* BAD STYLE: Taken from xklavier_private_xkb.h
|
||||
* Any ideas on architectural improvements are WELCOME
|
||||
*/
|
||||
extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine,
|
||||
const XklConfigRec * data,
|
||||
XkbComponentNamesPtr
|
||||
component_names);
|
||||
|
||||
extern void xkl_xkb_config_native_cleanup (XklEngine * engine,
|
||||
XkbComponentNamesPtr
|
||||
component_names);
|
||||
|
||||
static void update_xkb_layout (EekXklLayout *layout);
|
||||
|
||||
static void
|
||||
eek_xkl_layout_finalize (GObject *object)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (object);
|
||||
|
||||
g_free (priv->config.layouts);
|
||||
g_free (priv->config.variants);
|
||||
g_free (priv->config.options);
|
||||
G_OBJECT_CLASS (eek_xkl_layout_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LAYOUTS:
|
||||
eek_xkl_layout_set_layouts (EEK_XKL_LAYOUT(object),
|
||||
g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_VARIANTS:
|
||||
eek_xkl_layout_set_variants (EEK_XKL_LAYOUT(object),
|
||||
g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_OPTIONS:
|
||||
eek_xkl_layout_set_options (EEK_XKL_LAYOUT(object),
|
||||
g_value_get_boxed (value));
|
||||
break;
|
||||
default:
|
||||
g_object_set_property (object,
|
||||
g_param_spec_get_name (pspec),
|
||||
value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LAYOUTS:
|
||||
g_value_set_boxed (value,
|
||||
eek_xkl_layout_get_layouts (EEK_XKL_LAYOUT(object)));
|
||||
break;
|
||||
case PROP_VARIANTS:
|
||||
g_value_set_boxed (value,
|
||||
eek_xkl_layout_get_variants (EEK_XKL_LAYOUT(object)));
|
||||
break;
|
||||
case PROP_OPTIONS:
|
||||
g_value_set_boxed (value,
|
||||
eek_xkl_layout_get_options (EEK_XKL_LAYOUT(object)));
|
||||
break;
|
||||
default:
|
||||
g_object_get_property (object,
|
||||
g_param_spec_get_name (pspec),
|
||||
value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_class_init (EekXklLayoutClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekXklLayoutPrivate));
|
||||
|
||||
gobject_class->finalize = eek_xkl_layout_finalize;
|
||||
gobject_class->set_property = eek_xkl_layout_set_property;
|
||||
gobject_class->get_property = eek_xkl_layout_get_property;
|
||||
|
||||
pspec = g_param_spec_boxed ("layouts",
|
||||
"Layouts",
|
||||
"Libxklavier layouts",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_LAYOUTS, pspec);
|
||||
|
||||
pspec = g_param_spec_boxed ("variants",
|
||||
"Variants",
|
||||
"Libxklavier variants",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_VARIANTS, pspec);
|
||||
|
||||
pspec = g_param_spec_boxed ("options",
|
||||
"Options",
|
||||
"Libxklavier options",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_init (EekXklLayout *self)
|
||||
{
|
||||
EekXklLayoutPrivate *priv;
|
||||
Display *display;
|
||||
|
||||
priv = self->priv = EEK_XKL_LAYOUT_GET_PRIVATE (self);
|
||||
memset (&priv->config, 0, sizeof priv->config);
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
g_return_if_fail (display);
|
||||
|
||||
priv->engine = xkl_engine_get_instance (display);
|
||||
xkl_config_rec_get_from_server (&priv->config, priv->engine);
|
||||
update_xkb_layout (self);
|
||||
}
|
||||
|
||||
EekLayout *
|
||||
eek_xkl_layout_new (gchar **layouts,
|
||||
gchar **variants,
|
||||
gchar **options)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_XKL_LAYOUT, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
eek_xkl_layout_set_layouts (EekXklLayout *layout, gchar **layouts)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
g_strfreev (priv->config.layouts);
|
||||
priv->config.layouts = g_strdupv (layouts);
|
||||
update_xkb_layout (layout);
|
||||
}
|
||||
|
||||
void
|
||||
eek_xkl_layout_set_variants (EekXklLayout *layout, gchar **variants)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
g_strfreev (priv->config.variants);
|
||||
priv->config.variants = g_strdupv (variants);
|
||||
update_xkb_layout (layout);
|
||||
}
|
||||
|
||||
void
|
||||
eek_xkl_layout_set_options (EekXklLayout *layout, gchar **options)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_if_fail (priv);
|
||||
g_strfreev (priv->config.options);
|
||||
priv->config.options = g_strdupv (options);
|
||||
update_xkb_layout (layout);
|
||||
}
|
||||
|
||||
gchar **
|
||||
eek_xkl_layout_get_layouts (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return priv->config.layouts;
|
||||
}
|
||||
|
||||
gchar **
|
||||
eek_xkl_layout_get_variants (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return priv->config.variants;
|
||||
}
|
||||
|
||||
gchar **
|
||||
eek_xkl_layout_get_options (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return priv->config.options;
|
||||
}
|
||||
|
||||
static void
|
||||
update_xkb_layout (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = layout->priv;
|
||||
XkbComponentNamesRec names;
|
||||
|
||||
if (xkl_xkb_config_native_prepare (priv->engine, &priv->config, &names)) {
|
||||
EEK_XKB_LAYOUT_GET_CLASS (layout)->
|
||||
set_names (EEK_XKB_LAYOUT(layout), &names);
|
||||
xkl_xkb_config_native_cleanup (priv->engine, &names);
|
||||
}
|
||||
}
|
||||
70
eek/eek-xkl-layout.h
Normal file
70
eek/eek-xkl-layout.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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
|
||||
*/
|
||||
#ifndef EEK_XKL_LAYOUT_H
|
||||
#define EEK_XKL_LAYOUT_H 1
|
||||
|
||||
#include "eek-xkb-layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_XKL_LAYOUT (eek_xkl_layout_get_type())
|
||||
#define EEK_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayout))
|
||||
#define EEK_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
|
||||
#define EEK_IS_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKL_LAYOUT))
|
||||
#define EEK_IS_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKL_LAYOUT))
|
||||
#define EEK_XKL_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
|
||||
|
||||
typedef struct _EekXklLayout EekXklLayout;
|
||||
typedef struct _EekXklLayoutClass EekXklLayoutClass;
|
||||
typedef struct _EekXklLayoutPrivate EekXklLayoutPrivate;
|
||||
|
||||
struct _EekXklLayout
|
||||
{
|
||||
/*< private >*/
|
||||
EekXkbLayout parent;
|
||||
|
||||
EekXklLayoutPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekXklLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekXkbLayoutClass parent_class;
|
||||
};
|
||||
|
||||
GType eek_xkl_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
EekLayout *eek_xkl_layout_new (gchar **layouts,
|
||||
gchar **variants,
|
||||
gchar **options);
|
||||
|
||||
void eek_xkl_layout_set_layouts (EekXklLayout *layout,
|
||||
gchar **layouts);
|
||||
void eek_xkl_layout_set_variants (EekXklLayout *layout,
|
||||
gchar **variants);
|
||||
void eek_xkl_layout_set_options (EekXklLayout *layout,
|
||||
gchar **options);
|
||||
|
||||
gchar **eek_xkl_layout_get_layouts (EekXklLayout *layout);
|
||||
gchar **eek_xkl_layout_get_variants (EekXklLayout *layout);
|
||||
gchar **eek_xkl_layout_get_options (EekXklLayout *layout);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* #ifndef EEK_XKL_LAYOUT_H */
|
||||
26
eek/eek-xkl.h
Normal file
26
eek/eek-xkl.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
* 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
|
||||
*/
|
||||
#ifndef EEK_XKL_H
|
||||
#define EEK_XKL_H 1
|
||||
|
||||
#include "eek.h"
|
||||
#include "eek-xkl-layout.h"
|
||||
|
||||
#endif /* EEK_XKL_H */
|
||||
30
eek/eek-xkl.pc.in
Normal file
30
eek/eek-xkl.pc.in
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
|
||||
# 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
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: EEK-XKB
|
||||
Description: A Library to Create Keyboard-like UI (XKB Support)
|
||||
URL: http://github.com/ueno/eek
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -leek -leek-xkb
|
||||
Libs.private: @GTK2_LIBS@ @XKB_LIBS@
|
||||
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
|
||||
@ -17,5 +17,5 @@
|
||||
# 02110-1301 USA
|
||||
|
||||
noinst_PROGRAMS = eek-clutter-xkb-test
|
||||
eek_clutter_xkb_test_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(CLUTTER_CFLAGS) $(XKB_CFLAGS)
|
||||
eek_clutter_xkb_test_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la $(top_builddir)/eek/libeek-clutter.la $(GOBJECT2_LIBS) $(CLUTTER_LIBS) $(XKB_LIBS)
|
||||
eek_clutter_xkb_test_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(CLUTTER_CFLAGS) $(GTK2_CFLAGS) $(XKB_CFLAGS)
|
||||
eek_clutter_xkb_test_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la $(top_builddir)/eek/libeek-clutter.la $(GOBJECT2_LIBS) $(CLUTTER_LIBS) $(GTK2_CFLAGS) $(XKB_LIBS)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "eek/eek-clutter.h"
|
||||
#include "eek/eek-xkb.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -31,31 +32,6 @@ static const GOptionEntry options[] = {
|
||||
|
||||
gfloat stage_width, stage_height;
|
||||
|
||||
static gboolean
|
||||
on_event (ClutterStage *stage,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (event->type == CLUTTER_BUTTON_PRESS) {
|
||||
ClutterActor *actor = clutter_event_get_source (event);
|
||||
|
||||
if (EEK_IS_KEY(actor)) {
|
||||
guint keysym;
|
||||
const gchar *label = NULL;
|
||||
|
||||
keysym = eek_key_get_keysym (EEK_KEY(actor));
|
||||
if (keysym != EEK_INVALID_KEYSYM)
|
||||
label = eek_keysym_to_string (keysym);
|
||||
if (label) {
|
||||
printf ("%s", label);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_resize (GObject *object,
|
||||
GParamSpec *param_spec,
|
||||
@ -107,7 +83,6 @@ main (int argc, char *argv[])
|
||||
g_option_context_free (context);
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
layout = eek_xkb_layout_new (keycodes, geometry, symbols);
|
||||
@ -115,7 +90,6 @@ main (int argc, char *argv[])
|
||||
fprintf (stderr, "Failed to create layout\n");
|
||||
exit(1);
|
||||
}
|
||||
g_object_ref_sink (layout);
|
||||
|
||||
keyboard = eek_clutter_keyboard_new (CSW, CSH);
|
||||
if (keyboard == NULL) {
|
||||
@ -123,11 +97,13 @@ main (int argc, char *argv[])
|
||||
fprintf (stderr, "Failed to create keyboard\n");
|
||||
exit(1);
|
||||
}
|
||||
g_object_ref_sink (keyboard);
|
||||
|
||||
g_signal_connect (keyboard, "key-pressed", G_CALLBACK(key_pressed_event), NULL);
|
||||
g_signal_connect (keyboard, "key-pressed",
|
||||
G_CALLBACK(key_pressed_event), NULL);
|
||||
|
||||
eek_keyboard_set_layout (keyboard, layout);
|
||||
actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard));
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
#include "eek/eek-gtk.h"
|
||||
#include "eek/eek-xkb.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static gchar *symbols = NULL;
|
||||
static gchar *keycodes = NULL;
|
||||
static gchar *geometry = NULL;
|
||||
|
||||
static const GOptionEntry options[] = {
|
||||
{"symbols", '\0', 0, G_OPTION_ARG_STRING, &symbols,
|
||||
"Symbols component of the keyboard. If you omit this option, it is "
|
||||
"obtained from the X server; that is, the keyboard that is currently "
|
||||
"configured is drawn. Examples: --symbols=us or "
|
||||
"--symbols=us(pc104)+iso9995-3+group(switch)+ctrl(nocaps)", NULL},
|
||||
{"keycodes", '\0', 0, G_OPTION_ARG_STRING, &keycodes,
|
||||
"Keycodes component of the keyboard. If you omit this option, it is "
|
||||
"obtained from the X server; that is, the keyboard that is currently"
|
||||
" configured is drawn. Examples: --keycodes=xfree86+aliases(qwerty)",
|
||||
NULL},
|
||||
{"geometry", '\0', 0, G_OPTION_ARG_STRING, &geometry,
|
||||
"Geometry xkb component. If you omit this option, it is obtained from the"
|
||||
" X server; that is, the keyboard that is currently configured is drawn. "
|
||||
"Example: --geometry=kinesis", NULL},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
gfloat window_width, window_height;
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
EekLayout *layout;
|
||||
GtkWidget *window;
|
||||
GOptionContext *context;
|
||||
|
||||
context = g_option_context_new ("test-xkb-gtk");
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
g_option_context_parse (context, &argc, &argv, NULL);
|
||||
g_option_context_free (context);
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
layout = eek_xkb_layout_new (keycodes, geometry, symbols);
|
||||
if (layout == NULL) {
|
||||
fprintf (stderr, "Failed to create layout\n");
|
||||
exit(1);
|
||||
}
|
||||
g_object_ref_sink (layout);
|
||||
|
||||
keyboard = eek_gtk_keyboard_new ();
|
||||
if (keyboard == NULL) {
|
||||
g_object_unref (layout);
|
||||
fprintf (stderr, "Failed to create keyboard\n");
|
||||
exit(1);
|
||||
}
|
||||
g_object_ref_sink (keyboard);
|
||||
|
||||
eek_keyboard_set_layout (keyboard, layout);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(keyboard));
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -37,6 +37,7 @@ test_create (void)
|
||||
g_assert (EEK_IS_KEY(key1));
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
test_create_clutter (void)
|
||||
{
|
||||
@ -57,6 +58,7 @@ test_create_clutter (void)
|
||||
g_assert (CLUTTER_IS_ACTOR(actor));
|
||||
g_object_unref (keyboard);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
@ -64,7 +66,9 @@ main (int argc, char **argv)
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_test_add_func ("/eek-simple-test/create", test_create);
|
||||
#if 0
|
||||
clutter_init (&argc, &argv);
|
||||
g_test_add_func ("/eek-simple-test/create-clutter", test_create_clutter);
|
||||
#endif
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user