1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3 * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
23 #include <gdk/gdkdisplayprivate.h>
25 #import "GdkQuartzView.h"
26 #include "gdkwindow-quartz.h"
27 #include "gdkcursor-quartz.h"
28 #include "gdkprivate-quartz.h"
29 #include "gdkdevice-core-quartz.h"
31 static gboolean gdk_quartz_device_core_get_history (GdkDevice *device,
35 GdkTimeCoord ***events,
37 static void gdk_quartz_device_core_get_state (GdkDevice *device,
40 GdkModifierType *mask);
41 static void gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
44 static void gdk_quartz_device_core_warp (GdkDevice *device,
48 static gboolean gdk_quartz_device_core_query_state (GdkDevice *device,
50 GdkWindow **root_window,
51 GdkWindow **child_window,
56 GdkModifierType *mask);
57 static GdkGrabStatus gdk_quartz_device_core_grab (GdkDevice *device,
59 gboolean owner_events,
60 GdkEventMask event_mask,
61 GdkWindow *confine_to,
64 static void gdk_quartz_device_core_ungrab (GdkDevice *device,
66 static GdkWindow * gdk_quartz_device_core_window_at_position (GdkDevice *device,
69 GdkModifierType *mask,
70 gboolean get_toplevel);
71 static void gdk_quartz_device_core_select_window_events (GdkDevice *device,
73 GdkEventMask event_mask);
76 G_DEFINE_TYPE (GdkQuartzDeviceCore, gdk_quartz_device_core, GDK_TYPE_DEVICE)
79 gdk_quartz_device_core_class_init (GdkQuartzDeviceCoreClass *klass)
81 GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
83 device_class->get_history = gdk_quartz_device_core_get_history;
84 device_class->get_state = gdk_quartz_device_core_get_state;
85 device_class->set_window_cursor = gdk_quartz_device_core_set_window_cursor;
86 device_class->warp = gdk_quartz_device_core_warp;
87 device_class->query_state = gdk_quartz_device_core_query_state;
88 device_class->grab = gdk_quartz_device_core_grab;
89 device_class->ungrab = gdk_quartz_device_core_ungrab;
90 device_class->window_at_position = gdk_quartz_device_core_window_at_position;
91 device_class->select_window_events = gdk_quartz_device_core_select_window_events;
95 gdk_quartz_device_core_init (GdkQuartzDeviceCore *quartz_device_core)
99 device = GDK_DEVICE (quartz_device_core);
101 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
102 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
106 gdk_quartz_device_core_get_history (GdkDevice *device,
110 GdkTimeCoord ***events,
117 gdk_quartz_device_core_get_state (GdkDevice *device,
120 GdkModifierType *mask)
124 gdk_window_get_pointer (window, &x_int, &y_int, mask);
134 translate_coords_to_child_coords (GdkWindow *parent,
139 GdkWindow *current = child;
144 while (current != parent)
148 gdk_window_get_origin (current, &tmp_x, &tmp_y);
153 current = gdk_window_get_effective_parent (current);
158 gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
162 GdkQuartzCursor *cursor_private;
165 cursor_private = (GdkQuartzCursor *) cursor;
167 if (GDK_WINDOW_DESTROYED (window))
171 nscursor = [NSCursor arrowCursor];
173 nscursor = cursor_private->nscursor;
179 gdk_quartz_device_core_warp (GdkDevice *device,
184 CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
188 gdk_quartz_device_core_query_state_helper (GdkWindow *window,
192 GdkModifierType *mask)
197 GdkWindow *found_window;
199 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
201 if (GDK_WINDOW_DESTROYED (window))
209 toplevel = gdk_window_get_effective_toplevel (window);
211 *mask = _gdk_quartz_events_get_current_event_mask ();
213 /* Get the y coordinate, needs to be flipped. */
214 if (window == _gdk_root)
216 point = [NSEvent mouseLocation];
217 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
221 GdkWindowImplQuartz *impl;
224 impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
225 nswindow = impl->toplevel;
227 point = [nswindow mouseLocationOutsideOfEventStream];
230 y_tmp = toplevel->height - point.y;
235 found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
238 if (found_window == _gdk_root)
240 else if (found_window)
241 translate_coords_to_child_coords (window, found_window,
254 gdk_quartz_device_core_query_state (GdkDevice *device,
256 GdkWindow **root_window,
257 GdkWindow **child_window,
262 GdkModifierType *mask)
265 GdkWindow *found_window;
269 found_window = gdk_quartz_device_core_query_state_helper (window, device,
275 display = gdk_window_get_display (window);
278 *root_window = _gdk_root;
281 *child_window = found_window;
283 point = [NSEvent mouseLocation];
284 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
296 gdk_quartz_device_core_grab (GdkDevice *device,
298 gboolean owner_events,
299 GdkEventMask event_mask,
300 GdkWindow *confine_to,
304 /* Should remain empty */
305 return GDK_GRAB_SUCCESS;
309 gdk_quartz_device_core_ungrab (GdkDevice *device,
312 GdkDeviceGrabInfo *grab;
314 grab = _gdk_display_get_last_device_grab (_gdk_display, device);
316 grab->serial_end = 0;
318 _gdk_display_device_grab_update (_gdk_display, device, NULL, 0);
322 gdk_quartz_device_core_window_at_position (GdkDevice *device,
325 GdkModifierType *mask,
326 gboolean get_toplevel)
330 GdkWindow *found_window;
334 display = gdk_device_get_display (device);
335 screen = gdk_display_get_default_screen (display);
337 /* Get mouse coordinates, find window under the mouse pointer */
338 point = [NSEvent mouseLocation];
339 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
341 found_window = _gdk_quartz_window_find_child (_gdk_root, x_tmp, y_tmp,
345 translate_coords_to_child_coords (_gdk_root, found_window,
349 *win_x = found_window ? x_tmp : -1;
352 *win_y = found_window ? y_tmp : -1;
355 *mask = _gdk_quartz_events_get_current_event_mask ();
361 gdk_quartz_device_core_select_window_events (GdkDevice *device,
363 GdkEventMask event_mask)
365 /* The mask is set in the common code. */