Rewrite input event delivery path.
authorKristian Høgsberg <krh@redhat.com>
Fri, 12 Dec 2008 04:18:45 +0000 (23:18 -0500)
committerKristian Høgsberg <krh@redhat.com>
Fri, 12 Dec 2008 04:18:45 +0000 (23:18 -0500)
Instead of having the input driver push the events into the core server,
only to have the server call back out to the compositor hooks, the driver now
just calls the compositor directly.  The input drivers are always dependent on
the type of compositor anyway so there was no point in passing the events
through the server.  Now the server is only involved when it's time to actually
send the events to the clients.

Makefile.in
egl-compositor.c
evdev.c
wayland.c
wayland.h
window.c

index a5540f0..b0d6053 100644 (file)
@@ -35,7 +35,7 @@ egl-compositor :                              \
        wayland-util.o
 
 egl-compositor : CFLAGS += @EGL_COMPOSITOR_CFLAGS@
-egl-compositor : LDLIBS += @EGL_COMPOSITOR_LIBS@ -L. -lwayland-server -rdynamic -lrt
+egl-compositor : LDLIBS += -L. -lwayland-server @EGL_COMPOSITOR_LIBS@ -rdynamic -lrt
 
 flower : flower.o wayland-glib.o cairo-util.o
 gears : gears.o window.o wayland-glib.o cairo-util.o
@@ -45,7 +45,7 @@ terminal : terminal.o window.o wayland-glib.o cairo-util.o
 terminal : LDLIBS += -lutil
 
 $(clients) : CFLAGS += @CLIENT_CFLAGS@
-$(clients) : LDLIBS += @CLIENT_LIBS@ -L. -lwayland -lrt
+$(clients) : LDLIBS += -L. -lwayland @CLIENT_LIBS@ -lrt
 
 install : $(libs)
        install -d @libdir@ @libdir@/pkgconfig
index 069d675..77b9fbb 100644 (file)
 #include <xf86drmMode.h>
 #include <time.h>
 
-#include "wayland.h"
-#include "cairo-util.h"
-
 #include <GL/gl.h>
 #include <eagle.h>
 
+#include "wayland.h"
+#include "cairo-util.h"
+#include "egl-compositor.h"
+
 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 
