d3d12videosink: Add support for mouse scroll events

Handle WM_MOUSEHWHEEL and WM_MOUSEWHEEL events

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7774>
This commit is contained in:
Seungha Yang 2024-10-27 04:26:46 +09:00 committed by GStreamer Marge Bot
parent 62de46872c
commit d33f5a1de9
4 changed files with 70 additions and 3 deletions

View file

@ -262,6 +262,9 @@ static void gst_d3d12_video_sink_key_event (GstD3D12Window * window,
static void gst_d3d12_video_sink_mouse_event (GstD3D12Window * window, static void gst_d3d12_video_sink_mouse_event (GstD3D12Window * window,
const gchar * event, gint button, gdouble x, gdouble y, guint modifier, const gchar * event, gint button, gdouble x, gdouble y, guint modifier,
GstD3D12VideoSink * self); 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, static void gst_d3d12_video_sink_on_fullscreen (GstD3D12Window * window,
gboolean is_fullscreen, GstD3D12VideoSink * self); gboolean is_fullscreen, GstD3D12VideoSink * self);
static void gst_d3d12_video_sink_on_overlay (GstD3D12Window * window, 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_CALLBACK (gst_d3d12_video_sink_key_event), self);
g_signal_connect (priv->window, "mouse-event", g_signal_connect (priv->window, "mouse-event",
G_CALLBACK (gst_d3d12_video_sink_mouse_event), self); 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_signal_connect (priv->window, "fullscreen",
G_CALLBACK (gst_d3d12_video_sink_on_fullscreen), self); G_CALLBACK (gst_d3d12_video_sink_on_fullscreen), self);
g_signal_connect (priv->window, "overlay", 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); 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 static void
gst_d3d12_video_sink_on_fullscreen (GstD3D12Window * window, gst_d3d12_video_sink_on_fullscreen (GstD3D12Window * window,
gboolean is_fullscreen, GstD3D12VideoSink * self) gboolean is_fullscreen, GstD3D12VideoSink * self)

View file

@ -269,11 +269,26 @@ SwapChainProxy::handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam)
gint button = 0; gint button = 0;
const gchar *event = nullptr; const gchar *event = nullptr;
guint modifier = 0; guint modifier = 0;
gint delta_x = 0;
gint delta_y = 0;
auto xpos = GET_X_LPARAM (lparam); auto xpos = GET_X_LPARAM (lparam);
auto ypos = GET_Y_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; POINT updated_pos;
updated_pos.x = xpos; updated_pos.x = xpos;
updated_pos.y = ypos; updated_pos.y = ypos;
@ -333,6 +348,12 @@ SwapChainProxy::handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam)
button = 3; button = 3;
event = "mouse-double-click"; event = "mouse-double-click";
break; break;
case WM_MOUSEHWHEEL:
delta_x = GET_WHEEL_DELTA_WPARAM (wparam);
break;
case WM_MOUSEWHEEL:
delta_y = GET_WHEEL_DELTA_WPARAM (wparam);
break;
default: default:
return; return;
} }
@ -419,8 +440,13 @@ SwapChainProxy::handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam)
break; break;
} }
gst_d3d12_window_on_mouse_event (window_, if (msg == WM_MOUSEHWHEEL || msg == WM_MOUSEWHEEL) {
event, button, final_x, final_y, modifier); 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 GstFlowReturn
@ -671,6 +697,8 @@ parent_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
case WM_LBUTTONDBLCLK: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK: case WM_MBUTTONDBLCLK:
case WM_MOUSEHWHEEL:
case WM_MOUSEWHEEL:
{ {
auto proxy = server->get_direct_proxy (hwnd); auto proxy = server->get_direct_proxy (hwnd);
if (proxy) if (proxy)
@ -784,6 +812,8 @@ internal_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
case WM_LBUTTONDBLCLK: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK: case WM_MBUTTONDBLCLK:
case WM_MOUSEHWHEEL:
case WM_MOUSEWHEEL:
{ {
auto proxy = server->get_proxy (window, id); auto proxy = server->get_proxy (window, id);
if (proxy) if (proxy)

View file

@ -45,6 +45,7 @@ enum
{ {
SIGNAL_KEY_EVENT, SIGNAL_KEY_EVENT,
SIGNAL_MOUSE_EVENT, SIGNAL_MOUSE_EVENT,
SIGNAL_SCROLL_EVENT,
SIGNAL_FULLSCREEN, SIGNAL_FULLSCREEN,
SIGNAL_OVERLAY, SIGNAL_OVERLAY,
SIGNAL_LAST 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_NONE, 5, G_TYPE_STRING, G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
G_TYPE_UINT); 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] = d3d12_window_signals[SIGNAL_FULLSCREEN] =
g_signal_new_class_handler ("fullscreen", G_TYPE_FROM_CLASS (klass), g_signal_new_class_handler ("fullscreen", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, nullptr, nullptr, nullptr, nullptr, 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); 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 static gboolean
msg_io_cb (GIOChannel * source, GIOCondition condition, gpointer data) msg_io_cb (GIOChannel * source, GIOCondition condition, gpointer data)
{ {

View file

@ -143,6 +143,13 @@ void gst_d3d12_window_on_mouse_event (GstD3D12Window * window,
double ypos, double ypos,
guint modifier); 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, void gst_d3d12_window_get_create_params (GstD3D12Window * window,
std::wstring & title, std::wstring & title,
GstVideoRectangle * rect, GstVideoRectangle * rect,