[gtk+/xi2] First go at migrating the quartz backend to xi2 branch.



commit 5c3c1f450cd659a0aaa9dd821ea60f6c046a9e8e
Author: Kristian Rietveld <kris gtk org>
Date:   Sat Feb 6 16:54:27 2010 +0100

    First go at migrating the quartz backend to xi2 branch.

 gdk/quartz/Makefile.am             |    2 +
 gdk/quartz/gdkdevice-core.c        |  396 ++++++++++++++++++++++++++++++++++++
 gdk/quartz/gdkdevice-core.h        |   51 +++++
 gdk/quartz/gdkdevicemanager-core.c |  130 ++++++++++++
 gdk/quartz/gdkdevicemanager-core.h |   54 +++++
 gdk/quartz/gdkdisplay-quartz.c     |   11 +
 gdk/quartz/gdkevents-quartz.c      |  160 ++++++++-------
 gdk/quartz/gdkinput.c              |  310 ++++++++++-------------------
 gdk/quartz/gdkinputprivate.h       |    5 -
 gdk/quartz/gdkprivate-quartz.h     |    3 +-
 gdk/quartz/gdkwindow-quartz.c      |  112 ++++++-----
 11 files changed, 906 insertions(+), 328 deletions(-)
---
diff --git a/gdk/quartz/Makefile.am b/gdk/quartz/Makefile.am
index a5721b1..ac6c2c7 100644
--- a/gdk/quartz/Makefile.am
+++ b/gdk/quartz/Makefile.am
@@ -24,6 +24,8 @@ libgdk_quartz_la_SOURCES =    	\
 	gdkapplaunchcontext-quartz.c \
 	gdkcolor-quartz.c	\
 	gdkcursor-quartz.c	\
+	gdkdevice-core.c	\
+	gdkdevicemanager-core.c	\
 	gdkdisplay-quartz.c	\
 	gdkdnd-quartz.c		\
 	gdkdrawable-quartz.c	\
