Generate protocol types and metadata from xml
authorKristian Høgsberg <krh@bitplanet.net>
Tue, 3 Aug 2010 13:26:44 +0000 (09:26 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 3 Aug 2010 13:44:48 +0000 (09:44 -0400)
15 files changed:
.gitignore
Makefile
compositor-drm.c
compositor-x11.c
compositor.c
config.mk.in
configure.ac
protocol.xml [new file with mode: 0644]
scanner.c [new file with mode: 0644]
wayland-client.c
wayland-client.h
wayland-protocol.c [deleted file]
wayland-protocol.h [deleted file]
wayland.c
wayland.h

index 1281071..de7aa72 100644 (file)
@@ -1,3 +1,4 @@
+*.deps
 *.o
 *.so
 *.pc
index 2ea2d3a..fe2ea0f 100644 (file)
--- 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
index 05ab02a..b893fc4 100644 (file)
@@ -34,7 +34,6 @@
 #include <EGL/eglext.h>
 
 #include "wayland.h"
-#include "wayland-protocol.h"
 #include "compositor.h"
 
 struct drm_compositor {
index 6679e20..9c4f845 100644 (file)
@@ -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]))
index ac2960e..165c547 100644 (file)
@@ -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
index 00f465f..60af1cc 100644 (file)
@@ -18,6 +18,8 @@ CLIENT_LIBS = @CLIENT_LIBS@
 POPPLER_CFLAGS = @POPPLER_CFLAGS@
 POPPLER_LIBS = @POPPLER_LIBS@
 
+EXPAT_LIBS = @EXPAT_LIBS@
+
 first : all
 
 -include .*.deps
index fd64439..e544698 100644 (file)
@@ -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 (file)
index 0000000..b5cb783
--- /dev/null
@@ -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 (file)
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;
+}
index 912d682..eb9d698 100644 (file)
@@ -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,
index 2938ac8..482e32d 100644 (file)
 #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 (file)
index 5a989d4..0000000
+++ /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 (file)
index eca2108..0000000
+++ /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
index dcadf26..de2a5c0 100644 (file)
--- 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 {
index d4bdbc8..511fdef 100644 (file)
--- 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,