[vlc-devel] [PATCH] os2: implement one-instance feature
KO Myung-Hun
komh78 at gmail.com
Wed Nov 14 15:21:56 CET 2012
Back ports to 2.0 tree
KO Myung-Hun wrote:
>
>
> Jean-Baptiste Kempf wrote:
>> On 12 Nov, KO Myung-Hun wrote :
>>> If file manager is ok for Win32 as well, I'm ok.
>>
>> Of course...
>>
>
> Ok.
>
>
>
> 0001-os2-implement-one-instance-feature.patch
>
>
> From dd49eb83f985c9318072f3b627a2ff4ee9aeb78c Mon Sep 17 00:00:00 2001
> From: KO Myung-Hun <komh at chollian.net>
> Date: Sun, 11 Nov 2012 15:04:13 +0900
> Subject: [PATCH] os2: implement one-instance feature
>
> ---
> src/libvlc-module.c | 6 +-
> src/libvlc.c | 2 +-
> src/libvlc.h | 4 +-
> src/os2/specific.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> 4 files changed, 242 insertions(+), 6 deletions(-)
>
> diff --git a/src/libvlc-module.c b/src/libvlc-module.c
> index 7dd880b..cb92202 100644
> --- a/src/libvlc-module.c
> +++ b/src/libvlc-module.c
> @@ -1078,12 +1078,12 @@ static const char *const ppsz_prefres[] = {
> "Log all VLC messages to syslog (UNIX systems)." )
>
> #define ONEINSTANCE_TEXT N_("Allow only one running instance")
> -#if defined( WIN32 )
> +#if defined( WIN32 ) || defined( __OS2__ )
> #define ONEINSTANCE_LONGTEXT N_( \
> "Allowing only one running instance of VLC can sometimes be useful, " \
> "for example if you associated VLC with some media types and you " \
> "don't want a new instance of VLC to be opened each time you " \
> - "double-click on a file in the explorer. This option will allow you " \
> + "open a file in your file manager. This option will allow you " \
> "to play the file with the already running instance or enqueue it.")
> #elif defined( HAVE_DBUS )
> #define ONEINSTANCE_LONGTEXT N_( \
> @@ -2044,7 +2044,7 @@ vlc_module_begin ()
> add_bool( "playlist-autostart", true,
> AUTOSTART_TEXT, AUTOSTART_LONGTEXT, false )
> add_bool( "playlist-cork", true, CORK_TEXT, CORK_LONGTEXT, false )
> -#if defined(WIN32) || defined(HAVE_DBUS)
> +#if defined(WIN32) || defined(HAVE_DBUS) || defined(__OS2__)
> add_bool( "one-instance", 0, ONEINSTANCE_TEXT,
> ONEINSTANCE_LONGTEXT, true )
> add_bool( "started-from-file", 0, STARTEDFROMFILE_TEXT,
> diff --git a/src/libvlc.c b/src/libvlc.c
> index 65e27fe..7dd511b 100644
> --- a/src/libvlc.c
> +++ b/src/libvlc.c
> @@ -662,7 +662,7 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
> module_EndBank (true);
>
> vlc_DeinitActions( p_libvlc, priv->actions );
> -#ifdef WIN32
> +#if defined(WIN32) || defined(__OS2__)
> system_End( );
> #endif
> }
> diff --git a/src/libvlc.h b/src/libvlc.h
> index 5d557c8..4392f48 100644
> --- a/src/libvlc.h
> +++ b/src/libvlc.h
> @@ -41,10 +41,12 @@ size_t vlc_towc (const char *str, uint32_t *restrict pwc);
> */
> void system_Init ( void );
> void system_Configure ( libvlc_int_t *, int, const char *const [] );
> -#ifdef WIN32
> +#if defined(WIN32) || defined(__OS2__)
> void system_End(void);
> +#ifndef __OS2__
> size_t EnumClockSource( vlc_object_t *, const char *, char ***, char *** );
> #endif
> +#endif
> void vlc_CPU_init(void);
> void vlc_CPU_dump(vlc_object_t *);
>
> diff --git a/src/os2/specific.c b/src/os2/specific.c
> index 9cc2e09..c76f52e 100644
> --- a/src/os2/specific.c
> +++ b/src/os2/specific.c
> @@ -24,12 +24,99 @@
>
> #include <vlc_common.h>
> #include "../libvlc.h"
> +#include <vlc_playlist.h>
> +#include <vlc_url.h>
>
> #include <fcntl.h>
> #include <io.h>
>
> +#define VLC_IPC_PIPE "\\PIPE\\VLC\\IPC\\"VERSION
> +
> +#define IPC_CMD_GO 0x00
> +#define IPC_CMD_ENQUEUE 0x01
> +#define IPC_CMD_QUIT 0xFF
> +
> extern int _fmode_bin;
>
> +static HPIPE hpipeIPC = NULLHANDLE;
> +static int tidIPCFirst = -1;
> +static int tidIPCHelper = -1;
> +
> +static void IPCHelperThread( void *arg )
> +{
> + vlc_object_t *p_this = arg;
> +
> + ULONG ulCmd;
> + int i_argc;
> + char **ppsz_argv;
> + size_t i_len;
> + ULONG cbActual;
> + int i_options;
> +
> + /* Add files to the playlist */
> + playlist_t *p_playlist = pl_Get( p_this );
> +
> + do
> + {
> + DosConnectNPipe( hpipeIPC );
> +
> + /* Read command */
> + DosRead( hpipeIPC, &ulCmd, sizeof( ulCmd ), &cbActual );
> + if( ulCmd == IPC_CMD_QUIT )
> + continue;
> +
> + /* Read a count of arguments */
> + DosRead( hpipeIPC, &i_argc, sizeof( i_argc ), &cbActual );
> +
> + ppsz_argv = malloc( i_argc * sizeof( *ppsz_argv ));
> +
> + for( int i_opt = 0; i_opt < i_argc; i_opt++ )
> + {
> + /* Read a length of argv */
> + DosRead( hpipeIPC, &i_len, sizeof( i_len ), &cbActual );
> +
> + ppsz_argv[ i_opt ] = malloc( i_len );
> +
> + /* Read argv */
> + DosRead( hpipeIPC, ppsz_argv[ i_opt ], i_len, &cbActual );
> + }
> +
> + for( int i_opt = 0; i_opt < i_argc;)
> + {
> + i_options = 0;
> +
> + /* Count the input options */
> + while( i_opt + i_options + 1 < i_argc &&
> + *ppsz_argv[ i_opt + i_options + 1 ] == ':' )
> + i_options++;
> +
> + playlist_AddExt( p_playlist, ppsz_argv[ i_opt ], NULL,
> + PLAYLIST_APPEND |
> + (( i_opt || ulCmd == IPC_CMD_ENQUEUE ) ?
> + 0 : PLAYLIST_GO ),
> + PLAYLIST_END, -1, i_options,
> + ( char const ** )
> + ( i_options ? &ppsz_argv[ i_opt + 1 ] :
> + NULL ),
> + VLC_INPUT_OPTION_TRUSTED,
> + true, pl_Unlocked );
> +
> + for( ; i_options >= 0; i_options-- )
> + free( ppsz_argv[ i_opt++ ]);
> + }
> +
> + free( ppsz_argv );
> + } while( !DosDisConnectNPipe( hpipeIPC ) && ulCmd != IPC_CMD_QUIT );
> +
> + vlc_object_release( p_this );
> +
> + DosClose( hpipeIPC );
> + hpipeIPC = NULLHANDLE;
> +
> + tidIPCFirst = -1;
> + tidIPCHelper = -1;
> +}
> +
> void system_Init( void )
> {
> /* Set the default file-translation mode */
> @@ -39,7 +126,6 @@ void system_Init( void )
>
> void system_Configure( libvlc_int_t *p_this, int i_argc, const char *const ppsz_argv[] )
> {
> - VLC_UNUSED( i_argc ); VLC_UNUSED( ppsz_argv );
> if( var_InheritBool( p_this, "high-priority" ) )
> {
> if( !DosSetPriority( PRTYS_PROCESS, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 ) )
> @@ -51,4 +137,152 @@ void system_Configure( libvlc_int_t *p_this, int i_argc, const char *const ppsz_
> msg_Dbg( p_this, "could not raise process priority" );
> }
> }
> +
> + if( var_InheritBool( p_this, "one-instance" )
> + || ( var_InheritBool( p_this, "one-instance-when-started-from-file" )
> + && var_InheritBool( p_this, "started-from-file" ) ) )
> + {
> + HPIPE hpipe;
> + ULONG ulAction;
> + ULONG rc;
> +
> + msg_Info( p_this, "one instance mode ENABLED");
> +
> + /* Use a named pipe to check if another instance is already running */
> + for(;;)
> + {
> + rc = DosOpen( VLC_IPC_PIPE, &hpipe, &ulAction, 0, 0,
> + OPEN_ACTION_OPEN_IF_EXISTS,
> + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE |
> + OPEN_FLAGS_FAIL_ON_ERROR,
> + NULL );
> +
> + if( rc == ERROR_PIPE_BUSY )
> + DosWaitNPipe( VLC_IPC_PIPE, -1 );
> + else
> + break;
> + }
> +
> + if( rc )
> + {
> + rc = DosCreateNPipe( VLC_IPC_PIPE, &hpipeIPC,
> + NP_ACCESS_DUPLEX,
> + NP_WAIT | NP_TYPE_MESSAGE |
> + NP_READMODE_MESSAGE | 0x01,
> + 32768, 32768, 0 );
> + if( rc )
> + {
> + /* Failed to create a named pipe. Just ignore the option and
> + * go on as normal. */
> + msg_Err( p_this, "one instance mode DISABLED "
> + "(a named pipe couldn't be created)" );
> + return;
> + }
> +
> + /* We are the 1st instance. */
> + vlc_object_t* p_helper = vlc_custom_create( p_this,
> + sizeof( *p_helper ),
> + "ipc helper" );
> +
> + /* Save the tid of the first instance */
> + tidIPCFirst = _gettid();
> +
> + /* Run the helper thread */
> + tidIPCHelper = _beginthread( IPCHelperThread, NULL, 1024 * 1024,
> + p_helper );
> + if( tidIPCHelper == -1 )
> + {
> + msg_Err( p_this, "one instance mode DISABLED "
> + "(IPC helper thread couldn't be created)");
> + vlc_object_release( p_helper );
> +
> + tidIPCFirst = -1;
> + }
> + }
> + else
> + {
> + /* Another instance is running */
> + ULONG ulCmd = var_InheritBool( p_this, "playlist-enqueue") ?
> + IPC_CMD_ENQUEUE : IPC_CMD_GO;
> + ULONG cbActual;
> +
> + /* Write a command */
> + DosWrite( hpipe, &ulCmd, sizeof( ulCmd ), &cbActual );
> +
> + /* We assume that the remaining parameters are filenames
> + * and their input options */
> +
> + /* Write a count of arguments */
> + DosWrite( hpipe, &i_argc, sizeof( i_argc ), &cbActual );
> +
> + for( int i_opt = 0; i_opt < i_argc; i_opt++ )
> + {
> + /* We need to resolve relative paths in this instance */
> + char *mrl;
> + if( strstr( ppsz_argv[ i_opt ], "://" ))
> + mrl = strdup( ppsz_argv[ i_opt ] );
> + else
> + mrl = vlc_path2uri( ppsz_argv[ i_opt ], NULL );
> +
> + if( !mrl )
> + mrl = ( char * )ppsz_argv[ i_opt ];
> +
> + size_t i_len = strlen( mrl ) + 1;
> +
> + /* Write a length of an argument */
> + DosWrite( hpipe, &i_len, sizeof( i_len ), &cbActual );
> +
> + /* Write an argument */
> + DosWrite( hpipe, mrl, i_len, &cbActual );
> +
> + if( mrl != ppsz_argv[ i_opt ])
> + free( mrl );
> + }
> +
> + /* Close a named pipe of a client side */
> + DosClose( hpipe );
> +
> + /* Bye bye */
> + system_End();
> + exit( 0 );
> + }
> + }
> }
> +
> +/**
> + * Cleans up after system_Init() and system_Configure().
> + */
> +void system_End(void)
> +{
> + if( tidIPCFirst == _gettid())
> + {
> + HPIPE hpipe;
> + ULONG ulAction;
> + ULONG cbActual;
> + ULONG rc;
> +
> + do
> + {
> + rc = DosOpen( VLC_IPC_PIPE, &hpipe, &ulAction, 0, 0,
> + OPEN_ACTION_OPEN_IF_EXISTS,
> + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE |
> + OPEN_FLAGS_FAIL_ON_ERROR,
> + NULL );
> +
> + if( rc == ERROR_PIPE_BUSY )
> + DosWaitNPipe( VLC_IPC_PIPE, -1 );
> + else if( rc )
> + DosSleep( 1 );
> + } while( rc );
> +
> + /* Ask for IPCHelper to quit */
> + ULONG ulCmd = IPC_CMD_QUIT;
> + DosWrite( hpipe, &ulCmd, sizeof( ulCmd ), &cbActual );
> +
> + DosClose( hpipe );
> +
> + TID tid = tidIPCHelper;
> + DosWaitThread( &tid, DCWW_WAIT );
> + }
> +}
> +
>
>
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> http://mailman.videolan.org/listinfo/vlc-devel
--
KO Myung-Hun
Using Mozilla SeaMonkey 2.7.2
Under OS/2 Warp 4 for Korean with FixPak #15
In VirtualBox v4.1.22 on Intel Core i7-3615QM 2.30GHz with 8GB RAM
Korean OS/2 User Community : http://www.ecomstation.co.kr
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 0001-OS-2-implement-one-instance-feature.patch
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20121114/e4979f78/attachment.ksh>
More information about the vlc-devel
mailing list