From 590f3dfa1fcb812e4c334f574c6bb0431b131d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sat, 18 Dec 2010 15:38:49 -0500 Subject: [PATCH 01/42] Add Wayland backend --- Makefile.am | 4 +- configure.ac | 20 +- gdk/Makefile.am | 6 +- gdk/gdkdisplaymanager.c | 9 + gdk/wayland/Makefile.am | 45 + gdk/wayland/gdkapplaunchcontext-wayland.c | 90 ++ gdk/wayland/gdkcursor-wayland.c | 184 +++ gdk/wayland/gdkdevice-wayland.c | 216 ++++ gdk/wayland/gdkdevice-wayland.h | 68 + gdk/wayland/gdkdevicemanager-wayland.c | 443 +++++++ gdk/wayland/gdkdevicemanager-wayland.h | 59 + gdk/wayland/gdkdisplay-wayland.c | 795 ++++++++++++ gdk/wayland/gdkdisplay-wayland.h | 173 +++ gdk/wayland/gdkdisplaymanager-wayland.c | 298 +++++ gdk/wayland/gdkdnd-wayland.c | 190 +++ gdk/wayland/gdkeventsource.c | 167 +++ gdk/wayland/gdkeventsource.h | 44 + gdk/wayland/gdkkeys-wayland.c | 171 +++ gdk/wayland/gdkprivate-wayland.h | 141 ++ gdk/wayland/gdkscreen-wayland.c | 586 +++++++++ gdk/wayland/gdkscreen-wayland.h | 36 + gdk/wayland/gdkselection-wayland.c | 90 ++ gdk/wayland/gdkwayland.h | 38 + gdk/wayland/gdkwindow-wayland.c | 1419 +++++++++++++++++++++ gdk/wayland/gdkwindow-wayland.h | 150 +++ gtk/gtksettings.c | 9 +- 26 files changed, 5444 insertions(+), 7 deletions(-) create mode 100644 gdk/wayland/Makefile.am create mode 100644 gdk/wayland/gdkapplaunchcontext-wayland.c create mode 100644 gdk/wayland/gdkcursor-wayland.c create mode 100644 gdk/wayland/gdkdevice-wayland.c create mode 100644 gdk/wayland/gdkdevice-wayland.h create mode 100644 gdk/wayland/gdkdevicemanager-wayland.c create mode 100644 gdk/wayland/gdkdevicemanager-wayland.h create mode 100644 gdk/wayland/gdkdisplay-wayland.c create mode 100644 gdk/wayland/gdkdisplay-wayland.h create mode 100644 gdk/wayland/gdkdisplaymanager-wayland.c create mode 100644 gdk/wayland/gdkdnd-wayland.c create mode 100644 gdk/wayland/gdkeventsource.c create mode 100644 gdk/wayland/gdkeventsource.h create mode 100644 gdk/wayland/gdkkeys-wayland.c create mode 100644 gdk/wayland/gdkprivate-wayland.h create mode 100644 gdk/wayland/gdkscreen-wayland.c create mode 100644 gdk/wayland/gdkscreen-wayland.h create mode 100644 gdk/wayland/gdkselection-wayland.c create mode 100644 gdk/wayland/gdkwayland.h create mode 100644 gdk/wayland/gdkwindow-wayland.c create mode 100644 gdk/wayland/gdkwindow-wayland.h diff --git a/Makefile.am b/Makefile.am index 382837057f..2c6e77be6f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,11 +55,11 @@ MAINTAINERCLEANFILES = \ ## Copy .pc files to target-specific names -gtk+-x11-3.0.pc gtk+-win32-3.0.pc gtk+-quartz-3.0.pc: gtk+-3.0.pc +gtk+-x11-3.0.pc gtk+-win32-3.0.pc gtk+-quartz-3.0.pc gtk+-wayland-3.0.pc: gtk+-3.0.pc rm -f $@ && \ cp gtk+-3.0.pc $@ -gdk-x11-3.0.pc gdk-win32-3.0.pc gdk-quartz-3.0.pc: gdk-3.0.pc +gdk-x11-3.0.pc gdk-win32-3.0.pc gdk-quartz-3.0.pc gdk-wayland-3.0.pc: gdk-3.0.pc rm -f $@ && \ cp gdk-3.0.pc $@ diff --git a/configure.ac b/configure.ac index 71589c1df2..d33aeec6c2 100644 --- a/configure.ac +++ b/configure.ac @@ -290,6 +290,10 @@ AC_ARG_ENABLE(quartz-backend, [AC_HELP_STRING([--enable-quartz-backend], [enable the quartz gdk backend])], [backend_set=yes]) +AC_ARG_ENABLE(wayland-backend, + [AC_HELP_STRING([--enable-wayland-backend], + [enable the wayland gdk backend])], + [backend_set=yes]) if test -z "$backend_set"; then if test "$platform_win32" = yes; then @@ -345,6 +349,19 @@ else AM_CONDITIONAL(USE_QUARTZ, false) fi +if test "x$enable_wayland_backend" == "xyes"; then + # Wayland uses cairo-gl + cairo_backends="$cairo_backends cairo-gl" + GDK_BACKENDS="$GDK_BACKENDS wayland" + GIO_PACKAGE=gio-unix-2.0 + GDK_WINDOWING="$GDK_WINDOWING +#define GDK_WINDOWING_WAYLAND" + WAYLAND_PACKAGES="wayland-client xkbcommon" + AM_CONDITIONAL(USE_WAYLAND, true) +else + AM_CONDITIONAL(USE_WAYLAND, false) +fi + # strip leading space GDK_BACKENDS=${GDK_BACKENDS/# } @@ -1244,7 +1261,7 @@ fi CFLAGS="$saved_cflags" LDFLAGS="$saved_ldflags" -GDK_PACKAGES="$PANGO_PACKAGES $GIO_PACKAGE $X_PACKAGES gdk-pixbuf-2.0 $cairo_backends cairo-gobject" +GDK_PACKAGES="$PANGO_PACKAGES $GIO_PACKAGE $X_PACKAGES $WAYLAND_PACKAGES gdk-pixbuf-2.0 $cairo_backends cairo-gobject" GDK_DEP_LIBS="$GDK_EXTRA_LIBS `$PKG_CONFIG --libs $GDK_PACKAGES`" GDK_DEP_CFLAGS="`$PKG_CONFIG --cflags gthread-2.0 $GDK_PACKAGES` $GDK_EXTRA_CFLAGS" @@ -1668,6 +1685,7 @@ gdk/win32/Makefile gdk/win32/rc/Makefile gdk/win32/rc/gdk.rc gdk/quartz/Makefile +gdk/wayland/Makefile gdk/tests/Makefile gtk/Makefile gtk/makefile.msc diff --git a/gdk/Makefile.am b/gdk/Makefile.am index f81147e062..91fcbb0531 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -11,7 +11,7 @@ INTROSPECTION_COMPILER_ARGS = \ SUBDIRS = $(GDK_BACKENDS) . tests -DIST_SUBDIRS = win32 x11 quartz tests +DIST_SUBDIRS = win32 x11 quartz wayland tests CLEANFILES = @@ -176,6 +176,10 @@ libgdk_3_0_la_DEPENDENCIES = win32/libgdk-win32.la win32/rc/gdk-win32-res.o gdk. libgdk_3_0_la_LDFLAGS += -Wl,win32/rc/gdk-win32-res.o -export-symbols $(srcdir)/gdk.def endif # USE_WIN32 +if USE_WAYLAND +libgdk_3_0_la_LIBADD += wayland/libgdk-wayland.la +endif + if HAVE_INTROSPECTION introspection_files = \ diff --git a/gdk/gdkdisplaymanager.c b/gdk/gdkdisplaymanager.c index 160404d75c..f5bbc9508b 100644 --- a/gdk/gdkdisplaymanager.c +++ b/gdk/gdkdisplaymanager.c @@ -48,6 +48,10 @@ #include "win32/gdkwin32.h" #endif +#ifdef GDK_WINDOWING_WAYLAND +#include "wayland/gdkwayland.h" +#endif + /** * SECTION:gdkdisplaymanager * @Short_description: Maintains a list of all open GdkDisplays @@ -202,6 +206,11 @@ gdk_display_manager_get (void) if (backend == NULL || strcmp (backend, "win32") == 0) manager = g_object_new (gdk_win32_display_manager_get_type (), NULL); else +#endif +#ifdef GDK_WINDOWING_WAYLAND + if (backend == NULL || strcmp (backend, "wayland") == 0) + manager = g_object_new (gdk_wayland_display_manager_get_type (), NULL); + else #endif if (backend != NULL) g_error ("Unsupported GDK backend: %s", backend); diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am new file mode 100644 index 0000000000..0696483b52 --- /dev/null +++ b/gdk/wayland/Makefile.am @@ -0,0 +1,45 @@ +## Process this file with automake to produce Makefile.in +include $(top_srcdir)/Makefile.decl + +libgdkincludedir = $(includedir)/gtk-3.0/gdk + +INCLUDES = \ + -DG_LOG_DOMAIN=\"Gdk\" \ + -DGDK_COMPILATION \ + -I$(top_srcdir) \ + -I$(top_srcdir)/gdk \ + -I$(top_builddir)/gdk \ + $(GTK_DEBUG_FLAGS) \ + $(GDK_DEP_CFLAGS) + +LDADDS = $(GDK_DEP_LIBS) + +noinst_LTLIBRARIES = \ + libgdk-wayland.la + +libgdk_wayland_la_SOURCES = \ + gdkapplaunchcontext-wayland.c \ + gdkcursor-wayland.c \ + gdkdevice-wayland.h \ + gdkdevice-wayland.c \ + gdkdevicemanager-wayland.h \ + gdkdevicemanager-wayland.c \ + gdkdisplay-wayland.c \ + gdkdisplay-wayland.h \ + gdkdisplaymanager-wayland.c \ + gdkdnd-wayland.c \ + gdkeventsource.c \ + gdkeventsource.h \ + gdkkeys-wayland.c \ + gdkscreen-wayland.c \ + gdkscreen-wayland.h \ + gdkselection-wayland.c \ + gdkwindow-wayland.c \ + gdkwindow-wayland.h \ + gdkwayland.h \ + gdkprivate-wayland.h + +libgdkinclude_HEADERS = \ + gdkwayland.h + +-include $(top_srcdir)/git.mk diff --git a/gdk/wayland/gdkapplaunchcontext-wayland.c b/gdk/wayland/gdkapplaunchcontext-wayland.c new file mode 100644 index 0000000000..1ff2549c79 --- /dev/null +++ b/gdk/wayland/gdkapplaunchcontext-wayland.c @@ -0,0 +1,90 @@ +/* + * 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 +#include + +#include +#include + +#include "gdkwayland.h" +#include "gdkprivate-wayland.h" +#include "gdkapplaunchcontextprivate.h" +#include "gdkscreen.h" +#include "gdkinternals.h" +#include "gdkintl.h" + +static char * +gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context, + GAppInfo *info, + GList *files) +{ + return NULL; +} + +static void +gdk_wayland_app_launch_context_launch_failed (GAppLaunchContext *context, + const char *startup_notify_id) +{ +} + +typedef struct _GdkWaylandAppLaunchContext GdkWaylandAppLaunchContext; +typedef struct _GdkWaylandAppLaunchContextClass GdkWaylandAppLaunchContextClass; + +struct _GdkWaylandAppLaunchContext +{ + GdkAppLaunchContext base; + gchar *name; + guint serial; +}; + +struct _GdkWaylandAppLaunchContextClass +{ + GdkAppLaunchContextClass base_class; +}; + +G_DEFINE_TYPE (GdkWaylandAppLaunchContext, gdk_wayland_app_launch_context, GDK_TYPE_APP_LAUNCH_CONTEXT) + +static void +gdk_wayland_app_launch_context_class_init (GdkWaylandAppLaunchContextClass *klass) +{ + GAppLaunchContextClass *ctx_class = G_APP_LAUNCH_CONTEXT_CLASS (klass); + + ctx_class->get_startup_notify_id = gdk_wayland_app_launch_context_get_startup_notify_id; + ctx_class->launch_failed = gdk_wayland_app_launch_context_launch_failed; +} + +static void +gdk_wayland_app_launch_context_init (GdkWaylandAppLaunchContext *ctx) +{ +} + +GdkAppLaunchContext * +_gdk_wayland_display_get_app_launch_context (GdkDisplay *display) +{ + GdkAppLaunchContext *ctx; + + ctx = g_object_new (gdk_wayland_app_launch_context_get_type (), + "display", display, + NULL); + + return ctx; +} diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c new file mode 100644 index 0000000000..468be5296b --- /dev/null +++ b/gdk/wayland/gdkcursor-wayland.c @@ -0,0 +1,184 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "config.h" + +#define GDK_PIXBUF_ENABLE_BACKEND + +#include + +#include "gdkprivate-wayland.h" +#include "gdkcursorprivate.h" +#include "gdkdisplay-wayland.h" +#include "gdkwayland.h" +#include + +#define GDK_TYPE_WAYLAND_CURSOR (_gdk_wayland_cursor_get_type ()) +#define GDK_WAYLAND_CURSOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursor)) +#define GDK_WAYLAND_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursorClass)) +#define GDK_IS_WAYLAND_CURSOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_CURSOR)) +#define GDK_IS_WAYLAND_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_CURSOR)) +#define GDK_WAYLAND_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursorClass)) + +typedef struct _GdkWaylandCursor GdkWaylandCursor; +typedef struct _GdkWaylandCursorClass GdkWaylandCursorClass; + +struct _GdkWaylandCursor +{ + GdkCursor cursor; + gchar *name; + guint serial; +}; + +struct _GdkWaylandCursorClass +{ + GdkCursorClass cursor_class; +}; + +G_DEFINE_TYPE (GdkWaylandCursor, _gdk_wayland_cursor, GDK_TYPE_CURSOR) + +static guint theme_serial = 0; + +static void +gdk_wayland_cursor_finalize (GObject *object) +{ + GdkWaylandCursor *cursor = GDK_WAYLAND_CURSOR (object); + + g_free (cursor->name); + + G_OBJECT_CLASS (_gdk_wayland_cursor_parent_class)->finalize (object); +} + +static GdkPixbuf* +gdk_wayland_cursor_get_image (GdkCursor *cursor) +{ + return NULL; +} + +static void +_gdk_wayland_cursor_class_init (GdkWaylandCursorClass *wayland_cursor_class) +{ + GdkCursorClass *cursor_class = GDK_CURSOR_CLASS (wayland_cursor_class); + GObjectClass *object_class = G_OBJECT_CLASS (wayland_cursor_class); + + object_class->finalize = gdk_wayland_cursor_finalize; + + cursor_class->get_image = gdk_wayland_cursor_get_image; +} + +static void +_gdk_wayland_cursor_init (GdkWaylandCursor *cursor) +{ +} + +GdkCursor* +_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, + GdkCursorType cursor_type) +{ + GdkWaylandCursor *private; + + private = g_object_new (GDK_TYPE_WAYLAND_CURSOR, + "cursor-type", GDK_CURSOR_IS_PIXMAP, + "display", display, + NULL); + private->name = NULL; + private->serial = theme_serial; + + return GDK_CURSOR (private); +} + +GdkCursor* +_gdk_wayland_display_get_cursor_for_name (GdkDisplay *display, + const gchar *name) +{ + GdkWaylandCursor *private; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + private = g_object_new (GDK_TYPE_WAYLAND_CURSOR, + "cursor-type", GDK_CURSOR_IS_PIXMAP, + "display", display, + NULL); + private->name = g_strdup (name); + private->serial = theme_serial; + + return GDK_CURSOR (private); +} + +GdkCursor * +_gdk_wayland_display_get_cursor_for_pixbuf (GdkDisplay *display, + GdkPixbuf *pixbuf, + gint x, + gint y) +{ + GdkWaylandCursor *private; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + g_return_val_if_fail (0 <= x && x < gdk_pixbuf_get_width (pixbuf), NULL); + g_return_val_if_fail (0 <= y && y < gdk_pixbuf_get_height (pixbuf), NULL); + + private = g_object_new (GDK_TYPE_WAYLAND_CURSOR, + "cursor-type", GDK_CURSOR_IS_PIXMAP, + "display", display, + NULL); + + private->name = NULL; + private->serial = theme_serial; + + return GDK_CURSOR (private); +} + +void +_gdk_wayland_display_get_default_cursor_size (GdkDisplay *display, + guint *width, + guint *height) +{ + /* FIXME: wayland settings? */ + *width = 64; + *height = 64; +} + +void +_gdk_wayland_display_get_maximal_cursor_size (GdkDisplay *display, + guint *width, + guint *height) +{ + *width = 256; + *height = 256; +} + +gboolean +_gdk_wayland_display_supports_cursor_alpha (GdkDisplay *display) +{ + return TRUE; +} + +gboolean +_gdk_wayland_display_supports_cursor_color (GdkDisplay *display) +{ + return TRUE; +} diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c new file mode 100644 index 0000000000..fcdc54bf74 --- /dev/null +++ b/gdk/wayland/gdkdevice-wayland.c @@ -0,0 +1,216 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho + * + * 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 +#include "gdkdevice-wayland.h" +#include "gdkprivate-wayland.h" +#include "gdkwayland.h" + +static gboolean gdk_device_core_get_history (GdkDevice *device, + GdkWindow *window, + guint32 start, + guint32 stop, + GdkTimeCoord ***events, + gint *n_events); +static void gdk_device_core_get_state (GdkDevice *device, + GdkWindow *window, + gdouble *axes, + GdkModifierType *mask); +static void gdk_device_core_set_window_cursor (GdkDevice *device, + GdkWindow *window, + GdkCursor *cursor); +static void gdk_device_core_warp (GdkDevice *device, + GdkScreen *screen, + gint x, + gint y); +static gboolean gdk_device_core_query_state (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, + gint *root_x, + gint *root_y, + gint *win_x, + gint *win_y, + GdkModifierType *mask); +static GdkGrabStatus gdk_device_core_grab (GdkDevice *device, + GdkWindow *window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time_); +static void gdk_device_core_ungrab (GdkDevice *device, + guint32 time_); +static GdkWindow * gdk_device_core_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel); +static void gdk_device_core_select_window_events (GdkDevice *device, + GdkWindow *window, + GdkEventMask event_mask); + + +G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE) + +static void +gdk_device_core_class_init (GdkDeviceCoreClass *klass) +{ + GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + + device_class->get_history = gdk_device_core_get_history; + device_class->get_state = gdk_device_core_get_state; + device_class->set_window_cursor = gdk_device_core_set_window_cursor; + device_class->warp = gdk_device_core_warp; + device_class->query_state = gdk_device_core_query_state; + device_class->grab = gdk_device_core_grab; + device_class->ungrab = gdk_device_core_ungrab; + device_class->window_at_position = gdk_device_core_window_at_position; + device_class->select_window_events = gdk_device_core_select_window_events; +} + +static void +gdk_device_core_init (GdkDeviceCore *device_core) +{ + GdkDevice *device; + + device = GDK_DEVICE (device_core); + + _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1); + _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1); +} + +static gboolean +gdk_device_core_get_history (GdkDevice *device, + GdkWindow *window, + guint32 start, + guint32 stop, + GdkTimeCoord ***events, + gint *n_events) +{ + return FALSE; +} + +static void +gdk_device_core_get_state (GdkDevice *device, + GdkWindow *window, + gdouble *axes, + GdkModifierType *mask) +{ + gint x_int, y_int; + + gdk_window_get_pointer (window, &x_int, &y_int, mask); + + if (axes) + { + axes[0] = x_int; + axes[1] = y_int; + } +} + +static void +gdk_device_core_set_window_cursor (GdkDevice *device, + GdkWindow *window, + GdkCursor *cursor) +{ +} + +static void +gdk_device_core_warp (GdkDevice *device, + GdkScreen *screen, + gint x, + gint y) +{ +} + +static gboolean +gdk_device_core_query_state (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, + gint *root_x, + gint *root_y, + gint *win_x, + gint *win_y, + GdkModifierType *mask) +{ + GdkWaylandDevice *wd; + GdkScreen *default_screen; + + wd = GDK_DEVICE_CORE(device)->device; + default_screen = gdk_display_get_default_screen (wd->display); + + if (root_window) + *root_window = gdk_screen_get_root_window (default_screen); + if (child_window) + *child_window = wd->pointer_focus; + if (root_x) + *root_x = wd->x; + if (root_y) + *root_y = wd->y; + if (win_x) + *win_x = wd->surface_x; + if (win_y) + *win_y = wd->surface_y; + if (mask) + *mask = wd->modifiers; + + return TRUE; +} + +static GdkGrabStatus +gdk_device_core_grab (GdkDevice *device, + GdkWindow *window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time_) +{ + return GDK_GRAB_SUCCESS; +} + +static void +gdk_device_core_ungrab (GdkDevice *device, + guint32 time_) +{ +} + +static GdkWindow * +gdk_device_core_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel) +{ + GdkWaylandDevice *wd; + + wd = GDK_DEVICE_CORE(device)->device; + + return wd->pointer_focus; +} + +static void +gdk_device_core_select_window_events (GdkDevice *device, + GdkWindow *window, + GdkEventMask event_mask) +{ +} diff --git a/gdk/wayland/gdkdevice-wayland.h b/gdk/wayland/gdkdevice-wayland.h new file mode 100644 index 0000000000..88fac43a6e --- /dev/null +++ b/gdk/wayland/gdkdevice-wayland.h @@ -0,0 +1,68 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho + * + * 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. + */ + +#ifndef __GDK_DEVICE_CORE_H__ +#define __GDK_DEVICE_CORE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ()) +#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore)) +#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) +#define GDK_IS_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE)) +#define GDK_IS_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE)) +#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) + +typedef struct _GdkDeviceCore GdkDeviceCore; +typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass; +typedef struct _GdkWaylandDevice GdkWaylandDevice; + +struct _GdkWaylandDevice +{ + GdkDisplay *display; + GdkDevice *pointer; + GdkDevice *keyboard; + GdkModifierType modifiers; + GdkWindow *pointer_focus; + GdkWindow *keyboard_focus; + struct wl_input_device *device; + struct xkb_desc *xkb; + int32_t x, y, surface_x, surface_y; +}; + +struct _GdkDeviceCore +{ + GdkDevice parent_instance; + GdkWaylandDevice *device; +}; + +struct _GdkDeviceCoreClass +{ + GdkDeviceClass parent_class; +}; + +G_GNUC_INTERNAL +GType gdk_device_core_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GDK_DEVICE_CORE_H__ */ diff --git a/gdk/wayland/gdkdevicemanager-wayland.c b/gdk/wayland/gdkdevicemanager-wayland.c new file mode 100644 index 0000000000..c432ec7ea8 --- /dev/null +++ b/gdk/wayland/gdkdevicemanager-wayland.c @@ -0,0 +1,443 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho + * + * 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 +#include +#include +#include "gdkdevicemanager-wayland.h" +#include "gdkdevice-wayland.h" +#include "gdkkeysyms.h" +#include "gdkprivate-wayland.h" +#include "gdkeventsource.h" + + +static void gdk_device_manager_core_finalize (GObject *object); + +static GList * gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, + GdkDeviceType type); +static GdkDevice * gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager); + +G_DEFINE_TYPE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER) + +static void +gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass) +{ + GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_device_manager_core_finalize; + device_manager_class->list_devices = gdk_device_manager_core_list_devices; + device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer; +} + +static void +input_handle_motion(void *data, struct wl_input_device *input_device, + uint32_t time, + int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + event = gdk_event_new (GDK_NOTHING); + + device->x = x; + device->y = y; + device->surface_x = sx; + device->surface_y = sy; + + event->motion.type = GDK_MOTION_NOTIFY; + event->motion.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->motion.time = time; + event->motion.x = (gdouble) sx; + event->motion.y = (gdouble) sy; + event->motion.x_root = (gdouble) x; + event->motion.y_root = (gdouble) y; + event->motion.axes = NULL; + event->motion.state = device->modifiers; + event->motion.is_hint = 0; + + _gdk_wayland_display_deliver_event (device->display, event); +} + +static void +input_handle_button(void *data, struct wl_input_device *input_device, + uint32_t time, uint32_t button, uint32_t state) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + uint32_t modifier; + + fprintf (stderr, "button event %d, state %d\n", button, state); + + event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); + event->button.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->button.time = time; + event->button.x = (gdouble) device->surface_x; + event->button.y = (gdouble) device->surface_y; + event->button.x_root = (gdouble) device->x; + event->button.y_root = (gdouble) device->y; + event->button.axes = NULL; + event->button.state = device->modifiers; + event->button.button = button - 271; + + modifier = 1 << (8 + button - 272); + if (state) + device->modifiers |= modifier; + else + device->modifiers &= ~modifier; + + _gdk_wayland_display_deliver_event (device->display, event); +} + +static void +input_handle_key(void *data, struct wl_input_device *input_device, + uint32_t time, uint32_t key, uint32_t state) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + uint32_t code, modifier, level; + + event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); + event->key.window = g_object_ref (device->keyboard_focus); + gdk_event_set_device (event, device->keyboard); + event->button.time = time; + event->key.state = device->modifiers; + event->key.group = 0; + event->key.hardware_keycode = key; + + code = key + device->xkb->min_key_code; + + level = 0; + if (device->modifiers & ShiftMask && + XkbKeyGroupWidth(device->xkb, code, 0) > 1) + level = 1; + + event->key.keyval = XkbKeySymEntry(device->xkb, code, level, 0); + + modifier = device->xkb->map->modmap[code]; + if (state) + device->modifiers |= modifier; + else + device->modifiers &= ~modifier; + + event->key.is_modifier = modifier > 0; + + if (event->key.keyval == GDK_KEY_Escape) + { + event->key.length = 1; + event->key.string = g_strdup ("\033"); + } + else if (event->key.keyval == GDK_KEY_Return || + event->key.keyval == GDK_KEY_KP_Enter) + { + event->key.length = 1; + event->key.string = g_strdup ("\r"); + } + else if (event->key.state & GDK_CONTROL_MASK) + { + gsize bytes_written; + gint len; + gchar buf[7]; + int c = event->key.keyval; + + /* Apply the control key - Taken from Xlib */ + if ((c >= XK_at && c < '\177') || c == ' ') + c &= 0x1F; + else if (c == XK_2) + { + event->key.string = g_memdup ("\0\0", 2); + event->key.length = 1; + buf[0] = '\0'; + goto out; + } + else if (c >= XK_3 && c <= XK_7) + c -= (XK_3 - '\033'); + else if (c == XK_8) + c = '\177'; + else if (c == XK_slash) + c = '_' & 0x1F; + + len = g_unichar_to_utf8 (c, buf); + buf[len] = '\0'; + + event->key.string = g_locale_from_utf8 (buf, len, + NULL, &bytes_written, + NULL); + if (event->key.string) + event->key.length = bytes_written; + } + else + { + char buffer[128]; + xkb_keysym_to_string(event->key.keyval, buffer, sizeof buffer); + event->key.string = g_strdup (buffer); + event->key.length = strlen(event->key.string); + } + + out: + _gdk_wayland_display_deliver_event (device->display, event); + + fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n", + code, event->key.keyval, event->key.string, event->key.state); +} + +static void +input_handle_pointer_focus(void *data, + struct wl_input_device *input_device, + uint32_t time, struct wl_surface *surface, + int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + if (device->pointer_focus) + { + event = gdk_event_new (GDK_LEAVE_NOTIFY); + event->crossing.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->crossing.subwindow = NULL; + event->crossing.time = time; + event->crossing.x = (gdouble) device->surface_x; + event->crossing.y = (gdouble) device->surface_y; + event->crossing.x_root = (gdouble) device->x; + event->crossing.y_root = (gdouble) device->y; + + event->crossing.mode = GDK_CROSSING_NORMAL; + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + event->crossing.focus = TRUE; + event->crossing.state = 0; + + _gdk_wayland_display_deliver_event (device->display, event); + + g_object_unref(device->pointer_focus); + device->pointer_focus = NULL; + } + + if (surface) + { + device->pointer_focus = wl_surface_get_user_data(surface); + g_object_ref(device->pointer_focus); + + event = gdk_event_new (GDK_ENTER_NOTIFY); + event->crossing.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->crossing.subwindow = NULL; + event->crossing.time = time; + event->crossing.x = (gdouble) sx; + event->crossing.y = (gdouble) sy; + event->crossing.x_root = (gdouble) x; + event->crossing.y_root = (gdouble) y; + + event->crossing.mode = GDK_CROSSING_NORMAL; + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + event->crossing.focus = TRUE; + event->crossing.state = 0; + + device->surface_x = sx; + device->surface_y = sy; + device->x = x; + device->y = y; + + _gdk_wayland_display_deliver_event (device->display, event); + } + + fprintf (stderr, "pointer focus surface %p, window %p\n", + surface, device->pointer_focus); +} + +static void +update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) +{ + uint32_t *k, *end; + + end = keys->data + keys->size; + for (k = keys->data; k < end; k++) + device->modifiers |= device->xkb->map->modmap[*k]; + + fprintf (stderr, "modifiers: 0x%x\n", device->modifiers); +} + +static void +input_handle_keyboard_focus(void *data, + struct wl_input_device *input_device, + uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + fprintf (stderr, "keyboard focus surface %p\n", surface); + + if (device->keyboard_focus) + { + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = g_object_ref (device->keyboard_focus); + event->focus_change.send_event = FALSE; + event->focus_change.in = FALSE; + gdk_event_set_device (event, device->keyboard); + + g_object_unref(device->pointer_focus); + device->keyboard_focus = NULL; + + _gdk_wayland_display_deliver_event (device->display, event); + } + + if (surface) + { + device->keyboard_focus = wl_surface_get_user_data(surface); + g_object_ref(device->keyboard_focus); + + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = g_object_ref (device->keyboard_focus); + event->focus_change.send_event = FALSE; + event->focus_change.in = TRUE; + gdk_event_set_device (event, device->keyboard); + + update_modifiers (device, keys); + + _gdk_wayland_display_deliver_event (device->display, event); + } +} + +static const struct wl_input_device_listener input_device_listener = { + input_handle_motion, + input_handle_button, + input_handle_key, + input_handle_pointer_focus, + input_handle_keyboard_focus, +}; + +void +gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, + struct wl_input_device *wl_device) +{ + GdkDisplay *display; + GdkDeviceManagerCore *device_manager_core = + GDK_DEVICE_MANAGER_CORE(device_manager); + struct xkb_rule_names names; + GdkWaylandDevice *device; + + device = g_new0 (GdkWaylandDevice, 1); + display = gdk_device_manager_get_display (device_manager); + + device->display = display; + device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE, + "name", "Core Pointer", + "type", GDK_DEVICE_TYPE_MASTER, + "input-source", GDK_SOURCE_MOUSE, + "input-mode", GDK_MODE_SCREEN, + "has-cursor", TRUE, + "display", display, + "device-manager", device_manager, + NULL); + + device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE, + "name", "Core Keyboard", + "type", GDK_DEVICE_TYPE_MASTER, + "input-source", GDK_SOURCE_KEYBOARD, + "input-mode", GDK_MODE_SCREEN, + "has-cursor", FALSE, + "display", display, + "device-manager", device_manager, + NULL); + + GDK_DEVICE_CORE (device->pointer)->device = device; + GDK_DEVICE_CORE (device->keyboard)->device = device; + device->device = wl_device; + + names.rules = "evdev"; + names.model = "pc105"; + names.layout = "us"; + names.variant = ""; + names.options = ""; + device->xkb = xkb_compile_keymap_from_rules(&names); + + wl_input_device_add_listener(device->device, + &input_device_listener, device); + + device_manager_core->devices = + g_list_prepend (device_manager_core->devices, device->keyboard); + device_manager_core->devices = + g_list_prepend (device_manager_core->devices, device->pointer); + + _gdk_device_set_associated_device (device->pointer, device->keyboard); + _gdk_device_set_associated_device (device->keyboard, device->pointer); +} + +static void +gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager) +{ +} + +static void +free_device (void *data, void *user_data) +{ + g_object_unref (data); +} + +static void +gdk_device_manager_core_finalize (GObject *object) +{ + GdkDeviceManagerCore *device_manager_core; + + device_manager_core = GDK_DEVICE_MANAGER_CORE (object); + + g_list_foreach (device_manager_core->devices, free_device, NULL); + g_list_free (device_manager_core->devices); + + G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object); +} + +static GList * +gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, + GdkDeviceType type) +{ + GdkDeviceManagerCore *device_manager_core; + GList *devices = NULL; + + if (type == GDK_DEVICE_TYPE_MASTER) + { + device_manager_core = (GdkDeviceManagerCore *) device_manager; + devices = g_list_copy(device_manager_core->devices); + } + + return devices; +} + +static GdkDevice * +gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager) +{ + GdkDeviceManagerCore *device_manager_core; + + device_manager_core = (GdkDeviceManagerCore *) device_manager; + return device_manager_core->devices->data; +} + +GdkDeviceManager * +_gdk_device_manager_new (GdkDisplay *display) +{ + return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE, + "display", display, + NULL); +} diff --git a/gdk/wayland/gdkdevicemanager-wayland.h b/gdk/wayland/gdkdevicemanager-wayland.h new file mode 100644 index 0000000000..83c76e9983 --- /dev/null +++ b/gdk/wayland/gdkdevicemanager-wayland.h @@ -0,0 +1,59 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho + * + * 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. + */ + +#ifndef __GDK_DEVICE_MANAGER_CORE_H__ +#define __GDK_DEVICE_MANAGER_CORE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GDK_TYPE_DEVICE_MANAGER_CORE (gdk_device_manager_core_get_type ()) +#define GDK_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore)) +#define GDK_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) +#define GDK_IS_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE)) +#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE)) +#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) + +typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore; +typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass; + +struct _GdkDeviceManagerCore +{ + GdkDeviceManager parent_object; + GdkDevice *core_pointer; + GdkDevice *core_keyboard; + GList *devices; +}; + +struct _GdkDeviceManagerCoreClass +{ + GdkDeviceManagerClass parent_class; +}; + +GType gdk_device_manager_core_get_type (void) G_GNUC_CONST; + +void +gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, + struct wl_input_device *device); + +G_END_DECLS + +#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */ diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c new file mode 100644 index 0000000000..378fbea135 --- /dev/null +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -0,0 +1,795 @@ +/* + * Copyright © 2010 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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. + */ + +#define EGL_EGLEXT_PROTOTYPES 1 + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include "gdkwayland.h" +#include "gdkdisplay.h" +#include "gdkdisplay-wayland.h" +#include "gdkeventsource.h" +#include "gdkscreen.h" +#include "gdkscreen-wayland.h" +#include "gdkinternals.h" +#include "gdkdeviceprivate.h" +#include "gdkdevicemanager.h" +#include "gdkdevicemanager-wayland.h" +#include "gdkkeysprivate.h" + +#include + +typedef struct _GdkEventTypeWayland GdkEventTypeWayland; + +struct _GdkEventTypeWayland +{ + gint base; + gint n_events; +}; + +G_DEFINE_TYPE (GdkDisplayWayland, _gdk_display_wayland, GDK_TYPE_DISPLAY) + +/* GDK_VISIBILITY, + * GDK_MAP, + * GDK_UNMAP, + * GDK_PROPERTY_NOTIFY + * GDK_SELECTION_CLEAR + * GDK_SELECTION_ REQUEST + * GDK_SELECTION_NOTIFY + * GDK_CLIENT_EVENT, + * + * new keyboard mapping: _gdk_keymap_keys_changed (display); + * + * Selection owner change: GDK_OWNER_CHANGE; + * + * Screen size changes: _gdk_wayland_screen_size_changed (screen, xevent); + * + * XkbStateNotify: _gdk_keymap_state_changed (display, xevent); + */ + +static void +gdk_input_init (GdkDisplay *display) +{ + GdkDisplayWayland *display_wayland; + GdkDeviceManager *device_manager; + GdkDevice *device; + GList *list, *l; + + display_wayland = GDK_DISPLAY_WAYLAND (display); + device_manager = gdk_display_get_device_manager (display); + + /* For backwards compatibility, just add + * floating devices that are not keyboards. + */ + list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING); + + for (l = list; l; l = l->next) + { + device = l->data; + + if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) + continue; + + display_wayland->input_devices = g_list_prepend (display_wayland->input_devices, l->data); + } + + g_list_free (list); + + /* Now set "core" pointer to the first + * master device that is a pointer. + */ + list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER); + + for (l = list; l; l = l->next) + { + device = list->data; + + if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE) + continue; + + display->core_pointer = device; + break; + } + + /* Add the core pointer to the devices list */ + display_wayland->input_devices = g_list_prepend (display_wayland->input_devices, display->core_pointer); + + g_list_free (list); +} + +static void +drm_handle_device(void *data, struct wl_drm *compositor, const char *device) +{ + GdkDisplayWayland *display_wayland = data; + + fprintf(stderr, "display name: %s\n", device); + + display_wayland->device_name = g_strdup (device); +} + +static void drm_handle_authenticated(void *data, struct wl_drm *drm) +{ + GdkDisplayWayland *display_wayland = data; + + display_wayland->authenticated = TRUE; +} + +static const struct wl_drm_listener drm_listener = { + drm_handle_device, + drm_handle_authenticated +}; + +static void +shell_handle_configure(void *data, struct wl_shell *shell, + uint32_t time, uint32_t edges, + struct wl_surface *surface, + int32_t width, int32_t height) +{ + GdkWindow *window; + GdkDisplay *display; + GdkEvent *event; + + window = wl_surface_get_user_data(surface); + + printf("got configure: window %p, %dx%d, edges %d\n", + window, width, height, edges); + + display = gdk_window_get_display (window); + + event = gdk_event_new (GDK_CONFIGURE); + event->configure.window = window; + event->configure.send_event = FALSE; + event->configure.width = width; + event->configure.height = height; + + window->width = width; + window->height = height; + + _gdk_window_update_size (window); + _gdk_wayland_window_update_size (GDK_WINDOW_IMPL_WAYLAND (window->impl)); + + g_object_ref(window); + + _gdk_wayland_display_deliver_event (display, event); +} + +static const struct wl_shell_listener shell_listener = { + shell_handle_configure, +}; + +static void +output_handle_geometry(void *data, + struct wl_output *output, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + /* + g_signal_emit_by_name (screen, "monitors-changed"); + g_signal_emit_by_name (screen, "size-changed"); + */ +} + +static const struct wl_output_listener output_listener = { + output_handle_geometry, +}; + +static void +gdk_display_handle_global(struct wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data) +{ + GdkDisplayWayland *display_wayland = data; + GdkDisplay *gdk_display = GDK_DISPLAY_OBJECT (data); + struct wl_input_device *input; + + if (strcmp(interface, "compositor") == 0) { + display_wayland->compositor = wl_compositor_create(display, id); + } else if (strcmp(interface, "drm") == 0) { + display_wayland->drm = wl_drm_create(display, id); + wl_drm_add_listener(display_wayland->drm, + &drm_listener, display_wayland); + } else if (strcmp(interface, "shell") == 0) { + display_wayland->shell = wl_shell_create(display, id); + wl_shell_add_listener(display_wayland->shell, + &shell_listener, display_wayland); + } else if (strcmp(interface, "output") == 0) { + display_wayland->output = wl_output_create(display, id); + wl_output_add_listener(display_wayland->output, + &output_listener, display_wayland); + } else if (strcmp(interface, "input_device") == 0) { + input = wl_input_device_create(display, id); + gdk_device_manager_core_add_device (gdk_display->device_manager, input); + } +} + +static gboolean +gdk_display_init_egl(GdkDisplay *display) +{ + GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (display); + EGLint major, minor, i; + drm_magic_t magic; + void *p; + + static const struct { const char *f; unsigned int offset; } + extension_functions[] = { + { "eglCreateDRMImageMESA", offsetof(GdkDisplayWayland, create_drm_image) }, + { "glEGLImageTargetTexture2DOES", offsetof(GdkDisplayWayland, image_target_texture_2d) }, + { "eglExportDRMImageMESA", offsetof(GdkDisplayWayland, export_drm_image) }, + { "eglDestroyImageKHR", offsetof(GdkDisplayWayland, destroy_image) } + }; + + display_wayland->fd = open(display_wayland->device_name, O_RDWR); + if (display_wayland->fd < 0) { + fprintf(stderr, "drm open failed: %m\n"); + return FALSE; + } + + if (drmGetMagic(display_wayland->fd, &magic)) + { + fprintf(stderr, "DRI2: failed to get drm magic"); + return FALSE; + } + + /* Authenticate and wait for authenticated event */ + wl_drm_authenticate(display_wayland->drm, magic); + wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_WRITABLE); + while (!display_wayland->authenticated) + wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE); + + display_wayland->egl_display = eglGetDRMDisplayMESA(display_wayland->fd); + if (!eglInitialize(display_wayland->egl_display, &major, &minor)) { + fprintf(stderr, "failed to initialize display\n"); + return FALSE; + } + + eglBindAPI(EGL_OPENGL_API); + + display_wayland->egl_context = + eglCreateContext(display_wayland->egl_display, NULL, EGL_NO_CONTEXT, NULL); + if (display_wayland->egl_context == NULL) { + fprintf(stderr, "failed to create context\n"); + return FALSE; + } + + if (!eglMakeCurrent(display_wayland->egl_display, + NULL, NULL, display_wayland->egl_context)) { + fprintf(stderr, "faile to make context current\n"); + return FALSE; + } + + display_wayland->cairo_device = + cairo_egl_device_create(display_wayland->egl_display, + display_wayland->egl_context); + if (cairo_device_status (display_wayland->cairo_device) != CAIRO_STATUS_SUCCESS) { + fprintf(stderr, "failed to get cairo drm device\n"); + return FALSE; + } + + for (i = 0; i < G_N_ELEMENTS(extension_functions); i++) { + p = eglGetProcAddress(extension_functions[i].f); + *(void **) ((char *) display_wayland + extension_functions[i].offset) = p; + if (p == NULL) { + fprintf(stderr, "failed to look up %s\n", extension_functions[i].f); + return FALSE; + } + } + + fprintf(stderr, "egl initialized\n"); + + return TRUE; +} + +GdkDisplay * +_gdk_wayland_display_open (const gchar *display_name) +{ + struct wl_display *wl_display; + GdkDisplay *display; + GdkDisplayWayland *display_wayland; + GdkWindowAttr attr; + + gint i; + + wl_display = wl_display_connect(display_name); + if (!wl_display) + return NULL; + + display = g_object_new (GDK_TYPE_DISPLAY_WAYLAND, NULL); + display_wayland = GDK_DISPLAY_WAYLAND (display); + + display_wayland->wl_display = wl_display; + + /* initialize the display's screens */ + display_wayland->screens = g_new (GdkScreen *, 1); + for (i = 0; i < 1; i++) + display_wayland->screens[i] = _gdk_wayland_screen_new (display); + + /*set the default screen */ + display_wayland->default_screen = display_wayland->screens[0]; + + display->device_manager = _gdk_device_manager_new (display); + + /* Set up listener so we'll catch all events. */ + wl_display_add_global_listener(display_wayland->wl_display, + gdk_display_handle_global, display_wayland); + + /* Process connection events. */ + wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE); + + gdk_display_init_egl(display); + + display_wayland->event_source = _gdk_wayland_display_event_source_new (display); + + attr.window_type = GDK_WINDOW_TOPLEVEL; + attr.wclass = GDK_INPUT_OUTPUT; + attr.x = 10; + attr.y = 10; + attr.width = 10; + attr.height = 10; + attr.event_mask = 0; + + gdk_input_init (display); + + g_signal_emit_by_name (display, "opened"); + g_signal_emit_by_name (gdk_display_manager_get(), + "display_opened", display); + + return display; +} + +static void +gdk_wayland_display_dispose (GObject *object) +{ + GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (object); + gint i; + + _gdk_wayland_display_manager_remove_display (gdk_display_manager_get (), + GDK_DISPLAY (display_wayland)); + g_list_foreach (display_wayland->input_devices, + (GFunc) g_object_run_dispose, NULL); + + for (i = 0; i < 1; i++) + _gdk_screen_close (display_wayland->screens[i]); + + if (display_wayland->event_source) + { + g_source_destroy (display_wayland->event_source); + g_source_unref (display_wayland->event_source); + display_wayland->event_source = NULL; + } + + G_OBJECT_CLASS (_gdk_display_wayland_parent_class)->dispose (object); +} + +static void +gdk_wayland_display_finalize (GObject *object) +{ + GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (object); + gint i; + + /* Keymap */ + if (display_wayland->keymap) + g_object_unref (display_wayland->keymap); + + /* Atom Hashtable */ + g_hash_table_destroy (display_wayland->atom_from_virtual); + g_hash_table_destroy (display_wayland->atom_to_virtual); + + /* list of filters for client messages */ + g_list_foreach (display_wayland->client_filters, (GFunc) g_free, NULL); + g_list_free (display_wayland->client_filters); + + /* List of event window extraction functions */ + g_slist_foreach (display_wayland->event_types, (GFunc)g_free, NULL); + g_slist_free (display_wayland->event_types); + + /* input GdkDevice list */ + g_list_foreach (display_wayland->input_devices, (GFunc) g_object_unref, NULL); + g_list_free (display_wayland->input_devices); + + /* input GdkWindow list */ + g_list_foreach (display_wayland->input_windows, (GFunc) g_free, NULL); + g_list_free (display_wayland->input_windows); + + /* Free all GdkScreens */ + for (i = 0; i < 1; i++) + g_object_unref (display_wayland->screens[i]); + g_free (display_wayland->screens); + + g_free (display_wayland->startup_notification_id); + + /* X ID hashtable */ + g_hash_table_destroy (display_wayland->xid_ht); + + G_OBJECT_CLASS (_gdk_display_wayland_parent_class)->finalize (object); +} + +static G_CONST_RETURN gchar * +gdk_wayland_display_get_name (GdkDisplay *display) +{ + return "Wayland"; +} + +static gint +gdk_wayland_display_get_n_screens (GdkDisplay *display) +{ + return 1; +} + +static GdkScreen * +gdk_wayland_display_get_screen (GdkDisplay *display, + gint screen_num) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + g_return_val_if_fail (screen_num == 0, NULL); + + return GDK_DISPLAY_WAYLAND (display)->screens[0]; +} + +static GdkScreen * +gdk_wayland_display_get_default_screen (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + return GDK_DISPLAY_WAYLAND (display)->default_screen; +} + +static void +gdk_wayland_display_beep (GdkDisplay *display) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); +} + +static void +sync_callback(void *data) +{ + gboolean *done = data; + + *done = TRUE; +} + +static void +gdk_wayland_display_sync (GdkDisplay *display) +{ + GdkDisplayWayland *display_wayland; + gboolean done; + + g_return_if_fail (GDK_IS_DISPLAY (display)); + + display_wayland = GDK_DISPLAY_WAYLAND (display); + + wl_display_sync_callback(display_wayland->wl_display, sync_callback, &done); + wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_WRITABLE); + while (!done) + wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE); +} + +static void +gdk_wayland_display_flush (GdkDisplay *display) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + if (!display->closed) + wl_display_iterate(GDK_DISPLAY_WAYLAND (display)->wl_display, + WL_DISPLAY_WRITABLE); +} + +static gboolean +gdk_wayland_display_has_pending (GdkDisplay *display) +{ + return FALSE; +} + +static GdkWindow * +gdk_wayland_display_get_default_group (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + return NULL; +} + + +static gboolean +gdk_wayland_display_supports_selection_notification (GdkDisplay *display) +{ + GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (display); + + return display_wayland->have_xfixes; +} + +static gboolean +gdk_wayland_display_request_selection_notification (GdkDisplay *display, + GdkAtom selection) + +{ + return FALSE; +} + +static gboolean +gdk_wayland_display_supports_clipboard_persistence (GdkDisplay *display) +{ + return FALSE; +} + +static void +gdk_wayland_display_store_clipboard (GdkDisplay *display, + GdkWindow *clipboard_window, + guint32 time_, + const GdkAtom *targets, + gint n_targets) +{ +} + +static gboolean +gdk_wayland_display_supports_shapes (GdkDisplay *display) +{ + return GDK_DISPLAY_WAYLAND (display)->have_shapes; +} + +static gboolean +gdk_wayland_display_supports_input_shapes (GdkDisplay *display) +{ + return GDK_DISPLAY_WAYLAND (display)->have_input_shapes; +} + +static gboolean +gdk_wayland_display_supports_composite (GdkDisplay *display) +{ + return TRUE; +} + +static GList * +gdk_wayland_display_list_devices (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + return GDK_DISPLAY_WAYLAND (display)->input_devices; +} + +static gboolean +gdk_wayland_display_send_client_message (GdkDisplay *display, + GdkEvent *event, + GdkNativeWindow winid) +{ + return 0; +} + +static void +gdk_wayland_display_add_client_message_filter (GdkDisplay *display, + GdkAtom message_type, + GdkFilterFunc func, + gpointer data) +{ + GdkClientFilter *filter; + g_return_if_fail (GDK_IS_DISPLAY (display)); + filter = g_new (GdkClientFilter, 1); + + filter->type = message_type; + filter->function = func; + filter->data = data; + + GDK_DISPLAY_WAYLAND(display)->client_filters = + g_list_append (GDK_DISPLAY_WAYLAND (display)->client_filters, + filter); +} + +static void +gdk_wayland_display_before_process_all_updates (GdkDisplay *display) +{ +} + +static void +gdk_wayland_display_after_process_all_updates (GdkDisplay *display) +{ + /* Post the damage here instead? */ +} + +static gulong +gdk_wayland_display_get_next_serial (GdkDisplay *display) +{ + return 0; +} + +void +_gdk_wayland_display_make_default (GdkDisplay *display) +{ +} + +/** + * gdk_wayland_display_broadcast_startup_message: + * @display: a #GdkDisplay + * @message_type: startup notification message type ("new", "change", + * or "remove") + * @...: a list of key/value pairs (as strings), terminated by a + * %NULL key. (A %NULL value for a key will cause that key to be + * skipped in the output.) + * + * Sends a startup notification message of type @message_type to + * @display. + * + * This is a convenience function for use by code that implements the + * freedesktop startup notification specification. Applications should + * not normally need to call it directly. See the Startup + * Notification Protocol specification for + * definitions of the message types and keys that can be used. + * + * Since: 2.12 + **/ +void +gdk_wayland_display_broadcast_startup_message (GdkDisplay *display, + const char *message_type, + ...) +{ + GString *message; + va_list ap; + const char *key, *value, *p; + + message = g_string_new (message_type); + g_string_append_c (message, ':'); + + va_start (ap, message_type); + while ((key = va_arg (ap, const char *))) + { + value = va_arg (ap, const char *); + if (!value) + continue; + + g_string_append_printf (message, " %s=\"", key); + for (p = value; *p; p++) + { + switch (*p) + { + case ' ': + case '"': + case '\\': + g_string_append_c (message, '\\'); + break; + } + + g_string_append_c (message, *p); + } + g_string_append_c (message, '\"'); + } + va_end (ap); + + printf ("startup message: %s\n", message->str); + + g_string_free (message, TRUE); +} + +static void +gdk_wayland_display_notify_startup_complete (GdkDisplay *display, + const gchar *startup_id) +{ + gdk_wayland_display_broadcast_startup_message (display, "remove", + "ID", startup_id, + NULL); +} + +static void +gdk_wayland_display_event_data_copy (GdkDisplay *display, + const GdkEvent *src, + GdkEvent *dst) +{ +} + +static void +gdk_wayland_display_event_data_free (GdkDisplay *display, + GdkEvent *event) +{ +} + +static GdkKeymap * +gdk_wayland_display_get_keymap (GdkDisplay *display) +{ + GdkDisplayWayland *display_wayland; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + display_wayland = GDK_DISPLAY_WAYLAND (display); + + if (!display_wayland->keymap) + display_wayland->keymap = + g_object_new (_gdk_wayland_keymap_get_type(), NULL); + + display_wayland->keymap->display = display; + + return display_wayland->keymap; +} + +static void +gdk_wayland_display_push_error_trap (GdkDisplay *display) +{ +} + +static gint +gdk_wayland_display_pop_error_trap (GdkDisplay *display, + gboolean ignored) +{ + return 0; +} + +static void +_gdk_display_wayland_class_init (GdkDisplayWaylandClass * class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (class); + + object_class->dispose = gdk_wayland_display_dispose; + object_class->finalize = gdk_wayland_display_finalize; + + display_class->window_type = _gdk_wayland_window_get_type (); + display_class->get_name = gdk_wayland_display_get_name; + display_class->get_n_screens = gdk_wayland_display_get_n_screens; + display_class->get_screen = gdk_wayland_display_get_screen; + display_class->get_default_screen = gdk_wayland_display_get_default_screen; + display_class->beep = gdk_wayland_display_beep; + display_class->sync = gdk_wayland_display_sync; + display_class->flush = gdk_wayland_display_flush; + display_class->has_pending = gdk_wayland_display_has_pending; + display_class->queue_events = _gdk_wayland_display_queue_events; + display_class->get_default_group = gdk_wayland_display_get_default_group; + display_class->supports_selection_notification = gdk_wayland_display_supports_selection_notification; + display_class->request_selection_notification = gdk_wayland_display_request_selection_notification; + display_class->supports_clipboard_persistence = gdk_wayland_display_supports_clipboard_persistence; + display_class->store_clipboard = gdk_wayland_display_store_clipboard; + display_class->supports_shapes = gdk_wayland_display_supports_shapes; + display_class->supports_input_shapes = gdk_wayland_display_supports_input_shapes; + display_class->supports_composite = gdk_wayland_display_supports_composite; + display_class->list_devices = gdk_wayland_display_list_devices; + display_class->send_client_message = gdk_wayland_display_send_client_message; + display_class->add_client_message_filter = gdk_wayland_display_add_client_message_filter; + display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context; + display_class->get_drag_protocol = _gdk_wayland_display_get_drag_protocol; + display_class->get_cursor_for_type = _gdk_wayland_display_get_cursor_for_type; + display_class->get_cursor_for_name = _gdk_wayland_display_get_cursor_for_name; + display_class->get_cursor_for_pixbuf = _gdk_wayland_display_get_cursor_for_pixbuf; + display_class->get_default_cursor_size = _gdk_wayland_display_get_default_cursor_size; + display_class->get_maximal_cursor_size = _gdk_wayland_display_get_maximal_cursor_size; + display_class->supports_cursor_alpha = _gdk_wayland_display_supports_cursor_alpha; + display_class->supports_cursor_color = _gdk_wayland_display_supports_cursor_color; + display_class->before_process_all_updates = gdk_wayland_display_before_process_all_updates; + display_class->after_process_all_updates = gdk_wayland_display_after_process_all_updates; + display_class->get_next_serial = gdk_wayland_display_get_next_serial; + display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete; + display_class->event_data_copy = gdk_wayland_display_event_data_copy; + display_class->event_data_free = gdk_wayland_display_event_data_free; + display_class->create_window_impl = _gdk_wayland_display_create_window_impl; + display_class->get_keymap = gdk_wayland_display_get_keymap; + display_class->push_error_trap = gdk_wayland_display_push_error_trap; + display_class->pop_error_trap = gdk_wayland_display_pop_error_trap; + display_class->get_selection_owner = _gdk_wayland_display_get_selection_owner; + display_class->set_selection_owner = _gdk_wayland_display_set_selection_owner; + display_class->send_selection_notify = _gdk_wayland_display_send_selection_notify; + display_class->get_selection_property = _gdk_wayland_display_get_selection_property; + display_class->convert_selection = _gdk_wayland_display_convert_selection; + display_class->text_property_to_utf8_list = _gdk_wayland_display_text_property_to_utf8_list; + display_class->utf8_to_string_target = _gdk_wayland_display_utf8_to_string_target; +} + +static void +_gdk_display_wayland_init (GdkDisplayWayland *display) +{ + _gdk_wayland_display_manager_add_display (gdk_display_manager_get (), + GDK_DISPLAY (display)); +} diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h new file mode 100644 index 0000000000..d9dceaa195 --- /dev/null +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -0,0 +1,173 @@ +/* + * gdkdisplay-wayland.h + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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. + */ + +#ifndef __GDK_DISPLAY_WAYLAND__ +#define __GDK_DISPLAY_WAYLAND__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For gdk_get_program_class() */ + +#include "gdkdisplayprivate.h" + +G_BEGIN_DECLS + +typedef struct _GdkDisplayWayland GdkDisplayWayland; +typedef struct _GdkDisplayWaylandClass GdkDisplayWaylandClass; + +#define GDK_TYPE_DISPLAY_WAYLAND (_gdk_display_wayland_get_type()) +#define GDK_DISPLAY_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY_WAYLAND, GdkDisplayWayland)) +#define GDK_DISPLAY_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DISPLAY_WAYLAND, GdkDisplayWaylandClass)) +#define GDK_IS_DISPLAY_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DISPLAY_WAYLAND)) +#define GDK_IS_DISPLAY_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY_WAYLAND)) +#define GDK_DISPLAY_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY_WAYLAND, GdkDisplayWaylandClass)) + +struct _GdkDisplayWayland +{ + GdkDisplay parent_instance; + GdkScreen *default_screen; + GdkScreen **screens; + + gint grab_count; + + /* Keyboard related information */ + + gint xkb_event_type; + gboolean use_xkb; + + /* Whether we were able to turn on detectable-autorepeat using + * XkbSetDetectableAutorepeat. If FALSE, we'll fall back + * to checking the next event with XPending(). */ + gboolean have_xkb_autorepeat; + + GdkKeymap *keymap; + guint keymap_serial; + + gboolean have_xfixes; + gint xfixes_event_base; + + gboolean have_xcomposite; + gboolean have_xdamage; + gint xdamage_event_base; + + gboolean have_randr13; + gint xrandr_event_base; + + /* If the SECURITY extension is in place, whether this client holds + * a trusted authorization and so is allowed to make various requests + * (grabs, properties etc.) Otherwise always TRUE. */ + gboolean trusted_client; + + /* drag and drop information */ + GdkDragContext *current_dest_drag; + + /* data needed for MOTIF DnD */ + + Window motif_drag_window; + GdkWindow *motif_drag_gdk_window; + GList **motif_target_lists; + gint motif_n_target_lists; + + /* Mapping to/from virtual atoms */ + + GHashTable *atom_from_virtual; + GHashTable *atom_to_virtual; + + /* list of filters for client messages */ + GList *client_filters; + + /* List of functions to go from extension event => X window */ + GSList *event_types; + + /* X ID hashtable */ + GHashTable *xid_ht; + + /* translation queue */ + GQueue *translate_queue; + + /* Input device */ + /* input GdkDevice list */ + GList *input_devices; + + /* input GdkWindow list */ + GList *input_windows; + + /* Startup notification */ + gchar *startup_notification_id; + + /* Time of most recent user interaction. */ + gulong user_time; + + /* Sets of atoms for DND */ + guint base_dnd_atoms_precached : 1; + guint xdnd_atoms_precached : 1; + guint motif_atoms_precached : 1; + guint use_sync : 1; + + guint have_shapes : 1; + guint have_input_shapes : 1; + gint shape_event_base; + + /* The offscreen window that has the pointer in it (if any) */ + GdkWindow *active_offscreen_window; + + /* Wayland fields below */ + char *device_name; + struct wl_display *wl_display; + struct wl_drm *drm; + struct wl_compositor *compositor; + struct wl_shell *shell; + struct wl_output *output; + struct wl_input_device *input_device; + GSource *event_source; + int fd; + EGLDisplay egl_display; + EGLContext egl_context; + cairo_device_t *cairo_device; + int authenticated; + + PFNEGLCREATEDRMIMAGEMESA create_drm_image; + PFNEGLEXPORTDRMIMAGEMESA export_drm_image; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; + PFNEGLDESTROYIMAGEKHRPROC destroy_image; +}; + +struct _GdkDisplayWaylandClass +{ + GdkDisplayClass parent_class; +}; + +GType _gdk_display_wayland_get_type (void); +GdkScreen *_gdk_wayland_display_screen_for_xrootwin (GdkDisplay *display, + Window xrootwin); + +G_END_DECLS + +#endif /* __GDK_DISPLAY_WAYLAND__ */ diff --git a/gdk/wayland/gdkdisplaymanager-wayland.c b/gdk/wayland/gdkdisplaymanager-wayland.c new file mode 100644 index 0000000000..1b48014cdf --- /dev/null +++ b/gdk/wayland/gdkdisplaymanager-wayland.c @@ -0,0 +1,298 @@ +/* GDK - The GIMP Drawing Kit + * gdkdisplaymanager-wayland.c + * + * Copyright 2010 Red Hat, Inc. + * + * Author: Matthias clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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 "gdkdisplaymanagerprivate.h" +#include "gdkdisplay-wayland.h" +#include "gdkprivate-wayland.h" + +#include "gdkinternals.h" + +typedef struct _GdkWaylandDisplayManager GdkWaylandDisplayManager; +typedef struct _GdkWaylandDisplayManagerClass GdkWaylandDisplayManagerClass; + +#define GDK_TYPE_WAYLAND_DISPLAY_MANAGER (gdk_wayland_display_manager_get_type()) +#define GDK_WAYLAND_DISPLAY_MANAGER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_DISPLAY_MANAGER, GdkWaylandDisplayManager)) +#define GDK_WAYLAND_DISPLAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_DISPLAY_MANAGER, GdkWaylandDisplayManagerClass)) +#define GDK_IS_WAYLAND_DISPLAY_MANAGER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DISPLAY_MANAGER)) +#define GDK_IS_WAYLAND_DISPLAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_DISPLAY_MANAGER)) +#define GDK_WAYLAND_DISPLAY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_DISPLAY_MANAGER, GdkWaylandDisplayManagerClass)) + +struct _GdkWaylandDisplayManager +{ + GdkDisplayManager parent; + + GdkDisplay *default_display; + GSList *displays; +}; + +struct _GdkWaylandDisplayManagerClass +{ + GdkDisplayManagerClass parent_class; +}; + +G_DEFINE_TYPE (GdkWaylandDisplayManager, gdk_wayland_display_manager, GDK_TYPE_DISPLAY_MANAGER) + +static void +gdk_wayland_display_manager_finalize (GObject *object) +{ + g_error ("A GdkWaylandDisplayManager object was finalized. This should not happen"); + G_OBJECT_CLASS (gdk_wayland_display_manager_parent_class)->finalize (object); +} + +static GdkDisplay * +gdk_wayland_display_manager_open_display (GdkDisplayManager *manager, + const gchar *name) +{ + return _gdk_wayland_display_open (name); +} + +static GSList * +gdk_wayland_display_manager_list_displays (GdkDisplayManager *manager) +{ + return g_slist_copy (GDK_WAYLAND_DISPLAY_MANAGER (manager)->displays); +} + +static void +gdk_wayland_display_manager_set_default_display (GdkDisplayManager *manager, + GdkDisplay *display) +{ + GDK_WAYLAND_DISPLAY_MANAGER (manager)->default_display = display; + + _gdk_wayland_display_make_default (display); +} + +static GdkDisplay * +gdk_wayland_display_manager_get_default_display (GdkDisplayManager *manager) +{ + return GDK_WAYLAND_DISPLAY_MANAGER (manager)->default_display; +} + +static GdkAtom +gdk_wayland_display_manager_atom_intern (GdkDisplayManager *manager, + const gchar *atom_name, + gboolean dup) +{ + return 0; +} + +static gchar * +gdk_wayland_display_manager_get_atom_name (GdkDisplayManager *manager, + GdkAtom atom) +{ + return 0; +} + +static guint +gdk_wayland_display_manager_lookup_keyval (GdkDisplayManager *manager, + const gchar *keyval_name) +{ + return /* XStringToKeysym (keyval_name); */ 0; +} + +static gchar * +gdk_wayland_display_manager_get_keyval_name (GdkDisplayManager *manager, + guint keyval) +{ + return NULL; +} + +static void +gdk_wayland_display_manager_keyval_convert_case (GdkDisplayManager *manager, + guint symbol, + guint *lower, + guint *upper) +{ + guint xlower = symbol; + guint xupper = symbol; + + /* Check for directly encoded 24-bit UCS characters: */ + if ((symbol & 0xff000000) == 0x01000000) + { + if (lower) + *lower = gdk_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff)); + if (upper) + *upper = gdk_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff)); + return; + } + + switch (symbol >> 8) + { + case 0: /* Latin 1 */ + if ((symbol >= GDK_KEY_A) && (symbol <= GDK_KEY_Z)) + xlower += (GDK_KEY_a - GDK_KEY_A); + else if ((symbol >= GDK_KEY_a) && (symbol <= GDK_KEY_z)) + xupper -= (GDK_KEY_a - GDK_KEY_A); + else if ((symbol >= GDK_KEY_Agrave) && (symbol <= GDK_KEY_Odiaeresis)) + xlower += (GDK_KEY_agrave - GDK_KEY_Agrave); + else if ((symbol >= GDK_KEY_agrave) && (symbol <= GDK_KEY_odiaeresis)) + xupper -= (GDK_KEY_agrave - GDK_KEY_Agrave); + else if ((symbol >= GDK_KEY_Ooblique) && (symbol <= GDK_KEY_Thorn)) + xlower += (GDK_KEY_oslash - GDK_KEY_Ooblique); + else if ((symbol >= GDK_KEY_oslash) && (symbol <= GDK_KEY_thorn)) + xupper -= (GDK_KEY_oslash - GDK_KEY_Ooblique); + break; + + case 1: /* Latin 2 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol == GDK_KEY_Aogonek) + xlower = GDK_KEY_aogonek; + else if (symbol >= GDK_KEY_Lstroke && symbol <= GDK_KEY_Sacute) + xlower += (GDK_KEY_lstroke - GDK_KEY_Lstroke); + else if (symbol >= GDK_KEY_Scaron && symbol <= GDK_KEY_Zacute) + xlower += (GDK_KEY_scaron - GDK_KEY_Scaron); + else if (symbol >= GDK_KEY_Zcaron && symbol <= GDK_KEY_Zabovedot) + xlower += (GDK_KEY_zcaron - GDK_KEY_Zcaron); + else if (symbol == GDK_KEY_aogonek) + xupper = GDK_KEY_Aogonek; + else if (symbol >= GDK_KEY_lstroke && symbol <= GDK_KEY_sacute) + xupper -= (GDK_KEY_lstroke - GDK_KEY_Lstroke); + else if (symbol >= GDK_KEY_scaron && symbol <= GDK_KEY_zacute) + xupper -= (GDK_KEY_scaron - GDK_KEY_Scaron); + else if (symbol >= GDK_KEY_zcaron && symbol <= GDK_KEY_zabovedot) + xupper -= (GDK_KEY_zcaron - GDK_KEY_Zcaron); + else if (symbol >= GDK_KEY_Racute && symbol <= GDK_KEY_Tcedilla) + xlower += (GDK_KEY_racute - GDK_KEY_Racute); + else if (symbol >= GDK_KEY_racute && symbol <= GDK_KEY_tcedilla) + xupper -= (GDK_KEY_racute - GDK_KEY_Racute); + break; + + case 2: /* Latin 3 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_KEY_Hstroke && symbol <= GDK_KEY_Hcircumflex) + xlower += (GDK_KEY_hstroke - GDK_KEY_Hstroke); + else if (symbol >= GDK_KEY_Gbreve && symbol <= GDK_KEY_Jcircumflex) + xlower += (GDK_KEY_gbreve - GDK_KEY_Gbreve); + else if (symbol >= GDK_KEY_hstroke && symbol <= GDK_KEY_hcircumflex) + xupper -= (GDK_KEY_hstroke - GDK_KEY_Hstroke); + else if (symbol >= GDK_KEY_gbreve && symbol <= GDK_KEY_jcircumflex) + xupper -= (GDK_KEY_gbreve - GDK_KEY_Gbreve); + else if (symbol >= GDK_KEY_Cabovedot && symbol <= GDK_KEY_Scircumflex) + xlower += (GDK_KEY_cabovedot - GDK_KEY_Cabovedot); + else if (symbol >= GDK_KEY_cabovedot && symbol <= GDK_KEY_scircumflex) + xupper -= (GDK_KEY_cabovedot - GDK_KEY_Cabovedot); + break; + + case 3: /* Latin 4 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_KEY_Rcedilla && symbol <= GDK_KEY_Tslash) + xlower += (GDK_KEY_rcedilla - GDK_KEY_Rcedilla); + else if (symbol >= GDK_KEY_rcedilla && symbol <= GDK_KEY_tslash) + xupper -= (GDK_KEY_rcedilla - GDK_KEY_Rcedilla); + else if (symbol == GDK_KEY_ENG) + xlower = GDK_KEY_eng; + else if (symbol == GDK_KEY_eng) + xupper = GDK_KEY_ENG; + else if (symbol >= GDK_KEY_Amacron && symbol <= GDK_KEY_Umacron) + xlower += (GDK_KEY_amacron - GDK_KEY_Amacron); + else if (symbol >= GDK_KEY_amacron && symbol <= GDK_KEY_umacron) + xupper -= (GDK_KEY_amacron - GDK_KEY_Amacron); + break; + + case 6: /* Cyrillic */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_KEY_Serbian_DJE && symbol <= GDK_KEY_Serbian_DZE) + xlower -= (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje); + else if (symbol >= GDK_KEY_Serbian_dje && symbol <= GDK_KEY_Serbian_dze) + xupper += (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje); + else if (symbol >= GDK_KEY_Cyrillic_YU && symbol <= GDK_KEY_Cyrillic_HARDSIGN) + xlower -= (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu); + else if (symbol >= GDK_KEY_Cyrillic_yu && symbol <= GDK_KEY_Cyrillic_hardsign) + xupper += (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu); + break; + + case 7: /* Greek */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_KEY_Greek_ALPHAaccent && symbol <= GDK_KEY_Greek_OMEGAaccent) + xlower += (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent); + else if (symbol >= GDK_KEY_Greek_alphaaccent && symbol <= GDK_KEY_Greek_omegaaccent && + symbol != GDK_KEY_Greek_iotaaccentdieresis && + symbol != GDK_KEY_Greek_upsilonaccentdieresis) + xupper -= (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent); + else if (symbol >= GDK_KEY_Greek_ALPHA && symbol <= GDK_KEY_Greek_OMEGA) + xlower += (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA); + else if (symbol >= GDK_KEY_Greek_alpha && symbol <= GDK_KEY_Greek_omega && + symbol != GDK_KEY_Greek_finalsmallsigma) + xupper -= (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA); + break; + } + + if (lower) + *lower = xlower; + if (upper) + *upper = xupper; +} + +static void +gdk_wayland_display_manager_class_init (GdkWaylandDisplayManagerClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GdkDisplayManagerClass *manager_class = GDK_DISPLAY_MANAGER_CLASS (class); + + object_class->finalize = gdk_wayland_display_manager_finalize; + + manager_class->open_display = gdk_wayland_display_manager_open_display; + manager_class->list_displays = gdk_wayland_display_manager_list_displays; + manager_class->set_default_display = gdk_wayland_display_manager_set_default_display; + manager_class->get_default_display = gdk_wayland_display_manager_get_default_display; + manager_class->atom_intern = gdk_wayland_display_manager_atom_intern; + manager_class->get_atom_name = gdk_wayland_display_manager_get_atom_name; + manager_class->lookup_keyval = gdk_wayland_display_manager_lookup_keyval; + manager_class->get_keyval_name = gdk_wayland_display_manager_get_keyval_name; + manager_class->keyval_convert_case = gdk_wayland_display_manager_keyval_convert_case; +} + +static void +gdk_wayland_display_manager_init (GdkWaylandDisplayManager *manager) +{ +} + +void +_gdk_wayland_display_manager_add_display (GdkDisplayManager *manager, + GdkDisplay *display) +{ + GdkWaylandDisplayManager *manager_wayland = GDK_WAYLAND_DISPLAY_MANAGER (manager); + + if (manager_wayland->displays == NULL) + gdk_display_manager_set_default_display (manager, display); + + manager_wayland->displays = g_slist_prepend (manager_wayland->displays, display); +} + +void +_gdk_wayland_display_manager_remove_display (GdkDisplayManager *manager, + GdkDisplay *display) +{ + GdkWaylandDisplayManager *manager_wayland = GDK_WAYLAND_DISPLAY_MANAGER (manager); + + manager_wayland->displays = g_slist_remove (manager_wayland->displays, display); + + if (manager_wayland->default_display == display) + { + if (manager_wayland->displays) + gdk_display_manager_set_default_display (manager, manager_wayland->displays->data); + else + gdk_display_manager_set_default_display (manager, NULL); + } +} diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c new file mode 100644 index 0000000000..1d36e95732 --- /dev/null +++ b/gdk/wayland/gdkdnd-wayland.c @@ -0,0 +1,190 @@ +/* + * Copyright © 2010 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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 "gdkdndprivate.h" + +#include "gdkmain.h" +#include "gdkinternals.h" +#include "gdkproperty.h" +#include "gdkprivate-wayland.h" +#include "gdkscreen-wayland.h" +#include "gdkdisplay-wayland.h" + +#include + +#define GDK_TYPE_WAYLAND_DRAG_CONTEXT (gdk_wayland_drag_context_get_type ()) +#define GDK_WAYLAND_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_DRAG_CONTEXT, GdkWaylandDragContext)) +#define GDK_WAYLAND_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_DRAG_CONTEXT, GdkWaylandDragContextClass)) +#define GDK_IS_WAYLAND_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DRAG_CONTEXT)) +#define GDK_IS_WAYLAND_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_DRAG_CONTEXT)) +#define GDK_WAYLAND_DRAG_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_DRAG_CONTEXT, GdkWaylandDragContextClass)) + +typedef struct _GdkWaylandDragContext GdkWaylandDragContext; +typedef struct _GdkWaylandDragContextClass GdkWaylandDragContextClass; + +struct _GdkWaylandDragContext +{ + GdkDragContext context; +}; + +struct _GdkWaylandDragContextClass +{ + GdkDragContextClass parent_class; +}; + +static GList *contexts; + +G_DEFINE_TYPE (GdkWaylandDragContext, gdk_wayland_drag_context, GDK_TYPE_DRAG_CONTEXT) + +static void +gdk_wayland_drag_context_finalize (GObject *object) +{ + GdkDragContext *context = GDK_DRAG_CONTEXT (object); + + contexts = g_list_remove (contexts, context); + + G_OBJECT_CLASS (gdk_wayland_drag_context_parent_class)->finalize (object); +} + +static GdkWindow * +gdk_wayland_drag_context_find_window (GdkDragContext *context, + GdkWindow *drag_window, + GdkScreen *screen, + gint x_root, + gint y_root, + GdkDragProtocol *protocol) +{ + return NULL; +} + +static gboolean +gdk_wayland_drag_context_drag_motion (GdkDragContext *context, + GdkWindow *dest_window, + GdkDragProtocol protocol, + gint x_root, + gint y_root, + GdkDragAction suggested_action, + GdkDragAction possible_actions, + guint32 time) +{ + return FALSE; +} + +static void +gdk_wayland_drag_context_drag_abort (GdkDragContext *context, + guint32 time) +{ +} + +static void +gdk_wayland_drag_context_drag_drop (GdkDragContext *context, + guint32 time) +{ +} + +/* Destination side */ + +static void +gdk_wayland_drag_context_drag_status (GdkDragContext *context, + GdkDragAction action, + guint32 time_) +{ +} + +static void +gdk_wayland_drag_context_drop_reply (GdkDragContext *context, + gboolean accepted, + guint32 time_) +{ +} + +static void +gdk_wayland_drag_context_drop_finish (GdkDragContext *context, + gboolean success, + guint32 time) +{ +} + +static gboolean +gdk_wayland_drag_context_drop_status (GdkDragContext *context) +{ + return FALSE; +} + +static GdkAtom +gdk_wayland_drag_context_get_selection (GdkDragContext *context) +{ + return GDK_NONE; +} + +static void +gdk_wayland_drag_context_init (GdkWaylandDragContext *context) +{ + contexts = g_list_prepend (contexts, context); +} + +static void +gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkDragContextClass *context_class = GDK_DRAG_CONTEXT_CLASS (klass); + + object_class->finalize = gdk_wayland_drag_context_finalize; + + context_class->find_window = gdk_wayland_drag_context_find_window; + context_class->drag_status = gdk_wayland_drag_context_drag_status; + context_class->drag_motion = gdk_wayland_drag_context_drag_motion; + context_class->drag_abort = gdk_wayland_drag_context_drag_abort; + context_class->drag_drop = gdk_wayland_drag_context_drag_drop; + context_class->drop_reply = gdk_wayland_drag_context_drop_reply; + context_class->drop_finish = gdk_wayland_drag_context_drop_finish; + context_class->drop_status = gdk_wayland_drag_context_drop_status; + context_class->get_selection = gdk_wayland_drag_context_get_selection; +} + +GdkNativeWindow +_gdk_wayland_display_get_drag_protocol (GdkDisplay *display, + GdkNativeWindow xid, + GdkDragProtocol *protocol, + guint *version) + +{ + return 0; +} + +void +_gdk_wayland_window_register_dnd (GdkWindow *window) +{ +} + +GdkDragContext * +_gdk_wayland_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GList *targets) +{ + GdkDragContext *context; + + context = (GdkDragContext *) g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT, NULL); + + gdk_drag_context_set_device (context, device); + + return context; +} diff --git a/gdk/wayland/gdkeventsource.c b/gdk/wayland/gdkeventsource.c new file mode 100644 index 0000000000..12c9118201 --- /dev/null +++ b/gdk/wayland/gdkeventsource.c @@ -0,0 +1,167 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho + * + * 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 "gdkeventsource.h" +#include "gdkinternals.h" + +typedef struct _GdkWaylandEventSource { + GSource source; + GPollFD pfd; + uint32_t mask; + GdkDisplay *display; +} GdkWaylandEventSource; + +static GList *event_sources = NULL; + +static gboolean +gdk_event_source_prepare(GSource *base, gint *timeout) +{ + GdkWaylandEventSource *source = (GdkWaylandEventSource *) base; + GdkDisplayWayland *display = (GdkDisplayWayland *) source->display; + + *timeout = -1; + + /* We have to add/remove the GPollFD if we want to update our + * poll event mask dynamically. Instead, let's just flush all + * write on idle instead, which is what this amounts to. */ + + if (_gdk_event_queue_find_first (source->display) != NULL) + return TRUE; + + while (source->mask & WL_DISPLAY_WRITABLE) + wl_display_iterate(display->wl_display, WL_DISPLAY_WRITABLE); + + return FALSE; +} + +static gboolean +gdk_event_source_check(GSource *base) +{ + GdkWaylandEventSource *source = (GdkWaylandEventSource *) base; + + return _gdk_event_queue_find_first (source->display) != NULL || + source->pfd.revents; +} + +static gboolean +gdk_event_source_dispatch(GSource *base, + GSourceFunc callback, + gpointer data) +{ + GdkWaylandEventSource *source = (GdkWaylandEventSource *) base; + GdkDisplay *display = source->display; + GdkEvent *event; + + GDK_THREADS_ENTER (); + + event = gdk_display_get_event (display); + + if (event) + { + _gdk_event_emit (event); + + gdk_event_free (event); + } + + GDK_THREADS_LEAVE (); + + return TRUE; +} + +static void +gdk_event_source_finalize (GSource *source) +{ + event_sources = g_list_remove (event_sources, source); +} + +static GSourceFuncs wl_glib_source_funcs = { + gdk_event_source_prepare, + gdk_event_source_check, + gdk_event_source_dispatch, + gdk_event_source_finalize +}; + +static int +gdk_event_source_update(uint32_t mask, void *data) +{ + GdkWaylandEventSource *source = data; + + source->mask = mask; + + return 0; +} + +void +_gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event) +{ + GList *node; + static int serial; + + node = _gdk_event_queue_append (display, event); + _gdk_windowing_got_event (display, node, event, serial++); +} + +GSource * +_gdk_wayland_display_event_source_new (GdkDisplay *display) +{ + GSource *source; + GdkWaylandEventSource *wl_source; + GdkDisplayWayland *display_wayland; + char *name; + + source = g_source_new (&wl_glib_source_funcs, + sizeof (GdkWaylandEventSource)); + name = g_strdup_printf ("GDK Wayland Event source (%s)", "display name"); + g_source_set_name (source, name); + g_free (name); + wl_source = (GdkWaylandEventSource *) source; + + display_wayland = GDK_DISPLAY_WAYLAND (display); + wl_source->display = display; + wl_source->pfd.fd = wl_display_get_fd(display_wayland->wl_display, + gdk_event_source_update, source); + wl_source->pfd.events = G_IO_IN | G_IO_ERR; + g_source_add_poll(source, &wl_source->pfd); + + g_source_set_priority (source, GDK_PRIORITY_EVENTS); + g_source_set_can_recurse (source, TRUE); + g_source_attach (source, NULL); + + event_sources = g_list_prepend (event_sources, source); + + return source; +} + +void +_gdk_wayland_display_queue_events (GdkDisplay *display) +{ + GdkDisplayWayland *display_wayland; + GdkWaylandEventSource *source; + + display_wayland = GDK_DISPLAY_WAYLAND (display); + source = (GdkWaylandEventSource *) display_wayland->event_source; + + if (source->pfd.revents) + { + wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE); + source->pfd.revents = 0; + } +} diff --git a/gdk/wayland/gdkeventsource.h b/gdk/wayland/gdkeventsource.h new file mode 100644 index 0000000000..65a7ca3e78 --- /dev/null +++ b/gdk/wayland/gdkeventsource.h @@ -0,0 +1,44 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho + * + * 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. + */ + +#ifndef __GDK_EVENT_SOURCE_H__ +#define __GDK_EVENT_SOURCE_H__ + +#include "gdkprivate-wayland.h" + +G_BEGIN_DECLS + +typedef struct _GdkEventSource GdkEventSource; + +G_GNUC_INTERNAL +GSource * gdk_event_source_new (GdkDisplay *display); + +G_GNUC_INTERNAL +void gdk_event_source_select_events (GdkEventSource *source, + Window window, + GdkEventMask event_mask, + unsigned int extra_x_mask); + +G_GNUC_INTERNAL +void _gdk_deliver_event (GdkDisplay *display, GdkEvent *event); + + +G_END_DECLS + +#endif /* __GDK_EVENT_SOURCE_H__ */ diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c new file mode 100644 index 0000000000..87b139814a --- /dev/null +++ b/gdk/wayland/gdkkeys-wayland.c @@ -0,0 +1,171 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2000 Red Hat, Inc. + * + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "gdk.h" +#include "gdkwayland.h" + +#include "gdkprivate-wayland.h" +#include "gdkinternals.h" +#include "gdkdisplay-wayland.h" +#include "gdkkeysprivate.h" + +#include + +typedef struct _GdkWaylandKeymap GdkWaylandKeymap; +typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass; + +struct _GdkWaylandKeymap +{ + GdkKeymap parent_instance; +}; + +struct _GdkWaylandKeymapClass +{ + GdkKeymapClass parent_class; +}; + +#define GDK_TYPE_WAYLAND_KEYMAP (_gdk_wayland_keymap_get_type ()) +#define GDK_WAYLAND_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_KEYMAP, GdkWaylandKeyMap)) +#define GDK_IS_WAYLAND_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_KEYMAP)) + +G_DEFINE_TYPE (GdkWaylandKeymap, _gdk_wayland_keymap, GDK_TYPE_KEYMAP) + +static void +gdk_wayland_keymap_finalize (GObject *object) +{ + G_OBJECT_CLASS (_gdk_wayland_keymap_parent_class)->finalize (object); +} + +static PangoDirection +gdk_wayland_keymap_get_direction (GdkKeymap *keymap) +{ + return PANGO_DIRECTION_NEUTRAL; +} + +static gboolean +gdk_wayland_keymap_have_bidi_layouts (GdkKeymap *keymap) +{ + return FALSE; +} + +static gboolean +gdk_wayland_keymap_get_caps_lock_state (GdkKeymap *keymap) +{ + return FALSE; +} + +static gboolean +gdk_wayland_keymap_get_num_lock_state (GdkKeymap *keymap) +{ + return FALSE; +} + +static gboolean +gdk_wayland_keymap_get_entries_for_keyval (GdkKeymap *keymap, + guint keyval, + GdkKeymapKey **keys, + gint *n_keys) +{ + return FALSE; +} + +static gboolean +gdk_wayland_keymap_get_entries_for_keycode (GdkKeymap *keymap, + guint hardware_keycode, + GdkKeymapKey **keys, + guint **keyvals, + gint *n_entries) +{ + return FALSE; +} + +static guint +gdk_wayland_keymap_lookup_key (GdkKeymap *keymap, + const GdkKeymapKey *key) +{ + return 0; +} + +static gboolean +gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, + guint hardware_keycode, + GdkModifierType state, + gint group, + guint *keyval, + gint *effective_group, + gint *level, + GdkModifierType *consumed_modifiers) +{ + return FALSE; +} + + +static void +gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap, + GdkModifierType *state) +{ +} + +static gboolean +gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap, + GdkModifierType *state) +{ + return FALSE; +} + +static void +_gdk_wayland_keymap_class_init (GdkWaylandKeymapClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass); + + object_class->finalize = gdk_wayland_keymap_finalize; + + keymap_class->get_direction = gdk_wayland_keymap_get_direction; + keymap_class->have_bidi_layouts = gdk_wayland_keymap_have_bidi_layouts; + keymap_class->get_caps_lock_state = gdk_wayland_keymap_get_caps_lock_state; + keymap_class->get_num_lock_state = gdk_wayland_keymap_get_num_lock_state; + keymap_class->get_entries_for_keyval = gdk_wayland_keymap_get_entries_for_keyval; + keymap_class->get_entries_for_keycode = gdk_wayland_keymap_get_entries_for_keycode; + keymap_class->lookup_key = gdk_wayland_keymap_lookup_key; + keymap_class->translate_keyboard_state = gdk_wayland_keymap_translate_keyboard_state; + keymap_class->add_virtual_modifiers = gdk_wayland_keymap_add_virtual_modifiers; + keymap_class->map_virtual_modifiers = gdk_wayland_keymap_map_virtual_modifiers; +} + +static void +_gdk_wayland_keymap_init (GdkWaylandKeymap *keymap) +{ +} diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h new file mode 100644 index 0000000000..fa3b27861e --- /dev/null +++ b/gdk/wayland/gdkprivate-wayland.h @@ -0,0 +1,141 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * Private uninstalled header defining things local to X windowing code + */ + +#ifndef __GDK_PRIVATE_WAYLAND_H__ +#define __GDK_PRIVATE_WAYLAND_H__ + +#include +#include +#include +#include + +#include "gdkinternals.h" + +#include "config.h" + +#define GDK_SCREEN_DISPLAY(screen) (GDK_SCREEN_WAYLAND (screen)->display) +#define GDK_WINDOW_SCREEN(win) (gdk_window_get_screen (win)) +#define GDK_WINDOW_DISPLAY(win) (GDK_SCREEN_WAYLAND (GDK_WINDOW_SCREEN (win))->display) +#define GDK_WINDOW_IS_WAYLAND(win) (GDK_IS_WINDOW_IMPL_WAYLAND (((GdkWindow *)win)->impl)) + +GType _gdk_wayland_window_get_type (void); +GType _gdk_wayland_keymap_get_type (void); + +GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, + GdkCursorType cursor_type); +GdkCursor *_gdk_wayland_display_get_cursor_for_name (GdkDisplay *display, + const gchar *name); +GdkCursor *_gdk_wayland_display_get_cursor_for_pixbuf (GdkDisplay *display, + GdkPixbuf *pixbuf, + gint x, + gint y); +void _gdk_wayland_display_get_default_cursor_size (GdkDisplay *display, + guint *width, + guint *height); +void _gdk_wayland_display_get_maximal_cursor_size (GdkDisplay *display, + guint *width, + guint *height); +gboolean _gdk_wayland_display_supports_cursor_alpha (GdkDisplay *display); +gboolean _gdk_wayland_display_supports_cursor_color (GdkDisplay *display); + +GdkNativeWindow _gdk_wayland_display_get_drag_protocol (GdkDisplay *display, + GdkNativeWindow xid, + GdkDragProtocol *protocol, + guint *version); +void _gdk_wayland_window_register_dnd (GdkWindow *window); +GdkDragContext *_gdk_wayland_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GList *targets); + +void _gdk_wayland_display_create_window_impl (GdkDisplay *display, + GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask); + +GdkKeymap *_gdk_wayland_display_get_keymap (GdkDisplay *display); + +GdkWindow *_gdk_wayland_display_get_selection_owner (GdkDisplay *display, + GdkAtom selection); +gboolean _gdk_wayland_display_set_selection_owner (GdkDisplay *display, + GdkWindow *owner, + GdkAtom selection, + guint32 time, + gboolean send_event); +void _gdk_wayland_display_send_selection_notify (GdkDisplay *display, + GdkNativeWindow requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time); +gint _gdk_wayland_display_get_selection_property (GdkDisplay *display, + GdkWindow *requestor, + guchar **data, + GdkAtom *ret_type, + gint *ret_format); +void _gdk_wayland_display_convert_selection (GdkDisplay *display, + GdkWindow *requestor, + GdkAtom selection, + GdkAtom target, + guint32 time); +gint _gdk_wayland_display_text_property_to_utf8_list (GdkDisplay *display, + GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list); +gchar * _gdk_wayland_display_utf8_to_string_target (GdkDisplay *display, + const gchar *str); + +GdkDeviceManager *_gdk_device_manager_new (GdkDisplay *display); + +void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event); +GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display); +void _gdk_wayland_display_queue_events (GdkDisplay *display); + +GdkAppLaunchContext *_gdk_wayland_display_get_app_launch_context (GdkDisplay *display); + +GdkDisplay *_gdk_wayland_display_open (const gchar *display_name); +void _gdk_wayland_display_make_default (GdkDisplay *display); + +GdkWindow *_gdk_wayland_screen_create_root_window (GdkScreen *screen, + int width, + int height); + +GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display); + +void _gdk_wayland_display_manager_add_display (GdkDisplayManager *manager, + GdkDisplay *display); +void _gdk_wayland_display_manager_remove_display (GdkDisplayManager *manager, + GdkDisplay *display); + +#endif /* __GDK_PRIVATE_WAYLAND_H__ */ diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c new file mode 100644 index 0000000000..09adafbb63 --- /dev/null +++ b/gdk/wayland/gdkscreen-wayland.c @@ -0,0 +1,586 @@ +/* + * Copyright © 2010 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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 +#include + +#include +#include "gdkscreenprivate.h" +#include "gdkvisualprivate.h" +#include "gdkdisplay.h" +#include "gdkdisplay-wayland.h" +#include "gdkwayland.h" +#include "gdkprivate-wayland.h" + +typedef struct _GdkScreenWayland GdkScreenWayland; +typedef struct _GdkScreenWaylandClass GdkScreenWaylandClass; + +#define GDK_TYPE_SCREEN_WAYLAND (_gdk_screen_wayland_get_type ()) +#define GDK_SCREEN_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN_WAYLAND, GdkScreenWayland)) +#define GDK_SCREEN_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN_WAYLAND, GdkScreenWaylandClass)) +#define GDK_IS_SCREEN_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SCREEN_WAYLAND)) +#define GDK_IS_SCREEN_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN_WAYLAND)) +#define GDK_SCREEN_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN_WAYLAND, GdkScreenWaylandClass)) + +typedef struct _GdkWaylandMonitor GdkWaylandMonitor; + +struct _GdkScreenWayland +{ + GdkScreen parent_instance; + + GdkDisplay *display; + GdkWindow *root_window; + + int width, height; + int width_mm, height_mm; + + /* Window manager */ + long last_wmspec_check_time; + Window wmspec_check_window; + char *window_manager_name; + /* TRUE if wmspec_check_window has changed since last + * fetch of _NET_SUPPORTED + */ + guint need_refetch_net_supported : 1; + /* TRUE if wmspec_check_window has changed since last + * fetch of window manager name + */ + guint need_refetch_wm_name : 1; + + /* Visual Part */ + GdkVisual *argb_visual; + GdkVisual *premultiplied_argb_visual; + GdkVisual *rgb_visual; + + /* Xinerama/RandR 1.2 */ + gint n_monitors; + GdkWaylandMonitor *monitors; + gint primary_monitor; + + /* Xft resources for the display, used for default values for + * the Xft/ XSETTINGS + */ + gboolean xft_init; /* Whether we've intialized these values yet */ + gboolean xft_antialias; + gboolean xft_hinting; + gint xft_hintstyle; + gint xft_rgba; + gint xft_dpi; + + GdkAtom cm_selection_atom; + gboolean is_composited; +}; + +struct _GdkScreenWaylandClass +{ + GdkScreenClass parent_class; + + void (* window_manager_changed) (GdkScreenWayland *screen_wayland); +}; + +struct _GdkWaylandMonitor +{ + GdkRectangle geometry; + XID output; + int width_mm; + int height_mm; + char * output_name; + char * manufacturer; +}; + +G_DEFINE_TYPE (GdkScreenWayland, _gdk_screen_wayland, GDK_TYPE_SCREEN) + +static void +init_monitor_geometry (GdkWaylandMonitor *monitor, + int x, int y, int width, int height) +{ + monitor->geometry.x = x; + monitor->geometry.y = y; + monitor->geometry.width = width; + monitor->geometry.height = height; + + monitor->output = None; + monitor->width_mm = -1; + monitor->height_mm = -1; + monitor->output_name = NULL; + monitor->manufacturer = NULL; +} + +static void +free_monitors (GdkWaylandMonitor *monitors, + gint n_monitors) +{ + int i; + + for (i = 0; i < n_monitors; ++i) + { + g_free (monitors[i].output_name); + g_free (monitors[i].manufacturer); + } + + g_free (monitors); +} + +static void +deinit_multihead (GdkScreen *screen) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen); + + free_monitors (screen_wayland->monitors, screen_wayland->n_monitors); + + screen_wayland->n_monitors = 0; + screen_wayland->monitors = NULL; +} + +static void +init_multihead (GdkScreen *screen) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen); + + /* No multihead support of any kind for this screen */ + screen_wayland->n_monitors = 1; + screen_wayland->monitors = g_new0 (GdkWaylandMonitor, 1); + screen_wayland->primary_monitor = 0; + + init_monitor_geometry (screen_wayland->monitors, 0, 0, + screen_wayland->width, screen_wayland->height); +} + +static void +gdk_wayland_screen_dispose (GObject *object) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (object); + + if (screen_wayland->root_window) + _gdk_window_destroy (screen_wayland->root_window, TRUE); + + G_OBJECT_CLASS (_gdk_screen_wayland_parent_class)->dispose (object); + + screen_wayland->wmspec_check_window = None; +} + +static void +gdk_wayland_screen_finalize (GObject *object) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (object); + + if (screen_wayland->root_window) + g_object_unref (screen_wayland->root_window); + + /* Visual Part */ + g_object_unref (screen_wayland->argb_visual); + g_object_unref (screen_wayland->premultiplied_argb_visual); + g_object_unref (screen_wayland->rgb_visual); + + g_free (screen_wayland->window_manager_name); + + deinit_multihead (GDK_SCREEN (object)); + + G_OBJECT_CLASS (_gdk_screen_wayland_parent_class)->finalize (object); +} + +static GdkDisplay * +gdk_wayland_screen_get_display (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return GDK_SCREEN_WAYLAND (screen)->display; +} + +static gint +gdk_wayland_screen_get_width (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_WAYLAND (screen)->width; +} + +static gint +gdk_wayland_screen_get_height (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_WAYLAND (screen)->height; +} + +static gint +gdk_wayland_screen_get_width_mm (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_WAYLAND (screen)->width_mm; +} + +static gint +gdk_wayland_screen_get_height_mm (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_WAYLAND (screen)->height_mm; +} + +static gint +gdk_wayland_screen_get_number (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return 0; +} + +static GdkWindow * +gdk_wayland_screen_get_root_window (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return GDK_SCREEN_WAYLAND (screen)->root_window; +} + +static gint +gdk_wayland_screen_get_n_monitors (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_WAYLAND (screen)->n_monitors; +} + +static gint +gdk_wayland_screen_get_primary_monitor (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_WAYLAND (screen)->primary_monitor; +} + +static gint +gdk_wayland_screen_get_monitor_width_mm (GdkScreen *screen, + gint monitor_num) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen); + + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); + g_return_val_if_fail (monitor_num >= 0, -1); + g_return_val_if_fail (monitor_num < screen_wayland->n_monitors, -1); + + return screen_wayland->monitors[monitor_num].width_mm; +} + +static gint +gdk_wayland_screen_get_monitor_height_mm (GdkScreen *screen, + gint monitor_num) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen); + + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); + g_return_val_if_fail (monitor_num >= 0, -1); + g_return_val_if_fail (monitor_num < screen_wayland->n_monitors, -1); + + return screen_wayland->monitors[monitor_num].height_mm; +} + +static gchar * +gdk_wayland_screen_get_monitor_plug_name (GdkScreen *screen, + gint monitor_num) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen); + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + g_return_val_if_fail (monitor_num >= 0, NULL); + g_return_val_if_fail (monitor_num < screen_wayland->n_monitors, NULL); + + return g_strdup (screen_wayland->monitors[monitor_num].output_name); +} + +static void +gdk_wayland_screen_get_monitor_geometry (GdkScreen *screen, + gint monitor_num, + GdkRectangle *dest) +{ + GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen); + + g_return_if_fail (GDK_IS_SCREEN (screen)); + g_return_if_fail (monitor_num >= 0); + g_return_if_fail (monitor_num < screen_wayland->n_monitors); + + if (dest) + *dest = screen_wayland->monitors[monitor_num].geometry; +} + +static GdkVisual * +gdk_wayland_screen_get_system_visual (GdkScreen * screen) +{ + return (GdkVisual *) GDK_SCREEN_WAYLAND (screen)->argb_visual; +} + +static GdkVisual * +gdk_wayland_screen_get_rgba_visual (GdkScreen *screen) +{ + return (GdkVisual *) GDK_SCREEN_WAYLAND (screen)->argb_visual; +} + +static gboolean +gdk_wayland_screen_is_composited (GdkScreen *screen) +{ + return TRUE; +} + +static gchar * +gdk_wayland_screen_make_display_name (GdkScreen *screen) +{ + return NULL; +} + +static GdkWindow * +gdk_wayland_screen_get_active_window (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return NULL; +} + +static GList * +gdk_wayland_screen_get_window_stack (GdkScreen *screen) +{ + return NULL; +} + +static void +gdk_wayland_screen_broadcast_client_message (GdkScreen *screen, + GdkEvent *event) +{ +} + +static gboolean +gdk_wayland_screen_get_setting (GdkScreen *screen, + const gchar *name, + GValue *value) +{ + return FALSE; +} + +typedef struct _GdkWaylandVisual GdkWaylandVisual; +typedef struct _GdkWaylandVisualClass GdkWaylandVisualClass; + +struct _GdkWaylandVisual +{ + GdkVisual visual; + struct wl_visual *wl_visual; +}; + +struct _GdkWaylandVisualClass +{ + GdkVisualClass parent_class; +}; + +G_DEFINE_TYPE (GdkWaylandVisual, _gdk_wayland_visual, GDK_TYPE_VISUAL) + +static void +_gdk_wayland_visual_class_init (GdkWaylandVisualClass *klass) +{ +} + +static void +_gdk_wayland_visual_init (GdkWaylandVisual *visual) +{ +} + +static gint +gdk_wayland_screen_visual_get_best_depth (GdkScreen *screen) +{ + return 32; +} + +static GdkVisualType +gdk_wayland_screen_visual_get_best_type (GdkScreen *screen) +{ + return GDK_VISUAL_TRUE_COLOR; +} + +static GdkVisual* +gdk_wayland_screen_visual_get_best (GdkScreen *screen) +{ + return GDK_SCREEN_WAYLAND (screen)->argb_visual; +} + +static GdkVisual* +gdk_wayland_screen_visual_get_best_with_depth (GdkScreen *screen, + gint depth) +{ + return GDK_SCREEN_WAYLAND (screen)->argb_visual; +} + +static GdkVisual* +gdk_wayland_screen_visual_get_best_with_type (GdkScreen *screen, + GdkVisualType visual_type) +{ + return GDK_SCREEN_WAYLAND (screen)->argb_visual; +} + +static GdkVisual* +gdk_wayland_screen_visual_get_best_with_both (GdkScreen *screen, + gint depth, + GdkVisualType visual_type) +{ + return GDK_SCREEN_WAYLAND (screen)->argb_visual; +} + +static void +gdk_wayland_screen_query_depths (GdkScreen *screen, + gint **depths, + gint *count) +{ + static gint static_depths[] = { 32 }; + + *count = G_N_ELEMENTS(static_depths); + *depths = static_depths; +} + +static void +gdk_wayland_screen_query_visual_types (GdkScreen *screen, + GdkVisualType **visual_types, + gint *count) +{ + static GdkVisualType static_visual_types[] = { GDK_VISUAL_TRUE_COLOR }; + + *count = G_N_ELEMENTS(static_visual_types); + *visual_types = static_visual_types; +} + +static GList * +gdk_wayland_screen_list_visuals (GdkScreen *screen) +{ + GList *list; + GdkScreenWayland *screen_wayland; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + screen_wayland = GDK_SCREEN_WAYLAND (screen); + + list = g_list_append (NULL, screen_wayland->argb_visual); + list = g_list_append (NULL, screen_wayland->premultiplied_argb_visual); + list = g_list_append (NULL, screen_wayland->rgb_visual); + + return list; +} + +#define GDK_TYPE_WAYLAND_VISUAL (_gdk_wayland_visual_get_type ()) +#define GDK_WAYLAND_VISUAL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_VISUAL, GdkWaylandVisual)) + +static GdkVisual * +gdk_wayland_visual_new (GdkScreen *screen, struct wl_visual *wl_visual) +{ + GdkVisual *visual; + + visual = g_object_new (GDK_TYPE_WAYLAND_VISUAL, NULL); + visual->screen = GDK_SCREEN (screen); + visual->type = GDK_VISUAL_TRUE_COLOR; + visual->depth = 32; + + GDK_WAYLAND_VISUAL (visual)->wl_visual = wl_visual; + + return visual; +} + +GdkScreen * +_gdk_wayland_screen_new (GdkDisplay *display) +{ + GdkScreen *screen; + GdkScreenWayland *screen_wayland; + GdkDisplayWayland *display_wayland; + struct wl_visual *visual; + + display_wayland = GDK_DISPLAY_WAYLAND (display); + + screen = g_object_new (GDK_TYPE_SCREEN_WAYLAND, NULL); + + screen_wayland = GDK_SCREEN_WAYLAND (screen); + screen_wayland->display = display; + screen_wayland->wmspec_check_window = None; + /* we want this to be always non-null */ + screen_wayland->window_manager_name = g_strdup ("unknown"); + + screen_wayland->width = 8192; + screen_wayland->height = 8192; + + visual = wl_display_get_argb_visual(display_wayland->wl_display); + screen_wayland->argb_visual = gdk_wayland_visual_new (screen, visual); + + visual = + wl_display_get_premultiplied_argb_visual(display_wayland->wl_display); + screen_wayland->premultiplied_argb_visual = + gdk_wayland_visual_new (screen, visual); + + visual = wl_display_get_rgb_visual(display_wayland->wl_display); + screen_wayland->rgb_visual = gdk_wayland_visual_new (screen, visual); + + screen_wayland->root_window = + _gdk_wayland_screen_create_root_window (screen, + screen_wayland->width, + screen_wayland->height); + + init_multihead (screen); + + return screen; +} + +static void +_gdk_screen_wayland_class_init (GdkScreenWaylandClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass); + + object_class->dispose = gdk_wayland_screen_dispose; + object_class->finalize = gdk_wayland_screen_finalize; + + screen_class->get_display = gdk_wayland_screen_get_display; + screen_class->get_width = gdk_wayland_screen_get_width; + screen_class->get_height = gdk_wayland_screen_get_height; + screen_class->get_width_mm = gdk_wayland_screen_get_width_mm; + screen_class->get_height_mm = gdk_wayland_screen_get_height_mm; + screen_class->get_number = gdk_wayland_screen_get_number; + screen_class->get_root_window = gdk_wayland_screen_get_root_window; + screen_class->get_n_monitors = gdk_wayland_screen_get_n_monitors; + screen_class->get_primary_monitor = gdk_wayland_screen_get_primary_monitor; + screen_class->get_monitor_width_mm = gdk_wayland_screen_get_monitor_width_mm; + screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm; + screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name; + screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry; + screen_class->get_system_visual = gdk_wayland_screen_get_system_visual; + screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual; + screen_class->is_composited = gdk_wayland_screen_is_composited; + screen_class->make_display_name = gdk_wayland_screen_make_display_name; + screen_class->get_active_window = gdk_wayland_screen_get_active_window; + screen_class->get_window_stack = gdk_wayland_screen_get_window_stack; + screen_class->broadcast_client_message = gdk_wayland_screen_broadcast_client_message; + screen_class->get_setting = gdk_wayland_screen_get_setting; + screen_class->visual_get_best_depth = gdk_wayland_screen_visual_get_best_depth; + screen_class->visual_get_best_type = gdk_wayland_screen_visual_get_best_type; + screen_class->visual_get_best = gdk_wayland_screen_visual_get_best; + screen_class->visual_get_best_with_depth = gdk_wayland_screen_visual_get_best_with_depth; + screen_class->visual_get_best_with_type = gdk_wayland_screen_visual_get_best_with_type; + screen_class->visual_get_best_with_both = gdk_wayland_screen_visual_get_best_with_both; + screen_class->query_depths = gdk_wayland_screen_query_depths; + screen_class->query_visual_types = gdk_wayland_screen_query_visual_types; + screen_class->list_visuals = gdk_wayland_screen_list_visuals; +} + +static void +_gdk_screen_wayland_init (GdkScreenWayland *screen_wayland) +{ +} diff --git a/gdk/wayland/gdkscreen-wayland.h b/gdk/wayland/gdkscreen-wayland.h new file mode 100644 index 0000000000..9fa4baab81 --- /dev/null +++ b/gdk/wayland/gdkscreen-wayland.h @@ -0,0 +1,36 @@ +/* + * gdkscreen-wayland.h + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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. + */ + +#ifndef __GDK_SCREEN_WAYLAND_H__ +#define __GDK_SCREEN_WAYLAND_H__ + +#include "gdkprivate-wayland.h" +#include +#include + +G_BEGIN_DECLS + + +G_END_DECLS + +#endif /* __GDK_SCREEN_WAYLAND_H__ */ diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c new file mode 100644 index 0000000000..f2f4b2f1a6 --- /dev/null +++ b/gdk/wayland/gdkselection-wayland.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2010 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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 "gdkselection.h" +#include "gdkproperty.h" +#include "gdkprivate.h" + +#include + +GdkWindow * +_gdk_wayland_display_get_selection_owner (GdkDisplay *display, + GdkAtom selection) +{ + return NULL; +} + +gboolean +_gdk_wayland_display_set_selection_owner (GdkDisplay *display, + GdkWindow *owner, + GdkAtom selection, + guint32 time, + gboolean send_event) +{ + return FALSE; +} + +void +_gdk_wayland_display_send_selection_notify (GdkDisplay *display, + GdkNativeWindow requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time) +{ +} + +gint +_gdk_wayland_display_get_selection_property (GdkDisplay *display, + GdkWindow *requestor, + guchar **data, + GdkAtom *ret_type, + gint *ret_format) +{ + return 0; +} + +void +_gdk_wayland_display_convert_selection (GdkDisplay *display, + GdkWindow *requestor, + GdkAtom selection, + GdkAtom target, + guint32 time) +{ +} + +gint +_gdk_wayland_display_text_property_to_utf8_list (GdkDisplay *display, + GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) +{ + return 0; +} + +gchar * +_gdk_wayland_display_utf8_to_string_target (GdkDisplay *display, + const gchar *str) +{ + return NULL; +} diff --git a/gdk/wayland/gdkwayland.h b/gdk/wayland/gdkwayland.h new file mode 100644 index 0000000000..c9e9f6e14d --- /dev/null +++ b/gdk/wayland/gdkwayland.h @@ -0,0 +1,38 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GDK_WAYLAND_H__ +#define __GDK_WAYLAND_H__ + +#include + +G_BEGIN_DECLS + +GType gdk_wayland_display_manager_get_type (void); + +G_END_DECLS + +#endif /* __GDK_WAYLAND_H__ */ 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 +#include + +#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 +#include +#include + +#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; +} diff --git a/gdk/wayland/gdkwindow-wayland.h b/gdk/wayland/gdkwindow-wayland.h new file mode 100644 index 0000000000..f33afdf504 --- /dev/null +++ b/gdk/wayland/gdkwindow-wayland.h @@ -0,0 +1,150 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GDK_WINDOW_WAYLAND_H__ +#define __GDK_WINDOW_WAYLAND_H__ + +#include +#include + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _GdkToplevelWayland GdkToplevelWayland; +typedef struct _GdkWindowImplWayland GdkWindowImplWayland; +typedef struct _GdkWindowImplWaylandClass GdkWindowImplWaylandClass; +typedef struct _GdkXPositionInfo GdkXPositionInfo; + +/* Window implementation for Wayland + */ + +#define GDK_TYPE_WINDOW_IMPL_WAYLAND (_gdk_window_impl_wayland_get_type ()) +#define GDK_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWayland)) +#define GDK_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass)) +#define GDK_IS_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND)) +#define GDK_IS_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND)) +#define GDK_WINDOW_IMPL_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass)) + +struct _GdkWindowImplWayland +{ + GdkWindowImpl parent_instance; + + GdkWindow *wrapper; + + GdkToplevelWayland *toplevel; /* Toplevel-specific information */ + GdkCursor *cursor; + GHashTable *device_cursor; + + gint8 toplevel_window_type; + guint no_bg : 1; /* Set when the window background is temporarily + * unset during resizing and scaling */ + guint override_redirect : 1; + + struct wl_surface *surface; + EGLImageKHR *pending_image; + EGLImageKHR *next_image; + + cairo_surface_t *cairo_surface; + GLuint texture; + EGLImageKHR image; + +}; + +struct _GdkWindowImplWaylandClass +{ + GdkWindowImplClass parent_class; +}; + +struct _GdkToplevelWayland +{ + + /* Set if the window, or any descendent of it, is the server's focus window + */ + guint has_focus_window : 1; + + /* Set if window->has_focus_window and the focus isn't grabbed elsewhere. + */ + guint has_focus : 1; + + /* Set if the pointer is inside this window. (This is needed for + * for focus tracking) + */ + guint has_pointer : 1; + + /* Set if the window is a descendent of the focus window and the pointer is + * inside it. (This is the case where the window will receive keystroke + * events even window->has_focus_window is FALSE) + */ + guint has_pointer_focus : 1; + + /* Set if we are requesting these hints */ + guint skip_taskbar_hint : 1; + guint skip_pager_hint : 1; + guint urgency_hint : 1; + + guint on_all_desktops : 1; /* _NET_WM_STICKY == 0xFFFFFFFF */ + + guint have_sticky : 1; /* _NET_WM_STATE_STICKY */ + guint have_maxvert : 1; /* _NET_WM_STATE_MAXIMIZED_VERT */ + guint have_maxhorz : 1; /* _NET_WM_STATE_MAXIMIZED_HORZ */ + guint have_fullscreen : 1; /* _NET_WM_STATE_FULLSCREEN */ + + gulong map_serial; /* Serial of last transition from unmapped */ + + cairo_surface_t *icon_pixmap; + cairo_surface_t *icon_mask; + + /* Time of most recent user interaction. */ + gulong user_time; + + /* We use an extra X window for toplevel windows that we XSetInputFocus() + * to in order to avoid getting keyboard events redirected to subwindows + * that might not even be part of this app + */ + Window focus_window; +}; + +GType _gdk_window_impl_wayland_get_type (void); + +GdkToplevelWayland *_gdk_wayland_window_get_toplevel (GdkWindow *window); +void _gdk_wayland_window_attach_image (GdkWindow *window, + EGLImageKHR image); + +GdkCursor *_gdk_wayland_window_get_cursor (GdkWindow *window); +void _gdk_wayland_window_get_offsets (GdkWindow *window, + gint *x_offset, + gint *y_offset); + +void _gdk_wayland_window_update_size (GdkWindowImplWayland *drawable); + +G_END_DECLS + +#endif /* __GDK_WINDOW_WAYLAND_H__ */ diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index 44fe5c68ca..771f6e0fde 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -1466,9 +1466,12 @@ gtk_settings_get_for_screen (GdkScreen *screen) settings_init_style (settings); settings_update_double_click (settings); #ifdef GDK_WINDOWING_X11 - settings_update_cursor_theme (settings); - settings_update_resolution (settings); - settings_update_font_options (settings); + if (GDK_IS_X11_SCREEN (screen)) + { + settings_update_cursor_theme (settings); + settings_update_resolution (settings); + settings_update_font_options (settings); + } #endif settings_update_color_scheme (settings); } From e6c1f5d94d33b6356b572d45fbf1084d4bc85746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 6 Jan 2011 15:22:36 -0500 Subject: [PATCH 02/42] Dont iterate the display if there's nothing to write --- gdk/wayland/gdkdisplay-wayland.c | 4 ++-- gdk/wayland/gdkeventsource.c | 10 ++++++++++ gdk/wayland/gdkprivate-wayland.h | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 378fbea135..86a36f07c3 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -490,8 +490,8 @@ gdk_wayland_display_flush (GdkDisplay *display) g_return_if_fail (GDK_IS_DISPLAY (display)); if (!display->closed) - wl_display_iterate(GDK_DISPLAY_WAYLAND (display)->wl_display, - WL_DISPLAY_WRITABLE); + _gdk_wayland_display_flush (display, + GDK_DISPLAY_WAYLAND (display)->event_source); } static gboolean diff --git a/gdk/wayland/gdkeventsource.c b/gdk/wayland/gdkeventsource.c index 12c9118201..553cc35804 100644 --- a/gdk/wayland/gdkeventsource.c +++ b/gdk/wayland/gdkeventsource.c @@ -150,6 +150,16 @@ _gdk_wayland_display_event_source_new (GdkDisplay *display) return source; } +void +_gdk_wayland_display_flush (GdkDisplay *display, GSource *source) +{ + GdkWaylandEventSource *wayland_source = (GdkWaylandEventSource *) source; + + while (wayland_source->mask & WL_DISPLAY_WRITABLE) + wl_display_iterate(GDK_DISPLAY_WAYLAND (display)->wl_display, + WL_DISPLAY_WRITABLE); +} + void _gdk_wayland_display_queue_events (GdkDisplay *display) { diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index fa3b27861e..ef13fea1ba 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -121,6 +121,7 @@ GdkDeviceManager *_gdk_device_manager_new (GdkDisplay *display); void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event); GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display); void _gdk_wayland_display_queue_events (GdkDisplay *display); +void _gdk_wayland_display_flush (GdkDisplay *display, GSource *source); GdkAppLaunchContext *_gdk_wayland_display_get_app_launch_context (GdkDisplay *display); From 7bbc15821774c22c67ca4f56d958e6aff4dd756e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 6 Jan 2011 15:23:52 -0500 Subject: [PATCH 03/42] Remove copy of grab enum that's now in wayland core --- gdk/wayland/gdkwindow-wayland.c | 41 ++++++++++----------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 15a2e4c5f8..371f9d026a 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -216,13 +216,13 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display, 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)) @@ -1043,8 +1043,6 @@ gdk_wayland_window_set_keep_below (GdkWindow *window, gboolean setting) static GdkWindow * gdk_wayland_window_get_group (GdkWindow *window) { - GdkToplevelWayland *toplevel; - if (GDK_WINDOW_DESTROYED (window) || !WINDOW_IS_TOPLEVEL (window)) return NULL; @@ -1080,21 +1078,6 @@ gdk_wayland_window_set_functions (GdkWindow *window, { } -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, @@ -1116,35 +1099,35 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window, switch (edge) { case GDK_WINDOW_EDGE_NORTH_WEST: - grab_type = WL_DEVICE_GRAB_RESIZE_TOP_LEFT; + grab_type = WL_GRAB_RESIZE_TOP_LEFT; break; case GDK_WINDOW_EDGE_NORTH: - grab_type = WL_DEVICE_GRAB_RESIZE_TOP; + grab_type = WL_GRAB_RESIZE_TOP; break; case GDK_WINDOW_EDGE_NORTH_EAST: - grab_type = WL_DEVICE_GRAB_RESIZE_RIGHT; + grab_type = WL_GRAB_RESIZE_RIGHT; break; case GDK_WINDOW_EDGE_WEST: - grab_type = WL_DEVICE_GRAB_RESIZE_LEFT; + grab_type = WL_GRAB_RESIZE_LEFT; break; case GDK_WINDOW_EDGE_EAST: - grab_type = WL_DEVICE_GRAB_RESIZE_RIGHT; + grab_type = WL_GRAB_RESIZE_RIGHT; break; case GDK_WINDOW_EDGE_SOUTH_WEST: - grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM_LEFT; + grab_type = WL_GRAB_RESIZE_BOTTOM_LEFT; break; case GDK_WINDOW_EDGE_SOUTH: - grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM; + grab_type = WL_GRAB_RESIZE_BOTTOM; break; case GDK_WINDOW_EDGE_SOUTH_EAST: - grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT; + grab_type = WL_GRAB_RESIZE_BOTTOM_RIGHT; break; default: @@ -1248,16 +1231,15 @@ static void gdk_wayland_window_process_updates_recurse (GdkWindow *window, cairo_region_t *region) { +#if 0 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++) @@ -1266,6 +1248,7 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window, wl_surface_damage (impl->surface, rect.x, rect.y, rect.width, rect.height); } +#endif _gdk_window_process_updates_recurse (window, region); } From 56de871bf3ebde866a65e107eb3c40bc43c3f438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 6 Jan 2011 16:51:12 -0500 Subject: [PATCH 04/42] Create and attach buffer at process_updates time This way we don't try to show the buffer until we've handle the initial expose. --- gdk/wayland/gdkdisplay-wayland.c | 2 +- gdk/wayland/gdkwindow-wayland.c | 90 ++++++++++++++++++++++---------- gdk/wayland/gdkwindow-wayland.h | 44 +--------------- 3 files changed, 63 insertions(+), 73 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 86a36f07c3..fefa1f55cd 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -169,7 +169,7 @@ shell_handle_configure(void *data, struct wl_shell *shell, window->height = height; _gdk_window_update_size (window); - _gdk_wayland_window_update_size (GDK_WINDOW_IMPL_WAYLAND (window->impl)); + _gdk_wayland_window_update_size (window); g_object_ref(window); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 371f9d026a..a331529c4e 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -80,21 +80,59 @@ _gdk_wayland_window_init (GdkWaylandWindow *wayland_window) { } +#define GDK_TYPE_WINDOW_IMPL_WAYLAND (_gdk_window_impl_wayland_get_type ()) +#define GDK_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWayland)) +#define GDK_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass)) +#define GDK_IS_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND)) +#define GDK_IS_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND)) +#define GDK_WINDOW_IMPL_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass)) + +typedef struct _GdkWindowImplWayland GdkWindowImplWayland; +typedef struct _GdkWindowImplWaylandClass GdkWindowImplWaylandClass; + +struct _GdkWindowImplWayland +{ + GdkWindowImpl parent_instance; + + GdkWindow *wrapper; + + GdkToplevelWayland *toplevel; /* Toplevel-specific information */ + GdkCursor *cursor; + GHashTable *device_cursor; + + gint8 toplevel_window_type; + + struct wl_surface *surface; + struct wl_buffer *buffer; + EGLImageKHR *pending_image; + EGLImageKHR *next_image; + + cairo_surface_t *cairo_surface; + GLuint texture; + EGLImageKHR image; + +}; + +struct _GdkWindowImplWaylandClass +{ + GdkWindowImplClass parent_class; +}; + 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); + (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)) @@ -116,8 +154,9 @@ _gdk_wayland_window_get_toplevel (GdkWindow *window) * cairo surface) when its size has changed. **/ void -_gdk_wayland_window_update_size (GdkWindowImplWayland *impl) +_gdk_wayland_window_update_size (GdkWindow *window) { + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); @@ -140,6 +179,9 @@ _gdk_wayland_window_update_size (GdkWindowImplWayland *impl) impl->image = NULL; + wl_buffer_destroy(impl->buffer); + impl->buffer = NULL; + fprintf(stderr, " - cleared image\n"); } } @@ -270,7 +312,6 @@ _gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image) GdkWindowImplWayland *impl; EGLint name, stride; struct wl_visual *wl_visual; - struct wl_buffer *buffer; if (GDK_WINDOW_DESTROYED (window)) return; @@ -296,12 +337,10 @@ _gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image) 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); + impl->buffer = wl_drm_create_buffer(display_wayland->drm, + name, window->width, window->height, + stride, wl_visual); + wl_surface_attach (impl->surface, impl->buffer, 0, 0); g_object_ref(impl); @@ -433,10 +472,11 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) GdkToplevelWayland *toplevel; GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + display = gdk_window_get_display (window); + display_wayland = GDK_DISPLAY_WAYLAND (display); + 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 && @@ -445,13 +485,12 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) 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); + + fprintf(stderr, "window show, faked map event\n"); } static void @@ -554,7 +593,7 @@ gdk_window_wayland_move_resize (GdkWindow *window, if (height > 0) window->height = height; - _gdk_wayland_window_update_size (GDK_WINDOW_IMPL_WAYLAND (window->impl)); + _gdk_wayland_window_update_size (window); } static void @@ -1189,12 +1228,6 @@ gdk_wayland_window_configure_finished (GdkWindow *window) 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 @@ -1231,15 +1264,15 @@ static void gdk_wayland_window_process_updates_recurse (GdkWindow *window, cairo_region_t *region) { -#if 0 GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); cairo_rectangle_int_t rect; int i, n; - gdk_wayland_window_ref_cairo_surface (window); - - _gdk_wayland_window_attach_image (window, impl->image); - cairo_surface_destroy (impl->cairo_surface); + if (impl->buffer == NULL) + { + _gdk_wayland_window_attach_image (window, impl->image); + wl_surface_map_toplevel (impl->surface); + } n = cairo_region_num_rectangles(region); for (i = 0; i < n; i++) @@ -1248,7 +1281,6 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window, wl_surface_damage (impl->surface, rect.x, rect.y, rect.width, rect.height); } -#endif _gdk_window_process_updates_recurse (window, region); } diff --git a/gdk/wayland/gdkwindow-wayland.h b/gdk/wayland/gdkwindow-wayland.h index f33afdf504..62d40de4bd 100644 --- a/gdk/wayland/gdkwindow-wayland.h +++ b/gdk/wayland/gdkwindow-wayland.h @@ -39,50 +39,8 @@ G_BEGIN_DECLS typedef struct _GdkToplevelWayland GdkToplevelWayland; -typedef struct _GdkWindowImplWayland GdkWindowImplWayland; -typedef struct _GdkWindowImplWaylandClass GdkWindowImplWaylandClass; typedef struct _GdkXPositionInfo GdkXPositionInfo; -/* Window implementation for Wayland - */ - -#define GDK_TYPE_WINDOW_IMPL_WAYLAND (_gdk_window_impl_wayland_get_type ()) -#define GDK_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWayland)) -#define GDK_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass)) -#define GDK_IS_WINDOW_IMPL_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND)) -#define GDK_IS_WINDOW_IMPL_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND)) -#define GDK_WINDOW_IMPL_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass)) - -struct _GdkWindowImplWayland -{ - GdkWindowImpl parent_instance; - - GdkWindow *wrapper; - - GdkToplevelWayland *toplevel; /* Toplevel-specific information */ - GdkCursor *cursor; - GHashTable *device_cursor; - - gint8 toplevel_window_type; - guint no_bg : 1; /* Set when the window background is temporarily - * unset during resizing and scaling */ - guint override_redirect : 1; - - struct wl_surface *surface; - EGLImageKHR *pending_image; - EGLImageKHR *next_image; - - cairo_surface_t *cairo_surface; - GLuint texture; - EGLImageKHR image; - -}; - -struct _GdkWindowImplWaylandClass -{ - GdkWindowImplClass parent_class; -}; - struct _GdkToplevelWayland { @@ -143,7 +101,7 @@ void _gdk_wayland_window_get_offsets (GdkWindow *window, gint *x_offset, gint *y_offset); -void _gdk_wayland_window_update_size (GdkWindowImplWayland *drawable); +void _gdk_wayland_window_update_size (GdkWindow *window); G_END_DECLS From 799279daf07a1d2e476ef5eb7b1c3396f25dfbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 7 Jan 2011 10:16:17 -0500 Subject: [PATCH 05/42] Invalidate window on configure This will trigger a repaint of the window, but it may be more efficient to just copy back the old surface contents and let gtk+ just update the changed parts. --- gdk/wayland/gdkwindow-wayland.c | 39 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index a331529c4e..45d921be4e 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -106,6 +106,7 @@ struct _GdkWindowImplWayland struct wl_buffer *buffer; EGLImageKHR *pending_image; EGLImageKHR *next_image; + unsigned int mapped : 1; cairo_surface_t *cairo_surface; GLuint texture; @@ -159,6 +160,8 @@ _gdk_wayland_window_update_size (GdkWindow *window) GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); + GdkRectangle area; + cairo_region_t *region; fprintf(stderr, "update size, window %p\n", impl->wrapper); @@ -179,11 +182,23 @@ _gdk_wayland_window_update_size (GdkWindow *window) impl->image = NULL; - wl_buffer_destroy(impl->buffer); - impl->buffer = NULL; + if (impl->buffer) + { + wl_buffer_destroy(impl->buffer); + impl->buffer = NULL; + } fprintf(stderr, " - cleared image\n"); } + + area.x = 0; + area.y = 0; + area.width = window->width; + area.height = window->height; + + region = cairo_region_create_rectangle (&area); + _gdk_window_invalidate_for_expose (window, region); + cairo_region_destroy (region); } GdkWindow * @@ -318,19 +333,6 @@ _gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image) 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); @@ -345,8 +347,7 @@ _gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image) g_object_ref(impl); fprintf(stderr, "attach %p %dx%d (image %p, name %d)\n", - window, window->width, window->height, - impl->pending_image, name); + window, window->width, window->height, image, name); } static void @@ -1269,9 +1270,11 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window, int i, n; if (impl->buffer == NULL) + _gdk_wayland_window_attach_image (window, impl->image); + if (!impl->mapped) { - _gdk_wayland_window_attach_image (window, impl->image); wl_surface_map_toplevel (impl->surface); + impl->mapped = TRUE; } n = cairo_region_num_rectangles(region); From 7d29070faf4dadb8949b6abbc5e1f9b1f806a146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 7 Jan 2011 12:10:41 -0500 Subject: [PATCH 06/42] Implement GdkKeymap using libxkbcommon --- gdk/wayland/gdkdevice-wayland.h | 3 +- gdk/wayland/gdkdevicemanager-wayland.c | 29 ++-- gdk/wayland/gdkdisplay-wayland.c | 5 +- gdk/wayland/gdkkeys-wayland.c | 218 ++++++++++++++++++++++--- gdk/wayland/gdkprivate-wayland.h | 4 +- 5 files changed, 218 insertions(+), 41 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.h b/gdk/wayland/gdkdevice-wayland.h index 88fac43a6e..a8d4dd99d0 100644 --- a/gdk/wayland/gdkdevice-wayland.h +++ b/gdk/wayland/gdkdevice-wayland.h @@ -20,8 +20,8 @@ #ifndef __GDK_DEVICE_CORE_H__ #define __GDK_DEVICE_CORE_H__ +#include #include -#include G_BEGIN_DECLS @@ -45,7 +45,6 @@ struct _GdkWaylandDevice GdkWindow *pointer_focus; GdkWindow *keyboard_focus; struct wl_input_device *device; - struct xkb_desc *xkb; int32_t x, y, surface_x, surface_y; }; diff --git a/gdk/wayland/gdkdevicemanager-wayland.c b/gdk/wayland/gdkdevicemanager-wayland.c index c432ec7ea8..d1543f9a70 100644 --- a/gdk/wayland/gdkdevicemanager-wayland.c +++ b/gdk/wayland/gdkdevicemanager-wayland.c @@ -28,6 +28,7 @@ #include "gdkprivate-wayland.h" #include "gdkeventsource.h" +#include static void gdk_device_manager_core_finalize (GObject *object); @@ -116,6 +117,8 @@ input_handle_key(void *data, struct wl_input_device *input_device, GdkWaylandDevice *device = data; GdkEvent *event; uint32_t code, modifier, level; + struct xkb_desc *xkb; + GdkKeymap *keymap; event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); event->key.window = g_object_ref (device->keyboard_focus); @@ -125,16 +128,19 @@ input_handle_key(void *data, struct wl_input_device *input_device, event->key.group = 0; event->key.hardware_keycode = key; - code = key + device->xkb->min_key_code; + keymap = gdk_keymap_get_for_display (device->display); + xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); + + code = key + xkb->min_key_code; level = 0; if (device->modifiers & ShiftMask && - XkbKeyGroupWidth(device->xkb, code, 0) > 1) + XkbKeyGroupWidth(xkb, code, 0) > 1) level = 1; - event->key.keyval = XkbKeySymEntry(device->xkb, code, level, 0); + event->key.keyval = XkbKeySymEntry(xkb, code, level, 0); - modifier = device->xkb->map->modmap[code]; + modifier = xkb->map->modmap[code]; if (state) device->modifiers |= modifier; else @@ -269,10 +275,15 @@ static void update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) { uint32_t *k, *end; + GdkKeymap *keymap; + struct xkb_desc *xkb; + + keymap = gdk_keymap_get_for_display (device->display); + xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); end = keys->data + keys->size; for (k = keys->data; k < end; k++) - device->modifiers |= device->xkb->map->modmap[*k]; + device->modifiers |= xkb->map->modmap[*k]; fprintf (stderr, "modifiers: 0x%x\n", device->modifiers); } @@ -335,7 +346,6 @@ gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, GdkDisplay *display; GdkDeviceManagerCore *device_manager_core = GDK_DEVICE_MANAGER_CORE(device_manager); - struct xkb_rule_names names; GdkWaylandDevice *device; device = g_new0 (GdkWaylandDevice, 1); @@ -366,13 +376,6 @@ gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, GDK_DEVICE_CORE (device->keyboard)->device = device; device->device = wl_device; - names.rules = "evdev"; - names.model = "pc105"; - names.layout = "us"; - names.variant = ""; - names.options = ""; - device->xkb = xkb_compile_keymap_from_rules(&names); - wl_input_device_add_listener(device->device, &input_device_listener, device); diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index fefa1f55cd..34740d18d4 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -709,10 +709,7 @@ gdk_wayland_display_get_keymap (GdkDisplay *display) display_wayland = GDK_DISPLAY_WAYLAND (display); if (!display_wayland->keymap) - display_wayland->keymap = - g_object_new (_gdk_wayland_keymap_get_type(), NULL); - - display_wayland->keymap->display = display; + display_wayland->keymap = _gdk_wayland_keymap_new (display); return display_wayland->keymap; } diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c index 87b139814a..f18bf0e291 100644 --- a/gdk/wayland/gdkkeys-wayland.c +++ b/gdk/wayland/gdkkeys-wayland.c @@ -49,6 +49,7 @@ typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass; struct _GdkWaylandKeymap { GdkKeymap parent_instance; + struct xkb_desc *xkb; }; struct _GdkWaylandKeymapClass @@ -57,7 +58,7 @@ struct _GdkWaylandKeymapClass }; #define GDK_TYPE_WAYLAND_KEYMAP (_gdk_wayland_keymap_get_type ()) -#define GDK_WAYLAND_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_KEYMAP, GdkWaylandKeyMap)) +#define GDK_WAYLAND_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_KEYMAP, GdkWaylandKeymap)) #define GDK_IS_WAYLAND_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_KEYMAP)) G_DEFINE_TYPE (GdkWaylandKeymap, _gdk_wayland_keymap, GDK_TYPE_KEYMAP) @@ -94,39 +95,190 @@ gdk_wayland_keymap_get_num_lock_state (GdkKeymap *keymap) static gboolean gdk_wayland_keymap_get_entries_for_keyval (GdkKeymap *keymap, - guint keyval, - GdkKeymapKey **keys, - gint *n_keys) + guint keyval, + GdkKeymapKey **keys, + gint *n_keys) { - return FALSE; + GArray *retval; + uint32_t keycode; + struct xkb_desc *xkb; + + xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb; + keycode = xkb->min_key_code; + + retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey)); + + for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++) + { + gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode); + + gint group = 0; + gint level = 0; + gint total_syms = XkbKeyNumSyms (xkb, keycode); + gint i = 0; + uint32_t *entry; + + /* entry is an array with all syms for group 0, all + * syms for group 1, etc. and for each group the + * shift level syms are in order + */ + entry = XkbKeySymsPtr (xkb, keycode); + + for (i = 0; i < total_syms; i++) + { + /* check out our cool loop invariant */ + g_assert (i == (group * max_shift_levels + level)); + + if (entry[i] == keyval) + { + /* Found a match */ + GdkKeymapKey key; + + key.keycode = keycode; + key.group = group; + key.level = level; + + g_array_append_val (retval, key); + + g_assert (XkbKeySymEntry (xkb, keycode, level, group) == + keyval); + } + + level++; + + if (level == max_shift_levels) + { + level = 0; + group++; + } + } + } + + *n_keys = retval->len; + *keys = (GdkKeymapKey *) g_array_free (retval, FALSE); + + return *n_keys > 0; } static gboolean gdk_wayland_keymap_get_entries_for_keycode (GdkKeymap *keymap, - guint hardware_keycode, - GdkKeymapKey **keys, - guint **keyvals, - gint *n_entries) + guint hardware_keycode, + GdkKeymapKey **keys, + guint **keyvals, + gint *n_entries) { - return FALSE; + GArray *key_array; + GArray *keyval_array; + struct xkb_desc *xkb; + gint max_shift_levels; + gint group = 0; + gint level = 0; + gint total_syms; + gint i; + uint32_t *entry; + + g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); + g_return_val_if_fail (n_entries != NULL, FALSE); + + xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb; + + if (hardware_keycode < xkb->min_key_code || + hardware_keycode > xkb->max_key_code) + { + if (keys) + *keys = NULL; + if (keyvals) + *keyvals = NULL; + + *n_entries = 0; + return FALSE; + } + + if (keys) + key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey)); + else + key_array = NULL; + + if (keyvals) + keyval_array = g_array_new (FALSE, FALSE, sizeof (guint)); + else + keyval_array = NULL; + + /* See sec 15.3.4 in XKB docs */ + max_shift_levels = XkbKeyGroupsWidth (xkb, hardware_keycode); + total_syms = XkbKeyNumSyms (xkb, hardware_keycode); + + /* entry is an array with all syms for group 0, all + * syms for group 1, etc. and for each group the + * shift level syms are in order + */ + entry = XkbKeySymsPtr (xkb, hardware_keycode); + + for (i = 0; i < total_syms; i++) + { + /* check out our cool loop invariant */ + g_assert (i == (group * max_shift_levels + level)); + + if (key_array) + { + GdkKeymapKey key; + + key.keycode = hardware_keycode; + key.group = group; + key.level = level; + + g_array_append_val (key_array, key); + } + + if (keyval_array) + g_array_append_val (keyval_array, entry[i]); + + ++level; + + if (level == max_shift_levels) + { + level = 0; + ++group; + } + } + + *n_entries = 0; + + if (keys) + { + *n_entries = key_array->len; + *keys = (GdkKeymapKey*) g_array_free (key_array, FALSE); + } + + if (keyvals) + { + *n_entries = keyval_array->len; + *keyvals = (guint*) g_array_free (keyval_array, FALSE); + } + + return *n_entries > 0; } static guint gdk_wayland_keymap_lookup_key (GdkKeymap *keymap, - const GdkKeymapKey *key) + const GdkKeymapKey *key) { - return 0; + struct xkb_desc *xkb; + + xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb; + + return XkbKeySymEntry (xkb, key->keycode, key->level, key->group); } static gboolean gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, - guint hardware_keycode, - GdkModifierType state, - gint group, - guint *keyval, - gint *effective_group, - gint *level, - GdkModifierType *consumed_modifiers) + guint hardware_keycode, + GdkModifierType state, + gint group, + guint *keyval, + gint *effective_group, + gint *level, + GdkModifierType *consumed_modifiers) { return FALSE; } @@ -134,13 +286,13 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, static void gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap, - GdkModifierType *state) + GdkModifierType *state) { } static gboolean gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap, - GdkModifierType *state) + GdkModifierType *state) { return FALSE; } @@ -169,3 +321,27 @@ static void _gdk_wayland_keymap_init (GdkWaylandKeymap *keymap) { } + +GdkKeymap * +_gdk_wayland_keymap_new (GdkDisplay *display) +{ + GdkWaylandKeymap *keymap; + struct xkb_rule_names names; + + keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL); + GDK_KEYMAP (keymap)->display = display; + + names.rules = "evdev"; + names.model = "pc105"; + names.layout = "us"; + names.variant = ""; + names.options = ""; + keymap->xkb = xkb_compile_keymap_from_rules(&names); + + return GDK_KEYMAP (keymap); +} + +struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap) +{ + return GDK_WAYLAND_KEYMAP (keymap)->xkb; +} diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index ef13fea1ba..dcd9fa9227 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -46,7 +46,9 @@ #define GDK_WINDOW_IS_WAYLAND(win) (GDK_IS_WINDOW_IMPL_WAYLAND (((GdkWindow *)win)->impl)) GType _gdk_wayland_window_get_type (void); -GType _gdk_wayland_keymap_get_type (void); + +GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display); +struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap); GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, GdkCursorType cursor_type); From a65fcd0859898c86f0a980c38c9f4c079c6d8415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 7 Jan 2011 14:21:56 -0500 Subject: [PATCH 07/42] Hook up xkb_keysym_to_string and xkb_string_to_keysym --- gdk/wayland/gdkdisplaymanager-wayland.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdkdisplaymanager-wayland.c b/gdk/wayland/gdkdisplaymanager-wayland.c index 1b48014cdf..25aa6fb989 100644 --- a/gdk/wayland/gdkdisplaymanager-wayland.c +++ b/gdk/wayland/gdkdisplaymanager-wayland.c @@ -29,6 +29,8 @@ #include "gdkinternals.h" +#include + typedef struct _GdkWaylandDisplayManager GdkWaylandDisplayManager; typedef struct _GdkWaylandDisplayManagerClass GdkWaylandDisplayManagerClass; @@ -108,14 +110,32 @@ static guint gdk_wayland_display_manager_lookup_keyval (GdkDisplayManager *manager, const gchar *keyval_name) { - return /* XStringToKeysym (keyval_name); */ 0; + g_return_val_if_fail (keyval_name != NULL, 0); + + return xkb_string_to_keysym(keyval_name); } static gchar * gdk_wayland_display_manager_get_keyval_name (GdkDisplayManager *manager, guint keyval) { - return NULL; + static char buf[128]; + + switch (keyval) + { + case GDK_KEY_Page_Up: + return "Page_Up"; + case GDK_KEY_Page_Down: + return "Page_Down"; + case GDK_KEY_KP_Page_Up: + return "KP_Page_Up"; + case GDK_KEY_KP_Page_Down: + return "KP_Page_Down"; + } + + xkb_keysym_to_string(keyval, buf, sizeof buf); + + return buf; } static void From 846e2c0eee0a503e81df4a001a168b3e830b7edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 7 Jan 2011 20:22:16 -0500 Subject: [PATCH 08/42] Remove leftover _gdk_windowing_set_cairo_surface_size() --- gdk/wayland/gdkwindow-wayland.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 45d921be4e..6c2a6f236a 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -382,16 +382,6 @@ gdk_wayland_cairo_surface_destroy (void *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, From 1149c342bf9903bc828fe33c62b09ae9d576c687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 7 Jan 2011 20:49:40 -0500 Subject: [PATCH 09/42] Clean up buffer handling a bit --- gdk/wayland/gdkwindow-wayland.c | 161 ++++++++++++++++---------------- gdk/wayland/gdkwindow-wayland.h | 2 - 2 files changed, 81 insertions(+), 82 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 6c2a6f236a..3d796cde2c 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -103,15 +103,11 @@ struct _GdkWindowImplWayland gint8 toplevel_window_type; struct wl_surface *surface; - struct wl_buffer *buffer; - EGLImageKHR *pending_image; - EGLImageKHR *next_image; unsigned int mapped : 1; cairo_surface_t *cairo_surface; + cairo_surface_t *server_surface; GLuint texture; - EGLImageKHR image; - }; struct _GdkWindowImplWaylandClass @@ -171,26 +167,6 @@ _gdk_wayland_window_update_size (GdkWindow *window) 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; - - if (impl->buffer) - { - wl_buffer_destroy(impl->buffer); - impl->buffer = NULL; - } - - fprintf(stderr, " - cleared image\n"); - } - area.x = 0; area.y = 0; area.width = window->width; @@ -319,35 +295,62 @@ gdk_toplevel_wayland_free_contents (GdkDisplay *display, } } -void -_gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image) +static const cairo_user_data_key_t gdk_wayland_cairo_key; + +typedef struct _GdkWaylandCairoSurfaceData { + EGLImageKHR image; + GLuint texture; + struct wl_buffer *buffer; + GdkDisplayWayland *display; +} GdkWaylandCairoSurfaceData; + +struct wl_buffer * +_gdk_wayland_surface_get_buffer (GdkDisplayWayland *display, + cairo_surface_t *surface) +{ + GdkWaylandCairoSurfaceData *data; + EGLint name, stride; + struct wl_visual *visual; + int width, height; + + data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); + + if (data->buffer) + return data->buffer; + + visual = + wl_display_get_premultiplied_argb_visual(display->wl_display); + + width = cairo_gl_surface_get_width (surface); + height = cairo_gl_surface_get_height (surface); + display->export_drm_image (display->egl_display, + data->image, &name, NULL, &stride); + data->buffer = wl_drm_create_buffer(display->drm, + name, width, height, stride, visual); + + return data->buffer; +} + +static void +gdk_wayland_window_attach_image (GdkWindow *window) { GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (gdk_window_get_display (window)); - GdkWindowImplWayland *impl; - EGLint name, stride; - struct wl_visual *wl_visual; + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + struct wl_buffer *buffer; if (GDK_WINDOW_DESTROYED (window)) return; - impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + if (impl->server_surface == impl->cairo_surface) + return; - wl_visual = - wl_display_get_premultiplied_argb_visual(display_wayland->wl_display); + impl->server_surface = impl->cairo_surface; + buffer = _gdk_wayland_surface_get_buffer (display_wayland, + impl->cairo_surface); + wl_surface_attach (impl->surface, buffer, 0, 0); - display_wayland->export_drm_image (display_wayland->egl_display, - image, &name, NULL, &stride); - - impl->buffer = wl_drm_create_buffer(display_wayland->drm, - name, window->width, window->height, - stride, wl_visual); - wl_surface_attach (impl->surface, impl->buffer, 0, 0); - - g_object_ref(impl); - - fprintf(stderr, "attach %p %dx%d (image %p, name %d)\n", - window, window->width, window->height, image, name); + fprintf(stderr, "attach %p %dx%d\n", window, window->width, window->height); } static void @@ -372,23 +375,25 @@ gdk_window_impl_wayland_finalize (GObject *object) 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) +gdk_wayland_cairo_surface_destroy (void *p) { - GdkWindowImplWayland *impl = data; + GdkWaylandCairoSurfaceData *data = p; - impl->cairo_surface = NULL; + data->display->destroy_image (data->display->egl_display, data->image); + cairo_device_acquire(data->display->cairo_device); + glDeleteTextures(1, &data->texture); + cairo_device_release(data->display->cairo_device); + if (data->buffer) + wl_buffer_destroy(data->buffer); + g_free(data); } static cairo_surface_t * -gdk_wayland_create_cairo_surface (GdkWindowImplWayland *impl, - int width, - int height) +gdk_wayland_create_cairo_surface (GdkDisplayWayland *display, + int width, int height) { - GdkDisplayWayland *display_wayland = - GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); + GdkWaylandCairoSurfaceData *data; cairo_surface_t *surface; EGLint image_attribs[] = { @@ -399,26 +404,24 @@ gdk_wayland_create_cairo_surface (GdkWindowImplWayland *impl, 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); + data = g_new (GdkWaylandCairoSurfaceData, 1); + data->display = display; + data->buffer = NULL; + image_attribs[1] = width; + image_attribs[3] = height; + data->image = display->create_drm_image(display->egl_display, image_attribs); + glGenTextures(1, &data->texture); + glBindTexture(GL_TEXTURE_2D, data->texture); + display->image_target_texture_2d(GL_TEXTURE_2D, data->image); - glBindTexture(GL_TEXTURE_2D, impl->texture); - display_wayland->image_target_texture_2d(GL_TEXTURE_2D, impl->image); + printf("allocate image %dx%d (image %p)\n", width, height, data->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, + surface = cairo_gl_surface_create_for_texture(display->cairo_device, CAIRO_CONTENT_COLOR_ALPHA, - impl->texture, width, height); + data->texture, width, height); + + cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key, + data, gdk_wayland_cairo_surface_destroy); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) fprintf (stderr, "create gl surface failed\n"); @@ -430,6 +433,8 @@ static cairo_surface_t * gdk_wayland_window_ref_cairo_surface (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkDisplayWayland *display_wayland = + GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); if (GDK_WINDOW_DESTROYED (impl->wrapper)) return NULL; @@ -437,15 +442,12 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window) if (!impl->cairo_surface) { impl->cairo_surface = - gdk_wayland_create_cairo_surface (impl, + gdk_wayland_create_cairo_surface (display_wayland, 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); + + cairo_surface_reference (impl->cairo_surface); return impl->cairo_surface; } @@ -1259,8 +1261,7 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window, cairo_rectangle_int_t rect; int i, n; - if (impl->buffer == NULL) - _gdk_wayland_window_attach_image (window, impl->image); + gdk_wayland_window_attach_image (window); if (!impl->mapped) { wl_surface_map_toplevel (impl->surface); diff --git a/gdk/wayland/gdkwindow-wayland.h b/gdk/wayland/gdkwindow-wayland.h index 62d40de4bd..73d7ec61ba 100644 --- a/gdk/wayland/gdkwindow-wayland.h +++ b/gdk/wayland/gdkwindow-wayland.h @@ -93,8 +93,6 @@ struct _GdkToplevelWayland GType _gdk_window_impl_wayland_get_type (void); GdkToplevelWayland *_gdk_wayland_window_get_toplevel (GdkWindow *window); -void _gdk_wayland_window_attach_image (GdkWindow *window, - EGLImageKHR image); GdkCursor *_gdk_wayland_window_get_cursor (GdkWindow *window); void _gdk_wayland_window_get_offsets (GdkWindow *window, From 541d5172dd7de2b3859430f0ad02a628f49a25e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 8 Feb 2011 08:12:59 -0500 Subject: [PATCH 10/42] Track 2.99.3 API changes --- gdk/wayland/gdkdisplay-wayland.c | 43 ++---------------------------- gdk/wayland/gdkdnd-wayland.c | 8 ++---- gdk/wayland/gdkprivate-wayland.h | 11 ++++---- gdk/wayland/gdkselection-wayland.c | 4 +-- gdk/wayland/gdkwindow-wayland.c | 37 +++++++------------------ 5 files changed, 20 insertions(+), 83 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 34740d18d4..cb99a382be 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -306,7 +306,6 @@ _gdk_wayland_display_open (const gchar *display_name) struct wl_display *wl_display; GdkDisplay *display; GdkDisplayWayland *display_wayland; - GdkWindowAttr attr; gint i; @@ -340,14 +339,6 @@ _gdk_wayland_display_open (const gchar *display_name) display_wayland->event_source = _gdk_wayland_display_event_source_new (display); - attr.window_type = GDK_WINDOW_TOPLEVEL; - attr.wclass = GDK_INPUT_OUTPUT; - attr.x = 10; - attr.y = 10; - attr.width = 10; - attr.height = 10; - attr.event_mask = 0; - gdk_input_init (display); g_signal_emit_by_name (display, "opened"); @@ -566,33 +557,6 @@ gdk_wayland_display_list_devices (GdkDisplay *display) return GDK_DISPLAY_WAYLAND (display)->input_devices; } -static gboolean -gdk_wayland_display_send_client_message (GdkDisplay *display, - GdkEvent *event, - GdkNativeWindow winid) -{ - return 0; -} - -static void -gdk_wayland_display_add_client_message_filter (GdkDisplay *display, - GdkAtom message_type, - GdkFilterFunc func, - gpointer data) -{ - GdkClientFilter *filter; - g_return_if_fail (GDK_IS_DISPLAY (display)); - filter = g_new (GdkClientFilter, 1); - - filter->type = message_type; - filter->function = func; - filter->data = data; - - GDK_DISPLAY_WAYLAND(display)->client_filters = - g_list_append (GDK_DISPLAY_WAYLAND (display)->client_filters, - filter); -} - static void gdk_wayland_display_before_process_all_updates (GdkDisplay *display) { @@ -754,15 +718,12 @@ _gdk_display_wayland_class_init (GdkDisplayWaylandClass * class) display_class->supports_input_shapes = gdk_wayland_display_supports_input_shapes; display_class->supports_composite = gdk_wayland_display_supports_composite; display_class->list_devices = gdk_wayland_display_list_devices; - display_class->send_client_message = gdk_wayland_display_send_client_message; - display_class->add_client_message_filter = gdk_wayland_display_add_client_message_filter; display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context; - display_class->get_drag_protocol = _gdk_wayland_display_get_drag_protocol; + display_class->get_default_cursor_size = _gdk_wayland_display_get_default_cursor_size; + display_class->get_maximal_cursor_size = _gdk_wayland_display_get_maximal_cursor_size; display_class->get_cursor_for_type = _gdk_wayland_display_get_cursor_for_type; display_class->get_cursor_for_name = _gdk_wayland_display_get_cursor_for_name; display_class->get_cursor_for_pixbuf = _gdk_wayland_display_get_cursor_for_pixbuf; - display_class->get_default_cursor_size = _gdk_wayland_display_get_default_cursor_size; - display_class->get_maximal_cursor_size = _gdk_wayland_display_get_maximal_cursor_size; display_class->supports_cursor_alpha = _gdk_wayland_display_supports_cursor_alpha; display_class->supports_cursor_color = _gdk_wayland_display_supports_cursor_color; display_class->before_process_all_updates = gdk_wayland_display_before_process_all_updates; diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c index 1d36e95732..293456fb17 100644 --- a/gdk/wayland/gdkdnd-wayland.c +++ b/gdk/wayland/gdkdnd-wayland.c @@ -160,12 +160,8 @@ gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass) context_class->get_selection = gdk_wayland_drag_context_get_selection; } -GdkNativeWindow -_gdk_wayland_display_get_drag_protocol (GdkDisplay *display, - GdkNativeWindow xid, - GdkDragProtocol *protocol, - guint *version) - +GdkDragProtocol +_gdk_wayland_window_get_drag_protocol (GdkWindow *window, GdkWindow **target) { return 0; } diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index dcd9fa9227..bc5c6ed393 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -67,10 +67,9 @@ void _gdk_wayland_display_get_maximal_cursor_size (GdkDisplay *display, gboolean _gdk_wayland_display_supports_cursor_alpha (GdkDisplay *display); gboolean _gdk_wayland_display_supports_cursor_color (GdkDisplay *display); -GdkNativeWindow _gdk_wayland_display_get_drag_protocol (GdkDisplay *display, - GdkNativeWindow xid, - GdkDragProtocol *protocol, - guint *version); +GdkDragProtocol _gdk_wayland_window_get_drag_protocol (GdkWindow *window, + GdkWindow **target); + void _gdk_wayland_window_register_dnd (GdkWindow *window); GdkDragContext *_gdk_wayland_window_drag_begin (GdkWindow *window, GdkDevice *device, @@ -93,8 +92,8 @@ gboolean _gdk_wayland_display_set_selection_owner (GdkDisplay *display, GdkAtom selection, guint32 time, gboolean send_event); -void _gdk_wayland_display_send_selection_notify (GdkDisplay *display, - GdkNativeWindow requestor, +void _gdk_wayland_display_send_selection_notify (GdkDisplay *dispay, + GdkWindow *requestor, GdkAtom selection, GdkAtom target, GdkAtom property, diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c index f2f4b2f1a6..0faf82239a 100644 --- a/gdk/wayland/gdkselection-wayland.c +++ b/gdk/wayland/gdkselection-wayland.c @@ -43,8 +43,8 @@ _gdk_wayland_display_set_selection_owner (GdkDisplay *display, } void -_gdk_wayland_display_send_selection_notify (GdkDisplay *display, - GdkNativeWindow requestor, +_gdk_wayland_display_send_selection_notify (GdkDisplay *dispay, + GdkWindow *requestor, GdkAtom selection, GdkAtom target, GdkAtom property, diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 3d796cde2c..7859e3fb19 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -154,8 +154,6 @@ void _gdk_wayland_window_update_size (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); - GdkDisplayWayland *display_wayland = - GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); GdkRectangle area; cairo_region_t *region; @@ -234,11 +232,8 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display, 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); @@ -356,15 +351,12 @@ gdk_wayland_window_attach_image (GdkWindow *window) 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) @@ -575,10 +567,6 @@ gdk_window_wayland_move_resize (GdkWindow *window, gint width, gint height) { - GdkWindowImplWayland *impl; - - impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); - window->x = x; window->y = y; if (width > 0) @@ -1131,35 +1119,35 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window, switch (edge) { case GDK_WINDOW_EDGE_NORTH_WEST: - grab_type = WL_GRAB_RESIZE_TOP_LEFT; + grab_type = WL_SHELL_RESIZE_TOP_LEFT; break; case GDK_WINDOW_EDGE_NORTH: - grab_type = WL_GRAB_RESIZE_TOP; + grab_type = WL_SHELL_RESIZE_TOP; break; case GDK_WINDOW_EDGE_NORTH_EAST: - grab_type = WL_GRAB_RESIZE_RIGHT; + grab_type = WL_SHELL_RESIZE_RIGHT; break; case GDK_WINDOW_EDGE_WEST: - grab_type = WL_GRAB_RESIZE_LEFT; + grab_type = WL_SHELL_RESIZE_LEFT; break; case GDK_WINDOW_EDGE_EAST: - grab_type = WL_GRAB_RESIZE_RIGHT; + grab_type = WL_SHELL_RESIZE_RIGHT; break; case GDK_WINDOW_EDGE_SOUTH_WEST: - grab_type = WL_GRAB_RESIZE_BOTTOM_LEFT; + grab_type = WL_SHELL_RESIZE_BOTTOM_LEFT; break; case GDK_WINDOW_EDGE_SOUTH: - grab_type = WL_GRAB_RESIZE_BOTTOM; + grab_type = WL_SHELL_RESIZE_BOTTOM; break; case GDK_WINDOW_EDGE_SOUTH_EAST: - grab_type = WL_GRAB_RESIZE_BOTTOM_RIGHT; + grab_type = WL_SHELL_RESIZE_BOTTOM_RIGHT; break; default: @@ -1210,16 +1198,12 @@ 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); } @@ -1238,10 +1222,6 @@ gdk_wayland_window_set_composited (GdkWindow *window, 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) @@ -1416,6 +1396,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass) 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->get_drag_protocol = _gdk_wayland_window_get_drag_protocol; 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; From 546069f434f18966f2a82c856519ef938dfd5aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 8 Feb 2011 16:02:22 -0500 Subject: [PATCH 11/42] wayland: Use wayland-egl --- gdk/wayland/gdkdisplay-wayland.c | 65 +++++++------------------------- gdk/wayland/gdkdisplay-wayland.h | 10 ++--- gdk/wayland/gdkwindow-wayland.c | 40 +++++++------------- 3 files changed, 31 insertions(+), 84 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index cb99a382be..1b74068493 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -40,7 +40,7 @@ #include "gdkdevicemanager-wayland.h" #include "gdkkeysprivate.h" -#include +#include typedef struct _GdkEventTypeWayland GdkEventTypeWayland; @@ -120,28 +120,6 @@ gdk_input_init (GdkDisplay *display) g_list_free (list); } -static void -drm_handle_device(void *data, struct wl_drm *compositor, const char *device) -{ - GdkDisplayWayland *display_wayland = data; - - fprintf(stderr, "display name: %s\n", device); - - display_wayland->device_name = g_strdup (device); -} - -static void drm_handle_authenticated(void *data, struct wl_drm *drm) -{ - GdkDisplayWayland *display_wayland = data; - - display_wayland->authenticated = TRUE; -} - -static const struct wl_drm_listener drm_listener = { - drm_handle_device, - drm_handle_authenticated -}; - static void shell_handle_configure(void *data, struct wl_shell *shell, uint32_t time, uint32_t edges, @@ -205,10 +183,6 @@ gdk_display_handle_global(struct wl_display *display, uint32_t id, if (strcmp(interface, "compositor") == 0) { display_wayland->compositor = wl_compositor_create(display, id); - } else if (strcmp(interface, "drm") == 0) { - display_wayland->drm = wl_drm_create(display, id); - wl_drm_add_listener(display_wayland->drm, - &drm_listener, display_wayland); } else if (strcmp(interface, "shell") == 0) { display_wayland->shell = wl_shell_create(display, id); wl_shell_add_listener(display_wayland->shell, @@ -228,36 +202,17 @@ gdk_display_init_egl(GdkDisplay *display) { GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (display); EGLint major, minor, i; - drm_magic_t magic; void *p; static const struct { const char *f; unsigned int offset; } extension_functions[] = { - { "eglCreateDRMImageMESA", offsetof(GdkDisplayWayland, create_drm_image) }, { "glEGLImageTargetTexture2DOES", offsetof(GdkDisplayWayland, image_target_texture_2d) }, - { "eglExportDRMImageMESA", offsetof(GdkDisplayWayland, export_drm_image) }, + { "eglCreateImageKHR", offsetof(GdkDisplayWayland, create_image) }, { "eglDestroyImageKHR", offsetof(GdkDisplayWayland, destroy_image) } }; - display_wayland->fd = open(display_wayland->device_name, O_RDWR); - if (display_wayland->fd < 0) { - fprintf(stderr, "drm open failed: %m\n"); - return FALSE; - } - - if (drmGetMagic(display_wayland->fd, &magic)) - { - fprintf(stderr, "DRI2: failed to get drm magic"); - return FALSE; - } - - /* Authenticate and wait for authenticated event */ - wl_drm_authenticate(display_wayland->drm, magic); - wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_WRITABLE); - while (!display_wayland->authenticated) - wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE); - - display_wayland->egl_display = eglGetDRMDisplayMESA(display_wayland->fd); + display_wayland->egl_display = + eglGetDisplay((EGLNativeDisplayType) display_wayland->native_display); if (!eglInitialize(display_wayland->egl_display, &major, &minor)) { fprintf(stderr, "failed to initialize display\n"); return FALSE; @@ -318,6 +273,12 @@ _gdk_wayland_display_open (const gchar *display_name) display_wayland->wl_display = wl_display; + display_wayland->native_display = wl_egl_display_create(wl_display); + if (display_wayland->native_display == NULL) { + wl_display_destroy(wl_display); + return NULL; + } + /* initialize the display's screens */ display_wayland->screens = g_new (GdkScreen *, 1); for (i = 0; i < 1; i++) @@ -332,9 +293,6 @@ _gdk_wayland_display_open (const gchar *display_name) wl_display_add_global_listener(display_wayland->wl_display, gdk_display_handle_global, display_wayland); - /* Process connection events. */ - wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE); - gdk_display_init_egl(display); display_wayland->event_source = _gdk_wayland_display_event_source_new (display); @@ -369,6 +327,9 @@ gdk_wayland_display_dispose (GObject *object) display_wayland->event_source = NULL; } + eglTerminate(display_wayland->egl_display); + wl_egl_display_destroy(display_wayland->native_display); + G_OBJECT_CLASS (_gdk_display_wayland_parent_class)->dispose (object); } diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index d9dceaa195..d7de0f0832 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -139,23 +141,19 @@ struct _GdkDisplayWayland GdkWindow *active_offscreen_window; /* Wayland fields below */ - char *device_name; struct wl_display *wl_display; - struct wl_drm *drm; + struct wl_egl_display *native_display; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_output *output; struct wl_input_device *input_device; GSource *event_source; - int fd; EGLDisplay egl_display; EGLContext egl_context; cairo_device_t *cairo_device; - int authenticated; - PFNEGLCREATEDRMIMAGEMESA create_drm_image; - PFNEGLEXPORTDRMIMAGEMESA export_drm_image; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; + PFNEGLCREATEIMAGEKHRPROC create_image; PFNEGLDESTROYIMAGEKHRPROC destroy_image; }; diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 7859e3fb19..419ba046e5 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -40,6 +40,8 @@ #include #include +#include + #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \ (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) @@ -295,6 +297,7 @@ static const cairo_user_data_key_t gdk_wayland_cairo_key; typedef struct _GdkWaylandCairoSurfaceData { EGLImageKHR image; GLuint texture; + struct wl_egl_pixmap *pixmap; struct wl_buffer *buffer; GdkDisplayWayland *display; } GdkWaylandCairoSurfaceData; @@ -304,24 +307,12 @@ _gdk_wayland_surface_get_buffer (GdkDisplayWayland *display, cairo_surface_t *surface) { GdkWaylandCairoSurfaceData *data; - EGLint name, stride; - struct wl_visual *visual; - int width, height; data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); - if (data->buffer) - return data->buffer; - - visual = - wl_display_get_premultiplied_argb_visual(display->wl_display); - - width = cairo_gl_surface_get_width (surface); - height = cairo_gl_surface_get_height (surface); - display->export_drm_image (display->egl_display, - data->image, &name, NULL, &stride); - data->buffer = wl_drm_create_buffer(display->drm, - name, width, height, stride, visual); + if (!data->buffer) + data->buffer = + wl_egl_pixmap_create_buffer(display->native_display, data->pixmap); return data->buffer; } @@ -387,21 +378,18 @@ gdk_wayland_create_cairo_surface (GdkDisplayWayland *display, { GdkWaylandCairoSurfaceData *data; 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 - }; + struct wl_visual *visual; data = g_new (GdkWaylandCairoSurfaceData, 1); data->display = display; data->buffer = NULL; - image_attribs[1] = width; - image_attribs[3] = height; - data->image = display->create_drm_image(display->egl_display, image_attribs); + visual = wl_display_get_premultiplied_argb_visual(display->wl_display); + data->pixmap = + wl_egl_pixmap_create(display->native_display, width, height, visual, 0); + data->image = + display->create_image(display->egl_display, NULL, EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer) data->pixmap, NULL); + glGenTextures(1, &data->texture); glBindTexture(GL_TEXTURE_2D, data->texture); display->image_target_texture_2d(GL_TEXTURE_2D, data->image); From 3ef34335119d408fe621d4e8f9b6a902b540a5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 9 Feb 2011 14:48:29 -0500 Subject: [PATCH 12/42] wayland: Support setting cursors And a handful unrelated cleanups. Still doesn't really have an answer for cursor themes. --- configure.ac | 2 +- gdk/wayland/Makefile.am | 1 - gdk/wayland/gdkcursor-wayland.c | 185 +++++++++++++++++++++++-- gdk/wayland/gdkdevice-wayland.c | 13 ++ gdk/wayland/gdkdevice-wayland.h | 1 + gdk/wayland/gdkdevicemanager-wayland.c | 9 +- gdk/wayland/gdkdisplay-wayland.c | 37 ++--- gdk/wayland/gdkdisplay-wayland.h | 65 +-------- gdk/wayland/gdkeventsource.c | 2 +- gdk/wayland/gdkeventsource.h | 44 ------ gdk/wayland/gdkprivate-wayland.h | 4 + gdk/wayland/gdkscreen-wayland.c | 7 - gdk/wayland/gdkwindow-wayland.c | 1 - gdk/wayland/gdkwindow-wayland.h | 7 +- 14 files changed, 217 insertions(+), 161 deletions(-) delete mode 100644 gdk/wayland/gdkeventsource.h diff --git a/configure.ac b/configure.ac index d33aeec6c2..1b13ba3942 100644 --- a/configure.ac +++ b/configure.ac @@ -356,7 +356,7 @@ if test "x$enable_wayland_backend" == "xyes"; then GIO_PACKAGE=gio-unix-2.0 GDK_WINDOWING="$GDK_WINDOWING #define GDK_WINDOWING_WAYLAND" - WAYLAND_PACKAGES="wayland-client xkbcommon" + WAYLAND_PACKAGES="wayland-client xkbcommon wayland-egl" AM_CONDITIONAL(USE_WAYLAND, true) else AM_CONDITIONAL(USE_WAYLAND, false) diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am index 0696483b52..e39bcb003c 100644 --- a/gdk/wayland/Makefile.am +++ b/gdk/wayland/Makefile.am @@ -29,7 +29,6 @@ libgdk_wayland_la_SOURCES = \ gdkdisplaymanager-wayland.c \ gdkdnd-wayland.c \ gdkeventsource.c \ - gdkeventsource.h \ gdkkeys-wayland.c \ gdkscreen-wayland.c \ gdkscreen-wayland.h \ diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index 468be5296b..c633411c07 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -36,6 +36,8 @@ #include "gdkwayland.h" #include +#include + #define GDK_TYPE_WAYLAND_CURSOR (_gdk_wayland_cursor_get_type ()) #define GDK_WAYLAND_CURSOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursor)) #define GDK_WAYLAND_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursorClass)) @@ -51,6 +53,9 @@ struct _GdkWaylandCursor GdkCursor cursor; gchar *name; guint serial; + int x, y, width, height, size; + void *map; + struct wl_buffer *buffer; }; struct _GdkWaylandCursorClass @@ -78,6 +83,17 @@ gdk_wayland_cursor_get_image (GdkCursor *cursor) return NULL; } +struct wl_buffer * +_gdk_wayland_cursor_get_buffer (GdkCursor *cursor, int *x, int *y) +{ + GdkWaylandCursor *wayland_cursor = GDK_WAYLAND_CURSOR (cursor); + + *x = wayland_cursor->x; + *y = wayland_cursor->y; + + return wayland_cursor->buffer; +} + static void _gdk_wayland_cursor_class_init (GdkWaylandCursorClass *wayland_cursor_class) { @@ -94,20 +110,171 @@ _gdk_wayland_cursor_init (GdkWaylandCursor *cursor) { } -GdkCursor* +static void +set_pixbuf (GdkWaylandCursor *cursor, GdkPixbuf *pixbuf) +{ + int stride, i, n_channels; + unsigned char *pixels, *end, *argb_pixels, *s, *d; + + stride = gdk_pixbuf_get_rowstride(pixbuf); + pixels = gdk_pixbuf_get_pixels(pixbuf); + n_channels = gdk_pixbuf_get_n_channels(pixbuf); + argb_pixels = cursor->map; + +#define MULT(_d,c,a,t) \ + do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0) + + if (n_channels == 4) + { + for (i = 0; i < cursor->height; i++) + { + s = pixels + i * stride; + end = s + cursor->width * 4; + d = argb_pixels + i * cursor->width * 4; + while (s < end) + { + unsigned int t; + + MULT(d[0], s[2], s[3], t); + MULT(d[1], s[1], s[3], t); + MULT(d[2], s[0], s[3], t); + d[3] = s[3]; + s += 4; + d += 4; + } + } + } + else if (n_channels == 3) + { + for (i = 0; i < cursor->height; i++) + { + s = pixels + i * stride; + end = s + cursor->width * 3; + d = argb_pixels + i * cursor->width * 4; + while (s < end) + { + d[0] = s[2]; + d[1] = s[1]; + d[2] = s[0]; + d[3] = 0xff; + s += 3; + d += 4; + } + } + } +} + +static GdkCursor * +create_cursor(GdkDisplayWayland *display, GdkPixbuf *pixbuf, int x, int y) +{ + GdkWaylandCursor *cursor; + struct wl_visual *visual; + int stride, fd; + char *filename; + GError *error = NULL; + + cursor = g_object_new (GDK_TYPE_WAYLAND_CURSOR, + "cursor-type", GDK_CURSOR_IS_PIXMAP, + "display", display, + NULL); + cursor->name = NULL; + cursor->serial = theme_serial; + cursor->x = x; + cursor->y = y; + cursor->width = gdk_pixbuf_get_width (pixbuf); + cursor->height = gdk_pixbuf_get_height (pixbuf); + + stride = cursor->width * 4; + cursor->size = stride * cursor->height; + + fd = g_file_open_tmp("wayland-shm-XXXXXX", &filename, &error); + if (fd < 0) { + fprintf(stderr, "g_file_open_tmp failed: %s\n", error->message); + g_error_free (error); + return NULL; + } + + unlink (filename); + g_free (filename); + + if (ftruncate(fd, cursor->size) < 0) { + fprintf(stderr, "ftruncate failed: %m\n"); + close(fd); + return NULL; + } + + cursor->map = mmap(NULL, cursor->size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (cursor->map == MAP_FAILED) { + fprintf(stderr, "mmap failed: %m\n"); + close(fd); + return NULL; + } + + set_pixbuf (cursor, pixbuf); + + visual = wl_display_get_premultiplied_argb_visual(display->wl_display); + cursor->buffer = wl_shm_create_buffer(display->shm, + fd, + cursor->width, + cursor->height, + stride, visual); + + close(fd); + + return GDK_CURSOR (cursor); +} + +#define DATADIR "/usr/share/wayland" + +static const struct { + GdkCursorType type; + const char *filename; + int hotspot_x, hotspot_y; +} cursor_definitions[] = { + { GDK_XTERM, DATADIR "/xterm.png", 15, 15 }, + { GDK_BOTTOM_RIGHT_CORNER, DATADIR "/bottom_right_corner.png", 28, 28 } +}; + +GdkCursor * _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, GdkCursorType cursor_type) { - GdkWaylandCursor *private; + GdkDisplayWayland *wayland_display; + GdkPixbuf *pixbuf; + GError *error = NULL; + int i; - private = g_object_new (GDK_TYPE_WAYLAND_CURSOR, - "cursor-type", GDK_CURSOR_IS_PIXMAP, - "display", display, - NULL); - private->name = NULL; - private->serial = theme_serial; + for (i = 0; i < G_N_ELEMENTS (cursor_definitions); i++) + { + if (cursor_definitions[i].type == cursor_type) + break; + } - return GDK_CURSOR (private); + if (i == G_N_ELEMENTS (cursor_definitions)) + return NULL; + + wayland_display = GDK_DISPLAY_WAYLAND (display); + if (!wayland_display->cursors) + wayland_display->cursors = + g_new0 (GdkCursor *, G_N_ELEMENTS(cursor_definitions)); + if (wayland_display->cursors[i]) + return g_object_ref (wayland_display->cursors[i]); + + pixbuf = gdk_pixbuf_new_from_file(cursor_definitions[i].filename, &error); + if (error != NULL) + { + g_error_free(error); + return NULL; + } + + wayland_display->cursors[i] = + create_cursor(wayland_display, pixbuf, + cursor_definitions[i].hotspot_x, + cursor_definitions[i].hotspot_y); + g_object_unref (pixbuf); + + return g_object_ref (wayland_display->cursors[i]); } GdkCursor* diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index fcdc54bf74..c46ca1c29a 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -131,6 +131,19 @@ gdk_device_core_set_window_cursor (GdkDevice *device, GdkWindow *window, GdkCursor *cursor) { + GdkWaylandDevice *wd = GDK_DEVICE_CORE(device)->device; + struct wl_buffer *buffer; + int x, y; + + if (cursor) + { + buffer = _gdk_wayland_cursor_get_buffer(cursor, &x, &y); + wl_input_device_attach(wd->device, wd->time, buffer, x, y); + } + else + { + wl_input_device_attach(wd->device, wd->time, NULL, 0, 0); + } } static void diff --git a/gdk/wayland/gdkdevice-wayland.h b/gdk/wayland/gdkdevice-wayland.h index a8d4dd99d0..ce631c062d 100644 --- a/gdk/wayland/gdkdevice-wayland.h +++ b/gdk/wayland/gdkdevice-wayland.h @@ -46,6 +46,7 @@ struct _GdkWaylandDevice GdkWindow *keyboard_focus; struct wl_input_device *device; int32_t x, y, surface_x, surface_y; + uint32_t time; }; struct _GdkDeviceCore diff --git a/gdk/wayland/gdkdevicemanager-wayland.c b/gdk/wayland/gdkdevicemanager-wayland.c index d1543f9a70..5c9a3b348e 100644 --- a/gdk/wayland/gdkdevicemanager-wayland.c +++ b/gdk/wayland/gdkdevicemanager-wayland.c @@ -26,9 +26,9 @@ #include "gdkdevice-wayland.h" #include "gdkkeysyms.h" #include "gdkprivate-wayland.h" -#include "gdkeventsource.h" #include +#include static void gdk_device_manager_core_finalize (GObject *object); @@ -59,6 +59,7 @@ input_handle_motion(void *data, struct wl_input_device *input_device, event = gdk_event_new (GDK_NOTHING); + device->time = time; device->x = x; device->y = y; device->surface_x = sx; @@ -89,6 +90,7 @@ input_handle_button(void *data, struct wl_input_device *input_device, fprintf (stderr, "button event %d, state %d\n", button, state); + device->time = time; event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); event->button.window = g_object_ref (device->pointer_focus); gdk_event_set_device (event, device->pointer); @@ -120,6 +122,7 @@ input_handle_key(void *data, struct wl_input_device *input_device, struct xkb_desc *xkb; GdkKeymap *keymap; + device->time = time; event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); event->key.window = g_object_ref (device->keyboard_focus); gdk_event_set_device (event, device->keyboard); @@ -134,7 +137,7 @@ input_handle_key(void *data, struct wl_input_device *input_device, code = key + xkb->min_key_code; level = 0; - if (device->modifiers & ShiftMask && + if (device->modifiers & XKB_COMMON_SHIFT_MASK && XkbKeyGroupWidth(xkb, code, 0) > 1) level = 1; @@ -216,6 +219,7 @@ input_handle_pointer_focus(void *data, GdkWaylandDevice *device = data; GdkEvent *event; + device->time = time; if (device->pointer_focus) { event = gdk_event_new (GDK_LEAVE_NOTIFY); @@ -300,6 +304,7 @@ input_handle_keyboard_focus(void *data, fprintf (stderr, "keyboard focus surface %p\n", surface); + device->time = time; if (device->keyboard_focus) { event = gdk_event_new (GDK_FOCUS_CHANGE); diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 1b74068493..45184b0f00 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -17,10 +17,10 @@ * Boston, MA 02111-1307, USA. */ -#define EGL_EGLEXT_PROTOTYPES 1 - #include "config.h" +#include + #include #include #include @@ -31,7 +31,6 @@ #include "gdkwayland.h" #include "gdkdisplay.h" #include "gdkdisplay-wayland.h" -#include "gdkeventsource.h" #include "gdkscreen.h" #include "gdkscreen-wayland.h" #include "gdkinternals.h" @@ -40,8 +39,6 @@ #include "gdkdevicemanager-wayland.h" #include "gdkkeysprivate.h" -#include - typedef struct _GdkEventTypeWayland GdkEventTypeWayland; struct _GdkEventTypeWayland @@ -183,6 +180,8 @@ gdk_display_handle_global(struct wl_display *display, uint32_t id, if (strcmp(interface, "compositor") == 0) { display_wayland->compositor = wl_compositor_create(display, id); + } else if (strcmp(interface, "shm") == 0) { + display_wayland->shm = wl_shm_create(display, id); } else if (strcmp(interface, "shell") == 0) { display_wayland->shell = wl_shell_create(display, id); wl_shell_add_listener(display_wayland->shell, @@ -212,7 +211,7 @@ gdk_display_init_egl(GdkDisplay *display) }; display_wayland->egl_display = - eglGetDisplay((EGLNativeDisplayType) display_wayland->native_display); + eglGetDisplay(display_wayland->native_display); if (!eglInitialize(display_wayland->egl_display, &major, &minor)) { fprintf(stderr, "failed to initialize display\n"); return FALSE; @@ -300,8 +299,7 @@ _gdk_wayland_display_open (const gchar *display_name) gdk_input_init (display); g_signal_emit_by_name (display, "opened"); - g_signal_emit_by_name (gdk_display_manager_get(), - "display_opened", display); + g_signal_emit_by_name (gdk_display_manager_get(), "display_opened", display); return display; } @@ -343,18 +341,6 @@ gdk_wayland_display_finalize (GObject *object) if (display_wayland->keymap) g_object_unref (display_wayland->keymap); - /* Atom Hashtable */ - g_hash_table_destroy (display_wayland->atom_from_virtual); - g_hash_table_destroy (display_wayland->atom_to_virtual); - - /* list of filters for client messages */ - g_list_foreach (display_wayland->client_filters, (GFunc) g_free, NULL); - g_list_free (display_wayland->client_filters); - - /* List of event window extraction functions */ - g_slist_foreach (display_wayland->event_types, (GFunc)g_free, NULL); - g_slist_free (display_wayland->event_types); - /* input GdkDevice list */ g_list_foreach (display_wayland->input_devices, (GFunc) g_object_unref, NULL); g_list_free (display_wayland->input_devices); @@ -370,9 +356,6 @@ gdk_wayland_display_finalize (GObject *object) g_free (display_wayland->startup_notification_id); - /* X ID hashtable */ - g_hash_table_destroy (display_wayland->xid_ht); - G_OBJECT_CLASS (_gdk_display_wayland_parent_class)->finalize (object); } @@ -464,9 +447,7 @@ gdk_wayland_display_get_default_group (GdkDisplay *display) static gboolean gdk_wayland_display_supports_selection_notification (GdkDisplay *display) { - GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (display); - - return display_wayland->have_xfixes; + return TRUE; } static gboolean @@ -495,13 +476,13 @@ gdk_wayland_display_store_clipboard (GdkDisplay *display, static gboolean gdk_wayland_display_supports_shapes (GdkDisplay *display) { - return GDK_DISPLAY_WAYLAND (display)->have_shapes; + return TRUE; } static gboolean gdk_wayland_display_supports_input_shapes (GdkDisplay *display) { - return GDK_DISPLAY_WAYLAND (display)->have_input_shapes; + return TRUE; } static gboolean diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index d7de0f0832..ebe67d6480 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -60,61 +61,12 @@ struct _GdkDisplayWayland gint grab_count; /* Keyboard related information */ - - gint xkb_event_type; - gboolean use_xkb; - - /* Whether we were able to turn on detectable-autorepeat using - * XkbSetDetectableAutorepeat. If FALSE, we'll fall back - * to checking the next event with XPending(). */ - gboolean have_xkb_autorepeat; - GdkKeymap *keymap; guint keymap_serial; - gboolean have_xfixes; - gint xfixes_event_base; - - gboolean have_xcomposite; - gboolean have_xdamage; - gint xdamage_event_base; - - gboolean have_randr13; - gint xrandr_event_base; - - /* If the SECURITY extension is in place, whether this client holds - * a trusted authorization and so is allowed to make various requests - * (grabs, properties etc.) Otherwise always TRUE. */ - gboolean trusted_client; - /* drag and drop information */ GdkDragContext *current_dest_drag; - /* data needed for MOTIF DnD */ - - Window motif_drag_window; - GdkWindow *motif_drag_gdk_window; - GList **motif_target_lists; - gint motif_n_target_lists; - - /* Mapping to/from virtual atoms */ - - GHashTable *atom_from_virtual; - GHashTable *atom_to_virtual; - - /* list of filters for client messages */ - GList *client_filters; - - /* List of functions to go from extension event => X window */ - GSList *event_types; - - /* X ID hashtable */ - GHashTable *xid_ht; - - /* translation queue */ - GQueue *translate_queue; - - /* Input device */ /* input GdkDevice list */ GList *input_devices; @@ -127,16 +79,6 @@ struct _GdkDisplayWayland /* Time of most recent user interaction. */ gulong user_time; - /* Sets of atoms for DND */ - guint base_dnd_atoms_precached : 1; - guint xdnd_atoms_precached : 1; - guint motif_atoms_precached : 1; - guint use_sync : 1; - - guint have_shapes : 1; - guint have_input_shapes : 1; - gint shape_event_base; - /* The offscreen window that has the pointer in it (if any) */ GdkWindow *active_offscreen_window; @@ -144,6 +86,7 @@ struct _GdkDisplayWayland struct wl_display *wl_display; struct wl_egl_display *native_display; struct wl_compositor *compositor; + struct wl_shm *shm; struct wl_shell *shell; struct wl_output *output; struct wl_input_device *input_device; @@ -152,6 +95,8 @@ struct _GdkDisplayWayland EGLContext egl_context; cairo_device_t *cairo_device; + GdkCursor **cursors; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; PFNEGLCREATEIMAGEKHRPROC create_image; PFNEGLDESTROYIMAGEKHRPROC destroy_image; @@ -163,8 +108,6 @@ struct _GdkDisplayWaylandClass }; GType _gdk_display_wayland_get_type (void); -GdkScreen *_gdk_wayland_display_screen_for_xrootwin (GdkDisplay *display, - Window xrootwin); G_END_DECLS diff --git a/gdk/wayland/gdkeventsource.c b/gdk/wayland/gdkeventsource.c index 553cc35804..b48e880107 100644 --- a/gdk/wayland/gdkeventsource.c +++ b/gdk/wayland/gdkeventsource.c @@ -19,8 +19,8 @@ #include "config.h" -#include "gdkeventsource.h" #include "gdkinternals.h" +#include "gdkprivate-wayland.h" typedef struct _GdkWaylandEventSource { GSource source; diff --git a/gdk/wayland/gdkeventsource.h b/gdk/wayland/gdkeventsource.h deleted file mode 100644 index 65a7ca3e78..0000000000 --- a/gdk/wayland/gdkeventsource.h +++ /dev/null @@ -1,44 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 2009 Carlos Garnacho - * - * 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. - */ - -#ifndef __GDK_EVENT_SOURCE_H__ -#define __GDK_EVENT_SOURCE_H__ - -#include "gdkprivate-wayland.h" - -G_BEGIN_DECLS - -typedef struct _GdkEventSource GdkEventSource; - -G_GNUC_INTERNAL -GSource * gdk_event_source_new (GdkDisplay *display); - -G_GNUC_INTERNAL -void gdk_event_source_select_events (GdkEventSource *source, - Window window, - GdkEventMask event_mask, - unsigned int extra_x_mask); - -G_GNUC_INTERNAL -void _gdk_deliver_event (GdkDisplay *display, GdkEvent *event); - - -G_END_DECLS - -#endif /* __GDK_EVENT_SOURCE_H__ */ diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index bc5c6ed393..da215a121d 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -67,6 +67,10 @@ void _gdk_wayland_display_get_maximal_cursor_size (GdkDisplay *display, gboolean _gdk_wayland_display_supports_cursor_alpha (GdkDisplay *display); gboolean _gdk_wayland_display_supports_cursor_color (GdkDisplay *display); +struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkCursor *cursor, + int *x, + int *y); + GdkDragProtocol _gdk_wayland_window_get_drag_protocol (GdkWindow *window, GdkWindow **target); diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c index 09adafbb63..e7dbaba0ac 100644 --- a/gdk/wayland/gdkscreen-wayland.c +++ b/gdk/wayland/gdkscreen-wayland.c @@ -53,8 +53,6 @@ struct _GdkScreenWayland int width_mm, height_mm; /* Window manager */ - long last_wmspec_check_time; - Window wmspec_check_window; char *window_manager_name; /* TRUE if wmspec_check_window has changed since last * fetch of _NET_SUPPORTED @@ -99,7 +97,6 @@ struct _GdkScreenWaylandClass struct _GdkWaylandMonitor { GdkRectangle geometry; - XID output; int width_mm; int height_mm; char * output_name; @@ -117,7 +114,6 @@ init_monitor_geometry (GdkWaylandMonitor *monitor, monitor->geometry.width = width; monitor->geometry.height = height; - monitor->output = None; monitor->width_mm = -1; monitor->height_mm = -1; monitor->output_name = NULL; @@ -173,8 +169,6 @@ gdk_wayland_screen_dispose (GObject *object) _gdk_window_destroy (screen_wayland->root_window, TRUE); G_OBJECT_CLASS (_gdk_screen_wayland_parent_class)->dispose (object); - - screen_wayland->wmspec_check_window = None; } static void @@ -511,7 +505,6 @@ _gdk_wayland_screen_new (GdkDisplay *display) screen_wayland = GDK_SCREEN_WAYLAND (screen); screen_wayland->display = display; - screen_wayland->wmspec_check_window = None; /* we want this to be always non-null */ screen_wayland->window_manager_name = g_strdup ("unknown"); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 419ba046e5..d0cd39e954 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -34,7 +34,6 @@ #include "gdkwindow-wayland.h" #include "gdkdeviceprivate.h" #include "gdkdevice-wayland.h" -#include "gdkeventsource.h" #include #include diff --git a/gdk/wayland/gdkwindow-wayland.h b/gdk/wayland/gdkwindow-wayland.h index 73d7ec61ba..5b63f88b19 100644 --- a/gdk/wayland/gdkwindow-wayland.h +++ b/gdk/wayland/gdkwindow-wayland.h @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -82,12 +83,6 @@ struct _GdkToplevelWayland /* Time of most recent user interaction. */ gulong user_time; - - /* We use an extra X window for toplevel windows that we XSetInputFocus() - * to in order to avoid getting keyboard events redirected to subwindows - * that might not even be part of this app - */ - Window focus_window; }; GType _gdk_window_impl_wayland_get_type (void); From c36dfccc64296d0e0d504f983f4bc3c6e1539f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 9 Feb 2011 15:27:08 -0500 Subject: [PATCH 13/42] wayland: Consolidate device and devicemanager implementation --- gdk/wayland/Makefile.am | 3 - gdk/wayland/gdkdevice-wayland.c | 574 ++++++++++++++++++++++--- gdk/wayland/gdkdevice-wayland.h | 68 --- gdk/wayland/gdkdevicemanager-wayland.c | 451 ------------------- gdk/wayland/gdkdevicemanager-wayland.h | 59 --- gdk/wayland/gdkdisplay-wayland.c | 6 +- gdk/wayland/gdkprivate-wayland.h | 5 +- gdk/wayland/gdkwindow-wayland.c | 5 +- 8 files changed, 517 insertions(+), 654 deletions(-) delete mode 100644 gdk/wayland/gdkdevice-wayland.h delete mode 100644 gdk/wayland/gdkdevicemanager-wayland.c delete mode 100644 gdk/wayland/gdkdevicemanager-wayland.h diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am index e39bcb003c..3466311853 100644 --- a/gdk/wayland/Makefile.am +++ b/gdk/wayland/Makefile.am @@ -20,10 +20,7 @@ noinst_LTLIBRARIES = \ libgdk_wayland_la_SOURCES = \ gdkapplaunchcontext-wayland.c \ gdkcursor-wayland.c \ - gdkdevice-wayland.h \ gdkdevice-wayland.c \ - gdkdevicemanager-wayland.h \ - gdkdevicemanager-wayland.c \ gdkdisplay-wayland.c \ gdkdisplay-wayland.h \ gdkdisplaymanager-wayland.c \ diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index c46ca1c29a..a2bc8e520b 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -19,84 +19,81 @@ #include "config.h" +#include #include -#include "gdkdevice-wayland.h" +#include #include "gdkprivate-wayland.h" #include "gdkwayland.h" +#include "gdkkeysyms.h" +#include "gdkdeviceprivate.h" +#include "gdkdevicemanagerprivate.h" +#include "gdkprivate-wayland.h" -static gboolean gdk_device_core_get_history (GdkDevice *device, - GdkWindow *window, - guint32 start, - guint32 stop, - GdkTimeCoord ***events, - gint *n_events); -static void gdk_device_core_get_state (GdkDevice *device, - GdkWindow *window, - gdouble *axes, - GdkModifierType *mask); -static void gdk_device_core_set_window_cursor (GdkDevice *device, - GdkWindow *window, - GdkCursor *cursor); -static void gdk_device_core_warp (GdkDevice *device, - GdkScreen *screen, - gint x, - gint y); -static gboolean gdk_device_core_query_state (GdkDevice *device, - GdkWindow *window, - GdkWindow **root_window, - GdkWindow **child_window, - gint *root_x, - gint *root_y, - gint *win_x, - gint *win_y, - GdkModifierType *mask); -static GdkGrabStatus gdk_device_core_grab (GdkDevice *device, - GdkWindow *window, - gboolean owner_events, - GdkEventMask event_mask, - GdkWindow *confine_to, - GdkCursor *cursor, - guint32 time_); -static void gdk_device_core_ungrab (GdkDevice *device, - guint32 time_); -static GdkWindow * gdk_device_core_window_at_position (GdkDevice *device, - gint *win_x, - gint *win_y, - GdkModifierType *mask, - gboolean get_toplevel); -static void gdk_device_core_select_window_events (GdkDevice *device, - GdkWindow *window, - GdkEventMask event_mask); +#include +#include +#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ()) +#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore)) +#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) +#define GDK_IS_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE)) +#define GDK_IS_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE)) +#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) + +typedef struct _GdkDeviceCore GdkDeviceCore; +typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass; +typedef struct _GdkWaylandDevice GdkWaylandDevice; + +struct _GdkWaylandDevice +{ + GdkDisplay *display; + GdkDevice *pointer; + GdkDevice *keyboard; + GdkModifierType modifiers; + GdkWindow *pointer_focus; + GdkWindow *keyboard_focus; + struct wl_input_device *device; + int32_t x, y, surface_x, surface_y; + uint32_t time; +}; + +struct _GdkDeviceCore +{ + GdkDevice parent_instance; + GdkWaylandDevice *device; +}; + +struct _GdkDeviceCoreClass +{ + GdkDeviceClass parent_class; +}; G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE) -static void -gdk_device_core_class_init (GdkDeviceCoreClass *klass) +#define GDK_TYPE_DEVICE_MANAGER_CORE (gdk_device_manager_core_get_type ()) +#define GDK_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore)) +#define GDK_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) +#define GDK_IS_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE)) +#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE)) +#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) + +typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore; +typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass; + +struct _GdkDeviceManagerCore { - GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + GdkDeviceManager parent_object; + GdkDevice *core_pointer; + GdkDevice *core_keyboard; + GList *devices; +}; - device_class->get_history = gdk_device_core_get_history; - device_class->get_state = gdk_device_core_get_state; - device_class->set_window_cursor = gdk_device_core_set_window_cursor; - device_class->warp = gdk_device_core_warp; - device_class->query_state = gdk_device_core_query_state; - device_class->grab = gdk_device_core_grab; - device_class->ungrab = gdk_device_core_ungrab; - device_class->window_at_position = gdk_device_core_window_at_position; - device_class->select_window_events = gdk_device_core_select_window_events; -} - -static void -gdk_device_core_init (GdkDeviceCore *device_core) +struct _GdkDeviceManagerCoreClass { - GdkDevice *device; + GdkDeviceManagerClass parent_class; +}; - device = GDK_DEVICE (device_core); - - _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1); - _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1); -} +G_DEFINE_TYPE (GdkDeviceManagerCore, + gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER) static gboolean gdk_device_core_get_history (GdkDevice *device, @@ -227,3 +224,448 @@ gdk_device_core_select_window_events (GdkDevice *device, GdkEventMask event_mask) { } + +static void +gdk_device_core_class_init (GdkDeviceCoreClass *klass) +{ + GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + + device_class->get_history = gdk_device_core_get_history; + device_class->get_state = gdk_device_core_get_state; + device_class->set_window_cursor = gdk_device_core_set_window_cursor; + device_class->warp = gdk_device_core_warp; + device_class->query_state = gdk_device_core_query_state; + device_class->grab = gdk_device_core_grab; + device_class->ungrab = gdk_device_core_ungrab; + device_class->window_at_position = gdk_device_core_window_at_position; + device_class->select_window_events = gdk_device_core_select_window_events; +} + +static void +gdk_device_core_init (GdkDeviceCore *device_core) +{ + GdkDevice *device; + + device = GDK_DEVICE (device_core); + + _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1); + _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1); +} + +struct wl_input_device * +_gdk_wayland_device_get_device (GdkDevice *device) +{ + GDK_DEVICE_CORE (device)->device->device; +} + +static void +input_handle_motion(void *data, struct wl_input_device *input_device, + uint32_t time, + int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + event = gdk_event_new (GDK_NOTHING); + + device->time = time; + device->x = x; + device->y = y; + device->surface_x = sx; + device->surface_y = sy; + + event->motion.type = GDK_MOTION_NOTIFY; + event->motion.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->motion.time = time; + event->motion.x = (gdouble) sx; + event->motion.y = (gdouble) sy; + event->motion.x_root = (gdouble) x; + event->motion.y_root = (gdouble) y; + event->motion.axes = NULL; + event->motion.state = device->modifiers; + event->motion.is_hint = 0; + + _gdk_wayland_display_deliver_event (device->display, event); +} + +static void +input_handle_button(void *data, struct wl_input_device *input_device, + uint32_t time, uint32_t button, uint32_t state) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + uint32_t modifier; + + fprintf (stderr, "button event %d, state %d\n", button, state); + + device->time = time; + event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); + event->button.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->button.time = time; + event->button.x = (gdouble) device->surface_x; + event->button.y = (gdouble) device->surface_y; + event->button.x_root = (gdouble) device->x; + event->button.y_root = (gdouble) device->y; + event->button.axes = NULL; + event->button.state = device->modifiers; + event->button.button = button - 271; + + modifier = 1 << (8 + button - 272); + if (state) + device->modifiers |= modifier; + else + device->modifiers &= ~modifier; + + _gdk_wayland_display_deliver_event (device->display, event); +} + +static void +input_handle_key(void *data, struct wl_input_device *input_device, + uint32_t time, uint32_t key, uint32_t state) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + uint32_t code, modifier, level; + struct xkb_desc *xkb; + GdkKeymap *keymap; + + device->time = time; + event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); + event->key.window = g_object_ref (device->keyboard_focus); + gdk_event_set_device (event, device->keyboard); + event->button.time = time; + event->key.state = device->modifiers; + event->key.group = 0; + event->key.hardware_keycode = key; + + keymap = gdk_keymap_get_for_display (device->display); + xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); + + code = key + xkb->min_key_code; + + level = 0; + if (device->modifiers & XKB_COMMON_SHIFT_MASK && + XkbKeyGroupWidth(xkb, code, 0) > 1) + level = 1; + + event->key.keyval = XkbKeySymEntry(xkb, code, level, 0); + + modifier = xkb->map->modmap[code]; + if (state) + device->modifiers |= modifier; + else + device->modifiers &= ~modifier; + + event->key.is_modifier = modifier > 0; + + if (event->key.keyval == GDK_KEY_Escape) + { + event->key.length = 1; + event->key.string = g_strdup ("\033"); + } + else if (event->key.keyval == GDK_KEY_Return || + event->key.keyval == GDK_KEY_KP_Enter) + { + event->key.length = 1; + event->key.string = g_strdup ("\r"); + } + else if (event->key.state & GDK_CONTROL_MASK) + { + gsize bytes_written; + gint len; + gchar buf[7]; + int c = event->key.keyval; + + /* Apply the control key - Taken from Xlib */ + if ((c >= XK_at && c < '\177') || c == ' ') + c &= 0x1F; + else if (c == XK_2) + { + event->key.string = g_memdup ("\0\0", 2); + event->key.length = 1; + buf[0] = '\0'; + goto out; + } + else if (c >= XK_3 && c <= XK_7) + c -= (XK_3 - '\033'); + else if (c == XK_8) + c = '\177'; + else if (c == XK_slash) + c = '_' & 0x1F; + + len = g_unichar_to_utf8 (c, buf); + buf[len] = '\0'; + + event->key.string = g_locale_from_utf8 (buf, len, + NULL, &bytes_written, + NULL); + if (event->key.string) + event->key.length = bytes_written; + } + else + { + char buffer[128]; + xkb_keysym_to_string(event->key.keyval, buffer, sizeof buffer); + event->key.string = g_strdup (buffer); + event->key.length = strlen(event->key.string); + } + + out: + _gdk_wayland_display_deliver_event (device->display, event); + + fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n", + code, event->key.keyval, event->key.string, event->key.state); +} + +static void +input_handle_pointer_focus(void *data, + struct wl_input_device *input_device, + uint32_t time, struct wl_surface *surface, + int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + device->time = time; + if (device->pointer_focus) + { + event = gdk_event_new (GDK_LEAVE_NOTIFY); + event->crossing.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->crossing.subwindow = NULL; + event->crossing.time = time; + event->crossing.x = (gdouble) device->surface_x; + event->crossing.y = (gdouble) device->surface_y; + event->crossing.x_root = (gdouble) device->x; + event->crossing.y_root = (gdouble) device->y; + + event->crossing.mode = GDK_CROSSING_NORMAL; + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + event->crossing.focus = TRUE; + event->crossing.state = 0; + + _gdk_wayland_display_deliver_event (device->display, event); + + g_object_unref(device->pointer_focus); + device->pointer_focus = NULL; + } + + if (surface) + { + device->pointer_focus = wl_surface_get_user_data(surface); + g_object_ref(device->pointer_focus); + + event = gdk_event_new (GDK_ENTER_NOTIFY); + event->crossing.window = g_object_ref (device->pointer_focus); + gdk_event_set_device (event, device->pointer); + event->crossing.subwindow = NULL; + event->crossing.time = time; + event->crossing.x = (gdouble) sx; + event->crossing.y = (gdouble) sy; + event->crossing.x_root = (gdouble) x; + event->crossing.y_root = (gdouble) y; + + event->crossing.mode = GDK_CROSSING_NORMAL; + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + event->crossing.focus = TRUE; + event->crossing.state = 0; + + device->surface_x = sx; + device->surface_y = sy; + device->x = x; + device->y = y; + + _gdk_wayland_display_deliver_event (device->display, event); + } + + fprintf (stderr, "pointer focus surface %p, window %p\n", + surface, device->pointer_focus); +} + +static void +update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) +{ + uint32_t *k, *end; + GdkKeymap *keymap; + struct xkb_desc *xkb; + + keymap = gdk_keymap_get_for_display (device->display); + xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); + + end = keys->data + keys->size; + for (k = keys->data; k < end; k++) + device->modifiers |= xkb->map->modmap[*k]; + + fprintf (stderr, "modifiers: 0x%x\n", device->modifiers); +} + +static void +input_handle_keyboard_focus(void *data, + struct wl_input_device *input_device, + uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) +{ + GdkWaylandDevice *device = data; + GdkEvent *event; + + fprintf (stderr, "keyboard focus surface %p\n", surface); + + device->time = time; + if (device->keyboard_focus) + { + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = g_object_ref (device->keyboard_focus); + event->focus_change.send_event = FALSE; + event->focus_change.in = FALSE; + gdk_event_set_device (event, device->keyboard); + + g_object_unref(device->pointer_focus); + device->keyboard_focus = NULL; + + _gdk_wayland_display_deliver_event (device->display, event); + } + + if (surface) + { + device->keyboard_focus = wl_surface_get_user_data(surface); + g_object_ref(device->keyboard_focus); + + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = g_object_ref (device->keyboard_focus); + event->focus_change.send_event = FALSE; + event->focus_change.in = TRUE; + gdk_event_set_device (event, device->keyboard); + + update_modifiers (device, keys); + + _gdk_wayland_display_deliver_event (device->display, event); + } +} + +static const struct wl_input_device_listener input_device_listener = { + input_handle_motion, + input_handle_button, + input_handle_key, + input_handle_pointer_focus, + input_handle_keyboard_focus, +}; + +void +_gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, + struct wl_input_device *wl_device) +{ + GdkDisplay *display; + GdkDeviceManagerCore *device_manager_core = + GDK_DEVICE_MANAGER_CORE(device_manager); + GdkWaylandDevice *device; + + device = g_new0 (GdkWaylandDevice, 1); + display = gdk_device_manager_get_display (device_manager); + + device->display = display; + device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE, + "name", "Core Pointer", + "type", GDK_DEVICE_TYPE_MASTER, + "input-source", GDK_SOURCE_MOUSE, + "input-mode", GDK_MODE_SCREEN, + "has-cursor", TRUE, + "display", display, + "device-manager", device_manager, + NULL); + + device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE, + "name", "Core Keyboard", + "type", GDK_DEVICE_TYPE_MASTER, + "input-source", GDK_SOURCE_KEYBOARD, + "input-mode", GDK_MODE_SCREEN, + "has-cursor", FALSE, + "display", display, + "device-manager", device_manager, + NULL); + + GDK_DEVICE_CORE (device->pointer)->device = device; + GDK_DEVICE_CORE (device->keyboard)->device = device; + device->device = wl_device; + + wl_input_device_add_listener(device->device, + &input_device_listener, device); + + device_manager_core->devices = + g_list_prepend (device_manager_core->devices, device->keyboard); + device_manager_core->devices = + g_list_prepend (device_manager_core->devices, device->pointer); + + _gdk_device_set_associated_device (device->pointer, device->keyboard); + _gdk_device_set_associated_device (device->keyboard, device->pointer); +} + +static void +free_device (void *data, void *user_data) +{ + g_object_unref (data); +} + +static void +gdk_device_manager_core_finalize (GObject *object) +{ + GdkDeviceManagerCore *device_manager_core; + + device_manager_core = GDK_DEVICE_MANAGER_CORE (object); + + g_list_foreach (device_manager_core->devices, free_device, NULL); + g_list_free (device_manager_core->devices); + + G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object); +} + +static GList * +gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, + GdkDeviceType type) +{ + GdkDeviceManagerCore *device_manager_core; + GList *devices = NULL; + + if (type == GDK_DEVICE_TYPE_MASTER) + { + device_manager_core = (GdkDeviceManagerCore *) device_manager; + devices = g_list_copy(device_manager_core->devices); + } + + return devices; +} + +static GdkDevice * +gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager) +{ + GdkDeviceManagerCore *device_manager_core; + + device_manager_core = (GdkDeviceManagerCore *) device_manager; + return device_manager_core->devices->data; +} + +static void +gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass) +{ + GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_device_manager_core_finalize; + device_manager_class->list_devices = gdk_device_manager_core_list_devices; + device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer; +} + +static void +gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager) +{ +} + +GdkDeviceManager * +_gdk_wayland_device_manager_new (GdkDisplay *display) +{ + return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE, + "display", display, + NULL); +} diff --git a/gdk/wayland/gdkdevice-wayland.h b/gdk/wayland/gdkdevice-wayland.h deleted file mode 100644 index ce631c062d..0000000000 --- a/gdk/wayland/gdkdevice-wayland.h +++ /dev/null @@ -1,68 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 2009 Carlos Garnacho - * - * 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. - */ - -#ifndef __GDK_DEVICE_CORE_H__ -#define __GDK_DEVICE_CORE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ()) -#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore)) -#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) -#define GDK_IS_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE)) -#define GDK_IS_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE)) -#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass)) - -typedef struct _GdkDeviceCore GdkDeviceCore; -typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass; -typedef struct _GdkWaylandDevice GdkWaylandDevice; - -struct _GdkWaylandDevice -{ - GdkDisplay *display; - GdkDevice *pointer; - GdkDevice *keyboard; - GdkModifierType modifiers; - GdkWindow *pointer_focus; - GdkWindow *keyboard_focus; - struct wl_input_device *device; - int32_t x, y, surface_x, surface_y; - uint32_t time; -}; - -struct _GdkDeviceCore -{ - GdkDevice parent_instance; - GdkWaylandDevice *device; -}; - -struct _GdkDeviceCoreClass -{ - GdkDeviceClass parent_class; -}; - -G_GNUC_INTERNAL -GType gdk_device_core_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __GDK_DEVICE_CORE_H__ */ diff --git a/gdk/wayland/gdkdevicemanager-wayland.c b/gdk/wayland/gdkdevicemanager-wayland.c deleted file mode 100644 index 5c9a3b348e..0000000000 --- a/gdk/wayland/gdkdevicemanager-wayland.c +++ /dev/null @@ -1,451 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 2009 Carlos Garnacho - * - * 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 -#include -#include -#include "gdkdevicemanager-wayland.h" -#include "gdkdevice-wayland.h" -#include "gdkkeysyms.h" -#include "gdkprivate-wayland.h" - -#include -#include - -static void gdk_device_manager_core_finalize (GObject *object); - -static GList * gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, - GdkDeviceType type); -static GdkDevice * gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager); - -G_DEFINE_TYPE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER) - -static void -gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass) -{ - GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gdk_device_manager_core_finalize; - device_manager_class->list_devices = gdk_device_manager_core_list_devices; - device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer; -} - -static void -input_handle_motion(void *data, struct wl_input_device *input_device, - uint32_t time, - int32_t x, int32_t y, int32_t sx, int32_t sy) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - - event = gdk_event_new (GDK_NOTHING); - - device->time = time; - device->x = x; - device->y = y; - device->surface_x = sx; - device->surface_y = sy; - - event->motion.type = GDK_MOTION_NOTIFY; - event->motion.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->motion.time = time; - event->motion.x = (gdouble) sx; - event->motion.y = (gdouble) sy; - event->motion.x_root = (gdouble) x; - event->motion.y_root = (gdouble) y; - event->motion.axes = NULL; - event->motion.state = device->modifiers; - event->motion.is_hint = 0; - - _gdk_wayland_display_deliver_event (device->display, event); -} - -static void -input_handle_button(void *data, struct wl_input_device *input_device, - uint32_t time, uint32_t button, uint32_t state) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - uint32_t modifier; - - fprintf (stderr, "button event %d, state %d\n", button, state); - - device->time = time; - event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); - event->button.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->button.time = time; - event->button.x = (gdouble) device->surface_x; - event->button.y = (gdouble) device->surface_y; - event->button.x_root = (gdouble) device->x; - event->button.y_root = (gdouble) device->y; - event->button.axes = NULL; - event->button.state = device->modifiers; - event->button.button = button - 271; - - modifier = 1 << (8 + button - 272); - if (state) - device->modifiers |= modifier; - else - device->modifiers &= ~modifier; - - _gdk_wayland_display_deliver_event (device->display, event); -} - -static void -input_handle_key(void *data, struct wl_input_device *input_device, - uint32_t time, uint32_t key, uint32_t state) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - uint32_t code, modifier, level; - struct xkb_desc *xkb; - GdkKeymap *keymap; - - device->time = time; - event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); - event->key.window = g_object_ref (device->keyboard_focus); - gdk_event_set_device (event, device->keyboard); - event->button.time = time; - event->key.state = device->modifiers; - event->key.group = 0; - event->key.hardware_keycode = key; - - keymap = gdk_keymap_get_for_display (device->display); - xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); - - code = key + xkb->min_key_code; - - level = 0; - if (device->modifiers & XKB_COMMON_SHIFT_MASK && - XkbKeyGroupWidth(xkb, code, 0) > 1) - level = 1; - - event->key.keyval = XkbKeySymEntry(xkb, code, level, 0); - - modifier = xkb->map->modmap[code]; - if (state) - device->modifiers |= modifier; - else - device->modifiers &= ~modifier; - - event->key.is_modifier = modifier > 0; - - if (event->key.keyval == GDK_KEY_Escape) - { - event->key.length = 1; - event->key.string = g_strdup ("\033"); - } - else if (event->key.keyval == GDK_KEY_Return || - event->key.keyval == GDK_KEY_KP_Enter) - { - event->key.length = 1; - event->key.string = g_strdup ("\r"); - } - else if (event->key.state & GDK_CONTROL_MASK) - { - gsize bytes_written; - gint len; - gchar buf[7]; - int c = event->key.keyval; - - /* Apply the control key - Taken from Xlib */ - if ((c >= XK_at && c < '\177') || c == ' ') - c &= 0x1F; - else if (c == XK_2) - { - event->key.string = g_memdup ("\0\0", 2); - event->key.length = 1; - buf[0] = '\0'; - goto out; - } - else if (c >= XK_3 && c <= XK_7) - c -= (XK_3 - '\033'); - else if (c == XK_8) - c = '\177'; - else if (c == XK_slash) - c = '_' & 0x1F; - - len = g_unichar_to_utf8 (c, buf); - buf[len] = '\0'; - - event->key.string = g_locale_from_utf8 (buf, len, - NULL, &bytes_written, - NULL); - if (event->key.string) - event->key.length = bytes_written; - } - else - { - char buffer[128]; - xkb_keysym_to_string(event->key.keyval, buffer, sizeof buffer); - event->key.string = g_strdup (buffer); - event->key.length = strlen(event->key.string); - } - - out: - _gdk_wayland_display_deliver_event (device->display, event); - - fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n", - code, event->key.keyval, event->key.string, event->key.state); -} - -static void -input_handle_pointer_focus(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface, - int32_t x, int32_t y, int32_t sx, int32_t sy) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - - device->time = time; - if (device->pointer_focus) - { - event = gdk_event_new (GDK_LEAVE_NOTIFY); - event->crossing.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->crossing.subwindow = NULL; - event->crossing.time = time; - event->crossing.x = (gdouble) device->surface_x; - event->crossing.y = (gdouble) device->surface_y; - event->crossing.x_root = (gdouble) device->x; - event->crossing.y_root = (gdouble) device->y; - - event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - event->crossing.focus = TRUE; - event->crossing.state = 0; - - _gdk_wayland_display_deliver_event (device->display, event); - - g_object_unref(device->pointer_focus); - device->pointer_focus = NULL; - } - - if (surface) - { - device->pointer_focus = wl_surface_get_user_data(surface); - g_object_ref(device->pointer_focus); - - event = gdk_event_new (GDK_ENTER_NOTIFY); - event->crossing.window = g_object_ref (device->pointer_focus); - gdk_event_set_device (event, device->pointer); - event->crossing.subwindow = NULL; - event->crossing.time = time; - event->crossing.x = (gdouble) sx; - event->crossing.y = (gdouble) sy; - event->crossing.x_root = (gdouble) x; - event->crossing.y_root = (gdouble) y; - - event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - event->crossing.focus = TRUE; - event->crossing.state = 0; - - device->surface_x = sx; - device->surface_y = sy; - device->x = x; - device->y = y; - - _gdk_wayland_display_deliver_event (device->display, event); - } - - fprintf (stderr, "pointer focus surface %p, window %p\n", - surface, device->pointer_focus); -} - -static void -update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) -{ - uint32_t *k, *end; - GdkKeymap *keymap; - struct xkb_desc *xkb; - - keymap = gdk_keymap_get_for_display (device->display); - xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); - - end = keys->data + keys->size; - for (k = keys->data; k < end; k++) - device->modifiers |= xkb->map->modmap[*k]; - - fprintf (stderr, "modifiers: 0x%x\n", device->modifiers); -} - -static void -input_handle_keyboard_focus(void *data, - struct wl_input_device *input_device, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys) -{ - GdkWaylandDevice *device = data; - GdkEvent *event; - - fprintf (stderr, "keyboard focus surface %p\n", surface); - - device->time = time; - if (device->keyboard_focus) - { - event = gdk_event_new (GDK_FOCUS_CHANGE); - event->focus_change.window = g_object_ref (device->keyboard_focus); - event->focus_change.send_event = FALSE; - event->focus_change.in = FALSE; - gdk_event_set_device (event, device->keyboard); - - g_object_unref(device->pointer_focus); - device->keyboard_focus = NULL; - - _gdk_wayland_display_deliver_event (device->display, event); - } - - if (surface) - { - device->keyboard_focus = wl_surface_get_user_data(surface); - g_object_ref(device->keyboard_focus); - - event = gdk_event_new (GDK_FOCUS_CHANGE); - event->focus_change.window = g_object_ref (device->keyboard_focus); - event->focus_change.send_event = FALSE; - event->focus_change.in = TRUE; - gdk_event_set_device (event, device->keyboard); - - update_modifiers (device, keys); - - _gdk_wayland_display_deliver_event (device->display, event); - } -} - -static const struct wl_input_device_listener input_device_listener = { - input_handle_motion, - input_handle_button, - input_handle_key, - input_handle_pointer_focus, - input_handle_keyboard_focus, -}; - -void -gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, - struct wl_input_device *wl_device) -{ - GdkDisplay *display; - GdkDeviceManagerCore *device_manager_core = - GDK_DEVICE_MANAGER_CORE(device_manager); - GdkWaylandDevice *device; - - device = g_new0 (GdkWaylandDevice, 1); - display = gdk_device_manager_get_display (device_manager); - - device->display = display; - device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE, - "name", "Core Pointer", - "type", GDK_DEVICE_TYPE_MASTER, - "input-source", GDK_SOURCE_MOUSE, - "input-mode", GDK_MODE_SCREEN, - "has-cursor", TRUE, - "display", display, - "device-manager", device_manager, - NULL); - - device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE, - "name", "Core Keyboard", - "type", GDK_DEVICE_TYPE_MASTER, - "input-source", GDK_SOURCE_KEYBOARD, - "input-mode", GDK_MODE_SCREEN, - "has-cursor", FALSE, - "display", display, - "device-manager", device_manager, - NULL); - - GDK_DEVICE_CORE (device->pointer)->device = device; - GDK_DEVICE_CORE (device->keyboard)->device = device; - device->device = wl_device; - - wl_input_device_add_listener(device->device, - &input_device_listener, device); - - device_manager_core->devices = - g_list_prepend (device_manager_core->devices, device->keyboard); - device_manager_core->devices = - g_list_prepend (device_manager_core->devices, device->pointer); - - _gdk_device_set_associated_device (device->pointer, device->keyboard); - _gdk_device_set_associated_device (device->keyboard, device->pointer); -} - -static void -gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager) -{ -} - -static void -free_device (void *data, void *user_data) -{ - g_object_unref (data); -} - -static void -gdk_device_manager_core_finalize (GObject *object) -{ - GdkDeviceManagerCore *device_manager_core; - - device_manager_core = GDK_DEVICE_MANAGER_CORE (object); - - g_list_foreach (device_manager_core->devices, free_device, NULL); - g_list_free (device_manager_core->devices); - - G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object); -} - -static GList * -gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager, - GdkDeviceType type) -{ - GdkDeviceManagerCore *device_manager_core; - GList *devices = NULL; - - if (type == GDK_DEVICE_TYPE_MASTER) - { - device_manager_core = (GdkDeviceManagerCore *) device_manager; - devices = g_list_copy(device_manager_core->devices); - } - - return devices; -} - -static GdkDevice * -gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager) -{ - GdkDeviceManagerCore *device_manager_core; - - device_manager_core = (GdkDeviceManagerCore *) device_manager; - return device_manager_core->devices->data; -} - -GdkDeviceManager * -_gdk_device_manager_new (GdkDisplay *display) -{ - return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE, - "display", display, - NULL); -} diff --git a/gdk/wayland/gdkdevicemanager-wayland.h b/gdk/wayland/gdkdevicemanager-wayland.h deleted file mode 100644 index 83c76e9983..0000000000 --- a/gdk/wayland/gdkdevicemanager-wayland.h +++ /dev/null @@ -1,59 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 2009 Carlos Garnacho - * - * 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. - */ - -#ifndef __GDK_DEVICE_MANAGER_CORE_H__ -#define __GDK_DEVICE_MANAGER_CORE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define GDK_TYPE_DEVICE_MANAGER_CORE (gdk_device_manager_core_get_type ()) -#define GDK_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore)) -#define GDK_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) -#define GDK_IS_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE)) -#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE)) -#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass)) - -typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore; -typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass; - -struct _GdkDeviceManagerCore -{ - GdkDeviceManager parent_object; - GdkDevice *core_pointer; - GdkDevice *core_keyboard; - GList *devices; -}; - -struct _GdkDeviceManagerCoreClass -{ - GdkDeviceManagerClass parent_class; -}; - -GType gdk_device_manager_core_get_type (void) G_GNUC_CONST; - -void -gdk_device_manager_core_add_device (GdkDeviceManager *device_manager, - struct wl_input_device *device); - -G_END_DECLS - -#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */ diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 45184b0f00..0e68b7e572 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -36,7 +36,6 @@ #include "gdkinternals.h" #include "gdkdeviceprivate.h" #include "gdkdevicemanager.h" -#include "gdkdevicemanager-wayland.h" #include "gdkkeysprivate.h" typedef struct _GdkEventTypeWayland GdkEventTypeWayland; @@ -192,7 +191,8 @@ gdk_display_handle_global(struct wl_display *display, uint32_t id, &output_listener, display_wayland); } else if (strcmp(interface, "input_device") == 0) { input = wl_input_device_create(display, id); - gdk_device_manager_core_add_device (gdk_display->device_manager, input); + _gdk_wayland_device_manager_add_device (gdk_display->device_manager, + input); } } @@ -286,7 +286,7 @@ _gdk_wayland_display_open (const gchar *display_name) /*set the default screen */ display_wayland->default_screen = display_wayland->screens[0]; - display->device_manager = _gdk_device_manager_new (display); + display->device_manager = _gdk_wayland_device_manager_new (display); /* Set up listener so we'll catch all events. */ wl_display_add_global_listener(display_wayland->wl_display, diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index da215a121d..a9256831b0 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -121,7 +121,10 @@ gint _gdk_wayland_display_text_property_to_utf8_list (GdkDisplay *disp gchar * _gdk_wayland_display_utf8_to_string_target (GdkDisplay *display, const gchar *str); -GdkDeviceManager *_gdk_device_manager_new (GdkDisplay *display); +GdkDeviceManager *_gdk_wayland_device_manager_new (GdkDisplay *display); +void _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, + struct wl_input_device *device); +struct wl_input_device *_gdk_wayland_device_get_device (GdkDevice *device); void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event); GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index d0cd39e954..934b7b5940 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -33,7 +33,6 @@ #include "gdkinternals.h" #include "gdkwindow-wayland.h" #include "gdkdeviceprivate.h" -#include "gdkdevice-wayland.h" #include #include @@ -1148,7 +1147,7 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window, device = gdk_device_manager_get_client_pointer (dm); wl_shell_resize(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface, - GDK_DEVICE_CORE (device)->device->device, + _gdk_wayland_device_get_device (device), timestamp, grab_type); } @@ -1174,7 +1173,7 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window, 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); + _gdk_wayland_device_get_device (device), timestamp); } static void From de82b82dd879c2ae2132b13faf705537f3f78dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 9 Feb 2011 16:36:15 -0500 Subject: [PATCH 14/42] wayland: Clear modifier mask before restoring from keyboard_focus value --- gdk/wayland/gdkdevice-wayland.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index a2bc8e520b..39e17431dd 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -495,6 +495,7 @@ update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); end = keys->data + keys->size; + device->modifiers = 0; for (k = keys->data; k < end; k++) device->modifiers |= xkb->map->modmap[*k]; From f7f1b59e05551a40356c85535e64fb77cd6aa3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 10:49:09 -0500 Subject: [PATCH 15/42] wayland: Handle blank cursor --- gdk/wayland/gdkcursor-wayland.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index c633411c07..c71cf4f3f8 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -181,8 +181,16 @@ create_cursor(GdkDisplayWayland *display, GdkPixbuf *pixbuf, int x, int y) cursor->serial = theme_serial; cursor->x = x; cursor->y = y; - cursor->width = gdk_pixbuf_get_width (pixbuf); - cursor->height = gdk_pixbuf_get_height (pixbuf); + if (pixbuf) + { + cursor->width = gdk_pixbuf_get_width (pixbuf); + cursor->height = gdk_pixbuf_get_height (pixbuf); + } + else + { + cursor->width = 1; + cursor->height = 1; + } stride = cursor->width * 4; cursor->size = stride * cursor->height; @@ -211,7 +219,10 @@ create_cursor(GdkDisplayWayland *display, GdkPixbuf *pixbuf, int x, int y) return NULL; } - set_pixbuf (cursor, pixbuf); + if (pixbuf) + set_pixbuf (cursor, pixbuf); + else + memset (cursor->map, 0, 4); visual = wl_display_get_premultiplied_argb_visual(display->wl_display); cursor->buffer = wl_shm_create_buffer(display->shm, @@ -232,6 +243,7 @@ static const struct { const char *filename; int hotspot_x, hotspot_y; } cursor_definitions[] = { + { GDK_BLANK_CURSOR, NULL, 0, 0 }, { GDK_XTERM, DATADIR "/xterm.png", 15, 15 }, { GDK_BOTTOM_RIGHT_CORNER, DATADIR "/bottom_right_corner.png", 28, 28 } }; @@ -252,7 +264,11 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, } if (i == G_N_ELEMENTS (cursor_definitions)) - return NULL; + { + g_warning("unhandled cursor type %d, falling back to blank\n", + cursor_type); + i = 0; + } wayland_display = GDK_DISPLAY_WAYLAND (display); if (!wayland_display->cursors) @@ -261,7 +277,10 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, if (wayland_display->cursors[i]) return g_object_ref (wayland_display->cursors[i]); - pixbuf = gdk_pixbuf_new_from_file(cursor_definitions[i].filename, &error); + if (cursor_type != GDK_BLANK_CURSOR) + pixbuf = gdk_pixbuf_new_from_file(cursor_definitions[i].filename, &error); + else + pixbuf = NULL; if (error != NULL) { g_error_free(error); @@ -272,7 +291,8 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, create_cursor(wayland_display, pixbuf, cursor_definitions[i].hotspot_x, cursor_definitions[i].hotspot_y); - g_object_unref (pixbuf); + if (pixbuf) + g_object_unref (pixbuf); return g_object_ref (wayland_display->cursors[i]); } From 0583603b0943a37c3dbedd8f34c6403c8caca9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 10:49:51 -0500 Subject: [PATCH 16/42] wayland: Actually return device in _gdk_wayland_device_get_device() --- gdk/wayland/gdkdevice-wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 39e17431dd..46abf58611 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -255,7 +255,7 @@ gdk_device_core_init (GdkDeviceCore *device_core) struct wl_input_device * _gdk_wayland_device_get_device (GdkDevice *device) { - GDK_DEVICE_CORE (device)->device->device; + return GDK_DEVICE_CORE (device)->device->device; } static void From 3beb09adca63cce125b08b177cf64fb7eaa84bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 10:53:31 -0500 Subject: [PATCH 17/42] wayland: Copy translate_keyboard_string() form x11 backend --- gdk/wayland/gdkdevice-wayland.c | 117 ++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 52 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 46abf58611..c95d596cf9 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -321,6 +321,70 @@ input_handle_button(void *data, struct wl_input_device *input_device, _gdk_wayland_display_deliver_event (device->display, event); } +static void +translate_keyboard_string (GdkEventKey *event) +{ + gunichar c = 0; + gchar buf[7]; + + /* Fill in event->string crudely, since various programs + * depend on it. + */ + event->string = NULL; + + if (event->keyval != GDK_KEY_VoidSymbol) + c = gdk_keyval_to_unicode (event->keyval); + + if (c) + { + gsize bytes_written; + gint len; + + /* Apply the control key - Taken from Xlib + */ + if (event->state & GDK_CONTROL_MASK) + { + if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; + else if (c == '2') + { + event->string = g_memdup ("\0\0", 2); + event->length = 1; + buf[0] = '\0'; + return; + } + else if (c >= '3' && c <= '7') c -= ('3' - '\033'); + else if (c == '8') c = '\177'; + else if (c == '/') c = '_' & 0x1F; + } + + len = g_unichar_to_utf8 (c, buf); + buf[len] = '\0'; + + event->string = g_locale_from_utf8 (buf, len, + NULL, &bytes_written, + NULL); + if (event->string) + event->length = bytes_written; + } + else if (event->keyval == GDK_KEY_Escape) + { + event->length = 1; + event->string = g_strdup ("\033"); + } + else if (event->keyval == GDK_KEY_Return || + event->keyval == GDK_KEY_KP_Enter) + { + event->length = 1; + event->string = g_strdup ("\r"); + } + + if (!event->string) + { + event->length = 0; + event->string = g_strdup (""); + } +} + static void input_handle_key(void *data, struct wl_input_device *input_device, uint32_t time, uint32_t key, uint32_t state) @@ -360,59 +424,8 @@ input_handle_key(void *data, struct wl_input_device *input_device, event->key.is_modifier = modifier > 0; - if (event->key.keyval == GDK_KEY_Escape) - { - event->key.length = 1; - event->key.string = g_strdup ("\033"); - } - else if (event->key.keyval == GDK_KEY_Return || - event->key.keyval == GDK_KEY_KP_Enter) - { - event->key.length = 1; - event->key.string = g_strdup ("\r"); - } - else if (event->key.state & GDK_CONTROL_MASK) - { - gsize bytes_written; - gint len; - gchar buf[7]; - int c = event->key.keyval; + translate_keyboard_string (&event->key); - /* Apply the control key - Taken from Xlib */ - if ((c >= XK_at && c < '\177') || c == ' ') - c &= 0x1F; - else if (c == XK_2) - { - event->key.string = g_memdup ("\0\0", 2); - event->key.length = 1; - buf[0] = '\0'; - goto out; - } - else if (c >= XK_3 && c <= XK_7) - c -= (XK_3 - '\033'); - else if (c == XK_8) - c = '\177'; - else if (c == XK_slash) - c = '_' & 0x1F; - - len = g_unichar_to_utf8 (c, buf); - buf[len] = '\0'; - - event->key.string = g_locale_from_utf8 (buf, len, - NULL, &bytes_written, - NULL); - if (event->key.string) - event->key.length = bytes_written; - } - else - { - char buffer[128]; - xkb_keysym_to_string(event->key.keyval, buffer, sizeof buffer); - event->key.string = g_strdup (buffer); - event->key.length = strlen(event->key.string); - } - - out: _gdk_wayland_display_deliver_event (device->display, event); fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n", From 1b918d1b9316b23419de74b14f9518ed02937428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 10:54:10 -0500 Subject: [PATCH 18/42] wayland: Pretend selection works, print debug message --- gdk/wayland/gdkselection-wayland.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c index 0faf82239a..6c904a17a4 100644 --- a/gdk/wayland/gdkselection-wayland.c +++ b/gdk/wayland/gdkselection-wayland.c @@ -39,7 +39,10 @@ _gdk_wayland_display_set_selection_owner (GdkDisplay *display, guint32 time, gboolean send_event) { - return FALSE; + fprintf(stderr, "set selection owner: atom %ld, owner %p\n", + selection, owner); + + return TRUE; } void From 9f0ed18d5a955dbc08c2030eda07fe41293700fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 10:57:33 -0500 Subject: [PATCH 19/42] wayland: Set event screen --- gdk/wayland/gdkdevice-wayland.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index c95d596cf9..ddda0b84cd 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -264,6 +264,7 @@ input_handle_motion(void *data, struct wl_input_device *input_device, int32_t x, int32_t y, int32_t sx, int32_t sy) { GdkWaylandDevice *device = data; + GdkDisplayWayland *display = GDK_DISPLAY_WAYLAND (device->display); GdkEvent *event; event = gdk_event_new (GDK_NOTHING); @@ -285,6 +286,7 @@ input_handle_motion(void *data, struct wl_input_device *input_device, event->motion.axes = NULL; event->motion.state = device->modifiers; event->motion.is_hint = 0; + gdk_event_set_screen (event, display->screens[0]); _gdk_wayland_display_deliver_event (device->display, event); } @@ -294,6 +296,7 @@ input_handle_button(void *data, struct wl_input_device *input_device, uint32_t time, uint32_t button, uint32_t state) { GdkWaylandDevice *device = data; + GdkDisplayWayland *display = GDK_DISPLAY_WAYLAND (device->display); GdkEvent *event; uint32_t modifier; @@ -311,6 +314,7 @@ input_handle_button(void *data, struct wl_input_device *input_device, event->button.axes = NULL; event->button.state = device->modifiers; event->button.button = button - 271; + gdk_event_set_screen (event, display->screens[0]); modifier = 1 << (8 + button - 272); if (state) From f62e4a02b66dfd6fec42d310359f4b3d5afaaea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 10:58:43 -0500 Subject: [PATCH 20/42] wayland: Use GDK_NOTE for logging event debug messages --- gdk/wayland/gdkdevice-wayland.c | 37 ++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index ddda0b84cd..8abdb09249 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -288,6 +288,10 @@ input_handle_motion(void *data, struct wl_input_device *input_device, event->motion.is_hint = 0; gdk_event_set_screen (event, display->screens[0]); + GDK_NOTE (EVENTS, + g_message ("motion %d %d, state %d", + sx, sy, event->button.state)); + _gdk_wayland_display_deliver_event (device->display, event); } @@ -300,8 +304,6 @@ input_handle_button(void *data, struct wl_input_device *input_device, GdkEvent *event; uint32_t modifier; - fprintf (stderr, "button event %d, state %d\n", button, state); - device->time = time; event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); event->button.window = g_object_ref (device->pointer_focus); @@ -322,6 +324,11 @@ input_handle_button(void *data, struct wl_input_device *input_device, else device->modifiers &= ~modifier; + GDK_NOTE (EVENTS, + g_message ("button %d %s, state %d", + event->button.button, + state ? "press" : "release", event->button.state)); + _gdk_wayland_display_deliver_event (device->display, event); } @@ -432,8 +439,11 @@ input_handle_key(void *data, struct wl_input_device *input_device, _gdk_wayland_display_deliver_event (device->display, event); - fprintf (stderr, "keyboard event, code %d, sym %d, string %s, mods 0x%x\n", - code, event->key.keyval, event->key.string, event->key.state); + GDK_NOTE (EVENTS, + g_message ("keyboard event, code %d, sym %d, " + "string %s, mods 0x%x", + code, event->key.keyval, + event->key.string, event->key.state)); } static void @@ -465,6 +475,10 @@ input_handle_pointer_focus(void *data, _gdk_wayland_display_deliver_event (device->display, event); + GDK_NOTE (EVENTS, + g_message ("leave, device %p surface %p", + device, device->pointer_focus)); + g_object_unref(device->pointer_focus); device->pointer_focus = NULL; } @@ -495,10 +509,11 @@ input_handle_pointer_focus(void *data, device->y = y; _gdk_wayland_display_deliver_event (device->display, event); - } - fprintf (stderr, "pointer focus surface %p, window %p\n", - surface, device->pointer_focus); + GDK_NOTE (EVENTS, + g_message ("enter, device %p surface %p", + device, device->pointer_focus)); + } } static void @@ -543,6 +558,10 @@ input_handle_keyboard_focus(void *data, g_object_unref(device->pointer_focus); device->keyboard_focus = NULL; + GDK_NOTE (EVENTS, + g_message ("focus out, device %p surface %p", + device, device->keyboard_focus)); + _gdk_wayland_display_deliver_event (device->display, event); } @@ -559,6 +578,10 @@ input_handle_keyboard_focus(void *data, update_modifiers (device, keys); + GDK_NOTE (EVENTS, + g_message ("focus int, device %p surface %p", + device, device->keyboard_focus)); + _gdk_wayland_display_deliver_event (device->display, event); } } From df57389190a0077fa8de326b205fdbef1baafc2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 10:59:30 -0500 Subject: [PATCH 21/42] wayland: Unref the keyboard focus surface when losing keyboard focus --- gdk/wayland/gdkdevice-wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 8abdb09249..6f4237cbeb 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -555,7 +555,7 @@ input_handle_keyboard_focus(void *data, event->focus_change.in = FALSE; gdk_event_set_device (event, device->keyboard); - g_object_unref(device->pointer_focus); + g_object_unref(device->keyboard_focus); device->keyboard_focus = NULL; GDK_NOTE (EVENTS, From 9e1a0a1becfcd1553296ec3398754a4967280cce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 11:01:09 -0500 Subject: [PATCH 22/42] wayland: Fix indentation --- gdk/wayland/gdkdevice-wayland.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 6f4237cbeb..531e249a3a 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -587,11 +587,11 @@ input_handle_keyboard_focus(void *data, } static const struct wl_input_device_listener input_device_listener = { - input_handle_motion, - input_handle_button, - input_handle_key, - input_handle_pointer_focus, - input_handle_keyboard_focus, + input_handle_motion, + input_handle_button, + input_handle_key, + input_handle_pointer_focus, + input_handle_keyboard_focus, }; void From 4621c6476c6cc24240bc394535724d0cd86f8436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 11:01:30 -0500 Subject: [PATCH 23/42] wayland: Send visibility event after map --- gdk/wayland/gdkwindow-wayland.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 934b7b5940..9f567c1b8a 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -442,6 +442,7 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) GdkDisplayWayland *display_wayland; GdkToplevelWayland *toplevel; GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkEvent *event; display = gdk_window_get_display (window); display_wayland = GDK_DISPLAY_WAYLAND (display); @@ -460,6 +461,8 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) wl_surface_set_user_data(impl->surface, window); _gdk_make_event (window, GDK_MAP, NULL, FALSE); + event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY, NULL, FALSE); + event->visibility.state = GDK_VISIBILITY_UNOBSCURED; fprintf(stderr, "window show, faked map event\n"); } From df0815470c9b4072fc26fc7edf285a6374059886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 13:42:59 -0500 Subject: [PATCH 24/42] wayland: Return surface coordinates and mask in window_at_position --- gdk/wayland/gdkdevice-wayland.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 531e249a3a..63adc6b721 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -214,6 +214,9 @@ gdk_device_core_window_at_position (GdkDevice *device, GdkWaylandDevice *wd; wd = GDK_DEVICE_CORE(device)->device; + *win_x = wd->surface_x; + *win_y = wd->surface_y; + *mask = wd->modifiers; return wd->pointer_focus; } From b4129c14cbd2d20d37252c74c6af1b7ecc0511c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 13:44:45 -0500 Subject: [PATCH 25/42] gtkwidget: Only call X GDK functions when the window is an X window --- gtk/gtkwindow.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 7336d025d8..4a1452c39c 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -1698,7 +1698,7 @@ gtk_window_set_startup_id (GtkWindow *window, gdk_window = gtk_widget_get_window (widget); #ifdef GDK_WINDOWING_X11 - if (timestamp != GDK_CURRENT_TIME) + if (timestamp != GDK_CURRENT_TIME && GDK_IS_X11_WINDOW(gdk_window)) gdk_x11_window_set_user_time (gdk_window, timestamp); #endif @@ -4612,7 +4612,8 @@ gtk_window_show (GtkWidget *widget) /* Try to make sure that we have some focused widget */ #ifdef GDK_WINDOWING_X11 - is_plug = GTK_IS_PLUG (window); + is_plug = GDK_IS_X11_WINDOW (gtk_widget_get_window (widget)) && + GTK_IS_PLUG (window); #else is_plug = FALSE; #endif @@ -4978,12 +4979,18 @@ gtk_window_realize (GtkWidget *widget) if (priv->startup_id) { #ifdef GDK_WINDOWING_X11 - guint32 timestamp = extract_time_from_startup_id (priv->startup_id); - if (timestamp != GDK_CURRENT_TIME) - gdk_x11_window_set_user_time (gdk_window, timestamp); + if (GDK_IS_X11_WINDOW (gdk_window)) + { + guint32 timestamp = extract_time_from_startup_id (priv->startup_id); + if (timestamp != GDK_CURRENT_TIME) + gdk_x11_window_set_user_time (gdk_window, timestamp); + } + else #endif - if (!startup_id_is_fake (priv->startup_id)) - gdk_window_set_startup_id (gdk_window, priv->startup_id); + { + if (!startup_id_is_fake (priv->startup_id)) + gdk_window_set_startup_id (gdk_window, priv->startup_id); + } } /* Icons */ @@ -7352,13 +7359,16 @@ gtk_window_present_with_time (GtkWindow *window, if (timestamp == GDK_CURRENT_TIME) { #ifdef GDK_WINDOWING_X11 - GdkDisplay *display; + if (GDK_IS_X11_WINDOW(gdk_window)) + { + GdkDisplay *display; - display = gtk_widget_get_display (GTK_WIDGET (window)); - timestamp = gdk_x11_display_get_user_time (display); -#else - timestamp = gtk_get_current_event_time (); + display = gtk_widget_get_display (GTK_WIDGET (window)); + timestamp = gdk_x11_display_get_user_time (display); + } + else #endif + timestamp = gtk_get_current_event_time (); } gdk_window_focus (gdk_window, timestamp); From c3955ea0c251fea0141759719ddd46821ca5d0d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 14:08:53 -0500 Subject: [PATCH 26/42] wayland: Add a few more cursors --- gdk/wayland/gdkcursor-wayland.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index c71cf4f3f8..e977929faf 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -244,6 +244,10 @@ static const struct { int hotspot_x, hotspot_y; } cursor_definitions[] = { { GDK_BLANK_CURSOR, NULL, 0, 0 }, + { GDK_HAND1, DATADIR "/hand1.png", 18, 11 }, + { GDK_HAND2, DATADIR "/hand2.png", 14, 8 }, + { GDK_SB_H_DOUBLE_ARROW, DATADIR "/sb_h_double_arrow.png", 15, 15 }, + { GDK_SB_V_DOUBLE_ARROW, DATADIR "/sb_v_double_arrow.png", 15, 15 }, { GDK_XTERM, DATADIR "/xterm.png", 15, 15 }, { GDK_BOTTOM_RIGHT_CORNER, DATADIR "/bottom_right_corner.png", 28, 28 } }; @@ -277,12 +281,19 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, if (wayland_display->cursors[i]) return g_object_ref (wayland_display->cursors[i]); + GDK_NOTE (CURSOR, + g_message ("creating new cursor for type %d, filename %s", + cursor_type, cursor_definitions[i].filename)); + if (cursor_type != GDK_BLANK_CURSOR) pixbuf = gdk_pixbuf_new_from_file(cursor_definitions[i].filename, &error); else pixbuf = NULL; if (error != NULL) { + GDK_NOTE (CURSOR, + g_message ("failed to load %s: %s", + cursor_definitions[i].filename, error->message)); g_error_free(error); return NULL; } From f0fe810999556bf840db57ff4ef4a352b1bac1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 16:34:40 -0500 Subject: [PATCH 27/42] wayland: Adjust the hw keycode in key events for min_key_code --- gdk/wayland/gdkdevice-wayland.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 63adc6b721..672761618f 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -409,6 +409,9 @@ input_handle_key(void *data, struct wl_input_device *input_device, struct xkb_desc *xkb; GdkKeymap *keymap; + keymap = gdk_keymap_get_for_display (device->display); + xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); + device->time = time; event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE); event->key.window = g_object_ref (device->keyboard_focus); @@ -416,12 +419,8 @@ input_handle_key(void *data, struct wl_input_device *input_device, event->button.time = time; event->key.state = device->modifiers; event->key.group = 0; - event->key.hardware_keycode = key; - - keymap = gdk_keymap_get_for_display (device->display); - xkb = _gdk_wayland_keymap_get_xkb_desc (keymap); - code = key + xkb->min_key_code; + event->key.hardware_keycode = code; level = 0; if (device->modifiers & XKB_COMMON_SHIFT_MASK && From 0db8663e44aeb716f6c21de542581f13c87ecce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 16:35:38 -0500 Subject: [PATCH 28/42] wayland: Copy gdk_wayland_keymap_translate_keyboard_state from X11 backend --- gdk/wayland/gdkkeys-wayland.c | 184 +++++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 1 deletion(-) diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c index f18bf0e291..8336242368 100644 --- a/gdk/wayland/gdkkeys-wayland.c +++ b/gdk/wayland/gdkkeys-wayland.c @@ -270,6 +270,136 @@ gdk_wayland_keymap_lookup_key (GdkKeymap *keymap, return XkbKeySymEntry (xkb, key->keycode, key->level, key->group); } +/* This is copied straight from XFree86 Xlib, to: + * - add the group and level return. + * - change the interpretation of mods_rtrn as described + * in the docs for gdk_keymap_translate_keyboard_state() + * It's unchanged for ease of diff against the Xlib sources; don't + * reformat it. + */ +static int +MyEnhancedXkbTranslateKeyCode(struct xkb_desc * xkb, + KeyCode key, + unsigned int mods, + unsigned int * mods_rtrn, + uint32_t * keysym_rtrn, + int * group_rtrn, + int * level_rtrn) +{ + struct xkb_key_type *type; + int col,nKeyGroups; + unsigned preserve,effectiveGroup; + uint32_t *syms; + + if (mods_rtrn!=NULL) + *mods_rtrn = 0; + + nKeyGroups= XkbKeyNumGroups(xkb,key); + if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) { + if (keysym_rtrn!=NULL) + *keysym_rtrn = 0; + return 0; + } + + syms = XkbKeySymsPtr(xkb,key); + + /* find the offset of the effective group */ + col = 0; + effectiveGroup= XkbGroupForCoreState(mods); + if ( effectiveGroup>=nKeyGroups ) { + unsigned groupInfo= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(groupInfo)) { + default: + effectiveGroup %= nKeyGroups; + break; + case XkbClampIntoRange: + effectiveGroup = nKeyGroups-1; + break; + case XkbRedirectIntoRange: + effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo); + if (effectiveGroup>=nKeyGroups) + effectiveGroup= 0; + break; + } + } + col= effectiveGroup*XkbKeyGroupsWidth(xkb,key); + type = XkbKeyKeyType(xkb,key,effectiveGroup); + + preserve= 0; + if (type->map) { /* find the column (shift level) within the group */ + register int i; + struct xkb_kt_map_entry *entry; + /* ---- Begin section modified for GDK ---- */ + int found = 0; + + for (i=0,entry=type->map;imap_count;i++,entry++) { + if (mods_rtrn) { + int bits = 0; + unsigned long tmp = entry->mods.mask; + while (tmp) { + if ((tmp & 1) == 1) + bits++; + tmp >>= 1; + } + /* We always add one-modifiers levels to mods_rtrn since + * they can't wipe out bits in the state unless the + * level would be triggered. But return other modifiers + * + */ + if (bits == 1 || (mods&type->mods.mask)==entry->mods.mask) + *mods_rtrn |= entry->mods.mask; + } + + if (!found&&entry->active&&((mods&type->mods.mask)==entry->mods.mask)) { + col+= entry->level; + if (type->preserve) + preserve= type->preserve[i].mask; + + if (level_rtrn) + *level_rtrn = entry->level; + + found = 1; + } + } + /* ---- End section modified for GDK ---- */ + } + + if (keysym_rtrn!=NULL) + *keysym_rtrn= syms[col]; + if (mods_rtrn) { + /* ---- Begin section modified for GDK ---- */ + *mods_rtrn &= ~preserve; + /* ---- End section modified for GDK ---- */ + + /* ---- Begin stuff GDK comments out of the original Xlib version ---- */ + /* This is commented out because xkb_info is a private struct */ + +#if 0 + /* The Motif VTS doesn't get the help callback called if help + * is bound to Shift+, and it appears as though it + * is XkbTranslateKeyCode that is causing the problem. The + * core X version of XTranslateKey always OR's in ShiftMask + * and LockMask for mods_rtrn, so this "fix" keeps this behavior + * and solves the VTS problem. + */ + if ((xkb->dpy)&&(xkb->dpy->xkb_info)&& + (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) { *mods_rtrn|= (ShiftMask|LockMask); + } +#endif + + /* ---- End stuff GDK comments out of the original Xlib version ---- */ + } + + /* ---- Begin stuff GDK adds to the original Xlib version ---- */ + + if (group_rtrn) + *group_rtrn = effectiveGroup; + + /* ---- End stuff GDK adds to the original Xlib version ---- */ + + return (syms[col] != 0); +} + static gboolean gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, guint hardware_keycode, @@ -280,7 +410,59 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, gint *level, GdkModifierType *consumed_modifiers) { - return FALSE; + GdkWaylandKeymap *wayland_keymap; + uint32_t tmp_keyval = 0; + guint tmp_modifiers; + struct xkb_desc *xkb; + + g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); + g_return_val_if_fail (group < 4, FALSE); + + wayland_keymap = GDK_WAYLAND_KEYMAP (keymap); + xkb = wayland_keymap->xkb; + + if (keyval) + *keyval = 0; + if (effective_group) + *effective_group = 0; + if (level) + *level = 0; + if (consumed_modifiers) + *consumed_modifiers = 0; + + if (hardware_keycode < xkb->min_key_code || + hardware_keycode > xkb->max_key_code) + return FALSE; + + + /* replace bits 13 and 14 with the provided group */ + state &= ~(1 << 13 | 1 << 14); + state |= group << 13; + + MyEnhancedXkbTranslateKeyCode (xkb, + hardware_keycode, + state, + &tmp_modifiers, + &tmp_keyval, + effective_group, + level); + + if (state & ~tmp_modifiers & XKB_COMMON_LOCK_MASK) + tmp_keyval = gdk_keyval_to_upper (tmp_keyval); + + /* We need to augment the consumed modifiers with LockMask, since + * we handle that ourselves, and also with the group bits + */ + tmp_modifiers |= XKB_COMMON_LOCK_MASK | 1 << 13 | 1 << 14; + + + if (consumed_modifiers) + *consumed_modifiers = tmp_modifiers; + + if (keyval) + *keyval = tmp_keyval; + + return tmp_keyval != 0; } From 3b205de8964cbecf259f82668e5c3804500279f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 20:34:14 -0500 Subject: [PATCH 29/42] wayland: Port over missing xkb functionality from X11 backend --- gdk/wayland/gdkkeys-wayland.c | 90 ++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c index 8336242368..139e54824e 100644 --- a/gdk/wayland/gdkkeys-wayland.c +++ b/gdk/wayland/gdkkeys-wayland.c @@ -49,6 +49,7 @@ typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass; struct _GdkWaylandKeymap { GdkKeymap parent_instance; + GdkModifierType modmap[8]; struct xkb_desc *xkb; }; @@ -466,17 +467,103 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, } +static void +update_modmap (GdkWaylandKeymap *wayland_keymap) +{ + static struct { + const gchar *name; + uint32_t atom; + GdkModifierType mask; + } vmods[] = { + { "Meta", 0, GDK_META_MASK }, + { "Super", 0, GDK_SUPER_MASK }, + { "Hyper", 0, GDK_HYPER_MASK }, + { NULL, 0, 0 } + }; + + gint i, j, k; + + if (!vmods[0].atom) + for (i = 0; vmods[i].name; i++) + vmods[i].atom = xkb_intern_atom(vmods[i].name); + + for (i = 0; i < 8; i++) + wayland_keymap->modmap[i] = 1 << i; + + for (i = 0; i < XkbNumVirtualMods; i++) + { + for (j = 0; vmods[j].atom; j++) + { + if (wayland_keymap->xkb->names->vmods[i] == vmods[j].atom) + { + for (k = 0; k < 8; k++) + { + if (wayland_keymap->xkb->server->vmods[i] & (1 << k)) + wayland_keymap->modmap[k] |= vmods[j].mask; + } + } + } + } +} + static void gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap, GdkModifierType *state) { + GdkWaylandKeymap *wayland_keymap; + int i; + + wayland_keymap = GDK_WAYLAND_KEYMAP (keymap); + + for (i = 3; i < 8; i++) + { + if ((1 << i) & *state) + { + if (wayland_keymap->modmap[i] & GDK_MOD1_MASK) + *state |= GDK_MOD1_MASK; + if (wayland_keymap->modmap[i] & GDK_SUPER_MASK) + *state |= GDK_SUPER_MASK; + if (wayland_keymap->modmap[i] & GDK_HYPER_MASK) + *state |= GDK_HYPER_MASK; + if (wayland_keymap->modmap[i] & GDK_META_MASK) + *state |= GDK_META_MASK; + } + } } static gboolean gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap, GdkModifierType *state) { - return FALSE; + const guint vmods[] = { + GDK_SUPER_MASK, GDK_HYPER_MASK, GDK_META_MASK + }; + int i, j; + gboolean retval; + GdkWaylandKeymap *wayland_keymap; + struct xkb_desc *xkb; + + wayland_keymap = GDK_WAYLAND_KEYMAP (keymap); + xkb = wayland_keymap->xkb; + + for (j = 0; j < 3; j++) + { + if (*state & vmods[j]) + { + for (i = 3; i < 8; i++) + { + if (wayland_keymap->modmap[i] & vmods[j]) + { + if (*state & (1 << i)) + retval = FALSE; + else + *state |= 1 << i; + } + } + } + } + + return TRUE; } static void @@ -519,6 +606,7 @@ _gdk_wayland_keymap_new (GdkDisplay *display) names.variant = ""; names.options = ""; keymap->xkb = xkb_compile_keymap_from_rules(&names); + update_modmap (keymap); return GDK_KEYMAP (keymap); } From 22b9132ae53affc02fd25ad2814fa891aec92255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 22:04:26 -0500 Subject: [PATCH 30/42] wayland: Keep a reference to the surface we last attached --- gdk/wayland/gdkdisplay-wayland.c | 5 ---- gdk/wayland/gdkwindow-wayland.c | 46 ++++++++++++-------------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 0e68b7e572..3d0dc09ce5 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -128,9 +128,6 @@ shell_handle_configure(void *data, struct wl_shell *shell, window = wl_surface_get_user_data(surface); - printf("got configure: window %p, %dx%d, edges %d\n", - window, width, height, edges); - display = gdk_window_get_display (window); event = gdk_event_new (GDK_CONFIGURE); @@ -249,8 +246,6 @@ gdk_display_init_egl(GdkDisplay *display) } } - fprintf(stderr, "egl initialized\n"); - return TRUE; } diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 9f567c1b8a..ca14684831 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -157,8 +157,6 @@ _gdk_wayland_window_update_size (GdkWindow *window) GdkRectangle area; cairo_region_t *region; - fprintf(stderr, "update size, window %p\n", impl->wrapper); - if (impl->cairo_surface) { cairo_surface_destroy (impl->cairo_surface); @@ -300,27 +298,13 @@ typedef struct _GdkWaylandCairoSurfaceData { GdkDisplayWayland *display; } GdkWaylandCairoSurfaceData; -struct wl_buffer * -_gdk_wayland_surface_get_buffer (GdkDisplayWayland *display, - cairo_surface_t *surface) -{ - GdkWaylandCairoSurfaceData *data; - - data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key); - - if (!data->buffer) - data->buffer = - wl_egl_pixmap_create_buffer(display->native_display, data->pixmap); - - return data->buffer; -} - static void gdk_wayland_window_attach_image (GdkWindow *window) { - GdkDisplayWayland *display_wayland = + GdkDisplayWayland *display = GDK_DISPLAY_WAYLAND (gdk_window_get_display (window)); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkWaylandCairoSurfaceData *data; struct wl_buffer *buffer; if (GDK_WINDOW_DESTROYED (window)) @@ -329,12 +313,18 @@ gdk_wayland_window_attach_image (GdkWindow *window) if (impl->server_surface == impl->cairo_surface) return; + cairo_surface_reference (impl->cairo_surface); + if (impl->server_surface) + cairo_surface_destroy (impl->server_surface); impl->server_surface = impl->cairo_surface; - buffer = _gdk_wayland_surface_get_buffer (display_wayland, - impl->cairo_surface); - wl_surface_attach (impl->surface, buffer, 0, 0); - fprintf(stderr, "attach %p %dx%d\n", window, window->width, window->height); + data = cairo_surface_get_user_data (impl->cairo_surface, + &gdk_wayland_cairo_key); + if (!data->buffer) + data->buffer = + wl_egl_pixmap_create_buffer(display->native_display, data->pixmap); + + wl_surface_attach (impl->surface, data->buffer, 0, 0); } static void @@ -350,6 +340,8 @@ gdk_window_impl_wayland_finalize (GObject *object) if (impl->cursor) gdk_cursor_unref (impl->cursor); + if (impl->server_surface) + cairo_surface_destroy (impl->server_surface); g_hash_table_destroy (impl->device_cursor); @@ -392,8 +384,6 @@ gdk_wayland_create_cairo_surface (GdkDisplayWayland *display, glBindTexture(GL_TEXTURE_2D, data->texture); display->image_target_texture_2d(GL_TEXTURE_2D, data->image); - printf("allocate image %dx%d (image %p)\n", width, height, data->image); - surface = cairo_gl_surface_create_for_texture(display->cairo_device, CAIRO_CONTENT_COLOR_ALPHA, data->texture, width, height); @@ -463,8 +453,6 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) _gdk_make_event (window, GDK_MAP, NULL, FALSE); event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY, NULL, FALSE); event->visibility.state = GDK_VISIBILITY_UNOBSCURED; - - fprintf(stderr, "window show, faked map event\n"); } static void @@ -1192,8 +1180,6 @@ gdk_wayland_window_configure_finished (GdkWindow *window) if (!GDK_IS_WINDOW_IMPL_WAYLAND (window->impl)) return; - - fprintf(stderr, "configure %p finished\n", window); } static void @@ -1230,7 +1216,9 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window, cairo_rectangle_int_t rect; int i, n; - gdk_wayland_window_attach_image (window); + if (impl->cairo_surface) + gdk_wayland_window_attach_image (window); + if (!impl->mapped) { wl_surface_map_toplevel (impl->surface); From 6d20bcb84878e69b0f913911b1af498562ecadb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 22:21:08 -0500 Subject: [PATCH 31/42] wayland: Fix hiding and withdrawing surfaces --- gdk/wayland/gdkwindow-wayland.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index ca14684831..b5ddb654d4 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -453,6 +453,9 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) _gdk_make_event (window, GDK_MAP, NULL, FALSE); event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY, NULL, FALSE); event->visibility.state = GDK_VISIBILITY_UNOBSCURED; + + if (impl->cairo_surface) + gdk_wayland_window_attach_image (window); } static void @@ -462,10 +465,11 @@ gdk_wayland_window_hide (GdkWindow *window) if (impl->surface) { - fprintf (stderr, "hide surface %p\n", impl->surface); - wl_surface_destroy(impl->surface); impl->surface = NULL; + cairo_surface_destroy(impl->server_surface); + impl->server_surface = NULL; + impl->mapped = FALSE; } _gdk_window_clear_update_area (window); @@ -486,11 +490,11 @@ gdk_window_wayland_withdraw (GdkWindow *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); + cairo_surface_destroy(impl->server_surface); + impl->server_surface = NULL; + impl->mapped = FALSE; } } } @@ -736,9 +740,6 @@ gdk_wayland_window_destroy (GdkWindow *window, 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); } From cfb9c840e5f218909e6964fa0376e5c80d5aca09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 22:21:48 -0500 Subject: [PATCH 32/42] wayland: Remove some fprintf debug messages --- gdk/wayland/gdkdevice-wayland.c | 4 ---- gdk/wayland/gdkwindow-wayland.c | 2 -- 2 files changed, 6 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 672761618f..252bcef9f9 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -532,8 +532,6 @@ update_modifiers(GdkWaylandDevice *device, struct wl_array *keys) device->modifiers = 0; for (k = keys->data; k < end; k++) device->modifiers |= xkb->map->modmap[*k]; - - fprintf (stderr, "modifiers: 0x%x\n", device->modifiers); } static void @@ -546,8 +544,6 @@ input_handle_keyboard_focus(void *data, GdkWaylandDevice *device = data; GdkEvent *event; - fprintf (stderr, "keyboard focus surface %p\n", surface); - device->time = time; if (device->keyboard_focus) { diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index b5ddb654d4..6b36ab7305 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -236,8 +236,6 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display, 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) { From cd9155107527d37235a7737716e93d59b7c65831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 22:37:51 -0500 Subject: [PATCH 33/42] wayland: Fix resizing from other corners than just botton-right --- gdk/wayland/gdkdisplay-wayland.c | 5 +--- gdk/wayland/gdkwindow-wayland.c | 46 +++++++++++++++++++++++++------- gdk/wayland/gdkwindow-wayland.h | 5 +++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 3d0dc09ce5..06ebb65560 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -136,11 +136,8 @@ shell_handle_configure(void *data, struct wl_shell *shell, event->configure.width = width; event->configure.height = height; - window->width = width; - window->height = height; - _gdk_window_update_size (window); - _gdk_wayland_window_update_size (window); + _gdk_wayland_window_update_size (window, width, height, edges); g_object_ref(window); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 6b36ab7305..2f53d81ae2 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -108,6 +108,7 @@ struct _GdkWindowImplWayland cairo_surface_t *cairo_surface; cairo_surface_t *server_surface; GLuint texture; + uint32_t resize_edges; }; struct _GdkWindowImplWaylandClass @@ -151,7 +152,8 @@ _gdk_wayland_window_get_toplevel (GdkWindow *window) * cairo surface) when its size has changed. **/ void -_gdk_wayland_window_update_size (GdkWindow *window) +_gdk_wayland_window_update_size (GdkWindow *window, + int32_t width, int32_t height, uint32_t edges) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkRectangle area; @@ -163,6 +165,10 @@ _gdk_wayland_window_update_size (GdkWindow *window) impl->cairo_surface = NULL; } + window->width = width; + window->height = height; + impl->resize_edges = edges; + area.x = 0; area.y = 0; area.width = window->width; @@ -294,6 +300,7 @@ typedef struct _GdkWaylandCairoSurfaceData { struct wl_egl_pixmap *pixmap; struct wl_buffer *buffer; GdkDisplayWayland *display; + int32_t width, height; } GdkWaylandCairoSurfaceData; static void @@ -304,6 +311,7 @@ gdk_wayland_window_attach_image (GdkWindow *window) GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWaylandCairoSurfaceData *data; struct wl_buffer *buffer; + int32_t server_width, server_height, dx, dy; if (GDK_WINDOW_DESTROYED (window)) return; @@ -311,18 +319,38 @@ gdk_wayland_window_attach_image (GdkWindow *window) if (impl->server_surface == impl->cairo_surface) return; - cairo_surface_reference (impl->cairo_surface); if (impl->server_surface) - cairo_surface_destroy (impl->server_surface); - impl->server_surface = impl->cairo_surface; + { + data = cairo_surface_get_user_data (impl->server_surface, + &gdk_wayland_cairo_key); + server_width = data->width; + server_height = data->height; + cairo_surface_destroy (impl->server_surface); + } + else + { + server_width = 0; + server_height = 0; + } + impl->server_surface = cairo_surface_reference (impl->cairo_surface); data = cairo_surface_get_user_data (impl->cairo_surface, &gdk_wayland_cairo_key); if (!data->buffer) data->buffer = wl_egl_pixmap_create_buffer(display->native_display, data->pixmap); - wl_surface_attach (impl->surface, data->buffer, 0, 0); + if (impl->resize_edges & WL_SHELL_RESIZE_LEFT) + dx = server_width - data->width; + else + dx = 0; + + if (impl->resize_edges & WL_SHELL_RESIZE_TOP) + dy = server_height - data->height; + else + dy = 0; + + wl_surface_attach (impl->surface, data->buffer, dx, dy); } static void @@ -372,6 +400,8 @@ gdk_wayland_create_cairo_surface (GdkDisplayWayland *display, data->display = display; data->buffer = NULL; visual = wl_display_get_premultiplied_argb_visual(display->wl_display); + data->width = width; + data->height = height; data->pixmap = wl_egl_pixmap_create(display->native_display, width, height, visual, 0); data->image = @@ -548,12 +578,8 @@ gdk_window_wayland_move_resize (GdkWindow *window, { window->x = x; window->y = y; - if (width > 0) - window->width = width; - if (height > 0) - window->height = height; - _gdk_wayland_window_update_size (window); + _gdk_wayland_window_update_size (window, width, height, 0); } static void diff --git a/gdk/wayland/gdkwindow-wayland.h b/gdk/wayland/gdkwindow-wayland.h index 5b63f88b19..016ce6ab3b 100644 --- a/gdk/wayland/gdkwindow-wayland.h +++ b/gdk/wayland/gdkwindow-wayland.h @@ -94,7 +94,10 @@ void _gdk_wayland_window_get_offsets (GdkWindow *window, gint *x_offset, gint *y_offset); -void _gdk_wayland_window_update_size (GdkWindow *window); +void _gdk_wayland_window_update_size (GdkWindow *window, + int32_t width, + int32_t height, + uint32_t edges); G_END_DECLS From 4ca3e53a3e4fc0e0484de37f0c19a137384faf9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 22:51:23 -0500 Subject: [PATCH 34/42] wayland: Drop GdkToplevelWayland and gdkwindow-wayland.h --- gdk/wayland/Makefile.am | 1 - gdk/wayland/gdkprivate-wayland.h | 7 ++- gdk/wayland/gdkwindow-wayland.c | 97 +++++++++++++--------------- gdk/wayland/gdkwindow-wayland.h | 104 ------------------------------- 4 files changed, 48 insertions(+), 161 deletions(-) delete mode 100644 gdk/wayland/gdkwindow-wayland.h diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am index 3466311853..036856ae88 100644 --- a/gdk/wayland/Makefile.am +++ b/gdk/wayland/Makefile.am @@ -31,7 +31,6 @@ libgdk_wayland_la_SOURCES = \ gdkscreen-wayland.h \ gdkselection-wayland.c \ gdkwindow-wayland.c \ - gdkwindow-wayland.h \ gdkwayland.h \ gdkprivate-wayland.h diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index a9256831b0..e876494017 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -33,7 +33,6 @@ #include #include -#include #include #include "gdkinternals.h" @@ -45,7 +44,11 @@ #define GDK_WINDOW_DISPLAY(win) (GDK_SCREEN_WAYLAND (GDK_WINDOW_SCREEN (win))->display) #define GDK_WINDOW_IS_WAYLAND(win) (GDK_IS_WINDOW_IMPL_WAYLAND (((GdkWindow *)win)->impl)) -GType _gdk_wayland_window_get_type (void); +GType _gdk_wayland_window_get_type (void); +void _gdk_wayland_window_update_size (GdkWindow *window, + int32_t width, + int32_t height, + uint32_t edges); GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display); struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 2f53d81ae2..1e55e4477e 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -31,7 +31,6 @@ #include "gdkscreen-wayland.h" #include "gdkprivate-wayland.h" #include "gdkinternals.h" -#include "gdkwindow-wayland.h" #include "gdkdeviceprivate.h" #include @@ -96,7 +95,6 @@ struct _GdkWindowImplWayland GdkWindow *wrapper; - GdkToplevelWayland *toplevel; /* Toplevel-specific information */ GdkCursor *cursor; GHashTable *device_cursor; @@ -109,6 +107,45 @@ struct _GdkWindowImplWayland cairo_surface_t *server_surface; GLuint texture; uint32_t resize_edges; + + /* Set if the window, or any descendent of it, is the server's focus window + */ + guint has_focus_window : 1; + + /* Set if window->has_focus_window and the focus isn't grabbed elsewhere. + */ + guint has_focus : 1; + + /* Set if the pointer is inside this window. (This is needed for + * for focus tracking) + */ + guint has_pointer : 1; + + /* Set if the window is a descendent of the focus window and the pointer is + * inside it. (This is the case where the window will receive keystroke + * events even window->has_focus_window is FALSE) + */ + guint has_pointer_focus : 1; + + /* Set if we are requesting these hints */ + guint skip_taskbar_hint : 1; + guint skip_pager_hint : 1; + guint urgency_hint : 1; + + guint on_all_desktops : 1; /* _NET_WM_STICKY == 0xFFFFFFFF */ + + guint have_sticky : 1; /* _NET_WM_STATE_STICKY */ + guint have_maxvert : 1; /* _NET_WM_STATE_MAXIMIZED_VERT */ + guint have_maxhorz : 1; /* _NET_WM_STATE_MAXIMIZED_HORZ */ + guint have_fullscreen : 1; /* _NET_WM_STATE_FULLSCREEN */ + + gulong map_serial; /* Serial of last transition from unmapped */ + + cairo_surface_t *icon_pixmap; + cairo_surface_t *icon_mask; + + /* Time of most recent user interaction. */ + gulong user_time; }; struct _GdkWindowImplWaylandClass @@ -126,24 +163,6 @@ _gdk_window_impl_wayland_init (GdkWindowImplWayland *impl) (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. @@ -276,22 +295,6 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display, 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; - } -} - static const cairo_user_data_key_t gdk_wayland_cairo_key; typedef struct _GdkWaylandCairoSurfaceData { @@ -362,8 +365,6 @@ gdk_window_impl_wayland_finalize (GObject *object) impl = GDK_WINDOW_IMPL_WAYLAND (object); - g_free (impl->toplevel); - if (impl->cursor) gdk_cursor_unref (impl->cursor); if (impl->server_surface) @@ -458,22 +459,16 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) { GdkDisplay *display; GdkDisplayWayland *display_wayland; - GdkToplevelWayland *toplevel; GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkEvent *event; display = gdk_window_get_display (window); display_wayland = GDK_DISPLAY_WAYLAND (display); - if (WINDOW_IS_TOPLEVEL (window)) - { - 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); - } + if (impl->user_time != 0 && + display_wayland->user_time != 0 && + XSERVER_TIME_IS_LATER (display_wayland->user_time, impl->user_time)) + gdk_wayland_window_set_user_time (window, impl->user_time); impl->surface = wl_compositor_create_surface(display_wayland->compositor); wl_surface_set_user_data(impl->surface, window); @@ -742,16 +737,10 @@ 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); diff --git a/gdk/wayland/gdkwindow-wayland.h b/gdk/wayland/gdkwindow-wayland.h deleted file mode 100644 index 016ce6ab3b..0000000000 --- a/gdk/wayland/gdkwindow-wayland.h +++ /dev/null @@ -1,104 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * 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. - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GDK_WINDOW_WAYLAND_H__ -#define __GDK_WINDOW_WAYLAND_H__ - -#include -#include - -#include -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -typedef struct _GdkToplevelWayland GdkToplevelWayland; -typedef struct _GdkXPositionInfo GdkXPositionInfo; - -struct _GdkToplevelWayland -{ - - /* Set if the window, or any descendent of it, is the server's focus window - */ - guint has_focus_window : 1; - - /* Set if window->has_focus_window and the focus isn't grabbed elsewhere. - */ - guint has_focus : 1; - - /* Set if the pointer is inside this window. (This is needed for - * for focus tracking) - */ - guint has_pointer : 1; - - /* Set if the window is a descendent of the focus window and the pointer is - * inside it. (This is the case where the window will receive keystroke - * events even window->has_focus_window is FALSE) - */ - guint has_pointer_focus : 1; - - /* Set if we are requesting these hints */ - guint skip_taskbar_hint : 1; - guint skip_pager_hint : 1; - guint urgency_hint : 1; - - guint on_all_desktops : 1; /* _NET_WM_STICKY == 0xFFFFFFFF */ - - guint have_sticky : 1; /* _NET_WM_STATE_STICKY */ - guint have_maxvert : 1; /* _NET_WM_STATE_MAXIMIZED_VERT */ - guint have_maxhorz : 1; /* _NET_WM_STATE_MAXIMIZED_HORZ */ - guint have_fullscreen : 1; /* _NET_WM_STATE_FULLSCREEN */ - - gulong map_serial; /* Serial of last transition from unmapped */ - - cairo_surface_t *icon_pixmap; - cairo_surface_t *icon_mask; - - /* Time of most recent user interaction. */ - gulong user_time; -}; - -GType _gdk_window_impl_wayland_get_type (void); - -GdkToplevelWayland *_gdk_wayland_window_get_toplevel (GdkWindow *window); - -GdkCursor *_gdk_wayland_window_get_cursor (GdkWindow *window); -void _gdk_wayland_window_get_offsets (GdkWindow *window, - gint *x_offset, - gint *y_offset); - -void _gdk_wayland_window_update_size (GdkWindow *window, - int32_t width, - int32_t height, - uint32_t edges); - -G_END_DECLS - -#endif /* __GDK_WINDOW_WAYLAND_H__ */ From f2ac8c7ce3eb2a9d04811fcd42721c3129836f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 10 Feb 2011 23:00:12 -0500 Subject: [PATCH 35/42] wayland: Drop empty gdkscreen-wayland.h --- gdk/wayland/gdkdisplay-wayland.c | 2 +- gdk/wayland/gdkdnd-wayland.c | 1 - gdk/wayland/gdkscreen-wayland.h | 36 -------------------------------- gdk/wayland/gdkwindow-wayland.c | 1 - 4 files changed, 1 insertion(+), 39 deletions(-) delete mode 100644 gdk/wayland/gdkscreen-wayland.h diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 06ebb65560..a116ed1cd5 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -32,11 +32,11 @@ #include "gdkdisplay.h" #include "gdkdisplay-wayland.h" #include "gdkscreen.h" -#include "gdkscreen-wayland.h" #include "gdkinternals.h" #include "gdkdeviceprivate.h" #include "gdkdevicemanager.h" #include "gdkkeysprivate.h" +#include "gdkprivate-wayland.h" typedef struct _GdkEventTypeWayland GdkEventTypeWayland; diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c index 293456fb17..62c79759b5 100644 --- a/gdk/wayland/gdkdnd-wayland.c +++ b/gdk/wayland/gdkdnd-wayland.c @@ -25,7 +25,6 @@ #include "gdkinternals.h" #include "gdkproperty.h" #include "gdkprivate-wayland.h" -#include "gdkscreen-wayland.h" #include "gdkdisplay-wayland.h" #include diff --git a/gdk/wayland/gdkscreen-wayland.h b/gdk/wayland/gdkscreen-wayland.h deleted file mode 100644 index 9fa4baab81..0000000000 --- a/gdk/wayland/gdkscreen-wayland.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * gdkscreen-wayland.h - * - * Copyright 2001 Sun Microsystems Inc. - * - * Erwann Chenede - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library 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. - */ - -#ifndef __GDK_SCREEN_WAYLAND_H__ -#define __GDK_SCREEN_WAYLAND_H__ - -#include "gdkprivate-wayland.h" -#include -#include - -G_BEGIN_DECLS - - -G_END_DECLS - -#endif /* __GDK_SCREEN_WAYLAND_H__ */ diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 1e55e4477e..b7992bfb77 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -28,7 +28,6 @@ #include "gdkwindow.h" #include "gdkwindowimpl.h" #include "gdkdisplay-wayland.h" -#include "gdkscreen-wayland.h" #include "gdkprivate-wayland.h" #include "gdkinternals.h" #include "gdkdeviceprivate.h" From 6eac07d4f6622fc88efe4d60cd024ebb7fc55c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 11 Feb 2011 09:50:10 -0500 Subject: [PATCH 36/42] wayland: Trim some unused struct fields --- gdk/wayland/gdkdisplay-wayland.c | 30 ------------------------------ gdk/wayland/gdkdisplay-wayland.h | 12 ------------ gdk/wayland/gdkkeys-wayland.c | 6 ++---- gdk/wayland/gdkscreen-wayland.c | 31 +------------------------------ gdk/wayland/gdkwindow-wayland.c | 1 - 5 files changed, 3 insertions(+), 77 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index a116ed1cd5..884b1e5a83 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -38,34 +38,8 @@ #include "gdkkeysprivate.h" #include "gdkprivate-wayland.h" -typedef struct _GdkEventTypeWayland GdkEventTypeWayland; - -struct _GdkEventTypeWayland -{ - gint base; - gint n_events; -}; - G_DEFINE_TYPE (GdkDisplayWayland, _gdk_display_wayland, GDK_TYPE_DISPLAY) -/* GDK_VISIBILITY, - * GDK_MAP, - * GDK_UNMAP, - * GDK_PROPERTY_NOTIFY - * GDK_SELECTION_CLEAR - * GDK_SELECTION_ REQUEST - * GDK_SELECTION_NOTIFY - * GDK_CLIENT_EVENT, - * - * new keyboard mapping: _gdk_keymap_keys_changed (display); - * - * Selection owner change: GDK_OWNER_CHANGE; - * - * Screen size changes: _gdk_wayland_screen_size_changed (screen, xevent); - * - * XkbStateNotify: _gdk_keymap_state_changed (display, xevent); - */ - static void gdk_input_init (GdkDisplay *display) { @@ -337,10 +311,6 @@ gdk_wayland_display_finalize (GObject *object) g_list_foreach (display_wayland->input_devices, (GFunc) g_object_unref, NULL); g_list_free (display_wayland->input_devices); - /* input GdkWindow list */ - g_list_foreach (display_wayland->input_windows, (GFunc) g_free, NULL); - g_list_free (display_wayland->input_windows); - /* Free all GdkScreens */ for (i = 0; i < 1; i++) g_object_unref (display_wayland->screens[i]); diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index ebe67d6480..d575d40a8b 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -58,30 +58,18 @@ struct _GdkDisplayWayland GdkScreen *default_screen; GdkScreen **screens; - gint grab_count; - /* Keyboard related information */ GdkKeymap *keymap; - guint keymap_serial; - - /* drag and drop information */ - GdkDragContext *current_dest_drag; /* input GdkDevice list */ GList *input_devices; - /* input GdkWindow list */ - GList *input_windows; - /* Startup notification */ gchar *startup_notification_id; /* Time of most recent user interaction. */ gulong user_time; - /* The offscreen window that has the pointer in it (if any) */ - GdkWindow *active_offscreen_window; - /* Wayland fields below */ struct wl_display *wl_display; struct wl_egl_display *native_display; diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c index 139e54824e..1513fe7f89 100644 --- a/gdk/wayland/gdkkeys-wayland.c +++ b/gdk/wayland/gdkkeys-wayland.c @@ -539,12 +539,10 @@ gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap, GDK_SUPER_MASK, GDK_HYPER_MASK, GDK_META_MASK }; int i, j; - gboolean retval; GdkWaylandKeymap *wayland_keymap; - struct xkb_desc *xkb; + gboolean retval; wayland_keymap = GDK_WAYLAND_KEYMAP (keymap); - xkb = wayland_keymap->xkb; for (j = 0; j < 3; j++) { @@ -563,7 +561,7 @@ gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap, } } - return TRUE; + return retval; } static void diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c index e7dbaba0ac..b1cb479179 100644 --- a/gdk/wayland/gdkscreen-wayland.c +++ b/gdk/wayland/gdkscreen-wayland.c @@ -52,17 +52,6 @@ struct _GdkScreenWayland int width, height; int width_mm, height_mm; - /* Window manager */ - char *window_manager_name; - /* TRUE if wmspec_check_window has changed since last - * fetch of _NET_SUPPORTED - */ - guint need_refetch_net_supported : 1; - /* TRUE if wmspec_check_window has changed since last - * fetch of window manager name - */ - guint need_refetch_wm_name : 1; - /* Visual Part */ GdkVisual *argb_visual; GdkVisual *premultiplied_argb_visual; @@ -72,21 +61,8 @@ struct _GdkScreenWayland gint n_monitors; GdkWaylandMonitor *monitors; gint primary_monitor; - - /* Xft resources for the display, used for default values for - * the Xft/ XSETTINGS - */ - gboolean xft_init; /* Whether we've intialized these values yet */ - gboolean xft_antialias; - gboolean xft_hinting; - gint xft_hintstyle; - gint xft_rgba; - gint xft_dpi; - - GdkAtom cm_selection_atom; - gboolean is_composited; }; - + struct _GdkScreenWaylandClass { GdkScreenClass parent_class; @@ -184,8 +160,6 @@ gdk_wayland_screen_finalize (GObject *object) g_object_unref (screen_wayland->premultiplied_argb_visual); g_object_unref (screen_wayland->rgb_visual); - g_free (screen_wayland->window_manager_name); - deinit_multihead (GDK_SCREEN (object)); G_OBJECT_CLASS (_gdk_screen_wayland_parent_class)->finalize (object); @@ -505,9 +479,6 @@ _gdk_wayland_screen_new (GdkDisplay *display) screen_wayland = GDK_SCREEN_WAYLAND (screen); screen_wayland->display = display; - /* we want this to be always non-null */ - screen_wayland->window_manager_name = g_strdup ("unknown"); - screen_wayland->width = 8192; screen_wayland->height = 8192; diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index b7992bfb77..e2168d87fe 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -312,7 +312,6 @@ gdk_wayland_window_attach_image (GdkWindow *window) GDK_DISPLAY_WAYLAND (gdk_window_get_display (window)); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWaylandCairoSurfaceData *data; - struct wl_buffer *buffer; int32_t server_width, server_height, dx, dy; if (GDK_WINDOW_DESTROYED (window)) From ffe3af7f1cd916f21100a6a4090ede074b8973cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 11 Feb 2011 09:56:58 -0500 Subject: [PATCH 37/42] wayland: There's only one screen --- gdk/wayland/gdkdevice-wayland.c | 4 ++-- gdk/wayland/gdkdisplay-wayland.c | 24 +++++------------------- gdk/wayland/gdkdisplay-wayland.h | 3 +-- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 252bcef9f9..20d28bf4e2 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -289,7 +289,7 @@ input_handle_motion(void *data, struct wl_input_device *input_device, event->motion.axes = NULL; event->motion.state = device->modifiers; event->motion.is_hint = 0; - gdk_event_set_screen (event, display->screens[0]); + gdk_event_set_screen (event, display->screen); GDK_NOTE (EVENTS, g_message ("motion %d %d, state %d", @@ -319,7 +319,7 @@ input_handle_button(void *data, struct wl_input_device *input_device, event->button.axes = NULL; event->button.state = device->modifiers; event->button.button = button - 271; - gdk_event_set_screen (event, display->screens[0]); + gdk_event_set_screen (event, display->screen); modifier = 1 << (8 + button - 272); if (state) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 884b1e5a83..cb447d659f 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -227,8 +227,6 @@ _gdk_wayland_display_open (const gchar *display_name) GdkDisplay *display; GdkDisplayWayland *display_wayland; - gint i; - wl_display = wl_display_connect(display_name); if (!wl_display) return NULL; @@ -244,13 +242,7 @@ _gdk_wayland_display_open (const gchar *display_name) return NULL; } - /* initialize the display's screens */ - display_wayland->screens = g_new (GdkScreen *, 1); - for (i = 0; i < 1; i++) - display_wayland->screens[i] = _gdk_wayland_screen_new (display); - - /*set the default screen */ - display_wayland->default_screen = display_wayland->screens[0]; + display_wayland->screen = _gdk_wayland_screen_new (display); display->device_manager = _gdk_wayland_device_manager_new (display); @@ -274,15 +266,13 @@ static void gdk_wayland_display_dispose (GObject *object) { GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (object); - gint i; _gdk_wayland_display_manager_remove_display (gdk_display_manager_get (), GDK_DISPLAY (display_wayland)); g_list_foreach (display_wayland->input_devices, (GFunc) g_object_run_dispose, NULL); - for (i = 0; i < 1; i++) - _gdk_screen_close (display_wayland->screens[i]); + _gdk_screen_close (display_wayland->screen); if (display_wayland->event_source) { @@ -301,7 +291,6 @@ static void gdk_wayland_display_finalize (GObject *object) { GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (object); - gint i; /* Keymap */ if (display_wayland->keymap) @@ -311,10 +300,7 @@ gdk_wayland_display_finalize (GObject *object) g_list_foreach (display_wayland->input_devices, (GFunc) g_object_unref, NULL); g_list_free (display_wayland->input_devices); - /* Free all GdkScreens */ - for (i = 0; i < 1; i++) - g_object_unref (display_wayland->screens[i]); - g_free (display_wayland->screens); + g_object_unref (display_wayland->screen); g_free (display_wayland->startup_notification_id); @@ -340,7 +326,7 @@ gdk_wayland_display_get_screen (GdkDisplay *display, g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); g_return_val_if_fail (screen_num == 0, NULL); - return GDK_DISPLAY_WAYLAND (display)->screens[0]; + return GDK_DISPLAY_WAYLAND (display)->screen; } static GdkScreen * @@ -348,7 +334,7 @@ gdk_wayland_display_get_default_screen (GdkDisplay *display) { g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); - return GDK_DISPLAY_WAYLAND (display)->default_screen; + return GDK_DISPLAY_WAYLAND (display)->screen; } static void diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index d575d40a8b..87be6bb8ac 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -55,8 +55,7 @@ typedef struct _GdkDisplayWaylandClass GdkDisplayWaylandClass; struct _GdkDisplayWayland { GdkDisplay parent_instance; - GdkScreen *default_screen; - GdkScreen **screens; + GdkScreen *screen; /* Keyboard related information */ GdkKeymap *keymap; From 152dca40d3ca61235d74b37a7faa393ef87a0591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 11 Feb 2011 10:06:56 -0500 Subject: [PATCH 38/42] wayland: Remove window cursor hash --- gdk/wayland/gdkwindow-wayland.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index e2168d87fe..0388037731 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -95,7 +95,6 @@ struct _GdkWindowImplWayland GdkWindow *wrapper; GdkCursor *cursor; - GHashTable *device_cursor; gint8 toplevel_window_type; @@ -158,8 +157,6 @@ 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); } /** @@ -368,8 +365,6 @@ gdk_window_impl_wayland_finalize (GObject *object) if (impl->server_surface) cairo_surface_destroy (impl->server_surface); - g_hash_table_destroy (impl->device_cursor); - G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object); } @@ -595,21 +590,9 @@ 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); } From 1cd65aea5336cf2eb40adcaf5406fa1f9ec3359a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 11 Feb 2011 17:07:19 -0500 Subject: [PATCH 39/42] wayland: Only set x, y, and modifiers if the pointers are non-NULL --- gdk/wayland/gdkdevice-wayland.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 20d28bf4e2..2a051de4da 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -214,9 +214,12 @@ gdk_device_core_window_at_position (GdkDevice *device, GdkWaylandDevice *wd; wd = GDK_DEVICE_CORE(device)->device; - *win_x = wd->surface_x; - *win_y = wd->surface_y; - *mask = wd->modifiers; + if (win_x) + *win_x = wd->surface_x; + if (win_y) + *win_y = wd->surface_y; + if (mask) + *mask = wd->modifiers; return wd->pointer_focus; } From b5134619a047cd208257ff0adc7d3aeb54bdd426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 11 Feb 2011 17:20:14 -0500 Subject: [PATCH 40/42] wayland: Map transient surfaces as such --- gdk/wayland/gdkwindow-wayland.c | 37 ++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 0388037731..2fbcab991f 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -100,6 +100,7 @@ struct _GdkWindowImplWayland struct wl_surface *surface; unsigned int mapped : 1; + GdkWindow *transient_for; cairo_surface_t *cairo_surface; cairo_surface_t *server_surface; @@ -447,6 +448,32 @@ gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time) { } +static void +gdk_wayland_window_map (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkWindowImplWayland *parent; + + if (!impl->mapped) + { + if (impl->transient_for) + { + fprintf(stderr, "parent surface: %d, %d, transient surface %d, %d\n", + impl->transient_for->x, + impl->transient_for->y, + window->x, + window->y); + + parent = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl); + wl_surface_map_transient (impl->surface, parent->surface, + window->x, window->y, 0); + } + else + wl_surface_map_toplevel (impl->surface); + impl->mapped = TRUE; + } +} + static void gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) { @@ -881,6 +908,10 @@ static void gdk_wayland_window_set_transient_for (GdkWindow *window, GdkWindow *parent) { + GdkWindowImplWayland *impl; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + impl->transient_for = parent; } static void @@ -1214,11 +1245,7 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window, if (impl->cairo_surface) gdk_wayland_window_attach_image (window); - if (!impl->mapped) - { - wl_surface_map_toplevel (impl->surface); - impl->mapped = TRUE; - } + gdk_wayland_window_map (window); n = cairo_region_num_rectangles(region); for (i = 0; i < n; i++) From 0e1041a8afe021ebc5aff25ad76e113af09ca021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 1 Mar 2011 11:32:05 -0500 Subject: [PATCH 41/42] wayland: Add another cursor (left-ptr) --- gdk/wayland/gdkcursor-wayland.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index e977929faf..e93abc8bb4 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -246,6 +246,7 @@ static const struct { { GDK_BLANK_CURSOR, NULL, 0, 0 }, { GDK_HAND1, DATADIR "/hand1.png", 18, 11 }, { GDK_HAND2, DATADIR "/hand2.png", 14, 8 }, + { GDK_LEFT_PTR, DATADIR "/left_ptr.png", 10, 5 }, { GDK_SB_H_DOUBLE_ARROW, DATADIR "/sb_h_double_arrow.png", 15, 15 }, { GDK_SB_V_DOUBLE_ARROW, DATADIR "/sb_v_double_arrow.png", 15, 15 }, { GDK_XTERM, DATADIR "/xterm.png", 15, 15 }, From fcd58b0ffd0935567437b89bb077f60195336764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 1 Mar 2011 11:33:07 -0500 Subject: [PATCH 42/42] wayland: Add modifier masks for meta, hyper and super keys Makes alt keybindings work in vte. --- gdk/wayland/gdkkeys-wayland.c | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c index 1513fe7f89..55c95e35dc 100644 --- a/gdk/wayland/gdkkeys-wayland.c +++ b/gdk/wayland/gdkkeys-wayland.c @@ -589,6 +589,43 @@ _gdk_wayland_keymap_init (GdkWaylandKeymap *keymap) { } +static void +update_keymaps (GdkWaylandKeymap *keymap) +{ + struct xkb_desc *xkb = keymap->xkb; + gint keycode, total_syms, i, modifier; + uint32_t *entry; + guint mask; + + for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++) + { + total_syms = XkbKeyNumSyms (xkb, keycode); + + entry = XkbKeySymsPtr (xkb, keycode); + mask = 0; + for (i = 0; i < total_syms; i++) + { + switch (entry[i]) { + case GDK_KEY_Meta_L: + case GDK_KEY_Meta_R: + mask |= GDK_META_MASK; + break; + case GDK_KEY_Hyper_L: + case GDK_KEY_Hyper_R: + mask |= GDK_HYPER_MASK; + break; + case GDK_KEY_Super_L: + case GDK_KEY_Super_R: + mask |= GDK_SUPER_MASK; + break; + } + } + + modifier = g_bit_nth_lsf(xkb->map->modmap[keycode], -1); + keymap->modmap[modifier] |= mask; + } +} + GdkKeymap * _gdk_wayland_keymap_new (GdkDisplay *display) { @@ -604,7 +641,9 @@ _gdk_wayland_keymap_new (GdkDisplay *display) names.variant = ""; names.options = ""; keymap->xkb = xkb_compile_keymap_from_rules(&names); + update_modmap (keymap); + update_keymaps (keymap); return GDK_KEYMAP (keymap); }