This commit is contained in:
Daiki Ueno
2010-06-09 16:44:26 +09:00
parent 9e61919384
commit 662f619ba2
53 changed files with 2653 additions and 4894 deletions

9
README
View File

@ -40,13 +40,8 @@ and an XKB-based layout engine:
10: /* Apply the layout to the keyboard. */ 10: /* Apply the layout to the keyboard. */
11: eek_keyboard_set_layout (keyboard, layout); 11: eek_keyboard_set_layout (keyboard, layout);
12: 12:
13: clutter_group_add (CLUTTER_GROUP(stage), CLUTTER_ACTOR(keyboard)); 13: clutter_group_add (CLUTTER_GROUP(stage),
14: eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard)));
To use GTK+-based keyboard elements instead of Clutter, simply replace
line 8 and 13 with:
8: keyboard = eek_gtk_keyboard_new ();
13: gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(keyboard));
Footnotes: Footnotes:
[1] http://en.wikipedia.org/wiki/Builder_pattern [1] http://en.wikipedia.org/wiki/Builder_pattern

View File

@ -56,6 +56,5 @@ docs/reference/Makefile
docs/reference/eek/Makefile docs/reference/eek/Makefile
eek/eek.pc eek/eek.pc
eek/eek-clutter.pc eek/eek-clutter.pc
eek/eek-xkb.pc eek/eek-xkb.pc])
eek/eek-gtk.pc])
AC_OUTPUT AC_OUTPUT

View File

@ -77,8 +77,7 @@ EXTRA_HFILES=
# Header files to ignore when scanning. Use base file name, no paths # Header files to ignore when scanning. Use base file name, no paths
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES= eek-private.h \ IGNORE_HFILES= eek-private.h \
eek-clutter-private.h \ eek-keysym.h \
eek-keysyms.h \
$(NULL) $(NULL)
# Images to copy into HTML directory. # Images to copy into HTML directory.
@ -103,7 +102,6 @@ GTKDOC_CFLAGS = $(GOBJECT2_CFLAGS)
GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \ GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \
$(top_srcdir)/eek/libeek-clutter.la \ $(top_srcdir)/eek/libeek-clutter.la \
$(top_srcdir)/eek/libeek-xkb.la \ $(top_srcdir)/eek/libeek-xkb.la \
$(top_srcdir)/eek/libeek-gtk.la \
$(GOBJECT2_LIBS) \ $(GOBJECT2_LIBS) \
$(CLUTTER_LIBS) \ $(CLUTTER_LIBS) \
$(XKB_LIBS) \ $(XKB_LIBS) \

View File

@ -14,6 +14,8 @@
<chapter> <chapter>
<title>Base classes and interfaces</title> <title>Base classes and interfaces</title>
<xi:include href="xml/eek-element.xml"/>
<xi:include href="xml/eek-container.xml"/>
<xi:include href="xml/eek-keyboard.xml"/> <xi:include href="xml/eek-keyboard.xml"/>
<xi:include href="xml/eek-section.xml"/> <xi:include href="xml/eek-section.xml"/>
<xi:include href="xml/eek-key.xml"/> <xi:include href="xml/eek-key.xml"/>
@ -30,12 +32,6 @@
<title>XKB layout engine</title> <title>XKB layout engine</title>
<xi:include href="xml/eek-xkb-layout.xml"/> <xi:include href="xml/eek-xkb-layout.xml"/>
</chapter> </chapter>
<chapter>
<title>GTK keyboard elements</title>
<xi:include href="xml/eek-gtk-keyboard.xml"/>
<xi:include href="xml/eek-gtk-section.xml"/>
<xi:include href="xml/eek-gtk-key.xml"/>
</chapter>
<chapter id="object-tree"> <chapter id="object-tree">
<title>Object Hierarchy</title> <title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/> <xi:include href="xml/tree_index.sgml"/>

View File

@ -16,25 +16,21 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
lib_LTLIBRARIES = libeek.la libeek-clutter.la libeek-xkb.la libeek-gtk.la lib_LTLIBRARIES = libeek.la libeek-clutter.la libeek-xkb.la
libeek_la_SOURCES = \ libeek_la_SOURCES = \
eek-layout.c \ eek-layout.c \
eek-layout.h \ eek-layout.h \
eek-element.c \
eek-element.h \
eek-container.c \
eek-container.h \
eek-keyboard.c \ eek-keyboard.c \
eek-keyboard.h \ eek-keyboard.h \
eek-section.c \ eek-section.c \
eek-section.h \ eek-section.h \
eek-key.c \ eek-key.c \
eek-key.h \ eek-key.h \
eek-simple-keyboard.c \
eek-simple-keyboard.h \
eek-simple-section.c \
eek-simple-section.h \
eek-simple-key.c \
eek-simple-key.h \
eek-private.c \
eek-private.h \
eek-types.h \ eek-types.h \
eek-types.c \ eek-types.c \
eek-keysym.h \ eek-keysym.h \
@ -54,8 +50,8 @@ libeek_clutter_la_SOURCES = \
eek-clutter-section.h \ eek-clutter-section.h \
eek-clutter-key.c \ eek-clutter-key.c \
eek-clutter-key.h \ eek-clutter-key.h \
eek-clutter-private.c \ eek-clutter-key-actor.c \
eek-clutter-private.h \ eek-clutter-key-actor.h \
eek-clutter.h \ eek-clutter.h \
$(NULL) $(NULL)
@ -70,23 +66,10 @@ libeek_xkb_la_SOURCES = \
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS) libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS)
libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS) 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 eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
eek_HEADERS = \ eek_HEADERS = \
$(top_srcdir)/eek/eek-element.h \
$(top_srcdir)/eek/eek-container.h \
$(top_srcdir)/eek/eek-keyboard.h \ $(top_srcdir)/eek/eek-keyboard.h \
$(top_srcdir)/eek/eek-section.h \ $(top_srcdir)/eek/eek-section.h \
$(top_srcdir)/eek/eek-key.h \ $(top_srcdir)/eek/eek-key.h \
@ -111,7 +94,7 @@ eek-keyname-keysym-labels.h: keyname-keysym-labels.txt
$(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@ $(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = eek.pc eek-clutter.pc eek-xkb.pc eek-gtk.pc pkgconfig_DATA = eek.pc eek-clutter.pc eek-xkb.pc
DISTCLEANFILES = \ DISTCLEANFILES = \
eek-special-keysym-labels.h \ eek-special-keysym-labels.h \

561
eek/eek-clutter-key-actor.c Normal file
View File

@ -0,0 +1,561 @@
/*
* 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-clutter-key-actor
* @short_description: Custom #ClutterActor drawing a key shape
*/
#include <math.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-clutter-key-actor.h"
#include "eek-keysym.h"
#include <cogl/cogl.h>
#include <cogl/cogl-pango.h>
#define noKBDRAW_DEBUG
G_DEFINE_TYPE (EekClutterKeyActor, eek_clutter_key_actor,
CLUTTER_TYPE_GROUP);
#define EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorPrivate))
struct _EekClutterKeyActorPrivate
{
EekKey *key;
ClutterActor *texture;
};
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
eek_clutter_key_actor_real_paint (ClutterActor *self)
{
EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE (self);
PangoLayout *layout;
PangoRectangle logical_rect = { 0, };
CoglColor color;
ClutterGeometry geom;
EekBounds bounds;
eek_element_get_bounds (EEK_ELEMENT(priv->key), &bounds);
clutter_actor_set_anchor_point_from_gravity (self,
CLUTTER_GRAVITY_CENTER);
clutter_actor_set_position (self,
bounds.x + bounds.width / 2,
bounds.y + bounds.height / 2);
if (!priv->texture) {
priv->texture = get_texture (EEK_CLUTTER_KEY_ACTOR(self));
clutter_actor_set_position (priv->texture, 0, 0);
clutter_container_add_actor (CLUTTER_CONTAINER(self), priv->texture);
}
CLUTTER_ACTOR_CLASS (eek_clutter_key_actor_parent_class)->
paint (self);
/* Draw the label on the key. */
layout = clutter_actor_create_pango_layout (self, NULL);
draw_key_on_layout (priv->key, layout);
pango_layout_get_extents (layout, NULL, &logical_rect);
/* FIXME: Color should be configurable through a property. */
cogl_color_set_from_4ub (&color, 0x80, 0x00, 0x00, 0xff);
clutter_actor_get_allocation_geometry (self, &geom);
cogl_pango_render_layout (layout,
(geom.width - logical_rect.width / PANGO_SCALE) / 2,
(geom.height - logical_rect.height / PANGO_SCALE) / 2,
&color,
0);
g_object_unref (layout);
}
/* FIXME: This is a workaround for the bug
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
static void
eek_clutter_key_actor_real_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE (self);
PangoLayout *layout;
/* Draw the label on the key - just to validate the glyph cache. */
layout = clutter_actor_create_pango_layout (self, NULL);
draw_key_on_layout (priv->key, layout);
cogl_pango_ensure_glyph_cache_for_layout (layout);
g_object_unref (layout);
CLUTTER_ACTOR_CLASS (eek_clutter_key_actor_parent_class)->
get_preferred_width (self, for_height, min_width_p, natural_width_p);
}
static void
eek_clutter_key_actor_finalize (GObject *object)
{
EekClutterKeyActorPrivate *priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(object);
clutter_group_remove_all (CLUTTER_GROUP(object));
g_object_unref (priv->key);
if (priv->texture)
g_object_unref (priv->texture);
G_OBJECT_CLASS (eek_clutter_key_actor_parent_class)->finalize (object);
}
static void
eek_clutter_key_actor_class_init (EekClutterKeyActorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
g_type_class_add_private (gobject_class,
sizeof (EekClutterKeyActorPrivate));
klass->outline_textures = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
g_free);
actor_class->paint = eek_clutter_key_actor_real_paint;
/* FIXME: This is a workaround for the bug
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
actor_class->get_preferred_width =
eek_clutter_key_actor_real_get_preferred_width;
gobject_class->finalize = eek_clutter_key_actor_finalize;
}
static void
eek_clutter_key_actor_init (EekClutterKeyActor *self)
{
EekClutterKeyActorPrivate *priv;
priv = self->priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(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);
}
ClutterActor *
eek_clutter_key_actor_new (EekKey *key)
{
EekClutterKeyActor *actor;
actor = g_object_new (EEK_TYPE_CLUTTER_KEY_ACTOR, NULL);
actor->priv->key = key;
g_object_ref (actor->priv->key);
return CLUTTER_ACTOR(actor);
}
static void
on_key_animate_complete (ClutterAnimation *animation,
gpointer user_data)
{
ClutterActor *actor = (ClutterActor*)user_data;
/* reset after effect */
clutter_actor_set_opacity (actor, 0xff);
clutter_actor_set_scale (actor, 1.0, 1.0);
}
static void
key_enlarge (ClutterActor *actor)
{
clutter_actor_set_scale (actor, 1.0, 1.0);
clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150,
"scale-x", 1.5,
"scale-y", 1.5,
NULL);
}
static void
key_shrink (ClutterActor *actor)
{
clutter_actor_set_scale (actor, 1.5, 1.5);
clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
}
static gboolean
on_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
if (clutter_event_get_source (event) == actor) {
EekClutterKeyActorPrivate *priv =
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
ClutterActor *section;
g_return_val_if_fail (priv, FALSE);
/* 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);
if (event->type == CLUTTER_BUTTON_PRESS) {
key_enlarge (actor);
g_signal_emit_by_name (priv->key, "pressed");
} else if (event->type == CLUTTER_BUTTON_RELEASE) {
key_shrink (actor);
g_signal_emit_by_name (priv->key, "released");
}
}
return FALSE;
}
static gdouble
length (gdouble x, gdouble y)
{
return sqrt (x * x + y * y);
}
static gdouble
point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny)
{
return ax * nx + ay * ny;
}
static void
normal_form (gdouble ax, gdouble ay,
gdouble bx, gdouble by,
gdouble * nx, gdouble * ny, gdouble * d)
{
gdouble l;
*nx = by - ay;
*ny = ax - bx;
l = length (*nx, *ny);
*nx /= l;
*ny /= l;
*d = point_line_distance (ax, ay, *nx, *ny);
}
static void
inverse (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble * e, gdouble * f, gdouble * g, gdouble * h)
{
gdouble det;
det = a * d - b * c;
*e = d / det;
*f = -b / det;
*g = -c / det;
*h = a / det;
}
static void
multiply (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble e, gdouble f, gdouble * x, gdouble * y)
{
*x = a * e + b * f;
*y = c * e + d * f;
}
static void
intersect (gdouble n1x, gdouble n1y, gdouble d1,
gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y)
{
gdouble e, f, g, h;
inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h);
multiply (e, f, g, h, d1, d2, x, y);
}
/* draw an angle from the current point to b and then to c,
* with a rounded corner of the given radius.
*/
static void
rounded_corner (cairo_t * cr,
gdouble bx, gdouble by,
gdouble cx, gdouble cy, gdouble radius)
{
gdouble ax, ay;
gdouble n1x, n1y, d1;
gdouble n2x, n2y, d2;
gdouble pd1, pd2;
gdouble ix, iy;
gdouble dist1, dist2;
gdouble nx, ny, d;
gdouble a1x, a1y, c1x, c1y;
gdouble phi1, phi2;
cairo_get_current_point (cr, &ax, &ay);
#ifdef KBDRAW_DEBUG
printf (" current point: (%f, %f), radius %f:\n", ax, ay,
radius);
#endif
/* make sure radius is not too large */
dist1 = length (bx - ax, by - ay);
dist2 = length (cx - bx, cy - by);
radius = MIN (radius, MIN (dist1, dist2));
/* construct normal forms of the lines */
normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);
/* find which side of the line a,b the point c is on */
if (point_line_distance (cx, cy, n1x, n1y) < d1)
pd1 = d1 - radius;
else
pd1 = d1 + radius;
/* find which side of the line b,c the point a is on */
if (point_line_distance (ax, ay, n2x, n2y) < d2)
pd2 = d2 - radius;
else
pd2 = d2 + radius;
/* intersect the parallels to find the center of the arc */
intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);
nx = (bx - ax) / dist1;
ny = (by - ay) / dist1;
d = point_line_distance (ix, iy, nx, ny);
/* a1 is the point on the line a-b where the arc starts */
intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);
nx = (cx - bx) / dist2;
ny = (cy - by) / dist2;
d = point_line_distance (ix, iy, nx, ny);
/* c1 is the point on the line b-c where the arc ends */
intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);
/* determine the first angle */
if (a1x - ix == 0)
phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (a1x - ix > 0)
phi1 = atan ((a1y - iy) / (a1x - ix));
else
phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));
/* determine the second angle */
if (c1x - ix == 0)
phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (c1x - ix > 0)
phi2 = atan ((c1y - iy) / (c1x - ix));
else
phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));
/* compute the difference between phi2 and phi1 mod 2pi */
d = phi2 - phi1;
while (d < 0)
d += 2 * M_PI;
while (d > 2 * M_PI)
d -= 2 * M_PI;
#ifdef KBDRAW_DEBUG
printf (" line 1 to: (%f, %f):\n", a1x, a1y);
#endif
if (!(isnan (a1x) || isnan (a1y)))
cairo_line_to (cr, a1x, a1y);
/* pick the short arc from phi1 to phi2 */
if (d < M_PI)
cairo_arc (cr, ix, iy, radius, phi1, phi2);
else
cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);
#ifdef KBDRAW_DEBUG
printf (" line 2 to: (%f, %f):\n", cx, cy);
#endif
cairo_line_to (cr, cx, cy);
}
void
draw_rounded_polygon (cairo_t *cr,
gboolean filled,
gdouble radius,
EekPoint *points,
gint num_points)
{
gint i, j;
cairo_move_to (cr,
(gdouble) (points[num_points - 1].x +
points[0].x) / 2,
(gdouble) (points[num_points - 1].y +
points[0].y) / 2);
#ifdef KBDRAW_DEBUG
printf (" rounded polygon of radius %f:\n", radius);
#endif
for (i = 0; i < num_points; i++) {
j = (i + 1) % num_points;
rounded_corner (cr, (gdouble) points[i].x,
(gdouble) points[i].y,
(gdouble) (points[i].x + points[j].x) / 2,
(gdouble) (points[i].y + points[j].y) / 2,
radius);
#ifdef KBDRAW_DEBUG
printf (" corner (%d, %d) -> (%d, %d):\n",
points[i].x, points[i].y, points[j].x,
points[j].y);
#endif
};
cairo_close_path (cr);
if (filled)
cairo_fill (cr);
else
cairo_stroke (cr);
}
static ClutterActor *
create_texture_for_key (EekKey *key)
{
ClutterActor *texture;
cairo_t *cr;
cairo_pattern_t *pat;
EekOutline *outline;
EekBounds bounds;
outline = eek_key_get_outline (EEK_KEY(key));
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
texture = clutter_cairo_texture_new (bounds.width, bounds.height);
cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE(texture));
cairo_set_line_width (cr, 1);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0);
cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1);
cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
cairo_set_source (cr, pat);
draw_rounded_polygon (cr,
TRUE,
outline->corner_radius,
outline->points,
outline->num_points);
cairo_pattern_destroy (pat);
cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5);
draw_rounded_polygon (cr,
FALSE,
outline->corner_radius,
outline->points,
outline->num_points);
cairo_destroy (cr);
return texture;
}
static ClutterActor *
get_texture (EekClutterKeyActor *actor)
{
ClutterActor *texture;
GHashTable *outline_textures;
EekOutline *outline;
outline_textures = EEK_CLUTTER_KEY_ACTOR_GET_CLASS(actor)->
outline_textures;
outline = eek_key_get_outline (actor->priv->key);
texture = g_hash_table_lookup (outline_textures, outline);
if (texture == NULL) {
texture = create_texture_for_key (actor->priv->key);
g_hash_table_insert (outline_textures, outline, texture);
} else
texture = clutter_clone_new (texture);
return texture;
}
static void
draw_text_on_layout (PangoLayout *layout,
const gchar *text,
gdouble scale)
{
PangoFontDescription *font_desc;
#define FONT_SIZE (720 * 50)
/* FIXME: Font should be configurable through a property. */
font_desc = pango_font_description_from_string ("Sans");
pango_font_description_set_size (font_desc, FONT_SIZE * scale);
pango_layout_set_font_description (layout, font_desc);
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
pango_layout_set_text (layout, text, -1);
pango_font_description_free (font_desc);
}
static void
draw_key_on_layout (EekKey *key,
PangoLayout *layout)
{
PangoLayout *buffer;
PangoRectangle logical_rect = { 0, };
EekBounds bounds;
guint keysym;
const gchar *label, *empty_label = "";
gdouble scale_x, scale_y;
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
keysym = eek_key_get_keysym (key);
if (keysym == EEK_INVALID_KEYSYM)
return;
label = eek_keysym_to_string (keysym);
if (!label)
label = empty_label;
/* Compute the layout extents. */
buffer = pango_layout_copy (layout);
draw_text_on_layout (buffer, label, 1.0);
pango_layout_get_extents (buffer, NULL, &logical_rect);
scale_x = scale_y = 1.0;
if (PANGO_PIXELS(logical_rect.width) > bounds.width)
scale_x = bounds.width / PANGO_PIXELS(logical_rect.width);
if (PANGO_PIXELS(logical_rect.height) > bounds.height)
scale_y = bounds.height / PANGO_PIXELS(logical_rect.height);
g_object_unref (buffer);
/* Actually draw on the layout */
draw_text_on_layout (layout,
label,
(scale_x < scale_y ? scale_x : scale_y) * 0.8);
if (label != empty_label)
g_free ((gpointer)label);
}

View File

@ -0,0 +1,60 @@
/*
* 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_CLUTTER_KEY_ACTOR_H
#define EEK_CLUTTER_KEY_ACTOR_H 1
#include <clutter/clutter.h>
#include "eek-key.h"
G_BEGIN_DECLS
#define EEK_TYPE_CLUTTER_KEY_ACTOR (eek_clutter_key_actor_get_type())
#define EEK_CLUTTER_KEY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActor))
#define EEK_CLUTTER_KEY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorClass))
#define EEK_IS_CLUTTER_KEY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR))
#define EEK_IS_CLUTTER_KEY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEY_ACTOR))
#define EEK_CLUTTER_KEY_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEY_ACTOR, EekClutterKeyActorClass))
typedef struct _EekClutterKeyActor EekClutterKeyActor;
typedef struct _EekClutterKeyActorClass EekClutterKeyActorClass;
typedef struct _EekClutterKeyActorPrivate EekClutterKeyActorPrivate;
struct _EekClutterKeyActor
{
/*< private >*/
ClutterGroup parent;
/*< private >*/
EekClutterKeyActorPrivate *priv;
};
struct _EekClutterKeyActorClass
{
/*< private >*/
ClutterGroupClass parent_class;
/* outline pointer -> ClutterTexture */
GHashTable *outline_textures;
};
GType eek_clutter_key_actor_get_type (void) G_GNUC_CONST;
ClutterActor *eek_clutter_key_actor_new (EekKey *key);
G_END_DECLS
#endif /* EEK_CLUTTER_KEY_ACTOR_H */

View File

