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