Add experimental GTK support.

This commit is contained in:
Daiki Ueno
2010-06-07 06:42:23 +09:00
parent eb3e482e40
commit 54fb99688e
15 changed files with 1160 additions and 21 deletions

1
TODO
View File

@ -1,6 +1,5 @@
- modifier handling
- step-by-step scaling of key labels
- GTK+ keyboard elements
- matchbox-keyboard layout engine
- emit key events using libfakekey or xtest
- .spec

View File

@ -34,7 +34,9 @@ PKG_CHECK_MODULES([PANGO], [pango], ,
[AC_MSG_ERROR([Pango not found])])
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], ,
[AC_MSG_ERROR([Clutter not found])])
PKG_CHECK_MODULES([XKB], [gtk+-2.0 gdk-2.0 x11], ,
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 gdk-2.0], ,
[AC_MSG_ERROR([GTK2 support not found])])
PKG_CHECK_MODULES([XKB], [x11], ,
[AC_MSG_ERROR([XKB support not found])])
GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
@ -54,5 +56,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-gtk.pc])
AC_OUTPUT

View File

@ -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-gtk.la
libeek_la_SOURCES = \
eek-layout.c \
@ -67,8 +67,23 @@ libeek_xkb_la_SOURCES = \
eek-xkb-layout.c \
$(NULL)
libeek_xkb_la_CFLAGS = $(XKB_CFLAGS)
libeek_xkb_la_LIBADD = libeek.la $(XKB_LIBS)
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS)
libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS)
libeek_gtk_la_SOURCES = \
eek-gtk-keyboard.c \
eek-gtk-keyboard.h \
eek-gtk-section.c \
eek-gtk-section.h \
eek-gtk-key.c \
eek-gtk-key.h \
eek-gtk-private.c \
eek-gtk-private.h \
eek-gtk.h \
$(NULL)
libeek_gtk_la_CFLAGS = $(GTK2_CFLAGS)
libeek_gtk_la_LIBADD = libeek.la $(GTK2_LIBS)
eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
eek_HEADERS = \
@ -96,7 +111,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-gtk.pc
DISTCLEANFILES = \
eek-special-keysym-labels.h \

View File

@ -193,6 +193,12 @@ eek_key_iface_init (EekKeyIface *iface)
static void
eek_clutter_key_dispose (GObject *object)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
if (priv->simple) {
g_object_unref (priv->simple);
priv->simple = NULL;
}
clutter_group_remove_all (CLUTTER_GROUP(object));
G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object);
}
@ -200,9 +206,6 @@ eek_clutter_key_dispose (GObject *object)
static void
eek_clutter_key_finalize (GObject *object)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
g_object_unref (priv->simple);
G_OBJECT_CLASS (eek_clutter_key_parent_class)->finalize (object);
}

View File

@ -185,6 +185,12 @@ eek_keyboard_iface_init (EekKeyboardIface *iface)
static void
eek_clutter_keyboard_dispose (GObject *object)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object);
if (priv->simple) {
g_object_unref (priv->simple);
priv->simple = NULL;
}
clutter_group_remove_all (CLUTTER_GROUP(object));
G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->dispose (object);
}
@ -192,9 +198,6 @@ eek_clutter_keyboard_dispose (GObject *object)
static void
eek_clutter_keyboard_finalize (GObject *object)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object);
g_object_unref (priv->simple);
G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->finalize (object);
}

View File

@ -253,16 +253,19 @@ eek_section_iface_init (EekSectionIface *iface)
static void
eek_clutter_section_dispose (GObject *object)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object);
clutter_group_remove_all (CLUTTER_GROUP(object));
if (priv->simple) {
g_object_unref (priv->simple);
priv->simple = NULL;
}
G_OBJECT_CLASS (eek_clutter_section_parent_class)->dispose (object);
}
static void
eek_clutter_section_finalize (GObject *object)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object);
g_object_unref (priv->simple);
G_OBJECT_CLASS (eek_clutter_section_parent_class)->finalize (object);
}

323
eek/eek-gtk-key.c Normal file
View File

