wayland.o \
event-loop.o \
connection.o \
- wayland-util.o
+ wayland-util.o \
+ wayland-protocol.o
libwayland-server.so : CFLAGS += @FFI_CFLAGS@
libwayland-server.so : LDLIBS += @FFI_LIBS@ -ldl -rdynamic
libwayland.so : \
wayland-client.o \
connection.o \
- wayland-util.o
+ wayland-util.o \
+ wayland-protocol.o
$(libs) : CFLAGS += -fPIC
$(libs) :
#include <errno.h>
#include <sys/uio.h>
+#include "wayland-util.h"
#include "connection.h"
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
+#include <stdarg.h>
+
struct wl_connection;
#define WL_CONNECTION_READABLE 0x01
void wl_connection_consume(struct wl_connection *connection, size_t size);
int wl_connection_data(struct wl_connection *connection, uint32_t mask);
void wl_connection_write(struct wl_connection *connection, const void *data, size_t count);
+void wl_connection_vmarshal(struct wl_connection *connection, uint32_t id,
+ uint32_t opcode, const char *signature, va_list ap);
#endif
#include <sys/socket.h>
#include <sys/un.h>
#include <ctype.h>
+#include <assert.h>
#include <sys/poll.h>
+#include "wayland-protocol.h"
#include "connection.h"
#include "wayland-util.h"
#include "wayland-client.h"
};
struct wl_proxy {
- struct wl_display *display;
+ const struct wl_interface *interface;
uint32_t id;
+ struct wl_display *display;
};
struct wl_display {
wl_list_init(&display->global_list);
wl_list_init(&display->visual_list);
- display->proxy.display = display;
+ display->proxy.interface = &wl_display_interface;
display->proxy.id = wl_display_get_object_id(display, "display");
+ display->proxy.display = display;
display->connection = wl_connection_create(display->fd,
connection_update,
return display->fd;
}
-#define WL_DISPLAY_INVALID_OBJECT 0
-#define WL_DISPLAY_INVALID_METHOD 1
-#define WL_DISPLAY_NO_MEMORY 2
-#define WL_DISPLAY_GLOBAL 3
-
static void
handle_global(struct wl_display *display, uint32_t *p, uint32_t size)
{
return NULL;
compositor = malloc(sizeof *compositor);
- compositor->proxy.display = display;
+ compositor->proxy.interface = &wl_compositor_interface;
compositor->proxy.id = id;
+ compositor->proxy.display = display;
return compositor;
}
-#define WL_COMPOSITOR_CREATE_SURFACE 0
-#define WL_COMPOSITOR_COMMIT 1
+static void
+wl_proxy_vmarshal(struct wl_proxy *target, uint32_t opcode, va_list ap)
+{
+ struct wl_proxy *proxy;
+ uint32_t args[32], length, *p, size;
+ const char *s, *signature;
+ int i, count;
+
+ signature = target->interface->methods[opcode].signature;
+ count = strlen(signature);
+ /* FIXME: Make sure we don't overwrite args array. */
+
+ p = &args[2];
+ for (i = 0; i < count; i++) {
+ switch (signature[i]) {
+ case 'u':
+ case 'i':
+ *p++ = va_arg(ap, uint32_t);
+ break;
+ case 's':
+ s = va_arg(ap, const char *);
+ length = strlen(s);
+ *p++ = length;
+ memcpy(p, s, length);
+ p += DIV_ROUNDUP(length, sizeof(*p));
+ break;
+ case 'n':
+ case 'o':
+ proxy = va_arg(ap, struct wl_proxy *);
+ *p++ = proxy->id;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ size = (p - args) * sizeof *p;
+ args[0] = target->id;
+ args[1] = opcode | (size << 16);
+ wl_connection_write(target->display->connection, args, size);
+}
+
+static void
+wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
+{
+ va_list ap;
+
+ va_start(ap, opcode);
+ wl_proxy_vmarshal(proxy, opcode, ap);
+ va_end(ap);
+}
WL_EXPORT struct wl_surface *
wl_compositor_create_surface(struct wl_compositor *compositor)
{
struct wl_surface *surface;
- uint32_t request[3];
surface = malloc(sizeof *surface);
if (surface == NULL)
return NULL;
+ surface->proxy.interface = &wl_surface_interface;
surface->proxy.id = wl_display_allocate_id(compositor->proxy.display);
surface->proxy.display = compositor->proxy.display;
-
- request[0] = compositor->proxy.id;
- request[1] = WL_COMPOSITOR_CREATE_SURFACE | ((sizeof request) << 16);
- request[2] = surface->proxy.id;
- wl_connection_write(compositor->proxy.display->connection,
- request, sizeof request);
+ wl_proxy_marshal(&compositor->proxy,
+ WL_COMPOSITOR_CREATE_SURFACE, surface);
return surface;
}
WL_EXPORT void
wl_compositor_commit(struct wl_compositor *compositor, uint32_t key)
{
- uint32_t request[3];
-
- request[0] = compositor->proxy.id;
- request[1] = WL_COMPOSITOR_COMMIT | ((sizeof request) << 16);
- request[2] = key;
- wl_connection_write(compositor->proxy.display->connection,
- request, sizeof request);
+ wl_proxy_marshal(&compositor->proxy, WL_COMPOSITOR_COMMIT, key);
}
-#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
-
WL_EXPORT void
wl_surface_destroy(struct wl_surface *surface)
{
- uint32_t request[2];
-
- request[0] = surface->proxy.id;
- request[1] = WL_SURFACE_DESTROY | ((sizeof request) << 16);
-
- wl_connection_write(surface->proxy.display->connection,
- request, sizeof request);
+ wl_proxy_marshal(&surface->proxy, WL_SURFACE_DESTROY);
}
WL_EXPORT void
int32_t width, int32_t height, uint32_t stride,
struct wl_visual *visual)
{
- uint32_t request[7];
-
- request[0] = surface->proxy.id;
- request[1] = WL_SURFACE_ATTACH | ((sizeof request) << 16);
- request[2] = name;
- request[3] = width;
- request[4] = height;
- request[5] = stride;
- request[6] = visual->proxy.id;
-
- wl_connection_write(surface->proxy.display->connection,
- request, sizeof request);
+ wl_proxy_marshal(&surface->proxy, WL_SURFACE_ATTACH,
+ name, width, height, stride, visual);
}
WL_EXPORT void
wl_surface_map(struct wl_surface *surface,
int32_t x, int32_t y, int32_t width, int32_t height)
{
- uint32_t request[6];
-
- request[0] = surface->proxy.id;
- request[1] = WL_SURFACE_MAP | ((sizeof request) << 16);
- request[2] = x;
- request[3] = y;
- request[4] = width;
- request[5] = height;
-
- wl_connection_write(surface->proxy.display->connection,
- request, sizeof request);
+ wl_proxy_marshal(&surface->proxy,
+ WL_SURFACE_MAP, x, y, width, height);
}
WL_EXPORT void
uint32_t name, uint32_t stride,
int32_t x, int32_t y, int32_t width, int32_t height)
{
- uint32_t request[10];
-
- request[0] = surface->proxy.id;
- request[1] = WL_SURFACE_COPY | ((sizeof request) << 16);
- request[2] = dst_x;
- request[3] = dst_y;
- request[4] = name;
- request[5] = stride;
- request[6] = x;
- request[7] = y;
- request[8] = width;
- request[9] = height;
-
- wl_connection_write(surface->proxy.display->connection,
- request, sizeof request);
+ wl_proxy_marshal(&surface->proxy, WL_SURFACE_COPY,
+ dst_x, dst_y, name, stride, x, y, width, height);
}
WL_EXPORT void
wl_surface_damage(struct wl_surface *surface,
int32_t x, int32_t y, int32_t width, int32_t height)
{
- uint32_t request[6];
-
- request[0] = surface->proxy.id;
- request[1] = WL_SURFACE_DAMAGE | ((sizeof request) << 16);
- request[2] = x;
- request[3] = y;
- request[4] = width;
- request[5] = height;
-
- wl_connection_write(surface->proxy.display->connection,
- request, sizeof request);
+ wl_proxy_marshal(&surface->proxy,
+ WL_SURFACE_DAMAGE, x, y, width, height);
}
--- /dev/null
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+#include "wayland-protocol.h"
+
+static const struct wl_event display_events[] = {
+ { "invalid_object", "u" },
+ { "invalid_method", "uu" },
+ { "no_memory", "" },
+ { "global", "osu" },
+};
+
+WL_EXPORT const struct wl_interface wl_display_interface = {
+ "display", 1,
+ 0, NULL,
+ ARRAY_LENGTH(display_events), display_events,
+};
+
+
+static const struct wl_method compositor_methods[] = {
+ { "create_surface", "n" },
+ { "commit", "u" }
+};
+
+static const struct wl_event compositor_events[] = {
+ { "acknowledge", "uu" },
+ { "frame", "uu" }
+};
+
+WL_EXPORT const struct wl_interface wl_compositor_interface = {
+ "compositor", 1,
+ ARRAY_LENGTH(compositor_methods), compositor_methods,
+ ARRAY_LENGTH(compositor_events), compositor_events,
+};
+
+
+static const struct wl_method surface_methods[] = {
+ { "destroy", "" },
+ { "attach", "uuuuo" },
+ { "map", "iiii" },
+ { "copy", "iiuuiiii" },
+ { "damage", "iiii" }
+};
+
+WL_EXPORT const struct wl_interface wl_surface_interface = {
+ "surface", 1,
+ ARRAY_LENGTH(surface_methods), surface_methods,
+ 0, NULL,
+};
+
+
+static const struct wl_event input_device_events[] = {
+ { "motion", "iiii" },
+ { "button", "uuiiii" },
+ { "key", "uu" },
+};
+
+WL_EXPORT const struct wl_interface wl_input_device_interface = {
+ "input_device", 1,
+ 0, NULL,
+ ARRAY_LENGTH(input_device_events), input_device_events,
+};
--- /dev/null
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef WAYLAND_PROTOCOL_H
+#define WAYLAND_PROTOCOL_H
+
+#include <stdint.h>
+
+struct wl_argument {
+ uint32_t type;
+ void *data;
+};
+
+struct wl_method {
+ const char *name;
+ const char *signature;
+ const void **types;
+};
+
+struct wl_event {
+ const char *name;
+ const char *signature;
+};
+
+struct wl_interface {
+ const char *name;
+ int version;
+ int method_count;
+ const struct wl_method *methods;
+ int event_count;
+ const struct wl_event *events;
+};
+
+#define WL_DISPLAY_INVALID_OBJECT 0
+#define WL_DISPLAY_INVALID_METHOD 1
+#define WL_DISPLAY_NO_MEMORY 2
+#define WL_DISPLAY_GLOBAL 3
+
+extern const struct wl_interface wl_display_interface;
+
+
+#define WL_COMPOSITOR_CREATE_SURFACE 0
+#define WL_COMPOSITOR_COMMIT 1
+
+#define WL_COMPOSITOR_ACKNOWLEDGE 0
+#define WL_COMPOSITOR_FRAME 1
+
+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
+
+extern const struct wl_interface wl_surface_interface;
+
+
+#define WL_INPUT_MOTION 0
+#define WL_INPUT_BUTTON 1
+#define WL_INPUT_KEY 2
+
+extern const struct wl_interface wl_input_device_interface;
+
+#endif
#include <eagle.h>
#include "wayland.h"
+#include "wayland-protocol.h"
#include "cairo-util.h"
#include "wayland-system-compositor.h"
return;
memset(device, 0, sizeof *device);
- device->base.interface = wl_input_device_get_interface();
+ device->base.interface = &wl_input_device_interface;
wl_display_add_object(ec->wl_display, &device->base);
device->x = 100;
device->y = 100;
- device->pointer_surface = pointer_create(ec,
- device->x, device->y, 64, 64);
+ device->pointer_surface =
+ pointer_create(ec, device->x, device->y, 64, 64);
device->ec = ec;
dir = opendir(by_path_dir);
wl_event_loop_add_signal(loop, SIGUSR1, on_leave_vt, ec);
ec->enter_vt_source =
wl_event_loop_add_signal(loop, SIGUSR2, on_enter_vt, ec);
+
+ return 0;
}
static struct egl_compositor *
#include <assert.h>
#include <ffi.h>
+#include "wayland-protocol.h"
#include "wayland.h"
#include "connection.h"
ffi_call(&cif, func, &result, args);
}
-#define WL_DISPLAY_INVALID_OBJECT 0
-#define WL_DISPLAY_INVALID_METHOD 1
-#define WL_DISPLAY_NO_MEMORY 2
-#define WL_DISPLAY_GLOBAL 3
-
static void
wl_client_connection_data(int fd, uint32_t mask, void *data)
{
free(client);
}
-static const struct wl_method surface_methods[] = {
- { "destroy", "" },
- { "attach", "uuuuo" },
- { "map", "iiii" },
- { "copy", "iiuuiiii" },
- { "damage", "iiii" }
-};
-
-static const struct wl_interface surface_interface = {
- "surface", 1,
- ARRAY_LENGTH(surface_methods),
- surface_methods,
-};
-
WL_EXPORT int
wl_client_add_surface(struct wl_client *client,
struct wl_surface *surface,
struct wl_object_ref *ref;
surface->base.id = id;
- surface->base.interface = &surface_interface;
+ surface->base.interface = &wl_surface_interface;
surface->base.implementation = (void (**)(void)) implementation;
surface->client = client;
return 0;
}
-#define WL_COMPOSITOR_ACKNOWLEDGE 0
-#define WL_COMPOSITOR_FRAME 1
-
WL_EXPORT void
wl_client_send_acknowledge(struct wl_client *client,
struct wl_compositor *compositor,
WL_COMPOSITOR_ACKNOWLEDGE, key, frame);
}
-static const struct wl_method compositor_methods[] = {
- { "create_surface", "n" },
- { "commit", "u" }
-};
-
-static const struct wl_event compositor_events[] = {
- { "acknowledge", "uu" },
- { "frame", "uu" }
-};
-
-static const struct wl_interface compositor_interface = {
- "compositor", 1,
- ARRAY_LENGTH(compositor_methods), compositor_methods,
- ARRAY_LENGTH(compositor_events), compositor_events,
-};
-
WL_EXPORT int
wl_display_set_compositor(struct wl_display *display,
struct wl_compositor *compositor,
const struct wl_compositor_interface *implementation)
{
- compositor->base.interface = &compositor_interface;
+ compositor->base.interface = &wl_compositor_interface;
compositor->base.implementation = (void (**)(void)) implementation;
wl_display_add_object(display, &compositor->base);
return 0;
}
-static const struct wl_event display_events[] = {
- { "invalid_object", "u" },
- { "invalid_method", "uu" },
- { "no_memory", "" },
- { "global", "osu" },
-};
-
-static const struct wl_interface display_interface = {
- "display", 1,
- 0, NULL,
- ARRAY_LENGTH(display_events), display_events,
-};
-
WL_EXPORT struct wl_display *
wl_display_create(void)
{
display->client_id_range = 256; /* Gah, arbitrary... */
display->id = 1;
- display->base.interface = &display_interface;
+ display->base.interface = &wl_display_interface;
display->base.implementation = NULL;
wl_display_add_object(display, &display->base);
if (wl_display_add_global(display, &display->base)) {
va_end(ap);
}
-struct wl_input_device {
- struct wl_object base;
- struct wl_display *display;
-};
-
-static const struct wl_method input_device_methods[] = {
-};
-
-static const struct wl_event input_device_events[] = {
- { "motion", "iiii" },
- { "button", "uuiiii" },
- { "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,
-};
-
-WL_EXPORT const struct wl_interface *
-wl_input_device_get_interface(void)
-{
- return &input_device_interface;
-}
-
WL_EXPORT void
wl_display_post_frame(struct wl_display *display,
struct wl_compositor *compositor,
struct wl_client;
-enum {
- WL_ARGUMENT_UINT32,
- WL_ARGUMENT_STRING,
- WL_ARGUMENT_OBJECT,
- WL_ARGUMENT_NEW_ID
-};
-
-struct wl_argument {
- uint32_t type;
- void *data;
-};
-
-struct wl_method {
- const char *name;
- const char *signature;
- const void **types;
-};
-
-struct wl_event {
- const char *name;
- const char *signature;
-};
-
-struct wl_interface {
- const char *name;
- int version;
- int method_count;
- const struct wl_method *methods;
- int event_count;
- const struct wl_event *events;
-};
-
struct wl_object {
const struct wl_interface *interface;
void (**implementation)(void);
int wl_display_add_socket(struct wl_display *display, const char *name, size_t name_size);
void wl_display_run(struct wl_display *display);
-void
-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);
-
-const struct wl_interface *
-wl_input_device_get_interface(void);
-
-#define WL_INPUT_MOTION 0
-#define WL_INPUT_BUTTON 1
-#define WL_INPUT_KEY 2
+void 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);
struct wl_compositor {
struct wl_object base;