2 * Copyright © 2010 Intel Corporation
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.
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.
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/>.
27 #include "gdkwayland.h"
28 #include "gdkdisplay.h"
29 #include "gdkdisplay-wayland.h"
30 #include "gdkscreen.h"
31 #include "gdkinternals.h"
32 #include "gdkdeviceprivate.h"
33 #include "gdkdevicemanager.h"
34 #include "gdkkeysprivate.h"
35 #include "gdkprivate-wayland.h"
37 static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *wayland_display);
39 G_DEFINE_TYPE (GdkWaylandDisplay, gdk_wayland_display, GDK_TYPE_DISPLAY)
42 gdk_input_init (GdkDisplay *display)
44 GdkWaylandDisplay *display_wayland;
45 GdkDeviceManager *device_manager;
49 display_wayland = GDK_WAYLAND_DISPLAY (display);
50 device_manager = gdk_display_get_device_manager (display);
52 /* For backwards compatibility, just add
53 * floating devices that are not keyboards.
55 list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
57 for (l = list; l; l = l->next)
61 if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
64 display_wayland->input_devices = g_list_prepend (display_wayland->input_devices, l->data);
69 /* Now set "core" pointer to the first
70 * master device that is a pointer.
72 list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
74 for (l = list; l; l = l->next)
78 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
81 display->core_pointer = device;
85 /* Add the core pointer to the devices list */
86 display_wayland->input_devices = g_list_prepend (display_wayland->input_devices, display->core_pointer);
92 gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
93 const char *interface, uint32_t version)
95 GdkWaylandDisplay *display_wayland = data;
96 GdkDisplay *gdk_display = GDK_DISPLAY_OBJECT (data);
98 struct wl_output *output;
100 if (strcmp(interface, "wl_compositor") == 0) {
101 display_wayland->compositor =
102 wl_registry_bind(display_wayland->wl_registry, id, &wl_compositor_interface, 1);
103 } else if (strcmp(interface, "wl_shm") == 0) {
104 display_wayland->shm =
105 wl_registry_bind(display_wayland->wl_registry, id, &wl_shm_interface, 1);
107 /* SHM interface is prerequisite */
108 _gdk_wayland_display_load_cursor_theme(display_wayland);
109 } else if (strcmp(interface, "wl_shell") == 0) {
110 display_wayland->shell =
111 wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1);
112 } else if (strcmp(interface, "wl_output") == 0) {
114 wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
115 _gdk_wayland_screen_add_output(display_wayland->screen, output);
116 } else if (strcmp(interface, "wl_seat") == 0) {
117 seat = wl_registry_bind(display_wayland->wl_registry, id, &wl_seat_interface, 1);
118 _gdk_wayland_device_manager_add_device (gdk_display->device_manager,
120 } else if (strcmp(interface, "wl_data_device_manager") == 0) {
121 display_wayland->data_device_manager =
122 wl_registry_bind(display_wayland->wl_registry, id,
123 &wl_data_device_manager_interface, 1);
128 gdk_registry_handle_global_remove(void *data,
129 struct wl_registry *registry,
132 GdkWaylandDisplay *display_wayland = data;
134 /* We don't know what this item is - try as an output */
135 _gdk_wayland_screen_remove_output_by_id (display_wayland->screen, id);
138 static const struct wl_registry_listener registry_listener = {
139 gdk_registry_handle_global,
140 gdk_registry_handle_global_remove
144 _gdk_wayland_display_open (const gchar *display_name)
146 struct wl_display *wl_display;
148 GdkWaylandDisplay *display_wayland;
150 wl_display = wl_display_connect(display_name);
154 display = g_object_new (GDK_TYPE_WAYLAND_DISPLAY, NULL);
155 display_wayland = GDK_WAYLAND_DISPLAY (display);
157 display_wayland->wl_display = wl_display;
159 display_wayland->screen = _gdk_wayland_screen_new (display);
161 display->device_manager = _gdk_wayland_device_manager_new (display);
163 /* Set up listener so we'll catch all events. */
164 display_wayland->wl_registry = wl_display_get_registry(display_wayland->wl_display);
165 wl_registry_add_listener(display_wayland->wl_registry, ®istry_listener, display_wayland);
167 wl_display_dispatch(display_wayland->wl_display);
169 display_wayland->event_source =
170 _gdk_wayland_display_event_source_new (display);
172 gdk_input_init (display);
174 g_signal_emit_by_name (display, "opened");
175 g_signal_emit_by_name (gdk_display_manager_get(), "display_opened", display);
181 gdk_wayland_display_dispose (GObject *object)
183 GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object);
185 _gdk_wayland_display_manager_remove_display (gdk_display_manager_get (),
186 GDK_DISPLAY (display_wayland));
187 g_list_foreach (display_wayland->input_devices,
188 (GFunc) g_object_run_dispose, NULL);
190 _gdk_screen_close (display_wayland->screen);
192 if (display_wayland->event_source)
194 g_source_destroy (display_wayland->event_source);
195 g_source_unref (display_wayland->event_source);
196 display_wayland->event_source = NULL;
199 G_OBJECT_CLASS (gdk_wayland_display_parent_class)->dispose (object);
203 gdk_wayland_display_finalize (GObject *object)
205 GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object);
208 if (display_wayland->keymap)
209 g_object_unref (display_wayland->keymap);
211 /* input GdkDevice list */
212 g_list_free_full (display_wayland->input_devices, g_object_unref);
214 g_object_unref (display_wayland->screen);
216 g_free (display_wayland->startup_notification_id);
218 G_OBJECT_CLASS (gdk_wayland_display_parent_class)->finalize (object);
222 gdk_wayland_display_get_name (GdkDisplay *display)
228 gdk_wayland_display_get_n_screens (GdkDisplay *display)
234 gdk_wayland_display_get_screen (GdkDisplay *display,
237 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
238 g_return_val_if_fail (screen_num == 0, NULL);
240 return GDK_WAYLAND_DISPLAY (display)->screen;
244 gdk_wayland_display_get_default_screen (GdkDisplay *display)
246 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
248 return GDK_WAYLAND_DISPLAY (display)->screen;
252 gdk_wayland_display_beep (GdkDisplay *display)
254 g_return_if_fail (GDK_IS_DISPLAY (display));
258 gdk_wayland_display_sync (GdkDisplay *display)
260 GdkWaylandDisplay *display_wayland;
262 g_return_if_fail (GDK_IS_DISPLAY (display));
264 display_wayland = GDK_WAYLAND_DISPLAY (display);
266 wl_display_roundtrip(display_wayland->wl_display);
270 gdk_wayland_display_flush (GdkDisplay *display)
272 g_return_if_fail (GDK_IS_DISPLAY (display));
274 if (!display->closed)
275 wl_display_flush(GDK_WAYLAND_DISPLAY (display)->wl_display);;
279 gdk_wayland_display_has_pending (GdkDisplay *display)
285 gdk_wayland_display_get_default_group (GdkDisplay *display)
287 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
294 gdk_wayland_display_supports_selection_notification (GdkDisplay *display)
300 gdk_wayland_display_request_selection_notification (GdkDisplay *display,
308 gdk_wayland_display_supports_clipboard_persistence (GdkDisplay *display)
314 gdk_wayland_display_store_clipboard (GdkDisplay *display,
315 GdkWindow *clipboard_window,
317 const GdkAtom *targets,
323 gdk_wayland_display_supports_shapes (GdkDisplay *display)
329 gdk_wayland_display_supports_input_shapes (GdkDisplay *display)
335 gdk_wayland_display_supports_composite (GdkDisplay *display)
341 gdk_wayland_display_list_devices (GdkDisplay *display)
343 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
345 return GDK_WAYLAND_DISPLAY (display)->input_devices;
349 gdk_wayland_display_before_process_all_updates (GdkDisplay *display)
354 gdk_wayland_display_after_process_all_updates (GdkDisplay *display)
356 /* Post the damage here instead? */
360 gdk_wayland_display_get_next_serial (GdkDisplay *display)
362 static gulong serial = 0;
367 _gdk_wayland_display_make_default (GdkDisplay *display)
372 * gdk_wayland_display_broadcast_startup_message:
373 * @display: a #GdkDisplay
374 * @message_type: startup notification message type ("new", "change",
376 * @...: a list of key/value pairs (as strings), terminated by a
377 * %NULL key. (A %NULL value for a key will cause that key to be
378 * skipped in the output.)
380 * Sends a startup notification message of type @message_type to
383 * This is a convenience function for use by code that implements the
384 * freedesktop startup notification specification. Applications should
385 * not normally need to call it directly. See the <ulink
386 * url="http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt">Startup
387 * Notification Protocol specification</ulink> for
388 * definitions of the message types and keys that can be used.
393 gdk_wayland_display_broadcast_startup_message (GdkDisplay *display,
394 const char *message_type,
399 const char *key, *value, *p;
401 message = g_string_new (message_type);
402 g_string_append_c (message, ':');
404 va_start (ap, message_type);
405 while ((key = va_arg (ap, const char *)))
407 value = va_arg (ap, const char *);
411 g_string_append_printf (message, " %s=\"", key);
412 for (p = value; *p; p++)
419 g_string_append_c (message, '\\');
423 g_string_append_c (message, *p);
425 g_string_append_c (message, '\"');
429 g_string_free (message, TRUE);
433 gdk_wayland_display_notify_startup_complete (GdkDisplay *display,
434 const gchar *startup_id)
436 gdk_wayland_display_broadcast_startup_message (display, "remove",
442 gdk_wayland_display_event_data_copy (GdkDisplay *display,
449 gdk_wayland_display_event_data_free (GdkDisplay *display,
455 _gdk_wayland_display_get_keymap (GdkDisplay *display)
457 GdkDeviceManager *device_manager;
459 GdkDevice *core_keyboard = NULL;
460 static GdkKeymap *tmp_keymap = NULL;
462 device_manager = gdk_display_get_device_manager (display);
463 list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
465 for (l = list; l; l = l->next)
470 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
473 core_keyboard = device;
477 if (core_keyboard && tmp_keymap)
479 g_object_unref (tmp_keymap);
484 return _gdk_wayland_device_get_keymap (core_keyboard);
486 tmp_keymap = _gdk_wayland_keymap_new ();
492 gdk_wayland_display_push_error_trap (GdkDisplay *display)
497 gdk_wayland_display_pop_error_trap (GdkDisplay *display,
504 gdk_wayland_display_class_init (GdkWaylandDisplayClass * class)
506 GObjectClass *object_class = G_OBJECT_CLASS (class);
507 GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (class);
509 object_class->dispose = gdk_wayland_display_dispose;
510 object_class->finalize = gdk_wayland_display_finalize;
512 display_class->window_type = gdk_wayland_window_get_type ();
513 display_class->get_name = gdk_wayland_display_get_name;
514 display_class->get_n_screens = gdk_wayland_display_get_n_screens;
515 display_class->get_screen = gdk_wayland_display_get_screen;
516 display_class->get_default_screen = gdk_wayland_display_get_default_screen;
517 display_class->beep = gdk_wayland_display_beep;
518 display_class->sync = gdk_wayland_display_sync;
519 display_class->flush = gdk_wayland_display_flush;
520 display_class->has_pending = gdk_wayland_display_has_pending;
521 display_class->queue_events = _gdk_wayland_display_queue_events;
522 display_class->get_default_group = gdk_wayland_display_get_default_group;
523 display_class->supports_selection_notification = gdk_wayland_display_supports_selection_notification;
524 display_class->request_selection_notification = gdk_wayland_display_request_selection_notification;
525 display_class->supports_clipboard_persistence = gdk_wayland_display_supports_clipboard_persistence;
526 display_class->store_clipboard = gdk_wayland_display_store_clipboard;
527 display_class->supports_shapes = gdk_wayland_display_supports_shapes;
528 display_class->supports_input_shapes = gdk_wayland_display_supports_input_shapes;
529 display_class->supports_composite = gdk_wayland_display_supports_composite;
530 display_class->list_devices = gdk_wayland_display_list_devices;
531 display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context;
532 display_class->get_default_cursor_size = _gdk_wayland_display_get_default_cursor_size;
533 display_class->get_maximal_cursor_size = _gdk_wayland_display_get_maximal_cursor_size;
534 display_class->get_cursor_for_type = _gdk_wayland_display_get_cursor_for_type;
535 display_class->get_cursor_for_name = _gdk_wayland_display_get_cursor_for_name;
536 display_class->get_cursor_for_pixbuf = _gdk_wayland_display_get_cursor_for_pixbuf;
537 display_class->supports_cursor_alpha = _gdk_wayland_display_supports_cursor_alpha;
538 display_class->supports_cursor_color = _gdk_wayland_display_supports_cursor_color;
539 display_class->before_process_all_updates = gdk_wayland_display_before_process_all_updates;
540 display_class->after_process_all_updates = gdk_wayland_display_after_process_all_updates;
541 display_class->get_next_serial = gdk_wayland_display_get_next_serial;
542 display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
543 display_class->event_data_copy = gdk_wayland_display_event_data_copy;
544 display_class->event_data_free = gdk_wayland_display_event_data_free;
545 display_class->create_window_impl = _gdk_wayland_display_create_window_impl;
546 display_class->get_keymap = _gdk_wayland_display_get_keymap;
547 display_class->push_error_trap = gdk_wayland_display_push_error_trap;
548 display_class->pop_error_trap = gdk_wayland_display_pop_error_trap;
549 display_class->get_selection_owner = _gdk_wayland_display_get_selection_owner;
550 display_class->set_selection_owner = _gdk_wayland_display_set_selection_owner;
551 display_class->send_selection_notify = _gdk_wayland_display_send_selection_notify;
552 display_class->get_selection_property = _gdk_wayland_display_get_selection_property;
553 display_class->convert_selection = _gdk_wayland_display_convert_selection;
554 display_class->text_property_to_utf8_list = _gdk_wayland_display_text_property_to_utf8_list;
555 display_class->utf8_to_string_target = _gdk_wayland_display_utf8_to_string_target;
559 gdk_wayland_display_init (GdkWaylandDisplay *display)
561 _gdk_wayland_display_manager_add_display (gdk_display_manager_get (),
562 GDK_DISPLAY (display));
564 display->xkb_context = xkb_context_new (0);
568 _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *wayland_display)
571 const gchar *theme_name;
572 GValue v = G_VALUE_INIT;
574 g_assert (wayland_display);
575 g_assert (wayland_display->shm);
577 _gdk_wayland_display_get_default_cursor_size (GDK_DISPLAY (wayland_display),
579 g_value_init (&v, G_TYPE_STRING);
580 if (gdk_setting_get ("gtk-cursor-theme-name", &v))
581 theme_name = g_value_get_string (&v);
583 theme_name = "default";
585 wayland_display->cursor_theme = wl_cursor_theme_load (theme_name,
587 wayland_display->shm);
592 _gdk_wayland_display_get_serial (GdkWaylandDisplay *wayland_display)
594 return wayland_display->serial;
598 _gdk_wayland_display_update_serial (GdkWaylandDisplay *wayland_display,
601 if (serial > wayland_display->serial)
602 wayland_display->serial = serial;
606 * gdk_wayland_display_get_wl_display
607 * @display: (type GdkWaylandDisplay): a #GdkDisplay
609 * Returns the Wayland wl_display of a #GdkDisplay
611 * Returns: (transfer none): a Wayland wl_display
616 gdk_wayland_display_get_wl_display(GdkDisplay *display)
618 GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY(display);
620 g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY(display), NULL);
622 return wayland_display->wl_display;
626 * gdk_wayland_display_get_wl_compositor
627 * @display: (type GdkWaylandDisplay): a #GdkDisplay
629 * Returns the Wayland global singleton compositor of a #GdkDisplay
631 * Returns: (transfer none): a Wayland wl_compositor
635 struct wl_compositor *
636 gdk_wayland_display_get_wl_compositor (GdkDisplay *display)
638 GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY(display);
640 g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY(display), NULL);
642 return wayland_display->compositor;
646 * gdk_wayland_display_get_wl_shell
647 * @display: (type GdkWaylandDisplay): a #GdkDisplay
649 * Returns the Wayland global singleton shell of a #GdkDisplay
651 * Returns: (transfer none): a Wayland wl_shell
656 gdk_wayland_display_get_wl_shell (GdkDisplay *display)
658 GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY(display);
660 g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY(display), NULL);
662 return wayland_display->shell;