+struct egl_input_device {
+       struct wl_object base;
+       int32_t x, y;
+       struct egl_compositor *ec;
+       struct egl_surface *surface;
+};
+
 struct egl_compositor {
        struct wl_compositor base;
        EGLDisplay display;
@@ -58,11 +66,12 @@ struct egl_compositor {
        struct wl_display *wl_display;
        int gem_fd;
        int width, height;
-       struct egl_surface *pointer;
        struct egl_surface *background;
        struct egl_surface *overlay;
        double overlay_y, overlay_target, overlay_previous;
 
+       struct egl_input_device *input_device;
+
        struct wl_list surface_list;
 
        /* Repaint state. */
@@ -324,7 +333,10 @@ pointer_create(int x, int y, int width, int height)
        cairo_fill(cr);
        cairo_destroy(cr);
 
-       es = egl_surface_create_from_cairo_surface(surface, x, y, width, height);
+       es = egl_surface_create_from_cairo_surface(surface,
+                                                  x - hotspot_x,
+                                                  y - hotspot_y,
+                                                  width, height);
        
        cairo_surface_destroy(surface);
 
@@ -577,7 +589,7 @@ repaint(void *data)
 
        draw_surface(ec->overlay);
 
-       draw_surface(ec->pointer);
+       draw_surface(ec->input_device->surface);
 
        eglSwapBuffers(ec->display, ec->surface);
        ec->repaint_needed = 0;
@@ -727,15 +739,18 @@ notify_commit(struct wl_compositor *compositor)
 }
 
 static struct egl_surface *
-pick_surface(struct egl_compositor *ec, int32_t x, int32_t y)
+pick_surface(struct egl_input_device *device)
 {
+       struct egl_compositor *ec = device->ec;
        struct egl_surface *es;
 
        es = container_of(ec->surface_list.prev,
                          struct egl_surface, link);
        while (&es->link != &ec->surface_list) {
-               if (es->map.x <= x && x < es->map.x + es->map.width &&
-                   es->map.y <= y && y < es->map.y + es->map.height)
+               if (es->map.x <= device->x &&
+                   device->x < es->map.x + es->map.width &&
+                   es->map.y <= device->y &&
+                   device->y < es->map.y + es->map.height)
                        return es;
 
                es = container_of(es->link.prev,
@@ -745,59 +760,53 @@ pick_surface(struct egl_compositor *ec, int32_t x, int32_t y)
        return NULL;
 }
 
-static void
-notify_pointer_motion(struct wl_compositor *compositor,
-                     struct wl_object *source, int x, int y)
+void
+notify_motion(struct egl_input_device *device, int x, int y)
 {
-       struct egl_compositor *ec = (struct egl_compositor *) compositor;
        struct egl_surface *es;
        const int hotspot_x = 16, hotspot_y = 16;
        int32_t sx, sy;
 
-       es = pick_surface(ec, x, y);
+       es = pick_surface(device);
        if (es) {
                sx = (x - es->map.x) * es->width / es->map.width;
                sy = (y - es->map.y) * es->height / es->map.height;
-               wl_surface_post_event(es->wl_surface, source,
+               wl_surface_post_event(es->wl_surface, &device->base,
                                      WL_INPUT_MOTION, x, y, sx, sy);
        }
 
-       ec->pointer->map.x = x - hotspot_x;
-       ec->pointer->map.y = y - hotspot_y;
-       schedule_repaint(ec);
+       device->x = x;
+       device->y = y;
+       device->surface->map.x = x - hotspot_x;
+       device->surface->map.y = y - hotspot_y;
+
+       schedule_repaint(device->ec);
 }
 
-static void
-notify_pointer_button(struct wl_compositor *compositor,
-                     struct wl_object *source,
-                     int32_t button, int32_t state)
+void
+notify_button(struct egl_input_device *device,
+             int32_t button, int32_t state)
 {
-       struct egl_compositor *ec = (struct egl_compositor *) compositor;
        struct egl_surface *es;
-       const int hotspot_x = 16, hotspot_y = 16;
-       int x, y;
 
-       x = ec->pointer->map.x + hotspot_x;
-       y = ec->pointer->map.y + hotspot_y;
-
-       es = pick_surface(ec, x, y);
+       es = pick_surface(device);
        if (es) {
                wl_list_remove(&es->link);
-               wl_list_insert(ec->surface_list.prev, &es->link);
+               wl_list_insert(device->ec->surface_list.prev, &es->link);
 
                /* FIXME: Swallow click on raise? */
-               wl_surface_post_event(es->wl_surface, source, 
+               wl_surface_post_event(es->wl_surface, &device->base,
                                      WL_INPUT_BUTTON, button, state);
-       }
 
-       schedule_repaint(ec);
+               schedule_repaint(device->ec);
+       }
 }
 
-static void
-notify_key(struct wl_compositor *compositor,
-          struct wl_object *source, uint32_t key, uint32_t state)
+void
+notify_key(struct egl_input_device *device,
+          uint32_t key, uint32_t state)
 {
-       struct egl_compositor *ec = (struct egl_compositor *) compositor;
+       struct egl_compositor *ec = device->ec;
        struct egl_surface *es;
 
        if (key == KEY_ESC && state == 1) {
@@ -813,7 +822,7 @@ notify_key(struct wl_compositor *compositor,
                 * effectively gives us click to focus behavior. */
                es = container_of(ec->surface_list.prev,
                                  struct egl_surface, link);
-               wl_surface_post_event(es->wl_surface, source, 
+               wl_surface_post_event(es->wl_surface, &device->base, 
                                      WL_INPUT_KEY, key, state);
        }
 }
@@ -826,9 +835,6 @@ static const struct wl_compositor_interface interface = {
        notify_surface_copy,
        notify_surface_damage,
        notify_commit,
-       notify_pointer_motion,
-       notify_pointer_button,
-       notify_key
 };
 
 static const char pointer_device_file[] = 
@@ -836,27 +842,49 @@ static const char pointer_device_file[] =
 static const char keyboard_device_file[] = 
        "/dev/input/by-id/usb-Apple__Inc._Apple_Internal_Keyboard_._Trackpad-event-kbd";
 
+struct evdev_input_device *
+evdev_input_device_create(struct egl_input_device *device,
+                         struct wl_display *display, const char *path);
+
+void
+egl_device_get_position(struct egl_input_device *device, int32_t *x, int32_t *y);
+
 static void
-create_input_devices(struct wl_display *display)
+create_input_devices(struct egl_compositor *ec)
 {
-       struct wl_object *obj;
+       struct egl_input_device *device;
        const char *path;
 
+       device = malloc(sizeof *device);
+       if (device == NULL)
+               return;
+
+       device->base.interface = wl_input_device_get_interface();
+       wl_display_add_object(ec->wl_display, &device->base);
+       ec->input_device = device;
+       device->x = 100;
+       device->y = 100;
+       device->surface = pointer_create(device->x, device->y, 64, 64);
+       device->ec = ec;
+
        path = getenv("WAYLAND_POINTER");
        if (path == NULL)
                path = pointer_device_file;
 
-       obj = wl_input_device_create(display, path);
-       if (obj != NULL)
-               wl_display_add_object(display, obj);
+       evdev_input_device_create(device, ec->wl_display, path);
 
        path = getenv("WAYLAND_KEYBOARD");
        if (path == NULL)
                path = keyboard_device_file;
 
-       obj = wl_input_device_create(display, path);
-       if (obj != NULL)
-               wl_display_add_object(display, obj);
+       evdev_input_device_create(device, ec->wl_display, path);
+}
+
+void
+egl_device_get_position(struct egl_input_device *device, int32_t *x, int32_t *y)
+{
+       *x = device->x;
+       *y = device->y;
 }
 
 static uint32_t
@@ -1065,14 +1093,13 @@ egl_compositor_create(struct wl_display *display)
        glOrtho(0, ec->width, ec->height, 0, 0, 1000.0);
        glMatrixMode(GL_MODELVIEW);
 
-       create_input_devices(display);
+       create_input_devices(ec);
 
        wl_list_init(&ec->surface_list);
        filename = getenv("WAYLAND_BACKGROUND");
        if (filename == NULL)
                filename = "background.jpg";
        ec->background = background_create(filename, 1280, 800);
-       ec->pointer = pointer_create(100, 100, 64, 64);
        ec->overlay = overlay_create(0, ec->height, ec->width, 200);
        ec->overlay_y = ec->height;
        ec->overlay_target = ec->height;
diff --git a/evdev.c b/evdev.c
index b73ca9d..77f82fd 100644 (file)
--- a/evdev.c
+++ b/evdev.c
 #include <linux/input.h>
 
 #include "wayland.h"
+#include "egl-compositor.h"
 
-struct wl_input_device {
-       struct wl_object base;
+struct evdev_input_device {
+       struct egl_input_device *device;
        struct wl_event_source *source;
-       struct wl_display *display;
-       int fd;
        int tool, new_x, new_y;
-       int32_t x, y, base_x, base_y;
-};
-
-static const struct wl_method input_device_methods[] = {
-};
-
-static const struct wl_event input_device_events[] = {
-       { "motion", "iiii" },
-       { "button", "uu" },
-       { "key", "uu" },
-};
-
-static const struct wl_interface input_device_interface = {
-       "input_device", 1,
-       ARRAY_LENGTH(input_device_methods),
-       input_device_methods,
-       ARRAY_LENGTH(input_device_events),
-       input_device_events,
+       int base_x, base_y;
+       int fd;
 };
 
-static void wl_input_device_data(int fd, uint32_t mask, void *data)
+static void evdev_input_device_data(int fd, uint32_t mask, void *data)
 {
-       struct wl_input_device *device = data;
+       struct evdev_input_device *device = data;
        struct input_event ev[8], *e, *end;
        int len, value, dx, dy, absolute_event;
+       int x, y;
 
        dx = 0;
        dy = 0;
        absolute_event = 0;
+       egl_device_get_position(device->device, &x, &y);
+
 
        len = read(fd, &ev, sizeof ev);
        if (len < 0 || len % sizeof e[0] != 0) {
@@ -96,17 +82,17 @@ static void wl_input_device_data(int fd, uint32_t mask, void *data)
                        switch (e->code) {
                        case ABS_X:
                                if (device->new_x) {
-                                       device->base_x = device->x - value;
+                                       device->base_x = x - value;
                                        device->new_x = 0;
                                }
-                               device->x = device->base_x + value;
+                               x = device->base_x + value;
                                break;
                        case ABS_Y:
                                if (device->new_y) {
-                                       device->base_y = device->y - value;
+                                       device->base_y = y - value;
                                        device->new_y = 0;
                                }
-                               device->y = device->base_y + value;
+                               y = device->base_y + value;
                                break;
                        }
                        break;
@@ -133,54 +119,44 @@ static void wl_input_device_data(int fd, uint32_t mask, void *data)
                                break;
 
                        case BTN_LEFT:
-                               wl_display_post_button_event(device->display,
-                                                            &device->base, 0, value);
-                               break;
-
                        case BTN_RIGHT:
-                               wl_display_post_button_event(device->display,
-                                                            &device->base, 2, value);
-                               break;
-
                        case BTN_MIDDLE:
-                               wl_display_post_button_event(device->display,
-                                                            &device->base, 1, value);
+                       case BTN_SIDE:
+                       case BTN_EXTRA:
+                       case BTN_FORWARD:
+                       case BTN_BACK:
+                       case BTN_TASK:
+                               notify_button(device->device, e->code, value);
                                break;
 
                        default:
-                               wl_display_post_key_event(device->display,
-                                                         &device->base, e->code, value);
+                               notify_key(device->device, e->code, value);
                                break;
                        }
                }
        }
 
        if (dx != 0 || dy != 0)
-               wl_display_post_relative_event(device->display,
-                                              &device->base, dx, dy);
+               notify_motion(device->device, x + dx, y + dy);
        if (absolute_event && device->tool)
-               wl_display_post_absolute_event(device->display,
-                                              &device->base,
-                                              device->x, device->y);
+               notify_motion(device->device, x, y);
 }
 
-WL_EXPORT struct wl_object *
-wl_input_device_create(struct wl_display *display, const char *path)
+struct evdev_input_device *
+evdev_input_device_create(struct egl_input_device *master,
+                         struct wl_display *display, const char *path)
 {
-       struct wl_input_device *device;
+       struct evdev_input_device *device;
        struct wl_event_loop *loop;
 
        device = malloc(sizeof *device);
        if (device == NULL)
                return NULL;
 
-       device->base.interface = &input_device_interface;
-       device->display = display;
        device->tool = 1;
-       device->x = 100;
-       device->y = 100;
        device->new_x = 1;
        device->new_y = 1;
+       device->device = master;
 
        device->fd = open(path, O_RDONLY);
        if (device->fd < 0) {
@@ -192,12 +168,12 @@ wl_input_device_create(struct wl_display *display, const char *path)
        loop = wl_display_get_event_loop(display);
        device->source = wl_event_loop_add_fd(loop, device->fd,
                                              WL_EVENT_READABLE,
-                                             wl_input_device_data, device);
+                                             evdev_input_device_data, device);
        if (device->source == NULL) {
                close(device->fd);
                free(device);
                return NULL;
        }
 
-       return &device->base;
+       return device;
 }
index 4f41ebd..85301ab 100644 (file)
--- a/wayland.c
+++ b/wayland.c
@@ -62,9 +62,6 @@ struct wl_display {
        uint32_t id;
 
        struct wl_list global_list;
-
-       int32_t pointer_x;
-       int32_t pointer_y;
 };
 
 struct wl_surface {
@@ -582,9 +579,6 @@ wl_display_create(void)
        wl_list_init(&display->client_list);
        wl_list_init(&display->global_list);
 
-       display->pointer_x = 100;
-       display->pointer_y = 100;
-
        display->client_id_range = 256; /* Gah, arbitrary... */
 
        display->id = 1;
@@ -633,53 +627,35 @@ wl_surface_post_event(struct wl_surface *surface,
        va_end(ap);
 }
 
-WL_EXPORT void
-wl_display_post_relative_event(struct wl_display *display,
-                              struct wl_object *source, int dx, int dy)
-{
-       const struct wl_compositor_interface *interface;
-
-       display->pointer_x += dx;
-       display->pointer_y += dy;
-
-       interface = display->compositor->interface;
-       interface->notify_pointer_motion(display->compositor, source,
-                                        display->pointer_x, display->pointer_y);
-}
-
-WL_EXPORT void
-wl_display_post_absolute_event(struct wl_display *display,
-                              struct wl_object *source, int x, int y)
-{
-       const struct wl_compositor_interface *interface;
-
-       display->pointer_x = x;
-       display->pointer_y = y;
+struct wl_input_device {
+       struct wl_object base;
+       struct wl_display *display;
+       uint32_t button_state[16];
+       uint32_t button_count;
+       int32_t x, y;
+};
 
-       interface = display->compositor->interface;
-       interface->notify_pointer_motion(display->compositor, source,
-                                        display->pointer_x, display->pointer_y);
-}
+static const struct wl_method input_device_methods[] = {
+};
 
-WL_EXPORT void
-wl_display_post_button_event(struct wl_display *display,
-                            struct wl_object *source, int button, int state)
-{
-       const struct wl_compositor_interface *interface;
+static const struct wl_event input_device_events[] = {
+       { "motion", "iiii" },
+       { "button", "uu" },
+       { "key", "uu" },
+};
 
-       interface = display->compositor->interface;
-       interface->notify_pointer_button(display->compositor, source,
-                                        button, state);
-}
+static const struct wl_interface input_device_interface = {
+       "input_device", 1,
+       ARRAY_LENGTH(input_device_methods),
+       input_device_methods,
+       ARRAY_LENGTH(input_device_events),
+       input_device_events,
+};
 
-WL_EXPORT void
-wl_display_post_key_event(struct wl_display *display,
-                         struct wl_object *source, int key, int state)
+WL_EXPORT const struct wl_interface *
+wl_input_device_get_interface(void)
 {
-       const struct wl_compositor_interface *interface;
-
-       interface = display->compositor->interface;
-       interface->notify_key(display->compositor, source, key, state);
+       return &input_device_interface;
 }
 
 WL_EXPORT void
index 6125833..cc19ab3 100644 (file)
--- a/wayland.h
+++ b/wayland.h
@@ -99,6 +99,7 @@ struct wl_object {
 
 struct wl_surface;
 struct wl_display;
+struct wl_input_device;
 
 struct wl_map {
        int32_t x, y, width, height;
@@ -107,9 +108,6 @@ struct wl_map {
 void wl_surface_set_data(struct wl_surface *surface, void *data);
 void *wl_surface_get_data(struct wl_surface *surface);
 
-struct wl_object *
-wl_input_device_create(struct wl_display *display, const char *path);
-
 struct wl_display *wl_display_create(void);
 struct wl_event_loop *wl_display_get_event_loop(struct wl_display *display);
 int wl_display_add_socket(struct wl_display *display, const char *name, size_t name_size);
@@ -120,18 +118,9 @@ wl_display_add_object(struct wl_display *display, struct wl_object *object);
 int
 wl_display_add_global(struct wl_display *display, struct wl_object *object);
 
-void
-wl_display_post_relative_event(struct wl_display *display,
-                              struct wl_object *source, int dx, int dy);
-void
-wl_display_post_absolute_event(struct wl_display *display,
-                              struct wl_object *source, int x, int y);
-void
-wl_display_post_button_event(struct wl_display *display,
-                            struct wl_object *source, int button, int state);
-void
-wl_display_post_key_event(struct wl_display *display,
-                         struct wl_object *source, int key, int state);
+const struct wl_interface *
+wl_input_device_get_interface(void);
+
 void
 wl_display_post_frame(struct wl_display *display,
                      uint32_t frame, uint32_t msecs);
@@ -173,15 +162,6 @@ struct wl_compositor_interface {
                                      int32_t x, int32_t y,
                                      int32_t width, int32_t height);
        uint32_t (*notify_commit)(struct wl_compositor *compositor);
-       void (*notify_pointer_motion)(struct wl_compositor *compositor,
-                                     struct wl_object *source,
-                                     int32_t x, int32_t y);
-       void (*notify_pointer_button)(struct wl_compositor *compositor,
-                                     struct wl_object *source,
-                                     int32_t button, int32_t state);
-       void (*notify_key)(struct wl_compositor *compositor,
-                          struct wl_object *source,
-                          uint32_t key, uint32_t state);
 };
 
 void wl_display_set_compositor(struct wl_display *display,
index 6b42322..c44d29b 100644 (file)
--- a/window.c
+++ b/window.c
@@ -31,6 +31,7 @@
 #include <cairo.h>
 #include <glib.h>
 
+#include <linux/input.h>
 #include "wayland-client.h"
 #include "wayland-glib.h"
 
@@ -272,7 +273,7 @@ event_handler(struct wl_display *display,
                        location = LOCATION_OUTSIDE;
                }
 
-               if (button == 0 && state == 1) {
+               if (button == BTN_LEFT && state == 1) {
                        switch (location) {
                        case LOCATION_INTERIOR:
                                window->drag_x = window->x - window->last_x;
@@ -288,7 +289,7 @@ event_handler(struct wl_display *display,
                                window->state = WINDOW_STABLE;
                                break;
                        }
-               } else if (button == 0 && state == 0) {
+               } else if (button == BTN_LEFT && state == 0) {
                        window->state = WINDOW_STABLE;
                }
        } else if (opcode == 2) {