[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