levelkeyboard: Use a layer for managing keyboard views

This commit is contained in:
Dorota Czaplejewicz
2019-08-03 15:52:06 +00:00
parent 0b6935e50c
commit f371b14e89
22 changed files with 231 additions and 324 deletions

View File

@ -55,7 +55,7 @@ enum {
typedef struct _EekGtkKeyboardPrivate typedef struct _EekGtkKeyboardPrivate
{ {
EekRenderer *renderer; EekRenderer *renderer;
EekKeyboard *keyboard; LevelKeyboard *keyboard;
GtkCssProvider *css_provider; GtkCssProvider *css_provider;
GtkStyleContext *scontext; GtkStyleContext *scontext;
@ -117,14 +117,14 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
uint level = priv->keyboard->level; uint level = priv->keyboard->level;
/* redraw pressed key */ /* redraw pressed key */
list = eek_keyboard_get_pressed_keys (priv->keyboard); list = eek_keyboard_get_pressed_keys (level_keyboard_current(priv->keyboard));
for (head = list; head; head = g_list_next (head)) { for (head = list; head; head = g_list_next (head)) {
render_pressed_key (self, head->data, level); render_pressed_key (self, head->data, level);
} }
g_list_free (list); g_list_free (list);
/* redraw locked key */ /* redraw locked key */
list = eek_keyboard_get_locked_keys (priv->keyboard); list = eek_keyboard_get_locked_keys (level_keyboard_current(priv->keyboard));
for (head = list; head; head = g_list_next (head)) { for (head = list; head; head = g_list_next (head)) {
render_locked_key (self, ((EekModifierKey *)head->data)->key, level); render_locked_key (self, ((EekModifierKey *)head->data)->key, level);
} }
@ -168,7 +168,7 @@ static void drag(EekGtkKeyboard *self,
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y); EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
GList *list, *head; GList *list, *head;
list = eek_keyboard_get_pressed_keys (priv->keyboard); list = eek_keyboard_get_pressed_keys (level_keyboard_current(priv->keyboard));
if (key) { if (key) {
gboolean found = FALSE; gboolean found = FALSE;
@ -200,7 +200,7 @@ static void drag(EekGtkKeyboard *self,
static void release(EekGtkKeyboard *self, guint32 time) { static void release(EekGtkKeyboard *self, guint32 time) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
GList *list = eek_keyboard_get_pressed_keys (priv->keyboard); GList *list = eek_keyboard_get_pressed_keys (level_keyboard_current(priv->keyboard));
for (GList *head = list; head; head = g_list_next (head)) { for (GList *head = list; head; head = g_list_next (head)) {
EekKey *key = EEK_KEY(head->data); EekKey *key = EEK_KEY(head->data);
eek_keyboard_release_key(priv->keyboard, key, time); eek_keyboard_release_key(priv->keyboard, key, time);
@ -287,7 +287,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
elements, so that the default handler of elements, so that the default handler of
EekKeyboard::key-released signal can remove elements from its EekKeyboard::key-released signal can remove elements from its
internal copy */ internal copy */
list = eek_keyboard_get_pressed_keys (priv->keyboard); list = eek_keyboard_get_pressed_keys (level_keyboard_current(priv->keyboard));
for (head = list; head; head = g_list_next (head)) { for (head = list; head; head = g_list_next (head)) {
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released"); g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
g_signal_emit_by_name (head->data, "released"); g_signal_emit_by_name (head->data, "released");
@ -326,18 +326,14 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
static void static void
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self, eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
EekKeyboard *keyboard) LevelKeyboard *keyboard)
{ {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
if (priv->keyboard == keyboard) if (priv->keyboard == keyboard)
return; return;
if (priv->keyboard) { priv->keyboard = keyboard;
g_object_unref (priv->keyboard);
}
priv->keyboard = g_object_ref (keyboard);
} }
static void static void
@ -346,7 +342,7 @@ eek_gtk_keyboard_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekKeyboard *keyboard; LevelKeyboard *keyboard;
switch (prop_id) { switch (prop_id) {
case PROP_KEYBOARD: case PROP_KEYBOARD:
@ -373,14 +369,13 @@ eek_gtk_keyboard_dispose (GObject *object)
if (priv->keyboard) { if (priv->keyboard) {
GList *list, *head; GList *list, *head;
list = eek_keyboard_get_pressed_keys (priv->keyboard); list = eek_keyboard_get_pressed_keys (level_keyboard_current(priv->keyboard));
for (head = list; head; head = g_list_next (head)) { for (head = list; head; head = g_list_next (head)) {
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed"); 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_list_free (list);
g_object_unref (priv->keyboard);
priv->keyboard = NULL; priv->keyboard = NULL;
} }
@ -448,32 +443,12 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
* Returns: a #GtkWidget * Returns: a #GtkWidget
*/ */
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); 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;
static void return GTK_WIDGET(ret);
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);
} }
static void static void

View File

@ -45,7 +45,7 @@ struct _EekGtkKeyboardClass
}; };
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST; 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 G_END_DECLS
#endif /* EEK_GTK_KEYBOARD_H */ #endif /* EEK_GTK_KEYBOARD_H */

View File

@ -36,6 +36,7 @@
#include "eek-enumtypes.h" #include "eek-enumtypes.h"
#include "eekboard/key-emitter.h" #include "eekboard/key-emitter.h"
#include "keymap.h" #include "keymap.h"
#include "src/keyboard.h"
#include "src/symbol.h" #include "src/symbol.h"
#include "eek-keyboard.h" #include "eek-keyboard.h"
@ -72,10 +73,6 @@ struct _EekKeyboardPrivate
unsigned int old_level; unsigned int old_level;
GList *pressed_keys; GList *pressed_keys;
GList *locked_keys; GList *locked_keys;
GArray *outline_array;
/* Map key names to key objects: */
GHashTable *names;
/* modifiers dynamically assigned at run time */ /* modifiers dynamically assigned at run time */
EekModifierType num_lock_mask; EekModifierType num_lock_mask;
@ -116,27 +113,6 @@ on_key_unlocked (EekSection *section,
g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key); g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
} }
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);
}
EekSection * EekSection *
eek_keyboard_real_create_section (EekKeyboard *self) eek_keyboard_real_create_section (EekKeyboard *self)
{ {
@ -145,12 +121,6 @@ eek_keyboard_real_create_section (EekKeyboard *self)
section = g_object_new (EEK_TYPE_SECTION, NULL); section = g_object_new (EEK_TYPE_SECTION, NULL);
g_return_val_if_fail (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_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(section)); EEK_ELEMENT(section));
return section; return section;
@ -191,14 +161,14 @@ eek_keyboard_get_property (GObject *object,
} }
static void static void
set_level_from_modifiers (EekKeyboard *self, EekKey *key) set_level_from_modifiers (LevelKeyboard *keyboard, EekKeyboard *self, EekKey *key)
{ {
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self); EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */ /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
/* Use the numbers/letters bit from the old level */ /* Use the numbers/letters bit from the old level */
gint level = priv->old_level & 2; guint level = priv->old_level & 2;
/* Handle non-emitting keys */ /* Handle non-emitting keys */
if (key) { if (key) {
@ -243,9 +213,9 @@ set_level_from_modifiers (EekKeyboard *self, EekKey *key)
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH; priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
priv->old_level = level; priv->old_level = level;
self->level = level; keyboard->level = level;
eek_layout_update_layout(self); eek_layout_update_layout(keyboard);
} }
static void static void
@ -287,8 +257,8 @@ set_modifiers_with_key (EekKeyboard *self,
priv->modifiers = modifiers; priv->modifiers = modifiers;
} }
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) { void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp) {
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard); EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(level_keyboard_current(keyboard));
eek_key_set_pressed(key, TRUE); eek_key_set_pressed(key, TRUE);
priv->pressed_keys = g_list_prepend (priv->pressed_keys, key); priv->pressed_keys = g_list_prepend (priv->pressed_keys, key);
@ -301,22 +271,22 @@ void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestam
EekModifierType modifier = squeek_symbol_get_modifier_mask (symbol); EekModifierType modifier = squeek_symbol_get_modifier_mask (symbol);
if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) { if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
set_modifiers_with_key (keyboard, key, priv->modifiers | modifier); set_modifiers_with_key (level_keyboard_current(keyboard), key, priv->modifiers | modifier);
set_level_from_modifiers (keyboard, key); set_level_from_modifiers (keyboard, level_keyboard_current(keyboard), key);
} }
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
guint keycode = eek_key_get_keycode (key); guint keycode = eek_key_get_keycode (key);
EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard); EekModifierType modifiers = eek_keyboard_get_modifiers (level_keyboard_current(keyboard));
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp); emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
} }
void eek_keyboard_release_key( EekKeyboard *keyboard, void eek_keyboard_release_key(LevelKeyboard *keyboard,
EekKey *key, EekKey *key,
guint32 timestamp) { guint32 timestamp) {
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard); EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(level_keyboard_current(keyboard));
for (GList *head = priv->pressed_keys; head; head = g_list_next (head)) { for (GList *head = priv->pressed_keys; head; head = g_list_next (head)) {
if (head->data == key) { if (head->data == key) {
@ -334,25 +304,25 @@ void eek_keyboard_release_key( EekKeyboard *keyboard,
EekModifierType modifier = squeek_symbol_get_modifier_mask (symbol); EekModifierType modifier = squeek_symbol_get_modifier_mask (symbol);
switch (priv->modifier_behavior) { switch (priv->modifier_behavior) {
case EEK_MODIFIER_BEHAVIOR_NONE: case EEK_MODIFIER_BEHAVIOR_NONE:
set_modifiers_with_key (keyboard, key, priv->modifiers & ~modifier); set_modifiers_with_key (level_keyboard_current(keyboard), key, priv->modifiers & ~modifier);
break; break;
case EEK_MODIFIER_BEHAVIOR_LOCK: case EEK_MODIFIER_BEHAVIOR_LOCK:
priv->modifiers ^= modifier; priv->modifiers ^= modifier;
break; break;
case EEK_MODIFIER_BEHAVIOR_LATCH: case EEK_MODIFIER_BEHAVIOR_LATCH:
if (modifier) if (modifier)
set_modifiers_with_key (keyboard, key, priv->modifiers ^ modifier); set_modifiers_with_key (level_keyboard_current(keyboard), key, priv->modifiers ^ modifier);
else else
set_modifiers_with_key (keyboard, key, set_modifiers_with_key (level_keyboard_current(keyboard), key,
(priv->modifiers ^ modifier) & modifier); (priv->modifiers ^ modifier) & modifier);
break; break;
} }
set_level_from_modifiers (keyboard, key); set_level_from_modifiers (keyboard, level_keyboard_current(keyboard), key);
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
guint keycode = eek_key_get_keycode (key); guint keycode = eek_key_get_keycode (key);
guint modifiers = eek_keyboard_get_modifiers (keyboard); guint modifiers = eek_keyboard_get_modifiers (level_keyboard_current(keyboard));
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp); emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
} }
@ -367,24 +337,32 @@ static void
eek_keyboard_finalize (GObject *object) eek_keyboard_finalize (GObject *object)
{ {
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object); EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
guint i;
g_list_free (priv->pressed_keys); g_list_free (priv->pressed_keys);
g_list_free_full (priv->locked_keys, g_list_free_full (priv->locked_keys,
(GDestroyNotify) eek_modifier_key_free); (GDestroyNotify) eek_modifier_key_free);
g_hash_table_destroy (priv->names); G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
}
for (i = 0; i < priv->outline_array->len; i++) { void level_keyboard_deinit(LevelKeyboard *self) {
EekOutline *outline = &g_array_index (priv->outline_array, 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, EekOutline,
i); i);
g_slice_free1 (sizeof (EekPoint) * outline->num_points, g_slice_free1 (sizeof (EekPoint) * outline->num_points,
outline->points); outline->points);
} }
g_array_free (priv->outline_array, TRUE); g_array_free (self->outline_array, TRUE);
for (guint i = 0; i < 4; i++) {
// free self->view[i];
}
}
G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object); void level_keyboard_free(LevelKeyboard *self) {
level_keyboard_deinit(self);
g_free(self);
} }
static void static void
@ -482,12 +460,22 @@ eek_keyboard_init (EekKeyboard *self)
{ {
self->priv = EEK_KEYBOARD_GET_PRIVATE(self); self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE; 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);
self->level = 0;
self->scale = 1.0; self->scale = 1.0;
} }
void level_keyboard_init(LevelKeyboard *self) {
self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
}
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *view, GHashTable *name_key_hash) {
LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
level_keyboard_init(keyboard);
keyboard->view = view;
keyboard->manager = manager;
keyboard->names = name_key_hash;
return keyboard;
}
/** /**
* eek_keyboard_find_key_by_name: * eek_keyboard_find_key_by_name:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
@ -497,12 +485,10 @@ eek_keyboard_init (EekKeyboard *self)
* Return value: (transfer none): #EekKey whose name is @name * Return value: (transfer none): #EekKey whose name is @name
*/ */
EekKey * EekKey *
eek_keyboard_find_key_by_name (EekKeyboard *keyboard, eek_keyboard_find_key_by_name (LevelKeyboard *keyboard,
const gchar *name) const gchar *name)
{ {
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL); return g_hash_table_lookup (keyboard->names, name);
return g_hash_table_lookup (keyboard->priv->names,
name);
} }
/** /**
@ -554,15 +540,6 @@ eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
return keyboard->priv->modifier_behavior; 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: * eek_keyboard_get_modifiers:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
@ -577,30 +554,6 @@ eek_keyboard_get_modifiers (EekKeyboard *keyboard)
return keyboard->priv->modifiers; 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: * eek_keyboard_get_outline:
* @keyboard: an #EekKeyboard * @keyboard: an #EekKeyboard
@ -610,29 +563,13 @@ eek_keyboard_add_outline (EekKeyboard *keyboard,
* Returns: an #EekOutline, which should not be released * Returns: an #EekOutline, which should not be released
*/ */
EekOutline * EekOutline *
eek_keyboard_get_outline (EekKeyboard *keyboard, level_keyboard_get_outline (LevelKeyboard *keyboard,
guint oref) guint oref)
{ {
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL); if (oref > keyboard->outline_array->len)
if (oref > keyboard->priv->outline_array->len)
return NULL; return NULL;
return &g_array_index (keyboard->priv->outline_array, EekOutline, oref); return &g_array_index (keyboard->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;
} }
/** /**
@ -731,7 +668,7 @@ eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
* Returns: a string containing the XKB keymap. * Returns: a string containing the XKB keymap.
*/ */
gchar * gchar *
eek_keyboard_get_keymap(EekKeyboard *keyboard) eek_keyboard_get_keymap(LevelKeyboard *keyboard)
{ {
/* Start the keycodes and symbols sections with their respective headers. */ /* Start the keycodes and symbols sections with their respective headers. */
gchar *keycodes = g_strdup(keymap_keycodes_header); gchar *keycodes = g_strdup(keymap_keycodes_header);
@ -740,13 +677,13 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
/* Iterate over the keys in the name-to-key hash table. */ /* Iterate over the keys in the name-to-key hash table. */
GHashTableIter iter; GHashTableIter iter;
gpointer key_name, key_ptr; gpointer key_name, key_ptr;
g_hash_table_iter_init(&iter, keyboard->priv->names); 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, &key_name, &key_ptr)) {
gchar *current, *line; gchar *current, *line;
EekKey *key = EEK_KEY(key_ptr); 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. */ /* Don't include invalid keycodes in the keymap. */
if (keycode == EEK_INVALID_KEYCODE) if (keycode == EEK_INVALID_KEYCODE)
@ -780,3 +717,9 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
g_free(symbols); g_free(symbols);
return keymap; return keymap;
} }
EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard)
{
return keyboard->view;
//return keyboard->views[keyboard->level];
}