diff --git a/gdk/quartz/gdkdevice-core.c b/gdk/quartz/gdkdevice-core.c
new file mode 100644
index 0000000..dcd3204
--- /dev/null
+++ b/gdk/quartz/gdkdevice-core.c
@@ -0,0 +1,396 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg gnome org>
+ * Copyright (C) 2010 Kristian Rietveld <kris gtk 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"
+
+#import "GdkQuartzView.h"
+#include "gdkwindow-quartz.h"
+#include "gdkprivate-quartz.h"
+#include "gdkdevice-core.h"
+
+static gboolean gdk_device_core_get_history (GdkDevice      *device,
+                                             GdkWindow      *window,
+                                             guint32         start,
+                                             guint32         stop,
+                                             GdkTimeCoord ***events,
+                                             guint          *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,
+                             guint          *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
+translate_coords_to_child_coords (GdkWindow *parent,
+                                  GdkWindow *child,
+                                  gint      *x,
+                                  gint      *y)
+{
+  GdkWindow *current = child;
+
+  if (child == parent)
+    return;
+
+  while (current != parent)
+    {
+      gint tmp_x, tmp_y;
+
+      gdk_window_get_origin (current, &tmp_x, &tmp_y);
+
+      *x -= tmp_x;
+      *y -= tmp_y;
+
+      current = gdk_window_get_parent (current);
+    }
+}
+
+static void
+gdk_device_core_set_window_cursor (GdkDevice *device,
+                                   GdkWindow *window,
+                                   GdkCursor *cursor)
+{
+  GdkCursorPrivate *cursor_private;
+  NSCursor *nscursor;
+
+  cursor_private = (GdkCursorPrivate*) cursor;
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  if (!cursor)
+    nscursor = [NSCursor arrowCursor];
+  else
+    nscursor = cursor_private->nscursor;
+
+  [nscursor set];
+}
+
+static void
+gdk_device_core_warp (GdkDevice *device,
+                      GdkScreen *screen,
+                      gint       x,
+                      gint       y)
+{
+  CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
+}
+
+static GdkWindow *
+gdk_device_core_query_state_helper (GdkWindow       *window,
+                                    GdkDevice       *device,
+                                    gint            *x,
+                                    gint            *y,
+                                    GdkModifierType *mask)
+{
+  GdkWindowObject *toplevel;
+  GdkWindowObject *private;
+  NSPoint point;
+  gint x_tmp, y_tmp;
+  GdkWindow *found_window;
+
+  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
+
+  if (GDK_WINDOW_DESTROYED (window))
+    {
+      *x = 0;
+      *y = 0;
+      *mask = 0;
+      return NULL;
+    }
+
+  toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window));
+
+  *mask = _gdk_quartz_events_get_current_event_mask ();
+
+  /* Get the y coordinate, needs to be flipped. */
+  if (window == _gdk_root)
+    {
+      point = [NSEvent mouseLocation];
+      _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
+    }
+  else
+    {
+      GdkWindowImplQuartz *impl;
+      NSWindow *nswindow;
+
+      impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
+      private = GDK_WINDOW_OBJECT (toplevel);
+      nswindow = impl->toplevel;
+
+      point = [nswindow mouseLocationOutsideOfEventStream];
+
+      x_tmp = point.x;
+      y_tmp = private->height - point.y;
+
+      window = (GdkWindow *)toplevel;
+    }
+
+  found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
+                                                FALSE);
+  /* FIXME: Translate!!! */
+
+#if 0
+  /* We never return the root window. */
+  if (found_window == _gdk_root)
+    found_window = NULL;
+#endif
+  if (found_window)
+    translate_coords_to_child_coords (window, found_window,
+                                      &x_tmp, &y_tmp);
+
+  *x = x_tmp;
+  *y = y_tmp;
+
+  return found_window;
+}
+
+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)
+{
+  GdkDisplay *display;
+  GdkWindow *found_window;
+  NSPoint point;
+  gint x_tmp, y_tmp;
+
+  found_window = gdk_device_core_query_state_helper (window, device,
+                                                     win_x, win_y,
+                                                     mask);
+  if (!found_window)
+    return FALSE;
+
+  display = gdk_drawable_get_display (window);
+
+  if (root_window)
+    *root_window = _gdk_root;
+
+  if (child_window)
+    *child_window = found_window;
+
+  point = [NSEvent mouseLocation];
+  _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
+
+  if (root_x)
+    *root_x = x_tmp;
+
+  if (root_y)
+    *root_y = y_tmp;
+
+  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_)
+{
+  GdkDisplay *display;
+
+  display = gdk_device_get_display (device);
+
+  if (device->source == GDK_SOURCE_KEYBOARD)
+    {
+      /* Device is a keyboard */
+    }
+  else
+    {
+      _gdk_display_add_device_grab (display,
+                                    device,
+                                    window,
+                                    NULL,
+                                    GDK_OWNERSHIP_NONE,
+                                    owner_events,
+                                    event_mask,
+                                    0,
+                                    time_,
+                                    FALSE);
+    }
+
+  return GDK_GRAB_SUCCESS;
+}
+
+static void
+gdk_device_core_ungrab (GdkDevice *device,
+                        guint32    time_)
+{
+  GdkDisplay *display;
+
+  display = gdk_device_get_display (device);
+
+  if (device->source == GDK_SOURCE_KEYBOARD)
+    { /* FIXME */ }
+  else
+    {
+      GdkDeviceGrabInfo *grab;
+
+      grab = _gdk_display_get_last_device_grab (display, device);
+      if (grab)
+        grab->serial_end = 0;
+
+      _gdk_display_device_grab_update (display, device, 0);
+    }
+}
+
+static GdkWindow *
+gdk_device_core_window_at_position (GdkDevice       *device,
+                                    gint            *win_x,
+                                    gint            *win_y,
+                                    GdkModifierType *mask,
+                                    gboolean         get_toplevel)
+{
+  GdkDisplay *display;
+  GdkScreen *screen;
+  GdkWindow *found_window;
+  NSPoint point;
+  gint x_tmp, y_tmp;
+
+  display = gdk_device_get_display (device);
+  screen = gdk_display_get_default_screen (display);
+
+  /* Get mouse coordinates, find window under the mouse pointer */
+  point = [NSEvent mouseLocation];
+  _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
+
+  found_window = _gdk_quartz_window_find_child (_gdk_root, x_tmp, y_tmp,
+                                                get_toplevel);
+
+  if (found_window)
+    translate_coords_to_child_coords (_gdk_root, found_window,
+                                      &x_tmp, &y_tmp);
+
+  if (win_x)
+    *win_x = found_window ? x_tmp : -1;
+
+  if (win_y)
+    *win_y = found_window ? y_tmp : -1;
+
+  if (mask)
+    *mask = _gdk_quartz_events_get_current_event_mask ();
+
+  return found_window;
+}
+
+static void
+gdk_device_core_select_window_events (GdkDevice    *device,
+                                      GdkWindow    *window,
+                                      GdkEventMask  event_mask)
+{
+  /* The mask is set in the common code. */
+}
diff --git a/gdk/quartz/gdkdevice-core.h b/gdk/quartz/gdkdevice-core.h
new file mode 100644
index 0000000..8f53d6f
--- /dev/null
+++ b/gdk/quartz/gdkdevice-core.h
@@ -0,0 +1,51 @@
+/* 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>
+
+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;
+
+struct _GdkDeviceCore
+{
+  GdkDevice parent_instance;
+};
+
+struct _GdkDeviceCoreClass
+{
+  GdkDeviceClass parent_class;
+};
+
+GType gdk_device_core_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_CORE_H__ */
diff --git a/gdk/quartz/gdkdevicemanager-core.c b/gdk/quartz/gdkdevicemanager-core.c
new file mode 100644
index 0000000..d4765c1
--- /dev/null
+++ b/gdk/quartz/gdkdevicemanager-core.c
@@ -0,0 +1,130 @@
+/* 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/gdktypes.h>
+#include <gdk/gdkdevicemanager.h>
+#include "gdkdevicemanager-core.h"
+#include "gdkdevice-core.h"
+#include "gdkkeysyms.h"
+
+
+#define HAS_FOCUS(toplevel)                           \
+  ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
+static void    gdk_device_manager_core_finalize    (GObject *object);
+static void    gdk_device_manager_core_constructed (GObject *object);
+
+static GList * gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
+                                                     GdkDeviceType     type);
+
+
+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;
+  object_class->constructed = gdk_device_manager_core_constructed;
+  device_manager_class->list_devices = gdk_device_manager_core_list_devices;
+}
+
+static GdkDevice *
+create_core_pointer (GdkDeviceManager *device_manager,
+                     GdkDisplay       *display)
+{
+  return 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);
+}
+
+static GdkDevice *
+create_core_keyboard (GdkDeviceManager *device_manager,
+                      GdkDisplay       *display)
+{
+  return 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);
+}
+
+static void
+gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager)
+{
+}
+
+static void
+gdk_device_manager_core_finalize (GObject *object)
+{
+  GdkDeviceManagerCore *device_manager_core;
+
+  device_manager_core = GDK_DEVICE_MANAGER_CORE (object);
+
+  g_object_unref (device_manager_core->core_pointer);
+  g_object_unref (device_manager_core->core_keyboard);
+
+  G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object);
+}
+
+static void
+gdk_device_manager_core_constructed (GObject *object)
+{
+  GdkDeviceManagerCore *device_manager;
+  GdkDisplay *display;
+
+  device_manager = GDK_DEVICE_MANAGER_CORE (object);
+  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
+  device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
+  device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
+
+  _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
+  _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
+}
+
+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_prepend (devices, device_manager_core->core_keyboard);
+      devices = g_list_prepend (devices, device_manager_core->core_pointer);
+    }
+
+  return devices;
+}
diff --git a/gdk/quartz/gdkdevicemanager-core.h b/gdk/quartz/gdkdevicemanager-core.h
new file mode 100644
index 0000000..0a337fc
--- /dev/null
+++ b/gdk/quartz/gdkdevicemanager-core.h
@@ -0,0 +1,54 @@
+/* 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/gdkdevicemanager.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;
+};
+
+struct _GdkDeviceManagerCoreClass
+{
+  GdkDeviceManagerClass parent_class;
+};
+
+GType gdk_device_manager_core_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */
diff --git a/gdk/quartz/gdkdisplay-quartz.c b/gdk/quartz/gdkdisplay-quartz.c
index 5de6519..556f84e 100644
--- a/gdk/quartz/gdkdisplay-quartz.c
+++ b/gdk/quartz/gdkdisplay-quartz.c
@@ -23,6 +23,7 @@
 #include "gdk.h"
 #include "gdkprivate-quartz.h"
 #include "gdkscreen-quartz.h"
