libwayland.so $(compositors) :
gcc -o $@ $^ $(LDLIBS) -shared
-flower_objs = flower.o
+flower_objs = flower.o wayland-glib.o
pointer_objs = pointer.o
background_objs = background.o
window_objs = window.o gears.o
background : CFLAGS += $(shell pkg-config --cflags gdk-pixbuf-2.0)
background : LDLIBS += $(shell pkg-config --libs gdk-pixbuf-2.0)
+flower : CFLAGS += $(shell pkg-config --cflags glib-2.0)
+flower : LDLIBS += $(shell pkg-config --libs glib-2.0)
+
window : CFLAGS += $(EAGLE_CFLAGS)
window : LDLIBS += $(EAGLE_LDLIBS)
}
static int
-connection_update(struct wl_connection *connection,
- uint32_t mask, void *data)
+connection_update(uint32_t mask, void *data)
{
struct pollfd *p = data;
p->events = 0;
- if (mask & WL_CONNECTION_READABLE)
+ if (mask & WL_DISPLAY_READABLE)
p->events |= POLLIN;
- if (mask & WL_CONNECTION_WRITABLE)
+ if (mask & WL_DISPLAY_WRITABLE)
p->events |= POLLOUT;
return 0;
return -1;
}
- display = wl_display_create(socket_name,
- connection_update, &p[0]);
+ display = wl_display_create(socket_name);
if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n");
return -1;
}
- p[0].fd = wl_display_get_fd(display);
+ p[0].fd = wl_display_get_fd(display,
+ connection_update, &p[0]);
surface = wl_display_create_surface(display);
poll(p, 1, -1);
mask = 0;
if (p[0].revents & POLLIN)
- mask |= WL_CONNECTION_READABLE;
+ mask |= WL_DISPLAY_READABLE;
if (p[0].revents & POLLOUT)
- mask |= WL_CONNECTION_WRITABLE;
+ mask |= WL_DISPLAY_WRITABLE;
wl_display_iterate(display, mask);
}
#include <math.h>
#include <time.h>
#include <cairo.h>
+#include <glib.h>
#include "wayland-client.h"
+#include "wayland-glib.h"
static const char gem_device[] = "/dev/dri/card0";
static const char socket_name[] = "\0wayland";
return surface;
}
-static int
-connection_update(struct wl_connection *connection,
- uint32_t mask, void *data)
+struct flower {
+ struct wl_surface *surface;
+ int i;
+ int x, y, width, height;
+};
+
+static gboolean
+move_flower(gpointer data)
{
- struct pollfd *p = data;
+ struct flower *flower = data;
- p->events = 0;
- if (mask & WL_CONNECTION_READABLE)
- p->events |= POLLIN;
- if (mask & WL_CONNECTION_WRITABLE)
- p->events |= POLLOUT;
+ wl_surface_map(flower->surface,
+ flower->x + cos(flower->i / 31.0) * 400 - flower->width / 2,
+ flower->y + sin(flower->i / 27.0) * 300 - flower->height / 2,
+ flower->width, flower->height);
+ flower->i++;
- return 0;
+ return TRUE;
}
int main(int argc, char *argv[])
{
struct wl_display *display;
- struct wl_surface *surface;
- const int x = 512, y = 384, width = 200, height = 200;
- int fd, i, ret;
- uint32_t name, mask;
+ int fd;
+ uint32_t name;
cairo_surface_t *s;
- struct pollfd p[2];
struct timespec ts;
- struct itimerspec its;
- uint64_t expires;
+ GMainLoop *loop;
+ GSource *source;
+ struct flower flower;
fd = open(gem_device, O_RDWR);
if (fd < 0) {
return -1;
}
- display = wl_display_create(socket_name,
- connection_update, &p[0]);
+ loop = g_main_loop_new(NULL, FALSE);
+
+ display = wl_display_create(socket_name);
if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n");
return -1;
}
- p[0].fd = wl_display_get_fd(display);
- surface = wl_display_create_surface(display);
+ source = wayland_source_new(display);
+ g_source_attach(source, NULL);
- p[1].fd = timerfd_create(CLOCK_MONOTONIC, 0);
- if (p[1].fd < 0) {
- fprintf(stderr, "could not create timerfd\n: %m");
- return -1;
- }
+ flower.x = 512;
+ flower.y = 384;
+ flower.width = 200;
+ flower.height = 200;
+ flower.surface = wl_display_create_surface(display);
- p[1].events = POLLIN;
clock_gettime(CLOCK_MONOTONIC, &ts);
- its.it_value = ts;
- its.it_interval.tv_sec = 0;
- its.it_interval.tv_nsec = 20 * 1000000;
- if (timerfd_settime(p[1].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
- fprintf(stderr, "could not set timerfd\n: %m");
- return -1;
- }
-
srandom(ts.tv_nsec);
+ flower.i = ts.tv_nsec;
- s = draw_stuff(width, height);
+ s = draw_stuff(flower.width, flower.height);
name = name_cairo_surface(fd, s);
- wl_surface_attach(surface, name, width, height,
+ wl_surface_attach(flower.surface, name, flower.width, flower.height,
cairo_image_surface_get_stride(s));
- i = ts.tv_nsec;
- while (ret = poll(p, 2, -1), ret >= 0) {
- if (p[1].revents & POLLIN) {
- read(p[1].fd, &expires, sizeof expires);
- wl_surface_map(surface,
- x + cos(i / 31.0) * 400 - width / 2,
- y + sin(i / 27.0) * 300 - height / 2,
- width, height);
- i++;
- continue;
- }
-
- mask = 0;
- if (p[0].revents & POLLIN)
- mask |= WL_CONNECTION_READABLE;
- if (p[0].revents & POLLOUT)
- mask |= WL_CONNECTION_WRITABLE;
- if (mask)
- wl_display_iterate(display, mask);
- }
+ g_timeout_add(20, move_flower, &flower);
+
+ g_main_loop_run(loop);
return 0;
}
}
static int
-connection_update(struct wl_connection *connection,
- uint32_t mask, void *data)
+connection_update(uint32_t mask, void *data)
{
struct pollfd *p = data;
p->events = 0;
- if (mask & WL_CONNECTION_READABLE)
+ if (mask & WL_DISPLAY_READABLE)
p->events |= POLLIN;
- if (mask & WL_CONNECTION_WRITABLE)
+ if (mask & WL_DISPLAY_WRITABLE)
p->events |= POLLOUT;
return 0;
return -1;
}
- display = wl_display_create(socket_name,
- connection_update, &p[0]);
+ display = wl_display_create(socket_name);
if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n");
return -1;
}
- p[0].fd = wl_display_get_fd(display);
+ p[0].fd = wl_display_get_fd(display, connection_update, &p[0]);
pointer.width = 16;
pointer.height = 16;
poll(p, 1, -1);
mask = 0;
if (p[0].revents & POLLIN)
- mask |= WL_CONNECTION_READABLE;
+ mask |= WL_DISPLAY_READABLE;
if (p[0].revents & POLLOUT)
- mask |= WL_CONNECTION_WRITABLE;
+ mask |= WL_DISPLAY_WRITABLE;
wl_display_iterate(display, mask);
}
struct wl_connection *connection;
int fd;
uint32_t id;
+ uint32_t mask;
+
+ wl_display_update_func_t update;
+ void *update_data;
wl_display_event_func_t event_handler;
void *event_handler_data;
struct wl_proxy proxy;
};
+static int
+connection_update(struct wl_connection *connection,
+ uint32_t mask, void *data)
+{
+ struct wl_display *display = data;
+
+ display->mask = mask;
+ if (display->update)
+ return display->update(display->mask,
+ display->update_data);
+
+ return 0;
+}
+
struct wl_display *
-wl_display_create(const char *address,
- wl_connection_update_func_t update, void *data)
+wl_display_create(const char *address)
{
struct wl_display *display;
struct sockaddr_un name;
display->proxy.id = id;
display->connection = wl_connection_create(display->fd,
- update, data);
+ connection_update,
+ display);
return display;
}
}
int
-wl_display_get_fd(struct wl_display *display)
+wl_display_get_fd(struct wl_display *display,
+ wl_display_update_func_t update, void *data)
{
+ display->update = update;
+ display->update_data = data;
+
+ display->update(display->mask, display->update_data);
+
return display->fd;
}
#ifndef _WAYLAND_CLIENT_H
#define _WAYLAND_CLIENT_H
-#include "connection.h"
-
struct wl_display;
struct wl_surface;
-struct wl_display *wl_display_create(const char *address,
- wl_connection_update_func_t update, void *data);
+#define WL_DISPLAY_READABLE 0x01
+#define WL_DISPLAY_WRITABLE 0x02
+
+typedef int (*wl_display_update_func_t)(uint32_t mask, void *data);
+
+struct wl_display *wl_display_create(const char *address);
void wl_display_destroy(struct wl_display *display);
-int wl_display_get_fd(struct wl_display *display);
+int wl_display_get_fd(struct wl_display *display,
+ wl_display_update_func_t update, void *data);
+
void wl_display_iterate(struct wl_display *display, uint32_t mask);
typedef void (*wl_display_event_func_t)(struct wl_display *display,
--- /dev/null
+#include <stdint.h>
+#include <glib/giochannel.h>
+#include "wayland-client.h"
+#include "wayland-glib.h"
+
+struct _WaylandSource {
+ GSource source;
+ GPollFD pfd;
+ uint32_t mask;
+ struct wl_display *display;
+};
+
+static gboolean
+wayland_source_prepare(GSource *base, gint *timeout)
+{
+ WaylandSource *source = (WaylandSource *) base;
+
+ *timeout = -1;
+
+ /* We have to add/remove the GPollFD if we want to update our
+ * poll event mask dynamically. Instead, let's just flush all
+ * write on idle instead, which is what this amounts to. */
+
+ while (source->mask & WL_DISPLAY_WRITABLE)
+ wl_display_iterate(source->display,
+ WL_DISPLAY_WRITABLE);
+
+ return FALSE;
+}
+
+static gboolean
+wayland_source_check(GSource *base)
+{
+ WaylandSource *source = (WaylandSource *) base;
+
+ return source->pfd.revents;
+}
+
+static gboolean
+wayland_source_dispatch(GSource *base,
+ GSourceFunc callback,
+ gpointer data)
+{
+ WaylandSource *source = (WaylandSource *) base;
+
+ wl_display_iterate(source->display,
+ WL_DISPLAY_READABLE | WL_DISPLAY_WRITABLE);
+
+ return TRUE;
+}
+
+static GSourceFuncs wayland_source_funcs = {
+ wayland_source_prepare,
+ wayland_source_check,
+ wayland_source_dispatch,
+ NULL
+};
+
+static int
+wayland_source_update(uint32_t mask, void *data)
+{
+ WaylandSource *source = data;
+
+ source->mask = mask;
+
+ return 0;
+}
+
+GSource *
+wayland_source_new(struct wl_display *display)
+{
+ WaylandSource *source;
+
+ source = (WaylandSource *) g_source_new(&wayland_source_funcs,
+ sizeof (WaylandSource));
+ source->display = display;
+ source->pfd.fd = wl_display_get_fd(display,
+ wayland_source_update, source);
+ source->pfd.events = G_IO_IN | G_IO_ERR;
+ g_source_add_poll(&source->source, &source->pfd);
+
+ return &source->source;
+}
--- /dev/null
+#ifndef _WAYLAND_GLIB_H_
+#define _WAYLAND_GLIB_H_
+
+#include <glib/gmain.h>
+
+typedef struct _WaylandSource WaylandSource;
+
+GSource *wayland_source_new(struct wl_display *display);
+
+#endif
}
static int
-connection_update(struct wl_connection *connection,
- uint32_t mask, void *data)
+connection_update(uint32_t mask, void *data)
{
struct pollfd *p = data;
p->events = 0;
- if (mask & WL_CONNECTION_READABLE)
+ if (mask & WL_DISPLAY_READABLE)
p->events |= POLLIN;
- if (mask & WL_CONNECTION_WRITABLE)
+ if (mask & WL_DISPLAY_WRITABLE)
p->events |= POLLOUT;
return 0;
return -1;
}
- display = wl_display_create(socket_name,
- connection_update, &p[0]);
+ display = wl_display_create(socket_name);
if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n");
return -1;
}
- p[0].fd = wl_display_get_fd(display);
+ p[0].fd = wl_display_get_fd(display,
+ connection_update, &p[0]);
window.surface = wl_display_create_surface(display);
window.x = 200;
window.width, window.height);
angle += 1;
if (p[0].revents & POLLIN)
- mask |= WL_CONNECTION_READABLE;
+ mask |= WL_DISPLAY_READABLE;
if (p[0].revents & POLLOUT)
- mask |= WL_CONNECTION_WRITABLE;
+ mask |= WL_DISPLAY_WRITABLE;
if (mask)
wl_display_iterate(display, mask);
if (window.need_redraw) {