View File

@ -59,13 +59,7 @@ struct _EekKeyboard
EekContainer parent; EekContainer parent;
EekKeyboardPrivate *priv; 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; double scale;
guint level;
EekboardContextService *manager; // unowned reference
}; };
/** /**
@ -123,9 +117,24 @@ struct _EekModifierKey {
}; };
typedef struct _EekModifierKey EekModifierKey; typedef struct _EekModifierKey EekModifierKey;
/// Keyboard state holder
struct _LevelKeyboard {
guint id;
EekKeyboard *view;
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, /* Map key names to key objects: */
EekLayout *layout, GHashTable *names;
EekboardContextService *manager; // unowned reference
};
typedef struct _LevelKeyboard LevelKeyboard;
LevelKeyboard *eek_keyboard_new(EekLayout *layout,
gdouble initial_width, gdouble initial_width,
gdouble initial_height); gdouble initial_height);
GType eek_keyboard_get_type GType eek_keyboard_get_type
@ -154,19 +163,12 @@ EekSection *eek_keyboard_create_section
(EekKeyboard *keyboard); (EekKeyboard *keyboard);
EekKey *eek_keyboard_find_key_by_name EekKey *eek_keyboard_find_key_by_name
(EekKeyboard *keyboard, (LevelKeyboard *keyboard,
const gchar *name); const gchar *name);
guint eek_keyboard_add_outline EekOutline *level_keyboard_get_outline
(EekKeyboard *keyboard, (LevelKeyboard *keyboard,
EekOutline *outline);
EekOutline *eek_keyboard_get_outline
(EekKeyboard *keyboard,
guint oref); guint oref);
gsize eek_keyboard_get_n_outlines
(EekKeyboard *keyboard);
void eek_keyboard_set_num_lock_mask void eek_keyboard_set_num_lock_mask
(EekKeyboard *keyboard, (EekKeyboard *keyboard,
EekModifierType num_lock_mask); EekModifierType num_lock_mask);
@ -189,12 +191,16 @@ EekModifierKey *eek_modifier_key_copy
void eek_modifier_key_free void eek_modifier_key_free
(EekModifierKey *modkey); (EekModifierKey *modkey);
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp); void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp); void eek_keyboard_release_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
gchar * eek_keyboard_get_keymap gchar * eek_keyboard_get_keymap
(EekKeyboard *keyboard); (LevelKeyboard *keyboard);
EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard);
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *view, 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 /* Create an #EekSection instance and append it to @keyboard. This
* function is rarely called by application but called by #EekLayout * function is rarely called by application but called by #EekLayout
* implementation. * implementation.

View File

@ -31,6 +31,7 @@
#include "eek-layout.h" #include "eek-layout.h"
#include "eek-keyboard.h" #include "eek-keyboard.h"
#include "eekboard/eekboard-context-service.h" #include "eekboard/eekboard-context-service.h"
#include "eek-xml-layout.h"
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT) G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
@ -45,35 +46,12 @@ 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; const double section_spacing = 7.0;
struct place_data { struct place_data {
double desired_width; double desired_width;
double current_offset; double current_offset;
EekKeyboard *keyboard; LevelKeyboard *keyboard;
}; };
static void static void
@ -87,7 +65,7 @@ section_placer(EekElement *element, gpointer user_data)
eek_element_set_bounds(element, &section_bounds); eek_element_set_bounds(element, &section_bounds);
// Sections are rows now. Gather up all the keys and adjust their 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, &section_bounds); eek_element_get_bounds(element, &section_bounds);
section_bounds.y = data->current_offset; section_bounds.y = data->current_offset;
@ -105,7 +83,7 @@ section_counter(EekElement *element, gpointer user_data) {
} }
void void
eek_layout_place_sections(EekKeyboard *keyboard) eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level)
{ {
/* Order rows */ /* Order rows */
// This needs to be done after outlines, because outlines define key sizes // This needs to be done after outlines, because outlines define key sizes
@ -114,23 +92,23 @@ eek_layout_place_sections(EekKeyboard *keyboard)
// The keyboard width is given by the user via screen size. The height will be given dynamically. // 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 // TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
EekBounds keyboard_bounds = {0}; 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 = { struct place_data placer_data = {
.desired_width = keyboard_bounds.width, .desired_width = keyboard_bounds.width,
.current_offset = 0, .current_offset = 0,
.keyboard = keyboard, .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; 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; keyboard_bounds.height = total_height;
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds); eek_element_set_bounds(EEK_ELEMENT(level), &keyboard_bounds);
} }
void 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));
} }

