diff --git a/Makefile.in b/Makefile.in index a5540f0a..b0d60538 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/egl-compositor.c b/egl-compositor.c index 069d6756..77b9fbb7 100644 --- a/egl-compositor.c +++ b/egl-compositor.c @@ -41,14 +41,22 @@ #include #include -#include "wayland.h" -#include "cairo-util.h" - #include #include +#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 b73ca9d7..77f82fd0 100644 --- a/evdev.c +++ b/evdev.c @@ -29,42 +29,28 @@ #include #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; } diff --git a/wayland.c b/wayland.c index 4f41ebd3..85301ab7 100644 --- 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 diff --git a/wayland.h b/wayland.h index 61258339..cc19ab3a 100644 --- 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, diff --git a/window.c b/window.c index 6b42322a..c44d29bd 100644 --- a/window.c +++ b/window.c @@ -31,6 +31,7 @@ #include #include +#include #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) {