]> git.sesse.net Git - vlc/blob - src/interface/interface.c
D�but du changement de chaine.
[vlc] / src / interface / interface.c
1 /*******************************************************************************
2  * interface.c: interface access for other threads
3  * (c)1998 VideoLAN
4  *******************************************************************************
5  * This library provides basic functions for threads to interact with user
6  * interface, such as command line.
7  *******************************************************************************/
8
9 /*******************************************************************************
10  * Preamble
11  *******************************************************************************/
12 #include <errno.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/types.h>
17 #include <sys/uio.h>                                        /* for input.h */
18
19 #include "config.h"
20 #include "common.h"
21 #include "mtime.h"
22 #include "vlc_thread.h"
23 #include "input.h"
24 #include "intf_msg.h"
25 #include "interface.h"
26 #include "intf_cmd.h"
27 #include "intf_console.h"
28 #include "main.h"
29 #include "video.h"
30 #include "video_output.h"
31
32 #include "intf_sys.h"
33
34 /*******************************************************************************
35  * Constants
36  *******************************************************************************/
37
38 /* INTF_INPUT_CFG: pre-configured inputs */
39 #define INTF_MAX_INPUT_CFG              10
40 static const input_cfg_t INTF_INPUT_CFG[] = 
41 {
42     /*  properties                              method  
43      *  file    host    ip              port    vlan */
44     
45     /* Local input (unicast) */
46     {   INPUT_CFG_METHOD | INPUT_CFG_IP,        INPUT_METHOD_TS_UCAST,     
47         NULL,   NULL,   "127.0.0.1",    0,      0       },
48
49     /* Broadcasts */
50     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
51        NULL,    NULL,   NULL,           0,      0       },
52     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
53        NULL,    NULL,   NULL,           0,      1       },
54     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
55        NULL,    NULL,   NULL,           0,      2       },
56     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
57        NULL,    NULL,   NULL,           0,      3       },
58     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
59        NULL,    NULL,   NULL,           0,      4       },
60     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
61        NULL,    NULL,   NULL,           0,      5       },
62     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
63        NULL,    NULL,   NULL,           0,      6       },
64     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
65        NULL,    NULL,   NULL,           0,      7       },
66     {  INPUT_CFG_METHOD | INPUT_CFG_VLAN,       INPUT_METHOD_TS_VLAN_BCAST,
67        NULL,    NULL,   NULL,           0,      8       }
68 };
69
70 /*******************************************************************************
71  * intf_Create: prepare interface before main loop
72  *******************************************************************************
73  * This function opens output devices and create specific interfaces. It send
74  * it's own error messages.
75  *******************************************************************************/
76 intf_thread_t* intf_Create( void )
77 {    
78     intf_thread_t *p_intf;                                        
79
80     /* Allocate structure */
81     p_intf = malloc( sizeof( intf_thread_t ) );
82     if( !p_intf )
83     {
84         intf_ErrMsg("error: %s\n", strerror( ENOMEM ) );        
85         return( NULL );
86     }
87
88     /* Initialize structure */
89     p_intf->b_die =     0;    
90     p_intf->p_vout =    NULL;
91     p_intf->p_input =   NULL;   
92
93     /* Start interfaces */
94     p_intf->p_console = intf_ConsoleCreate();
95     if( p_intf->p_console == NULL )
96     {
97         intf_ErrMsg("error: can't create control console\n");
98         free( p_intf );
99         return( NULL );
100     }
101     if( intf_SysCreate( p_intf ) )
102     {
103         intf_ErrMsg("error: can't create interface\n");
104         intf_ConsoleDestroy( p_intf->p_console );
105         free( p_intf );
106         return( NULL );
107     }   
108
109     intf_Msg("Interface initialized\n");    
110     return( p_intf );
111 }
112
113 /*******************************************************************************
114  * intf_Run
115  *******************************************************************************
116  * Initialization script and main interface loop.
117  *******************************************************************************/
118 void intf_Run( intf_thread_t *p_intf )
119
120     /* Execute the initialization script - if a positive number is returned, 
121      * the script could be executed but failed */
122     if( intf_ExecScript( main_GetPszVariable( INTF_INIT_SCRIPT_VAR, INTF_INIT_SCRIPT_DEFAULT ) ) > 0 )
123     {
124         intf_ErrMsg("warning: error(s) during startup script\n");
125     }
126
127     /* Main loop */
128     while(!p_intf->b_die)
129     {
130         /* Flush waiting messages */
131         intf_FlushMsg();
132
133         /* Manage specific interface */
134         intf_SysManage( p_intf );
135
136         /* Check attached threads status */
137         if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error )
138         {
139             //?? add aout error detection
140             p_intf->b_die = 1;            
141         }    
142         if( (p_intf->p_input != NULL) && p_intf->p_input->b_error )
143         {
144             input_DestroyThread( p_intf->p_input /*, NULL */ );            
145             p_intf->p_input = NULL;            
146             intf_DbgMsg("Input thread destroyed\n");            
147         }
148
149         /* Sleep to avoid using all CPU - since some interfaces needs to access 
150          * keyboard events, a 100ms delay is a good compromise */
151         msleep( INTF_IDLE_SLEEP );
152     }
153 }
154
155 /*******************************************************************************
156  * intf_Destroy: clean interface after main loop
157  *******************************************************************************
158  * This function destroys specific interfaces and close output devices.
159  *******************************************************************************/
160 void intf_Destroy( intf_thread_t *p_intf )
161 {
162     /* Destroy interfaces */
163     intf_SysDestroy( p_intf );
164     intf_ConsoleDestroy( p_intf->p_console );
165
166     /* Free structure */
167     free( p_intf );
168 }
169
170 /*******************************************************************************
171  * intf_SelectInput: change input stream
172  *******************************************************************************
173  * Kill existing input, if any, and try to open a new one, using an input
174  * configuration table.
175  *******************************************************************************/
176 int intf_SelectInput( intf_thread_t * p_intf, int i_index )
177 {
178     intf_DbgMsg("0x%x\n", p_intf );
179     
180     /* Kill existing input, if any */
181     if( p_intf->p_input != NULL )
182     {        
183         input_DestroyThread( p_intf->p_input /*??, NULL*/ );
184     }
185
186     /* Check that input index is valid */
187     if( (i_index < 0)  || (INTF_MAX_INPUT_CFG < i_index) )
188     {        
189         p_intf->p_input = NULL;     
190         return( 1 );        
191     }    
192     
193     /* Open a new input */
194     p_intf->p_input = input_CreateThread( &INTF_INPUT_CFG[ i_index ] /*??, NULL*/ );        
195     return( p_intf->p_input == NULL );    
196 }
197
198 /*******************************************************************************
199  * intf_ProcessKey: process standard keys
200  *******************************************************************************
201  * This function will process standard keys and return non 0 if the key was
202  * unknown.
203  *******************************************************************************/
204 int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
205 {
206     switch( i_key )
207     {
208     case 'Q':                                                    /* quit order */
209     case 'q':
210     case 27:
211         p_intf->b_die = 1;
212         break;  
213     case '0':                                                 /* source change */
214     case '1':
215     case '2':
216     case '3':
217     case '4':
218     case '5':
219     case '6':
220     case '7':
221     case '8':
222     case '9':                    
223         if( intf_SelectInput( p_intf, i_key - '0' ) )
224         {
225             intf_ErrMsg("error: can not open channel %d\n", i_key - '0');            
226         }        
227         break;
228     case '+':                                                      /* volume + */
229         // ??
230         break;
231     case '-':                                                      /* volume - */
232         // ??
233         break;
234     case 'M':                                                   /* toggle mute */
235     case 'm':                    
236         // ??
237         break;      
238     case 'g':                                                       /* gamma - */
239         if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_LIMIT) )
240         {
241             vlc_mutex_lock( &p_intf->p_vout->change_lock );
242             p_intf->p_vout->f_gamma   -= INTF_GAMMA_STEP;                        
243             p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
244             vlc_mutex_unlock( &p_intf->p_vout->change_lock );
245         }                    
246         break;                                        
247     case 'G':                                                       /* gamma + */
248         if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_LIMIT) )
249         {       
250             vlc_mutex_lock( &p_intf->p_vout->change_lock );
251             p_intf->p_vout->f_gamma   += INTF_GAMMA_STEP;
252             p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
253             vlc_mutex_unlock( &p_intf->p_vout->change_lock );
254         }                    
255         break;  
256     case 'c':                                              /* toggle grayscale */
257         if( p_intf->p_vout != NULL )
258         {
259             vlc_mutex_lock( &p_intf->p_vout->change_lock );                        
260             p_intf->p_vout->b_grayscale = !p_intf->p_vout->b_grayscale;                    
261             p_intf->p_vout->i_changes  |= VOUT_GRAYSCALE_CHANGE;                        
262             vlc_mutex_unlock( &p_intf->p_vout->change_lock );      
263         }
264         break;  
265     case ' ':                                                   /* toggle info */
266         if( p_intf->p_vout != NULL )
267         {
268             vlc_mutex_lock( &p_intf->p_vout->change_lock );                        
269             p_intf->p_vout->b_info     = !p_intf->p_vout->b_info;                    
270             p_intf->p_vout->i_changes |= VOUT_INFO_CHANGE;                        
271             vlc_mutex_unlock( &p_intf->p_vout->change_lock );      
272         }
273         break;                                
274     default:                                                    /* unknown key */
275         return( 1 );        
276     }
277
278     return( 0 );    
279 }
280
281     
282