@ -20,205 +20,52 @@
/** /**
* SECTION:eek-clutter-key * SECTION:eek-clutter-key
* @short_description: #EekKey implemented as a #ClutterActor * @short_description: #EekKey embedding a #ClutterActor
*
* The #EekClutterKey class implements the #EekKeyIface interface as a
* #ClutterActor.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-clutter-key.h" #include "eek-clutter-key.h"
#include "eek-simple-key.h" #include "eek-clutter-key-actor.h"
#include "eek-keysym.h"
enum { G_DEFINE_TYPE (EekClutterKey, eek_clutter_key, EEK_TYPE_KEY);
PROP_0,
PROP_KEYCODE,
PROP_KEYSYMS,
PROP_COLUMN,
PROP_ROW,
PROP_OUTLINE,
PROP_BOUNDS,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST
};
static void eek_key_iface_init (EekKeyIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekClutterKey, eek_clutter_key,
CLUTTER_TYPE_GROUP,
G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY,
eek_key_iface_init));
#define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \ #define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate))
struct _EekClutterKeyPrivate struct _EekClutterKeyPrivate
{ {
EekSimpleKey *simple; ClutterActor *actor;
}; };
static guint static void
eek_clutter_key_real_get_keycode (EekKey *self) eek_clutter_key_real_set_name (EekElement *self,
const gchar *name)
{ {
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, EEK_INVALID_KEYCODE); EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)->
return eek_key_get_keycode (EEK_KEY(priv->simple)); set_name (self, name);
g_return_if_fail (priv->actor);
clutter_actor_set_name (CLUTTER_ACTOR(priv->actor), name);
} }
static void static void
eek_clutter_key_real_set_keysyms (EekKey *self, eek_clutter_key_real_set_bounds (EekElement *self,
guint *keysyms,
gint groups,
gint levels)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels);
}
static void
eek_clutter_key_real_get_keysyms (EekKey *self,
guint **keysyms,
gint *groups,
gint *levels)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_get_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels);
}
static gint
eek_clutter_key_real_get_groups (EekKey *self)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1);
return eek_key_get_groups (EEK_KEY(priv->simple));
}
static guint
eek_clutter_key_real_get_keysym (EekKey *self)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_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_clutter_key_real_set_index (EekKey *self,
gint column,
gint row)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_index (EEK_KEY(priv->simple), column, row);
}
static void
eek_clutter_key_real_get_index (EekKey *self,
gint *column,
gint *row)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_get_index (EEK_KEY(priv->simple), column, row);
}
static void
eek_clutter_key_real_set_outline (EekKey *self, EekOutline *outline)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_outline (EEK_KEY(priv->simple), outline);
}
static EekOutline *
eek_clutter_key_real_get_outline (EekKey *self)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, NULL);
return eek_key_get_outline (EEK_KEY(priv->simple));
}
static void
eek_clutter_key_real_set_bounds (EekKey *self, EekBounds *bounds)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_set_bounds (EEK_KEY(priv->simple), bounds);
clutter_actor_set_anchor_point_from_gravity (CLUTTER_ACTOR(self),
CLUTTER_GRAVITY_CENTER);
clutter_actor_set_position (CLUTTER_ACTOR(self),
bounds->x + bounds->width / 2,
bounds->y + bounds->height / 2);
}
static void
eek_clutter_key_real_get_bounds (EekKey *self,
EekBounds *bounds) EekBounds *bounds)
{ {
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv); EEK_ELEMENT_CLASS (eek_clutter_key_parent_class)->
return eek_key_get_bounds (EEK_KEY(priv->simple), bounds); set_bounds (self, bounds);
}
static void g_return_if_fail (priv->actor);
eek_clutter_key_real_set_keysym_index (EekKey *self,
gint group,
gint level)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self);
g_return_if_fail (priv); clutter_actor_set_position (priv->actor, bounds->x, bounds->y);
eek_key_set_keysym_index (EEK_KEY(priv->simple), group, level); clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
}
static void
eek_clutter_key_real_get_keysym_index (EekKey *self, gint *group, gint *level)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_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->get_keycode = eek_clutter_key_real_get_keycode;
iface->set_keysyms = eek_clutter_key_real_set_keysyms;
iface->get_keysyms = eek_clutter_key_real_get_keysyms;
iface->get_groups = eek_clutter_key_real_get_groups;
iface->get_keysym = eek_clutter_key_real_get_keysym;
iface->set_index = eek_clutter_key_real_set_index;
iface->get_index = eek_clutter_key_real_get_index;
iface->set_outline = eek_clutter_key_real_set_outline;
iface->get_outline = eek_clutter_key_real_get_outline;
iface->set_bounds = eek_clutter_key_real_set_bounds;
iface->get_bounds = eek_clutter_key_real_get_bounds;
iface->set_keysym_index = eek_clutter_key_real_set_keysym_index;
iface->get_keysym_index = eek_clutter_key_real_get_keysym_index;
}
static void
eek_clutter_key_dispose (GObject *object)
{
clutter_group_remove_all (CLUTTER_GROUP(object));
G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object);
} }
static void static void
@ -226,358 +73,40 @@ eek_clutter_key_finalize (GObject *object)
{ {
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
g_object_unref (priv->simple); if (priv->actor) {
clutter_group_remove_all (CLUTTER_GROUP(priv->actor));
g_object_unref (priv->actor);
}
G_OBJECT_CLASS (eek_clutter_key_parent_class)->finalize (object); G_OBJECT_CLASS (eek_clutter_key_parent_class)->finalize (object);
} }
static void
draw_text_on_layout (PangoLayout *layout,
const gchar *text,
gdouble scale)
{
PangoFontDescription *font_desc;
#define FONT_SIZE (720 * 50)
/* FIXME: Font should be configurable through a property. */
font_desc = pango_font_description_from_string ("Sans");
pango_font_description_set_size (font_desc, FONT_SIZE * scale);
pango_layout_set_font_description (layout, font_desc);
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
pango_layout_set_text (layout, text, -1);
pango_font_description_free (font_desc);
}
static void
draw_key_on_layout (EekKey *key,
PangoLayout *layout)
{
PangoLayout *buffer;
PangoRectangle logical_rect = { 0, };
EekBounds bounds;
guint keysym;
const gchar *label, *empty_label = "";
gdouble scale_x, scale_y;
eek_key_get_bounds (key, &bounds);
keysym = eek_key_get_keysym (key);
if (keysym == EEK_INVALID_KEYSYM)
return;
label = eek_keysym_to_string (keysym);
if (!label)
label = empty_label;
/* Compute the layout extents. */
buffer = pango_layout_copy (layout);
draw_text_on_layout (buffer, label, 1.0);
pango_layout_get_extents (buffer, NULL, &logical_rect);
scale_x = scale_y = 1.0;
if (PANGO_PIXELS(logical_rect.width) > bounds.width)
scale_x = bounds.width / PANGO_PIXELS(logical_rect.width);
if (PANGO_PIXELS(logical_rect.height) > bounds.height)
scale_y = bounds.height / PANGO_PIXELS(logical_rect.height);
g_object_unref (buffer);
/* Actually draw on the layout */
draw_text_on_layout (layout,
label,
(scale_x < scale_y ? scale_x : scale_y) * 0.8);
if (label != empty_label)
g_free ((gpointer)label);
}
static void
eek_clutter_key_paint (ClutterActor *self)
{
PangoLayout *layout;
PangoRectangle logical_rect = { 0, };
CoglColor color;
ClutterGeometry geom;
EekBounds bounds;
gfloat width, height;
gfloat x, y;
g_return_if_fail (CLUTTER_IS_ACTOR(self));
g_return_if_fail (EEK_IS_KEY(self));
/* Draw the background texture first. */
CLUTTER_ACTOR_CLASS (eek_clutter_key_parent_class)->paint (self);
/* Draw the label on the key. */
layout = clutter_actor_create_pango_layout (self, NULL);
draw_key_on_layout (EEK_KEY(self), layout);
pango_layout_get_extents (layout, NULL, &logical_rect);
/* FIXME: Color should be configurable through a property. */
cogl_color_set_from_4ub (&color, 0x80, 0x00, 0x00, 0xff);
clutter_actor_get_allocation_geometry (self, &geom);
cogl_pango_render_layout (layout,
(geom.width - logical_rect.width / PANGO_SCALE) / 2,
(geom.height - logical_rect.height / PANGO_SCALE) / 2,
&color,
0);
g_object_unref (layout);
}
/* FIXME: This is a workaround for the bug
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
static void
eek_clutter_key_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
PangoLayout *layout;
/* Draw the label on the key - just to validate the glyph cache. */
layout = clutter_actor_create_pango_layout (self, NULL);
draw_key_on_layout (EEK_KEY(self), layout);
cogl_pango_ensure_glyph_cache_for_layout (layout);
g_object_unref (layout);
CLUTTER_ACTOR_CLASS (eek_clutter_key_parent_class)->get_preferred_width
(self, for_height, min_width_p, natural_width_p);
}
static void
eek_clutter_key_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
g_return_if_fail (priv);
switch (prop_id) {
/* Properties which affect the appearance of the key as a
ClutterActor. */
case PROP_BOUNDS:
eek_key_set_bounds (EEK_KEY(object),
g_value_get_boxed (value));
break;
case PROP_OUTLINE:
eek_key_set_outline (EEK_KEY(object),
g_value_get_pointer (value));
break;
/* Otherwise delegate to priv->simple or the parent. */
case PROP_KEYCODE:
case PROP_KEYSYMS:
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_clutter_key_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object);
EekBounds bounds;
g_return_if_fail (priv);
switch (prop_id) {
case PROP_BOUNDS:
eek_key_get_bounds (EEK_KEY(object), &bounds);
g_value_set_boxed (value, &bounds);
break;
case PROP_KEYCODE:
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 static void
eek_clutter_key_class_init (EekClutterKeyClass *klass) eek_clutter_key_class_init (EekClutterKeyClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); EekElementClass *element_class = EEK_ELEMENT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class, g_type_class_add_private (gobject_class,
sizeof (EekClutterKeyPrivate)); sizeof (EekClutterKeyPrivate));
actor_class->paint = eek_clutter_key_paint; element_class->set_name = eek_clutter_key_real_set_name;
/* FIXME: This is a workaround for the bug element_class->set_bounds = eek_clutter_key_real_set_bounds;
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
actor_class->get_preferred_width = eek_clutter_key_get_preferred_width;
gobject_class->set_property = eek_clutter_key_set_property;
gobject_class->get_property = eek_clutter_key_get_property;
gobject_class->finalize = eek_clutter_key_finalize; gobject_class->finalize = eek_clutter_key_finalize;
gobject_class->dispose = eek_clutter_key_dispose;
g_object_class_override_property (gobject_class,
PROP_KEYCODE,
"keycode");
g_object_class_override_property (gobject_class,
PROP_KEYSYMS,
"keysyms");
g_object_class_override_property (gobject_class,
PROP_COLUMN,
"column");
g_object_class_override_property (gobject_class,
PROP_ROW,
"row");
g_object_class_override_property (gobject_class,
PROP_OUTLINE,
"outline");
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
g_object_class_override_property (gobject_class,
PROP_GROUP,
"group");
g_object_class_override_property (gobject_class,
PROP_LEVEL,
"level");
}
static void
on_key_animate_complete (ClutterAnimation *animation,
gpointer user_data)
{
ClutterActor *actor = (ClutterActor*)user_data;
/* reset after effect */
clutter_actor_set_opacity (actor, 0xff);
clutter_actor_set_scale (actor, 1.0, 1.0);
}
static void
key_enlarge (ClutterActor *actor)
{
clutter_actor_set_scale (actor, 1.0, 1.0);
clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150,
"scale-x", 1.5,
"scale-y", 1.5,
NULL);
}
static void
key_shrink (ClutterActor *actor)
{
clutter_actor_set_scale (actor, 1.5, 1.5);
clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150,
"scale-x", 1.0,
"scale-y", 1.0,
NULL);
}
static gboolean
on_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
g_return_val_if_fail (EEK_IS_KEY(actor), FALSE);
if (clutter_event_get_source (event) == actor) {
ClutterActor *section;
/* 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);
if (event->type == CLUTTER_BUTTON_PRESS)
key_enlarge (actor);
else if (event->type == CLUTTER_BUTTON_RELEASE)
key_shrink (actor);
}
return FALSE;
} }
static void static void
eek_clutter_key_init (EekClutterKey *self) eek_clutter_key_init (EekClutterKey *self)
{ {
EekClutterKeyPrivate *priv; EekClutterKeyPrivate *priv;
priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE (self); priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE (self);
priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEY, NULL); priv->actor = NULL;
clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE);
g_signal_connect (self, "event", G_CALLBACK (on_event), NULL);
} }
ClutterActor * ClutterActor *
eek_clutter_key_create_texture (EekClutterKey *key) eek_clutter_key_get_actor (EekClutterKey *key)
{ {
EekOutline *outline; EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(key);
EekBounds bounds; if (!priv->actor)
ClutterActor *texture; priv->actor = eek_clutter_key_actor_new (EEK_KEY(key));
cairo_t *cr; return priv->actor;
cairo_pattern_t *pat;
outline = eek_key_get_outline (EEK_KEY(key));
eek_key_get_bounds (EEK_KEY(key), &bounds);
texture = clutter_cairo_texture_new (bounds.width, bounds.height);
cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE(texture));
cairo_set_line_width (cr, 1);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0);
cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1);
cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
cairo_set_source (cr, pat);
eek_cairo_draw_rounded_polygon (cr,
TRUE,
outline->corner_radius,
outline->points,
outline->num_points);
cairo_pattern_destroy (pat);
cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5);
eek_cairo_draw_rounded_polygon (cr,
FALSE,
outline->corner_radius,
outline->points,
outline->num_points);
cairo_destroy (cr);
return texture;
}
/**
* eek_clutter_key_set_texture:
* @key: an #EekClutterKey
* @texture: an #ClutterActor
*
* Set the background texture of @key to @texture.
*/
void
eek_clutter_key_set_texture (EekClutterKey *key,
ClutterActor *texture)
{
clutter_actor_set_position (texture, 0, 0);
clutter_container_add_actor (CLUTTER_CONTAINER(key), texture);
} }

View File

@ -38,7 +38,7 @@ typedef struct _EekClutterKeyPrivate EekClutterKeyPrivate;
struct _EekClutterKey struct _EekClutterKey
{ {
/*< private >*/ /*< private >*/
ClutterGroup parent; EekKey parent;
/*< private >*/ /*< private >*/
EekClutterKeyPrivate *priv; EekClutterKeyPrivate *priv;
@ -47,14 +47,11 @@ struct _EekClutterKey
struct _EekClutterKeyClass struct _EekClutterKeyClass
{ {
/*< private >*/ /*< private >*/
ClutterGroupClass parent_class; EekKeyClass parent_class;
}; };
GType eek_clutter_key_get_type (void) G_GNUC_CONST; GType eek_clutter_key_get_type (void) G_GNUC_CONST;
ClutterActor *eek_clutter_key_get_actor (EekClutterKey *key);
ClutterActor *eek_clutter_key_create_texture (EekClutterKey *key);
void eek_clutter_key_set_texture (EekClutterKey *key,
ClutterActor *texture);
G_END_DECLS G_END_DECLS
#endif /* EEK_CLUTTER_KEY_H */ #endif /* EEK_CLUTTER_KEY_H */

View File

@ -20,31 +20,18 @@
/** /**
* SECTION:eek-clutter-keyboard * SECTION:eek-clutter-keyboard
* @short_description: #EekKeyboard implemented as a #ClutterActor * @short_description: #EekKeyboard embedding a #ClutterActor
*
* The #EekClutterKeyboard class implements the #EekKeyboardIface
* interface as a #ClutterActor.
*/ */
#include <string.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-clutter-keyboard.h" #include "eek-clutter-keyboard.h"
#include "eek-clutter-private.h" #include "eek-keyboard.h"
#include "eek-simple-keyboard.h"
enum { G_DEFINE_TYPE (EekClutterKeyboard, eek_clutter_keyboard, EEK_TYPE_KEYBOARD);
PROP_0,
PROP_BOUNDS,
PROP_LAST
};
static void eek_keyboard_iface_init (EekKeyboardIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekClutterKeyboard, eek_clutter_keyboard,
CLUTTER_TYPE_GROUP,
G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD,
eek_keyboard_iface_init));
#define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \ #define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardPrivate))
@ -52,254 +39,104 @@ G_DEFINE_TYPE_WITH_CODE (EekClutterKeyboard, eek_clutter_keyboard,
struct _EekClutterKeyboardPrivate struct _EekClutterKeyboardPrivate
{ {
EekSimpleKeyboard *simple; ClutterActor *actor;
gint group;
gint level;
}; };
static void static void
eek_clutter_keyboard_real_set_bounds (EekKeyboard *self, eek_clutter_keyboard_real_set_name (EekElement *self,
const gchar *name)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)->
set_name (self, name);
g_return_if_fail (priv->actor);
clutter_actor_set_name (priv->actor, name);
}
static void
eek_clutter_keyboard_real_set_bounds (EekElement *self,
EekBounds *bounds) EekBounds *bounds)
{ {
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv); EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)->
eek_keyboard_set_bounds (EEK_KEYBOARD(priv->simple), bounds); set_bounds (self, bounds);
clutter_actor_set_position (CLUTTER_ACTOR(self), bounds->x, bounds->y);
clutter_actor_set_size (CLUTTER_ACTOR(self), bounds->width, bounds->height); g_return_if_fail (priv->actor);
clutter_actor_set_position (priv->actor, bounds->x, bounds->y);
clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
} }
static void static void
eek_clutter_keyboard_real_get_bounds (EekKeyboard *self, key_pressed_event (EekSection *section,
EekBounds *bounds) EekKey *key,
EekKeyboard *keyboard)
{ {
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); g_signal_emit_by_name (keyboard, "key-pressed", key);
g_return_if_fail (priv);
return eek_keyboard_get_bounds (EEK_KEYBOARD(priv->simple), bounds);
} }
static void static void
eek_clutter_keyboard_real_set_keysym_index (EekKeyboard *self, key_released_event (EekSection *section,
gint group, EekKey *key,
gint level) EekKeyboard *keyboard)
{ {
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); g_signal_emit_by_name (keyboard, "key-released", key);
gint num_sections, num_keys, i, j;
g_return_if_fail (priv);
priv->group = group;
priv->level = level;
num_sections = clutter_group_get_n_children (CLUTTER_GROUP(self));
for (i = 0; i < num_sections; i++) {
ClutterActor *section;
section = clutter_group_get_nth_child (CLUTTER_GROUP(self), i);
g_return_if_fail (EEK_IS_CLUTTER_SECTION(section));
num_keys = clutter_group_get_n_children (CLUTTER_GROUP(section));
for (j = 0; j < num_keys; j++) {
ClutterActor *key;
key = clutter_group_get_nth_child (CLUTTER_GROUP(section), j);
g_return_if_fail (EEK_IS_CLUTTER_KEY(key));
eek_key_set_keysym_index (EEK_KEY(key), group, level);
}
}
}
static void
eek_clutter_keyboard_real_get_keysym_index (EekKeyboard *self,
gint *group,
gint *level)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv);
*group = priv->group;
*level = priv->level;
} }
static EekSection * static EekSection *
eek_clutter_keyboard_real_create_section (EekKeyboard *self, eek_clutter_keyboard_real_create_section (EekKeyboard *self)
const gchar *name,
gint angle,
EekBounds *bounds)
{ {
EekSection *section; EekSection *section;
ClutterActor *actor;
g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(self)); section = g_object_new (EEK_TYPE_CLUTTER_SECTION, NULL);
g_return_val_if_fail (section, NULL);
g_object_ref_sink (section);
section = g_object_new (EEK_TYPE_CLUTTER_SECTION, g_signal_connect (section, "key-pressed", G_CALLBACK(key_pressed_event), self);
"name", name, g_signal_connect (section, "key-released", G_CALLBACK(key_released_event), self);
"angle", angle,
"bounds", bounds,
NULL);
clutter_container_add_actor (CLUTTER_CONTAINER(self), EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
CLUTTER_ACTOR(section)); EEK_ELEMENT(section));
actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(self));
clutter_container_add_actor
(CLUTTER_CONTAINER(actor),
eek_clutter_section_get_actor (EEK_CLUTTER_SECTION(section)));
return section; return section;
} }
static void
eek_clutter_keyboard_real_foreach_section (EekKeyboard *self,
GFunc func,
gpointer user_data)
{
EekClutterCallbackData data;
g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(self));
data.func = func;
data.user_data = user_data;
clutter_container_foreach (CLUTTER_CONTAINER(self),
eek_clutter_callback,
&data);
}
static void
eek_clutter_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_clutter_keyboard_real_set_bounds;
iface->get_bounds = eek_clutter_keyboard_real_get_bounds;
iface->set_keysym_index = eek_clutter_keyboard_real_set_keysym_index;
iface->get_keysym_index = eek_clutter_keyboard_real_get_keysym_index;
iface->create_section = eek_clutter_keyboard_real_create_section;
iface->foreach_section = eek_clutter_keyboard_real_foreach_section;
iface->set_layout = eek_clutter_keyboard_real_set_layout;
}
static void
eek_clutter_keyboard_dispose (GObject *object)
{
clutter_group_remove_all (CLUTTER_GROUP(object));
G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->dispose (object);
}
static void static void
eek_clutter_keyboard_finalize (GObject *object) eek_clutter_keyboard_finalize (GObject *object)
{ {
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object);
g_object_unref (priv->simple); if (priv->actor) {
clutter_group_remove_all (CLUTTER_GROUP(priv->actor));
g_object_unref (priv->actor);
}
G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->finalize (object); G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->finalize (object);
} }
static void
eek_clutter_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_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_clutter_keyboard_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekClutterKeyboardPrivate *priv = EEK_CLUTTER_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_clutter_keyboard_paint (ClutterActor *self)
{
CLUTTER_ACTOR_CLASS (eek_clutter_keyboard_parent_class)->paint (self);
}
static void static void
eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass) eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); EekElementClass *element_class = EEK_ELEMENT_CLASS (klass);
GParamSpec *pspec; EekKeyboardClass *keyboard_class = EEK_KEYBOARD_CLASS (klass);
g_type_class_add_private (gobject_class, g_type_class_add_private (gobject_class,
sizeof (EekClutterKeyboardPrivate)); sizeof (EekClutterKeyboardPrivate));
gobject_class->set_property = eek_clutter_keyboard_set_property; keyboard_class->create_section = eek_clutter_keyboard_real_create_section;
gobject_class->get_property = eek_clutter_keyboard_get_property; element_class->set_name = eek_clutter_keyboard_real_set_name;
element_class->set_bounds = eek_clutter_keyboard_real_set_bounds;
gobject_class->finalize = eek_clutter_keyboard_finalize; gobject_class->finalize = eek_clutter_keyboard_finalize;
gobject_class->dispose = eek_clutter_keyboard_dispose;
actor_class->paint = eek_clutter_keyboard_paint;
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
}
static gboolean
on_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
EekKeyboard *keyboard;
EekKey *key;
ClutterActor *source;
g_return_val_if_fail (EEK_IS_KEYBOARD(user_data), FALSE);
keyboard = EEK_KEYBOARD(user_data);
source = clutter_event_get_source (event);
if (!EEK_IS_KEY(source))
return FALSE;
key = EEK_KEY(source);
if (event->type == CLUTTER_BUTTON_PRESS) {
guint keysym;
gint group, level;
keysym = eek_key_get_keysym (EEK_KEY(source));
if (keysym == 0xFFE1 || keysym == 0xFFE2) {
eek_keyboard_get_keysym_index (keyboard, &group, &level);
if (level == 0)
eek_keyboard_set_keysym_index (keyboard, group, 1);
else
eek_keyboard_set_keysym_index (keyboard, group, 0);
}
}
return FALSE;
} }
static void static void
@ -308,11 +145,7 @@ eek_clutter_keyboard_init (EekClutterKeyboard *self)
EekClutterKeyboardPrivate *priv; EekClutterKeyboardPrivate *priv;
priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL); priv->actor = NULL;
priv->group = priv->level = 0;
clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE);
g_signal_connect (self, "event", G_CALLBACK(on_event), self);
} }
/** /**
@ -326,10 +159,28 @@ EekKeyboard*
eek_clutter_keyboard_new (gfloat width, eek_clutter_keyboard_new (gfloat width,
gfloat height) gfloat height)
{ {
EekKeyboard *keyboard;
EekBounds bounds; EekBounds bounds;
bounds.x = bounds.y = 0; keyboard = g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, NULL);
g_return_val_if_fail (keyboard, NULL);
/* Can't call set_bounds of this class since it needs priv->actor
initialized */
memset (&bounds, 0, sizeof bounds);
bounds.width = width; bounds.width = width;
bounds.height = height; bounds.height = height;
return g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, "bounds", &bounds, NULL); EEK_ELEMENT_CLASS (eek_clutter_keyboard_parent_class)->
set_bounds (EEK_ELEMENT(keyboard), &bounds);
return keyboard;
}
ClutterActor *
eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard)
{
EekClutterKeyboardPrivate *priv =
EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard);
if (!priv->actor)
priv->actor = clutter_group_new ();
return priv->actor;
} }

