eekkey: Dropped in favor of Button
Each Button has a KeyState, which may be shared with other buttons. The list of pressed and locked buttons is used as a list of keys, causing a search for the button in the current view.
This commit is contained in:
		@ -35,7 +35,6 @@
 | 
				
			|||||||
#include "eek-renderer.h"
 | 
					#include "eek-renderer.h"
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
#include "eek-key.h"
 | 
					 | 
				
			||||||
#include "src/symbol.h"
 | 
					#include "src/symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-gtk-keyboard.h"
 | 
					#include "eek-gtk-keyboard.h"
 | 
				
			||||||
@ -64,18 +63,16 @@ typedef struct _EekGtkKeyboardPrivate
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
 | 
					G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void       on_key_pressed          (EekKey      *key, EekKeyboard *view,
 | 
					static void       on_button_pressed          (struct squeek_button *button, EekKeyboard *view,
 | 
				
			||||||
                                           EekGtkKeyboard *self);
 | 
					                                           EekGtkKeyboard *self);
 | 
				
			||||||
static void       on_key_released         (EekKey      *key,
 | 
					static void       on_button_released         (struct squeek_button *button,
 | 
				
			||||||
                                           EekKeyboard *view,
 | 
					                                           EekKeyboard *view,
 | 
				
			||||||
                                           EekGtkKeyboard *self);
 | 
					                                           EekGtkKeyboard *self);
 | 
				
			||||||
static void       render_pressed_key      (GtkWidget   *widget, EekKeyboard *view,
 | 
					static void       render_pressed_button      (GtkWidget   *widget, struct button_place *place);
 | 
				
			||||||
                                           EekKey      *key);
 | 
					static void       render_locked_button       (GtkWidget   *widget,
 | 
				
			||||||
static void       render_locked_key       (GtkWidget   *widget,
 | 
					                                           struct button_place *place);
 | 
				
			||||||
                                           EekKeyboard *view,
 | 
					static void       render_released_button     (GtkWidget   *widget,
 | 
				
			||||||
                                           EekKey      *key);
 | 
					                                           struct squeek_button *button);
 | 
				
			||||||
static void       render_released_key     (GtkWidget   *widget,
 | 
					 | 
				
			||||||
                                           EekKey      *key);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
					eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
				
			||||||
