1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
21 #include <X11/Xutil.h>
25 #include "gdkprivate.h"
29 /* Forward declarations */
31 static gint gdk_input_enable_window (GdkWindow *window,
32 GdkDevicePrivate *gdkdev);
33 static gint gdk_input_disable_window (GdkWindow *window,
34 GdkDevicePrivate *gdkdev);
35 static GdkInputWindow *gdk_input_window_find (GdkWindow *window);
36 static GdkDevicePrivate *gdk_input_find_device (guint32 id);
39 /* Incorporate the specific routines depending on compilation options */
41 static const GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y };
43 static const GdkDeviceInfo gdk_input_core_info =
54 /* Global variables */
56 GdkInputVTable gdk_input_vtable;
57 /* information about network port and host for gxid daemon */
58 gchar *gdk_input_gxid_host;
59 gint gdk_input_gxid_port;
60 gint gdk_input_ignore_core;
64 static GList *gdk_input_devices;
65 static GList *gdk_input_windows;
67 #include "gdkinputnone.h"
68 #include "gdkinputcommon.h"
69 #include "gdkinputxfree.h"
70 #include "gdkinputgxi.h"
73 gdk_input_list_devices (void)
75 return gdk_input_devices;
79 gdk_input_set_source (guint32 deviceid, GdkInputSource source)
81 GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
82 g_return_if_fail (gdkdev != NULL);
84 gdkdev->info.source = source;
88 gdk_input_set_mode (guint32 deviceid, GdkInputMode mode)
90 if (deviceid == GDK_CORE_POINTER)
93 if (gdk_input_vtable.set_mode)
94 return gdk_input_vtable.set_mode(deviceid,mode);
100 gdk_input_set_axes (guint32 deviceid, GdkAxisUse *axes)
102 if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_axes)
103 gdk_input_vtable.set_axes (deviceid, axes);
106 void gdk_input_set_key (guint32 deviceid,
109 GdkModifierType modifiers)
111 if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_key)
112 gdk_input_vtable.set_key (deviceid, index, keyval, modifiers);
116 gdk_input_motion_events (GdkWindow *window,
120 gint *nevents_return)
122 GdkWindowPrivate *window_private;
124 GdkTimeCoord *coords;
127 g_return_val_if_fail (window != NULL, NULL);
128 window_private = (GdkWindowPrivate *) window;
129 if (window_private->destroyed)
132 if (deviceid == GDK_CORE_POINTER)
134 xcoords = XGetMotionEvents (gdk_display,
135 window_private->xwindow,
136 start, stop, nevents_return);
139 coords = g_new (GdkTimeCoord, *nevents_return);
140 for (i=0; i<*nevents_return; i++)
142 coords[i].time = xcoords[i].time;
143 coords[i].x = xcoords[i].x;
144 coords[i].y = xcoords[i].y;
145 coords[i].pressure = 0.5;
146 coords[i].xtilt = 0.0;
147 coords[i].ytilt = 0.0;
159 if (gdk_input_vtable.motion_events)
161 return gdk_input_vtable.motion_events(window,
162 deviceid, start, stop,
174 gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
176 if (gdk_input_vtable.enable_window)
177 return gdk_input_vtable.enable_window (window, gdkdev);
183 gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
185 if (gdk_input_vtable.disable_window)
186 return gdk_input_vtable.disable_window(window,gdkdev);
192 static GdkInputWindow *
193 gdk_input_window_find(GdkWindow *window)
197 for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
198 if (((GdkInputWindow *)(tmp_list->data))->window == window)
199 return (GdkInputWindow *)(tmp_list->data);
201 return NULL; /* Not found */
204 /* FIXME: this routine currently needs to be called between creation
205 and the corresponding configure event (because it doesn't get the
206 root_relative_geometry). This should work with
207 gtk_window_set_extension_events, but will likely fail in other
211 gdk_input_set_extension_events (GdkWindow *window, gint mask,
212 GdkExtensionMode mode)
214 GdkWindowPrivate *window_private;
218 g_return_if_fail (window != NULL);
219 window_private = (GdkWindowPrivate*) window;
220 if (window_private->destroyed)
223 if (mode == GDK_EXTENSION_EVENTS_NONE)
228 iw = g_new(GdkInputWindow,1);
233 iw->obscuring = NULL;
234 iw->num_obscuring = 0;
237 gdk_input_windows = g_list_append(gdk_input_windows,iw);
238 window_private->extension_events = mask;
240 /* Add enter window events to the event mask */
241 /* FIXME, this is not needed for XINPUT_NONE */
242 gdk_window_set_events (window,
243 gdk_window_get_events (window) |
244 GDK_ENTER_NOTIFY_MASK);
248 iw = gdk_input_window_find (window);
251 gdk_input_windows = g_list_remove(gdk_input_windows,iw);
255 window_private->extension_events = 0;
258 for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
260 GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
262 if (gdkdev->info.deviceid != GDK_CORE_POINTER)
264 if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
265 && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
266 gdk_input_enable_window(window,gdkdev);
268 gdk_input_disable_window(window,gdkdev);
274 gdk_input_window_destroy (GdkWindow *window)
276 GdkInputWindow *input_window;
278 input_window = gdk_input_window_find (window);
279 g_return_if_fail (input_window != NULL);
281 gdk_input_windows = g_list_remove (gdk_input_windows,input_window);
282 g_free(input_window);
286 gdk_input_exit (void)
289 GdkDevicePrivate *gdkdev;
291 for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
293 gdkdev = (GdkDevicePrivate *)(tmp_list->data);
294 if (gdkdev->info.deviceid != GDK_CORE_POINTER)
296 gdk_input_set_mode(gdkdev->info.deviceid,GDK_MODE_DISABLED);
298 g_free(gdkdev->info.name);
300 g_free(gdkdev->axes);
302 g_free(gdkdev->info.axes);
303 g_free(gdkdev->info.keys);
308 g_list_free(gdk_input_devices);
310 for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
312 g_free(tmp_list->data);
314 g_list_free(gdk_input_windows);
317 static GdkDevicePrivate *
318 gdk_input_find_device(guint32 id)
320 GList *tmp_list = gdk_input_devices;
321 GdkDevicePrivate *gdkdev;
324 gdkdev = (GdkDevicePrivate *)(tmp_list->data);
325 if (gdkdev->info.deviceid == id)
327 tmp_list = tmp_list->next;
333 gdk_input_window_get_pointer (GdkWindow *window,
340 GdkModifierType *mask)
342 if (gdk_input_vtable.get_pointer)
343 gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure,