Commit 6d9536c7 authored by Antoine Cellerier's avatar Antoine Cellerier

Add mouse cursor drawing support in x11 screen.

parent 52c11814
Changes between 0.9.1 and 1.0.0-git: Changes between 0.9.1 and 1.0.0-git:
------------------------------------ ------------------------------------
Inputs:
* Mouse cursor support in x11 screen module
Decoders: Decoders:
* AES3 (SMPTE 302M) support * AES3 (SMPTE 302M) support
......
...@@ -73,6 +73,13 @@ ...@@ -73,6 +73,13 @@
"Follow the mouse when capturing a subscreen." ) "Follow the mouse when capturing a subscreen." )
#endif #endif
#ifdef SCREEN_MOUSE
#define MOUSE_TEXT N_( "Mouse pointer image" )
#define MOUSE_LONGTEXT N_( \
"If specifed, will use the image to draw the mouse pointer on the " \
"capture." )
#endif
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close( vlc_object_t * ); static void Close( vlc_object_t * );
...@@ -101,6 +108,11 @@ vlc_module_begin(); ...@@ -101,6 +108,11 @@ vlc_module_begin();
FOLLOW_MOUSE_LONGTEXT, true ); FOLLOW_MOUSE_LONGTEXT, true );
#endif #endif
#ifdef SCREEN_MOUSE
add_string( "screen-mouse-image", "", NULL, MOUSE_TEXT, MOUSE_LONGTEXT,
true );
#endif
#ifdef WIN32 #ifdef WIN32
add_integer( "screen-fragment-size", 0, NULL, FRAGS_TEXT, add_integer( "screen-fragment-size", 0, NULL, FRAGS_TEXT,
FRAGS_LONGTEXT, true ); FRAGS_LONGTEXT, true );
...@@ -189,6 +201,30 @@ static int Open( vlc_object_t *p_this ) ...@@ -189,6 +201,30 @@ static int Open( vlc_object_t *p_this )
} }
#endif #endif
#ifdef SCREEN_MOUSE
char * psz_mouse = var_CreateGetNonEmptyString( p_demux,
"screen-mouse-image" );
if( psz_mouse )
{
image_handler_t *p_image;
video_format_t fmt_in, fmt_out;
msg_Dbg( p_demux, "Using %s for the mouse pointer image", psz_mouse );
memset( &fmt_in, 0, sizeof( fmt_in ) );
memset( &fmt_out, 0, sizeof( fmt_out ) );
fmt_out.i_chroma = VLC_FOURCC('R','G','B','A');
p_image = image_HandlerCreate( p_demux );
if( p_image )
{
p_sys->p_mouse =
image_ReadUrl( p_image, psz_mouse, &fmt_in, &fmt_out );
image_HandlerDelete( p_image );
}
if( !p_sys->p_mouse )
msg_Err( p_demux, "Failed to open mouse pointer image (%s)",
psz_mouse );
}
#endif
p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt ); p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt );
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -203,6 +239,10 @@ static void Close( vlc_object_t *p_this ) ...@@ -203,6 +239,10 @@ static void Close( vlc_object_t *p_this )
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
screen_CloseCapture( p_demux ); screen_CloseCapture( p_demux );
#ifdef SCREEN_MOUSE
if( p_sys->p_mouse )
picture_Release( p_sys->p_mouse );
#endif
free( p_sys ); free( p_sys );
} }
......
...@@ -27,6 +27,11 @@ ...@@ -27,6 +27,11 @@
#if !defined( HAVE_WIN32 ) && !defined( HAVE_BEOS ) && !defined( HAVE_DARWIN ) #if !defined( HAVE_WIN32 ) && !defined( HAVE_BEOS ) && !defined( HAVE_DARWIN )
# define SCREEN_SUBSCREEN # define SCREEN_SUBSCREEN
# define SCREEN_MOUSE
#endif
#ifdef SCREEN_MOUSE
# include <vlc_image.h>
#endif #endif
typedef struct screen_data_t screen_data_t; typedef struct screen_data_t screen_data_t;
...@@ -51,6 +56,13 @@ struct demux_sys_t ...@@ -51,6 +56,13 @@ struct demux_sys_t
unsigned int i_width; unsigned int i_width;
#endif #endif
#ifdef SCREEN_MOUSE
picture_t *p_mouse;
filter_t *p_blend;
picture_t src;
picture_t dst;
#endif
screen_data_t *p_data; screen_data_t *p_data;
}; };
......
...@@ -82,9 +82,12 @@ int screen_InitCapture( demux_t *p_demux ) ...@@ -82,9 +82,12 @@ int screen_InitCapture( demux_t *p_demux )
} }
es_format_Init( &p_sys->fmt, VIDEO_ES, i_chroma ); es_format_Init( &p_sys->fmt, VIDEO_ES, i_chroma );
p_sys->fmt.video.i_visible_width =
p_sys->fmt.video.i_width = win_info.width; p_sys->fmt.video.i_width = win_info.width;
p_sys->fmt.video.i_visible_height =
p_sys->fmt.video.i_height = win_info.height; p_sys->fmt.video.i_height = win_info.height;
p_sys->fmt.video.i_bits_per_pixel = win_info.depth; p_sys->fmt.video.i_bits_per_pixel = win_info.depth;
p_sys->fmt.video.i_chroma = i_chroma;
#if 0 #if 0
win_info.visual->red_mask; win_info.visual->red_mask;
...@@ -102,6 +105,12 @@ int screen_CloseCapture( demux_t *p_demux ) ...@@ -102,6 +105,12 @@ int screen_CloseCapture( demux_t *p_demux )
Display *p_display = (Display *)p_sys->p_data; Display *p_display = (Display *)p_sys->p_data;
XCloseDisplay( p_display ); XCloseDisplay( p_display );
if( p_sys->p_blend )
{
module_Unneed( p_sys->p_blend, p_sys->p_blend->p_module );
vlc_object_detach( p_sys->p_blend );
vlc_object_release( p_sys->p_blend );
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -112,25 +121,28 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -112,25 +121,28 @@ block_t *screen_Capture( demux_t *p_demux )
block_t *p_block; block_t *p_block;
XImage *image; XImage *image;
int i_size; int i_size;
int root_x = 0, root_y = 0;
if( p_sys->b_follow_mouse ) if( p_sys->b_follow_mouse || p_sys->p_mouse )
{ {
Window root = DefaultRootWindow( p_display ), child; Window root = DefaultRootWindow( p_display ), child;
int root_x, root_y;
int win_x, win_y; int win_x, win_y;
unsigned int mask; unsigned int mask;
if( XQueryPointer( p_display, root, if( XQueryPointer( p_display, root,
&root, &child, &root_x, &root_y, &win_x, &win_y, &root, &child, &root_x, &root_y, &win_x, &win_y,
&mask ) ) &mask ) )
{ {
root_x -= p_sys->i_width/2; if( p_sys->b_follow_mouse )
if( root_x < 0 ) root_x = 0; {
p_sys->i_left = __MIN( (unsigned int)root_x, root_x -= p_sys->i_width/2;
p_sys->i_screen_width - p_sys->i_width ); if( root_x < 0 ) root_x = 0;
root_y -= p_sys->i_height/2; p_sys->i_left = __MIN( (unsigned int)root_x,
if( root_y < 0 ) root_y = 0; p_sys->i_screen_width - p_sys->i_width );
p_sys->i_top = __MIN( (unsigned int)root_y, root_y -= p_sys->i_height/2;
p_sys->i_screen_height - p_sys->i_height ); if( root_y < 0 ) root_y = 0;
p_sys->i_top = __MIN( (unsigned int)root_y,
p_sys->i_screen_height - p_sys->i_height );
}
} }
else else
msg_Dbg( p_demux, "XQueryPointer() failed" ); msg_Dbg( p_demux, "XQueryPointer() failed" );
...@@ -156,7 +168,65 @@ block_t *screen_Capture( demux_t *p_demux ) ...@@ -156,7 +168,65 @@ block_t *screen_Capture( demux_t *p_demux )
return 0; return 0;
} }
vlc_memcpy( p_block->p_buffer, image->data, i_size ); if( !p_sys->p_mouse )
vlc_memcpy( p_block->p_buffer, image->data, i_size );
else
{
if( !p_sys->src.i_planes )
vout_InitPicture( p_demux, &p_sys->src,
p_sys->fmt.video.i_chroma,
p_sys->fmt.video.i_width,
p_sys->fmt.video.i_height,
p_sys->fmt.video.i_aspect );
if( !p_sys->dst.i_planes )
vout_InitPicture( p_demux, &p_sys->dst,
p_sys->fmt.video.i_chroma,
p_sys->fmt.video.i_width,
p_sys->fmt.video.i_height,
p_sys->fmt.video.i_aspect );
if( !p_sys->p_blend )
{
p_sys->p_blend = vlc_object_create( p_demux, sizeof(filter_t) );
if( !p_sys->p_blend )
msg_Err( p_demux, "Could not allocate memory for blending module" );
else
{
es_format_Init( &p_sys->p_blend->fmt_in, VIDEO_ES,
VLC_FOURCC('R','G','B','A') );
p_sys->p_blend->fmt_in.video = p_sys->p_mouse->format;
p_sys->p_blend->fmt_out = p_sys->fmt;
p_sys->p_blend->p_module =
module_Need( p_sys->p_blend, "video blending", 0, 0 );
if( !p_sys->p_blend->p_module )
{
msg_Err( p_demux, "Could not load video blending module" );
vlc_object_detach( p_sys->p_blend );
vlc_object_release( p_sys->p_blend );
p_sys->p_blend = NULL;
}
}
}
if( p_sys->p_blend )
{
/* FIXME: why is this memcpy needed?!? (bug in blend?) */
vlc_memcpy( p_block->p_buffer, image->data, i_size );
p_sys->dst.p->p_pixels = p_block->p_buffer;
p_sys->src.p->p_pixels = image->data;
p_sys->p_blend->pf_video_blend( p_sys->p_blend,
&p_sys->dst,
&p_sys->src,
p_sys->p_mouse,
root_x,
root_y,
255 );
}
else
{
picture_Release( p_sys->p_mouse );
p_sys->p_mouse = NULL;
vlc_memcpy( p_block->p_buffer, image->data, i_size );
}
}
XDestroyImage( image ); XDestroyImage( image );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment