diff --git a/data/keyboards/geometry/compact.xml b/data/keyboards/geometry/compact.xml
index 2e0420ef..1fe0d7f5 100644
--- a/data/keyboards/geometry/compact.xml
+++ b/data/keyboards/geometry/compact.xml
@@ -1,57 +1,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -117,4 +68,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Shift_L z x c v b n m BackSpace
+ show_numbers preferences space period Return
+
+
+
+
+ Shift_L Z X C V B N M BackSpace
+ show_numbers preferences space period Return
+
+
+
+ at numbersign dollar percent ampersand minus underscore plus parenleft parenright
+ show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace
+ show_letters preferences space period Return
+
+
+ asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph
+ copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright
+ show_numbers backslash slash less greater equal bracketleft bracketright BackSpace
+ show_letters preferences space period Return
+
diff --git a/data/keyboards/geometry/number-keypad.xml b/data/keyboards/geometry/number-keypad.xml
index 2ce06a58..59e7678e 100644
--- a/data/keyboards/geometry/number-keypad.xml
+++ b/data/keyboards/geometry/number-keypad.xml
@@ -1,42 +1,8 @@
-
-
-
-
-
+
+
@@ -48,58 +14,27 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ 1 2 3 parenleft parenright
+ 4 5 6 numbersign asterisk
+
+
+
diff --git a/data/keyboards/symbols/special/number.xml b/data/keyboards/symbols/special/number.xml
index dc688d9f..cf0fd310 100644
--- a/data/keyboards/symbols/special/number.xml
+++ b/data/keyboards/symbols/special/number.xml
@@ -2,59 +2,116 @@
1
+ 1
+ 1
+ 1
2
+ 2
+ 2
+ 2
3
+ 3
+ 3
+ 3
parenleft
+ parenleft
+ parenleft
+ parenleft
parenright
+ parenright
+ parenright
+ parenright
4
+ 4
+ 4
+ 4
5
+ 5
+ 5
+ 5
6
+ 6
+ 6
+ 6
numbersign
+ numbersign
+ numbersign
+ numbersign
asterisk
+ asterisk
+ asterisk
+ asterisk
7
+ 7
+ 7
+ 7
8
+ 8
+ 8
+ 8
9
+ 9
+ 9
+ 9
plus
+ plus
+ plus
+ plus
minus
+ minus
+ minus
+ minus
0
+ 0
+ 0
+ 0
Return
+ Return
+ Return
+ Return
space
+ space
+ space
+ space
BackSpace
+ BackSpace
+ BackSpace
+ BackSpace
diff --git a/data/keyboards/symbols/us.xml b/data/keyboards/symbols/us.xml
index 43e9e5f5..10f986f6 100644
--- a/data/keyboards/symbols/us.xml
+++ b/data/keyboards/symbols/us.xml
@@ -1,5 +1,7 @@
+ asterisk
+ show_symbols
q
Q
@@ -58,7 +60,7 @@
p
P
0
- U25B3
+ Greek_tau
a
@@ -124,6 +126,9 @@
Return
+ Return
+ Return
+ Return
Shift_L
@@ -175,20 +180,30 @@
period
+ period
+ period
+ period
- show-numbers
- show-numbers
- show-letters
- show-letters
+ show_numbers
+ show_letters
preferences
+ preferences
+ preferences
+ preferences
space
+ space
+ space
+ space
BackSpace
+ BackSpace
+ BackSpace
+ BackSpace
diff --git a/eek/eek-element.c b/eek/eek-element.c
index a830729b..f9b6f3ae 100644
--- a/eek/eek-element.c
+++ b/eek/eek-element.c
@@ -38,8 +38,6 @@ enum {
PROP_0,
PROP_NAME,
PROP_BOUNDS,
- PROP_GROUP,
- PROP_LEVEL,
PROP_LAST
};
@@ -55,20 +53,10 @@ typedef struct _EekElementPrivate
gchar *name;
EekBounds bounds;
EekElement *parent;
- gint group;
- gint level;
} EekElementPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
-static void
-eek_element_real_symbol_index_changed (EekElement *self,
- gint group,
- gint level)
-{
- // g_debug ("symbol-index-changed");
-}
-
static void
eek_element_finalize (GObject *object)
{
@@ -95,12 +83,6 @@ eek_element_set_property (GObject *object,
case PROP_BOUNDS:
eek_element_set_bounds (element, g_value_get_boxed (value));
break;
- case PROP_GROUP:
- eek_element_set_group (element, g_value_get_int (value));
- break;
- case PROP_LEVEL:
- eek_element_set_level (element, g_value_get_int (value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -124,12 +106,6 @@ eek_element_get_property (GObject *object,
eek_element_get_bounds (element, &bounds);
g_value_set_boxed (value, &bounds);
break;
- case PROP_GROUP:
- g_value_set_int (value, eek_element_get_group (element));
- break;
- case PROP_LEVEL:
- g_value_set_int (value, eek_element_get_level (element));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -143,8 +119,6 @@ eek_element_class_init (EekElementClass *klass)
GParamSpec *pspec;
/* signals */
- klass->symbol_index_changed = eek_element_real_symbol_index_changed;
-
gobject_class->set_property = eek_element_set_property;
gobject_class->get_property = eek_element_get_property;
gobject_class->finalize = eek_element_finalize;
@@ -176,65 +150,12 @@ eek_element_class_init (EekElementClass *klass)
g_object_class_install_property (gobject_class,
PROP_BOUNDS,
pspec);
-
- /**
- * EekElement:group:
- *
- * The group value of the symbol index of #EekElement.
- */
- pspec = g_param_spec_int ("group",
- "Group",
- "Group value of the symbol index",
- -1, G_MAXINT, -1,
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class,
- PROP_GROUP,
- pspec);
-
- /**
- * EekElement:level:
- *
- * The level value of the symbol index of #EekElement.
- */
- pspec = g_param_spec_int ("level",
- "Level",
- "Level value of the symbol index",
- -1, G_MAXINT, -1,
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class,
- PROP_LEVEL,
- pspec);
-
- /**
- * EekElement::symbol-index-changed:
- * @element: an #EekElement
- * @group: row index of the symbol matrix of keys on @element
- * @level: column index of the symbol matrix of keys on @element
- *
- * The ::symbol-index-changed signal is emitted each time the
- * global configuration of group/level index changes.
- */
- signals[SYMBOL_INDEX_CHANGED] =
- g_signal_new (I_("symbol-index-changed"),
- G_TYPE_FROM_CLASS(gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(EekElementClass, symbol_index_changed),
- NULL,
- NULL,
- _eek_marshal_VOID__INT_INT,
- G_TYPE_NONE,
- 2,
- G_TYPE_INT,
- G_TYPE_INT);
}
static void
eek_element_init (EekElement *self)
{
- EekElementPrivate *priv = eek_element_get_instance_private (self);
-
- priv->group = -1;
- priv->level = -1;
+ (void)self;
}
/**
@@ -428,144 +349,3 @@ eek_element_set_size (EekElement *element,
bounds.height = height;
eek_element_set_bounds (element, &bounds);
}
-
-/**
- * eek_element_set_symbol_index:
- * @element: an #EekElement
- * @group: row index of the symbol matrix
- * @level: column index of the symbol matrix
- *
- * Set the default index of the symbol matrices of @element. The
- * setting affects the child, if child does not have the index set, as
- * well as this element. To unset, pass -1 as group/level.
- */
-void
-eek_element_set_symbol_index (EekElement *element,
- gint group,
- gint level)
-{
- gboolean emit_signal;
-
- g_return_if_fail (EEK_IS_ELEMENT(element));
-
- emit_signal = group != eek_element_get_group (element) ||
- level != eek_element_get_level (element);
-
- eek_element_set_group (element, group);
- eek_element_set_level (element, level);
-
- if (emit_signal)
- g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0, group, level);
-}
-
-/**
- * eek_element_get_symbol_index:
- * @element: an #EekElement
- * @group: a pointer where the group value of the symbol index will be stored
- * @level: a pointer where the level value of the symbol index will be stored
- *
- * Get the default index of the symbol matrices of @element.
- * If the index is not set, -1 will be returned.
- */
-void
-eek_element_get_symbol_index (EekElement *element,
- gint *group,
- gint *level)
-{
- g_return_if_fail (EEK_IS_ELEMENT(element));
- g_return_if_fail (group != NULL || level != NULL);
- if (group != NULL)
- *group = eek_element_get_group (element);
- if (level != NULL)
- *level = eek_element_get_level (element);
-}
-
-/**
- * eek_element_set_group:
- * @element: an #EekElement
- * @group: group index of @element
- *
- * Set the group value of the default symbol index of @element. To
- * unset, pass -1 as @group.
- *
- * See also: eek_element_set_symbol_index()
- */
-void
-eek_element_set_group (EekElement *element,
- gint group)
-{
- g_return_if_fail (EEK_IS_ELEMENT(element));
-
- EekElementPrivate *priv = eek_element_get_instance_private (element);
-
- if (priv->group != group) {
- priv->group = group;
- g_object_notify (G_OBJECT(element), "group");
- g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
- group, priv->level);
- }
-}
-
-/**
- * eek_element_set_level:
- * @element: an #EekElement
- * @level: level index of @element
- *
- * Set the level value of the default symbol index of @element. To
- * unset, pass -1 as @level.
- *
- * See also: eek_element_set_symbol_index()
- */
-void
-eek_element_set_level (EekElement *element,
- gint level)
-{
- g_return_if_fail (EEK_IS_ELEMENT(element));
-
- EekElementPrivate *priv = eek_element_get_instance_private (element);
-
- if (priv->level != level) {
- priv->level = level;
- g_object_notify (G_OBJECT(element), "level");
- g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
- priv->group, level);
- }
-}
-
-/**
- * eek_element_get_group:
- * @element: an #EekElement
- *
- * Return the group value of the default symbol index of @element.
- * If the value is not set, -1 will be returned.
- *
- * See also: eek_element_get_symbol_index()
- */
-gint
-eek_element_get_group (EekElement *element)
-{
- g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
-
- EekElementPrivate *priv = eek_element_get_instance_private (element);
-
- return priv->group;
-}
-
-/**
- * eek_element_get_level:
- * @element: an #EekElement
- *
- * Return the level value of the default symbol index of @element.
- * If the value is not set, -1 will be returned.
- *
- * See also: eek_element_get_symbol_index()
- */
-gint
-eek_element_get_level (EekElement *element)
-{
- g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
-
- EekElementPrivate *priv = eek_element_get_instance_private (element);
-
- return priv->level;
-}
diff --git a/eek/eek-element.h b/eek/eek-element.h
index 084d7b5f..12d19fdd 100644
--- a/eek/eek-element.h
+++ b/eek/eek-element.h
@@ -36,11 +36,6 @@ struct _EekElementClass
{
/*< private >*/
GObjectClass parent_class;
-
- /* signals */
- void (* symbol_index_changed) (EekElement *self,
- gint group,
- gint level);
};
GType eek_element_get_type (void) G_GNUC_CONST;
@@ -70,18 +65,5 @@ void eek_element_get_absolute_position (EekElement *element,
gdouble *x,
gdouble *y);
-void eek_element_set_symbol_index (EekElement *element,
- gint group,
- gint level);
-void eek_element_get_symbol_index (EekElement *element,
- gint *group,
- gint *level);
-void eek_element_set_group (EekElement *element,
- gint group);
-void eek_element_set_level (EekElement *element,
- gint level);
-gint eek_element_get_group (EekElement *element);
-gint eek_element_get_level (EekElement *element);
-
G_END_DECLS
#endif /* EEK_ELEMENT_H */
diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c
index 4ab85a97..c70637bc 100644
--- a/eek/eek-gtk-keyboard.c
+++ b/eek/eek-gtk-keyboard.c
@@ -32,12 +32,13 @@
#include
#include
-#include "eek-gtk-keyboard.h"
#include "eek-renderer.h"
#include "eek-keyboard.h"
#include "eek-section.h"
#include "eek-key.h"
-#include "eek-symbol.h"
+#include "src/symbol.h"
+
+#include "eek-gtk-keyboard.h"
enum {
PROP_0,
@@ -54,7 +55,7 @@ enum {
typedef struct _EekGtkKeyboardPrivate
{
EekRenderer *renderer;
- EekKeyboard *keyboard;
+ LevelKeyboard *keyboard;
GtkCssProvider *css_provider;
GtkStyleContext *scontext;
@@ -64,13 +65,13 @@ typedef struct _EekGtkKeyboardPrivate
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
static void on_key_pressed (EekKey *key,
- EekGtkKeyboard *self);
+ EekGtkKeyboard *self, guint level);
static void on_key_released (EekKey *key,
EekGtkKeyboard *self);
static void render_pressed_key (GtkWidget *widget,
- EekKey *key);
+ EekKey *key, guint level);
static void render_locked_key (GtkWidget *widget,
- EekKey *key);
+ EekKey *key, guint level);
static void render_released_key (GtkWidget *widget,
EekKey *key);
@@ -95,8 +96,6 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
EekGtkKeyboardPrivate *priv =
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
GtkAllocation allocation;
- GList *list, *head;
-
gtk_widget_get_allocation (self, &allocation);
if (!priv->renderer) {
@@ -113,19 +112,19 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
eek_renderer_render_keyboard (priv->renderer, cr);
+ uint level = priv->keyboard->level;
+
/* redraw pressed key */
- list = eek_keyboard_get_pressed_keys (priv->keyboard);
- for (head = list; head; head = g_list_next (head)) {
- render_pressed_key (self, head->data);
+ const GList *list = priv->keyboard->pressed_keys;
+ for (const GList *head = list; head; head = g_list_next (head)) {
+ render_pressed_key (self, head->data, level);
}
- g_list_free (list);
/* redraw locked key */
- list = eek_keyboard_get_locked_keys (priv->keyboard);
- for (head = list; head; head = g_list_next (head)) {
- render_locked_key (self, ((EekModifierKey *)head->data)->key);
+ list = priv->keyboard->locked_keys;
+ for (const GList *head = list; head; head = g_list_next (head)) {
+ render_locked_key (self, ((EekModifierKey *)head->data)->key, level);
}
- g_list_free (list);
return FALSE;
}
@@ -154,7 +153,8 @@ static void depress(EekGtkKeyboard *self,
if (key) {
eek_keyboard_press_key(priv->keyboard, key, time);
- on_key_pressed(key, self);
+ guint level = priv->keyboard->level;
+ on_key_pressed(key, self, level);
}
}
@@ -164,7 +164,7 @@ static void drag(EekGtkKeyboard *self,
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
GList *list, *head;
- list = eek_keyboard_get_pressed_keys (priv->keyboard);
+ list = g_list_copy(priv->keyboard->pressed_keys);
if (key) {
gboolean found = FALSE;
@@ -181,7 +181,8 @@ static void drag(EekGtkKeyboard *self,
if (!found) {
eek_keyboard_press_key(priv->keyboard, key, time);
- on_key_pressed(key, self);
+ guint level = priv->keyboard->level;
+ on_key_pressed(key, self, level);
}
} else {
for (head = list; head; head = g_list_next (head)) {
@@ -195,7 +196,7 @@ static void drag(EekGtkKeyboard *self,
static void release(EekGtkKeyboard *self, guint32 time) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
- GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
+ GList *list = g_list_copy(priv->keyboard->pressed_keys);
for (GList *head = list; head; head = g_list_next (head)) {
EekKey *key = EEK_KEY(head->data);
eek_keyboard_release_key(priv->keyboard, key, time);
@@ -282,7 +283,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
elements, so that the default handler of
EekKeyboard::key-released signal can remove elements from its
internal copy */
- list = eek_keyboard_get_pressed_keys (priv->keyboard);
+ list = g_list_copy(priv->keyboard->pressed_keys);
for (head = list; head; head = g_list_next (head)) {
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
g_signal_emit_by_name (head->data, "released");
@@ -309,8 +310,8 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
(gdouble)x,
(gdouble)y);
if (key) {
- EekSymbol *symbol = eek_key_get_symbol (key);
- const gchar *text = eek_symbol_get_tooltip (symbol);
+ //struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
+ const gchar *text = NULL; // FIXME
if (text) {
gtk_tooltip_set_text (tooltip, text);
return TRUE;
@@ -321,18 +322,14 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
static void
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
- EekKeyboard *keyboard)
+ LevelKeyboard *keyboard)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
if (priv->keyboard == keyboard)
return;
- if (priv->keyboard) {
- g_object_unref (priv->keyboard);
- }
-
- priv->keyboard = g_object_ref (keyboard);
+ priv->keyboard = keyboard;
}
static void
@@ -341,7 +338,7 @@ eek_gtk_keyboard_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- EekKeyboard *keyboard;
+ LevelKeyboard *keyboard;
switch (prop_id) {
case PROP_KEYBOARD:
@@ -368,14 +365,13 @@ eek_gtk_keyboard_dispose (GObject *object)
if (priv->keyboard) {
GList *list, *head;
- list = eek_keyboard_get_pressed_keys (priv->keyboard);
+ list = g_list_copy(priv->keyboard->pressed_keys);
for (head = list; head; head = g_list_next (head)) {
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
- g_signal_emit_by_name (head->data, "released", priv->keyboard);
+ g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard));
}
g_list_free (list);
- g_object_unref (priv->keyboard);
priv->keyboard = NULL;
}
@@ -443,37 +439,18 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
* Returns: a #GtkWidget
*/
GtkWidget *
-eek_gtk_keyboard_new (EekKeyboard *keyboard)
+eek_gtk_keyboard_new (LevelKeyboard *keyboard)
{
- return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
-}
-
-static void
-magnify_bounds (GtkWidget *self,
- EekBounds *bounds,
- EekBounds *large_bounds,
- gdouble scale)
-{
- GtkAllocation allocation;
- gdouble x, y;
-
- g_assert (scale >= 1.0);
-
- gtk_widget_get_allocation (self, &allocation);
-
- large_bounds->width = bounds->width * scale;
- large_bounds->height = bounds->height * scale;
-
- x = bounds->x - (large_bounds->width - bounds->width) / 2;
- y = bounds->y - large_bounds->height;
-
- large_bounds->x = CLAMP(x, 0, allocation.width - large_bounds->width);
- large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
+ EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
+ EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
+ priv->keyboard = keyboard;
+ return GTK_WIDGET(ret);
}
static void
render_pressed_key (GtkWidget *widget,
- EekKey *key)
+ EekKey *key,
+ guint level)
{
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
@@ -483,7 +460,7 @@ render_pressed_key (GtkWidget *widget,
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
- eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
+ eek_renderer_render_key (priv->renderer, cr, key, level, 1.0, TRUE);
/*
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
*/
@@ -494,7 +471,8 @@ render_pressed_key (GtkWidget *widget,
static void
render_locked_key (GtkWidget *widget,
- EekKey *key)
+ EekKey *key,
+ guint level)
{
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
@@ -504,7 +482,7 @@ render_locked_key (GtkWidget *widget,
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
- eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
+ eek_renderer_render_key (priv->renderer, cr, key, level, 1.0, TRUE);
gdk_window_end_draw_frame (window, context);
@@ -532,7 +510,8 @@ render_released_key (GtkWidget *widget,
static void
on_key_pressed (EekKey *key,
- EekGtkKeyboard *self)
+ EekGtkKeyboard *self,
+ guint level)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
@@ -540,7 +519,7 @@ on_key_pressed (EekKey *key,
if (!priv->renderer)
return;
- render_pressed_key (GTK_WIDGET(self), key);
+ render_pressed_key (GTK_WIDGET(self), key, level);
gtk_widget_queue_draw (GTK_WIDGET(self));
#if HAVE_LIBCANBERRA
diff --git a/eek/eek-gtk-keyboard.h b/eek/eek-gtk-keyboard.h
index 6355d5ec..051dc652 100644
--- a/eek/eek-gtk-keyboard.h
+++ b/eek/eek-gtk-keyboard.h
@@ -45,7 +45,7 @@ struct _EekGtkKeyboardClass
};
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
-GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
+GtkWidget *eek_gtk_keyboard_new (LevelKeyboard *keyboard);
G_END_DECLS
#endif /* EEK_GTK_KEYBOARD_H */
diff --git a/eek/eek-key.c b/eek/eek-key.c
index 91855c6b..0b4b6e3c 100644
--- a/eek/eek-key.c
+++ b/eek/eek-key.c
@@ -29,15 +29,15 @@
#include
-#include "eek-key.h"
#include "eek-section.h"
#include "eek-keyboard.h"
-#include "eek-symbol.h"
+#include "src/keyboard.h"
+#include "src/symbol.h"
+
+#include "eek-key.h"
enum {
PROP_0,
- PROP_KEYCODE,
- PROP_SYMBOL_MATRIX,
PROP_OREF,
PROP_LAST
};
@@ -52,10 +52,8 @@ static guint signals[LAST_SIGNAL] = { 0, };
typedef struct _EekKeyPrivate
{
- guint keycode;
- EekSymbolMatrix *symbol_matrix;
gulong oref; // UI outline reference
- gboolean is_pressed;
+ struct squeek_key *state;
gboolean is_locked;
} EekKeyPrivate;
@@ -89,7 +87,7 @@ eek_key_finalize (GObject *object)
EekKey *self = EEK_KEY (object);
EekKeyPrivate *priv = eek_key_get_instance_private (self);
- eek_symbol_matrix_free (priv->symbol_matrix);
+ squeek_key_free (priv->state);
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
}
@@ -100,15 +98,7 @@ eek_key_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- EekSymbolMatrix *matrix;
switch (prop_id) {
- case PROP_KEYCODE:
- eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
- break;
- case PROP_SYMBOL_MATRIX:
- matrix = g_value_get_boxed (value);
- eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
- break;
case PROP_OREF:
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
break;
@@ -125,13 +115,6 @@ eek_key_get_property (GObject *object,
GParamSpec *pspec)
{
switch (prop_id) {
- case PROP_KEYCODE:
- g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
- break;
- case PROP_SYMBOL_MATRIX:
- g_value_set_boxed (value,
- eek_key_get_symbol_matrix (EEK_KEY(object)));
- break;
case PROP_OREF:
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
break;
@@ -155,30 +138,6 @@ eek_key_class_init (EekKeyClass *klass)
klass->locked = eek_key_real_locked;
klass->unlocked = eek_key_real_unlocked;
- /**
- * EekKey:keycode:
- *
- * The keycode of #EekKey.
- */
- pspec = g_param_spec_uint ("keycode",
- "Keycode",
- "Keycode of the key",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
-
- /**
- * EekKey:symbol-matrix:
- *
- * The symbol matrix of #EekKey.
- */
- pspec = g_param_spec_boxed ("symbol-matrix",
- "Symbol matrix",
- "Symbol matrix of the key",
- EEK_TYPE_SYMBOL_MATRIX,
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
-
/**
* EekKey:oref:
*
@@ -232,9 +191,13 @@ static void
eek_key_init (EekKey *self)
{
EekKeyPrivate *priv = eek_key_get_instance_private (self);
- priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
+ priv->state = squeek_key_new (0);
}
+void eek_key_share_state(EekKey *self, struct squeek_key *state) {
+ EekKeyPrivate *priv = eek_key_get_instance_private (self);
+ priv->state = state;
+}
/**
* eek_key_set_keycode:
* @key: an #EekKey
@@ -254,7 +217,7 @@ eek_key_set_keycode (EekKey *key,
EekKeyPrivate *priv = eek_key_get_instance_private (key);
- priv->keycode = keycode;
+ squeek_key_set_keycode(priv->state, keycode);
}
/**
@@ -271,110 +234,7 @@ eek_key_get_keycode (EekKey *key)
EekKeyPrivate *priv = eek_key_get_instance_private (key);
- return priv->keycode;
-}
-
-/**
- * eek_key_set_symbol_matrix:
- * @key: an #EekKey
- * @matrix: an #EekSymbolMatrix
- *
- * Set the symbol matrix of @key to @matrix.
- */
-void
-eek_key_set_symbol_matrix (EekKey *key,
- EekSymbolMatrix *matrix)
-{
- g_return_if_fail (EEK_IS_KEY(key));
-
- EekKeyPrivate *priv = eek_key_get_instance_private (key);
-
- eek_symbol_matrix_free (priv->symbol_matrix);
- priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
-}
-
-/**
- * eek_key_get_symbol_matrix:
- * @key: an #EekKey
- *
- * Get the symbol matrix of @key.
- * Returns: (transfer none): #EekSymbolMatrix or %NULL
- */
-EekSymbolMatrix *
-eek_key_get_symbol_matrix (EekKey *key)
-{
- g_return_val_if_fail (EEK_IS_KEY(key), NULL);
-
- EekKeyPrivate *priv = eek_key_get_instance_private (key);
-
- return priv->symbol_matrix;
-}
-
-/**
- * eek_key_get_symbol:
- * @key: an #EekKey
- *
- * Get the current symbol of @key.
- * Return value: (transfer none): the current #EekSymbol or %NULL on failure
- */
-EekSymbol *
-eek_key_get_symbol (EekKey *key)
-{
- return eek_key_get_symbol_with_fallback (key, 0, 0);
-}
-
-/**
- * eek_key_get_symbol_with_fallback:
- * @key: an #EekKey
- * @fallback_group: fallback group index
- * @fallback_level: fallback level index
- *
- * Get the current symbol of @key.
- * Return value: (transfer none): the current #EekSymbol or %NULL on failure
- */
-EekSymbol *
-eek_key_get_symbol_with_fallback (EekKey *key,
- gint fallback_group,
- gint fallback_level)
-{
- gint group, level;
-
- g_return_val_if_fail (EEK_IS_KEY (key), NULL);
- g_return_val_if_fail (fallback_group >= 0, NULL);
- g_return_val_if_fail (fallback_level >= 0, NULL);
-
- eek_element_get_symbol_index (EEK_ELEMENT(key), &group, &level);
-
- if (group < 0 || level < 0) {
- EekElement *section;
-
- section = eek_element_get_parent (EEK_ELEMENT(key));
- g_return_val_if_fail (EEK_IS_SECTION (section), NULL);
-
- if (group < 0)
- group = eek_element_get_group (section);
-
- if (level < 0)
- level = eek_element_get_level (section);
-
- if (group < 0 || level < 0) {
- EekElement *keyboard;
-
- keyboard = eek_element_get_parent (section);
- g_return_val_if_fail (EEK_IS_KEYBOARD (keyboard), NULL);
-
- if (group < 0)
- group = eek_element_get_group (keyboard);
- if (level < 0)
- level = eek_element_get_level (keyboard);
- }
- }
-
- return eek_key_get_symbol_at_index (key,
- group,
- level,
- fallback_group,
- fallback_level);
+ return squeek_key_get_keycode(priv->state);
}
/**
@@ -388,46 +248,13 @@ eek_key_get_symbol_with_fallback (EekKey *key,
* Get the symbol at (@group, @level) in the symbol matrix of @key.
* Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
*/
-EekSymbol *
+struct squeek_symbol*
eek_key_get_symbol_at_index (EekKey *key,
gint group,
- gint level,
- gint fallback_group,
- gint fallback_level)
+ guint level)
{
EekKeyPrivate *priv = eek_key_get_instance_private (key);
- gint num_symbols;
-
- g_return_val_if_fail (fallback_group >= 0, NULL);
- g_return_val_if_fail (fallback_level >= 0, NULL);
-
- if (group < 0)
- group = fallback_group;
- if (level < 0)
- level = fallback_level;
-
- if (!priv->symbol_matrix)
- return NULL;
-
- num_symbols = priv->symbol_matrix->num_groups *
- priv->symbol_matrix->num_levels;
- if (num_symbols == 0)
- return NULL;
-
- if (group >= priv->symbol_matrix->num_groups) {
- if (fallback_group < 0)
- return NULL;
- group = fallback_group;
- }
-
- if (level >= priv->symbol_matrix->num_levels) {
- if (fallback_level < 0)
- return NULL;
- level = fallback_level;
- }
-
- return priv->symbol_matrix->data[group * priv->symbol_matrix->num_levels +
- level];
+ return squeek_key_get_symbol(priv->state, level);
}
/**
@@ -479,9 +306,9 @@ eek_key_is_pressed (EekKey *key)
{
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
- EekKeyPrivate *priv = eek_key_get_instance_private (key);
+ EekKeyPrivate *priv = (EekKeyPrivate*)eek_key_get_instance_private (key);
- return priv->is_pressed;
+ return (bool)squeek_key_is_pressed(priv->state);
}
/**
@@ -506,13 +333,10 @@ void eek_key_set_pressed(EekKey *key, gboolean value)
EekKeyPrivate *priv = eek_key_get_instance_private (key);
- priv->is_pressed = value;
+ squeek_key_set_pressed(priv->state, value);
}
-gboolean
-eek_key_has_label(EekKey *key)
-{
- EekSymbol *symbol = eek_key_get_symbol(key);
- return (eek_symbol_get_label(symbol) != NULL) ||
- (eek_symbol_get_icon_name(symbol) != NULL);
+struct squeek_key *eek_key_get_state(EekKey *key) {
+ EekKeyPrivate *priv = eek_key_get_instance_private (key);
+ return priv->state;
}
diff --git a/eek/eek-key.h b/eek/eek-key.h
index fb82f889..a6699333 100644
--- a/eek/eek-key.h
+++ b/eek/eek-key.h
@@ -26,7 +26,6 @@
#define EEK_KEY_H 1
#include "eek-element.h"
-#include "eek-symbol-matrix.h"
G_BEGIN_DECLS
@@ -59,19 +58,10 @@ 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);
-void eek_key_set_symbol_matrix (EekKey *key,
- EekSymbolMatrix *matrix);
-EekSymbolMatrix *eek_key_get_symbol_matrix (EekKey *key);
-EekSymbol *eek_key_get_symbol (EekKey *key);
-EekSymbol *eek_key_get_symbol_with_fallback
- (EekKey *key,
- gint fallback_group,
- gint fallback_level);
-EekSymbol *eek_key_get_symbol_at_index (EekKey *key,
+struct squeek_key *eek_key_get_state(EekKey *key);
+struct squeek_symbol *eek_key_get_symbol_at_index (EekKey *key,
gint group,
- gint level,
- gint fallback_group,
- gint fallback_level);
+ guint level);
void eek_key_set_oref (EekKey *key,
guint oref);
@@ -81,8 +71,6 @@ gboolean eek_key_is_pressed (EekKey *key);
gboolean eek_key_is_locked (EekKey *key);
void eek_key_set_pressed (EekKey *key,
gboolean value);
-
-gboolean eek_key_has_label (EekKey *key);
-
+void eek_key_share_state(EekKey *self, struct squeek_key *state);
G_END_DECLS
#endif /* EEK_KEY_H */
diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c
index 5319059a..19eb6bb2 100644
--- a/eek/eek-keyboard.c
+++ b/eek/eek-keyboard.c
@@ -30,18 +30,19 @@
#include "config.h"
#include
-#include "eek-keyboard.h"
#include "eek-marshalers.h"
#include "eek-section.h"
#include "eek-key.h"
-#include "eek-symbol.h"
#include "eek-enumtypes.h"
#include "eekboard/key-emitter.h"
#include "keymap.h"
+#include "src/keyboard.h"
+#include "src/symbol.h"
+
+#include "eek-keyboard.h"
enum {
PROP_0,
- PROP_MODIFIER_BEHAVIOR,
PROP_LAST
};
@@ -66,19 +67,7 @@ static guint signals[LAST_SIGNAL] = { 0, };
struct _EekKeyboardPrivate
{
- EekModifierBehavior modifier_behavior;
- EekModifierType modifiers;
- unsigned int old_level;
- GList *pressed_keys;
- GList *locked_keys;
- GArray *outline_array;
-
- /* Map key names to key objects: */
- GHashTable *names;
-
- /* modifiers dynamically assigned at run time */
- EekModifierType num_lock_mask;
- EekModifierType alt_gr_mask;
+ char dummy; // won't run otherwise
};
G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
@@ -115,37 +104,7 @@ on_key_unlocked (EekSection *section,
g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
}
-static void
-on_symbol_index_changed (EekSection *section,
- gint group,
- gint level,
- EekKeyboard *keyboard)
-{
- g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
-}
-
-static void
-section_child_added_cb (EekContainer *container,
- EekElement *element,
- EekKeyboard *keyboard)
-{
- const gchar *name = eek_element_get_name(element);
- g_hash_table_insert (keyboard->priv->names,
- (gpointer)name,
- element);
-}
-
-static void
-section_child_removed_cb (EekContainer *container,
- EekElement *element,
- EekKeyboard *keyboard)
-{
- const gchar *name = eek_element_get_name(element);
- g_hash_table_remove (keyboard->priv->names,
- name);
-}
-
-static EekSection *
+EekSection *
eek_keyboard_real_create_section (EekKeyboard *self)
{
EekSection *section;
@@ -153,12 +112,6 @@ eek_keyboard_real_create_section (EekKeyboard *self)
section = g_object_new (EEK_TYPE_SECTION, NULL);
g_return_val_if_fail (section, NULL);
- g_signal_connect (G_OBJECT(section), "child-added",
- G_CALLBACK(section_child_added_cb), self);
-
- g_signal_connect (G_OBJECT(section), "child-removed",
- G_CALLBACK(section_child_removed_cb), self);
-
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(section));
return section;
@@ -171,10 +124,6 @@ eek_keyboard_set_property (GObject *object,
GParamSpec *pspec)
{
switch (prop_id) {
- case PROP_MODIFIER_BEHAVIOR:
- eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(object),
- g_value_get_enum (value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -188,183 +137,117 @@ eek_keyboard_get_property (GObject *object,
GParamSpec *pspec)
{
switch (prop_id) {
- case PROP_MODIFIER_BEHAVIOR:
- g_value_set_enum (value,
- eek_keyboard_get_modifier_behavior (EEK_KEYBOARD(object)));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
-static void
-set_level_from_modifiers (EekKeyboard *self, EekKey *key)
+/// Updates the state of locked keys based on the key that was activated
+/// FIXME: make independent of what the key are named,
+/// and instead refer to the contained symbols
+static guint
+set_key_states (LevelKeyboard *keyboard,
+ EekKey *key,
+ guint new_level)
{
- EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
+ // Keys locking rules hardcoded for the time being...
+ const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
+ // Lock the shift whenever it's pressed on the baselevel
+ // TODO: need to lock shift on the destination level
+ if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
+ EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
+ modifier_key->modifiers = 0;
+ modifier_key->key = g_object_ref (key);
+ keyboard->locked_keys =
+ g_list_prepend (keyboard->locked_keys, modifier_key);
+ g_signal_emit_by_name (modifier_key->key, "locked");
+ }
+ if (keyboard->level == 1) {
+ // Only shift is locked in this state, unlock on any key press
+ for (GList *head = keyboard->locked_keys; head; ) {
+ EekModifierKey *modifier_key = head->data;
+ GList *next = g_list_next (head);
+ keyboard->locked_keys =
+ g_list_remove_link (keyboard->locked_keys, head);
+ g_signal_emit_by_name (modifier_key->key, "unlocked");
+ g_list_free1 (head);
+ head = next;
+ }
+ return 0;
+ }
+ return new_level;
+}
+
+// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
+static void
+set_level_from_press (LevelKeyboard *keyboard, EekKey *key)
+{
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
-
- /* Use the numbers/letters bit from the old level */
- gint level = priv->old_level & 2;
-
+ guint level = keyboard->level;
/* Handle non-emitting keys */
if (key) {
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
- if (g_strcmp0(name, "ABC123") == 0)
- level ^= 2;
- }
-
- level |= ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0);
-
- switch (priv->old_level) {
- case VIEW_LETTERS_UPPER:
- {
- /* Redirect upper case letters to numbers instead of symbols, clearing
- the shift modifier to keep the modifiers in sync with the level */
- if (level == VIEW_SYMBOLS) {
- level = VIEW_NUMBERS;
- priv->modifiers &= ~EEK_SHIFT_MASK;
+ if (g_strcmp0(name, "show_numbers") == 0) {
+ level = 2;
+ } else if (g_strcmp0(name, "show_letters") == 0) {
+ level = 0;
+ } else if (g_strcmp0(name, "show_symbols") == 0) {
+ level = 3;
+ } else if (g_strcmp0(name, "Shift_L") == 0) {
+ level ^= 1;
}
- break;
- }
- case VIEW_SYMBOLS:
- {
- /* Redirect symbols to lower case letters instead of upper case,
- clearing the shift modifier to keep the modifiers in sync with the
- level */
- if (level == VIEW_LETTERS_UPPER) {
- level = VIEW_LETTERS_LOWER;
- priv->modifiers &= ~EEK_SHIFT_MASK;
- }
- break;
- }
- case VIEW_LETTERS_LOWER: /* Direct transitions between views */
- case VIEW_NUMBERS:
- default:
- break;
}
- if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
- priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
- else
- priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
+ keyboard->level = set_key_states(keyboard, key, level);
- priv->old_level = level;
- eek_element_set_level (EEK_ELEMENT(self), level);
-
- eek_layout_update_layout(self);
+ eek_layout_update_layout(keyboard);
}
-static void
-set_modifiers_with_key (EekKeyboard *self,
- EekKey *key,
- EekModifierType modifiers)
-{
- EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
- EekModifierType enabled = (priv->modifiers ^ modifiers) & modifiers;
- EekModifierType disabled = (priv->modifiers ^ modifiers) & priv->modifiers;
-
- if (enabled != 0) {
- if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
- EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
- modifier_key->modifiers = enabled;
- modifier_key->key = g_object_ref (key);
- priv->locked_keys =
- g_list_prepend (priv->locked_keys, modifier_key);
- g_signal_emit_by_name (modifier_key->key, "locked");
- }
- } else {
- if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
- GList *head;
- for (head = priv->locked_keys; head; ) {
- EekModifierKey *modifier_key = head->data;
- if (modifier_key->modifiers & disabled) {
- GList *next = g_list_next (head);
- priv->locked_keys =
- g_list_remove_link (priv->locked_keys, head);
- g_signal_emit_by_name (modifier_key->key, "unlocked");
- g_list_free1 (head);
- head = next;
- } else
- head = g_list_next (head);
- }
- }
- }
-
- priv->modifiers = modifiers;
-}
-
-void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) {
- EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
-
+void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp) {
eek_key_set_pressed(key, TRUE);
- priv->pressed_keys = g_list_prepend (priv->pressed_keys, key);
+ keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key);
- EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
+ struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
+ key, 0, keyboard->level
+ );
if (!symbol)
return;
- EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
- if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
- set_modifiers_with_key (keyboard, key, priv->modifiers | modifier);
- set_level_from_modifiers (keyboard, key);
- }
+ // Only take action about setting level *after* the key has taken effect, i.e. on release
+ //set_level_from_press (keyboard, key);
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
guint keycode = eek_key_get_keycode (key);
- EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard);
- emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
+ emit_key_activated(keyboard->manager, keyboard, keycode, symbol, 0, TRUE, timestamp);
}
-void eek_keyboard_release_key( EekKeyboard *keyboard,
+void eek_keyboard_release_key(LevelKeyboard *keyboard,
EekKey *key,
guint32 timestamp) {
- EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
-
- for (GList *head = priv->pressed_keys; head; head = g_list_next (head)) {
+ for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) {
if (head->data == key) {
- priv->pressed_keys = g_list_remove_link (priv->pressed_keys, head);
+ keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head);
g_list_free1 (head);
break;
}
}
- EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
+ struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
+ key, 0, keyboard->level);
if (!symbol)
return;
- EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
-
- if (!symbol)
- return;
-
- modifier = eek_symbol_get_modifier_mask (symbol);
- switch (priv->modifier_behavior) {
- case EEK_MODIFIER_BEHAVIOR_NONE:
- set_modifiers_with_key (keyboard, key, priv->modifiers & ~modifier);
- break;
- case EEK_MODIFIER_BEHAVIOR_LOCK:
- priv->modifiers ^= modifier;
- break;
- case EEK_MODIFIER_BEHAVIOR_LATCH:
- if (modifier)
- set_modifiers_with_key (keyboard, key, priv->modifiers ^ modifier);
- else
- set_modifiers_with_key (keyboard, key,
- (priv->modifiers ^ modifier) & modifier);
- break;
- }
- set_level_from_modifiers (keyboard, key);
+ set_level_from_press (keyboard, key);
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
guint keycode = eek_key_get_keycode (key);
- guint modifiers = eek_keyboard_get_modifiers (keyboard);
- emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
+ emit_key_activated(keyboard->manager, keyboard, keycode, symbol, 0, FALSE, timestamp);
}
static void
@@ -376,25 +259,27 @@ eek_keyboard_dispose (GObject *object)
static void
eek_keyboard_finalize (GObject *object)
{
- EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
- guint i;
+ G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
+}
- g_list_free (priv->pressed_keys);
- g_list_free_full (priv->locked_keys,
- (GDestroyNotify) eek_modifier_key_free);
-
- g_hash_table_destroy (priv->names);
-
- for (i = 0; i < priv->outline_array->len; i++) {
- EekOutline *outline = &g_array_index (priv->outline_array,
+void level_keyboard_deinit(LevelKeyboard *self) {
+ g_hash_table_destroy (self->names);
+ for (guint i = 0; i < self->outline_array->len; i++) {
+ EekOutline *outline = &g_array_index (self->outline_array,
EekOutline,
i);
g_slice_free1 (sizeof (EekPoint) * outline->num_points,
outline->points);
}
- g_array_free (priv->outline_array, TRUE);
-
- G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
+ g_array_free (self->outline_array, TRUE);
+ for (guint i = 0; i < 4; i++) {
+ // free self->view[i];
+ }
+}
+
+void level_keyboard_free(LevelKeyboard *self) {
+ level_keyboard_deinit(self);
+ g_free(self);
}
static void
@@ -405,8 +290,6 @@ eek_keyboard_real_child_added (EekContainer *self,
G_CALLBACK(on_key_locked), self);
g_signal_connect (element, "key-unlocked",
G_CALLBACK(on_key_unlocked), self);
- g_signal_connect (element, "symbol-index-changed",
- G_CALLBACK(on_symbol_index_changed), self);
}
static void
@@ -422,9 +305,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
{
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- klass->create_section = eek_keyboard_real_create_section;
/* signals */
container_class->child_added = eek_keyboard_real_child_added;
@@ -435,21 +315,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
gobject_class->dispose = eek_keyboard_dispose;
gobject_class->finalize = eek_keyboard_finalize;
- /**
- * EekKeyboard:modifier-behavior:
- *
- * The modifier handling mode of #EekKeyboard.
- */
- pspec = g_param_spec_enum ("modifier-behavior",
- "Modifier behavior",
- "Modifier handling mode of the keyboard",
- EEK_TYPE_MODIFIER_BEHAVIOR,
- EEK_MODIFIER_BEHAVIOR_NONE,
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class,
- PROP_MODIFIER_BEHAVIOR,
- pspec);
-
/**
* EekKeyboard::key-locked:
* @keyboard: an #EekKeyboard
@@ -495,26 +360,22 @@ static void
eek_keyboard_init (EekKeyboard *self)
{
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
- self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
- self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
- self->priv->names = g_hash_table_new (g_str_hash, g_str_equal);
- eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
self->scale = 1.0;
}
-/**
- * eek_keyboard_create_section:
- * @keyboard: an #EekKeyboard
- *
- * Create an #EekSection instance and append it to @keyboard. This
- * function is rarely called by application but called by #EekLayout
- * implementation.
- */
-EekSection *
-eek_keyboard_create_section (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
- return EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
+void level_keyboard_init(LevelKeyboard *self) {
+ self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
+}
+
+LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash) {
+ LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
+ level_keyboard_init(keyboard);
+ for (uint i = 0; i < 4; i++) {
+ keyboard->views[i] = views[i];
+ }
+ keyboard->manager = manager;
+ keyboard->names = name_key_hash;
+ return keyboard;
}
/**
@@ -526,12 +387,10 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
* Return value: (transfer none): #EekKey whose name is @name
*/
EekKey *
-eek_keyboard_find_key_by_name (EekKeyboard *keyboard,
+eek_keyboard_find_key_by_name (LevelKeyboard *keyboard,
const gchar *name)
{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
- return g_hash_table_lookup (keyboard->priv->names,
- name);
+ return g_hash_table_lookup (keyboard->names, name);
}
/**
@@ -554,82 +413,6 @@ eek_keyboard_get_size (EekKeyboard *keyboard,
*height = bounds.height;
}
-/**
- * eek_keyboard_set_modifier_behavior:
- * @keyboard: an #EekKeyboard
- * @modifier_behavior: modifier behavior of @keyboard
- *
- * Set the modifier handling mode of @keyboard.
- */
-void
-eek_keyboard_set_modifier_behavior (EekKeyboard *keyboard,
- EekModifierBehavior modifier_behavior)
-{
- g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
- keyboard->priv->modifier_behavior = modifier_behavior;
-}
-
-/**
- * eek_keyboard_get_modifier_behavior:
- * @keyboard: an #EekKeyboard
- *
- * Get the modifier handling mode of @keyboard.
- * Returns: #EekModifierBehavior
- */
-EekModifierBehavior
-eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
- return keyboard->priv->modifier_behavior;
-}
-
-void
-eek_keyboard_set_modifiers (EekKeyboard *keyboard,
- EekModifierType modifiers)
-{
- g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
- keyboard->priv->modifiers = modifiers;
- set_level_from_modifiers (keyboard, NULL);
-}
-
-/**
- * eek_keyboard_get_modifiers:
- * @keyboard: an #EekKeyboard
- *
- * Get the current modifier status of @keyboard.
- * Returns: #EekModifierType
- */
-EekModifierType
-eek_keyboard_get_modifiers (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
- return keyboard->priv->modifiers;
-}
-
-/**
- * eek_keyboard_add_outline:
- * @keyboard: an #EekKeyboard
- * @outline: an #EekOutline
- *
- * Register an outline of @keyboard.
- * Returns: an unsigned integer ID of the registered outline, for
- * later reference
- */
-guint
-eek_keyboard_add_outline (EekKeyboard *keyboard,
- EekOutline *outline)
-{
- EekOutline *_outline;
-
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
-
- _outline = eek_outline_copy (outline);
- g_array_append_val (keyboard->priv->outline_array, *_outline);
- /* don't use eek_outline_free here, so as to keep _outline->points */
- g_slice_free (EekOutline, _outline);
- return keyboard->priv->outline_array->len - 1;
-}
-
/**
* eek_keyboard_get_outline:
* @keyboard: an #EekKeyboard
@@ -639,117 +422,13 @@ eek_keyboard_add_outline (EekKeyboard *keyboard,
* Returns: an #EekOutline, which should not be released
*/
EekOutline *
-eek_keyboard_get_outline (EekKeyboard *keyboard,
+level_keyboard_get_outline (LevelKeyboard *keyboard,
guint oref)
{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
-
- if (oref > keyboard->priv->outline_array->len)
+ if (oref > keyboard->outline_array->len)
return NULL;
- return &g_array_index (keyboard->priv->outline_array, EekOutline, oref);
-}
-
-/**
- * eek_keyboard_get_n_outlines:
- * @keyboard: an #EekKeyboard
- *
- * Get the number of outlines defined in @keyboard.
- * Returns: integer
- */
-gsize
-eek_keyboard_get_n_outlines (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
- return keyboard->priv->outline_array->len;
-}
-
-/**
- * eek_keyboard_set_num_lock_mask:
- * @keyboard: an #EekKeyboard
- * @num_lock_mask: an #EekModifierType
- *
- * Set modifier mask used as Num_Lock.
- */
-void
-eek_keyboard_set_num_lock_mask (EekKeyboard *keyboard,
- EekModifierType num_lock_mask)
-{
- g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
- keyboard->priv->num_lock_mask = num_lock_mask;
-}
-
-/**
- * eek_keyboard_get_num_lock_mask:
- * @keyboard: an #EekKeyboard
- *
- * Get modifier mask used as Num_Lock.
- * Returns: an #EekModifierType
- */
-EekModifierType
-eek_keyboard_get_num_lock_mask (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
- return keyboard->priv->num_lock_mask;
-}
-
-/**
- * eek_keyboard_set_alt_gr_mask:
- * @keyboard: an #EekKeyboard
- * @alt_gr_mask: an #EekModifierType
- *
- * Set modifier mask used as Alt_Gr.
- */
-void
-eek_keyboard_set_alt_gr_mask (EekKeyboard *keyboard,
- EekModifierType alt_gr_mask)
-{
- g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
- keyboard->priv->alt_gr_mask = alt_gr_mask;
-}
-
-/**
- * eek_keyboard_get_alt_gr_mask:
- * @keyboard: an #EekKeyboard
- *
- * Get modifier mask used as Alt_Gr.
- * Returns: an #EekModifierType
- */
-EekModifierType
-eek_keyboard_get_alt_gr_mask (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
- return keyboard->priv->alt_gr_mask;
-}
-
-/**
- * eek_keyboard_get_pressed_keys:
- * @keyboard: an #EekKeyboard
- *
- * Get pressed keys.
- * Returns: (transfer container) (element-type EekKey): A list of
- * pressed keys.
- */
-GList *
-eek_keyboard_get_pressed_keys (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
- return g_list_copy (keyboard->priv->pressed_keys);
-}
-
-/**
- * eek_keyboard_get_locked_keys:
- * @keyboard: an #EekKeyboard
- *
- * Get locked keys.
- * Returns: (transfer container) (element-type Eek.ModifierKey): A list
- * of locked keys.
- */
-GList *
-eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
-{
- g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
- return g_list_copy (keyboard->priv->locked_keys);
+ return &g_array_index (keyboard->outline_array, EekOutline, oref);
}
/**
@@ -760,7 +439,7 @@ eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
* Returns: a string containing the XKB keymap.
*/
gchar *
-eek_keyboard_get_keymap(EekKeyboard *keyboard)
+eek_keyboard_get_keymap(LevelKeyboard *keyboard)
{
/* Start the keycodes and symbols sections with their respective headers. */
gchar *keycodes = g_strdup(keymap_keycodes_header);
@@ -768,14 +447,15 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
/* Iterate over the keys in the name-to-key hash table. */
GHashTableIter iter;
- gpointer key_name, key_ptr;
- g_hash_table_iter_init(&iter, keyboard->priv->names);
+ gchar *key_name;
+ gpointer key_ptr;
+ g_hash_table_iter_init(&iter, keyboard->names);
- while (g_hash_table_iter_next(&iter, &key_name, &key_ptr)) {
+ while (g_hash_table_iter_next(&iter, (gpointer)&key_name, &key_ptr)) {
gchar *current, *line;
EekKey *key = EEK_KEY(key_ptr);
- int keycode = eek_key_get_keycode(key);
+ guint keycode = eek_key_get_keycode(key);
/* Don't include invalid keycodes in the keymap. */
if (keycode == EEK_INVALID_KEYCODE)
@@ -789,45 +469,13 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
g_free(line);
g_free(current);
- /* Find the symbols associated with the key. */
- EekSymbolMatrix *matrix = eek_key_get_symbol_matrix(key);
- EekSymbol *syms[4];
- int i, j;
-
- /* Get the symbols for all the levels defined for the key, then
- pad it out with the first symbol for all levels up to the fourth. */
- for (i = 0; i < matrix->num_levels; ++i)
- syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i);
-
- while (i < 4) {
- syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, 0);
- i++;
- }
-
- /* The four levels are split into two groups in the keymap.
- Generate strings for each of these groups, where an empty group is
- treated specially. */
-
- gchar *groups[2];
- for (i = 0, j = 0; i < 2; ++i, j += 2) {
- if (syms[j] && syms[j + 1])
- groups[i] = g_strjoin(", ", eek_symbol_get_name(syms[j]),
- eek_symbol_get_name(syms[j + 1]),
- NULL);
- else
- groups[i] = "";
- }
-
- /* Append a key definition to the symbols section. */
+ // FIXME: free
+ const char *key_str = squeek_key_to_keymap_entry(
+ (char*)key_name,
+ eek_key_get_state(key)
+ );
current = symbols;
- line = g_strdup_printf(" key <%s> { [ %s ], [ %s ] };\n",
- (char *)key_name, groups[0], groups[1]);
-
- g_free(groups[0]);
- g_free(groups[1]);
-
- symbols = g_strconcat(current, line, NULL);
- g_free(line);
+ symbols = g_strconcat(current, key_str, NULL);
g_free(current);
}
@@ -841,3 +489,8 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
g_free(symbols);
return keymap;
}
+
+EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard)
+{
+ return keyboard->views[keyboard->level];
+}
diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h
index 615e6fd2..3508a93c 100644
--- a/eek/eek-keyboard.h
+++ b/eek/eek-keyboard.h
@@ -59,12 +59,7 @@ struct _EekKeyboard
EekContainer parent;
EekKeyboardPrivate *priv;
- struct xkb_keymap *keymap;
- int keymap_fd; // keymap formatted as XKB string
- size_t keymap_len; // length of the data inside keymap_fd
double scale;
-
- EekboardContextService *manager; // unowned reference
};
/**
@@ -88,8 +83,6 @@ struct _EekKeyboardClass
gpointer get_symbol_index;
/*< public >*/
- EekSection *(* create_section) (EekKeyboard *self);
-
EekKey *(* find_key_by_name) (EekKeyboard *self,
const gchar *name);
@@ -124,8 +117,28 @@ struct _EekModifierKey {
};
typedef struct _EekModifierKey EekModifierKey;
+/// Keyboard state holder
+struct _LevelKeyboard {
+ EekKeyboard *views[4];
+ guint level;
+ struct xkb_keymap *keymap;
+ int keymap_fd; // keymap formatted as XKB string
+ size_t keymap_len; // length of the data inside keymap_fd
+ GArray *outline_array;
-EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
+ GList *pressed_keys;
+ GList *locked_keys;
+
+ /* Map key names to key objects: */
+ GHashTable *names;
+
+ guint id; // as a key to layout choices
+
+ EekboardContextService *manager; // unowned reference
+};
+typedef struct _LevelKeyboard LevelKeyboard;
+
+LevelKeyboard *eek_keyboard_new(EekboardContextService *manager,
EekLayout *layout,
gdouble initial_width,
gdouble initial_height);
@@ -140,61 +153,37 @@ void eek_keyboard_set_size
gdouble width,
gdouble height);
-void eek_keyboard_set_modifier_behavior
- (EekKeyboard *keyboard,
- EekModifierBehavior modifier_behavior);
-EekModifierBehavior eek_keyboard_get_modifier_behavior
- (EekKeyboard *keyboard);
-void eek_keyboard_set_modifiers
- (EekKeyboard *keyboard,
- EekModifierType modifiers);
-EekModifierType eek_keyboard_get_modifiers
- (EekKeyboard *keyboard);
-
EekSection *eek_keyboard_create_section
(EekKeyboard *keyboard);
EekKey *eek_keyboard_find_key_by_name
- (EekKeyboard *keyboard,
+ (LevelKeyboard *keyboard,
const gchar *name);
-guint eek_keyboard_add_outline
- (EekKeyboard *keyboard,
- EekOutline *outline);
-
-EekOutline *eek_keyboard_get_outline
- (EekKeyboard *keyboard,
+EekOutline *level_keyboard_get_outline
+ (LevelKeyboard *keyboard,
guint oref);
-gsize eek_keyboard_get_n_outlines
- (EekKeyboard *keyboard);
-
-void eek_keyboard_set_num_lock_mask
- (EekKeyboard *keyboard,
- EekModifierType num_lock_mask);
-EekModifierType eek_keyboard_get_num_lock_mask
- (EekKeyboard *keyboard);
-
-void eek_keyboard_set_alt_gr_mask
- (EekKeyboard *keyboard,
- EekModifierType alt_gr_mask);
-EekModifierType eek_keyboard_get_alt_gr_mask
- (EekKeyboard *keyboard);
-
-GList *eek_keyboard_get_pressed_keys
- (EekKeyboard *keyboard);
-GList *eek_keyboard_get_locked_keys
- (EekKeyboard *keyboard);
-
EekModifierKey *eek_modifier_key_copy
(EekModifierKey *modkey);
void eek_modifier_key_free
(EekModifierKey *modkey);
-void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
-void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
+void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
+void eek_keyboard_release_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
gchar * eek_keyboard_get_keymap
- (EekKeyboard *keyboard);
+ (LevelKeyboard *keyboard);
+
+EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard);
+LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash);
+void level_keyboard_deinit(LevelKeyboard *self);
+void level_keyboard_free(LevelKeyboard *self);
+/* Create an #EekSection instance and append it to @keyboard. This
+* function is rarely called by application but called by #EekLayout
+* implementation.
+*/
+EekSection *
+eek_keyboard_real_create_section (EekKeyboard *self);
G_END_DECLS
#endif /* EEK_KEYBOARD_H */
diff --git a/eek/eek-keysym.c b/eek/eek-keysym.c
index 5518e546..807c8beb 100644
--- a/eek/eek-keysym.c
+++ b/eek/eek-keysym.c
@@ -25,11 +25,7 @@
#include "config.h"
-#include
-#include
-
#include "eek-keysym.h"
-#include "eek-serializable.h"
/* modifier keys */
#define EEK_KEYSYM_Shift_L 0xffe1
@@ -59,204 +55,13 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
#include "eek-unicode-keysym-entries.h"
#include "eek-xkeysym-keysym-entries.h"
-
-static gchar *
-unichar_to_utf8 (gunichar uc)
+guint32
+eek_keysym_from_name (const gchar *name)
{
- if (g_unichar_isgraph (uc)) {
- gchar *buf;
- gint len;
-
- len = g_unichar_to_utf8 (uc, NULL);
- buf = g_malloc0 (len + 1);
- g_unichar_to_utf8 (uc, buf);
- return buf;
- }
- return g_strdup ("");
-}
-
-static int
-keysym_entry_compare_by_xkeysym (const void *key0, const void *key1)
-{
- const EekKeysymEntry *entry0 = key0, *entry1 = key1;
- return (gint) (entry0->xkeysym - entry1->xkeysym);
-}
-
-static EekKeysymEntry *
-find_keysym_entry_by_xkeysym (guint xkeysym,
- const EekKeysymEntry *entries,
- gint num_entries)
-{
- EekKeysymEntry key;
-
- key.xkeysym = xkeysym;
- return bsearch (&key, entries, num_entries, sizeof (EekKeysymEntry),
- keysym_entry_compare_by_xkeysym);
-}
-
-static gboolean
-get_unichar (guint xkeysym, gunichar *uc) {
- /* Check for Latin-1 characters (1:1 mapping) */
- if ((xkeysym >= 0x0020 && xkeysym <= 0x007e) ||
- (xkeysym >= 0x00a0 && xkeysym <= 0x00ff)) {
- *uc = xkeysym;
- return TRUE;
- }
-
- /* Also check for directly encoded 24-bit UCS characters:
- */
- if ((xkeysym & 0xff000000) == 0x01000000) {
- *uc = xkeysym & 0x00ffffff;
- return TRUE;
- }
-
- return FALSE;
-}
-
-G_INLINE_FUNC EekModifierType
-get_modifier_mask (guint xkeysym)
-{
- switch (xkeysym) {
- case EEK_KEYSYM_Shift_L:
- case EEK_KEYSYM_Shift_R:
- case EEK_KEYSYM_Caps_Lock:
- case EEK_KEYSYM_Shift_Lock:
- return EEK_SHIFT_MASK;
- case EEK_KEYSYM_ISO_Level3_Shift:
- return EEK_BUTTON1_MASK;
- case EEK_KEYSYM_Control_L:
- case EEK_KEYSYM_Control_R:
- return EEK_CONTROL_MASK;
- case EEK_KEYSYM_Alt_L:
- case EEK_KEYSYM_Alt_R:
- return EEK_MOD1_MASK;
- case EEK_KEYSYM_Meta_L:
- case EEK_KEYSYM_Meta_R:
- return EEK_META_MASK;
- case EEK_KEYSYM_Super_L:
- case EEK_KEYSYM_Super_R:
- return EEK_SUPER_MASK;
- case EEK_KEYSYM_Hyper_L:
- case EEK_KEYSYM_Hyper_R:
- return EEK_HYPER_MASK;
+ for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++) {
+ if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) {
+ return xkeysym_keysym_entries[i].xkeysym;
+ }
}
return 0;
}
-
-/**
- * eek_keysym_new_with_modifier:
- * @xkeysym: an X keysym value
- * @modifier_mask: modifier assigned to @xkeysym
- *
- * Create an #EekKeysym with given X keysym value @xkeysym and
- * modifier @modifier_mask.
- */
-EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
- EekModifierType modifier_mask)
-{
- EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
- *unichar_entry;
- gchar *name, *label;
- gunichar uc;
-
- special_entry =
- find_keysym_entry_by_xkeysym (xkeysym,
- special_keysym_entries,
- G_N_ELEMENTS(special_keysym_entries));
- xkeysym_entry =
- find_keysym_entry_by_xkeysym (xkeysym,
- xkeysym_keysym_entries,
- G_N_ELEMENTS(xkeysym_keysym_entries));
- unicode_entry =
- find_keysym_entry_by_xkeysym (xkeysym,
- unicode_keysym_entries,
- G_N_ELEMENTS(unicode_keysym_entries));
- unichar_entry = NULL;
- if (get_unichar (xkeysym, &uc)) {
- unichar_entry = g_slice_new (EekKeysymEntry);
- unichar_entry->xkeysym = xkeysym;
- unichar_entry->name = unichar_to_utf8 (uc);
- }
-
- name = NULL;
- if (xkeysym_entry) {
- name = g_strdup (xkeysym_entry->name);
- } else if (unichar_entry) {
- name = g_strdup (unichar_entry->name);
- } else if (unicode_entry) {
- name = g_strdup (unicode_entry->name);
- } else {
- name = g_strdup ("");
- }
-
- /* label */
- if (special_entry)
- label = g_strdup (special_entry->name);
- else if (unichar_entry)
- label = g_strdup (unichar_entry->name);
- else if (unicode_entry)
- label = g_strdup (unicode_entry->name);
- else
- label = g_strdup (name);
-
- EekSymbol *keysym = eek_symbol_new(name);
- eek_symbol_set_label(keysym, label);
- eek_symbol_set_modifier_mask(keysym, modifier_mask);
-
- g_free (name);
- g_free (label);
-
- if (unichar_entry) {
- g_free ((gpointer) unichar_entry->name);
- g_slice_free (EekKeysymEntry, unichar_entry);
- }
-
- keysym->xkeysym = xkeysym;
-
- return keysym;
-}
-
-/**
- * eek_keysym_new:
- * @xkeysym: an X keysym value
- *
- * Create an #EekKeysym with given X keysym value @xkeysym.
- */
-EekSymbol*
-eek_keysym_new (guint xkeysym)
-{
- return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
-}
-
-/**
- * eek_keysym_new_from_name:
- * @name: an X keysym name
- *
- * Create an #EekKeysym with an X keysym value looked up by @name.
- */
-EekSymbol*
-eek_keysym_new_from_name (const gchar *name)
-{
- for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
- if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
- return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
-
- EekSymbol *ret = eek_symbol_new(name);
- eek_symbol_set_label(ret, name);
- return ret;
-}
-
-/**
- * eek_keysym_get_xkeysym:
- * @keysym: an #EekKeysym
- *
- * Get an X keysym value associated with @keysym
- */
-guint
-eek_keysym_get_xkeysym (EekSymbol *keysym)
-{
- if (keysym->xkeysym == 0) {
- g_warning("Symbol %s was expected to have a valid keysym", keysym->name);
- }
- return keysym->xkeysym;
-}
diff --git a/eek/eek-keysym.h b/eek/eek-keysym.h
index e257a9c8..3056a165 100644
--- a/eek/eek-keysym.h
+++ b/eek/eek-keysym.h
@@ -25,25 +25,8 @@
#ifndef EEK_KEYSYM_H
#define EEK_KEYSYM_H 1
-#include
-#include "eek-symbol.h"
+#include "glib.h"
-G_BEGIN_DECLS
-
-/**
- * EEK_INVALID_KEYSYM:
- *
- * Pseudo keysym used for error reporting.
- */
-#define EEK_INVALID_KEYSYM (0)
-
-EekSymbol *eek_keysym_new (guint xkeysym);
-guint eek_keysym_get_xkeysym (EekSymbol *keysym);
-
-EekSymbol *eek_keysym_new_from_name (const gchar *name);
-EekSymbol *eek_keysym_new_with_modifier (guint xkeysym,
- EekModifierType modifier_mask);
-
-G_END_DECLS
+guint32 eek_keysym_from_name (const gchar *name);
#endif /* EEK_KEYSYM_H */
diff --git a/eek/eek-layout.c b/eek/eek-layout.c
index 8337450c..ce84e23c 100644
--- a/eek/eek-layout.c
+++ b/eek/eek-layout.c
@@ -31,6 +31,7 @@
#include "eek-layout.h"
#include "eek-keyboard.h"
#include "eekboard/eekboard-context-service.h"
+#include "eek-xml-layout.h"
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
@@ -45,35 +46,13 @@ eek_layout_init (EekLayout *self)
{
}
-/**
- * eek_keyboard_new:
- * @layout: an #EekLayout
- * @initial_width: initial width of the keyboard
- * @initial_height: initial height of the keyboard
- *
- * Create a new #EekKeyboard based on @layout.
- */
-EekKeyboard *
-eek_keyboard_new (EekboardContextService *manager,
- EekLayout *layout,
- gdouble initial_width,
- gdouble initial_height)
-{
- g_assert (EEK_IS_LAYOUT(layout));
- g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
-
- return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
- layout,
- initial_width,
- initial_height);
-}
-
const double section_spacing = 7.0;
struct place_data {
double desired_width;
double current_offset;
- EekKeyboard *keyboard;
+ // Needed for outline (bounds) retrieval
+ LevelKeyboard *keyboard;
};
static void
@@ -87,7 +66,7 @@ section_placer(EekElement *element, gpointer user_data)
eek_element_set_bounds(element, §ion_bounds);
// Sections are rows now. Gather up all the keys and adjust their bounds.
- eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
+ eek_section_place_keys(EEK_SECTION(element), data->keyboard);
eek_element_get_bounds(element, §ion_bounds);
section_bounds.y = data->current_offset;
@@ -105,7 +84,7 @@ section_counter(EekElement *element, gpointer user_data) {
}
void
-eek_layout_place_sections(EekKeyboard *keyboard)
+eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level)
{
/* Order rows */
// This needs to be done after outlines, because outlines define key sizes
@@ -114,23 +93,23 @@ eek_layout_place_sections(EekKeyboard *keyboard)
// The keyboard width is given by the user via screen size. The height will be given dynamically.
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
EekBounds keyboard_bounds = {0};
- eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
+ eek_element_get_bounds(EEK_ELEMENT(level), &keyboard_bounds);
struct place_data placer_data = {
.desired_width = keyboard_bounds.width,
.current_offset = 0,
.keyboard = keyboard,
};
- eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
+ eek_container_foreach_child(EEK_CONTAINER(level), section_placer, &placer_data);
double total_height = 0;
- eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
+ eek_container_foreach_child(EEK_CONTAINER(level), section_counter, &total_height);
keyboard_bounds.height = total_height;
- eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
+ eek_element_set_bounds(EEK_ELEMENT(level), &keyboard_bounds);
}
void
-eek_layout_update_layout(EekKeyboard *keyboard)
+eek_layout_update_layout(LevelKeyboard *keyboard)
{
- eek_layout_place_sections(keyboard);
+ eek_layout_place_sections(keyboard, level_keyboard_current(keyboard));
}
diff --git a/eek/eek-layout.h b/eek/eek-layout.h
index 746adbe3..7ee3195d 100644
--- a/eek/eek-layout.h
+++ b/eek/eek-layout.h
@@ -43,7 +43,7 @@ struct _EekLayoutClass
GObjectClass parent_class;
/*< public >*/
- EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
+ LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
EekLayout *self,
gdouble initial_width,
gdouble initial_height);
@@ -55,9 +55,14 @@ struct _EekLayoutClass
GType eek_layout_get_type (void) G_GNUC_CONST;
-void eek_layout_place_sections(EekKeyboard *keyboard);
+void eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level);
-void eek_layout_update_layout(EekKeyboard *keyboard);
+void eek_layout_update_layout(LevelKeyboard *keyboard);
+
+LevelKeyboard *
+level_keyboard_from_layout (EekLayout *layout,
+ gdouble initial_width,
+ gdouble initial_height);
G_END_DECLS
#endif /* EEK_LAYOUT_H */
diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c
index 5a32e0d3..85837618 100644
--- a/eek/eek-renderer.c
+++ b/eek/eek-renderer.c
@@ -23,15 +23,15 @@
#include
#include
#include
-#include
#include "eek-key.h"
#include "eek-section.h"
+#include "src/symbol.h"
+
#include "eek-renderer.h"
enum {
PROP_0,
- PROP_KEYBOARD,
PROP_PCONTEXT,
PROP_STYLE_CONTEXT,
PROP_LAST
@@ -39,7 +39,7 @@ enum {
typedef struct _EekRendererPrivate
{
- EekKeyboard *keyboard;
+ LevelKeyboard *keyboard;
PangoContext *pcontext;
GtkCssProvider *css_provider;
GtkStyleContext *scontext;
@@ -62,7 +62,6 @@ typedef struct _EekRendererPrivate
GHashTable *active_outline_surface_cache;
GHashTable *icons;
cairo_surface_t *keyboard_surface;
- gulong symbol_index_changed_handler;
} EekRendererPrivate;
@@ -79,21 +78,18 @@ extern void _eek_rounded_polygon (cairo_t *cr,
static void eek_renderer_real_render_key_label (EekRenderer *self,
PangoLayout *layout,
- EekKey *key);
+ EekKey *key, guint level);
static void invalidate (EekRenderer *renderer);
static void render_key (EekRenderer *self,
cairo_t *cr,
- EekKey *key,
+ EekKey *key, guint level,
gboolean active);
-static void on_symbol_index_changed (EekKeyboard *keyboard,
- gint group,
- gint level,
- gpointer user_data);
struct _CreateKeyboardSurfaceCallbackData {
cairo_t *cr;
EekRenderer *renderer;
+ uint level;
};
typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
@@ -114,7 +110,7 @@ create_keyboard_surface_key_callback (EekElement *element,
bounds.width + 100,
bounds.height + 100);
cairo_clip (data->cr);
- render_key (data->renderer, data->cr, EEK_KEY(element), FALSE);
+ render_key (data->renderer, data->cr, EEK_KEY(element), data->level, FALSE);
cairo_restore (data->cr);
}
@@ -152,7 +148,7 @@ render_keyboard_surface (EekRenderer *renderer)
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
- eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
+ eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
data.cr = cairo_create (priv->keyboard_surface);
data.renderer = renderer;
@@ -177,8 +173,9 @@ render_keyboard_surface (EekRenderer *renderer)
foreground.blue,
foreground.alpha);
+ data.level = priv->keyboard->level;
/* draw sections */
- eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
+ eek_container_foreach_child (EEK_CONTAINER(level_keyboard_current(priv->keyboard)),
create_keyboard_surface_section_callback,
&data);
cairo_restore (data.cr);
@@ -198,7 +195,7 @@ render_key_outline (EekRenderer *renderer,
guint oref;
oref = eek_key_get_oref (key);
- outline = eek_keyboard_get_outline (priv->keyboard, oref);
+ outline = level_keyboard_get_outline (priv->keyboard, oref);
if (outline == NULL)
return;
@@ -218,6 +215,7 @@ static void
render_key (EekRenderer *self,
cairo_t *cr,
EekKey *key,
+ guint level,
gboolean active)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
@@ -225,17 +223,14 @@ render_key (EekRenderer *self,
cairo_surface_t *outline_surface;
EekBounds bounds;
guint oref;
- EekSymbol *symbol;
+ struct squeek_symbol *symbol;
GHashTable *outline_surface_cache;
PangoLayout *layout;
PangoRectangle extents = { 0, };
EekColor foreground;
- if (!eek_key_has_label(key))
- return;
-
oref = eek_key_get_oref (key);
- outline = eek_keyboard_get_outline (priv->keyboard, oref);
+ outline = level_keyboard_get_outline (priv->keyboard, oref);
if (outline == NULL)
return;
@@ -280,15 +275,15 @@ render_key (EekRenderer *self,
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
/* render icon (if any) */
- symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
+ symbol = eek_key_get_symbol_at_index (key, 0, level);
if (!symbol)
return;
- if (eek_symbol_get_icon_name (symbol)) {
+ if (squeek_symbol_get_icon_name (symbol)) {
gint scale = priv->scale_factor;
cairo_surface_t *icon_surface =
eek_renderer_get_icon_surface (self,
- eek_symbol_get_icon_name (symbol),
+ squeek_symbol_get_icon_name (symbol),
16 / priv->scale,
scale);
if (icon_surface) {
@@ -316,7 +311,7 @@ render_key (EekRenderer *self,
/* render label */
layout = pango_cairo_create_layout (cr);
- eek_renderer_real_render_key_label (self, layout, key);
+ eek_renderer_real_render_key_label (self, layout, key, level);
pango_layout_get_extents (layout, NULL, &extents);
cairo_save (cr);
@@ -383,21 +378,22 @@ eek_renderer_apply_transformation_for_key (EekRenderer *self,
static void
eek_renderer_real_render_key_label (EekRenderer *self,
PangoLayout *layout,
- EekKey *key)
+ EekKey *key,
+ guint level)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
- EekSymbol *symbol;
+ struct squeek_symbol *symbol;
const gchar *label;
EekBounds bounds;
PangoFontDescription *font;
PangoLayoutLine *line;
gdouble scale;
- symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
+ symbol = eek_key_get_symbol_at_index(key, 0, level);
if (!symbol)
return;
- label = eek_symbol_get_label (symbol);
+ label = squeek_symbol_get_label (symbol);
if (!label)
return;
@@ -464,6 +460,7 @@ static void
eek_renderer_real_render_key (EekRenderer *self,
cairo_t *cr,
EekKey *key,
+ guint level,
gdouble scale,
gboolean rotate)
{
@@ -480,7 +477,7 @@ eek_renderer_real_render_key (EekRenderer *self,
cairo_translate (cr, bounds.x, bounds.y);
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
- render_key (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
+ render_key (self, cr, key, level, eek_key_is_pressed (key) || eek_key_is_locked (key));
cairo_restore (cr);
}
@@ -526,15 +523,6 @@ eek_renderer_set_property (GObject *object,
EEK_RENDERER(object));
switch (prop_id) {
- case PROP_KEYBOARD:
- priv->keyboard = g_value_get_object (value);
- g_object_ref (priv->keyboard);
-
- priv->symbol_index_changed_handler =
- g_signal_connect (priv->keyboard, "symbol-index-changed",
- G_CALLBACK(on_symbol_index_changed),
- object);
- break;
case PROP_PCONTEXT:
priv->pcontext = g_value_get_object (value);
g_object_ref (priv->pcontext);
@@ -555,13 +543,7 @@ eek_renderer_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- EekRendererPrivate *priv = eek_renderer_get_instance_private (
- EEK_RENDERER(object));
-
switch (prop_id) {
- case PROP_KEYBOARD:
- g_value_set_object (value, priv->keyboard);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -575,11 +557,6 @@ eek_renderer_dispose (GObject *object)
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
if (priv->keyboard) {
- if (g_signal_handler_is_connected (priv->keyboard,
- priv->symbol_index_changed_handler))
- g_signal_handler_disconnect (priv->keyboard,
- priv->symbol_index_changed_handler);
- g_object_unref (priv->keyboard);
priv->keyboard = NULL;
}
if (priv->pcontext) {
@@ -623,15 +600,6 @@ eek_renderer_class_init (EekRendererClass *klass)
gobject_class->dispose = eek_renderer_dispose;
gobject_class->finalize = eek_renderer_finalize;
- pspec = g_param_spec_object ("keyboard",
- "Keyboard",
- "Keyboard",
- EEK_TYPE_KEYBOARD,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class,
- PROP_KEYBOARD,
- pspec);
-
pspec = g_param_spec_object ("pango-context",
"Pango Context",
"Pango Context",
@@ -677,7 +645,6 @@ eek_renderer_init (EekRenderer *self)
NULL,
(GDestroyNotify)cairo_surface_destroy);
priv->keyboard_surface = NULL;
- priv->symbol_index_changed_handler = 0;
GtkIconTheme *theme = gtk_icon_theme_get_default ();
@@ -723,26 +690,18 @@ invalidate (EekRenderer *renderer)
}
}
-static void
-on_symbol_index_changed (EekKeyboard *keyboard,
- gint group,
- gint level,
- gpointer user_data)
-{
- EekRenderer *renderer = user_data;
- invalidate (renderer);
-}
-
EekRenderer *
-eek_renderer_new (EekKeyboard *keyboard,
+eek_renderer_new (LevelKeyboard *keyboard,
PangoContext *pcontext,
GtkStyleContext *scontext)
{
- return g_object_new (EEK_TYPE_RENDERER,
- "keyboard", keyboard,
+ EekRenderer *renderer = g_object_new (EEK_TYPE_RENDERER,
"pango-context", pcontext,
"style-context", scontext,
NULL);
+ EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
+ priv->keyboard = keyboard;
+ return renderer;
}
void
@@ -763,7 +722,7 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
/* Calculate a scale factor to use when rendering the keyboard into the
available space. */
- eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
+ eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
gdouble w = (bounds.x * 2) + bounds.width;
gdouble h = (bounds.y * 2) + bounds.height;
@@ -788,7 +747,7 @@ eek_renderer_get_size (EekRenderer *renderer,
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
- eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
+ eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
if (width)
*width = bounds.width;
if (height)
@@ -816,7 +775,7 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
eek_element_get_bounds (EEK_ELEMENT(key), bounds);
eek_element_get_bounds (section, §ion_bounds);
- eek_element_get_bounds (EEK_ELEMENT(priv->keyboard),
+ eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)),
&keyboard_bounds);
if (!rotate) {
@@ -940,6 +899,7 @@ void
eek_renderer_render_key (EekRenderer *renderer,
cairo_t *cr,
EekKey *key,
+ guint level,
gdouble scale,
gboolean rotate)
{
@@ -948,7 +908,7 @@ eek_renderer_render_key (EekRenderer *renderer,
g_return_if_fail (scale >= 0.0);
EEK_RENDERER_GET_CLASS(renderer)->
- render_key (renderer, cr, key, scale, rotate);
+ render_key (renderer, cr, key, level, scale, rotate);
}
void
@@ -1106,7 +1066,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
- eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
+ eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
/* Transform from widget coordinates to keyboard coordinates */
x = (x - priv->origin_x)/priv->scale - bounds.x;
@@ -1125,7 +1085,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
data.key = NULL;
data.renderer = renderer;
- eek_container_find (EEK_CONTAINER(priv->keyboard),
+ eek_container_find (EEK_CONTAINER(level_keyboard_current(priv->keyboard)),
find_key_by_position_section_callback,
&data);
return data.key;
diff --git a/eek/eek-renderer.h b/eek/eek-renderer.h
index 4e322b81..fda2ffad 100644
--- a/eek/eek-renderer.h
+++ b/eek/eek-renderer.h
@@ -21,9 +21,10 @@
#ifndef EEK_RENDERER_H
#define EEK_RENDERER_H 1
+#include
#include
+
#include "eek-keyboard.h"
-#include "eek-keysym.h"
#include "eek-types.h"
G_BEGIN_DECLS
@@ -44,6 +45,7 @@ struct _EekRendererClass
void (* render_key) (EekRenderer *self,
cairo_t *cr,
EekKey *key,
+ guint level,
gdouble scale,
gboolean rotate);
@@ -61,7 +63,7 @@ struct _EekRendererClass
};
GType eek_renderer_get_type (void) G_GNUC_CONST;
-EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
+EekRenderer *eek_renderer_new (LevelKeyboard *keyboard,
PangoContext *pcontext,
GtkStyleContext *scontext);
void eek_renderer_set_allocation_size
@@ -95,7 +97,7 @@ void eek_renderer_render_key_outline
void eek_renderer_render_key (EekRenderer *renderer,
cairo_t *cr,
- EekKey *key,
+ EekKey *key, guint level,
gdouble scale,
gboolean rotate);
diff --git a/eek/eek-section.c b/eek/eek-section.c
index 35078e6f..88508625 100644
--- a/eek/eek-section.c
+++ b/eek/eek-section.c
@@ -32,9 +32,9 @@
#include
#include "eek-keyboard.h"
-#include "eek-section.h"
#include "eek-key.h"
-#include "eek-symbol.h"
+
+#include "eek-section.h"
enum {
PROP_0,
@@ -121,7 +121,8 @@ on_unlocked (EekKey *key,
static EekKey *
eek_section_real_create_key (EekSection *self,
const gchar *name,
- gint keycode)
+ gint keycode,
+ guint oref)
{
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
@@ -130,9 +131,10 @@ eek_section_real_create_key (EekSection *self,
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
"name", name,
- "keycode", keycode,
NULL);
g_return_val_if_fail (key, NULL);
+ eek_key_set_keycode(key, keycode);
+ eek_key_set_oref(key, oref);
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(key));
@@ -140,79 +142,28 @@ eek_section_real_create_key (EekSection *self,
return key;
}
-static void
-set_level_from_modifiers (EekSection *self)
-{
- EekSectionPrivate *priv = eek_section_get_instance_private (self);
- EekKeyboard *keyboard;
- EekModifierType num_lock_mask;
- gint level = -1;
+EekKey *eek_section_create_button(EekSection *self,
+ const gchar *name,
+ struct squeek_key *state) {
+ EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
- keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
- num_lock_mask = eek_keyboard_get_num_lock_mask (keyboard);
- if (priv->modifiers & num_lock_mask)
- level = 1;
- eek_element_set_level (EEK_ELEMENT(self), level);
-}
+ EekRow *row = &priv->row;
+ row->num_columns++;
-static void
-eek_section_real_key_pressed (EekSection *self, EekKey *key)
-{
- EekSectionPrivate *priv = eek_section_get_instance_private (self);
- EekSymbol *symbol;
- EekKeyboard *keyboard;
- EekModifierBehavior behavior;
- EekModifierType modifier;
+ EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
+ "name", name,
+ NULL);
+ g_return_val_if_fail (key, NULL);
+ eek_key_share_state(key, state);
- symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
- if (!symbol)
- return;
-
- keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
- behavior = eek_keyboard_get_modifier_behavior (keyboard);
- modifier = eek_symbol_get_modifier_mask (symbol);
- if (behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
- priv->modifiers |= modifier;
- set_level_from_modifiers (self);
- }
-}
-
-static void
-eek_section_real_key_released (EekSection *self, EekKey *key)
-{
- EekSectionPrivate *priv = eek_section_get_instance_private (self);
- EekSymbol *symbol;
- EekKeyboard *keyboard;
- EekModifierBehavior behavior;
- EekModifierType modifier;
-
- symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
- if (!symbol)
- return;
-
- keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
- behavior = eek_keyboard_get_modifier_behavior (keyboard);
- modifier = eek_symbol_get_modifier_mask (symbol);
- switch (behavior) {
- case EEK_MODIFIER_BEHAVIOR_NONE:
- priv->modifiers &= ~modifier;
- break;
- case EEK_MODIFIER_BEHAVIOR_LOCK:
- priv->modifiers ^= modifier;
- break;
- case EEK_MODIFIER_BEHAVIOR_LATCH:
- priv->modifiers = (priv->modifiers ^ modifier) & modifier;
- break;
- }
- set_level_from_modifiers (self);
+ EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
+ EEK_ELEMENT(key));
+ return key;
}
static void
eek_section_finalize (GObject *object)
{
- EekSection *self = EEK_SECTION (object);
- EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
-
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
}
@@ -278,9 +229,6 @@ eek_section_class_init (EekSectionClass *klass)
klass->create_key = eek_section_real_create_key;
/* signals */
- klass->key_pressed = eek_section_real_key_pressed;
- klass->key_released = eek_section_real_key_released;
-
container_class->child_added = eek_section_real_child_added;
container_class->child_removed = eek_section_real_child_removed;
@@ -456,12 +404,13 @@ eek_section_get_row (EekSection *section,
EekKey *
eek_section_create_key (EekSection *section,
const gchar *name,
- gint keycode)
+ guint keycode,
+ guint oref)
{
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
- return EEK_SECTION_GET_CLASS(section)->create_key (section,
+ return eek_section_real_create_key (section,
name,
- keycode);
+ keycode, oref);
}
const double keyspacing = 4.0;
@@ -477,9 +426,9 @@ keysizer(EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element);
- EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
+ LevelKeyboard *keyboard = user_data;
uint oref = eek_key_get_oref (key);
- EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
+ EekOutline *outline = level_keyboard_get_outline (keyboard, oref);
if (outline && outline->num_points > 0) {
double minx = outline->points[0].x;
double maxx = minx;
@@ -512,11 +461,6 @@ keycounter (EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element);
- /* Skip keys without labels for the current level. This causes those
- keys to be hidden in the visible layout. */
- if (!eek_key_has_label(key))
- return;
-
struct keys_info *data = user_data;
data->count++;
EekBounds key_bounds = {0};
@@ -532,10 +476,6 @@ keyplacer(EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element);
- /* Skip keys without labels for the current level. */
- if (!eek_key_has_label(key))
- return;
-
double *current_offset = user_data;
EekBounds key_bounds = {0};
eek_element_get_bounds(element, &key_bounds);
@@ -546,7 +486,7 @@ keyplacer(EekElement *element, gpointer user_data)
}
void
-eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
+eek_section_place_keys(EekSection *section, LevelKeyboard *keyboard)
{
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
diff --git a/eek/eek-section.h b/eek/eek-section.h
index 03dfa4cf..808d0ff4 100644
--- a/eek/eek-section.h
+++ b/eek/eek-section.h
@@ -28,6 +28,8 @@
#include
#include "eek-container.h"
#include "eek-types.h"
+#include "eek-keyboard.h"
+#include "src/keyboard.h"
G_BEGIN_DECLS
@@ -66,10 +68,6 @@ struct _EekSectionClass
gint keycode);
/* signals */
- void (* key_pressed) (EekSection *self,
- EekKey *key);
- void (* key_released) (EekSection *self,
- EekKey *key);
void (* key_locked) (EekSection *self,
EekKey *key);
void (* key_unlocked) (EekSection *self,
@@ -99,12 +97,11 @@ void eek_section_get_row (EekSection *section,
EekKey *eek_section_create_key (EekSection *section,
const gchar *name,
- gint keycode);
-
-EekKey *eek_section_find_key_by_keycode (EekSection *section,
- guint keycode);
-
-void eek_section_place_keys (EekSection *section, EekKeyboard *keyboard);
+ guint keycode, guint oref);
+EekKey *eek_section_create_button(EekSection *self,
+ const gchar *name,
+ struct squeek_key *state);
+void eek_section_place_keys (EekSection *section, LevelKeyboard *keyboard);
G_END_DECLS
#endif /* EEK_SECTION_H */
diff --git a/eek/eek-symbol-matrix.c b/eek/eek-symbol-matrix.c
deleted file mode 100644
index cdfa24fb..00000000
--- a/eek/eek-symbol-matrix.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2011 Daiki Ueno
- * Copyright (C) 2011 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
- */
-#include "eek-symbol-matrix.h"
-
-EekSymbolMatrix *
-eek_symbol_matrix_new (gint num_groups,
- gint num_levels)
-{
- EekSymbolMatrix *matrix = g_slice_new (EekSymbolMatrix);
-
- matrix->num_groups = num_groups;
- matrix->num_levels = num_levels;
- matrix->data = g_slice_alloc0 (sizeof (EekSymbol *) *
- num_groups * num_levels);
- return matrix;
-}
-
-EekSymbolMatrix *
-eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
-{
- EekSymbolMatrix *retval;
- guint num_symbols = matrix->num_groups * matrix->num_levels;
-
- retval = g_slice_dup (EekSymbolMatrix, matrix);
- retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
- matrix->data);
- // FIXME: do a deep copy over the data in EekSymbol
- return retval;
-}
-
-void
-eek_symbol_matrix_free (EekSymbolMatrix *matrix)
-{
- guint num_symbols = matrix->num_groups * matrix->num_levels;
- g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
- g_slice_free (EekSymbolMatrix, matrix);
-}
-
-GType
-eek_symbol_matrix_get_type (void)
-{
- static GType our_type = 0;
-
- if (our_type == 0)
- our_type =
- g_boxed_type_register_static ("EekSymbolMatrix",
- (GBoxedCopyFunc)eek_symbol_matrix_copy,
- (GBoxedFreeFunc)eek_symbol_matrix_free);
- return our_type;
-}
-
-void
-eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
- gint group,
- gint level,
- EekSymbol *symbol)
-{
- g_return_if_fail (group >= 0 && group < matrix->num_groups);
- g_return_if_fail (level >= 0 && level < matrix->num_levels);
- matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
-}
-
-/**
- * eek_symbol_matrix_get_symbol:
- * @matrix: an #EekSymbolMatrix
- * @group: group index of @matrix
- * @level: level index of @matrix
- *
- * Get an #EekSymbol stored in the cell selected by (@group, @level)
- * in @matrix.
- *
- * Return value: (transfer none): an #EekSymbol.
- */
-EekSymbol *
-eek_symbol_matrix_get_symbol (EekSymbolMatrix *matrix,
- gint group,
- gint level)
-{
- g_return_val_if_fail (group >= 0 && group < matrix->num_groups, NULL);
- g_return_val_if_fail (level >= 0 && level < matrix->num_levels, NULL);
- return matrix->data[group * matrix->num_levels + level];
-}
diff --git a/eek/eek-symbol-matrix.h b/eek/eek-symbol-matrix.h
deleted file mode 100644
index c1ac431a..00000000
--- a/eek/eek-symbol-matrix.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2011 Daiki Ueno
- * Copyright (C) 2011 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_SYMBOL_MATRIX_H
-#define EEK_SYMBOL_MATRIX_H 1
-
-#include "eek-symbol.h"
-
-G_BEGIN_DECLS
-
-/**
- * EekSymbolMatrix:
- * @data: array of symbols
- * @num_groups: the number of groups (rows)
- * @num_levels: the number of levels (columns)
- *
- * Symbol matrix of a key.
- */
-struct _EekSymbolMatrix
-{
- /*< public >*/
- gint num_groups;
- gint num_levels;
- EekSymbol **data;
-};
-
-#define EEK_TYPE_SYMBOL_MATRIX (eek_symbol_matrix_get_type ())
-GType eek_symbol_matrix_get_type (void) G_GNUC_CONST;
-EekSymbolMatrix *eek_symbol_matrix_new (gint num_groups,
- gint num_levels);
-EekSymbolMatrix *eek_symbol_matrix_copy (const EekSymbolMatrix *matrix);
-void eek_symbol_matrix_free (EekSymbolMatrix *matrix);
-
-void eek_symbol_matrix_set_symbol
- (EekSymbolMatrix *matrix,
- gint group,
- gint level,
- EekSymbol *symbol);
-EekSymbol *eek_symbol_matrix_get_symbol
- (EekSymbolMatrix *matrix,
- gint group,
- gint level);
-
-G_END_DECLS
-
-#endif /* EEK_SYMBOL_MATRIX_H */
diff --git a/eek/eek-symbol.c b/eek/eek-symbol.c
index c17bb532..7b4b021c 100644
--- a/eek/eek-symbol.c
+++ b/eek/eek-symbol.c
@@ -30,42 +30,15 @@
#include "eek-symbol.h"
#include "eek-enumtypes.h"
-void
-eek_symbol_destroy (EekSymbol *priv)
-{
- g_free (priv->name);
- g_free (priv->label);
- g_free (priv->icon_name);
- g_free (priv->tooltip);
- g_free(priv->text);
- g_free(priv);
-}
-
EekSymbol *
eek_symbol_new (const gchar *name)
{
EekSymbol *self = g_new0(EekSymbol, 1);
- eek_symbol_set_name(self, name);
+ self->name = g_strdup (name);
self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
return self;
}
-void
-eek_symbol_set_name (EekSymbol *symbol,
- const gchar *name)
-{
- g_free (symbol->name);
- symbol->name = g_strdup (name);
-}
-
-const gchar *
-eek_symbol_get_name (EekSymbol *symbol)
-{
- if (symbol->name == NULL || *symbol->name == '\0')
- return NULL;
- return symbol->name;
-}
-
/**
* eek_symbol_set_label:
* @symbol: an #EekSymbol
@@ -81,20 +54,6 @@ eek_symbol_set_label (EekSymbol *symbol,
symbol->label = g_strdup (label);
}
-/**
- * eek_symbol_get_label:
- * @symbol: an #EekSymbol
- *
- * Get the label text of @symbol.
- */
-const gchar *
-eek_symbol_get_label (EekSymbol *symbol)
-{
- if (symbol->label == NULL || *symbol->label == '\0')
- return NULL;
- return symbol->label;
-}
-
/**
* eek_symbol_set_modifier_mask:
* @symbol: an #EekSymbol
@@ -118,15 +77,10 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
EekModifierType
eek_symbol_get_modifier_mask (EekSymbol *symbol)
{
+ return 0;
return symbol->modifier_mask;
}
-gboolean
-eek_symbol_is_modifier (EekSymbol *symbol)
-{
- return eek_symbol_get_modifier_mask (symbol) != 0;
-}
-
void
eek_symbol_set_icon_name (EekSymbol *symbol,
const gchar *icon_name)
@@ -138,9 +92,7 @@ eek_symbol_set_icon_name (EekSymbol *symbol,
const gchar *
eek_symbol_get_icon_name (EekSymbol *symbol)
{
- if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
- return NULL;
- return symbol->icon_name;
+ return NULL;
}
void
@@ -154,6 +106,7 @@ eek_symbol_set_tooltip (EekSymbol *symbol,
const gchar *
eek_symbol_get_tooltip (EekSymbol *symbol)
{
+ return NULL;
if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
return NULL;
return symbol->tooltip;
diff --git a/eek/eek-symbol.h b/eek/eek-symbol.h
deleted file mode 100644
index 6a0bcfbc..00000000
--- a/eek/eek-symbol.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011 Daiki Ueno
- * Copyright (C) 2011 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
- */
-
-#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
-#error "Only can be included directly."
-#endif
-
-#ifndef EEK_SYMBOL_H
-#define EEK_SYMBOL_H 1
-
-#include "eek-types.h"
-
-G_BEGIN_DECLS
-
-/**
- * EekSymbolCategory:
- * @EEK_SYMBOL_CATEGORY_LETTER: the symbol represents an alphabet letter
- * @EEK_SYMBOL_CATEGORY_FUNCTION: the symbol represents a function
- * @EEK_SYMBOL_CATEGORY_KEYNAME: the symbol does not have meaning but
- * have a name
- * @EEK_SYMBOL_CATEGORY_USER0: reserved for future use
- * @EEK_SYMBOL_CATEGORY_USER1: reserved for future use
- * @EEK_SYMBOL_CATEGORY_USER2: reserved for future use
- * @EEK_SYMBOL_CATEGORY_USER3: reserved for future use
- * @EEK_SYMBOL_CATEGORY_USER4: reserved for future use
- * @EEK_SYMBOL_CATEGORY_UNKNOWN: used for error reporting
- * @EEK_SYMBOL_CATEGORY_LAST: the last symbol category
- *
- * Category of the key symbols.
- */
-typedef enum {
- EEK_SYMBOL_CATEGORY_LETTER,
- EEK_SYMBOL_CATEGORY_FUNCTION,
- EEK_SYMBOL_CATEGORY_KEYNAME,
- EEK_SYMBOL_CATEGORY_USER0,
- EEK_SYMBOL_CATEGORY_USER1,
- EEK_SYMBOL_CATEGORY_USER2,
- EEK_SYMBOL_CATEGORY_USER3,
- EEK_SYMBOL_CATEGORY_USER4,
- EEK_SYMBOL_CATEGORY_UNKNOWN,
- EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
-} EekSymbolCategory;
-
-
-typedef struct _EekSymbol
-{
- /// Canonical name of the symbol
- gchar *name;
- /// Text used to display the symbol
- gchar *label;
- EekSymbolCategory category;
- EekModifierType modifier_mask;
- /// Icon name used to render the symbol
- gchar *icon_name;
- /// Tooltip text
- gchar *tooltip;
-
- // May not be present
- guint xkeysym;
- gchar *text;
-} EekSymbol;
-
-EekSymbol *eek_symbol_new (const gchar *name);
-void eek_symbol_free (EekSymbol *symbol);
-void eek_symbol_set_name (EekSymbol *symbol,
- const gchar *name);
-const gchar *eek_symbol_get_name (EekSymbol *symbol);
-void eek_symbol_set_label (EekSymbol *symbol,
- const gchar *label);
-const gchar *eek_symbol_get_label (EekSymbol *symbol);
-void eek_symbol_set_category (EekSymbol *symbol,
- EekSymbolCategory category);
-EekSymbolCategory eek_symbol_get_category (EekSymbol *symbol);
-EekModifierType eek_symbol_get_modifier_mask (EekSymbol *symbol);
-void eek_symbol_set_modifier_mask (EekSymbol *symbol,
- EekModifierType mask);
-gboolean eek_symbol_is_modifier (EekSymbol *symbol);
-void eek_symbol_set_icon_name (EekSymbol *symbol,
- const gchar *icon_name);
-const gchar *eek_symbol_get_icon_name (EekSymbol *symbol);
-void eek_symbol_set_tooltip (EekSymbol *symbol,
- const gchar *tooltip);
-const gchar * eek_symbol_get_tooltip (EekSymbol *symbol);
-
-const gchar *eek_symbol_category_get_name (EekSymbolCategory category);
-EekSymbolCategory eek_symbol_category_from_name (const gchar *name);
-
-G_END_DECLS
-
-#endif /* EEK_SYMBOL_H */
diff --git a/eek/eek-types.h b/eek/eek-types.h
index 7f3b9eea..51df26a0 100644
--- a/eek/eek-types.h
+++ b/eek/eek-types.h
@@ -150,6 +150,7 @@ typedef struct _EekOutline EekOutline;
typedef struct _EekColor EekColor;
typedef struct _EekboardContextService EekboardContextService;
+typedef struct _LevelKeyboard LevelKeyboard;
/**
* EekPoint:
diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c
index c84b2fae..06771df4 100644
--- a/eek/eek-xml-layout.c
+++ b/eek/eek-xml-layout.c
@@ -27,15 +27,16 @@
#include
#include
-#include "eek-xml-layout.h"
#include "eek-keyboard.h"
#include "eek-section.h"
#include "eek-key.h"
-#include "eek-keysym.h"
-#include "eek-text.h"
+#include "src/keyboard.h"
+#include "src/symbol.h"
#include "squeekboard-resources.h"
+#include "eek-xml-layout.h"
+
enum {
PROP_0,
PROP_ID,
@@ -67,16 +68,16 @@ static GList *parse_prerequisites
(const gchar *path,
GError **error);
static gboolean parse_geometry (const gchar *path,
- EekKeyboard *keyboard,
+ EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash,
GError **error);
static gboolean parse_symbols_with_prerequisites
(const gchar *keyboards_dir,
const gchar *name,
- EekKeyboard *keyboard,
+ LevelKeyboard *keyboard,
GList **loaded,
GError **error);
static gboolean parse_symbols (const gchar *path,
- EekKeyboard *keyboard,
+ LevelKeyboard *keyboard,
GError **error);
static gboolean validate (const gchar **valid_path_list,
@@ -232,40 +233,49 @@ struct _GeometryParseData {
GSList *element_stack;
EekBounds bounds;
- EekKeyboard *keyboard;
+ EekKeyboard **views;
+ guint view_idx;
EekSection *section;
EekKey *key;
- gint num_columns;
gint num_rows;
EekOrientation orientation;
gdouble corner_radius;
GSList *points;
gchar *name;
EekOutline outline;
- gchar *oref;
- gint keycode;
+ gchar *outline_id;
+ guint keycode;
- GHashTable *key_oref_hash;
- GHashTable *oref_outline_hash;
+ GString *text;
+
+ GArray *outline_array;
+
+ GHashTable *name_key_hash; // char* -> EekKey*
+ GHashTable *keyname_oref_hash; // char* -> guint
+ GHashTable *outlineid_oref_hash; // char* -> guint
};
typedef struct _GeometryParseData GeometryParseData;
static GeometryParseData *
-geometry_parse_data_new (EekKeyboard *keyboard)
+geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray *outline_array)
{
GeometryParseData *data = g_slice_new0 (GeometryParseData);
- data->keyboard = g_object_ref (keyboard);
- data->key_oref_hash =
- g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- g_free);
- data->oref_outline_hash =
+ data->views = views;
+ data->outline_array = outline_array;
+ data->keyname_oref_hash =
g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
- (GDestroyNotify)eek_outline_free);
+ NULL);
+ data->outlineid_oref_hash =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+
+ data->name_key_hash = name_key_hash;
+ data->text = g_string_sized_new (BUFSIZE);
data->keycode = 8;
return data;
}
@@ -273,21 +283,19 @@ geometry_parse_data_new (EekKeyboard *keyboard)
static void
geometry_parse_data_free (GeometryParseData *data)
{
- g_object_unref (data->keyboard);
- g_hash_table_destroy (data->key_oref_hash);
- g_hash_table_destroy (data->oref_outline_hash);
+ g_hash_table_destroy (data->keyname_oref_hash);
+ g_hash_table_destroy (data->outlineid_oref_hash);
+ g_string_free (data->text, TRUE);
g_slice_free (GeometryParseData, data);
}
static const gchar *geometry_valid_path_list[] = {
"geometry",
+ "button/geometry",
"bounds/geometry",
- "section/geometry",
+ "view/geometry",
+ "section/view/geometry",
"outline/geometry",
- "bounds/section/geometry",
- "row/section/geometry",
- "key/row/section/geometry",
- "bounds/key/row/section/geometry",
"point/outline/geometry",
};
@@ -355,14 +363,20 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
return;
}
bounds.height = g_strtod (attribute, NULL);
-
- if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
- eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
+ data->bounds = bounds;
goto out;
}
+ if (g_strcmp0 (element_name, "view") == 0) {
+ /* Create an empty keyboard to which geometry and symbols
+ information are applied. */
+ EekKeyboard *view = g_object_new (EEK_TYPE_KEYBOARD, NULL);
+ eek_element_set_bounds (EEK_ELEMENT(view), &data->bounds);
+ data->views[data->view_idx] = view;
+ }
+
if (g_strcmp0 (element_name, "section") == 0) {
- data->section = eek_keyboard_create_section (data->keyboard);
+ data->section = eek_keyboard_real_create_section (data->views[data->view_idx]);
attribute = get_attribute (attribute_names, attribute_values,
"id");
if (attribute != NULL)
@@ -374,62 +388,47 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
angle = strtol (attribute, NULL, 10);
eek_section_set_angle (data->section, angle);
}
+
goto out;
}
- if (g_strcmp0 (element_name, "row") == 0) {
- attribute = get_attribute (attribute_names, attribute_values,
- "orientation");
- if (attribute != NULL)
- data->orientation = strtol (attribute, NULL, 10);
-
- eek_section_add_row (data->section,
- data->num_columns,
- data->orientation);
-
- data->num_rows++;
- goto out;
- }
-
- if (g_strcmp0 (element_name, "key") == 0) {
- guint keycode;
-
- attribute = get_attribute (attribute_names, attribute_values,
+ if (g_strcmp0 (element_name, "button") == 0) {
+ const gchar *base_name = get_attribute (attribute_names, attribute_values,
"name");
- if (attribute == NULL) {
+ if (base_name == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
- "no \"name\" attribute for \"key\"");
+ "no \"name\" attribute for \"button\"");
return;
}
- gchar *name = g_strdup (attribute);
- attribute = get_attribute (attribute_names, attribute_values,
- "keycode");
- if (attribute != NULL)
- keycode = strtol (attribute, NULL, 10);
- else
- keycode = data->keycode++;
-
- data->key = eek_section_create_key (data->section,
- name,
- keycode);
-
- attribute = get_attribute (attribute_names, attribute_values,
+ const gchar *oref_name = get_attribute (attribute_names, attribute_values,
"oref");
- if (attribute == NULL) {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_MISSING_ATTRIBUTE,
- "no \"oref\" attribute for \"key\"");
- return;
+ if (oref_name == NULL) {
+ oref_name = "default";
}
- g_hash_table_insert (data->key_oref_hash,
- data->key,
- g_strdup (attribute));
+ const gchar *keycode_name = get_attribute (attribute_names, attribute_values,
+ "keycode");
- data->num_columns++;
+ guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->outlineid_oref_hash,
+ oref_name));
+ const gchar *name = base_name;
+ g_hash_table_insert (data->keyname_oref_hash,
+ g_strdup(name),
+ GUINT_TO_POINTER(oref));
+
+ EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
+ // never gets used! this section gets executed before any buttons get defined
+ if (key) {
+ if (keycode_name != NULL) {
+ // This sets the keycode for all buttons,
+ // since they share state
+ // TODO: get rid of this in the parser;
+ // this belongs after keymap is defined
+ eek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
+ }
+ }
goto out;
}
@@ -443,7 +442,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
"no \"id\" attribute for \"outline\"");
return;
}
- data->oref = g_strdup (attribute);
+ data->outline_id = g_strdup (attribute);
attribute = get_attribute (attribute_names, attribute_values,
"corner-radius");
@@ -488,6 +487,30 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
out:
data->element_stack = g_slist_prepend (data->element_stack,
g_strdup (element_name));
+ data->text->len = 0;
+}
+
+
+/**
+ * eek_keyboard_add_outline:
+ * @keyboard: an #EekKeyboard
+ * @outline: an #EekOutline
+ *
+ * Register an outline of @keyboard.
+ * Returns: an unsigned integer ID of the registered outline, for
+ * later reference
+ */
+static guint
+add_outline (GArray *outline_array,
+ EekOutline *outline)
+{
+ EekOutline *_outline;
+
+ _outline = eek_outline_copy (outline);
+ g_array_append_val (outline_array, *_outline);
+ /* don't use eek_outline_free here, so as to keep _outline->points */
+ g_slice_free (EekOutline, _outline);
+ return outline_array->len - 1;
}
static void
@@ -503,23 +526,72 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
data->element_stack = g_slist_next (data->element_stack);
g_slist_free1 (head);
+ const gchar *text = g_strndup (data->text->str, data->text->len);
+
+ if (g_strcmp0 (element_name, "view") == 0) {
+ data->view_idx++;
+ return;
+ }
+
if (g_strcmp0 (element_name, "section") == 0) {
+ // Split text on spaces and process each part
+ unsigned head = 0;
+ while (head < strlen(text)) {
+ // Skip to the first non-space character
+ for (; head < strlen(text); head++) {
+ if (text[head] != ' ') {
+ break;
+ }
+ }
+ unsigned start = head;
+
+ // Skip to the first space character
+ for (; head < strlen(text); head++) {
+ if (text[head] == ' ') {
+ break;
+ }
+ }
+ unsigned end = head;
+
+ /// Reached the end
+ if (start == end) {
+ break;
+ }
+
+ gchar *name = g_strndup (&text[start], end - start);
+ EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
+ if (!key) {
+ // Save button name together with its level,
+ // to account for buttons with the same name in multiple levels
+ guint keycode = data->keycode++;
+
+ guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->keyname_oref_hash, name));
+ // default value gives idx 0, which is guaranteed to be occupied
+ key = eek_section_create_key (data->section,
+ name,
+ keycode,
+ oref);
+ g_hash_table_insert (data->name_key_hash,
+ g_strdup(name),
+ key);
+ } else {
+ EekKey *new_key = eek_section_create_button(data->section, name, eek_key_get_state(key));
+ if (!new_key) {
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_MISSING_ATTRIBUTE,
+ "Couldn't create a shared button");
+ return;
+ }
+ eek_key_set_oref(new_key, eek_key_get_oref(key));
+ }
+ }
+
data->section = NULL;
data->num_rows = 0;
return;
}
- if (g_strcmp0 (element_name, "key") == 0) {
- data->key = NULL;
- return;
- }
-
- if (g_strcmp0 (element_name, "row") == 0) {
- data->num_columns = 0;
- data->orientation = EEK_ORIENTATION_HORIZONTAL;
- return;
- }
-
if (g_strcmp0 (element_name, "outline") == 0) {
EekOutline *outline = g_slice_new (EekOutline);
@@ -539,19 +611,30 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
g_slist_free (data->points);
data->points = NULL;
- g_hash_table_insert (data->oref_outline_hash,
- g_strdup (data->oref),
- outline);
+ guint oref = add_outline (data->outline_array, outline);
- g_free (data->oref);
+ g_hash_table_insert (data->outlineid_oref_hash,
+ data->outline_id,
+ GUINT_TO_POINTER(oref));
return;
}
}
+static void
+geometry_text_callback (GMarkupParseContext *pcontext,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ GeometryParseData *data = user_data;
+ g_string_append_len (data->text, text, (gssize)text_len);
+}
+
static const GMarkupParser geometry_parser = {
geometry_start_element_callback,
geometry_end_element_callback,
- 0,
+ geometry_text_callback,
0,
0
};
@@ -560,23 +643,22 @@ struct _SymbolsParseData {
GSList *element_stack;
GString *text;
- EekKeyboard *keyboard;
- EekKey *key;
- GSList *symbols;
+ LevelKeyboard *keyboard;
+ EekKeyboard *view;
+
gchar *label;
gchar *icon;
gchar *tooltip;
guint keyval;
- gint groups;
};
typedef struct _SymbolsParseData SymbolsParseData;
static SymbolsParseData *
-symbols_parse_data_new (EekKeyboard *keyboard)
+symbols_parse_data_new (LevelKeyboard *keyboard)
{
SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
- data->keyboard = g_object_ref (keyboard);
+ data->keyboard = keyboard;
data->text = g_string_sized_new (BUFSIZE);
return data;
}
@@ -584,13 +666,13 @@ symbols_parse_data_new (EekKeyboard *keyboard)
static void
symbols_parse_data_free (SymbolsParseData *data)
{
- g_object_unref (data->keyboard);
g_string_free (data->text, TRUE);
g_slice_free (SymbolsParseData, data);
}
static const gchar *symbols_valid_path_list[] = {
"symbols",
+ "symbol/symbols",
"include/symbols",
"key/symbols",
"text/key/symbols",
@@ -617,37 +699,6 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
error))
return;
- if (g_strcmp0 (element_name, "key") == 0) {
-
- attribute = get_attribute (attribute_names, attribute_values,
- "name");
- if (attribute == NULL) {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_MISSING_ATTRIBUTE,
- "no \"name\" attribute for \"key\"");
- return;
- }
-
- data->key = eek_keyboard_find_key_by_name (data->keyboard,
- attribute);
- if (data->key == NULL) {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_INVALID_CONTENT,
- "no such key %s", attribute);
- }
-
- attribute = get_attribute (attribute_names, attribute_values,
- "groups");
- if (attribute != NULL)
- data->groups = strtol (attribute, NULL, 10);
- else
- data->groups = 1;
- data->symbols = NULL;
- goto out;
- }
-
if (g_strcmp0 (element_name, "keysym") == 0) {
attribute = get_attribute (attribute_names, attribute_values,
"keyval");
@@ -680,7 +731,6 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
data->tooltip = g_strdup (attribute);
}
- out:
data->element_stack = g_slist_prepend (data->element_stack,
g_strdup (element_name));
data->text->len = 0;
@@ -695,80 +745,44 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
SymbolsParseData *data = user_data;
GSList *head = data->element_stack;
gchar *text;
- gint i;
g_free (head->data);
data->element_stack = g_slist_next (data->element_stack);
g_slist_free1 (head);
+ // TODO: this could all be moved to text handler
text = g_strndup (data->text->str, data->text->len);
- if (g_strcmp0 (element_name, "key") == 0) {
- if (!data->key) {
- return;
- }
-
- gint num_symbols = g_slist_length (data->symbols);
- gint levels = num_symbols / data->groups;
- EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
- levels);
- head = data->symbols = g_slist_reverse (data->symbols);
- for (i = 0; i < num_symbols; i++) {
- if (head && head->data) {
- matrix->data[i] = head->data;
- head = g_slist_next (head);
- } else
- matrix->data[i] = NULL;
- }
- g_slist_free (data->symbols);
- data->symbols = NULL;
-
- eek_key_set_symbol_matrix (data->key, matrix);
- eek_symbol_matrix_free (matrix);
- data->key = NULL;
- goto out;
- }
-
if (g_strcmp0 (element_name, "symbol") == 0 ||
g_strcmp0 (element_name, "keysym") == 0 ||
g_strcmp0 (element_name, "text") == 0) {
- EekSymbol *symbol;
- if (g_strcmp0 (element_name, "keysym") == 0) {
- EekSymbol *keysym;
- if (data->keyval != EEK_INVALID_KEYSYM)
- keysym = eek_keysym_new (data->keyval);
- else
- keysym = eek_keysym_new_from_name (text);
- symbol = keysym;
- } else if (g_strcmp0 (element_name, "text") == 0) {
- symbol = eek_text_new (text);
- } else {
- symbol = eek_symbol_new (text);
+ gchar *name = text;
+ EekKey *key = eek_keyboard_find_key_by_name (data->keyboard,
+ name);
+ if (key) {
+ squeek_key_add_symbol(
+ eek_key_get_state(key),
+ element_name,
+ text,
+ data->keyval,
+ data->label,
+ data->icon,
+ data->tooltip
+ );
}
- if (data->label) {
- eek_symbol_set_label (symbol, data->label);
- g_free (data->label);
- data->label = NULL;
- }
- if (data->icon) {
- eek_symbol_set_icon_name (symbol, data->icon);
- g_free (data->icon);
- data->icon = NULL;
- }
- if (data->tooltip) {
- eek_symbol_set_tooltip (symbol, data->tooltip);
- g_free (data->tooltip);
- data->tooltip = NULL;
- }
-
- data->symbols = g_slist_prepend (data->symbols, symbol);
+ data->keyval = 0;
+ g_free(data->label);
+ data->label = NULL;
+ g_free(data->icon);
+ data->icon = NULL;
+ g_free(data->tooltip);
+ data->tooltip = NULL;
goto out;
}
if (g_strcmp0 (element_name, "invalid") == 0) {
- data->symbols = g_slist_prepend (data->symbols, NULL);
goto out;
}
@@ -880,31 +894,37 @@ static const GMarkupParser prerequisites_parser = {
0
};
-static EekKeyboard *
-eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
- EekLayout *self,
- gdouble initial_width,
- gdouble initial_height)
+LevelKeyboard *
+eek_xml_layout_real_create_keyboard (EekLayout *self,
+ EekboardContextService *manager)
{
EekXmlLayout *layout = EEK_XML_LAYOUT (self);
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
gboolean retval;
- /* Create an empty keyboard to which geometry and symbols
- information are applied. */
- EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
- keyboard->manager = manager;
-
/* Read geometry information. */
gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
g_free (filename);
+ GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
+
+ // char* -> EekKey*
+ GHashTable *name_key_hash =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+ // One view for each level
+ EekKeyboard *views[4] = {0};
+
GError *error = NULL;
- retval = parse_geometry (path, keyboard, &error);
+ retval = parse_geometry (path, views, outline_array, name_key_hash, &error);
g_free (path);
if (!retval) {
- g_object_unref (keyboard);
+ for (uint i = 0; i < 4; i++) {
+ g_object_unref (views[i]);
+ }
g_warning ("can't parse geometry file %s: %s",
priv->desc->geometry,
error->message);
@@ -912,6 +932,12 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
return NULL;
}
+
+ LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_key_hash);
+
+ keyboard->outline_array = outline_array;
+ // FIXME: are symbols shared betwen views?
+
/* Read symbols information. */
GList *loaded = NULL;
retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
@@ -921,7 +947,13 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
&error);
g_list_free_full (loaded, g_free);
if (!retval) {
- g_object_unref (keyboard);
+ for (uint i = 0; i < 4; i++) {
+ if (views[i]) {
+ g_object_unref(views[i]);
+ views[i] = NULL;
+ }
+ }
+ //g_object_unref (view);
g_warning ("can't parse symbols file %s: %s",
priv->desc->symbols,
error->message);
@@ -929,11 +961,9 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
return NULL;
}
- eek_layout_place_sections(keyboard);
-
- /* Use pre-defined modifier mask here. */
- eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
- eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK);
+ for (uint i = 0; i < 4; i++) {
+ eek_layout_place_sections(keyboard, views[i]);
+ }
return keyboard;
}
@@ -996,12 +1026,9 @@ eek_xml_layout_finalize (GObject *object)
static void
eek_xml_layout_class_init (EekXmlLayoutClass *klass)
{
- EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
- layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
-
gobject_class->set_property = eek_xml_layout_set_property;
gobject_class->get_property = eek_xml_layout_get_property;
gobject_class->finalize = eek_xml_layout_finalize;
@@ -1122,13 +1149,10 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
}
static gboolean
-parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
+parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash, GError **error)
{
GeometryParseData *data;
GMarkupParseContext *pcontext;
- GHashTable *oref_hash;
- GHashTableIter iter;
- gpointer k, v;
GFile *file;
GFileInputStream *input;
gboolean retval;
@@ -1142,7 +1166,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
if (input == NULL)
return FALSE;
- data = geometry_parse_data_new (keyboard);
+ data = geometry_parse_data_new (views, name_key_hash, outline_array);
pcontext = g_markup_parse_context_new (&geometry_parser,
0,
data,
@@ -1157,23 +1181,29 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
}
/* Resolve outline references. */
+ /*
+ * GHashTable *oref_hash;
+ GHashTableIter iter;
+ gpointer k, v;
+
oref_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_iter_init (&iter, data->oref_outline_hash);
while (g_hash_table_iter_next (&iter, &k, &v)) {
EekOutline *outline = v;
gulong oref;
- oref = eek_keyboard_add_outline (data->keyboard, outline);
+ oref = add_outline (outline_array, outline);
g_hash_table_insert (oref_hash, k, GUINT_TO_POINTER(oref));
- }
+ }*/
+ /*
g_hash_table_iter_init (&iter, data->key_oref_hash);
while (g_hash_table_iter_next (&iter, &k, &v)) {
gpointer oref;
if (g_hash_table_lookup_extended (oref_hash, v, NULL, &oref))
eek_key_set_oref (EEK_KEY(k), GPOINTER_TO_UINT(oref));
- }
- g_hash_table_destroy (oref_hash);
+ }*/
+// g_hash_table_destroy (oref_hash);
geometry_parse_data_free (data);
return TRUE;
@@ -1182,7 +1212,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
static gboolean
parse_symbols_with_prerequisites (const gchar *keyboards_dir,
const gchar *name,
- EekKeyboard *keyboard,
+ LevelKeyboard *keyboard,
GList **loaded,
GError **error)
{
@@ -1232,7 +1262,7 @@ parse_symbols_with_prerequisites (const gchar *keyboards_dir,
}
static gboolean
-parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
+parse_symbols (const gchar *path, LevelKeyboard *keyboard, GError **error)
{
SymbolsParseData *data;
GMarkupParseContext *pcontext;
diff --git a/eek/eek-xml-layout.h b/eek/eek-xml-layout.h
index 1210ff17..8b89776f 100644
--- a/eek/eek-xml-layout.h
+++ b/eek/eek-xml-layout.h
@@ -62,5 +62,8 @@ GList *eek_xml_list_keyboards (void);
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
void eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
+LevelKeyboard *
+eek_xml_layout_real_create_keyboard (EekLayout *self,
+ EekboardContextService *manager);
G_END_DECLS
#endif /* EEK_XML_LAYOUT_H */
diff --git a/eek/eek.h b/eek/eek.h
index 8a27a445..6f0abcb4 100644
--- a/eek/eek.h
+++ b/eek/eek.h
@@ -26,9 +26,7 @@
#include "eek-section.h"
#include "eek-key.h"
#include "eek-layout.h"
-#include "eek-symbol.h"
#include "eek-keysym.h"
-#include "eek-text.h"
#include "eek-serializable.h"
void eek_init (void);
diff --git a/eek/meson.build b/eek/meson.build
index 851710b4..9e3880d6 100644
--- a/eek/meson.build
+++ b/eek/meson.build
@@ -1,7 +1,6 @@
gnome = import('gnome')
enum_headers = [
- 'eek-symbol.h',
'eek-types.h',
]
diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c
index c5d17645..e4200900 100644
--- a/eekboard/eekboard-context-service.c
+++ b/eekboard/eekboard-context-service.c
@@ -71,7 +71,7 @@ struct _EekboardContextServicePrivate {
gboolean visible;
gboolean fullscreen;
- EekKeyboard *keyboard; // currently used keyboard
+ LevelKeyboard *keyboard; // currently used keyboard
GHashTable *keyboard_hash; // a table of available keyboards, per layout
// TODO: make use of repeating buttons
@@ -86,11 +86,10 @@ struct _EekboardContextServicePrivate {
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
-static EekKeyboard *
+static LevelKeyboard *
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
const gchar *keyboard_type)
{
- EekKeyboard *keyboard;
EekLayout *layout;
GError *error;
@@ -135,7 +134,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
}
}
}
- keyboard = eek_keyboard_new (self, layout, CSW, CSH);
+ LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(layout, self);
if (!keyboard) {
g_error("Failed to create a keyboard");
}
@@ -148,6 +147,10 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
+ int f = open("maprs.map", O_CREAT | O_WRONLY);
+ write(f, keymap_str, strlen(keymap_str));
+ close(f);
+
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
@@ -315,21 +318,16 @@ settings_update_layout(EekboardContextService *context)
// generic part follows
static guint keyboard_id = 0;
- EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
+ LevelKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
GUINT_TO_POINTER(keyboard_id));
// create a keyboard
if (!keyboard) {
- EekboardContextServiceClass *klass = EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context);
- keyboard = klass->create_keyboard (context, keyboard_layout);
- eek_keyboard_set_modifier_behavior (keyboard,
- EEK_MODIFIER_BEHAVIOR_LATCH);
+ keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout);
g_hash_table_insert (context->priv->keyboard_hash,
GUINT_TO_POINTER(keyboard_id),
keyboard);
- g_object_set_data (G_OBJECT(keyboard),
- "keyboard-id",
- GUINT_TO_POINTER(keyboard_id));
+ keyboard->id = keyboard_id;
keyboard_id++;
}
// set as current
@@ -370,7 +368,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
- klass->create_keyboard = eekboard_context_service_real_create_keyboard;
klass->show_keyboard = eekboard_context_service_real_show_keyboard;
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
@@ -574,7 +571,7 @@ eekboard_context_service_destroy (EekboardContextService *context)
* Get keyboard currently active in @context.
* Returns: (transfer none): an #EekKeyboard
*/
-EekKeyboard *
+LevelKeyboard *
eekboard_context_service_get_keyboard (EekboardContextService *context)
{
return context->priv->keyboard;
@@ -594,7 +591,7 @@ eekboard_context_service_get_fullscreen (EekboardContextService *context)
}
void eekboard_context_service_set_keymap(EekboardContextService *context,
- const EekKeyboard *keyboard)
+ const LevelKeyboard *keyboard)
{
zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h
index b5ee738c..014f0dbc 100644
--- a/eekboard/eekboard-context-service.h
+++ b/eekboard/eekboard-context-service.h
@@ -97,13 +97,12 @@ void eekboard_context_service_show_keyboard
void eekboard_context_service_hide_keyboard
(EekboardContextService *context);
void eekboard_context_service_destroy (EekboardContextService *context);
-EekKeyboard *eekboard_context_service_get_keyboard
- (EekboardContextService *context);
+LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
gboolean eekboard_context_service_get_fullscreen
(EekboardContextService *context);
void eekboard_context_service_set_keymap(EekboardContextService *context,
- const EekKeyboard *keyboard);
+ const LevelKeyboard *keyboard);
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
uint32_t hint,
diff --git a/eekboard/key-emitter.c b/eekboard/key-emitter.c
index 79dbfa96..4548008f 100644
--- a/eekboard/key-emitter.c
+++ b/eekboard/key-emitter.c
@@ -22,6 +22,7 @@
#include "eekboard/key-emitter.h"
#include
+#include
#include "eekboard/eekboard-context-service.h"
@@ -84,14 +85,14 @@ update_modifier_info (SeatEmitter *client)
static void
send_fake_key (SeatEmitter *emitter,
- EekKeyboard *keyboard,
+ LevelKeyboard *keyboard,
guint keycode,
guint keyboard_modifiers,
gboolean pressed,
uint32_t timestamp)
{
uint32_t proto_modifiers = 0;
- guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
+ guint level = keyboard->level;
uint32_t group = (level / 2);
if (keyboard_modifiers & EEK_SHIFT_MASK)
@@ -104,7 +105,7 @@ send_fake_key (SeatEmitter *emitter,
void
emit_key_activated (EekboardContextService *manager,
- EekKeyboard *keyboard,
+ LevelKeyboard *keyboard,
guint keycode,
EekSymbol *symbol,
EekModifierType modifiers,
diff --git a/eekboard/key-emitter.h b/eekboard/key-emitter.h
index 91da3529..a8e0e30d 100644
--- a/eekboard/key-emitter.h
+++ b/eekboard/key-emitter.h
@@ -39,7 +39,7 @@ enum mod_indices {
};
void
-emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard,
+emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard,
guint keycode,
EekSymbol *symbol,
guint modifiers,
diff --git a/src/keyboard.h b/src/keyboard.h
new file mode 100644
index 00000000..ff336f5e
--- /dev/null
+++ b/src/keyboard.h
@@ -0,0 +1,23 @@
+#ifndef __KEYBOARD_H
+#define __KYBOARD_H
+
+#include "stdbool.h"
+#include "inttypes.h"
+
+struct squeek_key;
+
+struct squeek_key *squeek_key_new(uint32_t keycode);
+void squeek_key_free(struct squeek_key *key);
+void squeek_key_add_symbol(struct squeek_key* key,
+ const char *element_name,
+ const char *text, uint32_t keyval,
+ const char *label, const char *icon,
+ const char *tooltip);
+uint32_t squeek_key_is_pressed(struct squeek_key *key);
+void squeek_key_set_pressed(struct squeek_key *key, uint32_t pressed);
+uint32_t squeek_key_get_keycode(struct squeek_key *key);
+void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode);
+
+struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key, uint32_t level);
+const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key);
+#endif
diff --git a/src/keyboard.rs b/src/keyboard.rs
new file mode 100644
index 00000000..a7be346e
--- /dev/null
+++ b/src/keyboard.rs
@@ -0,0 +1,237 @@
+use std::vec::Vec;
+
+use super::symbol;
+
+/// Gathers stuff defined in C or called by C
+pub mod c {
+ use super::*;
+ use ::util::c::{ as_cstr, into_cstring };
+
+ use std::ffi::CString;
+ use std::os::raw::c_char;
+
+ // The following defined in C
+ #[no_mangle]
+ extern "C" {
+ fn eek_keysym_from_name(name: *const c_char) -> u32;
+ }
+
+
+ // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
+
+ // TODO: this will receive data from the filesystem,
+ // so it should handle garbled strings in the future
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_new(keycode: u32) -> *mut KeyState {
+ Box::into_raw(Box::new(
+ KeyState {
+ pressed: false,
+ keycode: keycode,
+ symbols: Vec::new(),
+ }
+ ))
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_free(key: *mut KeyState) {
+ unsafe { Box::from_raw(key) }; // gets dropped
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_is_pressed(key: *const KeyState) -> u32 {
+ let key = unsafe { &*key };
+ return key.pressed as u32;
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_set_pressed(key: *mut KeyState, pressed: u32) {
+ let key = unsafe { &mut *key };
+ key.pressed = pressed != 0;
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_get_keycode(key: *const KeyState) -> u32 {
+ let key = unsafe { &*key };
+ return key.keycode as u32;
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_set_keycode(key: *mut KeyState, code: u32) {
+ let key = unsafe { &mut *key };
+ key.keycode = code;
+ }
+
+ // TODO: this will receive data from the filesystem,
+ // so it should handle garbled strings in the future
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_add_symbol(
+ key: *mut KeyState,
+ element: *const c_char,
+ text_raw: *const c_char, keyval: u32,
+ label: *const c_char, icon: *const c_char,
+ tooltip: *const c_char,
+ ) {
+ let element = as_cstr(&element)
+ .expect("Missing element name");
+
+ let text = into_cstring(text_raw)
+ .unwrap_or_else(|e| {
+ eprintln!("Text unreadable: {}", e);
+ None
+ })
+ .and_then(|text| {
+ if text.as_bytes() == b"" {
+ None
+ } else {
+ Some(text)
+ }
+ });
+
+ let key = unsafe { &mut *key };
+
+ if key.symbols.len() > 0 {
+ eprintln!("Key {:?} already has a symbol defined", text);
+ return;
+ }
+
+
+ let icon = into_cstring(icon)
+ .unwrap_or_else(|e| {
+ eprintln!("Icon name unreadable: {}", e);
+ None
+ });
+
+ use symbol::*;
+ // Only read label if there's no icon
+ let label = match icon {
+ Some(icon) => Label::IconName(icon),
+ None => Label::Text(
+ into_cstring(label)
+ .unwrap_or_else(|e| {
+ eprintln!("Label unreadable: {}", e);
+ Some(CString::new(" ").unwrap())
+ })
+ .unwrap_or_else(|| {
+ eprintln!("Label missing");
+ CString::new(" ").unwrap()
+ })
+ ),
+ };
+
+ let tooltip = into_cstring(tooltip)
+ .unwrap_or_else(|e| {
+ eprintln!("Tooltip unreadable: {}", e);
+ None
+ });
+
+ let symbol = match element.to_bytes() {
+ b"symbol" => Symbol {
+ action: Action::Submit {
+ text: text,
+ keys: Vec::new(),
+ },
+ label: label,
+ tooltip: tooltip,
+ },
+ b"keysym" => {
+ let keysym = XKeySym(
+ if keyval == 0 {
+ unsafe { eek_keysym_from_name(text_raw) }
+ } else {
+ keyval
+ }
+ );
+ Symbol {
+ action: match KeySym::from_u32(keysym.0) {
+ KeySym::Shift => Action::SetLevel(1),
+ _ => Action::Submit {
+ text: text,
+ keys: vec![keysym],
+ }
+ },
+ label: label,
+ tooltip: tooltip,
+ }
+ },
+ _ => panic!("unsupported element type {:?}", element),
+ };
+
+ key.symbols.push(symbol);
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_get_symbol(
+ key: *const KeyState, index: u32
+ ) -> *const symbol::Symbol {
+ let key = unsafe { &*key };
+ let index = index as usize;
+ &key.symbols[
+ if index < key.symbols.len() { index } else { 0 }
+ ] as *const symbol::Symbol
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_key_to_keymap_entry(
+ key_name: *const c_char,
+ key: *const KeyState,
+ ) -> *const c_char {
+ let key_name = as_cstr(&key_name)
+ .expect("Missing key name")
+ .to_str()
+ .expect("Bad key name");
+
+ let key = unsafe { &*key };
+ let symbol_names = key.symbols.iter()
+ .map(|symbol| {
+ match &symbol.action {
+ symbol::Action::Submit { text: Some(text), .. } => {
+ Some(
+ text.clone()
+ .into_string().expect("Bad symbol")
+ )
+ },
+ _ => None
+ }
+ })
+ .collect::>();
+
+ let inner = match symbol_names.len() {
+ 1 => match &symbol_names[0] {
+ Some(name) => format!("[ {} ]", name),
+ _ => format!("[ ]"),
+ },
+ 4 => {
+ let first = match (&symbol_names[0], &symbol_names[1]) {
+ (Some(left), Some(right)) => format!("{}, {}", left, right),
+ _ => format!(""),
+ };
+ let second = match (&symbol_names[2], &symbol_names[3]) {
+ (Some(left), Some(right)) => format!("{}, {}", left, right),
+ _ => format!(""),
+ };
+ format!("[ {} ], [ {} ]", first, second)
+ },
+ _ => panic!("Unsupported number of symbols: {}", symbol_names.len()),
+ };
+
+ CString::new(format!(" key <{}> {{ {} }};\n", key_name, inner))
+ .expect("Couldn't convert string")
+ .into_raw()
+ }
+}
+
+#[derive(Debug)]
+pub struct KeyState {
+ pressed: bool,
+ keycode: u32,
+ symbols: Vec,
+}
diff --git a/src/lib.rs b/src/lib.rs
index 64e3ca10..c863f5df 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,3 +2,6 @@
mod bitflags;
mod imservice;
+mod keyboard;
+mod symbol;
+mod util;
diff --git a/src/meson.build b/src/meson.build
index fde961f9..9ffe478b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -27,9 +27,6 @@ sources = [
'../eek/eek-renderer.c',
'../eek/eek-section.c',
'../eek/eek-serializable.c',
- '../eek/eek-symbol.c',
- '../eek/eek-symbol-matrix.c',
- '../eek/eek-text.c',
'../eek/eek-types.c',
'../eek/eek-xml-layout.c',
'../eek/layersurface.c',
diff --git a/src/server-context-service.c b/src/server-context-service.c
index 8b81dd54..67b7ced6 100644
--- a/src/server-context-service.c
+++ b/src/server-context-service.c
@@ -83,9 +83,7 @@ on_notify_keyboard (GObject *object,
GParamSpec *spec,
ServerContextService *context)
{
- const EekKeyboard *keyboard;
-
- keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
+ const LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
if (!keyboard)
g_error("Programmer error: keyboard layout was unset!");
@@ -141,13 +139,13 @@ set_geometry (ServerContextService *context)
GdkWindow *root = gdk_screen_get_root_window (screen);
GdkDisplay *display = gdk_display_get_default ();
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, root);
- EekKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
+ LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
GdkRectangle rect;
EekBounds bounds;
gdk_monitor_get_geometry (monitor, &rect);
- eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
+ eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(keyboard)), &bounds);
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
gint width = rect.width;
@@ -228,14 +226,12 @@ destroy_window (ServerContextService *context)
static void
make_widget (ServerContextService *context)
{
- EekKeyboard *keyboard;
-
if (context->widget) {
gtk_widget_destroy(context->widget);
context->widget = NULL;
}
- keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
+ LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
context->widget = eek_gtk_keyboard_new (keyboard);
diff --git a/src/symbol.h b/src/symbol.h
new file mode 100644
index 00000000..440dabe5
--- /dev/null
+++ b/src/symbol.h
@@ -0,0 +1,24 @@
+#ifndef __SYMBOL_H
+#define __SYMBOL_H
+
+#include "stdbool.h"
+#include "inttypes.h"
+// Defined in Rust
+
+struct squeek_symbol;
+struct squeek_symbols;
+
+void squeek_symbols_add(struct squeek_symbols*,
+ const char *element_name,
+ const char *text, uint32_t keyval,
+ const char *label, const char *icon,
+ const char *tooltip);
+
+
+const char *squeek_symbol_get_name(struct squeek_symbol* symbol);
+const char *squeek_symbol_get_label(struct squeek_symbol* symbol);
+const char *squeek_symbol_get_icon_name(struct squeek_symbol* symbol);
+uint32_t squeek_symbol_get_modifier_mask(struct squeek_symbol* symbol);
+
+void squeek_symbol_print(struct squeek_symbol* symbol);
+#endif
diff --git a/src/symbol.rs b/src/symbol.rs
new file mode 100644
index 00000000..ae5bcec3
--- /dev/null
+++ b/src/symbol.rs
@@ -0,0 +1,138 @@
+use std::ffi::CString;
+
+
+/// Gathers stuff defined in C or called by C
+pub mod c {
+ use super::*;
+
+ use std::ffi::CStr;
+ use std::os::raw::c_char;
+ use std::ptr;
+
+ // The following defined in C
+
+ // Legacy; Will never be used in Rust as a bit field
+ enum ModifierMask {
+ Nothing = 0,
+ Shift = 1,
+ }
+
+ // The following defined in Rust.
+
+ // TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
+ // Symbols are owned by Rust and will move towards no C manipulation, so it may make sense not to wrap them
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_symbol_get_name(symbol: *const Symbol) -> *const c_char {
+ let symbol = unsafe { &*symbol };
+ match &symbol.action {
+ Action::Submit { text: Some(text), .. } => text.as_ptr(),
+ _ => ptr::null(),
+ }
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_symbol_get_label(symbol: *const Symbol) -> *const c_char {
+ let symbol = unsafe { &*symbol };
+ match &symbol.label {
+ Label::Text(text) => text.as_ptr(),
+ // returning static strings to C is a bit cumbersome
+ Label::IconName(_) => unsafe {
+ CStr::from_bytes_with_nul_unchecked(b"icon\0")
+ }.as_ptr(),
+ }
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_symbol_get_icon_name(symbol: *const Symbol) -> *const c_char {
+ let symbol = unsafe { &*symbol };
+ match &symbol.label {
+ Label::Text(_) => ptr::null(),
+ Label::IconName(name) => name.as_ptr(),
+ }
+ }
+
+ // Legacy; throw away
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_symbol_get_modifier_mask(symbol: *const Symbol) -> u32 {
+ let symbol = unsafe { &*symbol };
+ (match &symbol.action {
+ Action::SetLevel(1) => ModifierMask::Shift,
+ _ => ModifierMask::Nothing,
+ }) as u32
+ }
+
+ #[no_mangle]
+ pub extern "C"
+ fn squeek_symbol_print(symbol: *const Symbol) {
+ let symbol = unsafe { &*symbol };
+ println!("{:?}", symbol);
+ }
+}
+
+/// Just defines some int->identifier mappings for convenience
+#[derive(Debug)]
+pub enum KeySym {
+ Unknown = 0,
+ Shift = 0xffe1,
+}
+
+impl KeySym {
+ pub fn from_u32(num: u32) -> KeySym {
+ match num {
+ 0xffe1 => KeySym::Shift,
+ _ => KeySym::Unknown,
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct XKeySym(pub u32);
+
+#[derive(Debug)]
+pub enum Label {
+ /// Text used to display the symbol
+ Text(CString),
+ /// Icon name used to render the symbol
+ IconName(CString),
+}
+
+/// Use to switch layouts
+type Level = u8;
+
+/// Use to send modified keypresses
+#[derive(Debug)]
+pub enum Modifier {
+ Control,
+ Alt,
+}
+
+/// Action to perform on the keypress and, in reverse, on keyrelease
+#[derive(Debug)]
+pub enum Action {
+ /// Switch to this level TODO: reverse?
+ SetLevel(Level),
+ /// Set this modifier TODO: release?
+ SetModifier(Modifier),
+ /// Submit some text
+ Submit {
+ /// orig: Canonical name of the symbol
+ text: Option,
+ /// The key events this symbol submits when submitting text is not possible
+ keys: Vec,
+ },
+}
+
+/// Contains a static description of a particular key's actions
+#[derive(Debug)]
+pub struct Symbol {
+ /// The action that this key performs
+ pub action: Action,
+ /// Label to display to the user
+ pub label: Label,
+ // FIXME: is it used?
+ pub tooltip: Option,
+}
diff --git a/src/util.rs b/src/util.rs
new file mode 100644
index 00000000..e2846b31
--- /dev/null
+++ b/src/util.rs
@@ -0,0 +1,49 @@
+pub mod c {
+ use std::ffi::{ CStr, CString };
+ use std::os::raw::c_char;
+ use std::str::Utf8Error;
+
+ pub fn as_str(s: &*const c_char) -> Result