From 427524aedf0373250b907640f4f69d1bf3f16b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 8 Oct 2008 13:32:07 -0400 Subject: [PATCH] Use new connection object in client code too. --- Makefile | 2 +- NOTES | 4 ++ client.c | 53 ++++++++++++----- socket.c | 0 wayland-client.c | 148 +++++++++++++++++------------------------------ wayland-client.h | 20 +++---- 6 files changed, 104 insertions(+), 123 deletions(-) delete mode 100644 socket.c diff --git a/Makefile b/Makefile index d8fd4ed3..21f28e81 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ wayland_objs = wayland.o event-loop.o connection.o hash.o compositor.o wayland : $(wayland_objs) gcc -o $@ $(wayland_objs) $(LDLIBS) -libwayland_objs = wayland-client.o +libwayland_objs = wayland-client.o connection.o libwayland.so : $(libwayland_objs) gcc -o $@ $(libwayland_objs) -shared diff --git a/NOTES b/NOTES index b3e72119..ced5835c 100644 --- a/NOTES +++ b/NOTES @@ -60,6 +60,10 @@ synaptics, 3-button emulation, xkb, scim changing screen resolution, adding monitors. +What to do when protocol out buffer fills up? Just block on write +would work I guess. Clients are supposed to throttle using the bread +crumb events, so we shouldn't get into this situation. + RMI diff --git a/client.c b/client.c index 48294c0d..8eb83b37 100644 --- a/client.c +++ b/client.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -92,15 +93,30 @@ draw_stuff(int width, int height) return surface; } +static int +connection_update(struct wl_connection *connection, + uint32_t mask, void *data) +{ + struct pollfd *p = data; + + p->events = 0; + if (mask & WL_CONNECTION_READABLE) + p->events |= POLLIN; + if (mask & WL_CONNECTION_WRITABLE) + p->events |= POLLOUT; + + return 0; +} + int main(int argc, char *argv[]) { - struct wl_connection *connection; struct wl_display *display; struct wl_surface *surface; const int x = 400, y = 200, width = 300, height = 300; - int fd; - uint32_t name; + int fd, i, ret; + uint32_t name, mask; cairo_surface_t *s; + struct pollfd p[1]; fd = open(gem_device, O_RDWR); if (fd < 0) { @@ -108,13 +124,13 @@ int main(int argc, char *argv[]) return -1; } - connection = wl_connection_create(socket_name); - if (connection == NULL) { - fprintf(stderr, "failed to create connection: %m\n"); + display = wl_display_create(socket_name, + connection_update, &p[0]); + if (display == NULL) { + fprintf(stderr, "failed to create display: %m\n"); return -1; } - - display = wl_connection_get_display(connection); + p[0].fd = wl_display_get_fd(display); surface = wl_display_create_surface(display); @@ -124,13 +140,22 @@ int main(int argc, char *argv[]) wl_surface_attach(surface, name, width, height, cairo_image_surface_get_stride(s)); - wl_surface_map(surface, x, y, width, height); - if (wl_connection_flush(connection) < 0) { - fprintf(stderr, "flush error: %m\n"); - return -1; + i = 0; + while (ret = poll(p, 1, 40), ret >= 0) { + if (ret == 0) { + wl_surface_map(surface, x + i, y + i, width, height); + i++; + continue; + } + + mask = 0; + if (p[0].revents & POLLIN) + mask |= WL_CONNECTION_READABLE; + if (p[0].revents & POLLOUT) + mask |= WL_CONNECTION_WRITABLE; + if (mask) + wl_display_iterate(display, mask); } - wl_connection_iterate(connection); - return 0; } diff --git a/socket.c b/socket.c deleted file mode 100644 index e69de29b..00000000 diff --git a/wayland-client.c b/wayland-client.c index afa43c84..025f69ce 100644 --- a/wayland-client.c +++ b/wayland-client.c @@ -10,6 +10,9 @@ #include #include +#include "connection.h" +#include "wayland-client.h" + static const char socket_name[] = "\0wayland"; struct wl_buffer { @@ -17,45 +20,41 @@ struct wl_buffer { int head, tail; }; -struct wl_connection { - int fd; - struct wl_buffer in, out; - struct wl_display *display; - uint32_t id; -}; - struct wl_proxy { - struct wl_connection *connection; + struct wl_display *display; uint32_t id; }; struct wl_display { struct wl_proxy proxy; + struct wl_connection *connection; + int fd; + uint32_t id; }; struct wl_surface { struct wl_proxy proxy; }; -struct wl_connection * -wl_connection_create(const char *address) +struct wl_display * +wl_display_create(const char *address, + wl_connection_update_func_t update, void *data) { - struct wl_connection *connection; struct wl_display *display; struct sockaddr_un name; socklen_t size; char buffer[256]; uint32_t id, length; - connection = malloc(sizeof *connection); - if (connection == NULL) + display = malloc(sizeof *display); + if (display == NULL) return NULL; - memset(connection, 0, sizeof *connection); - connection->id = 256; /* Need to get our id-range. */ - connection->fd = socket(PF_LOCAL, SOCK_STREAM, 0); - if (connection->fd < 0) { - free(connection); + memset(display, 0, sizeof *display); + display->id = 256; /* Need to get our id-range. */ + display->fd = socket(PF_LOCAL, SOCK_STREAM, 0); + if (display->fd < 0) { + free(display); return NULL; } @@ -64,76 +63,71 @@ wl_connection_create(const char *address) size = offsetof (struct sockaddr_un, sun_path) + sizeof socket_name; - if (connect (connection->fd, (struct sockaddr *) &name, size) < 0) { - close(connection->fd); - free(connection); + if (connect(display->fd, (struct sockaddr *) &name, size) < 0) { + close(display->fd); + free(display); return NULL; } /* FIXME: actually discover advertised objects here. */ - read(connection->fd, &id, sizeof id); - read(connection->fd, &length, sizeof length); - read(connection->fd, buffer, (length + 3) & ~3); + read(display->fd, &id, sizeof id); + read(display->fd, &length, sizeof length); + read(display->fd, buffer, (length + 3) & ~3); - display = malloc(sizeof *display); - display->proxy.connection = connection; + display->proxy.display = display; display->proxy.id = id; - connection->display = display; - return connection; + display->connection = wl_connection_create(display->fd, + update, data); + + return display; } void -wl_connection_destroy(struct wl_connection *connection) +wl_display_destroy(struct wl_display *display) { - close(connection->fd); - free(connection->display); - free(connection); + wl_connection_destroy(display->connection); + close(display->fd); + free(display); } int -wl_connection_get_fd(struct wl_connection *connection) +wl_display_get_fd(struct wl_display *display) { - return connection->fd; + return display->fd; } static void handle_event(struct wl_connection *connection) { - struct wl_buffer *b; - uint32_t *p, opcode, size; + uint32_t p[2], opcode, size; - b = &connection->in; - p = (uint32_t *) (b->data + b->tail); + wl_connection_copy(connection, p, sizeof p); opcode = p[1] & 0xffff; size = p[1] >> 16; printf("signal from object %d, opcode %d, size %d\n", p[0], opcode, size); - b->tail += size; + wl_connection_consume(connection, sizeof p); } void -wl_connection_iterate(struct wl_connection *connection) +wl_display_iterate(struct wl_display *display, uint32_t mask) { - struct wl_buffer *b; - uint32_t *p, opcode, size; + uint32_t p[2], opcode, size; int len; - b = &connection->in; - len = read(connection->fd, b->data + b->head, sizeof b->data); - b->head += len; + len = wl_connection_data(display->connection, mask); while (len > 0) { - - if (b->head - b->tail < 8) + if (len < sizeof p) break; - p = (uint32_t *) (b->data + b->tail); + wl_connection_copy(display->connection, p, sizeof p); opcode = p[1] & 0xffff; size = p[1] >> 16; - if (b->head - b->tail < size) + if (len < size) break; - handle_event(connection); + handle_event(display->connection); } if (len < 0) { @@ -142,52 +136,25 @@ wl_connection_iterate(struct wl_connection *connection) } } -int -wl_connection_flush(struct wl_connection *connection) -{ - struct wl_buffer *b; - int len; - - b = &connection->out; - if (b->head == b->tail) - return 0; - - len = write(connection->fd, b->data + b->tail, b->head - b->tail); - b->tail += len; - - return len; -}; - -struct wl_display * -wl_connection_get_display(struct wl_connection *connection) -{ - return connection->display; -} - #define WL_DISPLAY_CREATE_SURFACE 0 struct wl_surface * wl_display_create_surface(struct wl_display *display) { struct wl_surface *surface; - struct wl_connection *connection; uint32_t request[3]; surface = malloc(sizeof *surface); if (surface == NULL) return NULL; - connection = display->proxy.connection; - surface->proxy.id = connection->id++; - surface->proxy.connection = connection; + surface->proxy.id = display->id++; + surface->proxy.display = display; request[0] = display->proxy.id; request[1] = WL_DISPLAY_CREATE_SURFACE | ((sizeof request) << 16); request[2] = surface->proxy.id; - - memcpy(connection->out.data + connection->out.head, - request, sizeof request); - connection->out.head += sizeof request; + wl_connection_write(display->connection, request, sizeof request); return surface; } @@ -199,22 +166,18 @@ wl_display_create_surface(struct wl_display *display) void wl_surface_destroy(struct wl_surface *surface) { uint32_t request[2]; - struct wl_connection *connection; request[0] = surface->proxy.id; request[1] = WL_SURFACE_DESTROY | ((sizeof request) << 16); - connection = surface->proxy.connection; - memcpy(connection->out.data + connection->out.head, - request, sizeof request); - connection->out.head += sizeof request; + wl_connection_write(surface->proxy.display->connection, + request, sizeof request); } void wl_surface_attach(struct wl_surface *surface, uint32_t name, int width, int height, int stride) { uint32_t request[6]; - struct wl_connection *connection; request[0] = surface->proxy.id; request[1] = WL_SURFACE_ATTACH | ((sizeof request) << 16); @@ -223,10 +186,8 @@ void wl_surface_attach(struct wl_surface *surface, request[4] = height; request[5] = stride; - connection = surface->proxy.connection; - memcpy(connection->out.data + connection->out.head, - request, sizeof request); - connection->out.head += sizeof request; + wl_connection_write(surface->proxy.display->connection, + request, sizeof request); } @@ -234,7 +195,6 @@ void wl_surface_map(struct wl_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height) { uint32_t request[6]; - struct wl_connection *connection; request[0] = surface->proxy.id; request[1] = WL_SURFACE_MAP | ((sizeof request) << 16); @@ -243,8 +203,6 @@ void wl_surface_map(struct wl_surface *surface, request[4] = width; request[5] = height; - connection = surface->proxy.connection; - memcpy(connection->out.data + connection->out.head, - request, sizeof request); - connection->out.head += sizeof request; + wl_connection_write(surface->proxy.display->connection, + request, sizeof request); } diff --git a/wayland-client.h b/wayland-client.h index 2d6c799a..843b43fb 100644 --- a/wayland-client.h +++ b/wayland-client.h @@ -1,23 +1,17 @@ #ifndef _WAYLAND_CLIENT_H #define _WAYLAND_CLIENT_H -struct wl_connection; +#include "connection.h" + struct wl_display; struct wl_surface; -struct wl_connection * -wl_connection_create(const char *address); -void -wl_connection_destroy(struct wl_connection *connection); -int -wl_connection_get_fd(struct wl_connection *connection); -void -wl_connection_iterate(struct wl_connection *connection); -int -wl_connection_flush(struct wl_connection *connection); +struct wl_display *wl_display_create(const char *address, + wl_connection_update_func_t update, void *data); +void wl_display_destroy(struct wl_display *display); +int wl_display_get_fd(struct wl_display *display); +void wl_display_iterate(struct wl_display *display, uint32_t mask); -struct wl_display * -wl_connection_get_display(struct wl_connection *connection); struct wl_surface * wl_display_create_surface(struct wl_display *display);