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 29 #include "wayland-server.h" 30 #include "wayland-client.h" 31 32 /* info about a client on server side */ 33 struct client_info { 34 struct display *display; 35 struct wl_client *wl_client; 36 struct wl_listener destroy_listener; 37 const char *name; /* for debugging */ 38 39 int pipe; 40 pid_t pid; 41 int exit_code; 42 43 struct wl_list link; 44 void *data; /* for arbitrary use */ 45 }; 46 47 struct display { 48 struct wl_display *wl_display; 49 50 struct wl_list clients; 51 uint32_t clients_no; 52 uint32_t clients_terminated_no; 53 54 /* list of clients waiting for display_resumed event */ 55 struct wl_list waiting_for_resume; 56 uint32_t wfr_num; 57 }; 58 59 /* This is a helper structure for clients. 60 * Instead of calling wl_display_connect() and all the other stuff, 61 * client can use client_connect and it will return this structure 62 * filled. */ 63 struct client { 64 struct wl_display *wl_display; 65 struct test_compositor *tc; 66 67 int display_stopped; 68 }; 69 70 struct client *client_connect(void); 71 void client_disconnect(struct client *); 72 int stop_display(struct client *, int); 73 74 /** 75 * Usual workflow: 76 * 77 * d = display_create(); 78 * 79 * wl_global_create(d->wl_display, ...); 80 * ... other setups ... 81 * 82 * client_create(d, client_main, data); 83 * client_create(d, client_main2, data); 84 * 85 * display_run(d); 86 * display_destroy(d); 87 */ 88 struct display *display_create(void); 89 void display_destroy(struct display *d); 90 void display_run(struct display *d); 91 92 /* After n clients called stop_display(..., n), the display 93 * is stopped and can process the code after display_run(). 94 * This function rerun the display again and send display_resumed 95 * event to waiting clients, so the clients will stop waiting and continue */ 96 void display_resume(struct display *d); 97 98 struct client_info *client_create_with_name(struct display *d, 99 void (*client_main)(void *data), 100 void *data, 101 const char *name); 102 #define client_create(d, c, data) client_create_with_name((d), (c), data, (#c)) 103 #define client_create_noarg(d, c) \ 104 client_create_with_name((d), (void(*)(void *)) (c), NULL, (#c)) 105