+#include "gdkdevicemanager-core.h"
 
 GdkWindow *
 gdk_display_get_default_group (GdkDisplay *display)
@@ -40,6 +41,14 @@ _gdk_windowing_set_default_display (GdkDisplay *display)
   g_assert (display == NULL || _gdk_display == display);
 }
 
+GdkDeviceManager *
+_gdk_device_manager_new (GdkDisplay *display)
+{
+  return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
+                       "display", display,
+                       NULL);
+}
+
 GdkDisplay *
 gdk_display_open (const gchar *display_name)
 {
@@ -50,6 +59,7 @@ gdk_display_open (const gchar *display_name)
   [NSApplication sharedApplication];
 
   _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL);
+  _gdk_display->device_manager = _gdk_device_manager_new (_gdk_display);
 
   _gdk_visual_init ();
 
@@ -58,6 +68,7 @@ gdk_display_open (const gchar *display_name)
   _gdk_windowing_window_init ();
 
   _gdk_events_init ();
+
   _gdk_input_init ();
 
 #if 0
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index 1a0b678..de51f10 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -75,70 +75,48 @@ gdk_event_get_graphics_expose (GdkWindow *window)
   return NULL;
 }
 
-GdkGrabStatus
-gdk_keyboard_grab (GdkWindow  *window,
-		   gint        owner_events,
-		   guint32     time)
-{
-  GdkDisplay *display;
-  GdkWindow  *toplevel;
-
-  g_return_val_if_fail (window != NULL, 0);
-  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
-
-  display = gdk_drawable_get_display (window);
-  toplevel = gdk_window_get_toplevel (window);
-
-  _gdk_display_set_has_keyboard_grab (display,
-                                      window,
-                                      toplevel,
-                                      owner_events,
-                                      0,
-                                      time);
-
-  return GDK_GRAB_SUCCESS;
-}
-
-void
-gdk_display_keyboard_ungrab (GdkDisplay *display,
-			     guint32     time)
-{
-  _gdk_display_unset_has_keyboard_grab (display, FALSE);
-}
-
 void
-gdk_display_pointer_ungrab (GdkDisplay *display,
-			    guint32     time)
+gdk_device_ungrab (GdkDevice *device,
+                   guint32    time_)
 {
-  GdkPointerGrabInfo *grab;
+  GdkDeviceGrabInfo *grab;
 
-  grab = _gdk_display_get_last_pointer_grab (display);
+  grab = _gdk_display_get_last_device_grab (_gdk_display, device);
   if (grab)
     grab->serial_end = 0;
 
-  _gdk_display_pointer_grab_update (display, 0);
+  _gdk_display_device_grab_update (_gdk_display, device, 0);
 }
 
 GdkGrabStatus
-_gdk_windowing_pointer_grab (GdkWindow    *window,
-                             GdkWindow    *native,
-                             gboolean	   owner_events,
-                             GdkEventMask  event_mask,
-                             GdkWindow    *confine_to,
-                             GdkCursor    *cursor,
-                             guint32       time)
+_gdk_windowing_device_grab (GdkDevice    *device,
+                            GdkWindow    *window,
+                            GdkWindow    *native,
+                            gboolean      owner_events,
+                            GdkEventMask  event_mask,
+                            GdkWindow    *confine_to,
+                            GdkCursor    *cursor,
+                            guint32       time)
 {
   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
   g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
 
-  _gdk_display_add_pointer_grab (_gdk_display,
-                                 window,
-                                 native,
-                                 owner_events,
-                                 event_mask,
-                                 0,
-                                 time,
-                                 FALSE);
+  if (!window || GDK_WINDOW_DESTROYED (window))
+    return GDK_GRAB_NOT_VIEWABLE;
+
+  /* FIXME: Eventually, just call the grab class method on the device.
+   * But that call is lacking a native parameter.
+   */
+  _gdk_display_add_device_grab (_gdk_display,
+                                device,
+                                window,
+                                native,
+                                GDK_OWNERSHIP_NONE,
+                                owner_events,
+                                event_mask,
+                                0,
+                                time,
+                                FALSE);
 
   return GDK_GRAB_SUCCESS;
 }
