summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-05-30 10:36:54 -0400
committerChristopher James Halse Rogers <christopher.halse.rogers@canonical.com>2012-06-13 15:26:21 +1000
commit7e4944804ec174a5ad01e2ab8b3c9b04f0df9e12 (patch)
tree65135361f69dcf6bcbe01ee1557f93b02d00547e
parentead90b8016c21f31025b060d4726c6f25901387a (diff)
xwayland: Track keyboard state, reset on keyboard enter/leave
-rw-r--r--hw/xfree86/xwayland/xwayland-input.c24
-rw-r--r--hw/xfree86/xwayland/xwayland-private.h1
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;