1 /*****************************************************************************
2 * rc.c : remote control stdin/stdout plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: rc.c,v 1.16 2002/06/01 18:04:49 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 vlc_mutex_t change_lock;
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 input_thread_t *p_input;
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 p_input = vlc_object_find( p_intf->p_vlc,
191 VLC_OBJECT_INPUT, FIND_CHILD );
196 vlc_mutex_lock( &p_input->stream.stream_lock );
197 if( !p_input->b_die && p_input->stream.i_mux_rate )
199 #define A p_input->stream.p_selected_area
200 f_ratio = 1.0 / ( 50 * p_input->stream.i_mux_rate );
201 i_newpos = A->i_tell * f_ratio;
203 if( i_oldpos != i_newpos )
206 printf( "pos: %li s / %li s\n", (long int)i_newpos,
207 (long int)(f_ratio * A->i_size) );
211 vlc_mutex_unlock( &p_input->stream.stream_lock );
214 /* Is there something to do? */
215 if( b_complete == 1 )
217 char *p_cmd = p_buffer;
223 if( p_cmd[1] == ' ' )
225 // playlist_Add( p_intf, PLAYLIST_END, p_cmd + 2 );
226 // playlist_Jumpto( p_intf->p_vlc->p_playlist,
227 // p_intf->p_vlc->p_playlist->i_size-2 );
233 vlc_dumpstructure( p_intf->p_vlc );
240 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
248 vout_thread_t *p_vout;
249 p_vout = vlc_object_find( p_input,
250 VLC_OBJECT_VOUT, FIND_CHILD );
254 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
255 vlc_object_release( p_vout );
267 p_intf->p_vlc->b_die = 1;
275 i_dummy < MAX_LINE_LENGTH && p_cmd[ i_dummy ] >= '0'
276 && p_cmd[ i_dummy ] <= '9';
282 p_cmd[ i_dummy ] = 0;
283 input_Seek( p_input, (off_t)atoi( p_cmd + 1 ),
284 INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
285 /* rcreseek(f_cpos); */
292 printf( "help for remote control commands\n" );
293 printf( "h . . . . . . . . . . . . . . . . . . . . . help\n" );
294 printf( "a XYZ . . . . . . . . . . append XYZ to playlist\n" );
295 printf( "p . . . . . . . . . . . . . . . . . toggle pause\n" );
296 printf( "f . . . . . . . . . . . . . . toggle fullscreen\n" );
297 printf( "r X . . . seek in seconds, for instance `r 3.5'\n" );
298 printf( "q . . . . . . . . . . . . . . . . . . . . . quit\n" );
299 printf( "end of help\n" );
303 printf( "unknown command `%s'\n", p_cmd );
310 vlc_object_release( p_input );
313 msleep( INTF_IDLE_SLEEP );