[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