1*84e872a0SLloyd Pique /* 2*84e872a0SLloyd Pique * Copyright © 2008 Kristian Høgsberg 3*84e872a0SLloyd Pique * 4*84e872a0SLloyd Pique * Permission is hereby granted, free of charge, to any person obtaining 5*84e872a0SLloyd Pique * a copy of this software and associated documentation files (the 6*84e872a0SLloyd Pique * "Software"), to deal in the Software without restriction, including 7*84e872a0SLloyd Pique * without limitation the rights to use, copy, modify, merge, publish, 8*84e872a0SLloyd Pique * distribute, sublicense, and/or sell copies of the Software, and to 9*84e872a0SLloyd Pique * permit persons to whom the Software is furnished to do so, subject to 10*84e872a0SLloyd Pique * the following conditions: 11*84e872a0SLloyd Pique * 12*84e872a0SLloyd Pique * The above copyright notice and this permission notice (including the 13*84e872a0SLloyd Pique * next paragraph) shall be included in all copies or substantial 14*84e872a0SLloyd Pique * portions of the Software. 15*84e872a0SLloyd Pique * 16*84e872a0SLloyd Pique * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17*84e872a0SLloyd Pique * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18*84e872a0SLloyd Pique * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19*84e872a0SLloyd Pique * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20*84e872a0SLloyd Pique * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21*84e872a0SLloyd Pique * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22*84e872a0SLloyd Pique * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23*84e872a0SLloyd Pique * SOFTWARE. 24*84e872a0SLloyd Pique */ 25*84e872a0SLloyd Pique 26*84e872a0SLloyd Pique #ifndef WAYLAND_CLIENT_CORE_H 27*84e872a0SLloyd Pique #define WAYLAND_CLIENT_CORE_H 28*84e872a0SLloyd Pique 29*84e872a0SLloyd Pique #include <stdint.h> 30*84e872a0SLloyd Pique #include "wayland-util.h" 31*84e872a0SLloyd Pique #include "wayland-version.h" 32*84e872a0SLloyd Pique 33*84e872a0SLloyd Pique #ifdef __cplusplus 34*84e872a0SLloyd Pique extern "C" { 35*84e872a0SLloyd Pique #endif 36*84e872a0SLloyd Pique 37*84e872a0SLloyd Pique /** \class wl_proxy 38*84e872a0SLloyd Pique * 39*84e872a0SLloyd Pique * \brief Represents a protocol object on the client side. 40*84e872a0SLloyd Pique * 41*84e872a0SLloyd Pique * A wl_proxy acts as a client side proxy to an object existing in the 42*84e872a0SLloyd Pique * compositor. The proxy is responsible for converting requests made by the 43*84e872a0SLloyd Pique * clients with \ref wl_proxy_marshal() into Wayland's wire format. Events 44*84e872a0SLloyd Pique * coming from the compositor are also handled by the proxy, which will in 45*84e872a0SLloyd Pique * turn call the handler set with \ref wl_proxy_add_listener(). 46*84e872a0SLloyd Pique * 47*84e872a0SLloyd Pique * \note With the exception of function \ref wl_proxy_set_queue(), functions 48*84e872a0SLloyd Pique * accessing a wl_proxy are not normally used by client code. Clients 49*84e872a0SLloyd Pique * should normally use the higher level interface generated by the scanner to 50*84e872a0SLloyd Pique * interact with compositor objects. 51*84e872a0SLloyd Pique * 52*84e872a0SLloyd Pique */ 53*84e872a0SLloyd Pique struct wl_proxy; 54*84e872a0SLloyd Pique 55*84e872a0SLloyd Pique /** \class wl_display 56*84e872a0SLloyd Pique * 57*84e872a0SLloyd Pique * \brief Represents a connection to the compositor and acts as a proxy to 58*84e872a0SLloyd Pique * the wl_display singleton object. 59*84e872a0SLloyd Pique * 60*84e872a0SLloyd Pique * A wl_display object represents a client connection to a Wayland 61*84e872a0SLloyd Pique * compositor. It is created with either \ref wl_display_connect() or 62*84e872a0SLloyd Pique * \ref wl_display_connect_to_fd(). A connection is terminated using 63*84e872a0SLloyd Pique * \ref wl_display_disconnect(). 64*84e872a0SLloyd Pique * 65*84e872a0SLloyd Pique * A wl_display is also used as the \ref wl_proxy for the wl_display 66*84e872a0SLloyd Pique * singleton object on the compositor side. 67*84e872a0SLloyd Pique * 68*84e872a0SLloyd Pique * A wl_display object handles all the data sent from and to the 69*84e872a0SLloyd Pique * compositor. When a \ref wl_proxy marshals a request, it will write its wire 70*84e872a0SLloyd Pique * representation to the display's write buffer. The data is sent to the 71*84e872a0SLloyd Pique * compositor when the client calls \ref wl_display_flush(). 72*84e872a0SLloyd Pique * 73*84e872a0SLloyd Pique * Incoming data is handled in two steps: queueing and dispatching. In the 74*84e872a0SLloyd Pique * queue step, the data coming from the display fd is interpreted and 75*84e872a0SLloyd Pique * added to a queue. On the dispatch step, the handler for the incoming 76*84e872a0SLloyd Pique * event set by the client on the corresponding \ref wl_proxy is called. 77*84e872a0SLloyd Pique * 78*84e872a0SLloyd Pique * A wl_display has at least one event queue, called the <em>default 79*84e872a0SLloyd Pique * queue</em>. Clients can create additional event queues with \ref 80*84e872a0SLloyd Pique * wl_display_create_queue() and assign \ref wl_proxy's to it. Events 81*84e872a0SLloyd Pique * occurring in a particular proxy are always queued in its assigned queue. 82*84e872a0SLloyd Pique * A client can ensure that a certain assumption, such as holding a lock 83*84e872a0SLloyd Pique * or running from a given thread, is true when a proxy event handler is 84*84e872a0SLloyd Pique * called by assigning that proxy to an event queue and making sure that 85*84e872a0SLloyd Pique * this queue is only dispatched when the assumption holds. 86*84e872a0SLloyd Pique * 87*84e872a0SLloyd Pique * The default queue is dispatched by calling \ref wl_display_dispatch(). 88*84e872a0SLloyd Pique * This will dispatch any events queued on the default queue and attempt 89*84e872a0SLloyd Pique * to read from the display fd if it's empty. Events read are then queued 90*84e872a0SLloyd Pique * on the appropriate queues according to the proxy assignment. 91*84e872a0SLloyd Pique * 92*84e872a0SLloyd Pique * A user created queue is dispatched with \ref wl_display_dispatch_queue(). 93*84e872a0SLloyd Pique * This function behaves exactly the same as wl_display_dispatch() 94*84e872a0SLloyd Pique * but it dispatches given queue instead of the default queue. 95*84e872a0SLloyd Pique * 96*84e872a0SLloyd Pique * A real world example of event queue usage is Mesa's implementation of 97*84e872a0SLloyd Pique * eglSwapBuffers() for the Wayland platform. This function might need 98*84e872a0SLloyd Pique * to block until a frame callback is received, but dispatching the default 99*84e872a0SLloyd Pique * queue could cause an event handler on the client to start drawing 100*84e872a0SLloyd Pique * again. This problem is solved using another event queue, so that only 101*84e872a0SLloyd Pique * the events handled by the EGL code are dispatched during the block. 102*84e872a0SLloyd Pique * 103*84e872a0SLloyd Pique * This creates a problem where a thread dispatches a non-default 104*84e872a0SLloyd Pique * queue, reading all the data from the display fd. If the application 105*84e872a0SLloyd Pique * would call \em poll(2) after that it would block, even though there 106*84e872a0SLloyd Pique * might be events queued on the default queue. Those events should be 107*84e872a0SLloyd Pique * dispatched with \ref wl_display_dispatch_pending() or \ref 108*84e872a0SLloyd Pique * wl_display_dispatch_queue_pending() before flushing and blocking. 109*84e872a0SLloyd Pique */ 110*84e872a0SLloyd Pique struct wl_display; 111*84e872a0SLloyd Pique 112*84e872a0SLloyd Pique /** \class wl_event_queue 113*84e872a0SLloyd Pique * 114*84e872a0SLloyd Pique * \brief A queue for \ref wl_proxy object events. 115*84e872a0SLloyd Pique * 116*84e872a0SLloyd Pique * Event queues allows the events on a display to be handled in a thread-safe 117*84e872a0SLloyd Pique * manner. See \ref wl_display for details. 118*84e872a0SLloyd Pique * 119*84e872a0SLloyd Pique */ 120*84e872a0SLloyd Pique struct wl_event_queue; 121*84e872a0SLloyd Pique 122*84e872a0SLloyd Pique /** Destroy proxy after marshalling 123*84e872a0SLloyd Pique * @ingroup wl_proxy 124*84e872a0SLloyd Pique */ 125*84e872a0SLloyd Pique #define WL_MARSHAL_FLAG_DESTROY (1 << 0) 126*84e872a0SLloyd Pique 127*84e872a0SLloyd Pique void 128*84e872a0SLloyd Pique wl_event_queue_destroy(struct wl_event_queue *queue); 129*84e872a0SLloyd Pique 130*84e872a0SLloyd Pique struct wl_proxy * 131*84e872a0SLloyd Pique wl_proxy_marshal_flags(struct wl_proxy *proxy, uint32_t opcode, 132*84e872a0SLloyd Pique const struct wl_interface *interface, 133*84e872a0SLloyd Pique uint32_t version, 134*84e872a0SLloyd Pique uint32_t flags, ...); 135*84e872a0SLloyd Pique 136*84e872a0SLloyd Pique struct wl_proxy * 137*84e872a0SLloyd Pique wl_proxy_marshal_array_flags(struct wl_proxy *proxy, uint32_t opcode, 138*84e872a0SLloyd Pique const struct wl_interface *interface, 139*84e872a0SLloyd Pique uint32_t version, 140*84e872a0SLloyd Pique uint32_t flags, 141*84e872a0SLloyd Pique union wl_argument *args); 142*84e872a0SLloyd Pique 143*84e872a0SLloyd Pique void 144*84e872a0SLloyd Pique wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...); 145*84e872a0SLloyd Pique 146*84e872a0SLloyd Pique void 147*84e872a0SLloyd Pique wl_proxy_marshal_array(struct wl_proxy *p, uint32_t opcode, 148*84e872a0SLloyd Pique union wl_argument *args); 149*84e872a0SLloyd Pique 150*84e872a0SLloyd Pique struct wl_proxy * 151*84e872a0SLloyd Pique wl_proxy_create(struct wl_proxy *factory, 152*84e872a0SLloyd Pique const struct wl_interface *interface); 153*84e872a0SLloyd Pique 154*84e872a0SLloyd Pique void * 155*84e872a0SLloyd Pique wl_proxy_create_wrapper(void *proxy); 156*84e872a0SLloyd Pique 157*84e872a0SLloyd Pique void 158*84e872a0SLloyd Pique wl_proxy_wrapper_destroy(void *proxy_wrapper); 159*84e872a0SLloyd Pique 160*84e872a0SLloyd Pique struct wl_proxy * 161*84e872a0SLloyd Pique wl_proxy_marshal_constructor(struct wl_proxy *proxy, 162*84e872a0SLloyd Pique uint32_t opcode, 163*84e872a0SLloyd Pique const struct wl_interface *interface, 164*84e872a0SLloyd Pique ...); 165*84e872a0SLloyd Pique 166*84e872a0SLloyd Pique struct wl_proxy * 167*84e872a0SLloyd Pique wl_proxy_marshal_constructor_versioned(struct wl_proxy *proxy, 168*84e872a0SLloyd Pique uint32_t opcode, 169*84e872a0SLloyd Pique const struct wl_interface *interface, 170*84e872a0SLloyd Pique uint32_t version, 171*84e872a0SLloyd Pique ...); 172*84e872a0SLloyd Pique 173*84e872a0SLloyd Pique struct wl_proxy * 174*84e872a0SLloyd Pique wl_proxy_marshal_array_constructor(struct wl_proxy *proxy, 175*84e872a0SLloyd Pique uint32_t opcode, union wl_argument *args, 176*84e872a0SLloyd Pique const struct wl_interface *interface); 177*84e872a0SLloyd Pique 178*84e872a0SLloyd Pique struct wl_proxy * 179*84e872a0SLloyd Pique wl_proxy_marshal_array_constructor_versioned(struct wl_proxy *proxy, 180*84e872a0SLloyd Pique uint32_t opcode, 181*84e872a0SLloyd Pique union wl_argument *args, 182*84e872a0SLloyd Pique const struct wl_interface *interface, 183*84e872a0SLloyd Pique uint32_t version); 184*84e872a0SLloyd Pique 185*84e872a0SLloyd Pique void 186*84e872a0SLloyd Pique wl_proxy_destroy(struct wl_proxy *proxy); 187*84e872a0SLloyd Pique 188*84e872a0SLloyd Pique int 189*84e872a0SLloyd Pique wl_proxy_add_listener(struct wl_proxy *proxy, 190*84e872a0SLloyd Pique void (**implementation)(void), void *data); 191*84e872a0SLloyd Pique 192*84e872a0SLloyd Pique const void * 193*84e872a0SLloyd Pique wl_proxy_get_listener(struct wl_proxy *proxy); 194*84e872a0SLloyd Pique 195*84e872a0SLloyd Pique int 196*84e872a0SLloyd Pique wl_proxy_add_dispatcher(struct wl_proxy *proxy, 197*84e872a0SLloyd Pique wl_dispatcher_func_t dispatcher_func, 198*84e872a0SLloyd Pique const void * dispatcher_data, void *data); 199*84e872a0SLloyd Pique 200*84e872a0SLloyd Pique void 201*84e872a0SLloyd Pique wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data); 202*84e872a0SLloyd Pique 203*84e872a0SLloyd Pique void * 204*84e872a0SLloyd Pique wl_proxy_get_user_data(struct wl_proxy *proxy); 205*84e872a0SLloyd Pique 206*84e872a0SLloyd Pique uint32_t 207*84e872a0SLloyd Pique wl_proxy_get_version(struct wl_proxy *proxy); 208*84e872a0SLloyd Pique 209*84e872a0SLloyd Pique uint32_t 210*84e872a0SLloyd Pique wl_proxy_get_id(struct wl_proxy *proxy); 211*84e872a0SLloyd Pique 212*84e872a0SLloyd Pique void 213*84e872a0SLloyd Pique wl_proxy_set_tag(struct wl_proxy *proxy, 214*84e872a0SLloyd Pique const char * const *tag); 215*84e872a0SLloyd Pique 216*84e872a0SLloyd Pique const char * const * 217*84e872a0SLloyd Pique wl_proxy_get_tag(struct wl_proxy *proxy); 218*84e872a0SLloyd Pique 219*84e872a0SLloyd Pique const char * 220*84e872a0SLloyd Pique wl_proxy_get_class(struct wl_proxy *proxy); 221*84e872a0SLloyd Pique 222*84e872a0SLloyd Pique void 223*84e872a0SLloyd Pique wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue); 224*84e872a0SLloyd Pique 225*84e872a0SLloyd Pique struct wl_proxy * 226*84e872a0SLloyd Pique wl_proxy_from_object(struct wl_object *object); 227*84e872a0SLloyd Pique 228*84e872a0SLloyd Pique struct wl_display * 229*84e872a0SLloyd Pique wl_display_connect(const char *name); 230*84e872a0SLloyd Pique 231*84e872a0SLloyd Pique struct wl_display * 232*84e872a0SLloyd Pique wl_display_connect_to_fd(int fd); 233*84e872a0SLloyd Pique 234*84e872a0SLloyd Pique void 235*84e872a0SLloyd Pique wl_display_disconnect(struct wl_display *display); 236*84e872a0SLloyd Pique 237*84e872a0SLloyd Pique int 238*84e872a0SLloyd Pique wl_display_get_fd(struct wl_display *display); 239*84e872a0SLloyd Pique 240*84e872a0SLloyd Pique int 241*84e872a0SLloyd Pique wl_display_dispatch(struct wl_display *display); 242*84e872a0SLloyd Pique 243*84e872a0SLloyd Pique int 244*84e872a0SLloyd Pique wl_display_dispatch_queue(struct wl_display *display, 245*84e872a0SLloyd Pique struct wl_event_queue *queue); 246*84e872a0SLloyd Pique 247*84e872a0SLloyd Pique int 248*84e872a0SLloyd Pique wl_display_dispatch_queue_pending(struct wl_display *display, 249*84e872a0SLloyd Pique struct wl_event_queue *queue); 250*84e872a0SLloyd Pique 251*84e872a0SLloyd Pique int 252*84e872a0SLloyd Pique wl_display_dispatch_pending(struct wl_display *display); 253*84e872a0SLloyd Pique 254*84e872a0SLloyd Pique int 255*84e872a0SLloyd Pique wl_display_get_error(struct wl_display *display); 256*84e872a0SLloyd Pique 257*84e872a0SLloyd Pique uint32_t 258*84e872a0SLloyd Pique wl_display_get_protocol_error(struct wl_display *display, 259*84e872a0SLloyd Pique const struct wl_interface **interface, 260*84e872a0SLloyd Pique uint32_t *id); 261*84e872a0SLloyd Pique 262*84e872a0SLloyd Pique int 263*84e872a0SLloyd Pique wl_display_flush(struct wl_display *display); 264*84e872a0SLloyd Pique 265*84e872a0SLloyd Pique int 266*84e872a0SLloyd Pique wl_display_roundtrip_queue(struct wl_display *display, 267*84e872a0SLloyd Pique struct wl_event_queue *queue); 268*84e872a0SLloyd Pique 269*84e872a0SLloyd Pique int 270*84e872a0SLloyd Pique wl_display_roundtrip(struct wl_display *display); 271*84e872a0SLloyd Pique 272*84e872a0SLloyd Pique struct wl_event_queue * 273*84e872a0SLloyd Pique wl_display_create_queue(struct wl_display *display); 274*84e872a0SLloyd Pique 275*84e872a0SLloyd Pique int 276*84e872a0SLloyd Pique wl_display_prepare_read_queue(struct wl_display *display, 277*84e872a0SLloyd Pique struct wl_event_queue *queue); 278*84e872a0SLloyd Pique 279*84e872a0SLloyd Pique int 280*84e872a0SLloyd Pique wl_display_prepare_read(struct wl_display *display); 281*84e872a0SLloyd Pique 282*84e872a0SLloyd Pique void 283*84e872a0SLloyd Pique wl_display_cancel_read(struct wl_display *display); 284*84e872a0SLloyd Pique 285*84e872a0SLloyd Pique int 286*84e872a0SLloyd Pique wl_display_read_events(struct wl_display *display); 287*84e872a0SLloyd Pique 288*84e872a0SLloyd Pique void 289*84e872a0SLloyd Pique wl_log_set_handler_client(wl_log_func_t handler); 290*84e872a0SLloyd Pique 291*84e872a0SLloyd Pique /** 292*84e872a0SLloyd Pique * The message type. 293*84e872a0SLloyd Pique */ 294*84e872a0SLloyd Pique enum wl_client_message_type { 295*84e872a0SLloyd Pique /** The message is a request */ 296*84e872a0SLloyd Pique WL_CLIENT_MESSAGE_REQUEST, 297*84e872a0SLloyd Pique 298*84e872a0SLloyd Pique /** The message is an event */ 299*84e872a0SLloyd Pique WL_CLIENT_MESSAGE_EVENT, 300*84e872a0SLloyd Pique }; 301*84e872a0SLloyd Pique 302*84e872a0SLloyd Pique /** 303*84e872a0SLloyd Pique * The message discard reason codes. 304*84e872a0SLloyd Pique */ 305*84e872a0SLloyd Pique enum wl_client_message_discarded_reason { 306*84e872a0SLloyd Pique /** The message was handled normally, and not discarded. */ 307*84e872a0SLloyd Pique WL_CLIENT_MESSAGE_NOT_DISCARDED = 0, 308*84e872a0SLloyd Pique 309*84e872a0SLloyd Pique /** The target was not alive at dispatch time */ 310*84e872a0SLloyd Pique WL_CLIENT_MESSAGE_DISCARD_DEAD_PROXY_ON_DISPATCH, 311*84e872a0SLloyd Pique 312*84e872a0SLloyd Pique /** The target had no listener or dispatcher */ 313*84e872a0SLloyd Pique WL_CLIENT_MESSAGE_DISCARD_NO_LISTENER_ON_DISPATCH, 314*84e872a0SLloyd Pique 315*84e872a0SLloyd Pique /** The target was not valid when the event was demarshalled */ 316*84e872a0SLloyd Pique WL_CLIENT_MESSAGE_DISCARD_UNKNOWN_ID_ON_DEMARSHAL, 317*84e872a0SLloyd Pique }; 318*84e872a0SLloyd Pique 319*84e872a0SLloyd Pique /** 320*84e872a0SLloyd Pique * The structure used to communicate details about an observed message to the 321*84e872a0SLloyd Pique * registered observers. 322*84e872a0SLloyd Pique */ 323*84e872a0SLloyd Pique struct wl_client_observed_message { 324*84e872a0SLloyd Pique /** The target for the message */ 325*84e872a0SLloyd Pique struct wl_proxy *proxy; 326*84e872a0SLloyd Pique 327*84e872a0SLloyd Pique /** The message opcode */ 328*84e872a0SLloyd Pique int message_opcode; 329*84e872a0SLloyd Pique 330*84e872a0SLloyd Pique /** The protocol message structure */ 331*84e872a0SLloyd Pique const struct wl_message *message; 332*84e872a0SLloyd Pique 333*84e872a0SLloyd Pique /** The count of arguments to the message */ 334*84e872a0SLloyd Pique int arguments_count; 335*84e872a0SLloyd Pique 336*84e872a0SLloyd Pique /** The argument array for the messagge */ 337*84e872a0SLloyd Pique const union wl_argument *arguments; 338*84e872a0SLloyd Pique 339*84e872a0SLloyd Pique /** The discard reason code */ 340*84e872a0SLloyd Pique enum wl_client_message_discarded_reason discarded_reason; 341*84e872a0SLloyd Pique 342*84e872a0SLloyd Pique /** 343*84e872a0SLloyd Pique * The discard reason string, or NULL if the event was not discarded. 344*84e872a0SLloyd Pique * 345*84e872a0SLloyd Pique * This string is only for convenience for a observer that does 346*84e872a0SLloyd Pique * logging. The string values should not be considered stable, and 347*84e872a0SLloyd Pique * are not localized. 348*84e872a0SLloyd Pique */ 349*84e872a0SLloyd Pique const char *discarded_reason_str; 350*84e872a0SLloyd Pique }; 351*84e872a0SLloyd Pique 352*84e872a0SLloyd Pique /** 353*84e872a0SLloyd Pique * The signature for a client message observer function, as registered with 354*84e872a0SLloyd Pique * wl_display_add_client_observer(). 355*84e872a0SLloyd Pique * 356*84e872a0SLloyd Pique * \param user_data \c user_data pointer given when the observer was 357*84e872a0SLloyd Pique * registered with \c wl_display_create_client_observer 358*84e872a0SLloyd Pique * \param type type of message 359*84e872a0SLloyd Pique * \param message details for the message 360*84e872a0SLloyd Pique */ 361*84e872a0SLloyd Pique typedef void (*wl_client_message_observer_func_t)( 362*84e872a0SLloyd Pique void *user_data, enum wl_client_message_type type, 363*84e872a0SLloyd Pique const struct wl_client_observed_message *message); 364*84e872a0SLloyd Pique 365*84e872a0SLloyd Pique /** \class wl_client_observer 366*84e872a0SLloyd Pique * 367*84e872a0SLloyd Pique * \brief Represents a client message observer 368*84e872a0SLloyd Pique * 369*84e872a0SLloyd Pique * A client observer allows the client to observe all request and event 370*84e872a0SLloyd Pique * message traffic to and from the client. For events, the observer is 371*84e872a0SLloyd Pique * also given a discard reason if the event wasn't handled. 372*84e872a0SLloyd Pique * 373*84e872a0SLloyd Pique * The typical use for the observer is to allow the client implementation to 374*84e872a0SLloyd Pique * do its own debug logging, as the default when setting WAYLAND_DEBUG is to 375*84e872a0SLloyd Pique * log to stderr. 376*84e872a0SLloyd Pique * 377*84e872a0SLloyd Pique * With this runtime call, the client can also enable and disable the observer 378*84e872a0SLloyd Pique * at any time. 379*84e872a0SLloyd Pique * 380*84e872a0SLloyd Pique * The protocol-logger-test.c file has an example of a logger implementation. 381*84e872a0SLloyd Pique */ 382*84e872a0SLloyd Pique struct wl_client_observer; 383*84e872a0SLloyd Pique 384*84e872a0SLloyd Pique struct wl_client_observer * 385*84e872a0SLloyd Pique wl_display_create_client_observer(struct wl_display *display, 386*84e872a0SLloyd Pique wl_client_message_observer_func_t observer, 387*84e872a0SLloyd Pique void *user_data); 388*84e872a0SLloyd Pique 389*84e872a0SLloyd Pique void 390*84e872a0SLloyd Pique wl_client_observer_destroy(struct wl_client_observer *observer); 391*84e872a0SLloyd Pique 392*84e872a0SLloyd Pique #ifdef __cplusplus 393*84e872a0SLloyd Pique } 394*84e872a0SLloyd Pique #endif 395*84e872a0SLloyd Pique 396*84e872a0SLloyd Pique #endif 397