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
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
#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;
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. */
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);
draw_surface(ec->overlay);
- draw_surface(ec->pointer);
+ draw_surface(ec->input_device->surface);
eglSwapBuffers(ec->display, ec->surface);
ec->repaint_needed = 0;
}
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,
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) {
* 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);
}
}
notify_surface_copy,
notify_surface_damage,
notify_commit,
- notify_pointer_motion,
- notify_pointer_button,
- notify_key
};
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
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;
#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) {
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;
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) {
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;
}
uint32_t id;
struct wl_list global_list;
-
- int32_t pointer_x;
- int32_t pointer_y;
};
struct wl_surface {
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;
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
struct wl_surface;
struct wl_display;
+struct wl_input_device;
struct wl_map {
int32_t x, y, width, height;
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);
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);
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,
#include <cairo.h>
#include <glib.h>
+#include <linux/input.h>
#include "wayland-client.h"
#include "wayland-glib.h"
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;
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) {