]> git.sesse.net Git - vlc/blob - modules/access/dvdplay/intf.c
0cb548919c56ff67b9e2158bf71da192bf251683
[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.4 2002/11/08 10:26:52 gbazin 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;
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
63 /* Exported functions */
64 static void RunIntf        ( intf_thread_t *p_intf );
65
66 /*****************************************************************************
67  * OpenIntf: initialize dummy interface
68  *****************************************************************************/
69 int E_(OpenIntf) ( vlc_object_t *p_this )
70 {
71     intf_thread_t *p_intf = (intf_thread_t *)p_this;
72
73     /* Allocate instance and initialize some members */
74     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
75     if( p_intf->p_sys == NULL )
76     {
77         return( 1 );
78     };
79
80     p_intf->pf_run = RunIntf;
81
82     p_intf->p_sys->m_still_time = 0;
83     p_intf->p_sys->b_inf_still = 0;
84     p_intf->p_sys->b_still = 0;
85
86     return( 0 );
87 }
88
89 /*****************************************************************************
90  * CloseIntf: destroy dummy interface
91  *****************************************************************************/
92 void E_(CloseIntf) ( vlc_object_t *p_this )
93 {
94     intf_thread_t *p_intf = (intf_thread_t *)p_this;
95
96     /* Destroy structure */
97     free( p_intf->p_sys );
98 }
99
100
101 /*****************************************************************************
102  * RunIntf: main loop
103  *****************************************************************************/
104 static void RunIntf( intf_thread_t *p_intf )
105 {
106     vlc_object_t *      p_vout = NULL;
107     mtime_t             mtime = 0;
108     mtime_t             mlast = 0;
109
110     if( InitThread( p_intf ) < 0 )
111     {
112         msg_Err( p_intf, "can't initialize intf" );
113         return;
114     }
115     msg_Dbg( p_intf, "intf initialized" );
116
117     /* Main loop */
118     while( !p_intf->b_die )
119     {
120         vlc_mutex_lock( &p_intf->change_lock );
121
122         /*
123          * still images
124          */
125 #if 1
126         if( p_intf->p_sys->b_still && !p_intf->p_sys->b_inf_still )
127         {
128             if( p_intf->p_sys->m_still_time > 0 )
129             {
130                 /* update remaining still time */
131                 mtime = mdate();
132                 if( mlast )
133                 {
134                     p_intf->p_sys->m_still_time -= mtime - mlast;
135                 }
136
137                 mlast = mtime;
138             }
139             else
140             {
141                 /* still time elasped */
142                 input_SetStatus( p_intf->p_sys->p_input,
143                                  INPUT_STATUS_PLAY );
144                 p_intf->p_sys->m_still_time = 0;
145                 p_intf->p_sys->b_still = 0;
146                 mlast = 0;
147             }
148         }
149 #else
150         if( p_intf->p_sys->m_still_time != (mtime_t)(-1) )
151         {
152             if( p_intf->p_sys->m_still_time )
153             {
154                 mtime = mdate();
155                 if( mlast )
156                 {
157                     p_intf->p_sys->m_still_time -= mtime - mlast;
158                 }
159                 if( !p_intf->p_sys->m_still_time )
160                 {
161                     input_SetStatus( p_intf->p_sys->p_input,
162                                      INPUT_STATUS_PLAY );
163                 }
164                 mlast = mtime;
165             }
166
167         }
168 #endif
169
170         /* 
171          * mouse cursor
172          */
173         if( p_vout && ( p_intf->p_sys->b_click || p_intf->p_sys->b_move ) )
174         {
175             vlc_value_t val;
176             int i_activate;
177
178             var_Get( p_vout, "mouse-x", &val );
179             p_intf->p_sys->control.mouse.i_x = val.i_int;
180             var_Get( p_vout, "mouse-y", &val );
181             p_intf->p_sys->control.mouse.i_y = val.i_int;
182
183             if( p_intf->p_sys->b_click )
184             {
185                 p_intf->p_sys->control.type = DVDCtrlMouseActivate;
186                 p_intf->p_sys->b_click = VLC_FALSE;
187             }
188             else
189             {
190                 p_intf->p_sys->control.type = DVDCtrlMouseSelect;
191                 p_intf->p_sys->b_move = VLC_FALSE;
192             }
193
194             /* we can safely interact with libdvdplay
195              * with the stream lock */
196             vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
197
198             i_activate = dvdplay_button( p_intf->p_sys->p_dvd->vmg,
199                                          &p_intf->p_sys->control );
200
201             vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
202
203             if( i_activate && p_intf->p_sys->b_still )
204             {
205                 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
206                 p_intf->p_sys->b_still = 0;
207                 p_intf->p_sys->b_inf_still = 0;
208                 p_intf->p_sys->m_still_time = 0;
209             }
210         }
211
212         vlc_mutex_unlock( &p_intf->change_lock );
213
214         /* 
215          * video output
216          */
217         if( p_vout && p_vout->b_die )
218         {
219             var_DelCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
220             var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
221             vlc_object_release( p_vout );
222             p_vout = NULL;
223         }
224
225         if( p_vout == NULL )
226         {
227             p_vout = vlc_object_find( p_intf->p_sys->p_input,
228                                       VLC_OBJECT_VOUT, FIND_CHILD );
229             if( p_vout )
230             {
231                 var_AddCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
232                 var_AddCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
233             }
234         }
235
236         /* Wait a bit */
237         msleep( INTF_IDLE_SLEEP );
238     }
239
240     if( p_vout )
241     {
242         var_DelCallback( p_vout, "mouse-moved", MouseEvent, p_intf );
243         var_DelCallback( p_vout, "mouse-clicked", MouseEvent, p_intf );
244         vlc_object_release( p_vout );
245     }
246
247     vlc_object_release( p_intf->p_sys->p_input );
248 }
249
250 /*****************************************************************************
251  * InitThread:
252  *****************************************************************************/
253 static int InitThread( intf_thread_t * p_intf )
254 {
255     /* we might need some locking here */
256     if( !p_intf->b_die )
257     {
258         input_thread_t * p_input;
259         dvd_data_t * p_dvd;
260
261         p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
262         p_dvd = (dvd_data_t*)p_input->p_access_data;
263
264         p_dvd->p_intf = p_intf;
265
266         vlc_mutex_lock( &p_intf->change_lock );
267
268         p_intf->p_sys->p_input = p_input;
269         p_intf->p_sys->p_dvd = p_dvd;
270
271         p_intf->p_sys->b_move = VLC_FALSE;
272         p_intf->p_sys->b_click = VLC_FALSE;
273
274         vlc_mutex_unlock( &p_intf->change_lock );
275
276         return 0;
277     }
278     else
279     {
280         return -1;
281     }
282 }
283
284 /*****************************************************************************
285  * MouseEvent: callback for mouse events
286  *****************************************************************************/
287 static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
288                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
289 {
290     intf_thread_t *p_intf = (intf_thread_t *)p_data;
291
292     vlc_mutex_lock( &p_intf->change_lock );
293
294     if( psz_var[6] == 'c' ) /* "mouse-clicked" */
295     {
296         p_intf->p_sys->b_click = VLC_TRUE;
297     }
298     else if( psz_var[6] == 'm' ) /* "mouse-moved" */
299     {
300         p_intf->p_sys->b_move = VLC_TRUE;
301     }
302
303     vlc_mutex_unlock( &p_intf->change_lock );
304
305     return VLC_SUCCESS;
306 }
307
308 /*****************************************************************************
309  * dvdIntfStillTime: function provided to demux plugin to request
310  * still images
311  *****************************************************************************/
312 int dvdIntfStillTime( intf_thread_t *p_intf, int i_sec )
313 {
314     vlc_mutex_lock( &p_intf->change_lock );
315 #if 1
316
317     if( i_sec == 0xff )
318     {
319         p_intf->p_sys->b_still = 1;
320         p_intf->p_sys->b_inf_still = 1;
321     }
322     else if( i_sec > 0 )
323     {
324         p_intf->p_sys->b_still = 1;
325         p_intf->p_sys->m_still_time = 1000000 * i_sec;
326     }
327 #else
328     if( i_sec > 0 )
329     {
330         if( i_sec == 0xff )
331         {
332             p_intf->p_sys->m_still_time = (mtime_t)(-1);
333             msg_Warn( p_intf, I64Fd, p_intf->p_sys->m_still_time );
334         }
335         else
336         {
337             p_intf->p_sys->m_still_time = 1000000 * i_sec;
338         }
339     }
340 #endif
341     vlc_mutex_unlock( &p_intf->change_lock );
342
343     return VLC_SUCCESS;
344 }
345