View File

@ -43,7 +43,7 @@ struct _EekLayoutClass
GObjectClass parent_class; GObjectClass parent_class;
/*< public >*/ /*< public >*/
EekKeyboard* (* create_keyboard) (EekboardContextService *manager, LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
EekLayout *self, EekLayout *self,
gdouble initial_width, gdouble initial_width,
gdouble initial_height); gdouble initial_height);
@ -55,9 +55,14 @@ struct _EekLayoutClass
GType eek_layout_get_type (void) G_GNUC_CONST; 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 G_END_DECLS
#endif /* EEK_LAYOUT_H */ #endif /* EEK_LAYOUT_H */

View File

@ -32,7 +32,6 @@
enum { enum {
PROP_0, PROP_0,
PROP_KEYBOARD,
PROP_PCONTEXT, PROP_PCONTEXT,
PROP_STYLE_CONTEXT, PROP_STYLE_CONTEXT,
PROP_LAST PROP_LAST
@ -40,7 +39,7 @@ enum {
typedef struct _EekRendererPrivate typedef struct _EekRendererPrivate
{ {
EekKeyboard *keyboard; LevelKeyboard *keyboard;
PangoContext *pcontext; PangoContext *pcontext;
GtkCssProvider *css_provider; GtkCssProvider *css_provider;
GtkStyleContext *scontext; GtkStyleContext *scontext;
@ -149,7 +148,7 @@ render_keyboard_surface (EekRenderer *renderer)
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground); 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.cr = cairo_create (priv->keyboard_surface);
data.renderer = renderer; data.renderer = renderer;
@ -176,7 +175,7 @@ render_keyboard_surface (EekRenderer *renderer)
data.level = priv->keyboard->level; data.level = priv->keyboard->level;
/* draw sections */ /* 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, create_keyboard_surface_section_callback,
&data); &data);
cairo_restore (data.cr); cairo_restore (data.cr);
@ -196,7 +195,7 @@ render_key_outline (EekRenderer *renderer,
guint oref; guint oref;
oref = eek_key_get_oref (key); 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) if (outline == NULL)
return; return;
@ -231,7 +230,7 @@ render_key (EekRenderer *self,
EekColor foreground; EekColor foreground;
oref = eek_key_get_oref (key); 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) if (outline == NULL)
return; return;
@ -524,10 +523,6 @@ eek_renderer_set_property (GObject *object,
EEK_RENDERER(object)); EEK_RENDERER(object));
switch (prop_id) { switch (prop_id) {
case PROP_KEYBOARD:
priv->keyboard = g_value_get_object (value);
g_object_ref (priv->keyboard);
break;
case PROP_PCONTEXT: case PROP_PCONTEXT:
priv->pcontext = g_value_get_object (value); priv->pcontext = g_value_get_object (value);
g_object_ref (priv->pcontext); g_object_ref (priv->pcontext);
@ -548,13 +543,7 @@ eek_renderer_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekRendererPrivate *priv = eek_renderer_get_instance_private (
EEK_RENDERER(object));
switch (prop_id) { switch (prop_id) {
case PROP_KEYBOARD:
g_value_set_object (value, priv->keyboard);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -568,7 +557,6 @@ eek_renderer_dispose (GObject *object)
EekRendererPrivate *priv = eek_renderer_get_instance_private (self); EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
if (priv->keyboard) { if (priv->keyboard) {
g_object_unref (priv->keyboard);
priv->keyboard = NULL; priv->keyboard = NULL;
} }
if (priv->pcontext) { if (priv->pcontext) {
@ -612,15 +600,6 @@ eek_renderer_class_init (EekRendererClass *klass)
gobject_class->dispose = eek_renderer_dispose; gobject_class->dispose = eek_renderer_dispose;
gobject_class->finalize = eek_renderer_finalize; 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", pspec = g_param_spec_object ("pango-context",
"Pango Context", "Pango Context",
"Pango Context", "Pango Context",
@ -712,15 +691,17 @@ invalidate (EekRenderer *renderer)
} }
EekRenderer * EekRenderer *
eek_renderer_new (EekKeyboard *keyboard, eek_renderer_new (LevelKeyboard *keyboard,
PangoContext *pcontext, PangoContext *pcontext,
GtkStyleContext *scontext) GtkStyleContext *scontext)
{ {
return g_object_new (EEK_TYPE_RENDERER, EekRenderer *renderer = g_object_new (EEK_TYPE_RENDERER,
"keyboard", keyboard,
"pango-context", pcontext, "pango-context", pcontext,
"style-context", scontext, "style-context", scontext,
NULL); NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
priv->keyboard = keyboard;
return renderer;
} }
void void
@ -741,7 +722,7 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
/* Calculate a scale factor to use when rendering the keyboard into the /* Calculate a scale factor to use when rendering the keyboard into the
available space. */ 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 w = (bounds.x * 2) + bounds.width;
gdouble h = (bounds.y * 2) + bounds.height; gdouble h = (bounds.y * 2) + bounds.height;
@ -766,7 +747,7 @@ eek_renderer_get_size (EekRenderer *renderer,
EekRendererPrivate *priv = eek_renderer_get_instance_private (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) if (width)
*width = bounds.width; *width = bounds.width;
if (height) if (height)
@ -794,7 +775,7 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
eek_element_get_bounds (EEK_ELEMENT(key), bounds); eek_element_get_bounds (EEK_ELEMENT(key), bounds);
eek_element_get_bounds (section, &section_bounds); eek_element_get_bounds (section, &section_bounds);
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)),
&keyboard_bounds); &keyboard_bounds);
if (!rotate) { if (!rotate) {
@ -1085,7 +1066,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL); g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (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);
/* Transform from widget coordinates to keyboard coordinates */ /* Transform from widget coordinates to keyboard coordinates */
x = (x - priv->origin_x)/priv->scale - bounds.x; x = (x - priv->origin_x)/priv->scale - bounds.x;
@ -1104,7 +1085,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
data.key = NULL; data.key = NULL;
data.renderer = renderer; 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, find_key_by_position_section_callback,
&data); &data);
return data.key; return data.key;

