]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkdevice-core-quartz.c
x11: Clean up xsettings header
[~andy/gtk] / gdk / quartz / gdkdevice-core-quartz.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3  * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
4  *
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.
9  *
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.
14  *
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/>.
17  */
18
19 #include "config.h"
20
21 #include <gdk/gdkdeviceprivate.h>
22 #include <gdk/gdkdisplayprivate.h>
23
24 #import "GdkQuartzView.h"
25 #include "gdkquartzwindow.h"
26 #include "gdkquartzcursor.h"
27 #include "gdkprivate-quartz.h"
28 #include "gdkquartzdevice-core.h"
29
30 struct _GdkQuartzDeviceCore
31 {
32   GdkDevice parent_instance;
33 };
34
35 struct _GdkQuartzDeviceCoreClass
36 {
37   GdkDeviceClass parent_class;
38 };
39
40 static gboolean gdk_quartz_device_core_get_history (GdkDevice      *device,
41                                                     GdkWindow      *window,
42                                                     guint32         start,
43                                                     guint32         stop,
44                                                     GdkTimeCoord ***events,
45                                                     gint           *n_events);
46 static void gdk_quartz_device_core_get_state (GdkDevice       *device,
47                                               GdkWindow       *window,
48                                               gdouble         *axes,
49                                               GdkModifierType *mask);
50 static void gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
51                                                       GdkWindow *window,
52                                                       GdkCursor *cursor);
53 static void gdk_quartz_device_core_warp (GdkDevice *device,
54                                          GdkScreen *screen,
55                                          gint       x,
56                                          gint       y);
57 static void gdk_quartz_device_core_query_state (GdkDevice        *device,
58                                                 GdkWindow        *window,
59                                                 GdkWindow       **root_window,
60                                                 GdkWindow       **child_window,
61                                                 gint             *root_x,
62                                                 gint             *root_y,
63                                                 gint             *win_x,
64                                                 gint             *win_y,
65                                                 GdkModifierType  *mask);
66 static GdkGrabStatus gdk_quartz_device_core_grab   (GdkDevice     *device,
67                                                     GdkWindow     *window,
68                                                     gboolean       owner_events,
69                                                     GdkEventMask   event_mask,
70                                                     GdkWindow     *confine_to,
71                                                     GdkCursor     *cursor,
72                                                     guint32        time_);
73 static void          gdk_quartz_device_core_ungrab (GdkDevice     *device,
74                                                     guint32        time_);
75 static GdkWindow * gdk_quartz_device_core_window_at_position (GdkDevice       *device,
76                                                               gint            *win_x,
77                                                               gint            *win_y,
78                                                               GdkModifierType *mask,
79                                                               gboolean         get_toplevel);
80 static void      gdk_quartz_device_core_select_window_events (GdkDevice       *device,
81                                                               GdkWindow       *window,
82                                                               GdkEventMask     event_mask);
83
84
85 G_DEFINE_TYPE (GdkQuartzDeviceCore, gdk_quartz_device_core, GDK_TYPE_DEVICE)
86
87 static void
88 gdk_quartz_device_core_class_init (GdkQuartzDeviceCoreClass *klass)
89 {
90   GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
91
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;
101 }
102
103 static void
104 gdk_quartz_device_core_init (GdkQuartzDeviceCore *quartz_device_core)
105 {
106   GdkDevice *device;
107
108   device = GDK_DEVICE (quartz_device_core);
109
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);
112 }
113
114 static gboolean
115 gdk_quartz_device_core_get_history (GdkDevice      *device,
116                                     GdkWindow      *window,
117                                     guint32         start,
118                                     guint32         stop,
119                                     GdkTimeCoord ***events,
120                                     gint           *n_events)
121 {
122   return FALSE;
123 }
124
125 static void
126 gdk_quartz_device_core_get_state (GdkDevice       *device,
127                                   GdkWindow       *window,
128                                   gdouble         *axes,
129                                   GdkModifierType *mask)
130 {
131   gint x_int, y_int;
132
133   gdk_window_get_pointer (window, &x_int, &y_int, mask);
134
135   if (axes)
136     {
137       axes[0] = x_int;
138       axes[1] = y_int;
139     }
140 }
141
142 static void
143 translate_coords_to_child_coords (GdkWindow *parent,
144                                   GdkWindow *child,
145                                   gint      *x,
146                                   gint      *y)
147 {
148   GdkWindow *current = child;
149
150   if (child == parent)
151     return;
152
153   while (current != parent)
154     {
155       gint tmp_x, tmp_y;
156
157       gdk_window_get_origin (current, &tmp_x, &tmp_y);
158
159       *x -= tmp_x;
160       *y -= tmp_y;
161
162       current = gdk_window_get_effective_parent (current);
163     }
164 }
165
166 static void
167 gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
168                                           GdkWindow *window,
169                                           GdkCursor *cursor)
170 {
171   NSCursor *nscursor;
172
173   if (GDK_WINDOW_DESTROYED (window))
174     return;
175
176   nscursor = _gdk_quartz_cursor_get_ns_cursor (cursor);
177
178   [nscursor set];
179 }
180
181 static void
182 gdk_quartz_device_core_warp (GdkDevice *device,
183                              GdkScreen *screen,
184                              gint       x,
185                              gint       y)
186 {
187   CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
188 }
189
190 static GdkWindow *
191 gdk_quartz_device_core_query_state_helper (GdkWindow       *window,
192                                            GdkDevice       *device,
193                                            gint            *x,
194                                            gint            *y,
195                                            GdkModifierType *mask)
196 {
197   GdkWindow *toplevel;
198   NSPoint point;
199   gint x_tmp, y_tmp;
200   GdkWindow *found_window;
201
202   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
203
204   if (GDK_WINDOW_DESTROYED (window))
205     {
206       *x = 0;
207       *y = 0;
208       *mask = 0;
209       return NULL;
210     }
211
212   toplevel = gdk_window_get_effective_toplevel (window);
213
214   if (mask)
215     *mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
216         _gdk_quartz_events_get_current_mouse_modifiers ();
217
218   /* Get the y coordinate, needs to be flipped. */
219   if (window == _gdk_root)
220     {
221       point = [NSEvent mouseLocation];
222       _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
223     }
224   else
225     {
226       GdkWindowImplQuartz *impl;
227       NSWindow *nswindow;
228
229       impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
230       nswindow = impl->toplevel;
231
232       point = [nswindow mouseLocationOutsideOfEventStream];
233
234       x_tmp = point.x;
235       y_tmp = toplevel->height - point.y;
236
237       window = toplevel;
238     }
239
240   found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
241                                                 FALSE);
242
243   if (found_window == _gdk_root)
244     found_window = NULL;
245   else if (found_window)
246     translate_coords_to_child_coords (window, found_window,
247                                       &x_tmp, &y_tmp);
248
249   if (x)
250     *x = x_tmp;
251
252   if (y)
253     *y = y_tmp;
254
255   return found_window;
256 }
257
258 static void
259 gdk_quartz_device_core_query_state (GdkDevice        *device,
260                                     GdkWindow        *window,
261                                     GdkWindow       **root_window,
262                                     GdkWindow       **child_window,
263                                     gint             *root_x,
264                                     gint             *root_y,
265                                     gint             *win_x,
266                                     gint             *win_y,
267                                     GdkModifierType  *mask)
268 {
269   GdkWindow *found_window;
270   NSPoint point;
271   gint x_tmp, y_tmp;
272
273   found_window = gdk_quartz_device_core_query_state_helper (window, device,
274                                                             win_x, win_y,
275                                                             mask);
276
277   if (root_window)
278     *root_window = _gdk_root;
279
280   if (child_window)
281     *child_window = found_window;
282
283   point = [NSEvent mouseLocation];
284   _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
285
286   if (root_x)
287     *root_x = x_tmp;
288
289   if (root_y)
290     *root_y = y_tmp;
291 }
292
293 static GdkGrabStatus
294 gdk_quartz_device_core_grab (GdkDevice    *device,
295                              GdkWindow    *window,
296                              gboolean      owner_events,
297                              GdkEventMask  event_mask,
298                              GdkWindow    *confine_to,
299                              GdkCursor    *cursor,
300                              guint32       time_)
301 {
302   /* Should remain empty */
303   return GDK_GRAB_SUCCESS;
304 }
305
306 static void
307 gdk_quartz_device_core_ungrab (GdkDevice *device,
308                                guint32    time_)
309 {
310   GdkDeviceGrabInfo *grab;
311
312   grab = _gdk_display_get_last_device_grab (_gdk_display, device);
313   if (grab)
314     grab->serial_end = 0;
315
316   _gdk_display_device_grab_update (_gdk_display, device, NULL, 0);
317 }
318
319 static GdkWindow *
320 gdk_quartz_device_core_window_at_position (GdkDevice       *device,
321                                            gint            *win_x,
322                                            gint            *win_y,
323                                            GdkModifierType *mask,
324                                            gboolean         get_toplevel)
325 {
326   GdkDisplay *display;
327   GdkScreen *screen;
328   GdkWindow *found_window;
329   NSPoint point;
330   gint x_tmp, y_tmp;
331
332   display = gdk_device_get_display (device);
333   screen = gdk_display_get_default_screen (display);
334
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);
338
339   found_window = _gdk_quartz_window_find_child (_gdk_root, x_tmp, y_tmp,
340                                                 get_toplevel);
341
342   if (found_window)
343     translate_coords_to_child_coords (_gdk_root, found_window,
344                                       &x_tmp, &y_tmp);
345
346   if (win_x)
347     *win_x = found_window ? x_tmp : -1;
348
349   if (win_y)
350     *win_y = found_window ? y_tmp : -1;
351
352   if (mask)
353     *mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
354         _gdk_quartz_events_get_current_mouse_modifiers ();
355
356   return found_window;
357 }
358
359 static void
360 gdk_quartz_device_core_select_window_events (GdkDevice    *device,
361                                              GdkWindow    *window,
362                                              GdkEventMask  event_mask)
363 {
364   /* The mask is set in the common code. */
365 }