From d33f5a1de9f5fc44a934f72c25be1da903cf9085 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 27 Oct 2024 04:26:46 +0900 Subject: [PATCH] d3d12videosink: Add support for mouse scroll events Handle WM_MOUSEHWHEEL and WM_MOUSEWHEEL events Part-of: --- .../sys/d3d12/gstd3d12videosink.cpp | 15 ++++++++ .../sys/d3d12/gstd3d12window-win32.cpp | 36 +++++++++++++++++-- .../sys/d3d12/gstd3d12window.cpp | 15 ++++++++ .../sys/d3d12/gstd3d12window.h | 7 ++++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp index b1814939f4..4d816338f8 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp @@ -262,6 +262,9 @@ static void gst_d3d12_video_sink_key_event (GstD3D12Window * window, static void gst_d3d12_video_sink_mouse_event (GstD3D12Window * window, const gchar * event, gint button, gdouble x, gdouble y, guint modifier, GstD3D12VideoSink * self); +static void gst_d3d12_video_sink_scroll_event (GstD3D12Window * window, + gint delta_x, gint delta_y, gdouble x, gdouble y, guint modifier, + GstD3D12VideoSink * self); static void gst_d3d12_video_sink_on_fullscreen (GstD3D12Window * window, gboolean is_fullscreen, GstD3D12VideoSink * self); static void gst_d3d12_video_sink_on_overlay (GstD3D12Window * window, @@ -575,6 +578,8 @@ gst_d3d12_video_sink_init (GstD3D12VideoSink * self) G_CALLBACK (gst_d3d12_video_sink_key_event), self); g_signal_connect (priv->window, "mouse-event", G_CALLBACK (gst_d3d12_video_sink_mouse_event), self); + g_signal_connect (priv->window, "scroll-event", + G_CALLBACK (gst_d3d12_video_sink_scroll_event), self); g_signal_connect (priv->window, "fullscreen", G_CALLBACK (gst_d3d12_video_sink_on_fullscreen), self); g_signal_connect (priv->window, "overlay", @@ -1028,6 +1033,16 @@ gst_d3d12_video_sink_mouse_event (GstD3D12Window * window, const gchar * event, gst_navigation_send_event_simple (GST_NAVIGATION (self), mouse_event); } +static void +gst_d3d12_video_sink_scroll_event (GstD3D12Window * window, + gint delta_x, gint delta_y, gdouble x, gdouble y, guint modifier, + GstD3D12VideoSink * self) +{ + gst_navigation_send_event_simple (GST_NAVIGATION (self), + gst_navigation_event_new_mouse_scroll (x, y, delta_x, delta_y, + (GstNavigationModifierType) modifier)); +} + static void gst_d3d12_video_sink_on_fullscreen (GstD3D12Window * window, gboolean is_fullscreen, GstD3D12VideoSink * self) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window-win32.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window-win32.cpp index f1d7b9c900..6e64baaa34 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window-win32.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window-win32.cpp @@ -269,11 +269,26 @@ SwapChainProxy::handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam) gint button = 0; const gchar *event = nullptr; guint modifier = 0; + gint delta_x = 0; + gint delta_y = 0; auto xpos = GET_X_LPARAM (lparam); auto ypos = GET_Y_LPARAM (lparam); - if (parent_hwnd_ && parent_hwnd_ != hwnd_) { + if (msg == WM_MOUSEHWHEEL || msg == WM_MOUSEWHEEL) { + /* wheel events coordinates are relative to screen */ + POINT updated_pos; + updated_pos.x = xpos; + updated_pos.y = ypos; + + if (!ScreenToClient (hwnd_, &updated_pos)) { + GST_WARNING_OBJECT (window_, "Couldn't convert screen position to client"); + return; + } + + xpos = updated_pos.x; + ypos = updated_pos.y; + } else if (parent_hwnd_ && parent_hwnd_ != hwnd_) { POINT updated_pos; updated_pos.x = xpos; updated_pos.y = ypos; @@ -333,6 +348,12 @@ SwapChainProxy::handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam) button = 3; event = "mouse-double-click"; break; + case WM_MOUSEHWHEEL: + delta_x = GET_WHEEL_DELTA_WPARAM (wparam); + break; + case WM_MOUSEWHEEL: + delta_y = GET_WHEEL_DELTA_WPARAM (wparam); + break; default: return; } @@ -419,8 +440,13 @@ SwapChainProxy::handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam) break; } - gst_d3d12_window_on_mouse_event (window_, - event, button, final_x, final_y, modifier); + if (msg == WM_MOUSEHWHEEL || msg == WM_MOUSEWHEEL) { + gst_d3d12_window_on_scroll_event (window_, delta_x, delta_y, final_x, + final_y, modifier); + } else { + gst_d3d12_window_on_mouse_event (window_, + event, button, final_x, final_y, modifier); + } } GstFlowReturn @@ -671,6 +697,8 @@ parent_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_MBUTTONDBLCLK: + case WM_MOUSEHWHEEL: + case WM_MOUSEWHEEL: { auto proxy = server->get_direct_proxy (hwnd); if (proxy) @@ -784,6 +812,8 @@ internal_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_MBUTTONDBLCLK: + case WM_MOUSEHWHEEL: + case WM_MOUSEWHEEL: { auto proxy = server->get_proxy (window, id); if (proxy) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp index 36c7666231..b5d42bea33 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp @@ -45,6 +45,7 @@ enum { SIGNAL_KEY_EVENT, SIGNAL_MOUSE_EVENT, + SIGNAL_SCROLL_EVENT, SIGNAL_FULLSCREEN, SIGNAL_OVERLAY, SIGNAL_LAST @@ -184,6 +185,12 @@ gst_d3d12_window_class_init (GstD3D12WindowClass * klass) G_TYPE_NONE, 5, G_TYPE_STRING, G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_UINT); + d3d12_window_signals[SIGNAL_SCROLL_EVENT] = + g_signal_new_class_handler ("scroll-event", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, nullptr, nullptr, nullptr, nullptr, + G_TYPE_NONE, 5, G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, + G_TYPE_UINT); + d3d12_window_signals[SIGNAL_FULLSCREEN] = g_signal_new_class_handler ("fullscreen", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, nullptr, nullptr, nullptr, nullptr, @@ -233,6 +240,14 @@ gst_d3d12_window_on_mouse_event (GstD3D12Window * window, const gchar * event, event, button, xpos, ypos, modifier); } +void +gst_d3d12_window_on_scroll_event (GstD3D12Window * window, gint delta_x, + gint delta_y, double xpos, double ypos, guint modifier) +{ + g_signal_emit (window, d3d12_window_signals[SIGNAL_SCROLL_EVENT], 0, + delta_x, delta_y, xpos, ypos, modifier); +} + static gboolean msg_io_cb (GIOChannel * source, GIOCondition condition, gpointer data) { diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h index f896d4c11c..ccace7efa9 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h @@ -143,6 +143,13 @@ void gst_d3d12_window_on_mouse_event (GstD3D12Window * window, double ypos, guint modifier); +void gst_d3d12_window_on_scroll_event (GstD3D12Window * window, + gint delta_x, + gint delta_y, + double xpos, + double ypos, + guint modifier); + void gst_d3d12_window_get_create_params (GstD3D12Window * window, std::wstring & title, GstVideoRectangle * rect,