diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2010-12-18 15:38:49 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2011-02-05 16:11:54 -0500 |
commit | 590f3dfa1fcb812e4c334f574c6bb0431b131d04 (patch) | |
tree | 8cc912daf60928b0dd532a0172d4bedbcfdc96cf | |
parent | bfaf472e703a5378fe8e6b59e116e28dea7ccace (diff) | |
download | gtk+-590f3dfa1fcb812e4c334f574c6bb0431b131d04.tar.gz |
Add Wayland backend
26 files changed, 5444 insertions, 7 deletions
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 @@ -203,6 +207,11 @@ gdk_display_manager_get (void) 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); else 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 <string.h> +#include <unistd.h> + +#include <glib.h> +#include <gio/gdesktopappinfo.h> + +#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 <string.h> + +#include "gdkprivate-wayland.h" +#include "gdkcursorprivate.h" +#include "gdkdisplay-wayland.h" +#include "gdkwayland.h" +#include <gdk-pixbuf/gdk-pixbuf.h> + +#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 <carlosg@gnome.org> + * + * 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 <gdk/gdkwindow.h> +#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 <carlosg@gnome.org> + * + * 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 <gdk/gdkdeviceprivate.h> +#include <X11/extensions/XKBcommon.h> + +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 <carlosg@gnome.org> + * + * 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 <string.h> +#include <gdk/gdktypes.h> +#include <gdk/gdkdevicemanager.h> +#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 <carlosg@gnome.org> + * + * 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 <gdk/gdkdevicemanagerprivate.h> +#include <wayland-client.h> + +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 <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +#include <glib.h> +#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 <xf86drm.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) +{ + 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 <ulink + * url="http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt">Startup + * Notification Protocol specification</ulink> 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 <erwann.chenede@sun.com> + * + * 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 <stdint.h> +#include <wayland-client.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <cairo-gl.h> +#include <glib.h> +#include <gdk/gdkkeys.h> +#include <gdk/gdkwindow.h> +#include <gdk/gdkinternals.h> +#include <gdk/gdk.h> /* 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 <string.h> + +#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 <carlosg@gnome.org> + * + * 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 <carlosg@gnome.org> + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> + +#include "gdk.h" +#include "gdkwayland.h" + +#include "gdkprivate-wayland.h" +#include "gdkinternals.h" +#include "gdkdisplay-wayland.h" +#include "gdkkeysprivate.h" + +#include <X11/extensions/XKBcommon.h> + +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 <gdk/gdkcursor.h> +#include <gdk/gdkprivate.h> +#include <gdk/wayland/gdkwindow-wayland.h> +#include <gdk/wayland/gdkdisplay-wayland.h> + +#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 <stdlib.h> +#include <string.h> + +#include <glib.h> +#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 <erwann.chenede@sun.com> + * + * 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 <gdk/gdkscreenprivate.h> +#include <gdk/gdkvisual.h> + +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 <string.h> + +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 <gdk/gdk.h> + +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 <netinet/in.h> +#include <unistd.h> + +#include "gdk.h" +#include "gdkwayland.h" + +#include "gdkwindow.h" +#include "gdkwindowimpl.h" +#include "gdkdisplay-wayland.h" +#include "gdkscreen-wayland.h" +#include "gdkprivate-wayland.h" +#include "gdkinternals.h" +#include "gdkwindow-wayland.h" +#include "gdkdeviceprivate.h" +#include "gdkdevice-wayland.h" +#include "gdkeventsource.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) + +#define WINDOW_IS_TOPLEVEL(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) + +/* Return whether time1 is considered later than time2 as far as xserver + * time is concerned. Accounts for wraparound. + */ +#define XSERVER_TIME_IS_LATER(time1, time2) \ + ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \ + (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \ + ) + +typedef struct _GdkWaylandWindow GdkWaylandWindow; +typedef struct _GdkWaylandWindowClass GdkWaylandWindowClass; + +struct _GdkWaylandWindow { + GdkWindow parent; +}; + +struct _GdkWaylandWindowClass { + GdkWindowClass parent_class; +}; + +G_DEFINE_TYPE (GdkWaylandWindow, _gdk_wayland_window, GDK_TYPE_WINDOW) + +static void +_gdk_wayland_window_class_init (GdkWaylandWindowClass *wayland_window_class) +{ +} + +static void +_gdk_wayland_window_init (GdkWaylandWindow *wayland_window) +{ +} + +G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL) + +static void +_gdk_window_impl_wayland_init (GdkWindowImplWayland *impl) +{ + impl->toplevel_window_type = -1; + impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) gdk_cursor_unref); +} + +GdkToplevelWayland * +_gdk_wayland_window_get_toplevel (GdkWindow *window) +{ + GdkWindowImplWayland *impl; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (!WINDOW_IS_TOPLEVEL (window)) + return NULL; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (!impl->toplevel) + impl->toplevel = g_new0 (GdkToplevelWayland, 1); + + return impl->toplevel; +} + +/** + * _gdk_wayland_window_update_size: + * @drawable: a #GdkDrawableImplWayland. + * + * Updates the state of the drawable (in particular the drawable's + * cairo surface) when its size has changed. + **/ +void +_gdk_wayland_window_update_size (GdkWindowImplWayland *impl) +{ + GdkDisplayWayland *display_wayland = + GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); + + fprintf(stderr, "update size, window %p\n", impl->wrapper); + + if (impl->cairo_surface) + { + cairo_surface_destroy (impl->cairo_surface); + impl->cairo_surface = NULL; + } + + if (impl->image) + { + if (impl->image == impl->next_image) + impl->next_image = NULL; + + if (impl->image != impl->pending_image) + display_wayland->destroy_image(display_wayland->egl_display, + impl->image); + + impl->image = NULL; + + fprintf(stderr, " - cleared image\n"); + } +} + +GdkWindow * +_gdk_wayland_screen_create_root_window (GdkScreen *screen, + int width, int height) +{ + GdkWindow *window; + GdkWindowImplWayland *impl; + + window = _gdk_display_create_window (gdk_screen_get_display (screen)); + window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL); + window->impl_window = window; + window->visual = gdk_screen_get_system_visual (screen); + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + impl->wrapper = GDK_WINDOW (window); + + window->window_type = GDK_WINDOW_ROOT; + window->depth = 32; + + window->x = 0; + window->y = 0; + window->abs_x = 0; + window->abs_y = 0; + window->width = width; + window->height = height; + window->viewable = TRUE; + + /* see init_randr_support() in gdkscreen-wayland.c */ + window->event_mask = GDK_STRUCTURE_MASK; + + return window; +} + +static const gchar * +get_default_title (void) +{ + const char *title; + + title = g_get_application_name (); + if (!title) + title = g_get_prgname (); + if (!title) + title = ""; + + return title; +} + +void +_gdk_wayland_display_create_window_impl (GdkDisplay *display, + GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask) +{ + GdkWindowImplWayland *impl; + GdkDisplayWayland *display_wayland; + const char *title; + + display_wayland = GDK_DISPLAY_WAYLAND (display); + + impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL); + window->impl = GDK_WINDOW_IMPL (impl); + impl->wrapper = GDK_WINDOW (window); + + printf("impl_new for window %p: %p\n", window, impl); + + if (window->width > 65535 || + window->height > 65535) + { + g_warning ("Native Windows wider or taller than 65535 pixels are not supported"); + + if (window->width > 65535) + window->width = 65535; + if (window->height > 65535) + window->height = 65535; + } + + g_object_ref (window); + + switch (GDK_WINDOW_TYPE (window)) + { + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_TEMP: + if (attributes_mask & GDK_WA_TITLE) + title = attributes->title; + else + title = get_default_title (); + + gdk_window_set_title (window, title); + break; + + case GDK_WINDOW_CHILD: + default: + break; + } + + if (attributes_mask & GDK_WA_TYPE_HINT) + gdk_window_set_type_hint (window, attributes->type_hint); +} + +static void +gdk_toplevel_wayland_free_contents (GdkDisplay *display, + GdkToplevelWayland *toplevel) +{ + if (toplevel->icon_pixmap) + { + cairo_surface_destroy (toplevel->icon_pixmap); + toplevel->icon_pixmap = NULL; + } + if (toplevel->icon_mask) + { + cairo_surface_destroy (toplevel->icon_mask); + toplevel->icon_mask = NULL; + } +} + +void +_gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image) +{ + GdkDisplayWayland *display_wayland = + GDK_DISPLAY_WAYLAND (gdk_window_get_display (window)); + GdkWindowImplWayland *impl; + EGLint name, stride; + struct wl_visual *wl_visual; + struct wl_buffer *buffer; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (impl->pending_image) + { + if (impl->next_image && impl->next_image != impl->image) + display_wayland->destroy_image(display_wayland->egl_display, + impl->next_image); + + impl->next_image = image; + + return; + } + + impl->pending_image = image; + + wl_visual = + wl_display_get_premultiplied_argb_visual(display_wayland->wl_display); + + display_wayland->export_drm_image (display_wayland->egl_display, + image, &name, NULL, &stride); + + buffer = wl_drm_create_buffer(display_wayland->drm, + name, window->width, window->height, + stride, wl_visual); + wl_surface_attach (impl->surface, buffer, 0, 0); + wl_surface_map_toplevel (impl->surface); + wl_buffer_destroy(buffer); + + g_object_ref(impl); + + fprintf(stderr, "attach %p %dx%d (image %p, name %d)\n", + window, window->width, window->height, + impl->pending_image, name); +} + +static void +gdk_window_impl_wayland_finalize (GObject *object) +{ + GdkWindow *wrapper; + GdkWindowImplWayland *impl; + + g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (object)); + + impl = GDK_WINDOW_IMPL_WAYLAND (object); + + wrapper = impl->wrapper; + + g_free (impl->toplevel); + + if (impl->cursor) + gdk_cursor_unref (impl->cursor); + + g_hash_table_destroy (impl->device_cursor); + + G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object); +} + +static const cairo_user_data_key_t gdk_wayland_cairo_key; + +static void +gdk_wayland_cairo_surface_destroy (void *data) +{ + GdkWindowImplWayland *impl = data; + + impl->cairo_surface = NULL; +} + +gboolean +_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + int width, + int height) +{ + fprintf (stderr, "_gdk_windowing_set_cairo_surface_size\n"); + + return FALSE; +} + +static cairo_surface_t * +gdk_wayland_create_cairo_surface (GdkWindowImplWayland *impl, + int width, + int height) +{ + GdkDisplayWayland *display_wayland = + GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper)); + cairo_surface_t *surface; + + EGLint image_attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + + if (impl->image == NULL) + { + image_attribs[1] = width; + image_attribs[3] = height; + impl->image = + display_wayland->create_drm_image(display_wayland->egl_display, + image_attribs); + if (impl->texture == 0) + glGenTextures(1, &impl->texture); + + glBindTexture(GL_TEXTURE_2D, impl->texture); + display_wayland->image_target_texture_2d(GL_TEXTURE_2D, impl->image); + + printf("allocate image %dx%d (image %p, window %p)\n", + width, height, impl->image, impl->wrapper); + } + + surface = cairo_gl_surface_create_for_texture(display_wayland->cairo_device, + CAIRO_CONTENT_COLOR_ALPHA, + impl->texture, width, height); + + if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) + fprintf (stderr, "create gl surface failed\n"); + + return surface; +} + +static cairo_surface_t * +gdk_wayland_window_ref_cairo_surface (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (GDK_WINDOW_DESTROYED (impl->wrapper)) + return NULL; + + if (!impl->cairo_surface) + { + impl->cairo_surface = + gdk_wayland_create_cairo_surface (impl, + impl->wrapper->width, + impl->wrapper->height); + + cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key, + impl, gdk_wayland_cairo_surface_destroy); + } + else + cairo_surface_reference (impl->cairo_surface); + + return impl->cairo_surface; +} + +static void +gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time) +{ +} + +static void +gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped) +{ + GdkDisplay *display; + GdkDisplayWayland *display_wayland; + GdkToplevelWayland *toplevel; + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (WINDOW_IS_TOPLEVEL (window)) + { + display = gdk_window_get_display (window); + display_wayland = GDK_DISPLAY_WAYLAND (display); + toplevel = _gdk_wayland_window_get_toplevel (window); + + if (toplevel->user_time != 0 && + display_wayland->user_time != 0 && + XSERVER_TIME_IS_LATER (display_wayland->user_time, toplevel->user_time)) + gdk_wayland_window_set_user_time (window, display_wayland->user_time); + } + + display = gdk_window_get_display (window); + display_wayland = GDK_DISPLAY_WAYLAND (display); + + impl->surface = wl_compositor_create_surface(display_wayland->compositor); + wl_surface_set_user_data(impl->surface, window); + + _gdk_make_event (window, GDK_MAP, NULL, FALSE); +} + +static void +gdk_wayland_window_hide (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (impl->surface) + { + fprintf (stderr, "hide surface %p\n", impl->surface); + + wl_surface_destroy(impl->surface); + impl->surface = NULL; + } + + _gdk_window_clear_update_area (window); +} + +static void +gdk_window_wayland_withdraw (GdkWindow *window) +{ + GdkWindowImplWayland *impl; + + if (!window->destroyed) + { + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_WITHDRAWN); + + g_assert (!GDK_WINDOW_IS_MAPPED (window)); + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + if (impl->surface) + { + fprintf (stderr, "hide surface %p\n", impl->surface); + + wl_surface_destroy(impl->surface); + impl->surface = NULL; + cairo_surface_destroy(GDK_WINDOW_IMPL_WAYLAND(impl)->cairo_surface); + } + } +} + +static void +gdk_window_wayland_set_events (GdkWindow *window, + GdkEventMask event_mask) +{ + GDK_WINDOW (window)->event_mask = event_mask; +} + +static GdkEventMask +gdk_window_wayland_get_events (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return 0; + else + return GDK_WINDOW (window)->event_mask; +} + +static void +gdk_window_wayland_raise (GdkWindow *window) +{ + /* FIXME: wl_shell_raise() */ +} + +static void +gdk_window_wayland_lower (GdkWindow *window) +{ + /* FIXME: wl_shell_lower() */ +} + +static void +gdk_window_wayland_restack_under (GdkWindow *window, + GList *native_siblings) +{ +} + +static void +gdk_window_wayland_restack_toplevel (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ +} + +static void +gdk_window_wayland_move_resize (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowImplWayland *impl; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + window->x = x; + window->y = y; + if (width > 0) + window->width = width; + if (height > 0) + window->height = height; + + _gdk_wayland_window_update_size (GDK_WINDOW_IMPL_WAYLAND (window->impl)); +} + +static void +gdk_window_wayland_set_background (GdkWindow *window, + cairo_pattern_t *pattern) +{ +} + +static gboolean +gdk_window_wayland_reparent (GdkWindow *window, + GdkWindow *new_parent, + gint x, + gint y) +{ + return FALSE; +} + +static void +gdk_window_wayland_set_device_cursor (GdkWindow *window, + GdkDevice *device, + GdkCursor *cursor) +{ + GdkWindowImplWayland *impl; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_IS_DEVICE (device)); + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (!cursor) + g_hash_table_remove (impl->device_cursor, device); + else + { + g_hash_table_replace (impl->device_cursor, + device, gdk_cursor_ref (cursor)); + } + + if (!GDK_WINDOW_DESTROYED (window)) + GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor); +} + +static void +gdk_window_wayland_get_geometry (GdkWindow *window, + gint *x, + gint *y, + gint *width, + gint *height) +{ + if (!GDK_WINDOW_DESTROYED (window)) + { + if (x) + *x = window->x; + if (y) + *y = window->y; + if (width) + *width = window->width; + if (height) + *height = window->height; + } +} + +static gint +gdk_window_wayland_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) +{ + /* We can't do this. */ + if (root_x) + *root_x = 0; + if (root_y) + *root_y = 0; + + return 1; +} + +static gboolean +gdk_window_wayland_get_device_state (GdkWindow *window, + GdkDevice *device, + gint *x, + gint *y, + GdkModifierType *mask) +{ + gboolean return_val; + + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE); + + return_val = TRUE; + + if (!GDK_WINDOW_DESTROYED (window)) + { + GdkWindow *child; + + GDK_DEVICE_GET_CLASS (device)->query_state (device, window, + NULL, &child, + NULL, NULL, + x, y, mask); + return_val = (child != NULL); + } + + return return_val; +} + +static void +gdk_window_wayland_shape_combine_region (GdkWindow *window, + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static void +gdk_window_wayland_input_shape_combine_region (GdkWindow *window, + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static gboolean +gdk_window_wayland_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + return TRUE; +} + +static gboolean +gdk_wayland_window_queue_antiexpose (GdkWindow *window, + cairo_region_t *area) +{ + return FALSE; +} + +static void +gdk_wayland_window_translate (GdkWindow *window, + cairo_region_t *area, + gint dx, + gint dy) +{ + cairo_surface_t *surface; + cairo_t *cr; + + surface = gdk_wayland_window_ref_cairo_surface (window->impl_window); + cr = cairo_create (surface); + cairo_surface_destroy (surface); + + gdk_cairo_region (cr, area); + cairo_clip (cr); + cairo_set_source_surface (cr, cairo_get_target (cr), dx, dy); + cairo_push_group (cr); + cairo_paint (cr); + cairo_pop_group_to_source (cr); + cairo_paint (cr); + cairo_destroy (cr); +} + +static void +gdk_wayland_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) +{ + GdkToplevelWayland *toplevel; + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + g_return_if_fail (GDK_IS_WINDOW (window)); + + toplevel = _gdk_wayland_window_get_toplevel (window); + if (toplevel) + gdk_toplevel_wayland_free_contents (gdk_window_get_display (window), + toplevel); + + if (impl->cairo_surface) + { + cairo_surface_finish (impl->cairo_surface); + cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key, + NULL, NULL); + } + + if (impl->texture) + glDeleteTextures(1, &impl->texture); + + if (!recursing && !foreign_destroy) + { + fprintf (stderr, "destroy window, surface %p\n", + GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface); + + if (GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface) + wl_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface); + } +} + +static void +gdk_window_wayland_destroy_foreign (GdkWindow *window) +{ +} + +static cairo_surface_t * +gdk_window_wayland_resize_cairo_surface (GdkWindow *window, + cairo_surface_t *surface, + gint width, + gint height) +{ + return surface; +} + +static cairo_region_t * +gdk_wayland_window_get_shape (GdkWindow *window) +{ + return NULL; +} + +static cairo_region_t * +gdk_wayland_window_get_input_shape (GdkWindow *window) +{ + return NULL; +} + +static void +gdk_wayland_window_focus (GdkWindow *window, + guint32 timestamp) +{ + /* FIXME: wl_shell_focus() */ +} + +static void +gdk_wayland_window_set_type_hint (GdkWindow *window, + GdkWindowTypeHint hint) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; + + switch (hint) + { + case GDK_WINDOW_TYPE_HINT_DIALOG: + case GDK_WINDOW_TYPE_HINT_MENU: + case GDK_WINDOW_TYPE_HINT_TOOLBAR: + case GDK_WINDOW_TYPE_HINT_UTILITY: + case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN: + case GDK_WINDOW_TYPE_HINT_DOCK: + case GDK_WINDOW_TYPE_HINT_DESKTOP: + case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: + case GDK_WINDOW_TYPE_HINT_POPUP_MENU: + case GDK_WINDOW_TYPE_HINT_TOOLTIP: + case GDK_WINDOW_TYPE_HINT_NOTIFICATION: + case GDK_WINDOW_TYPE_HINT_COMBO: + case GDK_WINDOW_TYPE_HINT_DND: + break; + default: + g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint); + /* Fall thru */ + case GDK_WINDOW_TYPE_HINT_NORMAL: + break; + } +} + +static GdkWindowTypeHint +gdk_wayland_window_get_type_hint (GdkWindow *window) +{ + return GDK_WINDOW_TYPE_HINT_NORMAL; +} + +void +gdk_wayland_window_set_modal_hint (GdkWindow *window, + gboolean modal) +{ +} + +static void +gdk_wayland_window_set_skip_taskbar_hint (GdkWindow *window, + gboolean skips_taskbar) +{ +} + +static void +gdk_wayland_window_set_skip_pager_hint (GdkWindow *window, + gboolean skips_pager) +{ +} + +static void +gdk_wayland_window_set_urgency_hint (GdkWindow *window, + gboolean urgent) +{ +} + +static void +gdk_wayland_window_set_geometry_hints (GdkWindow *window, + const GdkGeometry *geometry, + GdkWindowHints geom_mask) +{ + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + /* + * GDK_HINT_POS + * GDK_HINT_USER_POS + * GDK_HINT_USER_SIZE + * GDK_HINT_MIN_SIZE + * GDK_HINT_MAX_SIZE + * GDK_HINT_BASE_SIZE + * GDK_HINT_RESIZE_INC + * GDK_HINT_ASPECT + * GDK_HINT_WIN_GRAVITY + */ +} + +static void +gdk_wayland_window_set_title (GdkWindow *window, + const gchar *title) +{ + g_return_if_fail (title != NULL); + + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_set_role (GdkWindow *window, + const gchar *role) +{ +} + +static void +gdk_wayland_window_set_startup_id (GdkWindow *window, + const gchar *startup_id) +{ +} + +static void +gdk_wayland_window_set_transient_for (GdkWindow *window, + GdkWindow *parent) +{ +} + +static void +gdk_wayland_window_get_root_origin (GdkWindow *window, + gint *x, + gint *y) +{ + if (x) + *x = 0; + + if (y) + *y = 0; +} + +static void +gdk_wayland_window_get_frame_extents (GdkWindow *window, + GdkRectangle *rect) +{ + rect->x = window->x; + rect->y = window->y; + rect->width = window->width; + rect->height = window->height; +} + +static void +gdk_wayland_window_set_override_redirect (GdkWindow *window, + gboolean override_redirect) +{ +} + +static void +gdk_wayland_window_set_accept_focus (GdkWindow *window, + gboolean accept_focus) +{ +} + +static void +gdk_wayland_window_set_focus_on_map (GdkWindow *window, + gboolean focus_on_map) +{ + focus_on_map = focus_on_map != FALSE; + + if (window->focus_on_map != focus_on_map) + { + window->focus_on_map = focus_on_map; + + if ((!GDK_WINDOW_DESTROYED (window)) && + (!window->focus_on_map) && + WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + gdk_wayland_window_set_user_time (window, 0); + } +} + +static void +gdk_wayland_window_set_icon_list (GdkWindow *window, + GList *pixbufs) +{ +} + +static void +gdk_wayland_window_set_icon_name (GdkWindow *window, + const gchar *name) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_iconify (GdkWindow *window) +{ +} + +static void +gdk_wayland_window_deiconify (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + if (GDK_WINDOW_IS_MAPPED (window)) + { + gdk_window_show (window); + } + else + { + /* Flip our client side flag, the real work happens on map. */ + gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0); + } +} + +static void +gdk_wayland_window_stick (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_unstick (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_maximize (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_unmaximize (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_fullscreen (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_unfullscreen (GdkWindow *window) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_set_keep_above (GdkWindow *window, + gboolean setting) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static void +gdk_wayland_window_set_keep_below (GdkWindow *window, gboolean setting) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; +} + +static GdkWindow * +gdk_wayland_window_get_group (GdkWindow *window) +{ + GdkToplevelWayland *toplevel; + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return NULL; + + return NULL; +} + +static void +gdk_wayland_window_set_group (GdkWindow *window, + GdkWindow *leader) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD); + g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader)); +} + +static void +gdk_wayland_window_set_decorations (GdkWindow *window, + GdkWMDecoration decorations) +{ +} + +static gboolean +gdk_wayland_window_get_decorations (GdkWindow *window, + GdkWMDecoration *decorations) +{ + return FALSE; +} + +static void +gdk_wayland_window_set_functions (GdkWindow *window, + GdkWMFunction functions) +{ +} + +enum wl_grab_type { + WL_DEVICE_GRAB_NONE = 0, + WL_DEVICE_GRAB_RESIZE_TOP = 1, + WL_DEVICE_GRAB_RESIZE_BOTTOM = 2, + WL_DEVICE_GRAB_RESIZE_LEFT = 4, + WL_DEVICE_GRAB_RESIZE_TOP_LEFT = 5, + WL_DEVICE_GRAB_RESIZE_BOTTOM_LEFT = 6, + WL_DEVICE_GRAB_RESIZE_RIGHT = 8, + WL_DEVICE_GRAB_RESIZE_TOP_RIGHT = 9, + WL_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT = 10, + WL_DEVICE_GRAB_RESIZE_MASK = 15, + WL_DEVICE_GRAB_MOVE = 16, + WL_DEVICE_GRAB_MOTION = 17 +}; + +static void +gdk_wayland_window_begin_resize_drag (GdkWindow *window, + GdkWindowEdge edge, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) +{ + GdkDisplay *display = gdk_window_get_display (window); + GdkDeviceManager *dm; + GdkWindowImplWayland *impl; + GdkDevice *device; + uint32_t grab_type; + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + switch (edge) + { + case GDK_WINDOW_EDGE_NORTH_WEST: + grab_type = WL_DEVICE_GRAB_RESIZE_TOP_LEFT; + break; + + case GDK_WINDOW_EDGE_NORTH: + grab_type = WL_DEVICE_GRAB_RESIZE_TOP; + break; + + case GDK_WINDOW_EDGE_NORTH_EAST: + grab_type = WL_DEVICE_GRAB_RESIZE_RIGHT; + break; + + case GDK_WINDOW_EDGE_WEST: + grab_type = WL_DEVICE_GRAB_RESIZE_LEFT; + break; + + case GDK_WINDOW_EDGE_EAST: + grab_type = WL_DEVICE_GRAB_RESIZE_RIGHT; + break; + + case GDK_WINDOW_EDGE_SOUTH_WEST: + grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM_LEFT; + break; + + case GDK_WINDOW_EDGE_SOUTH: + grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM; + break; + + case GDK_WINDOW_EDGE_SOUTH_EAST: + grab_type = WL_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT; + break; + + default: + g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", + edge); + return; + } + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + dm = gdk_display_get_device_manager (display); + device = gdk_device_manager_get_client_pointer (dm); + + wl_shell_resize(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface, + GDK_DEVICE_CORE (device)->device->device, + timestamp, grab_type); +} + +static void +gdk_wayland_window_begin_move_drag (GdkWindow *window, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) +{ + GdkDisplay *display = gdk_window_get_display (window); + GdkDeviceManager *dm; + GdkWindowImplWayland *impl; + GdkDevice *device; + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + dm = gdk_display_get_device_manager (display); + device = gdk_device_manager_get_client_pointer (dm); + + wl_shell_move(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface, + GDK_DEVICE_CORE (device)->device->device, timestamp); +} + +static void +gdk_wayland_window_enable_synchronized_configure (GdkWindow *window) +{ +} + +static void +gdk_wayland_window_configure_finished (GdkWindow *window) +{ + GdkWindowImplWayland *impl; + + if (!WINDOW_IS_TOPLEVEL (window)) + return; + + if (!GDK_IS_WINDOW_IMPL_WAYLAND (window->impl)) + return; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + fprintf(stderr, "configure %p finished\n", window); + + gdk_wayland_window_ref_cairo_surface (GDK_WINDOW (impl)); + + _gdk_wayland_window_attach_image (window, impl->image); + + cairo_surface_destroy (impl->cairo_surface); +} + +static void +gdk_wayland_window_set_opacity (GdkWindow *window, + gdouble opacity) +{ +} + +static void +gdk_wayland_window_set_composited (GdkWindow *window, + gboolean composited) +{ +} + +static void +gdk_wayland_window_destroy_notify (GdkWindow *window) +{ + GdkWindowImplWayland *window_impl; + + window_impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN) + g_warning ("GdkWindow %p unexpectedly destroyed", window); + + _gdk_window_destroy (window, TRUE); + } + + g_object_unref (window); +} + +static void +gdk_wayland_window_process_updates_recurse (GdkWindow *window, + cairo_region_t *region) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + cairo_rectangle_int_t rect; + int i, n; + +#if 0 + gdk_wayland_window_ref_cairo_surface (window); + + _gdk_wayland_window_attach_image (window, impl->image); + cairo_surface_destroy (impl->cairo_surface); +#endif + + n = cairo_region_num_rectangles(region); + for (i = 0; i < n; i++) + { + cairo_region_get_rectangle (region, i, &rect); + wl_surface_damage (impl->surface, + rect.x, rect.y, rect.width, rect.height); + } + + _gdk_window_process_updates_recurse (window, region); +} + +static void +gdk_wayland_window_sync_rendering (GdkWindow *window) +{ +} + +static gboolean +gdk_wayland_window_simulate_key (GdkWindow *window, + gint x, + gint y, + guint keyval, + GdkModifierType modifiers, + GdkEventType key_pressrelease) +{ + return FALSE; +} + +static gboolean +gdk_wayland_window_simulate_button (GdkWindow *window, + gint x, + gint y, + guint button, /*1..3*/ + GdkModifierType modifiers, + GdkEventType button_pressrelease) +{ + return FALSE; +} + +static gboolean +gdk_wayland_window_get_property (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gulong offset, + gulong length, + gint pdelete, + GdkAtom *actual_property_type, + gint *actual_format_type, + gint *actual_length, + guchar **data) +{ + return FALSE; +} + +static void +gdk_wayland_window_change_property (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gint format, + GdkPropMode mode, + const guchar *data, + gint nelements) +{ +} + +static void +gdk_wayland_window_delete_property (GdkWindow *window, + GdkAtom property) +{ +} + +static void +_gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass); + + object_class->finalize = gdk_window_impl_wayland_finalize; + + impl_class->ref_cairo_surface = gdk_wayland_window_ref_cairo_surface; + impl_class->show = gdk_wayland_window_show; + impl_class->hide = gdk_wayland_window_hide; + impl_class->withdraw = gdk_window_wayland_withdraw; + impl_class->set_events = gdk_window_wayland_set_events; + impl_class->get_events = gdk_window_wayland_get_events; + impl_class->raise = gdk_window_wayland_raise; + impl_class->lower = gdk_window_wayland_lower; + impl_class->restack_under = gdk_window_wayland_restack_under; + impl_class->restack_toplevel = gdk_window_wayland_restack_toplevel; + impl_class->move_resize = gdk_window_wayland_move_resize; + impl_class->set_background = gdk_window_wayland_set_background; + impl_class->reparent = gdk_window_wayland_reparent; + impl_class->set_device_cursor = gdk_window_wayland_set_device_cursor; + impl_class->get_geometry = gdk_window_wayland_get_geometry; + impl_class->get_root_coords = gdk_window_wayland_get_root_coords; + impl_class->get_device_state = gdk_window_wayland_get_device_state; + impl_class->shape_combine_region = gdk_window_wayland_shape_combine_region; + impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region; + impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities; + impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose; + impl_class->translate = gdk_wayland_window_translate; + impl_class->destroy = gdk_wayland_window_destroy; + impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign; + impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface; + impl_class->get_shape = gdk_wayland_window_get_shape; + impl_class->get_input_shape = gdk_wayland_window_get_input_shape; + /* impl_class->beep */ + + impl_class->focus = gdk_wayland_window_focus; + impl_class->set_type_hint = gdk_wayland_window_set_type_hint; + impl_class->get_type_hint = gdk_wayland_window_get_type_hint; + impl_class->set_modal_hint = gdk_wayland_window_set_modal_hint; + impl_class->set_skip_taskbar_hint = gdk_wayland_window_set_skip_taskbar_hint; + impl_class->set_skip_pager_hint = gdk_wayland_window_set_skip_pager_hint; + impl_class->set_urgency_hint = gdk_wayland_window_set_urgency_hint; + impl_class->set_geometry_hints = gdk_wayland_window_set_geometry_hints; + impl_class->set_title = gdk_wayland_window_set_title; + impl_class->set_role = gdk_wayland_window_set_role; + impl_class->set_startup_id = gdk_wayland_window_set_startup_id; + impl_class->set_transient_for = gdk_wayland_window_set_transient_for; + impl_class->get_root_origin = gdk_wayland_window_get_root_origin; + impl_class->get_frame_extents = gdk_wayland_window_get_frame_extents; + impl_class->set_override_redirect = gdk_wayland_window_set_override_redirect; + impl_class->set_accept_focus = gdk_wayland_window_set_accept_focus; + impl_class->set_focus_on_map = gdk_wayland_window_set_focus_on_map; + impl_class->set_icon_list = gdk_wayland_window_set_icon_list; + impl_class->set_icon_name = gdk_wayland_window_set_icon_name; + impl_class->iconify = gdk_wayland_window_iconify; + impl_class->deiconify = gdk_wayland_window_deiconify; + impl_class->stick = gdk_wayland_window_stick; + impl_class->unstick = gdk_wayland_window_unstick; + impl_class->maximize = gdk_wayland_window_maximize; + impl_class->unmaximize = gdk_wayland_window_unmaximize; + impl_class->fullscreen = gdk_wayland_window_fullscreen; + impl_class->unfullscreen = gdk_wayland_window_unfullscreen; + impl_class->set_keep_above = gdk_wayland_window_set_keep_above; + impl_class->set_keep_below = gdk_wayland_window_set_keep_below; + impl_class->get_group = gdk_wayland_window_get_group; + impl_class->set_group = gdk_wayland_window_set_group; + impl_class->set_decorations = gdk_wayland_window_set_decorations; + impl_class->get_decorations = gdk_wayland_window_get_decorations; + impl_class->set_functions = gdk_wayland_window_set_functions; + impl_class->begin_resize_drag = gdk_wayland_window_begin_resize_drag; + impl_class->begin_move_drag = gdk_wayland_window_begin_move_drag; + impl_class->enable_synchronized_configure = gdk_wayland_window_enable_synchronized_configure; + impl_class->configure_finished = gdk_wayland_window_configure_finished; + impl_class->set_opacity = gdk_wayland_window_set_opacity; + impl_class->set_composited = gdk_wayland_window_set_composited; + impl_class->destroy_notify = gdk_wayland_window_destroy_notify; + impl_class->register_dnd = _gdk_wayland_window_register_dnd; + impl_class->drag_begin = _gdk_wayland_window_drag_begin; + impl_class->process_updates_recurse = gdk_wayland_window_process_updates_recurse; + impl_class->sync_rendering = gdk_wayland_window_sync_rendering; + impl_class->simulate_key = gdk_wayland_window_simulate_key; + impl_class->simulate_button = gdk_wayland_window_simulate_button; + impl_class->get_property = gdk_wayland_window_get_property; + impl_class->change_property = gdk_wayland_window_change_property; + impl_class->delete_property = gdk_wayland_window_delete_property; +} 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 <gdk/wayland/gdkprivate-wayland.h> +#include <gdk/gdkwindowimpl.h> + +#include <stdint.h> +#include <wayland-client.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GL/gl.h> + +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); } |