@@ -146,19 +124,27 @@ _gdk_windowing_pointer_grab (GdkWindow    *window,
 static void
 break_all_grabs (guint32 time)
 {
-  GdkPointerGrabInfo *grab;
-
-  if (_gdk_display->keyboard_grab.window)
-    _gdk_display_unset_has_keyboard_grab (_gdk_display, FALSE);
+  GList *list, *l;
+  GdkDeviceManager *device_manager;
 
-  grab = _gdk_display_get_last_pointer_grab (_gdk_display);
-  if (grab)
+  device_manager = gdk_display_get_device_manager (_gdk_display);
+  list = gdk_device_manager_list_devices (device_manager,
+                                          GDK_DEVICE_TYPE_MASTER);
+  for (l = list; l; l = l->next)
     {
-      grab->serial_end = 0;
-      grab->implicit_ungrab = TRUE;
+      GdkDeviceGrabInfo *grab;
+
+      grab = _gdk_display_get_last_device_grab (_gdk_display, l->data);
+      if (grab)
+        {
+          grab->serial_end = 0;
+          grab->implicit_ungrab = TRUE;
+        }
+
+      _gdk_display_device_grab_update (_gdk_display, l->data, 0);
     }
 
-  _gdk_display_pointer_grab_update (_gdk_display, 0);
+  g_list_free (list);
 }
 
 static void
@@ -356,6 +342,8 @@ create_focus_event (GdkWindow *window,
   event->focus_change.window = window;
   event->focus_change.in = in;
 
+  gdk_event_set_device (event, _gdk_display->core_pointer);
+
   return event;
 }
 
@@ -518,8 +506,10 @@ find_toplevel_under_pointer (GdkDisplay *display,
                              gint       *y)
 {
   GdkWindow *toplevel;
+  GdkPointerWindowInfo *info;
 
-  toplevel = display->pointer_info.toplevel_under_pointer;
+  info = _gdk_display_get_pointer_info (display, display->core_pointer);
+  toplevel = info->toplevel_under_pointer;
   if (toplevel)
     {
       GdkWindowObject *private;
@@ -538,6 +528,37 @@ find_toplevel_under_pointer (GdkDisplay *display,
   return toplevel;
 }
 
+static GdkWindow *
+find_toplevel_for_keyboard_grab (GdkDisplay *display)
+{
+  GList *list, *l;
+  GdkWindow *toplevel = NULL;
+  GdkDeviceManager *device_manager;
+
+  device_manager = gdk_display_get_device_manager (display);
+  list = gdk_device_manager_list_devices (device_manager,
+                                          GDK_DEVICE_TYPE_MASTER);
+  for (l = list; l; l = l->next)
+    {
+      GdkDeviceGrabInfo *grab;
+      GdkDevice *device = l->data;
+
+      if (device->source != GDK_SOURCE_KEYBOARD)
+        continue;
+
+      grab = _gdk_display_get_last_device_grab (display, device);
+      if (grab && grab->window && !grab->owner_events)
+        {
+          toplevel = gdk_window_get_toplevel (grab->window);
+          break;
+        }
+    }
+
+  g_list_free (list);
+
+  return toplevel;
+}
+
 /* This function finds the correct window to send an event to, taking
  * into account grabs, event propagation, and event masks.
  */
@@ -585,7 +606,7 @@ find_window_for_ns_event (NSEvent *nsevent,
     case NSOtherMouseDragged:
       {
 	GdkDisplay *display;
-        GdkPointerGrabInfo *grab;
+        GdkDeviceGrabInfo *grab;
 
         display = gdk_drawable_get_display (toplevel);
 
@@ -598,7 +619,8 @@ find_window_for_ns_event (NSEvent *nsevent,
 	 * event_mask. For either value of owner_events, unreported
 	 * events are discarded.
 	 */
-        grab = _gdk_display_get_last_pointer_grab (display);
+        grab = _gdk_display_get_last_device_grab (display,
+                                                  display->core_pointer);
 	if (grab)
 	  {
             /* Implicit grabs do not go through XGrabPointer and thus the
@@ -729,10 +751,7 @@ find_window_for_ns_event (NSEvent *nsevent,
     case NSKeyDown:
     case NSKeyUp:
     case NSFlagsChanged:
-      if (_gdk_display->keyboard_grab.window && !_gdk_display->keyboard_grab.owner_events)
-        return gdk_window_get_toplevel (_gdk_display->keyboard_grab.window);
-
-      return toplevel;
+      return find_toplevel_for_keyboard_grab (_gdk_display);
 
     default:
       /* Ignore everything else. */
@@ -766,6 +785,8 @@ fill_crossing_event (GdkWindow       *toplevel,
   event->crossing.detail = detail;
   event->crossing.state = get_keyboard_modifiers_from_ns_event (nsevent);
 
+  gdk_event_set_device (event, _gdk_display->core_pointer);
+
   /* FIXME: Focus and button state? */
 }
 
@@ -1184,9 +1205,10 @@ gdk_event_translate (GdkEvent *event,
         }
       else if (![impl->toplevel isKeyWindow])
         {
-          GdkPointerGrabInfo *grab;
+          GdkDeviceGrabInfo *grab;
 
-          grab = _gdk_display_get_last_pointer_grab (_gdk_display);
+          grab = _gdk_display_get_last_device_grab (_gdk_display,
+                                                    _gdk_display->core_pointer);
           if (!grab)
             [impl->toplevel makeKeyWindow];
         }
diff --git a/gdk/quartz/gdkinput.c b/gdk/quartz/gdkinput.c
index d05638c..c431fc4 100644
--- a/gdk/quartz/gdkinput.c
+++ b/gdk/quartz/gdkinput.c
@@ -31,11 +31,11 @@
 #include "gdkinput.h"
 #include "gdkprivate.h"
 #include "gdkinputprivate.h"
+#include <gdkdevice.h>
+#include <gdkdeviceprivate.h>
 
-static GdkDeviceAxis gdk_input_core_axes[] = {
-  { GDK_AXIS_X, 0, 0 },
-  { GDK_AXIS_Y, 0, 0 }
-};
+/* Addition used for extension_events mask */
+#define GDK_ALL_DEVICES_MASK (1<<30)
 
 GdkDevice *_gdk_core_pointer = NULL;
 
@@ -47,62 +47,6 @@ gint              _gdk_input_ignore_core;
 GList            *_gdk_input_windows;
 GList            *_gdk_input_devices;
 
-void
-_gdk_init_input_core (void)
-{
-  _gdk_core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL);
-  
-  _gdk_core_pointer->name = "Core Pointer";
-  _gdk_core_pointer->source = GDK_SOURCE_MOUSE;
-  _gdk_core_pointer->mode = GDK_MODE_SCREEN;
-  _gdk_core_pointer->has_cursor = TRUE;
-  _gdk_core_pointer->num_axes = 2;
-  _gdk_core_pointer->axes = gdk_input_core_axes;
-  _gdk_core_pointer->num_keys = 0;
-  _gdk_core_pointer->keys = NULL;
-
-  _gdk_display->core_pointer = _gdk_core_pointer;
-}
-
-static void
-gdk_device_finalize (GObject *object)
-{
-  g_error ("A GdkDevice object was finalized. This should not happen");
-}
-
-static void
-gdk_device_class_init (GObjectClass *class)
-{
-  class->finalize = gdk_device_finalize;
-}
-
-GType
-gdk_device_get_type (void)
-{
-  static GType object_type = 0;
-
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-      {
-        sizeof (GdkDeviceClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) gdk_device_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (GdkDevicePrivate),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) NULL,
-      };
-      
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "GdkDevice",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
-}
 
 GList *
 gdk_devices_list (void)
@@ -116,112 +60,50 @@ gdk_display_list_devices (GdkDisplay *dpy)
   return _gdk_input_devices;
 }
 
-void
-gdk_device_set_source (GdkDevice *device,
-		       GdkInputSource source)
-{
-  device->source = source;
-}
-
-
-void
-gdk_device_set_key (GdkDevice      *device,
-		    guint           index,
-		    guint           keyval,
-		    GdkModifierType modifiers)
-{
-  g_return_if_fail (device != NULL);
-  g_return_if_fail (index < device->num_keys);
-
-  device->keys[index].keyval = keyval;
-  device->keys[index].modifiers = modifiers;
-}
-
-void
-gdk_device_set_axis_use (GdkDevice   *device,
-			 guint        index,
-			 GdkAxisUse   use)
+static void
+_gdk_input_select_device_events (GdkWindow *impl_window,
+                                 GdkDevice *device)
 {
-  g_return_if_fail (device != NULL);
-  g_return_if_fail (index < device->num_axes);
-
-  device->axes[index].use = use;
-
-  switch (use)
+  guint event_mask;
+  GdkWindowObject *w;
+  GdkInputWindow *iw;
+  GdkInputMode mode;
+  gboolean has_cursor;
+  GdkDeviceType type;
+  GList *l;
+
+  event_mask = 0;
+  iw = ((GdkWindowObject *)impl_window)->input_window;
+
+  g_object_get (device,
+                "type", &type,
+                "input-mode", &mode,
+                "has-cursor", &has_cursor,
+                NULL);
+
+  if (iw == NULL ||
+      mode == GDK_MODE_DISABLED ||
+      type == GDK_DEVICE_TYPE_MASTER)
+    return;
+
+  for (l = _gdk_input_windows; l != NULL; l = l->next)
     {
-    case GDK_AXIS_X:
-    case GDK_AXIS_Y:
-      device->axes[index].min = 0.;
-      device->axes[index].max = 0.;
-      break;
-    case GDK_AXIS_XTILT:
-    case GDK_AXIS_YTILT:
-      device->axes[index].min = -1.;
-      device->axes[index].max = 1;
-      break;
-    default:
-      device->axes[index].min = 0.;
-      device->axes[index].max = 1;
-      break;
-    }
-}
+      w = l->data;
 
-void 
-gdk_device_get_state (GdkDevice       *device,
-                      GdkWindow       *window,
-                      gdouble         *axes,
-                      GdkModifierType *mask)
-{
-  gint x_int, y_int;
+      if (has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
+        {
+          event_mask = w->extension_events;
 
-  g_assert (device == _gdk_core_pointer);
-      
-  gdk_window_get_pointer (window, &x_int, &y_int, mask);
+          if (event_mask)
+            event_mask |= GDK_PROXIMITY_OUT_MASK
+                | GDK_BUTTON_PRESS_MASK
+                | GDK_BUTTON_RELEASE_MASK;
 
-  if (axes)
-    {
-      axes[0] = x_int;
-      axes[1] = y_int;
+          gdk_window_set_device_events ((GdkWindow *) w, device, event_mask);
+        }
     }
 }
 
-void 
-gdk_device_free_history (GdkTimeCoord **events,
-			 gint           n_events)
-{
-  gint i;
-  
-  for (i = 0; i < n_events; i++)
-    g_free (events[i]);
-
-  g_free (events);
-}
-
-gboolean
-gdk_device_get_history  (GdkDevice         *device,
-			 GdkWindow         *window,
-			 guint32            start,
-			 guint32            stop,
-			 GdkTimeCoord    ***events,
-			 gint              *n_events)
-{
-  g_return_val_if_fail (window != NULL, FALSE);
-  g_return_val_if_fail (GDK_WINDOW_IS_QUARTZ (window), FALSE);
-  g_return_val_if_fail (events != NULL, FALSE);
-  g_return_val_if_fail (n_events != NULL, FALSE);
-
-  *n_events = 0;
-  *events = NULL;
-  return FALSE;
-}
-
-gboolean
-gdk_device_set_mode (GdkDevice   *device,
-                     GdkInputMode mode)
-{
-  return FALSE;
-}
-
 gint
 _gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
 {
@@ -254,10 +136,12 @@ _gdk_input_window_find(GdkWindow *window)
    cases */
 
 void
-gdk_input_set_extension_events (GdkWindow *window, gint mask,
-				GdkExtensionMode mode)
+gdk_input_set_extension_events (GdkWindow        *window,
+                                gint              mask,
+                                GdkExtensionMode  mode)
 {
   GdkWindowObject *window_private;
+  GdkWindowObject *impl_window;
   GList *tmp_list;
   GdkInputWindow *iw;
 
@@ -265,13 +149,14 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
   g_return_if_fail (GDK_WINDOW_IS_QUARTZ (window));
 
   window_private = (GdkWindowObject*) window;
+  impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
 
   if (mode == GDK_EXTENSION_EVENTS_NONE)
     mask = 0;
 
   if (mask != 0)
     {
-      iw = g_new(GdkInputWindow,1);
+      iw = g_new (GdkInputWindow, 1);
 
       iw->window = window;
       iw->mode = mode;
@@ -280,39 +165,32 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
       iw->num_obscuring = 0;
       iw->grabbed = FALSE;
 
-      _gdk_input_windows = g_list_append (_gdk_input_windows,iw);
+      _gdk_input_windows = g_list_append (_gdk_input_windows, iw);
       window_private->extension_events = mask;
 
       /* Add enter window events to the event mask */
       /* FIXME, this is not needed for XINPUT_NONE */
       gdk_window_set_events (window,
-			     gdk_window_get_events (window) | 
-			     GDK_ENTER_NOTIFY_MASK);
+                             gdk_window_get_events (window) | 
+                             GDK_ENTER_NOTIFY_MASK);
     }
   else
     {
       iw = _gdk_input_window_find (window);
       if (iw)
-	{
-	  _gdk_input_windows = g_list_remove (_gdk_input_windows,iw);
-	  g_free (iw);
-	}
+        {
+          _gdk_input_windows = g_list_remove (_gdk_input_windows,iw);
+          g_free (iw);
+        }
 
       window_private->extension_events = 0;
     }
 
   for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
     {
-      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      GdkDevice *dev = tmp_list->data;
 
-      if (gdkdev != (GdkDevicePrivate *)_gdk_core_pointer)
-	{
-	  if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
-	      && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
-	    _gdk_input_enable_window (window,gdkdev);
-	  else
-	    _gdk_input_disable_window (window,gdkdev);
-	}
+      _gdk_input_select_device_events (GDK_WINDOW (impl_window), dev);
     }
 }
 
@@ -329,10 +207,57 @@ _gdk_input_window_destroy (GdkWindow *window)
 }
 
 void
+_gdk_input_check_extension_events (GdkDevice *device)
+{
+}
+
+void
 _gdk_input_init (void)
 {
-  _gdk_init_input_core ();
-  _gdk_input_devices = g_list_append (NULL, _gdk_core_pointer);
+  GdkDeviceManager *device_manager;
+  GList *list, *l;
+
+  device_manager = gdk_display_get_device_manager (_gdk_display);
+
+  /* For backward 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)
+    {
+      GdkDevice *device = l->data;
+
+      if (device->source == GDK_SOURCE_KEYBOARD)
+        continue;
+
+      _gdk_input_devices = g_list_prepend (_gdk_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)
+    {
+      GdkDevice *device = list->data;
+
+      if (device->source != GDK_SOURCE_MOUSE)
+        continue;
+
+      _gdk_display->core_pointer = device;
+      break;
+    }
+
+  g_list_free (list);
+
+  /* Add the core pointer to the devices list */
+  _gdk_input_devices = g_list_prepend (_gdk_input_devices,
+                                       _gdk_display->core_pointer);
+
   _gdk_input_ignore_core = FALSE;
 }
 
@@ -364,30 +289,3 @@ _gdk_input_exit (void)
     }
   g_list_free (_gdk_input_windows);
 }
-
-gboolean
-gdk_device_get_axis (GdkDevice *device, gdouble *axes, GdkAxisUse use, gdouble *value)
-{
-  gint i;
-  
-  g_return_val_if_fail (device != NULL, FALSE);
-
-  if (axes == NULL)
-    return FALSE;
-  
-  for (i = 0; i < device->num_axes; i++)
-    if (device->axes[i].use == use)
-      {
-	if (value)
-	  *value = axes[i];
-	return TRUE;
-      }
-  
-  return FALSE;
-}
-
-void
-_gdk_input_window_crossing (GdkWindow *window,
-                            gboolean   enter)
-{
-}
diff --git a/gdk/quartz/gdkinputprivate.h b/gdk/quartz/gdkinputprivate.h
index b8f13ac..0868f33 100644
--- a/gdk/quartz/gdkinputprivate.h
+++ b/gdk/quartz/gdkinputprivate.h
@@ -97,11 +97,6 @@ struct _GdkDevicePrivate {
   GdkDevice  info;
 };
 
-struct _GdkDeviceClass
-{
-  GObjectClass parent_class;
-};
-
 struct _GdkInputWindow
 {
   /* gdk window */
diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h
index 49aafb4..0809dcf 100644
--- a/gdk/quartz/gdkprivate-quartz.h
+++ b/gdk/quartz/gdkprivate-quartz.h
@@ -152,7 +152,8 @@ void       _gdk_quartz_window_nspoint_to_gdk_xy     (NSPoint    point,
                                                      gint      *y);
 GdkWindow *_gdk_quartz_window_find_child            (GdkWindow *window,
 						     gint       x,
-						     gint       y);
+						     gint       y,
+                                                     gboolean   get_toplevel);
 void       _gdk_quartz_window_attach_to_parent      (GdkWindow *window);
 void       _gdk_quartz_window_detach_from_parent    (GdkWindow *window);
 void       _gdk_quartz_window_did_become_main       (GdkWindow *window);
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index a8e385f..f1aa026 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -23,6 +23,7 @@
 #include <Carbon/Carbon.h>
 
 #include "gdk.h"
+#include "gdkdeviceprivate.h"
 #include "gdkwindowimpl.h"
 #include "gdkprivate-quartz.h"
 #include "gdkscreen-quartz.h"
@@ -143,20 +144,16 @@ gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
 static void
 check_grab_unmap (GdkWindow *window)
 {
+  GList *list, *l;
   GdkDisplay *display = gdk_drawable_get_display (window);
+  GdkDeviceManager *device_manager;
 
-  _gdk_display_end_pointer_grab (display, 0, window, TRUE);
-
-  if (display->keyboard_grab.window)
+  device_manager = gdk_display_get_device_manager (display);
+  list = gdk_device_manager_list_devices (device_manager,
+                                          GDK_DEVICE_TYPE_FLOATING);
+  for (l = list; l; l = l->next)
     {
-      GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
-      GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window);
-
-      while (tmp && tmp != private)
-	tmp = tmp->parent;
-
-      if (tmp)
-	_gdk_display_unset_has_keyboard_grab (display, TRUE);
+      _gdk_display_end_device_grab (display, l->data, 0, window, TRUE);
     }
 }
 
@@ -164,20 +161,16 @@ static void
 check_grab_destroy (GdkWindow *window)
 {
   GdkDisplay *display = gdk_drawable_get_display (window);
-  GdkPointerGrabInfo *grab;
+  GdkDeviceGrabInfo *grab;
 
   /* Make sure there is no lasting grab in this native window */
-  grab = _gdk_display_get_last_pointer_grab (display);
+  grab = _gdk_display_get_last_device_grab (display, display->core_pointer);
   if (grab && grab->native_window == window)
     {
       /* Serials are always 0 in quartz, but for clarity: */
       grab->serial_end = grab->serial_start;
       grab->implicit_ungrab = TRUE;
     }
-
-  if (window == display->keyboard_grab.native_window &&
-      display->keyboard_grab.window != NULL)
-    _gdk_display_unset_has_keyboard_grab (display, TRUE);
 }
 
 static void
@@ -698,7 +691,8 @@ find_child_window_helper (GdkWindow *window,
 			  gint       x,
 			  gint       y,
 			  gint       x_offset,
-			  gint       y_offset)
+			  gint       y_offset,
+                          gboolean   get_toplevel)
 {
   GdkWindowImplQuartz *impl;
   GList *l;
@@ -751,13 +745,15 @@ find_child_window_helper (GdkWindow *window,
             }
         }
 
