diff options
Diffstat (limited to 'gdk/x11/gdkinput.c')
-rw-r--r-- | gdk/x11/gdkinput.c | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/gdk/x11/gdkinput.c b/gdk/x11/gdkinput.c new file mode 100644 index 000000000..ad4b1fcc9 --- /dev/null +++ b/gdk/x11/gdkinput.c @@ -0,0 +1,324 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include "../config.h" +#include "gdk.h" +#include "gdkx.h" +#include "gdkprivate.h" +#include "gdkinput.h" + + +/* Forward declarations */ + +static gint gdk_input_enable_window (GdkWindow *window, + GdkDevicePrivate *gdkdev); +static gint gdk_input_disable_window (GdkWindow *window, + GdkDevicePrivate *gdkdev); +static GdkInputWindow *gdk_input_window_find (GdkWindow *window); +static GdkDevicePrivate *gdk_input_find_device (guint32 id); + + +/* Incorporate the specific routines depending on compilation options */ + +static GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y }; + +static GdkDeviceInfo gdk_input_core_info = +{ + GDK_CORE_POINTER, + "Core Pointer", + GDK_SOURCE_MOUSE, + GDK_MODE_SCREEN, + TRUE, + 2, + gdk_input_core_axes +}; + +/* Global variables */ + +GdkInputVTable gdk_input_vtable; +/* information about network port and host for gxid daemon */ +gchar *gdk_input_gxid_host; +gint gdk_input_gxid_port; +gint gdk_input_ignore_core; + +/* Local variables */ + +static GList *gdk_input_devices; +static GList *gdk_input_windows; + +#include "gdkinputnone.h" +#include "gdkinputcommon.h" +#include "gdkinputxfree.h" +#include "gdkinputgxi.h" + +GList * +gdk_input_list_devices () +{ + return gdk_input_devices; +} + +void +gdk_input_set_source (guint32 deviceid, GdkInputSource source) +{ + GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid); + g_return_if_fail (gdkdev != NULL); + + gdkdev->info.source = source; +} + +gint +gdk_input_set_mode (guint32 deviceid, GdkInputMode mode) +{ + if (deviceid == GDK_CORE_POINTER) + return FALSE; + + if (gdk_input_vtable.set_mode) + return gdk_input_vtable.set_mode(deviceid,mode); + else + return FALSE; +} + +void +gdk_input_set_axes (guint32 deviceid, GdkAxisUse *axes) +{ + if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_axes) + gdk_input_vtable.set_axes (deviceid, axes); +} + +GdkTimeCoord * +gdk_input_motion_events (GdkWindow *window, + guint32 deviceid, + guint32 start, + guint32 stop, + gint *nevents_return) +{ + XTimeCoord *xcoords; + GdkTimeCoord *coords; + int i; + + if (deviceid == GDK_CORE_POINTER) + { + xcoords = XGetMotionEvents (gdk_display, + ((GdkWindowPrivate *)window)->xwindow, + start, stop, nevents_return); + if (xcoords) + { + coords = g_new (GdkTimeCoord, *nevents_return); + for (i=0; i<*nevents_return; i++) + { + coords[i].time = xcoords[i].time; + coords[i].x = xcoords[i].x; + coords[i].y = xcoords[i].y; + coords[i].pressure = 0.5; + coords[i].xtilt = 0.0; + coords[i].ytilt = 0.0; + } + + XFree(xcoords); + + return coords; + } + else + return NULL; + } + else + { + if (gdk_input_vtable.motion_events) + { + return gdk_input_vtable.motion_events(window, + deviceid, start, stop, + nevents_return); + } + else + { + *nevents_return = 0; + return NULL; + } + } +} + +static gint +gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) +{ + if (gdk_input_vtable.enable_window) + return gdk_input_vtable.enable_window (window, gdkdev); + else + return TRUE; +} + +static gint +gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) +{ + if (gdk_input_vtable.disable_window) + return gdk_input_vtable.disable_window(window,gdkdev); + else + return TRUE; +} + + +static GdkInputWindow * +gdk_input_window_find(GdkWindow *window) +{ + GList *tmp_list; + + for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next) + if (((GdkInputWindow *)(tmp_list->data))->window == window) + return (GdkInputWindow *)(tmp_list->data); + + return NULL; /* Not found */ +} + +/* FIXME: this routine currently needs to be called between creation + and the corresponding configure event (because it doesn't get the + root_relative_geometry). This should work with + gtk_window_set_extension_events, but will likely fail in other + cases */ + +void +gdk_input_set_extension_events (GdkWindow *window, gint mask, + GdkExtensionMode mode) +{ + GList *tmp_list; + GdkInputWindow *iw; + + g_return_if_fail (window != NULL); + + if (mode == GDK_EXTENSION_EVENTS_NONE) + mask = 0; + + if (mask != 0) + { + iw = g_new(GdkInputWindow,1); + + iw->window = window; + iw->mode = mode; + + iw->obscuring = NULL; + iw->num_obscuring = 0; + iw->grabbed = FALSE; + + gdk_input_windows = g_list_append(gdk_input_windows,iw); + ((GdkWindowPrivate *)window)->extension_events = mask; + + /* Add enter window events to the event mask */ + /* FIXME, this is not needed for XINPUT_NONE */ + gdk_window_set_events (window, + gdk_window_get_events (window) | + GDK_ENTER_NOTIFY_MASK); + } + else + { + iw = gdk_input_window_find (window); + if (iw) + { + gdk_input_windows = g_list_remove(gdk_input_windows,iw); + g_free(iw); + } + + ((GdkWindowPrivate *)window)->extension_events = 0; + } + + for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + { + GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data); + + if (gdkdev->info.deviceid != GDK_CORE_POINTER) + { + if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED + && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL)) + gdk_input_enable_window(window,gdkdev); + else + gdk_input_disable_window(window,gdkdev); + } + } +} + +void +gdk_input_window_destroy (GdkWindow *window) +{ + GdkInputWindow *input_window; + + input_window = gdk_input_window_find (window); + g_return_if_fail (input_window != NULL); + + gdk_input_windows = g_list_remove(gdk_input_windows,input_window); + g_free(input_window); +} + +void +gdk_input_exit (void) +{ + GList *tmp_list; + GdkDevicePrivate *gdkdev; + + for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + { + gdkdev = (GdkDevicePrivate *)(tmp_list->data); + if (gdkdev->info.deviceid != GDK_CORE_POINTER) + { + gdk_input_set_mode(gdkdev->info.deviceid,GDK_MODE_DISABLED); + + g_free(gdkdev->info.name); +#ifndef XINPUT_NONE + g_free(gdkdev->axes); +#endif + g_free(gdkdev->info.axes); + g_free(gdkdev); + } + } + + g_list_free(gdk_input_devices); + + for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next) + { + g_free(tmp_list->data); + } + g_list_free(gdk_input_windows); +} + +static GdkDevicePrivate * +gdk_input_find_device(guint32 id) +{ + GList *tmp_list = gdk_input_devices; + GdkDevicePrivate *gdkdev; + while (tmp_list) + { + gdkdev = (GdkDevicePrivate *)(tmp_list->data); + if (gdkdev->info.deviceid == id) + return gdkdev; + tmp_list = tmp_list->next; + } + return NULL; +} + +void +gdk_input_window_get_pointer (GdkWindow *window, + guint32 deviceid, + gdouble *x, + gdouble *y, + gdouble *pressure, + gdouble *xtilt, + gdouble *ytilt, + GdkModifierType *mask) +{ + if (gdk_input_vtable.get_pointer) + gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure, + xtilt, ytilt, mask); +} |