Hi, What's the point of this now that we have the proxy wrapper approach?
Cheers, Giulio 2016-05-17 8:18 GMT+02:00 <spit...@gmail.com>: > From: Bill Spitzak <spit...@gmail.com> > > Scanner produces a wl_xyz_new() for each object, and for each constructor > request it produces an "_id" version that takes one of these, instead of > creating one. This allows the queue and listener to be set before creation of > the object so events always go to the correct queue. > > Existing code using proxy_wrapper changed to use this. > > To implement this two new api's were added to wayland-client-core.h: > > wl_proxy_new(interface) > > wl_proxy_marshal_id(...): Same as wl_proxy_marshal except it handles 'n' > arguments > and assigns an id to them. wl_proxy_marshal could do this but it would add > overhead > to search for the 'n' to non-constructor requests. > > v2: Moved definition of wl_proxy back out of header file > v3: _new api and named request _id. > > Signed-off-by: Bill Spitzak <spit...@gmail.com> > --- > src/scanner.c | 59 ++++++++++++++++++++++++++++++++++++++ > src/wayland-client-core.h | 6 ++++ > src/wayland-client.c | 72 > ++++++++++++++++++++++++++++++++++++----------- > tests/queue-test.c | 15 +++++----- > 4 files changed, 127 insertions(+), 25 deletions(-) > > diff --git a/src/scanner.c b/src/scanner.c > index 33271bc..fbe8193 100644 > --- a/src/scanner.c > +++ b/src/scanner.c > @@ -1176,6 +1176,51 @@ emit_stubs(struct wl_list *message_list, struct > interface *interface) > ret->interface_name, ret->name); > > printf("}\n\n"); > + > + /* Produce the _id version of constructor calls. > + * FIXME: this is a cut + paste patch, it would be better > + * to reuse the above code and/or make the old constructor > + * be the special case. > + */ > + if (!ret) > + continue; > + if (!ret->interface_name) > + continue; /* wl_registry_bind_id nyi */ > + printf("/**\n" > + " * @ingroup iface_%s\n", interface->name); > + printf(" *\n" > + " * Same as %s_%s() except it uses an existing proxy > created by\n" > + " * %s_new().\n" > + " */\n", interface->name, m->name, > ret->interface_name); > + printf("static inline void\n"); > + > + printf("%s_%s_id(struct %s *%s", > + interface->name, m->name, > + interface->name, interface->name); > + > + wl_list_for_each(a, &m->arg_list, link) { > + printf(", "); > + if (a->type != NEW_ID) > + emit_type(a); > + else > + printf("struct %s *", ret->interface_name); > + printf("%s", a->name); > + } > + > + printf(")\n" > + "{\n" > + "\twl_proxy_marshal_id((struct wl_proxy *) %s,\n" > + "\t\t\t %s_%s", > + interface->name, > + interface->uppercase_name, > + m->uppercase_name); > + > + wl_list_for_each(a, &m->arg_list, link) { > + printf(", %s", a->name); > + } > + printf(");\n"); > + > + printf("}\n\n"); > } > } > > @@ -1349,6 +1394,20 @@ emit_structs(struct wl_list *message_list, struct > interface *interface, enum sid > printf("};\n\n"); > > if (side == CLIENT) { > + if (strcmp(interface->name, "wl_display")) > + printf("/**\n" > + " * @ingroup iface_%s\n" > + " *\n" > + " * Create a %s and allocate an id.\n" > + " */\n" > + "static inline struct %s *\n" > + "%s_new(void)\n" > + "{\n" > + "\treturn (struct %s *) wl_proxy_new(&%s_interface);\n" > + "}\n\n", > + interface->name, interface->name, interface->name, > + interface->name, interface->name, interface->name); > + > printf("/**\n" > " * @ingroup iface_%s\n" > " */\n", interface->name); > diff --git a/src/wayland-client-core.h b/src/wayland-client-core.h > index 52bb553..8e48cab 100644 > --- a/src/wayland-client-core.h > +++ b/src/wayland-client-core.h > @@ -125,10 +125,16 @@ void > wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...); > > void > +wl_proxy_marshal_id(struct wl_proxy *proxy, uint32_t opcode, ...); > + > +void > wl_proxy_marshal_array(struct wl_proxy *p, uint32_t opcode, > union wl_argument *args); > > struct wl_proxy * > +wl_proxy_new(const struct wl_interface *interface); > + > +struct wl_proxy * > wl_proxy_create(struct wl_proxy *factory, > const struct wl_interface *interface); > > diff --git a/src/wayland-client.c b/src/wayland-client.c > index f67678b..d539bf7 100644 > --- a/src/wayland-client.c > +++ b/src/wayland-client.c > @@ -324,8 +324,17 @@ wl_display_create_queue(struct wl_display *display) > return queue; > } > > -static struct wl_proxy * > -proxy_new(const struct wl_interface *interface) > +/** Create a proxy object with a given interface > + * > + * \param interface Interface the proxy object should use > + * \return A newly allocated proxy object or NULL on failure > + * > + * This function creates a new proxy object with the supplied interface. > + * Caller should pass this to a constructor message to fill in the id > + * and cause the matching object to be created by the server. > + */ > +WL_EXPORT struct wl_proxy * > +wl_proxy_new(const struct wl_interface *interface) > { > struct wl_proxy *proxy = zalloc(sizeof *proxy); > if (proxy) { > @@ -358,7 +367,7 @@ WL_EXPORT struct wl_proxy * > wl_proxy_create(struct wl_proxy *factory, const struct wl_interface > *interface) > { > struct wl_display *display = factory->display; > - struct wl_proxy *proxy = proxy_new(interface); > + struct wl_proxy *proxy = wl_proxy_new(interface); > if (proxy == NULL) > return NULL; > > @@ -379,7 +388,7 @@ wl_proxy_create_for_id(struct wl_proxy *factory, > uint32_t id, const struct wl_interface *interface) > { > struct wl_display *display = factory->display; > - struct wl_proxy *proxy = proxy_new(interface); > + struct wl_proxy *proxy = wl_proxy_new(interface); > if (proxy == NULL) > return NULL; > > @@ -657,7 +666,7 @@ wl_proxy_marshal_array_constructor_versioned(struct > wl_proxy *factory, > struct wl_proxy *new_proxy = NULL; > > if (interface) { > - new_proxy = proxy_new(interface); > + new_proxy = wl_proxy_new(interface); > if (new_proxy == NULL) > return NULL; > new_proxy->display = factory->display; > @@ -701,6 +710,42 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t > opcode, ...) > proxy_marshal_array(proxy, opcode, args, NULL); > } > > +/** Same as wl_proxy_marshal() except this also searches for a new_id > + * argument and allocates an id for the object. > + * > + * \param factory The proxy object > + * \param opcode Opcode of the request to be sent > + * \param ... Extra arguments for the given request > + * > + * \note This should not normally be used by non-generated code. > + * > + * \sa wl_proxy_new() > + * > + * \memberof wl_proxy > + */ > +WL_EXPORT void > +wl_proxy_marshal_id(struct wl_proxy *factory, uint32_t opcode, ...) > +{ > + union wl_argument args[WL_CLOSURE_MAX_ARGS]; > + va_list ap; > + struct wl_proxy* new_proxy; > + > + va_start(ap, opcode); > + > wl_argument_from_va_list(factory->object.interface->methods[opcode].signature, > + args, WL_CLOSURE_MAX_ARGS, ap); > + va_end(ap); > + > + new_proxy = (struct wl_proxy *)(args[new_id_index(factory, > opcode)].o); > + if (new_proxy->object.id) > + wl_abort("proxy already has an id"); > + new_proxy->display = factory->display; > + if (new_proxy->queue == NULL) > + new_proxy->queue = factory->queue; > + new_proxy->version = factory->version; > + > + proxy_marshal_array(factory, opcode, args, new_proxy); > +} > + > /** Prepare a request to be sent to the compositor > * > * \param factory The proxy object > @@ -1104,24 +1149,17 @@ static const struct wl_callback_listener > sync_listener = { > WL_EXPORT int > wl_display_roundtrip_queue(struct wl_display *display, struct wl_event_queue > *queue) > { > - struct wl_display *display_wrapper; > struct wl_callback *callback; > int done, ret = 0; > > done = 0; > - > - display_wrapper = wl_proxy_create_wrapper(display); > - if (!display_wrapper) > - return -1; > - > - wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue); > - callback = wl_display_sync(display_wrapper); > - wl_proxy_wrapper_destroy(display_wrapper); > - > + callback = wl_callback_new(); > if (callback == NULL) > return -1; > - > + wl_proxy_set_queue((struct wl_proxy *) callback, queue); > wl_callback_add_listener(callback, &sync_listener, &done); > + wl_display_sync_id(display, callback); > + > while (!done && ret >= 0) > ret = wl_display_dispatch_queue(display, queue); > > @@ -2034,7 +2072,7 @@ WL_EXPORT void * > wl_proxy_create_wrapper(void *factory) > { > struct wl_proxy *wrapped_proxy = factory; > - struct wl_proxy *wrapper = proxy_new(wrapped_proxy->object.interface); > + struct wl_proxy *wrapper = > wl_proxy_new(wrapped_proxy->object.interface); > if (!wrapper) > return NULL; > > diff --git a/tests/queue-test.c b/tests/queue-test.c > index 932bc55..61a2903 100644 > --- a/tests/queue-test.c > +++ b/tests/queue-test.c > @@ -119,15 +119,17 @@ client_test_multiple_queues(void) > assert(queue); > > state.done = false; > - callback1 = wl_display_sync(state.display); > + callback1 = wl_callback_new(); > assert(callback1 != NULL); > wl_callback_add_listener(callback1, &sync_listener, &state); > wl_proxy_set_queue((struct wl_proxy *) callback1, queue); > + wl_display_sync_id(state.display, callback1); > > - state.callback2 = wl_display_sync(state.display); > + state.callback2 = wl_callback_new(); > assert(state.callback2 != NULL); > wl_callback_add_listener(state.callback2, &sync_listener, NULL); > wl_proxy_set_queue((struct wl_proxy *) state.callback2, queue); > + wl_display_sync_id(state.display, state.callback2); > > wl_display_flush(state.display); > > @@ -209,7 +211,6 @@ client_test_queue_proxy_wrapper(void) > { > struct wl_event_queue *queue; > struct wl_display *display; > - struct wl_display *display_wrapper; > struct wl_callback *callback; > bool done = false; > > @@ -226,12 +227,10 @@ client_test_queue_proxy_wrapper(void) > queue = wl_display_create_queue(display); > assert(queue); > > - display_wrapper = wl_proxy_create_wrapper(display); > - assert(display_wrapper); > - wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue); > - callback = wl_display_sync(display_wrapper); > - wl_proxy_wrapper_destroy(display_wrapper); > + callback = wl_callback_new(); > assert(callback != NULL); > + wl_proxy_set_queue((struct wl_proxy *) callback, queue); > + wl_display_sync_id(display, callback); > > /* Pretend we are now another thread and dispatch the dispatch the > main > * queue while also knowing our callback is read and queued. */ > -- > 1.9.1 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel