File: | cdk/wayland/cdkdisplay-wayland.c |
Warning: | line 1391, column 13 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright © 2010 Intel Corporation | |||
3 | * | |||
4 | * This library is free software; you can redistribute it and/or | |||
5 | * modify it under the terms of the GNU Library General Public | |||
6 | * License as published by the Free Software Foundation; either | |||
7 | * version 2 of the License, or (at your option) any later version. | |||
8 | * | |||
9 | * This library is distributed in the hope that it will be useful, | |||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
12 | * Library General Public License for more details. | |||
13 | * | |||
14 | * You should have received a copy of the GNU Library General Public | |||
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
16 | */ | |||
17 | ||||
18 | #include "config.h" | |||
19 | ||||
20 | #include <stdlib.h> | |||
21 | #include <string.h> | |||
22 | #include <errno(*__errno_location ()).h> | |||
23 | #include <unistd.h> | |||
24 | #include <fcntl.h> | |||
25 | ||||
26 | #ifdef HAVE_LINUX_MEMFD_H1 | |||
27 | #include <linux1/memfd.h> | |||
28 | #endif | |||
29 | ||||
30 | #include <sys/mman.h> | |||
31 | #include <sys/syscall.h> | |||
32 | ||||
33 | #include <glib.h> | |||
34 | #include "cdkwayland.h" | |||
35 | #include "cdkdisplay.h" | |||
36 | #include "cdkdisplay-wayland.h" | |||
37 | #include "cdkscreen.h" | |||
38 | #include "cdkinternals.h" | |||
39 | #include "cdkdeviceprivate.h" | |||
40 | #include "cdkdevicemanager.h" | |||
41 | #include "cdkkeysprivate.h" | |||
42 | #include "cdkprivate-wayland.h" | |||
43 | #include "cdkglcontext-wayland.h" | |||
44 | #include "cdkwaylandmonitor.h" | |||
45 | #include "cdk-private.h" | |||
46 | #include "pointer-gestures-unstable-v1-client-protocol.h" | |||
47 | #include "tablet-unstable-v2-client-protocol.h" | |||
48 | #include "xdg-shell-unstable-v6-client-protocol.h" | |||
49 | #include "xdg-foreign-unstable-v1-client-protocol.h" | |||
50 | #include "server-decoration-client-protocol.h" | |||
51 | ||||
52 | /** | |||
53 | * SECTION:wayland_interaction | |||
54 | * @Short_description: Wayland backend-specific functions | |||
55 | * @Title: Wayland Interaction | |||
56 | * | |||
57 | * The functions in this section are specific to the CDK Wayland backend. | |||
58 | * To use them, you need to include the `<cdk/cdkwayland.h>` header and use | |||
59 | * the Wayland-specific pkg-config files to build your application (either | |||
60 | * `cdk-wayland-3.0` or `ctk+-wayland-3.0`). | |||
61 | * | |||
62 | * To make your code compile with other CDK backends, guard backend-specific | |||
63 | * calls by an ifdef as follows. Since CDK may be built with multiple | |||
64 | * backends, you should also check for the backend that is in use (e.g. by | |||
65 | * using the CDK_IS_WAYLAND_DISPLAY() macro). | |||
66 | * |[<!-- language="C" --> | |||
67 | * #ifdef CDK_WINDOWING_WAYLAND | |||
68 | * if (CDK_IS_WAYLAND_DISPLAY (display)) | |||
69 | * { | |||
70 | * // make Wayland-specific calls here | |||
71 | * } | |||
72 | * else | |||
73 | * #endif | |||
74 | * #ifdef CDK_WINDOWING_X11 | |||
75 | * if (CDK_IS_X11_DISPLAY (display)) | |||
76 | * { | |||
77 | * // make X11-specific calls here | |||
78 | * } | |||
79 | * else | |||
80 | * #endif | |||
81 | * g_error ("Unsupported CDK backend"); | |||
82 | * ]| | |||
83 | */ | |||
84 | ||||
85 | #define MIN_SYSTEM_BELL_DELAY_MS20 20 | |||
86 | ||||
87 | #define CTK_SHELL1_VERSION3 3 | |||
88 | ||||
89 | static void _cdk_wayland_display_load_cursor_theme (CdkWaylandDisplay *display_wayland); | |||
90 | ||||
91 | G_DEFINE_TYPE (CdkWaylandDisplay, cdk_wayland_display, CDK_TYPE_DISPLAY)static void cdk_wayland_display_init (CdkWaylandDisplay *self ); static void cdk_wayland_display_class_init (CdkWaylandDisplayClass *klass); static GType cdk_wayland_display_get_type_once (void ); static gpointer cdk_wayland_display_parent_class = ((void* )0); static gint CdkWaylandDisplay_private_offset; static void cdk_wayland_display_class_intern_init (gpointer klass) { cdk_wayland_display_parent_class = g_type_class_peek_parent (klass); if (CdkWaylandDisplay_private_offset != 0) g_type_class_adjust_private_offset (klass, &CdkWaylandDisplay_private_offset ); cdk_wayland_display_class_init ((CdkWaylandDisplayClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer cdk_wayland_display_get_instance_private (CdkWaylandDisplay *self) { return (((gpointer) ((guint8*) ( self) + (glong) (CdkWaylandDisplay_private_offset)))); } GType cdk_wayland_display_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = cdk_wayland_display_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType cdk_wayland_display_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((cdk_display_get_type ()), g_intern_static_string ("CdkWaylandDisplay" ), sizeof (CdkWaylandDisplayClass), (GClassInitFunc)(void (*) (void)) cdk_wayland_display_class_intern_init, sizeof (CdkWaylandDisplay ), (GInstanceInitFunc)(void (*)(void)) cdk_wayland_display_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } | |||
92 | ||||
93 | static void | |||
94 | async_roundtrip_callback (void *data, | |||
95 | struct wl_callback *callback, | |||
96 | uint32_t time G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
97 | { | |||
98 | CdkWaylandDisplay *display_wayland = data; | |||
99 | ||||
100 | display_wayland->async_roundtrips = | |||
101 | g_list_remove (display_wayland->async_roundtrips, callback); | |||
102 | wl_callback_destroy (callback); | |||
103 | } | |||
104 | ||||
105 | static const struct wl_callback_listener async_roundtrip_listener = { | |||
106 | async_roundtrip_callback | |||
107 | }; | |||
108 | ||||
109 | static void | |||
110 | _cdk_wayland_display_async_roundtrip (CdkWaylandDisplay *display_wayland) | |||
111 | { | |||
112 | struct wl_callback *callback; | |||
113 | ||||
114 | callback = wl_display_sync (display_wayland->wl_display); | |||
115 | wl_callback_add_listener (callback, | |||
116 | &async_roundtrip_listener, | |||
117 | display_wayland); | |||
118 | display_wayland->async_roundtrips = | |||
119 | g_list_append (display_wayland->async_roundtrips, callback); | |||
120 | } | |||
121 | ||||
122 | static void | |||
123 | xdg_wm_base_ping (void *data, | |||
124 | struct xdg_wm_base *xdg_wm_base, | |||
125 | uint32_t serial) | |||
126 | { | |||
127 | CdkWaylandDisplay *display_wayland = data; | |||
128 | ||||
129 | _cdk_wayland_display_update_serial (display_wayland, serial); | |||
130 | ||||
131 | CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message ("ping, shell %p, serial %u\n", xdg_wm_base, serial); }; } while (0) | |||
132 | g_message ("ping, shell %p, serial %u\n", xdg_wm_base, serial))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message ("ping, shell %p, serial %u\n", xdg_wm_base, serial); }; } while (0); | |||
133 | ||||
134 | xdg_wm_base_pong (xdg_wm_base, serial); | |||
135 | } | |||
136 | ||||
137 | static const struct xdg_wm_base_listener xdg_wm_base_listener = { | |||
138 | xdg_wm_base_ping, | |||
139 | }; | |||
140 | ||||
141 | static void | |||
142 | zxdg_shell_v6_ping (void *data, | |||
143 | struct zxdg_shell_v6 *xdg_shell, | |||
144 | uint32_t serial) | |||
145 | { | |||
146 | CdkWaylandDisplay *display_wayland = data; | |||
147 | ||||
148 | _cdk_wayland_display_update_serial (display_wayland, serial); | |||
149 | ||||
150 | CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message ("ping, shell %p, serial %u\n", xdg_shell, serial); }; } while (0) | |||
151 | g_message ("ping, shell %p, serial %u\n", xdg_shell, serial))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message ("ping, shell %p, serial %u\n", xdg_shell, serial); }; } while (0); | |||
152 | ||||
153 | zxdg_shell_v6_pong (xdg_shell, serial); | |||
154 | } | |||
155 | ||||
156 | static const struct zxdg_shell_v6_listener zxdg_shell_v6_listener = { | |||
157 | zxdg_shell_v6_ping, | |||
158 | }; | |||
159 | ||||
160 | static gboolean | |||
161 | is_known_global (gpointer key G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
162 | gpointer value, | |||
163 | gpointer user_data) | |||
164 | { | |||
165 | const char *required_global = user_data; | |||
166 | const char *known_global = value; | |||
167 | ||||
168 | return g_strcmp0 (required_global, known_global) == 0; | |||
169 | } | |||
170 | ||||
171 | static gboolean | |||
172 | has_required_globals (CdkWaylandDisplay *display_wayland, | |||
173 | const char *required_globals[]) | |||
174 | { | |||
175 | int i = 0; | |||
176 | ||||
177 | while (required_globals[i]) | |||
178 | { | |||
179 | if (g_hash_table_find (display_wayland->known_globals, | |||
180 | is_known_global, | |||
181 | (gpointer)required_globals[i]) == NULL((void*)0)) | |||
182 | return FALSE(0); | |||
183 | ||||
184 | i++; | |||
185 | } | |||
186 | ||||
187 | return TRUE(!(0)); | |||
188 | } | |||
189 | ||||
190 | typedef struct _OnHasGlobalsClosure OnHasGlobalsClosure; | |||
191 | ||||
192 | typedef void (*HasGlobalsCallback) (CdkWaylandDisplay *display_wayland, | |||
193 | OnHasGlobalsClosure *closure); | |||
194 | ||||
195 | struct _OnHasGlobalsClosure | |||
196 | { | |||
197 | HasGlobalsCallback handler; | |||
198 | const char **required_globals; | |||
199 | }; | |||
200 | ||||
201 | static void | |||
202 | process_on_globals_closures (CdkWaylandDisplay *display_wayland) | |||
203 | { | |||
204 | GList *iter; | |||
205 | ||||
206 | iter = display_wayland->on_has_globals_closures; | |||
207 | while (iter != NULL((void*)0)) | |||
208 | { | |||
209 | GList *next = iter->next; | |||
210 | OnHasGlobalsClosure *closure = iter->data; | |||
211 | ||||
212 | if (has_required_globals (display_wayland, | |||
213 | closure->required_globals)) | |||
214 | { | |||
215 | closure->handler (display_wayland, closure); | |||
216 | g_free (closure); | |||
217 | display_wayland->on_has_globals_closures = | |||
218 | g_list_delete_link (display_wayland->on_has_globals_closures, iter); | |||
219 | } | |||
220 | ||||
221 | iter = next; | |||
222 | } | |||
223 | } | |||
224 | ||||
225 | typedef struct | |||
226 | { | |||
227 | OnHasGlobalsClosure base; | |||
228 | uint32_t id; | |||
229 | uint32_t version; | |||
230 | } SeatAddedClosure; | |||
231 | ||||
232 | static void | |||
233 | _cdk_wayland_display_add_seat (CdkWaylandDisplay *display_wayland, | |||
234 | uint32_t id, | |||
235 | uint32_t version) | |||
236 | { | |||
237 | CdkDisplay *cdk_display = CDK_DISPLAY_OBJECT (display_wayland)((((CdkDisplay*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display_wayland)), ((cdk_display_get_type ())))))); | |||
238 | struct wl_seat *seat; | |||
239 | ||||
240 | display_wayland->seat_version = MIN (version, 5)(((version) < (5)) ? (version) : (5)); | |||
241 | seat = wl_registry_bind (display_wayland->wl_registry, | |||
242 | id, &wl_seat_interface, | |||
243 | display_wayland->seat_version); | |||
244 | _cdk_wayland_device_manager_add_seat (cdk_display->device_manager, | |||
245 | id, seat); | |||
246 | _cdk_wayland_display_async_roundtrip (display_wayland); | |||
247 | } | |||
248 | ||||
249 | static void | |||
250 | seat_added_closure_run (CdkWaylandDisplay *display_wayland, | |||
251 | OnHasGlobalsClosure *closure) | |||
252 | { | |||
253 | SeatAddedClosure *seat_added_closure = (SeatAddedClosure*)closure; | |||
254 | ||||
255 | _cdk_wayland_display_add_seat (display_wayland, | |||
256 | seat_added_closure->id, | |||
257 | seat_added_closure->version); | |||
258 | } | |||
259 | ||||
260 | static void | |||
261 | postpone_on_globals_closure (CdkWaylandDisplay *display_wayland, | |||
262 | OnHasGlobalsClosure *closure) | |||
263 | { | |||
264 | display_wayland->on_has_globals_closures = | |||
265 | g_list_append (display_wayland->on_has_globals_closures, closure); | |||
266 | } | |||
267 | ||||
268 | #ifdef G_ENABLE_DEBUG1 | |||
269 | ||||
270 | static const char * | |||
271 | get_format_name (enum wl_shm_format format) | |||
272 | { | |||
273 | int i; | |||
274 | #define FORMAT(s) { WL_SHM_FORMAT_ ## s, #s } | |||
275 | struct { int format; const char *name; } formats[] = { | |||
276 | FORMAT(ARGB8888), | |||
277 | FORMAT(XRGB8888), | |||
278 | FORMAT(C8), | |||
279 | FORMAT(RGB332), | |||
280 | FORMAT(BGR233), | |||
281 | FORMAT(XRGB4444), | |||
282 | FORMAT(XBGR4444), | |||
283 | FORMAT(RGBX4444), | |||
284 | FORMAT(BGRX4444), | |||
285 | FORMAT(ARGB4444), | |||
286 | FORMAT(ABGR4444), | |||
287 | FORMAT(RGBA4444), | |||
288 | FORMAT(BGRA4444), | |||
289 | FORMAT(XRGB1555), | |||
290 | FORMAT(XBGR1555), | |||
291 | FORMAT(RGBX5551), | |||
292 | FORMAT(BGRX5551), | |||
293 | FORMAT(ARGB1555), | |||
294 | FORMAT(ABGR1555), | |||
295 | FORMAT(RGBA5551), | |||
296 | FORMAT(BGRA5551), | |||
297 | FORMAT(RGB565), | |||
298 | FORMAT(BGR565), | |||
299 | FORMAT(RGB888), | |||
300 | FORMAT(BGR888), | |||
301 | FORMAT(XBGR8888), | |||
302 | FORMAT(RGBX8888), | |||
303 | FORMAT(BGRX8888), | |||
304 | FORMAT(ABGR8888), | |||
305 | FORMAT(RGBA8888), | |||
306 | FORMAT(BGRA8888), | |||
307 | FORMAT(XRGB2101010), | |||
308 | FORMAT(XBGR2101010), | |||
309 | FORMAT(RGBX1010102), | |||
310 | FORMAT(BGRX1010102), | |||
311 | FORMAT(ARGB2101010), | |||
312 | FORMAT(ABGR2101010), | |||
313 | FORMAT(RGBA1010102), | |||
314 | FORMAT(BGRA1010102), | |||
315 | FORMAT(YUYV), | |||
316 | FORMAT(YVYU), | |||
317 | FORMAT(UYVY), | |||
318 | FORMAT(VYUY), | |||
319 | FORMAT(AYUV), | |||
320 | FORMAT(NV12), | |||
321 | FORMAT(NV21), | |||
322 | FORMAT(NV16), | |||
323 | FORMAT(NV61), | |||
324 | FORMAT(YUV410), | |||
325 | FORMAT(YVU410), | |||
326 | FORMAT(YUV411), | |||
327 | FORMAT(YVU411), | |||
328 | FORMAT(YUV420), | |||
329 | FORMAT(YVU420), | |||
330 | FORMAT(YUV422), | |||
331 | FORMAT(YVU422), | |||
332 | FORMAT(YUV444), | |||
333 | FORMAT(YVU444), | |||
334 | { 0xffffffff, NULL((void*)0) } | |||
335 | }; | |||
336 | #undef FORMAT | |||
337 | ||||
338 | for (i = 0; formats[i].name; i++) | |||
339 | { | |||
340 | if (formats[i].format == format) | |||
341 | return formats[i].name; | |||
342 | } | |||
343 | return NULL((void*)0); | |||
344 | } | |||
345 | #endif | |||
346 | ||||
347 | static void | |||
348 | wl_shm_format (void *data G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
349 | struct wl_shm *wl_shm G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
350 | uint32_t format) | |||
351 | { | |||
352 | CDK_NOTE (MISC, g_message ("supported pixel format %s", get_format_name (format)))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message ("supported pixel format %s", get_format_name (format)); }; } while (0); | |||
353 | } | |||
354 | ||||
355 | static const struct wl_shm_listener wl_shm_listener = { | |||
356 | wl_shm_format | |||
357 | }; | |||
358 | ||||
359 | static void | |||
360 | server_decoration_manager_default_mode (void *data, | |||
361 | struct org_kde_kwin_server_decoration_manager *manager G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
362 | uint32_t mode) | |||
363 | { | |||
364 | g_assert (mode <= ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER)do { if (mode <= ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER ) ; else g_assertion_message_expr ("Cdk", "cdkdisplay-wayland.c" , 364, ((const char*) (__func__)), "mode <= ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER" ); } while (0); | |||
365 | const char *modes[] = { | |||
366 | [ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE] = "none", | |||
367 | [ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT] = "client", | |||
368 | [ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER] = "server", | |||
369 | }; | |||
370 | CdkWaylandDisplay *display_wayland = data; | |||
371 | g_debug ("Compositor prefers decoration mode '%s'", modes[mode]); | |||
372 | display_wayland->server_decoration_mode = mode; | |||
373 | } | |||
374 | ||||
375 | static const struct org_kde_kwin_server_decoration_manager_listener server_decoration_listener = { | |||
376 | .default_mode = server_decoration_manager_default_mode | |||
377 | }; | |||
378 | ||||
379 | gboolean | |||
380 | cdk_wayland_display_prefers_ssd (CdkDisplay *display) | |||
381 | { | |||
382 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
383 | if (display_wayland->server_decoration_manager) | |||
384 | return display_wayland->server_decoration_mode == ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER; | |||
385 | return FALSE(0); | |||
386 | } | |||
387 | ||||
388 | static void | |||
389 | cdk_registry_handle_global (void *data, | |||
390 | struct wl_registry *registry G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
391 | uint32_t id, | |||
392 | const char *interface, | |||
393 | uint32_t version) | |||
394 | { | |||
395 | CdkWaylandDisplay *display_wayland = data; | |||
396 | struct wl_output *output; | |||
397 | ||||
398 | CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message ("add global %u, interface %s, version %u", id, interface, version ); }; } while (0) | |||
399 | g_message ("add global %u, interface %s, version %u", id, interface, version))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message ("add global %u, interface %s, version %u", id, interface, version ); }; } while (0); | |||
400 | ||||
401 | if (strcmp (interface, "wl_compositor") == 0) | |||
402 | { | |||
403 | display_wayland->compositor = | |||
404 | wl_registry_bind (display_wayland->wl_registry, id, &wl_compositor_interface, MIN (version, 3)(((version) < (3)) ? (version) : (3))); | |||
405 | display_wayland->compositor_version = MIN (version, 3)(((version) < (3)) ? (version) : (3)); | |||
406 | } | |||
407 | else if (strcmp (interface, "wl_shm") == 0) | |||
408 | { | |||
409 | display_wayland->shm = | |||
410 | wl_registry_bind (display_wayland->wl_registry, id, &wl_shm_interface, 1); | |||
411 | wl_shm_add_listener (display_wayland->shm, &wl_shm_listener, display_wayland); | |||
412 | } | |||
413 | else if (strcmp (interface, "xdg_wm_base") == 0) | |||
414 | { | |||
415 | display_wayland->xdg_wm_base_id = id; | |||
416 | } | |||
417 | else if (strcmp (interface, "zxdg_shell_v6") == 0) | |||
418 | { | |||
419 | display_wayland->zxdg_shell_v6_id = id; | |||
420 | } | |||
421 | else if (strcmp (interface, "ctk_shell1") == 0) | |||
422 | { | |||
423 | display_wayland->ctk_shell = | |||
424 | wl_registry_bind(display_wayland->wl_registry, id, | |||
425 | &ctk_shell1_interface, | |||
426 | MIN (version, CTK_SHELL1_VERSION)(((version) < (3)) ? (version) : (3))); | |||
427 | _cdk_wayland_screen_set_has_ctk_shell (display_wayland->screen); | |||
428 | display_wayland->ctk_shell_version = version; | |||
429 | } | |||
430 | else if (strcmp (interface, "wl_output") == 0) | |||
431 | { | |||
432 | output = | |||
433 | wl_registry_bind (display_wayland->wl_registry, id, &wl_output_interface, MIN (version, 2)(((version) < (2)) ? (version) : (2))); | |||
434 | _cdk_wayland_screen_add_output (display_wayland->screen, id, output, MIN (version, 2)(((version) < (2)) ? (version) : (2))); | |||
435 | _cdk_wayland_display_async_roundtrip (display_wayland); | |||
436 | } | |||
437 | else if (strcmp (interface, "wl_seat") == 0) | |||
438 | { | |||
439 | static const char *required_device_manager_globals[] = { | |||
440 | "wl_compositor", | |||
441 | "wl_data_device_manager", | |||
442 | NULL((void*)0) | |||
443 | }; | |||
444 | ||||
445 | if (has_required_globals (display_wayland, | |||
446 | required_device_manager_globals)) | |||
447 | _cdk_wayland_display_add_seat (display_wayland, id, version); | |||
448 | else | |||
449 | { | |||
450 | SeatAddedClosure *closure; | |||
451 | ||||
452 | closure = g_new0 (SeatAddedClosure, 1)((SeatAddedClosure *) g_malloc0_n ((1), sizeof (SeatAddedClosure ))); | |||
453 | closure->base.handler = seat_added_closure_run; | |||
454 | closure->base.required_globals = required_device_manager_globals; | |||
455 | closure->id = id; | |||
456 | closure->version = version; | |||
457 | postpone_on_globals_closure (display_wayland, &closure->base); | |||
458 | } | |||
459 | } | |||
460 | else if (strcmp (interface, "wl_data_device_manager") == 0) | |||
461 | { | |||
462 | display_wayland->data_device_manager_version = MIN (version, 3)(((version) < (3)) ? (version) : (3)); | |||
463 | display_wayland->data_device_manager = | |||
464 | wl_registry_bind (display_wayland->wl_registry, id, &wl_data_device_manager_interface, | |||
465 | display_wayland->data_device_manager_version); | |||
466 | } | |||
467 | else if (strcmp (interface, "wl_subcompositor") == 0) | |||
468 | { | |||
469 | display_wayland->subcompositor = | |||
470 | wl_registry_bind (display_wayland->wl_registry, id, &wl_subcompositor_interface, 1); | |||
471 | } | |||
472 | else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0 && | |||
473 | version == CDK_ZWP_POINTER_GESTURES_V1_VERSION1) | |||
474 | { | |||
475 | display_wayland->pointer_gestures = | |||
476 | wl_registry_bind (display_wayland->wl_registry, | |||
477 | id, &zwp_pointer_gestures_v1_interface, version); | |||
478 | } | |||
479 | else if (strcmp (interface, "ctk_primary_selection_device_manager") == 0) | |||
480 | { | |||
481 | display_wayland->ctk_primary_selection_manager = | |||
482 | wl_registry_bind(display_wayland->wl_registry, id, | |||
483 | &ctk_primary_selection_device_manager_interface, 1); | |||
484 | } | |||
485 | else if (strcmp (interface, "zwp_primary_selection_device_manager_v1") == 0) | |||
486 | { | |||
487 | display_wayland->zwp_primary_selection_manager_v1 = | |||
488 | wl_registry_bind(display_wayland->wl_registry, id, | |||
489 | &zwp_primary_selection_device_manager_v1_interface, 1); | |||
490 | } | |||
491 | else if (strcmp (interface, "zwp_tablet_manager_v2") == 0) | |||
492 | { | |||
493 | display_wayland->tablet_manager = | |||
494 | wl_registry_bind(display_wayland->wl_registry, id, | |||
495 | &zwp_tablet_manager_v2_interface, 1); | |||
496 | } | |||
497 | else if (strcmp (interface, "zxdg_exporter_v1") == 0) | |||
498 | { | |||
499 | display_wayland->xdg_exporter = | |||
500 | wl_registry_bind (display_wayland->wl_registry, id, | |||
501 | &zxdg_exporter_v1_interface, 1); | |||
502 | } | |||
503 | else if (strcmp (interface, "zxdg_importer_v1") == 0) | |||
504 | { | |||
505 | display_wayland->xdg_importer = | |||
506 | wl_registry_bind (display_wayland->wl_registry, id, | |||
507 | &zxdg_importer_v1_interface, 1); | |||
508 | } | |||
509 | else if (strcmp (interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) | |||
510 | { | |||
511 | display_wayland->keyboard_shortcuts_inhibit = | |||
512 | wl_registry_bind (display_wayland->wl_registry, id, | |||
513 | &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1); | |||
514 | } | |||
515 | else if (strcmp (interface, "org_kde_kwin_server_decoration_manager") == 0) | |||
516 | { | |||
517 | display_wayland->server_decoration_manager = | |||
518 | wl_registry_bind (display_wayland->wl_registry, id, | |||
519 | &org_kde_kwin_server_decoration_manager_interface, 1); | |||
520 | org_kde_kwin_server_decoration_manager_add_listener (display_wayland->server_decoration_manager, | |||
521 | &server_decoration_listener, | |||
522 | display_wayland); | |||
523 | } | |||
524 | else if (strcmp(interface, "zxdg_output_manager_v1") == 0) | |||
525 | { | |||
526 | display_wayland->xdg_output_manager_version = MIN (version, 3)(((version) < (3)) ? (version) : (3)); | |||
527 | display_wayland->xdg_output_manager = | |||
528 | wl_registry_bind (display_wayland->wl_registry, id, | |||
529 | &zxdg_output_manager_v1_interface, | |||
530 | display_wayland->xdg_output_manager_version); | |||
531 | display_wayland->xdg_output_version = version; | |||
532 | _cdk_wayland_screen_init_xdg_output (display_wayland->screen); | |||
533 | _cdk_wayland_display_async_roundtrip (display_wayland); | |||
534 | } | |||
535 | ||||
536 | g_hash_table_insert (display_wayland->known_globals, | |||
537 | GUINT_TO_POINTER (id)((gpointer) (gulong) (id)), g_strdup (interface)g_strdup_inline (interface)); | |||
538 | ||||
539 | process_on_globals_closures (display_wayland); | |||
540 | } | |||
541 | ||||
542 | static void | |||
543 | cdk_registry_handle_global_remove (void *data, | |||
544 | struct wl_registry *registry G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
545 | uint32_t id) | |||
546 | { | |||
547 | CdkWaylandDisplay *display_wayland = data; | |||
548 | CdkDisplay *display = CDK_DISPLAY (display_wayland)((((CdkDisplay*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display_wayland)), ((cdk_display_get_type ())))))); | |||
549 | ||||
550 | CDK_NOTE (MISC, g_message ("remove global %u", id))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message ("remove global %u", id); }; } while (0); | |||
551 | _cdk_wayland_device_manager_remove_seat (display->device_manager, id); | |||
552 | _cdk_wayland_screen_remove_output (display_wayland->screen, id); | |||
553 | ||||
554 | g_hash_table_remove (display_wayland->known_globals, GUINT_TO_POINTER (id)((gpointer) (gulong) (id))); | |||
555 | ||||
556 | /* FIXME: the object needs to be destroyed here, we're leaking */ | |||
557 | } | |||
558 | ||||
559 | static const struct wl_registry_listener registry_listener = { | |||
560 | cdk_registry_handle_global, | |||
561 | cdk_registry_handle_global_remove | |||
562 | }; | |||
563 | ||||
564 | static void | |||
565 | log_handler (const char *format, va_list args) | |||
566 | { | |||
567 | g_logv (G_LOG_DOMAIN"Cdk", G_LOG_LEVEL_DEBUG, format, args); | |||
568 | } | |||
569 | ||||
570 | static void | |||
571 | load_cursor_theme_closure_run (CdkWaylandDisplay *display_wayland, | |||
572 | OnHasGlobalsClosure *closure G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
573 | { | |||
574 | _cdk_wayland_display_load_cursor_theme (display_wayland); | |||
575 | } | |||
576 | ||||
577 | static void | |||
578 | _cdk_wayland_display_prepare_cursor_themes (CdkWaylandDisplay *display_wayland) | |||
579 | { | |||
580 | OnHasGlobalsClosure *closure; | |||
581 | static const char *required_cursor_theme_globals[] = { | |||
582 | "wl_shm", | |||
583 | NULL((void*)0) | |||
584 | }; | |||
585 | ||||
586 | closure = g_new0 (OnHasGlobalsClosure, 1)((OnHasGlobalsClosure *) g_malloc0_n ((1), sizeof (OnHasGlobalsClosure ))); | |||
587 | closure->handler = load_cursor_theme_closure_run; | |||
588 | closure->required_globals = required_cursor_theme_globals; | |||
589 | postpone_on_globals_closure (display_wayland, closure); | |||
590 | } | |||
591 | ||||
592 | CdkDisplay * | |||
593 | _cdk_wayland_display_open (const gchar *display_name) | |||
594 | { | |||
595 | struct wl_display *wl_display; | |||
596 | CdkDisplay *display; | |||
597 | CdkWaylandDisplay *display_wayland; | |||
598 | ||||
599 | CDK_NOTE (MISC, g_message ("opening display %s", display_name ? display_name : ""))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message ("opening display %s", display_name ? display_name : ""); }; } while (0); | |||
600 | ||||
601 | /* If this variable is unset then wayland initialisation will surely | |||
602 | * fail, logging a fatal error in the process. Save ourselves from | |||
603 | * that. | |||
604 | */ | |||
605 | if (g_getenv ("XDG_RUNTIME_DIR") == NULL((void*)0)) | |||
606 | return NULL((void*)0); | |||
607 | ||||
608 | wl_log_set_handler_client (log_handler); | |||
609 | ||||
610 | wl_display = wl_display_connect (display_name); | |||
611 | if (!wl_display) | |||
612 | return NULL((void*)0); | |||
613 | ||||
614 | display = g_object_new (CDK_TYPE_WAYLAND_DISPLAY(cdk_wayland_display_get_type()), NULL((void*)0)); | |||
615 | display->device_manager = _cdk_wayland_device_manager_new (display); | |||
616 | ||||
617 | display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
618 | display_wayland->wl_display = wl_display; | |||
619 | display_wayland->screen = _cdk_wayland_screen_new (display); | |||
620 | display_wayland->event_source = _cdk_wayland_display_event_source_new (display); | |||
621 | ||||
622 | display_wayland->known_globals = | |||
623 | g_hash_table_new_full (NULL((void*)0), NULL((void*)0), NULL((void*)0), g_free); | |||
624 | ||||
625 | _cdk_wayland_display_init_cursors (display_wayland); | |||
626 | _cdk_wayland_display_prepare_cursor_themes (display_wayland); | |||
627 | ||||
628 | display_wayland->wl_registry = wl_display_get_registry (display_wayland->wl_display); | |||
629 | wl_registry_add_listener (display_wayland->wl_registry, ®istry_listener, display_wayland); | |||
630 | ||||
631 | _cdk_wayland_display_async_roundtrip (display_wayland); | |||
632 | ||||
633 | /* Wait for initializing to complete. This means waiting for all | |||
634 | * asynchrounous roundtrips that were triggered during initial roundtrip. */ | |||
635 | while (g_list_length (display_wayland->async_roundtrips) > 0) | |||
636 | { | |||
637 | if (wl_display_dispatch (display_wayland->wl_display) < 0) | |||
638 | { | |||
639 | g_object_unref (display); | |||
640 | return NULL((void*)0); | |||
641 | } | |||
642 | } | |||
643 | ||||
644 | if (display_wayland->xdg_wm_base_id) | |||
645 | { | |||
646 | display_wayland->shell_variant = CDK_WAYLAND_SHELL_VARIANT_XDG_SHELL; | |||
647 | display_wayland->xdg_wm_base = | |||
648 | wl_registry_bind (display_wayland->wl_registry, | |||
649 | display_wayland->xdg_wm_base_id, | |||
650 | &xdg_wm_base_interface, 1); | |||
651 | xdg_wm_base_add_listener (display_wayland->xdg_wm_base, | |||
652 | &xdg_wm_base_listener, | |||
653 | display_wayland); | |||
654 | } | |||
655 | else if (display_wayland->zxdg_shell_v6_id) | |||
656 | { | |||
657 | display_wayland->shell_variant = CDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6; | |||
658 | display_wayland->zxdg_shell_v6 = | |||
659 | wl_registry_bind (display_wayland->wl_registry, | |||
660 | display_wayland->zxdg_shell_v6_id, | |||
661 | &zxdg_shell_v6_interface, 1); | |||
662 | zxdg_shell_v6_add_listener (display_wayland->zxdg_shell_v6, | |||
663 | &zxdg_shell_v6_listener, | |||
664 | display_wayland); | |||
665 | } | |||
666 | else | |||
667 | { | |||
668 | g_warning ("The Wayland compositor does not provide any supported shell interface, " | |||
669 | "not using Wayland display"); | |||
670 | g_object_unref (display); | |||
671 | ||||
672 | return NULL((void*)0); | |||
673 | } | |||
674 | ||||
675 | display_wayland->selection = cdk_wayland_selection_new (); | |||
676 | ||||
677 | g_signal_emit_by_name (display, "opened"); | |||
678 | ||||
679 | return display; | |||
680 | } | |||
681 | ||||
682 | static void | |||
683 | cdk_wayland_display_dispose (GObject *object) | |||
684 | { | |||
685 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (object)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((cdk_wayland_display_get_type() )))))); | |||
686 | ||||
687 | _cdk_screen_close (display_wayland->screen); | |||
688 | ||||
689 | if (display_wayland->event_source) | |||
690 | { | |||
691 | g_source_destroy (display_wayland->event_source); | |||
692 | g_source_unref (display_wayland->event_source); | |||
693 | display_wayland->event_source = NULL((void*)0); | |||
694 | } | |||
695 | ||||
696 | if (display_wayland->selection) | |||
697 | { | |||
698 | cdk_wayland_selection_free (display_wayland->selection); | |||
699 | display_wayland->selection = NULL((void*)0); | |||
700 | } | |||
701 | ||||
702 | g_list_free_full (display_wayland->async_roundtrips, (GDestroyNotify) wl_callback_destroy); | |||
703 | ||||
704 | if (display_wayland->known_globals) | |||
705 | { | |||
706 | g_hash_table_destroy (display_wayland->known_globals); | |||
707 | display_wayland->known_globals = NULL((void*)0); | |||
708 | } | |||
709 | ||||
710 | g_list_free_full (display_wayland->on_has_globals_closures, g_free); | |||
711 | ||||
712 | G_OBJECT_CLASS (cdk_wayland_display_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((cdk_wayland_display_parent_class)), (((GType) ((20) << (2))))))))->dispose (object); | |||
713 | } | |||
714 | ||||
715 | static void | |||
716 | cdk_wayland_display_finalize (GObject *object) | |||
717 | { | |||
718 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (object)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((cdk_wayland_display_get_type() )))))); | |||
719 | guint i; | |||
720 | ||||
721 | _cdk_wayland_display_finalize_cursors (display_wayland); | |||
722 | ||||
723 | g_object_unref (display_wayland->screen); | |||
724 | ||||
725 | g_free (display_wayland->startup_notification_id); | |||
726 | g_free (display_wayland->cursor_theme_name); | |||
727 | xkb_context_unref (display_wayland->xkb_context); | |||
728 | ||||
729 | for (i = 0; i < CDK_WAYLAND_THEME_SCALES_COUNT4; i++) | |||
730 | { | |||
731 | if (display_wayland->scaled_cursor_themes[i]) | |||
732 | { | |||
733 | wl_cursor_theme_destroy (display_wayland->scaled_cursor_themes[i]); | |||
734 | display_wayland->scaled_cursor_themes[i] = NULL((void*)0); | |||
735 | } | |||
736 | } | |||
737 | ||||
738 | g_ptr_array_free (display_wayland->monitors, TRUE(!(0))); | |||
739 | ||||
740 | wl_display_disconnect(display_wayland->wl_display); | |||
741 | ||||
742 | G_OBJECT_CLASS (cdk_wayland_display_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((cdk_wayland_display_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | |||
743 | } | |||
744 | ||||
745 | static const gchar * | |||
746 | cdk_wayland_display_get_name (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
747 | { | |||
748 | const gchar *name; | |||
749 | ||||
750 | name = g_getenv ("WAYLAND_DISPLAY"); | |||
751 | if (name == NULL((void*)0)) | |||
752 | name = "wayland-0"; | |||
753 | ||||
754 | return name; | |||
755 | } | |||
756 | ||||
757 | static CdkScreen * | |||
758 | cdk_wayland_display_get_default_screen (CdkDisplay *display) | |||
759 | { | |||
760 | g_return_val_if_fail (CDK_IS_DISPLAY (display), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__ )), "CDK_IS_DISPLAY (display)"); return (((void*)0)); } } while (0); | |||
761 | ||||
762 | return CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( )))))))->screen; | |||
763 | } | |||
764 | ||||
765 | void | |||
766 | cdk_wayland_display_system_bell (CdkDisplay *display, | |||
767 | CdkWindow *window) | |||
768 | { | |||
769 | CdkWaylandDisplay *display_wayland; | |||
770 | struct ctk_surface1 *ctk_surface; | |||
771 | gint64 now_ms; | |||
772 | ||||
773 | g_return_if_fail (CDK_IS_DISPLAY (display))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__ )), "CDK_IS_DISPLAY (display)"); return; } } while (0); | |||
774 | ||||
775 | display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
776 | ||||
777 | if (!display_wayland->ctk_shell) | |||
778 | return; | |||
779 | ||||
780 | if (window) | |||
781 | ctk_surface = cdk_wayland_window_get_ctk_surface (window); | |||
782 | else | |||
783 | ctk_surface = NULL((void*)0); | |||
784 | ||||
785 | now_ms = g_get_monotonic_time () / 1000; | |||
786 | if (now_ms - display_wayland->last_bell_time_ms < MIN_SYSTEM_BELL_DELAY_MS20) | |||
787 | return; | |||
788 | ||||
789 | display_wayland->last_bell_time_ms = now_ms; | |||
790 | ||||
791 | ctk_shell1_system_bell (display_wayland->ctk_shell, ctk_surface); | |||
792 | } | |||
793 | ||||
794 | static void | |||
795 | cdk_wayland_display_beep (CdkDisplay *display) | |||
796 | { | |||
797 | cdk_wayland_display_system_bell (display, NULL((void*)0)); | |||
798 | } | |||
799 | ||||
800 | static void | |||
801 | cdk_wayland_display_sync (CdkDisplay *display) | |||
802 | { | |||
803 | CdkWaylandDisplay *display_wayland; | |||
804 | ||||
805 | g_return_if_fail (CDK_IS_DISPLAY (display))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__ )), "CDK_IS_DISPLAY (display)"); return; } } while (0); | |||
806 | ||||
807 | display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
808 | ||||
809 | wl_display_roundtrip (display_wayland->wl_display); | |||
810 | } | |||
811 | ||||
812 | static void | |||
813 | cdk_wayland_display_flush (CdkDisplay *display) | |||
814 | { | |||
815 | g_return_if_fail (CDK_IS_DISPLAY (display))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__ )), "CDK_IS_DISPLAY (display)"); return; } } while (0); | |||
816 | ||||
817 | if (!display->closed) | |||
818 | wl_display_flush (CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( )))))))->wl_display); | |||
819 | } | |||
820 | ||||
821 | static void | |||
822 | cdk_wayland_display_make_default (CdkDisplay *display) | |||
823 | { | |||
824 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
825 | const gchar *startup_id; | |||
826 | ||||
827 | g_free (display_wayland->startup_notification_id); | |||
828 | display_wayland->startup_notification_id = NULL((void*)0); | |||
829 | ||||
830 | startup_id = cdk_get_desktop_startup_id (); | |||
831 | if (startup_id) | |||
832 | display_wayland->startup_notification_id = g_strdup (startup_id)g_strdup_inline (startup_id); | |||
833 | } | |||
834 | ||||
835 | static gboolean | |||
836 | cdk_wayland_display_has_pending (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
837 | { | |||
838 | return FALSE(0); | |||
839 | } | |||
840 | ||||
841 | static CdkWindow * | |||
842 | cdk_wayland_display_get_default_group (CdkDisplay *display) | |||
843 | { | |||
844 | g_return_val_if_fail (CDK_IS_DISPLAY (display), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__ )), "CDK_IS_DISPLAY (display)"); return (((void*)0)); } } while (0); | |||
845 | ||||
846 | return NULL((void*)0); | |||
847 | } | |||
848 | ||||
849 | ||||
850 | static gboolean | |||
851 | cdk_wayland_display_supports_selection_notification (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
852 | { | |||
853 | return FALSE(0); | |||
854 | } | |||
855 | ||||
856 | static gboolean | |||
857 | cdk_wayland_display_request_selection_notification (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
858 | CdkAtom selection G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
859 | ||||
860 | { | |||
861 | return FALSE(0); | |||
862 | } | |||
863 | ||||
864 | static gboolean | |||
865 | cdk_wayland_display_supports_clipboard_persistence (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
866 | { | |||
867 | return FALSE(0); | |||
868 | } | |||
869 | ||||
870 | static void | |||
871 | cdk_wayland_display_store_clipboard (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
872 | CdkWindow *clipboard_window G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
873 | guint32 time_ G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
874 | const CdkAtom *targets G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
875 | gint n_targets G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
876 | { | |||
877 | } | |||
878 | ||||
879 | static gboolean | |||
880 | cdk_wayland_display_supports_shapes (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
881 | { | |||
882 | return FALSE(0); | |||
883 | } | |||
884 | ||||
885 | static gboolean | |||
886 | cdk_wayland_display_supports_input_shapes (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
887 | { | |||
888 | return TRUE(!(0)); | |||
889 | } | |||
890 | ||||
891 | static gboolean | |||
892 | cdk_wayland_display_supports_composite (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
893 | { | |||
894 | return FALSE(0); | |||
895 | } | |||
896 | ||||
897 | static void | |||
898 | cdk_wayland_display_before_process_all_updates (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
899 | { | |||
900 | } | |||
901 | ||||
902 | static void | |||
903 | cdk_wayland_display_after_process_all_updates (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
904 | { | |||
905 | /* Post the damage here instead? */ | |||
906 | } | |||
907 | ||||
908 | static gulong | |||
909 | cdk_wayland_display_get_next_serial (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
910 | { | |||
911 | static gulong serial = 0; | |||
912 | return ++serial; | |||
913 | } | |||
914 | ||||
915 | /** | |||
916 | * cdk_wayland_display_set_startup_notification_id: | |||
917 | * @display: (type CdkWaylandDisplay): a #CdkDisplay | |||
918 | * @startup_id: the startup notification ID (must be valid utf8) | |||
919 | * | |||
920 | * Sets the startup notification ID for a display. | |||
921 | * | |||
922 | * This is usually taken from the value of the DESKTOP_STARTUP_ID | |||
923 | * environment variable, but in some cases (such as the application not | |||
924 | * being launched using exec()) it can come from other sources. | |||
925 | * | |||
926 | * The startup ID is also what is used to signal that the startup is | |||
927 | * complete (for example, when opening a window or when calling | |||
928 | * cdk_notify_startup_complete()). | |||
929 | * | |||
930 | * Since: 3.22 | |||
931 | **/ | |||
932 | void | |||
933 | cdk_wayland_display_set_startup_notification_id (CdkDisplay *display, | |||
934 | const char *startup_id) | |||
935 | { | |||
936 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
937 | ||||
938 | g_free (display_wayland->startup_notification_id); | |||
939 | display_wayland->startup_notification_id = g_strdup (startup_id)g_strdup_inline (startup_id); | |||
940 | } | |||
941 | ||||
942 | static void | |||
943 | cdk_wayland_display_notify_startup_complete (CdkDisplay *display, | |||
944 | const gchar *startup_id) | |||
945 | { | |||
946 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
947 | ||||
948 | if (startup_id == NULL((void*)0)) | |||
949 | { | |||
950 | startup_id = display_wayland->startup_notification_id; | |||
951 | ||||
952 | if (startup_id == NULL((void*)0)) | |||
953 | return; | |||
954 | } | |||
955 | ||||
956 | if (display_wayland->ctk_shell) | |||
957 | ctk_shell1_set_startup_id (display_wayland->ctk_shell, startup_id); | |||
958 | } | |||
959 | ||||
960 | static CdkKeymap * | |||
961 | _cdk_wayland_display_get_keymap (CdkDisplay *display) | |||
962 | { | |||
963 | CdkDevice *core_keyboard = NULL((void*)0); | |||
964 | static CdkKeymap *tmp_keymap = NULL((void*)0); | |||
965 | ||||
966 | core_keyboard = cdk_seat_get_keyboard (cdk_display_get_default_seat (display)); | |||
967 | ||||
968 | if (core_keyboard && tmp_keymap) | |||
969 | { | |||
970 | g_object_unref (tmp_keymap); | |||
971 | tmp_keymap = NULL((void*)0); | |||
972 | } | |||
973 | ||||
974 | if (core_keyboard) | |||
975 | return _cdk_wayland_device_get_keymap (core_keyboard); | |||
976 | ||||
977 | if (!tmp_keymap) | |||
978 | tmp_keymap = _cdk_wayland_keymap_new (); | |||
979 | ||||
980 | return tmp_keymap; | |||
981 | } | |||
982 | ||||
983 | static void | |||
984 | cdk_wayland_display_push_error_trap (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
985 | { | |||
986 | } | |||
987 | ||||
988 | static gint | |||
989 | cdk_wayland_display_pop_error_trap (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
990 | gboolean ignored G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
991 | { | |||
992 | return 0; | |||
993 | } | |||
994 | ||||
995 | static int | |||
996 | cdk_wayland_display_get_n_monitors (CdkDisplay *display) | |||
997 | { | |||
998 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
999 | ||||
1000 | return display_wayland->monitors->len; | |||
1001 | } | |||
1002 | ||||
1003 | static CdkMonitor * | |||
1004 | cdk_wayland_display_get_monitor (CdkDisplay *display, | |||
1005 | int monitor_num) | |||
1006 | { | |||
1007 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
1008 | ||||
1009 | if (monitor_num < 0 || monitor_num >= display_wayland->monitors->len) | |||
1010 | return NULL((void*)0); | |||
1011 | ||||
1012 | return (CdkMonitor *)display_wayland->monitors->pdata[monitor_num]; | |||
1013 | } | |||
1014 | ||||
1015 | static CdkMonitor * | |||
1016 | cdk_wayland_display_get_monitor_at_window (CdkDisplay *display, | |||
1017 | CdkWindow *window) | |||
1018 | { | |||
1019 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
1020 | struct wl_output *output; | |||
1021 | int i; | |||
1022 | ||||
1023 | g_return_val_if_fail (CDK_IS_WAYLAND_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((cdk_wayland_window_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0) ); else __r = g_type_check_instance_is_a (__inst, __t); __r; } )))))) { } else { g_return_if_fail_warning ("Cdk", ((const char *) (__func__)), "CDK_IS_WAYLAND_WINDOW (window)"); return ((( void*)0)); } } while (0); | |||
1024 | ||||
1025 | output = cdk_wayland_window_get_wl_output (window); | |||
1026 | if (output == NULL((void*)0)) | |||
1027 | return NULL((void*)0); | |||
1028 | ||||
1029 | for (i = 0; i < display_wayland->monitors->len; i++) | |||
1030 | { | |||
1031 | CdkMonitor *monitor = display_wayland->monitors->pdata[i]; | |||
1032 | ||||
1033 | if (cdk_wayland_monitor_get_wl_output (monitor) == output) | |||
1034 | return monitor; | |||
1035 | } | |||
1036 | ||||
1037 | return NULL((void*)0); | |||
1038 | } | |||
1039 | ||||
1040 | static void | |||
1041 | cdk_wayland_display_class_init (CdkWaylandDisplayClass *class) | |||
1042 | { | |||
1043 | GObjectClass *object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); | |||
1044 | CdkDisplayClass *display_class = CDK_DISPLAY_CLASS (class)((((CdkDisplayClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), ((cdk_display_get_type ())))))); | |||
1045 | ||||
1046 | object_class->dispose = cdk_wayland_display_dispose; | |||
1047 | object_class->finalize = cdk_wayland_display_finalize; | |||
1048 | ||||
1049 | display_class->window_type = cdk_wayland_window_get_type (); | |||
1050 | display_class->get_name = cdk_wayland_display_get_name; | |||
1051 | display_class->get_default_screen = cdk_wayland_display_get_default_screen; | |||
1052 | display_class->beep = cdk_wayland_display_beep; | |||
1053 | display_class->sync = cdk_wayland_display_sync; | |||
1054 | display_class->flush = cdk_wayland_display_flush; | |||
1055 | display_class->make_default = cdk_wayland_display_make_default; | |||
1056 | display_class->has_pending = cdk_wayland_display_has_pending; | |||
1057 | display_class->queue_events = _cdk_wayland_display_queue_events; | |||
1058 | display_class->get_default_group = cdk_wayland_display_get_default_group; | |||
1059 | display_class->supports_selection_notification = cdk_wayland_display_supports_selection_notification; | |||
1060 | display_class->request_selection_notification = cdk_wayland_display_request_selection_notification; | |||
1061 | display_class->supports_clipboard_persistence = cdk_wayland_display_supports_clipboard_persistence; | |||
1062 | display_class->store_clipboard = cdk_wayland_display_store_clipboard; | |||
1063 | display_class->supports_shapes = cdk_wayland_display_supports_shapes; | |||
1064 | display_class->supports_input_shapes = cdk_wayland_display_supports_input_shapes; | |||
1065 | display_class->supports_composite = cdk_wayland_display_supports_composite; | |||
1066 | display_class->get_app_launch_context = _cdk_wayland_display_get_app_launch_context; | |||
1067 | display_class->get_default_cursor_size = _cdk_wayland_display_get_default_cursor_size; | |||
1068 | display_class->get_maximal_cursor_size = _cdk_wayland_display_get_maximal_cursor_size; | |||
1069 | display_class->get_cursor_for_type = _cdk_wayland_display_get_cursor_for_type; | |||
1070 | display_class->get_cursor_for_name = _cdk_wayland_display_get_cursor_for_name; | |||
1071 | display_class->get_cursor_for_surface = _cdk_wayland_display_get_cursor_for_surface; | |||
1072 | display_class->supports_cursor_alpha = _cdk_wayland_display_supports_cursor_alpha; | |||
1073 | display_class->supports_cursor_color = _cdk_wayland_display_supports_cursor_color; | |||
1074 | display_class->before_process_all_updates = cdk_wayland_display_before_process_all_updates; | |||
1075 | display_class->after_process_all_updates = cdk_wayland_display_after_process_all_updates; | |||
1076 | display_class->get_next_serial = cdk_wayland_display_get_next_serial; | |||
1077 | display_class->notify_startup_complete = cdk_wayland_display_notify_startup_complete; | |||
1078 | display_class->create_window_impl = _cdk_wayland_display_create_window_impl; | |||
1079 | display_class->get_keymap = _cdk_wayland_display_get_keymap; | |||
1080 | display_class->push_error_trap = cdk_wayland_display_push_error_trap; | |||
1081 | display_class->pop_error_trap = cdk_wayland_display_pop_error_trap; | |||
1082 | display_class->get_selection_owner = _cdk_wayland_display_get_selection_owner; | |||
1083 | display_class->set_selection_owner = _cdk_wayland_display_set_selection_owner; | |||
1084 | display_class->send_selection_notify = _cdk_wayland_display_send_selection_notify; | |||
1085 | display_class->get_selection_property = _cdk_wayland_display_get_selection_property; | |||
1086 | display_class->convert_selection = _cdk_wayland_display_convert_selection; | |||
1087 | display_class->text_property_to_utf8_list = _cdk_wayland_display_text_property_to_utf8_list; | |||
1088 | display_class->utf8_to_string_target = _cdk_wayland_display_utf8_to_string_target; | |||
1089 | ||||
1090 | display_class->make_gl_context_current = cdk_wayland_display_make_gl_context_current; | |||
1091 | ||||
1092 | display_class->get_n_monitors = cdk_wayland_display_get_n_monitors; | |||
1093 | display_class->get_monitor = cdk_wayland_display_get_monitor; | |||
1094 | display_class->get_monitor_at_window = cdk_wayland_display_get_monitor_at_window; | |||
1095 | } | |||
1096 | ||||
1097 | static void | |||
1098 | cdk_wayland_display_init (CdkWaylandDisplay *display) | |||
1099 | { | |||
1100 | display->xkb_context = xkb_context_new (0); | |||
1101 | ||||
1102 | display->monitors = g_ptr_array_new_with_free_func (g_object_unref); | |||
1103 | } | |||
1104 | ||||
1105 | void | |||
1106 | cdk_wayland_display_set_cursor_theme (CdkDisplay *display, | |||
1107 | const gchar *name, | |||
1108 | gint size) | |||
1109 | { | |||
1110 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY(display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
1111 | struct wl_cursor_theme *theme; | |||
1112 | int i; | |||
1113 | ||||
1114 | g_assert (display_wayland)do { if (display_wayland) ; else g_assertion_message_expr ("Cdk" , "cdkdisplay-wayland.c", 1114, ((const char*) (__func__)), "display_wayland" ); } while (0); | |||
1115 | g_assert (display_wayland->shm)do { if (display_wayland->shm) ; else g_assertion_message_expr ("Cdk", "cdkdisplay-wayland.c", 1115, ((const char*) (__func__ )), "display_wayland->shm"); } while (0); | |||
1116 | ||||
1117 | if (g_strcmp0 (name, display_wayland->cursor_theme_name) == 0 && | |||
1118 | display_wayland->cursor_theme_size == size) | |||
1119 | return; | |||
1120 | ||||
1121 | theme = wl_cursor_theme_load (name, size, display_wayland->shm); | |||
1122 | if (theme == NULL((void*)0)) | |||
1123 | { | |||
1124 | g_warning ("Failed to load cursor theme %s", name); | |||
1125 | return; | |||
1126 | } | |||
1127 | ||||
1128 | for (i = 0; i < CDK_WAYLAND_THEME_SCALES_COUNT4; i++) | |||
1129 | { | |||
1130 | if (display_wayland->scaled_cursor_themes[i]) | |||
1131 | { | |||
1132 | wl_cursor_theme_destroy (display_wayland->scaled_cursor_themes[i]); | |||
1133 | display_wayland->scaled_cursor_themes[i] = NULL((void*)0); | |||
1134 | } | |||
1135 | } | |||
1136 | display_wayland->scaled_cursor_themes[0] = theme; | |||
1137 | if (display_wayland->cursor_theme_name != NULL((void*)0)) | |||
1138 | g_free (display_wayland->cursor_theme_name); | |||
1139 | display_wayland->cursor_theme_name = g_strdup (name)g_strdup_inline (name); | |||
1140 | display_wayland->cursor_theme_size = size; | |||
1141 | ||||
1142 | _cdk_wayland_display_update_cursors (display_wayland); | |||
1143 | } | |||
1144 | ||||
1145 | struct wl_cursor_theme * | |||
1146 | _cdk_wayland_display_get_scaled_cursor_theme (CdkWaylandDisplay *display_wayland, | |||
1147 | guint scale) | |||
1148 | { | |||
1149 | struct wl_cursor_theme *theme; | |||
1150 | ||||
1151 | g_assert (display_wayland->cursor_theme_name)do { if (display_wayland->cursor_theme_name) ; else g_assertion_message_expr ("Cdk", "cdkdisplay-wayland.c", 1151, ((const char*) (__func__ )), "display_wayland->cursor_theme_name"); } while (0); | |||
1152 | g_assert (scale <= CDK_WAYLAND_MAX_THEME_SCALE)do { if (scale <= 4) ; else g_assertion_message_expr ("Cdk" , "cdkdisplay-wayland.c", 1152, ((const char*) (__func__)), "scale <= CDK_WAYLAND_MAX_THEME_SCALE" ); } while (0); | |||
1153 | g_assert (scale >= 1)do { if (scale >= 1) ; else g_assertion_message_expr ("Cdk" , "cdkdisplay-wayland.c", 1153, ((const char*) (__func__)), "scale >= 1" ); } while (0); | |||
1154 | ||||
1155 | theme = display_wayland->scaled_cursor_themes[scale - 1]; | |||
1156 | if (!theme) | |||
1157 | { | |||
1158 | theme = wl_cursor_theme_load (display_wayland->cursor_theme_name, | |||
1159 | display_wayland->cursor_theme_size * scale, | |||
1160 | display_wayland->shm); | |||
1161 | if (theme == NULL((void*)0)) | |||
1162 | { | |||
1163 | g_warning ("Failed to load cursor theme %s with scale %u", | |||
1164 | display_wayland->cursor_theme_name, scale); | |||
1165 | return NULL((void*)0); | |||
1166 | } | |||
1167 | display_wayland->scaled_cursor_themes[scale - 1] = theme; | |||
1168 | } | |||
1169 | ||||
1170 | return theme; | |||
1171 | } | |||
1172 | ||||
1173 | static void | |||
1174 | _cdk_wayland_display_load_cursor_theme (CdkWaylandDisplay *display_wayland) | |||
1175 | { | |||
1176 | guint size; | |||
1177 | const gchar *name; | |||
1178 | GValue v = G_VALUE_INIT{ 0, { { 0 } } }; | |||
1179 | ||||
1180 | g_assert (display_wayland)do { if (display_wayland) ; else g_assertion_message_expr ("Cdk" , "cdkdisplay-wayland.c", 1180, ((const char*) (__func__)), "display_wayland" ); } while (0); | |||
1181 | g_assert (display_wayland->shm)do { if (display_wayland->shm) ; else g_assertion_message_expr ("Cdk", "cdkdisplay-wayland.c", 1181, ((const char*) (__func__ )), "display_wayland->shm"); } while (0); | |||
1182 | ||||
1183 | g_value_init (&v, G_TYPE_INT((GType) ((6) << (2)))); | |||
1184 | if (cdk_screen_get_setting (display_wayland->screen, "ctk-cursor-theme-size", &v)) | |||
1185 | size = g_value_get_int (&v); | |||
1186 | else | |||
1187 | size = 32; | |||
1188 | g_value_unset (&v); | |||
1189 | ||||
1190 | g_value_init (&v, G_TYPE_STRING((GType) ((16) << (2)))); | |||
1191 | if (cdk_screen_get_setting (display_wayland->screen, "ctk-cursor-theme-name", &v)) | |||
1192 | name = g_value_get_string (&v); | |||
1193 | else | |||
1194 | name = "default"; | |||
1195 | ||||
1196 | cdk_wayland_display_set_cursor_theme (CDK_DISPLAY (display_wayland)((((CdkDisplay*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((display_wayland)), ((cdk_display_get_type ())))))), name, size); | |||
1197 | g_value_unset (&v); | |||
1198 | } | |||
1199 | ||||
1200 | guint32 | |||
1201 | _cdk_wayland_display_get_serial (CdkWaylandDisplay *display_wayland) | |||
1202 | { | |||
1203 | return display_wayland->serial; | |||
1204 | } | |||
1205 | ||||
1206 | void | |||
1207 | _cdk_wayland_display_update_serial (CdkWaylandDisplay *display_wayland, | |||
1208 | guint32 serial) | |||
1209 | { | |||
1210 | display_wayland->serial = serial; | |||
1211 | } | |||
1212 | ||||
1213 | /** | |||
1214 | * cdk_wayland_display_get_wl_display: | |||
1215 | * @display: (type CdkWaylandDisplay): a #CdkDisplay | |||
1216 | * | |||
1217 | * Returns the Wayland wl_display of a #CdkDisplay. | |||
1218 | * | |||
1219 | * Returns: (transfer none): a Wayland wl_display | |||
1220 | * | |||
1221 | * Since: 3.8 | |||
1222 | */ | |||
1223 | struct wl_display * | |||
1224 | cdk_wayland_display_get_wl_display (CdkDisplay *display) | |||
1225 | { | |||
1226 | g_return_val_if_fail (CDK_IS_WAYLAND_DISPLAY (display), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_wayland_display_get_type()) ); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__)), "CDK_IS_WAYLAND_DISPLAY (display)"); return (((void*)0)); } } while (0); | |||
1227 | ||||
1228 | return CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( )))))))->wl_display; | |||
1229 | } | |||
1230 | ||||
1231 | /** | |||
1232 | * cdk_wayland_display_get_wl_compositor: | |||
1233 | * @display: (type CdkWaylandDisplay): a #CdkDisplay | |||
1234 | * | |||
1235 | * Returns the Wayland global singleton compositor of a #CdkDisplay. | |||
1236 | * | |||
1237 | * Returns: (transfer none): a Wayland wl_compositor | |||
1238 | * | |||
1239 | * Since: 3.8 | |||
1240 | */ | |||
1241 | struct wl_compositor * | |||
1242 | cdk_wayland_display_get_wl_compositor (CdkDisplay *display) | |||
1243 | { | |||
1244 | g_return_val_if_fail (CDK_IS_WAYLAND_DISPLAY (display), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_wayland_display_get_type()) ); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__)), "CDK_IS_WAYLAND_DISPLAY (display)"); return (((void*)0)); } } while (0); | |||
1245 | ||||
1246 | return CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( )))))))->compositor; | |||
1247 | } | |||
1248 | ||||
1249 | static const cairo_user_data_key_t cdk_wayland_shm_surface_cairo_key; | |||
1250 | ||||
1251 | typedef struct _CdkWaylandCairoSurfaceData { | |||
1252 | gpointer buf; | |||
1253 | size_t buf_length; | |||
1254 | struct wl_shm_pool *pool; | |||
1255 | struct wl_buffer *buffer; | |||
1256 | CdkWaylandDisplay *display; | |||
1257 | uint32_t scale; | |||
1258 | } CdkWaylandCairoSurfaceData; | |||
1259 | ||||
1260 | static int | |||
1261 | open_shared_memory (void) | |||
1262 | { | |||
1263 | static gboolean force_shm_open = FALSE(0); | |||
1264 | int ret = -1; | |||
1265 | ||||
1266 | #if !defined (__NR_memfd_create319) | |||
1267 | force_shm_open = TRUE(!(0)); | |||
1268 | #endif | |||
1269 | ||||
1270 | do | |||
1271 | { | |||
1272 | #if defined (__NR_memfd_create319) | |||
1273 | if (!force_shm_open) | |||
1274 | { | |||
1275 | ret = syscall (__NR_memfd_create319, "cdk-wayland", MFD_CLOEXEC0x0001U); | |||
1276 | ||||
1277 | /* fall back to shm_open until debian stops shipping 3.16 kernel | |||
1278 | * See bug 766341 | |||
1279 | */ | |||
1280 | if (ret < 0 && errno(*__errno_location ()) == ENOSYS38) | |||
1281 | force_shm_open = TRUE(!(0)); | |||
1282 | } | |||
1283 | #endif | |||
1284 | ||||
1285 | if (force_shm_open) | |||
1286 | { | |||
1287 | #if defined (__FreeBSD__) | |||
1288 | ret = shm_open (SHM_ANON, O_CREAT0100 | O_EXCL0200 | O_RDWR02 | O_CLOEXEC02000000, 0600); | |||
1289 | #else | |||
1290 | char name[NAME_MAX255 - 1] = ""; | |||
1291 | ||||
1292 | sprintf (name, "/cdk-wayland-%x", g_random_int ()); | |||
1293 | ||||
1294 | ret = shm_open (name, O_CREAT0100 | O_EXCL0200 | O_RDWR02 | O_CLOEXEC02000000, 0600); | |||
1295 | ||||
1296 | if (ret >= 0) | |||
1297 | shm_unlink (name); | |||
1298 | else if (errno(*__errno_location ()) == EEXIST17) | |||
1299 | continue; | |||
1300 | #endif | |||
1301 | } | |||
1302 | } | |||
1303 | while (ret < 0 && errno(*__errno_location ()) == EINTR4); | |||
1304 | ||||
1305 | if (ret < 0) | |||
1306 | g_critical (G_STRLOC"cdkdisplay-wayland.c" ":" "1306" ": creating shared memory file (using %s) failed: %m", | |||
1307 | force_shm_open? "shm_open" : "memfd_create"); | |||
1308 | ||||
1309 | return ret; | |||
1310 | } | |||
1311 | ||||
1312 | static struct wl_shm_pool * | |||
1313 | create_shm_pool (struct wl_shm *shm, | |||
1314 | int size, | |||
1315 | size_t *buf_length, | |||
1316 | void **data_out) | |||
1317 | { | |||
1318 | struct wl_shm_pool *pool; | |||
1319 | int fd; | |||
1320 | void *data; | |||
1321 | ||||
1322 | fd = open_shared_memory (); | |||
1323 | ||||
1324 | if (fd < 0) | |||
1325 | return NULL((void*)0); | |||
1326 | ||||
1327 | if (ftruncate (fd, size) < 0) | |||
1328 | { | |||
1329 | g_critical (G_STRLOC"cdkdisplay-wayland.c" ":" "1329" ": Truncating shared memory file failed: %m"); | |||
1330 | close (fd); | |||
1331 | return NULL((void*)0); | |||
1332 | } | |||
1333 | ||||
1334 | data = mmap (NULL((void*)0), size, PROT_READ0x1 | PROT_WRITE0x2, MAP_SHARED0x01, fd, 0); | |||
1335 | ||||
1336 | if (data == MAP_FAILED((void *) -1)) | |||
1337 | { | |||
1338 | g_critical (G_STRLOC"cdkdisplay-wayland.c" ":" "1338" ": mmap'ping shared memory file failed: %m"); | |||
1339 | close (fd); | |||
1340 | return NULL((void*)0); | |||
1341 | } | |||
1342 | ||||
1343 | pool = wl_shm_create_pool (shm, fd, size); | |||
1344 | ||||
1345 | close (fd); | |||
1346 | ||||
1347 | *data_out = data; | |||
1348 | *buf_length = size; | |||
1349 | ||||
1350 | return pool; | |||
1351 | } | |||
1352 | ||||
1353 | static void | |||
1354 | cdk_wayland_cairo_surface_destroy (void *p) | |||
1355 | { | |||
1356 | CdkWaylandCairoSurfaceData *data = p; | |||
1357 | ||||
1358 | if (data->buffer) | |||
1359 | wl_buffer_destroy (data->buffer); | |||
1360 | ||||
1361 | if (data->pool) | |||
1362 | wl_shm_pool_destroy (data->pool); | |||
1363 | ||||
1364 | munmap (data->buf, data->buf_length); | |||
1365 | g_free (data); | |||
1366 | } | |||
1367 | ||||
1368 | cairo_surface_t * | |||
1369 | _cdk_wayland_display_create_shm_surface (CdkWaylandDisplay *display, | |||
1370 | int width, | |||
1371 | int height, | |||
1372 | guint scale) | |||
1373 | { | |||
1374 | CdkWaylandCairoSurfaceData *data; | |||
1375 | cairo_surface_t *surface = NULL((void*)0); | |||
1376 | cairo_status_t status; | |||
1377 | int stride; | |||
1378 | ||||
1379 | data = g_new (CdkWaylandCairoSurfaceData, 1)((CdkWaylandCairoSurfaceData *) g_malloc_n ((1), sizeof (CdkWaylandCairoSurfaceData ))); | |||
| ||||
1380 | data->display = display; | |||
1381 | data->buffer = NULL((void*)0); | |||
1382 | data->scale = scale; | |||
1383 | ||||
1384 | stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width*scale); | |||
1385 | ||||
1386 | data->pool = create_shm_pool (display->shm, | |||
1387 | height*scale*stride, | |||
1388 | &data->buf_length, | |||
1389 | &data->buf); | |||
1390 | ||||
1391 | surface = cairo_image_surface_create_for_data (data->buf, | |||
| ||||
1392 | CAIRO_FORMAT_ARGB32, | |||
1393 | width*scale, | |||
1394 | height*scale, | |||
1395 | stride); | |||
1396 | ||||
1397 | data->buffer = wl_shm_pool_create_buffer (data->pool, 0, | |||
1398 | width*scale, height*scale, | |||
1399 | stride, WL_SHM_FORMAT_ARGB8888); | |||
1400 | ||||
1401 | cairo_surface_set_user_data (surface, &cdk_wayland_shm_surface_cairo_key, | |||
1402 | data, cdk_wayland_cairo_surface_destroy); | |||
1403 | ||||
1404 | cairo_surface_set_device_scale (surface, scale, scale); | |||
1405 | ||||
1406 | status = cairo_surface_status (surface); | |||
1407 | if (status != CAIRO_STATUS_SUCCESS) | |||
1408 | { | |||
1409 | g_critical (G_STRLOC"cdkdisplay-wayland.c" ":" "1409" ": Unable to create Cairo image surface: %s", | |||
1410 | cairo_status_to_string (status)); | |||
1411 | } | |||
1412 | ||||
1413 | return surface; | |||
1414 | } | |||
1415 | ||||
1416 | struct wl_buffer * | |||
1417 | _cdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface) | |||
1418 | { | |||
1419 | CdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &cdk_wayland_shm_surface_cairo_key); | |||
1420 | return data->buffer; | |||
1421 | } | |||
1422 | ||||
1423 | gboolean | |||
1424 | _cdk_wayland_is_shm_surface (cairo_surface_t *surface) | |||
1425 | { | |||
1426 | return cairo_surface_get_user_data (surface, &cdk_wayland_shm_surface_cairo_key) != NULL((void*)0); | |||
1427 | } | |||
1428 | ||||
1429 | CdkWaylandSelection * | |||
1430 | cdk_wayland_display_get_selection (CdkDisplay *display) | |||
1431 | { | |||
1432 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
1433 | ||||
1434 | return display_wayland->selection; | |||
1435 | } | |||
1436 | ||||
1437 | /** | |||
1438 | * cdk_wayland_display_query_registry: | |||
1439 | * @display: a wayland #CdkDisplay | |||
1440 | * @interface: global interface to query in the registry | |||
1441 | * | |||
1442 | * Returns %TRUE if the the interface was found in the display | |||
1443 | * wl_registry.global handler. | |||
1444 | * | |||
1445 | * Returns: %TRUE if the global is offered by the compositor | |||
1446 | * | |||
1447 | * Since: 3.22.27 | |||
1448 | **/ | |||
1449 | gboolean | |||
1450 | cdk_wayland_display_query_registry (CdkDisplay *display, | |||
1451 | const gchar *global) | |||
1452 | { | |||
1453 | CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((display)), ((cdk_wayland_display_get_type( ))))))); | |||
1454 | GHashTableIter iter; | |||
1455 | gchar *value; | |||
1456 | ||||
1457 | g_return_val_if_fail (CDK_IS_WAYLAND_DISPLAY (display), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_wayland_display_get_type()) ); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__)), "CDK_IS_WAYLAND_DISPLAY (display)"); return ((0)); } } while (0); | |||
1458 | g_return_val_if_fail (global != NULL, FALSE)do { if ((global != ((void*)0))) { } else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__)), "global != NULL"); return ((0)); } } while (0); | |||
1459 | ||||
1460 | g_hash_table_iter_init (&iter, display_wayland->known_globals); | |||
1461 | ||||
1462 | while (g_hash_table_iter_next (&iter, NULL((void*)0), (gpointer*) &value)) | |||
1463 | { | |||
1464 | if (strcmp (value, global) == 0) | |||
1465 | return TRUE(!(0)); | |||
1466 | } | |||
1467 | ||||
1468 | return FALSE(0); | |||
1469 | } |