View File

@ -25,7 +25,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_CLUTTER_KEYBOARD (eek_clutter_keyboard_get_type()) #define EEK_TYPE_CLUTTER_KEYBOARD (eek_clutter_keyboard_get_type())
#define EEK_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekKeyboard)) #define EEK_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboard))
#define EEK_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass)) #define EEK_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass))
#define EEK_IS_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEYBOARD)) #define EEK_IS_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEYBOARD))
#define EEK_IS_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEYBOARD)) #define EEK_IS_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEYBOARD))
@ -38,7 +38,7 @@ typedef struct _EekClutterKeyboardPrivate EekClutterKeyboardPrivate;
struct _EekClutterKeyboard struct _EekClutterKeyboard
{ {
/*< private >*/ /*< private >*/
ClutterGroup parent; EekKeyboard parent;
EekClutterKeyboardPrivate *priv; EekClutterKeyboardPrivate *priv;
}; };
@ -46,13 +46,13 @@ struct _EekClutterKeyboard
struct _EekClutterKeyboardClass struct _EekClutterKeyboardClass
{ {
/*< private >*/ /*< private >*/
ClutterGroupClass parent_class; EekKeyboardClass parent_class;
}; };
GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST; GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST;
EekKeyboard *eek_clutter_keyboard_new (gfloat width, EekKeyboard *eek_clutter_keyboard_new (gfloat width,
gfloat height); gfloat height);
ClutterActor *eek_clutter_keyboard_get_actor (EekClutterKeyboard *keyboard);
G_END_DECLS G_END_DECLS
#endif /* EEK_CLUTTER_KEYBOARD_H */ #endif /* EEK_CLUTTER_KEYBOARD_H */

View File

@ -1,31 +0,0 @@
/*
* 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-clutter-private.h"
void
eek_clutter_callback (ClutterActor *actor, gpointer user_data)
{
EekClutterCallbackData *data = user_data;
data->func (actor, data->user_data);
}

View File

@ -1,34 +0,0 @@
/*
* 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_CLUTTER_PRIVATE_H
#define EEK_CLUTTER_PRIVATE_H 1
#include <glib/gtypes.h>
#include <clutter/clutter.h>
struct _EekClutterCallbackData {
GFunc func;
gpointer user_data;
};
typedef struct _EekClutterCallbackData EekClutterCallbackData;
void eek_clutter_callback (ClutterActor *actor, gpointer user_data);
#endif /* EEK_CLUTTER_PRIVATE_H */

View File

@ -20,103 +20,51 @@
/** /**
* SECTION:eek-clutter-section * SECTION:eek-clutter-section
* @short_description: #EekSection implemented as a #ClutterActor * @short_description: #EekSection embedding a #ClutterActor
*
* The #EekClutterSection class implements the #EekSectionIface
* interface as a #ClutterActor.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-clutter-section.h" #include "eek-clutter-section.h"
#include "eek-clutter-private.h"
#include "eek-simple-section.h"
#include <stdio.h>
enum { G_DEFINE_TYPE (EekClutterSection, eek_clutter_section, EEK_TYPE_SECTION);
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 (EekClutterSection, eek_clutter_section,
CLUTTER_TYPE_GROUP,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION,
eek_section_iface_init));
#define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \ #define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate))
struct _EekClutterSectionPrivate struct _EekClutterSectionPrivate
{ {
EekSimpleSection *simple; ClutterActor *actor;
GHashTable *key_outline_texture_hash; /* outline pointer -> texture */
}; };
static void static void
eek_clutter_section_real_set_rows (EekSection *self, eek_clutter_section_real_set_name (EekElement *self,
gint rows) const gchar *name)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv); EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)->
eek_section_set_rows (EEK_SECTION(priv->simple), rows); set_name (self, name);
}
static gint g_return_if_fail (priv->actor);
eek_clutter_section_real_get_rows (EekSection *self)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1); clutter_actor_set_name (priv->actor, name);
return eek_section_get_rows (EEK_SECTION(priv->simple));
} }
static void static void
eek_clutter_section_real_set_columns (EekSection *self, eek_clutter_section_real_set_bounds (EekElement *self,
gint row, EekBounds *bounds)
gint columns)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv); EEK_ELEMENT_CLASS (eek_clutter_section_parent_class)->
eek_section_set_columns (EEK_SECTION(priv->simple), row, columns); set_bounds (self, bounds);
}
static gint g_return_if_fail (priv->actor);
eek_clutter_section_real_get_columns (EekSection *self,
gint row)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1); clutter_actor_set_position (priv->actor, bounds->x, bounds->y);
return eek_section_get_columns (EEK_SECTION(priv->simple), row); clutter_actor_set_size (priv->actor, bounds->width, bounds->height);
}
static void
eek_clutter_section_real_set_orientation (EekSection *self,
gint row,
EekOrientation orientation)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_section_set_orientation (EEK_SECTION(priv->simple), row, orientation);
}
static EekOrientation
eek_clutter_section_real_get_orientation (EekSection *self,
gint row)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_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 static void
@ -125,245 +73,106 @@ eek_clutter_section_real_set_angle (EekSection *self,
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv); EEK_SECTION_CLASS (eek_clutter_section_parent_class)->
eek_section_set_angle (EEK_SECTION(priv->simple), angle); set_angle (self, angle);
clutter_actor_set_rotation (CLUTTER_ACTOR(self),
g_return_if_fail (priv->actor);
clutter_actor_set_rotation (priv->actor,
CLUTTER_Z_AXIS, CLUTTER_Z_AXIS,
angle, eek_section_get_angle (self),
0, 0, 0, 0);
0,
0);
}
static gint
eek_clutter_section_real_get_angle (EekSection *self)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, 0);
eek_section_get_angle (EEK_SECTION(priv->simple));
} }
static void static void
eek_clutter_section_real_set_bounds (EekSection *self, pressed_event (EekKey *key, gpointer user_data)
EekBounds *bounds)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); g_signal_emit_by_name (user_data, "key-pressed", key);
g_return_if_fail (priv);
eek_section_set_bounds (EEK_SECTION(priv->simple), bounds);
clutter_actor_set_position (CLUTTER_ACTOR(self), bounds->x, bounds->y);
clutter_actor_set_size (CLUTTER_ACTOR(self), bounds->width, bounds->height);
} }
static void static void
eek_clutter_section_real_get_bounds (EekSection *self, released_event (EekKey *key, gpointer user_data)
EekBounds *bounds)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); g_signal_emit_by_name (user_data, "key-released", key);
g_return_if_fail (priv);
return eek_section_get_bounds (EEK_SECTION(priv->simple), bounds);
} }
static EekKey * static EekKey *
eek_clutter_section_real_create_key (EekSection *self, eek_clutter_section_real_create_key (EekSection *self,
const gchar *name,
guint keycode,
guint *keysyms,
gint num_groups,
gint num_levels,
gint column, gint column,
gint row, gint row)
EekOutline *outline,
EekBounds *bounds)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self);
EekKey *key; EekKey *key;
EekKeysymMatrix matrix; gint num_columns, num_rows;
gint columns, rows; EekOrientation orientation;
ClutterActor *texture; ClutterActor *actor;
g_return_val_if_fail (priv, NULL); num_rows = eek_section_get_n_rows (self);
g_return_val_if_fail (0 <= row && row < num_rows, NULL);
eek_section_get_row (self, row, &num_columns, &orientation);
g_return_val_if_fail (column < num_columns, 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_CLUTTER_KEY, key = g_object_new (EEK_TYPE_CLUTTER_KEY,
"name", name,
"keycode", keycode,
"keysyms", &matrix,
"column", column, "column", column,
"row", row, "row", row,
"outline", outline,
"bounds", bounds,
NULL); NULL);
g_return_val_if_fail (key, NULL); g_return_val_if_fail (key, NULL);
g_object_ref_sink (key);
texture = g_hash_table_lookup (priv->key_outline_texture_hash, outline); g_signal_connect (key, "pressed", G_CALLBACK(pressed_event), self);
if (texture == NULL) { g_signal_connect (key, "released", G_CALLBACK(released_event), self);
texture = eek_clutter_key_create_texture (EEK_CLUTTER_KEY(key));
g_hash_table_insert (priv->key_outline_texture_hash, outline, texture); EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
} else EEK_ELEMENT(key));
texture = clutter_clone_new (texture);
actor = eek_clutter_section_get_actor (EEK_CLUTTER_SECTION(self));
clutter_container_add_actor
(CLUTTER_CONTAINER(actor),
eek_clutter_key_get_actor (EEK_CLUTTER_KEY(key)));
eek_clutter_key_set_texture (EEK_CLUTTER_KEY(key), texture);
clutter_container_add_actor (CLUTTER_CONTAINER(self),
CLUTTER_ACTOR(key));
return key; return key;
} }
static void
eek_clutter_section_real_foreach_key (EekSection *self,
GFunc func,
gpointer user_data)
{
EekClutterCallbackData data;
g_return_if_fail (EEK_IS_CLUTTER_SECTION(self));
data.func = func;
data.user_data = user_data;
clutter_container_foreach (CLUTTER_CONTAINER(self),
eek_clutter_callback,
&data);
}
static void
eek_section_iface_init (EekSectionIface *iface)
{
iface->set_rows = eek_clutter_section_real_set_rows;
iface->get_rows = eek_clutter_section_real_get_rows;
iface->set_columns = eek_clutter_section_real_set_columns;
iface->get_columns = eek_clutter_section_real_get_columns;
iface->set_orientation = eek_clutter_section_real_set_orientation;
iface->get_orientation = eek_clutter_section_real_get_orientation;
iface->set_angle = eek_clutter_section_real_set_angle;
iface->get_angle = eek_clutter_section_real_get_angle;
iface->set_bounds = eek_clutter_section_real_set_bounds;
iface->get_bounds = eek_clutter_section_real_get_bounds;
iface->create_key = eek_clutter_section_real_create_key;
iface->foreach_key = eek_clutter_section_real_foreach_key;
}
static void
eek_clutter_section_dispose (GObject *object)
{
clutter_group_remove_all (CLUTTER_GROUP(object));
G_OBJECT_CLASS (eek_clutter_section_parent_class)->dispose (object);
}
static void static void
eek_clutter_section_finalize (GObject *object) eek_clutter_section_finalize (GObject *object)
{ {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object);
g_object_unref (priv->simple); if (priv->actor) {
clutter_group_remove_all (CLUTTER_GROUP(priv->actor));
g_object_unref (priv->actor);
}
G_OBJECT_CLASS (eek_clutter_section_parent_class)->finalize (object); G_OBJECT_CLASS (eek_clutter_section_parent_class)->finalize (object);
} }
static void
eek_clutter_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_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_clutter_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekClutterSectionPrivate *priv = EEK_CLUTTER_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_clutter_section_paint (ClutterActor *self)
{
ClutterGeometry geom;
CLUTTER_ACTOR_CLASS (eek_clutter_section_parent_class)->paint (self);
//clutter_actor_get_allocation_geometry (self, &geom);
//cogl_set_source_color4ub (0x80, 0x00, 0x00, 0xff);
//cogl_rectangle (0, 0, geom.width, geom.height);
}
static void static void
eek_clutter_section_class_init (EekClutterSectionClass *klass) eek_clutter_section_class_init (EekClutterSectionClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); EekElementClass *element_class = EEK_ELEMENT_CLASS (klass);
GParamSpec *pspec; EekSectionClass *section_class = EEK_SECTION_CLASS (klass);
g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate)); g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate));
gobject_class->set_property = eek_clutter_section_set_property; section_class->set_angle = eek_clutter_section_real_set_angle;
gobject_class->get_property = eek_clutter_section_get_property; section_class->create_key = eek_clutter_section_real_create_key;
element_class->set_name = eek_clutter_section_real_set_name;
element_class->set_bounds = eek_clutter_section_real_set_bounds;
gobject_class->finalize = eek_clutter_section_finalize; gobject_class->finalize = eek_clutter_section_finalize;
gobject_class->dispose = eek_clutter_section_dispose;
actor_class->paint = eek_clutter_section_paint;
g_object_class_override_property (gobject_class,
PROP_ANGLE,
"angle");
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
} }
static void static void
eek_clutter_section_init (EekClutterSection *self) eek_clutter_section_init (EekClutterSection *self)
{ {
EekClutterSectionPrivate *priv; EekClutterSectionPrivate *priv;
priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self); priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self);
priv->simple = g_object_new (EEK_TYPE_SIMPLE_SECTION, NULL); priv->actor = NULL;
priv->key_outline_texture_hash = }
g_hash_table_new_full (g_direct_hash,
g_direct_equal, ClutterActor *
NULL, eek_clutter_section_get_actor (EekClutterSection *section)
g_free); {
EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(section);
if (!priv->actor)
priv->actor = clutter_group_new ();
return priv->actor;
} }

View File

@ -38,19 +38,19 @@ typedef struct _EekClutterSectionPrivate EekClutterSectionPrivate;
struct _EekClutterSection struct _EekClutterSection
{ {
/*< private >*/ /*< private >*/
ClutterGroup parent; EekSection parent;
/*< private >*/
EekClutterSectionPrivate *priv; EekClutterSectionPrivate *priv;
}; };
struct _EekClutterSectionClass struct _EekClutterSectionClass
{ {
/*< private >*/ /*< private >*/
ClutterGroupClass parent_class; EekSectionClass parent_class;
}; };
GType eek_clutter_section_get_type (void) G_GNUC_CONST; GType eek_clutter_section_get_type (void) G_GNUC_CONST;
ClutterActor *eek_clutter_section_get_actor (EekClutterSection *section);
G_END_DECLS G_END_DECLS
#endif /* EEK_CLUTTER_SECTION_H */ #endif /* EEK_CLUTTER_SECTION_H */

157
eek/eek-container.c Normal file
View File

@ -0,0 +1,157 @@
/*
* 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-container
* @short_description: Base class of a keyboard container
*
* The #EekContainerClass class represents a keyboard container, which
* shall be used to implement #EekKeyboard and #EekSection.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-container.h"
enum {
CHILD_ADDED,
CHILD_REMOVED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_ABSTRACT_TYPE (EekContainer, eek_container, EEK_TYPE_ELEMENT);
#define EEK_CONTAINER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CONTAINER, EekContainerPrivate))
struct _EekContainerPrivate
{
GSList *children;
};
static void
eek_container_real_add_child (EekContainer *self,
EekElement *child)
{
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
g_return_if_fail (EEK_IS_ELEMENT(child));
g_object_ref (child);
priv->children = g_slist_prepend (priv->children, child);
}
static void
eek_container_real_remove_child (EekContainer *self,
EekElement *child)
{
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
GSList *head;
g_return_if_fail (EEK_IS_ELEMENT(child));
head = g_slist_find (priv->children, child);
g_return_if_fail (head);
g_object_unref (child);
priv->children = g_slist_remove_link (priv->children, head);
}
static void
eek_container_real_foreach_child (EekContainer *self,
EekCallback callback,
gpointer user_data)
{
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
GSList *head;
for (head = priv->children; head; head = g_slist_next (head))
(*callback) (EEK_ELEMENT(head->data), user_data);
}
static void
eek_container_finalize (GObject *object)
{
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object);
GSList *head;
for (head = priv->children; head; head = g_slist_next (head))
g_object_unref (head->data);
g_slist_free (priv->children);
G_OBJECT_CLASS(eek_container_parent_class)->finalize (object);
}
static void
eek_container_class_init (EekContainerClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (gobject_class,
sizeof (EekContainerPrivate));
klass->add_child = eek_container_real_add_child;
klass->remove_child = eek_container_real_remove_child;
klass->foreach_child = eek_container_real_foreach_child;
gobject_class->finalize = eek_container_finalize;
signals[CHILD_ADDED] =
g_signal_new ("child-added",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekContainerClass, child_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
EEK_TYPE_ELEMENT);
signals[CHILD_REMOVED] =
g_signal_new ("child-removed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekContainerClass, child_removed),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
EEK_TYPE_ELEMENT);
}
static void
eek_container_init (EekContainer *self)
{
EekContainerPrivate *priv;
priv = self->priv = EEK_CONTAINER_GET_PRIVATE(self);
priv->children = NULL;
}
void
eek_container_foreach_child (EekContainer *container,
EekCallback callback,
gpointer user_data)
{
g_return_if_fail (EEK_IS_CONTAINER(container));
EEK_CONTAINER_GET_CLASS(container)->foreach_child (container,
callback,
user_data);
}

79
eek/eek-container.h Normal file
View File

@ -0,0 +1,79 @@
/*
* 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_CONTAINER_H
#define EEK_CONTAINER_H 1
#include "eek-element.h"
G_BEGIN_DECLS
#define EEK_TYPE_CONTAINER (eek_container_get_type())
#define EEK_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CONTAINER, EekContainer))
#define EEK_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CONTAINER, EekContainerClass))
#define EEK_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CONTAINER))
#define EEK_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CONTAINER))
#define EEK_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CONTAINER, EekContainerClass))
typedef struct _EekContainer EekContainer;
typedef struct _EekContainerClass EekContainerClass;
typedef struct _EekContainerPrivate EekContainerPrivate;
typedef void (*EekCallback) (EekElement *element, gpointer user_data);
struct _EekContainer
{
/*< private >*/
EekElement parent;
/*< public >*/
EekContainerPrivate *priv;
};
struct _EekContainerClass
{
/*< private >*/
EekElementClass parent_class;
void (* add_child) (EekContainer *self,
EekElement *element);
void (* remove_child) (EekContainer *self,
EekElement *element);
/*< public >*/
void (* foreach_child) (EekContainer *self,
EekCallback callback,
gpointer user_data);
/* signals */
void (* child_added) (EekContainer *self,
EekElement *element);
void (* child_removed) (EekContainer *self,
EekElement *element);
};
GType eek_container_get_type (void) G_GNUC_CONST;
void eek_container_foreach_child (EekContainer *self,
EekCallback callback,
gpointer user_data);
G_END_DECLS
#endif /* EEK_CONTAINER_H */

235
eek/eek-element.c Normal file
View File

@ -0,0 +1,235 @@
/*
* 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-element
* @short_description: Base class of a keyboard element
*
* The #EekElementClass class represents a keyboard element, which
* shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
*/
#include <string.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-element.h"
enum {
PROP_0,
PROP_NAME,
PROP_BOUNDS,
PROP_LAST
};
G_DEFINE_ABSTRACT_TYPE (EekElement, eek_element, G_TYPE_INITIALLY_UNOWNED);
#define EEK_ELEMENT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_ELEMENT, EekElementPrivate))
struct _EekElementPrivate
{
gchar *name;
EekBounds bounds;
};
static void
eek_element_real_set_name (EekElement *self,
const gchar *name)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
priv->name = g_strdup (name);
g_object_notify (G_OBJECT(self), "name");
}
static G_CONST_RETURN gchar *
eek_element_real_get_name (EekElement *self)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
return priv->name;
}
static void
eek_element_real_set_bounds (EekElement *self,
EekBounds *bounds)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
priv->bounds = *bounds;
}
static void
eek_element_real_get_bounds (EekElement *self,
EekBounds *bounds)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
g_return_if_fail (bounds);
*bounds = priv->bounds;
g_object_notify (G_OBJECT(self), "bounds");
}
static void
eek_element_finalize (GObject *object)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(object);
g_free (priv->name);
}
static void
eek_element_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
g_return_if_fail (EEK_IS_ELEMENT(object));
switch (prop_id) {
case PROP_NAME:
eek_element_set_name (EEK_ELEMENT(object),
g_value_get_string (value));
break;
case PROP_BOUNDS:
eek_element_set_bounds (EEK_ELEMENT(object),
g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_element_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekBounds bounds;
g_return_if_fail (EEK_IS_ELEMENT(object));
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, eek_element_get_name (EEK_ELEMENT(object)));
break;
case PROP_BOUNDS:
eek_element_get_bounds (EEK_ELEMENT(object), &bounds);
g_value_set_boxed (value, &bounds);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_element_class_init (EekElementClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class,
sizeof (EekElementPrivate));
klass->set_name = eek_element_real_set_name;
klass->get_name = eek_element_real_get_name;
klass->set_bounds = eek_element_real_set_bounds;
klass->get_bounds = eek_element_real_get_bounds;
gobject_class->set_property = eek_element_set_property;
gobject_class->get_property = eek_element_get_property;
gobject_class->finalize = eek_element_finalize;
/**
* EekElement:name:
*
* The name of #EekElement.
*/
pspec = g_param_spec_string ("name",
"Name",
"Name",
NULL,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_NAME,
pspec);
/**
* EekElement:bounds:
*
* The bounding box of #EekElement.
*/
pspec = g_param_spec_boxed ("bounds",
"Bounds",
"Bounding box of the element",
EEK_TYPE_BOUNDS,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_BOUNDS,
pspec);
}
static void
eek_element_init (EekElement *self)
{
EekElementPrivate *priv;
priv = self->priv = EEK_ELEMENT_GET_PRIVATE(self);
priv->name = NULL;
memset (&priv->bounds, 0, sizeof priv->bounds);
}
void
eek_element_set_name (EekElement *element,
const gchar *name)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
EEK_ELEMENT_GET_CLASS(element)->set_name (element, name);
}
G_CONST_RETURN gchar *
eek_element_get_name (EekElement *element)
{
g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
return EEK_ELEMENT_GET_CLASS(element)->get_name (element);
}
void
eek_element_set_bounds (EekElement *element,
EekBounds *bounds)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
EEK_ELEMENT_GET_CLASS(element)->set_bounds (element, bounds);
}
void
eek_element_get_bounds (EekElement *element,
EekBounds *bounds)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
EEK_ELEMENT_GET_CLASS(element)->get_bounds (element, bounds);
}

