1 /*****************************************************************************
2 * rc.c : remote control stdin/stdout plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: rc.c,v 1.19 2002/06/07 23:05:03 sam Exp $
7 * Authors: Peter Surda <shurdeek@panorama.sth.ac.at>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
30 #include <errno.h> /* ENOMEM */
42 #ifdef HAVE_SYS_TIME_H
43 # include <sys/time.h>
45 #include <sys/types.h>
48 #include <winsock2.h> /* select() */
51 /*****************************************************************************
52 * intf_sys_t: description and status of rc interface
53 *****************************************************************************/
56 input_thread_t * p_input;
59 #define MAX_LINE_LENGTH 256
61 /*****************************************************************************
63 *****************************************************************************/
64 static void intf_getfunctions ( function_list_t * p_function_list );
65 static int intf_Open ( intf_thread_t *p_intf );
66 static void intf_Close ( intf_thread_t *p_intf );
67 static void intf_Run ( intf_thread_t *p_intf );
69 /*****************************************************************************
70 * Build configuration tree.
71 *****************************************************************************/
76 SET_DESCRIPTION( _("remote control interface module") )
77 ADD_CAPABILITY( INTF, 20 )
81 intf_getfunctions( &p_module->p_functions->intf );
84 MODULE_DEACTIVATE_START
85 MODULE_DEACTIVATE_STOP
87 /*****************************************************************************
88 * Functions exported as capabilities. They are declared as static so that
89 * we don't pollute the namespace too much.
90 *****************************************************************************/
91 static void intf_getfunctions( function_list_t * p_function_list )
93 p_function_list->functions.intf.pf_open = intf_Open;
94 p_function_list->functions.intf.pf_close = intf_Close;
95 p_function_list->functions.intf.pf_run = intf_Run;
98 /*****************************************************************************
99 * intf_Open: initialize and create stuff
100 *****************************************************************************/
101 static int intf_Open( intf_thread_t *p_intf )
103 /* Non-buffered stdout */
104 setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
106 /* Allocate instance and initialize some members */
107 p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
108 if( p_intf->p_sys == NULL )
110 msg_Err( p_intf, "out of memory" );
116 freopen( "CONOUT$", "w", stdout );
117 freopen( "CONOUT$", "w", stderr );
118 freopen( "CONIN$", "r", stdin );
119 printf( VERSION_MESSAGE "\n" );
122 printf( "remote control interface initialized, `h' for help\n" );
126 /*****************************************************************************
127 * intf_Close: destroy interface stuff
128 *****************************************************************************/
129 static void intf_Close( intf_thread_t *p_intf )
131 /* Destroy structure */
132 free( p_intf->p_sys );
135 /*****************************************************************************
136 * intf_Run: rc thread
137 *****************************************************************************
138 * This part of the interface is in a separate thread so that we can call
139 * exec() from within it without annoying the rest of the program.
140 *****************************************************************************/
141 static void intf_Run( intf_thread_t *p_intf )
143 char p_buffer[ MAX_LINE_LENGTH + 1 ];
144 vlc_bool_t b_complete = 0;
149 fd_set fds; /* stdin changed? */
150 struct timeval tv; /* how long to wait */
154 p_intf->p_sys->p_input = NULL;
156 while( !p_intf->b_die )
164 FD_SET( STDIN_FILENO, &fds );
166 i_dummy = select( 32, &fds, NULL, NULL, &tv );
171 while( !p_intf->b_die
172 && i_size < MAX_LINE_LENGTH
173 && read( STDIN_FILENO, p_buffer + i_size, 1 ) > 0
174 && p_buffer[ i_size ] != '\r'
175 && p_buffer[ i_size ] != '\n' )
180 if( i_size == MAX_LINE_LENGTH
181 || p_buffer[ i_size ] == '\r'
182 || p_buffer[ i_size ] == '\n' )
184 p_buffer[ i_size ] = 0;
189 /* Manage the input part */
190 if( p_intf->p_sys->p_input == NULL )
192 p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
195 else if( p_intf->p_sys->p_input->b_dead )
197 vlc_object_release( p_intf->p_sys->p_input );
198 p_intf->p_sys->p_input = NULL;
201 if( p_intf->p_sys->p_input )
203 input_thread_t *p_input = p_intf->p_sys->p_input;
206 vlc_mutex_lock( &p_input->stream.stream_lock );
207 if( !p_input->b_die && p_input->stream.i_mux_rate )
209 #define A p_input->stream.p_selected_area
210 f_ratio = 1.0 / ( 50 * p_input->stream.i_mux_rate );
211 i_newpos = A->i_tell * f_ratio;
213 if( i_oldpos != i_newpos )
216 printf( "pos: %li s / %li s\n", (long int)i_newpos,
217 (long int)(f_ratio * A->i_size) );
221 vlc_mutex_unlock( &p_input->stream.stream_lock );
224 /* Is there something to do? */
225 if( b_complete == 1 )
227 char *p_cmd = p_buffer;
233 if( p_cmd[1] == ' ' )
235 playlist_t *p_playlist;
236 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
240 playlist_Add( p_playlist, p_cmd + 2,
241 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
242 vlc_object_release( p_playlist );
249 vlc_dumpstructure( p_intf->p_vlc );
254 if( p_intf->p_sys->p_input )
256 input_SetStatus( p_intf->p_sys->p_input,
257 INPUT_STATUS_PAUSE );
263 if( p_intf->p_sys->p_input )
265 vout_thread_t *p_vout;
266 p_vout = vlc_object_find( p_intf->p_sys->p_input,
267 VLC_OBJECT_VOUT, FIND_CHILD );
271 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
272 vlc_object_release( p_vout );
284 p_intf->p_vlc->b_die = 1;
289 if( p_intf->p_sys->p_input )
292 i_dummy < MAX_LINE_LENGTH && p_cmd[ i_dummy ] >= '0'
293 && p_cmd[ i_dummy ] <= '9';
299 p_cmd[ i_dummy ] = 0;
300 input_Seek( p_intf->p_sys->p_input,
301 (off_t)atoi( p_cmd + 1 ),
302 INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
303 /* rcreseek(f_cpos); */
310 printf( "help for remote control commands\n" );
311 printf( "h . . . . . . . . . . . . . . . . . . . . . help\n" );
312 printf( "a XYZ . . . . . . . . . . append XYZ to playlist\n" );
313 printf( "p . . . . . . . . . . . . . . . . . toggle pause\n" );
314 printf( "f . . . . . . . . . . . . . . toggle fullscreen\n" );
315 printf( "r X . . . seek in seconds, for instance `r 3.5'\n" );
316 printf( "q . . . . . . . . . . . . . . . . . . . . . quit\n" );
317 printf( "end of help\n" );
321 printf( "unknown command `%s'\n", p_cmd );
326 msleep( INTF_IDLE_SLEEP );
329 if( p_intf->p_sys->p_input )
331 vlc_object_release( p_intf->p_sys->p_input );
332 p_intf->p_sys->p_input = NULL;