Fix object finalization.
Add XKL wrapper (not ready).
This commit is contained in:
		@ -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,
 | 
			
		||||
                                                               g_direct_equal,
 | 
			
		||||
                                                               NULL,
 | 
			
		||||
                                                               g_free);
 | 
			
		||||
    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
 | 
			
		||||
{
 | 
			
		||||
@ -51,29 +52,35 @@ struct _EekContainerClass
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekElementClass parent_class;
 | 
			
		||||
 | 
			
		||||
    void (* add_child)     (EekContainer *self,
 | 
			
		||||
                            EekElement   *element);
 | 
			
		||||
    void        (* add_child)     (EekContainer  *self,
 | 
			
		||||
                                   EekElement    *element);
 | 
			
		||||
 | 
			
		||||
    void (* remove_child)  (EekContainer *self,
 | 
			
		||||
                            EekElement   *element);
 | 
			
		||||
    void        (* remove_child)  (EekContainer  *self,
 | 
			
		||||
                                   EekElement    *element);
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    void (* foreach_child) (EekContainer *self,
 | 
			
		||||
                            EekCallback   callback,
 | 
			
		||||
                            gpointer      user_data);
 | 
			
		||||
    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,
 | 
			
		||||
                            EekElement   *element);
 | 
			
		||||
    void (* child_removed) (EekContainer *self,
 | 
			
		||||
                            EekElement   *element);
 | 
			
		||||
    void        (* child_added)   (EekContainer  *self,
 | 
			
		||||
                                   EekElement    *element);
 | 
			
		||||
    void        (* child_removed) (EekContainer  *self,
 | 
			
		||||
                                   EekElement    *element);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType eek_container_get_type      (void) G_GNUC_CONST;
 | 
			
		||||