77
eek/eek-element.h Normal file
View File

@ -0,0 +1,77 @@
/*
* 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_ELEMENT_H
#define EEK_ELEMENT_H 1
#include <glib-object.h>
#include "eek-types.h"
G_BEGIN_DECLS
#define EEK_TYPE_ELEMENT (eek_element_get_type())
#define EEK_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_ELEMENT, EekElement))
#define EEK_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_ELEMENT, EekElementClass))
#define EEK_IS_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_ELEMENT))
#define EEK_IS_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_ELEMENT))
#define EEK_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_ELEMENT, EekElementClass))
typedef struct _EekElement EekElement;
typedef struct _EekElementClass EekElementClass;
typedef struct _EekElementPrivate EekElementPrivate;
struct _EekElement
{
/*< private >*/
GInitiallyUnowned parent;
EekElementPrivate *priv;
};
struct _EekElementClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
void (* set_name) (EekElement *element,
const gchar *name);
G_CONST_RETURN gchar *(* get_name) (EekElement *element);
void (* set_bounds) (EekElement *element,
EekBounds *bounds);
void (* get_bounds) (EekElement *element,
EekBounds *bounds);
};
GType eek_element_get_type (void) G_GNUC_CONST;
void eek_element_set_name (EekElement *element,
const gchar *name);
G_CONST_RETURN gchar *eek_element_get_name (EekElement *element);
void eek_element_set_bounds (EekElement *element,
EekBounds *bounds);
void eek_element_get_bounds (EekElement *element,
EekBounds *bounds);
G_END_DECLS
#endif /* EEK_ELEMENT_H */

View File

@ -1,350 +0,0 @@
/*
* 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_KEYCODE,
PROP_KEYSYMS,
PROP_COLUMN,
PROP_ROW,
PROP_OUTLINE,
PROP_BOUNDS,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST
};
static void eek_key_iface_init (EekKeyIface *iface);
G_DEFINE_TYPE_WITH_CODE (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 guint
eek_gtk_key_real_get_keycode (EekKey *self)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, EEK_INVALID_KEYCODE);
return eek_key_get_keycode (EEK_KEY(priv->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);
if (groups > 0 && levels > 0)
eek_key_set_keysym_index (EEK_KEY(self), 0, 0);
}
static void
eek_gtk_key_real_get_keysyms (EekKey *self,
guint **keysyms,
gint *groups,
gint *levels)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
eek_key_get_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels);
}
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->get_keycode = eek_gtk_key_real_get_keycode;
iface->set_keysyms = eek_gtk_key_real_set_keysyms;
iface->get_keysyms = eek_gtk_key_real_get_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)
{
G_OBJECT_CLASS (eek_gtk_key_parent_class)->dispose (object);
}
static void
eek_gtk_key_finalize (GObject *object)
{
EekGtkKeyPrivate *priv = EEK_GTK_KEY_GET_PRIVATE(object);
g_object_unref (priv->simple);
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_KEYCODE:
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_KEYCODE:
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_KEYCODE,
"keycode");
g_object_class_override_property (gobject_class,
PROP_KEYSYMS,
"keysyms");
g_object_class_override_property (gobject_class,
PROP_COLUMN,
"column");
g_object_class_override_property (gobject_class,
PROP_ROW,
"row");
g_object_class_override_property (gobject_class,
PROP_OUTLINE,
"outline");
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
g_object_class_override_property (gobject_class,
PROP_GROUP,
"group");
g_object_class_override_property (gobject_class,
PROP_LEVEL,
"level");
}
static void
eek_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);
}

View File

@ -1,56 +0,0 @@
/*
* 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_GTK_KEY_H
#define EEK_GTK_KEY_H 1
#include <gtk/gtk.h>
#include "eek-key.h"
G_BEGIN_DECLS
#define EEK_TYPE_GTK_KEY (eek_gtk_key_get_type())
#define EEK_GTK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_KEY, EekGtkKey))
#define EEK_GTK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_KEY, EekGtkKeyClass))
#define EEK_IS_GTK_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_KEY))
#define EEK_IS_GTK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_KEY))
#define EEK_GTK_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_KEY, EekGtkKeyClass))
typedef struct _EekGtkKey EekGtkKey;
typedef struct _EekGtkKeyClass EekGtkKeyClass;
typedef struct _EekGtkKeyPrivate EekGtkKeyPrivate;
struct _EekGtkKey
{
/*< private >*/
GtkButton parent;
/*< private >*/
EekGtkKeyPrivate *priv;
};
struct _EekGtkKeyClass
{
/*< private >*/
GtkButtonClass parent_class;
};
GType eek_gtk_key_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* EEK_GTK_KEY_H */

View File

@ -1,298 +0,0 @@
/*
* 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)
{
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
}
static void
eek_gtk_keyboard_finalize (GObject *object)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
g_object_unref (priv->simple);
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);
}

View File

@ -1,57 +0,0 @@
/*
* 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_GTK_KEYBOARD_H
#define EEK_GTK_KEYBOARD_H 1
#include "eek-gtk-section.h"
#include "eek-keyboard.h"
G_BEGIN_DECLS
#define EEK_TYPE_GTK_KEYBOARD (eek_gtk_keyboard_get_type())
#define EEK_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_KEYBOARD, EekKeyboard))
#define EEK_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
#define EEK_IS_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_KEYBOARD))
#define EEK_IS_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_KEYBOARD))
#define EEK_GTK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
typedef struct _EekGtkKeyboard EekGtkKeyboard;
typedef struct _EekGtkKeyboardClass EekGtkKeyboardClass;
typedef struct _EekGtkKeyboardPrivate EekGtkKeyboardPrivate;
struct _EekGtkKeyboard
{
/*< private >*/
GtkVBox parent;
EekGtkKeyboardPrivate *priv;
};
struct _EekGtkKeyboardClass
{
/*< private >*/
GtkVBoxClass parent_class;
};
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
EekKeyboard *eek_gtk_keyboard_new (void);
G_END_DECLS
#endif /* EEK_GTK_KEYBOARD_H */

View File

@ -1,31 +0,0 @@
/*
* 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);
}

View File

@ -1,34 +0,0 @@
/*
* 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_GTK_PRIVATE_H
#define EEK_GTK_PRIVATE_H 1
#include <glib/gtypes.h>
#include <gtk/gtk.h>
struct _EekGtkCallbackData {
GFunc func;
gpointer user_data;
};
typedef struct _EekGtkCallbackData EekGtkCallbackData;
void eek_gtk_callback (GtkWidget *actor, gpointer user_data);
#endif /* EEK_GTK_PRIVATE_H */

View File

@ -1,345 +0,0 @@
/*
* 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 keycode,
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,
"keycode", keycode,
"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)
{
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_unref (priv->simple);
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;
}

View File

@ -1,56 +0,0 @@
/*
* 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_GTK_SECTION_H
#define EEK_GTK_SECTION_H 1
#include "eek-gtk-key.h"
#include "eek-section.h"
G_BEGIN_DECLS
#define EEK_TYPE_GTK_SECTION (eek_gtk_section_get_type())
#define EEK_GTK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_SECTION, EekGtkSection))
#define EEK_GTK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_SECTION, EekGtkSectionClass))
#define EEK_IS_GTK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_SECTION))
#define EEK_IS_GTK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_SECTION))
#define EEK_GTK_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_SECTION, EekGtkSectionClass))
typedef struct _EekGtkSection EekGtkSection;
typedef struct _EekGtkSectionClass EekGtkSectionClass;
typedef struct _EekGtkSectionPrivate EekGtkSectionPrivate;
struct _EekGtkSection
{
/*< private >*/
GtkVBox parent;
/*< private >*/
EekGtkSectionPrivate *priv;
};
struct _EekGtkSectionClass
{
/*< private >*/
GtkVBoxClass parent_class;
};
GType eek_gtk_section_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* EEK_GTK_SECTION_H */

View File

@ -1,26 +0,0 @@
/*
* 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_GTK_H
#define EEK_GTK_H 1
#include "eek.h"
#include "eek-gtk-keyboard.h"
#endif /* EEK_GTK_H */

View File

@ -1,30 +0,0 @@
# 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

@ -20,39 +20,339 @@
/** /**
* SECTION:eek-key * SECTION:eek-key
* @short_description: Base interface of a key * @short_description: Base class of a key
* @see_also: #EekSection
* *
* The #EekKeyIface interface represents a key, which is parented to * The #EekKeyClass class represents a key.
* #EekSectionIface.
*/ */
#include <string.h>
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-key.h" #include "eek-key.h"
#include "eek-keysym.h" #include "eek-keysym.h"
static void enum {
eek_key_base_init (gpointer g_iface) PROP_0,
{ PROP_KEYCODE,
static gboolean is_initialized = FALSE; PROP_KEYSYMS,
PROP_COLUMN,
PROP_ROW,
PROP_OUTLINE,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST
};
if (!is_initialized) { enum {
PRESSED,
RELEASED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT);
#define EEK_KEY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate))
struct _EekKeyPrivate
{
guint keycode;
EekKeysymMatrix keysyms;
gint column;
gint row;
EekOutline *outline;
gint group;
gint level;
};
static void
eek_key_real_set_keycode (EekKey *self, guint keycode)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
priv->keycode = keycode;
}
static guint
eek_key_real_get_keycode (EekKey *self)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
return priv->keycode;
}
static void
eek_key_real_set_keysyms (EekKey *self,
guint *keysyms,
gint num_groups,
gint num_levels)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
gint num_keysyms = num_groups * num_levels;
if (num_keysyms > 0) {
priv->keysyms.data =
g_slice_alloc (num_keysyms * sizeof(guint));
memcpy (priv->keysyms.data, keysyms,
num_keysyms * sizeof(guint));
}
priv->keysyms.num_groups = num_groups;
priv->keysyms.num_levels = num_levels;
#if DEBUG
{
const gchar *name;
gint i;
name = eek_element_get_name (EEK_ELEMENT(self));
fprintf (stderr, "%s: ", name);
for (i = 0; i < priv->keysyms.num_groups * priv->keysyms.num_levels; i++)
fprintf (stderr, "\"%s\" ", eek_keysym_to_string (priv->keysyms.data[i]));
fprintf (stderr, "\n");
}
#endif
}
static void
eek_key_real_get_keysyms (EekKey *self,
guint **keysyms,
gint *num_groups,
gint *num_levels)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
if (num_groups)
*num_groups = priv->keysyms.num_groups;
if (num_levels)
*num_levels = priv->keysyms.num_levels;
if (keysyms && num_keysyms > 0) {
*keysyms = g_slice_alloc (num_keysyms * sizeof(guint));
memcpy (*keysyms, priv->keysyms.data, num_keysyms * sizeof(guint));
}
}
static guint
eek_key_real_get_keysym (EekKey *self)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
if (num_keysyms == 0)
return EEK_INVALID_KEYSYM;
return priv->keysyms.data[priv->group * priv->keysyms.num_levels +
priv->level];
}
static void
eek_key_real_set_index (EekKey *self,
gint column,
gint row)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
g_return_if_fail (0 <= column);
g_return_if_fail (0 <= row);
priv->column = column;
priv->row = row;
}
static void
eek_key_real_get_index (EekKey *self,
gint *column,
gint *row)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
if (column)
*column = priv->column;
if (row)
*row = priv->row;
}
static void
eek_key_real_set_outline (EekKey *self, EekOutline *outline)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
priv->outline = outline;
}
static EekOutline *
eek_key_real_get_outline (EekKey *self)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
return priv->outline;
}
static void
eek_key_real_set_keysym_index (EekKey *self,
gint group,
gint level)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
g_return_if_fail (0 <= group);
if (group >= priv->keysyms.num_groups)
group = 0;
g_return_if_fail (0 <= level && level < priv->keysyms.num_levels);
priv->group = group;
priv->level = level;
}
static void
eek_key_real_get_keysym_index (EekKey *self,
gint *group,
gint *level)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
g_return_if_fail (group);
g_return_if_fail (level);
if (group)
*group = priv->group;
if (level)
*level = priv->level;
}
static void
eek_key_finalize (GObject *object)
{
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object);
gint num_keysyms = priv->keysyms.num_groups * priv->keysyms.num_levels;
g_slice_free1 (num_keysyms * sizeof (guint), priv->keysyms.data);
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
}
static void
eek_key_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekKeysymMatrix *matrix;
gint column, row;
gint group, level;
g_return_if_fail (EEK_IS_KEY(object));
switch (prop_id) {
case PROP_KEYCODE:
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
break;
case PROP_KEYSYMS:
matrix = g_value_get_boxed (value);
eek_key_set_keysyms (EEK_KEY(object),
matrix->data,
matrix->num_groups,
matrix->num_levels);
break;
case PROP_COLUMN:
eek_key_get_index (EEK_KEY(object), &column, &row);
eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row);
break;
case PROP_ROW:
eek_key_get_index (EEK_KEY(object), &column, &row);
eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
break;
case PROP_OUTLINE:
eek_key_set_outline (EEK_KEY(object), g_value_get_pointer (value));
break;
case PROP_GROUP:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
eek_key_set_keysym_index (EEK_KEY(object), g_value_get_int (value),
level);
break;
case PROP_LEVEL:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
eek_key_set_keysym_index (EEK_KEY(object), group,
g_value_get_int (value));
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_key_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekKeysymMatrix matrix;
gint column, row;
gint group, level;
g_return_if_fail (EEK_IS_KEY(object));
switch (prop_id) {
case PROP_KEYCODE:
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
break;
case PROP_KEYSYMS:
eek_key_get_keysyms (EEK_KEY(object), &matrix.data, &matrix.num_groups,
&matrix.num_levels);
g_value_set_boxed (value, &matrix);
break;
case PROP_COLUMN:
eek_key_get_index (EEK_KEY(object), &column, &row);
g_value_set_int (value, column);
break;
case PROP_ROW:
eek_key_get_index (EEK_KEY(object), &column, &row);
g_value_set_int (value, row);
break;
case PROP_OUTLINE:
g_value_set_pointer (value, eek_key_get_outline (EEK_KEY(object)));
break;
case PROP_GROUP:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
g_value_set_int (value, group);
break;
case PROP_LEVEL:
eek_key_get_keysym_index (EEK_KEY(object), &group, &level);
g_value_set_int (value, level);
break;
default:
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_key_class_init (EekKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
/** g_type_class_add_private (gobject_class,
* EekKey:name: sizeof (EekKeyPrivate));
*
* The name of #EekKey. klass->get_keycode = eek_key_real_get_keycode;
*/ klass->set_keycode = eek_key_real_set_keycode;
pspec = g_param_spec_string ("name", klass->set_keysyms = eek_key_real_set_keysyms;
"Name", klass->get_keysyms = eek_key_real_get_keysyms;
"Name", klass->get_keysym = eek_key_real_get_keysym;
NULL, klass->set_index = eek_key_real_set_index;
G_PARAM_READWRITE); klass->get_index = eek_key_real_get_index;
g_object_interface_install_property (g_iface, pspec); klass->set_outline = eek_key_real_set_outline;
klass->get_outline = eek_key_real_get_outline;
klass->set_keysym_index = eek_key_real_set_keysym_index;
klass->get_keysym_index = eek_key_real_get_keysym_index;
gobject_class->set_property = eek_key_set_property;
gobject_class->get_property = eek_key_get_property;
gobject_class->finalize = eek_key_finalize;
/** /**
* EekKey:keycode: * EekKey:keycode:
@ -64,7 +364,7 @@ eek_key_base_init (gpointer g_iface)
"Keycode of the key", "Keycode of the key",
0, G_MAXUINT, 0, 0, G_MAXUINT, 0,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
/** /**
* EekKey:keysyms: * EekKey:keysyms:
@ -76,7 +376,7 @@ eek_key_base_init (gpointer g_iface)
"Symbol matrix of the key", "Symbol matrix of the key",
EEK_TYPE_KEYSYM_MATRIX, EEK_TYPE_KEYSYM_MATRIX,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class, PROP_KEYSYMS, pspec);
/** /**
* EekKey:column: * EekKey:column:
@ -88,7 +388,7 @@ eek_key_base_init (gpointer g_iface)
"Column index of the key in section", "Column index of the key in section",
-1, G_MAXINT, -1, -1, G_MAXINT, -1,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
/** /**
* EekKey:row: * EekKey:row:
@ -100,7 +400,7 @@ eek_key_base_init (gpointer g_iface)
"Row index of the key in section", "Row index of the key in section",
-1, G_MAXINT, -1, -1, G_MAXINT, -1,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class, PROP_ROW, pspec);
/** /**
* EekKey:outline: * EekKey:outline:
@ -114,19 +414,7 @@ eek_key_base_init (gpointer g_iface)
"Outline", "Outline",
"Pointer to outline shape of the key", "Pointer to outline shape of the key",
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class, PROP_OUTLINE, pspec);
/**
* EekKey:bounds:
*
* The bounding box of #EekKey.
*/
pspec = g_param_spec_boxed ("bounds",
"Bounds",
"Bounding box of the key",
EEK_TYPE_BOUNDS,
G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
/** /**
* EekKey:group: * EekKey:group:
@ -138,7 +426,7 @@ eek_key_base_init (gpointer g_iface)
"Current group of the key", "Current group of the key",
0, 64, 0, 0, 64, 0,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class, PROP_GROUP, pspec);
/** /**
* EekKey:level: * EekKey:level:
@ -150,278 +438,131 @@ eek_key_base_init (gpointer g_iface)
"Current level of the key", "Current level of the key",
0, 3, 0, 0, 3, 0,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class, PROP_LEVEL, pspec);
is_initialized = TRUE; signals[PRESSED] =
} g_signal_new ("pressed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
0,
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,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
} }
GType static void
eek_key_get_type (void) eek_key_init (EekKey *self)
{ {
static GType iface_type = 0; EekKeyPrivate *priv;
if (iface_type == 0) { priv = self->priv = EEK_KEY_GET_PRIVATE(self);
static const GTypeInfo info = { priv->keycode = 0;
sizeof (EekKeyIface), memset (&priv->keysyms, 0, sizeof priv->keysyms);
eek_key_base_init, /* iface_base_init */ priv->column = priv->row = 0;
NULL /* iface_base_finalize */ priv->outline = NULL;
}; priv->group = priv->level = 0;
}
iface_type = g_type_register_static (G_TYPE_INTERFACE,
"EekKey", void
&info, eek_key_set_keycode (EekKey *key,
0); guint keycode)
} {
return iface_type; g_return_if_fail (EEK_IS_KEY (key));
EEK_KEY_GET_CLASS(key)->set_keycode (key, keycode);
} }
/**
* eek_key_get_keycode:
* @key: an #EekKey
*
* Get the keycode of @key.
*/
guint guint
eek_key_get_keycode (EekKey *key) eek_key_get_keycode (EekKey *key)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
return EEK_KEY_GET_CLASS(key)->get_keycode (key);
g_return_val_if_fail (iface, EEK_INVALID_KEYCODE);
g_return_val_if_fail (iface->get_keycode, EEK_INVALID_KEYCODE);
return (*iface->get_keycode) (key);
} }
/**
* eek_key_set_keysyms:
* @key: an #EekKey
* @keysyms: symbol matrix of @key
* @num_groups: the number of groups (rows) of @keysyms
* @num_levels: the number of levels (columns) of @keysyms
*
* Set the symbol matrix of @key to @keysyms. @keysyms is an array of
* symbols (unsigned int) and the length must match with @num_groups *
* @num_levels.
*/
void void
eek_key_set_keysyms (EekKey *key, eek_key_set_keysyms (EekKey *key,
guint *keysyms, guint *keysyms,
gint num_groups, gint num_groups,
gint num_levels) gint num_levels)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->set_keysyms (key, keysyms, num_groups, num_levels);
g_return_if_fail (iface);
g_return_if_fail (iface->set_keysyms);
(*iface->set_keysyms) (key, keysyms, num_groups, num_levels);
} }
/**
* eek_key_get_keysyms:
* @key: an #EekKey
* @keysyms: pointer where symbol matrix of @key will be stored
* @num_groups: pointer where the number of groups (rows) of @keysyms
* will be stored
* @num_levels: pointer where the number of levels (columns) of
* @keysyms will be stored
*
* Get the symbol matrix of @key to @keysyms. @keysyms is an array of
* symbols (unsigned int) and the length must match with @num_groups *
* @num_levels.
*/
void void
eek_key_get_keysyms (EekKey *key, eek_key_get_keysyms (EekKey *key,
guint **keysyms, guint **keysyms,
gint *num_groups, gint *num_groups,
gint *num_levels) gint *num_levels)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->get_keysyms (key, keysyms, num_groups, num_levels);
g_return_if_fail (iface);
g_return_if_fail (iface->get_keysyms);
(*iface->get_keysyms) (key, keysyms, num_groups, num_levels);
} }
/**
* eek_key_get_groups:
* @key: an #EekKey
*
* Get the number of groups (rows) of the symbol matrix of @key.
*/
gint
eek_key_get_groups (EekKey *key)
{
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
g_return_val_if_fail (iface, -1);
g_return_val_if_fail (iface->get_groups, -1);
return (*iface->get_groups) (key);
}
/**
* eek_key_get_keysym:
* @key: an #EekKey
*
* Get the current symbol of @key. It is depend on the current group
* and level, and the symbol matrix of @key. They are set through
* eek_key_set_keysym_index() and eek_key_set_keysyms(), respectively.
*/
guint guint
eek_key_get_keysym (EekKey *key) eek_key_get_keysym (EekKey *key)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_val_if_fail (EEK_IS_KEY(key), EEK_INVALID_KEYSYM);
return EEK_KEY_GET_CLASS(key)->get_keysym (key);
g_return_val_if_fail (iface, EEK_INVALID_KEYSYM);
g_return_val_if_fail (iface->get_keysym, EEK_INVALID_KEYSYM);
return (*iface->get_keysym) (key);
} }
/**
* eek_key_set_index:
* @key: an #EekKey
* @column: column index in the section
* @row: row index in the section
*
* Set column and row index of @key in the parent section.
*/
void void
eek_key_set_index (EekKey *key, eek_key_set_index (EekKey *key,
gint column, gint column,
gint row) gint row)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->set_index (key, column, row);
g_return_if_fail (iface);
g_return_if_fail (iface->set_index);
(*iface->set_index) (key, column, row);
} }
/**
* eek_key_get_index:
* @key: an #EekKey
* @column: a pointer to where column index in the section is stored
* @row: a pointer to where row index in the section is stored
*
* Get column and row index of @key in the parent section.
*/
void void
eek_key_get_index (EekKey *key, eek_key_get_index (EekKey *key,
gint *column, gint *column,
gint *row) gint *row)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->get_index (key, column, row);
g_return_if_fail (iface);
g_return_if_fail (iface->get_index);
return (*iface->get_index) (key, column, row);
} }
/**
* eek_key_set_outline:
* @key: an #EekKey
* @outline: a pointer to the outline shape of @key
*
* Set outline shape of @key.
*/
void void
eek_key_set_outline (EekKey *key, eek_key_set_outline (EekKey *key,
EekOutline *outline) EekOutline *outline)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->set_outline (key, outline);
g_return_if_fail (iface);
g_return_if_fail (iface->set_outline);
(*iface->set_outline) (key, outline);
} }
/**
* eek_key_get_outline:
* @key: an #EekKey
*
* Get outline shape of @key as a pointer.
*/
EekOutline * EekOutline *
eek_key_get_outline (EekKey *key) eek_key_get_outline (EekKey *key)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_val_if_fail (EEK_IS_KEY (key), NULL);
return EEK_KEY_GET_CLASS(key)->get_outline (key);
g_return_val_if_fail (iface, NULL);
g_return_val_if_fail (iface->get_outline, NULL);
return (*iface->get_outline) (key);
} }
/**
* eek_key_set_bounds:
* @key: an #EekKey
* @bounds: bounding box of @key
*
* Set the bounding box of @key to @bounds.
*/
void
eek_key_set_bounds (EekKey *key,
EekBounds *bounds)
{
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
g_return_if_fail (iface);
g_return_if_fail (iface->set_bounds);
(*iface->set_bounds) (key, bounds);
}
/**
* eek_key_get_bounds:
* @key: an #EekKey
* @bounds: the bounding box of @key
*
* Get the bounding box of @key.
*/
void
eek_key_get_bounds (EekKey *key,
EekBounds *bounds)
{
EekKeyIface *iface = EEK_KEY_GET_IFACE(key);
g_return_if_fail (iface);
g_return_if_fail (iface->get_bounds);
return (*iface->get_bounds) (key, bounds);
}
/**
* eek_key_set_keysym_index:
* @key: an #EekKey
* @group: row index of the symbol matrix #EekKey:keysyms
* @level: column index of the symbol matrix #EekKey:keysyms
*
* Select a cell of the symbol matrix of @key.
*/
void void
eek_key_set_keysym_index (EekKey *key, eek_key_set_keysym_index (EekKey *key,
gint group, gint group,
gint level) gint level)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->set_keysym_index (key, group, level);
g_return_if_fail (iface);
g_return_if_fail (iface->set_keysym_index);
(*iface->set_keysym_index) (key, group, level);
} }
/**
* eek_key_get_keysym_index:
* @key: an #EekKey
* @group: a pointer where row index of the symbol matrix #EekKey:keysyms
* will be stored
* @level: a pointer where column index of the symbol matrix
* #EekKey:keysyms will be stored
*
* Get the current cell position of the symbol matrix of @key.
*/
void void
eek_key_get_keysym_index (EekKey *key, gint *column, gint *row) eek_key_get_keysym_index (EekKey *key,
gint *group,
gint *level)
{ {
EekKeyIface *iface = EEK_KEY_GET_IFACE(key); g_return_if_fail (EEK_IS_KEY(key));
EEK_KEY_GET_CLASS(key)->get_keysym_index (key, group, level);
g_return_if_fail (iface);
g_return_if_fail (iface->get_keysym_index);
return (*iface->get_keysym_index) (key, column, row);
} }

