mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 05:31:15 +00:00
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
This commit is contained in:
parent
898a62c1ac
commit
8960debc24
2 changed files with 49 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue