]> git.sesse.net Git - vlc/blob - plugins/text/intf_rc.c
*) Added "#include <string.>" to include/threads.h
[vlc] / plugins / text / intf_rc.c
1 /*****************************************************************************
2  * intf_rc.cpp: remote control interface
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: intf_rc.cpp,v 0.1 2001/04/27 shurdeek
6  *
7  * Authors: Peter Surda <shurdeek@panorama.sth.ac.at>
8  *
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.
13  * 
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.
18  *
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  *****************************************************************************/
23
24 #define MODULE_NAME rc
25 #include "modules_inner.h"
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "defs.h"
31
32 #include <errno.h>                                                 /* ENOMEM */
33 #include <stdlib.h>                                                /* free() */
34 #include <string.h>                                            /* strerror() */
35 #include <stdio.h>
36 #include <ctype.h>
37 #include <unistd.h>
38 #include <sys/time.h>
39 #include <sys/types.h>
40
41 #if defined( WIN32 )
42 #include <winsock2.h>                                            /* select() */
43 #endif
44
45 #include "config.h"
46 #include "common.h"
47 #include "intf_msg.h"
48 #include "threads.h"
49 #include "mtime.h"
50 #include "tests.h"
51
52 #include "stream_control.h"
53 #include "input_ext-intf.h"
54
55 #include "intf_playlist.h"
56 #include "interface.h"
57
58 #include "video.h"
59 #include "video_output.h"
60
61 #include "modules.h"
62 #include "modules_export.h"
63
64 /*****************************************************************************
65  * intf_sys_t: description and status of rc interface
66  *****************************************************************************/
67 typedef struct intf_sys_s
68 {
69     vlc_mutex_t         change_lock;
70
71 } intf_sys_t;
72
73 #define MAX_LINE_LENGTH 256
74
75 /*****************************************************************************
76  * Local prototypes.
77  *****************************************************************************/
78 static int  intf_Probe     ( probedata_t *p_data );
79 static int  intf_Open      ( intf_thread_t *p_intf );
80 static void intf_Close     ( intf_thread_t *p_intf );
81 static void intf_Run       ( intf_thread_t *p_intf );
82
83 /*****************************************************************************
84  * Functions exported as capabilities. They are declared as static so that
85  * we don't pollute the namespace too much.
86  *****************************************************************************/
87 void _M( intf_getfunctions )( function_list_t * p_function_list )
88 {
89     p_function_list->pf_probe = intf_Probe;
90     p_function_list->functions.intf.pf_open  = intf_Open;
91     p_function_list->functions.intf.pf_close = intf_Close;
92     p_function_list->functions.intf.pf_run   = intf_Run;
93 }
94
95 /*****************************************************************************
96  * intf_Probe: probe the interface and return a score
97  *****************************************************************************
98  * This function tries to initialize rc and returns a score to the
99  * plugin manager so that it can select the best plugin.
100  *****************************************************************************/
101 static int intf_Probe( probedata_t *p_data )
102 {
103     if( TestMethod( INTF_METHOD_VAR, "rc" ) )
104     {
105         return( 999 );
106     }
107
108     return( 2 );
109 }
110
111 /*****************************************************************************
112  * intf_Open: initialize and create stuff
113  *****************************************************************************/
114 static int intf_Open( intf_thread_t *p_intf )
115 {
116     /* Non-buffered stdout */
117     setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
118
119     /* Allocate instance and initialize some members */
120     p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
121     if( p_intf->p_sys == NULL )
122     {
123         intf_ErrMsg( "intf error: %s", strerror(ENOMEM) );
124         return( 1 );
125     }
126
127     return( 0 );
128 }
129
130 /*****************************************************************************
131  * intf_Close: destroy interface stuff
132  *****************************************************************************/
133 static void intf_Close( intf_thread_t *p_intf )
134 {
135     /* Destroy structure */
136     free( p_intf->p_sys );
137 }
138
139 /*****************************************************************************
140  * intf_Run: rc thread
141  *****************************************************************************
142  * This part of the interface is in a separate thread so that we can call
143  * exec() from within it without annoying the rest of the program.
144  *****************************************************************************/
145 static void intf_Run( intf_thread_t *p_intf )
146 {
147     char      p_cmd[ MAX_LINE_LENGTH + 1 ];
148     int       i_cmd_pos;
149     boolean_t b_complete = 0;
150
151     int       i_dummy;
152     off_t     i_oldpos = 0;
153     off_t     i_newpos;
154     fd_set    fds;                                         /* stdin changed? */
155     struct timeval tv;                                   /* how long to wait */
156
157     double    f_cpos;
158     double    f_ratio = 1;
159
160     while( !p_intf->b_die )
161     {
162 #define S p_intf->p_input->stream
163         if( p_intf->p_input != NULL )
164         {
165             /* Get position */
166             if( S.i_mux_rate )
167             {
168                 f_ratio = 1.0 / ( 50 * S.i_mux_rate );
169                 i_newpos = S.p_selected_area->i_tell * f_ratio;
170
171                 if( i_oldpos != i_newpos )
172                 {
173                     i_oldpos = i_newpos;
174                     intf_Msg( "rc: pos: %li s / %li s", (long int)i_newpos,
175                               (long int)( f_ratio *
176                                           S.p_selected_area->i_size ) );
177                 }
178             }
179         }
180 #undef S
181
182         b_complete = 0;
183         i_cmd_pos = 0;
184
185         /* Check stdin */
186         tv.tv_sec = 0;
187         tv.tv_usec = 50000;
188         FD_ZERO( &fds );
189         FD_SET( STDIN_FILENO, &fds );
190
191         if( select( 32, &fds, NULL, NULL, &tv ) )
192         {
193             while( !p_intf->b_die
194                     && i_cmd_pos < MAX_LINE_LENGTH
195                     && read( STDIN_FILENO, p_cmd + i_cmd_pos, 1 ) > 0
196                     && p_cmd[ i_cmd_pos ] != '\r'
197                     && p_cmd[ i_cmd_pos ] != '\n' )
198             {
199                 i_cmd_pos++;
200             }
201
202             if( i_cmd_pos == MAX_LINE_LENGTH
203                  || p_cmd[ i_cmd_pos ] == '\r'
204                  || p_cmd[ i_cmd_pos ] == '\n' )
205             {
206                 p_cmd[ i_cmd_pos ] = 0;
207                 b_complete = 1;
208             }
209         }
210
211         /* Is there something to do? */
212         if( b_complete == 1 )
213         {
214             switch( p_cmd[ 0 ] )
215             {
216             case 'p':
217             case 'P':
218                 if( p_intf->p_input != NULL )
219                 {
220                     input_SetStatus( p_intf->p_input, INPUT_STATUS_PAUSE );
221                 }
222                 break;
223
224             case 'f':
225             case 'F':
226                 vlc_mutex_lock( &p_vout_bank->lock );
227                 /* XXX: only fullscreen the first video output */
228                 if( p_vout_bank->i_count )
229                 {
230                     p_vout_bank->pp_vout[0]->i_changes
231                                       |= VOUT_FULLSCREEN_CHANGE;
232                 }
233                 vlc_mutex_unlock( &p_vout_bank->lock );
234                 break;
235
236             case 'm':
237             case 'M':
238 #if 0
239                 double picratio = p_intf->p_input->p_default_vout->i_width 
240                     / p_intf->p_input->p_default_vout->i_height;
241                 if (picratio
242                 p_intf->p_input->p_default_vout->i_width=800
243                 p_intf->p_input->p_default_vout->i_changes |= 
244                     VOUT_FULLSCREEN_CHANGE;
245 #endif
246                 break;
247
248             case 's':
249             case 'S':
250                 ;
251                 break;
252
253             case 'q':
254             case 'Q':
255                 p_intf->b_die = 1;
256                 break;
257
258             case 'r':
259             case 'R':
260                 if( p_intf->p_input != NULL )
261                 {
262                     for( i_dummy = 1;
263                          i_dummy < MAX_LINE_LENGTH && p_cmd[ i_dummy ] >= '0'
264                                                    && p_cmd[ i_dummy ] <= '9';
265                          i_dummy++ )
266                     {
267                         ;
268                     }
269
270                     p_cmd[ i_dummy ] = 0;
271                     f_cpos = atof( p_cmd + 1 );
272                     input_Seek( p_intf->p_input, (off_t) (f_cpos / f_ratio) );
273                     /* rcreseek(f_cpos); */
274                 }
275                 break;
276
277             default:
278                 intf_Msg( "rc: unknown command `%s'", p_cmd );
279                 break;
280             }
281         }
282
283         p_intf->pf_manage( p_intf );
284         msleep( INTF_IDLE_SLEEP );
285     }
286 }
287