]> git.sesse.net Git - vlc/blob - modules/access/dvdplay/intf.c
* src/video_output/video_output.c: add a key-pressed variable to p_vout
[vlc] / modules / access / dvdplay / intf.c
1 /*****************************************************************************
2  * intf.c: interface for DVD video manager
3  *****************************************************************************
4  * Copyright (C) 2002 VideoLAN
5  * $Id: intf.c,v 1.5 2003/01/12 15:38:35 sigmunau Exp $
6  *
7  * Authors: Stéphane Borel <stef@via.ecp.fr>
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 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <string.h>
29 #include <unistd.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/intf.h>
33
34 #include "stream_control.h"
35 #include "input_ext-intf.h"
36 #include "input_ext-dec.h"
37
38 #include "dvd.h"
39
40 /*****************************************************************************
41  * intf_sys_t: description and status of interface
42  *****************************************************************************/
43 struct intf_sys_t
44 {
45     input_thread_t *    p_input;
46     dvd_data_t *        p_dvd;
47
48     vlc_bool_t          b_still;
49     vlc_bool_t          b_inf_still;
50     mtime_t             m_still_time;
51
52     dvdplay_ctrl_t      control;
53     vlc_bool_t          b_click, b_move, b_key_pressed;
54 };
55
56 /*****************************************************************************
57  * Local prototypes.
58  *****************************************************************************/
59 static int  InitThread     ( intf_thread_t *p_intf );
60 static int  MouseEvent     ( vlc_object_t *, char const *,
61                              vlc_value_t, vlc_value_t, void * );
62 static int  KeyEvent       ( vlc_object_t *, char const *,
63                              vlc_value_t, vlc_value_t, void * );
64
65 /* Exported functions */
66 static void RunIntf        ( intf_thread_t *p_intf );
67
68 /*****************************************************************************
69  * OpenIntf: initialize dummy interface
70  *****************************************************************************/
71 int E_(OpenIntf) ( vlc_object_t *p_this )
72 {
73     intf_thread_t *p_intf = (intf_thread_t *)p_this;
74
75     /* Allocate instance and initialize some members */
76     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
77     if( p_intf->p_sys == NULL )
78     {
79         return( 1 );
80     };
81
82     p_intf->pf_run = RunIntf;
83
84     p_intf->p_sys->m_still_time = 0;
85     p_intf->p_sys->b_inf_still = 0;
86     p_intf->p_sys->b_still = 0;
87
88     return( 0 );
89 }
90
91 /*****************************************************************************
92  * CloseIntf: destroy dummy interface
93  *****************************************************************************/
94 void E_(CloseIntf) ( vlc_object_t *p_this )
95 {
96     intf_thread_t *p_intf = (intf_thread_t *)p_this;
97
98     /* Destroy structure */
99     free( p_intf->p_sys );
100 }
101
102
103 /*****************************************************************************
104  * RunIntf: main loop
105  *****************************************************************************/
106 static void RunIntf( intf_thread_t *p_intf )
107 {
108     vlc_object_t *      p_vout = NULL;
109     mtime_t             mtime = 0;
110     mtime_t             mlast = 0;
111
112     if( InitThread( p_intf ) < 0 )
113     {
114         msg_Err( p_intf, "can't initialize intf" );
115         return;
116     }
117     msg_Dbg( p_intf, "intf initialized" );
118
119     /* Main loop */
120     while( !p_intf->b_die )
121     {
122         vlc_mutex_lock( &p_intf->change_lock );
123
124         /*
125          * still images
126          */
127 #if 1
128         if( p_intf->p_sys->b_still && !p_intf->p_sys->b_inf_still )
129         {
130             if( p_intf->p_sys->m_still_time > 0 )
131             {
132                 /* update remaining still time */
133                 mtime = mdate();
134                 if( mlast )
135                 {
136                     p_intf->p_sys->m_still_time -= mtime - mlast;
137                 }
138
139                 mlast = mtime;
140             }
141             else
142             {
143                 /* still time elasped */
144                 input_SetStatus( p_intf->p_sys->p_input,
145                                  INPUT_STATUS_PLAY );
146                 p_intf->p_sys->m_still_time = 0;
147                 p_intf->p_sys->b_still = 0;
148                 mlast = 0;
149             }
150         }
151 #else
152         if( p_intf->p_sys->m_still_time != (mtime_t)(-1) )
153         {
154             if( p_intf->p_sys->m_still_time )
155             {
156                 mtime = mdate();
157                 if( mlast )
158                 {
159                     p_intf->p_sys->m_still_time -= mtime - mlast;
160                 }
161                 if( !p_intf->p_sys->m_still_time )
162                 {
163                     input_SetStatus( p_intf->p_sys->p_input,
164                                      INPUT_STATUS_PLAY );
165                 }
166                 mlast = mtime;
167             }
168
169         }
170 #endif
171
172         /* 
173          * mouse cursor
174          */
175         if( p_vout && ( p_intf->p_sys->b_click || p_intf->p_sys->b_move ) )
176         {
177             vlc_value_t val;
178             int i_activate;
179
180             var_Get( p_vout, "mouse-x", &val );
181             p_intf->p_sys->control.mouse.i_x = val.i_int;
182             var_Get( p_vout, "mouse-y", &val );
183             p_intf->p_sys->control.mouse.i_y = val.i_int;
184
185             if( p_intf->p_sys->b_click )
186             {
187                 p_intf->p_sys->control.type = DVDCtrlMouseActivate;
188                 p_intf->p_sys->b_click = VLC_FALSE;
189             }
190             else
191             {
192                 p_intf->p_sys->control.type = DVDCtrlMouseSelect;
193                 p_intf->p_sys->b_move = VLC_FALSE;
194             }
195
196             /* we can safely interact with libdvdplay
197              * with the stream lock */
198             vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
199
200             i_activate = dvdplay_button( p_intf->p_sys->p_dvd->vmg,
201                                          &p_intf->p_sys->control );
202
203             vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
204
205             if( i_activate && p_intf->p_sys->b_still )
206             {
207                 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
208                 p_intf->p_sys->b_still = 0;
209                 p_intf->p_sys->b_inf_still = 0;
210                 p_intf->p_sys->m_still_time = 0;
211             }
212         }
213
214         /*
215          * keyboard event
216          */
217         if( p_vout && p_intf->p_sys->b_key_pressed )
218         {
219             vlc_value_t val;
220             int i_activate;
221
222             p_intf->p_sys->b_key_pressed = VLC_FALSE;
223             
224             var_Get( p_vout, "key-pressed", &val );
225             if ( val.psz_string )
226             {
227                 if( !strcmp( val.psz_string, "LEFT" ) )
228                 {
229                     p_intf->p_sys->control.type = DVDCtrlLeftButtonSelect;
230                 }
231                 else if( !strcmp( val.psz_string, "RIGHT" ) )
232                 {
233                     p_intf->p_sys->control.type = DVDCtrlRightButtonSelect;
234                 }
235                 else if( !strcmp( val.psz_string, "UP" ) )
236                 {
237                     p_intf->p_sys->control.type = DVDCtrlUpperButtonSelect;
238                 }
239                 else if( !strcmp( val.psz_string, "DOWN" ) )
240                 {
241                     p_intf->p_sys->control.type = DVDCtrlLowerButtonSelect;
242                 }
243                 else if( !strcmp( val.psz_string, "ENTER" ) )
244                 {
245                     p_intf->p_sys->control.type = DVDCtrlButtonActivate;
246                 }
247                 /* we can safely interact with libdvdplay
248                  * with the stream lock */
249                 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
250                 
251                 i_activate = dvdplay_button( p_intf->p_sys->p_dvd->vmg,
252                                              &p_intf->p_sys->control );
253                 
254                 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
255                 
256                 if( i_activate && p_intf->p_sys->b_still )
257                 {
258                     input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
259                     p_intf->p_sys->b_still = 0;
260                     p_intf->p_sys->b_inf_still = 0;
261                     p_intf->p_sys->m_still_time = 0;
262                 }
263             }
264         }
265                 
266
267         vlc_mutex_unlock( &p_intf->change_lock );
268
269         /* 
270          * video output
271          */
272         if( p_vout && p_vout->b_die )
273         {
274             var_DelCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
275             var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
276             var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
277             vlc_object_release( p_vout );
278             p_vout = NULL;
279         }
280
281         if( p_vout == NULL )
282         {
283             p_vout = vlc_object_find( p_intf->p_sys->p_input,
284                                       VLC_OBJECT_VOUT, FIND_CHILD );
285             if( p_vout )
286             {
287                 var_AddCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
288                 var_AddCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
289                 var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
290             }
291         }
292
293         /* Wait a bit */
294         msleep( INTF_IDLE_SLEEP );
295     }
296
297     if( p_vout )
298     {
299         var_DelCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
300         var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
301         var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
302         vlc_object_release( p_vout );
303     }
304
305     vlc_object_release( p_intf->p_sys->p_input );
306 }
307
308 /*****************************************************************************
309  * InitThread:
310  *****************************************************************************/
311 static int InitThread( intf_thread_t * p_intf )
312 {
313     /* we might need some locking here */
314     if( !p_intf->b_die )
315     {
316         input_thread_t * p_input;
317         dvd_data_t * p_dvd;
318
319         p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
320         p_dvd = (dvd_data_t*)p_input->p_access_data;
321
322         p_dvd->p_intf = p_intf;
323
324         vlc_mutex_lock( &p_intf->change_lock );
325
326         p_intf->p_sys->p_input = p_input;
327         p_intf->p_sys->p_dvd = p_dvd;
328
329         p_intf->p_sys->b_move = VLC_FALSE;
330         p_intf->p_sys->b_click = VLC_FALSE;
331         p_intf->p_sys->b_key_pressed = VLC_FALSE;
332
333         vlc_mutex_unlock( &p_intf->change_lock );
334
335         return 0;
336     }
337     else
338     {
339         return -1;
340     }
341 }
342
343 /*****************************************************************************
344  * MouseEvent: callback for mouse events
345  *****************************************************************************/
346 static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
347                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
348 {
349     intf_thread_t *p_intf = (intf_thread_t *)p_data;
350
351     vlc_mutex_lock( &p_intf->change_lock );
352
353     if( psz_var[6] == 'c' ) /* "mouse-clicked" */
354     {
355         p_intf->p_sys->b_click = VLC_TRUE;
356     }
357     else if( psz_var[6] == 'm' ) /* "mouse-moved" */
358     {
359         p_intf->p_sys->b_move = VLC_TRUE;
360     }
361
362     vlc_mutex_unlock( &p_intf->change_lock );
363
364     return VLC_SUCCESS;
365 }
366
367 /*****************************************************************************
368  * KeyEvent: callback for keyboard events
369  *****************************************************************************/
370 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
371                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
372 {
373     intf_thread_t *p_intf = (intf_thread_t *)p_data;
374     vlc_mutex_lock( &p_intf->change_lock );
375
376     p_intf->p_sys->b_key_pressed = VLC_TRUE;
377     
378     vlc_mutex_unlock( &p_intf->change_lock );
379
380     return VLC_SUCCESS;
381 }
382
383 /*****************************************************************************
384  * dvdIntfStillTime: function provided to demux plugin to request
385  * still images
386  *****************************************************************************/
387 int dvdIntfStillTime( intf_thread_t *p_intf, int i_sec )
388 {
389     vlc_mutex_lock( &p_intf->change_lock );
390 #if 1
391
392     if( i_sec == 0xff )
393     {
394         p_intf->p_sys->b_still = 1;
395         p_intf->p_sys->b_inf_still = 1;
396     }
397     else if( i_sec > 0 )
398     {
399         p_intf->p_sys->b_still = 1;
400         p_intf->p_sys->m_still_time = 1000000 * i_sec;
401     }
402 #else
403     if( i_sec > 0 )
404     {
405         if( i_sec == 0xff )
406         {
407             p_intf->p_sys->m_still_time = (mtime_t)(-1);
408             msg_Warn( p_intf, I64Fd, p_intf->p_sys->m_still_time );
409         }
410         else
411         {
412             p_intf->p_sys->m_still_time = 1000000 * i_sec;
413         }
414     }
415 #endif
416     vlc_mutex_unlock( &p_intf->change_lock );
417
418     return VLC_SUCCESS;
419 }
420