void wl_connection_sync(struct wl_connection *connection) { uint32_t p[2]; struct wl_buffer *b; int size, avail, head; b = &connection->in; size = sizeof p; do { head = connection->in.head; if (head < b->tail) avail = ARRAY_LENGTH(b->data) - (b->tail - head); else avail = head - b->tail; if (avail < size) wl_connection_data(connection, WL_CONNECTION_READABLE); else if (size == sizeof p) { /* If the header is available, get the full size. */ wl_connection_copy(connection, p, sizeof p); size = p[1] >> 16; } } while (avail < size); }
static struct wl_backend * wl_display_create_backend(struct wl_display *display, struct wl_proxy *backend_adv) { uint32_t id; struct wl_backend *be; struct { char *device, *driver; } reply; wl_connection_marshal(display->connection, NULL, backend_adv->id, 0, ""); wl_connection_data(display->connection, WL_CONNECTION_WRITABLE); wl_connection_sync(display->connection); /* FIXME: we expect no other events to arrive. */ id = wl_connection_demarshal_mem(display->connection, NULL, &reply, sizeof reply, "|ss"); if (id != backend_adv->id) abort (); be = _wl_backend_create (reply.device, reply.driver, 0); free (reply.device); free (reply.driver); return be; }
WL_EXPORT void wl_display_iterate(struct wl_display *display, uint32_t mask) { uint32_t p[2], opcode, size; int len; len = wl_connection_data(display->connection, mask); while (len > 0) { if (len < sizeof p) break; wl_connection_copy(display->connection, p, sizeof p); opcode = p[1] & 0xffff; size = p[1] >> 16; if (len < size) break; handle_event(display, p[0], opcode, size); len -= size; } if (len < 0) { fprintf(stderr, "read error: %m\n"); exit(EXIT_FAILURE); } }
static void marshal(struct marshal_data *data, const char *format, int size, ...) { struct wl_closure *closure; static const uint32_t opcode = 4444; static struct wl_object sender = { NULL, NULL, 1234 }; struct wl_message message = { "test", format, NULL }; va_list ap; va_start(ap, size); closure = wl_closure_vmarshal(&sender, opcode, ap, &message); va_end(ap); assert(closure); assert(wl_closure_send(closure, data->write_connection) == 0); wl_closure_destroy(closure); assert(data->write_mask == (WL_CONNECTION_WRITABLE | WL_CONNECTION_READABLE)); assert(wl_connection_data(data->write_connection, WL_CONNECTION_WRITABLE) == 0); assert(data->write_mask == WL_CONNECTION_READABLE); assert(read(data->s[0], data->buffer, sizeof data->buffer) == size); assert(data->buffer[0] == sender.id); assert(data->buffer[1] == (opcode | (size << 16))); }
static int wl_connection_put_fd(struct wl_connection *connection, int32_t fd) { if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) if (wl_connection_data(connection, WL_CONNECTION_WRITABLE)) return -1; wl_buffer_put(&connection->fds_out, &fd, sizeof fd); return 0; }
int wl_connection_queue(struct wl_connection *connection, const void *data, size_t count) { if (connection->out.head - connection->out.tail + count > ARRAY_LENGTH(connection->out.data)) if (wl_connection_data(connection, WL_CONNECTION_WRITABLE)) return -1; wl_buffer_put(&connection->out, data, count); return 0; }
static void marshal_demarshal(struct marshal_data *data, void (*func)(void), int size, const char *format, ...) { struct wl_closure *closure; static const int opcode = 4444; static struct wl_object sender = { NULL, NULL, 1234 }; struct wl_message message = { "test", format, NULL }; struct wl_map objects; struct wl_object object; va_list ap; uint32_t msg[1] = { 1234 }; va_start(ap, format); closure = wl_closure_vmarshal(&sender, opcode, ap, &message); va_end(ap); assert(closure); assert(wl_closure_send(closure, data->write_connection) == 0); wl_closure_destroy(closure); assert(data->write_mask == (WL_CONNECTION_WRITABLE | WL_CONNECTION_READABLE)); assert(wl_connection_data(data->write_connection, WL_CONNECTION_WRITABLE) == 0); assert(data->write_mask == WL_CONNECTION_READABLE); assert(wl_connection_data(data->read_connection, WL_CONNECTION_READABLE) == size); wl_map_init(&objects); object.id = msg[0]; closure = wl_connection_demarshal(data->read_connection, size, &objects, &message); wl_closure_invoke(closure, &object, func, data); wl_closure_destroy(closure); }
int wl_connection_write(struct wl_connection *connection, const void *data, size_t count) { if (connection->out.head - connection->out.tail + count > ARRAY_LENGTH(connection->out.data)) if (wl_connection_data(connection, WL_CONNECTION_WRITABLE)) return -1; wl_buffer_put(&connection->out, data, count); if (!connection->write_signalled) { connection->update(connection, WL_CONNECTION_READABLE | WL_CONNECTION_WRITABLE, connection->data); connection->write_signalled = 1; } return 0; }
static void demarshal(struct marshal_data *data, const char *format, uint32_t *msg, void (*func)(void)) { struct wl_message message = { "test", format, NULL }; struct wl_closure *closure; struct wl_map objects; struct wl_object object; int size = msg[1]; assert(write(data->s[1], msg, size) == size); assert(wl_connection_data(data->read_connection, WL_CONNECTION_READABLE) == size); wl_map_init(&objects); object.id = msg[0]; closure = wl_connection_demarshal(data->read_connection, size, &objects, &message); assert(closure); wl_closure_invoke(closure, &object, func, data); wl_closure_destroy(closure); }