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_destroy(struct wl_global *global); |
251 | |
252 | /** A filter function for wl_global objects |
253 | * |
254 | * \param client The client object |
255 | * \param global The global object to show or hide |
256 | * \param data The user data pointer |
257 | * |
258 | * A filter function enables the server to decide which globals to |
259 | * advertise to each client. |
260 | * |
261 | * When a wl_global filter is set, the given callback funtion will be |
262 | * called during wl_global advertisment and binding. |
263 | * |
264 | * This function should return true if the global object should be made |
265 | * visible to the client or false otherwise. |
266 | */ |
267 | typedef bool (*wl_display_global_filter_func_t)(const struct wl_client *client, |
268 | const struct wl_global *global, |
269 | void *data); |
270 | |
271 | void |
272 | wl_display_set_global_filter(struct wl_display *display, |
273 | wl_display_global_filter_func_t filter, |
274 | void *data); |
275 | |
276 | const struct wl_interface * |
277 | wl_global_get_interface(const struct wl_global *global); |
278 | |
279 | void * |
280 | wl_global_get_user_data(const struct wl_global *global); |
281 | |
282 | struct wl_client * |
283 | wl_client_create(struct wl_display *display, int fd); |
284 | |
285 | struct wl_list * |
286 | wl_display_get_client_list(struct wl_display *display); |
287 | |
288 | struct wl_list * |
289 | wl_client_get_link(struct wl_client *client); |
290 | |
291 | struct wl_client * |
292 | wl_client_from_link(struct wl_list *link); |
293 | |
294 | /** Iterate over a list of clients. */ |
295 | #define wl_client_for_each(client, list) \ |
296 | for (client = wl_client_from_link((list)->next); \ |
297 | wl_client_get_link(client) != (list); \ |
298 | client = wl_client_from_link(wl_client_get_link(client)->next)) |
299 | |
300 | void |
301 | wl_client_destroy(struct wl_client *client); |
302 | |
303 | void |
304 | wl_client_flush(struct wl_client *client); |
305 | |
306 | void |
307 | wl_client_get_credentials(struct wl_client *client, |
308 | pid_t *pid, uid_t *uid, gid_t *gid); |
309 | |
310 | int |
311 | wl_client_get_fd(struct wl_client *client); |
312 | |
313 | void |
314 | wl_client_add_destroy_listener(struct wl_client *client, |
315 | struct wl_listener *listener); |
316 | |
317 | struct wl_listener * |
318 | wl_client_get_destroy_listener(struct wl_client *client, |
319 | wl_notify_func_t notify); |
320 | |
321 | struct wl_resource * |
322 | wl_client_get_object(struct wl_client *client, uint32_t id); |
323 | |
324 | void |
325 | wl_client_post_no_memory(struct wl_client *client); |
326 | |
327 | void |
328 | wl_client_post_implementation_error(struct wl_client *client, |
329 | const char* msg, ...) WL_PRINTF(2,3); |
330 | |
331 | void |
332 | wl_client_add_resource_created_listener(struct wl_client *client, |
333 | struct wl_listener *listener); |
334 | |
335 | typedef enum wl_iterator_result (*wl_client_for_each_resource_iterator_func_t)( |
336 | struct wl_resource *resource, |
337 | void *user_data); |
338 | |
339 | void |
340 | wl_client_for_each_resource(struct wl_client *client, |
341 | wl_client_for_each_resource_iterator_func_t iterator, |
342 | void *user_data); |
343 | |
344 | /** \class wl_listener |
345 | * |
346 | * \brief A single listener for Wayland signals |
347 | * |
348 | * wl_listener provides the means to listen for wl_signal notifications. Many |
349 | * Wayland objects use wl_listener for notification of significant events like |
350 | * object destruction. |
351 | * |
352 | * Clients should create wl_listener objects manually and can register them as |
353 | * listeners to signals using #wl_signal_add, assuming the signal is |
354 | * directly accessible. For opaque structs like wl_event_loop, adding a |
355 | * listener should be done through provided accessor methods. A listener can |
356 | * only listen to one signal at a time. |
357 | * |
358 | * \code |
359 | * struct wl_listener your_listener; |
360 | * |
361 | * your_listener.notify = your_callback_method; |
362 | * |
363 | * // Direct access |
364 | * wl_signal_add(&some_object->destroy_signal, &your_listener); |
365 | * |
366 | * // Accessor access |
367 | * wl_event_loop *loop = ...; |
368 | * wl_event_loop_add_destroy_listener(loop, &your_listener); |
369 | * \endcode |
370 | * |
371 | * If the listener is part of a larger struct, #wl_container_of can be used |
372 | * to retrieve a pointer to it: |
373 | * |
374 | * \code |
375 | * void your_listener(struct wl_listener *listener, void *data) |
376 | * { |
377 | * struct your_data *data; |
378 | * |
379 | * your_data = wl_container_of(listener, data, your_member_name); |
380 | * } |
381 | * \endcode |
382 | * |
383 | * If you need to remove a listener from a signal, use wl_list_remove(). |
384 | * |
385 | * \code |
386 | * wl_list_remove(&your_listener.link); |
387 | * \endcode |
388 | * |
389 | * \sa wl_signal |
390 | */ |
391 | struct wl_listener { |
392 | struct wl_list link; |
393 | wl_notify_func_t notify; |
394 | }; |
395 | |
396 | /** \class wl_signal |
397 | * |
398 | * \brief A source of a type of observable event |
399 | * |
400 | * Signals are recognized points where significant events can be observed. |
401 | * Compositors as well as the server can provide signals. Observers are |
402 | * wl_listener's that are added through #wl_signal_add. Signals are emitted |
403 | * using #wl_signal_emit, which will invoke all listeners until that |
404 | * listener is removed by wl_list_remove() (or whenever the signal is |
405 | * destroyed). |
406 | * |
407 | * \sa wl_listener for more information on using wl_signal |
408 | */ |
409 | struct wl_signal { |
410 | struct wl_list listener_list; |
411 | }; |
412 | |
413 | /** Initialize a new \ref wl_signal for use. |
414 | * |
415 | * \param signal The signal that will be initialized |
416 | * |
417 | * \memberof wl_signal |
418 | */ |
419 | static inline void |
420 | wl_signal_init(struct wl_signal *signal) |
421 | { |
422 | wl_list_init(&signal->listener_list); |
423 | } |
424 | |
425 | /** Add the specified listener to this signal. |
426 | * |
427 | * \param signal The signal that will emit events to the listener |
428 | * \param listener The listener to add |
429 | * |
430 | * \memberof wl_signal |
431 | */ |
432 | static inline void |
433 | wl_signal_add(struct wl_signal *signal, struct wl_listener *listener) |
434 | { |
435 | wl_list_insert(signal->listener_list.prev, &listener->link); |
436 | } |
437 | |
438 | /** Gets the listener struct for the specified callback. |
439 | * |
440 | * \param signal The signal that contains the specified listener |
441 | * \param notify The listener that is the target of this search |
442 | * \return the list item that corresponds to the specified listener, or NULL |
443 | * if none was found |
444 | * |
445 | * \memberof wl_signal |
446 | */ |
447 | static inline struct wl_listener * |
448 | wl_signal_get(struct wl_signal *signal, wl_notify_func_t notify) |
449 | { |
450 | struct wl_listener *l; |
451 | |
452 | wl_list_for_each(l, &signal->listener_list, link) |
453 | if (l->notify == notify) |
454 | return l; |
455 | |
456 | return NULL; |
457 | } |
458 | |
459 | /** Emits this signal, notifying all registered listeners. |
460 | * |
461 | * \param signal The signal object that will emit the signal |
462 | * \param data The data that will be emitted with the signal |
463 | * |
464 | * \memberof wl_signal |
465 | */ |
466 | static inline void |
467 | wl_signal_emit(struct wl_signal *signal, void *data) |
468 | { |
469 | struct wl_listener *l, *next; |
470 | |
471 | wl_list_for_each_safe(l, next, &signal->listener_list, link) |
472 | l->notify(l, data); |
473 | } |
474 | |
475 | typedef void (*wl_resource_destroy_func_t)(struct wl_resource *resource); |
476 | |
477 | /* |
478 | * Post an event to the client's object referred to by 'resource'. |
479 | * 'opcode' is the event number generated from the protocol XML |
480 | * description (the event name). The variable arguments are the event |
481 | * parameters, in the order they appear in the protocol XML specification. |
482 | * |
483 | * The variable arguments' types are: |
484 | * - type=uint: uint32_t |
485 | * - type=int: int32_t |
486 | * - type=fixed: wl_fixed_t |
487 | * - type=string: (const char *) to a nil-terminated string |
488 | * - type=array: (struct wl_array *) |
489 | * - type=fd: int, that is an open file descriptor |
490 | * - type=new_id: (struct wl_object *) or (struct wl_resource *) |
491 | * - type=object: (struct wl_object *) or (struct wl_resource *) |
492 | */ |
493 | void |
494 | wl_resource_post_event(struct wl_resource *resource, |
495 | uint32_t opcode, ...); |
496 | |
497 | void |
498 | wl_resource_post_event_array(struct wl_resource *resource, |
499 | uint32_t opcode, union wl_argument *args); |
500 | |
501 | void |
502 | wl_resource_queue_event(struct wl_resource *resource, |
503 | uint32_t opcode, ...); |
504 | |
505 | void |
506 | wl_resource_queue_event_array(struct wl_resource *resource, |
507 | uint32_t opcode, union wl_argument *args); |
508 | |
509 | /* msg is a printf format string, variable args are its args. */ |
510 | void |
511 | wl_resource_post_error(struct wl_resource *resource, |
512 | uint32_t code, const char *msg, ...) WL_PRINTF(3, 4); |
513 | |
514 | void |
515 | wl_resource_post_no_memory(struct wl_resource *resource); |
516 | |
517 | struct wl_display * |
518 | wl_client_get_display(struct wl_client *client); |
519 | |
520 | struct wl_resource * |
521 | wl_resource_create(struct wl_client *client, |
522 | const struct wl_interface *interface, |
523 | int version, uint32_t id); |
524 | |
525 | void |
526 | wl_resource_set_implementation(struct wl_resource *resource, |
527 | const void *implementation, |
528 | void *data, |
529 | wl_resource_destroy_func_t destroy); |
530 | |
531 | void |
532 | wl_resource_set_dispatcher(struct wl_resource *resource, |
533 | wl_dispatcher_func_t dispatcher, |
534 | const void *implementation, |
535 | void *data, |
536 | wl_resource_destroy_func_t destroy); |
537 | |
538 | void |
539 | wl_resource_destroy(struct wl_resource *resource); |
540 | |
541 | uint32_t |
542 | wl_resource_get_id(struct wl_resource *resource); |
543 | |
544 | struct wl_list * |
545 | wl_resource_get_link(struct wl_resource *resource); |
546 | |
547 | struct wl_resource * |
548 | wl_resource_from_link(struct wl_list *resource); |
549 | |
550 | struct wl_resource * |
551 | wl_resource_find_for_client(struct wl_list *list, struct wl_client *client); |
552 | |
553 | struct wl_client * |
554 | wl_resource_get_client(struct wl_resource *resource); |
555 | |
556 | void |
557 | wl_resource_set_user_data(struct wl_resource *resource, void *data); |
558 | |
559 | void * |
560 | wl_resource_get_user_data(struct wl_resource *resource); |
561 | |
562 | int |
563 | wl_resource_get_version(struct wl_resource *resource); |
564 | |
565 | void |
566 | wl_resource_set_destructor(struct wl_resource *resource, |
567 | wl_resource_destroy_func_t destroy); |
568 | |
569 | int |
570 | wl_resource_instance_of(struct wl_resource *resource, |
571 | const struct wl_interface *interface, |
572 | const void *implementation); |
573 | const char * |
574 | wl_resource_get_class(struct wl_resource *resource); |
575 | |
576 | void |
577 | wl_resource_add_destroy_listener(struct wl_resource *resource, |
578 | struct wl_listener *listener); |
579 | |
580 | struct wl_listener * |
581 | wl_resource_get_destroy_listener(struct wl_resource *resource, |
582 | wl_notify_func_t notify); |
583 | |
584 | #define wl_resource_for_each(resource, list) \ |
585 | for (resource = 0, resource = wl_resource_from_link((list)->next); \ |
586 | wl_resource_get_link(resource) != (list); \ |
587 | resource = wl_resource_from_link(wl_resource_get_link(resource)->next)) |
588 | |
589 | #define wl_resource_for_each_safe(resource, tmp, list) \ |
590 | for (resource = 0, tmp = 0, \ |
591 | resource = wl_resource_from_link((list)->next), \ |
592 | tmp = wl_resource_from_link((list)->next->next); \ |
593 | wl_resource_get_link(resource) != (list); \ |
594 | resource = tmp, \ |
595 | tmp = wl_resource_from_link(wl_resource_get_link(resource)->next)) |
596 | |
597 | struct wl_shm_buffer * |
598 | wl_shm_buffer_get(struct wl_resource *resource); |
599 | |
600 | void |
601 | wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer); |
602 | |
603 | void |
604 | wl_shm_buffer_end_access(struct wl_shm_buffer *buffer); |
605 | |
606 | void * |
607 | wl_shm_buffer_get_data(struct wl_shm_buffer *buffer); |
608 | |
609 | int32_t |
610 | wl_shm_buffer_get_stride(struct wl_shm_buffer *buffer); |
611 | |
612 | uint32_t |
613 | wl_shm_buffer_get_format(struct wl_shm_buffer *buffer); |
614 | |
615 | int32_t |
616 | wl_shm_buffer_get_width(struct wl_shm_buffer *buffer); |
617 | |
618 | int32_t |
619 | wl_shm_buffer_get_height(struct wl_shm_buffer *buffer); |
620 | |
621 | struct wl_shm_pool * |
622 | wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer); |
623 | |
624 | void |
625 | wl_shm_pool_unref(struct wl_shm_pool *pool); |
626 | |
627 | int |
628 | wl_display_init_shm(struct wl_display *display); |
629 | |
630 | uint32_t * |
631 | wl_display_add_shm_format(struct wl_display *display, uint32_t format); |
632 | |
633 | struct wl_shm_buffer * |
634 | wl_shm_buffer_create(struct wl_client *client, |
635 | uint32_t id, int32_t width, int32_t height, |
636 | int32_t stride, uint32_t format) WL_DEPRECATED; |
637 | |
638 | void |
639 | wl_log_set_handler_server(wl_log_func_t handler); |
640 | |
641 | enum wl_protocol_logger_type { |
642 | WL_PROTOCOL_LOGGER_REQUEST, |
643 | WL_PROTOCOL_LOGGER_EVENT, |
644 | }; |
645 | |
646 | struct wl_protocol_logger_message { |
647 | struct wl_resource *resource; |
648 | int message_opcode; |
649 | const struct wl_message *message; |
650 | int arguments_count; |
651 | const union wl_argument *arguments; |
652 | }; |
653 | |
654 | typedef void (*wl_protocol_logger_func_t)(void *user_data, |
655 | enum wl_protocol_logger_type direction, |
656 | const struct wl_protocol_logger_message *message); |
657 | |
658 | struct wl_protocol_logger * |
659 | wl_display_add_protocol_logger(struct wl_display *display, |
660 | wl_protocol_logger_func_t, void *user_data); |
661 | |
662 | void |
663 | wl_protocol_logger_destroy(struct wl_protocol_logger *logger); |
664 | |
665 | #ifdef __cplusplus |
666 | } |
667 | #endif |
668 | |
669 | #endif |
670 | |