diff options
author | Matthias Clasen <mclasen@redhat.com> | 2010-05-25 18:38:44 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2010-05-25 18:38:44 -0400 |
commit | bd4609b14042a91646cd9057764eecfbc6faf42b (patch) | |
tree | 8721405d2b45a998f87cccc672b4070780907fb8 /gdk/win32/gdkdevice-wintab.c | |
parent | a538f639b69a39d7bb85b39af2dfd296d28fc0aa (diff) | |
download | gtk+-bd4609b14042a91646cd9057764eecfbc6faf42b.tar.gz |
Merge the xi2-for-master branch
Diffstat (limited to 'gdk/win32/gdkdevice-wintab.c')
-rw-r--r-- | gdk/win32/gdkdevice-wintab.c | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/gdk/win32/gdkdevice-wintab.c b/gdk/win32/gdkdevice-wintab.c new file mode 100644 index 0000000000..392e10b2e4 --- /dev/null +++ b/gdk/win32/gdkdevice-wintab.c @@ -0,0 +1,386 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include <gdk/gdkwindow.h> + +#include <windowsx.h> +#include <objbase.h> + +#include "gdkwin32.h" +#include "gdkdevice-wintab.h" + +static GQuark quark_window_input_info = 0; +static GSList *input_windows = NULL; + +typedef struct +{ + gdouble root_x; + gdouble root_y; + GHashTable *device_events; +} GdkWindowInputInfo; + +static gboolean gdk_device_wintab_get_history (GdkDevice *device, + GdkWindow *window, + guint32 start, + guint32 stop, + GdkTimeCoord ***events, + guint *n_events); +static void gdk_device_wintab_get_state (GdkDevice *device, + GdkWindow *window, + gdouble *axes, + GdkModifierType *mask); +static void gdk_device_wintab_set_window_cursor (GdkDevice *device, + GdkWindow *window, + GdkCursor *cursor); +static void gdk_device_wintab_warp (GdkDevice *device, + GdkScreen *screen, + gint x, + gint y); +static gboolean gdk_device_wintab_query_state (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, + gint *root_x, + gint *root_y, + gint *win_x, + gint *win_y, + GdkModifierType *mask); +static GdkGrabStatus gdk_device_wintab_grab (GdkDevice *device, + GdkWindow *window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time_); +static void gdk_device_wintab_ungrab (GdkDevice *device, + guint32 time_); +static GdkWindow * gdk_device_wintab_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel); +static void gdk_device_wintab_select_window_events (GdkDevice *device, + GdkWindow *window, + GdkEventMask event_mask); + + +G_DEFINE_TYPE (GdkDeviceWintab, gdk_device_wintab, GDK_TYPE_DEVICE) + +static void +gdk_device_wintab_class_init (GdkDeviceWintabClass *klass) +{ + GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + + device_class->get_history = gdk_device_wintab_get_history; + device_class->get_state = gdk_device_wintab_get_state; + device_class->set_window_cursor = gdk_device_wintab_set_window_cursor; + device_class->warp = gdk_device_wintab_warp; + device_class->query_state = gdk_device_wintab_query_state; + device_class->grab = gdk_device_wintab_grab; + device_class->ungrab = gdk_device_wintab_ungrab; + device_class->window_at_position = gdk_device_wintab_window_at_position; + device_class->select_window_events = gdk_device_wintab_select_window_events; + + quark_window_input_info = g_quark_from_static_string ("gdk-window-input-info"); +} + +static void +gdk_device_wintab_init (GdkDeviceWintab *device_wintab) +{ + GdkDevice *device; + + device = GDK_DEVICE (device_wintab); +} + +static gboolean +gdk_device_wintab_get_history (GdkDevice *device, + GdkWindow *window, + guint32 start, + guint32 stop, + GdkTimeCoord ***events, + guint *n_events) +{ + return FALSE; +} + +static void +gdk_device_wintab_get_state (GdkDevice *device, + GdkWindow *window, + gdouble *axes, + GdkModifierType *mask) +{ + GdkDeviceWintab *device_wintab; + + device_wintab = GDK_DEVICE_WINTAB (device); + + /* For now just use the last known button and axis state of the device. + * Since graphical tablets send an insane amount of motion events each + * second, the info should be fairly up to date */ + if (mask) + { + gdk_window_get_pointer (window, NULL, NULL, mask); + *mask &= 0xFF; /* Mask away core pointer buttons */ + *mask |= ((device_wintab->button_state << 8) + & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK + | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK + | GDK_BUTTON5_MASK)); + } + + if (device_wintab->last_axis_data) + _gdk_device_wintab_translate_axes (device, window, axes, NULL, NULL); +} + +static void +gdk_device_wintab_set_window_cursor (GdkDevice *device, + GdkWindow *window, + GdkCursor *cursor) +{ +} + +static void +gdk_device_wintab_warp (GdkDevice *device, + GdkScreen *screen, + gint x, + gint y) +{ +} + +static gboolean +gdk_device_wintab_query_state (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, + gint *root_x, + gint *root_y, + gint *win_x, + gint *win_y, + GdkModifierType *mask) +{ + return FALSE; +} + +static GdkGrabStatus +gdk_device_wintab_grab (GdkDevice *device, + GdkWindow *window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time_) +{ + return GDK_GRAB_SUCCESS; +} + +static void +gdk_device_wintab_ungrab (GdkDevice *device, + guint32 time_) +{ +} + +static GdkWindow * +gdk_device_wintab_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel) +{ + return NULL; +} + +static void +input_info_free (GdkWindowInputInfo *info) +{ + g_hash_table_destroy (info->device_events); + g_free (info); +} + +static void +gdk_device_wintab_select_window_events (GdkDevice *device, + GdkWindow *window, + GdkEventMask event_mask) +{ + GdkWindowInputInfo *info; + + info = g_object_get_qdata (G_OBJECT (window), + quark_window_input_info); + if (event_mask) + { + if (!info) + { + info = g_new0 (GdkWindowInputInfo, 1); + info->device_events = g_hash_table_new (NULL, NULL); + + g_object_set_qdata_full (G_OBJECT (window), + quark_window_input_info, + info, + (GDestroyNotify) input_info_free); + input_windows = g_slist_prepend (input_windows, window); + } + + g_hash_table_insert (info->device_events, device, + GUINT_TO_POINTER (event_mask)); + } + else if (info) + { + g_hash_table_remove (info->device_events, device); + + if (g_hash_table_size (info->device_events) == 0) + { + g_object_set_qdata (G_OBJECT (window), + quark_window_input_info, + NULL); + input_windows = g_slist_remove (input_windows, window); + } + } +} + +GdkEventMask +_gdk_device_wintab_get_events (GdkDeviceWintab *device, + GdkWindow *window) +{ + GdkWindowInputInfo *info; + + info = g_object_get_qdata (G_OBJECT (window), + quark_window_input_info); + + if (!info) + return 0; + + return GPOINTER_TO_UINT (g_hash_table_lookup (info->device_events, device)); +} + +gboolean +_gdk_device_wintab_get_window_coords (GdkWindow *window, + gdouble *root_x, + gdouble *root_y) +{ + GdkWindowInputInfo *info; + + info = g_object_get_qdata (G_OBJECT (window), + quark_window_input_info); + + if (!info) + return FALSE; + + *root_x = info->root_x; + *root_y = info->root_y; + + return TRUE; +} + +void +_gdk_device_wintab_update_window_coords (GdkWindow *window) +{ + GdkWindowInputInfo *info; + gint root_x, root_y; + + info = g_object_get_qdata (G_OBJECT (window), + quark_window_input_info); + + g_return_if_fail (info != NULL); + + gdk_window_get_origin (window, &root_x, &root_y); + info->root_x = (gdouble) root_x; + info->root_y = (gdouble) root_y; +} + +void +_gdk_device_wintab_translate_axes (GdkDeviceWintab *device_wintab, + GdkWindow *window, + gdouble *axes, + gdouble *x, + gdouble *y) +{ + GdkDevice *device; + GdkWindow *impl_window; + gdouble root_x, root_y; + gdouble temp_x, temp_y; + gint i; + + device = GDK_DEVICE (device_wintab); + impl_window = _gdk_window_get_impl_window (window); + temp_x = temp_y = 0; + + if (!_gdk_device_wintab_get_window_coords (impl_window, &root_x, &root_y)) + return; + + for (i = 0; i < device->num_axes; i++) + { + GdkAxisUse use; + + use = _gdk_device_get_axis_use (device, i); + + switch (use) + { + case GDK_AXIS_X: + case GDK_AXIS_Y: + if (gdk_device_get_mode (device) == GDK_MODE_WINDOW) + _gdk_device_translate_window_coord (device, window, i, + device_wintab->last_axis_data[i], + &axes[i]); + else + _gdk_device_translate_screen_coord (device, window, + root_x, root_y, i, + device_wintab->last_axis_data[i], + &axes[i]); + if (use == GDK_AXIS_X) + temp_x = axes[i]; + else if (use == GDK_AXIS_Y) + temp_y = axes[i]; + + break; + default: + _gdk_device_translate_axis (device, i, + device_wintab->last_axis_data[i], + &axes[i]); + break; + } + } + + if (x) + *x = temp_x; + + if (y) + *y = temp_y; +} + +void +_gdk_input_check_extension_events (GdkDevice *device) +{ + GSList *l; + + if (!GDK_IS_DEVICE_WINTAB (device)) + return; + + for (l = input_windows; l; l = l->next) + { + GdkWindowObject *window_private; + GdkEventMask event_mask = 0; + + window_private = l->data; + + if (gdk_device_get_mode (device) != GDK_MODE_DISABLED) + event_mask = window_private->extension_events; + + gdk_window_set_device_events (GDK_WINDOW (window_private), + device, event_mask); + } +} |