@ -117,15 +114,23 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
				
			|||||||
    EekKeyboard *view = priv->keyboard->views[priv->keyboard->level];
 | 
					    EekKeyboard *view = priv->keyboard->views[priv->keyboard->level];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* redraw pressed key */
 | 
					    /* redraw pressed key */
 | 
				
			||||||
    const GList *list = priv->keyboard->pressed_keys;
 | 
					    const GList *list = priv->keyboard->pressed_buttons;
 | 
				
			||||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
					    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
        render_pressed_key (self, view, head->data);
 | 
					        struct button_place place = eek_keyboard_get_button_by_state(
 | 
				
			||||||
 | 
					            view, squeek_button_get_key(head->data)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        render_pressed_button (self, &place);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* redraw locked key */
 | 
					    /* redraw locked key */
 | 
				
			||||||
    list = priv->keyboard->locked_keys;
 | 
					    list = priv->keyboard->locked_buttons;
 | 
				
			||||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
					    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
        render_locked_key (self, view, ((EekModifierKey *)head->data)->key);
 | 
					        struct button_place place = eek_keyboard_get_button_by_state(
 | 
				
			||||||
 | 
					            view, squeek_button_get_key(
 | 
				
			||||||
 | 
					                ((EekModifierKey *)head->data)->button
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        render_locked_button (self, &place);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
@ -152,11 +157,11 @@ static void depress(EekGtkKeyboard *self,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
					    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
				
			||||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, view, x, y);
 | 
					    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (key) {
 | 
					    if (button) {
 | 
				
			||||||
        eek_keyboard_press_key(priv->keyboard, key, time);
 | 
					        eek_keyboard_press_button(priv->keyboard, button, time);
 | 
				
			||||||
        on_key_pressed(key, view, self);
 | 
					        on_button_pressed(button, view, self);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -164,32 +169,32 @@ static void drag(EekGtkKeyboard *self,
 | 
				
			|||||||
                 gdouble x, gdouble y, guint32 time) {
 | 
					                 gdouble x, gdouble y, guint32 time) {
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
					    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
				
			||||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, view, x, y);
 | 
					    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
				
			||||||
    GList *list, *head;
 | 
					    GList *list, *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list = g_list_copy(priv->keyboard->pressed_keys);
 | 
					    list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (key) {
 | 
					    if (button) {
 | 
				
			||||||
        gboolean found = FALSE;
 | 
					        gboolean found = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (head = list; head; head = g_list_next (head)) {
 | 
					        for (head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
            if (head->data == key) {
 | 
					            if (head->data == button) {
 | 
				
			||||||
                found = TRUE;
 | 
					                found = TRUE;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
					                eek_keyboard_release_button(priv->keyboard, head->data, time);
 | 
				
			||||||
                on_key_released(key, view, self);
 | 
					                on_button_released(button, view, self);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g_list_free (list);
 | 
					        g_list_free (list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!found) {
 | 
					        if (!found) {
 | 
				
			||||||
            eek_keyboard_press_key(priv->keyboard, key, time);
 | 
					            eek_keyboard_press_button(priv->keyboard, button, time);
 | 
				
			||||||
            on_key_pressed(key, view, self);
 | 
					            on_button_pressed(button, view, self);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        for (head = list; head; head = g_list_next (head)) {
 | 
					        for (head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
            eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
					            eek_keyboard_release_button(priv->keyboard, button, time);
 | 
				
			||||||
            on_key_released(EEK_KEY(head->data), view, self);
 | 
					            on_button_released(button, view, self);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g_list_free (list);
 | 
					        g_list_free (list);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -200,11 +205,11 @@ static void release(EekGtkKeyboard *self, guint32 time) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
					    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GList *list = g_list_copy(priv->keyboard->pressed_keys);
 | 
					    GList *list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
				
			||||||
    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);
 | 
					        struct squeek_button *button = head->data;
 | 
				
			||||||
        eek_keyboard_release_key(priv->keyboard, key, time);
 | 
					        eek_keyboard_release_button(priv->keyboard, button, time);
 | 
				
			||||||
        on_key_released(key, view, self);
 | 
					        on_button_released(button, view, self);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    g_list_free (list);
 | 
					    g_list_free (list);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -287,7 +292,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 = g_list_copy(priv->keyboard->pressed_keys);
 | 
					        list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
				
			||||||
        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");
 | 
				
			||||||
@ -309,11 +314,11 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget  *widget,
 | 
				
			|||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
					    EekKeyboard *view = level_keyboard_current(priv->keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer,
 | 
					    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer,
 | 
				
			||||||
                                                     view,
 | 
					                                                     view,
 | 
				
			||||||
                                                     (gdouble)x,
 | 
					                                                     (gdouble)x,
 | 
				
			||||||
                                                     (gdouble)y);
 | 
					                                                     (gdouble)y);
 | 
				
			||||||
    if (key) {
 | 
					    if (button) {
 | 
				
			||||||
        //struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
 | 
					        //struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
 | 
				
			||||||
        const gchar *text = NULL; // FIXME
 | 
					        const gchar *text = NULL; // FIXME
 | 
				
			||||||
        if (text) {
 | 
					        if (text) {
 | 
				
			||||||
@ -369,7 +374,7 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
				
			|||||||
    if (priv->keyboard) {
 | 
					    if (priv->keyboard) {
 | 
				
			||||||
        GList *list, *head;
 | 
					        GList *list, *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        list = g_list_copy(priv->keyboard->pressed_keys);
 | 
					        list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
				
			||||||
        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", level_keyboard_current(priv->keyboard));
 | 
					            g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard));
 | 
				
			||||||
@ -452,9 +457,8 @@ eek_gtk_keyboard_new (LevelKeyboard *keyboard)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_pressed_key (GtkWidget *widget,
 | 
					render_pressed_button (GtkWidget *widget,
 | 
				
			||||||
                    EekKeyboard *view,
 | 
					                       struct button_place *place)
 | 
				
			||||||
                    EekKey    *key)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
					    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
@ -464,7 +468,7 @@ render_pressed_key (GtkWidget *widget,
 | 
				
			|||||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
					    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
				
			||||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
					    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_render_key (priv->renderer, cr, view, key, 1.0, TRUE);
 | 
					    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
					    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ -474,9 +478,7 @@ render_pressed_key (GtkWidget *widget,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_locked_key (GtkWidget *widget,
 | 
					render_locked_button (GtkWidget *widget, struct button_place *place)
 | 
				
			||||||
                   EekKeyboard *view,
 | 
					 | 
				
			||||||
                   EekKey    *key)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
					    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
@ -486,7 +488,7 @@ render_locked_key (GtkWidget *widget,
 | 
				
			|||||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
					    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
				
			||||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
					    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_render_key (priv->renderer, cr, view, key, 1.0, TRUE);
 | 
					    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gdk_window_end_draw_frame (window, context);
 | 
					    gdk_window_end_draw_frame (window, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -494,10 +496,10 @@ render_locked_key (GtkWidget *widget,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_released_key (GtkWidget *widget,
 | 
					render_released_button (GtkWidget *widget,
 | 
				
			||||||
                     EekKey    *key)
 | 
					                        struct squeek_button *button)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    (void)key;
 | 
					    (void)button;
 | 
				
			||||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
					    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -514,7 +516,7 @@ render_released_key (GtkWidget *widget,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
on_key_pressed (EekKey      *key,
 | 
					on_button_pressed (struct squeek_button *button,
 | 
				
			||||||
                EekKeyboard *view,
 | 
					                EekKeyboard *view,
 | 
				
			||||||
                EekGtkKeyboard *self)
 | 
					                EekGtkKeyboard *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -524,7 +526,14 @@ on_key_pressed (EekKey      *key,
 | 
				
			|||||||
    if (!priv->renderer)
 | 
					    if (!priv->renderer)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render_pressed_key (GTK_WIDGET(self), view, key);
 | 
					    struct button_place place = {
 | 
				
			||||||
 | 
					        .button = button,
 | 
				
			||||||
 | 
					        .section = eek_keyboard_get_section(view, button),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    if (!place.section) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    render_pressed_button (GTK_WIDGET(self), &place);
 | 
				
			||||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
					    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if HAVE_LIBCANBERRA
 | 
					#if HAVE_LIBCANBERRA
 | 
				
			||||||
@ -537,7 +546,7 @@ on_key_pressed (EekKey      *key,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
on_key_released (EekKey      *key,
 | 
					on_button_released (struct squeek_button *button,
 | 
				
			||||||
                 EekKeyboard *view,
 | 
					                 EekKeyboard *view,
 | 
				
			||||||
                 EekGtkKeyboard *self)
 | 
					                 EekGtkKeyboard *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -548,7 +557,7 @@ on_key_released (EekKey      *key,
 | 
				
			|||||||
    if (!priv->renderer)
 | 
					    if (!priv->renderer)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render_released_key (GTK_WIDGET(self), key);
 | 
					    render_released_button (GTK_WIDGET(self), button);
 | 
				
			||||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
					    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if HAVE_LIBCANBERRA
 | 
					#if HAVE_LIBCANBERRA
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										277
									
								
								eek/eek-key.c
									
									
									
									
									
								
							
							
						
						
									
										277
									
								
								eek/eek-key.c
									
									
									
									
									
								
							@ -1,277 +0,0 @@
 | 
				
			|||||||
/* 
 | 
					 | 
				
			||||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
					 | 
				
			||||||
 * Copyright (C) 2010-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
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * SECTION:eek-key
 | 
					 | 
				
			||||||
 * @short_description: Base class of a key
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * The #EekKeyClass class represents a key.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "config.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "eek-section.h"
 | 
					 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					 | 
				
			||||||
#include "src/keyboard.h"
 | 
					 | 
				
			||||||
#include "src/symbol.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "eek-key.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
    PROP_0,
 | 
					 | 
				
			||||||
    PROP_OREF,
 | 
					 | 
				
			||||||
    PROP_LAST
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct _EekKeyPrivate
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gulong oref; // UI outline reference
 | 
					 | 
				
			||||||
    struct squeek_key *state;
 | 
					 | 
				
			||||||
} EekKeyPrivate;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
eek_key_set_locked (EekKey *self, gboolean value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
					 | 
				
			||||||
    squeek_key_set_pressed(priv->state, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
eek_key_finalize (GObject *object)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EekKey        *self = EEK_KEY (object);
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    squeek_key_free (priv->state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
eek_key_set_property (GObject      *object,
 | 
					 | 
				
			||||||
                      guint         prop_id,
 | 
					 | 
				
			||||||
                      const GValue *value,
 | 
					 | 
				
			||||||
                      GParamSpec   *pspec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    switch (prop_id) {
 | 
					 | 
				
			||||||
    case PROP_OREF:
 | 
					 | 
				
			||||||
        eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
eek_key_get_property (GObject    *object,
 | 
					 | 
				
			||||||
                      guint       prop_id,
 | 
					 | 
				
			||||||
                      GValue     *value,
 | 
					 | 
				
			||||||
                      GParamSpec *pspec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    switch (prop_id) {
 | 
					 | 
				
			||||||
    case PROP_OREF:
 | 
					 | 
				
			||||||
        g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
eek_key_class_init (EekKeyClass *klass)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
					 | 
				
			||||||
    GParamSpec        *pspec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gobject_class->set_property = eek_key_set_property;
 | 
					 | 
				
			||||||
    gobject_class->get_property = eek_key_get_property;
 | 
					 | 
				
			||||||
    gobject_class->finalize     = eek_key_finalize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * EekKey:oref:
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * The outline id of #EekKey.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    pspec = g_param_spec_ulong ("oref",
 | 
					 | 
				
			||||||
                                "Oref",
 | 
					 | 
				
			||||||
                                "Outline id of the key",
 | 
					 | 
				
			||||||
                                0, G_MAXULONG, 0,
 | 
					 | 
				
			||||||
                                G_PARAM_READWRITE);
 | 
					 | 
				
			||||||
    g_object_class_install_property (gobject_class, PROP_OREF, pspec);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
eek_key_init (EekKey *self)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
 * @keycode: keycode
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Set the keycode of @key to @keycode.  Since typically the keycode
 | 
					 | 
				
			||||||
 * value is used to find a key in a keyboard by calling
 | 
					 | 
				
			||||||
 * eek_keyboard_find_key_by_keycode, it is not necessarily the same as
 | 
					 | 
				
			||||||
 * the X keycode but it should be unique in the keyboard @key belongs
 | 
					 | 
				
			||||||
 * to.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
eek_key_set_keycode (EekKey *key,
 | 
					 | 
				
			||||||
                     guint   keycode)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_if_fail (EEK_IS_KEY (key));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    squeek_key_set_keycode(priv->state, keycode);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_key_get_keycode:
 | 
					 | 
				
			||||||
 * @key: an #EekKey
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Get keycode of @key.
 | 
					 | 
				
			||||||
 * Returns: keycode or %EEK_INVALID_KEYCODE on failure
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
guint
 | 
					 | 
				
			||||||
eek_key_get_keycode (EekKey *key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return squeek_key_get_keycode(priv->state);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_key_get_symbol_at_index:
 | 
					 | 
				
			||||||
 * @key: an #EekKey
 | 
					 | 
				
			||||||
 * @group: group index of the symbol matrix
 | 
					 | 
				
			||||||
 * @level: level index of the symbol matrix
 | 
					 | 
				
			||||||
 * @fallback_group: fallback group index
 | 
					 | 
				
			||||||
 * @fallback_level: fallback level index
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Get the symbol at (@group, @level) in the symbol matrix of @key.
 | 
					 | 
				
			||||||
 * Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct squeek_symbol*
 | 
					 | 
				
			||||||
eek_key_get_symbol_at_index (EekKey *key,
 | 
					 | 
				
			||||||
                             gint    group)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
    return squeek_key_get_symbol(priv->state);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_key_set_oref:
 | 
					 | 
				
			||||||
 * @key: an #EekKey
 | 
					 | 
				
			||||||
 * @oref: outline id of @key
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Set the outline id of @key to @oref.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
eek_key_set_oref (EekKey *key,
 | 
					 | 
				
			||||||
                  guint   oref)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (priv->oref != oref) {
 | 
					 | 
				
			||||||
        priv->oref = oref;
 | 
					 | 
				
			||||||
        g_object_notify (G_OBJECT(key), "oref");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_key_get_oref:
 | 
					 | 
				
			||||||
 * @key: an #EekKey
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Get the outline id of @key.
 | 
					 | 
				
			||||||
 * Returns: unsigned integer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
guint
 | 
					 | 
				
			||||||
eek_key_get_oref (EekKey *key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_val_if_fail (EEK_IS_KEY (key), 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return priv->oref;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_key_is_pressed:
 | 
					 | 
				
			||||||
 * @key: an #EekKey
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Return %TRUE if key is marked as pressed.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
gboolean
 | 
					 | 
				
			||||||
eek_key_is_pressed (EekKey *key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = (EekKeyPrivate*)eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (bool)squeek_key_is_pressed(priv->state);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_key_is_locked:
 | 
					 | 
				
			||||||
 * @key: an #EekKey
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Return %TRUE if key is marked as locked.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
gboolean
 | 
					 | 
				
			||||||
eek_key_is_locked (EekKey *key)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (bool)squeek_key_is_locked(priv->state);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void eek_key_set_pressed(EekKey *key, gboolean value)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    squeek_key_set_pressed(priv->state, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct squeek_key *eek_key_get_state(EekKey *key) {
 | 
					 | 
				
			||||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
					 | 
				
			||||||
    return priv->state;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,72 +0,0 @@
 | 
				
			|||||||
/* 
 | 
					 | 
				
			||||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
					 | 
				
			||||||
 * Copyright (C) 2010-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 <eek/eek.h> can be included directly."
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef EEK_KEY_H
 | 
					 | 
				
			||||||
#define EEK_KEY_H 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "eek-element.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
G_BEGIN_DECLS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define EEK_TYPE_KEY (eek_key_get_type())
 | 
					 | 
				
			||||||
G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * EekKeyClass:
 | 
					 | 
				
			||||||
 * @pressed: class handler for #EekKey::pressed signal
 | 
					 | 
				
			||||||
 * @released: class handler for #EekKey::released signal
 | 
					 | 
				
			||||||
 * @locked: class handler for #EekKey::locked signal
 | 
					 | 
				
			||||||
 * @unlocked: class handler for #EekKey::unlocked signal
 | 
					 | 
				
			||||||
 * @cancelled: class handler for #EekKey::cancelled signal
 | 
					 | 
				
			||||||
 * @is_pressed: virtual function for getting whether the key is pressed
 | 
					 | 
				
			||||||
 * @is_locked: virtual function for getting whether the key is locked
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct _EekKeyClass
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /*< private >*/
 | 
					 | 
				
			||||||
    EekElementClass parent_class;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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);
 | 
					 | 
				
			||||||
struct squeek_key *eek_key_get_state(EekKey *key);
 | 
					 | 
				
			||||||
struct squeek_symbol *eek_key_get_symbol_at_index (EekKey          *key,
 | 
					 | 
				
			||||||
                                              gint             group);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void             eek_key_set_oref            (EekKey          *key,
 | 
					 | 
				
			||||||
                                              guint            oref);
 | 
					 | 
				
			||||||
guint            eek_key_get_oref            (EekKey          *key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gboolean         eek_key_is_pressed          (EekKey          *key);
 | 
					 | 
				
			||||||
gboolean         eek_key_is_locked           (EekKey          *key);
 | 
					 | 
				
			||||||
void             eek_key_set_pressed         (EekKey          *key,
 | 
					 | 
				
			||||||
                                              gboolean         value);
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
eek_key_set_locked (EekKey *self, gboolean value);
 | 
					 | 
				
			||||||
void eek_key_share_state(EekKey *self, struct squeek_key *state);
 | 
					 | 
				
			||||||
G_END_DECLS
 | 
					 | 
				
			||||||
#endif  /* EEK_KEY_H */
 | 
					 | 
				
			||||||
@ -31,7 +31,6 @@
 | 
				
			|||||||
#include <glib/gprintf.h>
 | 
					#include <glib/gprintf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
#include "eek-key.h"
 | 
					 | 
				
			||||||
#include "eek-enumtypes.h"
 | 
					#include "eek-enumtypes.h"
 | 
				
			||||||
#include "eekboard/key-emitter.h"
 | 
					#include "eekboard/key-emitter.h"
 | 
				
			||||||
#include "keymap.h"
 | 
					#include "keymap.h"
 | 
				
			||||||
@ -81,7 +80,6 @@ eek_modifier_key_copy (EekModifierKey *modkey)
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
eek_modifier_key_free (EekModifierKey *modkey)
 | 
					eek_modifier_key_free (EekModifierKey *modkey)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_object_unref (modkey->key);
 | 
					 | 
				
			||||||
    g_slice_free (EekModifierKey, modkey);
 | 
					    g_slice_free (EekModifierKey, modkey);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -129,30 +127,30 @@ eek_keyboard_get_property (GObject    *object,
 | 
				
			|||||||
/// and instead refer to the contained symbols
 | 
					/// and instead refer to the contained symbols
 | 
				
			||||||
static guint
 | 
					static guint
 | 
				
			||||||
set_key_states (LevelKeyboard    *keyboard,
 | 
					set_key_states (LevelKeyboard    *keyboard,
 | 
				
			||||||
                        EekKey         *key,
 | 
					                struct squeek_button *button,
 | 
				
			||||||
                guint new_level)
 | 
					                guint new_level)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    struct squeek_key *key = squeek_button_get_key(button);
 | 
				
			||||||
    // Keys locking rules hardcoded for the time being...
 | 
					    // Keys locking rules hardcoded for the time being...
 | 
				
			||||||
    const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
 | 
					    const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
 | 
				
			||||||
    // Lock the shift whenever it's pressed on the baselevel
 | 
					    // Lock the shift whenever it's pressed on the baselevel
 | 
				
			||||||
    // TODO: need to lock shift on the destination level
 | 
					    // TODO: need to lock shift on the destination level
 | 
				
			||||||
    if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
 | 
					    if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
 | 
				
			||||||
        EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
					        EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
				
			||||||
        modifier_key->modifiers = 0;
 | 
					        modifier_key->modifiers = 0;
 | 
				
			||||||
        modifier_key->key = g_object_ref (key);
 | 
					        modifier_key->button = button;
 | 
				
			||||||
        keyboard->locked_keys =
 | 
					        keyboard->locked_buttons =
 | 
				
			||||||
            g_list_prepend (keyboard->locked_keys, modifier_key);
 | 
					            g_list_prepend (keyboard->locked_buttons, modifier_key);
 | 
				
			||||||
        eek_key_set_locked(modifier_key->key, true);
 | 
					        squeek_key_set_locked(key, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (keyboard->level == 1) {
 | 
					    if (keyboard->level == 1) {
 | 
				
			||||||
        // Only shift is locked in this state, unlock on any key press
 | 
					        // Only shift is locked in this state, unlock on any key press
 | 
				
			||||||
        for (GList *head = keyboard->locked_keys; head; ) {
 | 
					        for (GList *head = keyboard->locked_buttons; head; ) {
 | 
				
			||||||
            EekModifierKey *modifier_key = head->data;
 | 
					            EekModifierKey *modifier_key = head->data;
 | 
				
			||||||
            GList *next = g_list_next (head);
 | 
					            GList *next = g_list_next (head);
 | 
				
			||||||
            keyboard->locked_keys =
 | 
					            keyboard->locked_buttons =
 | 
				
			||||||
                g_list_remove_link (keyboard->locked_keys, head);
 | 
					                g_list_remove_link (keyboard->locked_buttons, head);
 | 
				
			||||||
            eek_key_set_locked(modifier_key->key, false);
 | 
					            squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
 | 
				
			||||||
            g_list_free1 (head);
 | 
					            g_list_free1 (head);
 | 
				
			||||||
            head = next;
 | 
					            head = next;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -163,13 +161,13 @@ set_key_states (LevelKeyboard    *keyboard,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
 | 
					// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
set_level_from_press (LevelKeyboard *keyboard, EekKey *key)
 | 
					set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* 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 */
 | 
				
			||||||
    guint level = keyboard->level;
 | 
					    guint level = keyboard->level;
 | 
				
			||||||
    /* Handle non-emitting keys */
 | 
					    /* Handle non-emitting keys */
 | 
				
			||||||
    if (key) {
 | 
					    if (button) {
 | 
				
			||||||
        const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
 | 
					        const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button)));
 | 
				
			||||||
        if (g_strcmp0(name, "show_numbers") == 0) {
 | 
					        if (g_strcmp0(name, "show_numbers") == 0) {
 | 
				
			||||||
            level = 2;
 | 
					            level = 2;
 | 
				
			||||||
        } else if (g_strcmp0(name, "show_letters") == 0) {
 | 
					        } else if (g_strcmp0(name, "show_letters") == 0) {
 | 
				
			||||||
@ -181,18 +179,17 @@ set_level_from_press (LevelKeyboard *keyboard, EekKey *key)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    keyboard->level = set_key_states(keyboard, key, level);
 | 
					    keyboard->level = set_key_states(keyboard, button, level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_layout_update_layout(keyboard);
 | 
					    eek_layout_update_layout(keyboard);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp) {
 | 
					void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
 | 
				
			||||||
    eek_key_set_pressed(key, TRUE);
 | 
					    struct squeek_key *key = squeek_button_get_key(button);
 | 
				
			||||||
    keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key);
 | 
					    squeek_key_set_pressed(key, TRUE);
 | 
				
			||||||
 | 
					    keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
 | 
					    struct squeek_symbol *symbol = squeek_key_get_symbol(key);
 | 
				
			||||||
        key, 0
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    if (!symbol)
 | 
					    if (!symbol)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -201,32 +198,31 @@ void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timest
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // "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 = squeek_key_get_keycode (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
 | 
					    emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void eek_keyboard_release_key(LevelKeyboard *keyboard,
 | 
					void eek_keyboard_release_button(LevelKeyboard *keyboard,
 | 
				
			||||||
                               EekKey      *key,
 | 
					                              struct squeek_button *button,
 | 
				
			||||||
                               guint32      timestamp) {
 | 
					                               guint32      timestamp) {
 | 
				
			||||||
    for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) {
 | 
					    for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) {
 | 
				
			||||||
        if (head->data == key) {
 | 
					        if (head->data == button) {
 | 
				
			||||||
            keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head);
 | 
					            keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, head);
 | 
				
			||||||
            g_list_free1 (head);
 | 
					            g_list_free1 (head);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
 | 
					    struct squeek_symbol *symbol = squeek_button_get_symbol(button);
 | 
				
			||||||
        key, 0);
 | 
					 | 
				
			||||||
    if (!symbol)
 | 
					    if (!symbol)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_level_from_press (keyboard, key);
 | 
					    set_level_from_press (keyboard, button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // "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 = squeek_key_get_keycode (squeek_button_get_key(button));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
 | 
					    emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -306,14 +302,14 @@ void level_keyboard_init(LevelKeyboard *self) {
 | 
				
			|||||||
    self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
					    self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash) {
 | 
					LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_button_hash) {
 | 
				
			||||||
    LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
 | 
					    LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
 | 
				
			||||||
    level_keyboard_init(keyboard);
 | 
					    level_keyboard_init(keyboard);
 | 
				
			||||||
    for (uint i = 0; i < 4; i++) {
 | 
					    for (uint i = 0; i < 4; i++) {
 | 
				
			||||||
        keyboard->views[i] = views[i];
 | 
					        keyboard->views[i] = views[i];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    keyboard->manager = manager;
 | 
					    keyboard->manager = manager;
 | 
				
			||||||
    keyboard->names = name_key_hash;
 | 
					    keyboard->names = name_button_hash;
 | 
				
			||||||
    return keyboard;
 | 
					    return keyboard;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -325,8 +321,8 @@ LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *
 | 
				
			|||||||
 * Find an #EekKey whose name is @name.
 | 
					 * Find an #EekKey whose name is @name.
 | 
				
			||||||
 * Return value: (transfer none): #EekKey whose name is @name
 | 
					 * Return value: (transfer none): #EekKey whose name is @name
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
EekKey *
 | 
					struct squeek_button*
 | 
				
			||||||
eek_keyboard_find_key_by_name (LevelKeyboard *keyboard,
 | 
					eek_keyboard_find_button_by_name (LevelKeyboard *keyboard,
 | 
				
			||||||
                               const gchar *name)
 | 
					                               const gchar *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return g_hash_table_lookup (keyboard->names, name);
 | 
					    return g_hash_table_lookup (keyboard->names, name);
 | 
				
			||||||
@ -386,15 +382,16 @@ eek_keyboard_get_keymap(LevelKeyboard *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;
 | 
				
			||||||
    gchar *key_name;
 | 
					    gchar *button_name;
 | 
				
			||||||
    gpointer key_ptr;
 | 
					    gpointer button_ptr;
 | 
				
			||||||
    g_hash_table_iter_init(&iter, keyboard->names);
 | 
					    g_hash_table_iter_init(&iter, keyboard->names);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (g_hash_table_iter_next(&iter, (gpointer)&key_name, &key_ptr)) {
 | 
					    while (g_hash_table_iter_next(&iter, (gpointer)&button_name, &button_ptr)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        gchar *current, *line;
 | 
					        gchar *current, *line;
 | 
				
			||||||
        EekKey *key = EEK_KEY(key_ptr);
 | 
					        struct squeek_button *button = button_ptr;
 | 
				
			||||||
        guint keycode = eek_key_get_keycode(key);
 | 
					        struct squeek_key *key = squeek_button_get_key(button);
 | 
				
			||||||
 | 
					        guint keycode = squeek_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)
 | 
				
			||||||
@ -402,7 +399,7 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        /* Append a key name-to-keycode definition to the keycodes section. */
 | 
					        /* Append a key name-to-keycode definition to the keycodes section. */
 | 
				
			||||||
        current = keycodes;
 | 
					        current = keycodes;
 | 
				
			||||||
        line = g_strdup_printf("        <%s> = %i;\n", (char *)key_name, keycode);
 | 
					        line = g_strdup_printf("        <%s> = %i;\n", (char *)button_name, keycode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        keycodes = g_strconcat(current, line, NULL);
 | 
					        keycodes = g_strconcat(current, line, NULL);
 | 
				
			||||||
        g_free(line);
 | 
					        g_free(line);
 | 
				
			||||||
@ -410,8 +407,8 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // FIXME: free
 | 
					        // FIXME: free
 | 
				
			||||||
        const char *key_str = squeek_key_to_keymap_entry(
 | 
					        const char *key_str = squeek_key_to_keymap_entry(
 | 
				
			||||||
            (char*)key_name,
 | 
					            (char*)button_name,
 | 
				
			||||||
            eek_key_get_state(key)
 | 
					            key
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        current = symbols;
 | 
					        current = symbols;
 | 
				
			||||||
        symbols = g_strconcat(current, key_str, NULL);
 | 
					        symbols = g_strconcat(current, key_str, NULL);
 | 
				
			||||||
@ -435,34 +432,57 @@ EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct GetSectionData {
 | 
					struct GetSectionData {
 | 
				
			||||||
    const EekKey *key;
 | 
					    const struct squeek_button *button;
 | 
				
			||||||
    EekSection *section;
 | 
					    EekSection *section;
 | 
				
			||||||
 | 
					    const struct squeek_key *needle;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gint check_right_key(EekElement *element, gpointer user_data) {
 | 
					void find_button_in_section(EekElement *element, gpointer user_data) {
 | 
				
			||||||
    EekKey *key = EEK_KEY(element);
 | 
					 | 
				
			||||||
    struct GetSectionData *data = user_data;
 | 
					 | 
				
			||||||
    if (key == data->key) {
 | 
					 | 
				
			||||||
        return TRUE;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        return FALSE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void find_key_in_section(EekElement *element, gpointer user_data) {
 | 
					 | 
				
			||||||
    EekSection *section = EEK_SECTION(element);
 | 
					    EekSection *section = EEK_SECTION(element);
 | 
				
			||||||
    struct GetSectionData *data = user_data;
 | 
					    struct GetSectionData *data = user_data;
 | 
				
			||||||
    if (eek_container_find(EEK_CONTAINER(section), check_right_key, &data)) {
 | 
					    if (data->section) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (eek_section_find(section, data->button)) {
 | 
				
			||||||
        data->section = section;
 | 
					        data->section = section;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekSection *eek_keyboard_get_section(EekKeyboard *keyboard,
 | 
					EekSection *eek_keyboard_get_section(EekKeyboard *keyboard,
 | 
				
			||||||
                                     const EekKey *key) {
 | 
					                                     const struct squeek_button *button) {
 | 
				
			||||||
    struct GetSectionData data = {
 | 
					    struct GetSectionData data = {
 | 
				
			||||||
        .key = key,
 | 
					        .button = button,
 | 
				
			||||||
        .section = NULL,
 | 
					        .section = NULL,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    eek_container_foreach_child(EEK_CONTAINER(keyboard), find_key_in_section, &data);
 | 
					    eek_container_foreach_child(EEK_CONTAINER(keyboard), find_button_in_section, &data);
 | 
				
			||||||
    return data.section;
 | 
					    return data.section;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void find_key_in_section(EekElement *element, gpointer user_data) {
 | 
				
			||||||
 | 
					    EekSection *section = EEK_SECTION(element);
 | 
				
			||||||
 | 
					    struct GetSectionData *data = user_data;
 | 
				
			||||||
 | 
					    if (data->button) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    data->button = eek_section_find_key(section, data->needle);
 | 
				
			||||||
 | 
					    if (data->button) {
 | 
				
			||||||
 | 
					        data->section = section;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: return multiple
 | 
				
			||||||
 | 
					struct button_place eek_keyboard_get_button_by_state(EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                                             const struct squeek_key *key) {
 | 
				
			||||||
 | 
					    struct GetSectionData data = {
 | 
				
			||||||
 | 
					        .section = NULL,
 | 
				
			||||||
 | 
					        .button = NULL,
 | 
				
			||||||
 | 
					        .needle = key,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    eek_container_foreach_child(EEK_CONTAINER(keyboard), find_key_in_section, &data);
 | 
				
			||||||
 | 
					    struct button_place ret = {
 | 
				
			||||||
 | 
					        .section = data.section,
 | 
				
			||||||
 | 
					        .button = (struct squeek_button*)data.button,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,7 @@
 | 
				
			|||||||
#include "eek-container.h"
 | 
					#include "eek-container.h"
 | 
				
			||||||
#include "eek-types.h"
 | 
					#include "eek-types.h"
 | 
				
			||||||
#include "eek-layout.h"
 | 
					#include "eek-layout.h"
 | 
				
			||||||
 | 
					#include "src/layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_BEGIN_DECLS
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -113,7 +114,7 @@ struct _EekKeyboardClass
 | 
				
			|||||||
struct _EekModifierKey {
 | 
					struct _EekModifierKey {
 | 
				
			||||||
    /*< public >*/
 | 
					    /*< public >*/
 | 
				
			||||||
    EekModifierType modifiers;
 | 
					    EekModifierType modifiers;
 | 
				
			||||||
    EekKey *key;
 | 
					    struct squeek_button *button;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct _EekModifierKey EekModifierKey;
 | 
					typedef struct _EekModifierKey EekModifierKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -126,10 +127,10 @@ struct _LevelKeyboard {
 | 
				
			|||||||
    size_t keymap_len; // length of the data inside keymap_fd
 | 
					    size_t keymap_len; // length of the data inside keymap_fd
 | 
				
			||||||
    GArray *outline_array;
 | 
					    GArray *outline_array;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GList *pressed_keys;
 | 
					    GList *pressed_buttons; // struct squeek_button*
 | 
				
			||||||
    GList *locked_keys;
 | 
					    GList *locked_buttons; // struct squeek_button*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Map key names to key objects: */
 | 
					    /* Map button names to button objects: */
 | 
				
			||||||
    GHashTable *names;
 | 
					    GHashTable *names;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    guint id; // as a key to layout choices
 | 
					    guint id; // as a key to layout choices
 | 
				
			||||||
@ -157,11 +158,18 @@ EekSection         *eek_keyboard_create_section
 | 
				
			|||||||
                                     (EekKeyboard        *keyboard);
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
EekSection         *eek_keyboard_get_section
 | 
					EekSection         *eek_keyboard_get_section
 | 
				
			||||||
                                     (EekKeyboard *keyboard,
 | 
					                                     (EekKeyboard *keyboard,
 | 
				
			||||||
                                      const EekKey *key);
 | 
					                                      const struct squeek_button *button);
 | 
				
			||||||
EekKey             *eek_keyboard_find_key_by_name
 | 
					struct squeek_button *eek_keyboard_find_button_by_name(LevelKeyboard *keyboard,
 | 
				
			||||||
                                     (LevelKeyboard *keyboard,
 | 
					 | 
				
			||||||
                                      const gchar        *name);
 | 
					                                      const gchar        *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Represents the path to the button within a view
 | 
				
			||||||
 | 
					struct button_place {
 | 
				
			||||||
 | 
					    EekSection *section;
 | 
				
			||||||
 | 
					    struct squeek_button *button;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct button_place eek_keyboard_get_button_by_state(EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                                             const struct squeek_key *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekOutline         *level_keyboard_get_outline
 | 
					EekOutline         *level_keyboard_get_outline
 | 
				
			||||||
                                     (LevelKeyboard        *keyboard,
 | 
					                                     (LevelKeyboard        *keyboard,
 | 
				
			||||||
@ -171,14 +179,14 @@ EekModifierKey     *eek_modifier_key_copy
 | 
				
			|||||||
void                eek_modifier_key_free
 | 
					void                eek_modifier_key_free
 | 
				
			||||||
                                     (EekModifierKey      *modkey);
 | 
					                                     (EekModifierKey      *modkey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
					void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
				
			||||||
void eek_keyboard_release_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
					void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gchar *             eek_keyboard_get_keymap
 | 
					gchar *             eek_keyboard_get_keymap
 | 
				
			||||||
                                     (LevelKeyboard *keyboard);
 | 
					                                     (LevelKeyboard *keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard);
 | 
					EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard);
 | 
				
			||||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash);
 | 
					LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_button_hash);
 | 
				
			||||||
void level_keyboard_deinit(LevelKeyboard *self);
 | 
					void level_keyboard_deinit(LevelKeyboard *self);
 | 
				
			||||||
void level_keyboard_free(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
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,6 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
					#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-key.h"
 | 
					 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
#include "src/symbol.h"
 | 
					#include "src/symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -76,33 +75,33 @@ extern void _eek_rounded_polygon               (cairo_t     *cr,
 | 
				
			|||||||
                                                EekPoint    *points,
 | 
					                                                EekPoint    *points,
 | 
				
			||||||
                                                guint         num_points);
 | 
					                                                guint         num_points);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void eek_renderer_real_render_key_label (EekRenderer *self,
 | 
					static void eek_renderer_real_render_button_label (EekRenderer *self,
 | 
				
			||||||
                                                PangoLayout *layout,
 | 
					                                                PangoLayout *layout,
 | 
				
			||||||
                                                EekKey      *key);
 | 
					                                                struct squeek_button *button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void invalidate                         (EekRenderer *renderer);
 | 
					static void invalidate                         (EekRenderer *renderer);
 | 
				
			||||||
static void render_key                         (EekRenderer *self,
 | 
					static void render_button                         (EekRenderer *self,
 | 
				
			||||||
                                                cairo_t     *cr, EekKeyboard *view,
 | 
					                                                cairo_t     *cr, struct button_place *place,
 | 
				
			||||||
                                                EekKey      *key,
 | 
					 | 
				
			||||||
                                                gboolean     active);
 | 
					                                                gboolean     active);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _CreateKeyboardSurfaceCallbackData {
 | 
					struct _CreateKeyboardSurfaceCallbackData {
 | 
				
			||||||
    cairo_t *cr;
 | 
					    cairo_t *cr;
 | 
				
			||||||
    EekRenderer *renderer;
 | 
					    EekRenderer *renderer;
 | 
				
			||||||
    EekKeyboard *view;
 | 
					    EekKeyboard *view;
 | 
				
			||||||
 | 
					    EekSection *section;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
 | 
					typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
create_keyboard_surface_key_callback (EekElement *element,
 | 
					create_keyboard_surface_button_callback (gpointer item,
 | 
				
			||||||
                                      gpointer    user_data)
 | 
					                                      gpointer    user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    struct squeek_button *button = item;
 | 
				
			||||||
    CreateKeyboardSurfaceCallbackData *data = user_data;
 | 
					    CreateKeyboardSurfaceCallbackData *data = user_data;
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds = squeek_button_get_bounds(button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_save (data->cr);
 | 
					    cairo_save (data->cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_element_get_bounds (element, &bounds);
 | 
					 | 
				
			||||||
    cairo_translate (data->cr, bounds.x, bounds.y);
 | 
					    cairo_translate (data->cr, bounds.x, bounds.y);
 | 
				
			||||||
    cairo_rectangle (data->cr,
 | 
					    cairo_rectangle (data->cr,
 | 
				
			||||||
                     0.0,
 | 
					                     0.0,
 | 
				
			||||||
@ -110,7 +109,11 @@ create_keyboard_surface_key_callback (EekElement *element,
 | 
				
			|||||||
                     bounds.width + 100,
 | 
					                     bounds.width + 100,
 | 
				
			||||||
                     bounds.height + 100);
 | 
					                     bounds.height + 100);
 | 
				
			||||||
    cairo_clip (data->cr);
 | 
					    cairo_clip (data->cr);
 | 
				
			||||||
    render_key (data->renderer, data->cr, data->view, EEK_KEY(element), FALSE);
 | 
					    struct button_place place = {
 | 
				
			||||||
 | 
					        .section = data->section,
 | 
				
			||||||
 | 
					        .button = button,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    render_button (data->renderer, data->cr, &place, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_restore (data->cr);
 | 
					    cairo_restore (data->cr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -131,8 +134,9 @@ create_keyboard_surface_section_callback (EekElement *element,
 | 
				
			|||||||
    angle = eek_section_get_angle (EEK_SECTION(element));
 | 
					    angle = eek_section_get_angle (EEK_SECTION(element));
 | 
				
			||||||
    cairo_rotate (data->cr, angle * G_PI / 180);
 | 
					    cairo_rotate (data->cr, angle * G_PI / 180);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_container_foreach_child (EEK_CONTAINER(element),
 | 
					    data->section = EEK_SECTION(element);
 | 
				
			||||||
                                 create_keyboard_surface_key_callback,
 | 
					    eek_section_foreach(EEK_SECTION(element),
 | 
				
			||||||
 | 
					                                 create_keyboard_surface_button_callback,
 | 
				
			||||||
                                 data);
 | 
					                                 data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_restore (data->cr);
 | 
					    cairo_restore (data->cr);
 | 
				
			||||||
@ -185,22 +189,20 @@ render_keyboard_surface (EekRenderer *renderer, EekKeyboard *view)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_key_outline (EekRenderer *renderer,
 | 
					render_button_outline (EekRenderer *renderer,
 | 
				
			||||||
                    cairo_t     *cr,
 | 
					                    cairo_t     *cr,
 | 
				
			||||||
                    EekKey      *key,
 | 
					                    struct squeek_button *button,
 | 
				
			||||||
                    gboolean     active)
 | 
					                    gboolean     active)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
					    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
				
			||||||
    EekOutline *outline;
 | 
					    EekOutline *outline;
 | 
				
			||||||
    EekBounds bounds;
 | 
					 | 
				
			||||||
    guint oref;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oref = eek_key_get_oref (key);
 | 
					    guint oref = squeek_button_get_oref(button);
 | 
				
			||||||
    outline = level_keyboard_get_outline (priv->keyboard, oref);
 | 
					    outline = level_keyboard_get_outline (priv->keyboard, oref);
 | 
				
			||||||
    if (outline == NULL)
 | 
					    if (outline == NULL)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
 | 
					    EekBounds bounds = squeek_button_get_bounds(button);
 | 
				
			||||||
    gtk_style_context_set_state(priv->key_context,
 | 
					    gtk_style_context_set_state(priv->key_context,
 | 
				
			||||||
        active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
 | 
					        active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -213,30 +215,26 @@ render_key_outline (EekRenderer *renderer,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_key (EekRenderer *self,
 | 
					render_button (EekRenderer *self,
 | 
				
			||||||
            cairo_t     *cr,
 | 
					            cairo_t     *cr,
 | 
				
			||||||
            EekKeyboard *view,
 | 
					            struct button_place *place,
 | 
				
			||||||
            EekKey      *key,
 | 
					 | 
				
			||||||
            gboolean     active)
 | 
					            gboolean     active)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
					    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
				
			||||||
    EekOutline *outline;
 | 
					    EekOutline *outline;
 | 
				
			||||||
    cairo_surface_t *outline_surface;
 | 
					    cairo_surface_t *outline_surface;
 | 
				
			||||||
    EekBounds bounds;
 | 
					 | 
				
			||||||
    guint oref;
 | 
					 | 
				
			||||||
    struct squeek_symbol *symbol;
 | 
					 | 
				
			||||||
    GHashTable *outline_surface_cache;
 | 
					    GHashTable *outline_surface_cache;
 | 
				
			||||||
    PangoLayout *layout;
 | 
					    PangoLayout *layout;
 | 
				
			||||||
    PangoRectangle extents = { 0, };
 | 
					    PangoRectangle extents = { 0, };
 | 
				
			||||||
    EekColor foreground;
 | 
					    EekColor foreground;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    oref = eek_key_get_oref (key);
 | 
					    guint oref = squeek_button_get_oref (place->button);
 | 
				
			||||||
    outline = level_keyboard_get_outline (priv->keyboard, oref);
 | 
					    outline = level_keyboard_get_outline (priv->keyboard, oref);
 | 
				
			||||||
    if (outline == NULL)
 | 
					    if (outline == NULL)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* render outline */
 | 
					    /* render outline */
 | 
				
			||||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
					    EekBounds bounds = squeek_button_get_bounds(place->button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (active)
 | 
					    if (active)
 | 
				
			||||||
        outline_surface_cache = priv->active_outline_surface_cache;
 | 
					        outline_surface_cache = priv->active_outline_surface_cache;
 | 
				
			||||||
@ -260,8 +258,8 @@ render_key (EekRenderer *self,
 | 
				
			|||||||
        cairo_paint (cr);
 | 
					        cairo_paint (cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cairo_save (cr);
 | 
					        cairo_save (cr);
 | 
				
			||||||
        eek_renderer_apply_transformation_for_key (self, cr, view, key, 1.0, FALSE);
 | 
					        eek_renderer_apply_transformation_for_button (self, cr, place, 1.0, FALSE);
 | 
				
			||||||
        render_key_outline (self, cr, key, active);
 | 
					        render_button_outline (self, cr, place->button, active);
 | 
				
			||||||
        cairo_restore (cr);
 | 
					        cairo_restore (cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cairo_destroy (cr);
 | 
					        cairo_destroy (cr);
 | 
				
			||||||
@ -276,7 +274,7 @@ render_key (EekRenderer *self,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
 | 
					    eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
 | 
				
			||||||
    /* render icon (if any) */
 | 
					    /* render icon (if any) */
 | 
				
			||||||
    symbol = eek_key_get_symbol_at_index (key, 0);
 | 
					    struct squeek_symbol *symbol = squeek_button_get_symbol(place->button);
 | 
				
			||||||
    if (!symbol)
 | 
					    if (!symbol)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -312,7 +310,7 @@ render_key (EekRenderer *self,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* render label */
 | 
					    /* render label */
 | 
				
			||||||
    layout = pango_cairo_create_layout (cr);
 | 
					    layout = pango_cairo_create_layout (cr);
 | 
				
			||||||
    eek_renderer_real_render_key_label (self, layout, key);
 | 
					    eek_renderer_real_render_button_label (self, layout, place->button);
 | 
				
			||||||
    pango_layout_get_extents (layout, NULL, &extents);
 | 
					    pango_layout_get_extents (layout, NULL, &extents);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_save (cr);
 | 
					    cairo_save (cr);
 | 
				
			||||||
@ -348,23 +346,20 @@ render_key (EekRenderer *self,
 | 
				
			|||||||
 *  normal keys for popups.
 | 
					 *  normal keys for popups.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
eek_renderer_apply_transformation_for_key (EekRenderer *self,
 | 
					eek_renderer_apply_transformation_for_button (EekRenderer *self,
 | 
				
			||||||
                                           cairo_t     *cr,
 | 
					                                           cairo_t     *cr,
 | 
				
			||||||
                                           EekKeyboard *view,
 | 
					                                           struct button_place *place,
 | 
				
			||||||
                                           EekKey      *key,
 | 
					 | 
				
			||||||
                                           gdouble      scale,
 | 
					                                           gdouble      scale,
 | 
				
			||||||
                                           gboolean     rotate)
 | 
					                                           gboolean     rotate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekSection *section;
 | 
					 | 
				
			||||||
    EekBounds bounds, rotated_bounds;
 | 
					    EekBounds bounds, rotated_bounds;
 | 
				
			||||||
    gint angle;
 | 
					    gint angle;
 | 
				
			||||||
    gdouble s;
 | 
					    gdouble s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_get_key_bounds (self, view, key, &bounds, FALSE);
 | 
					    eek_renderer_get_button_bounds (self, place, &bounds, FALSE);
 | 
				
			||||||
    eek_renderer_get_key_bounds (self, view, key, &rotated_bounds, TRUE);
 | 
					    eek_renderer_get_button_bounds (self, place, &rotated_bounds, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    section = eek_keyboard_get_section(view, key);
 | 
					    angle = eek_section_get_angle (place->section);
 | 
				
			||||||
    angle = eek_section_get_angle (section);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_scale (cr, scale, scale);
 | 
					    cairo_scale (cr, scale, scale);
 | 
				
			||||||
    if (rotate) {
 | 
					    if (rotate) {
 | 
				
			||||||
@ -378,19 +373,18 @@ eek_renderer_apply_transformation_for_key (EekRenderer *self,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_renderer_real_render_key_label (EekRenderer *self,
 | 
					eek_renderer_real_render_button_label (EekRenderer *self,
 | 
				
			||||||
                                    PangoLayout *layout,
 | 
					                                    PangoLayout *layout,
 | 
				
			||||||
                                    EekKey      *key)
 | 
					                                    struct squeek_button *button)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
					    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
				
			||||||
    struct squeek_symbol *symbol;
 | 
					
 | 
				
			||||||
    const gchar *label;
 | 
					    const gchar *label;
 | 
				
			||||||
    EekBounds bounds;
 | 
					 | 
				
			||||||
    PangoFontDescription *font;
 | 
					    PangoFontDescription *font;
 | 
				
			||||||
    PangoLayoutLine *line;
 | 
					    PangoLayoutLine *line;
 | 
				
			||||||
    gdouble scale;
 | 
					    gdouble scale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    symbol = eek_key_get_symbol_at_index(key, 0);
 | 
					    struct squeek_symbol *symbol = squeek_button_get_symbol(button);
 | 
				
			||||||
    if (!symbol)
 | 
					    if (!symbol)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -415,7 +409,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
 | 
				
			|||||||
        pango_font_description_set_size (priv->font, (gint)round(size * 0.6));
 | 
					        pango_font_description_set_size (priv->font, (gint)round(size * 0.6));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
					    EekBounds bounds = squeek_button_get_bounds(button);
 | 
				
			||||||
    scale = MIN((bounds.width - priv->border_width) / bounds.width,
 | 
					    scale = MIN((bounds.width - priv->border_width) / bounds.width,
 | 
				
			||||||
                (bounds.height - priv->border_width) / bounds.height);
 | 
					                (bounds.height - priv->border_width) / bounds.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -434,16 +428,19 @@ eek_renderer_real_render_key_label (EekRenderer *self,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_renderer_real_render_key_outline (EekRenderer *self,
 | 
					eek_renderer_real_render_button_outline (EekRenderer *self,
 | 
				
			||||||
                                      cairo_t     *cr,
 | 
					                                      cairo_t     *cr,
 | 
				
			||||||
                                      EekKeyboard *view,
 | 
					                                      struct button_place *place,
 | 
				
			||||||
                                      EekKey      *key,
 | 
					 | 
				
			||||||
                                      gdouble      scale,
 | 
					                                      gdouble      scale,
 | 
				
			||||||
                                      gboolean     rotate)
 | 
					                                      gboolean     rotate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    cairo_save (cr);
 | 
					    cairo_save (cr);
 | 
				
			||||||
    eek_renderer_apply_transformation_for_key (self, cr, view, key, scale, rotate);
 | 
					    eek_renderer_apply_transformation_for_button (self, cr, place, scale, rotate);
 | 
				
			||||||
    render_key_outline (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
 | 
					    struct squeek_key *key = squeek_button_get_key(place->button);
 | 
				
			||||||
 | 
					    render_button_outline (
 | 
				
			||||||
 | 
					                self, cr, place->button,
 | 
				
			||||||
 | 
					                squeek_key_is_pressed(key) || squeek_key_is_locked (key)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    cairo_restore (cr);
 | 
					    cairo_restore (cr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -459,17 +456,16 @@ eek_renderer_real_render_key_outline (EekRenderer *self,
 | 
				
			|||||||
 *   Renders a key separately from the normal keyboard rendering.
 | 
					 *   Renders a key separately from the normal keyboard rendering.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_renderer_real_render_key (EekRenderer *self,
 | 
					eek_renderer_real_render_button (EekRenderer *self,
 | 
				
			||||||
                              cairo_t     *cr,
 | 
					                              cairo_t     *cr,
 | 
				
			||||||
                              EekKeyboard *view,
 | 
					                              struct button_place *place,
 | 
				
			||||||
                              EekKey      *key,
 | 
					 | 
				
			||||||
                              gdouble      scale,
 | 
					                              gdouble      scale,
 | 
				
			||||||
                              gboolean     rotate)
 | 
					                              gboolean     rotate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
					    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_get_key_bounds (self, view, key, &bounds, rotate);
 | 
					    eek_renderer_get_button_bounds (self, place, &bounds, rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_save (cr);
 | 
					    cairo_save (cr);
 | 
				
			||||||
    /* Because this function is called separately from the keyboard rendering
 | 
					    /* Because this function is called separately from the keyboard rendering
 | 
				
			||||||
@ -478,8 +474,12 @@ eek_renderer_real_render_key (EekRenderer *self,
 | 
				
			|||||||
    cairo_scale (cr, priv->scale, priv->scale);
 | 
					    cairo_scale (cr, priv->scale, priv->scale);
 | 
				
			||||||
    cairo_translate (cr, bounds.x, bounds.y);
 | 
					    cairo_translate (cr, bounds.x, bounds.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_apply_transformation_for_key (self, cr, view, key, scale, rotate);
 | 
					    eek_renderer_apply_transformation_for_button (self, cr, place, scale, rotate);
 | 
				
			||||||
    render_key (self, cr, view, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
 | 
					    struct squeek_key *key = squeek_button_get_key(place->button);
 | 
				
			||||||
 | 
					    render_button (
 | 
				
			||||||
 | 
					                self, cr, place,
 | 
				
			||||||
 | 
					                squeek_key_is_pressed(key) || squeek_key_is_locked (key)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    cairo_restore (cr);
 | 
					    cairo_restore (cr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -593,8 +593,8 @@ eek_renderer_class_init (EekRendererClass *klass)
 | 
				
			|||||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
					    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
    GParamSpec        *pspec;
 | 
					    GParamSpec        *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    klass->render_key_outline = eek_renderer_real_render_key_outline;
 | 
					    klass->render_key_outline = eek_renderer_real_render_button_outline;
 | 
				
			||||||
    klass->render_key = eek_renderer_real_render_key;
 | 
					    klass->render_button = eek_renderer_real_render_button;
 | 
				
			||||||
    klass->render_keyboard = eek_renderer_real_render_keyboard;
 | 
					    klass->render_keyboard = eek_renderer_real_render_keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gobject_class->set_property = eek_renderer_set_property;
 | 
					    gobject_class->set_property = eek_renderer_set_property;
 | 
				
			||||||
@ -757,44 +757,43 @@ eek_renderer_get_size (EekRenderer *renderer,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
eek_renderer_get_key_bounds (EekRenderer *renderer,
 | 
					eek_renderer_get_button_bounds (EekRenderer *renderer,
 | 
				
			||||||
                             EekKeyboard *view,
 | 
					                                struct button_place *place,
 | 
				
			||||||
                             EekKey      *key,
 | 
					 | 
				
			||||||
                             EekBounds   *bounds,
 | 
					                             EekBounds   *bounds,
 | 
				
			||||||
                             gboolean     rotate)
 | 
					                             gboolean     rotate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekSection *section = eek_keyboard_get_section(view, key);
 | 
					 | 
				
			||||||
    EekBounds section_bounds, keyboard_bounds;
 | 
					    EekBounds section_bounds, keyboard_bounds;
 | 
				
			||||||
    gint angle = 0;
 | 
					    gint angle = 0;
 | 
				
			||||||
    EekPoint points[4], min, max;
 | 
					    EekPoint points[4], min, max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
					    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
				
			||||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
					    g_return_if_fail (place);
 | 
				
			||||||
    g_return_if_fail (bounds != NULL);
 | 
					    g_return_if_fail (bounds != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
					    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_element_get_bounds (EEK_ELEMENT(key), bounds);
 | 
					    EekBounds button_bounds = squeek_button_get_bounds(place->button);
 | 
				
			||||||
    eek_element_get_bounds (EEK_ELEMENT(section), §ion_bounds);
 | 
					    eek_element_get_bounds (EEK_ELEMENT(place->section), §ion_bounds);
 | 
				
			||||||
    eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)),
 | 
					    eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)),
 | 
				
			||||||
                            &keyboard_bounds);
 | 
					                            &keyboard_bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!rotate) {
 | 
					    if (!rotate) {
 | 
				
			||||||
        bounds->x += keyboard_bounds.x + section_bounds.x;
 | 
					        button_bounds.x += keyboard_bounds.x + section_bounds.x;
 | 
				
			||||||
        bounds->y += keyboard_bounds.y + section_bounds.y;
 | 
					        button_bounds.y += keyboard_bounds.y + section_bounds.y;
 | 
				
			||||||
 | 
					        *bounds = button_bounds;
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    points[0].x = bounds->x;
 | 
					    points[0].x = button_bounds.x;
 | 
				
			||||||
    points[0].y = bounds->y;
 | 
					    points[0].y = button_bounds.y;
 | 
				
			||||||
    points[1].x = points[0].x + bounds->width;
 | 
					    points[1].x = points[0].x + button_bounds.width;
 | 
				
			||||||
    points[1].y = points[0].y;
 | 
					    points[1].y = points[0].y;
 | 
				
			||||||
    points[2].x = points[1].x;
 | 
					    points[2].x = points[1].x;
 | 
				
			||||||
    points[2].y = points[1].y + bounds->height;
 | 
					    points[2].y = points[1].y + button_bounds.height;
 | 
				
			||||||
    points[3].x = points[0].x;
 | 
					    points[3].x = points[0].x;
 | 
				
			||||||
    points[3].y = points[2].y;
 | 
					    points[3].y = points[2].y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (rotate)
 | 
					    if (rotate)
 | 
				
			||||||
        angle = eek_section_get_angle (EEK_SECTION(section));
 | 
					        angle = eek_section_get_angle (EEK_SECTION(place->section));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    min = points[2];
 | 
					    min = points[2];
 | 
				
			||||||
    max = points[0];
 | 
					    max = points[0];
 | 
				
			||||||
@ -847,19 +846,17 @@ eek_renderer_create_pango_layout (EekRenderer  *renderer)
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
eek_renderer_render_key_outline (EekRenderer *renderer,
 | 
					eek_renderer_render_key_outline (EekRenderer *renderer,
 | 
				
			||||||
                                 cairo_t     *cr,
 | 
					                                 cairo_t     *cr,
 | 
				
			||||||
                                 EekKeyboard *view,
 | 
					                                 struct button_place *place,
 | 
				
			||||||
                                 EekKey      *key,
 | 
					 | 
				
			||||||
                                 gdouble      scale,
 | 
					                                 gdouble      scale,
 | 
				
			||||||
                                 gboolean     rotate)
 | 
					                                 gboolean     rotate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
					    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
				
			||||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
					    g_return_if_fail (place);
 | 
				
			||||||
    g_return_if_fail (scale >= 0.0);
 | 
					    g_return_if_fail (scale >= 0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EEK_RENDERER_GET_CLASS(renderer)->render_key_outline (renderer,
 | 
					    EEK_RENDERER_GET_CLASS(renderer)->render_key_outline (renderer,
 | 
				
			||||||
                                                          cr,
 | 
					                                                          cr,
 | 
				
			||||||
                                                          view,
 | 
					                                                          place,
 | 
				
			||||||
                                                          key,
 | 
					 | 
				
			||||||
                                                          scale,
 | 
					                                                          scale,
 | 
				
			||||||
                                                          rotate);
 | 
					                                                          rotate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -899,19 +896,18 @@ eek_renderer_get_icon_surface (EekRenderer *renderer,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
eek_renderer_render_key (EekRenderer *renderer,
 | 
					eek_renderer_render_button (EekRenderer *renderer,
 | 
				
			||||||
                         cairo_t     *cr,
 | 
					                         cairo_t     *cr,
 | 
				
			||||||
                         EekKeyboard *view,
 | 
					                         struct button_place *place,
 | 
				
			||||||
                         EekKey      *key,
 | 
					 | 
				
			||||||
                         gdouble      scale,
 | 
					                         gdouble      scale,
 | 
				
			||||||
                         gboolean     rotate)
 | 
					                         gboolean     rotate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
					    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
				
			||||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
					    g_return_if_fail (place);
 | 
				
			||||||
    g_return_if_fail (scale >= 0.0);
 | 
					    g_return_if_fail (scale >= 0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EEK_RENDERER_GET_CLASS(renderer)->
 | 
					    EEK_RENDERER_GET_CLASS(renderer)->
 | 
				
			||||||
        render_key (renderer, cr, view, key, scale, rotate);
 | 
					        render_button (renderer, cr, place, scale, rotate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -968,7 +964,7 @@ struct _FindKeyByPositionCallbackData {
 | 
				
			|||||||
    EekPoint point;
 | 
					    EekPoint point;
 | 
				
			||||||
    EekPoint origin;
 | 
					    EekPoint origin;
 | 
				
			||||||
    gint angle;
 | 
					    gint angle;
 | 
				
			||||||
    EekKey *key;
 | 
					    struct squeek_button *button;
 | 
				
			||||||
    EekRenderer *renderer;
 | 
					    EekRenderer *renderer;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct _FindKeyByPositionCallbackData FindKeyByPositionCallbackData;
 | 
					typedef struct _FindKeyByPositionCallbackData FindKeyByPositionCallbackData;
 | 
				
			||||||
@ -981,16 +977,19 @@ sign (EekPoint *p1, EekPoint *p2, EekPoint *p3)
 | 
				
			|||||||
        (p2->x - p3->x) * (p1->y - p3->y);
 | 
					        (p2->x - p3->x) * (p1->y - p3->y);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gint
 | 
					static void
 | 
				
			||||||
find_key_by_position_key_callback (EekElement *element,
 | 
					find_button_by_position_key_callback (gpointer item,
 | 
				
			||||||
                                   gpointer user_data)
 | 
					                                   gpointer user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    struct squeek_button *button = item;
 | 
				
			||||||
    FindKeyByPositionCallbackData *data = user_data;
 | 
					    FindKeyByPositionCallbackData *data = user_data;
 | 
				
			||||||
    EekBounds bounds;
 | 
					    if (data->button) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    EekPoint points[4];
 | 
					    EekPoint points[4];
 | 
				
			||||||
    gboolean b1, b2, b3;
 | 
					    gboolean b1, b2, b3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_element_get_bounds (element, &bounds);
 | 
					    EekBounds bounds = squeek_button_get_bounds(button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    points[0].x = bounds.x;
 | 
					    points[0].x = bounds.x;
 | 
				
			||||||
    points[0].y = bounds.y;
 | 
					    points[0].y = bounds.y;
 | 
				
			||||||
@ -1012,8 +1011,8 @@ find_key_by_position_key_callback (EekElement *element,
 | 
				
			|||||||
    b3 = sign (&data->point, &points[2], &points[0]) < 0.0;
 | 
					    b3 = sign (&data->point, &points[2], &points[0]) < 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (b1 == b2 && b2 == b3) {
 | 
					    if (b1 == b2 && b2 == b3) {
 | 
				
			||||||
        data->key = EEK_KEY(element);
 | 
					        data->button = button;
 | 
				
			||||||
        return 0;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    b1 = sign (&data->point, &points[2], &points[3]) < 0.0;
 | 
					    b1 = sign (&data->point, &points[2], &points[3]) < 0.0;
 | 
				
			||||||
@ -1021,17 +1020,15 @@ find_key_by_position_key_callback (EekElement *element,
 | 
				
			|||||||
    b3 = sign (&data->point, &points[0], &points[2]) < 0.0;
 | 
					    b3 = sign (&data->point, &points[0], &points[2]) < 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (b1 == b2 && b2 == b3) {
 | 
					    if (b1 == b2 && b2 == b3) {
 | 
				
			||||||
        data->key = EEK_KEY(element);
 | 
					        data->button = button;
 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return -1;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gint
 | 
					static gint
 | 
				
			||||||
find_key_by_position_section_callback (EekElement *element,
 | 
					find_button_by_position_section_callback (EekElement *element,
 | 
				
			||||||
                                       gpointer user_data)
 | 
					                                       gpointer user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    EekSection *section = EEK_SECTION(element);
 | 
				
			||||||
    FindKeyByPositionCallbackData *data = user_data;
 | 
					    FindKeyByPositionCallbackData *data = user_data;
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
    EekPoint origin;
 | 
					    EekPoint origin;
 | 
				
			||||||
@ -1042,11 +1039,9 @@ find_key_by_position_section_callback (EekElement *element,
 | 
				
			|||||||
    data->origin.y += bounds.y;
 | 
					    data->origin.y += bounds.y;
 | 
				
			||||||
    data->angle = eek_section_get_angle (EEK_SECTION(element));
 | 
					    data->angle = eek_section_get_angle (EEK_SECTION(element));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_container_find (EEK_CONTAINER(element),
 | 
					    eek_section_foreach(section, find_button_by_position_key_callback, data);
 | 
				
			||||||
                        find_key_by_position_key_callback,
 | 
					 | 
				
			||||||
                        data);
 | 
					 | 
				
			||||||
    data->origin = origin;
 | 
					    data->origin = origin;
 | 
				
			||||||
    return data->key ? 0 : -1;
 | 
					    return data->button ? 0 : -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -1058,8 +1053,8 @@ find_key_by_position_section_callback (EekElement *element,
 | 
				
			|||||||
 * Return value: the key located at the position x, y in widget coordinates, or
 | 
					 * Return value: the key located at the position x, y in widget coordinates, or
 | 
				
			||||||
 *   NULL if no key can be found at that location
 | 
					 *   NULL if no key can be found at that location
 | 
				
			||||||
 **/
 | 
					 **/
 | 
				
			||||||
EekKey *
 | 
					struct squeek_button *
 | 
				
			||||||
eek_renderer_find_key_by_position (EekRenderer *renderer,
 | 
					eek_renderer_find_button_by_position (EekRenderer *renderer,
 | 
				
			||||||
                                   EekKeyboard *view,
 | 
					                                   EekKeyboard *view,
 | 
				
			||||||
                                   gdouble      x,
 | 
					                                   gdouble      x,
 | 
				
			||||||
                                   gdouble      y)
 | 
					                                   gdouble      y)
 | 
				
			||||||
@ -1086,11 +1081,11 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
 | 
				
			|||||||
    data.point.y = y;
 | 
					    data.point.y = y;
 | 
				
			||||||
    data.origin.x = 0;
 | 
					    data.origin.x = 0;
 | 
				
			||||||
    data.origin.y = 0;
 | 
					    data.origin.y = 0;
 | 
				
			||||||
    data.key = NULL;
 | 
					    data.button = NULL;
 | 
				
			||||||
    data.renderer = renderer;
 | 
					    data.renderer = renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_container_find (EEK_CONTAINER(view),
 | 
					    eek_container_find (EEK_CONTAINER(view),
 | 
				
			||||||
                        find_key_by_position_section_callback,
 | 
					                        find_button_by_position_section_callback,
 | 
				
			||||||
                        &data);
 | 
					                        &data);
 | 
				
			||||||
    return data.key;
 | 
					    return data.button;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -38,15 +38,13 @@ struct _EekRendererClass
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void             (* render_key_outline) (EekRenderer *self,
 | 
					    void             (* render_key_outline) (EekRenderer *self,
 | 
				
			||||||
                                             cairo_t     *cr,
 | 
					                                             cairo_t     *cr,
 | 
				
			||||||
                                             EekKeyboard *view,
 | 
					                                             struct button_place *place,
 | 
				
			||||||
                                             EekKey      *key,
 | 
					 | 
				
			||||||
                                             gdouble      scale,
 | 
					                                             gdouble      scale,
 | 
				
			||||||
                                             gboolean     rotate);
 | 
					                                             gboolean     rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void             (* render_key)         (EekRenderer *self,
 | 
					    void             (* render_button)         (EekRenderer *self,
 | 
				
			||||||
                                             cairo_t     *cr,
 | 
					                                             cairo_t     *cr,
 | 
				
			||||||
                                             EekKeyboard *view,
 | 
					                                             struct button_place *place,
 | 
				
			||||||
                                             EekKey      *key,
 | 
					 | 
				
			||||||
                                             gdouble      scale,
 | 
					                                             gdouble      scale,
 | 
				
			||||||
                                             gboolean     rotate);
 | 
					                                             gboolean     rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,8 +72,8 @@ void             eek_renderer_set_allocation_size
 | 
				
			|||||||
void             eek_renderer_get_size         (EekRenderer     *renderer,
 | 
					void             eek_renderer_get_size         (EekRenderer     *renderer,
 | 
				
			||||||
                                                gdouble         *width,
 | 
					                                                gdouble         *width,
 | 
				
			||||||
                                                gdouble         *height);
 | 
					                                                gdouble         *height);
 | 
				
			||||||
void             eek_renderer_get_key_bounds   (EekRenderer     *renderer, EekKeyboard *view,
 | 
					void             eek_renderer_get_button_bounds   (EekRenderer     *renderer,
 | 
				
			||||||
                                                EekKey          *key,
 | 
					                                                struct button_place *button,
 | 
				
			||||||
                                                EekBounds       *bounds,
 | 
					                                                EekBounds       *bounds,
 | 
				
			||||||
                                                gboolean         rotate);
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -91,15 +89,14 @@ void             eek_renderer_render_key_label (EekRenderer     *renderer,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void             eek_renderer_render_key_outline
 | 
					void             eek_renderer_render_key_outline
 | 
				
			||||||
                                               (EekRenderer     *renderer,
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
                                                cairo_t         *cr, EekKeyboard *view,
 | 
					                                                cairo_t         *cr,
 | 
				
			||||||
                                                EekKey          *key,
 | 
					                                                struct button_place *place,
 | 
				
			||||||
                                                gdouble          scale,
 | 
					                                                gdouble          scale,
 | 
				
			||||||
                                                gboolean         rotate);
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void             eek_renderer_render_key       (EekRenderer     *renderer,
 | 
					void             eek_renderer_render_button       (EekRenderer     *renderer,
 | 
				
			||||||
                                                cairo_t         *cr,
 | 
					                                                cairo_t         *cr,
 | 
				
			||||||
                                                EekKeyboard *view,
 | 
					                                                struct button_place *place,
 | 
				
			||||||
                                                EekKey          *key,
 | 
					 | 
				
			||||||
                                                gdouble          scale,
 | 
					                                                gdouble          scale,
 | 
				
			||||||
                                                gboolean         rotate);
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -123,14 +120,12 @@ void             eek_renderer_get_foreground_color
 | 
				
			|||||||
                                                EekColor        *color);
 | 
					                                                EekColor        *color);
 | 
				
			||||||
void             eek_renderer_set_border_width (EekRenderer     *renderer,
 | 
					void             eek_renderer_set_border_width (EekRenderer     *renderer,
 | 
				
			||||||
                                                gdouble          border_width);
 | 
					                                                gdouble          border_width);
 | 
				
			||||||
EekKey          *eek_renderer_find_key_by_position
 | 
					struct squeek_button *eek_renderer_find_button_by_position(EekRenderer     *renderer, EekKeyboard *view,
 | 
				
			||||||
                                               (EekRenderer     *renderer, EekKeyboard *view,
 | 
					 | 
				
			||||||
                                                gdouble          x,
 | 
					                                                gdouble          x,
 | 
				
			||||||
                                                gdouble          y);
 | 
					                                                gdouble          y);
 | 
				
			||||||
void             eek_renderer_apply_transformation_for_key
 | 
					void             eek_renderer_apply_transformation_for_button
 | 
				
			||||||
                                               (EekRenderer     *renderer,
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
                                                cairo_t         *cr, EekKeyboard *view,
 | 
					                                                cairo_t         *cr, struct button_place *place,
 | 
				
			||||||
                                                EekKey          *key,
 | 
					 | 
				
			||||||
                                                gdouble          scale,
 | 
					                                                gdouble          scale,
 | 
				
			||||||
                                                gboolean         rotate);
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,7 +32,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "eek-key.h"
 | 
					#include "layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,41 +46,32 @@ typedef struct _EekSectionPrivate
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    gint angle;
 | 
					    gint angle;
 | 
				
			||||||
    EekModifierType modifiers;
 | 
					    EekModifierType modifiers;
 | 
				
			||||||
 | 
					    GPtrArray *buttons; // struct squeek_button*
 | 
				
			||||||
} EekSectionPrivate;
 | 
					} EekSectionPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
 | 
					G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_ELEMENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static EekKey *
 | 
					struct squeek_button*
 | 
				
			||||||
eek_section_real_create_key (EekSection *self,
 | 
					eek_section_create_button (EekSection *self,
 | 
				
			||||||
                             const gchar *name,
 | 
					                             const gchar *name,
 | 
				
			||||||
                             gint        keycode,
 | 
					                             guint        keycode,
 | 
				
			||||||
                             guint oref)
 | 
					                             guint oref)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
 | 
					    struct squeek_button *button = squeek_button_new(keycode, oref);
 | 
				
			||||||
                                         "name", name,
 | 
					    g_return_val_if_fail (button, NULL);
 | 
				
			||||||
                                         NULL);
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
    g_return_val_if_fail (key, NULL);
 | 
					    g_ptr_array_add(priv->buttons, button);
 | 
				
			||||||
    eek_key_set_keycode(key, keycode);
 | 
					    return button;
 | 
				
			||||||
    eek_key_set_oref(key, oref);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
					 | 
				
			||||||
                                              EEK_ELEMENT(key));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return key;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekKey *eek_section_create_button(EekSection *self,
 | 
					struct squeek_button *eek_section_create_button_with_state(EekSection *self,
 | 
				
			||||||
                                  const gchar *name,
 | 
					                                  const gchar *name,
 | 
				
			||||||
                                    struct squeek_key *state) {
 | 
					                                    struct squeek_button *source) {
 | 
				
			||||||
    EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
 | 
					    struct squeek_button *button = squeek_button_new_with_state(source);
 | 
				
			||||||
                                         "name", name,
 | 
					    g_return_val_if_fail (button, NULL);
 | 
				
			||||||
                                         NULL);
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
    g_return_val_if_fail (key, NULL);
 | 
					    g_ptr_array_add(priv->buttons, button);
 | 
				
			||||||
    eek_key_share_state(key, state);
 | 
					    return button;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
					 | 
				
			||||||
                                              EEK_ELEMENT(key));
 | 
					 | 
				
			||||||
    return key;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -122,35 +113,13 @@ eek_section_get_property (GObject    *object,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
eek_section_real_child_added (EekContainer *self,
 | 
					 | 
				
			||||||
                              EekElement   *element)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    (void)self;
 | 
					 | 
				
			||||||
    (void)element;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
eek_section_real_child_removed (EekContainer *self,
 | 
					 | 
				
			||||||
                                EekElement   *element)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    (void)self;
 | 
					 | 
				
			||||||
    (void)element;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_section_class_init (EekSectionClass *klass)
 | 
					eek_section_class_init (EekSectionClass *klass)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
 | 
					 | 
				
			||||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
					    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
    GParamSpec        *pspec;
 | 
					    GParamSpec        *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    klass->create_key = eek_section_real_create_key;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* signals */
 | 
					    /* signals */
 | 
				
			||||||
    container_class->child_added = eek_section_real_child_added;
 | 
					 | 
				
			||||||
    container_class->child_removed = eek_section_real_child_removed;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gobject_class->set_property = eek_section_set_property;
 | 
					    gobject_class->set_property = eek_section_set_property;
 | 
				
			||||||
    gobject_class->get_property = eek_section_get_property;
 | 
					    gobject_class->get_property = eek_section_get_property;
 | 
				
			||||||
    gobject_class->finalize     = eek_section_finalize;
 | 
					    gobject_class->finalize     = eek_section_finalize;
 | 
				
			||||||
@ -173,7 +142,8 @@ eek_section_class_init (EekSectionClass *klass)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
eek_section_init (EekSection *self)
 | 
					eek_section_init (EekSection *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* void */
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
 | 
					    priv->buttons = g_ptr_array_new();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -213,30 +183,6 @@ eek_section_get_angle (EekSection *section)
 | 
				
			|||||||
    return priv->angle;
 | 
					    return priv->angle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_section_create_key:
 | 
					 | 
				
			||||||
 * @section: an #EekSection
 | 
					 | 
				
			||||||
 * @name: a name
 | 
					 | 
				
			||||||
 * @keycode: a keycode
 | 
					 | 
				
			||||||
 * @column: the column index of the key
 | 
					 | 
				
			||||||
 * @row: the row index of the key
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Create an #EekKey instance and append it to @section.  This
 | 
					 | 
				
			||||||
 * function is rarely called by application but called by #EekLayout
 | 
					 | 
				
			||||||
 * implementation.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
EekKey *
 | 
					 | 
				
			||||||
eek_section_create_key (EekSection *section,
 | 
					 | 
				
			||||||
                        const gchar *name,
 | 
					 | 
				
			||||||
                        guint        keycode,
 | 
					 | 
				
			||||||
                        guint oref)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
 | 
					 | 
				
			||||||
    return eek_section_real_create_key (section,
 | 
					 | 
				
			||||||
                                                       name,
 | 
					 | 
				
			||||||
                                                       keycode, oref);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const double keyspacing = 4.0;
 | 
					const double keyspacing = 4.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct keys_info {
 | 
					struct keys_info {
 | 
				
			||||||
@ -245,13 +191,14 @@ struct keys_info {
 | 
				
			|||||||
    double biggest_height;
 | 
					    double biggest_height;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Set button size to match the outline. Reset position
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
keysizer(EekElement *element, gpointer user_data)
 | 
					buttonsizer(gpointer item, gpointer user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekKey *key = EEK_KEY(element);
 | 
					    struct squeek_button *button = item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LevelKeyboard *keyboard = user_data;
 | 
					    LevelKeyboard *keyboard = user_data;
 | 
				
			||||||
    uint oref = eek_key_get_oref (key);
 | 
					    uint oref = squeek_button_get_oref(button);
 | 
				
			||||||
    EekOutline *outline = level_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;
 | 
				
			||||||
@ -272,21 +219,23 @@ keysizer(EekElement *element, gpointer user_data)
 | 
				
			|||||||
                maxy = p.y;
 | 
					                maxy = p.y;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        EekBounds key_bounds = {0};
 | 
					        EekBounds key_bounds = {
 | 
				
			||||||
        eek_element_get_bounds(element, &key_bounds);
 | 
					            .height = maxy - miny,
 | 
				
			||||||
        key_bounds.height = maxy - miny;
 | 
					            .width = maxx - minx,
 | 
				
			||||||
        key_bounds.width = maxx - minx;
 | 
					            .x = 0,
 | 
				
			||||||
        eek_element_set_bounds(element, &key_bounds);
 | 
					            .y = 0,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        squeek_button_set_bounds(button, key_bounds);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
keycounter (EekElement *element, gpointer user_data)
 | 
					buttoncounter (gpointer item, gpointer user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    struct squeek_button *button = item;
 | 
				
			||||||
    struct keys_info *data = user_data;
 | 
					    struct keys_info *data = user_data;
 | 
				
			||||||
    data->count++;
 | 
					    data->count++;
 | 
				
			||||||
    EekBounds key_bounds = {0};
 | 
					    EekBounds key_bounds = squeek_button_get_bounds(button);
 | 
				
			||||||
    eek_element_get_bounds(element, &key_bounds);
 | 
					 | 
				
			||||||
    data->total_width += key_bounds.width;
 | 
					    data->total_width += key_bounds.width;
 | 
				
			||||||
    if (key_bounds.height > data->biggest_height) {
 | 
					    if (key_bounds.height > data->biggest_height) {
 | 
				
			||||||
        data->biggest_height = key_bounds.height;
 | 
					        data->biggest_height = key_bounds.height;
 | 
				
			||||||
@ -294,30 +243,63 @@ keycounter (EekElement *element, gpointer user_data)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
keyplacer(EekElement *element, gpointer user_data)
 | 
					buttonplacer(gpointer item, gpointer user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    struct squeek_button *button = item;
 | 
				
			||||||
    double *current_offset = user_data;
 | 
					    double *current_offset = user_data;
 | 
				
			||||||
    EekBounds key_bounds = {0};
 | 
					    EekBounds key_bounds = squeek_button_get_bounds(button);
 | 
				
			||||||
    eek_element_get_bounds(element, &key_bounds);
 | 
					 | 
				
			||||||
    key_bounds.x = *current_offset;
 | 
					    key_bounds.x = *current_offset;
 | 
				
			||||||
    key_bounds.y = 0;
 | 
					    key_bounds.y = 0;
 | 
				
			||||||
    eek_element_set_bounds(element, &key_bounds);
 | 
					    squeek_button_set_bounds(button, key_bounds);
 | 
				
			||||||
    *current_offset += key_bounds.width + keyspacing;
 | 
					    *current_offset += key_bounds.width + keyspacing;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
eek_section_place_keys(EekSection *section, LevelKeyboard *keyboard)
 | 
					eek_section_place_keys(EekSection *section, LevelKeyboard *keyboard)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_ptr_array_foreach(priv->buttons, buttonsizer, keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct keys_info keyinfo = {0};
 | 
					    struct keys_info keyinfo = {0};
 | 
				
			||||||
    eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo);
 | 
					    g_ptr_array_foreach(priv->buttons, buttoncounter, &keyinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EekBounds section_bounds = {0};
 | 
					    EekBounds section_bounds = {0};
 | 
				
			||||||
    eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
					    eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
 | 
					    double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
 | 
				
			||||||
    eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset);
 | 
					    g_ptr_array_foreach(priv->buttons, buttonplacer, &key_offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    section_bounds.height = keyinfo.biggest_height;
 | 
					    section_bounds.height = keyinfo.biggest_height;
 | 
				
			||||||
    eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
					    eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void eek_section_foreach (EekSection *section,
 | 
				
			||||||
 | 
					                     GFunc      func,
 | 
				
			||||||
 | 
					                          gpointer   user_data) {
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
				
			||||||
 | 
					    g_ptr_array_foreach(priv->buttons, func, user_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean eek_section_find(EekSection *section,
 | 
				
			||||||
 | 
					                          const struct squeek_button *button) {
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
				
			||||||
 | 
					    return g_ptr_array_find(priv->buttons, button, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean button_has_key(gconstpointer buttonptr, gconstpointer keyptr) {
 | 
				
			||||||
 | 
					    const struct squeek_button *button = buttonptr;
 | 
				
			||||||
 | 
					    const struct squeek_key *key = keyptr;
 | 
				
			||||||
 | 
					    return squeek_button_has_key((struct squeek_button*)button, key) != 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct squeek_button *eek_section_find_key(EekSection *section,
 | 
				
			||||||
 | 
					                                           const struct squeek_key *key) {
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
				
			||||||
 | 
					    guint index;
 | 
				
			||||||
 | 
					    gboolean ret = g_ptr_array_find_with_equal_func(priv->buttons, key, button_has_key, &index);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        return g_ptr_array_index(priv->buttons, index);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return NULL;// TODO: store keys in locked_keys, pressed_keys
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,11 +30,12 @@
 | 
				
			|||||||
#include "eek-types.h"
 | 
					#include "eek-types.h"
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "src/keyboard.h"
 | 
					#include "src/keyboard.h"
 | 
				
			||||||
 | 
					#include "src/layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_BEGIN_DECLS
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EEK_TYPE_SECTION (eek_section_get_type())
 | 
					#define EEK_TYPE_SECTION (eek_section_get_type())
 | 
				
			||||||
G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
 | 
					G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekElement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * EekSectionClass:
 | 
					 * EekSectionClass:
 | 
				
			||||||
@ -51,13 +52,7 @@ G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
 | 
				
			|||||||
struct _EekSectionClass
 | 
					struct _EekSectionClass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /*< private >*/
 | 
					    /*< private >*/
 | 
				
			||||||
    EekContainerClass parent_class;
 | 
					    EekElementClass parent_class;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*< public >*/
 | 
					 | 
				
			||||||
    EekKey *(* create_key)          (EekSection     *self,
 | 
					 | 
				
			||||||
                                     const gchar    *name,
 | 
					 | 
				
			||||||
                                     gint            keycode,
 | 
					 | 
				
			||||||
                                     guint oref);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*< private >*/
 | 
					    /*< private >*/
 | 
				
			||||||
    /* padding */
 | 
					    /* padding */
 | 
				
			||||||
@ -70,13 +65,21 @@ void    eek_section_set_angle            (EekSection     *section,
 | 
				
			|||||||
                                          gint            angle);
 | 
					                                          gint            angle);
 | 
				
			||||||
gint    eek_section_get_angle            (EekSection     *section);
 | 
					gint    eek_section_get_angle            (EekSection     *section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekKey *eek_section_create_key           (EekSection     *section,
 | 
					struct squeek_button *eek_section_create_button (EekSection     *section,
 | 
				
			||||||
                                          const gchar    *name,
 | 
					                                          const gchar    *name,
 | 
				
			||||||
                                          guint keycode, guint oref);
 | 
					                                          guint keycode, guint oref);
 | 
				
			||||||
EekKey *eek_section_create_button(EekSection *self,
 | 
					struct squeek_button *eek_section_create_button_with_state(EekSection *self,
 | 
				
			||||||
                                  const gchar *name,
 | 
					                                  const gchar *name,
 | 
				
			||||||
                                    struct squeek_key *state);
 | 
					                                    struct squeek_button *source);
 | 
				
			||||||
void eek_section_place_keys              (EekSection     *section, LevelKeyboard *keyboard);
 | 
					void eek_section_place_keys              (EekSection     *section, LevelKeyboard *keyboard);
 | 
				
			||||||
 | 
					void eek_section_foreach (EekSection *section,
 | 
				
			||||||
 | 
					                     GFunc      func,
 | 
				
			||||||
 | 
					                     gpointer   user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean eek_section_find(EekSection *section,
 | 
				
			||||||
 | 
					                     const struct squeek_button *button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct squeek_button *eek_section_find_key(EekSection *section,
 | 
				
			||||||
 | 
					                                           const struct squeek_key *key);
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_SECTION_H */
 | 
					#endif  /* EEK_SECTION_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
#include "eek-key.h"
 | 
					 | 
				
			||||||
#include "src/keyboard.h"
 | 
					#include "src/keyboard.h"
 | 
				
			||||||
#include "src/symbol.h"
 | 
					#include "src/symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,7 +67,7 @@ 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 **views, GArray *outline_array, GHashTable *name_key_hash,
 | 
					                                      EekKeyboard **views, GArray *outline_array, GHashTable *name_button_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,
 | 
				
			||||||
@ -236,7 +235,6 @@ struct _GeometryParseData {
 | 
				
			|||||||
    EekKeyboard **views;
 | 
					    EekKeyboard **views;
 | 
				
			||||||
    guint view_idx;
 | 
					    guint view_idx;
 | 
				
			||||||
    EekSection *section;
 | 
					    EekSection *section;
 | 
				
			||||||
    EekKey *key;
 | 
					 | 
				
			||||||
    gint num_rows;
 | 
					    gint num_rows;
 | 
				
			||||||
    EekOrientation orientation;
 | 
					    EekOrientation orientation;
 | 
				
			||||||
    gdouble corner_radius;
 | 
					    gdouble corner_radius;
 | 
				
			||||||
@ -250,14 +248,14 @@ struct _GeometryParseData {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    GArray *outline_array;
 | 
					    GArray *outline_array;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GHashTable *name_key_hash; // char* -> EekKey*
 | 
					    GHashTable *name_button_hash; // char* -> struct squeek_button*
 | 
				
			||||||
    GHashTable *keyname_oref_hash; // char* -> guint
 | 
					    GHashTable *keyname_oref_hash; // char* -> guint
 | 
				
			||||||
    GHashTable *outlineid_oref_hash; // char* -> guint
 | 
					    GHashTable *outlineid_oref_hash; // char* -> guint
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct _GeometryParseData GeometryParseData;
 | 
					typedef struct _GeometryParseData GeometryParseData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GeometryParseData *
 | 
					static GeometryParseData *
 | 
				
			||||||
geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray *outline_array)
 | 
					geometry_parse_data_new (EekKeyboard **views, GHashTable *name_button_hash, GArray *outline_array)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GeometryParseData *data = g_slice_new0 (GeometryParseData);
 | 
					    GeometryParseData *data = g_slice_new0 (GeometryParseData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -274,7 +272,7 @@ geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray
 | 
				
			|||||||
                               g_free,
 | 
					                               g_free,
 | 
				
			||||||
                               NULL);
 | 
					                               NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data->name_key_hash = name_key_hash;
 | 
					    data->name_button_hash = name_button_hash;
 | 
				
			||||||
    data->text = g_string_sized_new (BUFSIZE);
 | 
					    data->text = g_string_sized_new (BUFSIZE);
 | 
				
			||||||
    data->keycode = 8;
 | 
					    data->keycode = 8;
 | 
				
			||||||
    return data;
 | 
					    return data;
 | 
				
			||||||
@ -418,15 +416,16 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
                             g_strdup(name),
 | 
					                             g_strdup(name),
 | 
				
			||||||
                             GUINT_TO_POINTER(oref));
 | 
					                             GUINT_TO_POINTER(oref));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
 | 
					        struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
 | 
				
			||||||
        // never gets used! this section gets executed before any buttons get defined
 | 
					        // never gets used! this section gets executed before any buttons get defined
 | 
				
			||||||
        if (key) {
 | 
					        if (button) {
 | 
				
			||||||
            if (keycode_name != NULL) {
 | 
					            if (keycode_name != NULL) {
 | 
				
			||||||
                // This sets the keycode for all buttons,
 | 
					                // This sets the keycode for all buttons,
 | 
				
			||||||
                // since they share state
 | 
					                // since they share state
 | 
				
			||||||
                // TODO: get rid of this in the parser;
 | 
					                // TODO: get rid of this in the parser;
 | 
				
			||||||
                // this belongs after keymap is defined
 | 
					                // this belongs after keymap is defined
 | 
				
			||||||
                eek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
 | 
					                struct squeek_key *key = squeek_button_get_key(button);
 | 
				
			||||||
 | 
					                squeek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -559,31 +558,30 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            gchar *name = g_strndup (&text[start], end - start);
 | 
					            gchar *name = g_strndup (&text[start], end - start);
 | 
				
			||||||
            EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
 | 
					            struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
 | 
				
			||||||
            if (!key) {
 | 
					            if (!button) {
 | 
				
			||||||
                // Save button name together with its level,
 | 
					                // Save button name together with its level,
 | 
				
			||||||
                // to account for buttons with the same name in multiple levels
 | 
					                // to account for buttons with the same name in multiple levels
 | 
				
			||||||
                guint keycode = data->keycode++;
 | 
					                guint keycode = data->keycode++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->keyname_oref_hash, name));
 | 
					                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
 | 
					                // default value gives idx 0, which is guaranteed to be occupied
 | 
				
			||||||
                key = eek_section_create_key (data->section,
 | 
					                button = eek_section_create_button (data->section,
 | 
				
			||||||
                                                    name,
 | 
					                                                    name,
 | 
				
			||||||
                                                    keycode,
 | 
					                                                    keycode,
 | 
				
			||||||
                                              oref);
 | 
					                                              oref);
 | 
				
			||||||
                g_hash_table_insert (data->name_key_hash,
 | 
					                g_hash_table_insert (data->name_button_hash,
 | 
				
			||||||
                                     g_strdup(name),
 | 
					                                     g_strdup(name),
 | 
				
			||||||
                                     key);
 | 
					                                     button);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                EekKey *new_key = eek_section_create_button(data->section, name, eek_key_get_state(key));
 | 
					                struct squeek_button *new_button = eek_section_create_button_with_state(data->section, name, button);
 | 
				
			||||||
                if (!new_key) {
 | 
					                if (!new_button) {
 | 
				
			||||||
                    g_set_error (error,
 | 
					                    g_set_error (error,
 | 
				
			||||||
                                 G_MARKUP_ERROR,
 | 
					                                 G_MARKUP_ERROR,
 | 
				
			||||||
                                 G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
					                                 G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
				
			||||||
                                 "Couldn't create a shared button");
 | 
					                                 "Couldn't create a shared button");
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                eek_key_set_oref(new_key, eek_key_get_oref(key));
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -736,11 +734,11 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
    if (g_strcmp0 (element_name, "symbol") == 0) {
 | 
					    if (g_strcmp0 (element_name, "symbol") == 0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        gchar *name = text;
 | 
					        gchar *name = text;
 | 
				
			||||||
        EekKey *key = eek_keyboard_find_key_by_name (data->keyboard,
 | 
					        struct squeek_button *button = eek_keyboard_find_button_by_name (data->keyboard,
 | 
				
			||||||
                                                   name);
 | 
					                                                   name);
 | 
				
			||||||
        if (key) {
 | 
					        if (button) {
 | 
				
			||||||
            squeek_key_add_symbol(
 | 
					            squeek_key_add_symbol(
 | 
				
			||||||
                eek_key_get_state(key),
 | 
					                squeek_button_get_key(button),
 | 
				
			||||||
                element_name,
 | 
					                element_name,
 | 
				
			||||||
                text,
 | 
					                text,
 | 
				
			||||||
                data->keyval,
 | 
					                data->keyval,
 | 
				
			||||||
@ -887,8 +885,8 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
					    GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // char* -> EekKey*
 | 
					    // char* -> struct squeek_button*
 | 
				
			||||||
    GHashTable *name_key_hash =
 | 
					    GHashTable *name_button_hash =
 | 
				
			||||||
            g_hash_table_new_full (g_str_hash,
 | 
					            g_hash_table_new_full (g_str_hash,
 | 
				
			||||||
                                   g_str_equal,
 | 
					                                   g_str_equal,
 | 
				
			||||||
                                   g_free,
 | 
					                                   g_free,
 | 
				
			||||||
@ -897,7 +895,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
				
			|||||||
    EekKeyboard *views[4] = {0};
 | 
					    EekKeyboard *views[4] = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GError *error = NULL;
 | 
					    GError *error = NULL;
 | 
				
			||||||
    retval = parse_geometry (path, views, outline_array, name_key_hash, &error);
 | 
					    retval = parse_geometry (path, views, outline_array, name_button_hash, &error);
 | 
				
			||||||
    g_free (path);
 | 
					    g_free (path);
 | 
				
			||||||
    if (!retval) {
 | 
					    if (!retval) {
 | 
				
			||||||
        for (uint i = 0; i < 4; i++) {
 | 
					        for (uint i = 0; i < 4; i++) {
 | 
				
			||||||
@ -911,7 +909,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_key_hash);
 | 
					    LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_button_hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    keyboard->outline_array = outline_array;
 | 
					    keyboard->outline_array = outline_array;
 | 
				
			||||||
    // FIXME: are symbols shared betwen views?
 | 
					    // FIXME: are symbols shared betwen views?
 | 
				
			||||||
@ -1129,7 +1127,7 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash, GError **error)
 | 
					parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, GHashTable *name_button_hash, GError **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GeometryParseData *data;
 | 
					    GeometryParseData *data;
 | 
				
			||||||
    GMarkupParseContext *pcontext;
 | 
					    GMarkupParseContext *pcontext;
 | 
				
			||||||
@ -1146,7 +1144,7 @@ parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, G
 | 
				
			|||||||
    if (input == NULL)
 | 
					    if (input == NULL)
 | 
				
			||||||
        return FALSE;
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data = geometry_parse_data_new (views, name_key_hash, outline_array);
 | 
					    data = geometry_parse_data_new (views, name_button_hash, outline_array);
 | 
				
			||||||
    pcontext = g_markup_parse_context_new (&geometry_parser,
 | 
					    pcontext = g_markup_parse_context_new (&geometry_parser,
 | 
				
			||||||
                                           0,
 | 
					                                           0,
 | 
				
			||||||
                                           data,
 | 
					                                           data,
 | 
				
			||||||
@ -1357,7 +1355,7 @@ validate (const gchar **valid_path_list,
 | 
				
			|||||||
          GSList       *element_stack,
 | 
					          GSList       *element_stack,
 | 
				
			||||||
          GError      **error)
 | 
					          GError      **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    gint i;
 | 
					    guint i;
 | 
				
			||||||
    gchar *element_path;
 | 
					    gchar *element_path;
 | 
				
			||||||
    GSList *head, *p;
 | 
					    GSList *head, *p;
 | 
				
			||||||
    GString *string;
 | 
					    GString *string;
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
#include "eek-key.h"
 | 
					 | 
				
			||||||
#include "eek-layout.h"
 | 
					#include "eek-layout.h"
 | 
				
			||||||
#include "eek-keysym.h"
 | 
					#include "eek-keysym.h"
 | 
				
			||||||
#include "eek-serializable.h"
 | 
					#include "eek-serializable.h"
 | 
				
			||||||
 | 
				
			|||||||
@ -28,9 +28,20 @@ pub mod c {
 | 
				
			|||||||
    /// Since C doesn't respect borrowing rules,
 | 
					    /// Since C doesn't respect borrowing rules,
 | 
				
			||||||
    /// RefCell will enforce them dynamically (only 1 writer/many readers)
 | 
					    /// RefCell will enforce them dynamically (only 1 writer/many readers)
 | 
				
			||||||
    /// Rc is implied and will ensure timely dropping
 | 
					    /// Rc is implied and will ensure timely dropping
 | 
				
			||||||
 | 
					    #[repr(transparent)]
 | 
				
			||||||
    pub struct CKeyState(*const RefCell<KeyState>);
 | 
					    pub struct CKeyState(*const RefCell<KeyState>);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    impl Clone for CKeyState {
 | 
				
			||||||
 | 
					        fn clone(&self) -> Self {
 | 
				
			||||||
 | 
					            CKeyState(self.0.clone())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl CKeyState {
 | 
					    impl CKeyState {
 | 
				
			||||||
        fn unwrap(self) -> Rc<RefCell<KeyState>> {
 | 
					        pub fn wrap(state: Rc<RefCell<KeyState>>) -> CKeyState {
 | 
				
			||||||
 | 
					            CKeyState(Rc::into_raw(state))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        pub fn unwrap(self) -> Rc<RefCell<KeyState>> {
 | 
				
			||||||
            unsafe { Rc::from_raw(self.0) }
 | 
					            unsafe { Rc::from_raw(self.0) }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        fn to_owned(self) -> KeyState {
 | 
					        fn to_owned(self) -> KeyState {
 | 
				
			||||||
@ -67,7 +78,7 @@ pub mod c {
 | 
				
			|||||||
                symbol: None,
 | 
					                symbol: None,
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        ));
 | 
					        ));
 | 
				
			||||||
        CKeyState(Rc::into_raw(state))
 | 
					        CKeyState::wrap(state)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    #[no_mangle]
 | 
					    #[no_mangle]
 | 
				
			||||||
@ -195,8 +206,8 @@ pub mod c {
 | 
				
			|||||||
    fn squeek_key_get_symbol(key: CKeyState) -> *const symbol::Symbol {
 | 
					    fn squeek_key_get_symbol(key: CKeyState) -> *const symbol::Symbol {
 | 
				
			||||||
        key.borrow_mut(|key| {
 | 
					        key.borrow_mut(|key| {
 | 
				
			||||||
            match key.symbol {
 | 
					            match key.symbol {
 | 
				
			||||||
                /// This pointer stays after the function exits,
 | 
					                // This pointer stays after the function exits,
 | 
				
			||||||
                /// so it must reference borrowed data and not any copy
 | 
					                // so it must reference borrowed data and not any copy
 | 
				
			||||||
                Some(ref symbol) => symbol as *const symbol::Symbol,
 | 
					                Some(ref symbol) => symbol as *const symbol::Symbol,
 | 
				
			||||||
                None => ptr::null(),
 | 
					                None => ptr::null(),
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -239,13 +250,51 @@ pub mod c {
 | 
				
			|||||||
            .expect("Couldn't convert string")
 | 
					            .expect("Couldn't convert string")
 | 
				
			||||||
            .into_raw()
 | 
					            .into_raw()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					        #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_key_get_action_name(
 | 
				
			||||||
 | 
					        key_name: *const c_char,
 | 
				
			||||||
 | 
					        key: CKeyState,
 | 
				
			||||||
 | 
					    ) -> *const c_char {
 | 
				
			||||||
 | 
					        let key_name = as_cstr(&key_name)
 | 
				
			||||||
 | 
					            .expect("Missing key name")
 | 
				
			||||||
 | 
					            .to_str()
 | 
				
			||||||
 | 
					            .expect("Bad key name");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let symbol_name = match key.to_owned().symbol {
 | 
				
			||||||
 | 
					            Some(ref symbol) => match &symbol.action {
 | 
				
			||||||
 | 
					                symbol::Action::Submit { text: Some(text), .. } => {
 | 
				
			||||||
 | 
					                    Some(
 | 
				
			||||||
 | 
					                        text.clone()
 | 
				
			||||||
 | 
					                            .into_string().expect("Bad symbol")
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                _ => None
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            None => {
 | 
				
			||||||
 | 
					                eprintln!("Key {} has no symbol", key_name);
 | 
				
			||||||
 | 
					                None
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let inner = match symbol_name {
 | 
				
			||||||
 | 
					            Some(name) => format!("[ {} ]", name),
 | 
				
			||||||
 | 
					            _ => format!("[ ]"),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CString::new(format!("        key <{}> {{ {} }};\n", key_name, inner))
 | 
				
			||||||
 | 
					            .expect("Couldn't convert string")
 | 
				
			||||||
 | 
					            .into_raw()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
pub struct KeyState {
 | 
					pub struct KeyState {
 | 
				
			||||||
    pressed: bool,
 | 
					    pub pressed: bool,
 | 
				
			||||||
    locked: bool,
 | 
					    pub locked: bool,
 | 
				
			||||||
    keycode: u32,
 | 
					    pub keycode: u32,
 | 
				
			||||||
    // TODO: remove the optionality of a symbol
 | 
					    // TODO: remove the optionality of a symbol
 | 
				
			||||||
    symbol: Option<symbol::Symbol>,
 | 
					    pub symbol: Option<symbol::Symbol>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										40
									
								
								src/layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/layout.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					#ifndef __LAYOUT_H
 | 
				
			||||||
 | 
					#define __LAYOUT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "inttypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek/eek-container.h"
 | 
				
			||||||
 | 
					#include "src/keyboard.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct squeek_button;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					struct squeek_buttons;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct squeek_buttons *squeek_buttons_new();
 | 
				
			||||||
 | 
					void squeek_buttons_free(struct squeek_buttons*);
 | 
				
			||||||
 | 
					void squeek_buttons_foreach(const struct squeek_buttons*,
 | 
				
			||||||
 | 
					                            ButtonCallback   callback,
 | 
				
			||||||
 | 
					                            gpointer      user_data);
 | 
				
			||||||
 | 
					struct squeek_button *squeek_buttons_find_by_position(
 | 
				
			||||||
 | 
					    const struct squeek_buttons *buttons,
 | 
				
			||||||
 | 
					    double x, double y,
 | 
				
			||||||
 | 
					    double origin_x, double origin_y,
 | 
				
			||||||
 | 
					    double angle);
 | 
				
			||||||
 | 
					void squeek_buttons_add(struct squeek_buttons*, const struct squeek_button* button);
 | 
				
			||||||
 | 
					void squeek_buttons_remove_key(struct squeek_buttons*, const struct squeek_key* key);
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					struct squeek_button *squeek_button_new(uint32_t keycode, uint32_t oref);
 | 
				
			||||||
 | 
					struct squeek_button *squeek_button_new_with_state(const struct squeek_button* source);
 | 
				
			||||||
 | 
					uint32_t squeek_button_get_oref(const struct squeek_button*);
 | 
				
			||||||
 | 
					EekBounds squeek_button_get_bounds(const struct squeek_button*);
 | 
				
			||||||
 | 
					void squeek_button_set_bounds(struct squeek_button* button, EekBounds bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct squeek_symbol *squeek_button_get_symbol (
 | 
				
			||||||
 | 
					    const struct squeek_button *button);
 | 
				
			||||||
 | 
					struct squeek_key *squeek_button_get_key(struct squeek_button*);
 | 
				
			||||||
 | 
					uint32_t *squeek_button_has_key(const struct squeek_button* button,
 | 
				
			||||||
 | 
					                                const struct squeek_key *key);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										147
									
								
								src/layout.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/layout.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					use std::cell::RefCell;
 | 
				
			||||||
 | 
					use std::rc::Rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ::symbol::*;
 | 
				
			||||||
 | 
					use ::keyboard::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Gathers stuff defined in C or called by C
 | 
				
			||||||
 | 
					pub mod c {
 | 
				
			||||||
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use std::ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The following defined in C
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// The index in the relevant outline table
 | 
				
			||||||
 | 
					    #[repr(C)]
 | 
				
			||||||
 | 
					    #[derive(Clone)]
 | 
				
			||||||
 | 
					    pub struct OutlineRef(u32);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// Defined in eek-types.h
 | 
				
			||||||
 | 
					    #[repr(C)]
 | 
				
			||||||
 | 
					    #[derive(Clone)]
 | 
				
			||||||
 | 
					    pub struct Bounds {
 | 
				
			||||||
 | 
					        x: f64,
 | 
				
			||||||
 | 
					        y: f64,
 | 
				
			||||||
 | 
					        width: f64,
 | 
				
			||||||
 | 
					        height: f64
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_new(keycode: u32, oref: u32) -> *mut ::layout::Button {
 | 
				
			||||||
 | 
					        let state: Rc<RefCell<::keyboard::KeyState>> = Rc::new(RefCell::new(
 | 
				
			||||||
 | 
					            ::keyboard::KeyState {
 | 
				
			||||||
 | 
					                pressed: false,
 | 
				
			||||||
 | 
					                locked: false,
 | 
				
			||||||
 | 
					                keycode: keycode,
 | 
				
			||||||
 | 
					                symbol: None,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					        Box::into_raw(Box::new(::layout::Button {
 | 
				
			||||||
 | 
					            oref: OutlineRef(oref),
 | 
				
			||||||
 | 
					            bounds: None,
 | 
				
			||||||
 | 
					            state: state,
 | 
				
			||||||
 | 
					        }))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_new_with_state(source: *mut ::layout::Button) -> *mut ::layout::Button {
 | 
				
			||||||
 | 
					        let source = unsafe { &*source };
 | 
				
			||||||
 | 
					        let button = Box::new(source.clone());
 | 
				
			||||||
 | 
					        Box::into_raw(button)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_get_oref(button: *const ::layout::Button) -> u32 {
 | 
				
			||||||
 | 
					        let button = unsafe { &*button };
 | 
				
			||||||
 | 
					        button.oref.0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Bounds transparently mapped to C, therefore no pointer needed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_get_bounds(button: *const ::layout::Button) -> Bounds {
 | 
				
			||||||
 | 
					        let button = unsafe { &*button };
 | 
				
			||||||
 | 
					        match &button.bounds {
 | 
				
			||||||
 | 
					            Some(bounds) => bounds.clone(),
 | 
				
			||||||
 | 
					            None => panic!("Button doesn't have any bounds yet"),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// Set bounds by consuming the value
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_set_bounds(button: *mut ::layout::Button, bounds: Bounds) {
 | 
				
			||||||
 | 
					        let button = unsafe { &mut *button };
 | 
				
			||||||
 | 
					        button.bounds = Some(bounds);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// Borrow a new reference to key state. Doesn't need freeing
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_get_key(
 | 
				
			||||||
 | 
					        button: *mut ::layout::Button
 | 
				
			||||||
 | 
					    ) -> ::keyboard::c::CKeyState {
 | 
				
			||||||
 | 
					        let button = unsafe { &mut *button };
 | 
				
			||||||
 | 
					        ::keyboard::c::CKeyState::wrap(button.state.clone())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// Really should just return the label
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_get_symbol(
 | 
				
			||||||
 | 
					        button: *const ::layout::Button,
 | 
				
			||||||
 | 
					    ) -> *const Symbol {
 | 
				
			||||||
 | 
					        let button = unsafe { &*button };
 | 
				
			||||||
 | 
					        let state = button.state.borrow();
 | 
				
			||||||
 | 
					        match state.symbol {
 | 
				
			||||||
 | 
					            Some(ref symbol) => symbol as *const Symbol,
 | 
				
			||||||
 | 
					            None => ptr::null(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_button_has_key(
 | 
				
			||||||
 | 
					        button: *const ::layout::Button,
 | 
				
			||||||
 | 
					        state: ::keyboard::c::CKeyState,
 | 
				
			||||||
 | 
					    ) -> u32 {
 | 
				
			||||||
 | 
					        let button = unsafe { &*button };
 | 
				
			||||||
 | 
					        let state = state.unwrap();
 | 
				
			||||||
 | 
					        let equal = Rc::ptr_eq(&button.state, &state);
 | 
				
			||||||
 | 
					        Rc::into_raw(state); // Prevent dropping
 | 
				
			||||||
 | 
					        equal as u32
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    #[cfg(test)]
 | 
				
			||||||
 | 
					    mod test {
 | 
				
			||||||
 | 
					        use super::*;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        #[test]
 | 
				
			||||||
 | 
					        fn button_has_key() {
 | 
				
			||||||
 | 
					            let button = squeek_button_new(0, 0);
 | 
				
			||||||
 | 
					            let state = squeek_button_get_key(button);
 | 
				
			||||||
 | 
					            assert_eq!(squeek_button_has_key(button, state.clone()), 1);
 | 
				
			||||||
 | 
					            let other_button = squeek_button_new(0, 0);
 | 
				
			||||||
 | 
					            assert_eq!(squeek_button_has_key(other_button, state.clone()), 0);
 | 
				
			||||||
 | 
					            let other_state = ::keyboard::c::squeek_key_new(0);
 | 
				
			||||||
 | 
					            assert_eq!(squeek_button_has_key(button, other_state), 0);
 | 
				
			||||||
 | 
					            let shared_button = squeek_button_new_with_state(button);
 | 
				
			||||||
 | 
					            assert_eq!(squeek_button_has_key(shared_button, state), 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// The graphical representation of a button
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub struct Button {
 | 
				
			||||||
 | 
					    oref: c::OutlineRef,
 | 
				
			||||||
 | 
					    /// TODO: abolish Option, buttons should be created with bounds fully formed
 | 
				
			||||||
 | 
					    bounds: Option<c::Bounds>,
 | 
				
			||||||
 | 
					    /// current state, shared with other buttons
 | 
				
			||||||
 | 
					    pub state: Rc<RefCell<KeyState>>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -3,5 +3,6 @@ mod bitflags;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
mod imservice;
 | 
					mod imservice;
 | 
				
			||||||
mod keyboard;
 | 
					mod keyboard;
 | 
				
			||||||
 | 
					mod layout;
 | 
				
			||||||
mod symbol;
 | 
					mod symbol;
 | 
				
			||||||
mod util;
 | 
					mod util;
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,6 @@ sources = [
 | 
				
			|||||||
  '../eek/eek-container.c',
 | 
					  '../eek/eek-container.c',
 | 
				
			||||||
  '../eek/eek-element.c',
 | 
					  '../eek/eek-element.c',
 | 
				
			||||||
  '../eek/eek-gtk-keyboard.c',
 | 
					  '../eek/eek-gtk-keyboard.c',
 | 
				
			||||||
  '../eek/eek-key.c',
 | 
					 | 
				
			||||||
  '../eek/eek-keyboard.c',
 | 
					  '../eek/eek-keyboard.c',
 | 
				
			||||||
  '../eek/eek-keyboard-drawing.c',
 | 
					  '../eek/eek-keyboard-drawing.c',
 | 
				
			||||||
  '../eek/eek-keysym.c',
 | 
					  '../eek/eek-keysym.c',
 | 
				
			||||||
 | 
				
			|||||||
@ -26,15 +26,15 @@ test_create (void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    EekKeyboard *keyboard;
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
    EekSection *section;
 | 
					    EekSection *section;
 | 
				
			||||||
    EekKey *key0, *key1;
 | 
					    struct squeek_button *button0, *button1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
 | 
					    keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
 | 
				
			||||||
    section = eek_keyboard_real_create_section (keyboard);
 | 
					    section = eek_keyboard_real_create_section (keyboard);
 | 
				
			||||||
    g_assert (EEK_IS_SECTION(section));
 | 
					    g_assert (EEK_IS_SECTION(section));
 | 
				
			||||||
    key0 = eek_section_create_key (section, "key0", 1, 0);
 | 
					    button0 = eek_section_create_button (section, "key0", 1, 0);
 | 
				
			||||||
    g_assert (EEK_IS_KEY(key0));
 | 
					    g_assert (button0);
 | 
				
			||||||
    key1 = eek_section_create_key (section, "key1", 2, 0);
 | 
					    button1 = eek_section_create_button (section, "key1", 2, 0);
 | 
				
			||||||
    g_assert (EEK_IS_KEY(key1));
 | 
					    g_assert (button1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user