summaryrefslogtreecommitdiff
path: root/egl-compositor.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2008-12-11 23:18:45 -0500
committerKristian Høgsberg <krh@redhat.com>2008-12-11 23:18:45 -0500
commit5ee1a60f1a03b3176332f6d4f27744d0dfdb0601 (patch)
tree84afd32f96b8f045f24a382c06e6e585183ef877 /egl-compositor.c
parentd1c58d60f6c212c3de1f2c214745ef4db9623c7e (diff)
Rewrite input event delivery path.
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.
Diffstat (limited to 'egl-compositor.c')
-rw-r--r--egl-compositor.c129
1 files changed, 78 insertions, 51 deletions
diff --git a/egl-compositor.c b/egl-compositor.c
index 069d675..77b9fbb 100644
--- a/egl-compositor.c
+++ b/egl-compositor.c
@@ -41,14 +41,22 @@
#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;