summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-08-03 09:26:44 -0400
committerKristian Høgsberg <krh@bitplanet.net>2010-08-03 09:44:48 -0400
commita1f3f60bea874d758694c827ff27fa05ff0a2910 (patch)
treef40ac5f2e749da5e0979386810804becf55354ea
parentc37c57aec7128be829fa80640d7236ca0a4b56fc (diff)
Generate protocol types and metadata from xml
-rw-r--r--.gitignore1
-rw-r--r--Makefile32
-rw-r--r--compositor-drm.c1
-rw-r--r--compositor-x11.c1
-rw-r--r--compositor.c26
-rw-r--r--config.mk.in2
-rw-r--r--configure.ac11
-rw-r--r--protocol.xml137
-rw-r--r--scanner.c443
-rw-r--r--wayland-client.c15
-rw-r--r--wayland-client.h50
-rw-r--r--wayland-protocol.c104
-rw-r--r--wayland-protocol.h79
-rw-r--r--wayland.c2
-rw-r--r--wayland.h22
15 files changed, 637 insertions, 289 deletions
diff --git a/.gitignore b/.gitignore
index 1281071..de7aa72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+*.deps
*.o
*.so
*.pc
diff --git a/Makefile b/Makefile
index 2ea2d3a..fe2ea0f 100644
--- a/Makefile
+++ b/Makefile
@@ -3,22 +3,34 @@ include config.mk
subdirs = clients spec
libs = libwayland-server.so libwayland.so
-all : $(libs) compositor subdirs-all
+all : $(libs) compositor subdirs-all scanner
libwayland-server.so : \
+ wayland-protocol.o \
wayland.o \
event-loop.o \
connection.o \
wayland-util.o \
- wayland-hash.o \
- wayland-protocol.o
+ wayland-hash.o
libwayland.so : \
+ wayland-protocol.o \
wayland-client.o \
connection.o \
wayland-util.o \
- wayland-hash.o \
- wayland-protocol.o
+ wayland-hash.o
+
+wayland.o : wayland-server-protocol.h
+wayland-client.o : wayland-client-protocol.h
+
+wayland-protocol.c : protocol.xml scanner
+ ./scanner code < $< > $@
+
+wayland-server-protocol.h : protocol.xml scanner
+ ./scanner server-header < $< > $@
+
+wayland-client-protocol.h : protocol.xml scanner
+ ./scanner client-header < $< > $@
$(libs) : CFLAGS += -fPIC $(FFI_CFLAGS)
$(libs) : LDLIBS += $(FFI_LIBS)
@@ -35,6 +47,12 @@ compositor : \
compositor : CFLAGS += $(COMPOSITOR_CFLAGS)
compositor : LDLIBS += ./libwayland-server.so $(COMPOSITOR_LIBS) -rdynamic -lrt -lEGL -lm
+scanner : \
+ scanner.o \
+ wayland-util.o
+
+scanner : LDLIBS += $(EXPAT_LIBS)
+
subdirs-all subdirs-clean :
for f in $(subdirs); do $(MAKE) -C $$f $(@:subdirs-%=%); done
@@ -46,7 +64,9 @@ install : $(libs) compositor
install 70-wayland.rules ${udev_rules_dir}
clean : subdirs-clean
- rm -f compositor *.o *.so
+ rm -f compositor scanner *.o *.so
+ rm -f wayland-protocol.c \
+ wayland-server-protocol.h wayland-client-protocol.h
config.mk : config.mk.in
./config.status
diff --git a/compositor-drm.c b/compositor-drm.c
index 05ab02a..b893fc4 100644
--- a/compositor-drm.c
+++ b/compositor-drm.c
@@ -34,7 +34,6 @@
#include <EGL/eglext.h>
#include "wayland.h"
-#include "wayland-protocol.h"
#include "compositor.h"
struct drm_compositor {
diff --git a/compositor-x11.c b/compositor-x11.c
index 6679e20..9c4f845 100644
--- a/compositor-x11.c
+++ b/compositor-x11.c
@@ -38,7 +38,6 @@
#include <EGL/eglext.h>
#include "wayland.h"
-#include "wayland-protocol.h"
#include "compositor.h"
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
diff --git a/compositor.c b/compositor.c
index ac2960e..165c547 100644
--- a/compositor.c
+++ b/compositor.c
@@ -38,7 +38,7 @@
#include <EGL/eglext.h>
#include "wayland.h"
-#include "wayland-protocol.h"
+#include "wayland-server-protocol.h"
#include "cairo-util.h"
#include "compositor.h"
@@ -425,8 +425,8 @@ surface_destroy(struct wl_client *client,
static void
surface_attach(struct wl_client *client,
struct wl_surface *surface, uint32_t name,
- uint32_t width, uint32_t height, uint32_t stride,
- struct wl_object *visual)
+ int32_t width, int32_t height, uint32_t stride,
+ struct wl_visual *visual)
{
struct wlsc_surface *es = (struct wlsc_surface *) surface;
struct wlsc_compositor *ec = es->compositor;
@@ -441,11 +441,11 @@ surface_attach(struct wl_client *client,
es->width = width;
es->height = height;
- if (visual == &ec->argb_visual.base)
+ if (visual == &ec->argb_visual)
es->visual = &ec->argb_visual;
- else if (visual == &ec->premultiplied_argb_visual.base)
+ else if (visual == &ec->premultiplied_argb_visual)
es->visual = &ec->premultiplied_argb_visual;
- else if (visual == &ec->rgb_visual.base)
+ else if (visual == &ec->rgb_visual)
es->visual = &ec->rgb_visual;
else
/* FIXME: Smack client with an exception event */;
@@ -559,13 +559,13 @@ wlsc_input_device_set_keyboard_focus(struct wlsc_input_device *device,
(!surface || device->keyboard_focus->base.client != surface->base.client))
wl_surface_post_event(&device->keyboard_focus->base,
&device->base,
- WL_INPUT_KEYBOARD_FOCUS,
+ WL_INPUT_DEVICE_KEYBOARD_FOCUS,
time, NULL, &device->keys);
if (surface)
wl_surface_post_event(&surface->base,
&device->base,
- WL_INPUT_KEYBOARD_FOCUS,
+ WL_INPUT_DEVICE_KEYBOARD_FOCUS,
time, &surface->base, &device->keys);
device->keyboard_focus = surface;
@@ -583,12 +583,12 @@ wlsc_input_device_set_pointer_focus(struct wlsc_input_device *device,
(!surface || device->pointer_focus->base.client != surface->base.client))
wl_surface_post_event(&device->pointer_focus->base,
&device->base,
- WL_INPUT_POINTER_FOCUS,
+ WL_INPUT_DEVICE_POINTER_FOCUS,
time, NULL);
if (surface)
wl_surface_post_event(&surface->base,
&device->base,
- WL_INPUT_POINTER_FOCUS,
+ WL_INPUT_DEVICE_POINTER_FOCUS,
time, &surface->base);
device->pointer_focus = surface;
@@ -644,7 +644,7 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
if (es)
wl_surface_post_event(&es->base, &device->base,
- WL_INPUT_MOTION, time, x, y, sx, sy);
+ WL_INPUT_DEVICE_MOTION, time, x, y, sx, sy);
wlsc_matrix_init(&device->sprite->matrix);
wlsc_matrix_scale(&device->sprite->matrix, 64, 64, 1);
@@ -675,7 +675,7 @@ notify_button(struct wlsc_input_device *device,
/* FIXME: Swallow click on raise? */
wl_surface_post_event(&surface->base, &device->base,
- WL_INPUT_BUTTON, time, button, state);
+ WL_INPUT_DEVICE_BUTTON, time, button, state);
wlsc_compositor_schedule_repaint(compositor);
}
@@ -730,7 +730,7 @@ notify_key(struct wlsc_input_device *device,
if (device->keyboard_focus != NULL)
wl_surface_post_event(&device->keyboard_focus->base,
&device->base,
- WL_INPUT_KEY, time, key, state);
+ WL_INPUT_DEVICE_KEY, time, key, state);
}
static uint32_t
diff --git a/config.mk.in b/config.mk.in
index 00f465f..60af1cc 100644
--- a/config.mk.in
+++ b/config.mk.in
@@ -18,6 +18,8 @@ CLIENT_LIBS = @CLIENT_LIBS@
POPPLER_CFLAGS = @POPPLER_CFLAGS@
POPPLER_LIBS = @POPPLER_LIBS@
+EXPAT_LIBS = @EXPAT_LIBS@
+
first : all
-include .*.deps
diff --git a/configure.ac b/configure.ac
index fd64439..e544698 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,5 +14,16 @@ if test $CC = gcc; then
fi
AC_SUBST(GCC_CFLAGS)
+EXPAT_LIB=""
+AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
+ [ expat=$withval
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib" ] )
+AC_CHECK_HEADERS(expat.h, [AC_DEFINE(HAVE_EXPAT_H)],
+ [AC_MSG_ERROR([Can't find expat.h. Please install expat.])])
+AC_CHECK_LIB(expat, XML_ParserCreate, [EXPAT_LIBS="-lexpat"],
+ [AC_MSG_ERROR([Can't find expat library. Please install expat.])])
+AC_SUBST(EXPAT_LIBS)
+
AC_CONFIG_FILES([config.mk wayland-server.pc wayland.pc])
AC_OUTPUT
diff --git a/protocol.xml b/protocol.xml
new file mode 100644
index 0000000..b5cb783
--- /dev/null
+++ b/protocol.xml
@@ -0,0 +1,137 @@
+<protocol>
+
+ <interface name="display" version="1">
+ <event name="invalid_object">
+ <arg name="object_id" type="uint"/>
+ </event>
+
+ <event name="invalid_method">
+ <arg name="object_id" type="uint"/>
+ <arg name="opcode" type="uint"/>
+ </event>
+
+ <event name="no_memory"/>
+
+ <event name="global">
+ <arg name="id" type="new_id"/>
+ <arg name="name" type="string"/>
+ <arg name="version" type="uint"/>
+ </event>
+
+ <event name="range">
+ <arg name="base" type="uint"/>
+ </event>
+ </interface>
+
+ <interface name="compositor" version="1">
+ <request name="create_surface">
+ <arg name="id" type="new_id"/>
+ </request>
+
+ <request name="commit">
+ <arg name="key" type="uint"/>
+ </request>
+
+ <event name="device">
+ <arg name="name" type="string"/>
+ </event>
+
+ <event name="acknowledge">
+ <arg name="key" type="uint"/>
+ <arg name="frame" type="uint"/>
+ </event>
+
+ <event name="frame">
+ <arg name="frame" type="uint"/>
+ <arg name="timestamp" type="uint"/>
+ </event>
+ </interface>
+
+ <interface name="shell" version="1">
+ <request name="move">
+ <arg name="time" type="uint"/>
+ </request>
+
+ <request name="resize">
+ <arg name="time" type="uint"/>
+ <arg name="edges" type="uint"/>
+ </request>
+
+ <event name="configure">
+ <arg name="surface" type="surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </event>
+ </interface>
+
+ <interface name="surface" version="1">
+ <request name="destroy"/>
+
+ <request name="attach">
+ <arg name="name" type="uint"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ <arg name="stride" type="uint"/>
+ <arg name="visual" type="visual"/>
+ </request>
+
+ <request name="map">
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </request>
+
+ <request name="damage">
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </request>
+ </interface>
+
+ <interface name="input_device" version="1">
+ <event name="motion">
+ <arg name="time" type="uint"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="surface_x" type="int"/>
+ <arg name="surface_y" type="int"/>
+ </event>
+
+ <event name="button">
+ <arg name="time" type="uint"/>
+ <arg name="button" type="uint"/>
+ <arg name="state" type="uint"/>
+ </event>
+
+ <event name="key">
+ <arg name="time" type="uint"/>
+ <arg name="key" type="uint"/>
+ <arg name="state" type="uint"/>
+ </event>
+
+ <event name="pointer_focus">
+ <arg name="time" type="uint"/>
+ <arg name="surface" type="surface"/>
+ </event>
+
+ <event name="keyboard_focus">
+ <arg name="time" type="uint"/>
+ <arg name="surface" type="surface"/>
+ <arg name="keys" type="array"/>
+ </event>
+ </interface>
+
+ <interface name="output" version="1">
+ <event name="geometry">
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </event>
+ </interface>
+
+ <interface name="visual" version="1">
+
+</protocol> \ No newline at end of file
diff --git a/scanner.c b/scanner.c
new file mode 100644
index 0000000..47e13ee
--- /dev/null
+++ b/scanner.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <expat.h>
+
+#include "wayland-util.h"
+
+static const char copyright[] =
+ "/*\n"
+ " * Copyright © 2010 Kristian Høgsberg\n"
+ " *\n"
+ " * Permission to use, copy, modify, distribute, and sell this software and its\n"
+ " * documentation for any purpose is hereby granted without fee, provided that\n"
+ " * the above copyright notice appear in all copies and that both that copyright\n"
+ " * notice and this permission notice appear in supporting documentation, and\n"
+ " * that the name of the copyright holders not be used in advertising or\n"
+ " * publicity pertaining to distribution of the software without specific,\n"
+ " * written prior permission. The copyright holders make no representations\n"
+ " * about the suitability of this software for any purpose. It is provided \"as\n"
+ " * is\" without express or implied warranty.\n"
+ " *\n"
+ " * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\n"
+ " * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO\n"
+ " * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR\n"
+ " * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\n"
+ " * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n"
+ " * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\n"
+ " * OF THIS SOFTWARE.\n"
+ " */\n";
+
+static int
+usage(int ret)
+{
+ fprintf(stderr, "usage: ./scanner [header|code]\n");
+ exit(ret);
+}
+
+#define XML_BUFFER_SIZE 4096
+
+struct protocol {
+ struct wl_list interface_list;
+};
+
+struct interface {
+ char *name;
+ char *uppercase_name;
+ int version;
+ struct wl_list request_list;
+ struct wl_list event_list;
+ struct wl_list link;
+};
+
+struct message {
+ char *name;
+ char *uppercase_name;
+ struct wl_list arg_list;
+ struct wl_list link;
+};
+
+enum arg_type {
+ NEW_ID,
+ INT,
+ UNSIGNED,
+ STRING,
+ OBJECT,
+ ARRAY
+};
+
+struct arg {
+ char *name;
+ enum arg_type type;
+ char *object_name;
+ struct wl_list link;
+};
+
+struct parse_context {
+ struct protocol *protocol;
+ struct interface *interface;
+ struct message *message;
+};
+
+static char *
+uppercase_dup(const char *src)
+{
+ char *u;
+ int i;
+
+ u = strdup(src);
+ for (i = 0; u[i]; i++)
+ u[i] = toupper(u[i]);
+ u[i] = '\0';
+
+ return u;
+}
+
+static void
+start_element(void *data, const char *element_name, const char **atts)
+{
+ struct parse_context *ctx = data;
+ struct interface *interface;
+ struct message *message;
+ struct arg *arg;
+ const char *name, *type;
+ int i, version;
+
+ name = 0;
+ type = 0;
+ version = 0;
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "name") == 0)
+ name = atts[i + 1];
+ if (strcmp(atts[i], "version") == 0)
+ version = atoi(atts[i + 1]);
+ if (strcmp(atts[i], "type") == 0)
+ type = atts[i + 1];
+ }
+
+ if (strcmp(element_name, "interface") == 0) {
+ if (name == NULL) {
+ fprintf(stderr, "no interface name given\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (version == 0) {
+ fprintf(stderr, "no interface version given\n");
+ exit(EXIT_FAILURE);
+ }
+
+ interface = malloc(sizeof *interface);
+ interface->name = strdup(name);
+ interface->uppercase_name = uppercase_dup(name);
+ interface->version = version;
+ wl_list_init(&interface->request_list);
+ wl_list_init(&interface->event_list);
+ wl_list_insert(ctx->protocol->interface_list.prev,
+ &interface->link);
+ ctx->interface = interface;
+ } else if (strcmp(element_name, "request") == 0 ||
+ strcmp(element_name, "event") == 0) {
+ if (name == NULL) {
+ fprintf(stderr, "no request name given\n");
+ exit(EXIT_FAILURE);
+ }
+
+ message = malloc(sizeof *message);
+ message->name = strdup(name);
+ message->uppercase_name = uppercase_dup(name);
+ wl_list_init(&message->arg_list);
+
+ if (strcmp(element_name, "request") == 0)
+ wl_list_insert(ctx->interface->request_list.prev,
+ &message->link);
+ else
+ wl_list_insert(ctx->interface->event_list.prev,
+ &message->link);
+
+ ctx->message = message;
+ } else if (strcmp(element_name, "arg") == 0) {
+ arg = malloc(sizeof *arg);
+ arg->name = strdup(name);
+
+ if (strcmp(type, "new_id") == 0)
+ arg->type = NEW_ID;
+ else if (strcmp(type, "int") == 0)
+ arg->type = INT;
+ else if (strcmp(type, "uint") == 0)
+ arg->type = UNSIGNED;
+ else if (strcmp(type, "string") == 0)
+ arg->type = STRING;
+ else if (strcmp(type, "array") == 0)
+ arg->type = ARRAY;
+ else {
+ arg->type = OBJECT;
+ arg->object_name = strdup(type);
+ }
+
+ wl_list_insert(ctx->message->arg_list.prev,
+ &arg->link);
+ }
+}
+
+static void
+emit_opcodes(struct wl_list *message_list, struct interface *interface)
+{
+ struct message *m;
+ int opcode;
+
+ if (wl_list_empty(message_list))
+ return;
+
+ opcode = 0;
+ wl_list_for_each(m, message_list, link)
+ printf("#define WL_%s_%s\t%d\n",
+ interface->uppercase_name, m->uppercase_name, opcode++);
+
+ printf("\n");
+}
+
+static void
+emit_structs(struct wl_list *message_list, struct interface *interface)
+{
+ struct message *m;
+ struct arg *a;
+ int is_interface;
+
+ is_interface = message_list == &interface->request_list;
+ printf("struct wl_%s_%s {\n", interface->name,
+ is_interface ? "interface" : "listener");
+
+ wl_list_for_each(m, message_list, link) {
+ printf("\tvoid (*%s)(", m->name);
+
+ if (is_interface) {
+ printf("struct wl_client *client, struct wl_%s *%s",
+ interface->name, interface->name);
+ } else {
+ printf("void *data, struct wl_%s *%s",
+ interface->name, interface->name);
+ }
+
+ if (!wl_list_empty(&m->arg_list))
+ printf(", ");
+
+ wl_list_for_each(a, &m->arg_list, link) {
+ switch (a->type) {
+ default:
+ case INT:
+ printf("int32_t ");
+ break;
+ case NEW_ID:
+ case UNSIGNED:
+ printf("uint32_t ");
+ break;
+ case STRING:
+ printf("const char *");
+ break;
+ case OBJECT:
+ printf("struct wl_%s *", a->object_name);
+ break;
+ case ARRAY:
+ printf("struct wl_array *");
+ break;
+ }
+ printf("%s%s",
+ a->name,
+ a->link.next == &m->arg_list ? "" : ", ");
+ }
+
+ printf(");\n");
+ }
+
+ printf("};\n\n");
+}
+
+static void
+emit_header(struct protocol *protocol, int server)
+{
+ struct interface *i;
+
+ printf("%s\n\n"
+ "#ifndef WAYLAND_PROTOCOL_H\n"
+ "#define WAYLAND_PROTOCOL_H\n"
+ "\n"
+ "#ifdef __cplusplus\n"
+ "extern \"C\" {\n"
+ "#endif\n"
+ "\n"
+ "#include <stdint.h>\n"
+ "#include \"wayland-util.h\"\n\n"
+ "struct wl_client;\n\n", copyright);
+
+ wl_list_for_each(i, &protocol->interface_list, link)
+ printf("struct wl_%s;\n", i->name);
+ printf("\n");
+
+ wl_list_for_each(i, &protocol->interface_list, link) {
+
+ if (server) {
+ emit_structs(&i->request_list, i);
+ emit_opcodes(&i->event_list, i);
+ } else {
+ emit_structs(&i->event_list, i);
+ emit_opcodes(&i->request_list, i);
+ }
+
+ printf("extern const struct wl_interface "
+ "wl_%s_interface;\n\n",
+ i->name);
+ }
+
+ printf("#ifdef __cplusplus\n"
+ "}\n"
+ "#endif\n"
+ "\n"
+ "#endif\n");
+}
+
+static void
+emit_messages(struct wl_list *message_list,
+ struct interface *interface, const char *suffix)
+{
+ struct message *m;
+ struct arg *a;
+
+ if (wl_list_empty(message_list))
+ return;
+
+ printf("static const struct wl_message "
+ "%s_%s[] = {\n",
+ interface->name, suffix);
+
+ wl_list_for_each(m, message_list, link) {
+ printf("\t{ \"%s\", \"", m->name);
+ wl_list_for_each(a, &m->arg_list, link) {
+ switch (a->type) {
+ default:
+ case INT:
+ printf("i");
+ break;
+ case NEW_ID:
+ printf("n");
+ break;
+ case UNSIGNED:
+ printf("u");
+ break;
+ case STRING:
+ printf("s");
+ break;
+ case OBJECT:
+ printf("o");
+ break;
+ case ARRAY:
+ printf("a");
+ break;
+ }
+ }
+ printf("\" },\n");
+ }
+
+ printf("};\n\n");
+}
+
+static void
+emit_code(struct protocol *protocol)
+{
+ struct interface *i;
+
+ printf("%s\n\n"
+ "#include <stdlib.h>\n"
+ "#include <stdint.h>\n"
+ "#include \"wayland-util.h\"\n\n",
+ copyright);
+
+ wl_list_for_each(i, &protocol->interface_list, link) {
+
+ emit_messages(&i->request_list, i, "requests");
+ emit_messages(&i->event_list, i, "events");
+
+ printf("WL_EXPORT const struct wl_interface "
+ "wl_%s_interface = {\n"
+ "\t\"%s\", %d,\n",
+ i->name, i->name, i->version);
+
+ if (!wl_list_empty(&i->request_list))
+ printf("\tARRAY_LENGTH(%s_requests), %s_requests,\n",
+ i->name, i->name);
+ else
+ printf("\t0, NULL,\n");
+
+ if (!wl_list_empty(&i->event_list))
+ printf("\tARRAY_LENGTH(%s_events), %s_events,\n",
+ i->name, i->name);
+ else
+ printf("\t0, NULL,\n");
+
+ printf("};\n\n");
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ struct parse_context ctx;
+ struct protocol protocol;
+ XML_Parser parser;
+ int len;
+ void *buf;
+
+ if (argc != 2)
+ usage(EXIT_FAILURE);
+
+ wl_list_init(&protocol.interface_list);
+ ctx.protocol = &protocol;
+
+ parser = XML_ParserCreate(NULL);
+ XML_SetUserData(parser, &ctx);
+ if (parser == NULL) {
+ fprintf(stderr, "failed to create parser\n");
+ exit(EXIT_FAILURE);
+ }
+
+ XML_SetElementHandler(parser, start_element, NULL);
+ do {
+ buf = XML_GetBuffer(parser, XML_BUFFER_SIZE);
+ len = fread(buf, 1, XML_BUFFER_SIZE, stdin);
+ if (len < 0) {
+ fprintf(stderr, "fread: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ XML_ParseBuffer(parser, len, len == 0);
+
+ } while (len > 0);
+
+ XML_ParserFree(parser);
+
+ if (strcmp(argv[1], "client-header") == 0) {
+ emit_header(&protocol, 0);
+ } else if (strcmp(argv[1], "server-header") == 0) {
+ emit_header(&protocol, 1);
+ } else if (strcmp(argv[1], "code") == 0) {
+ emit_code(&protocol);
+ }
+
+ return 0;
+}
diff --git a/wayland-client.c b/wayland-client.c
index 912d682..eb9d698 100644
--- a/wayland-client.c
+++ b/wayland-client.c
@@ -33,7 +33,7 @@
#include <assert.h>
#include <sys/poll.h>
-#include "wayland-protocol.h"
+#include "wayland-client-protocol.h"
#include "connection.h"
#include "wayland-util.h"
#include "wayland-client.h"
@@ -334,19 +334,6 @@ display_handle_range(void *data,
display->next_range = range;
}
-struct wl_display_listener {
- void (*invalid_object)(void *data,
- struct wl_display *display, uint32_t id);
- void (*invalid_method)(void *data, struct wl_display *display,
- uint32_t id, uint32_t opcode);
- void (*no_memory)(void *data,
- struct wl_display *display);
- void (*global)(void *data, struct wl_display *display,
- uint32_t id, const char *interface, uint32_t version);
- void (*range)(void *data,
- struct wl_display *display, uint32_t range);
-};
-
static const struct wl_display_listener display_listener = {
display_handle_invalid_object,
display_handle_invalid_method,
diff --git a/wayland-client.h b/wayland-client.h
index 2938ac8..482e32d 100644
--- a/wayland-client.h
+++ b/wayland-client.h
@@ -24,16 +24,12 @@
#define _WAYLAND_CLIENT_H
#include "wayland-util.h"
+#include "wayland-client-protocol.h"
#ifdef __cplusplus
extern "C" {
#endif
-struct wl_object;
-struct wl_display;
-struct wl_surface;
-struct wl_visual;
-
#define WL_DISPLAY_READABLE 0x01
#define WL_DISPLAY_WRITABLE 0x02
@@ -70,18 +66,6 @@ wl_display_get_premultiplied_argb_visual(struct wl_display *display);
struct wl_visual *
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);
- void (*frame)(void *data,
- struct wl_compositor *compositor,
- uint32_t frame, uint32_t timestamp);
-};
-
struct wl_surface *
wl_compositor_create_surface(struct wl_compositor *compositor);
void
@@ -104,43 +88,11 @@ void wl_surface_damage(struct wl_surface *surface,
void wl_surface_set_user_data(struct wl_surface *surface, void *user_data);
void *wl_surface_get_user_data(struct wl_surface *surface);
-struct wl_output;
-struct wl_output_listener {
- void (*geometry)(void *data,
- struct wl_output *output,
- int32_t width, int32_t height);
-};
-
int
wl_output_add_listener(struct wl_output *output,
const struct wl_output_listener *listener,
void *data);
-struct wl_input_device;
-struct wl_input_device_listener {
- void (*motion)(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- int32_t x, int32_t y, int32_t sx, int32_t sy);
- void (*button)(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- uint32_t button, uint32_t state);
- void (*key)(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- uint32_t button, uint32_t state);
- void (*pointer_focus)(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- struct wl_surface *surface);
- void (*keyboard_focus)(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- struct wl_surface *surface,
- struct wl_array *keys);
-};
-
int
wl_input_device_add_listener(struct wl_input_device *input_device,
const struct wl_input_device_listener *listener,
diff --git a/wayland-protocol.c b/wayland-protocol.c
deleted file mode 100644
index 5a989d4..0000000
--- a/wayland-protocol.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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_message display_events[] = {
- { "invalid_object", "u" },
- { "invalid_method", "uu" },
- { "no_memory", "" },
- { "global", "nsu" },
- { "range", "u" },
-};
-
-WL_EXPORT const struct wl_interface wl_display_interface = {
- "display", 1,
- 0, NULL,
- ARRAY_LENGTH(display_events), display_events,
-};
-
-
-static const struct wl_message compositor_methods[] = {
- { "create_surface", "n" },
- { "commit", "u" }
-};
-
-static const struct wl_message compositor_events[] = {
- { "device", "s" },
- { "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_message surface_methods[] = {
- { "destroy", "" },
- { "attach", "uuuuo" },
- { "map", "iiii" },
- { "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_message input_device_events[] = {
- { "motion", "uiiii" },
- { "button", "uuu" },
- { "key", "uuu" },
- { "pointer_focus", "uo" },
- { "keyboard_focus", "uoa" },
-};
-
-WL_EXPORT const struct wl_interface wl_input_device_interface = {
- "input_device", 1,
- 0, NULL,
- ARRAY_LENGTH(input_device_events), input_device_events,
-};
-
-
-static const struct wl_message output_events[] = {
- { "geometry", "uu" },
-};
-
-WL_EXPORT const struct wl_interface wl_output_interface = {
- "output", 1,
- 0, NULL,
- ARRAY_LENGTH(output_events), output_events,
-};
-
-WL_EXPORT const struct wl_interface wl_visual_interface = {
- "visual", 1,
- 0, NULL,
- 0, NULL,
-};
diff --git a/wayland-protocol.h b/wayland-protocol.h
deleted file mode 100644
index eca2108..0000000
--- a/wayland-protocol.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-#define WL_DISPLAY_INVALID_OBJECT 0
-#define WL_DISPLAY_INVALID_METHOD 1
-#define WL_DISPLAY_NO_MEMORY 2
-#define WL_DISPLAY_GLOBAL 3
-#define WL_DISPLAY_RANGE 4
-
-extern const struct wl_interface wl_display_interface;
-
-
-#define WL_COMPOSITOR_CREATE_SURFACE 0
-#define WL_COMPOSITOR_COMMIT 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_DAMAGE 3
-
-extern const struct wl_interface wl_surface_interface;
-
-
-#define WL_INPUT_MOTION 0
-#define WL_INPUT_BUTTON 1
-#define WL_INPUT_KEY 2
-#define WL_INPUT_POINTER_FOCUS 3
-#define WL_INPUT_KEYBOARD_FOCUS 4
-
-extern const struct wl_interface wl_input_device_interface;
-
-
-#define WL_OUTPUT_GEOMETRY 0
-
-extern const struct wl_interface wl_output_interface;
-
-
-extern const struct wl_interface wl_visual_interface;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/wayland.c b/wayland.c
index dcadf26..de2a5c0 100644
--- a/wayland.c
+++ b/wayland.c
@@ -34,8 +34,8 @@
#include <assert.h>
#include <ffi.h>
-#include "wayland-protocol.h"
#include "wayland.h"
+#include "wayland-server-protocol.h"
#include "connection.h"
struct wl_client {
diff --git a/wayland.h b/wayland.h
index d4bdbc8..511fdef 100644
--- a/wayland.h
+++ b/wayland.h
@@ -29,6 +29,7 @@ extern "C" {
#include <stdint.h>
#include "wayland-util.h"
+#include "wayland-server-protocol.h"
enum {
WL_EVENT_READABLE = 0x01,
@@ -99,27 +100,6 @@ struct wl_surface {
struct wl_list link;
};
-struct wl_compositor_interface {
- void (*create_surface)(struct wl_client *client,
- struct wl_compositor *compositor, uint32_t id);
- void (*commit)(struct wl_client *client,
- struct wl_compositor *compositor, uint32_t key);
-};
-
-struct wl_surface_interface {
- void (*destroy)(struct wl_client *client,
- struct wl_surface *surface);
- void (*attach)(struct wl_client *client,
- struct wl_surface *surface, uint32_t name,
- uint32_t width, uint32_t height, uint32_t stride,
- struct wl_object *visual);
- void (*map)(struct wl_client *client,
- struct wl_surface *surface,
- int32_t x, int32_t y, int32_t width, int32_t height);
- void (*damage)(struct wl_client *client, struct wl_surface *surface,
- int32_t x, int32_t y, int32_t width, int32_t height);
-};
-
void
wl_client_post_event(struct wl_client *client,
struct wl_object *sender,