d3d11videosink: Translate mouse position
authorSeungha Yang <seungha@centricular.com>
Mon, 1 Aug 2022 20:06:24 +0000 (05:06 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 2 Aug 2022 14:24:22 +0000 (14:24 +0000)
Converts mouse cursor position represented in display coordinates to
stream coordinates.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2824>

subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp
subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_win32.cpp

index b551f26..bdb7801 100644 (file)
@@ -396,11 +396,93 @@ void
 gst_d3d11_window_on_mouse_event (GstD3D11Window * window, const gchar * event,
     gint button, gdouble x, gdouble y)
 {
+  RECT render_rect;
+  GstVideoOrientationMethod method;
+  LONG xpos, ypos;
+  gdouble display_w, display_h, src_w, src_h;
+  gint in_w, in_h;
+
   g_return_if_fail (GST_IS_D3D11_WINDOW (window));
 
   if (!window->enable_navigation_events)
     return;
 
+  gst_d3d11_device_lock (window->device);
+  method = window->method;
+  render_rect = window->render_rect;
+  in_w = window->info.width;
+  in_h = window->info.height;
+  gst_d3d11_device_unlock (window->device);
+
+  display_w = render_rect.right - render_rect.left;
+  display_h = render_rect.bottom - render_rect.top;
+  xpos = (LONG) x;
+  ypos = (LONG) y;
+
+  /* if backbuffer surface size is unknown or mouse point located at
+   * outside of render area, ignore it */
+  if (display_w <= 0 || display_h <= 0 || in_w <= 0 || in_h <= 0 ||
+      xpos < render_rect.left || xpos >= render_rect.right ||
+      ypos < render_rect.top || ypos >= render_rect.bottom) {
+    return;
+  }
+
+  switch (method) {
+    case GST_VIDEO_ORIENTATION_90R:
+    case GST_VIDEO_ORIENTATION_90L:
+    case GST_VIDEO_ORIENTATION_UL_LR:
+    case GST_VIDEO_ORIENTATION_UR_LL:
+      src_w = in_h;
+      src_h = in_w;
+      break;
+    default:
+      src_w = in_w;
+      src_h = in_h;
+      break;
+  }
+
+  xpos = ((xpos - render_rect.left) / display_w) * src_w;
+  ypos = ((ypos - render_rect.top) / display_h) * src_h;
+
+  xpos = CLAMP (xpos, 0, (LONG) (src_w - 1));
+  ypos = CLAMP (ypos, 0, (LONG) (src_h - 1));
+
+  /* Reverse rotate/flip if needed */
+  switch (method) {
+    case GST_VIDEO_ORIENTATION_90R:
+      x = ypos;
+      y = src_w - xpos;
+      break;
+    case GST_VIDEO_ORIENTATION_90L:
+      x = src_h - ypos;
+      y = xpos;
+      break;
+    case GST_VIDEO_ORIENTATION_UR_LL:
+      x = src_h - ypos;
+      y = src_w - xpos;
+      break;
+    case GST_VIDEO_ORIENTATION_UL_LR:
+      x = ypos;
+      y = xpos;
+      break;
+    case GST_VIDEO_ORIENTATION_180:
+      x = src_w - xpos;
+      y = src_h - ypos;
+      break;
+    case GST_VIDEO_ORIENTATION_HORIZ:
+      x = src_w - xpos;
+      y = ypos;
+      break;
+    case GST_VIDEO_ORIENTATION_VERT:
+      x = xpos;
+      y = src_h - ypos;
+      break;
+    default:
+      x = xpos;
+      y = ypos;
+      break;
+  }
+
   g_signal_emit (window, d3d11_window_signals[SIGNAL_MOUSE_EVENT], 0,
       event, button, x, y);
 }
index ea8b9df..2cbd11a 100644 (file)
@@ -621,7 +621,6 @@ gst_d3d11_window_win32_on_mouse_event (GstD3D11WindowWin32 * self,
   if (!window->enable_navigation_events)
     return;
 
-  /* FIXME: convert to render coordinate */
   switch (uMsg) {
     case WM_MOUSEMOVE:
       button = 0;