summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-02-23 22:30:29 -0500
committerKristian Høgsberg <krh@redhat.com>2009-02-23 22:30:29 -0500
commit3c38fa0c3e55893911f85edeb0a0eaa4460e59ca (patch)
tree0f3d0c98eee039bfbc6a69ebdb809a357dc8f09e
parent7e3e860031282d439e4f2da5477a6c96392ea09d (diff)
downloadwayland-3c38fa0c3e55893911f85edeb0a0eaa4460e59ca.tar.gz
wayland-3c38fa0c3e55893911f85edeb0a0eaa4460e59ca.tar.xz
wayland-3c38fa0c3e55893911f85edeb0a0eaa4460e59ca.zip
Include the currently pressed keys in keyboard focus event.
-rw-r--r--connection.c29
-rw-r--r--wayland-client.h3
-rw-r--r--wayland-protocol.c2
-rw-r--r--wayland-system-compositor.c24
-rw-r--r--wayland-util.c44
-rw-r--r--wayland-util.h9
-rw-r--r--window.c4
7 files changed, 106 insertions, 9 deletions
diff --git a/connection.c b/connection.c
index 112ee4f..b37e940 100644
--- a/connection.c
+++ b/connection.c
@@ -229,6 +229,7 @@ wl_connection_vmarshal(struct wl_connection *connection,
{
struct wl_object *object;
uint32_t args[32], length, *p, size;
+ struct wl_array *array;
const char *s;
int i, count;
@@ -254,6 +255,16 @@ wl_connection_vmarshal(struct wl_connection *connection,
object = va_arg(ap, struct wl_object *);
*p++ = object ? object->id : 0;
break;
+ case 'a':
+ array = va_arg(ap, struct wl_array *);
+ if (array == NULL || array->size == 0) {
+ *p++ = 0;
+ break;
+ }
+ *p++ = array->size;
+ memcpy(p, array->data, array->size);
+ p = (void *) p + array->size;
+ break;
default:
assert(0);
break;
@@ -283,6 +294,7 @@ wl_connection_demarshal(struct wl_connection *connection,
char *string;
void *object;
uint32_t new_id;
+ struct wl_array *array;
} values[20];
void *args[20];
struct wl_object *object;
@@ -344,6 +356,20 @@ wl_connection_demarshal(struct wl_connection *connection,
printf("object already exists (%d)\n", *p);
p++;
break;
+ case 'a':
+ types[i] = &ffi_type_pointer;
+ length = *p++;
+ values[i].array = malloc(length + sizeof *values[i].array);
+ if (values[i].array == NULL) {
+ /* FIXME: Send NO_MEMORY */
+ return;
+ }
+ values[i].array->size = length;
+ values[i].array->alloc = 0;
+ values[i].array->data = values[i].array + 1;
+ memcpy(values[i].array->data, p, length);
+ p += DIV_ROUNDUP(length, sizeof *p);
+ break;
default:
printf("unknown type\n");
break;
@@ -359,6 +385,9 @@ wl_connection_demarshal(struct wl_connection *connection,
case 's':
free(values[i].string);
break;
+ case 'a':
+ free(values[i].array);
+ break;
}
}
}
diff --git a/wayland-client.h b/wayland-client.h
index 8e8850a..cb2bd29 100644
--- a/wayland-client.h
+++ b/wayland-client.h
@@ -124,7 +124,8 @@ struct wl_input_device_listener {
struct wl_surface *surface);
void (*keyboard_focus)(void *data,
struct wl_input_device *input_device,
- struct wl_surface *surface);
+ struct wl_surface *surface,
+ struct wl_array *keys);
};
int
diff --git a/wayland-protocol.c b/wayland-protocol.c
index c542205..464af2b 100644
--- a/wayland-protocol.c
+++ b/wayland-protocol.c
@@ -77,7 +77,7 @@ static const struct wl_message input_device_events[] = {
{ "button", "uuiiii" },
{ "key", "uu" },
{ "pointer_focus", "o" },
- { "keyboard_focus", "o" },
+ { "keyboard_focus", "oa" },
};
WL_EXPORT const struct wl_interface wl_input_device_interface = {
diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c
index d0674ec..5524dbb 100644
--- a/wayland-system-compositor.c
+++ b/wayland-system-compositor.c
@@ -88,6 +88,7 @@ struct wlsc_input_device {
struct wlsc_surface *grab_surface;
struct wlsc_surface *pointer_focus;
struct wlsc_surface *keyboard_focus;
+ struct wl_array keys;
};
struct wlsc_compositor {
@@ -870,14 +871,13 @@ wlsc_input_device_set_keyboard_focus(struct wlsc_input_device *device,
(!surface || device->keyboard_focus->base.client != surface->base.client))
wl_surface_post_event(&device->keyboard_focus->base,
&device->base,
- WL_INPUT_KEYBOARD_FOCUS, NULL);
+ WL_INPUT_KEYBOARD_FOCUS, NULL, NULL);
- /* FIXME: We need to send the currently held down keys in the
- * keyboard focus event. */
if (surface)
wl_surface_post_event(&surface->base,
&device->base,
- WL_INPUT_KEYBOARD_FOCUS, &surface->base);
+ WL_INPUT_KEYBOARD_FOCUS,
+ &surface->base, &device->keys);
device->keyboard_focus = surface;
}
@@ -1051,6 +1051,10 @@ notify_key(struct wlsc_input_device *device,
uint32_t key, uint32_t state)
{
struct wlsc_compositor *ec = device->ec;
+ uint32_t *k, *end;
+
+ if (!ec->vt_active)
+ return;
switch (key | ec->meta_state) {
case KEY_EJECTCD | META_DOWN:
@@ -1083,8 +1087,16 @@ notify_key(struct wlsc_input_device *device,
return;
}
- if (!ec->vt_active)
- return;
+ end = device->keys.data + device->keys.size;
+ for (k = device->keys.data; k < end; k++) {
+ if (*k == key)
+ *k = *--end;
+ }
+ device->keys.size = (void *) end - device->keys.data;
+ if (state) {
+ k = wl_array_add(&device->keys, sizeof *k);
+ *k = key;
+ }
if (device->keyboard_focus != NULL)
wl_surface_post_event(&device->keyboard_focus->base,
diff --git a/wayland-util.c b/wayland-util.c
index 4fae435..a5ab8be 100644
--- a/wayland-util.c
+++ b/wayland-util.c
@@ -137,3 +137,47 @@ wl_list_empty(struct wl_list *list)
{
return list->next == list;
}
+
+void
+wl_array_init(struct wl_array *array)
+{
+ memset(array, 0, sizeof *array);
+}
+
+void
+wl_array_release(struct wl_array *array)
+{
+ free(array->data);
+}
+
+void *
+wl_array_add(struct wl_array *array, int size)
+{
+ int alloc;
+ void *data, *p;
+
+ if (array->alloc > 0)
+ alloc = array->alloc;
+ else
+ alloc = 16;
+
+ while (alloc < array->size + size)
+ alloc *= 2;
+
+ if (array->alloc < alloc) {
+ if (array->alloc > 0)
+ data = realloc(array->data, alloc);
+ else
+ data = malloc(alloc);
+
+ if (data == NULL)
+ return 0;
+ array->data = data;
+ array->alloc = alloc;
+ }
+
+ p = array->data + array->size;
+ array->size += size;
+
+ return p;
+}
diff --git a/wayland-util.h b/wayland-util.h
index ffb6f6d..9da870c 100644
--- a/wayland-util.h
+++ b/wayland-util.h
@@ -82,5 +82,14 @@ void wl_list_remove(struct wl_list *elm);
int wl_list_length(struct wl_list *list);
int wl_list_empty(struct wl_list *list);
+struct wl_array {
+ uint32_t size;
+ uint32_t alloc;
+ void *data;
+};
+
+void wl_array_init(struct wl_array *array);
+void wl_array_release(struct wl_array *array);
+void *wl_array_add(struct wl_array *array, int size);
#endif
diff --git a/window.c b/window.c
index b306a23..9c29b62 100644
--- a/window.c
+++ b/window.c
@@ -33,6 +33,7 @@
#include <cairo-drm.h>
#include <linux/input.h>
+#include "wayland-util.h"
#include "wayland-client.h"
#include "wayland-glib.h"
@@ -490,7 +491,8 @@ window_handle_pointer_focus(void *data,
static void
window_handle_keyboard_focus(void *data,
struct wl_input_device *input_device,
- struct wl_surface *surface)
+ struct wl_surface *surface,
+ struct wl_array *keys)
{
struct window *window = data;