]> git.sesse.net Git - vlc/blob - modules/access/vcdx/intf.c
Minor name-change tidying up.
[vlc] / modules / access / vcdx / intf.c
1 /*****************************************************************************
2  * intf.c: Video CD interface to handle user interaction and still time
3  *****************************************************************************
4  * Copyright (C) 2002,2003 VideoLAN
5  * $Id: intf.c,v 1.7 2003/11/26 01:28:52 rocky Exp $
6  *
7  * Authors: Rocky Bernstein <rocky@panix.com>
8  *   from DVD code by Stéphane Borel <stef@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <vlc/vlc.h>
29 #include <vlc/intf.h>
30
31 #include "stream_control.h"
32 #include "input_ext-intf.h"
33 #include "input_ext-dec.h"
34 #include "vlc_keys.h"
35
36 #include "vcd.h"
37 #include "vcdplayer.h"
38
39 /*****************************************************************************
40  * intf_sys_t: description and status of interface
41  *****************************************************************************/
42 struct intf_sys_t
43 {
44     input_thread_t    * p_input;
45     thread_vcd_data_t * p_vcd;
46
47     vlc_bool_t          b_still;
48     vlc_bool_t          b_inf_still;
49     mtime_t             m_still_time;
50
51 #if FINISHED
52     vcdplay_ctrl_t      control;
53 #else 
54     int                 control;
55 #endif
56     vlc_bool_t          b_click, b_move, b_key_pressed;
57 };
58
59 /*****************************************************************************
60  * Local prototypes.
61  *****************************************************************************/
62 static int  InitThread     ( intf_thread_t *p_intf );
63 static int  MouseEvent     ( vlc_object_t *, char const *,
64                              vlc_value_t, vlc_value_t, void * );
65 static int  KeyEvent       ( vlc_object_t *, char const *,
66                              vlc_value_t, vlc_value_t, void * );
67
68 /* Exported functions */
69 static void RunIntf        ( intf_thread_t *p_intf );
70
71 /*****************************************************************************
72  * OpenIntf: initialize dummy interface
73  *****************************************************************************/
74 int E_(VCDOpenIntf) ( vlc_object_t *p_this )
75 {
76     intf_thread_t *p_intf = (intf_thread_t *)p_this;
77
78     msg_Dbg( p_intf, "VCDOpenIntf" );
79
80     /* Allocate instance and initialize some members */
81     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
82     if( p_intf->p_sys == NULL )
83     {
84         return( 1 );
85     };
86
87     p_intf->pf_run = RunIntf;
88
89     var_AddCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
90     p_intf->p_sys->m_still_time = 0;
91     p_intf->p_sys->b_inf_still = 0;
92     p_intf->p_sys->b_still = 0;
93
94     return( 0 );
95 }
96
97 /*****************************************************************************
98  * CloseIntf: destroy dummy interface
99  *****************************************************************************/
100 void E_(VCDCloseIntf) ( vlc_object_t *p_this )
101 {
102     intf_thread_t *p_intf = (intf_thread_t *)p_this;
103
104     /* Destroy structure */
105     free( p_intf->p_sys );
106 }
107
108
109 /*****************************************************************************
110  * RunIntf: main loop
111  *****************************************************************************/
112 static void RunIntf( intf_thread_t *p_intf )
113 {
114     vlc_object_t      * p_vout = NULL;
115     thread_vcd_data_t * p_vcd;
116     input_thread_t    * p_input;
117     
118     /* What you add to the last input number entry. It accumulates all of
119        the 10_ADD keypresses */
120     int number_addend = 0; 
121     
122     if( InitThread( p_intf ) < 0 )
123     {
124         msg_Err( p_intf, "can't initialize intf" );
125         return;
126     }
127
128     p_input = p_intf->p_sys->p_input;
129     p_vcd   = p_intf->p_sys->p_vcd = 
130       (thread_vcd_data_t *) p_input->p_access_data;
131
132     dbg_print( INPUT_DBG_CALL, "intf initialized" );
133
134     /* Main loop */
135     while( !p_intf->b_die )
136     {
137       vlc_mutex_lock( &p_intf->change_lock );
138
139       /*
140        * keyboard event
141        */
142       if( p_vout && p_intf->p_sys->b_key_pressed )
143         {
144           vlc_value_t val;
145           int i, i_action = -1;
146           struct hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
147
148           p_intf->p_sys->b_key_pressed = VLC_FALSE;
149           
150           /* Find action triggered by hotkey (if any) */
151           var_Get( p_intf->p_vlc, "key-pressed", &val );
152
153           dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );
154
155           for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
156             {
157               if( p_hotkeys[i].i_key == val.i_int )
158                 {
159                   i_action = p_hotkeys[i].i_action;
160                 }
161             }
162           
163           if( i_action != -1) {
164             switch (i_action) {
165               
166             case ACTIONID_NAV_LEFT: 
167               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)", 
168                          number_addend );
169               do {
170                 vcdplayer_play_prev( p_input );
171               } while (number_addend-- > 0);
172               break;
173
174             case ACTIONID_NAV_RIGHT:
175               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
176                          number_addend );
177               do {
178                 vcdplayer_play_next( p_input );
179               } while (number_addend-- > 0);
180               break;
181
182             case ACTIONID_NAV_UP:
183               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
184               do {
185                 vcdplayer_play_return( p_input );
186               } while (number_addend-- > 0);
187               break;
188
189             case ACTIONID_NAV_DOWN:
190               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default"  );
191               vcdplayer_play_default( p_input );
192               break;
193
194             case ACTIONID_NAV_ACTIVATE: 
195               {
196                 vcdinfo_itemid_t itemid;
197                 itemid.type=p_vcd->play_item.type;
198
199                 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );
200
201                 if ( vcdplayer_pbc_is_on( p_vcd ) && number_addend != 0 ) {
202                   lid_t next_num=vcdinfo_selection_get_lid(p_vcd->vcd, 
203                                                            p_vcd->cur_lid,
204                                                            number_addend);
205                   if (VCDINFO_INVALID_LID != next_num) {
206                     itemid.num  = next_num;
207                     itemid.type = VCDINFO_ITEM_TYPE_LID;
208                     VCDPlay( p_input, itemid );
209                   }
210                 } else {
211                   itemid.num = number_addend;
212                   VCDPlay( p_input, itemid );
213                 }
214                 break;
215               }
216             }
217             number_addend = 0;
218           } else {
219             unsigned int digit_entered=0;
220
221             switch (val.i_int) {
222             case '9':
223               digit_entered++;
224             case '8':
225               digit_entered++;
226             case '7':
227               digit_entered++;
228             case '6':
229               digit_entered++;
230             case '5':
231               digit_entered++;
232             case '4':
233               digit_entered++;
234             case '3':
235               digit_entered++;
236             case '2':
237               digit_entered++;
238             case '1':
239               digit_entered++;
240             case '0':
241               {
242                 number_addend *= 10;
243                 number_addend += digit_entered;
244                 dbg_print( INPUT_DBG_EVENT, 
245                            "Added %d. Number is now: %d\n", 
246                            digit_entered, number_addend);
247                 break;
248               }
249             }
250           }
251         }
252
253       
254       vlc_mutex_unlock( &p_intf->change_lock );
255       
256       if( p_vout == NULL )
257         {
258           p_vout = vlc_object_find( p_intf->p_sys->p_input,
259                                     VLC_OBJECT_VOUT, FIND_CHILD );
260           if( p_vout )
261             {
262               var_AddCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
263               var_AddCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
264               var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
265             }
266         }
267       
268       
269       /* Wait a bit */
270       msleep( INTF_IDLE_SLEEP );
271     }
272
273     if( p_vout )
274     {
275         var_DelCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
276         var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
277         var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
278         vlc_object_release( p_vout );
279     }
280
281     vlc_object_release( p_intf->p_sys->p_input );
282 }
283
284 /*****************************************************************************
285  * InitThread:
286  *****************************************************************************/
287 static int InitThread( intf_thread_t * p_intf )
288 {
289     /* We might need some locking here */
290     if( !p_intf->b_die )
291     {
292         input_thread_t * p_input;
293
294         p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
295
296         /* Maybe the input just died */
297         if( p_input == NULL )
298         {
299             return VLC_EGENERIC;
300         }
301
302         vlc_mutex_lock( &p_intf->change_lock );
303
304         p_intf->p_sys->p_input = p_input;
305
306         p_intf->p_sys->b_move = VLC_FALSE;
307         p_intf->p_sys->b_click = VLC_FALSE;
308         p_intf->p_sys->b_key_pressed = VLC_FALSE;
309
310         vlc_mutex_unlock( &p_intf->change_lock );
311
312         return VLC_SUCCESS;
313     }
314     else
315     {
316         return VLC_EGENERIC;
317     }
318 }
319
320 /*****************************************************************************
321  * MouseEvent: callback for mouse events
322  *****************************************************************************/
323 static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
324                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
325 {
326     intf_thread_t *p_intf = (intf_thread_t *)p_data;
327
328     vlc_mutex_lock( &p_intf->change_lock );
329
330     if( psz_var[6] == 'c' ) /* "mouse-clicked" */
331     {
332         p_intf->p_sys->b_click = VLC_TRUE;
333     }
334     else if( psz_var[6] == 'm' ) /* "mouse-moved" */
335     {
336         p_intf->p_sys->b_move = VLC_TRUE;
337     }
338
339     vlc_mutex_unlock( &p_intf->change_lock );
340
341     return VLC_SUCCESS;
342 }
343
344 /*****************************************************************************
345  * KeyEvent: callback for keyboard events
346  *****************************************************************************/
347 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
348                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
349 {
350     intf_thread_t *p_intf = (intf_thread_t *)p_data;
351     vlc_mutex_lock( &p_intf->change_lock );
352
353     p_intf->p_sys->b_key_pressed = VLC_TRUE;
354     
355     vlc_mutex_unlock( &p_intf->change_lock );
356
357     return VLC_SUCCESS;
358 }
359
360 /*****************************************************************************
361  * dvdIntfStillTime: function provided to demux plugin to request
362  * still images
363  *****************************************************************************/
364 int vcdIntfStillTime( intf_thread_t *p_intf, int i_sec )
365 {
366     vlc_mutex_lock( &p_intf->change_lock );
367
368     if( i_sec == 0xff )
369     {
370         p_intf->p_sys->b_still = 1;
371         p_intf->p_sys->b_inf_still = 1;
372     }
373     else if( i_sec > 0 )
374     {
375         p_intf->p_sys->b_still = 1;
376         p_intf->p_sys->m_still_time = 1000000 * i_sec;
377     }
378     vlc_mutex_unlock( &p_intf->change_lock );
379
380     return VLC_SUCCESS;
381 }
382
383 /*****************************************************************************
384  * vcdIntfStillTime: function provided to reset still image
385  *****************************************************************************/
386 int vcdIntfResetStillTime( intf_thread_t *p_intf )
387 {
388     vlc_mutex_lock( &p_intf->change_lock );
389     p_intf->p_sys->m_still_time = 0;
390     input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
391     vlc_mutex_unlock( &p_intf->change_lock );
392
393     return VLC_SUCCESS;
394 }