mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-10-29 05:40: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); | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| wl_connection_vmarshal(struct wl_connection *connection, | ||||
| 		       struct wl_object *sender, | ||||
|  | @ -338,36 +364,74 @@ wl_connection_vmarshal(struct wl_connection *connection, | |||
| 		       const struct wl_message *message) | ||||
| { | ||||
| 	struct wl_closure *closure = &connection->closure; | ||||
| 	struct wl_object *object; | ||||
| 	uint32_t length, *p, size; | ||||
| 	struct wl_object **objectp, *object; | ||||
| 	uint32_t length, *p, *start, size; | ||||
| 	int dup_fd; | ||||
| 	struct wl_array *array; | ||||
| 	const char *s; | ||||
| 	int i, count, fd; | ||||
| 	struct wl_array **arrayp, *array; | ||||
| 	const char **sp, *s; | ||||
| 	char *extra; | ||||
| 	int i, count, fd, extra_size; | ||||
| 
 | ||||
| 	count = strlen(message->signature); | ||||
| 	p = &closure->buffer[2]; | ||||
| 	for (i = 0; i < count; i++) { | ||||
| 		switch (message->signature[i]) { | ||||
| 	extra_size = wl_message_size_extra(message); | ||||
| 	closure->message = message; | ||||
| 	count = strlen(message->signature) + 2; | ||||
| 	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': | ||||
| 			closure->types[i] = &ffi_type_uint32; | ||||
| 			closure->args[i] = p; | ||||
| 			*p++ = va_arg(ap, uint32_t); | ||||
| 			break; | ||||
| 		case 'i': | ||||
| 			closure->types[i] = &ffi_type_sint32; | ||||
| 			closure->args[i] = p; | ||||
| 			*p++ = va_arg(ap, int32_t); | ||||
| 			break; | ||||
| 		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 *); | ||||
| 			length = s ? strlen(s) + 1: 0; | ||||
| 			*p++ = length; | ||||
| 
 | ||||
| 			*sp = (const char *) p; | ||||
| 
 | ||||
| 			memcpy(p, s, length); | ||||
| 			p += DIV_ROUNDUP(length, sizeof(*p)); | ||||
| 			p += DIV_ROUNDUP(length, sizeof *p); | ||||
| 			break; | ||||
| 		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 *); | ||||
| 			*objectp = object; | ||||
| 			*p++ = object ? object->id : 0; | ||||
| 			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': | ||||
| 			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 *); | ||||
| 			if (array == NULL || array->size == 0) { | ||||
| 				*p++ = 0; | ||||
|  | @ -375,8 +439,14 @@ wl_connection_vmarshal(struct wl_connection *connection, | |||
| 			} | ||||
| 			*p++ = 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; | ||||
| 
 | ||||
| 		case 'h': | ||||
| 			fd = va_arg(ap, int); | ||||
| 			dup_fd = dup(fd); | ||||
|  | @ -393,35 +463,10 @@ wl_connection_vmarshal(struct wl_connection *connection, | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	size = (p - closure->buffer) * sizeof *p; | ||||
| 	closure->buffer[0] = sender->id; | ||||
| 	closure->buffer[1] = opcode | (size << 16); | ||||
| 	wl_connection_write(connection, closure->buffer, 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; | ||||
| 	size = (p - start) * sizeof *p; | ||||
| 	start[0] = sender->id; | ||||
| 	start[1] = opcode | (size << 16); | ||||
| 	wl_connection_write(connection, start, size); | ||||
| } | ||||
| 
 | ||||
| struct wl_closure * | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Kristian Høgsberg
						Kristian Høgsberg