View File

@ -21,24 +21,37 @@
#define EEK_KEY_H 1 #define EEK_KEY_H 1
#include <glib-object.h> #include <glib-object.h>
#include "eek-element.h"
#include "eek-types.h" #include "eek-types.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_KEY (eek_key_get_type()) #define EEK_TYPE_KEY (eek_key_get_type())
#define EEK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEY, EekKey)) #define EEK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEY, EekKey))
#define EEK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEY, EekKeyClass))
#define EEK_IS_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEY)) #define EEK_IS_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEY))
#define EEK_KEY_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_KEY, EekKeyIface)) #define EEK_IS_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEY))
#define EEK_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEY, EekKeyClass))
typedef struct _EekKeyIface EekKeyIface; typedef struct _EekKeyClass EekKeyClass;
typedef struct _EekKey EekKey; typedef struct _EekKeyPrivate EekKeyPrivate;
struct _EekKeyIface struct _EekKey
{ {
/*< private >*/ /*< private >*/
GTypeInterface g_iface; EekElement parent;
EekKeyPrivate *priv;
};
struct _EekKeyClass
{
/*< private >*/
EekElementClass parent_class;
/*< public >*/ /*< public >*/
void (* set_keycode) (EekKey *self,
guint keycode);
guint (* get_keycode) (EekKey *self); guint (* get_keycode) (EekKey *self);
void (* set_keysyms) (EekKey *self, void (* set_keysyms) (EekKey *self,
guint *keysyms, guint *keysyms,
@ -48,7 +61,6 @@ struct _EekKeyIface
guint **keysyms, guint **keysyms,
gint *num_groups, gint *num_groups,
gint *num_levels); gint *num_levels);
gint (* get_groups) (EekKey *self);
guint (* get_keysym) (EekKey *self); guint (* get_keysym) (EekKey *self);
void (* set_index) (EekKey *self, void (* set_index) (EekKey *self,
@ -61,10 +73,6 @@ struct _EekKeyIface
void (* set_outline) (EekKey *self, void (* set_outline) (EekKey *self,
EekOutline *outline); EekOutline *outline);
EekOutline *(* get_outline) (EekKey *self); EekOutline *(* get_outline) (EekKey *self);
void (* set_bounds) (EekKey *self,
EekBounds *bounds);
void (* get_bounds) (EekKey *self,
EekBounds *bounds);
void (* set_keysym_index) (EekKey *self, void (* set_keysym_index) (EekKey *self,
gint group, gint group,
@ -76,6 +84,8 @@ struct _EekKeyIface
GType eek_key_get_type (void) G_GNUC_CONST; GType eek_key_get_type (void) G_GNUC_CONST;
void eek_key_set_keycode (EekKey *key,
guint keycode);
guint eek_key_get_keycode (EekKey *key); guint eek_key_get_keycode (EekKey *key);
void eek_key_set_keysyms (EekKey *key, void eek_key_set_keysyms (EekKey *key,
guint *keysyms, guint *keysyms,
@ -85,7 +95,6 @@ void eek_key_get_keysyms (EekKey *key,
guint **keysyms, guint **keysyms,
gint *num_groups, gint *num_groups,
gint *num_levels); gint *num_levels);
gint eek_key_get_groups (EekKey *key);
guint eek_key_get_keysym (EekKey *key); guint eek_key_get_keysym (EekKey *key);
void eek_key_set_index (EekKey *key, void eek_key_set_index (EekKey *key,
@ -98,10 +107,6 @@ void eek_key_get_index (EekKey *key,
void eek_key_set_outline (EekKey *key, void eek_key_set_outline (EekKey *key,
EekOutline *outline); EekOutline *outline);
EekOutline *eek_key_get_outline (EekKey *key); EekOutline *eek_key_get_outline (EekKey *key);
void eek_key_set_bounds (EekKey *key,
EekBounds *bounds);
void eek_key_get_bounds (EekKey *key,
EekBounds *bounds);
void eek_key_set_keysym_index (EekKey *key, void eek_key_set_keysym_index (EekKey *key,
gint group, gint group,

View File

@ -20,14 +20,11 @@
/** /**
* SECTION:eek-keyboard * SECTION:eek-keyboard
* @short_description: Base interface of a keyboard * @short_description: Base class of a keyboard
* @see_also: #EekSection * @see_also: #EekSection
* *
* The #EekKeyboardIface interface represents a keyboard, which * The #EekKeyboardClass class represents a keyboard, which consists
* consists of one or more sections of the #EekSectionIface interface. * of one or more sections of the #EekSectionClass class.
*
* #EekKeyboardIface follows the Builder pattern and is responsible
* for creation of sections.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -35,85 +32,270 @@
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-keyboard.h" #include "eek-keyboard.h"
#include "eek-section.h"
#include "eek-key.h"
static void enum {
eek_keyboard_base_init (gpointer g_iface) PROP_0,
{ PROP_GROUP,
static gboolean is_initialized = FALSE; PROP_LEVEL,
PROP_LAST
if (!is_initialized) {
GParamSpec *pspec;
/**
* EekKeyboard:bounds:
*
* The bounding box of #EekKeyboard.
*/
pspec = g_param_spec_boxed ("bounds",
"Bounds",
"Bounding box of the keyboard",
EEK_TYPE_BOUNDS,
G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
is_initialized = TRUE;
}
}
GType
eek_keyboard_get_type (void)
{
static GType iface_type = 0;
if (iface_type == 0) {
static const GTypeInfo info = {
sizeof (EekKeyboardIface),
eek_keyboard_base_init,
NULL
}; };
iface_type = g_type_register_static (G_TYPE_INTERFACE, enum {
"EekKeyboard", KEY_PRESSED,
&info, KEY_RELEASED,
0); LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
#define EEK_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate))
struct _EekKeyboardPrivate
{
gint group;
gint level;
};
struct keysym_index {
gint group;
gint level;
};
static void
set_keysym_index_for_key (EekElement *element,
gpointer user_data)
{
struct keysym_index *ki;
g_return_if_fail (EEK_IS_KEY(element));
ki = user_data;
eek_key_set_keysym_index (EEK_KEY(element), ki->group, ki->level);
} }
return iface_type;
static void
set_keysym_index_for_section (EekElement *element,
gpointer user_data)
{
eek_container_foreach_child (EEK_CONTAINER(element),
set_keysym_index_for_key,
user_data);
} }
static void
eek_keyboard_real_set_keysym_index (EekKeyboard *self,
gint group,
gint level)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
struct keysym_index ki;
ki.group = priv->group = group;
ki.level = priv->level = level;
eek_container_foreach_child (EEK_CONTAINER(self),
set_keysym_index_for_section,
&ki);
}
void
eek_keyboard_real_get_keysym_index (EekKeyboard *self,
gint *group,
gint *level)
{
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (group || level);
if (group)
*group = priv->group;
if (level)
*level = priv->level;
}
static void
key_pressed_event (EekSection *section,
EekKey *key,
EekKeyboard *keyboard)
{
g_signal_emit_by_name (keyboard, "key-pressed", key);
}
static void
key_released_event (EekSection *section,
EekKey *key,
EekKeyboard *keyboard)
{
g_signal_emit_by_name (keyboard, "key-released", key);
}
static EekSection *
eek_keyboard_real_create_section (EekKeyboard *self)
{
EekSection *section;
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);
g_signal_connect (section, "key-released", G_CALLBACK(key_released_event), self);
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(section));
return section;
}
static void
eek_keyboard_real_set_layout (EekKeyboard *keyboard,
EekLayout *layout)
{
g_return_if_fail (EEK_IS_LAYOUT(layout));
EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard);
if (g_object_is_floating (layout))
g_object_unref (layout);
}
static void
eek_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
gint group, level;
g_return_if_fail (EEK_IS_KEYBOARD(object));
switch (prop_id) {
case PROP_GROUP:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level);
eek_keyboard_set_keysym_index (EEK_KEYBOARD(object),
g_value_get_int (value),
level);
break;
case PROP_LEVEL:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level);
eek_keyboard_set_keysym_index (EEK_KEYBOARD(object),
group,
g_value_get_int (value));
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_keyboard_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
gint group, level;
g_return_if_fail (EEK_IS_KEYBOARD(object));
switch (prop_id) {
case PROP_GROUP:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &group, &level);
g_value_set_int (value, group);
break;
case PROP_LEVEL:
eek_keyboard_get_keysym_index (EEK_KEYBOARD(object), &level, &level);
g_value_set_int (value, level);
break;
default:
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_keyboard_class_init (EekKeyboardClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class,
sizeof (EekKeyboardPrivate));
klass->set_keysym_index = eek_keyboard_real_set_keysym_index;
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;
gobject_class->get_property = eek_keyboard_get_property;
gobject_class->set_property = eek_keyboard_set_property;
/** /**
* eek_keyboard_set_bounds: * EekKeyboard:group:
* @keyboard: an #EekKeyboard
* @bounds: bounding box of the keyboard
* *
* Set the bounding box of @keyboard to @bounds. * The group (row) index of symbol matrix of #EekKeyboard.
*/ */
void pspec = g_param_spec_int ("group",
eek_keyboard_set_bounds (EekKeyboard *keyboard, "Group",
EekBounds *bounds) "Group index of symbol matrix of the keyboard",
{ 0, G_MAXINT, 0,
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
g_return_if_fail (iface); PROP_GROUP,
g_return_if_fail (iface->set_bounds); pspec);
(*iface->set_bounds) (keyboard, bounds);
}
/** /**
* eek_keyboard_get_bounds: * EekKeyboard:level:
* @keyboard: an #EekKeyboard
* @bounds: the bounding box of @keyboard
* *
* Get the bounding box of @keyboard. * The level (row) index of symbol matrix of #EekKeyboard.
*/ */
void pspec = g_param_spec_int ("level",
eek_keyboard_get_bounds (EekKeyboard *keyboard, "Level",
EekBounds *bounds) "Level index of symbol matrix of the keyboard",
{ 0, G_MAXINT, 0,
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_LEVEL,
pspec);
g_return_if_fail (iface); signals[KEY_PRESSED] =
g_return_if_fail (iface->get_bounds); g_signal_new ("key-pressed",
return (*iface->get_bounds) (keyboard, bounds); G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
EEK_TYPE_KEY);
signals[KEY_RELEASED] =
g_signal_new ("key-released",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
EEK_TYPE_KEY);
}
static void
eek_keyboard_init (EekKeyboard *self)
{
EekKeyboardPrivate *priv;
priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
priv->group = priv->level = 0;
} }
/** /**
@ -125,19 +307,16 @@ eek_keyboard_get_bounds (EekKeyboard *keyboard,
* Select a cell of the symbol matrix of each key on @keyboard. * Select a cell of the symbol matrix of each key on @keyboard.
*/ */
void void
eek_keyboard_set_keysym_index (EekKeyboard *self, eek_keyboard_set_keysym_index (EekKeyboard *keyboard,
gint group, gint group,
gint level) gint level)
{ {
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(self); g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
EEK_KEYBOARD_GET_CLASS(keyboard)->set_keysym_index (keyboard, group, level);
g_return_if_fail (iface);
g_return_if_fail (iface->set_keysym_index);
(*iface->set_keysym_index) (self, group, level);
} }
/** /**
* eek_keyboard_set_keysym_index: * eek_keyboard_get_keysym_index:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
* @group: a pointer where row index of the symbol matrix of keys on * @group: a pointer where row index of the symbol matrix of keys on
* @keyboard will be stored * @keyboard will be stored
@ -147,57 +326,29 @@ eek_keyboard_set_keysym_index (EekKeyboard *self,
* Get the current cell position of the symbol matrix of each key on @keyboard. * Get the current cell position of the symbol matrix of each key on @keyboard.
*/ */
void void
eek_keyboard_get_keysym_index (EekKeyboard *self, eek_keyboard_get_keysym_index (EekKeyboard *keyboard,
gint *group, gint *group,
gint *level) gint *level)
{ {
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(self); g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
EEK_KEYBOARD_GET_CLASS(keyboard)->get_keysym_index (keyboard, group, level);
g_return_if_fail (iface);
g_return_if_fail (iface->get_keysym_index);
return (*iface->get_keysym_index) (self, group, level);
} }
/** /**
* eek_keyboard_create_section: * eek_keyboard_create_section:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
* @name: name of the section * @name: name of the section
* @angle: rotation angle of the section
* @bounds: bounding box of the section * @bounds: bounding box of the section
* *
* Create an #EekSection instance and attach it to @keyboard. * Create an #EekSection instance and attach it to @keyboard.
*/ */
EekSection * EekSection *
eek_keyboard_create_section (EekKeyboard *keyboard, eek_keyboard_create_section (EekKeyboard *keyboard)
const gchar *name,
gint angle,
EekBounds *bounds)
{ {
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); EekSection *section;
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
g_return_val_if_fail (iface, NULL); section = EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
g_return_val_if_fail (iface->create_section, NULL); return section;
return (*iface->create_section) (keyboard, name, angle, bounds);
}
/**
* eek_keyboard_foreach_section:
* @keyboard: an #EekKeyboard
* @func: a callback of #GFunc
* @user_data: a pointer to an object passed to @func
*
* Iterate over @keyboard's children list.
*/
void
eek_keyboard_foreach_section (EekKeyboard *keyboard,
GFunc func,
gpointer user_data)
{
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard);
g_return_if_fail (iface);
g_return_if_fail (iface->foreach_section);
(*iface->foreach_section) (keyboard, func, user_data);
} }
/** /**
@ -212,10 +363,6 @@ void
eek_keyboard_set_layout (EekKeyboard *keyboard, eek_keyboard_set_layout (EekKeyboard *keyboard,
EekLayout *layout) EekLayout *layout)
{ {
EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
EEK_KEYBOARD_GET_CLASS(keyboard)->set_layout (keyboard, layout);
g_return_if_fail (iface);
g_return_if_fail (iface->set_layout);
g_return_if_fail (EEK_IS_LAYOUT(layout));
(*iface->set_layout) (keyboard, layout);
} }

View File

@ -20,42 +20,45 @@
#ifndef EEK_KEYBOARD_H #ifndef EEK_KEYBOARD_H
#define EEK_KEYBOARD_H 1 #define EEK_KEYBOARD_H 1
#include "eek-section.h" #include <glib-object.h>
#include "eek-container.h"
#include "eek-types.h"
#include "eek-layout.h" #include "eek-layout.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_KEYBOARD (eek_keyboard_get_type()) #define EEK_TYPE_KEYBOARD (eek_keyboard_get_type())
#define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard)) #define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard))
#define EEK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYBOARD, EekKeyboardClass))
#define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD)) #define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD))
#define EEK_KEYBOARD_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardIface)) #define EEK_IS_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYBOARD))
#define EEK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYBOARD, EekKeyboardClass))
typedef struct _EekKeyboardIface EekKeyboardIface; typedef struct _EekKeyboardClass EekKeyboardClass;
typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
struct _EekKeyboardIface struct _EekKeyboard
{ {
/*< private >*/ /*< private >*/
GTypeInterface g_iface; EekContainer parent;
EekKeyboardPrivate *priv;
};
struct _EekKeyboardClass
{
/*< private >*/
EekContainerClass parent_class;
/*< public >*/ /*< public >*/
void (* set_bounds) (EekKeyboard *self,
EekBounds *bounds);
void (* get_bounds) (EekKeyboard *self,
EekBounds *bounds);
void (* set_keysym_index) (EekKeyboard *self, void (* set_keysym_index) (EekKeyboard *self,
gint group, gint group,
gint level); gint level);
void (* get_keysym_index) (EekKeyboard *self, void (* get_keysym_index) (EekKeyboard *self,
gint *group, gint *group,
gint *level); gint *level);
EekSection *(* create_section) (EekKeyboard *self,
const gchar *name,
gint angle,
EekBounds *bounds);
void (* foreach_section) (EekKeyboard *self, EekSection *(* create_section) (EekKeyboard *self);
GFunc func,
gpointer user_data);
void (* set_layout) (EekKeyboard *self, void (* set_layout) (EekKeyboard *self,
EekLayout *layout); EekLayout *layout);
@ -63,10 +66,6 @@ struct _EekKeyboardIface
GType eek_keyboard_get_type (void) G_GNUC_CONST; GType eek_keyboard_get_type (void) G_GNUC_CONST;
void eek_keyboard_set_bounds (EekKeyboard *keyboard,
EekBounds *bounds);
void eek_keyboard_get_bounds (EekKeyboard *keyboard,
EekBounds *bounds);
void eek_keyboard_set_keysym_index (EekKeyboard *self, void eek_keyboard_set_keysym_index (EekKeyboard *self,
gint group, gint group,
gint level); gint level);
@ -74,14 +73,7 @@ void eek_keyboard_get_keysym_index (EekKeyboard *self,
gint *group, gint *group,
gint *level); gint *level);
EekSection *eek_keyboard_create_section (EekKeyboard *keyboard, EekSection *eek_keyboard_create_section (EekKeyboard *keyboard);
const gchar *name,
gint angle,
EekBounds *bounds);
void eek_keyboard_foreach_section (EekKeyboard *keyboard,
GFunc func,
gpointer user_data);
void eek_keyboard_set_layout (EekKeyboard *keyboard, void eek_keyboard_set_layout (EekKeyboard *keyboard,
EekLayout *layout); EekLayout *layout);

View File

@ -20,10 +20,10 @@
/** /**
* SECTION:eek-layout * SECTION:eek-layout
* @short_description: Base class of a layout engine * @short_description: Base interface of a layout engine
* *
* The #EekLayout class is a base abstract class of layout engine * The #EekLayout class is a base interface of layout engine which
* which arranges keyboard elements. * arranges keyboard elements.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -33,31 +33,39 @@
#include "eek-layout.h" #include "eek-layout.h"
#include "eek-keyboard.h" #include "eek-keyboard.h"
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_INITIALLY_UNOWNED);
static void static void
eek_layout_finalize (GObject *object) eek_layout_base_init (gpointer gobject_class)
{ {
G_OBJECT_CLASS (eek_layout_parent_class)->finalize (object); static gboolean is_initialized = FALSE;
if (!is_initialized) {
/* TODO: signals */
is_initialized = TRUE;
}
} }
static void GType
eek_layout_dispose (GObject *object) eek_layout_get_type (void)
{ {
G_OBJECT_CLASS (eek_layout_parent_class)->dispose (object); static GType iface_type = 0;
if (iface_type == 0) {
static const GTypeInfo info = {
sizeof (EekLayoutIface),
eek_layout_base_init,
NULL,
};
iface_type = g_type_register_static (G_TYPE_INTERFACE,
"EekLayout",
&info, 0);
}
return iface_type;
} }
static void void
eek_layout_class_init (EekLayoutClass *klass) eek_layout_apply (EekLayout *layout,
EekKeyboard *keyboard)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); g_return_if_fail (EEK_IS_LAYOUT(layout));
GParamSpec *pspec; EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard);
gobject_class->finalize = eek_layout_finalize;
gobject_class->dispose = eek_layout_dispose;
} }
static void
eek_layout_init (EekLayout *self)
{
}

