[vlc-devel] commit: Add mouse cursor drawing support in x11 screen. (Antoine Cellerier )
git version control
git at videolan.org
Thu Sep 4 17:57:07 CEST 2008
vlc | branch: master | Antoine Cellerier <dionoea at videolan.org> | Thu Sep 4 18:00:09 2008 +0200| [6d9536c7663f926889b44a6deb125152acfb3508] | committer: Antoine Cellerier
Add mouse cursor drawing support in x11 screen.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6d9536c7663f926889b44a6deb125152acfb3508
---
NEWS | 3 +
modules/access/screen/screen.c | 40 +++++++++++++++++
modules/access/screen/screen.h | 12 +++++
modules/access/screen/x11.c | 92 +++++++++++++++++++++++++++++++++++-----
4 files changed, 136 insertions(+), 11 deletions(-)
diff --git a/NEWS b/NEWS
index e3b4156..5a8ace1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
Changes between 0.9.1 and 1.0.0-git:
------------------------------------
+Inputs:
+ * Mouse cursor support in x11 screen module
+
Decoders:
* AES3 (SMPTE 302M) support
diff --git a/modules/access/screen/screen.c b/modules/access/screen/screen.c
index 6f92341..3cb984e 100644
--- a/modules/access/screen/screen.c
+++ b/modules/access/screen/screen.c
@@ -73,6 +73,13 @@
"Follow the mouse when capturing a subscreen." )
#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 void Close( vlc_object_t * );
@@ -101,6 +108,11 @@ vlc_module_begin();
FOLLOW_MOUSE_LONGTEXT, true );
#endif
+#ifdef SCREEN_MOUSE
+ add_string( "screen-mouse-image", "", NULL, MOUSE_TEXT, MOUSE_LONGTEXT,
+ true );
+#endif
+
#ifdef WIN32
add_integer( "screen-fragment-size", 0, NULL, FRAGS_TEXT,
FRAGS_LONGTEXT, true );
@@ -189,6 +201,30 @@ static int Open( vlc_object_t *p_this )
}
#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 );
return VLC_SUCCESS;
@@ -203,6 +239,10 @@ static void Close( vlc_object_t *p_this )
demux_sys_t *p_sys = p_demux->p_sys;
screen_CloseCapture( p_demux );
+#ifdef SCREEN_MOUSE
+ if( p_sys->p_mouse )
+ picture_Release( p_sys->p_mouse );
+#endif
free( p_sys );
}
diff --git a/modules/access/screen/screen.h b/modules/access/screen/screen.h
index d3b1299..be86163 100644
--- a/modules/access/screen/screen.h
+++ b/modules/access/screen/screen.h
@@ -27,6 +27,11 @@
#if !defined( HAVE_WIN32 ) && !defined( HAVE_BEOS ) && !defined( HAVE_DARWIN )
# define SCREEN_SUBSCREEN
+# define SCREEN_MOUSE
+#endif
+
+#ifdef SCREEN_MOUSE
+# include <vlc_image.h>
#endif
typedef struct screen_data_t screen_data_t;
@@ -51,6 +56,13 @@ struct demux_sys_t
unsigned int i_width;
#endif
+#ifdef SCREEN_MOUSE
+ picture_t *p_mouse;
+ filter_t *p_blend;
+ picture_t src;
+ picture_t dst;
+#endif
+
screen_data_t *p_data;
};
diff --git a/modules/access/screen/x11.c b/modules/access/screen/x11.c
index f576096..f20a382 100644
--- a/modules/access/screen/x11.c
+++ b/modules/access/screen/x11.c
@@ -82,9 +82,12 @@ int screen_InitCapture( demux_t *p_demux )
}
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_visible_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_chroma = i_chroma;
#if 0
win_info.visual->red_mask;
@@ -102,6 +105,12 @@ int screen_CloseCapture( demux_t *p_demux )
Display *p_display = (Display *)p_sys->p_data;
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;
}
@@ -112,25 +121,28 @@ block_t *screen_Capture( demux_t *p_demux )
block_t *p_block;
XImage *image;
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;
- int root_x, root_y;
int win_x, win_y;
unsigned int mask;
if( XQueryPointer( p_display, root,
&root, &child, &root_x, &root_y, &win_x, &win_y,
&mask ) )
{
- root_x -= p_sys->i_width/2;
- if( root_x < 0 ) root_x = 0;
- p_sys->i_left = __MIN( (unsigned int)root_x,
- p_sys->i_screen_width - p_sys->i_width );
- root_y -= p_sys->i_height/2;
- 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 );
+ if( p_sys->b_follow_mouse )
+ {
+ root_x -= p_sys->i_width/2;
+ if( root_x < 0 ) root_x = 0;
+ p_sys->i_left = __MIN( (unsigned int)root_x,
+ p_sys->i_screen_width - p_sys->i_width );
+ root_y -= p_sys->i_height/2;
+ 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
msg_Dbg( p_demux, "XQueryPointer() failed" );
@@ -156,7 +168,65 @@ block_t *screen_Capture( demux_t *p_demux )
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 );
More information about the vlc-devel
mailing list