diff --git a/gdk/win32/gdkdevice-winpointer.c b/gdk/win32/gdkdevice-winpointer.c new file mode 100644 index 0000000000..6456b723a5 --- /dev/null +++ b/gdk/win32/gdkdevice-winpointer.c @@ -0,0 +1,185 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2020 the GTK team + * + * 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 . + */ + +#include "config.h" + +#include + +#include + +#include "gdkwin32.h" +#include "gdkdevice-winpointer.h" +#include "gdkdisplay-win32.h" + +G_DEFINE_TYPE (GdkDeviceWinpointer, gdk_device_winpointer, GDK_TYPE_DEVICE) + +static GdkModifierType +get_keyboard_mask (void) +{ + GdkModifierType mask = 0; + BYTE kbd[256]; + + GetKeyboardState (kbd); + 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_ALT_MASK; + + return mask; +} + +static void +gdk_device_winpointer_set_surface_cursor (GdkDevice *device, + GdkSurface *window, + GdkCursor *cursor) +{ +} + +void +gdk_device_winpointer_query_state (GdkDevice *device, + GdkSurface *window, + GdkSurface **child_window, + double *win_x, + double *win_y, + GdkModifierType *mask) +{ + GdkDeviceWinpointer *device_winpointer; + POINT point; + HWND hwnd, hwndc; + int scale; + + device_winpointer = GDK_DEVICE_WINPOINTER (device); + if (window) + { + scale = GDK_WIN32_SURFACE (window)->surface_scale; + hwnd = GDK_SURFACE_HWND (window); + } + else + { + GdkDisplay *display = gdk_device_get_display (device); + + scale = GDK_WIN32_DISPLAY (display)->surface_scale; + hwnd = NULL; + } + + GetCursorPos (&point); + + if (hwnd) + ScreenToClient (hwnd, &point); + + if (win_x) + *win_x = point.x / scale; + + if (win_y) + *win_y = point.y / scale; + + if (!window) + { + if (win_x) + *win_x += _gdk_offset_x; + + if (win_y) + *win_y += _gdk_offset_y; + } + + if (hwnd && 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 (mask) + { + *mask = get_keyboard_mask (); + *mask |= device_winpointer->last_button_mask; + } +} + +static GdkGrabStatus +gdk_device_winpointer_grab (GdkDevice *device, + GdkSurface *window, + gboolean owner_events, + GdkEventMask event_mask, + GdkSurface *confine_to, + GdkCursor *cursor, + guint32 time_) +{ + return GDK_GRAB_SUCCESS; +} + +static void +gdk_device_winpointer_ungrab (GdkDevice *device, + guint32 time_) +{ +} + +static GdkSurface * +gdk_device_winpointer_surface_at_position (GdkDevice *device, + double *win_x, + double *win_y, + GdkModifierType *mask) +{ + return NULL; +} + +static void +gdk_device_winpointer_init (GdkDeviceWinpointer *device_winpointer) +{ + device_winpointer->device_handle = NULL; + device_winpointer->start_cursor_id = 0; + device_winpointer->end_cursor_id = 0; + + device_winpointer->origin_x = 0; + device_winpointer->origin_y = 0; + device_winpointer->scale_x = 0.0; + device_winpointer->scale_y = 0.0; + + device_winpointer->last_axis_data = NULL; + device_winpointer->num_axes = 0; + device_winpointer->last_button_mask = 0; +} + +static void +gdk_device_winpointer_finalize (GObject *object) +{ + GdkDeviceWinpointer *device_winpointer = GDK_DEVICE_WINPOINTER (object); + + g_free (device_winpointer->last_axis_data); + + G_OBJECT_CLASS (gdk_device_winpointer_parent_class)->finalize (object); +} + +static void +gdk_device_winpointer_class_init (GdkDeviceWinpointerClass *klass) +{ + GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_device_winpointer_finalize; + device_class->set_surface_cursor = gdk_device_winpointer_set_surface_cursor; + device_class->grab = gdk_device_winpointer_grab; + device_class->ungrab = gdk_device_winpointer_ungrab; + device_class->surface_at_position = gdk_device_winpointer_surface_at_position; +} diff --git a/gdk/win32/gdkdevice-winpointer.h b/gdk/win32/gdkdevice-winpointer.h new file mode 100644 index 0000000000..73146d7e4e --- /dev/null +++ b/gdk/win32/gdkdevice-winpointer.h @@ -0,0 +1,64 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2020 the GTK team + * + * 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 . + */ + +#ifndef __GDK_DEVICE_WINPOINTER_H__ +#define __GDK_DEVICE_WINPOINTER_H__ + +#include + +#include + +G_BEGIN_DECLS + +#define GDK_TYPE_DEVICE_WINPOINTER (gdk_device_winpointer_get_type ()) +#define GDK_DEVICE_WINPOINTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointer)) +#define GDK_DEVICE_WINPOINTER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointerClass)) +#define GDK_IS_DEVICE_WINPOINTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_WINPOINTER)) +#define GDK_IS_DEVICE_WINPOINTER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_WINPOINTER)) +#define GDK_DEVICE_WINPOINTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointerClass)) + +typedef struct _GdkDeviceWinpointer GdkDeviceWinpointer; +typedef struct _GdkDeviceWinpointerClass GdkDeviceWinpointerClass; + +struct _GdkDeviceWinpointer +{ + GdkDevice parent_instance; + + HANDLE device_handle; + UINT32 start_cursor_id; + UINT32 end_cursor_id; + + int origin_x; + int origin_y; + double scale_x; + double scale_y; + + double *last_axis_data; + unsigned num_axes; + GdkModifierType last_button_mask; +}; + +struct _GdkDeviceWinpointerClass +{ + GdkDeviceClass parent_class; +}; + +GType gdk_device_winpointer_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GDK_DEVICE_WINPOINTER_H__ */ diff --git a/gdk/win32/meson.build b/gdk/win32/meson.build index a29d222665..3542154663 100644 --- a/gdk/win32/meson.build +++ b/gdk/win32/meson.build @@ -6,6 +6,7 @@ gdk_win32_sources = files([ 'gdkdevicemanager-win32.c', 'gdkdevice-virtual.c', 'gdkdevice-win32.c', + 'gdkdevice-winpointer.c', 'gdkdevice-wintab.c', 'gdkdisplay-win32.c', 'gdkdisplaymanager-win32.c',