]> git.sesse.net Git - vlc/blob - src/interface/interface.c
Mise place du scaling, episode II
[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  * intf_Create: prepare interface before main loop
36  *******************************************************************************
37  * This function opens output devices and create specific interfaces. It send
38  * it's own error messages.
39  *******************************************************************************/
40 intf_thread_t* intf_Create( void )
41 {    
42     intf_thread_t *p_intf;                                        
43
44     /* Allocate structure */
45     p_intf = malloc( sizeof( intf_thread_t ) );
46     if( !p_intf )
47     {
48         intf_ErrMsg("error: %s\n", strerror( ENOMEM ) );        
49         return( NULL );
50     }
51
52     /* Initialize structure */
53     p_intf->b_die =     0;    
54     p_intf->p_vout =    NULL;
55     p_intf->p_input =   NULL;   
56
57     /* Start interfaces */
58     p_intf->p_console = intf_ConsoleCreate();
59     if( p_intf->p_console == NULL )
60     {
61         intf_ErrMsg("error: can't create control console\n");
62         free( p_intf );
63         return( NULL );
64     }
65     if( intf_SysCreate( p_intf ) )
66     {
67         intf_ErrMsg("error: can't create interface\n");
68         intf_ConsoleDestroy( p_intf->p_console );
69         free( p_intf );
70         return( NULL );
71     }   
72
73     intf_Msg("Interface initialized\n");    
74     return( p_intf );
75 }
76
77 /*******************************************************************************
78  * intf_Run
79  *******************************************************************************
80  * Initialization script and main interface loop.
81  *******************************************************************************/
82 void intf_Run( intf_thread_t *p_intf )
83
84     /* Execute the initialization script - if a positive number is returned, 
85      * the script could be executed but failed */
86     if( intf_ExecScript( main_GetPszVariable( INTF_INIT_SCRIPT_VAR, INTF_INIT_SCRIPT_DEFAULT ) ) > 0 )
87     {
88         intf_ErrMsg("warning: error(s) during startup script\n");
89     }
90
91     /* Main loop */
92     while(!p_intf->b_die)
93     {
94         /* Flush waiting messages */
95         intf_FlushMsg();
96
97         /* Manage specific interface */
98         intf_SysManage( p_intf );
99
100         /* Check attached threads status */
101         if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error )
102         {
103             //?? add aout error detection
104             p_intf->b_die = 1;            
105         }    
106         if( (p_intf->p_input != NULL) && p_intf->p_input->b_error )
107         {
108             input_DestroyThread( p_intf->p_input, NULL );            
109             p_intf->p_input = NULL;            
110             intf_DbgMsg("Input thread destroyed\n");            
111         }
112
113         /* Sleep to avoid using all CPU - since some interfaces needs to access 
114          * keyboard events, a 100ms delay is a good compromise */
115         msleep( INTF_IDLE_SLEEP );
116     }
117 }
118
119 /*******************************************************************************
120  * intf_Destroy: clean interface after main loop
121  *******************************************************************************
122  * This function destroys specific interfaces and close output devices.
123  *******************************************************************************/
124 void intf_Destroy( intf_thread_t *p_intf )
125 {
126     /* Destroy interfaces */
127     intf_SysDestroy( p_intf );
128     intf_ConsoleDestroy( p_intf->p_console );
129
130     /* Free structure */
131     free( p_intf );
132 }
133
134 /*******************************************************************************
135  * intf_SelectInput: change input stream
136  *******************************************************************************
137  * Kill existing input, if any, and try to open a new one, using an input
138  * configuration table.
139  *******************************************************************************/
140 int intf_SelectInput( intf_thread_t * p_intf, int i_index )
141 {
142     intf_DbgMsg("\n");
143
144     /* If VLANs are not active, return with an error */
145     if( !p_main->b_vlans )
146     {
147         intf_ErrMsg("error: VLANs are not activated\n");
148         return( 1 );        
149     }    
150     
151     /* Kill existing input, if any */
152     if( p_intf->p_input != NULL )
153     {        
154         input_DestroyThread( p_intf->p_input, NULL );
155     }
156
157     /* Open a new input */
158     intf_Msg("Switching to channel %d\n", i_index );    
159     p_intf->p_input = input_CreateThread( INPUT_METHOD_TS_VLAN_BCAST, NULL, 0, i_index, 
160                                           p_intf->p_vout, p_main->p_aout, NULL );        
161     return( p_intf->p_input == NULL );    
162 }
163
164 /*******************************************************************************
165  * intf_ProcessKey: process standard keys
166  *******************************************************************************
167  * This function will process standard keys and return non 0 if the key was
168  * unknown.
169  *******************************************************************************/
170 int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
171 {
172     switch( i_key )
173     {
174     case 'Q':                                                    /* quit order */
175     case 'q':
176     case 27: /* escape key */
177         p_intf->b_die = 1;
178         break;  
179     case '0':                                                 /* source change */
180     case '1':
181     case '2':
182     case '3':
183     case '4':
184     case '5':
185     case '6':
186     case '7':
187     case '8':
188     case '9':                    
189         if( intf_SelectInput( p_intf, i_key - '0' ) )
190         {
191             intf_ErrMsg("error: can not open channel %d\n", i_key - '0');            
192         }        
193         break;
194     case '+':                                                      /* volume + */
195         // ??
196         break;
197     case '-':                                                      /* volume - */
198         // ??
199         break;
200     case 'M':                                                   /* toggle mute */
201     case 'm':                    
202         // ??
203         break;      
204     case 'g':                                                       /* gamma - */
205         if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_LIMIT) )
206         {
207             vlc_mutex_lock( &p_intf->p_vout->change_lock );
208             p_intf->p_vout->f_gamma   -= INTF_GAMMA_STEP;                        
209             p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
210             vlc_mutex_unlock( &p_intf->p_vout->change_lock );
211         }                    
212         break;                                        
213     case 'G':                                                       /* gamma + */
214         if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_LIMIT) )
215         {       
216             vlc_mutex_lock( &p_intf->p_vout->change_lock );
217             p_intf->p_vout->f_gamma   += INTF_GAMMA_STEP;
218             p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
219             vlc_mutex_unlock( &p_intf->p_vout->change_lock );
220         }                    
221         break;  
222     case 'c':                                              /* toggle grayscale */
223         if( p_intf->p_vout != NULL )
224         {
225             vlc_mutex_lock( &p_intf->p_vout->change_lock );                        
226             p_intf->p_vout->b_grayscale = !p_intf->p_vout->b_grayscale;                    
227             p_intf->p_vout->i_changes  |= VOUT_GRAYSCALE_CHANGE;                        
228             vlc_mutex_unlock( &p_intf->p_vout->change_lock );      
229         }
230         break;  
231     case ' ':                                              /* toggle interface */
232         if( p_intf->p_vout != NULL )
233         {
234             vlc_mutex_lock( &p_intf->p_vout->change_lock );                        
235             p_intf->p_vout->b_interface     = !p_intf->p_vout->b_interface;                    
236             p_intf->p_vout->i_changes |= VOUT_INTF_CHANGE;                        
237             vlc_mutex_unlock( &p_intf->p_vout->change_lock );      
238         }
239         break;                                
240     case 'i':                                                   /* toggle info */
241         if( p_intf->p_vout != NULL )
242         {
243             vlc_mutex_lock( &p_intf->p_vout->change_lock );                        
244             p_intf->p_vout->b_info     = !p_intf->p_vout->b_info;                    
245             p_intf->p_vout->i_changes |= VOUT_INFO_CHANGE;                        
246             vlc_mutex_unlock( &p_intf->p_vout->change_lock );      
247         }
248         break;                                
249     case 's':                                                 /* toggle scaling */
250         if( p_intf->p_vout != NULL )
251         {
252             vlc_mutex_lock( &p_intf->p_vout->change_lock );                        
253             p_intf->p_vout->b_scale    = !p_intf->p_vout->b_scale;                    
254             p_intf->p_vout->i_changes |= VOUT_SCALE_CHANGE;                        
255             vlc_mutex_unlock( &p_intf->p_vout->change_lock );      
256         }
257         break;                                
258    default:                                                    /* unknown key */
259         return( 1 );        
260     }
261
262     return( 0 );    
263 }
264
265     
266