]> git.sesse.net Git - vlc/commitdiff
* include/os_specific.h, src/libvlc.[c,h], src/misc/win32_specific.c: new win32 speci...
authorGildas Bazin <gbazin@videolan.org>
Mon, 29 Sep 2003 17:36:35 +0000 (17:36 +0000)
committerGildas Bazin <gbazin@videolan.org>
Mon, 29 Sep 2003 17:36:35 +0000 (17:36 +0000)
 Running another vlc (with --one-instance as well) will only transfer the requested playlist items to the first instance.

include/os_specific.h
src/libvlc.c
src/libvlc.h
src/misc/beos_specific.cpp
src/misc/charset.c
src/misc/darwin_specific.m
src/misc/win32_specific.c

index c9f59aa2fb561f73ac5276b58a55074da200825b..dafab02164c66082751859a2fe61c0527a235194 100644 (file)
@@ -2,7 +2,7 @@
  * os_specific.h: OS specific features
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: os_specific.h,v 1.10 2002/11/11 14:39:11 sam Exp $
+ * $Id: os_specific.h,v 1.11 2003/09/29 17:36:34 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -45,7 +45,7 @@ extern "C" {
  *****************************************************************************/
 #ifdef _NEED_OS_SPECIFIC_H
     void system_Init       ( vlc_t *, int *, char *[] );
-    void system_Configure  ( vlc_t * );
+    void system_Configure  ( vlc_t *, int *, char *[] );
     void system_End        ( vlc_t * );
 #else
 #   define system_Init( a, b, c ) {}
index 6fee305f28074bba2224a416be18739dfd05672f..2997c6f0f899c4d8581e24c2de2bdd8a79c3cfa7 100644 (file)
@@ -2,7 +2,7 @@
  * libvlc.c: main libvlc source
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.c,v 1.96 2003/09/24 21:31:54 gbazin Exp $
+ * $Id: libvlc.c,v 1.97 2003/09/29 17:36:34 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -472,7 +472,7 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
     /*
      * System specific configuration
      */
-    system_Configure( p_vlc );
+    system_Configure( p_vlc, &i_argc, ppsz_argv );
 
     /*
      * Message queue options
index d7cd7ba18350fc273de05631f720923b876616ec..9de50aa3301bccf05f79d03b06ba64926e21c424 100644 (file)
@@ -2,7 +2,7 @@
  * libvlc.h: main libvlc header
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.h,v 1.89 2003/09/24 21:31:54 gbazin Exp $
+ * $Id: libvlc.h,v 1.90 2003/09/29 17:36:35 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -448,6 +448,14 @@ static char *ppsz_language[] = { "auto", "en", "en_GB", "de", "fr", "it", "ja",
 #define DEMUX_LONGTEXT N_( \
     "This is a legacy entry to let you configure demux modules")
 
+#define ONEINSTANCE_TEXT N_("Allow only one running instance of VLC")
+#define ONEINSTANCE_LONGTEXT N_( \
+    "Allowing only one running instance of VLC can sometimes be useful, " \
+    "for instance 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 " \
+    "to play the file with the already running instance or enqueue it.")
+
 #define HPRIORITY_TEXT N_("Increase the priority of the process")
 #define HPRIORITY_LONGTEXT N_( \
     "Increasing the priority of the process will very likely improve your " \
@@ -691,6 +699,7 @@ vlc_module_begin();
     add_module( "demux", "demux", NULL, NULL, DEMUX_TEXT, DEMUX_LONGTEXT, VLC_TRUE );
 
 #if defined(WIN32)
+    add_bool( "one-instance", 0, NULL, ONEINSTANCE_TEXT, ONEINSTANCE_LONGTEXT, VLC_TRUE );
     add_bool( "high-priority", 1, NULL, HPRIORITY_TEXT, HPRIORITY_LONGTEXT, VLC_TRUE );
     add_bool( "fast-mutex", 0, NULL, FAST_MUTEX_TEXT, FAST_MUTEX_LONGTEXT, VLC_TRUE );
     add_integer( "win9x-cv-method", 0, NULL, WIN9X_CV_TEXT, WIN9X_CV_LONGTEXT, VLC_TRUE );
index d1740e0ca22c03a91193408c40cf18936ab158ee..e8d80a021213e80e8c3af77de4db261d8cb94167 100644 (file)
@@ -2,7 +2,7 @@
  * beos_init.cpp: Initialization for BeOS specific features 
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: beos_specific.cpp,v 1.31 2003/05/08 01:05:14 titer Exp $
+ * $Id: beos_specific.cpp,v 1.32 2003/09/29 17:36:35 gbazin Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *
@@ -89,7 +89,7 @@ void system_Init( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
 /*****************************************************************************
  * system_Configure: check for system specific configuration options.
  *****************************************************************************/
-void system_Configure( vlc_t * )
+void system_Configure( vlc_t *, int *pi_argc, char *ppsz_argv[] )
 {
 
 }
index cb4611878aacb8f1996c542cfc4c62b874d1983c..2c3f2a533303a4ad8c25020f0b2a1dd1b51a1d94 100644 (file)
@@ -1,8 +1,9 @@
 /*****************************************************************************
- * charset.c: Determine a canonical name for the current locale's character encoding.
+ * charset.c: Determine a canonical name for the current locale's character
+ *            encoding.
  *****************************************************************************
  * Copyright (C) 2003 VideoLAN
- * $Id: charset.c,v 1.2 2003/08/23 22:19:07 fenrir Exp $
+ * $Id: charset.c,v 1.3 2003/09/29 17:36:35 gbazin Exp $
  *
  * Authors: Derk-Jan Hartman <thedj at users.sf.net>
  *
@@ -197,7 +198,7 @@ static const char* vlc_charset_aliases( const char *psz_name )
 }
 
 /* Returns charset from "language_COUNTRY.charset@modifier" string */
-static charvlc_encoding_from_locale( char *psz_locale )
+static char *vlc_encoding_from_locale( char *psz_locale )
 {
     char *psz_dot = strchr( psz_locale, '.' );
 
index ced3d23ff09a398ca45e985b5bb6dff42842488c..8ccbc35c6d417db9c13566a9b1c05b0daca71e87 100644 (file)
@@ -2,7 +2,7 @@
  * darwin_specific.m: Darwin specific features 
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: darwin_specific.m,v 1.13 2003/04/08 08:36:00 massiot Exp $
+ * $Id: darwin_specific.m,v 1.14 2003/09/29 17:36:35 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -116,7 +116,7 @@ void system_Init( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
 /*****************************************************************************
  * system_Configure: check for system specific configuration options.
  *****************************************************************************/
-void system_Configure( vlc_t *p_this )
+void system_Configure( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
 {
 
 }
index b49ec1400609ad4bc56f1b4c8611fc8be08a7396..f6c5f50aa715a860fbd120b8b06bf6ac5368ee43 100644 (file)
@@ -2,7 +2,7 @@
  * win32_specific.c: Win32 specific features
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: win32_specific.c,v 1.24 2003/07/31 21:46:37 gbazin Exp $
+ * $Id: win32_specific.c,v 1.25 2003/09/29 17:36:35 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Gildas Bazin <gbazin@netcourrier.com>
 #include <stdlib.h>                                                /* free() */
 
 #include <vlc/vlc.h>
+#include "vlc_playlist.h"
+
+#ifdef WIN32                       /* optind, getopt(), included in unistd.h */
+#   include "../extras/getopt.h"
+#endif
 
 #if !defined( UNDER_CE )
 #   include <fcntl.h>
@@ -108,7 +113,10 @@ void system_Init( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
 /*****************************************************************************
  * system_Configure: check for system specific configuration options.
  *****************************************************************************/
-void system_Configure( vlc_t *p_this )
+static void IPCHelperThread( vlc_object_t * );
+LRESULT CALLBACK WMCOPYWNDPROC( HWND, UINT, WPARAM, LPARAM );
+
+void system_Configure( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
 {
 #if !defined( UNDER_CE )
     p_this->p_libvlc->b_fast_mutex = config_GetInt( p_this, "fast-mutex" );
@@ -129,10 +137,204 @@ void system_Configure( vlc_t *p_this )
             msg_Dbg( p_this, "raised process priority" );
     }
     else
-       msg_Dbg( p_this, "raised process priority" );
+        msg_Dbg( p_this, "raised process priority" );
+
+    if( config_GetInt( p_this, "one-instance" ) )
+    {
+        HANDLE hmutex;
+
+        msg_Info( p_this, "One instance mode ENABLED");
+
+        /* Use a named mutex to check if another instance is already running */
+        if( ( hmutex = CreateMutex( NULL, TRUE, "VLC ipc "VERSION ) ) == NULL )
+        {
+            /* Failed for some reason. Just ignore the option and go on as
+             * normal. */
+            msg_Err( p_this, "One instance mode DISABLED "
+                     "(mutex couldn't be created)" );
+            return;
+        }
+
+        if( GetLastError() != ERROR_ALREADY_EXISTS )
+        {
+            /* We are the 1st instance. */
+            vlc_object_t *p_helper =
+             (vlc_object_t *)vlc_object_create( p_this, sizeof(vlc_object_t) );
+
+            /* Run the helper thread */
+            if( vlc_thread_create( p_helper, "IPC helper", IPCHelperThread,
+                                   VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
+            {
+                msg_Err( p_this, "One instance mode DISABLED "
+                         "(IPC helper thread couldn't be created)" );
+
+            }
+
+            /* Initialization done.
+             * Release the mutex to unblock other instances */
+            ReleaseMutex( hmutex );
+        }
+        else
+        {
+            /* Another instance is running */
+
+            HWND ipcwindow;
+
+            /* Wait until the 1st instance is initialized */
+            WaitForSingleObject( hmutex, INFINITE );
+
+            /* Locate the window created by the IPC helper thread of the
+             * 1st instance */
+            if( ( ipcwindow = FindWindow( NULL, "VLC ipc "VERSION ) )
+                == NULL )
+            {
+                msg_Err( p_this, "One instance mode DISABLED "
+                         "(couldn't find 1st instance of program)" );
+                ReleaseMutex( hmutex );
+                return;
+            }
+
+            /* We assume that the remaining parameters are filenames
+             * and their input options */
+            if( *pi_argc - 1 >= optind )
+            {
+                COPYDATASTRUCT wm_data;
+                int i_opt, i_data;
+                char *p_data;
+
+                i_data = sizeof(int);
+                for( i_opt = optind; i_opt < *pi_argc; i_opt++ )
+                {
+                    i_data += sizeof(int);
+                    i_data += strlen( ppsz_argv[ i_opt ] ) + 1;
+                }
+
+                p_data = (char *)malloc( i_data );
+                *((int *)&p_data[0]) = *pi_argc - optind;
+                i_data = sizeof(int);
+                for( i_opt = optind; i_opt < *pi_argc; i_opt++ )
+                {
+                    int i_len = strlen( ppsz_argv[ i_opt ] ) + 1;
+                    *((int *)&p_data[i_data]) = i_len;
+                    i_data += sizeof(int);
+                    memcpy( &p_data[i_data], ppsz_argv[ i_opt ], i_len );
+                    i_data += i_len;
+                }
+
+                /* Send our playlist items to the 1st instance */
+                wm_data.dwData = 0;
+                wm_data.cbData = i_data;
+                wm_data.lpData = p_data;
+                SendMessage( ipcwindow, WM_COPYDATA, 0, (LPARAM)&wm_data );
+            }
+
+            /* Initialization done.
+             * Release the mutex to unblock other instances */
+            ReleaseMutex( hmutex );
+
+            /* Bye bye */
+            system_End( p_this );
+            exit( 0 );
+        }
+    }
+
 #endif
 }
 
+static void IPCHelperThread( vlc_object_t *p_this )
+{
+    HWND ipcwindow;
+    MSG message;
+
+    ipcwindow =
+        CreateWindow( "STATIC",                      /* name of window class */
+                  "VLC ipc "VERSION,                /* window title bar text */
+                  0,                                         /* window style */
+                  0,                                 /* default X coordinate */
+                  0,                                 /* default Y coordinate */
+                  0,                                         /* window width */
+                  0,                                        /* window height */
+                  NULL,                                  /* no parent window */
+                  NULL,                            /* no menu in this window */
+                  GetModuleHandle(NULL),  /* handle of this program instance */
+                  NULL );                               /* sent to WM_CREATE */
+
+    SetWindowLong( ipcwindow, GWL_WNDPROC, (LONG)WMCOPYWNDPROC );
+    SetWindowLong( ipcwindow, GWL_USERDATA, (LONG)p_this );
+
+    /* Signal the creation of the thread and events queue */
+    vlc_thread_ready( p_this );
+
+    while( GetMessage( &message, NULL, 0, 0 ) )
+    {
+        TranslateMessage( &message );
+        DispatchMessage( &message );
+    }
+}
+
+LRESULT CALLBACK WMCOPYWNDPROC( HWND hwnd, UINT uMsg, WPARAM wParam,
+                                LPARAM lParam )
+{
+    if( uMsg == WM_COPYDATA )
+    {
+        COPYDATASTRUCT *pwm_data = (COPYDATASTRUCT*)lParam;
+        vlc_object_t *p_this;
+        playlist_t *p_playlist;
+
+        p_this = (vlc_object_t *)GetWindowLong( hwnd, GWL_USERDATA );
+
+        if( !p_this ) return 0;
+
+        /* Add files to the playlist */
+        p_playlist = (playlist_t *)vlc_object_find( p_this,
+                                                    VLC_OBJECT_PLAYLIST,
+                                                    FIND_ANYWHERE );
+        if( !p_playlist ) return 0;
+
+        if( pwm_data->lpData )
+        {
+            int i_argc, i_data, i_opt, i_options;
+            char **ppsz_argv;
+            char *p_data = (char *)pwm_data->lpData;
+
+            i_argc = *((int *)&p_data[0]);
+            ppsz_argv = (char **)malloc( i_argc * sizeof(char *) );
+            i_data = sizeof(int);
+            for( i_opt = 0; i_opt < i_argc; i_opt++ )
+            {
+                ppsz_argv[i_opt] = &p_data[i_data + sizeof(int)];
+                i_data += *((int *)&p_data[i_data]);
+                i_data += sizeof(int);
+            }
+
+            for( i_opt = 0; i_opt < i_argc; i_opt++ )
+            {
+                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_Add( p_playlist, ppsz_argv[ i_opt ],
+                    (char const **)( i_options ? &ppsz_argv[i_opt+1] : NULL ),
+                    i_options, PLAYLIST_APPEND | (i_opt? 0 : PLAYLIST_GO),
+                    PLAYLIST_END );
+
+                i_opt += i_options;
+            }
+
+            free( ppsz_argv );
+        }
+
+        vlc_object_release( p_playlist );
+    }
+
+    return DefWindowProc( hwnd, uMsg, wParam, lParam );
+}
+
 /*****************************************************************************
  * system_End: terminate winsock.
  *****************************************************************************/