windows.networking.hostname/tests: Check if passed HSTRING is duplicated.
[wine.git] / dlls / winewayland.drv / wayland.c
blobd35bd061b7eeab9a7c209c89897861cb1e28bab5
1 /*
2 * Wayland core handling
4 * Copyright (c) 2020 Alexandros Frantzis for Collabora Ltd
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #if 0
22 #pragma makedep unix
23 #endif
25 #include "config.h"
27 #include "waylanddrv.h"
29 #include "wine/debug.h"
31 #include <stdlib.h>
33 WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
35 struct wayland process_wayland =
37 .output_list = {&process_wayland.output_list, &process_wayland.output_list},
38 .output_mutex = PTHREAD_MUTEX_INITIALIZER
41 /**********************************************************************
42 * xdg_wm_base handling
45 static void xdg_wm_base_handle_ping(void *data, struct xdg_wm_base *shell,
46 uint32_t serial)
48 xdg_wm_base_pong(shell, serial);
51 static const struct xdg_wm_base_listener xdg_wm_base_listener =
53 xdg_wm_base_handle_ping
56 /**********************************************************************
57 * Registry handling
60 static void registry_handle_global(void *data, struct wl_registry *registry,
61 uint32_t id, const char *interface,
62 uint32_t version)
64 TRACE("interface=%s version=%u id=%u\n", interface, version, id);
66 if (strcmp(interface, "wl_output") == 0)
68 if (!wayland_output_create(id, version))
69 ERR("Failed to create wayland_output for global id=%u\n", id);
71 else if (strcmp(interface, "zxdg_output_manager_v1") == 0)
73 struct wayland_output *output;
75 process_wayland.zxdg_output_manager_v1 =
76 wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface,
77 version < 3 ? version : 3);
79 /* Add zxdg_output_v1 to existing outputs. */
80 wl_list_for_each(output, &process_wayland.output_list, link)
81 wayland_output_use_xdg_extension(output);
83 else if (strcmp(interface, "wl_compositor") == 0)
85 process_wayland.wl_compositor =
86 wl_registry_bind(registry, id, &wl_compositor_interface, 4);
88 else if (strcmp(interface, "xdg_wm_base") == 0)
90 /* Bind version 2 so that compositors (e.g., sway) can properly send tiled
91 * states, instead of falling back to (ab)using the maximized state. */
92 process_wayland.xdg_wm_base =
93 wl_registry_bind(registry, id, &xdg_wm_base_interface,
94 version < 2 ? version : 2);
95 xdg_wm_base_add_listener(process_wayland.xdg_wm_base, &xdg_wm_base_listener, NULL);
97 else if (strcmp(interface, "wl_shm") == 0)
99 process_wayland.wl_shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
103 static void registry_handle_global_remove(void *data, struct wl_registry *registry,
104 uint32_t id)
106 struct wayland_output *output, *tmp;
108 TRACE("id=%u\n", id);
110 wl_list_for_each_safe(output, tmp, &process_wayland.output_list, link)
112 if (output->global_id == id)
114 TRACE("removing output->name=%s\n", output->current.name);
115 wayland_output_destroy(output);
116 return;
121 static const struct wl_registry_listener registry_listener = {
122 registry_handle_global,
123 registry_handle_global_remove
126 /**********************************************************************
127 * wayland_process_init
129 * Initialise the per process wayland objects.
132 BOOL wayland_process_init(void)
134 struct wl_display *wl_display_wrapper;
136 process_wayland.wl_display = wl_display_connect(NULL);
137 if (!process_wayland.wl_display)
138 return FALSE;
140 TRACE("wl_display=%p\n", process_wayland.wl_display);
142 if (!(process_wayland.wl_event_queue = wl_display_create_queue(process_wayland.wl_display)))
144 ERR("Failed to create event queue\n");
145 return FALSE;
148 if (!(wl_display_wrapper = wl_proxy_create_wrapper(process_wayland.wl_display)))
150 ERR("Failed to create proxy wrapper for wl_display\n");
151 return FALSE;
153 wl_proxy_set_queue((struct wl_proxy *) wl_display_wrapper,
154 process_wayland.wl_event_queue);
156 process_wayland.wl_registry = wl_display_get_registry(wl_display_wrapper);
157 wl_proxy_wrapper_destroy(wl_display_wrapper);
158 if (!process_wayland.wl_registry)
160 ERR("Failed to get to wayland registry\n");
161 return FALSE;
164 /* Populate registry */
165 wl_registry_add_listener(process_wayland.wl_registry, &registry_listener, NULL);
167 /* We need two roundtrips. One to get and bind globals, one to handle all
168 * initial events produced from registering the globals. */
169 wl_display_roundtrip_queue(process_wayland.wl_display, process_wayland.wl_event_queue);
170 wl_display_roundtrip_queue(process_wayland.wl_display, process_wayland.wl_event_queue);
172 /* Check for required protocol globals. */
173 if (!process_wayland.wl_compositor)
175 ERR("Wayland compositor doesn't support wl_compositor\n");
176 return FALSE;
178 if (!process_wayland.xdg_wm_base)
180 ERR("Wayland compositor doesn't support xdg_wm_base\n");
181 return FALSE;
183 if (!process_wayland.wl_shm)
185 ERR("Wayland compositor doesn't support wl_shm\n");
186 return FALSE;
189 wayland_init_display_devices(FALSE);
191 process_wayland.initialized = TRUE;
193 return TRUE;