]> git.sesse.net Git - vlc/commitdiff
Add mouse cursor drawing support in x11 screen.
authorAntoine Cellerier <dionoea@videolan.org>
Thu, 4 Sep 2008 16:00:09 +0000 (18:00 +0200)
committerAntoine Cellerier <dionoea@videolan.org>
Thu, 4 Sep 2008 16:00:29 +0000 (18:00 +0200)
NEWS
modules/access/screen/screen.c
modules/access/screen/screen.h
modules/access/screen/x11.c

diff --git a/NEWS b/NEWS
index e3b41566c2a8ee26e7f5cf0f1a92ee3835545875..5a8ace12a020009626228c0c31d2819bec2292ee 100644 (file)
--- 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
 
index 6f92341657e05a0b5ac8a1a72a593b7201b2c198..3cb984e4793fc157990da5705e90e7901a590581 100644 (file)
     "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 );
 }
 
index d3b1299625374c6efdb36ba9cca505d79a3828b3..be861635d18ca382d3d27e720e40db755e49968f 100644 (file)
 
 #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;
 };
 
index f576096785f298fc9ddbfb3003da9e6b25507401..f20a38208284e285730ed89180a0d3c416ea2ab7 100644 (file)
@@ -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 );