summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2008-12-21 22:45:33 -0500
committerKristian Høgsberg <krh@redhat.com>2008-12-21 22:45:33 -0500
commit97079ad52c313d4b622110cae978ee7c2392b714 (patch)
tree004e03287519426cee79da9b9e5dfe5a4b440157
parentfb6d68ddbe76d2cf716bf6075e6e1afe2caaea1e (diff)
downloadwayland-97079ad52c313d4b622110cae978ee7c2392b714.tar.gz
wayland-97079ad52c313d4b622110cae978ee7c2392b714.tar.xz
wayland-97079ad52c313d4b622110cae978ee7c2392b714.zip
Send client id range as an event.
This also makes the server send the event again when the client is about to exhaust its current client range.
-rw-r--r--wayland-client.c74
-rw-r--r--wayland-protocol.c1
-rw-r--r--wayland-protocol.h1
-rw-r--r--wayland.c24
4 files changed, 68 insertions, 32 deletions
diff --git a/wayland-client.c b/wayland-client.c
index a898fd2..8a597f5 100644
--- a/wayland-client.c
+++ b/wayland-client.c
@@ -57,7 +57,7 @@ struct wl_display {
struct wl_proxy proxy;
struct wl_connection *connection;
int fd;
- uint32_t id;
+ uint32_t id, id_count, next_range;
uint32_t mask;
struct wl_list global_list;
struct wl_list visual_list;
@@ -162,10 +162,6 @@ wl_display_create(const char *name, size_t name_size)
return NULL;
}
- /* FIXME: We'll need a protocol for getting a new range, I
- * guess... */
- read(display->fd, &display->id, sizeof display->id);
-
wl_list_init(&display->global_list);
wl_list_init(&display->visual_list);
@@ -222,29 +218,50 @@ wl_display_get_fd(struct wl_display *display,
}
static void
-handle_global(struct wl_display *display, uint32_t *p, uint32_t size)
+handle_display_event(struct wl_display *display,
+ uint32_t opcode, uint32_t *p, uint32_t size)
{
struct wl_global *global;
uint32_t length;
- global = malloc(sizeof *global);
- if (global == NULL)
- return;
-
- global->id = p[0];
- length = p[1];
- global->interface = malloc(length + 1);
- if (global->interface == NULL) {
- free(global);
- return;
+ switch (opcode) {
+ case WL_DISPLAY_INVALID_OBJECT:
+ fprintf(stderr, "sent request to invalid object\n");
+ break;
+
+ case WL_DISPLAY_INVALID_METHOD:
+ fprintf(stderr, "sent invalid request opcode\n");
+ break;
+
+ case WL_DISPLAY_NO_MEMORY:
+ fprintf(stderr, "server out of memory\n");
+ break;
+
+ case WL_DISPLAY_GLOBAL:
+ global = malloc(sizeof *global);
+ if (global == NULL)
+ return;
+
+ global->id = p[0];
+ length = p[1];
+ global->interface = malloc(length + 1);
+ if (global->interface == NULL) {
+ free(global);
+ return;
+ }
+ memcpy(global->interface, &p[2], length);
+ global->interface[length] = '\0';
+ global->version = p[2 + DIV_ROUNDUP(length, sizeof *p)];
+ wl_list_insert(display->global_list.prev, &global->link);
+
+ if (strcmp(global->interface, "visual") == 0)
+ add_visual(display, global);
+ break;
+
+ case WL_DISPLAY_RANGE:
+ display->next_range = p[0];
+ break;
}
- memcpy(global->interface, &p[2], length);
- global->interface[length] = '\0';
- global->version = p[2 + DIV_ROUNDUP(length, sizeof *p)];
- wl_list_insert(display->global_list.prev, &global->link);
-
- if (strcmp(global->interface, "visual") == 0)
- add_visual(display, global);
}
static void
@@ -254,8 +271,8 @@ handle_event(struct wl_display *display,
uint32_t p[32];
wl_connection_copy(display->connection, p, size);
- if (object == 1 && opcode == WL_DISPLAY_GLOBAL) {
- handle_global(display, p + 2, size);
+ if (object == 1) {
+ handle_display_event(display, opcode, p + 2, size);
} else if (display->event_handler != NULL)
display->event_handler(display, object, opcode, size, p + 2,
display->event_handler_data);
@@ -303,6 +320,13 @@ wl_display_set_event_handler(struct wl_display *display,
WL_EXPORT uint32_t
wl_display_allocate_id(struct wl_display *display)
{
+ if (display->id_count == 0) {
+ display->id_count = 256;
+ display->id = display->next_range;
+ }
+
+ display->id_count--;
+
return display->id++;
}
diff --git a/wayland-protocol.c b/wayland-protocol.c
index 5b20154..4c61810 100644
--- a/wayland-protocol.c
+++ b/wayland-protocol.c
@@ -30,6 +30,7 @@ static const struct wl_message display_events[] = {
{ "invalid_method", "uu" },
{ "no_memory", "" },
{ "global", "osu" },
+ { "range", "u" },
};
WL_EXPORT const struct wl_interface wl_display_interface = {
diff --git a/wayland-protocol.h b/wayland-protocol.h
index f5deea3..c71cfdc 100644
--- a/wayland-protocol.h
+++ b/wayland-protocol.h
@@ -49,6 +49,7 @@ struct wl_interface {
#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;
diff --git a/wayland.c b/wayland.c
index 48e1513..6ad1887 100644
--- a/wayland.c
+++ b/wayland.c
@@ -44,6 +44,7 @@ struct wl_client {
struct wl_display *display;
struct wl_list object_list;
struct wl_list link;
+ uint32_t id_count;
};
struct wl_display {
@@ -270,6 +271,15 @@ wl_client_connection_update(struct wl_connection *connection,
return wl_event_source_fd_update(client->source, mask);
}
+static void
+wl_display_post_range(struct wl_display *display, struct wl_client *client)
+{
+ wl_client_marshal(client, &client->display->base,
+ WL_DISPLAY_RANGE, display->client_id_range);
+ display->client_id_range += 256;
+ client->id_count += 256;
+}
+
static struct wl_client *
wl_client_create(struct wl_display *display, int fd)
{
@@ -285,16 +295,13 @@ wl_client_create(struct wl_display *display, int fd)
client->source = wl_event_loop_add_fd(display->loop, fd,
WL_EVENT_READABLE,
wl_client_connection_data, client);
- client->connection = wl_connection_create(fd,
- wl_client_connection_update,
- client);
+ client->connection =
+ wl_connection_create(fd, wl_client_connection_update, client);
+
wl_list_init(&client->object_list);
wl_list_init(&client->link);
- wl_connection_write(client->connection,
- &display->client_id_range,
- sizeof display->client_id_range);
- display->client_id_range += 256;
+ wl_display_post_range(display, client);
ref = container_of(display->global_list.next,
struct wl_object_ref, link);
@@ -353,6 +360,9 @@ wl_client_add_surface(struct wl_client *client,
struct wl_display *display = client->display;
struct wl_object_ref *ref;
+ if (client->id_count-- < 64)
+ wl_display_post_range(display, client);
+
surface->base.id = id;
surface->base.interface = &wl_surface_interface;
surface->base.implementation = (void (**)(void)) implementation;