diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2012-05-30 10:36:54 -0400 |
---|---|---|
committer | Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> | 2012-06-13 15:26:21 +1000 |
commit | 7e4944804ec174a5ad01e2ab8b3c9b04f0df9e12 (patch) | |
tree | 65135361f69dcf6bcbe01ee1557f93b02d00547e | |
parent | ead90b8016c21f31025b060d4726c6f25901387a (diff) |
xwayland: Track keyboard state, reset on keyboard enter/leave
-rw-r--r-- | hw/xfree86/xwayland/xwayland-input.c | 24 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland-private.h | 1 |
2 files changed, 22 insertions, 3 deletions
diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c index 706623ad2..e01cd8aca 100644 --- a/hw/xfree86/xwayland/xwayland-input.c +++ b/hw/xfree86/xwayland/xwayland-input.c @@ -369,6 +369,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, { struct xwl_seat *xwl_seat = data; uint32_t modifier; + uint32_t *k, *end; xwl_seat->xwl_screen->serial = serial; @@ -387,6 +388,17 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, else xwl_seat->modifiers &= ~modifier; + end = xwl_seat->keys.data + xwl_seat->keys.size; + for (k = xwl_seat->keys.data; k < end; k++) { + if (*k == key) + *k = *--end; + } + xwl_seat->keys.size = (void *) end - xwl_seat->keys.data; + if (state) { + k = wl_array_add(&xwl_seat->keys, sizeof *k); + *k = key; + } + xf86PostKeyboardEvent(xwl_seat->keyboard, key + 8, state); } @@ -396,19 +408,20 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, struct wl_surface *surface, struct wl_array *keys) { struct xwl_seat *xwl_seat = data; - uint32_t *k, *end; + uint32_t *k; xwl_seat->xwl_screen->serial = serial; xwl_seat->modifiers = 0; - end = (uint32_t *) ((char *) keys->data + keys->size); - for (k = keys->data; k < end; k++) { + wl_array_copy(&xwl_seat->keys, keys); + wl_array_for_each(k, &xwl_seat->keys) { switch (*k) { case KEY_LEFTMETA: case KEY_RIGHTMETA: xwl_seat->modifiers |= MODIFIER_META; break; } + xf86PostKeyboardEvent(xwl_seat->keyboard, *k + 8, 1); } } @@ -417,8 +430,12 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) { struct xwl_seat *xwl_seat = data; + uint32_t *k; xwl_seat->xwl_screen->serial = serial; + + wl_array_for_each(k, &xwl_seat->keys) + xf86PostKeyboardEvent(xwl_seat->keyboard, *k + 8, 0); } static const struct wl_keyboard_listener keyboard_listener = { @@ -472,6 +489,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, xwl_seat->id = id; wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat); + wl_array_init(&xwl_seat->keys); } static void diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h index f1fec23e8..89ba8d1e4 100644 --- a/hw/xfree86/xwayland/xwayland-private.h +++ b/hw/xfree86/xwayland/xwayland-private.h @@ -94,6 +94,7 @@ struct xwl_seat { struct wl_seat *seat; struct wl_pointer *wl_pointer; struct wl_keyboard *wl_keyboard; + struct wl_array keys; int grab; struct xwl_window *focus_window; int32_t grab_x, grab_y; |