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, see <http://www.gnu.org/licenses/>.
21 #include <gdk/gdkdeviceprivate.h>
22 #include <gdk/gdkdisplayprivate.h>
24 #import "GdkQuartzView.h"
25 #include "gdkquartzwindow.h"
26 #include "gdkquartzcursor.h"
27 #include "gdkprivate-quartz.h"
28 #include "gdkquartzdevice-core.h"
30 struct _GdkQuartzDeviceCore
32 GdkDevice parent_instance;
35 struct _GdkQuartzDeviceCoreClass
37 GdkDeviceClass parent_class;
40 static gboolean gdk_quartz_device_core_get_history (GdkDevice *device,
44 GdkTimeCoord ***events,
46 static void gdk_quartz_device_core_get_state (GdkDevice *device,
49 GdkModifierType *mask);
50 static void gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
53 static void gdk_quartz_device_core_warp (GdkDevice *device,
57 static void gdk_quartz_device_core_query_state (GdkDevice *device,
59 GdkWindow **root_window,
60 GdkWindow **child_window,
65 GdkModifierType *mask);
66 static GdkGrabStatus gdk_quartz_device_core_grab (GdkDevice *device,
68 gboolean owner_events,
69 GdkEventMask event_mask,
70 GdkWindow *confine_to,
73 static void gdk_quartz_device_core_ungrab (GdkDevice *device,
75 static GdkWindow * gdk_quartz_device_core_window_at_position (GdkDevice *device,
78 GdkModifierType *mask,
79 gboolean get_toplevel);
80 static void gdk_quartz_device_core_select_window_events (GdkDevice *device,
82 GdkEventMask event_mask);
85 G_DEFINE_TYPE (GdkQuartzDeviceCore, gdk_quartz_device_core, GDK_TYPE_DEVICE)
88 gdk_quartz_device_core_class_init (GdkQuartzDeviceCoreClass *klass)
90 GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
92 device_class->get_history = gdk_quartz_device_core_get_history;
93 device_class->get_state = gdk_quartz_device_core_get_state;
94 device_class->set_window_cursor = gdk_quartz_device_core_set_window_cursor;
95 device_class->warp = gdk_quartz_device_core_warp;
96 device_class->query_state = gdk_quartz_device_core_query_state;
97 device_class->grab = gdk_quartz_device_core_grab;
98 device_class->ungrab = gdk_quartz_device_core_ungrab;
99 device_class->window_at_position = gdk_quartz_device_core_window_at_position;
100 device_class->select_window_events = gdk_quartz_device_core_select_window_events;
104 gdk_quartz_device_core_init (GdkQuartzDeviceCore *quartz_device_core)
108 device = GDK_DEVICE (quartz_device_core);
110 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
111 _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
115 gdk_quartz_device_core_get_history (GdkDevice *device,
119 GdkTimeCoord ***events,
126 gdk_quartz_device_core_get_state (GdkDevice *device,
129 GdkModifierType *mask)
133 gdk_window_get_pointer (window, &x_int, &y_int, mask);
143 translate_coords_to_child_coords (GdkWindow *parent,
148 GdkWindow *current = child;
153 while (current != parent)
157 gdk_window_get_origin (current, &tmp_x, &tmp_y);
162 current = gdk_window_get_effective_parent (current);
167 gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
173 if (GDK_WINDOW_DESTROYED (window))
176 nscursor = _gdk_quartz_cursor_get_ns_cursor (cursor);
182 gdk_quartz_device_core_warp (GdkDevice *device,
187 CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
191 gdk_quartz_device_core_query_state_helper (GdkWindow *window,
195 GdkModifierType *mask)
200 GdkWindow *found_window;
202 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
204 if (GDK_WINDOW_DESTROYED (window))
212 toplevel = gdk_window_get_effective_toplevel (window);
215 *mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
216 _gdk_quartz_events_get_current_mouse_modifiers ();
218 /* Get the y coordinate, needs to be flipped. */
219 if (window == _gdk_root)
221 point = [NSEvent mouseLocation];
222 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
226 GdkWindowImplQuartz *impl;
229 impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
230 nswindow = impl->toplevel;
232 point = [nswindow mouseLocationOutsideOfEventStream];
235 y_tmp = toplevel->height - point.y;
240 found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
243 if (found_window == _gdk_root)
245 else if (found_window)
246 translate_coords_to_child_coords (window, found_window,
259 gdk_quartz_device_core_query_state (GdkDevice *device,
261 GdkWindow **root_window,
262 GdkWindow **child_window,
267 GdkModifierType *mask)
269 GdkWindow *found_window;
273 found_window = gdk_quartz_device_core_query_state_helper (window, device,
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);
294 gdk_quartz_device_core_grab (GdkDevice *device,
296 gboolean owner_events,
297 GdkEventMask event_mask,
298 GdkWindow *confine_to,
302 /* Should remain empty */
303 return GDK_GRAB_SUCCESS;
307 gdk_quartz_device_core_ungrab (GdkDevice *device,
310 GdkDeviceGrabInfo *grab;
312 grab = _gdk_display_get_last_device_grab (_gdk_display, device);
314 grab->serial_end = 0;
316 _gdk_display_device_grab_update (_gdk_display, device, NULL, 0);
320 gdk_quartz_device_core_window_at_position (GdkDevice *device,
323 GdkModifierType *mask,
324 gboolean get_toplevel)
328 GdkWindow *found_window;
332 display = gdk_device_get_display (device);
333 screen = gdk_display_get_default_screen (display);
335 /* Get mouse coordinates, find window under the mouse pointer */
336 point = [NSEvent mouseLocation];
337 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
339 found_window = _gdk_quartz_window_find_child (_gdk_root, x_tmp, y_tmp,
343 translate_coords_to_child_coords (_gdk_root, found_window,
347 *win_x = found_window ? x_tmp : -1;
350 *win_y = found_window ? y_tmp : -1;
353 *mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
354 _gdk_quartz_events_get_current_mouse_modifiers ();
360 gdk_quartz_device_core_select_window_events (GdkDevice *device,
362 GdkEventMask event_mask)
364 /* The mask is set in the common code. */