GType       eek_container_get_type      (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void  eek_container_foreach_child (EekContainer *self,
 | 
			
		||||
                                   EekCallback   callback,
 | 
			
		||||
                                   gpointer      user_data);
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -51,32 +51,38 @@ struct _EekKeyboardClass
 | 
			
		||||
    EekContainerClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    void        (* set_keysym_index) (EekKeyboard *self,
 | 
			
		||||
                                      gint         group,
 | 
			
		||||
                                      gint         level);
 | 
			
		||||
    void        (* get_keysym_index) (EekKeyboard *self,
 | 
			
		||||
                                      gint        *group,
 | 
			
		||||
                                      gint        *level);
 | 
			
		||||
    void        (* set_keysym_index)    (EekKeyboard *self,
 | 
			
		||||
                                         gint         group,
 | 
			
		||||
                                         gint         level);
 | 
			
		||||
    void        (* get_keysym_index)    (EekKeyboard *self,
 | 
			
		||||
                                         gint        *group,
 | 
			
		||||
                                         gint        *level);
 | 
			
		||||
 | 
			
		||||
    EekSection *(* create_section)   (EekKeyboard *self);
 | 
			
		||||
    EekSection *(* create_section)      (EekKeyboard *self);
 | 
			
		||||
 | 
			
		||||
    void        (* set_layout)       (EekKeyboard *self,
 | 
			
		||||
                                      EekLayout   *layout);
 | 
			
		||||
    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;
 | 
			
		||||
GType       eek_keyboard_get_type            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void        eek_keyboard_set_keysym_index (EekKeyboard *self,
 | 
			
		||||
                                           gint         group,
 | 
			
		||||
                                           gint         level);
 | 
			
		||||
void        eek_keyboard_get_keysym_index (EekKeyboard *self,
 | 
			
		||||
                                           gint        *group,
 | 
			
		||||
                                           gint        *level);
 | 
			
		||||
void        eek_keyboard_set_keysym_index    (EekKeyboard *self,
 | 
			
		||||
                                              gint         group,
 | 
			
		||||
                                              gint         level);
 | 
			
		||||
void        eek_keyboard_get_keysym_index    (EekKeyboard *self,
 | 
			
		||||
                                              gint        *group,
 | 
			
		||||
                                              gint        *level);
 | 
			
		||||
 | 
			
		||||
EekSection *eek_keyboard_create_section   (EekKeyboard *keyboard);
 | 
			
		||||
EekSection *eek_keyboard_create_section      (EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
void        eek_keyboard_set_layout       (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekLayout   *layout);
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -50,42 +50,48 @@ struct _EekSectionClass
 | 
			
		||||
    EekContainerClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    void    (* set_angle)    (EekSection     *self,
 | 
			
		||||
                              gint            angle);
 | 
			
		||||
    gint    (* get_angle)    (EekSection     *self);
 | 
			
		||||
    void    (* set_angle)           (EekSection     *self,
 | 
			
		||||
                                     gint            angle);
 | 
			
		||||
    gint    (* get_angle)           (EekSection     *self);
 | 
			
		||||
 | 
			
		||||
    gint    (* get_n_rows)   (EekSection     *self);
 | 
			
		||||
    void    (* add_row)      (EekSection     *self,
 | 
			
		||||
                              gint            num_columns,
 | 
			
		||||
                              EekOrientation  orientation);
 | 
			
		||||
    void    (* get_row)      (EekSection     *self,
 | 
			
		||||
                              gint            index,
 | 
			
		||||
                              gint           *num_columns,
 | 
			
		||||
                              EekOrientation *orientation);
 | 
			
		||||
    gint    (* get_n_rows)          (EekSection     *self);
 | 
			
		||||
    void    (* add_row)             (EekSection     *self,
 | 
			
		||||
                                     gint            num_columns,
 | 
			
		||||
                                     EekOrientation  orientation);
 | 
			
		||||
    void    (* get_row)             (EekSection     *self,
 | 
			
		||||
                                     gint            index,
 | 
			
		||||
                                     gint           *num_columns,
 | 
			
		||||
                                     EekOrientation *orientation);
 | 
			
		||||
 | 
			
		||||
    EekKey *(* create_key)   (EekSection     *self,
 | 
			
		||||
                              gint            row,
 | 
			
		||||
                              gint            column);
 | 
			
		||||
    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;
 | 
			
		||||
GType   eek_section_get_type            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void    eek_section_set_angle  (EekSection     *section,
 | 
			
		||||
                                gint            angle);
 | 
			
		||||
gint    eek_section_get_angle  (EekSection     *section);
 | 
			
		||||
void    eek_section_set_angle           (EekSection     *section,
 | 
			
		||||
                                         gint            angle);
 | 
			
		||||
gint    eek_section_get_angle           (EekSection     *section);
 | 
			
		||||
 | 
			
		||||
gint    eek_section_get_n_rows (EekSection     *section);
 | 
			
		||||
void    eek_section_add_row    (EekSection     *section,
 | 
			
		||||
                                gint            num_columns,
 | 
			
		||||
                                EekOrientation  orientation);
 | 
			
		||||
void    eek_section_get_row    (EekSection     *section,
 | 
			
		||||
                                gint            index,
 | 
			
		||||
                                gint           *num_columns,
 | 
			
		||||
                                EekOrientation *orientation);
 | 
			
		||||
gint    eek_section_get_n_rows          (EekSection     *section);
 | 
			
		||||
void    eek_section_add_row             (EekSection     *section,
 | 
			
		||||
                                         gint            num_columns,
 | 
			
		||||
                                         EekOrientation  orientation);
 | 
			
		||||
void    eek_section_get_row             (EekSection     *section,
 | 
			
		||||
                                         gint            index,
 | 
			
		||||
                                         gint           *num_columns,
 | 
			
		||||
                                         EekOrientation *orientation);
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_create_key (EekSection     *section,
 | 
			
		||||
                                gint            column,
 | 
			
		||||
                                gint            row);
 | 
			
		||||
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,7 +331,8 @@ eek_xkb_layout_finalize (GObject *object)
 | 
			
		||||
    g_free (priv->names.keycodes);
 | 
			
		||||
    g_free (priv->names.geometry);
 | 
			
		||||
    g_free (priv->names.symbols);
 | 
			
		||||
    g_hash_table_unref (priv->outline_hash);
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
@ -392,12 +406,13 @@ eek_layout_iface_init (EekLayoutIface *iface)
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
 | 
			
		||||
 | 
			
		||||
    gobject_class->finalize     = eek_xkb_layout_finalize;
 | 
			
		||||
    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,34 +50,26 @@ 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;
 | 
			
		||||
 | 
			
		||||
EekLayout            *eek_xkb_layout_new          (const gchar   *keycodes,
 | 
			
		||||
                                                   const gchar   *geometry,
 | 
			
		||||
                                                   const gchar   *symbols);
 | 
			
		||||
EekLayout            *eek_xkb_layout_new          (const gchar  *keycodes,
 | 
			
		||||
                                                   const gchar  *geometry,
 | 
			
		||||
                                                   const gchar  *symbols);
 | 
			
		||||
 | 
			
		||||
void                  eek_xkb_layout_set_keycodes (EekXkbLayout  *layout,
 | 
			
		||||
                                                   const gchar   *keycodes);
 | 
			
		||||
void                  eek_xkb_layout_set_geometry (EekXkbLayout  *layout,
 | 
			
		||||
                                                   const gchar   *geometry);
 | 
			
		||||
void                  eek_xkb_layout_set_symbols  (EekXkbLayout  *layout,
 | 
			
		||||
                                                   const gchar   *symbols);
 | 
			
		||||
void                  eek_xkb_layout_set_keycodes (EekXkbLayout *layout,
 | 
			
		||||
                                                   const gchar  *keycodes);
 | 
			
		||||
void                  eek_xkb_layout_set_geometry (EekXkbLayout *layout,
 | 
			
		||||
                                                   const gchar  *geometry);
 | 
			
		||||
void                  eek_xkb_layout_set_symbols  (EekXkbLayout *layout,
 | 
			
		||||
                                                   const gchar  *symbols);
 | 
			
		||||
 | 
			
		||||
G_CONST_RETURN gchar *eek_xkb_layout_get_keycodes (EekXkbLayout * layout);
 | 
			
		||||
G_CONST_RETURN gchar *eek_xkb_layout_get_geometry (EekXkbLayout * layout);
 | 
			
		||||
G_CONST_RETURN gchar *eek_xkb_layout_get_symbols  (EekXkbLayout * layout);
 | 
			
		||||
G_CONST_RETURN gchar *eek_xkb_layout_get_keycodes (EekXkbLayout *layout);
 | 
			
		||||
G_CONST_RETURN gchar *eek_xkb_layout_get_geometry (EekXkbLayout *layout);
 | 
			
		||||
G_CONST_RETURN gchar *eek_xkb_layout_get_symbols  (EekXkbLayout *layout);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif				/* #ifndef EEK_XKB_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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@
 | 
			
		||||
		Reference in New Issue
	
	Block a user