static void dispatch_event(struct wl_display *display, struct wl_event_queue *queue) { struct wl_closure *closure; struct wl_proxy *proxy; int opcode; bool proxy_destroyed; closure = container_of(queue->event_list.next, struct wl_closure, link); wl_list_remove(&closure->link); opcode = closure->opcode; /* Verify that the receiving object is still valid by checking if has * been destroyed by the application. */ decrease_closure_args_refcount(closure); proxy = closure->proxy; proxy_destroyed = !!(proxy->flags & WL_PROXY_FLAG_DESTROYED); proxy->refcount--; if (proxy_destroyed) { if (!proxy->refcount) free(proxy); wl_closure_destroy(closure); return; } pthread_mutex_unlock(&display->mutex); if (proxy->dispatcher) { if (wl_debug) wl_closure_print(closure, &proxy->object, false); wl_closure_dispatch(closure, proxy->dispatcher, &proxy->object, opcode); } else if (proxy->object.implementation) { if (wl_debug) wl_closure_print(closure, &proxy->object, false); wl_closure_invoke(closure, WL_CLOSURE_INVOKE_CLIENT, &proxy->object, opcode, proxy->user_data); } wl_closure_destroy(closure); pthread_mutex_lock(&display->mutex); }
/** Prepare a request to be sent to the compositor * * \param proxy The proxy object * \param opcode Opcode of the request to be sent * \param args Extra arguments for the given request * * Translates the request given by opcode and the extra arguments into the * wire format and write it to the connection buffer. This version takes an * array of the union type wl_argument. * * \note This is intended to be used by language bindings and not in * non-generated code. * * \sa wl_proxy_marshal() * * \memberof wl_proxy */ WL_EXPORT void wl_proxy_marshal_array(struct wl_proxy *proxy, uint32_t opcode, union wl_argument *args) { struct wl_closure *closure; pthread_mutex_lock(&proxy->display->mutex); closure = wl_closure_marshal(&proxy->object, opcode, args, &proxy->object.interface->methods[opcode]); if (closure == NULL) { fprintf(stderr, "Error marshalling request\n"); abort(); } if (wl_debug) wl_closure_print(closure, &proxy->object, true); if (wl_closure_send(closure, proxy->display->connection)) { fprintf(stderr, "Error sending request: %m\n"); abort(); } wl_closure_destroy(closure); pthread_mutex_unlock(&proxy->display->mutex); }
/** Prepare a request to be sent to the compositor * * \param proxy The proxy object * \param opcode Opcode of the request to be sent * \param args Extra arguments for the given request * \param interface The interface to use for the new proxy * * Translates the request given by opcode and the extra arguments into the * wire format and write it to the connection buffer. This version takes an * array of the union type wl_argument. * * For new-id arguments, this function will allocate a new wl_proxy * and send the ID to the server. The new wl_proxy will be returned * on success or NULL on errror with errno set accordingly. * * \note This is intended to be used by language bindings and not in * non-generated code. * * \sa wl_proxy_marshal() * * \memberof wl_proxy */ WL_EXPORT struct wl_proxy * wl_proxy_marshal_array_constructor(struct wl_proxy *proxy, uint32_t opcode, union wl_argument *args, const struct wl_interface *interface) { struct wl_closure *closure; struct wl_proxy *new_proxy = NULL; const struct wl_message *message; pthread_mutex_lock(&proxy->display->mutex); message = &proxy->object.interface->methods[opcode]; if (interface) { new_proxy = create_outgoing_proxy(proxy, message, args, interface); if (new_proxy == NULL) goto err_unlock; } closure = wl_closure_marshal(&proxy->object, opcode, args, message); if (closure == NULL) { wl_log("Error marshalling request: %m\n"); abort(); } if (debug_client) wl_closure_print(closure, &proxy->object, true); if (wl_closure_send(closure, proxy->display->connection)) { wl_log("Error sending request: %m\n"); abort(); } wl_closure_destroy(closure); err_unlock: pthread_mutex_unlock(&proxy->display->mutex); return new_proxy; }