diff --git a/Makefile.in b/Makefile.in index 0f269a34..5910911b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -13,7 +13,8 @@ libwayland-server.so : \ 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 @@ -21,7 +22,8 @@ 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) : diff --git a/connection.c b/connection.c index 9d63f826..54309631 100644 --- a/connection.c +++ b/connection.c @@ -27,6 +27,7 @@ #include #include +#include "wayland-util.h" #include "connection.h" #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) diff --git a/connection.h b/connection.h index a9a0d711..68d63964 100644 --- a/connection.h +++ b/connection.h @@ -23,6 +23,8 @@ #ifndef _CONNECTION_H_ #define _CONNECTION_H_ +#include + struct wl_connection; #define WL_CONNECTION_READABLE 0x01 @@ -39,5 +41,7 @@ void wl_connection_copy(struct wl_connection *connection, void *data, size_t siz 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 diff --git a/wayland-client.c b/wayland-client.c index d6471ac3..a898fd26 100644 --- a/wayland-client.c +++ b/wayland-client.c @@ -30,8 +30,10 @@ #include #include #include +#include #include +#include "wayland-protocol.h" #include "connection.h" #include "wayland-util.h" #include "wayland-client.h" @@ -46,8 +48,9 @@ struct wl_global { }; struct wl_proxy { - struct wl_display *display; + const struct wl_interface *interface; uint32_t id; + struct wl_display *display; }; struct wl_display { @@ -166,8 +169,9 @@ wl_display_create(const char *name, size_t name_size) 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, @@ -217,11 +221,6 @@ wl_display_get_fd(struct wl_display *display, 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) { @@ -324,33 +323,80 @@ wl_display_get_compositor(struct wl_display *display) 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; } @@ -358,31 +404,13 @@ wl_compositor_create_surface(struct wl_compositor *compositor) 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 @@ -390,35 +418,16 @@ wl_surface_attach(struct wl_surface *surface, uint32_t name, 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 @@ -426,36 +435,14 @@ wl_surface_copy(struct wl_surface *surface, int32_t dst_x, int32_t dst_y, 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); } diff --git a/wayland-protocol.c b/wayland-protocol.c new file mode 100644 index 00000000..3af3c626 --- /dev/null +++ b/wayland-protocol.c @@ -0,0 +1,84 @@ +/* + * 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 +#include +#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, +}; diff --git a/wayland-protocol.h b/wayland-protocol.h new file mode 100644 index 00000000..a5c97c02 --- /dev/null +++ b/wayland-protocol.h @@ -0,0 +1,85 @@ +/* + * 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 + +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 diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c index ef4dca2e..073386fa 100644 --- a/wayland-system-compositor.c +++ b/wayland-system-compositor.c @@ -46,6 +46,7 @@ #include #include "wayland.h" +#include "wayland-protocol.h" #include "cairo-util.h" #include "wayland-system-compositor.h" @@ -695,12 +696,12 @@ create_input_device(struct egl_compositor *ec, const char *glob) 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); @@ -947,6 +948,8 @@ static int setup_tty(struct egl_compositor *ec, struct wl_event_loop *loop) 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 * diff --git a/wayland.c b/wayland.c index fe5f9db7..45b4fae3 100644 --- a/wayland.c +++ b/wayland.c @@ -34,6 +34,7 @@ #include #include +#include "wayland-protocol.h" #include "wayland.h" #include "connection.h" @@ -203,11 +204,6 @@ wl_client_demarshal(struct wl_client *client, struct wl_object *target, 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) { @@ -348,20 +344,6 @@ wl_client_destroy(struct wl_client *client) 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, @@ -372,7 +354,7 @@ wl_client_add_surface(struct wl_client *client, 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; @@ -390,9 +372,6 @@ wl_client_add_surface(struct wl_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, @@ -405,28 +384,12 @@ wl_client_send_acknowledge(struct wl_client *client, 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); @@ -436,19 +399,6 @@ wl_display_set_compositor(struct wl_display *display, 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) { @@ -476,7 +426,7 @@ 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)) { @@ -522,34 +472,6 @@ wl_surface_post_event(struct wl_surface *surface, 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, diff --git a/wayland.h b/wayland.h index ecf0c7e6..ff435721 100644 --- a/wayland.h +++ b/wayland.h @@ -66,38 +66,6 @@ struct wl_event_source *wl_event_loop_add_idle(struct wl_event_loop *loop, 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); @@ -116,17 +84,8 @@ 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); 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;