View File

@ -28,31 +28,24 @@ G_BEGIN_DECLS
#define EEK_TYPE_LAYOUT (eek_layout_get_type()) #define EEK_TYPE_LAYOUT (eek_layout_get_type())
#define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout)) #define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout))
#define EEK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_LAYOUT, EekLayoutClass))
#define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT)) #define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT))
#define EEK_IS_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_LAYOUT)) #define EEK_LAYOUT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_LAYOUT, EekLayoutIface))
#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass))
typedef struct _EekLayoutClass EekLayoutClass; typedef struct _EekLayoutIface EekLayoutIface;
typedef struct _EekLayout EekLayout; typedef struct _EekLayout EekLayout;
struct _EekLayout struct _EekLayoutIface
{ {
/*< private >*/ /*< private >*/
GInitiallyUnowned parent; GTypeInterface parent_iface;
};
struct _EekLayoutClass void (*apply) (EekLayout *self,
{
/*< private >*/
GInitiallyUnownedClass parent_class;
/*< public >*/
void (*apply_to_keyboard) (EekLayout *self,
EekKeyboard *keyboard); EekKeyboard *keyboard);
}; };
GType eek_layout_get_type (void) G_GNUC_CONST; GType eek_layout_get_type (void) G_GNUC_CONST;
void eek_layout_apply (EekLayout *layout,
EekKeyboard *keyboard);
G_END_DECLS G_END_DECLS
#endif /* EEK_LAYOUT_H */ #endif /* EEK_LAYOUT_H */

View File

@ -1,234 +0,0 @@
/*
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eek-private.h"
#include <math.h>
#define noKBDRAW_DEBUG
static gdouble
length (gdouble x, gdouble y)
{
return sqrt (x * x + y * y);
}
static gdouble
point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny)
{
return ax * nx + ay * ny;
}
static void
normal_form (gdouble ax, gdouble ay,
gdouble bx, gdouble by,
gdouble * nx, gdouble * ny, gdouble * d)
{
gdouble l;
*nx = by - ay;
*ny = ax - bx;
l = length (*nx, *ny);
*nx /= l;
*ny /= l;
*d = point_line_distance (ax, ay, *nx, *ny);
}
static void
inverse (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble * e, gdouble * f, gdouble * g, gdouble * h)
{
gdouble det;
det = a * d - b * c;
*e = d / det;
*f = -b / det;
*g = -c / det;
*h = a / det;
}
static void
multiply (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble e, gdouble f, gdouble * x, gdouble * y)
{
*x = a * e + b * f;
*y = c * e + d * f;
}
static void
intersect (gdouble n1x, gdouble n1y, gdouble d1,
gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y)
{
gdouble e, f, g, h;
inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h);
multiply (e, f, g, h, d1, d2, x, y);
}
/* draw an angle from the current point to b and then to c,
* with a rounded corner of the given radius.
*/
static void
rounded_corner (cairo_t * cr,
gdouble bx, gdouble by,
gdouble cx, gdouble cy, gdouble radius)
{
gdouble ax, ay;
gdouble n1x, n1y, d1;
gdouble n2x, n2y, d2;
gdouble pd1, pd2;
gdouble ix, iy;
gdouble dist1, dist2;
gdouble nx, ny, d;
gdouble a1x, a1y, c1x, c1y;
gdouble phi1, phi2;
cairo_get_current_point (cr, &ax, &ay);
#ifdef KBDRAW_DEBUG
printf (" current point: (%f, %f), radius %f:\n", ax, ay,
radius);
#endif
/* make sure radius is not too large */
dist1 = length (bx - ax, by - ay);
dist2 = length (cx - bx, cy - by);
radius = MIN (radius, MIN (dist1, dist2));
/* construct normal forms of the lines */
normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);
/* find which side of the line a,b the point c is on */
if (point_line_distance (cx, cy, n1x, n1y) < d1)
pd1 = d1 - radius;
else
pd1 = d1 + radius;
/* find which side of the line b,c the point a is on */
if (point_line_distance (ax, ay, n2x, n2y) < d2)
pd2 = d2 - radius;
else
pd2 = d2 + radius;
/* intersect the parallels to find the center of the arc */
intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);
nx = (bx - ax) / dist1;
ny = (by - ay) / dist1;
d = point_line_distance (ix, iy, nx, ny);
/* a1 is the point on the line a-b where the arc starts */
intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);
nx = (cx - bx) / dist2;
ny = (cy - by) / dist2;
d = point_line_distance (ix, iy, nx, ny);
/* c1 is the point on the line b-c where the arc ends */
intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);
/* determine the first angle */
if (a1x - ix == 0)
phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (a1x - ix > 0)
phi1 = atan ((a1y - iy) / (a1x - ix));
else
phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));
/* determine the second angle */
if (c1x - ix == 0)
phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (c1x - ix > 0)
phi2 = atan ((c1y - iy) / (c1x - ix));
else
phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));
/* compute the difference between phi2 and phi1 mod 2pi */
d = phi2 - phi1;
while (d < 0)
d += 2 * M_PI;
while (d > 2 * M_PI)
d -= 2 * M_PI;
#ifdef KBDRAW_DEBUG
printf (" line 1 to: (%f, %f):\n", a1x, a1y);
#endif
if (!(isnan (a1x) || isnan (a1y)))
cairo_line_to (cr, a1x, a1y);
/* pick the short arc from phi1 to phi2 */
if (d < M_PI)
cairo_arc (cr, ix, iy, radius, phi1, phi2);
else
cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);
#ifdef KBDRAW_DEBUG
printf (" line 2 to: (%f, %f):\n", cx, cy);
#endif
cairo_line_to (cr, cx, cy);
}
void
eek_cairo_draw_rounded_polygon (cairo_t * cr,
gboolean filled,
gdouble radius,
EekPoint * points,
gint num_points)
{
gint i, j;
cairo_move_to (cr,
(gdouble) (points[num_points - 1].x +
points[0].x) / 2,
(gdouble) (points[num_points - 1].y +
points[0].y) / 2);
#ifdef KBDRAW_DEBUG
printf (" rounded polygon of radius %f:\n", radius);
#endif
for (i = 0; i < num_points; i++) {
j = (i + 1) % num_points;
rounded_corner (cr, (gdouble) points[i].x,
(gdouble) points[i].y,
(gdouble) (points[i].x + points[j].x) / 2,
(gdouble) (points[i].y + points[j].y) / 2,
radius);
#ifdef KBDRAW_DEBUG
printf (" corner (%d, %d) -> (%d, %d):\n",
points[i].x, points[i].y, points[j].x,
points[j].y);
#endif
};
cairo_close_path (cr);
if (filled)
cairo_fill (cr);
else
cairo_stroke (cr);
}

View File

@ -1,36 +0,0 @@
/*
* 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_PRIVATE_H
#define EEK_PRIVATE_H 1
#include <glib/gtypes.h>
#include <cairo/cairo.h>
#include "eek-types.h"
G_BEGIN_DECLS
void eek_cairo_draw_rounded_polygon (cairo_t * cr,
gboolean filled,
gdouble radius,
EekPoint * points,
gint num_points);
G_END_DECLS
#endif /* EEK_PRIVATE_H */

View File

@ -20,66 +20,227 @@
/** /**
* SECTION:eek-section * SECTION:eek-section
* @short_description: Base interface of a keyboard section * @short_description: Base class of a section
* @see_also: #EekKeyboard, #EekKey * @see_also: #EekKey
* *
* The #EekSectionIface interface represents a keyboard section, which * The #EekSectionClass class represents a section, which consists
* is parented to #EekKeyboardIface and can have one or more keys of * of one or more keys of the #EekKeyClass class.
* the #EekKeyIface interface.
*
* #EekSectionIface follows the Builder pattern and is responsible for
* creation of keys.
*/ */
#include <string.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-section.h" #include "eek-section.h"
#include "eek-key.h"
enum {
PROP_0,
PROP_ANGLE,
PROP_LAST
};
enum {
KEY_PRESSED,
KEY_RELEASED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (EekSection, eek_section, EEK_TYPE_CONTAINER);
#define EEK_SECTION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SECTION, EekSectionPrivate))
struct _EekRow
{
gint num_columns;
EekOrientation orientation;
};
typedef struct _EekRow EekRow;
struct _EekSectionPrivate
{
gint angle;
GSList *rows;
GSList *keys;
};
static void static void
eek_section_base_init (gpointer g_iface) eek_section_real_set_angle (EekSection *self,
gint angle)
{ {
static gboolean is_initialized = FALSE; EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
if (!is_initialized) { priv->angle = angle;
g_object_notify (G_OBJECT(self), "angle");
}
static gint
eek_section_real_get_angle (EekSection *self)
{
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
return priv->angle;
}
static gint
eek_section_real_get_n_rows (EekSection *self)
{
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
return g_slist_length (priv->rows);
}
static void
eek_section_real_add_row (EekSection *self,
gint num_columns,
EekOrientation orientation)
{
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
EekRow *row;
row = g_slice_new (EekRow);
row->num_columns = num_columns;
row->orientation = orientation;
priv->rows = g_slist_append (priv->rows, row);
}
static void
eek_section_real_get_row (EekSection *self,
gint index,
gint *num_columns,
EekOrientation *orientation)
{
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
EekRow *row;
row = g_slist_nth_data (priv->rows, index);
g_return_if_fail (row);
if (num_columns)
*num_columns = row->num_columns;
if (orientation)
*orientation = row->orientation;
}
static void
pressed_event (EekKey *key, EekSection *section)
{
g_signal_emit_by_name (section, "key-pressed", key);
}
static void
released_event (EekKey *key, EekSection *section)
{
g_signal_emit_by_name (section, "key-released", key);
}
static EekKey *
eek_section_real_create_key (EekSection *self,
gint column,
gint row)
{
EekKey *key;
gint num_columns, num_rows;
EekOrientation orientation;
num_rows = eek_section_get_n_rows (self);
g_return_val_if_fail (0 <= row && row < num_rows, NULL);
eek_section_get_row (self, row, &num_columns, &orientation);
g_return_val_if_fail (column < num_columns, NULL);
key = g_object_new (EEK_TYPE_KEY,
"column", column,
"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);
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(key));
return key;
}
static void
eek_section_finalize (GObject *object)
{
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(object);
GSList *head;
for (head = priv->rows; head; head = g_slist_next (head))
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);
}
static void
eek_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_ANGLE:
eek_section_set_angle (EEK_SECTION(object),
g_value_get_int (value));
break;
default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_ANGLE:
g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
break;
default:
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_section_class_init (EekSectionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
/** g_type_class_add_private (gobject_class, sizeof (EekSectionPrivate));
* EekSection:name:
*
* The name of #EekSection.
*/
pspec = g_param_spec_string ("name",
"Name",
"Name",
NULL,
G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
/** klass->set_angle = eek_section_real_set_angle;
* EekSection:columns: klass->get_angle = eek_section_real_get_angle;
* klass->get_n_rows = eek_section_real_get_n_rows;
* The number of columns in #EekSection. klass->add_row = eek_section_real_add_row;
*/ klass->get_row = eek_section_real_get_row;
pspec = g_param_spec_int ("columns", klass->create_key = eek_section_real_create_key;
"Columns",
"The number of columns in the section",
0, G_MAXINT, 0,
G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
/** gobject_class->set_property = eek_section_set_property;
* EekSection:rows: gobject_class->get_property = eek_section_get_property;
* gobject_class->finalize = eek_section_finalize;
* The number of rows in #EekSection.
*/
pspec = g_param_spec_int ("rows",
"Rows",
"The number of rows of the section",
0, G_MAXINT, 0,
G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
/** /**
* EekSection:angle: * EekSection:angle:
@ -91,279 +252,97 @@ eek_section_base_init (gpointer g_iface)
"Rotation angle of the section", "Rotation angle of the section",
-360, 360, 0, -360, 360, 0,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec); g_object_class_install_property (gobject_class,
PROP_ANGLE,
pspec);
/** signals[KEY_PRESSED] =
* EekSection:bounds: g_signal_new ("key-pressed",
* G_TYPE_FROM_CLASS(gobject_class),
* The bounding box of #EekSection. G_SIGNAL_RUN_FIRST,
*/ 0,
pspec = g_param_spec_boxed ("bounds", NULL,
"Bounds", NULL,
"Bounding box of the section", g_cclosure_marshal_VOID__OBJECT,
EEK_TYPE_BOUNDS, G_TYPE_NONE,
G_PARAM_READWRITE); 1,
g_object_interface_install_property (g_iface, pspec); EEK_TYPE_KEY);
is_initialized = TRUE; signals[KEY_RELEASED] =
} g_signal_new ("key-released",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
EEK_TYPE_KEY);
} }
GType static void
eek_section_get_type (void) eek_section_init (EekSection *self)
{ {
static GType iface_type = 0; EekSectionPrivate *priv;
if (iface_type == 0) { priv = self->priv = EEK_SECTION_GET_PRIVATE (self);
static const GTypeInfo info = { priv->angle = 0;
sizeof (EekSectionIface), priv->rows = NULL;
eek_section_base_init, priv->keys = NULL;
NULL
};
iface_type = g_type_register_static (G_TYPE_INTERFACE,
"EekSection",
&info,
0);
}
return iface_type;
} }
/**
* eek_section_set_rows:
* @section: an #EekSection
* @rows: the number of rows in @section
*
* Set the number of rows in @section to @rows.
*/
void
eek_section_set_rows (EekSection *section,
gint rows)
{
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
g_return_if_fail (iface->set_rows);
(*iface->set_rows) (section, rows);
}
/**
* eek_section_get_rows:
* @section: an #EekSection
*
* Get the number of rows in @section.
*/
gint
eek_section_get_rows (EekSection *section)
{
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
g_return_val_if_fail (iface->get_rows, -1);
return (*iface->get_rows) (section);
}
/**
* eek_section_set_columns:
* @section: an #EekSection
* @row: row index in @section
* @columns: the number of keys on @row
*
* Set the number of keys on the @row-th row in @section.
*/
void
eek_section_set_columns (EekSection *section,
gint row,
gint columns)
{
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
g_return_if_fail (iface->set_columns);
(*iface->set_columns) (section, row, columns);
}
/**
* eek_section_get_columns:
* @section: an #EekSection
* @row: row index in @section
*
* Get the number of keys on the @row-th row in @section.
*/
gint
eek_section_get_columns (EekSection *section,
gint row)
{
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
g_return_if_fail (iface->get_columns);
return (*iface->get_columns) (section, row);
}
/**
* eek_section_set_orientation:
* @section: an #EekSection
* @row: row index in @section
* @orientation: either %EEK_ORIENTATION_HORIZONTAL or %EEK_ORIENTATION_VERTICAL
*
* Set the orientation of the @row-th row in @section to @orientation.
*/
void
eek_section_set_orientation (EekSection *section,
gint row,
EekOrientation orientation)
{
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
g_return_if_fail (iface->set_orientation);
(*iface->set_orientation) (section, row, orientation);
}
/**
* eek_section_get_orientation:
* @section: an #EekSection
* @row: row index in @section
*
* Get the orientation of the @row-th row in @section.
* Returns: either %EEK_ORIENTATION_HORIZONTAL or %EEK_ORIENTATION_VERTICAL
*/
EekOrientation
eek_section_get_orientation (EekSection *section,
gint row)
{
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section);
g_return_val_if_fail (iface->get_orientation, EEK_ORIENTATION_INVALID);
return (*iface->get_orientation) (section, row);
}
/**
* eek_section_set_angle:
* @section: an #EekSection
* @angle: rotation angle of @section
*
* Set the rotation angle of @section to @angle.
*/
void void
eek_section_set_angle (EekSection *section, eek_section_set_angle (EekSection *section,
gint angle) gint angle)
{ {
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); g_return_if_fail (EEK_IS_SECTION(section));
EEK_SECTION_GET_CLASS(section)->set_angle (section, angle);
g_return_if_fail (iface->set_angle);
(*iface->set_angle) (section, angle);
} }
/**
* eek_section_get_angle:
* @section: an #EekSection
*
* Get the rotation angle of @section.
*/
gint gint
eek_section_get_angle (EekSection *section) eek_section_get_angle (EekSection *section)
{ {
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); g_return_val_if_fail (EEK_IS_SECTION(section), -1);
return EEK_SECTION_GET_CLASS(section)->get_angle (section);
g_return_val_if_fail (iface->get_angle, 0);
return (*iface->get_angle) (section);
} }
/** gint
* eek_section_set_bounds: eek_section_get_n_rows (EekSection *section)
* @section: an #EekSection
* @bounds: bounding box of @section
*
* Set the bounding box of @section to @bounds.
*/
void
eek_section_set_bounds (EekSection *section,
EekBounds *bounds)
{ {
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); g_return_val_if_fail (EEK_IS_SECTION(section), -1);
return EEK_SECTION_GET_CLASS(section)->get_n_rows (section);
g_return_if_fail (iface->set_bounds);
(*iface->set_bounds) (section, bounds);
} }
/**
* eek_section_get_bounds:
* @section: an #EekSection
* @bounds: the bounding box of @section
*
* Get the bounding box of @section.
*/
void void
eek_section_get_bounds (EekSection *section, eek_section_add_row (EekSection *section,
EekBounds *bounds) gint num_columns,
EekOrientation orientation)
{ {
EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); g_return_if_fail (EEK_IS_SECTION(section));
EEK_SECTION_GET_CLASS(section)->add_row (section,
g_return_if_fail (iface->get_bounds); num_columns,
return (*iface->get_bounds) (section, bounds); orientation);
}
void
eek_section_get_row (EekSection *section,
gint index,
gint *num_columns,
EekOrientation *orientation)
{
g_return_if_fail (EEK_IS_SECTION(section));
EEK_SECTION_GET_CLASS(section)->get_row (section,
index,
num_columns,
orientation);
} }
/**
* eek_section_create_key:
* @section: an #EekSection
* @name: name of the key
* @keysyms: symbol matrix of the key
* @num_groups: number of rows in the @keysyms
* @num_levels: number of columns in the @keysyms
* @column: column index in the @section
* @row: row index in the section
* @outline: outline shape of the key
* @bounds: bounding box of the key
*
* Create an #EekKey instance and attach it to @section.
*/
EekKey * EekKey *
eek_section_create_key (EekSection *section, eek_section_create_key (EekSection *section,
const gchar *name,
guint keycode,
guint *keysyms,
gint num_groups,
gint num_levels,
gint column, gint column,
gint row, gint row)
EekOutline *outline,
EekBounds *bounds)
{ {
EekSectionIface *iface; g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
return EEK_SECTION_GET_CLASS(section)->create_key (section, column, row);
g_return_if_fail (EEK_IS_SECTION(section));
iface = EEK_SECTION_GET_IFACE(section);
g_return_if_fail (iface->create_key);
return (*iface->create_key) (section,
name,
keycode,
keysyms,
num_groups,
num_levels,
column,
row,
outline,
bounds);
}
/**
* eek_section_foreach_key:
* @section: an #EekSection
* @func: a callback of #GFunc
* @user_data: a pointer to an object passed to @func
*
* Iterate over @section's children list.
*/
void
eek_section_foreach_key (EekSection *section,
GFunc func,
gpointer user_data)
{
EekSectionIface *iface;
g_return_if_fail (EEK_IS_SECTION(section));
iface = EEK_SECTION_GET_IFACE(section);
g_return_if_fail (iface->foreach_key);
return (*iface->foreach_key) (section, func, user_data);
} }

View File

