diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c index 5966c64e..2eff0fd7 100644 --- a/eek/eek-gtk-keyboard.c +++ b/eek/eek-gtk-keyboard.c @@ -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) { diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index 78807fed..d6a8fce5 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -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); } diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h index 744cfe7d..d04a4489 100644 --- a/eek/eek-keyboard.h +++ b/eek/eek-keyboard.h @@ -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); diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index 80440425..9bc78dc7 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -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, diff --git a/src/keyboard.h b/src/keyboard.h index ef402e2f..8011f345 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -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); diff --git a/src/keyboard.rs b/src/keyboard.rs index c2356b00..144a7d87 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -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 {