| /* |
| * Copyright (c) 2014 Red Hat, Inc. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sublicense, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the |
| * next paragraph) shall be included in all copies or substantial |
| * portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| */ |
| |
| #include <stdint.h> |
| #include <unistd.h> |
| |
| #include "wayland-server.h" |
| #include "wayland-client.h" |
| |
| /* info about a client on server side */ |
| struct client_info { |
| struct display *display; |
| struct wl_client *wl_client; |
| struct wl_listener destroy_listener; |
| const char *name; /* for debugging */ |
| |
| int pipe; |
| pid_t pid; |
| int exit_code; |
| |
| struct wl_list link; |
| void *data; /* for arbitrary use */ |
| }; |
| |
| struct display { |
| struct wl_display *wl_display; |
| |
| struct wl_list clients; |
| uint32_t clients_no; |
| uint32_t clients_terminated_no; |
| |
| /* list of clients waiting for display_resumed event */ |
| struct wl_list waiting_for_resume; |
| uint32_t wfr_num; |
| }; |
| |
| /* This is a helper structure for clients. |
| * Instead of calling wl_display_connect() and all the other stuff, |
| * client can use client_connect and it will return this structure |
| * filled. */ |
| struct client { |
| struct wl_display *wl_display; |
| struct test_compositor *tc; |
| |
| int display_stopped; |
| }; |
| |
| struct client *client_connect(void); |
| void client_disconnect(struct client *); |
| int stop_display(struct client *, int); |
| |
| /** |
| * Usual workflow: |
| * |
| * d = display_create(); |
| * |
| * wl_global_create(d->wl_display, ...); |
| * ... other setups ... |
| * |
| * client_create(d, client_main, data); |
| * client_create(d, client_main2, data); |
| * |
| * display_run(d); |
| * display_destroy(d); |
| */ |
| struct display *display_create(void); |
| void display_destroy(struct display *d); |
| void display_run(struct display *d); |
| |
| /* After n clients called stop_display(..., n), the display |
| * is stopped and can process the code after display_run(). |
| * This function rerun the display again and send display_resumed |
| * event to waiting clients, so the clients will stop waiting and continue */ |
| void display_resume(struct display *d); |
| |
| struct client_info *client_create_with_name(struct display *d, |
| void (*client_main)(void *data), |
| void *data, |
| const char *name); |
| #define client_create(d, c, data) client_create_with_name((d), (c), data, (#c)) |
| #define client_create_noarg(d, c) \ |
| client_create_with_name((d), (void(*)(void *)) (c), NULL, (#c)) |