@ -20,102 +20,72 @@
#ifndef EEK_SECTION_H #ifndef EEK_SECTION_H
#define EEK_SECTION_H 1 #define EEK_SECTION_H 1
#include "eek-key.h" #include <glib-object.h>
#include "eek-container.h"
#include "eek-types.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_SECTION (eek_section_get_type()) #define EEK_TYPE_SECTION (eek_section_get_type())
#define EEK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SECTION, EekSection)) #define EEK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SECTION, EekSection))
#define EEK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SECTION, EekSectionClass))
#define EEK_IS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SECTION)) #define EEK_IS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SECTION))
#define EEK_SECTION_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_SECTION, EekSectionIface)) #define EEK_IS_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SECTION))
#define EEK_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SECTION, EekSectionClass))
typedef struct _EekSectionIface EekSectionIface; typedef struct _EekSectionClass EekSectionClass;
typedef struct _EekSection EekSection; typedef struct _EekSectionPrivate EekSectionPrivate;
struct _EekSectionIface struct _EekSection
{ {
/*< private >*/ /*< private >*/
GTypeInterface g_iface; EekContainer parent;
EekSectionPrivate *priv;
};
struct _EekSectionClass
{
/*< private >*/
EekContainerClass parent_class;
/*< public >*/ /*< public >*/
void (* set_rows) (EekSection *self,
gint rows);
gint (* get_rows) (EekSection *self);
void (* set_columns) (EekSection *self,
gint row,
gint columns);
gint (* get_columns) (EekSection *self,
gint row);
void (* set_orientation) (EekSection *self,
gint row,
EekOrientation orientation);
EekOrientation (* get_orientation) (EekSection *self,
gint row);
void (* set_angle) (EekSection *self, void (* set_angle) (EekSection *self,
gint angle); gint angle);
gint (* get_angle) (EekSection *self); gint (* get_angle) (EekSection *self);
void (* set_bounds) (EekSection *self, gint (* get_n_rows) (EekSection *self);
EekBounds *bounds); void (* add_row) (EekSection *self,
void (* get_bounds) (EekSection *self, gint num_columns,
EekBounds *bounds); EekOrientation orientation);
void (* get_row) (EekSection *self,
gint index,
gint *num_columns,
EekOrientation *orientation);
EekKey *(* create_key) (EekSection *self, EekKey *(* create_key) (EekSection *self,
const gchar *name,
guint keycode,
guint *keysyms,
gint num_groups,
gint num_levels,
gint column,
gint row, gint row,
EekOutline *outline, gint column);
EekBounds *bounds);
void (* foreach_key) (EekSection *self,
GFunc func,
gpointer user_data);
}; };
GType eek_section_get_type (void) G_GNUC_CONST; GType eek_section_get_type (void) G_GNUC_CONST;
void eek_section_set_rows (EekSection *section,
gint rows);
gint eek_section_get_rows (EekSection *section);
void eek_section_set_columns (EekSection *section,
gint row,
gint columns);
gint eek_section_get_columns (EekSection *section,
gint row);
void eek_section_set_orientation (EekSection *section,
gint row,
EekOrientation orientation);
EekOrientation eek_section_get_orientation (EekSection *section,
gint row);
void eek_section_set_angle (EekSection *section, void eek_section_set_angle (EekSection *section,
gint angle); gint angle);
gint eek_section_get_angle (EekSection *section); gint eek_section_get_angle (EekSection *section);
void eek_section_set_bounds (EekSection *section, gint eek_section_get_n_rows (EekSection *section);
EekBounds *bounds); void eek_section_add_row (EekSection *section,
void eek_section_get_bounds (EekSection *section, gint num_columns,
EekBounds *bounds); EekOrientation orientation);
void eek_section_get_row (EekSection *section,
gint index,
gint *num_columns,
EekOrientation *orientation);
EekKey *eek_section_create_key (EekSection *section, EekKey *eek_section_create_key (EekSection *section,
const gchar *name,
guint keycode,
guint *keysyms,
gint num_groups,
gint num_levels,
gint column, gint column,
gint row, gint row);
EekOutline *outline,
EekBounds *bounds);
void eek_section_foreach_key (EekSection *section,
GFunc func,
gpointer user_data);
G_END_DECLS G_END_DECLS
#endif /* EEK_SECTION_H */ #endif /* EEK_SECTION_H */

View File

@ -1,439 +0,0 @@
/*
* 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-simple-key.h"
#include "eek-keysym.h"
#include <string.h>
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#endif
enum {
PROP_0,
PROP_NAME,
PROP_KEYCODE,
PROP_KEYSYMS,
PROP_COLUMN,
PROP_ROW,
PROP_OUTLINE,
PROP_BOUNDS,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST
};
static void eek_key_iface_init (EekKeyIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekSimpleKey, eek_simple_key,
G_TYPE_INITIALLY_UNOWNED,
G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY,
eek_key_iface_init));
#define EEK_SIMPLE_KEY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyPrivate))
struct _EekSimpleKeyPrivate
{
gchar *name;
guint keycode;
guint *keysyms;
gint num_levels;
gint num_groups;
gint column;
gint row;
EekOutline *outline;
EekBounds bounds;
gint group;
gint level;
};
static guint
eek_simple_key_real_get_keycode (EekKey *self)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, EEK_INVALID_KEYCODE);
return priv->keycode;
}
static void
eek_simple_key_real_set_keysyms (EekKey *self,
guint *keysyms,
gint groups,
gint levels)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
if (priv->keysyms)
g_slice_free (guint, priv->keysyms);
priv->keysyms = g_slice_alloc (groups * levels * sizeof(guint));
memcpy (priv->keysyms, keysyms, groups * levels * sizeof(guint));
priv->num_groups = groups;
priv->num_levels = levels;
#if DEBUG
{
gint i;
fprintf (stderr, "%s: ", priv->name);
for (i = 0; i < groups * levels; i++)
fprintf (stderr, "\"%s\" ", eek_keysym_to_string (keysyms[i]));
fprintf (stderr, "\n");
}
#endif
}
static void
eek_simple_key_real_get_keysyms (EekKey *self,
guint **keysyms,
gint *groups,
gint *levels)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (groups);
g_return_if_fail (levels);
g_return_if_fail (keysyms);
*groups = priv->num_groups;
*levels = priv->num_levels;
if (priv->keysyms) {
*keysyms = g_slice_alloc (*groups * *levels * sizeof(guint));
memcpy (*keysyms, priv->keysyms, *groups * *levels * sizeof(guint));
} else
*keysyms = NULL;
}
static gint
eek_simple_key_real_get_groups (EekKey *self)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1);
return priv->num_groups;
}
static guint
eek_simple_key_real_get_keysym (EekKey *self)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, EEK_INVALID_KEYSYM);
if (priv->num_groups * priv->num_levels == 0)
return EEK_INVALID_KEYSYM;
return priv->keysyms[priv->group * priv->num_levels + priv->level];
}
static void
eek_simple_key_real_set_index (EekKey *self,
gint column,
gint row)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (column < 0);
g_return_if_fail (row < 0);
priv->column = column;
priv->row = row;
}
static void
eek_simple_key_real_get_index (EekKey *self,
gint *column,
gint *row)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (column);
g_return_if_fail (row);
*column = priv->column;
*row = priv->row;
}
static void
eek_simple_key_real_set_outline (EekKey *self, EekOutline *outline)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
priv->outline = outline;
}
static EekOutline *
eek_simple_key_real_get_outline (EekKey *self)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_val_if_fail (priv, NULL);
return priv->outline;
}
static void
eek_simple_key_real_set_bounds (EekKey *self,
EekBounds *bounds)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
priv->bounds = *bounds;
}
static void
eek_simple_key_real_get_bounds (EekKey *self,
EekBounds *bounds)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (bounds);
*bounds = priv->bounds;
}
static void
eek_simple_key_real_set_keysym_index (EekKey *self,
gint group,
gint level)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (0 <= group);
if (group >= priv->num_groups)
group = 0;
g_return_if_fail (0 <= level && level < priv->num_levels);
priv->group = group;
priv->level = level;
}
static void
eek_simple_key_real_get_keysym_index (EekKey *self,
gint *group,
gint *level)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (group);
g_return_if_fail (level);
*group = priv->group;
*level = priv->level;
}
static void
eek_key_iface_init (EekKeyIface *iface)
{
iface->get_keycode = eek_simple_key_real_get_keycode;
iface->set_keysyms = eek_simple_key_real_set_keysyms;
iface->get_keysyms = eek_simple_key_real_get_keysyms;
iface->get_groups = eek_simple_key_real_get_groups;
iface->get_keysym = eek_simple_key_real_get_keysym;
iface->set_index = eek_simple_key_real_set_index;
iface->get_index = eek_simple_key_real_get_index;
iface->set_outline = eek_simple_key_real_set_outline;
iface->get_outline = eek_simple_key_real_get_outline;
iface->set_bounds = eek_simple_key_real_set_bounds;
iface->get_bounds = eek_simple_key_real_get_bounds;
iface->set_keysym_index = eek_simple_key_real_set_keysym_index;
iface->get_keysym_index = eek_simple_key_real_get_keysym_index;
}
static void
eek_simple_key_dispose (GObject *object)
{
G_OBJECT_CLASS (eek_simple_key_parent_class)->dispose (object);
}
static void
eek_simple_key_finalize (GObject *object)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object);
g_free (priv->name);
g_slice_free (guint, priv->keysyms);
G_OBJECT_CLASS (eek_simple_key_parent_class)->finalize (object);
}
static void
eek_simple_key_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object);
EekKeysymMatrix *matrix;
g_return_if_fail (priv);
switch (prop_id) {
case PROP_NAME:
g_free (priv->name);
priv->name = g_strdup (g_value_get_string (value));
break;
case PROP_KEYCODE:
priv->keycode = g_value_get_uint (value);
break;
case PROP_KEYSYMS:
matrix = g_value_get_boxed (value);
eek_key_set_keysyms (EEK_KEY(object),
matrix->data,
matrix->num_groups,
matrix->num_levels);
break;
case PROP_COLUMN:
priv->column = g_value_get_int (value);
break;
case PROP_ROW:
priv->row = g_value_get_int (value);
break;
case PROP_OUTLINE:
priv->outline = g_value_get_pointer (value);
break;
case PROP_BOUNDS:
priv->bounds = *(EekBounds *)g_value_get_boxed (value);
break;
case PROP_GROUP:
priv->group = g_value_get_int (value);
break;
case PROP_LEVEL:
priv->level = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_simple_key_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object);
EekKeysymMatrix matrix;
g_return_if_fail (priv);
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, priv->name);
break;
case PROP_KEYCODE:
g_value_set_uint (value, priv->keycode);
break;
case PROP_KEYSYMS:
matrix.data = priv->keysyms;
matrix.num_groups = priv->num_groups;
matrix.num_levels = priv->num_levels;
g_value_set_boxed (value, &matrix);
break;
case PROP_COLUMN:
g_value_set_int (value, priv->column);
break;
case PROP_ROW:
g_value_set_int (value, priv->row);
break;
case PROP_OUTLINE:
g_value_set_pointer (value, priv->outline);
break;
case PROP_BOUNDS:
g_value_set_boxed (value, &priv->bounds);
break;
case PROP_GROUP:
g_value_set_int (value, priv->group);
break;
case PROP_LEVEL:
g_value_set_int (value, priv->level);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_simple_key_class_init (EekSimpleKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class,
sizeof (EekSimpleKeyPrivate));
gobject_class->set_property = eek_simple_key_set_property;
gobject_class->get_property = eek_simple_key_get_property;
gobject_class->finalize = eek_simple_key_finalize;
gobject_class->dispose = eek_simple_key_dispose;
g_object_class_override_property (gobject_class,
PROP_NAME,
"name");
g_object_class_override_property (gobject_class,
PROP_KEYCODE,
"keycode");
g_object_class_override_property (gobject_class,
PROP_KEYSYMS,
"keysyms");
g_object_class_override_property (gobject_class,
PROP_COLUMN,
"column");
g_object_class_override_property (gobject_class,
PROP_ROW,
"row");
g_object_class_override_property (gobject_class,
PROP_OUTLINE,
"outline");
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
g_object_class_override_property (gobject_class,
PROP_GROUP,
"group");
g_object_class_override_property (gobject_class,
PROP_LEVEL,
"level");
}
static void
eek_simple_key_init (EekSimpleKey *self)
{
EekSimpleKeyPrivate *priv;
priv = self->priv = EEK_SIMPLE_KEY_GET_PRIVATE(self);
priv->keysyms = NULL;
priv->keycode = 0;
priv->num_groups = 0;
priv->num_levels = 0;
priv->column = 0;
priv->row = 0;
priv->outline = NULL;
memset (&priv->bounds, 0, sizeof priv->bounds);
}

View File

@ -1,55 +0,0 @@
/*
* 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_SIMPLE_KEY_H
#define EEK_SIMPLE_KEY_H 1
#include "eek-key.h"
G_BEGIN_DECLS
#define EEK_TYPE_SIMPLE_KEY (eek_simple_key_get_type())
#define EEK_SIMPLE_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKey))
#define EEK_SIMPLE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyClass))
#define EEK_IS_SIMPLE_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_KEY))
#define EEK_IS_SIMPLE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_KEY))
#define EEK_SIMPLE_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyClass))
typedef struct _EekSimpleKey EekSimpleKey;
typedef struct _EekSimpleKeyClass EekSimpleKeyClass;
typedef struct _EekSimpleKeyPrivate EekSimpleKeyPrivate;
struct _EekSimpleKey
{
/*< private >*/
GInitiallyUnowned parent;
/*< private >*/
EekSimpleKeyPrivate *priv;
};
struct _EekSimpleKeyClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
};
GType eek_simple_key_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* EEK_SIMPLE_KEY_H */

View File

@ -1,217 +0,0 @@
/*
* 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-simple-keyboard.h"
enum {
PROP_0,
PROP_BOUNDS,
PROP_LAST
};
static void eek_keyboard_iface_init (EekKeyboardIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekSimpleKeyboard, eek_simple_keyboard,
G_TYPE_INITIALLY_UNOWNED,
G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD,
eek_keyboard_iface_init));
#define EEK_SIMPLE_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardPrivate))
struct _EekSimpleKeyboardPrivate
{
EekBounds bounds;
GSList *sections;
};
static void
eek_simple_keyboard_real_set_bounds (EekKeyboard *self,
EekBounds *bounds)
{
EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv);
priv->bounds = *bounds;
}
static void
eek_simple_keyboard_real_get_bounds (EekKeyboard *self,
EekBounds *bounds)
{
EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (bounds);
*bounds = priv->bounds;
}
static EekSection *
eek_simple_keyboard_real_create_section (EekKeyboard *self,
const gchar *name,
gint angle,
EekBounds *bounds)
{
EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self);
EekSection *section;
g_return_val_if_fail (priv, NULL);
section = g_object_new (EEK_TYPE_SIMPLE_SECTION,
"name", name,
"angle", angle,
"bounds", bounds,
NULL);
g_return_val_if_fail (section, NULL);
priv->sections = g_slist_prepend (priv->sections, section);
return section;
}
static void
eek_simple_keyboard_real_foreach_section (EekKeyboard *self,
GFunc func,
gpointer user_data)
{
EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self);
g_return_if_fail (priv);
g_slist_foreach (priv->sections, func, user_data);
}
static void
eek_simple_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_simple_keyboard_real_set_bounds;
iface->get_bounds = eek_simple_keyboard_real_get_bounds;
iface->create_section = eek_simple_keyboard_real_create_section;
iface->foreach_section = eek_simple_keyboard_real_foreach_section;
iface->set_layout = eek_simple_keyboard_real_set_layout;
}
static void
eek_simple_keyboard_dispose (GObject *object)
{
EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object);
GSList *head;
for (head = priv->sections; head; head = g_slist_next (head))
g_object_unref (head->data);
G_OBJECT_CLASS (eek_simple_keyboard_parent_class)->dispose (object);
}
static void
eek_simple_keyboard_finalize (GObject *object)
{
EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object);
g_slist_free (priv->sections);
G_OBJECT_CLASS (eek_simple_keyboard_parent_class)->finalize (object);
}
static void
eek_simple_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_BOUNDS:
eek_keyboard_set_bounds (EEK_KEYBOARD(object),
g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_simple_keyboard_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object);
g_return_if_fail (priv);
switch (prop_id) {
case PROP_BOUNDS:
g_value_set_boxed (value, &priv->bounds);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_simple_keyboard_class_init (EekSimpleKeyboardClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class,
sizeof (EekSimpleKeyboardPrivate));
gobject_class->set_property = eek_simple_keyboard_set_property;
gobject_class->get_property = eek_simple_keyboard_get_property;
gobject_class->finalize = eek_simple_keyboard_finalize;
gobject_class->dispose = eek_simple_keyboard_dispose;
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
}
static void
eek_simple_keyboard_init (EekSimpleKeyboard *self)
{
EekSimpleKeyboardPrivate *priv;
priv = self->priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self);
priv->sections = NULL;
}
EekKeyboard*
eek_simple_keyboard_new (void)
{
return g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL);
}

View File

@ -1,57 +0,0 @@
/*
* 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_SIMPLE_KEYBOARD_H
#define EEK_SIMPLE_KEYBOARD_H 1
#include "eek-simple-section.h"
#include "eek-keyboard.h"
G_BEGIN_DECLS
#define EEK_TYPE_SIMPLE_KEYBOARD (eek_simple_keyboard_get_type())
#define EEK_SIMPLE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekKeyboard))
#define EEK_SIMPLE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardClass))
#define EEK_IS_SIMPLE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_KEYBOARD))
#define EEK_IS_SIMPLE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_KEYBOARD))
#define EEK_SIMPLE_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardClass))
typedef struct _EekSimpleKeyboard EekSimpleKeyboard;
typedef struct _EekSimpleKeyboardClass EekSimpleKeyboardClass;
typedef struct _EekSimpleKeyboardPrivate EekSimpleKeyboardPrivate;
struct _EekSimpleKeyboard
{
/*< private >*/
GInitiallyUnowned parent;
EekSimpleKeyboardPrivate *priv;
};
struct _EekSimpleKeyboardClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
};
GType eek_simple_keyboard_get_type (void) G_GNUC_CONST;
EekKeyboard *eek_simple_keyboard_new (void);
G_END_DECLS
#endif /* EEK_SIMPLE_KEYBOARD_H */

View File

@ -1,352 +0,0 @@
/*
* 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-simple-section.h"
#include <string.h>
enum {
PROP_0,
PROP_NAME,
PROP_COLUMNS,
PROP_ROWS,
PROP_ANGLE,
PROP_BOUNDS,
PROP_LAST
};
static void eek_section_iface_init (EekSectionIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekSimpleSection, eek_simple_section,
G_TYPE_INITIALLY_UNOWNED,
G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION,
eek_section_iface_init));
#define EEK_SIMPLE_SECTION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionPrivate))
struct _EekSimpleSectionPrivate
{
gchar *name;
gint num_rows;
gint *num_columns;
EekOrientation *orientations;
gint angle;
EekBounds bounds;
GSList *keys;
};
static void
eek_simple_section_real_set_rows (EekSection *self,
gint rows)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (rows >= 0);
priv->num_rows = rows;
if (rows > 0) {
g_free (priv->num_columns);
priv->num_columns = g_slice_alloc (sizeof(gint) * priv->num_rows);
g_free (priv->orientations);
priv->orientations =
g_slice_alloc (sizeof(EekOrientation) * priv->num_rows);
}
}
static gint
eek_simple_section_real_get_rows (EekSection *self)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1);
return priv->num_rows;
}
static void
eek_simple_section_real_set_columns (EekSection *self,
gint row,
gint columns)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (0 <= row && row < priv->num_rows);
priv->num_columns[row] = columns;
}
static gint
eek_simple_section_real_get_columns (EekSection *self,
gint row)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, -1);
g_return_val_if_fail (0 <= row && row < priv->num_rows, -1);
return priv->num_columns[row];
}
static void
eek_simple_section_real_set_orientation (EekSection *self,
gint row,
EekOrientation orientation)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (0 <= row && row < priv->num_rows);
priv->orientations[row] = orientation;
}
static EekOrientation
eek_simple_section_real_get_orientation (EekSection *self,
gint row)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, EEK_ORIENTATION_INVALID);
g_return_if_fail (0 <= row && row < priv->num_rows);
return priv->orientations[row];
}
static void
eek_simple_section_real_set_angle (EekSection *self,
gint angle)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
priv->angle = angle;
}
static gint
eek_simple_section_real_get_angle (EekSection *self)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_val_if_fail (priv, 0);
return priv->angle;
}
static void
eek_simple_section_real_set_bounds (EekSection *self,
EekBounds *bounds)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (bounds);
priv->bounds = *bounds;
}
static void
eek_simple_section_real_get_bounds (EekSection *self, EekBounds *bounds)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
g_return_if_fail (bounds);
priv->bounds = *bounds;
}
static EekKey *
eek_simple_section_real_create_key (EekSection *self,
const gchar *name,
guint keycode,
guint *keysyms,
gint num_groups,
gint num_levels,
gint column,
gint row,
EekOutline *outline,
EekBounds *bounds)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
EekKey *key;
EekKeysymMatrix matrix;
g_return_val_if_fail (priv, NULL);
g_return_val_if_fail (0 <= row && row < priv->num_rows, NULL);
g_return_val_if_fail (column < priv->num_columns[row], NULL);
matrix.data = keysyms;
matrix.num_groups = num_groups;
matrix.num_levels = num_levels;
key = g_object_new (EEK_TYPE_SIMPLE_KEY,
"name", name,
"keycode", keycode,
"keysyms", &matrix,
"column", column,
"row", row,
"outline", outline,
"bounds", bounds,
NULL);
g_return_val_if_fail (key, NULL);
priv->keys = g_slist_prepend (priv->keys, key);
return key;
}
static void
eek_simple_section_real_foreach_key (EekSection *self,
GFunc func,
gpointer user_data)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self);
g_return_if_fail (priv);
g_slist_foreach (priv->keys, func, user_data);
}
static void
eek_section_iface_init (EekSectionIface *iface)
{
iface->set_rows = eek_simple_section_real_set_rows;
iface->get_rows = eek_simple_section_real_get_rows;
iface->set_columns = eek_simple_section_real_set_columns;
iface->get_columns = eek_simple_section_real_get_columns;
iface->set_orientation = eek_simple_section_real_set_orientation;
iface->get_orientation = eek_simple_section_real_get_orientation;
iface->set_angle = eek_simple_section_real_set_angle;
iface->get_angle = eek_simple_section_real_get_angle;
iface->set_bounds = eek_simple_section_real_set_bounds;
iface->get_bounds = eek_simple_section_real_get_bounds;
iface->create_key = eek_simple_section_real_create_key;
iface->foreach_key = eek_simple_section_real_foreach_key;
}
static void
eek_simple_section_dispose (GObject *object)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object);
GSList *head;
for (head = priv->keys; head; head = g_slist_next (head))
g_object_unref (head->data);
G_OBJECT_CLASS (eek_simple_section_parent_class)->dispose (object);
}
static void
eek_simple_section_finalize (GObject *object)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object);
g_free (priv->name);
g_slist_free (priv->keys);
g_slice_free (gint, priv->num_columns);
g_slice_free (EekOrientation, priv->orientations);
G_OBJECT_CLASS (eek_simple_section_parent_class)->finalize (object);
}
static void
eek_simple_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object);
switch (prop_id) {
case PROP_NAME:
g_free (priv->name);
priv->name = g_strdup (g_value_get_string (value));
break;
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_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_simple_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object);
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, priv->name);
break;
case PROP_ANGLE:
g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
break;
case PROP_BOUNDS:
g_value_set_boxed (value, &priv->bounds);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break;
}
}
static void
eek_simple_section_class_init (EekSimpleSectionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (gobject_class, sizeof (EekSimpleSectionPrivate));
gobject_class->set_property = eek_simple_section_set_property;
gobject_class->get_property = eek_simple_section_get_property;
gobject_class->finalize = eek_simple_section_finalize;
gobject_class->dispose = eek_simple_section_dispose;
g_object_class_override_property (gobject_class,
PROP_NAME,
"name");
g_object_class_override_property (gobject_class,
PROP_ANGLE,
"angle");
g_object_class_override_property (gobject_class,
PROP_BOUNDS,
"bounds");
}
static void
eek_simple_section_init (EekSimpleSection *self)
{
EekSimpleSectionPrivate *priv;
priv = self->priv = EEK_SIMPLE_SECTION_GET_PRIVATE (self);
priv->angle = 0;
memset (&priv->bounds, 0, sizeof priv->bounds);
priv->keys = NULL;
priv->num_rows = 0;
priv->num_columns = NULL;
priv->orientations = NULL;
}

View File

@ -1,56 +0,0 @@
/*
* 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_SIMPLE_SECTION_H
#define EEK_SIMPLE_SECTION_H 1
#include "eek-simple-key.h"
#include "eek-section.h"
G_BEGIN_DECLS
#define EEK_TYPE_SIMPLE_SECTION (eek_simple_section_get_type())
#define EEK_SIMPLE_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSection))
#define EEK_SIMPLE_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionClass))
#define EEK_IS_SIMPLE_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_SECTION))
#define EEK_IS_SIMPLE_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_SECTION))
#define EEK_SIMPLE_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionClass))
typedef struct _EekSimpleSection EekSimpleSection;
typedef struct _EekSimpleSectionClass EekSimpleSectionClass;
typedef struct _EekSimpleSectionPrivate EekSimpleSectionPrivate;
struct _EekSimpleSection
{
/*< private >*/
GInitiallyUnowned parent;
/*< private >*/
EekSimpleSectionPrivate *priv;
};
struct _EekSimpleSectionClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
};
GType eek_simple_section_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* EEK_SIMPLE_SECTION_H */