@ -0,0 +1,323 @@
/*
* 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-gtk-key
* @short_description: #EekKey implemented as a #GtkWidget
*
* The #EekClutterKey class implements the #EekKeyIface interface as a
* #GtkWidget.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-gtk-key.h"
#include "eek-simple-key.h"
#include "eek-keysym.h"
enum {
PROP_0,
PROP_KEYSYMS,
PROP_COLUMN,
PROP_ROW,
PROP_OUTLINE,
PROP_BOUNDS,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST
};
static void eek_key_iface_init (EekKeyIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekGtkKey, eek_gtk_key,
GTK_TYPE_BUTTON,
G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY,
eek_key_iface_init));
#define EEK_GTK_KEY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEY, EekGtkKeyPrivate))
struct _EekGtkKeyPrivate
{
EekSimpleKey *simple;
};
static void
eek_gtk_key_real_set_keysyms (EekKey *self,
guint *keysyms,
gint groups,
gint levels)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels);
eek_key_set_keysym_index (EEK_KEY(self), 0, 0);
}
static gint
eek_gtk_key_real_get_groups (EekKey *self)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1);
return eek_key_get_groups (EEK_KEY(priv->simple));
}
static guint
eek_gtk_key_real_get_keysym (EekKey *self)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, EEK_INVALID_KEYSYM);
return eek_key_get_keysym (EEK_KEY(priv->simple));
}
static void
eek_gtk_key_real_set_index (EekKey *self,
gint column,
gint row)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_index (EEK_KEY(priv->simple), column, row);
}
static void
eek_gtk_key_real_get_index (EekKey *self,
gint *column,
gint *row)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_get_index (EEK_KEY(priv->simple), column, row);
}
static void
eek_gtk_key_real_set_outline (EekKey *self, EekOutline *outline)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_outline (EEK_KEY(priv->simple), outline);
}
static EekOutline *
eek_gtk_key_real_get_outline (EekKey *self)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, NULL);
return eek_key_get_outline (EEK_KEY(priv->simple));
}
static void
eek_gtk_key_real_set_bounds (EekKey *self, EekBounds *bounds)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_bounds (EEK_KEY(priv->simple), bounds);
}
static void
eek_gtk_key_real_get_bounds (EekKey *self,
EekBounds *bounds)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
return eek_key_get_bounds (EEK_KEY(priv->simple), bounds);
}
static void
eek_gtk_key_real_set_keysym_index (EekKey *self,
gint group,
gint level)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
guint keysym;
g_return_if_fail (priv);
eek_key_set_keysym_index (EEK_KEY(priv->simple), group, level);
keysym = eek_key_get_keysym (self);
if (keysym != EEK_INVALID_KEYSYM) {
const gchar *label;
label = eek_keysym_to_string (keysym);
gtk_button_set_label (GTK_BUTTON(self), label ? label : "");
}
}
static void
eek_gtk_key_real_get_keysym_index (EekKey *self, gint *group, gint *level)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
return eek_key_get_keysym_index (EEK_KEY(priv->simple), group, level);
}
static void
eek_key_iface_init (EekKeyIface *iface)
{
iface->set_keysyms = eek_gtk_key_real_set_keysyms;
iface->get_groups = eek_gtk_key_real_get_groups;
iface->get_keysym = eek_gtk_key_real_get_keysym;
iface->set_index = eek_gtk_key_real_set_index;
iface->get_index = eek_gtk_key_real_get_index;
iface->set_outline = eek_gtk_key_real_set_outline;
iface->get_outline = eek_gtk_key_real_get_outline;
iface->set_bounds = eek_gtk_key_real_set_bounds;
iface->get_bounds = eek_gtk_key_real_get_bounds;
iface->set_keysym_index = eek_gtk_key_real_set_keysym_index;
iface->get_keysym_index = eek_gtk_key_real_get_keysym_index;
}
static void
eek_gtk_key_dispose (GObject *object)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(object);
if (priv->simple) {
g_object_unref (priv->simple);
priv->simple = NULL;
}
G_OBJECT_CLASS (eek_gtk_key_parent_class)->dispose (object);
}
static void
eek_gtk_key_finalize (GObject *object)
{
G_OBJECT_CLASS (eek_gtk_key_parent_class)->finalize (object);
}
static void
eek_gtk_key_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(object);
EekKeysymMatrix *matrix;
g_return_if_fail (priv);
switch (prop_id) {
case PROP_KEYSYMS:
matrix = g_value_get_boxed (value);
eek_key_set_keysyms (EEK_KEY(object),
matrix->data,
matrix->num_groups,
matrix->num_levels);
break;
case PROP_BOUNDS:
case PROP_OUTLINE:
case PROP_COLUMN:
case PROP_GROUP:
case PROP_ROW:
case PROP_LEVEL:
g_object_set_property (G_OBJECT(priv->simple),
g_param_spec_get_name (pspec),
value);
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_gtk_key_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(object);
g_return_if_fail (priv);
switch (prop_id) {
case PROP_BOUNDS:
case PROP_KEYSYMS:
case PROP_COLUMN:
case PROP_ROW:
case PROP_OUTLINE:
case PROP_GROUP:
case PROP_LEVEL:
g_object_get_property (G_OBJECT(priv->simple),
g_param_spec_get_name (pspec),
value);
break;
default:
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_gtk_key_class_init (EekGtkKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class,
sizeof (EekGtkKeyPrivate));
gobject_class->set_property = eek_gtk_key_set_property;
gobject_class->get_property = eek_gtk_key_get_property;
gobject_class->finalize = eek_gtk_key_finalize;
gobject_class->dispose = eek_gtk_key_dispose;
g_object_class_override_property (gobject_class,
PROP_KEYSYMS,
"keysyms");
g_object_class_override_property (gobject_class,
PROP_COLUMN,
"column");
g_object_class_override_property (gobject_class,
PROP_ROW,
"row");
g_object_class_override_property (gobject_class,
PROP_OUTLINE,
"outline");
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
g_object_class_override_property (gobject_class,
PROP_GROUP,
"group");
g_object_class_override_property (gobject_class,
PROP_LEVEL,
"level");
}
static void
eek_gtk_key_init (EekGtkKey *self)
{
EekGtkKeyPrivate *priv;
priv = self->priv = EEK_GTK_KEY_GET_PRIVATE(self);
priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEY, NULL);
}

301
eek/eek-gtk-keyboard.c Normal file
View File

@ -0,0 +1,301 @@
/*
* 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-gtk-keyboard
* @short_description: #EekKeyboard implemented as a #GtkWidget
*
* The #EekGtkKeyboard class implements the #EekKeyboardIface
* interface as a #GtkWidget.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-gtk-keyboard.h"
#include "eek-gtk-private.h"
#include "eek-simple-keyboard.h"
enum {
PROP_0,
PROP_BOUNDS,
PROP_LAST
};
static void eek_keyboard_iface_init (EekKeyboardIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekGtkKeyboard, eek_gtk_keyboard,
GTK_TYPE_VBOX,
G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD,
eek_keyboard_iface_init));
#define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate))
struct _EekGtkKeyboardPrivate
{
EekSimpleKeyboard *simple;
gint group;
gint level;
};
static void
eek_gtk_keyboard_real_set_bounds (EekKeyboard *self,
EekBounds *bounds)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_keyboard_set_bounds (EEK_KEYBOARD(priv->simple), bounds);
}
static void
eek_gtk_keyboard_real_get_bounds (EekKeyboard *self,
EekBounds *bounds)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv);
return eek_keyboard_get_bounds (EEK_KEYBOARD(priv->simple), bounds);
}
struct keysym_index {
gint group;
gint level;
};
static void
key_set_keysym_index (gpointer self, gpointer user_data)
{
struct keysym_index *ki;
g_return_if_fail (EEK_IS_KEY(self));
eek_key_set_keysym_index (self, ki->group, ki->level);
}
static void
section_set_keysym_index (gpointer self, gpointer user_data)
{
EekGtkCallbackData data;
data.func = key_set_keysym_index;
data.user_data = user_data;
g_return_if_fail (EEK_IS_GTK_SECTION(self));
gtk_container_foreach (GTK_CONTAINER(self), eek_gtk_callback, &data);
}
static void
eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self,
gint group,
gint level)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
EekGtkCallbackData data;
struct keysym_index ki;
g_return_if_fail (priv);
priv->group = group;
priv->level = level;
ki.group = group;
ki.level = level;
data.func = section_set_keysym_index;
data.user_data = &ki;
gtk_container_foreach (GTK_CONTAINER(self), eek_gtk_callback, &data);
}
static void
eek_gtk_keyboard_real_get_keysym_index (EekKeyboard *self,
gint *group,
gint *level)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv);
*group = priv->group;
*level = priv->level;
}
static EekSection *
eek_gtk_keyboard_real_create_section (EekKeyboard *self,
const gchar *name,
gint angle,
EekBounds *bounds)
{
EekSection *section;
g_return_if_fail (EEK_IS_GTK_KEYBOARD(self));
section = g_object_new (EEK_TYPE_GTK_SECTION,
"name", name,
"angle", angle,
"bounds", bounds,
NULL);
gtk_box_pack_start (GTK_BOX(self), GTK_WIDGET(section), FALSE, FALSE, 0);
return section;
}
static void
eek_gtk_keyboard_real_foreach_section (EekKeyboard *self,
GFunc func,
gpointer user_data)
{
EekGtkCallbackData data;
g_return_if_fail (EEK_IS_GTK_KEYBOARD(self));
data.func = func;
data.user_data = user_data;
gtk_container_foreach (GTK_CONTAINER(self),
eek_gtk_callback,
&data);
}
static void
eek_gtk_keyboard_real_set_layout (EekKeyboard *self,
EekLayout *layout)
{
g_return_if_fail (EEK_IS_KEYBOARD(self));
g_return_if_fail (EEK_IS_LAYOUT(layout));
EEK_LAYOUT_GET_CLASS(layout)->apply_to_keyboard (layout, self);
if (g_object_is_floating (layout))
g_object_unref (layout);
}
static void
eek_keyboard_iface_init (EekKeyboardIface *iface)
{
iface->set_bounds = eek_gtk_keyboard_real_set_bounds;
iface->get_bounds = eek_gtk_keyboard_real_get_bounds;
iface->set_keysym_index = eek_gtk_keyboard_real_set_keysym_index;
iface->get_keysym_index = eek_gtk_keyboard_real_get_keysym_index;
iface->create_section = eek_gtk_keyboard_real_create_section;
iface->foreach_section = eek_gtk_keyboard_real_foreach_section;
iface->set_layout = eek_gtk_keyboard_real_set_layout;
}
static void
eek_gtk_keyboard_dispose (GObject *object)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
if (priv->simple) {
g_object_unref (priv->simple);
priv->simple = NULL;
}
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
}
static void
eek_gtk_keyboard_finalize (GObject *object)
{
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->finalize (object);
}
static void
eek_gtk_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
g_return_if_fail (priv);
switch (prop_id) {
case PROP_BOUNDS:
eek_keyboard_set_bounds (EEK_KEYBOARD(object),
g_value_get_boxed (value));
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_gtk_keyboard_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
g_return_if_fail (priv);
switch (prop_id) {
case PROP_BOUNDS:
eek_keyboard_set_bounds (EEK_KEYBOARD(object),
g_value_get_boxed (value));
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class,
sizeof (EekGtkKeyboardPrivate));
gobject_class->set_property = eek_gtk_keyboard_set_property;
gobject_class->get_property = eek_gtk_keyboard_get_property;
gobject_class->finalize = eek_gtk_keyboard_finalize;
gobject_class->dispose = eek_gtk_keyboard_dispose;
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
}
static void
eek_gtk_keyboard_init (EekGtkKeyboard *self)
{
EekGtkKeyboardPrivate *priv;
priv = self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL);
priv->group = priv->level = 0;
}
/**
* eek_gtk_keyboard_new:
*
* Create a new #EekGtkKeyboard.
*/
EekKeyboard*
eek_gtk_keyboard_new (void)
{
return g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL);
}