View File

@ -63,7 +63,7 @@ struct _EekRendererClass
}; };
GType eek_renderer_get_type (void) G_GNUC_CONST; GType eek_renderer_get_type (void) G_GNUC_CONST;
EekRenderer *eek_renderer_new (EekKeyboard *keyboard, EekRenderer *eek_renderer_new (LevelKeyboard *keyboard,
PangoContext *pcontext, PangoContext *pcontext,
GtkStyleContext *scontext); GtkStyleContext *scontext);
void eek_renderer_set_allocation_size void eek_renderer_set_allocation_size

View File

@ -404,9 +404,9 @@ keysizer(EekElement *element, gpointer user_data)
{ {
EekKey *key = EEK_KEY(element); EekKey *key = EEK_KEY(element);
EekKeyboard *keyboard = EEK_KEYBOARD(user_data); LevelKeyboard *keyboard = user_data;
uint oref = eek_key_get_oref (key); 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) { if (outline && outline->num_points > 0) {
double minx = outline->points[0].x; double minx = outline->points[0].x;
double maxx = minx; double maxx = minx;
@ -464,7 +464,7 @@ keyplacer(EekElement *element, gpointer user_data)
} }
void 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); eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);

View File

@ -28,6 +28,7 @@
#include <glib-object.h> #include <glib-object.h>
#include "eek-container.h" #include "eek-container.h"
#include "eek-types.h" #include "eek-types.h"
#include "eek-keyboard.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -97,7 +98,7 @@ EekKey *eek_section_create_key (EekSection *section,
const gchar *name, const gchar *name,
guint keycode); guint keycode);
void eek_section_place_keys (EekSection *section, EekKeyboard *keyboard); void eek_section_place_keys (EekSection *section, LevelKeyboard *keyboard);
G_END_DECLS G_END_DECLS
#endif /* EEK_SECTION_H */ #endif /* EEK_SECTION_H */

