Move protocol metadata to wayland-protocol.[ch].

This lets us share the metadata between server and client and we
can now use a va_arg marshalling function for sending client
requets.
This commit is contained in:
Kristian Høgsberg 2008-12-21 21:50:23 -05:00
parent bf967b469f
commit fe831a7494
9 changed files with 263 additions and 216 deletions

View File

@ -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) :

View File

@ -27,6 +27,7 @@
#include <errno.h>
#include <sys/uio.h>
#include "wayland-util.h"
#include "connection.h"
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])

View File

@ -23,6 +23,8 @@
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#include <stdarg.h>
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

View File

@ -30,8 +30,10 @@
#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"
@ -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);
}

84
wayland-protocol.c Normal file
View File

@ -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 <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,
};

85
wayland-protocol.h Normal file
View File

@ -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 <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

View File

@ -46,6 +46,7 @@
#include <eagle.h>
#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 *

View File

@ -34,6 +34,7 @@
#include <assert.h>
#include <ffi.h>
#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,

View File

@ -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;