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/gdkdeviceprivate.h>
24 #include <gdk/gdkdisplayprivate.h>
26 #import "GdkQuartzView.h"
27 #include "gdkquartzwindow.h"
28 #include "gdkquartzcursor.h"
29 #include "gdkprivate-quartz.h"
30 #include "gdkquartzdevice-core.h"
32 struct _GdkQuartzDeviceCore
34 GdkDevice parent_instance;
37 struct _GdkQuartzDeviceCoreClass
39 GdkDeviceClass parent_class;
42 static gboolean gdk_quartz_device_core_get_history (GdkDevice *device,
46 GdkTimeCoord ***events,
48 static void gdk_quartz_device_core_get_state (GdkDevice *device,
51 GdkModifierType *mask);
52 static void gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
55 static void gdk_quartz_device_core_warp (GdkDevice *device,
59 static gboolean gdk_quartz_device_core_query_state (GdkDevice *device,
61 GdkWindow **root_window,
62 GdkWindow **child_window,
67 GdkModifierType *mask);
68 static GdkGrabStatus gdk_quartz_device_core_grab (GdkDevice *device,
70 gboolean owner_events,
71 GdkEventMask event_mask,
72 GdkWindow *confine_to,
75 static void gdk_quartz_device_core_ungrab (GdkDevice *device,
77 static GdkWindow * gdk_quartz_device_core_window_at_position (GdkDevice *device,
80 GdkModifierType *mask,
81 gboolean get_toplevel);
82 static void gdk_quartz_device_core_select_window_events (GdkDevice *device,
84 GdkEventMask event_mask);
87 G_DEFINE_TYPE (GdkQuartzDeviceCore, gdk_quartz_device_core, GDK_TYPE_DEVICE)
90 gdk_quartz_device_core_class_init (GdkQuartzDeviceCoreClass *klass)
92 GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
94 device_class->get_history = gdk_quartz_device_core_get_history;
95 device_class->get_state = gdk_quartz_device_core_get_state;
96 device_class->set_window_cursor = gdk_quartz_device_core_set_window_cursor;
97 device_class->warp = gdk_quartz_device_core_warp;
98 device_class->query_state = gdk_quartz_device_core_query_state;
99 device_class->grab = gdk_quartz_device_core_grab;
100 device_class->ungrab = gdk_quartz_device_core_ungrab;
101 device_class->window_at_position = gdk_quartz_device_core_window_at_position;
102 device_class->select_window_events = gdk_quartz_device_core_select_window_events;
106 gdk_quartz_device_core_init (GdkQuartzDeviceCore *quartz_device_core)
110 device = GDK_DEVICE (quartz_device_core);
112 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
113 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
117 gdk_quartz_device_core_get_history (GdkDevice *device,
121 GdkTimeCoord ***events,
128 gdk_quartz_device_core_get_state (GdkDevice *device,
131 GdkModifierType *mask)
135 gdk_window_get_pointer (window, &x_int, &y_int, mask);
145 translate_coords_to_child_coords (GdkWindow *parent,
150 GdkWindow *current = child;
155 while (current != parent)
159 gdk_window_get_origin (current, &tmp_x, &tmp_y);
164 current = gdk_window_get_effective_parent (current);
169 gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
175 if (GDK_WINDOW_DESTROYED (window))
178 nscursor = _gdk_quartz_cursor_get_ns_cursor (cursor);
184 gdk_quartz_device_core_warp (GdkDevice *device,
189 CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
193 gdk_quartz_device_core_query_state_helper (GdkWindow *window,
197 GdkModifierType *mask)
202 GdkWindow *found_window;
204 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
206 if (GDK_WINDOW_DESTROYED (window))
214 toplevel = gdk_window_get_effective_toplevel (window);
217 *mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
218 _gdk_quartz_events_get_current_mouse_modifiers ();
220 /* Get the y coordinate, needs to be flipped. */
221 if (window == _gdk_root)
223 point = [NSEvent mouseLocation];
224 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
228 GdkWindowImplQuartz *impl;
231 impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
232 nswindow = impl->toplevel;
234 point = [nswindow mouseLocationOutsideOfEventStream];
237 y_tmp = toplevel->height - point.y;
242 found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
245 if (found_window == _gdk_root)
247 else if (found_window)
248 translate_coords_to_child_coords (window, found_window,
261 gdk_quartz_device_core_query_state (GdkDevice *device,
263 GdkWindow **root_window,
264 GdkWindow **child_window,
269 GdkModifierType *mask)
272 GdkWindow *found_window;
276 found_window = gdk_quartz_device_core_query_state_helper (window, device,
282 display = gdk_window_get_display (window);
285 *root_window = _gdk_root;
288 *child_window = found_window;
290 point = [NSEvent mouseLocation];
291 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
303 gdk_quartz_device_core_grab (GdkDevice *device,
305 gboolean owner_events,
306 GdkEventMask event_mask,
307 GdkWindow *confine_to,
311 /* Should remain empty */
312 return GDK_GRAB_SUCCESS;
316 gdk_quartz_device_core_ungrab (GdkDevice *device,
319 GdkDeviceGrabInfo *grab;
321 grab = _gdk_display_get_last_device_grab (_gdk_display, device);
323 grab->serial_end = 0;
325 _gdk_display_device_grab_update (_gdk_display, device, NULL, 0);
329 gdk_quartz_device_core_window_at_position (GdkDevice *device,
332 GdkModifierType *mask,
333 gboolean get_toplevel)
337 GdkWindow *found_window;
341 display = gdk_device_get_display (device);
342 screen = gdk_display_get_default_screen (display);
344 /* Get mouse coordinates, find window under the mouse pointer */
345 point = [NSEvent mouseLocation];
346 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
348 found_window = _gdk_quartz_window_find_child (_gdk_root, x_tmp, y_tmp,
352 translate_coords_to_child_coords (_gdk_root, found_window,
356 *win_x = found_window ? x_tmp : -1;
359 *win_y = found_window ? y_tmp : -1;
362 *mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
363 _gdk_quartz_events_get_current_mouse_modifiers ();
369 gdk_quartz_device_core_select_window_events (GdkDevice *device,
371 GdkEventMask event_mask)
373 /* The mask is set in the common code. */