View File

@ -17,6 +17,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA * 02110-1301 USA
*/ */
/**
* SECTION:eek-types
* @short_description: Miscellaneous types
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */

View File

@ -30,6 +30,8 @@ typedef enum {
EEK_ORIENTATION_INVALID = -1 EEK_ORIENTATION_INVALID = -1
} EekOrientation; } EekOrientation;
typedef struct _EekKey EekKey;
typedef struct _EekSection EekSection;
typedef struct _EekKeyboard EekKeyboard; typedef struct _EekKeyboard EekKeyboard;
/** /**

View File

@ -37,10 +37,17 @@
#include <string.h> #include <string.h>
#include "eek-xkb-layout.h" #include "eek-xkb-layout.h"
#include "eek-keyboard.h" #include "eek-keyboard.h"
#include "eek-section.h"
#include "eek-key.h"
#include "eek-keysym.h"
#define noKBDRAW_DEBUG #define noKBDRAW_DEBUG
G_DEFINE_TYPE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT); static void eek_layout_iface_init (EekLayoutIface *iface);
G_DEFINE_TYPE_WITH_CODE (EekXkbLayout, eek_xkb_layout, G_TYPE_INITIALLY_UNOWNED,
G_IMPLEMENT_INTERFACE (EEK_TYPE_LAYOUT,
eek_layout_iface_init));
#define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \ #define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate))
@ -72,8 +79,6 @@ struct _EekXkbLayoutPrivate
gint scale_denominator; gint scale_denominator;
}; };
#define INVALID_KEYCODE ((guint)(-1))
static guint static guint
find_keycode (EekXkbLayout *layout, gchar *key_name); find_keycode (EekXkbLayout *layout, gchar *key_name);
@ -104,7 +109,7 @@ xkb_to_pixmap_double (EekXkbLayout *layout,
return d * priv->scale_numerator / priv->scale_denominator; return d * priv->scale_numerator / priv->scale_denominator;
} }
static EekKey * static void
create_key (EekXkbLayout *layout, create_key (EekXkbLayout *layout,
EekSection *section, EekSection *section,
gint column, gint column,
@ -120,11 +125,11 @@ create_key (EekXkbLayout *layout,
EekXkbLayoutPrivate *priv = layout->priv; EekXkbLayoutPrivate *priv = layout->priv;
EekKey *key; EekKey *key;
EekBounds bounds; EekBounds bounds;
guint *keysyms; guint *keysyms = NULL;
gchar name[XkbKeyNameLength + 1]; gchar name[XkbKeyNameLength + 1];
EekOutline *outline; EekOutline *outline;
KeyCode keycode; KeyCode keycode;
gint num_groups, num_levels; gint num_groups, num_levels, num_keysyms;
xkbgeometry = priv->xkb->geom; xkbgeometry = priv->xkb->geom;
xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx]; xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
@ -133,7 +138,7 @@ create_key (EekXkbLayout *layout,
xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] : xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
xkbshape->primary; xkbshape->primary;
outline = g_new0 (EekOutline, 1); outline = g_slice_new (EekOutline);
outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius); outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius);
if (xkboutline->num_points <= 2) { /* rectangular */ if (xkboutline->num_points <= 2) { /* rectangular */
@ -179,16 +184,16 @@ create_key (EekXkbLayout *layout,
bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1); bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1);
keycode = find_keycode (layout, name); keycode = find_keycode (layout, name);
if (keycode == INVALID_KEYCODE) if (keycode == EEK_INVALID_KEYCODE)
num_groups = num_levels = 0; num_groups = num_levels = 0;
else { else {
KeySym keysym; KeySym keysym;
gint num_keysyms, i, j; gint i, j;
num_groups = XkbKeyNumGroups (priv->xkb, keycode); num_groups = XkbKeyNumGroups (priv->xkb, keycode);
num_levels = XkbKeyGroupsWidth (priv->xkb, keycode); num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
num_keysyms = num_groups * num_levels; num_keysyms = num_groups * num_levels;
keysyms = g_malloc0 ((num_keysyms) * sizeof(guint)); keysyms = g_slice_alloc0 (num_keysyms * sizeof(guint));
for (i = 0; i < num_groups; i++) for (i = 0; i < num_groups; i++)
for (j = 0; j < num_levels; j++) { for (j = 0; j < num_levels; j++) {
keysym = XkbKeySymEntry (priv->xkb, keycode, j, i); keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
@ -196,16 +201,15 @@ create_key (EekXkbLayout *layout,
} }
} }
eek_section_create_key (section, key = eek_section_create_key (section, column, row);
name, eek_element_set_name (EEK_ELEMENT(key), name);
keycode, eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
keysyms, eek_key_set_keycode (key, keycode);
num_groups, eek_key_set_keysyms (key, keysyms, num_groups, num_levels);
num_levels, if (keysyms)
column, g_slice_free1 (num_keysyms * sizeof(guint), keysyms);
row, eek_key_set_keysym_index (key, 0, 0);
outline, eek_key_set_outline (key, outline);
&bounds);
} }
static void static void
@ -229,22 +233,21 @@ create_section (EekXkbLayout *layout,
priv = layout->priv; priv = layout->priv;
xkbgeometry = priv->xkb->geom; xkbgeometry = priv->xkb->geom;
name = XGetAtomName (priv->display, xkbsection->name); name = XGetAtomName (priv->display, xkbsection->name);
section = eek_keyboard_create_section (keyboard, section = eek_keyboard_create_section (keyboard);
name, eek_element_set_name (EEK_ELEMENT(section), name);
eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
eek_section_set_angle (section,
/* angle is in tenth of degree */ /* angle is in tenth of degree */
xkbsection->angle / 10, xkbsection->angle / 10);
&bounds);
eek_section_set_rows (section, xkbsection->num_rows);
for (i = 0; i < xkbsection->num_rows; i++) { for (i = 0; i < xkbsection->num_rows; i++) {
XkbRowRec *xkbrow; XkbRowRec *xkbrow;
xkbrow = &xkbsection->rows[i]; xkbrow = &xkbsection->rows[i];
left = xkbrow->left; left = xkbrow->left;
top = xkbrow->top; top = xkbrow->top;
eek_section_set_columns (section, i, xkbrow->num_keys); eek_section_add_row (section,
eek_section_set_orientation (section, xkbrow->num_keys,
i,
xkbrow->vertical ? xkbrow->vertical ?
EEK_ORIENTATION_VERTICAL : EEK_ORIENTATION_VERTICAL :
EEK_ORIENTATION_HORIZONTAL); EEK_ORIENTATION_HORIZONTAL);
@ -280,39 +283,33 @@ create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
xkbgeometry = priv->xkb->geom; xkbgeometry = priv->xkb->geom;
eek_keyboard_get_bounds (keyboard, &bounds); eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height); setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height);
bounds.x = bounds.y = 0; bounds.x = bounds.y = 0;
bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm); bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm); bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm);
eek_keyboard_set_bounds (keyboard, &bounds);
for (i = 0; i < xkbgeometry->num_sections; i++) { for (i = 0; i < xkbgeometry->num_sections; i++) {
XkbSectionRec *xkbsection; XkbSectionRec *xkbsection;
EekSection *section;
xkbsection = &xkbgeometry->sections[i]; xkbsection = &xkbgeometry->sections[i];
create_section (layout, keyboard, xkbsection); create_section (layout, keyboard, xkbsection);
} }
eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
} }
static void static void
eek_xkb_layout_apply_to_keyboard (EekLayout *layout, EekKeyboard *keyboard) eek_xkb_layout_real_apply (EekLayout *layout, EekKeyboard *keyboard)
{ {
g_return_if_fail (EEK_IS_XKB_LAYOUT(layout));
g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
create_keyboard (EEK_XKB_LAYOUT(layout), keyboard); create_keyboard (EEK_XKB_LAYOUT(layout), keyboard);
if (g_object_is_floating (keyboard)) if (g_object_is_floating (keyboard))
g_object_unref (keyboard); g_object_unref (keyboard);
} }
static void
eek_xkb_layout_dispose (GObject *object)
{
G_OBJECT_CLASS (eek_xkb_layout_parent_class)->dispose (object);
}
static void static void
eek_xkb_layout_finalize (GObject *object) eek_xkb_layout_finalize (GObject *object)
{ {
@ -321,7 +318,8 @@ eek_xkb_layout_finalize (GObject *object)
g_free (priv->names.keycodes); g_free (priv->names.keycodes);
g_free (priv->names.geometry); g_free (priv->names.geometry);
g_free (priv->names.symbols); g_free (priv->names.symbols);
g_hash_table_unref (priv->outline_hash); /* XXX */
//g_hash_table_unref (priv->outline_hash);
XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */ XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */
G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object); G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object);
} }
@ -349,7 +347,9 @@ eek_xkb_layout_set_property (GObject *object,
eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name); eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break; break;
} }
} }
@ -377,27 +377,31 @@ eek_xkb_layout_get_property (GObject *object,
g_value_set_string (value, name); g_value_set_string (value, name);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break; break;
} }
} }
static void
eek_layout_iface_init (EekLayoutIface *iface)
{
iface->apply = eek_xkb_layout_real_apply;
}
static void static void
eek_xkb_layout_class_init (EekXkbLayoutClass *klass) eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate)); g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
gobject_class->finalize = eek_xkb_layout_finalize; gobject_class->finalize = eek_xkb_layout_finalize;
gobject_class->dispose = eek_xkb_layout_dispose;
gobject_class->set_property = eek_xkb_layout_set_property; gobject_class->set_property = eek_xkb_layout_set_property;
gobject_class->get_property = eek_xkb_layout_get_property; gobject_class->get_property = eek_xkb_layout_get_property;
layout_class->apply_to_keyboard = eek_xkb_layout_apply_to_keyboard;
pspec = g_param_spec_string ("keycodes", pspec = g_param_spec_string ("keycodes",
"Keycodes", "Keycodes",
"XKB keycodes component name", "XKB keycodes component name",
@ -420,6 +424,12 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
g_object_class_install_property (gobject_class, PROP_SYMBOLS, pspec); g_object_class_install_property (gobject_class, PROP_SYMBOLS, pspec);
} }
static void
outline_free (gpointer data)
{
g_slice_free (EekOutline, data);
}
static void static void
eek_xkb_layout_init (EekXkbLayout *self) eek_xkb_layout_init (EekXkbLayout *self)
{ {
@ -443,7 +453,7 @@ eek_xkb_layout_init (EekXkbLayout *self)
priv->outline_hash = g_hash_table_new_full (g_direct_hash, priv->outline_hash = g_hash_table_new_full (g_direct_hash,
g_direct_equal, g_direct_equal,
NULL, NULL,
g_free); outline_free);
if (priv->xkb == NULL) { if (priv->xkb == NULL) {
g_critical ("XkbGetKeyboard failed to get keyboard from the server!"); g_critical ("XkbGetKeyboard failed to get keyboard from the server!");
return; return;
@ -515,10 +525,12 @@ eek_xkb_layout_new (const gchar *keycodes,
const gchar *geometry, const gchar *geometry,
const gchar *symbols) const gchar *symbols)
{ {
EekXkbLayout *layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL); EekXkbLayout *layout;
EekXkbLayoutPrivate *priv = layout->priv; EekXkbLayoutPrivate *priv;
layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL);
g_return_val_if_fail (layout, NULL); g_return_val_if_fail (layout, NULL);
priv = layout->priv;
if (keycodes) if (keycodes)
priv->names.keycodes = g_strdup (keycodes); priv->names.keycodes = g_strdup (keycodes);
if (geometry) if (geometry)
@ -609,8 +621,6 @@ G_CONST_RETURN gchar *
eek_xkb_layout_get_geometry (EekXkbLayout *layout) eek_xkb_layout_get_geometry (EekXkbLayout *layout)
{ {
EekXkbLayoutPrivate *priv = layout->priv; EekXkbLayoutPrivate *priv = layout->priv;
char *name;
return priv->names.geometry; return priv->names.geometry;
} }
@ -682,7 +692,7 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
EekXkbLayoutPrivate *priv = layout->priv; EekXkbLayoutPrivate *priv = layout->priv;
if (!priv->xkb) if (!priv->xkb)
return INVALID_KEYCODE; return EEK_INVALID_KEYCODE;
#ifdef KBDRAW_DEBUG #ifdef KBDRAW_DEBUG
printf (" looking for keycode for (%c%c%c%c)\n", printf (" looking for keycode for (%c%c%c%c)\n",
@ -736,7 +746,7 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
palias++; palias++;
} }
return INVALID_KEYCODE; return EEK_INVALID_KEYCODE;
} }
static void static void

View File

@ -40,7 +40,7 @@ typedef struct _EekXkbLayoutPrivate EekXkbLayoutPrivate;
struct _EekXkbLayout struct _EekXkbLayout
{ {
/*< private >*/ /*< private >*/
EekLayout parent; GInitiallyUnowned parent;
EekXkbLayoutPrivate *priv; EekXkbLayoutPrivate *priv;
}; };
@ -48,7 +48,7 @@ struct _EekXkbLayout
struct _EekXkbLayoutClass struct _EekXkbLayoutClass
{ {
/*< private >*/ /*< private >*/
EekLayoutClass parent_class; GInitiallyUnownedClass parent_class;
void (* set_keycodes) (EekXkbLayout *self, void (* set_keycodes) (EekXkbLayout *self,
const gchar *keycodes); const gchar *keycodes);

View File

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

@ -4,8 +4,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define CSW 1280 #define CSW 640
#define CSH 1024 #define CSH 480
static gchar *symbols = NULL; static gchar *symbols = NULL;
static gchar *keycodes = NULL; static gchar *keycodes = NULL;
@ -83,12 +83,21 @@ on_resize (GObject *object,
&value); &value);
} }
static void
key_pressed_event (EekKeyboard *keyboard,
EekKey *key)
{
guint keysym = eek_key_get_keysym (key);
g_return_if_fail (keysym != EEK_INVALID_KEYSYM);
g_debug ("%s", eek_keysym_to_string (keysym));
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
EekKeyboard *keyboard; EekKeyboard *keyboard;
EekLayout *layout; EekLayout *layout;
ClutterActor *stage; ClutterActor *stage, *actor;
ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff }; ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff };
GOptionContext *context; GOptionContext *context;
@ -116,16 +125,17 @@ main (int argc, char *argv[])
} }
g_object_ref_sink (keyboard); g_object_ref_sink (keyboard);
g_signal_connect (keyboard, "key-pressed", G_CALLBACK(key_pressed_event), NULL);
eek_keyboard_set_layout (keyboard, layout); eek_keyboard_set_layout (keyboard, layout);
actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard));
stage = clutter_stage_get_default (); stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color); clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_get_size (CLUTTER_ACTOR(keyboard), &stage_width, &stage_height); clutter_actor_get_size (actor, &stage_width, &stage_height);
clutter_actor_set_size (stage, stage_width, stage_height); clutter_actor_set_size (stage, stage_width, stage_height);
clutter_group_add (CLUTTER_GROUP(stage), CLUTTER_ACTOR(keyboard)); clutter_group_add (CLUTTER_GROUP(stage), actor);
clutter_actor_show_all (stage); clutter_actor_show_all (stage);
@ -139,11 +149,6 @@ main (int argc, char *argv[])
G_CALLBACK (on_resize), G_CALLBACK (on_resize),
NULL); NULL);
g_signal_connect (stage,
"event",
G_CALLBACK (on_event),
NULL);
clutter_main (); clutter_main ();
return 0; return 0;

View File

@ -16,13 +16,13 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
INCLUDES = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(SIMPLE_CFLAGS) $(XKB_CFLAGS) INCLUDES = -I$(top_srcdir) $(CLUTTER_CFLAGS) $(GOBJECT2_CFLAGS) $(SIMPLE_CFLAGS) $(XKB_CFLAGS)
TESTS = eek-simple-test eek-xkb-test TESTS = eek-simple-test eek-xkb-test
noinst_PROGRAMS = $(TESTS) noinst_PROGRAMS = $(TESTS)
eek_simple_test_SOURCES = eek-simple-test.c eek_simple_test_SOURCES = eek-simple-test.c
eek_simple_test_LDADD = $(top_builddir)/eek/libeek.la eek_simple_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-clutter.la
eek_xkb_test_SOURCES = eek-xkb-test.c eek_xkb_test_SOURCES = eek-xkb-test.c
eek_xkb_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la eek_xkb_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la

View File

@ -17,74 +17,44 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA * 02110-1301 USA
*/ */
#include "eek-simple-keyboard.h" #include "eek.h"
#include "eek-clutter.h"
static void static void
test_create (void) test_create (void)
{ {
EekKeyboard *keyboard; EekKeyboard *keyboard;
EekSection *section; EekSection *section;
EekKey *key; EekKey *key0, *key1;
EekOutline outline = {45.0, NULL, 0}; keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
EekBounds bounds = {0.1, 0.2, 3.0, 4.0}; section = eek_keyboard_create_section (keyboard);
EekKeysymMatrix *matrix; g_assert (EEK_IS_SECTION(section));
GValue value = {0}; eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
gint iv; key0 = eek_section_create_key (section, 0, 0);
const gchar *sv; g_assert (EEK_IS_KEY(key0));
gpointer bv; key1 = eek_section_create_key (section, 1, 0);
guint keysyms[] = {'a', 'b', 'c', 'd', 'e', 'f'}; g_assert (EEK_IS_KEY(key1));
}
keyboard = eek_simple_keyboard_new (); static void
g_assert (keyboard); test_create_clutter (void)
g_assert (g_object_is_floating (keyboard)); {
EekKeyboard *keyboard;
EekSection *section;
EekKey *key0, *key1;
ClutterActor *actor;
section = eek_keyboard_create_section (keyboard, keyboard = eek_clutter_keyboard_new (640.0, 480.0);
"test-section", section = eek_keyboard_create_section (keyboard);
45, g_assert (EEK_IS_SECTION(section));
&bounds); eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
g_assert (section); key0 = eek_section_create_key (section, 0, 0);
g_value_init (&value, G_TYPE_STRING); g_assert (EEK_IS_KEY(key0));
g_object_get_property (G_OBJECT(section), "name", &value); key1 = eek_section_create_key (section, 1, 0);
sv = g_value_get_string (&value); g_assert (EEK_IS_KEY(key1));
g_assert_cmpstr (sv, ==, "test-section"); actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard));
g_value_unset (&value); g_assert (CLUTTER_IS_ACTOR(actor));
g_value_init (&value, G_TYPE_INT);
g_object_get_property (G_OBJECT(section), "angle", &value);
iv = g_value_get_int (&value);
g_assert_cmpint (iv, ==, 45);
g_value_unset (&value);
g_value_init (&value, EEK_TYPE_BOUNDS);
g_object_get_property (G_OBJECT(section), "bounds", &value);
bv = g_value_get_boxed (&value);
g_assert (bv);
g_assert_cmpfloat (((EekBounds *)bv)->x, ==, 0.1);
g_value_unset (&value);
key = eek_section_create_key (section,
"test-key",
0,
keysyms,
3,
2,
1,
2,
&outline,
&bounds);
g_assert (key);
g_value_init (&value, EEK_TYPE_KEYSYM_MATRIX);
g_object_get_property (G_OBJECT(key), "keysyms", &value);
matrix = g_value_get_boxed (&value);
g_assert_cmpint (matrix->data[0], ==, 'a');
g_value_unset (&value);
g_value_init (&value, G_TYPE_POINTER);
g_object_get_property (G_OBJECT(key), "outline", &value);
bv = g_value_get_pointer (&value);
g_assert (bv == &outline);
g_value_unset (&value);
g_object_unref (keyboard); g_object_unref (keyboard);
} }
@ -94,5 +64,7 @@ main (int argc, char **argv)
g_type_init (); g_type_init ();
g_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
g_test_add_func ("/eek-simple-test/create", test_create); g_test_add_func ("/eek-simple-test/create", test_create);
clutter_init (&argc, &argv);
g_test_add_func ("/eek-simple-test/create-clutter", test_create_clutter);
return g_test_run (); return g_test_run ();
} }