Merge branch 'buttonlists' into 'master'
Buttonlists See merge request Librem5/squeekboard!145
This commit is contained in:
		@ -63,14 +63,14 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_A
 | 
			
		||||
 | 
			
		||||
static void       on_button_pressed          (struct squeek_button *button, struct squeek_view *view,
 | 
			
		||||
                                              EekGtkKeyboard *self);
 | 
			
		||||
static void       on_button_released         (struct squeek_button *button,
 | 
			
		||||
static void       on_button_released         (const struct squeek_button *button,
 | 
			
		||||
                                              struct squeek_view *view,
 | 
			
		||||
                                              EekGtkKeyboard *self);
 | 
			
		||||
static void       render_pressed_button      (GtkWidget *widget, struct button_place *place);
 | 
			
		||||
static void       render_locked_button       (GtkWidget *widget,
 | 
			
		||||
                                              struct button_place *place);
 | 
			
		||||
static void       render_released_button     (GtkWidget *widget,
 | 
			
		||||
                                              struct squeek_button *button);
 | 
			
		||||
                                              const struct squeek_button *button);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
			
		||||
@ -112,22 +112,20 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
    struct squeek_view *view = priv->keyboard->views[priv->keyboard->level];
 | 
			
		||||
 | 
			
		||||
    /* redraw pressed key */
 | 
			
		||||
    const GList *list = priv->keyboard->pressed_buttons;
 | 
			
		||||
    const GList *list = priv->keyboard->pressed_keys;
 | 
			
		||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct button_place place = squeek_view_find_key(
 | 
			
		||||
            view, squeek_button_get_key(head->data)
 | 
			
		||||
            view, head->data
 | 
			
		||||
        );
 | 
			
		||||
        if (place.button)
 | 
			
		||||
            render_pressed_button (self, &place);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* redraw locked key */
 | 
			
		||||
    list = priv->keyboard->locked_buttons;
 | 
			
		||||
    list = priv->keyboard->locked_keys;
 | 
			
		||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct button_place place = squeek_view_find_key(
 | 
			
		||||
            view, squeek_button_get_key(
 | 
			
		||||
                ((EekModifierKey *)head->data)->button
 | 
			
		||||
            )
 | 
			
		||||
            view, ((EekModifierKey *)head->data)->key
 | 
			
		||||
        );
 | 
			
		||||
        if (place.button)
 | 
			
		||||
            render_locked_button (self, &place);
 | 
			
		||||
