include ../config.mk
+CFLAGS += -I.. $(CLIENT_CFLAGS)
+LDLIBS += -L.. -lwayland $(CLIENT_LIBS) -lrt -lm
+
egl_clients = gears
cairo_clients = flower screenshot terminal image view
view : view.o window.o wayland-glib.o
terminal : LDLIBS += -lutil
-image : CFLAGS += $(GDK_PIXBUF_CFLAGS)
-image : LDLIBS += $(GDK_PIXBUF_LIBS)
view : CFLAGS += $(POPPLER_CFLAGS)
view : LDLIBS += $(POPPLER_LIBS)
-
-$(egl_clients) : CFLAGS += $(EGL_CLIENT_CFLAGS)
-$(egl_clients) : LDLIBS += -L.. -lwayland $(EGL_CLIENT_LIBS) -lrt -lm
-$(cairo_clients) : CFLAGS += $(CAIRO_CLIENT_CFLAGS) $(EGL_CLIENT_CFLAGS)
-$(cairo_clients) : LDLIBS += -L.. -lwayland $(CAIRO_CLIENT_LIBS) $(EGL_CLIENT_LIBS) -lrt -lm
int main(int argc, char *argv[])
{
- struct wl_display *display;
- struct wl_visual *visual;
- int fd;
cairo_surface_t *s;
struct timespec ts;
struct flower flower;
struct window *window;
struct display *d;
- struct wl_compositor *compositor;
struct rectangle rectangle;
EGLDisplay display;
}
static void
-handle_acknowledge(void *data,
- struct wl_compositor *compositor,
- uint32_t key, uint32_t frame)
+acknowledge_handler(struct window *window,
+ uint32_t key, uint32_t frame,
+ void *data)
{
struct gears *gears = data;
}
static void
-handle_frame(void *data,
- struct wl_compositor *compositor,
- uint32_t frame, uint32_t timestamp)
+frame_handler(struct window *window,
+ uint32_t frame, uint32_t timestamp, void *data)
{
struct gears *gears = data;
gears->angle = (GLfloat) (timestamp % 8192) * 360 / 8192.0;
}
-static const struct wl_compositor_listener compositor_listener = {
- handle_acknowledge,
- handle_frame,
-};
-
static struct gears *
gears_create(struct display *display)
{
if (glCheckFramebufferStatus (GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE)
fprintf(stderr, "framebuffer incomplete\n");
- gears->compositor = display_get_compositor(display);
-
resize_window(gears);
draw_gears(gears);
- handle_frame(gears, gears->compositor, 0, 0);
+ frame_handler(gears->window, 0, 0, gears);
window_set_resize_handler(gears->window, resize_handler, gears);
window_set_keyboard_focus_handler(gears->window, keyboard_focus_handler, gears);
-
- wl_compositor_add_listener(gears->compositor,
- &compositor_listener, gears);
+ window_set_acknowledge_handler(gears->window, acknowledge_handler, gears);
+ window_set_frame_handler(gears->window, frame_handler, gears);
return gears;
}
struct image {
struct window *window;
struct display *display;
- struct wl_compositor *compositor;
uint32_t key;
gboolean redraw_scheduled;
}
static void
-handle_acknowledge(void *data,
- struct wl_compositor *compositor,
- uint32_t key, uint32_t frame)
+acknowledge_handler(struct window *window,
+ uint32_t key, uint32_t frame, void *data)
{
struct image *image = data;
}
}
-static void
-handle_frame(void *data,
- struct wl_compositor *compositor,
- uint32_t frame, uint32_t timestamp)
-{
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- handle_acknowledge,
- handle_frame,
-};
-
static struct image *
image_create(struct display *display, uint32_t key, const char *filename)
{
image->key = key + 100;
image->redraw_scheduled = 1;
- image->compositor = display_get_compositor(display);
window_set_resize_handler(image->window, resize_handler, image);
window_set_keyboard_focus_handler(image->window, keyboard_focus_handler, image);
-
- wl_compositor_add_listener(image->compositor, &compositor_listener, image);
+ window_set_acknowledge_handler(image->window, acknowledge_handler, image);
image_draw(image);
struct terminal {
struct window *window;
struct display *display;
- struct wl_compositor *compositor;
int redraw_scheduled, redraw_pending;
char *data;
int width, height, start, row, column;
}
static void
-handle_acknowledge(void *data,
- struct wl_compositor *compositor,
- uint32_t key, uint32_t frame)
+acknowledge_handler(struct window *window,
+ uint32_t key, uint32_t frame, void *data)
{
struct terminal *terminal = data;
}
static void
-handle_frame(void *data,
- struct wl_compositor *compositor,
- uint32_t frame, uint32_t timestamp)
-{
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- handle_acknowledge,
- handle_frame,
-};
-
-static void
key_handler(struct window *window, uint32_t key, uint32_t unicode,
uint32_t state, uint32_t modifiers, void *data)
{
terminal->redraw_scheduled = 1;
terminal->margin = 5;
- terminal->compositor = display_get_compositor(display);
window_set_fullscreen(terminal->window, terminal->fullscreen);
window_set_resize_handler(terminal->window, resize_handler, terminal);
-
- wl_compositor_add_listener(terminal->compositor,
- &compositor_listener, terminal);
+ window_set_acknowledge_handler(terminal->window, acknowledge_handler, terminal);
window_set_key_handler(terminal->window, key_handler, terminal);
window_set_keyboard_focus_handler(terminal->window,
struct view {
struct window *window;
struct display *display;
- struct wl_compositor *compositor;
uint32_t key;
gboolean redraw_scheduled;
&rectangle,
view->surface);
- wl_compositor_commit(view->compositor, view->key);
+ window_commit(view->window, 0);
}
static gboolean
}
static void
-handle_acknowledge(void *data,
- struct wl_compositor *compositor,
- uint32_t key, uint32_t frame)
+acknowledge_handler(struct window *window,
+ uint32_t key, uint32_t frame, void *data)
{
struct view *view = data;
view_schedule_redraw(view);
}
-static void
-handle_frame(void *data,
- struct wl_compositor *compositor,
- uint32_t frame, uint32_t timestamp)
-{
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- handle_acknowledge,
- handle_frame,
-};
-
static struct view *
view_create(struct display *display, uint32_t key, const char *filename)
{
view->key = key + 100;
view->redraw_scheduled = 1;
- view->compositor = display_get_compositor(display);
window_set_resize_handler(view->window, resize_handler, view);
window_set_key_handler(view->window, key_handler, view);
window_set_keyboard_focus_handler(view->window,
keyboard_focus_handler, view);
-
- wl_compositor_add_listener(view->compositor,
- &compositor_listener, view);
+ window_set_acknowledge_handler(view->window, acknowledge_handler, view);
view->document = poppler_document_new_from_file(view->filename,
NULL, &error);
#include <time.h>
#include <cairo.h>
#include <glib.h>
+#include <glib-object.h>
#define EGL_EGLEXT_PROTOTYPES 1
#define GL_GLEXT_PROTOTYPES 1
int fd;
GMainLoop *loop;
GSource *source;
+ struct wl_list window_list;
+ char *device_name;
};
struct window {
window_resize_handler_t resize_handler;
window_key_handler_t key_handler;
window_keyboard_focus_handler_t keyboard_focus_handler;
+ window_acknowledge_handler_t acknowledge_handler;
window_frame_handler_t frame_handler;
void *user_data;
+ struct wl_list link;
};
static void
return window->cairo_surface;
}
-static void
-window_handle_acknowledge(void *data,
- struct wl_compositor *compositor,
- uint32_t key, uint32_t frame)
-{
- struct window *window = data;
- cairo_surface_t *pending;
-
- /* The acknowledge event means that the server
- * processed our last commit request and we can now
- * safely free the old window buffer if we resized and
- * render the next frame into our back buffer.. */
-
- pending = window->pending_surface;
- window->pending_surface = NULL;
- if (pending != window->cairo_surface)
- window_attach_surface(window);
- cairo_surface_destroy(pending);
-}
-
-static void
-window_handle_frame(void *data,
- struct wl_compositor *compositor,
- uint32_t frame, uint32_t timestamp)
-{
- struct window *window = data;
-
- if (window->frame_handler)
- (*window->frame_handler)(window, frame, timestamp, window->user_data);
-}
-
-static const struct wl_compositor_listener compositor_listener = {
- window_handle_acknowledge,
- window_handle_frame,
-};
-
enum window_state {
WINDOW_STABLE,
WINDOW_MOVING,
}
void
+window_set_acknowledge_handler(struct window *window,
+ window_acknowledge_handler_t handler, void *data)
+{
+ window->acknowledge_handler = handler;
+ window->user_data = data;
+}
+
+void
window_set_frame_handler(struct window *window,
window_frame_handler_t handler, void *data)
{
window->state = WINDOW_STABLE;
window->decoration = 1;
- wl_compositor_add_listener(display->compositor,
- &compositor_listener, window);
+ wl_list_insert(display->window_list.prev, &window->link);
wl_input_device_add_listener(display->input_device,
&input_device_listener, window);
}
static void
+display_handle_device(void *data,
+ struct wl_compositor *compositor,
+ const char *device)
+{
+ struct display *d = data;
+
+ d->device_name = strdup(device);
+}
+
+static void
+display_handle_acknowledge(void *data,
+ struct wl_compositor *compositor,
+ uint32_t key, uint32_t frame)
+{
+ struct display *d = data;
+ struct window *window;
+ cairo_surface_t *pending;
+
+ /* The acknowledge event means that the server processed our
+ * last commit request and we can now safely free the old
+ * window buffer if we resized and render the next frame into
+ * our back buffer.. */
+ wl_list_for_each(window, &d->window_list, link) {
+ pending = window->pending_surface;
+ window->pending_surface = NULL;
+ if (pending != window->cairo_surface)
+ window_attach_surface(window);
+ cairo_surface_destroy(pending);
+ if (window->acknowledge_handler)
+ (*window->acknowledge_handler)(window, key, frame, window->user_data);
+ }
+}
+
+static void
+display_handle_frame(void *data,
+ struct wl_compositor *compositor,
+ uint32_t frame, uint32_t timestamp)
+{
+ struct display *d = data;
+ struct window *window;
+
+ wl_list_for_each(window, &d->window_list, link) {
+ if (window->frame_handler)
+ (*window->frame_handler)(window, frame,
+ timestamp, window->user_data);
+ }
+}
+
+static const struct wl_compositor_listener compositor_listener = {
+ display_handle_device,
+ display_handle_acknowledge,
+ display_handle_frame,
+};
+
+static void
display_handle_geometry(void *data,
struct wl_output *output,
int32_t width, int32_t height)
if (wl_object_implements(object, "compositor", 1)) {
d->compositor = (struct wl_compositor *) object;
+ wl_compositor_add_listener(d->compositor, &compositor_listener, d);
} else if (wl_object_implements(object, "output", 1)) {
d->output = (struct wl_output *) object;
wl_output_add_listener(d->output, &output_listener, d);
}
}
-static const char gem_device[] = "/dev/dri/card0";
static const char socket_name[] = "\0wayland";
struct display *
struct display *d;
EGLint major, minor, count;
EGLConfig config;
- struct wl_display *display;
int fd;
GOptionContext *context;
GError *error;
EGL_NONE
};
+ g_type_init();
+
context = g_option_context_new(NULL);
if (option_entries) {
g_option_context_add_main_entries(context, option_entries, "Wayland View");
if (d == NULL)
return NULL;
- fd = open(gem_device, O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "drm open failed: %m\n");
+ d->display = wl_display_create(socket_name, sizeof socket_name);
+ if (d->display == NULL) {
+ fprintf(stderr, "failed to create display: %m\n");
return NULL;
}
- display = wl_display_create(socket_name, sizeof socket_name);
- if (display == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
+ /* Set up listener so we'll catch all events. */
+ wl_display_add_global_listener(d->display,
+ display_handle_global, d);
+
+ /* Process connection events. */
+ wl_display_iterate(d->display, WL_DISPLAY_READABLE);
+
+ fd = open(d->device_name, O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "drm open failed: %m\n");
return NULL;
}
return NULL;
}
- d->display = display;
d->device = cairo_egl_device_create(d->dpy, d->ctx);
if (d->device == NULL) {
fprintf(stderr, "failed to get cairo drm device\n");
return NULL;
}
- /* Set up listener so we'll catch all events. */
- wl_display_add_global_listener(display,
- display_handle_global, d);
-
- /* Process connection events. */
- wl_display_iterate(display, WL_DISPLAY_READABLE);
-
d->loop = g_main_loop_new(NULL, FALSE);
- d->source = wl_glib_source_new(display);
+ d->source = wl_glib_source_new(d->display);
g_source_attach(d->source, NULL);
+ wl_list_init(&d->window_list);
+
return d;
}
typedef void (*window_resize_handler_t)(struct window *window, void *data);
typedef void (*window_frame_handler_t)(struct window *window, uint32_t frame, uint32_t timestamp, void *data);
-typedef void (*window_acknowledge_handler_t)(struct window *window, uint32_t key, void *data);
+typedef void (*window_acknowledge_handler_t)(struct window *window, uint32_t key, uint32_t frame, void *data);
typedef void (*window_key_handler_t)(struct window *window, uint32_t key, uint32_t unicode,
uint32_t state, uint32_t modifiers, void *data);
typedef void (*window_keyboard_focus_handler_t)(struct window *window,
void *data);
void
+window_set_acknowledge_handler(struct window *window,
+ window_acknowledge_handler_t handler, void *data);
+
+void
window_set_frame_handler(struct window *window,
window_frame_handler_t handler, void *data);
return -1;
}
- ec->drm_fd = open(udev_device_get_devnode(device), O_RDWR);
+ ec->base.device = strdup(udev_device_get_devnode(device));
+ ec->drm_fd = open(ec->base.device, O_RDWR);
if (ec->drm_fd < 0) {
/* Probably permissions error */
fprintf(stderr, "couldn't open %s, skipping\n",
FFI_CFLAGS = @FFI_CFLAGS@
FFI_LIBS = @FFI_LIBS@
-EGL_CLIENT_CFLAGS = @EGL_CLIENT_CFLAGS@
-EGL_CLIENT_LIBS = @EGL_CLIENT_LIBS@
-
-CAIRO_CLIENT_CFLAGS = @CAIRO_CLIENT_CFLAGS@
-CAIRO_CLIENT_LIBS = @CAIRO_CLIENT_LIBS@
-
-GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
-GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
+CLIENT_CFLAGS = @CLIENT_CFLAGS@
+CLIENT_LIBS = @CLIENT_LIBS@
POPPLER_CFLAGS = @POPPLER_CFLAGS@
POPPLER_LIBS = @POPPLER_LIBS@
PKG_CHECK_MODULES(COMPOSITOR,
[egl gl libpng cairo gdk-pixbuf-2.0 libudev >= 136 libdrm >= 2.4.17])
-PKG_CHECK_MODULES(EGL_CLIENT, [egl gl cairo glib-2.0 libudev])
-PKG_CHECK_MODULES(CAIRO_CLIENT, [cairo-gl glib-2.0])
-PKG_CHECK_MODULES(GDK_PIXBUF, [gdk-pixbuf-2.0])
+PKG_CHECK_MODULES(CLIENT, [egl gl cairo-gl gdk-pixbuf-2.0 glib-2.0 gobject-2.0])
PKG_CHECK_MODULES(POPPLER, [poppler-glib gdk-2.0])
if test $CC = gcc; then
wl_display_get_rgb_visual(struct wl_display *display);
struct wl_compositor_listener {
+ void (*device)(void *data,
+ struct wl_compositor *compositor,
+ const char *device);
void (*acknowledge)(void *data,
struct wl_compositor *compositor,
uint32_t key, uint32_t frame);
};
static const struct wl_message compositor_events[] = {
+ { "device", "s" },
{ "acknowledge", "uu" },
{ "frame", "uu" }
};
#define WL_COMPOSITOR_CREATE_SURFACE 0
#define WL_COMPOSITOR_COMMIT 1
-#define WL_COMPOSITOR_ACKNOWLEDGE 0
-#define WL_COMPOSITOR_FRAME 1
+#define WL_COMPOSITOR_DEVICE 0
+#define WL_COMPOSITOR_ACKNOWLEDGE 1
+#define WL_COMPOSITOR_FRAME 2
extern const struct wl_interface wl_compositor_interface;
#define WL_SURFACE_DESTROY 0
#define WL_SURFACE_ATTACH 1
#define WL_SURFACE_MAP 2
-#define WL_SURFACE_COPY 3
-#define WL_SURFACE_DAMAGE 4
+#define WL_SURFACE_DAMAGE 3
extern const struct wl_interface wl_surface_interface;
WL_COMPOSITOR_ACKNOWLEDGE, key, frame);
}
+static void
+post_compositor_device(struct wl_client *client, struct wl_object *global)
+{
+ struct wl_compositor *compositor =
+ container_of(global, struct wl_compositor, base);
+
+ wl_client_post_event(client, global,
+ WL_COMPOSITOR_DEVICE, compositor->device);
+}
+
WL_EXPORT int
wl_display_set_compositor(struct wl_display *display,
struct wl_compositor *compositor,
compositor->base.implementation = (void (**)(void)) implementation;
wl_display_add_object(display, &compositor->base);
- if (wl_display_add_global(display, &compositor->base, NULL))
+ if (wl_display_add_global(display, &compositor->base, post_compositor_device))
return -1;
return 0;
struct wl_compositor {
struct wl_object base;
+ const char *device;
};
struct wl_surface {