blob: 98cb341c315f4ec5705ea889e0566a1ee8409e7c [file] [log] [blame]
Kristian Høgsbergffd710e2008-12-02 15:15:01 -05001/*
2 * Copyright © 2008 Kristian Høgsberg
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040023#include <stdlib.h>
24#include <stdint.h>
25#include <stddef.h>
26#include <stdio.h>
Kristian Høgsbergc2b633e2008-11-28 19:12:45 -050027#include <stdarg.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040028#include <errno.h>
29#include <string.h>
30#include <unistd.h>
31#include <sys/socket.h>
32#include <sys/un.h>
Kristian Høgsberg5503bf82008-11-06 10:38:17 -050033#include <dlfcn.h>
Kristian Høgsbergc2b633e2008-11-28 19:12:45 -050034#include <assert.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040035#include <ffi.h>
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040036
Kristian Høgsbergfe831a72008-12-21 21:50:23 -050037#include "wayland-protocol.h"
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040038#include "wayland.h"
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040039#include "connection.h"
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040040
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040041struct wl_client {
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040042 struct wl_connection *connection;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040043 struct wl_event_source *source;
44 struct wl_display *display;
Kristian Høgsberg94a2e862008-10-11 21:37:55 -040045 struct wl_list object_list;
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -050046 struct wl_list link;
Kristian Høgsberg97079ad2008-12-21 22:45:33 -050047 uint32_t id_count;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040048};
49
50struct wl_display {
51 struct wl_object base;
52 struct wl_event_loop *loop;
Kristian Høgsberg864c4682008-12-12 11:05:17 -050053 struct wl_hash *objects;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040054
Kristian Høgsbergd2412e22008-12-15 20:35:24 -050055 struct wl_list pending_frame_list;
Kristian Høgsbergf9212892008-10-11 18:40:23 -040056 uint32_t client_id_range;
Kristian Høgsberg1e4b86a2008-11-23 23:41:08 -050057 uint32_t id;
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -050058
Kristian Høgsberg14fcff72008-11-23 19:10:23 -050059 struct wl_list global_list;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040060};
61
Kristian Høgsberg94a2e862008-10-11 21:37:55 -040062struct wl_object_ref {
63 struct wl_object *object;
64 struct wl_list link;
65};
Kristian Høgsbergdc0f3552008-12-07 15:22:22 -050066
Kristian Høgsbergee02ca62008-12-21 23:37:12 -050067struct wl_global {
68 struct wl_object *object;
69 wl_client_connect_func_t func;
70 struct wl_list link;
71};
72
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040073void
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040074wl_client_destroy(struct wl_client *client);
Kristian Høgsbergc5089872008-10-08 10:47:59 -040075
Kristian Høgsbergee02ca62008-12-21 23:37:12 -050076WL_EXPORT void
77wl_client_post_event(struct wl_client *client, struct wl_object *sender,
78 uint32_t opcode, ...)
79{
80 va_list ap;
81
82 va_start(ap, opcode);
Kristian Høgsbergb3131d92008-12-24 19:30:25 -050083 wl_connection_vmarshal(client->connection,
84 sender, opcode, ap,
85 &sender->interface->events[opcode]);
Kristian Høgsbergee02ca62008-12-21 23:37:12 -050086 va_end(ap);
87}
88
Kristian Høgsberg5a75c902008-12-10 13:16:50 -050089static void
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040090wl_client_connection_data(int fd, uint32_t mask, void *data)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040091{
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040092 struct wl_client *client = data;
93 struct wl_connection *connection = client->connection;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040094 struct wl_object *object;
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040095 uint32_t p[2], opcode, size;
96 uint32_t cmask = 0;
97 int len;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040098
Kristian Høgsberg680f1c72008-10-08 12:48:46 -040099 if (mask & WL_EVENT_READABLE)
100 cmask |= WL_CONNECTION_READABLE;
101 if (mask & WL_EVENT_WRITEABLE)
102 cmask |= WL_CONNECTION_WRITABLE;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400103
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400104 len = wl_connection_data(connection, cmask);
105 if (len < 0) {
106 wl_client_destroy(client);
107 return;
108 }
Kristian Høgsbergc5089872008-10-08 10:47:59 -0400109
Kristian Høgsberg1e4b86a2008-11-23 23:41:08 -0500110 while (len >= sizeof p) {
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400111 wl_connection_copy(connection, p, sizeof p);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400112 opcode = p[1] & 0xffff;
113 size = p[1] >> 16;
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400114 if (len < size)
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400115 break;
116
Kristian Høgsberg864c4682008-12-12 11:05:17 -0500117 object = wl_hash_lookup(client->display->objects, p[0]);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400118 if (object == NULL) {
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500119 wl_client_post_event(client, &client->display->base,
120 WL_DISPLAY_INVALID_OBJECT, p[0]);
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400121 wl_connection_consume(connection, size);
122 len -= size;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400123 continue;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400124 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400125
126 if (opcode >= object->interface->method_count) {
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500127 wl_client_post_event(client, &client->display->base,
128 WL_DISPLAY_INVALID_METHOD, p[0], opcode);
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400129 wl_connection_consume(connection, size);
130 len -= size;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400131 continue;
132 }
133
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500134 wl_connection_demarshal(client->connection,
135 size,
136 client->display->objects,
137 object->implementation[opcode],
138 client,
139 object,
140 &object->interface->methods[opcode]);
141
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400142 wl_connection_consume(connection, size);
143 len -= size;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400144 }
145}
146
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400147static int
148wl_client_connection_update(struct wl_connection *connection,
149 uint32_t mask, void *data)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400150{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400151 struct wl_client *client = data;
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400152 uint32_t emask = 0;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400153
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400154 if (mask & WL_CONNECTION_READABLE)
155 emask |= WL_EVENT_READABLE;
156 if (mask & WL_CONNECTION_WRITABLE)
157 emask |= WL_EVENT_WRITEABLE;
Kristian Høgsbergc5089872008-10-08 10:47:59 -0400158
Kristian Høgsberg4a298902008-11-28 18:35:25 -0500159 return wl_event_source_fd_update(client->source, mask);
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400160}
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400161
Kristian Høgsberg97079ad2008-12-21 22:45:33 -0500162static void
163wl_display_post_range(struct wl_display *display, struct wl_client *client)
164{
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500165 wl_client_post_event(client, &client->display->base,
166 WL_DISPLAY_RANGE, display->client_id_range);
Kristian Høgsberg97079ad2008-12-21 22:45:33 -0500167 display->client_id_range += 256;
168 client->id_count += 256;
169}
170
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500171static struct wl_client *
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400172wl_client_create(struct wl_display *display, int fd)
173{
174 struct wl_client *client;
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500175 struct wl_global *global;
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400176
177 client = malloc(sizeof *client);
178 if (client == NULL)
179 return NULL;
180
181 memset(client, 0, sizeof *client);
182 client->display = display;
183 client->source = wl_event_loop_add_fd(display->loop, fd,
184 WL_EVENT_READABLE,
185 wl_client_connection_data, client);
Kristian Høgsberg97079ad2008-12-21 22:45:33 -0500186 client->connection =
187 wl_connection_create(fd, wl_client_connection_update, client);
188
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400189 wl_list_init(&client->object_list);
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500190 wl_list_init(&client->link);
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400191
Kristian Høgsberg97079ad2008-12-21 22:45:33 -0500192 wl_display_post_range(display, client);
Kristian Høgsbergf9212892008-10-11 18:40:23 -0400193
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500194 global = container_of(display->global_list.next,
195 struct wl_global, link);
196 while (&global->link != &display->global_list) {
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500197 wl_client_post_event(client, &client->display->base,
198 WL_DISPLAY_GLOBAL,
199 global->object,
200 global->object->interface->name,
201 global->object->interface->version);
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500202 global = container_of(global->link.next,
203 struct wl_global, link);
204 }
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500205
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500206 global = container_of(display->global_list.next,
207 struct wl_global, link);
208 while (&global->link != &display->global_list) {
209 if (global->func)
210 global->func(client, global->object);
211 global = container_of(global->link.next,
212 struct wl_global, link);
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500213 }
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400214
215 return client;
216}
217
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500218static void
219wl_object_destroy(struct wl_object *object)
220{
221 const struct wl_surface_interface *interface =
222 (const struct wl_surface_interface *) object->implementation;
223
224 /* FIXME: Need generic object destructor. */
225 interface->destroy(NULL, (struct wl_surface *) object);
226}
227
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400228void
229wl_client_destroy(struct wl_client *client)
230{
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400231 struct wl_object_ref *ref;
232
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400233 printf("disconnect from client %p\n", client);
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400234
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -0500235 wl_list_remove(&client->link);
236
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400237 while (client->object_list.next != &client->object_list) {
238 ref = container_of(client->object_list.next,
239 struct wl_object_ref, link);
240 wl_list_remove(&ref->link);
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500241 wl_object_destroy(ref->object);
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400242 free(ref);
243 }
244
Kristian Høgsberg4a298902008-11-28 18:35:25 -0500245 wl_event_source_remove(client->source);
Kristian Høgsberg680f1c72008-10-08 12:48:46 -0400246 wl_connection_destroy(client->connection);
247 free(client);
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400248}
249
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500250WL_EXPORT int
251wl_client_add_surface(struct wl_client *client,
252 struct wl_surface *surface,
253 const struct wl_surface_interface *implementation,
254 uint32_t id)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400255{
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500256 struct wl_display *display = client->display;
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400257 struct wl_object_ref *ref;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400258
Kristian Høgsberg97079ad2008-12-21 22:45:33 -0500259 if (client->id_count-- < 64)
260 wl_display_post_range(display, client);
261
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500262 surface->base.id = id;
Kristian Høgsbergfe831a72008-12-21 21:50:23 -0500263 surface->base.interface = &wl_surface_interface;
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500264 surface->base.implementation = (void (**)(void)) implementation;
265 surface->client = client;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400266
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400267 ref = malloc(sizeof *ref);
268 if (ref == NULL) {
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500269 wl_client_post_event(client, &display->base,
270 WL_DISPLAY_NO_MEMORY);
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400271 return -1;
272 }
273
274 ref->object = &surface->base;
Kristian Høgsberg864c4682008-12-12 11:05:17 -0500275 wl_hash_insert(display->objects, &surface->base);
Kristian Høgsberg94a2e862008-10-11 21:37:55 -0400276 wl_list_insert(client->object_list.prev, &ref->link);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400277
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400278 return 0;
279}
280
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500281WL_EXPORT void
282wl_client_send_acknowledge(struct wl_client *client,
283 struct wl_compositor *compositor,
284 uint32_t key, uint32_t frame)
Kristian Høgsberg40979232008-11-25 22:40:39 -0500285{
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500286 wl_list_remove(&client->link);
287 wl_list_insert(client->display->pending_frame_list.prev,
288 &client->link);
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500289 wl_client_post_event(client, &compositor->base,
290 WL_COMPOSITOR_ACKNOWLEDGE, key, frame);
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500291}
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500292
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500293WL_EXPORT int
294wl_display_set_compositor(struct wl_display *display,
295 struct wl_compositor *compositor,
296 const struct wl_compositor_interface *implementation)
297{
Kristian Høgsbergfe831a72008-12-21 21:50:23 -0500298 compositor->base.interface = &wl_compositor_interface;
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500299 compositor->base.implementation = (void (**)(void)) implementation;
300
301 wl_display_add_object(display, &compositor->base);
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500302 if (wl_display_add_global(display, &compositor->base, NULL))
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500303 return -1;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500304
305 return 0;
306}
307
Kristian Høgsberg122912c2008-12-05 11:13:50 -0500308WL_EXPORT struct wl_display *
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400309wl_display_create(void)
310{
311 struct wl_display *display;
312
313 display = malloc(sizeof *display);
314 if (display == NULL)
315 return NULL;
316
317 display->loop = wl_event_loop_create();
318 if (display->loop == NULL) {
319 free(display);
320 return NULL;
321 }
322
Kristian Høgsberg864c4682008-12-12 11:05:17 -0500323 display->objects = wl_hash_create();
324 if (display->objects == NULL) {
325 free(display);
326 return NULL;
327 }
328
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500329 wl_list_init(&display->pending_frame_list);
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500330 wl_list_init(&display->global_list);
Kristian Høgsbergf9bc7952008-11-02 10:12:29 -0500331
Kristian Høgsbergf9212892008-10-11 18:40:23 -0400332 display->client_id_range = 256; /* Gah, arbitrary... */
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400333
Kristian Høgsberg1e4b86a2008-11-23 23:41:08 -0500334 display->id = 1;
Kristian Høgsbergfe831a72008-12-21 21:50:23 -0500335 display->base.interface = &wl_display_interface;
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500336 display->base.implementation = NULL;
Kristian Høgsberg1e4b86a2008-11-23 23:41:08 -0500337 wl_display_add_object(display, &display->base);
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500338 if (wl_display_add_global(display, &display->base, NULL)) {
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500339 wl_event_loop_destroy(display->loop);
340 free(display);
341 return NULL;
342 }
343
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400344 return display;
345}
346
Kristian Høgsberg1e4b86a2008-11-23 23:41:08 -0500347WL_EXPORT void
348wl_display_add_object(struct wl_display *display, struct wl_object *object)
349{
350 object->id = display->id++;
Kristian Høgsberg864c4682008-12-12 11:05:17 -0500351 wl_hash_insert(display->objects, object);
Kristian Høgsberg1e4b86a2008-11-23 23:41:08 -0500352}
353
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500354WL_EXPORT int
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500355wl_display_add_global(struct wl_display *display,
356 struct wl_object *object, wl_client_connect_func_t func)
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500357{
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500358 struct wl_global *global;
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500359
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500360 global = malloc(sizeof *global);
361 if (global == NULL)
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500362 return -1;
363
Kristian Høgsbergee02ca62008-12-21 23:37:12 -0500364 global->object = object;
365 global->func = func;
366 wl_list_insert(display->global_list.prev, &global->link);
Kristian Høgsberg14fcff72008-11-23 19:10:23 -0500367
368 return 0;
369}
370
Kristian Høgsbergcddc0ad2008-11-24 00:31:49 -0500371WL_EXPORT void
Kristian Høgsberg5a75c902008-12-10 13:16:50 -0500372wl_surface_post_event(struct wl_surface *surface,
373 struct wl_object *sender,
374 uint32_t event, ...)
Kristian Høgsberg715a0812008-12-10 10:42:04 -0500375{
Kristian Høgsberg5a75c902008-12-10 13:16:50 -0500376 va_list ap;
Kristian Høgsberg715a0812008-12-10 10:42:04 -0500377
Kristian Høgsberg5a75c902008-12-10 13:16:50 -0500378 va_start(ap, event);
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500379 wl_connection_vmarshal(surface->client->connection,
380 sender, event, ap,
381 &sender->interface->events[event]);
Kristian Høgsberg5a75c902008-12-10 13:16:50 -0500382 va_end(ap);
Kristian Høgsberg715a0812008-12-10 10:42:04 -0500383}
384
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500385WL_EXPORT void
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500386wl_display_post_frame(struct wl_display *display,
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500387 struct wl_compositor *compositor,
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500388 uint32_t frame, uint32_t msecs)
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500389{
390 struct wl_client *client;
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500391
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500392 client = container_of(display->pending_frame_list.next,
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500393 struct wl_client, link);
394
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500395 while (&client->link != &display->pending_frame_list) {
Kristian Høgsbergb3131d92008-12-24 19:30:25 -0500396 wl_client_post_event(client, &compositor->base,
397 WL_COMPOSITOR_FRAME, frame, msecs);
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500398 client = container_of(client->link.next,
399 struct wl_client, link);
400 }
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500401
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500402 wl_list_remove(&display->pending_frame_list);
403 wl_list_init(&display->pending_frame_list);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400404}
405
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500406WL_EXPORT struct wl_event_loop *
Kristian Høgsberg5ebb3172008-10-11 19:21:35 -0400407wl_display_get_event_loop(struct wl_display *display)
408{
409 return display->loop;
410}
411
Kristian Høgsberg122912c2008-12-05 11:13:50 -0500412WL_EXPORT void
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400413wl_display_run(struct wl_display *display)
414{
415 while (1)
416 wl_event_loop_wait(display->loop);
417}
418
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400419static void
420socket_data(int fd, uint32_t mask, void *data)
421{
422 struct wl_display *display = data;
423 struct sockaddr_un name;
424 socklen_t length;
425 int client_fd;
426
427 length = sizeof name;
428 client_fd = accept (fd, (struct sockaddr *) &name, &length);
429 if (client_fd < 0)
430 fprintf(stderr, "failed to accept\n");
431
432 wl_client_create(display, client_fd);
433}
434
Kristian Høgsberg122912c2008-12-05 11:13:50 -0500435WL_EXPORT int
Kristian Høgsbergdc0f3552008-12-07 15:22:22 -0500436wl_display_add_socket(struct wl_display *display,
437 const char *name, size_t name_size)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400438{
Kristian Høgsbergdc0f3552008-12-07 15:22:22 -0500439 struct sockaddr_un addr;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400440 int sock;
441 socklen_t size;
442
443 sock = socket(PF_LOCAL, SOCK_STREAM, 0);
444 if (sock < 0)
445 return -1;
446
Kristian Høgsbergdc0f3552008-12-07 15:22:22 -0500447 addr.sun_family = AF_LOCAL;
448 memcpy(addr.sun_path, name, name_size);
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400449
Kristian Høgsbergdc0f3552008-12-07 15:22:22 -0500450 size = offsetof (struct sockaddr_un, sun_path) + name_size;
451 if (bind(sock, (struct sockaddr *) &addr, size) < 0)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400452 return -1;
453
454 if (listen(sock, 1) < 0)
455 return -1;
456
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400457 wl_event_loop_add_fd(display->loop, sock,
458 WL_EVENT_READABLE,
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400459 socket_data, display);
460
461 return 0;
462}