-      if (x >= temp_x && y >= temp_y &&
+      if ((!get_toplevel || (get_toplevel && window == _gdk_root)) &&
+          x >= temp_x && y >= temp_y &&
 	  x < temp_x + child_private->width && y < temp_y + child_private->height)
 	{
 	  /* Look for child windows. */
 	  return find_child_window_helper (l->data,
 					   x, y,
-					   temp_x, temp_y);
+					   temp_x, temp_y,
+                                           get_toplevel);
 	}
     }
   
@@ -771,12 +767,13 @@ find_child_window_helper (GdkWindow *window,
 GdkWindow *
 _gdk_quartz_window_find_child (GdkWindow *window,
 			       gint       x,
-			       gint       y)
+			       gint       y,
+                               gboolean   get_toplevel)
 {
   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
 
   if (x >= 0 && y >= 0 && x < private->width && y < private->height)
-    return find_child_window_helper (window, x, y, 0, 0);
+    return find_child_window_helper (window, x, y, 0, 0, get_toplevel);
 
   return NULL;
 }
@@ -1701,8 +1698,9 @@ gdk_window_quartz_set_back_pixmap (GdkWindow *window,
 }
 
 static void
-gdk_window_quartz_set_cursor (GdkWindow *window,
-                              GdkCursor *cursor)
+gdk_window_quartz_set_device_cursor (GdkWindow *window,
+                                     GdkDevice *device,
+                                     GdkCursor *cursor)
 {
   GdkCursorPrivate *cursor_private;
   NSCursor *nscursor;
@@ -1893,10 +1891,11 @@ gdk_window_get_root_origin (GdkWindow *window,
 
 /* Returns coordinates relative to the passed in window. */
 static GdkWindow *
-gdk_window_quartz_get_pointer_helper (GdkWindow       *window,
-                                      gint            *x,
-                                      gint            *y,
-                                      GdkModifierType *mask)
+gdk_window_quartz_get_device_state_helper (GdkWindow       *window,
+                                           GdkDevice       *device,
+                                           gint            *x,
+                                           gint            *y,
+                                           GdkModifierType *mask)
 {
   GdkWindowObject *toplevel;
   GdkWindowObject *private;
@@ -1941,7 +1940,8 @@ gdk_window_quartz_get_pointer_helper (GdkWindow       *window,
       window = (GdkWindow *)toplevel;
     }
 
-  found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp);
+  found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
+                                                FALSE);
 
   /* We never return the root window. */
   if (found_window == _gdk_root)
@@ -1954,26 +1954,30 @@ gdk_window_quartz_get_pointer_helper (GdkWindow       *window,
 }
 
 static gboolean
-gdk_window_quartz_get_pointer (GdkWindow       *window,
-                               gint            *x,
-                               gint            *y,
-                               GdkModifierType *mask)
+gdk_window_quartz_get_device_state (GdkWindow       *window,
+                                    GdkDevice       *device,
+                                    gint            *x,
+                                    gint            *y,
+                                    GdkModifierType *mask)
 {
-  return gdk_window_quartz_get_pointer_helper (window, x, y, mask) != NULL;
+  return gdk_window_quartz_get_device_state_helper (window,
+                                                    device,
+                                                    x, y, mask) != NULL;
 }
 
 /* Returns coordinates relative to the root. */
 void
-_gdk_windowing_get_pointer (GdkDisplay       *display,
-                            GdkScreen       **screen,
-                            gint             *x,
-                            gint             *y,
-                            GdkModifierType  *mask)
+_gdk_windowing_get_device_state (GdkDisplay       *display,
+                                 GdkDevice        *device,
+                                 GdkScreen       **screen,
+                                 gint             *x,
+                                 gint             *y,
+                                 GdkModifierType  *mask)
 {
   g_return_if_fail (display == _gdk_display);
   
   *screen = _gdk_screen;
-  gdk_window_quartz_get_pointer_helper (_gdk_root, x, y, mask);
+  gdk_window_quartz_get_device_state_helper (_gdk_root, device, x, y, mask);
 }
 
 void
@@ -1997,9 +2001,10 @@ _gdk_windowing_window_at_pointer (GdkDisplay      *display,
   gint x, y;
   GdkModifierType tmp_mask = 0;
 
-  found_window = gdk_window_quartz_get_pointer_helper (_gdk_root,
-                                                       &x, &y,
-                                                       &tmp_mask);
+  found_window = gdk_window_quartz_get_device_state_helper (_gdk_root,
+                                                            display->core_pointer,
+                                                            &x, &y,
+                                                            &tmp_mask);
   if (found_window)
     {
       GdkWindowObject *private;
@@ -2052,6 +2057,21 @@ _gdk_windowing_window_at_pointer (GdkDisplay      *display,
   return found_window;
 }
 
+GdkWindow*
+_gdk_windowing_window_at_device_position (GdkDisplay      *display,
+                                          GdkDevice       *device,
+                                          gint            *win_x,
+                                          gint            *win_y,
+                                          GdkModifierType *mask,
+                                          gboolean         get_toplevel)
+{
+  return GDK_DEVICE_GET_CLASS (device)->window_at_position (device,
+                                                            win_x, win_y,
+                                                            mask,
+                                                            get_toplevel);
+}
+
+
 static GdkEventMask  
 gdk_window_quartz_get_events (GdkWindow *window)
 {
@@ -3078,10 +3098,10 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->set_background = gdk_window_quartz_set_background;
   iface->set_back_pixmap = gdk_window_quartz_set_back_pixmap;
   iface->reparent = gdk_window_quartz_reparent;
-  iface->set_cursor = gdk_window_quartz_set_cursor;
+  iface->set_device_cursor = gdk_window_quartz_set_device_cursor;
   iface->get_geometry = gdk_window_quartz_get_geometry;
   iface->get_root_coords = gdk_window_quartz_get_root_coords;
-  iface->get_pointer = gdk_window_quartz_get_pointer;
+  iface->get_device_state = gdk_window_quartz_get_device_state;
   iface->get_deskrelative_origin = gdk_window_quartz_get_deskrelative_origin;
   iface->shape_combine_region = gdk_window_quartz_shape_combine_region;
   iface->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
@@ -3089,6 +3109,4 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->queue_antiexpose = _gdk_quartz_window_queue_antiexpose;
   iface->queue_translation = _gdk_quartz_window_queue_translation;
   iface->destroy = _gdk_quartz_window_destroy;
-  iface->input_window_destroy = _gdk_input_window_destroy;
-  iface->input_window_crossing = _gdk_input_window_crossing;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]