[gtk: 10/19] Add new GdkDeviceWinpointer type




commit 9a8a9451b1269c20560925087d76120bb315df2b
Author: Luca Bacci <luca bacci982 gmail com>
Date:   Fri Jul 2 10:53:16 2021 +0200

    Add new GdkDeviceWinpointer type

 gdk/win32/gdkdevice-winpointer.c | 221 +++++++++++++++++++++++++++++++++++++++
 gdk/win32/gdkdevice-winpointer.h |  64 ++++++++++++
 gdk/win32/meson.build            |   1 +
 3 files changed, 286 insertions(+)
---
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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gdk/gdksurface.h>
+
+#include <windows.h>
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GDK_DEVICE_WINPOINTER_H__
+#define __GDK_DEVICE_WINPOINTER_H__
+
+#include <gdk/gdkdeviceprivate.h>
+
+#include <windows.h>
+
+#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',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]