mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-04-08 08:21:16 -04:00
Fill out a closure when sending events as well
This commit is contained in:
parent
4f14f6e109
commit
7cd36185d7
1 changed files with 86 additions and 41 deletions
127
connection.c
127
connection.c
|
|
@ -331,6 +331,32 @@ wl_connection_write(struct wl_connection *connection,
|
||||||
connection->data);
|
connection->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
wl_message_size_extra(const struct wl_message *message)
|
||||||
|
{
|
||||||
|
int i, extra;
|
||||||
|
|
||||||
|
for (i = 0, extra = 0; message->signature[i]; i++) {
|
||||||
|
|
||||||
|
switch (message->signature[i]) {
|
||||||
|
case 's':
|
||||||
|
case 'o':
|
||||||
|
extra += sizeof (void *);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
extra += sizeof (void *) + sizeof (struct wl_array);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
extra += sizeof (uint32_t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extra;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wl_connection_vmarshal(struct wl_connection *connection,
|
wl_connection_vmarshal(struct wl_connection *connection,
|
||||||
struct wl_object *sender,
|
struct wl_object *sender,
|
||||||
|
|
@ -338,36 +364,74 @@ wl_connection_vmarshal(struct wl_connection *connection,
|
||||||
const struct wl_message *message)
|
const struct wl_message *message)
|
||||||
{
|
{
|
||||||
struct wl_closure *closure = &connection->closure;
|
struct wl_closure *closure = &connection->closure;
|
||||||
struct wl_object *object;
|
struct wl_object **objectp, *object;
|
||||||
uint32_t length, *p, size;
|
uint32_t length, *p, *start, size;
|
||||||
int dup_fd;
|
int dup_fd;
|
||||||
struct wl_array *array;
|
struct wl_array **arrayp, *array;
|
||||||
const char *s;
|
const char **sp, *s;
|
||||||
int i, count, fd;
|
char *extra;
|
||||||
|
int i, count, fd, extra_size;
|
||||||
|
|
||||||
count = strlen(message->signature);
|
extra_size = wl_message_size_extra(message);
|
||||||
p = &closure->buffer[2];
|
closure->message = message;
|
||||||
for (i = 0; i < count; i++) {
|
count = strlen(message->signature) + 2;
|
||||||
switch (message->signature[i]) {
|
extra = (char *) closure->buffer;
|
||||||
|
start = &closure->buffer[DIV_ROUNDUP(extra_size, sizeof *p)];
|
||||||
|
p = &start[2];
|
||||||
|
for (i = 2; i < count; i++) {
|
||||||
|
switch (message->signature[i - 2]) {
|
||||||
case 'u':
|
case 'u':
|
||||||
|
closure->types[i] = &ffi_type_uint32;
|
||||||
|
closure->args[i] = p;
|
||||||
*p++ = va_arg(ap, uint32_t);
|
*p++ = va_arg(ap, uint32_t);
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
|
closure->types[i] = &ffi_type_sint32;
|
||||||
|
closure->args[i] = p;
|
||||||
*p++ = va_arg(ap, int32_t);
|
*p++ = va_arg(ap, int32_t);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
|
closure->types[i] = &ffi_type_pointer;
|
||||||
|
closure->args[i] = extra;
|
||||||
|
sp = (const char **) extra;
|
||||||
|
extra += sizeof *sp;
|
||||||
|
|
||||||
s = va_arg(ap, const char *);
|
s = va_arg(ap, const char *);
|
||||||
length = s ? strlen(s) + 1: 0;
|
length = s ? strlen(s) + 1: 0;
|
||||||
*p++ = length;
|
*p++ = length;
|
||||||
|
|
||||||
|
*sp = (const char *) p;
|
||||||
|
|
||||||
memcpy(p, s, length);
|
memcpy(p, s, length);
|
||||||
p += DIV_ROUNDUP(length, sizeof(*p));
|
p += DIV_ROUNDUP(length, sizeof *p);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'n':
|
closure->types[i] = &ffi_type_pointer;
|
||||||
|
closure->args[i] = extra;
|
||||||
|
objectp = (struct wl_object **) extra;
|
||||||
|
extra += sizeof *objectp;
|
||||||
|
|
||||||
object = va_arg(ap, struct wl_object *);
|
object = va_arg(ap, struct wl_object *);
|
||||||
|
*objectp = object;
|
||||||
*p++ = object ? object->id : 0;
|
*p++ = object ? object->id : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
closure->types[i] = &ffi_type_uint32;
|
||||||
|
closure->args[i] = p;
|
||||||
|
object = va_arg(ap, struct wl_object *);
|
||||||
|
*p++ = object->id;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
|
closure->types[i] = &ffi_type_pointer;
|
||||||
|
closure->args[i] = extra;
|
||||||
|
arrayp = (struct wl_array **) extra;
|
||||||
|
extra += sizeof *arrayp;
|
||||||
|
|
||||||
|
*arrayp = (struct wl_array *) extra;
|
||||||
|
extra += sizeof **arrayp;
|
||||||
|
|
||||||
array = va_arg(ap, struct wl_array *);
|
array = va_arg(ap, struct wl_array *);
|
||||||
if (array == NULL || array->size == 0) {
|
if (array == NULL || array->size == 0) {
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
|
|
@ -375,8 +439,14 @@ wl_connection_vmarshal(struct wl_connection *connection,
|
||||||
}
|
}
|
||||||
*p++ = array->size;
|
*p++ = array->size;
|
||||||
memcpy(p, array->data, array->size);
|
memcpy(p, array->data, array->size);
|
||||||
p = (void *) p + array->size;
|
|
||||||
|
(*arrayp)->size = array->size;
|
||||||
|
(*arrayp)->alloc = array->alloc;
|
||||||
|
(*arrayp)->data = p;
|
||||||
|
|
||||||
|
p += DIV_ROUNDUP(array->size, sizeof *p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
fd = va_arg(ap, int);
|
fd = va_arg(ap, int);
|
||||||
dup_fd = dup(fd);
|
dup_fd = dup(fd);
|
||||||
|
|
@ -393,35 +463,10 @@ wl_connection_vmarshal(struct wl_connection *connection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size = (p - closure->buffer) * sizeof *p;
|
size = (p - start) * sizeof *p;
|
||||||
closure->buffer[0] = sender->id;
|
start[0] = sender->id;
|
||||||
closure->buffer[1] = opcode | (size << 16);
|
start[1] = opcode | (size << 16);
|
||||||
wl_connection_write(connection, closure->buffer, size);
|
wl_connection_write(connection, start, size);
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
wl_message_size_extra(const struct wl_message *message)
|
|
||||||
{
|
|
||||||
int i, extra;
|
|
||||||
|
|
||||||
for (i = 0, extra = 0; message->signature[i]; i++) {
|
|
||||||
|
|
||||||
switch (message->signature[i - 2]) {
|
|
||||||
case 's':
|
|
||||||
case 'o':
|
|
||||||
extra += sizeof (void *);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
extra += sizeof (void *) + sizeof (struct wl_array);
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
extra += sizeof (uint32_t);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return extra;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wl_closure *
|
struct wl_closure *
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue