summaryrefslogtreecommitdiff
path: root/gdk/win32
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/win32')
-rw-r--r--gdk/win32/Makefile.am2
-rw-r--r--gdk/win32/gdkdevice-virtual.c429
-rw-r--r--gdk/win32/gdkdevice-virtual.h54
-rw-r--r--gdk/win32/gdkdevice-win32.c127
-rw-r--r--gdk/win32/gdkdevice-wintab.c209
-rw-r--r--gdk/win32/gdkdevice-wintab.h9
-rw-r--r--gdk/win32/gdkdevicemanager-win32.c261
-rw-r--r--gdk/win32/gdkdevicemanager-win32.h4
-rw-r--r--gdk/win32/gdkevents-win32.c80
-rw-r--r--gdk/win32/gdkinput.c2
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));
}