]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkinput.c
Merge branch 'master' into client-side-windows
[~andy/gtk] / gdk / quartz / gdkinput.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28 #include <stdlib.h>
29
30 #include "gdkprivate-quartz.h"
31 #include "gdkinput.h"
32 #include "gdkprivate.h"
33 #include "gdkinputprivate.h"
34
35 static GdkDeviceAxis gdk_input_core_axes[] = {
36   { GDK_AXIS_X, 0, 0 },
37   { GDK_AXIS_Y, 0, 0 }
38 };
39
40 GdkDevice *_gdk_core_pointer = NULL;
41
42 /* Global variables  */
43
44 gchar            *_gdk_input_gxid_host;
45 gint              _gdk_input_gxid_port;
46 gint              _gdk_input_ignore_core;
47 GList            *_gdk_input_windows;
48 GList            *_gdk_input_devices;
49
50 void
51 _gdk_init_input_core (void)
52 {
53   _gdk_core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL);
54   
55   _gdk_core_pointer->name = "Core Pointer";
56   _gdk_core_pointer->source = GDK_SOURCE_MOUSE;
57   _gdk_core_pointer->mode = GDK_MODE_SCREEN;
58   _gdk_core_pointer->has_cursor = TRUE;
59   _gdk_core_pointer->num_axes = 2;
60   _gdk_core_pointer->axes = gdk_input_core_axes;
61   _gdk_core_pointer->num_keys = 0;
62   _gdk_core_pointer->keys = NULL;
63
64   _gdk_display->core_pointer = _gdk_core_pointer;
65 }
66
67 static void
68 gdk_device_finalize (GObject *object)
69 {
70   g_error ("A GdkDevice object was finalized. This should not happen");
71 }
72
73 static void
74 gdk_device_class_init (GObjectClass *class)
75 {
76   class->finalize = gdk_device_finalize;
77 }
78
79 GType
80 gdk_device_get_type (void)
81 {
82   static GType object_type = 0;
83
84   if (!object_type)
85     {
86       static const GTypeInfo object_info =
87       {
88         sizeof (GdkDeviceClass),
89         (GBaseInitFunc) NULL,
90         (GBaseFinalizeFunc) NULL,
91         (GClassInitFunc) gdk_device_class_init,
92         NULL,           /* class_finalize */
93         NULL,           /* class_data */
94         sizeof (GdkDevicePrivate),
95         0,              /* n_preallocs */
96         (GInstanceInitFunc) NULL,
97       };
98       
99       object_type = g_type_register_static (G_TYPE_OBJECT,
100                                             "GdkDevice",
101                                             &object_info, 0);
102     }
103   
104   return object_type;
105 }
106
107 GList *
108 gdk_devices_list (void)
109 {
110   return _gdk_input_devices;
111 }
112
113 GList *
114 gdk_display_list_devices (GdkDisplay *dpy)
115 {
116   return _gdk_input_devices;
117 }
118
119 void
120 gdk_device_set_source (GdkDevice *device,
121                        GdkInputSource source)
122 {
123   device->source = source;
124 }
125
126
127 void
128 gdk_device_set_key (GdkDevice      *device,
129                     guint           index,
130                     guint           keyval,
131                     GdkModifierType modifiers)
132 {
133   g_return_if_fail (device != NULL);
134   g_return_if_fail (index < device->num_keys);
135
136   device->keys[index].keyval = keyval;
137   device->keys[index].modifiers = modifiers;
138 }
139
140 void
141 gdk_device_set_axis_use (GdkDevice   *device,
142                          guint        index,
143                          GdkAxisUse   use)
144 {
145   g_return_if_fail (device != NULL);
146   g_return_if_fail (index < device->num_axes);
147
148   device->axes[index].use = use;
149
150   switch (use)
151     {
152     case GDK_AXIS_X:
153     case GDK_AXIS_Y:
154       device->axes[index].min = 0.;
155       device->axes[index].max = 0.;
156       break;
157     case GDK_AXIS_XTILT:
158     case GDK_AXIS_YTILT:
159       device->axes[index].min = -1.;
160       device->axes[index].max = 1;
161       break;
162     default:
163       device->axes[index].min = 0.;
164       device->axes[index].max = 1;
165       break;
166     }
167 }
168
169 void 
170 gdk_device_get_state (GdkDevice       *device,
171                       GdkWindow       *window,
172                       gdouble         *axes,
173                       GdkModifierType *mask)
174 {
175   gint x_int, y_int;
176
177   g_assert (device == _gdk_core_pointer);
178       
179   gdk_window_get_pointer (window, &x_int, &y_int, mask);
180
181   if (axes)
182     {
183       axes[0] = x_int;
184       axes[1] = y_int;
185     }
186 }
187
188 void 
189 gdk_device_free_history (GdkTimeCoord **events,
190                          gint           n_events)
191 {
192   gint i;
193   
194   for (i = 0; i < n_events; i++)
195     g_free (events[i]);
196
197   g_free (events);
198 }
199
200 gboolean
201 gdk_device_get_history  (GdkDevice         *device,
202                          GdkWindow         *window,
203                          guint32            start,
204                          guint32            stop,
205                          GdkTimeCoord    ***events,
206                          gint              *n_events)
207 {
208   g_return_val_if_fail (window != NULL, FALSE);
209   g_return_val_if_fail (GDK_WINDOW_IS_QUARTZ (window), FALSE);
210   g_return_val_if_fail (events != NULL, FALSE);
211   g_return_val_if_fail (n_events != NULL, FALSE);
212
213   *n_events = 0;
214   *events = NULL;
215   return FALSE;
216 }
217
218 gboolean
219 gdk_device_set_mode (GdkDevice   *device,
220                      GdkInputMode mode)
221 {
222   return FALSE;
223 }
224
225 gint
226 _gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
227 {
228   return TRUE;
229 }
230
231 gint
232 _gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
233 {
234   return TRUE;
235 }
236
237
238 GdkInputWindow *
239 _gdk_input_window_find(GdkWindow *window)
240 {
241   GList *tmp_list;
242
243   for (tmp_list=_gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
244     if (((GdkInputWindow *)(tmp_list->data))->window == window)
245       return (GdkInputWindow *)(tmp_list->data);
246
247   return NULL;      /* Not found */
248 }
249
250 /* FIXME: this routine currently needs to be called between creation
251    and the corresponding configure event (because it doesn't get the
252    root_relative_geometry).  This should work with
253    gtk_window_set_extension_events, but will likely fail in other
254    cases */
255
256 void
257 gdk_input_set_extension_events (GdkWindow *window, gint mask,
258                                 GdkExtensionMode mode)
259 {
260   GdkWindowObject *window_private;
261   GList *tmp_list;
262   GdkInputWindow *iw;
263
264   g_return_if_fail (window != NULL);
265   g_return_if_fail (GDK_WINDOW_IS_QUARTZ (window));
266
267   window_private = (GdkWindowObject*) window;
268
269   if (mode == GDK_EXTENSION_EVENTS_NONE)
270     mask = 0;
271
272   if (mask != 0)
273     {
274       iw = g_new(GdkInputWindow,1);
275
276       iw->window = window;
277       iw->mode = mode;
278
279       iw->obscuring = NULL;
280       iw->num_obscuring = 0;
281       iw->grabbed = FALSE;
282
283       _gdk_input_windows = g_list_append (_gdk_input_windows,iw);
284       window_private->extension_events = mask;
285
286       /* Add enter window events to the event mask */
287       /* FIXME, this is not needed for XINPUT_NONE */
288       gdk_window_set_events (window,
289                              gdk_window_get_events (window) | 
290                              GDK_ENTER_NOTIFY_MASK);
291     }
292   else
293     {
294       iw = _gdk_input_window_find (window);
295       if (iw)
296         {
297           _gdk_input_windows = g_list_remove (_gdk_input_windows,iw);
298           g_free (iw);
299         }
300
301       window_private->extension_events = 0;
302     }
303
304   for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
305     {
306       GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
307
308       if (gdkdev != (GdkDevicePrivate *)_gdk_core_pointer)
309         {
310           if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
311               && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
312             _gdk_input_enable_window (window,gdkdev);
313           else
314             _gdk_input_disable_window (window,gdkdev);
315         }
316     }
317 }
318
319 void
320 _gdk_input_window_destroy (GdkWindow *window)
321 {
322   GdkInputWindow *input_window;
323
324   input_window = _gdk_input_window_find (window);
325   g_return_if_fail (input_window != NULL);
326
327   _gdk_input_windows = g_list_remove (_gdk_input_windows,input_window);
328   g_free (input_window);
329 }
330
331 void
332 _gdk_input_init (void)
333 {
334   _gdk_init_input_core ();
335   _gdk_input_devices = g_list_append (NULL, _gdk_core_pointer);
336   _gdk_input_ignore_core = FALSE;
337 }
338
339 void
340 _gdk_input_exit (void)
341 {
342   GList *tmp_list;
343   GdkDevicePrivate *gdkdev;
344
345   for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
346     {
347       gdkdev = (GdkDevicePrivate *)(tmp_list->data);
348       if (gdkdev != (GdkDevicePrivate *)_gdk_core_pointer)
349         {
350           gdk_device_set_mode ((GdkDevice *)gdkdev, GDK_MODE_DISABLED);
351
352           g_free (gdkdev->info.name);
353           g_free (gdkdev->info.axes);
354           g_free (gdkdev->info.keys);
355           g_free (gdkdev);
356         }
357     }
358
359   g_list_free (_gdk_input_devices);
360
361   for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
362     {
363       g_free (tmp_list->data);
364     }
365   g_list_free (_gdk_input_windows);
366 }
367
368 gboolean
369 gdk_device_get_axis (GdkDevice *device, gdouble *axes, GdkAxisUse use, gdouble *value)
370 {
371   gint i;
372   
373   g_return_val_if_fail (device != NULL, FALSE);
374
375   if (axes == NULL)
376     return FALSE;
377   
378   for (i = 0; i < device->num_axes; i++)
379     if (device->axes[i].use == use)
380       {
381         if (value)
382           *value = axes[i];
383         return TRUE;
384       }
385   
386   return FALSE;
387 }