View File

@ -150,6 +150,7 @@ typedef struct _EekOutline EekOutline;
typedef struct _EekColor EekColor; typedef struct _EekColor EekColor;
typedef struct _EekboardContextService EekboardContextService; typedef struct _EekboardContextService EekboardContextService;
typedef struct _LevelKeyboard LevelKeyboard;
/** /**
* EekPoint: * EekPoint:

View File

@ -68,16 +68,16 @@ static GList *parse_prerequisites
(const gchar *path, (const gchar *path,
GError **error); GError **error);
static gboolean parse_geometry (const gchar *path, static gboolean parse_geometry (const gchar *path,
EekKeyboard *keyboard, EekKeyboard *keyboard, GArray *outline_array, GHashTable *name_key_hash,
GError **error); GError **error);
static gboolean parse_symbols_with_prerequisites static gboolean parse_symbols_with_prerequisites
(const gchar *keyboards_dir, (const gchar *keyboards_dir,
const gchar *name, const gchar *name,
EekKeyboard *keyboard, LevelKeyboard *keyboard,
GList **loaded, GList **loaded,
GError **error); GError **error);
static gboolean parse_symbols (const gchar *path, static gboolean parse_symbols (const gchar *path,
EekKeyboard *keyboard, LevelKeyboard *keyboard,
GError **error); GError **error);
static gboolean validate (const gchar **valid_path_list, static gboolean validate (const gchar **valid_path_list,
@ -255,7 +255,7 @@ struct _GeometryParseData {
typedef struct _GeometryParseData GeometryParseData; typedef struct _GeometryParseData GeometryParseData;
static GeometryParseData * static GeometryParseData *
geometry_parse_data_new (EekKeyboard *keyboard) geometry_parse_data_new (EekKeyboard *keyboard, GHashTable *name_key_hash)
{ {
GeometryParseData *data = g_slice_new0 (GeometryParseData); GeometryParseData *data = g_slice_new0 (GeometryParseData);
@ -271,12 +271,7 @@ geometry_parse_data_new (EekKeyboard *keyboard)
g_free, g_free,
(GDestroyNotify)eek_outline_free); (GDestroyNotify)eek_outline_free);
data->name_key_hash = data->name_key_hash = name_key_hash;
g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
data->text = g_string_sized_new (BUFSIZE); data->text = g_string_sized_new (BUFSIZE);
data->keycode = 8; data->keycode = 8;
return data; return data;
@ -600,7 +595,8 @@ struct _SymbolsParseData {
GSList *element_stack; GSList *element_stack;
GString *text; GString *text;
EekKeyboard *keyboard; LevelKeyboard *keyboard;
EekKeyboard *view;
EekKey *key; EekKey *key;
gchar *label; gchar *label;
gchar *icon; gchar *icon;
@ -611,11 +607,11 @@ struct _SymbolsParseData {
typedef struct _SymbolsParseData SymbolsParseData; typedef struct _SymbolsParseData SymbolsParseData;
static SymbolsParseData * static SymbolsParseData *
symbols_parse_data_new (EekKeyboard *keyboard) symbols_parse_data_new (LevelKeyboard *keyboard)
{ {
SymbolsParseData *data = g_slice_new0 (SymbolsParseData); SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
data->keyboard = g_object_ref (keyboard); data->keyboard = keyboard;
data->text = g_string_sized_new (BUFSIZE); data->text = g_string_sized_new (BUFSIZE);
return data; return data;
} }
@ -623,7 +619,6 @@ symbols_parse_data_new (EekKeyboard *keyboard)
static void static void
symbols_parse_data_free (SymbolsParseData *data) symbols_parse_data_free (SymbolsParseData *data)
{ {
g_object_unref (data->keyboard);
g_string_free (data->text, TRUE); g_string_free (data->text, TRUE);
g_slice_free (SymbolsParseData, data); g_slice_free (SymbolsParseData, data);
} }
@ -881,11 +876,9 @@ static const GMarkupParser prerequisites_parser = {
0 0
}; };
static EekKeyboard * LevelKeyboard *
eek_xml_layout_real_create_keyboard (EekboardContextService *manager, eek_xml_layout_real_create_keyboard (EekLayout *self,
EekLayout *self, EekboardContextService *manager)
gdouble initial_width,
gdouble initial_height)
{ {
EekXmlLayout *layout = EEK_XML_LAYOUT (self); EekXmlLayout *layout = EEK_XML_LAYOUT (self);
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout); EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
@ -893,19 +886,26 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
/* Create an empty keyboard to which geometry and symbols /* Create an empty keyboard to which geometry and symbols
information are applied. */ information are applied. */
EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL); EekKeyboard *view = g_object_new (EEK_TYPE_KEYBOARD, NULL);
keyboard->manager = manager;
/* Read geometry information. */ /* Read geometry information. */
gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry); gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL); gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
g_free (filename); g_free (filename);
GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
GHashTable *name_key_hash =
g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
; // char* -> EekKey*
GError *error = NULL; GError *error = NULL;
retval = parse_geometry (path, keyboard, &error); retval = parse_geometry (path, view, outline_array, name_key_hash, &error);
g_free (path); g_free (path);
if (!retval) { if (!retval) {
g_object_unref (keyboard); g_object_unref (view);
g_warning ("can't parse geometry file %s: %s", g_warning ("can't parse geometry file %s: %s",
priv->desc->geometry, priv->desc->geometry,
error->message); error->message);
@ -913,6 +913,12 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
return NULL; return NULL;
} }
LevelKeyboard *keyboard = level_keyboard_new(manager, view, name_key_hash);
keyboard->outline_array = outline_array;
// FIXME: are symbols shared betwen views?
/* Read symbols information. */ /* Read symbols information. */
GList *loaded = NULL; GList *loaded = NULL;
retval = parse_symbols_with_prerequisites (priv->keyboards_dir, retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
@ -922,7 +928,7 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
&error); &error);
g_list_free_full (loaded, g_free); g_list_free_full (loaded, g_free);
if (!retval) { if (!retval) {
g_object_unref (keyboard); g_object_unref (view);
g_warning ("can't parse symbols file %s: %s", g_warning ("can't parse symbols file %s: %s",
priv->desc->symbols, priv->desc->symbols,
error->message); error->message);
@ -930,11 +936,11 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
return NULL; return NULL;
} }
eek_layout_place_sections(keyboard); eek_layout_place_sections(keyboard, view);
/* Use pre-defined modifier mask here. */ /* Use pre-defined modifier mask here. */
eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK); eek_keyboard_set_num_lock_mask (view, EEK_MOD2_MASK);
eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK); eek_keyboard_set_alt_gr_mask (view, EEK_BUTTON1_MASK);
return keyboard; return keyboard;
} }
@ -997,12 +1003,9 @@ eek_xml_layout_finalize (GObject *object)
static void static void
eek_xml_layout_class_init (EekXmlLayoutClass *klass) eek_xml_layout_class_init (EekXmlLayoutClass *klass)
{ {
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
gobject_class->set_property = eek_xml_layout_set_property; gobject_class->set_property = eek_xml_layout_set_property;
gobject_class->get_property = eek_xml_layout_get_property; gobject_class->get_property = eek_xml_layout_get_property;
gobject_class->finalize = eek_xml_layout_finalize; gobject_class->finalize = eek_xml_layout_finalize;
@ -1122,8 +1125,30 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
g_slice_free (EekXmlKeyboardDesc, desc); g_slice_free (EekXmlKeyboardDesc, desc);
} }
/**
* 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 gboolean static gboolean
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error) parse_geometry (const gchar *path, EekKeyboard *keyboard, GArray *outline_array, GHashTable *name_key_hash, GError **error)
{ {
GeometryParseData *data; GeometryParseData *data;
GMarkupParseContext *pcontext; GMarkupParseContext *pcontext;
@ -1143,7 +1168,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
if (input == NULL) if (input == NULL)
return FALSE; return FALSE;
data = geometry_parse_data_new (keyboard); data = geometry_parse_data_new (keyboard, name_key_hash);
pcontext = g_markup_parse_context_new (&geometry_parser, pcontext = g_markup_parse_context_new (&geometry_parser,
0, 0,
data, data,
@ -1164,7 +1189,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
EekOutline *outline = v; EekOutline *outline = v;
gulong oref; 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_insert (oref_hash, k, GUINT_TO_POINTER(oref));
} }
@ -1183,7 +1208,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
static gboolean static gboolean
parse_symbols_with_prerequisites (const gchar *keyboards_dir, parse_symbols_with_prerequisites (const gchar *keyboards_dir,
const gchar *name, const gchar *name,
EekKeyboard *keyboard, LevelKeyboard *keyboard,
GList **loaded, GList **loaded,
GError **error) GError **error)
{ {
@ -1233,7 +1258,7 @@ parse_symbols_with_prerequisites (const gchar *keyboards_dir,
} }
static gboolean static gboolean
parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error) parse_symbols (const gchar *path, LevelKeyboard *keyboard, GError **error)
{ {
SymbolsParseData *data; SymbolsParseData *data;
GMarkupParseContext *pcontext; GMarkupParseContext *pcontext;

View File

@ -62,5 +62,8 @@ GList *eek_xml_list_keyboards (void);
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc); EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
void eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc); void eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
LevelKeyboard *
eek_xml_layout_real_create_keyboard (EekLayout *self,
EekboardContextService *manager);
G_END_DECLS G_END_DECLS
#endif /* EEK_XML_LAYOUT_H */ #endif /* EEK_XML_LAYOUT_H */

