1 /* 2 * Copyright (c) 2014 Red Hat, Inc. 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 #include <stdint.h> 27 #include <unistd.h> 28 #include <stdatomic.h> 29 30 #include "wayland-server.h" 31 #include "wayland-client.h" 32 33 /* info about a client on server side */ 34 struct client_info { 35 struct display *display; 36 struct wl_client *wl_client; 37 struct wl_listener destroy_listener; 38 const char *name; /* for debugging */ 39 40 int pipe; 41 pid_t pid; 42 int exit_code; 43 int kill_code; 44 45 struct wl_list link; 46 void *data; /* for arbitrary use */ 47 int log_fd; 48 }; 49 50 struct display { 51 struct wl_display *wl_display; 52 struct wl_global *test_global; 53 54 struct wl_list clients; 55 uint32_t clients_no; 56 uint32_t clients_terminated_no; 57 58 /* list of clients waiting for display_resumed event */ 59 struct wl_list waiting_for_resume; 60 uint32_t wfr_num; 61 }; 62 63 /* This is a helper structure for clients. 64 * Instead of calling wl_display_connect() and all the other stuff, 65 * client can use client_connect and it will return this structure 66 * filled. */ 67 struct client { 68 struct wl_display *wl_display; 69 struct test_compositor *tc; 70 71 atomic_bool display_stopped; 72 }; 73 74 struct client *client_connect(void); 75 void client_disconnect(struct client *); 76 int stop_display(struct client *, int); 77 void noop_request(struct client *); 78 79 /** 80 * Usual workflow: 81 * 82 * d = display_create(); 83 * 84 * wl_global_create(d->wl_display, ...); 85 * ... other setups ... 86 * 87 * client_create(d, client_main, data); 88 * client_create(d, client_main2, data); 89 * 90 * display_run(d); 91 * display_destroy(d); 92 */ 93 struct display *display_create(void); 94 void display_destroy(struct display *d); 95 void display_destroy_expect_signal(struct display *d, int signum); 96 void display_run(struct display *d); 97 98 /* This function posts the display_resumed event to all waiting clients, 99 * so that after flushing events the clients will stop waiting and continue. 100 * 101 * (Calling `display_run` after this function will resume the display loop.) 102 */ 103 void display_post_resume_events(struct display *d); 104 /* After n clients called stop_display(..., n), the display 105 * is stopped and can process the code after display_run(). 106 * 107 * This function posts the display_resumed event to the waiting 108 * clients, so that the clients will stop waiting and continue; 109 * it then reruns the display. */ 110 void display_resume(struct display *d); 111 112 /* The file descriptor containing the client log. This is only valid in the 113 * test client processes. */ 114 extern int client_log_fd; 115 116 struct client_info *client_create_with_name(struct display *d, 117 void (*client_main)(void *data), 118 void *data, 119 const char *name); 120 #define client_create(d, c, data) client_create_with_name((d), (c), data, (#c)) 121 #define client_create_noarg(d, c) \ 122 client_create_with_name((d), (void(*)(void *)) (c), NULL, (#c)) 123