@ -160,7 +158,11 @@ static void depress(EekGtkKeyboard *self,
 | 
			
		||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
			
		||||
 | 
			
		||||
    if (button) {
 | 
			
		||||
        eek_keyboard_press_button(priv->keyboard, button, time);
 | 
			
		||||
        eek_keyboard_press_key(
 | 
			
		||||
            priv->keyboard,
 | 
			
		||||
            squeek_button_get_key(button),
 | 
			
		||||
            time
 | 
			
		||||
        );
 | 
			
		||||
        on_button_pressed(button, view, self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -173,29 +175,42 @@ static void drag(EekGtkKeyboard *self,
 | 
			
		||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
 | 
			
		||||
    list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
			
		||||
    list = g_list_copy(priv->keyboard->pressed_keys);
 | 
			
		||||
 | 
			
		||||
    if (button) {
 | 
			
		||||
        gboolean found = FALSE;
 | 
			
		||||
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            if (head->data == button) {
 | 
			
		||||
            struct squeek_key *key = head->data;
 | 
			
		||||
            if (squeek_button_has_key(button, key)) {
 | 
			
		||||
                found = TRUE;
 | 
			
		||||
            } else {
 | 
			
		||||
                eek_keyboard_release_button(priv->keyboard, head->data, time);
 | 
			
		||||
                on_button_released(button, view, self);
 | 
			
		||||
                eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
                // The released handler proceeds to ignore this info...
 | 
			
		||||
                // let's do this for consistency nevertheless
 | 
			
		||||
                struct button_place place = squeek_view_find_key(view, key);
 | 
			
		||||
                on_button_released(place.button, view, self);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
 | 
			
		||||
        if (!found) {
 | 
			
		||||
            eek_keyboard_press_button(priv->keyboard, button, time);
 | 
			
		||||
            eek_keyboard_press_key(
 | 
			
		||||
                priv->keyboard,
 | 
			
		||||
                squeek_button_get_key(button),
 | 
			
		||||
                time
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            on_button_pressed(button, view, self);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            eek_keyboard_release_button(priv->keyboard, head->data, time);
 | 
			
		||||
            on_button_released(head->data, view, self);
 | 
			
		||||
            struct squeek_key *key = head->data;
 | 
			
		||||
            eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
            // The released handler proceeds to ignore this info...
 | 
			
		||||
            // let's do this for consistency nevertheless
 | 
			
		||||
            struct button_place place = squeek_view_find_key(view, key);
 | 
			
		||||
            on_button_released(place.button, view, self);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
    }
 | 
			
		||||
@ -207,11 +222,14 @@ static void release(EekGtkKeyboard *self, guint32 time)
 | 
			
		||||
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    GList *list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
			
		||||
    GList *list = g_list_copy(priv->keyboard->pressed_keys);
 | 
			
		||||
    for (GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct squeek_button *button = head->data;
 | 
			
		||||
        eek_keyboard_release_button(priv->keyboard, button, time);
 | 
			
		||||
        on_button_released(button, view, self);
 | 
			
		||||
        struct squeek_key *key = head->data;
 | 
			
		||||
        eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
        // The released handler proceeds to ignore this info...
 | 
			
		||||
        // let's do this for consistency nevertheless
 | 
			
		||||
        struct button_place place = squeek_view_find_key(view, key);
 | 
			
		||||
        on_button_released(place.button, view, self);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
}
 | 
			
		||||
@ -290,11 +308,11 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *head;
 | 
			
		||||
 | 
			
		||||
        for (head = priv->keyboard->pressed_buttons; head; head = g_list_next (head)) {
 | 
			
		||||
        for (head = priv->keyboard->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
            /* Unlike other places where we call this, we don't call
 | 
			
		||||
               on_button_released afterwards since we don't want to queue a
 | 
			
		||||
               redraw. */
 | 
			
		||||
            eek_keyboard_release_button(priv->keyboard, head->data,
 | 
			
		||||
            eek_keyboard_release_key(priv->keyboard, head->data,
 | 
			
		||||
                                        gdk_event_get_time(NULL));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -355,8 +373,8 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *head;
 | 
			
		||||
 | 
			
		||||
        for (head = priv->keyboard->pressed_buttons; head; head = g_list_next (head)) {
 | 
			
		||||
            eek_keyboard_release_button(priv->keyboard, head->data,
 | 
			
		||||
        for (head = priv->keyboard->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
            eek_keyboard_release_key(priv->keyboard, head->data,
 | 
			
		||||
                                        gdk_event_get_time(NULL));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -464,9 +482,10 @@ render_locked_button (GtkWidget *widget, struct button_place *place)
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: does it really redraw the entire keyboard?
 | 
			
		||||
static void
 | 
			
		||||
render_released_button (GtkWidget *widget,
 | 
			
		||||
                        struct squeek_button *button)
 | 
			
		||||
                        const struct squeek_button *button)
 | 
			
		||||
{
 | 
			
		||||
    (void)button;
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
@ -515,7 +534,7 @@ on_button_pressed (struct squeek_button *button,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_button_released (struct squeek_button *button,
 | 
			
		||||
on_button_released (const struct squeek_button *button,
 | 
			
		||||
                    struct squeek_view *view,
 | 
			
		||||
                    EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -55,10 +55,9 @@ eek_modifier_key_free (EekModifierKey *modkey)
 | 
			
		||||
/// and instead refer to the contained symbols
 | 
			
		||||
static guint
 | 
			
		||||
set_key_states (LevelKeyboard    *keyboard,
 | 
			
		||||
                struct squeek_button *button,
 | 
			
		||||
                struct squeek_key *key,
 | 
			
		||||
                guint new_level)
 | 
			
		||||
{
 | 
			
		||||
    struct squeek_key *key = squeek_button_get_key(button);
 | 
			
		||||
    // Keys locking rules hardcoded for the time being...
 | 
			
		||||
    const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
 | 
			
		||||
    // Lock the shift whenever it's pressed on the baselevel
 | 
			
		||||
@ -66,19 +65,19 @@ set_key_states (LevelKeyboard    *keyboard,
 | 
			
		||||
    if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
 | 
			
		||||
        EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
			
		||||
        modifier_key->modifiers = 0;
 | 
			
		||||
        modifier_key->button = button;
 | 
			
		||||
        keyboard->locked_buttons =
 | 
			
		||||
            g_list_prepend (keyboard->locked_buttons, modifier_key);
 | 
			
		||||
        modifier_key->key = key;
 | 
			
		||||
        keyboard->locked_keys =
 | 
			
		||||
            g_list_prepend (keyboard->locked_keys, modifier_key);
 | 
			
		||||
        squeek_key_set_locked(key, true);
 | 
			
		||||
    }
 | 
			
		||||
    if (keyboard->level == 1) {
 | 
			
		||||
        // Only shift is locked in this state, unlock on any key press
 | 
			
		||||
        for (GList *head = keyboard->locked_buttons; head; ) {
 | 
			
		||||
        for (GList *head = keyboard->locked_keys; head; ) {
 | 
			
		||||
            EekModifierKey *modifier_key = head->data;
 | 
			
		||||
            GList *next = g_list_next (head);
 | 
			
		||||
            keyboard->locked_buttons =
 | 
			
		||||
                g_list_remove_link (keyboard->locked_buttons, head);
 | 
			
		||||
            squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
 | 
			
		||||
            keyboard->locked_keys =
 | 
			
		||||
                g_list_remove_link (keyboard->locked_keys, head);
 | 
			
		||||
            squeek_key_set_locked(modifier_key->key, false);
 | 
			
		||||
            g_list_free1 (head);
 | 
			
		||||
            head = next;
 | 
			
		||||
        }
 | 
			
		||||
@ -89,13 +88,13 @@ set_key_states (LevelKeyboard    *keyboard,
 | 
			
		||||
 | 
			
		||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
 | 
			
		||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_key *key)
 | 
			
		||||
{
 | 
			
		||||
    /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
 | 
			
		||||
    guint level = keyboard->level;
 | 
			
		||||
    /* Handle non-emitting keys */
 | 
			
		||||
    if (button) {
 | 
			
		||||
        const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button)));
 | 
			
		||||
    if (key) {
 | 
			
		||||
        const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
 | 
			
		||||
        if (g_strcmp0(name, "show_numbers") == 0) {
 | 
			
		||||
            level = 2;
 | 
			
		||||
        } else if (g_strcmp0(name, "show_letters") == 0) {
 | 
			
		||||
@ -107,15 +106,14 @@ set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keyboard->level = set_key_states(keyboard, button, level);
 | 
			
		||||
    keyboard->level = set_key_states(keyboard, key, level);
 | 
			
		||||
 | 
			
		||||
    eek_layout_update_layout(keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
 | 
			
		||||
    struct squeek_key *key = squeek_button_get_key(button);
 | 
			
		||||
void eek_keyboard_press_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp) {
 | 
			
		||||
    squeek_key_set_pressed(key, TRUE);
 | 
			
		||||
    keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button);
 | 
			
		||||
    keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key);
 | 
			
		||||
 | 
			
		||||
    struct squeek_symbol *symbol = squeek_key_get_symbol(key);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
@ -131,26 +129,26 @@ void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *bu
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_release_button(LevelKeyboard *keyboard,
 | 
			
		||||
                                 struct squeek_button *button,
 | 
			
		||||
                                 guint32 timestamp) {
 | 
			
		||||
    for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) {
 | 
			
		||||
        if (head->data == button) {
 | 
			
		||||
            keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, head);
 | 
			
		||||
void eek_keyboard_release_key(LevelKeyboard *keyboard,
 | 
			
		||||
                              struct squeek_key *key,
 | 
			
		||||
                              guint32 timestamp) {
 | 
			
		||||
    for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
        if (squeek_key_equal(head->data, key)) {
 | 
			
		||||
            keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head);
 | 
			
		||||
            g_list_free1 (head);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct squeek_symbol *symbol = squeek_button_get_symbol(button);
 | 
			
		||||
    struct squeek_symbol *symbol = squeek_key_get_symbol(key);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    set_level_from_press (keyboard, button);
 | 
			
		||||
    set_level_from_press (keyboard, key);
 | 
			
		||||
 | 
			
		||||
    // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
 | 
			
		||||
 | 
			
		||||
    guint keycode = squeek_key_get_keycode (squeek_button_get_key(button));
 | 
			
		||||
    guint keycode = squeek_key_get_keycode (key);
 | 
			
		||||
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ G_BEGIN_DECLS
 | 
			
		||||
struct _EekModifierKey {
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    struct squeek_button *button;
 | 
			
		||||
    struct squeek_key *key;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekModifierKey EekModifierKey;
 | 
			
		||||
 | 
			
		||||
@ -49,8 +49,8 @@ struct _LevelKeyboard {
 | 
			
		||||
    size_t keymap_len; // length of the data inside keymap_fd
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
 | 
			
		||||
    GList *pressed_buttons; // struct squeek_button*
 | 
			
		||||
    GList *locked_buttons; // struct squeek_button*
 | 
			
		||||
    GList *pressed_keys; // struct squeek_key*
 | 
			
		||||
    GList *locked_keys; // struct EekModifierKey*
 | 
			
		||||
 | 
			
		||||
    /* Map button names to button objects: */
 | 
			
		||||
    GHashTable *names;
 | 
			
		||||
@ -78,8 +78,8 @@ EekModifierKey     *eek_modifier_key_copy
 | 
			
		||||
void                eek_modifier_key_free
 | 
			
		||||
                                     (EekModifierKey      *modkey);
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_press_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
gchar *             eek_keyboard_get_keymap
 | 
			
		||||
                                     (LevelKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
@ -992,6 +992,7 @@ eek_renderer_find_button_by_position (EekRenderer *renderer,
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    /* Transform from widget coordinates to keyboard coordinates */
 | 
			
		||||
    EekPoint point = {
 | 
			
		||||
        .x = (x - priv->origin_x)/priv->scale,
 | 
			
		||||
        .y = (y - priv->origin_y)/priv->scale,
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef __KEYBOARD_H
 | 
			
		||||
#define __KYBOARD_H
 | 
			
		||||
#define __KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#include "stdbool.h"
 | 
			
		||||
#include "inttypes.h"
 | 
			
		||||
@ -19,6 +19,7 @@ uint32_t squeek_key_is_locked(struct squeek_key *key);
 | 
			
		||||
void squeek_key_set_locked(struct squeek_key *key, uint32_t pressed);
 | 
			
		||||
uint32_t squeek_key_get_keycode(struct squeek_key *key);
 | 
			
		||||
void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode);
 | 
			
		||||
uint32_t squeek_key_equal(struct squeek_key* key, struct squeek_key* key1);
 | 
			
		||||
 | 
			
		||||
struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key);
 | 
			
		||||
const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key);
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,13 @@ pub mod c {
 | 
			
		||||
        unsafe { key.unwrap() }; // reference dropped
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Compares pointers to the data
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_equal(key: CKeyState, key2: CKeyState) -> u32 {
 | 
			
		||||
        return Rc::ptr_eq(&key.clone_ref(), &key2.clone_ref()) as u32
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_is_pressed(key: CKeyState) -> u32 {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user