| 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 | } |