From: Luca Bacci Date: Fri, 2 Jul 2021 08:53:16 +0000 (+0200) Subject: Add new GdkDeviceWinpointer type X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~1^2~6^2~8 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=9a8a9451b1269c20560925087d76120bb315df2b;p=gtk4.git Add new GdkDeviceWinpointer type --- diff --git a/gdk/win32/gdkdevice-winpointer.c b/gdk/win32/gdkdevice-winpointer.c new file mode 100644 index 0000000000..b5639bf114 --- /dev/null +++ b/gdk/win32/gdkdevice-winpointer.c @@ -0,0 +1,221 @@ +/* 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 void +screen_to_client (HWND hwnd, POINT screen_pt, POINT *client_pt) +{ + *client_pt = screen_pt; + ScreenToClient (hwnd, client_pt); +} + +static GdkSurface * +gdk_device_winpointer_surface_at_position (GdkDevice *device, + double *win_x, + double *win_y, + GdkModifierType *mask) +{ + GdkSurface *surface = NULL; + GdkWin32Surface *impl = NULL; + POINT screen_pt, client_pt; + HWND hwnd; + RECT rect; + + if (!GetCursorPos (&screen_pt)) + return NULL; + + /* Use WindowFromPoint instead of ChildWindowFromPoint(Ex). + * Only WindowFromPoint is able to look through transparent + * layered windows. + */ + hwnd = GetAncestor (WindowFromPoint (screen_pt), GA_ROOT); + + /* Verify that we're really inside the client area of the surface */ + GetClientRect (hwnd, &rect); + screen_to_client (hwnd, screen_pt, &client_pt); + if (!PtInRect (&rect, client_pt)) + hwnd = NULL; + + surface = gdk_win32_handle_table_lookup (hwnd); + + if (surface && (win_x || win_y)) + { + impl = GDK_WIN32_SURFACE (surface); + + if (win_x) + *win_x = client_pt.x / impl->surface_scale; + if (win_y) + *win_y = client_pt.y / impl->surface_scale; + } + + return surface; +} + +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_button_mask = 0; +} + +static void +gdk_device_winpointer_finalize (GObject *object) +{ + GdkDeviceWinpointer *device_winpointer = GDK_DEVICE_WINPOINTER (object); + + 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..de13d51415 --- /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 + +#include "winpointer.h" + +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; + + 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 8891a74081..b46699ee4a 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',