]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkinput.c
Make this compile without framebuffer enabled
[~andy/gtk] / gdk / x11 / 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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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-1999.  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 <stdlib.h>
28 #include <X11/Xlib.h>
29 #include <X11/Xutil.h>
30 #include "config.h"
31
32 #include "gdkx.h"
33 #include "gdkinput.h"
34 #include "gdkprivate.h"
35 #include "gdkinputprivate.h"
36
37 static const GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y };
38
39 const GdkDeviceInfo gdk_input_core_info =
40 {
41   GDK_CORE_POINTER,
42   "Core Pointer",
43   GDK_SOURCE_MOUSE,
44   GDK_MODE_SCREEN,
45   TRUE,
46   2,
47   gdk_input_core_axes
48 };
49
50 /* Global variables  */
51
52 GdkInputVTable    gdk_input_vtable;
53 /* information about network port and host for gxid daemon */
54 gchar            *gdk_input_gxid_host;
55 gint              gdk_input_gxid_port;
56 gint              gdk_input_ignore_core;
57
58 GList            *gdk_input_devices;
59 GList            *gdk_input_windows;
60
61 GList *
62 gdk_input_list_devices (void)
63 {
64   return gdk_input_devices;
65 }
66
67 void
68 gdk_input_set_source (guint32 deviceid, GdkInputSource source)
69 {
70   GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
71   g_return_if_fail (gdkdev != NULL);
72
73   gdkdev->info.source = source;
74 }
75
76 gboolean
77 gdk_input_set_mode (guint32 deviceid, GdkInputMode mode)
78 {
79   if (deviceid == GDK_CORE_POINTER)
80     return FALSE;
81
82   if (gdk_input_vtable.set_mode)
83     return gdk_input_vtable.set_mode(deviceid,mode);
84   else
85     return FALSE;
86 }
87
88 void
89 gdk_input_set_axes (guint32 deviceid, GdkAxisUse *axes)
90 {
91   if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_axes)
92     gdk_input_vtable.set_axes (deviceid, axes);
93 }
94
95 void gdk_input_set_key (guint32 deviceid,
96                         guint   index,
97                         guint   keyval,
98                         GdkModifierType modifiers)
99 {
100   if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_key)
101     gdk_input_vtable.set_key (deviceid, index, keyval, modifiers);
102 }
103
104 GdkTimeCoord *
105 gdk_input_motion_events (GdkWindow *window,
106                          guint32 deviceid,
107                          guint32 start,
108                          guint32 stop,
109                          gint *nevents_return)
110 {
111   XTimeCoord *xcoords;
112   GdkTimeCoord *coords;
113   int i;
114
115   g_return_val_if_fail (window != NULL, NULL);
116   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
117   
118   if (GDK_WINDOW_DESTROYED (window))
119     return NULL;
120
121   if (deviceid == GDK_CORE_POINTER)
122     {
123       xcoords = XGetMotionEvents (GDK_DRAWABLE_XDISPLAY (window),
124                                   GDK_DRAWABLE_XID (window),
125                                   start, stop, nevents_return);
126       if (xcoords)
127         {
128           coords = g_new (GdkTimeCoord, *nevents_return);
129           for (i=0; i<*nevents_return; i++)
130             {
131               coords[i].time = xcoords[i].time;
132               coords[i].x = xcoords[i].x;
133               coords[i].y = xcoords[i].y;
134               coords[i].pressure = 0.5;
135               coords[i].xtilt = 0.0;
136               coords[i].ytilt = 0.0;
137             }
138
139           XFree (xcoords);
140
141           return coords;
142         }
143       else
144         return NULL;
145     }
146   else
147     {
148       if (gdk_input_vtable.motion_events)
149         {
150           return gdk_input_vtable.motion_events(window,
151                                                 deviceid, start, stop,
152                                                 nevents_return);
153         }
154       else
155         {
156           *nevents_return = 0;
157           return NULL;
158         }
159     }
160 }
161
162 gint
163 gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
164 {
165   if (gdk_input_vtable.enable_window)
166     return gdk_input_vtable.enable_window (window, gdkdev);
167   else
168     return TRUE;
169 }
170
171 gint
172 gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
173 {
174   if (gdk_input_vtable.disable_window)
175     return gdk_input_vtable.disable_window(window,gdkdev);
176   else
177     return TRUE;
178 }
179
180
181 GdkInputWindow *
182 gdk_input_window_find(GdkWindow *window)
183 {
184   GList *tmp_list;
185
186   for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
187     if (((GdkInputWindow *)(tmp_list->data))->window == window)
188       return (GdkInputWindow *)(tmp_list->data);
189
190   return NULL;      /* Not found */
191 }
192
193 /* FIXME: this routine currently needs to be called between creation
194    and the corresponding configure event (because it doesn't get the
195    root_relative_geometry).  This should work with
196    gtk_window_set_extension_events, but will likely fail in other
197    cases */
198
199 void
200 gdk_input_set_extension_events (GdkWindow *window, gint mask,
201                                 GdkExtensionMode mode)
202 {
203   GdkWindowObject *window_private;
204   GList *tmp_list;
205   GdkInputWindow *iw;
206
207   g_return_if_fail (window != NULL);
208   g_return_if_fail (GDK_IS_WINDOW (window));
209
210   window_private = (GdkWindowObject*) window;
211   if (GDK_WINDOW_DESTROYED (window))
212     return;
213
214   if (mode == GDK_EXTENSION_EVENTS_NONE)
215     mask = 0;
216
217   if (mask != 0)
218     {
219       iw = g_new(GdkInputWindow,1);
220
221       iw->window = window;
222       iw->mode = mode;
223
224       iw->obscuring = NULL;
225       iw->num_obscuring = 0;
226       iw->grabbed = FALSE;
227
228       gdk_input_windows = g_list_append(gdk_input_windows,iw);
229       window_private->extension_events = mask;
230
231       /* Add enter window events to the event mask */
232       /* FIXME, this is not needed for XINPUT_NONE */
233       gdk_window_set_events (window,
234                              gdk_window_get_events (window) | 
235                              GDK_ENTER_NOTIFY_MASK);
236     }
237   else
238     {
239       iw = gdk_input_window_find (window);
240       if (iw)
241         {
242           gdk_input_windows = g_list_remove(gdk_input_windows,iw);
243           g_free(iw);
244         }
245
246       window_private->extension_events = 0;
247     }
248
249   for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
250     {
251       GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
252
253       if (gdkdev->info.deviceid != GDK_CORE_POINTER)
254         {
255           if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
256               && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
257             gdk_input_enable_window(window,gdkdev);
258           else
259             gdk_input_disable_window(window,gdkdev);
260         }
261     }
262 }
263
264 void
265 gdk_input_window_destroy (GdkWindow *window)
266 {
267   GdkInputWindow *input_window;
268
269   input_window = gdk_input_window_find (window);
270   g_return_if_fail (input_window != NULL);
271
272   gdk_input_windows = g_list_remove (gdk_input_windows,input_window);
273   g_free(input_window);
274 }
275
276 void
277 gdk_input_exit (void)
278 {
279   GList *tmp_list;
280   GdkDevicePrivate *gdkdev;
281
282   for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
283     {
284       gdkdev = (GdkDevicePrivate *)(tmp_list->data);
285       if (gdkdev->info.deviceid != GDK_CORE_POINTER)
286         {
287           gdk_input_set_mode(gdkdev->info.deviceid,GDK_MODE_DISABLED);
288
289           g_free(gdkdev->info.name);
290 #ifndef XINPUT_NONE       
291           g_free(gdkdev->axes);
292 #endif    
293           g_free(gdkdev->info.axes);
294           g_free(gdkdev->info.keys);
295           g_free(gdkdev);
296         }
297     }
298
299   g_list_free(gdk_input_devices);
300
301   for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
302     {
303       g_free(tmp_list->data);
304     }
305   g_list_free(gdk_input_windows);
306 }
307
308 GdkDevicePrivate *
309 gdk_input_find_device(guint32 id)
310 {
311   GList *tmp_list = gdk_input_devices;
312   GdkDevicePrivate *gdkdev;
313   while (tmp_list)
314     {
315       gdkdev = (GdkDevicePrivate *)(tmp_list->data);
316       if (gdkdev->info.deviceid == id)
317         return gdkdev;
318       tmp_list = tmp_list->next;
319     }
320   return NULL;
321 }
322
323 void
324 gdk_input_window_get_pointer (GdkWindow       *window,
325                               guint32     deviceid,
326                               gdouble         *x,
327                               gdouble         *y,
328                               gdouble         *pressure,
329                               gdouble         *xtilt,
330                               gdouble         *ytilt,
331                               GdkModifierType *mask)
332 {
333   if (gdk_input_vtable.get_pointer)
334     gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure,
335                                   xtilt, ytilt, mask);
336 }