31
eek/eek-gtk-private.c Normal file
View File

@ -0,0 +1,31 @@
/*
* 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
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-gtk-private.h"
void
eek_gtk_callback (GtkWidget *widget, gpointer user_data)
{
EekGtkCallbackData *data = user_data;
data->func (widget, data->user_data);
}

355
eek/eek-gtk-section.c Normal file
View File

@ -0,0 +1,355 @@
/*
* 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-gtk-section
* @short_description: #EekSection implemented as a #GtkWidget
*
* The #EekGtkSection class implements the #EekSectionIface
* interface as a #GtkWidget.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-gtk-section.h"
#include "eek-gtk-private.h"
#include "eek-simple-section.h"
#include <stdio.h>
enum {
PROP_0,
PROP_COLUMNS,
PROP_ROWS,
PROP_ANGLE,
PROP_BOUNDS,
PROP_LAST
};
static void eek_section_iface_init (EekSectionIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekGtkSection, eek_gtk_section,
GTK_TYPE_VBOX,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION,
eek_section_iface_init));
#define EEK_GTK_SECTION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_SECTION, EekGtkSectionPrivate))
struct _EekGtkSectionPrivate
{
EekSimpleSection *simple;
GtkWidget **rows; /* GtkHBox * */
};
static void
eek_gtk_section_real_set_rows (EekSection *self,
gint rows)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_section_set_rows (EEK_SECTION(priv->simple), rows);
priv->rows = g_slice_alloc0 (sizeof(GtkHBox *) * rows);
}
static gint
eek_gtk_section_real_get_rows (EekSection *self)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1);
return eek_section_get_rows (EEK_SECTION(priv->simple));
}
static void
eek_gtk_section_real_set_columns (EekSection *self,
gint row,
gint columns)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_section_set_columns (EEK_SECTION(priv->simple), row, columns);
}
static gint
eek_gtk_section_real_get_columns (EekSection *self,
gint row)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1);
return eek_section_get_columns (EEK_SECTION(priv->simple), row);
}
static void
eek_gtk_section_real_set_orientation (EekSection *self,
gint row,
EekOrientation orientation)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_section_set_orientation (EEK_SECTION(priv->simple), row, orientation);
}
static EekOrientation
eek_gtk_section_real_get_orientation (EekSection *self,
gint row)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, EEK_ORIENTATION_INVALID);
return eek_section_get_orientation (EEK_SECTION(priv->simple), row);
}
static void
eek_gtk_section_real_set_angle (EekSection *self,
gint angle)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_section_set_angle (EEK_SECTION(priv->simple), angle);
}
static gint
eek_gtk_section_real_get_angle (EekSection *self)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, 0);
eek_section_get_angle (EEK_SECTION(priv->simple));
}
static void
eek_gtk_section_real_set_bounds (EekSection *self,
EekBounds *bounds)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_section_set_bounds (EEK_SECTION(priv->simple), bounds);
}
static void
eek_gtk_section_real_get_bounds (EekSection *self,
EekBounds *bounds)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
return eek_section_get_bounds (EEK_SECTION(priv->simple), bounds);
}
static EekKey *
eek_gtk_section_real_create_key (EekSection *self,
const gchar *name,
guint *keysyms,
gint num_groups,
gint num_levels,
gint column,
gint row,
EekOutline *outline,
EekBounds *bounds)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
EekKey *key;
EekKeysymMatrix matrix;
gint columns, rows;
g_return_val_if_fail (priv, NULL);
rows = eek_section_get_rows (self);
g_return_val_if_fail (0 <= row && row < rows, NULL);
columns = eek_section_get_columns (self, row);
g_return_val_if_fail (column < columns, NULL);
matrix.data = keysyms;
matrix.num_groups = num_groups;
matrix.num_levels = num_levels;
key = g_object_new (EEK_TYPE_GTK_KEY,
"name", name,
"keysyms", &matrix,
"column", column,
"row", row,
"outline", outline,
"bounds", bounds,
NULL);
g_return_val_if_fail (key, NULL);
if (priv->rows[row] == NULL) {
priv->rows[row] = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX(self), priv->rows[row],
FALSE, FALSE, 0);
gtk_box_reorder_child (GTK_BOX(self), priv->rows[row], row);
}
gtk_box_pack_start (GTK_BOX(priv->rows[row]), GTK_WIDGET(key),
FALSE, FALSE, 0);
gtk_box_reorder_child (GTK_BOX(priv->rows[row]), GTK_WIDGET(key), column);
return key;
}
static void
eek_gtk_section_real_foreach_key (EekSection *self,
GFunc func,
gpointer user_data)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(self);
EekGtkCallbackData data;
gint i, num_rows;
g_return_if_fail (priv);
data.func = func;
data.user_data = user_data;
num_rows = eek_section_get_rows (self);
for (i = 0; i < num_rows; i++)
gtk_container_foreach (GTK_CONTAINER(priv->rows[i]),
eek_gtk_callback,
&data);
}
static void
eek_section_iface_init (EekSectionIface *iface)
{
iface->set_rows = eek_gtk_section_real_set_rows;
iface->get_rows = eek_gtk_section_real_get_rows;
iface->set_columns = eek_gtk_section_real_set_columns;
iface->get_columns = eek_gtk_section_real_get_columns;
iface->set_orientation = eek_gtk_section_real_set_orientation;
iface->get_orientation = eek_gtk_section_real_get_orientation;
iface->set_angle = eek_gtk_section_real_set_angle;
iface->get_angle = eek_gtk_section_real_get_angle;
iface->set_bounds = eek_gtk_section_real_set_bounds;
iface->get_bounds = eek_gtk_section_real_get_bounds;
iface->create_key = eek_gtk_section_real_create_key;
iface->foreach_key = eek_gtk_section_real_foreach_key;
}
static void
eek_gtk_section_dispose (GObject *object)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(object);
gint i, num_rows;
num_rows = eek_section_get_rows (EEK_SECTION(object));
for (i = 0; i < num_rows; i++)
if (priv->rows[i]) {
g_object_unref (priv->rows[i]);
priv->rows[i] = NULL;
}
if (priv->simple) {
g_object_unref (priv->simple);
priv->simple = NULL;
}
G_OBJECT_CLASS (eek_gtk_section_parent_class)->dispose (object);
}
static void
eek_gtk_section_finalize (GObject *object)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(object);
g_slice_free (GtkWidget *, priv->rows);
G_OBJECT_CLASS (eek_gtk_section_parent_class)->finalize (object);
}
static void
eek_gtk_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(object);
switch (prop_id) {
case PROP_ANGLE:
eek_section_set_angle (EEK_SECTION(object),
g_value_get_int (value));
break;
case PROP_BOUNDS:
eek_section_set_bounds (EEK_SECTION(object),
g_value_get_boxed (value));
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_gtk_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekGtkSectionPrivate *priv = EEK_GTK_SECTION_GET_PRIVATE(object);
EekBounds bounds;
switch (prop_id) {
case PROP_ANGLE:
g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
break;
case PROP_BOUNDS:
eek_section_get_bounds (EEK_SECTION(object), &bounds);
g_value_set_boxed (value, &bounds);
break;
default:
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_gtk_section_class_init (EekGtkSectionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class, sizeof (EekGtkSectionPrivate));
gobject_class->set_property = eek_gtk_section_set_property;
gobject_class->get_property = eek_gtk_section_get_property;
gobject_class->finalize = eek_gtk_section_finalize;
gobject_class->dispose = eek_gtk_section_dispose;
g_object_class_override_property (gobject_class,
PROP_ANGLE,
"angle");
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
}
static void
eek_gtk_section_init (EekGtkSection *self)
{
EekGtkSectionPrivate *priv;
priv = self->priv = EEK_GTK_SECTION_GET_PRIVATE (self);
priv->simple = g_object_new (EEK_TYPE_SIMPLE_SECTION, NULL);
priv->rows = NULL;
}

30
eek/eek-gtk.pc.in Normal file
View 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-GTK
Description: A Library to Create Keyboard-like UI (GTK Support)
URL: http://github.com/ueno/eek
Version: @VERSION@
Libs: -L${libdir} -leek -leek-gtk
Libs.private: @GTK2_LIBS@
Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -26,5 +26,5 @@ 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: @XKB_LIBS@
Libs.private: @GTK2_LIBS@ @XKB_LIBS@
Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -16,6 +16,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
noinst_PROGRAMS = eek-clutter-xkb-test
noinst_PROGRAMS = eek-clutter-xkb-test eek-gtk-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_gtk_xkb_test_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(GTK2_CFLAGS) $(XKB_CFLAGS)
eek_gtk_xkb_test_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la $(top_builddir)/eek/libeek-gtk.la $(GOBJECT2_LIBS) $(GTK2_LIBS) $(XKB_LIBS)

View File

@ -0,0 +1,70 @@
#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;
}