-/*******************************************************************************
+/*****************************************************************************
* interface.c: interface access for other threads
- * (c)1998 VideoLAN
- *******************************************************************************
* This library provides basic functions for threads to interact with user
* interface, such as command line.
- *******************************************************************************/
-
-/*******************************************************************************
+ *****************************************************************************
+ * Copyright (C) 1998-2001 VideoLAN
+ * $Id: interface.c,v 1.97 2002/07/31 20:56:52 sam Exp $
+ *
+ * Authors: Vincent Seguin <seguin@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
* Preamble
- *******************************************************************************/
-#include <pthread.h>
-#include <stdio.h>
-#include <netinet/in.h>
-#include <sys/soundcard.h>
-#include <sys/uio.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "config.h"
-#include "common.h"
-#include "mtime.h"
-#include "thread.h"
-
-#include "input.h"
-#include "input_vlan.h"
-#include "decoder_fifo.h"
+ *****************************************************************************/
+#include <errno.h> /* ENOMEM */
+#include <stdlib.h> /* free(), strtol() */
+#include <stdio.h> /* FILE */
+#include <string.h> /* strerror() */
+#include <sys/types.h> /* off_t */
-#include "audio_output.h"
-#include "audio_decoder.h"
+#include <vlc/vlc.h>
-#include "video.h"
-#include "video_output.h"
-#include "video_decoder.h"
+#include "stream_control.h"
+#include "input_ext-intf.h"
+
+#include "audio_output.h"
-#include "xconsole.h"
#include "interface.h"
-#include "intf_msg.h"
-#include "intf_cmd.h"
-#include "pgm_data.h"
-/* ?? remove useless headers */
+#include "video.h"
+#include "video_output.h"
-/*
+/*****************************************************************************
* Local prototypes
- */
-static int StartInterface ( intf_thread_t *p_intf );
-static void EndInterface ( intf_thread_t *p_intf );
-
-/*******************************************************************************
- * intf_Run
- *******************************************************************************
- * what it does:
- * - Create an X11 console
- * - wait for a command and try to execute it
- * - interpret the order returned after the command execution
- * - print the messages of the message queue (intf_FlushMsg)
- * return value: 0 if successful, < 0 otherwise
- *******************************************************************************/
-int intf_Run( intf_thread_t *p_intf )
+ *****************************************************************************/
+static void Manager( intf_thread_t *p_intf );
+
+/*****************************************************************************
+ * intf_Create: prepare interface before main loop
+ *****************************************************************************
+ * This function opens output devices and creates specific interfaces. It sends
+ * its own error messages.
+ *****************************************************************************/
+intf_thread_t* __intf_Create( vlc_object_t *p_this )
{
- /* When it is started, interface won't die immediatly */
- p_intf->b_die = 0;
- if( StartInterface( p_intf ) ) /* error */
+ intf_thread_t * p_intf;
+ char *psz_name;
+
+ /* Allocate structure */
+ p_intf = vlc_object_create( p_this, VLC_OBJECT_INTF );
+ if( !p_intf )
{
- return( 1 );
+ msg_Err( p_this, "out of memory" );
+ return NULL;
}
-
- /* Main loop */
- while(!p_intf->b_die)
- {
- /* Flush waiting messages */
- intf_FlushMsg();
- /* Manage specific interfaces */
- intf_ManageXConsole( &p_intf->xconsole ); /* X11 console */
+ /* Choose the best module */
+ psz_name = config_GetPsz( p_intf, "intf" );
+ p_intf->p_module = module_Need( p_intf, "interface", psz_name );
- /* Sleep to avoid using all CPU - since some interfaces needs to access
- * keyboard events, a 100ms delay is a good compromise */
- msleep( INTF_IDLE_SLEEP );
+ if( psz_name ) free( psz_name );
+ if( p_intf->p_module == NULL )
+ {
+ msg_Err( p_intf, "no suitable intf module" );
+ vlc_object_destroy( p_intf );
+ return NULL;
}
- /* End of interface thread - the main() function will close all remaining
- * output threads */
- EndInterface( p_intf );
- return ( 0 );
-}
+ /* Initialize structure */
+ p_intf->b_menu = 0;
+ p_intf->b_menu_change = 0;
-/* following functions are local */
+ /* Initialize mutexes */
+ vlc_mutex_init( p_intf, &p_intf->change_lock );
-/*******************************************************************************
- * StartInterface: prepare interface before main loop
- *******************************************************************************
- * This function opens output devices and create specific interfaces. It send
- * it's own error messages.
- *******************************************************************************/
-static int StartInterface( intf_thread_t *p_intf )
-{
- int i_thread; /* thread index */
-#ifdef AUTO_SPAWN
- int fd;
-#endif
+ msg_Dbg( p_intf, "interface initialized" );
- /* Empty all threads array */
- for( i_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
- {
- p_intf->pp_vout[i_thread] = NULL;
- }
- for( i_thread = 0; i_thread < INPUT_MAX_THREADS; i_thread++ )
+ /* Attach interface to its parent object */
+ vlc_object_attach( p_intf, p_this );
+
+ return p_intf;
+}
+
+/*****************************************************************************
+ * intf_RunThread: launch the interface thread
+ *****************************************************************************
+ * This function either creates a new thread and runs the interface in it,
+ * or runs the interface in the current thread, depending on b_block.
+ *****************************************************************************/
+vlc_error_t intf_RunThread( intf_thread_t *p_intf )
+{
+ if( p_intf->b_block )
{
- p_intf->pp_input[i_thread] = NULL;
- }
+ /* Run a manager thread, launch the interface, kill the manager */
+ if( vlc_thread_create( p_intf, "manager", Manager, 0 ) )
+ {
+ msg_Err( p_intf, "cannot spawn manager thread" );
+ return VLC_EGENERIC;
+ }
+
+ p_intf->pf_run( p_intf );
- /* Start X11 Console*/
- if( intf_OpenXConsole( &p_intf->xconsole ) )
+ p_intf->b_die = 1;
+
+ /* Do not join the thread... intf_StopThread will do it for us */
+ }
+ else
{
- intf_ErrMsg("intf error: can't open X11 console\n");
- return( 1 );
+ /* Run the interface in a separate thread */
+ if( vlc_thread_create( p_intf, "interface", p_intf->pf_run, 0 ) )
+ {
+ msg_Err( p_intf, "cannot spawn interface thread" );
+ return VLC_EGENERIC;
+ }
}
-#ifdef AUTO_SPAWN
- /* Execute the initialization script (typically spawn an input thread) */
- if ( (fd = open( INIT_SCRIPT, O_RDONLY )) != -1 )
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * intf_StopThread: end the interface thread
+ *****************************************************************************
+ * This function asks the interface thread to stop.
+ *****************************************************************************/
+void intf_StopThread( intf_thread_t *p_intf )
+{
+ /* Tell the interface to die */
+ if( !p_intf->b_block )
{
- /* Startup script does exist */
- close( fd );
- intf_ExecScript( "vlc.init" );
+ p_intf->b_die = 1;
}
-#endif
- return( 0 );
+ /* Wait for the thread to exit */
+ vlc_thread_join( p_intf );
}
-/*******************************************************************************
- * EndInterface: clean interface after main loop
- *******************************************************************************
+/*****************************************************************************
+ * intf_Destroy: clean interface after main loop
+ *****************************************************************************
* This function destroys specific interfaces and close output devices.
- *******************************************************************************/
-static void EndInterface( intf_thread_t *p_intf )
+ *****************************************************************************/
+void intf_Destroy( intf_thread_t *p_intf )
{
- int i_thread; /* thread index */
- boolean_t b_thread; /* flag for remaing threads */
- int pi_vout_status[VOUT_MAX_THREADS]; /* vout threads status */
-
-
-
- /* Close X11 console */
- intf_CloseXConsole( &p_intf->xconsole );
-
- /* Destroy all remaining input threads */
- for( i_thread = 0; i_thread < INPUT_MAX_THREADS; i_thread++ )
- {
- if( p_intf->pp_input[i_thread] != NULL )
- {
- input_DestroyThread( p_intf->pp_input[i_thread] );
- }
- }
+ /* Unlock module */
+ module_Unneed( p_intf, p_intf->p_module );
- /* Destroy all remaining video output threads - all destruction orders are send,
- * then all THREAD_OVER status are received */
- for( i_thread = 0, b_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
- {
- if( p_intf->pp_vout[i_thread] != NULL )
- {
- vout_DestroyThread( p_intf->pp_vout[i_thread], &pi_vout_status[i_thread] );
- b_thread = 1;
- }
- }
- while( b_thread )
+ vlc_mutex_destroy( &p_intf->change_lock );
+
+ /* Free structure */
+ vlc_object_destroy( p_intf );
+}
+
+/* Following functions are local */
+
+/*****************************************************************************
+ * Manager: helper thread for blocking interfaces
+ *****************************************************************************
+ * If the interface is launched in the main thread, it will not listen to
+ * p_vlc->b_die events because it is only supposed to listen to p_intf->b_die.
+ * This thread takes care of the matter.
+ *****************************************************************************/
+static void Manager( intf_thread_t *p_intf )
+{
+ while( !p_intf->b_die )
{
- msleep( INTF_IDLE_SLEEP );
- b_thread = 0;
- for( i_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
+ msleep( INTF_IDLE_SLEEP );
+
+ if( p_intf->p_vlc->b_die )
{
- if( (p_intf->pp_vout[i_thread] != NULL)
- && (pi_vout_status[i_thread] != THREAD_OVER) )
- {
- b_thread = 1;
- }
+ p_intf->b_die = 1;
+ return;
}
}
-
-
}
+