View File

@ -71,7 +71,7 @@ struct _EekboardContextServicePrivate {
gboolean visible; gboolean visible;
gboolean fullscreen; gboolean fullscreen;
EekKeyboard *keyboard; // currently used keyboard LevelKeyboard *keyboard; // currently used keyboard
GHashTable *keyboard_hash; // a table of available keyboards, per layout GHashTable *keyboard_hash; // a table of available keyboards, per layout
// TODO: make use of repeating buttons // TODO: make use of repeating buttons
@ -86,11 +86,10 @@ struct _EekboardContextServicePrivate {
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT); G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
static EekKeyboard * static LevelKeyboard *
eekboard_context_service_real_create_keyboard (EekboardContextService *self, eekboard_context_service_real_create_keyboard (EekboardContextService *self,
const gchar *keyboard_type) const gchar *keyboard_type)
{ {
EekKeyboard *keyboard;
EekLayout *layout; EekLayout *layout;
GError *error; 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) { if (!keyboard) {
g_error("Failed to create a keyboard"); g_error("Failed to create a keyboard");
} }
@ -319,21 +318,18 @@ settings_update_layout(EekboardContextService *context)
// generic part follows // generic part follows
static guint keyboard_id = 0; 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)); GUINT_TO_POINTER(keyboard_id));
// create a keyboard // create a keyboard
if (!keyboard) { if (!keyboard) {
EekboardContextServiceClass *klass = EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context); keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout);
keyboard = klass->create_keyboard (context, keyboard_layout); eek_keyboard_set_modifier_behavior (level_keyboard_current(keyboard),
eek_keyboard_set_modifier_behavior (keyboard,
EEK_MODIFIER_BEHAVIOR_LATCH); EEK_MODIFIER_BEHAVIOR_LATCH);
g_hash_table_insert (context->priv->keyboard_hash, g_hash_table_insert (context->priv->keyboard_hash,
GUINT_TO_POINTER(keyboard_id), GUINT_TO_POINTER(keyboard_id),
keyboard); keyboard);
g_object_set_data (G_OBJECT(keyboard), keyboard->id = keyboard_id;
"keyboard-id",
GUINT_TO_POINTER(keyboard_id));
keyboard_id++; keyboard_id++;
} }
// set as current // set as current
@ -374,7 +370,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
klass->create_keyboard = eekboard_context_service_real_create_keyboard;
klass->show_keyboard = eekboard_context_service_real_show_keyboard; klass->show_keyboard = eekboard_context_service_real_show_keyboard;
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard; klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
@ -578,7 +573,7 @@ eekboard_context_service_destroy (EekboardContextService *context)
* Get keyboard currently active in @context. * Get keyboard currently active in @context.
* Returns: (transfer none): an #EekKeyboard * Returns: (transfer none): an #EekKeyboard
*/ */
EekKeyboard * LevelKeyboard *
eekboard_context_service_get_keyboard (EekboardContextService *context) eekboard_context_service_get_keyboard (EekboardContextService *context)
{ {
return context->priv->keyboard; return context->priv->keyboard;
@ -598,7 +593,7 @@ eekboard_context_service_get_fullscreen (EekboardContextService *context)
} }
void eekboard_context_service_set_keymap(EekboardContextService *context, void eekboard_context_service_set_keymap(EekboardContextService *context,
const EekKeyboard *keyboard) const LevelKeyboard *keyboard)
{ {
zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard, zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,

View File

@ -97,13 +97,12 @@ void eekboard_context_service_show_keyboard
void eekboard_context_service_hide_keyboard void eekboard_context_service_hide_keyboard
(EekboardContextService *context); (EekboardContextService *context);
void eekboard_context_service_destroy (EekboardContextService *context); void eekboard_context_service_destroy (EekboardContextService *context);
EekKeyboard *eekboard_context_service_get_keyboard LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
(EekboardContextService *context);
gboolean eekboard_context_service_get_fullscreen gboolean eekboard_context_service_get_fullscreen
(EekboardContextService *context); (EekboardContextService *context);
void eekboard_context_service_set_keymap(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, void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
uint32_t hint, uint32_t hint,

View File

@ -85,7 +85,7 @@ update_modifier_info (SeatEmitter *client)
static void static void
send_fake_key (SeatEmitter *emitter, send_fake_key (SeatEmitter *emitter,
EekKeyboard *keyboard, LevelKeyboard *keyboard,
guint keycode, guint keycode,
guint keyboard_modifiers, guint keyboard_modifiers,
gboolean pressed, gboolean pressed,
@ -105,7 +105,7 @@ send_fake_key (SeatEmitter *emitter,
void void
emit_key_activated (EekboardContextService *manager, emit_key_activated (EekboardContextService *manager,
EekKeyboard *keyboard, LevelKeyboard *keyboard,
guint keycode, guint keycode,
EekSymbol *symbol, EekSymbol *symbol,
EekModifierType modifiers, EekModifierType modifiers,

View File

@ -39,7 +39,7 @@ enum mod_indices {
}; };
void void
emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard, emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard,
guint keycode, guint keycode,
EekSymbol *symbol, EekSymbol *symbol,
guint modifiers, guint modifiers,

View File

@ -19,4 +19,5 @@ uint32_t squeek_key_get_keycode(struct squeek_key *key);
void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode); 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); 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 #endif

View File

@ -83,9 +83,7 @@ on_notify_keyboard (GObject *object,
GParamSpec *spec, GParamSpec *spec,
ServerContextService *context) ServerContextService *context)
{ {
const EekKeyboard *keyboard; const LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
if (!keyboard) if (!keyboard)
g_error("Programmer error: keyboard layout was unset!"); g_error("Programmer error: keyboard layout was unset!");
@ -141,13 +139,13 @@ set_geometry (ServerContextService *context)
GdkWindow *root = gdk_screen_get_root_window (screen); GdkWindow *root = gdk_screen_get_root_window (screen);
GdkDisplay *display = gdk_display_get_default (); GdkDisplay *display = gdk_display_get_default ();
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, root); 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; GdkRectangle rect;
EekBounds bounds; EekBounds bounds;
gdk_monitor_get_geometry (monitor, &rect); 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))) { if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
gint width = rect.width; gint width = rect.width;
@ -228,14 +226,12 @@ destroy_window (ServerContextService *context)
static void static void
make_widget (ServerContextService *context) make_widget (ServerContextService *context)
{ {
EekKeyboard *keyboard;
if (context->widget) { if (context->widget) {
gtk_widget_destroy(context->widget); gtk_widget_destroy(context->widget);
context->widget = NULL; 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); context->widget = eek_gtk_keyboard_new (keyboard);

View File

@ -21,6 +21,4 @@ const char *squeek_symbol_get_icon_name(struct squeek_symbol* symbol);
uint32_t squeek_symbol_get_modifier_mask(struct squeek_symbol* symbol); uint32_t squeek_symbol_get_modifier_mask(struct squeek_symbol* symbol);
void squeek_symbol_print(struct squeek_symbol* symbol); void squeek_symbol_print(struct squeek_symbol* symbol);
const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_symbols *symbols);
#endif #endif

View File

@ -30,7 +30,7 @@ static void
test_output_parse (void) test_output_parse (void)
{ {
EekLayout *layout; EekLayout *layout;
EekKeyboard *keyboard; LevelKeyboard *keyboard;
GError *error; GError *error;
error = NULL; error = NULL;
@ -39,9 +39,9 @@ test_output_parse (void)
/* We don't need the context service to parse an XML file, so we can pass /* We don't need the context service to parse an XML file, so we can pass
NULL when creating a keyboard. */ NULL when creating a keyboard. */
keyboard = eek_keyboard_new (NULL, layout, 640, 480); keyboard = eek_xml_layout_real_create_keyboard(layout, NULL);
g_object_unref (layout); g_object_unref (layout);
g_object_unref (keyboard); level_keyboard_free(keyboard);
} }
int int

View File

@ -32,14 +32,14 @@ static void
test_check_xkb (void) test_check_xkb (void)
{ {
EekLayout *layout; EekLayout *layout;
EekKeyboard *keyboard; LevelKeyboard *keyboard;
GError *error; GError *error;
error = NULL; error = NULL;
layout = eek_xml_layout_new ("us", &error); layout = eek_xml_layout_new ("us", &error);
g_assert_no_error (error); g_assert_no_error (error);
keyboard = eek_keyboard_new (NULL, layout, 640, 480); keyboard = eek_xml_layout_real_create_keyboard(layout, NULL);
gchar *keymap_str = eek_keyboard_get_keymap(keyboard); gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
@ -58,7 +58,7 @@ test_check_xkb (void)
} }
g_object_unref (layout); g_object_unref (layout);
g_object_unref (keyboard); level_keyboard_free(keyboard);
} }
int int