1 | /* |
2 | * Copyright © 2008 Kristian Høgsberg |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining |
5 | * a copy of this software and associated documentation files (the |
6 | * "Software"), to deal in the Software without restriction, including |
7 | * without limitation the rights to use, copy, modify, merge, publish, |
8 | * distribute, sublicense, and/or sell copies of the Software, and to |
9 | * permit persons to whom the Software is furnished to do so, subject to |
10 | * the following conditions: |
11 | * |
12 | * The above copyright notice and this permission notice (including the |
13 | * next paragraph) shall be included in all copies or substantial |
14 | * portions of the Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
20 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
21 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 | * SOFTWARE. |
24 | */ |
25 | |
26 | #ifndef WAYLAND_SERVER_CORE_H |
27 | #define WAYLAND_SERVER_CORE_H |
28 | |
29 | #include <sys/types.h> |
30 | #include <stdint.h> |
31 | #include <stdbool.h> |
32 | #include "wayland-util.h" |
33 | #include "wayland-version.h" |
34 | |
35 | #ifdef __cplusplus |
36 | extern "C" { |
37 | #endif |
38 | |
39 | enum { |
40 | WL_EVENT_READABLE = 0x01, |
41 | WL_EVENT_WRITABLE = 0x02, |
42 | WL_EVENT_HANGUP = 0x04, |
43 | WL_EVENT_ERROR = 0x08 |
44 | }; |
45 | |
46 | /** File descriptor dispatch function type |
47 | * |
48 | * Functions of this type are used as callbacks for file descriptor events. |
49 | * |
50 | * \param fd The file descriptor delivering the event. |
51 | * \param mask Describes the kind of the event as a bitwise-or of: |
52 | * \c WL_EVENT_READABLE, \c WL_EVENT_WRITABLE, \c WL_EVENT_HANGUP, |
53 | * \c WL_EVENT_ERROR. |
54 | * \param data The user data argument of the related wl_event_loop_add_fd() |
55 | * call. |
56 | * \return If the event source is registered for re-check with |
57 | * wl_event_source_check(): 0 for all done, 1 for needing a re-check. |
58 | * If not registered, the return value is ignored and should be zero. |
59 | * |
60 | * \sa wl_event_loop_add_fd() |
61 | * \memberof wl_event_source |
62 | */ |
63 | typedef int (*wl_event_loop_fd_func_t)(int fd, uint32_t mask, void *data); |
64 | |
65 | /** Timer dispatch function type |
66 | * |
67 | * Functions of this type are used as callbacks for timer expiry. |
68 | * |
69 | * \param data The user data argument of the related wl_event_loop_add_timer() |
70 | * call. |
71 | * \return If the event source is registered for re-check with |
72 | * wl_event_source_check(): 0 for all done, 1 for needing a re-check. |
73 | * If not registered, the return value is ignored and should be zero. |
74 | * |
75 | * \sa wl_event_loop_add_timer() |
76 | * \memberof wl_event_source |
77 | */ |
78 | typedef int (*wl_event_loop_timer_func_t)(void *data); |
79 | |
80 | /** Signal dispatch function type |
81 | * |
82 | * Functions of this type are used as callbacks for (POSIX) signals. |
83 | * |
84 | * \param signal_number |
85 | * \param data The user data argument of the related wl_event_loop_add_signal() |
86 | * call. |
87 | * \return If the event source is registered for re-check with |
88 | * wl_event_source_check(): 0 for all done, 1 for needing a re-check. |
89 | * If not registered, the return value is ignored and should be zero. |
90 | * |
91 | * \sa wl_event_loop_add_signal() |
92 | * \memberof wl_event_source |
93 | */ |
94 | typedef int (*wl_event_loop_signal_func_t)(int signal_number, void *data); |
95 | |
96 | /** Idle task function type |
97 | * |
98 | * Functions of this type are used as callbacks before blocking in |
99 | * wl_event_loop_dispatch(). |
100 | * |
101 | * \param data The user data argument of the related wl_event_loop_add_idle() |
102 | * call. |
103 | * |
104 | * \sa wl_event_loop_add_idle() wl_event_loop_dispatch() |
105 | * \memberof wl_event_source |
106 | */ |
107 | typedef void (*wl_event_loop_idle_func_t)(void *data); |
108 | |
109 | /** \struct wl_event_loop |
110 | * |
111 | * \brief An event loop context |
112 | * |
113 | * Usually you create an event loop context, add sources to it, and call |
114 | * wl_event_loop_dispatch() in a loop to process events. |
115 | * |
116 | * \sa wl_event_source |
117 | */ |
118 | |
119 | /** \struct wl_event_source |
120 | * |
121 | * \brief An abstract event source |
122 | * |
123 | * This is the generic type for fd, timer, signal, and idle sources. |
124 | * Functions that operate on specific source types must not be used with |
125 | * a different type, even if the function signature allows it. |
126 | */ |
127 | |
128 | struct wl_event_loop * |
129 | wl_event_loop_create(void); |
130 | |
131 | void |
132 | wl_event_loop_destroy(struct wl_event_loop *loop); |
133 | |
134 | struct wl_event_source * |
135 | wl_event_loop_add_fd(struct wl_event_loop *loop, |
136 | int fd, uint32_t mask, |
137 | wl_event_loop_fd_func_t func, |
138 | void *data); |
139 | |
140 | int |
141 | wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask); |
142 | |
143 | struct wl_event_source * |
144 | wl_event_loop_add_timer(struct wl_event_loop *loop, |
145 | wl_event_loop_timer_func_t func, |
146 | void *data); |
147 | |
148 | struct wl_event_source * |
149 | wl_event_loop_add_signal(struct wl_event_loop *loop, |
150 | int signal_number, |
151 | wl_event_loop_signal_func_t func, |
152 | void *data); |
153 | |
154 | int |
155 | wl_event_source_timer_update(struct wl_event_source *source, |
156 | int ms_delay); |
157 | |
158 | int |
159 | wl_event_source_remove(struct wl_event_source *source); |
160 | |
161 | void |
162 | wl_event_source_check(struct wl_event_source *source); |
163 | |
164 | int |
165 | wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout); |
166 | |
167 | void |
168 | wl_event_loop_dispatch_idle(struct wl_event_loop *loop); |
169 | |
170 | struct wl_event_source * |
171 | wl_event_loop_add_idle(struct wl_event_loop *loop, |
172 | wl_event_loop_idle_func_t func, |
173 | void *data); |
174 | |
175 | int |
176 | wl_event_loop_get_fd(struct wl_event_loop *loop); |
177 | |
178 | struct wl_listener; |
179 | |
180 | typedef void (*wl_notify_func_t)(struct wl_listener *listener, void *data); |
181 | |
182 | void |
183 | wl_event_loop_add_destroy_listener(struct wl_event_loop *loop, |
184 | struct wl_listener *listener); |
185 | |
186 | struct wl_listener * |
187 | wl_event_loop_get_destroy_listener(struct wl_event_loop *loop, |
188 | wl_notify_func_t notify); |
189 | |
190 | struct wl_display * |
191 | wl_display_create(void); |
192 | |
193 | void |
194 | wl_display_destroy(struct wl_display *display); |
195 | |
196 | struct wl_event_loop * |
197 | wl_display_get_event_loop(struct wl_display *display); |
198 | |
199 | int |
200 | wl_display_add_socket(struct wl_display *display, const char *name); |
201 | |
202 | const char * |
203 | wl_display_add_socket_auto(struct wl_display *display); |
204 | |
205 | int |
206 | wl_display_add_socket_fd(struct wl_display *display, int sock_fd); |
207 | |
208 | void |
209 | wl_display_terminate(struct wl_display *display); |
210 | |
211 | void |
212 | wl_display_run(struct wl_display *display); |
213 | |
214 | void |
215 | wl_display_flush_clients(struct wl_display *display); |
216 | |
217 | void |
218 | wl_display_destroy_clients(struct wl_display *display); |
219 | |
220 | struct wl_client; |
221 | |
222 | typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data, |
223 | uint32_t version, uint32_t id); |
224 | |
225 | uint32_t |
226 | wl_display_get_serial(struct wl_display *display); |
227 | |
228 | uint32_t |
229 | wl_display_next_serial(struct wl_display *display); |
230 | |
231 | void |
232 | wl_display_add_destroy_listener(struct wl_display *display, |
233 | struct wl_listener *listener); |
234 | |
235 | void |
236 | wl_display_add_client_created_listener(struct wl_display *display, |
237 | struct wl_listener *listener); |
238 | |
239 | struct wl_listener * |
240 | wl_display_get_destroy_listener(struct wl_display *display, |
241 | wl_notify_func_t notify); |
242 | |
243 | struct wl_global * |
244 | wl_global_create(struct wl_display *display, |
245 | const struct wl_interface *interface, |
246 | int version, |
247 | void *data, wl_global_bind_func_t bind); |
248 | |
249 | void |
250 | wl_global_remove(struct wl_global *global); |
251 | |
252 | void |
253 | wl_global_destroy(struct wl_global *global); |
254 | |
255 | /** A filter function for wl_global objects |
256 | * |
257 | * \param client The client object |
258 | * \param global The global object to show or hide |
259 | * \param data The user data pointer |
260 | * |
261 | * A filter function enables the server to decide which globals to |
262 | * advertise to each client. |
263 | * |
264 | * When a wl_global filter is set, the given callback function will be |
265 | * called during wl_global advertisement and binding. |
266 | * |
267 | * This function should return true if the global object should be made |
268 | * visible to the client or false otherwise. |
269 | */ |
270 | typedef bool (*wl_display_global_filter_func_t)(const struct wl_client *client, |
271 | const struct wl_global *global, |
272 | void *data); |
273 | |
274 | void |
275 | wl_display_set_global_filter(struct wl_display *display, |
276 | wl_display_global_filter_func_t filter, |
277 | void *data); |
278 | |
279 | const struct wl_interface * |
280 | wl_global_get_interface(const struct wl_global *global); |
281 | |
282 | struct wl_display * |
283 | wl_global_get_display(const struct wl_global *global); |
284 | |
285 | void * |
286 | wl_global_get_user_data(const struct wl_global *global); |
287 | |
288 | void |
289 | wl_global_set_user_data(struct wl_global *global, void *data); |
290 | |
291 | struct wl_client * |
292 | wl_client_create(struct wl_display *display, int fd); |
293 | |
294 | struct wl_list * |
295 | wl_display_get_client_list(struct wl_display *display); |
296 | |
297 | struct wl_list * |
298 | wl_client_get_link(struct wl_client *client); |
299 | |
300 | struct wl_client * |
301 | wl_client_from_link(struct wl_list *link); |
302 | |
303 | /** Iterate over a list of clients. */ |
304 | #define wl_client_for_each(client, list) \ |
305 | for (client = wl_client_from_link((list)->next); \ |
306 | wl_client_get_link(client) != (list); \ |
307 | client = wl_client_from_link(wl_client_get_link(client)->next)) |
308 | |
309 | void |
310 | wl_client_destroy(struct wl_client *client); |
311 | |
312 | void |
313 | wl_client_flush(struct wl_client *client); |
314 | |
315 | void |
316 | wl_client_get_credentials(struct wl_client *client, |
317 | pid_t *pid, uid_t *uid, gid_t *gid); |
318 | |
319 | int |
320 | wl_client_get_fd(struct wl_client *client); |
321 | |
322 | void |
323 | wl_client_add_destroy_listener(struct wl_client *client, |
324 | struct wl_listener *listener); |
325 | |
326 | struct wl_listener * |
327 | wl_client_get_destroy_listener(struct wl_client *client, |
328 | wl_notify_func_t notify); |
329 | |
330 | struct wl_resource * |
331 | wl_client_get_object(struct wl_client *client, uint32_t id); |
332 | |
333 | void |
334 | wl_client_post_no_memory(struct wl_client *client); |
335 | |
336 | void |
337 | wl_client_post_implementation_error(struct wl_client *client, |
338 | const char* msg, ...) WL_PRINTF(2,3); |
339 | |
340 | void |
341 | wl_client_add_resource_created_listener(struct wl_client *client, |
342 | struct wl_listener *listener); |
343 | |
344 | typedef enum wl_iterator_result (*wl_client_for_each_resource_iterator_func_t)( |
345 | struct wl_resource *resource, |
346 | void *user_data); |
347 | |
348 | void |
349 | wl_client_for_each_resource(struct wl_client *client, |
350 | wl_client_for_each_resource_iterator_func_t iterator, |
351 | void *user_data); |
352 | |
353 | /** \class wl_listener |
354 | * |
355 | * \brief A single listener for Wayland signals |
356 | * |
357 | * wl_listener provides the means to listen for wl_signal notifications. Many |
358 | * Wayland objects use wl_listener for notification of significant events like |
359 | * object destruction. |
360 | * |
361 | * Clients should create wl_listener objects manually and can register them as |
362 | * listeners to signals using #wl_signal_add, assuming the signal is |
363 | * directly accessible. For opaque structs like wl_event_loop, adding a |
364 | * listener should be done through provided accessor methods. A listener can |
365 | * only listen to one signal at a time. |
366 | * |
367 | * \code |
368 | * struct wl_listener your_listener; |
369 | * |
370 | * your_listener.notify = your_callback_method; |
371 | * |
372 | * // Direct access |
373 | * wl_signal_add(&some_object->destroy_signal, &your_listener); |
374 | * |
375 | * // Accessor access |
376 | * wl_event_loop *loop = ...; |
377 | * wl_event_loop_add_destroy_listener(loop, &your_listener); |
378 | * \endcode |
379 | * |
380 | * If the listener is part of a larger struct, #wl_container_of can be used |
381 | * to retrieve a pointer to it: |
382 | * |
383 | * \code |
384 | * void your_listener(struct wl_listener *listener, void *data) |
385 | * { |
386 | * struct your_data *data; |
387 | * |
388 | * your_data = wl_container_of(listener, data, your_member_name); |
389 | * } |
390 | * \endcode |
391 | * |
392 | * If you need to remove a listener from a signal, use wl_list_remove(). |
393 | * |
394 | * \code |
395 | * wl_list_remove(&your_listener.link); |
396 | * \endcode |
397 | * |
398 | * \sa wl_signal |
399 | */ |
400 | struct wl_listener { |
401 | struct wl_list link; |
402 | wl_notify_func_t notify; |
403 | }; |
404 | |
405 | /** \class wl_signal |
406 | * |
407 | * \brief A source of a type of observable event |
408 | * |
409 | * Signals are recognized points where significant events can be observed. |
410 | * Compositors as well as the server can provide signals. Observers are |
411 | * wl_listener's that are added through #wl_signal_add. Signals are emitted |
412 | * using #wl_signal_emit, which will invoke all listeners until that |
413 | * listener is removed by wl_list_remove() (or whenever the signal is |
414 | * destroyed). |
415 | * |
416 | * \sa wl_listener for more information on using wl_signal |
417 | */ |
418 | struct wl_signal { |
419 | struct wl_list listener_list; |
420 | }; |
421 | |
422 | /** Initialize a new \ref wl_signal for use. |
423 | * |
424 | * \param signal The signal that will be initialized |
425 | * |
426 | * \memberof wl_signal |
427 | */ |
428 | static inline void |
429 | wl_signal_init(struct wl_signal *signal) |
430 | { |
431 | wl_list_init(list: &signal->listener_list); |
432 | } |
433 | |
434 | /** Add the specified listener to this signal. |
435 | * |
436 | * \param signal The signal that will emit events to the listener |
437 | * \param listener The listener to add |
438 | * |
439 | * \memberof wl_signal |
440 | */ |
441 | static inline void |
442 | wl_signal_add(struct wl_signal *signal, struct wl_listener *listener) |
443 | { |
444 | wl_list_insert(list: signal->listener_list.prev, elm: &listener->link); |
445 | } |
446 | |
447 | /** Gets the listener struct for the specified callback. |
448 | * |
449 | * \param signal The signal that contains the specified listener |
450 | * \param notify The listener that is the target of this search |
451 | * \return the list item that corresponds to the specified listener, or NULL |
452 | * if none was found |
453 | * |
454 | * \memberof wl_signal |
455 | */ |
456 | static inline struct wl_listener * |
457 | wl_signal_get(struct wl_signal *signal, wl_notify_func_t notify) |
458 | { |
459 | struct wl_listener *l; |
460 | |
461 | wl_list_for_each(l, &signal->listener_list, link) |
462 | if (l->notify == notify) |
463 | return l; |
464 | |
465 | return NULL; |
466 | } |
467 | |
468 | /** Emits this signal, notifying all registered listeners. |
469 | * |
470 | * \param signal The signal object that will emit the signal |
471 | * \param data The data that will be emitted with the signal |
472 | * |
473 | * \memberof wl_signal |
474 | */ |
475 | static inline void |
476 | wl_signal_emit(struct wl_signal *signal, void *data) |
477 | { |
478 | struct wl_listener *l, *next; |
479 | |
480 | wl_list_for_each_safe(l, next, &signal->listener_list, link) |
481 | l->notify(l, data); |
482 | } |
483 | |
484 | typedef void (*wl_resource_destroy_func_t)(struct wl_resource *resource); |
485 | |
486 | /* |
487 | * Post an event to the client's object referred to by 'resource'. |
488 | * 'opcode' is the event number generated from the protocol XML |
489 | * description (the event name). The variable arguments are the event |
490 | * parameters, in the order they appear in the protocol XML specification. |
491 | * |
492 | * The variable arguments' types are: |
493 | * - type=uint: uint32_t |
494 | * - type=int: int32_t |
495 | * - type=fixed: wl_fixed_t |
496 | * - type=string: (const char *) to a nil-terminated string |
497 | * - type=array: (struct wl_array *) |
498 | * - type=fd: int, that is an open file descriptor |
499 | * - type=new_id: (struct wl_object *) or (struct wl_resource *) |
500 | * - type=object: (struct wl_object *) or (struct wl_resource *) |
501 | */ |
502 | void |
503 | wl_resource_post_event(struct wl_resource *resource, |
504 | uint32_t opcode, ...); |
505 | |
506 | void |
507 | wl_resource_post_event_array(struct wl_resource *resource, |
508 | uint32_t opcode, union wl_argument *args); |
509 | |
510 | void |
511 | wl_resource_queue_event(struct wl_resource *resource, |
512 | uint32_t opcode, ...); |
513 | |
514 | void |
515 | wl_resource_queue_event_array(struct wl_resource *resource, |
516 | uint32_t opcode, union wl_argument *args); |
517 | |
518 | /* msg is a printf format string, variable args are its args. */ |
519 | void |
520 | wl_resource_post_error(struct wl_resource *resource, |
521 | uint32_t code, const char *msg, ...) WL_PRINTF(3, 4); |
522 | |
523 | void |
524 | wl_resource_post_no_memory(struct wl_resource *resource); |
525 | |
526 | struct wl_display * |
527 | wl_client_get_display(struct wl_client *client); |
528 | |
529 | struct wl_resource * |
530 | wl_resource_create(struct wl_client *client, |
531 | const struct wl_interface *interface, |
532 | int version, uint32_t id); |
533 | |
534 | void |
535 | wl_resource_set_implementation(struct wl_resource *resource, |
536 | const void *implementation, |
537 | void *data, |
538 | wl_resource_destroy_func_t destroy); |
539 | |
540 | void |
541 | wl_resource_set_dispatcher(struct wl_resource *resource, |
542 | wl_dispatcher_func_t dispatcher, |
543 | const void *implementation, |
544 | void *data, |
545 | wl_resource_destroy_func_t destroy); |
546 | |
547 | void |
548 | wl_resource_destroy(struct wl_resource *resource); |
549 | |
550 | uint32_t |
551 | wl_resource_get_id(struct wl_resource *resource); |
552 | |
553 | struct wl_list * |
554 | wl_resource_get_link(struct wl_resource *resource); |
555 | |
556 | struct wl_resource * |
557 | wl_resource_from_link(struct wl_list *resource); |
558 | |
559 | struct wl_resource * |
560 | wl_resource_find_for_client(struct wl_list *list, struct wl_client *client); |
561 | |
562 | struct wl_client * |
563 | wl_resource_get_client(struct wl_resource *resource); |
564 | |
565 | void |
566 | wl_resource_set_user_data(struct wl_resource *resource, void *data); |
567 | |
568 | void * |
569 | wl_resource_get_user_data(struct wl_resource *resource); |
570 | |
571 | int |
572 | wl_resource_get_version(struct wl_resource *resource); |
573 | |
574 | void |
575 | wl_resource_set_destructor(struct wl_resource *resource, |
576 | wl_resource_destroy_func_t destroy); |
577 | |
578 | int |
579 | wl_resource_instance_of(struct wl_resource *resource, |
580 | const struct wl_interface *interface, |
581 | const void *implementation); |
582 | const char * |
583 | wl_resource_get_class(struct wl_resource *resource); |
584 | |
585 | void |
586 | wl_resource_add_destroy_listener(struct wl_resource *resource, |
587 | struct wl_listener *listener); |
588 | |
589 | struct wl_listener * |
590 | wl_resource_get_destroy_listener(struct wl_resource *resource, |
591 | wl_notify_func_t notify); |
592 | |
593 | #define wl_resource_for_each(resource, list) \ |
594 | for (resource = 0, resource = wl_resource_from_link((list)->next); \ |
595 | wl_resource_get_link(resource) != (list); \ |
596 | resource = wl_resource_from_link(wl_resource_get_link(resource)->next)) |
597 | |
598 | #define wl_resource_for_each_safe(resource, tmp, list) \ |
599 | for (resource = 0, tmp = 0, \ |
600 | resource = wl_resource_from_link((list)->next), \ |
601 | tmp = wl_resource_from_link((list)->next->next); \ |
602 | wl_resource_get_link(resource) != (list); \ |
603 | resource = tmp, \ |
604 | tmp = wl_resource_from_link(wl_resource_get_link(resource)->next)) |
605 | |
606 | struct wl_shm_buffer * |
607 | wl_shm_buffer_get(struct wl_resource *resource); |
608 | |
609 | void |
610 | wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer); |
611 | |
612 | void |
613 | wl_shm_buffer_end_access(struct wl_shm_buffer *buffer); |
614 | |
615 | void * |
616 | wl_shm_buffer_get_data(struct wl_shm_buffer *buffer); |
617 | |
618 | int32_t |
619 | wl_shm_buffer_get_stride(struct wl_shm_buffer *buffer); |
620 | |
621 | uint32_t |
622 | wl_shm_buffer_get_format(struct wl_shm_buffer *buffer); |
623 | |
624 | int32_t |
625 | wl_shm_buffer_get_width(struct wl_shm_buffer *buffer); |
626 | |
627 | int32_t |
628 | wl_shm_buffer_get_height(struct wl_shm_buffer *buffer); |
629 | |
630 | struct wl_shm_pool * |
631 | wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer); |
632 | |
633 | void |
634 | wl_shm_pool_unref(struct wl_shm_pool *pool); |
635 | |
636 | int |
637 | wl_display_init_shm(struct wl_display *display); |
638 | |
639 | uint32_t * |
640 | wl_display_add_shm_format(struct wl_display *display, uint32_t format); |
641 | |
642 | struct wl_shm_buffer * |
643 | wl_shm_buffer_create(struct wl_client *client, |
644 | uint32_t id, int32_t width, int32_t height, |
645 | int32_t stride, uint32_t format) WL_DEPRECATED; |
646 | |
647 | void |
648 | wl_log_set_handler_server(wl_log_func_t handler); |
649 | |
650 | enum wl_protocol_logger_type { |
651 | WL_PROTOCOL_LOGGER_REQUEST, |
652 | WL_PROTOCOL_LOGGER_EVENT, |
653 | }; |
654 | |
655 | struct wl_protocol_logger_message { |
656 | struct wl_resource *resource; |
657 | int message_opcode; |
658 | const struct wl_message *message; |
659 | int arguments_count; |
660 | const union wl_argument *arguments; |
661 | }; |
662 | |
663 | typedef void (*wl_protocol_logger_func_t)(void *user_data, |
664 | enum wl_protocol_logger_type direction, |
665 | const struct wl_protocol_logger_message *message); |
666 | |
667 | struct wl_protocol_logger * |
668 | wl_display_add_protocol_logger(struct wl_display *display, |
669 | wl_protocol_logger_func_t, void *user_data); |
670 | |
671 | void |
672 | wl_protocol_logger_destroy(struct wl_protocol_logger *logger); |
673 | |
674 | #ifdef __cplusplus |
675 | } |
676 | #endif |
677 | |
678 | #endif |
679 | |