diff options
Diffstat (limited to 'gdk/wayland/gdkwindow-wayland.c')
-rw-r--r-- | gdk/wayland/gdkwindow-wayland.c | 1419 |
1 files changed, 1419 insertions, 0 deletions
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c new file mode 100644 index 0000000000..15a2e4c5f8 --- /dev/null +++ b/gdk/wayland/gdkwindow-wayland.c @@ -0,0 +1,1419 @@ +/* + * Copyright © 2010 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include <netinet/in.h> +#include <unistd.h> + +#include "gdk.h" +#include "gdkwayland.h" + +#include "gdkwindow.h" +#include "gdkwindowimpl.h" +#include "gdkdisplay-wayland.h" +#include "gdkscreen-wayland.h" +#include "gdkprivate-wayland.h" +#include "gdkinternals.h" +#include "gdkwindow-wayland.h" +#include "gdkdeviceprivate.h" +#include "gdkdevice-wayland.h" +#include "gdkeventsource.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) + +#define WINDOW_IS_TOPLEVEL(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) + +/* Return whether time1 is considered later than time2 as far as xserver + * time is concerned. Accounts for wraparound. + */ +#define XSERVER_TIME_IS_LATER(time1, time2) \ + ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \ + (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \ + ) + +typedef struct _GdkWaylandWindow GdkWaylandWindow; +typedef struct _GdkWaylandWindowClass GdkWaylandWindowClass; + +struct _GdkWaylandWindow { + GdkWindow parent; +}; + +struct _GdkWaylandWindowClass { + GdkWindowClass parent_class; +}; + +G_DEFINE_TYPE (GdkWaylandWindow, _gdk_wayland_window, GDK_TYPE_WINDOW) + +static void +_gdk_wayland_window_class_init (GdkWaylandWindowClass *wayland_window_class) +{ +} + +static void +_gdk_wayland_window_init (GdkWaylandWindow *wayland_window) +{ +} + +G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL) + +static void +_gdk_window_impl_wayland_init (GdkWindowImplWayland *impl) +{ + impl->toplevel_window_type = -1; + impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) gdk_cursor_unref); +} + +GdkToplevelWayland * +_gdk_wayland_window_get_toplevel (GdkWindow *window) +{ + GdkWindowImplWayland *impl; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (!WINDOW_IS_TOPLEVEL (window)) + return NULL; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (!impl->toplevel) + impl->toplevel = g_new0 (GdkToplevelWayland, 1); + + return impl->toplevel; +} + +/** + * _gdk_wayland_window_update_size: + * @drawable: a #GdkDrawableImplWayland. + * + * Updates the state of the drawable (in particular the drawable's + * cairo surface) when its size has changed. + **/ +void +_gdk_wayland_window_update_size (GdkWindowImplWayland *impl) +{ + GdkDisplayWayland *display_wayland = + GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); + + fprintf(stderr, "update size, window %p\n", impl->wrapper); + + if (impl->cairo_surface) + { + cairo_surface_destroy (impl->cairo_surface); + impl->cairo_surface = NULL; + } + + if (impl->image) + { + if (impl->image == impl->next_image) + impl->next_image = NULL; + + if (impl->image != impl->pending_image) + display_wayland->destroy_image(display_wayland->egl_display, + impl->image); + + impl->image = NULL; + + fprintf(stderr, " - cleared image\n"); + } +} + +GdkWindow * +_gdk_wayland_screen_create_root_window (GdkScreen *screen, + int width, int height) +{ + GdkWindow *window; + GdkWindowImplWayland *impl; + + window = _gdk_display_create_window (gdk_screen_get_display (screen)); + window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL); + window->impl_window = window; + window->visual = gdk_screen_get_system_visual (screen); + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + impl->wrapper = GDK_WINDOW (window); + + window->window_type = GDK_WINDOW_ROOT; + window->depth = 32; + + window->x = 0; + window->y = 0; + window->abs_x = 0; + window->abs_y = 0; + window->width = width; + window->height = height; + window->viewable = TRUE; + + /* see init_randr_support() in gdkscreen-wayland.c */ + window->event_mask = GDK_STRUCTURE_MASK; + + return window; +} + +static const gchar * +get_default_title (void) +{ + const char *title; + + title = g_get_application_name (); + if (!title) + title = g_get_prgname (); + if (!title) + title = ""; + + return title; +} + +void +_gdk_wayland_display_create_window_impl (GdkDisplay *display, + GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask) +{ + GdkWindowImplWayland *impl; + GdkDisplayWayland *display_wayland; + const char *title; + + display_wayland = GDK_DISPLAY_WAYLAND (display); + + impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL); + window->impl = GDK_WINDOW_IMPL (impl); + impl->wrapper = GDK_WINDOW (window); + + printf("impl_new for window %p: %p\n", window, impl); + + if (window->width > 65535 || + window->height > 65535) + { + g_warning ("Native Windows wider or taller than 65535 pixels are not supported"); + + if (window->width > 65535) + window->width = 65535; + if (window->height > 65535) + window->height = 65535; + } + + g_object_ref (window); + + switch (GDK_WINDOW_TYPE (window)) + { + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_TEMP: + if (attributes_mask & GDK_WA_TITLE) + title = attributes->title; + else + title = get_default_title (); + + gdk_window_set_title (window, title); + break; + + case GDK_WINDOW_CHILD: + default: + break; + } + + if (attributes_mask & GDK_WA_TYPE_HINT) + gdk_window_set_type_hint (window, attributes->type_hint); +} + +static void +gdk_toplevel_wayland_free_contents (GdkDisplay *display, + GdkToplevelWayland *toplevel) +{ + if (toplevel->icon_pixmap) + { + cairo_surface_destroy (toplevel->icon_pixmap); + toplevel->icon_pixmap = NULL; + } + if (toplevel->icon_mask) + { + cairo_surface_destroy (toplevel->icon_mask); + toplevel->icon_mask = NULL; + } +} + +void +_gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image) +{ + GdkDisplayWayland *display_wayland = + GDK_DISPLAY_WAYLAND (gdk_window_get_display (window)); + GdkWindowImplWayland *impl; + EGLint name, stride; + struct wl_visual *wl_visual; + struct wl_buffer *buffer; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (impl->pending_image) + { + if (impl->next_image && impl->next_image != impl->image) + display_wayland->destroy_image(display_wayland->egl_display, + impl->next_image); + + impl->next_image = image; + + return; + } + + impl->pending_image = image; + + wl_visual = + wl_display_get_premultiplied_argb_visual(display_wayland->wl_display); + + display_wayland->export_drm_image (display_wayland->egl_display, + image, &name, NULL, &stride); + + buffer = wl_drm_create_buffer(display_wayland->drm, + name, window->width, window->height, + stride, wl_visual); + wl_surface_attach (impl->surface, buffer, 0, 0); + wl_surface_map_toplevel (impl->surface); + wl_buffer_destroy(buffer); + + g_object_ref(impl); + + fprintf(stderr, "attach %p %dx%d (image %p, name %d)\n", + window, window->width, window->height, + impl->pending_image, name); +} + +static void +gdk_window_impl_wayland_finalize (GObject *object) +{ + GdkWindow *wrapper; + GdkWindowImplWayland *impl; + + g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (object)); + + impl = GDK_WINDOW_IMPL_WAYLAND (object); + + wrapper = impl->wrapper; + + g_free (impl->toplevel); + + if (impl->cursor) + gdk_cursor_unref (impl->cursor); + + g_hash_table_destroy (impl->device_cursor); + + G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object); +} + +static const cairo_user_data_key_t gdk_wayland_cairo_key; + +static void +gdk_wayland_cairo_surface_destroy (void *data) +{ + GdkWindowImplWayland *impl = data; + + impl->cairo_surface = NULL; +} + +gboolean +_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + int width, + int height) +{ + fprintf (stderr, "_gdk_windowing_set_cairo_surface_size\n"); + + return FALSE; +} + +static cairo_surface_t * +gdk_wayland_create_cairo_surface (GdkWindowImplWayland *impl, + int width, + int height) +{ + GdkDisplayWayland *display_wayland = + GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); + cairo_surface_t *surface; + + EGLint image_attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + + if (impl->image == NULL) + { + image_attribs[1] = width; + image_attribs[3] = height; + impl->image = + display_wayland->create_drm_image(display_wayland->egl_display, + image_attribs); + if (impl->texture == 0) + glGenTextures(1, &impl->texture); + + glBindTexture(GL_TEXTURE_2D, impl->texture); + display_wayland->image_target_texture_2d(GL_TEXTURE_2D, impl->image); + + printf("allocate image %dx%d (image %p, window %p)\n", + width, height, impl->image, impl->wrapper); + } + + surface = cairo_gl_surface_create_for_texture(display_wayland->cairo_device, + CAIRO_CONTENT_COLOR_ALPHA, + impl->texture, width, height); + + if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) + fprintf (stderr, "create gl surface failed\n"); + + return surface; +} + +static cairo_surface_t * +gdk_wayland_window_ref_cairo_surface (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (GDK_WINDOW_DESTROYED (impl->wrapper)) + return NULL; + + if (!impl->cairo_surface) + { + impl->cairo_surface = + gdk_wayland_create_cairo_surface (impl, + impl->wrapper->width, + impl->wrapper->height); + + cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key, + impl, gdk_wayland_cairo_surface_destroy); + } + else + cairo_surface_reference (impl->cairo_surface); + + return impl->cairo_surface; +} + +static void +gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time) +{ +} + +static void +gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) +{ + GdkDisplay *display; + GdkDisplayWayland *display_wayland; + GdkToplevelWayland *toplevel; + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (WINDOW_IS_TOPLEVEL (window)) + { + display = gdk_window_get_display (window); + display_wayland = GDK_DISPLAY_WAYLAND (display); + toplevel = _gdk_wayland_window_get_toplevel (window); + + if (toplevel->user_time != 0 && + display_wayland->user_time != 0 && + XSERVER_TIME_IS_LATER (display_wayland->user_time, toplevel->user_time)) + gdk_wayland_window_set_user_time (window, display_wayland->user_time); + } + + display = gdk_window_get_display (window); + display_wayland = GDK_DISPLAY_WAYLAND (display); + + impl->surface = wl_compositor_create_surface(display_wayland->compositor); + wl_surface_set_user_data(impl->surface, window); + + _gdk_make_event (window, GDK_MAP, NULL, FALSE); +} + +static void +gdk_wayland_window_hide (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (impl->surface) + { + fprintf (stderr, "hide surface %p\n", impl->surface); + + wl_surface_destroy(impl->surface); + impl->surface = NULL; + } + + _gdk_window_clear_update_area (window); +} + +static void +gdk_window_wayland_withdraw (GdkWindow *window) +{ + GdkWindowImplWayland *impl; + + if (!window->destroyed) + { + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_WITHDRAWN); + + g_assert (!GDK_WINDOW_IS_MAPPED (window)); + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + if (impl->surface) + { + fprintf (stderr, "hide surface %p\n", impl->surface); + + wl_surface_destroy(impl->surface); + impl->surface = NULL; + cairo_surface_destroy(GDK_WINDOW_IMPL_WAYLAND(impl)->cairo_surface); + } + } +} + +static void +gdk_window_wayland_set_events (GdkWindow *window, + GdkEventMask event_mask) +{ + GDK_WINDOW (window)->event_mask = event_mask; +} + +static GdkEventMask +gdk_window_wayland_get_events (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return 0; + else + return GDK_WINDOW (window)->event_mask; +} + +static void +gdk_window_wayland_raise (GdkWindow *window) +{ + /* FIXME: wl_shell_raise() */ +} + +static void +gdk_window_wayland_lower (GdkWindow *window) +{ + /* FIXME: wl_shell_lower() */ +} + +static void +gdk_window_wayland_restack_under (GdkWindow *window, + GList *native_siblings) +{ +} + +static void +gdk_window_wayland_restack_toplevel (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ +} + +static void +gdk_window_wayland_move_resize (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowImplWayland *impl; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + window->x = x; + window->y = y; + if (width > 0) + window->width = width; + if (height > 0) + window->height = height; + + _gdk_wayland_window_update_size (GDK_WINDOW_IMPL_WAYLAND (window->impl)); +} + +static void +gdk_window_wayland_set_background (GdkWindow *window, + cairo_pattern_t *pattern) +{ +} + +static gboolean +gdk_window_wayland_reparent (GdkWindow *window, + GdkWindow *new_parent, + gint x, + gint y) +{ + return FALSE; +} + +static void +gdk_window_wayland_set_device_cursor (GdkWindow *window, + GdkDevice *device, + GdkCursor *cursor) +{ + GdkWindowImplWayland *impl; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_IS_DEVICE (device)); + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (!cursor) + g_hash_table_remove (impl->device_cursor, device); + else + { + g_hash_table_replace (impl->device_cursor, + device, gdk_cursor_ref (cursor)); + } + + if (!GDK_WINDOW_DESTROYED (window)) + GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor); +} + +static void +gdk_window_wayland_get_geometry (GdkWindow *window, + gint *x, + gint *y, + gint *width, + gint *height) +{ + if (!GDK_WINDOW_DESTROYED (window)) + { + if (x) + *x = window->x; + if (y) + *y = window->y; + if (width) + *width = window->width; + if (height) + *height = window->height; + } +} + +static gint +gdk_window_wayland_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) +{ + /* We can't do this. */ + if (root_x) + *root_x = 0; + if (root_y) + *root_y = 0; + + return 1; +} + +static gboolean +gdk_window_wayland_get_device_state (GdkWindow *window, + GdkDevice *device, + gint *x, + gint *y, + GdkModifierType *mask) +{ + gboolean return_val; + + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE); + + return_val = TRUE; + + if (!GDK_WINDOW_DESTROYED (window)) + { + GdkWindow *child; + + GDK_DEVICE_GET_CLASS (device)->query_state (device, window, + NULL, &child, + NULL, NULL, + x, y, mask); + return_val = (child != NULL); + } + + return return_val; +} + +static void +gdk_window_wayland_shape_combine_region (GdkWindow *window, + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static void +gdk_window_wayland_input_shape_combine_region (GdkWindow *window, + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static gboolean +gdk_window_wayland_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + return TRUE; +} + +static gboolean +gdk_wayland_window_queue_antiexpose (GdkWindow *window, + cairo_region_t *area) +{ + return FALSE; +} + +static void +gdk_wayland_window_translate (GdkWindow *window, + cairo_region_t *area, + gint dx, + gint dy) +{ + cairo_surface_t *surface; + cairo_t *cr; + + surface = gdk_wayland_window_ref_cairo_surface (window->impl_window); + cr = cairo_create (surface); + cairo_surface_destroy (surface); + + gdk_cairo_region (cr, area); + cairo_clip (cr); + cairo_set_source_surface (cr, cairo_get_target (cr), dx, dy); + cairo_push_group (cr); + cairo_paint (cr); + cairo_pop_group_to_source (cr); + cairo_paint (cr); + cairo_destroy (cr); +} + +static void +gdk_wayland_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) +{ + GdkToplevelWayland *toplevel; + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + g_return_if_fail (GDK_IS_WINDOW (window)); + + toplevel = _gdk_wayland_window_get_toplevel (window); + if (toplevel) + gdk_toplevel_wayland_free_contents (gdk_window_get_display (window), + toplevel); + + if (impl->cairo_surface) + { + cairo_surface_finish (impl->cairo_surface); + cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key, + NULL, NULL); + } + + if (impl->texture) + glDeleteTextures(1, &impl->texture); + + if (!recursing && !foreign_destroy) + { + fprintf (stderr, "destroy window, surface %p\n", + GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface); + + if (GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface) + wl_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface); + } +} + +static void +gdk_window_wayland_destroy_foreign (GdkWindow *window) +{ +} + +static cairo_surface_t * +gdk_window_wayland_resize_cairo_surface (GdkWindow *window, + cairo_surface_t *surface, + gint width, + gint height) +{ + return surface; +} + +static cairo_region_t * +gdk_wayland_window_get_shape (GdkWindow *window) +{ + return NULL; +} + +static cairo_region_t * +gdk_wayland_window_get_input_shape (GdkWindow *window) +{ + return NULL; +} + +static void +gdk_wayland_window_focus (GdkWindow *window, + guint32 timestamp) +{ + /* FIXME: wl_shell_focus() */ +} + +static void +gdk_wayland_window_set_type_hint (GdkWindow *window, + GdkWindowTypeHint hint) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; + + switch (hint) + { + case GDK_WINDOW_TYPE_HINT_DIALOG: + case GDK_WINDOW_TYPE_HINT_MENU: + case GDK_WINDOW_TYPE_HINT_TOOLBAR: + case GDK_WINDOW_TYPE_HINT_UTILITY: + case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN: + case GDK_WINDOW_TYPE_HINT_DOCK: + case GDK_WINDOW_TYPE_HINT_DESKTOP: + case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: + case GDK_WINDOW_TYPE_HINT_POPUP_MENU: + case GDK_WINDOW_TYPE_HINT_TOOLTIP: + case GDK_WINDOW_TYPE_HINT_NOTIFICATION: + case GDK_WINDOW_TYPE_HINT_COMBO: + case GDK_WINDOW_TYPE_HINT_DND: + break; + default: + g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint); + /* Fall thru */ + case GDK_WINDOW_TYPE_HINT_NORMAL: + break; + } +} + +static GdkWindowTypeHint +gdk_wayland_window_get_type_hint (GdkWindow *window) +{ + return GDK_WINDOW_TYPE_HINT_NORMAL; +} + +void +gdk_wayland_window_set_modal_hint (GdkWindow *window, + gboolean modal) +{ +} + +static void +gdk_wayland_window_set_skip_taskbar_hint (GdkWindow *window, + gboolean skips_taskbar) +{ +} + +static void +gdk_wayland_window_set_skip_pager_hint (GdkWindow *window, + gboolean skips_pager) +{ +} + +static void +gdk_wayland_window_set_urgency_hint (GdkWindow *window, + gboolean urgent) +{ +} + +static void +gdk_wayland_window_set_geometry_hints (GdkWindow *window, + const GdkGeometry *geometry, + GdkWindowHints geom_mask) +{ + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + /* + * GDK_HINT_POS + * GDK_HINT_USER_POS + * GDK_HINT_USER_SIZE + * GDK_HINT_MIN_SIZE + * GDK_HINT_MAX_SIZE + * GDK_HINT_BASE_SIZE + * GDK_HINT_RESIZE_INC + * GDK_HINT_ASPECT + * GDK_HINT_WIN_GRAVITY + */ +} + +static void +gdk_wayland_window_set_title (GdkWindow *window, + const gchar *title) +{ + g_return_if_fail (title != NULL); + + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_set_role (GdkWindow *window, + const gchar *role) +{ +} + +static void +gdk_wayland_window_set_startup_id (GdkWindow *window, + const gchar *startup_id) +{ +} + +static void +gdk_wayland_window_set_transient_for (GdkWindow *window, + GdkWindow *parent) +{ +} + +static void +gdk_wayland_window_get_root_origin (GdkWindow *window, + gint *x, + gint *y) +{ + if (x) + *x = 0; + + if (y) + *y = 0; +} + +static void +gdk_wayland_window_get_frame_extents (GdkWindow *window, + GdkRectangle *rect) +{ + rect->x = window->x; + rect->y = window->y; + rect->width = window->width; + rect->height = window->height; +} + +static void +gdk_wayland_window_set_override_redirect (GdkWindow *window, + gboolean override_redirect) +{ +} + +static void +gdk_wayland_window_set_accept_focus (GdkWindow *window, + gboolean accept_focus) +{ +} + +static void +gdk_wayland_window_set_focus_on_map (GdkWindow *window, + gboolean focus_on_map) +{ + focus_on_map = focus_on_map != FALSE; + + if (window->focus_on_map != focus_on_map) + { + window->focus_on_map = focus_on_map; + + if ((!GDK_WINDOW_DESTROYED (window)) && + (!window->focus_on_map) && + WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + gdk_wayland_window_set_user_time (window, 0); + } +} + +static void +gdk_wayland_window_set_icon_list (GdkWindow *window, + GList *pixbufs) +{ +} + +static void +gdk_wayland_window_set_icon_name (GdkWindow *window, + const gchar *name) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_iconify (GdkWindow *window) +{ +} + +static void +gdk_wayland_window_deiconify (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + if (GDK_WINDOW_IS_MAPPED (window)) + { + gdk_window_show (window); + } + else + { + /* Flip our client side flag, the real work happens on map. */ + gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0); + } +} + +static void +gdk_wayland_window_stick (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_unstick (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_maximize (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_unmaximize (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_fullscreen (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_unfullscreen (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_set_keep_above (GdkWindow *window, + gboolean setting) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_set_keep_below (GdkWindow *window, gboolean setting) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static GdkWindow * +gdk_wayland_window_get_group (GdkWindow *window) +{ + GdkToplevelWayland *toplevel; + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return NULL; + + return NULL; +} + +static void +gdk_wayland_window_set_group (GdkWindow *window, + GdkWindow *leader) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD); + g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader)); +} + +static void +gdk_wayland_window_set_decorations (GdkWindow *window, + GdkWMDecoration decorations) +{ +} + +static gboolean +gdk_wayland_window_get_decorations (GdkWindow *window, + GdkWMDecoration *decorations) +{ + return FALSE; +} + +static void +gdk_wayland_window_set_functions (GdkWindow *window, + GdkWMFunction functions) +{ +} + +enum wl_grab_type { + WL_DEVICE_GRAB_NONE = 0, + WL_DEVICE_GRAB_RESIZE_TOP = 1, + WL_DEVICE_GRAB_RESIZE_BOTTOM = 2, + WL_DEVICE_GRAB_RESIZE_LEFT = 4, + WL_DEVICE_GRAB_RESIZE_TOP_LEFT = 5, + WL_DEVICE_GRAB_RESIZE_BOTTOM_LEFT = 6, + WL_DEVICE_GRAB_RESIZE_RIGHT = 8, + WL_DEVICE_GRAB_RESIZE_TOP_RIGHT = 9, + WL_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT = 10, + WL_DEVICE_GRAB_RESIZE_MASK = 15, + WL_DEVICE_GRAB_MOVE = 16, + WL_DEVICE_GRAB_MOTION = 17 +}; + +static void +gdk_wayland_window_begin_resize_drag (GdkWindow *window, + GdkWindowEdge edge, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) +{ + GdkDisplay *display = gdk_window_get_display (window); + GdkDeviceManager *dm; + GdkWindowImplWayland *impl; + GdkDevice *device; + uint32_t grab_type; + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + switch (edge) + { + case GDK_WINDOW_EDGE_NORTH_WEST: + grab_type = WL_DEVICE_GRAB_RESIZE_TOP_LEFT; + break; + + case GDK_WINDOW_EDGE_NORTH: + grab_type = WL_DEVICE_GRAB_RESIZE_TOP; + break; + + case GDK_WINDOW_EDGE_NORTH_EAST: + grab_type = WL_DEVICE_GRAB_RESIZE_RIGHT; + break; + + case GDK_WINDOW_EDGE_WEST: + grab_type = WL_DEVICE_GRAB_RESIZE_LEFT; + break; + + case GDK_WINDOW_EDGE_EAST: + grab_type = WL_DEVICE_GRAB_RESIZE_RIGHT; + break; + + case GDK_WINDOW_EDGE_SOUTH_WEST: + grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM_LEFT; + break; + + case GDK_WINDOW_EDGE_SOUTH: + grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM; + break; + + case GDK_WINDOW_EDGE_SOUTH_EAST: + grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT; + break; + + default: + g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", + edge); + return; + } + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + dm = gdk_display_get_device_manager (display); + device = gdk_device_manager_get_client_pointer (dm); + + wl_shell_resize(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface, + GDK_DEVICE_CORE (device)->device->device, + timestamp, grab_type); +} + +static void +gdk_wayland_window_begin_move_drag (GdkWindow *window, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) +{ + GdkDisplay *display = gdk_window_get_display (window); + GdkDeviceManager *dm; + GdkWindowImplWayland *impl; + GdkDevice *device; + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + dm = gdk_display_get_device_manager (display); + device = gdk_device_manager_get_client_pointer (dm); + + wl_shell_move(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface, + GDK_DEVICE_CORE (device)->device->device, timestamp); +} + +static void +gdk_wayland_window_enable_synchronized_configure (GdkWindow *window) +{ +} + +static void +gdk_wayland_window_configure_finished (GdkWindow *window) +{ + GdkWindowImplWayland *impl; + + if (!WINDOW_IS_TOPLEVEL (window)) + return; + + if (!GDK_IS_WINDOW_IMPL_WAYLAND (window->impl)) + return; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + fprintf(stderr, "configure %p finished\n", window); + + gdk_wayland_window_ref_cairo_surface (GDK_WINDOW (impl)); + + _gdk_wayland_window_attach_image (window, impl->image); + + cairo_surface_destroy (impl->cairo_surface); +} + +static void +gdk_wayland_window_set_opacity (GdkWindow *window, + gdouble opacity) +{ +} + +static void +gdk_wayland_window_set_composited (GdkWindow *window, + gboolean composited) +{ +} + +static void +gdk_wayland_window_destroy_notify (GdkWindow *window) +{ + GdkWindowImplWayland *window_impl; + + window_impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN) + g_warning ("GdkWindow %p unexpectedly destroyed", window); + + _gdk_window_destroy (window, TRUE); + } + + g_object_unref (window); +} + +static void +gdk_wayland_window_process_updates_recurse (GdkWindow *window, + cairo_region_t *region) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + cairo_rectangle_int_t rect; + int i, n; + +#if 0 + gdk_wayland_window_ref_cairo_surface (window); + + _gdk_wayland_window_attach_image (window, impl->image); + cairo_surface_destroy (impl->cairo_surface); +#endif + + n = cairo_region_num_rectangles(region); + for (i = 0; i < n; i++) + { + cairo_region_get_rectangle (region, i, &rect); + wl_surface_damage (impl->surface, + rect.x, rect.y, rect.width, rect.height); + } + + _gdk_window_process_updates_recurse (window, region); +} + +static void +gdk_wayland_window_sync_rendering (GdkWindow *window) +{ +} + +static gboolean +gdk_wayland_window_simulate_key (GdkWindow *window, + gint x, + gint y, + guint keyval, + GdkModifierType modifiers, + GdkEventType key_pressrelease) +{ + return FALSE; +} + +static gboolean +gdk_wayland_window_simulate_button (GdkWindow *window, + gint x, + gint y, + guint button, /*1..3*/ + GdkModifierType modifiers, + GdkEventType button_pressrelease) +{ + return FALSE; +} + +static gboolean +gdk_wayland_window_get_property (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gulong offset, + gulong length, + gint pdelete, + GdkAtom *actual_property_type, + gint *actual_format_type, + gint *actual_length, + guchar **data) +{ + return FALSE; +} + +static void +gdk_wayland_window_change_property (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gint format, + GdkPropMode mode, + const guchar *data, + gint nelements) +{ +} + +static void +gdk_wayland_window_delete_property (GdkWindow *window, + GdkAtom property) +{ +} + +static void +_gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass); + + object_class->finalize = gdk_window_impl_wayland_finalize; + + impl_class->ref_cairo_surface = gdk_wayland_window_ref_cairo_surface; + impl_class->show = gdk_wayland_window_show; + impl_class->hide = gdk_wayland_window_hide; + impl_class->withdraw = gdk_window_wayland_withdraw; + impl_class->set_events = gdk_window_wayland_set_events; + impl_class->get_events = gdk_window_wayland_get_events; + impl_class->raise = gdk_window_wayland_raise; + impl_class->lower = gdk_window_wayland_lower; + impl_class->restack_under = gdk_window_wayland_restack_under; + impl_class->restack_toplevel = gdk_window_wayland_restack_toplevel; + impl_class->move_resize = gdk_window_wayland_move_resize; + impl_class->set_background = gdk_window_wayland_set_background; + impl_class->reparent = gdk_window_wayland_reparent; + impl_class->set_device_cursor = gdk_window_wayland_set_device_cursor; + impl_class->get_geometry = gdk_window_wayland_get_geometry; + impl_class->get_root_coords = gdk_window_wayland_get_root_coords; + impl_class->get_device_state = gdk_window_wayland_get_device_state; + impl_class->shape_combine_region = gdk_window_wayland_shape_combine_region; + impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region; + impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities; + impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose; + impl_class->translate = gdk_wayland_window_translate; + impl_class->destroy = gdk_wayland_window_destroy; + impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign; + impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface; + impl_class->get_shape = gdk_wayland_window_get_shape; + impl_class->get_input_shape = gdk_wayland_window_get_input_shape; + /* impl_class->beep */ + + impl_class->focus = gdk_wayland_window_focus; + impl_class->set_type_hint = gdk_wayland_window_set_type_hint; + impl_class->get_type_hint = gdk_wayland_window_get_type_hint; + impl_class->set_modal_hint = gdk_wayland_window_set_modal_hint; + impl_class->set_skip_taskbar_hint = gdk_wayland_window_set_skip_taskbar_hint; + impl_class->set_skip_pager_hint = gdk_wayland_window_set_skip_pager_hint; + impl_class->set_urgency_hint = gdk_wayland_window_set_urgency_hint; + impl_class->set_geometry_hints = gdk_wayland_window_set_geometry_hints; + impl_class->set_title = gdk_wayland_window_set_title; + impl_class->set_role = gdk_wayland_window_set_role; + impl_class->set_startup_id = gdk_wayland_window_set_startup_id; + impl_class->set_transient_for = gdk_wayland_window_set_transient_for; + impl_class->get_root_origin = gdk_wayland_window_get_root_origin; + impl_class->get_frame_extents = gdk_wayland_window_get_frame_extents; + impl_class->set_override_redirect = gdk_wayland_window_set_override_redirect; + impl_class->set_accept_focus = gdk_wayland_window_set_accept_focus; + impl_class->set_focus_on_map = gdk_wayland_window_set_focus_on_map; + impl_class->set_icon_list = gdk_wayland_window_set_icon_list; + impl_class->set_icon_name = gdk_wayland_window_set_icon_name; + impl_class->iconify = gdk_wayland_window_iconify; + impl_class->deiconify = gdk_wayland_window_deiconify; + impl_class->stick = gdk_wayland_window_stick; + impl_class->unstick = gdk_wayland_window_unstick; + impl_class->maximize = gdk_wayland_window_maximize; + impl_class->unmaximize = gdk_wayland_window_unmaximize; + impl_class->fullscreen = gdk_wayland_window_fullscreen; + impl_class->unfullscreen = gdk_wayland_window_unfullscreen; + impl_class->set_keep_above = gdk_wayland_window_set_keep_above; + impl_class->set_keep_below = gdk_wayland_window_set_keep_below; + impl_class->get_group = gdk_wayland_window_get_group; + impl_class->set_group = gdk_wayland_window_set_group; + impl_class->set_decorations = gdk_wayland_window_set_decorations; + impl_class->get_decorations = gdk_wayland_window_get_decorations; + impl_class->set_functions = gdk_wayland_window_set_functions; + impl_class->begin_resize_drag = gdk_wayland_window_begin_resize_drag; + impl_class->begin_move_drag = gdk_wayland_window_begin_move_drag; + impl_class->enable_synchronized_configure = gdk_wayland_window_enable_synchronized_configure; + impl_class->configure_finished = gdk_wayland_window_configure_finished; + impl_class->set_opacity = gdk_wayland_window_set_opacity; + impl_class->set_composited = gdk_wayland_window_set_composited; + impl_class->destroy_notify = gdk_wayland_window_destroy_notify; + impl_class->register_dnd = _gdk_wayland_window_register_dnd; + impl_class->drag_begin = _gdk_wayland_window_drag_begin; + impl_class->process_updates_recurse = gdk_wayland_window_process_updates_recurse; + impl_class->sync_rendering = gdk_wayland_window_sync_rendering; + impl_class->simulate_key = gdk_wayland_window_simulate_key; + impl_class->simulate_button = gdk_wayland_window_simulate_button; + impl_class->get_property = gdk_wayland_window_get_property; + impl_class->change_property = gdk_wayland_window_change_property; + impl_class->delete_property = gdk_wayland_window_delete_property; +} |