summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Zwoch <fzwoch@gmail.com>2016-01-05 18:50:45 +0100
committerSebastian Dröge <sebastian@centricular.com>2016-11-02 10:38:59 +0200
commit8960debc249a6d0eb4589ef04f77428762e92d33 (patch)
treead20e162377dede19e3d5b9ab52f548f4a616b14
parent898a62c1acd33754c75fb2c039b5c30a2d053e4a (diff)
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
-rw-r--r--sys/winscreencap/gstdx9screencapsrc.c47
-rw-r--r--sys/winscreencap/gstdx9screencapsrc.h2
2 files changed, 49 insertions, 0 deletions
diff --git a/sys/winscreencap/gstdx9screencapsrc.c b/sys/winscreencap/gstdx9screencapsrc.c
index d3bd61cdb..0e2cfb241 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 07622a983..2621c150a 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