From 8960debc249a6d0eb4589ef04f77428762e92d33 Mon Sep 17 00:00:00 2001 From: Florian Zwoch Date: Tue, 5 Jan 2016 18:50:45 +0100 Subject: [PATCH] dx9screencapsrc: add "cursor" option to draw the cursor Drawing is done via the GDI drawing functions. The cursor is converted to a monochrome version before drawing. This is because the GDI drawing functions seem to have undefined behavior with cursor images including an alpha channel. I could not find any other reliable way to draw these alpha channel cursors without producing unwanted artifacts. These type of cursors were introduced with Window Vista when run with it's Aero theme. Also adjust the cursor coordinates when capturing non-primary screens via the "monitor" option. https://bugzilla.gnome.org/show_bug.cgi?id=760172 --- sys/winscreencap/gstdx9screencapsrc.c | 47 +++++++++++++++++++++++++++++++++++ sys/winscreencap/gstdx9screencapsrc.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/sys/winscreencap/gstdx9screencapsrc.c b/sys/winscreencap/gstdx9screencapsrc.c index d3bd61c..0e2cfb2 100644 --- a/sys/winscreencap/gstdx9screencapsrc.c +++ b/sys/winscreencap/gstdx9screencapsrc.c @@ -61,6 +61,7 @@ enum { PROP_0, PROP_MONITOR, + PROP_SHOW_CURSOR, PROP_X_POS, PROP_Y_POS, PROP_WIDTH, @@ -121,6 +122,11 @@ gst_dx9screencapsrc_class_init (GstDX9ScreenCapSrcClass * klass) "Which monitor to use (0 = 1st monitor and default)", 0, G_MAXINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (go_class, PROP_SHOW_CURSOR, + g_param_spec_boolean ("cursor", "Show mouse cursor", + "Whether to show mouse cursor (default off)", + FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (go_class, PROP_X_POS, g_param_spec_int ("x", "X", "Horizontal coordinate of top left corner for the screen capture " @@ -161,6 +167,8 @@ gst_dx9screencapsrc_init (GstDX9ScreenCapSrc * src) src->capture_h = 0; src->monitor = 0; + src->show_cursor = FALSE; + src->monitor_info.cbSize = sizeof(MONITORINFO); gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME); gst_base_src_set_live (GST_BASE_SRC (src), TRUE); @@ -204,6 +212,9 @@ gst_dx9screencapsrc_set_property (GObject * object, case PROP_MONITOR: src->monitor = g_value_get_int (value); break; + case PROP_SHOW_CURSOR: + src->show_cursor = g_value_get_boolean (value); + break; case PROP_X_POS: src->capture_x = g_value_get_int (value); break; @@ -232,6 +243,9 @@ gst_dx9screencapsrc_get_property (GObject * object, guint prop_id, case PROP_MONITOR: g_value_set_int (value, src->monitor); break; + case PROP_SHOW_CURSOR: + g_value_set_boolean (value, src->show_cursor); + break; case PROP_X_POS: g_value_set_int (value, src->capture_x); break; @@ -366,6 +380,7 @@ gst_dx9screencapsrc_start (GstBaseSrc * bsrc) { GstDX9ScreenCapSrc *src = GST_DX9SCREENCAPSRC (bsrc); D3DPRESENT_PARAMETERS d3dpp; + HMONITOR monitor; HRESULT res; src->frame_number = -1; @@ -395,6 +410,9 @@ gst_dx9screencapsrc_start (GstBaseSrc * bsrc) if (FAILED (res)) return FALSE; + monitor = IDirect3D9_GetAdapterMonitor (g_d3d9, src->monitor); + GetMonitorInfo (monitor, &src->monitor_info); + return SUCCEEDED (IDirect3DDevice9_CreateOffscreenPlainSurface (src->d3d9_device, src->disp_mode.Width, src->disp_mode.Height, D3DFMT_A8R8G8B8, @@ -539,6 +557,35 @@ gst_dx9screencapsrc_create (GstPushSrc * push_src, GstBuffer ** buf) return GST_FLOW_ERROR; } + if (src->show_cursor) { + CURSORINFO ci; + + ci.cbSize = sizeof (CURSORINFO); + GetCursorInfo (&ci); + if (ci.flags & CURSOR_SHOWING) { + ICONINFO ii; + HDC memDC; + + GetIconInfo (ci.hCursor, &ii); + + if (SUCCEEDED (IDirect3DSurface9_GetDC (src->surface, &memDC))) { + HCURSOR cursor = CopyImage (ci.hCursor, IMAGE_CURSOR, 0, 0, + LR_MONOCHROME | LR_DEFAULTSIZE); + + DrawIcon (memDC, + ci.ptScreenPos.x - ii.xHotspot - src->monitor_info.rcMonitor.left, + ci.ptScreenPos.y - ii.yHotspot - src->monitor_info.rcMonitor.top, + cursor); + + DestroyCursor (cursor); + IDirect3DSurface9_ReleaseDC (src->surface, memDC); + } + + DeleteObject (ii.hbmColor); + DeleteObject (ii.hbmMask); + } + } + hres = IDirect3DSurface9_LockRect (src->surface, &locked_rect, &(src->src_rect), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY); diff --git a/sys/winscreencap/gstdx9screencapsrc.h b/sys/winscreencap/gstdx9screencapsrc.h index 07622a9..2621c15 100644 --- a/sys/winscreencap/gstdx9screencapsrc.h +++ b/sys/winscreencap/gstdx9screencapsrc.h @@ -55,6 +55,7 @@ struct _GstDX9ScreenCapSrc gint capture_w; gint capture_h; guint monitor; + gboolean show_cursor; /* Source pad frame rate */ gint rate_numerator; @@ -69,6 +70,7 @@ struct _GstDX9ScreenCapSrc D3DDISPLAYMODE disp_mode; IDirect3DSurface9 *surface; IDirect3DDevice9 *d3d9_device; + MONITORINFO monitor_info; }; struct _GstDX9ScreenCapSrcClass -- 2.7.4