1 /*****************************************************************************
2 * specific.c: OS/2 specific features
3 *****************************************************************************
4 * Copyright (C) 2010 KO Myung-Hun
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
25 #include <vlc_common.h>
26 #include "../libvlc.h"
27 #include <vlc_playlist.h>
28 #include <vlc_input.h>
29 #include <vlc_interface.h>
35 #define VLC_IPC_PIPE "\\PIPE\\VLC\\IPC\\"VERSION
37 #define IPC_CMD_GO 0x00
38 #define IPC_CMD_ENQUEUE 0x01
39 #define IPC_CMD_QUIT 0xFF
41 extern int _fmode_bin
;
43 static HPIPE hpipeIPC
= NULLHANDLE
;
44 static int tidIPCFirst
= -1;
45 static int tidIPCHelper
= -1;
47 static void IPCHelperThread( void *arg
)
49 libvlc_int_t
*libvlc
= arg
;
58 /* Add files to the playlist */
59 playlist_t
*p_playlist
;
63 DosConnectNPipe( hpipeIPC
);
66 DosRead( hpipeIPC
, &ulCmd
, sizeof( ulCmd
), &cbActual
);
67 if( ulCmd
== IPC_CMD_QUIT
)
70 /* Read a count of arguments */
71 DosRead( hpipeIPC
, &i_argc
, sizeof( i_argc
), &cbActual
);
73 ppsz_argv
= malloc( i_argc
* sizeof( *ppsz_argv
));
75 for( int i_opt
= 0; i_opt
< i_argc
; i_opt
++ )
77 /* Read a length of argv */
78 DosRead( hpipeIPC
, &i_len
, sizeof( i_len
), &cbActual
);
80 ppsz_argv
[ i_opt
] = malloc( i_len
);
83 DosRead( hpipeIPC
, ppsz_argv
[ i_opt
], i_len
, &cbActual
);
86 p_playlist
= libvlc_priv(libvlc
)->playlist
;
88 for( int i_opt
= 0; i_opt
< i_argc
;)
92 /* Count the input options */
93 while( i_opt
+ i_options
+ 1 < i_argc
&&
94 *ppsz_argv
[ i_opt
+ i_options
+ 1 ] == ':' )
100 playlist_AddExt( p_playlist
, ppsz_argv
[ i_opt
], NULL
,
102 (( i_opt
|| ulCmd
== IPC_CMD_ENQUEUE
) ?
104 PLAYLIST_END
, -1, i_options
,
106 ( i_options
? &ppsz_argv
[ i_opt
+ 1 ] :
108 VLC_INPUT_OPTION_TRUSTED
,
112 for( ; i_options
>= 0; i_options
-- )
113 free( ppsz_argv
[ i_opt
++ ]);
117 } while( !DosDisConnectNPipe( hpipeIPC
) && ulCmd
!= IPC_CMD_QUIT
);
119 DosClose( hpipeIPC
);
120 hpipeIPC
= NULLHANDLE
;
126 void system_Init( void )
128 /* Set the default file-translation mode */
130 setmode( fileno( stdin
), O_BINARY
); /* Needed for pipes */
133 void system_Configure( libvlc_int_t
*p_this
, int i_argc
, const char *const ppsz_argv
[] )
135 if( var_InheritBool( p_this
, "high-priority" ) )
137 if( !DosSetPriority( PRTYS_PROCESS
, PRTYC_REGULAR
, PRTYD_MAXIMUM
, 0 ) )
139 msg_Dbg( p_this
, "raised process priority" );
143 msg_Dbg( p_this
, "could not raise process priority" );
147 if( var_InheritBool( p_this
, "one-instance" )
148 || ( var_InheritBool( p_this
, "one-instance-when-started-from-file" )
149 && var_InheritBool( p_this
, "started-from-file" ) ) )
155 msg_Info( p_this
, "one instance mode ENABLED");
157 /* Use a named pipe to check if another instance is already running */
160 rc
= DosOpen( VLC_IPC_PIPE
, &hpipe
, &ulAction
, 0, 0,
161 OPEN_ACTION_OPEN_IF_EXISTS
,
162 OPEN_ACCESS_READWRITE
| OPEN_SHARE_DENYREADWRITE
|
163 OPEN_FLAGS_FAIL_ON_ERROR
,
166 if( rc
== ERROR_PIPE_BUSY
)
167 DosWaitNPipe( VLC_IPC_PIPE
, -1 );
174 rc
= DosCreateNPipe( VLC_IPC_PIPE
, &hpipeIPC
,
176 NP_WAIT
| NP_TYPE_MESSAGE
|
177 NP_READMODE_MESSAGE
| 0x01,
181 /* Failed to create a named pipe. Just ignore the option and
182 * go on as normal. */
183 msg_Err( p_this
, "one instance mode DISABLED "
184 "(a named pipe couldn't be created)" );
188 /* We are the 1st instance. */
190 /* Save the tid of the first instance */
191 tidIPCFirst
= _gettid();
193 /* Run the helper thread */
194 tidIPCHelper
= _beginthread( IPCHelperThread
, NULL
, 1024 * 1024,
196 if( tidIPCHelper
== -1 )
198 msg_Err( p_this
, "one instance mode DISABLED "
199 "(IPC helper thread couldn't be created)");
206 /* Another instance is running */
207 ULONG ulCmd
= var_InheritBool( p_this
, "playlist-enqueue") ?
208 IPC_CMD_ENQUEUE
: IPC_CMD_GO
;
211 /* Write a command */
212 DosWrite( hpipe
, &ulCmd
, sizeof( ulCmd
), &cbActual
);
214 /* We assume that the remaining parameters are filenames
215 * and their input options */
217 /* Write a count of arguments */
218 DosWrite( hpipe
, &i_argc
, sizeof( i_argc
), &cbActual
);
220 for( int i_opt
= 0; i_opt
< i_argc
; i_opt
++ )
222 /* We need to resolve relative paths in this instance */
224 if( strstr( ppsz_argv
[ i_opt
], "://" ))
225 mrl
= strdup( ppsz_argv
[ i_opt
] );
227 mrl
= vlc_path2uri( ppsz_argv
[ i_opt
], NULL
);
230 mrl
= ( char * )ppsz_argv
[ i_opt
];
232 size_t i_len
= strlen( mrl
) + 1;
234 /* Write a length of an argument */
235 DosWrite( hpipe
, &i_len
, sizeof( i_len
), &cbActual
);
237 /* Write an argument */
238 DosWrite( hpipe
, mrl
, i_len
, &cbActual
);
240 if( mrl
!= ppsz_argv
[ i_opt
])
244 /* Close a named pipe of a client side */
255 * Cleans up after system_Init() and system_Configure().
257 void system_End(void)
259 if( tidIPCFirst
== _gettid())
268 rc
= DosOpen( VLC_IPC_PIPE
, &hpipe
, &ulAction
, 0, 0,
269 OPEN_ACTION_OPEN_IF_EXISTS
,
270 OPEN_ACCESS_READWRITE
| OPEN_SHARE_DENYREADWRITE
|
271 OPEN_FLAGS_FAIL_ON_ERROR
,
274 if( rc
== ERROR_PIPE_BUSY
)
275 DosWaitNPipe( VLC_IPC_PIPE
, -1 );
280 /* Ask for IPCHelper to quit */
281 ULONG ulCmd
= IPC_CMD_QUIT
;
282 DosWrite( hpipe
, &ulCmd
, sizeof( ulCmd
), &cbActual
);
286 TID tid
= tidIPCHelper
;
287 DosWaitThread( &tid
, DCWW_WAIT
);