diff options
Diffstat (limited to 'gdk/win32')
-rw-r--r-- | gdk/win32/Makefile.am | 2 | ||||
-rw-r--r-- | gdk/win32/gdkdevice-virtual.c | 429 | ||||
-rw-r--r-- | gdk/win32/gdkdevice-virtual.h | 54 | ||||
-rw-r--r-- | gdk/win32/gdkdevice-win32.c | 127 | ||||
-rw-r--r-- | gdk/win32/gdkdevice-wintab.c | 209 | ||||
-rw-r--r-- | gdk/win32/gdkdevice-wintab.h | 9 | ||||
-rw-r--r-- | gdk/win32/gdkdevicemanager-win32.c | 261 | ||||
-rw-r--r-- | gdk/win32/gdkdevicemanager-win32.h | 4 | ||||
-rw-r--r-- | gdk/win32/gdkevents-win32.c | 80 | ||||
-rw-r--r-- | gdk/win32/gdkinput.c | 2 |
10 files changed, 779 insertions, 398 deletions
diff --git a/gdk/win32/Makefile.am b/gdk/win32/Makefile.am index 7a4c1334b8..492e1c55d9 100644 --- a/gdk/win32/Makefile.am +++ b/gdk/win32/Makefile.am @@ -29,6 +29,8 @@ libgdk_win32_la_SOURCES = \ gdkcursor-win32.c \ gdkdevicemanager-win32.c \ gdkdevicemanager-win32.h \ + gdkdevice-virtual.c \ + gdkdevice-virtual.h \ gdkdevice-win32.c \ gdkdevice-win32.h \ gdkdevice-wintab.c \ diff --git a/gdk/win32/gdkdevice-virtual.c b/gdk/win32/gdkdevice-virtual.c new file mode 100644 index 0000000000..3a779dc5b2 --- /dev/null +++ b/gdk/win32/gdkdevice-virtual.c @@ -0,0 +1,429 @@ +/* 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gdk/gdkwindow.h>
+
+#include <windowsx.h>
+#include <objbase.h>
+
+#include "gdkdisplayprivate.h"
+#include "gdkdevice-virtual.h"
+#include "gdkwin32.h"
+
+static gboolean gdk_device_virtual_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ gint *n_events);
+static void gdk_device_virtual_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask);
+static void gdk_device_virtual_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor);
+static void gdk_device_virtual_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y);
+static void gdk_device_virtual_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_virtual_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_);
+static void gdk_device_virtual_ungrab (GdkDevice *device,
+ guint32 time_);
+static GdkWindow * gdk_device_virtual_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel);
+static void gdk_device_virtual_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask);
+
+
+G_DEFINE_TYPE (GdkDeviceVirtual, gdk_device_virtual, GDK_TYPE_DEVICE)
+
+static void
+gdk_device_virtual_class_init (GdkDeviceVirtualClass *klass)
+{
+ GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
+
+ device_class->get_history = gdk_device_virtual_get_history;
+ device_class->get_state = gdk_device_virtual_get_state;
+ device_class->set_window_cursor = gdk_device_virtual_set_window_cursor;
+ device_class->warp = gdk_device_virtual_warp;
+ device_class->query_state = gdk_device_virtual_query_state;
+ device_class->grab = gdk_device_virtual_grab;
+ device_class->ungrab = gdk_device_virtual_ungrab;
+ device_class->window_at_position = gdk_device_virtual_window_at_position;
+ device_class->select_window_events = gdk_device_virtual_select_window_events;
+}
+
+static void
+gdk_device_virtual_init (GdkDeviceVirtual *device_virtual)
+{
+ GdkDevice *device;
+
+ device = GDK_DEVICE (device_virtual);
+
+}
+
+void
+_gdk_device_virtual_set_active (GdkDevice *device,
+ GdkDevice *new_active)
+{
+ GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
+ int n_axes, i;
+ GdkAtom label_atom;
+ GdkAxisUse use;
+ gdouble min_value, max_value, resolution;
+
+ if (virtual->active_device == new_active)
+ return;
+
+ virtual->active_device = new_active;
+
+ if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
+ {
+ _gdk_device_reset_axes (device);
+ n_axes = gdk_device_get_n_axes (new_active);
+ for (i = 0; i < n_axes; i++)
+ {
+ _gdk_device_get_axis_info (new_active, i,
+ &label_atom, &use,
+ &min_value, &max_value, &resolution);
+ _gdk_device_add_axis (device,
+ label_atom, use,
+ min_value, max_value, resolution);
+ }
+ }
+
+ g_signal_emit_by_name (G_OBJECT (device), "changed");
+}
+
+static gboolean
+gdk_device_virtual_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ gint *n_events)
+{
+ /* History is only per slave device */
+ return FALSE;
+}
+
+static void
+gdk_device_virtual_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask)
+{
+ GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
+ GdkDevice *active = virtual->active_device;
+
+ GDK_DEVICE_GET_CLASS (active)->get_state (active,
+ window, axes, mask);
+}
+
+static void
+gdk_device_virtual_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor)
+{
+ GdkWin32Cursor *cursor_private;
+ GdkWindow *parent_window;
+ GdkWindowImplWin32 *impl;
+ HCURSOR hcursor;
+ HCURSOR hprevcursor;
+
+ impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ cursor_private = (GdkWin32Cursor*) cursor;
+
+ hprevcursor = impl->hcursor;
+
+ if (!cursor)
+ hcursor = NULL;
+ else
+ hcursor = cursor_private->hcursor;
+
+ if (hcursor != NULL)
+ {
+ /* If the pointer is over our window, set new cursor */
+ GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
+
+ if (curr_window == window ||
+ (curr_window && window == gdk_window_get_toplevel (curr_window)))
+ SetCursor (hcursor);
+ else
+ {
+ /* Climb up the tree and find whether our window is the
+ * first ancestor that has cursor defined, and if so, set
+ * new cursor.
+ */
+ while (curr_window && curr_window->impl &&
+ !GDK_WINDOW_IMPL_WIN32 (curr_window->impl)->hcursor)
+ {
+ curr_window = curr_window->parent;
+ if (curr_window == GDK_WINDOW (window))
+ {
+ SetCursor (hcursor);
+ break;
+ }
+ }
+ }
+ }
+
+ /* Unset the previous cursor: Need to make sure it's no longer in
+ * use before we destroy it, in case we're not over our window but
+ * the cursor is still set to our old one.
+ */
+ if (hprevcursor != NULL &&
+ GetCursor () == hprevcursor)
+ {
+ /* Look for a suitable cursor to use instead */
+ hcursor = NULL;
+ parent_window = GDK_WINDOW (window)->parent;
+
+ while (hcursor == NULL)
+ {
+ if (parent_window)
+ {
+ impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
+ hcursor = impl->hcursor;
+ parent_window = parent_window->parent;
+ }
+ else
+ hcursor = LoadCursor (NULL, IDC_ARROW);
+ }
+
+ SetCursor (hcursor);
+ }
+}
+
+static void
+gdk_device_virtual_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y)
+{
+ SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
+}
+
+static void
+gdk_device_virtual_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)
+{
+ GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
+
+ _gdk_device_query_state (virtual->active_device,
+ window, root_window, child_window,
+ root_x, root_y,
+ win_x, win_y,
+ mask);
+}
+
+static GdkGrabStatus
+gdk_device_virtual_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_)
+{
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ HCURSOR hcursor;
+ GdkWin32Cursor *cursor_private;
+
+ cursor_private = (GdkWin32Cursor*) cursor;
+
+ if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
+ {
+ if (!cursor)
+ hcursor = NULL;
+ else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL)
+ WIN32_API_FAILED ("CopyCursor");
+
+ if (_gdk_win32_grab_cursor != NULL)
+ {
+ if (GetCursor () == _gdk_win32_grab_cursor)
+ SetCursor (NULL);
+ DestroyCursor (_gdk_win32_grab_cursor);
+ }
+
+ _gdk_win32_grab_cursor = hcursor;
+
+ if (_gdk_win32_grab_cursor != NULL)
+ SetCursor (_gdk_win32_grab_cursor);
+ else if (impl->hcursor != NULL)
+ SetCursor (impl->hcursor);
+ else
+ SetCursor (LoadCursor (NULL, IDC_ARROW));
+
+ SetCapture (GDK_WINDOW_HWND (window));
+ }
+
+ return GDK_GRAB_SUCCESS;
+}
+
+static void
+gdk_device_virtual_ungrab (GdkDevice *device,
+ guint32 time_)
+{
+ GdkDeviceGrabInfo *info;
+ GdkDisplay *display;
+
+ display = gdk_device_get_display (device);
+ info = _gdk_display_get_last_device_grab (display, device);
+
+ if (info)
+ info->serial_end = 0;
+
+ if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
+ {
+ if (_gdk_win32_grab_cursor != NULL)
+ {
+ if (GetCursor () == _gdk_win32_grab_cursor)
+ SetCursor (NULL);
+ DestroyCursor (_gdk_win32_grab_cursor);
+ }
+ _gdk_win32_grab_cursor = NULL;
+
+ ReleaseCapture ();
+ }
+
+ _gdk_display_device_grab_update (display, device, NULL, 0);
+}
+
+static void
+screen_to_client (HWND hwnd, POINT screen_pt, POINT *client_pt)
+{
+ *client_pt = screen_pt;
+ ScreenToClient (hwnd, client_pt);
+}
+
+static GdkWindow *
+gdk_device_virtual_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel)
+{
+ GdkWindow *window = NULL;
+ POINT screen_pt, client_pt;
+ HWND hwnd, hwndc;
+ RECT rect;
+
+ GetCursorPos (&screen_pt);
+
+ if (get_toplevel)
+ {
+ /* Only consider visible children of the desktop to avoid the various
+ * non-visible windows you often find on a running Windows box. These
+ * might overlap our windows and cause our walk to fail. As we assume
+ * WindowFromPoint() can find our windows, we follow similar logic
+ * here, and ignore invisible and disabled windows.
+ */
+ hwnd = GetDesktopWindow ();
+ do {
+ window = gdk_win32_handle_table_lookup (hwnd);
+
+ if (window != NULL &&
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT &&
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
+ break;
+
+ screen_to_client (hwnd, screen_pt, &client_pt);
+ hwndc = ChildWindowFromPointEx (hwnd, client_pt, CWP_SKIPDISABLED |
+ CWP_SKIPINVISIBLE);
+
+ /* Verify that we're really inside the client area of the window */
+ if (hwndc != hwnd)
+ {
+ GetClientRect (hwndc, &rect);
+ screen_to_client (hwndc, screen_pt, &client_pt);
+ if (!PtInRect (&rect, client_pt))
+ hwndc = hwnd;
+ }
+
+ } while (hwndc != hwnd && (hwnd = hwndc, 1));
+
+ }
+ else
+ {
+ hwnd = WindowFromPoint (screen_pt);
+
+ /* Verify that we're really inside the client area of the window */
+ GetClientRect (hwnd, &rect);
+ screen_to_client (hwnd, screen_pt, &client_pt);
+ if (!PtInRect (&rect, client_pt))
+ hwnd = NULL;
+
+ /* If we didn't hit any window at that point, return the desktop */
+ if (hwnd == NULL)
+ {
+ if (win_x)
+ *win_x = screen_pt.x + _gdk_offset_x;
+ if (win_y)
+ *win_y = screen_pt.y + _gdk_offset_y;
+ return _gdk_root;
+ }
+
+ window = gdk_win32_handle_table_lookup (hwnd);
+ }
+
+ if (window && (win_x || win_y))
+ {
+ if (win_x)
+ *win_x = client_pt.x;
+ if (win_y)
+ *win_y = client_pt.y;
+ }
+
+ return window;
+}
+
+static void
+gdk_device_virtual_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask)
+{
+}
diff --git a/gdk/win32/gdkdevice-virtual.h b/gdk/win32/gdkdevice-virtual.h new file mode 100644 index 0000000000..e552a5d2fc --- /dev/null +++ b/gdk/win32/gdkdevice-virtual.h @@ -0,0 +1,54 @@ +/* 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GDK_DEVICE_VIRTUAL_H__
+#define __GDK_DEVICE_VIRTUAL_H__
+
+#include <gdk/gdkdeviceprivate.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_DEVICE_VIRTUAL (gdk_device_virtual_get_type ())
+#define GDK_DEVICE_VIRTUAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_VIRTUAL, GdkDeviceVirtual))
+#define GDK_DEVICE_VIRTUAL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_VIRTUAL, GdkDeviceVirtualClass))
+#define GDK_IS_DEVICE_VIRTUAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_VIRTUAL))
+#define GDK_IS_DEVICE_VIRTUAL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_VIRTUAL))
+#define GDK_DEVICE_VIRTUAL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_VIRTUAL, GdkDeviceVirtualClass))
+
+typedef struct _GdkDeviceVirtual GdkDeviceVirtual;
+typedef struct _GdkDeviceVirtualClass GdkDeviceVirtualClass;
+
+struct _GdkDeviceVirtual
+{
+ GdkDevice parent_instance;
+ GdkDevice *active_device;
+};
+
+struct _GdkDeviceVirtualClass
+{
+ GdkDeviceClass parent_class;
+};
+
+GType gdk_device_virtual_get_type (void) G_GNUC_CONST;
+
+void _gdk_device_virtual_set_active (GdkDevice *device,
+ GdkDevice *new_active);
+
+
+G_END_DECLS
+
+#endif /* __GDK_DEVICE_VIRTUAL_H__ */
diff --git a/gdk/win32/gdkdevice-win32.c b/gdk/win32/gdkdevice-win32.c index 1cc1797ce3..042ef349a2 100644 --- a/gdk/win32/gdkdevice-win32.c +++ b/gdk/win32/gdkdevice-win32.c @@ -133,74 +133,6 @@ gdk_device_win32_set_window_cursor (GdkDevice *device, GdkWindow *window, GdkCursor *cursor) { - GdkWin32Cursor *cursor_private; - GdkWindow *parent_window; - GdkWindowImplWin32 *impl; - HCURSOR hcursor; - HCURSOR hprevcursor; - - impl = GDK_WINDOW_IMPL_WIN32 (window->impl); - cursor_private = (GdkWin32Cursor*) cursor; - - hprevcursor = impl->hcursor; - - if (!cursor) - hcursor = NULL; - else - hcursor = cursor_private->hcursor; - - if (hcursor != NULL) - { - /* If the pointer is over our window, set new cursor */ - GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL); - - if (curr_window == window || - (curr_window && window == gdk_window_get_toplevel (curr_window))) - SetCursor (hcursor); - else - { - /* Climb up the tree and find whether our window is the - * first ancestor that has cursor defined, and if so, set - * new cursor. - */ - while (curr_window && curr_window->impl && - !GDK_WINDOW_IMPL_WIN32 (curr_window->impl)->hcursor) - { - curr_window = curr_window->parent; - if (curr_window == GDK_WINDOW (window)) - { - SetCursor (hcursor); - break; - } - } - } - } - - /* Unset the previous cursor: Need to make sure it's no longer in - * use before we destroy it, in case we're not over our window but - * the cursor is still set to our old one. - */ - if (hprevcursor != NULL && - GetCursor () == hprevcursor) - { - /* Look for a suitable cursor to use instead */ - hcursor = NULL; - parent_window = GDK_WINDOW (window)->parent; - - while (hcursor == NULL) - { - if (parent_window) - { - impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl); - hcursor = impl->hcursor; - parent_window = parent_window->parent; - } - else - hcursor = LoadCursor (NULL, IDC_ARROW); - } - - SetCursor (hcursor); - } } static void @@ -209,7 +141,6 @@ gdk_device_win32_warp (GdkDevice *device, gint x, gint y) { - SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y); } static GdkModifierType @@ -309,68 +240,14 @@ gdk_device_win32_grab (GdkDevice *device, GdkCursor *cursor, guint32 time_) { - GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl); - HCURSOR hcursor; - GdkWin32Cursor *cursor_private; - - cursor_private = (GdkWin32Cursor*) cursor; - - if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD) - { - if (!cursor) - hcursor = NULL; - else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL) - WIN32_API_FAILED ("CopyCursor"); - - if (_gdk_win32_grab_cursor != NULL) - { - if (GetCursor () == _gdk_win32_grab_cursor) - SetCursor (NULL); - DestroyCursor (_gdk_win32_grab_cursor); - } - - _gdk_win32_grab_cursor = hcursor; - - if (_gdk_win32_grab_cursor != NULL) - SetCursor (_gdk_win32_grab_cursor); - else if (impl->hcursor != NULL) - SetCursor (impl->hcursor); - else - SetCursor (LoadCursor (NULL, IDC_ARROW)); - - SetCapture (GDK_WINDOW_HWND (window)); - } - - return GDK_GRAB_SUCCESS; + /* No support for grabbing the slave atm */ + return GDK_GRAB_NOT_VIEWABLE; } static void gdk_device_win32_ungrab (GdkDevice *device, guint32 time_) { - GdkDeviceGrabInfo *info; - GdkDisplay *display; - - display = gdk_device_get_display (device); - info = _gdk_display_get_last_device_grab (display, device); - - if (info) - info->serial_end = 0; - - if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD) - { - if (_gdk_win32_grab_cursor != NULL) - { - if (GetCursor () == _gdk_win32_grab_cursor) - SetCursor (NULL); - DestroyCursor (_gdk_win32_grab_cursor); - } - _gdk_win32_grab_cursor = NULL; - - ReleaseCapture (); - } - - _gdk_display_device_grab_update (display, device, NULL, 0); } static void diff --git a/gdk/win32/gdkdevice-wintab.c b/gdk/win32/gdkdevice-wintab.c index 0a4474229d..6af23bad43 100644 --- a/gdk/win32/gdkdevice-wintab.c +++ b/gdk/win32/gdkdevice-wintab.c @@ -25,16 +25,6 @@ #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, @@ -96,8 +86,6 @@ gdk_device_wintab_class_init (GdkDeviceWintabClass *klass) 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 @@ -119,6 +107,32 @@ gdk_device_wintab_get_history (GdkDevice *device, return FALSE; } +static GdkModifierType +get_current_mask (void) +{ + GdkModifierType mask; + BYTE kbd[256]; + + GetKeyboardState (kbd); + mask = 0; + if (kbd[VK_SHIFT] & 0x80) + mask |= GDK_SHIFT_MASK; + if (kbd[VK_CAPITAL] & 0x80) + mask |= GDK_LOCK_MASK; + if (kbd[VK_CONTROL] & 0x80) + mask |= GDK_CONTROL_MASK; + if (kbd[VK_MENU] & 0x80) + mask |= GDK_MOD1_MASK; + if (kbd[VK_LBUTTON] & 0x80) + mask |= GDK_BUTTON1_MASK; + if (kbd[VK_MBUTTON] & 0x80) + mask |= GDK_BUTTON2_MASK; + if (kbd[VK_RBUTTON] & 0x80) + mask |= GDK_BUTTON3_MASK; + + return mask; +} + static void gdk_device_wintab_get_state (GdkDevice *device, GdkWindow *window, @@ -134,7 +148,7 @@ gdk_device_wintab_get_state (GdkDevice *device, * second, the info should be fairly up to date */ if (mask) { - gdk_window_get_pointer (window, NULL, NULL, mask); + *mask = get_current_mask (); *mask &= 0xFF; /* Mask away core pointer buttons */ *mask |= ((device_wintab->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK @@ -142,7 +156,7 @@ gdk_device_wintab_get_state (GdkDevice *device, | GDK_BUTTON5_MASK)); } - if (device_wintab->last_axis_data) + if (axes && device_wintab->last_axis_data) _gdk_device_wintab_translate_axes (device_wintab, window, axes, NULL, NULL); } @@ -172,7 +186,66 @@ gdk_device_wintab_query_state (GdkDevice *device, gint *win_y, GdkModifierType *mask) { - g_warning ("query_state unimplemented for wintab devices. Expect bad things."); + GdkDeviceWintab *device_wintab; + POINT point; + HWND hwnd, hwndc; + + device_wintab = GDK_DEVICE_WINTAB (device); + + hwnd = GDK_WINDOW_HWND (window); + GetCursorPos (&point); + + if (root_x) + *root_x = point.x; + + if (root_y) + *root_y = point.y; + + ScreenToClient (hwnd, &point); + + if (win_x) + *win_x = point.x; + + if (win_y) + *win_y = point.y; + + if (window == _gdk_root) + { + if (win_x) + *win_x += _gdk_offset_x; + + if (win_y) + *win_y += _gdk_offset_y; + } + + if (child_window) + { + hwndc = ChildWindowFromPoint (hwnd, point); + + if (hwndc && hwndc != hwnd) + *child_window = gdk_win32_handle_table_lookup (hwndc); + else + *child_window = NULL; /* Direct child unknown to gdk */ + } + + if (root_window) + { + GdkScreen *screen; + + screen = gdk_window_get_screen (window); + *root_window = gdk_screen_get_root_window (screen); + } + + if (mask) + { + *mask = get_current_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)); + + } } static GdkGrabStatus @@ -204,111 +277,10 @@ gdk_device_wintab_window_at_position (GdkDevice *device, } 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); - } - } -} - -gboolean -_gdk_device_wintab_wants_events (GdkWindow *window) -{ - GdkWindowInputInfo *info; - - info = g_object_get_qdata (G_OBJECT (window), - quark_window_input_info); - - return info != NULL; -} - -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 @@ -320,7 +292,7 @@ _gdk_device_wintab_translate_axes (GdkDeviceWintab *device_wintab, { GdkDevice *device; GdkWindow *impl_window; - gdouble root_x, root_y; + gint root_x, root_y; gdouble temp_x, temp_y; gint i; @@ -328,8 +300,7 @@ _gdk_device_wintab_translate_axes (GdkDeviceWintab *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; + gdk_window_get_origin (impl_window, &root_x, &root_y); for (i = 0; i < gdk_device_get_n_axes (device); i++) { diff --git a/gdk/win32/gdkdevice-wintab.h b/gdk/win32/gdkdevice-wintab.h index 987d8bf683..bba08ff125 100644 --- a/gdk/win32/gdkdevice-wintab.h +++ b/gdk/win32/gdkdevice-wintab.h @@ -39,6 +39,7 @@ struct _GdkDeviceWintab { GdkDevice parent_instance; + gboolean sends_core; gint *last_axis_data; gint button_state; @@ -59,14 +60,6 @@ struct _GdkDeviceWintabClass GType gdk_device_wintab_get_type (void) G_GNUC_CONST; -gboolean _gdk_device_wintab_wants_events (GdkWindow *window); -GdkEventMask _gdk_device_wintab_get_events (GdkDeviceWintab *device, - GdkWindow *window); -gboolean _gdk_device_wintab_get_window_coords (GdkWindow *window, - gdouble *root_x, - gdouble *root_y); -void _gdk_device_wintab_update_window_coords (GdkWindow *window); - void _gdk_device_wintab_translate_axes (GdkDeviceWintab *device, GdkWindow *window, gdouble *axes, diff --git a/gdk/win32/gdkdevicemanager-win32.c b/gdk/win32/gdkdevicemanager-win32.c index d51acbca92..4d26b24a81 100644 --- a/gdk/win32/gdkdevicemanager-win32.c +++ b/gdk/win32/gdkdevicemanager-win32.c @@ -27,6 +27,7 @@ #include "gdkdevicemanager-win32.h" #include "gdkdeviceprivate.h" #include "gdkdevice-win32.h" +#include "gdkdevice-virtual.h" #include "gdkdevice-wintab.h" #include "gdkdisplayprivate.h" @@ -38,18 +39,18 @@ #include <pktdef.h> #define DEBUG_WINTAB 1 /* Verbose debug messages enabled */ -#define PROXIMITY_OUT_DELAY 200 /* In milliseconds, see set_ignore_core */ #define TWOPI (2 * G_PI) static GList *wintab_contexts = NULL; static GdkWindow *wintab_window = NULL; -static guint ignore_core_timer = 0; extern gint _gdk_input_ignore_core; typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c); typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c); typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b); typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c); +typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b); +typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b); typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b); typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c); typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b); @@ -58,6 +59,8 @@ static t_WTInfoA p_WTInfoA; static t_WTInfoW p_WTInfoW; static t_WTEnable p_WTEnable; static t_WTOpenA p_WTOpenA; +static t_WTGetA p_WTGetA; +static t_WTSetA p_WTSetA; static t_WTOverlap p_WTOverlap; static t_WTPacket p_WTPacket; static t_WTQueueSizeSet p_WTQueueSizeSet; @@ -86,25 +89,31 @@ gdk_device_manager_win32_class_init (GdkDeviceManagerWin32Class *klass) } static GdkDevice * -create_core_pointer (GdkDeviceManager *device_manager) +create_pointer (GdkDeviceManager *device_manager, + GType g_type, + const char *name, + GdkDeviceType type) { - return g_object_new (GDK_TYPE_DEVICE_WIN32, - "name", "Core Pointer", - "type", GDK_DEVICE_TYPE_MASTER, + return g_object_new (g_type, + "name", name, + "type", type, "input-source", GDK_SOURCE_MOUSE, "input-mode", GDK_MODE_SCREEN, - "has-cursor", TRUE, + "has-cursor", type == GDK_DEVICE_TYPE_MASTER, "display", _gdk_display, "device-manager", device_manager, NULL); } static GdkDevice * -create_core_keyboard (GdkDeviceManager *device_manager) +create_keyboard (GdkDeviceManager *device_manager, + GType g_type, + const char *name, + GdkDeviceType type) { - return g_object_new (GDK_TYPE_DEVICE_WIN32, - "name", "Core Keyboard", - "type", GDK_DEVICE_TYPE_MASTER, + return g_object_new (g_type, + "name", name, + "type", type, "input-source", GDK_SOURCE_KEYBOARD, "input-mode", GDK_MODE_SCREEN, "has-cursor", FALSE, @@ -419,6 +428,10 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager) return; if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL) return; + if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL) + return; + if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL) + return; if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL) return; if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL) @@ -496,7 +509,7 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager) #if DEBUG_WINTAB GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc))); #endif - lc.lcOptions |= CXO_MESSAGES; + lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES; lc.lcStatus = 0; lc.lcMsgBase = WT_DEFBASE; lc.lcPktRate = 0; @@ -506,8 +519,8 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager) lc.lcBtnUpMask = lc.lcBtnDnMask = ~0; lc.lcOutOrgX = axis_x.axMin; lc.lcOutOrgY = axis_y.axMin; - lc.lcOutExtX = axis_x.axMax - axis_x.axMin; - lc.lcOutExtY = axis_y.axMax - axis_y.axMin; + lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1; + lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1; lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */ #if DEBUG_WINTAB GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix), @@ -537,7 +550,7 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager) * with a smaller queue size. */ GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n")); - for (i = 32; i >= 1; i >>= 1) + for (i = 128; i >= 1; i >>= 1) { if ((*p_WTQueueSizeSet) (*hctx, i)) { @@ -575,14 +588,21 @@ _gdk_input_wintab_init_check (GdkDeviceManager *_device_manager) device = g_object_new (GDK_TYPE_DEVICE_WINTAB, "name", device_name, - "type", GDK_DEVICE_TYPE_SLAVE, + "type", GDK_DEVICE_TYPE_FLOATING, "input-source", GDK_SOURCE_PEN, "input-mode", GDK_MODE_SCREEN, - "has-cursor", FALSE, + "has-cursor", lc.lcOptions & CXO_SYSTEM, "display", _gdk_display, "device-manager", device_manager, NULL); + device->sends_core = lc.lcOptions & CXO_SYSTEM; + if (device->sends_core) + { + _gdk_device_set_associated_device (device_manager->system_pointer, GDK_DEVICE (device)); + _gdk_device_add_slave (device_manager->core_pointer, GDK_DEVICE (device)); + } + g_free (csrname_utf8); device->hctx = *hctx; @@ -684,8 +704,35 @@ gdk_device_manager_win32_constructed (GObject *object) GdkDeviceManagerWin32 *device_manager; device_manager = GDK_DEVICE_MANAGER_WIN32 (object); - device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager)); - device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager)); + device_manager->core_pointer = + create_pointer (GDK_DEVICE_MANAGER (device_manager), + GDK_TYPE_DEVICE_VIRTUAL, + "Virtual Core Pointer", + GDK_DEVICE_TYPE_MASTER); + device_manager->system_pointer = + create_pointer (GDK_DEVICE_MANAGER (device_manager), + GDK_TYPE_DEVICE_WIN32, + "System Aggregated Pointer", + GDK_DEVICE_TYPE_SLAVE); + _gdk_device_virtual_set_active (device_manager->core_pointer, + device_manager->system_pointer); + _gdk_device_set_associated_device (device_manager->system_pointer, device_manager->core_pointer); + _gdk_device_add_slave (device_manager->core_pointer, device_manager->system_pointer); + + device_manager->core_keyboard = + create_keyboard (GDK_DEVICE_MANAGER (device_manager), + GDK_TYPE_DEVICE_VIRTUAL, + "Virtual Core Keyboard", + GDK_DEVICE_TYPE_MASTER); + device_manager->system_keyboard = + create_keyboard (GDK_DEVICE_MANAGER (device_manager), + GDK_TYPE_DEVICE_WIN32, + "System Aggregated Keyboard", + GDK_DEVICE_TYPE_SLAVE); + _gdk_device_virtual_set_active (device_manager->core_keyboard, + device_manager->system_keyboard); + _gdk_device_set_associated_device (device_manager->system_keyboard, device_manager->core_keyboard); + _gdk_device_add_slave (device_manager->core_keyboard, device_manager->system_keyboard); _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard); _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer); @@ -696,7 +743,7 @@ gdk_device_manager_win32_list_devices (GdkDeviceManager *device_manager, GdkDeviceType type) { GdkDeviceManagerWin32 *device_manager_win32; - GList *devices = NULL; + GList *devices = NULL, *l; device_manager_win32 = (GdkDeviceManagerWin32 *) device_manager; @@ -705,10 +752,24 @@ gdk_device_manager_win32_list_devices (GdkDeviceManager *device_manager, devices = g_list_prepend (devices, device_manager_win32->core_keyboard); devices = g_list_prepend (devices, device_manager_win32->core_pointer); } - else if (type == GDK_DEVICE_TYPE_FLOATING) - devices = g_list_copy (device_manager_win32->wintab_devices); + else + { + if (type == GDK_DEVICE_TYPE_SLAVE) + { + devices = g_list_prepend (devices, device_manager_win32->system_keyboard); + devices = g_list_prepend (devices, device_manager_win32->system_pointer); + } + + for (l = device_manager_win32->wintab_devices; l != NULL; l = l->next) + { + GdkDevice *device = l->data; + + if (gdk_device_get_device_type (device) == type) + devices = g_list_prepend (devices, device); + } + } - return devices; + return g_list_reverse (devices); } static GdkDevice * @@ -791,41 +852,6 @@ get_modifier_key_state (void) return state; } -static gboolean -ignore_core_timefunc (gpointer data) -{ - /* The delay has passed */ - _gdk_input_ignore_core = FALSE; - ignore_core_timer = 0; - - return FALSE; /* remove timeout */ -} - -/* - * Set or unset the _gdk_input_ignore_core variable that tells GDK - * to ignore events for the core pointer when the tablet is in proximity - * The unsetting is delayed slightly so that if a tablet event arrives - * just after proximity out, it does not cause a core pointer event - * which e.g. causes GIMP to switch tools. - */ -static void -set_ignore_core (gboolean ignore) -{ - if (ignore) - { - _gdk_input_ignore_core = TRUE; - /* Remove any pending clear */ - if (ignore_core_timer) - { - g_source_remove (ignore_core_timer); - ignore_core_timer = 0; - } - } - else if (!ignore_core_timer) - ignore_core_timer = gdk_threads_add_timeout (PROXIMITY_OUT_DELAY, - ignore_core_timefunc, NULL); -} - static GdkDeviceWintab * _gdk_device_manager_find_wintab_device (HCTX hctx, UINT cursor) @@ -855,15 +881,16 @@ _gdk_input_other_event (GdkEvent *event, MSG *msg, GdkWindow *window) { + GdkDeviceManagerWin32 *device_manager; GdkDisplay *display; - GdkDeviceWintab *device = NULL; + GdkDeviceWintab *source_device = NULL; GdkDeviceGrabInfo *last_grab; GdkEventMask masktest; guint key_state; POINT pt; PACKET packet; - gdouble root_x, root_y; + gint root_x, root_y; gint num_axes; gint x, y; guint translated_buttons, button_diff, button_mask; @@ -878,6 +905,8 @@ _gdk_input_other_event (GdkEvent *event, return FALSE; } + device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (_gdk_display)); + window = gdk_window_at_pointer (&x, &y); if (window == NULL) window = _gdk_root; @@ -889,7 +918,7 @@ _gdk_input_other_event (GdkEvent *event, g_print ("_gdk_input_other_event: window=%p %+d%+d\n", GDK_WINDOW_HWND (window), x, y)); - if (msg->message == WT_PACKET) + if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE) { if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet)) return FALSE; @@ -907,14 +936,14 @@ _gdk_input_other_event (GdkEvent *event, return FALSE; } - if ((device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam, - packet.pkCursor)) == NULL) + if ((source_device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam, + packet.pkCursor)) == NULL) return FALSE; - if (gdk_device_get_mode (GDK_DEVICE (device)) == GDK_MODE_DISABLED) + if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED) return FALSE; - last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (device)); + last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (source_device)); if (last_grab && last_grab->window) { @@ -930,29 +959,29 @@ _gdk_input_other_event (GdkEvent *event, } num_axes = 0; - if (device->pktdata & PK_X) - device->last_axis_data[num_axes++] = packet.pkX; - if (device->pktdata & PK_Y) - device->last_axis_data[num_axes++] = packet.pkY; - if (device->pktdata & PK_NORMAL_PRESSURE) - device->last_axis_data[num_axes++] = packet.pkNormalPressure; - if (device->pktdata & PK_ORIENTATION) + if (source_device->pktdata & PK_X) + source_device->last_axis_data[num_axes++] = packet.pkX; + if (source_device->pktdata & PK_Y) + source_device->last_axis_data[num_axes++] = packet.pkY; + if (source_device->pktdata & PK_NORMAL_PRESSURE) + source_device->last_axis_data[num_axes++] = packet.pkNormalPressure; + if (source_device->pktdata & PK_ORIENTATION) { - decode_tilt (device->last_axis_data + num_axes, - device->orientation_axes, &packet); + decode_tilt (source_device->last_axis_data + num_axes, + source_device->orientation_axes, &packet); num_axes += 2; } translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07); - if (translated_buttons != device->button_state) + if (translated_buttons != source_device->button_state) { /* At least one button has changed state so produce a button event * If more than one button has changed state (unlikely), * just care about the first and act on the next the next time * we get a packet */ - button_diff = translated_buttons ^ device->button_state; + button_diff = translated_buttons ^ source_device->button_state; /* Gdk buttons are numbered 1.. */ event->button.button = 1; @@ -977,39 +1006,33 @@ _gdk_input_other_event (GdkEvent *event, event->any.type = GDK_BUTTON_PRESS; masktest = GDK_BUTTON_PRESS_MASK; } - device->button_state ^= button_mask; + source_device->button_state ^= button_mask; } else { event->any.type = GDK_MOTION_NOTIFY; masktest = GDK_POINTER_MOTION_MASK; - if (device->button_state & (1 << 0)) + if (source_device->button_state & (1 << 0)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK; - if (device->button_state & (1 << 1)) + if (source_device->button_state & (1 << 1)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK; - if (device->button_state & (1 << 2)) + if (source_device->button_state & (1 << 2)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK; } /* Now we can check if the window wants the event, and * propagate if necessary. */ - while (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0) + while ((gdk_window_get_device_events (window, GDK_DEVICE (source_device)) & masktest) == 0 && + (gdk_device_get_device_type (GDK_DEVICE (source_device)) == GDK_DEVICE_TYPE_SLAVE && + (gdk_window_get_events (window) & masktest) == 0)) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n")); - if (window->parent == GDK_WINDOW (_gdk_root)) + if (window->parent == GDK_WINDOW (_gdk_root) || + window->parent == NULL) return FALSE; - /* It is not good to propagate the extended events up to the parent - * if this window wants normal (not extended) motion/button events */ - if (window->event_mask & masktest) - { - GDK_NOTE (EVENTS_OR_INPUT, - g_print ("... wants ordinary event, ignoring this\n")); - return FALSE; - } - pt.x = x; pt.y = y; ClientToScreen (GDK_WINDOW_HWND (window), &pt); @@ -1023,21 +1046,20 @@ _gdk_input_other_event (GdkEvent *event, GDK_WINDOW_HWND (window), x, y)); } - if (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0) - return FALSE; - event->any.window = window; key_state = get_modifier_key_state (); if (event->any.type == GDK_BUTTON_PRESS || event->any.type == GDK_BUTTON_RELEASE) { event->button.time = _gdk_win32_get_next_tick (msg->time); - gdk_event_set_device (event, GDK_DEVICE (device)); + if (source_device->sends_core) + gdk_event_set_device (event, device_manager->core_pointer); + gdk_event_set_source_device (event, GDK_DEVICE (source_device)); event->button.axes = g_new (gdouble, num_axes); - _gdk_device_wintab_get_window_coords (window, &root_x, &root_y); + gdk_window_get_origin (window, &root_x, &root_y); - _gdk_device_wintab_translate_axes (device, + _gdk_device_wintab_translate_axes (source_device, window, event->button.axes, &event->button.x, @@ -1047,7 +1069,7 @@ _gdk_input_other_event (GdkEvent *event, event->button.y_root = event->button.y + root_y; event->button.state = - key_state | ((device->button_state << 8) + key_state | ((source_device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); @@ -1063,12 +1085,13 @@ _gdk_input_other_event (GdkEvent *event, { event->motion.time = _gdk_win32_get_next_tick (msg->time); event->motion.is_hint = FALSE; - gdk_event_set_device (event, GDK_DEVICE (device)); + gdk_event_set_device (event, device_manager->core_pointer); + gdk_event_set_source_device (event, GDK_DEVICE (source_device)); event->motion.axes = g_new (gdouble, num_axes); - _gdk_device_wintab_get_window_coords (window, &root_x, &root_y); + gdk_window_get_origin (window, &root_x, &root_y); - _gdk_device_wintab_translate_axes (device, + _gdk_device_wintab_translate_axes (source_device, window, event->motion.axes, &event->motion.x, @@ -1078,7 +1101,7 @@ _gdk_input_other_event (GdkEvent *event, event->motion.y_root = event->motion.y + root_y; event->motion.state = - key_state | ((device->button_state << 8) + key_state | ((source_device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); @@ -1089,25 +1112,31 @@ _gdk_input_other_event (GdkEvent *event, } return TRUE; + case WT_CSRCHANGE: + if ((source_device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam, + packet.pkCursor)) == NULL) + return FALSE; + + if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED) + return FALSE; + + if (source_device->sends_core) + { + _gdk_device_virtual_set_active (device_manager->core_pointer, GDK_DEVICE (source_device)); + _gdk_input_ignore_core = TRUE; + } + + return FALSE; + case WT_PROXIMITY: if (LOWORD (msg->lParam) == 0) { - event->proximity.type = GDK_PROXIMITY_OUT; - set_ignore_core (FALSE); + _gdk_input_ignore_core = FALSE; + _gdk_device_virtual_set_active (device_manager->core_pointer, + device_manager->system_pointer); } - else - { - event->proximity.type = GDK_PROXIMITY_IN; - set_ignore_core (TRUE); - } - event->proximity.time = _gdk_win32_get_next_tick (msg->time); - gdk_event_set_device (event, GDK_DEVICE (device)); - GDK_NOTE (EVENTS_OR_INPUT, - g_print ("WINTAB proximity %s\n", - (event->proximity.type == GDK_PROXIMITY_IN ? - "in" : "out"))); - return TRUE; + return FALSE; } return FALSE; diff --git a/gdk/win32/gdkdevicemanager-win32.h b/gdk/win32/gdkdevicemanager-win32.h index 66f847fb68..2fbea0682a 100644 --- a/gdk/win32/gdkdevicemanager-win32.h +++ b/gdk/win32/gdkdevicemanager-win32.h @@ -35,8 +35,12 @@ typedef struct _GdkDeviceManagerWin32Class GdkDeviceManagerWin32Class; struct _GdkDeviceManagerWin32 { GdkDeviceManager parent_object; + /* Master Devices */ GdkDevice *core_pointer; GdkDevice *core_keyboard; + /* Fake slave devices */ + GdkDevice *system_pointer; + GdkDevice *system_keyboard; GList *wintab_devices; }; diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index fc01381f6c..2bc7c12477 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -192,14 +192,17 @@ generate_focus_event (GdkDeviceManager *device_manager, gboolean in) { GdkDevice *device; + GdkDevice *source_device; GdkEvent *event; device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard; + source_device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->system_keyboard; event = gdk_event_new (GDK_FOCUS_CHANGE); event->focus_change.window = window; event->focus_change.in = in; gdk_event_set_device (event, device); + gdk_event_set_source_device (event, source_device); _gdk_win32_append_event (event); } @@ -212,11 +215,18 @@ generate_grab_broken_event (GdkDeviceManager *device_manager, { GdkEvent *event = gdk_event_new (GDK_GRAB_BROKEN); GdkDevice *device; + GdkDevice *source_device; if (keyboard) - device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard; + { + device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard; + source_device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->system_keyboard; + } else - device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer; + { + device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer; + source_device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->system_pointer; + } event->grab_broken.window = window; event->grab_broken.send_event = 0; @@ -224,6 +234,7 @@ generate_grab_broken_event (GdkDeviceManager *device_manager, event->grab_broken.implicit = FALSE; event->grab_broken.grab_window = grab_window; gdk_event_set_device (event, device); + gdk_event_set_source_device (event, device); _gdk_win32_append_event (event); } @@ -1130,13 +1141,10 @@ send_crossing_event (GdkDisplay *display, event->crossing.detail = notify_type; event->crossing.focus = FALSE; event->crossing.state = mask; - gdk_event_set_device (event, _gdk_display->core_pointer); + gdk_event_set_device (event, device_manager->core_pointer); + gdk_event_set_source_device (event, device_manager->system_pointer); _gdk_win32_append_event (event); - - if (type == GDK_ENTER_NOTIFY && - _gdk_device_wintab_wants_events (window)) - _gdk_device_wintab_update_window_coords (window); } static GdkWindow * @@ -1655,6 +1663,12 @@ generate_button_event (GdkEventType type, MSG *msg) { GdkEvent *event = gdk_event_new (type); + GdkDeviceManagerWin32 *device_manager; + + if (_gdk_input_ignore_core) + return; + + device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (_gdk_display)); event->button.window = window; event->button.time = _gdk_win32_get_next_tick (msg->time); @@ -1665,7 +1679,8 @@ generate_button_event (GdkEventType type, event->button.axes = NULL; event->button.state = build_pointer_event_state (msg); event->button.button = button; - gdk_event_set_device (event, _gdk_display->core_pointer); + gdk_event_set_device (event, device_manager->core_pointer); + gdk_event_set_source_device (event, device_manager->system_pointer); _gdk_win32_append_event (event); } @@ -1841,6 +1856,7 @@ gdk_event_translate (MSG *msg, GdkWindow *orig_window, *new_window; GdkDeviceManager *device_manager; + GdkDeviceManagerWin32 *device_manager_win32; GdkDeviceGrabInfo *keyboard_grab = NULL; GdkDeviceGrabInfo *pointer_grab = NULL; @@ -1892,11 +1908,12 @@ gdk_event_translate (MSG *msg, } device_manager = gdk_display_get_device_manager (_gdk_display); + device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (device_manager); keyboard_grab = _gdk_display_get_last_device_grab (_gdk_display, - GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard); + device_manager_win32->core_keyboard); pointer_grab = _gdk_display_get_last_device_grab (_gdk_display, - GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer); + device_manager_win32->core_pointer); g_object_ref (window); @@ -2051,7 +2068,8 @@ gdk_event_translate (MSG *msg, event->key.string = NULL; event->key.length = 0; event->key.hardware_keycode = msg->wParam; - gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard); + gdk_event_set_device (event, device_manager_win32->core_keyboard); + gdk_event_set_source_device (event, device_manager_win32->system_keyboard); if (HIWORD (msg->lParam) & KF_EXTENDED) { switch (msg->wParam) @@ -2168,7 +2186,8 @@ gdk_event_translate (MSG *msg, /* Build a key press event */ event = gdk_event_new (GDK_KEY_PRESS); event->key.window = window; - gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard); + gdk_event_set_device (event, device_manager_win32->core_keyboard); + gdk_event_set_source_device (event, device_manager_win32->system_keyboard); build_wm_ime_composition_event (event, msg, wbuf[i], key_state); _gdk_win32_append_event (event); @@ -2179,7 +2198,8 @@ gdk_event_translate (MSG *msg, /* Build a key release event. */ event = gdk_event_new (GDK_KEY_RELEASE); event->key.window = window; - gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard); + gdk_event_set_device (event, device_manager_win32->core_keyboard); + gdk_event_set_source_device (event, device_manager_win32->system_keyboard); build_wm_ime_composition_event (event, msg, wbuf[i], key_state); _gdk_win32_append_event (event); @@ -2361,19 +2381,23 @@ gdk_event_translate (MSG *msg, current_root_x = msg->pt.x + _gdk_offset_x; current_root_y = msg->pt.y + _gdk_offset_y; - event = gdk_event_new (GDK_MOTION_NOTIFY); - event->motion.window = window; - event->motion.time = _gdk_win32_get_next_tick (msg->time); - event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam); - event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam); - event->motion.x_root = current_root_x; - event->motion.y_root = current_root_y; - event->motion.axes = NULL; - event->motion.state = build_pointer_event_state (msg); - event->motion.is_hint = FALSE; - gdk_event_set_device (event, _gdk_display->core_pointer); + if (!_gdk_input_ignore_core) + { + event = gdk_event_new (GDK_MOTION_NOTIFY); + event->motion.window = window; + event->motion.time = _gdk_win32_get_next_tick (msg->time); + event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam); + event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam); + event->motion.x_root = current_root_x; + event->motion.y_root = current_root_y; + event->motion.axes = NULL; + event->motion.state = build_pointer_event_state (msg); + event->motion.is_hint = FALSE; + gdk_event_set_device (event, device_manager_win32->core_pointer); + gdk_event_set_source_device (event, device_manager_win32->system_pointer); - _gdk_win32_append_event (event); + _gdk_win32_append_event (event); + } return_val = TRUE; break; @@ -2485,7 +2509,8 @@ gdk_event_translate (MSG *msg, event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x; event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y; event->scroll.state = build_pointer_event_state (msg); - gdk_event_set_device (event, _gdk_display->core_pointer); + gdk_event_set_device (event, device_manager_win32->core_pointer); + gdk_event_set_source_device (event, device_manager_win32->system_pointer); _gdk_win32_append_event (event); @@ -2763,9 +2788,6 @@ gdk_event_translate (MSG *msg, !IsIconic (msg->hwnd) && !GDK_WINDOW_DESTROYED (window)) _gdk_win32_emit_configure_event (window); - - if (_gdk_device_wintab_wants_events (window)) - _gdk_device_wintab_update_window_coords (window); } if ((windowpos->flags & SWP_HIDEWINDOW) && diff --git a/gdk/win32/gdkinput.c b/gdk/win32/gdkinput.c index 223cf46814..19101cbe60 100644 --- a/gdk/win32/gdkinput.c +++ b/gdk/win32/gdkinput.c @@ -75,6 +75,6 @@ _gdk_input_init (GdkDisplay *display) _gdk_input_devices = g_list_concat (_gdk_input_devices, g_list_copy (device_manager->wintab_devices)); - _gdk_input_wintab_init_check (device_manager); + _gdk_input_wintab_init_check (GDK_DEVICE_MANAGER (device_manager)); } |