#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_vout.h>
+#include <assert.h>
#include "filter_common.h"
static void RemoveAllVout ( vout_thread_t *p_vout );
-static int SendEvents( vlc_object_t *, char const *,
+static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
+static int FullscreenEventUp( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
+static int FullscreenEventDown( vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void * );
/*****************************************************************************
* Module descriptor
#define CFG_PREFIX "wall-"
-vlc_module_begin();
- set_description( N_("Wall video filter") );
- set_shortname( N_("Image wall" ));
- set_capability( "video filter", 0 );
- set_category( CAT_VIDEO );
- set_subcategory( SUBCAT_VIDEO_VFILTER );
+vlc_module_begin ()
+ set_description( N_("Wall video filter") )
+ set_shortname( N_("Image wall" ))
+ set_capability( "video filter", 0 )
+ set_category( CAT_VIDEO )
+ set_subcategory( SUBCAT_VIDEO_VFILTER )
- add_integer( CFG_PREFIX "cols", 3, NULL, COLS_TEXT, COLS_LONGTEXT, false );
- add_integer( CFG_PREFIX "rows", 3, NULL, ROWS_TEXT, ROWS_LONGTEXT, false );
+ add_integer( CFG_PREFIX "cols", 3, NULL, COLS_TEXT, COLS_LONGTEXT, false )
+ add_integer( CFG_PREFIX "rows", 3, NULL, ROWS_TEXT, ROWS_LONGTEXT, false )
add_string( CFG_PREFIX "active", NULL, NULL, ACTIVE_TEXT, ACTIVE_LONGTEXT,
- true );
- add_string( CFG_PREFIX "element-aspect", "4:3", NULL, ASPECT_TEXT, ASPECT_LONGTEXT, false );
+ true )
+ add_string( CFG_PREFIX "element-aspect", "4:3", NULL, ASPECT_TEXT, ASPECT_LONGTEXT, false )
- add_shortcut( "wall" );
- set_callbacks( Create, Destroy );
-vlc_module_end();
+ add_shortcut( "wall" )
+ set_callbacks( Create, Destroy )
+vlc_module_end ()
static const char *const ppsz_filter_options[] = {
"cols", "rows", "active", "element-aspect", NULL
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
- {
- msg_Err( p_vout, "out of memory" );
return VLC_ENOMEM;
- }
p_vout->pf_init = Init;
p_vout->pf_end = End;
sizeof(struct vout_list_t) );
if( p_vout->p_sys->pp_vout == NULL )
{
- msg_Err( p_vout, "out of memory" );
free( p_vout->p_sys );
return VLC_ENOMEM;
}
*****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
- int i_index, i_row, i_col, i_width, i_height, i_left, i_top;
+ int i_row, i_col, i_width, i_height, i_left, i_top;
unsigned int i_target_width,i_target_height;
- picture_t *p_pic;
video_format_t fmt;
int i_aspect = 4*VOUT_ASPECT_FACTOR/3;
int i_align = 0;
{
msg_Warn( p_vout, "invalid aspect ratio specification" );
}
- free( psz_aspect );
}
+ free( psz_aspect );
i_xpos = var_CreateGetInteger( p_vout, "video-x" );
i_ypos = var_CreateGetInteger( p_vout, "video-y" );
w1 &= ~1;
h1 = w1 * VOUT_ASPECT_FACTOR / i_aspect&~1;
h1 &= ~1;
-
+
h2 = p_vout->output.i_height / p_vout->p_sys->i_row&~1;
h2 &= ~1;
w2 = h2 * i_aspect / VOUT_ASPECT_FACTOR&~1;
w2 &= ~1;
-
+
if ( h1 * p_vout->p_sys->i_row < p_vout->output.i_height )
{
unsigned int i_tmp;
p_vout->p_sys->i_vout = 0;
msg_Dbg( p_vout, "target window (%d,%d)-(%d,%d)", i_hstart,i_vstart,i_hend,i_vend );
-
+
i_top = 0;
i_height = 0;
i_align |= VOUT_ALIGN_RIGHT;
}
}
-
+
if( i_row * i_target_height >= i_vstart &&
( i_row + 1 ) * i_target_height <= i_vend )
{
RemoveAllVout( p_vout );
return VLC_EGENERIC;
}
- ADD_CALLBACKS(
- p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout,
- SendEvents );
+ vout_filter_SetupChild( p_vout, p_vout->p_sys->pp_vout[p_vout->p_sys->i_vout].p_vout,
+ MouseEvent, FullscreenEventUp, FullscreenEventDown, true );
p_vout->p_sys->i_vout++;
}
}
- ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
-
- ADD_PARENT_CALLBACKS( SendEventsToChild );
+ vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
return VLC_SUCCESS;
}
*****************************************************************************/
static void End( vout_thread_t *p_vout )
{
- int i_index;
+ RemoveAllVout( p_vout );
- /* Free the fake output buffers we allocated */
- for( i_index = I_OUTPUTPICTURES ; i_index ; )
- {
- i_index--;
- free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
- }
+ vout_filter_ReleaseDirectBuffers( p_vout );
}
/*****************************************************************************
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
- RemoveAllVout( p_vout );
-
- DEL_PARENT_CALLBACKS( SendEventsToChild );
free( p_vout->p_sys->pp_vout );
free( p_vout->p_sys );
0, 0, 0 )
) == NULL )
{
- if( p_vout->b_die || p_vout->b_error )
+ if( !vlc_object_alive (p_vout) || p_vout->b_error )
{
vout_DestroyPicture(
p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic );
msleep( VOUT_OUTMEM_SLEEP );
}
+ p_outpic->date = p_pic->date;
- vout_DatePicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout,
- p_outpic, p_pic->date );
vout_LinkPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout,
p_outpic );
*****************************************************************************/
static void RemoveAllVout( vout_thread_t *p_vout )
{
- while( p_vout->p_sys->i_vout )
+ vout_sys_t *p_sys = p_vout->p_sys;
+
+ while( p_sys->i_vout )
{
- --p_vout->p_sys->i_vout;
- if( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].b_active )
- {
- DEL_CALLBACKS(
- p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout,
- SendEvents );
- vlc_object_detach(
- p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout );
- vout_Destroy(
- p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout );
- }
+ p_sys->i_vout--;
+ if( p_sys->pp_vout[p_sys->i_vout ].b_active )
+ {
+ vout_filter_SetupChild( p_vout, p_sys->pp_vout[p_sys->i_vout].p_vout,
+ MouseEvent, FullscreenEventUp, FullscreenEventDown, false );
+ vout_CloseAndRelease( p_sys->pp_vout[p_sys->i_vout].p_vout );
+ }
}
}
-/*****************************************************************************
- * SendEvents: forward mouse and keyboard events to the parent p_vout
- *****************************************************************************/
-static int SendEvents( vlc_object_t *p_this, char const *psz_var,
- vlc_value_t oldval, vlc_value_t newval, void *_p_vout )
+/**
+ * Forward mouse event with proper conversion.
+ */
+static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
+ vout_thread_t *p_vout = p_data;
+ vout_sys_t *p_sys = p_vout->p_sys;
VLC_UNUSED(oldval);
- vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
int i_vout;
- vlc_value_t sentval = newval;
/* Find the video output index */
- for( i_vout = 0; i_vout < p_vout->p_sys->i_vout; i_vout++ )
+ for( i_vout = 0; i_vout < p_sys->i_vout; i_vout++ )
{
- if( p_this == (vlc_object_t *)p_vout->p_sys->pp_vout[ i_vout ].p_vout )
- {
+ if( p_sys->pp_vout[i_vout].b_active &&
+ p_this == VLC_OBJECT(p_sys->pp_vout[i_vout].p_vout) )
break;
- }
- }
-
- if( i_vout == p_vout->p_sys->i_vout )
- {
- return VLC_EGENERIC;
}
+ assert( i_vout < p_vout->p_sys->i_vout );
/* Translate the mouse coordinates */
if( !strcmp( psz_var, "mouse-x" ) )
- {
- sentval.i_int += p_vout->output.i_width
- * (i_vout % p_vout->p_sys->i_col)
- / p_vout->p_sys->i_col;
- }
+ newval.i_int += p_vout->output.i_width * (i_vout % p_sys->i_col) / p_sys->i_col;
else if( !strcmp( psz_var, "mouse-y" ) )
+ newval.i_int += p_vout->output.i_height * (i_vout / p_sys->i_row) / p_sys->i_row;
+
+ return var_Set( p_vout, psz_var, newval );
+}
+
+/**
+ * Forward fullscreen event to/from the childrens.
+ */
+static bool IsFullscreenActive( vout_thread_t *p_vout )
+{
+ vout_sys_t *p_sys = p_vout->p_sys;
+ for( int i = 0; i < p_sys->i_vout; i++ )
{
- sentval.i_int += p_vout->output.i_height
- * (i_vout / p_vout->p_sys->i_row)
- / p_vout->p_sys->i_row;
+ if( p_sys->pp_vout[i].b_active &&
+ var_GetBool( p_sys->pp_vout[i].p_vout, "fullscreen" ) )
+ return true;
}
+ return false;
+}
+static int FullscreenEventUp( vlc_object_t *p_this, char const *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ vout_thread_t *p_vout = p_data;
+ VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(newval);
- var_Set( p_vout, psz_var, sentval );
-
+ const bool b_fullscreen = IsFullscreenActive( p_vout );
+ if( !var_GetBool( p_vout, "fullscreen" ) != !b_fullscreen )
+ return var_SetBool( p_vout, "fullscreen", b_fullscreen );
return VLC_SUCCESS;
}
-
-/*****************************************************************************
- * SendEventsToChild: forward events to the child/children vout
- *****************************************************************************/
-static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
- vlc_value_t oldval, vlc_value_t newval, void *p_data )
+static int FullscreenEventDown( vlc_object_t *p_this, char const *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
- VLC_UNUSED(p_data); VLC_UNUSED(oldval);
- vout_thread_t *p_vout = (vout_thread_t *)p_this;
- int i_row, i_col, i_vout = 0;
+ vout_thread_t *p_vout = (vout_thread_t*)p_this;
+ vout_sys_t *p_sys = p_vout->p_sys;
+ VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_var);
- for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ )
+ const bool b_fullscreen = IsFullscreenActive( p_vout );
+ if( !b_fullscreen != !newval.b_bool )
{
- for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ )
+ for( int i = 0; i < p_sys->i_vout; i++ )
{
- var_Set( p_vout->p_sys->pp_vout[ i_vout ].p_vout, psz_var, newval);
- if( !strcmp( psz_var, "fullscreen" ) ) break;
- i_vout++;
+ if( !p_sys->pp_vout[i].b_active )
+ continue;
+
+ vout_thread_t *p_child = p_sys->pp_vout[i].p_vout;
+ if( !var_GetBool( p_child, "fullscreen" ) != !newval.b_bool )
+ {
+ var_SetBool( p_child, "fullscreen", newval.b_bool );
+ if( newval.b_bool )
+ return VLC_SUCCESS;
+ }
}
}
-
return VLC_SUCCESS;
}
+