]> git.sesse.net Git - vlc/blob - src/interface/interface.c
* include/interface.h: renamed this file to vlc_interface.h to avoid name
[vlc] / src / interface / interface.c
1 /*****************************************************************************
2  * interface.c: interface access for other threads
3  * This library provides basic functions for threads to interact with user
4  * interface, such as command line.
5  *****************************************************************************
6  * Copyright (C) 1998-2001 VideoLAN
7  * $Id: interface.c,v 1.104 2003/06/24 13:33:49 sam Exp $
8  *
9  * Authors: Vincent Seguin <seguin@via.ecp.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>                                      /* free(), strtol() */
30 #include <stdio.h>                                                   /* FILE */
31 #include <string.h>                                            /* strerror() */
32
33 #include <vlc/vlc.h>
34
35 #include "stream_control.h"
36 #include "input_ext-intf.h"
37
38 #include "audio_output.h"
39
40 #include "vlc_interface.h"
41
42 #include "video.h"
43 #include "video_output.h"
44
45 /*****************************************************************************
46  * Local prototypes
47  *****************************************************************************/
48 static void Manager( intf_thread_t *p_intf );
49
50 /*****************************************************************************
51  * intf_Create: prepare interface before main loop
52  *****************************************************************************
53  * This function opens output devices and creates specific interfaces. It sends
54  * its own error messages.
55  *****************************************************************************/
56 intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
57 {
58     intf_thread_t * p_intf;
59     char *psz_intf;
60
61     /* Allocate structure */
62     p_intf = vlc_object_create( p_this, VLC_OBJECT_INTF );
63     if( !p_intf )
64     {
65         msg_Err( p_this, "out of memory" );
66         return NULL;
67     }
68
69     /* XXX: workaround for a bug in VLC 0.5.0 where the dvdplay plugin was
70      * registering itself in $interface, which we do not want to happen. */
71     psz_intf = config_GetPsz( p_intf, "intf" );
72     if( psz_intf )
73     {
74         if( !strcasecmp( psz_intf, "dvdplay" ) )
75         {
76             config_PutPsz( p_intf, "intf", "" );
77         }
78         free( psz_intf );
79     }
80
81     /* Choose the best module */
82     p_intf->p_module = module_Need( p_intf, "interface", psz_module );
83
84     if( p_intf->p_module == NULL )
85     {
86         msg_Err( p_intf, "no suitable intf module" );
87         vlc_object_destroy( p_intf );
88         return NULL;
89     }
90
91     /* Initialize structure */
92     p_intf->b_menu        = VLC_FALSE;
93     p_intf->b_menu_change = VLC_FALSE;
94
95     /* Initialize mutexes */
96     vlc_mutex_init( p_intf, &p_intf->change_lock );
97
98     msg_Dbg( p_intf, "interface initialized" );
99
100     /* Attach interface to its parent object */
101     vlc_object_attach( p_intf, p_this );
102
103     return p_intf;
104 }
105
106 /*****************************************************************************
107  * intf_RunThread: launch the interface thread
108  *****************************************************************************
109  * This function either creates a new thread and runs the interface in it,
110  * or runs the interface in the current thread, depending on b_block.
111  *****************************************************************************/
112 int intf_RunThread( intf_thread_t *p_intf )
113 {
114     if( p_intf->b_block )
115     {
116         /* Run a manager thread, launch the interface, kill the manager */
117         if( vlc_thread_create( p_intf, "manager", Manager,
118                                VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
119         {
120             msg_Err( p_intf, "cannot spawn manager thread" );
121             return VLC_EGENERIC;
122         }
123
124         p_intf->pf_run( p_intf );
125
126         p_intf->b_die = VLC_TRUE;
127
128         /* Do not join the thread... intf_StopThread will do it for us */
129     }
130     else
131     {
132         /* Run the interface in a separate thread */
133         if( vlc_thread_create( p_intf, "interface", p_intf->pf_run,
134                                VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
135         {
136             msg_Err( p_intf, "cannot spawn interface thread" );
137             return VLC_EGENERIC;
138         }
139     }
140
141     return VLC_SUCCESS;
142 }
143
144 /*****************************************************************************
145  * intf_StopThread: end the interface thread
146  *****************************************************************************
147  * This function asks the interface thread to stop.
148  *****************************************************************************/
149 void intf_StopThread( intf_thread_t *p_intf )
150 {
151     /* Tell the interface to die */
152     if( !p_intf->b_block )
153     {
154         p_intf->b_die = VLC_TRUE;
155     }
156
157     /* Wait for the thread to exit */
158     vlc_thread_join( p_intf );
159 }
160
161 /*****************************************************************************
162  * intf_Destroy: clean interface after main loop
163  *****************************************************************************
164  * This function destroys specific interfaces and close output devices.
165  *****************************************************************************/
166 void intf_Destroy( intf_thread_t *p_intf )
167 {
168     /* Unlock module */
169     module_Unneed( p_intf, p_intf->p_module );
170
171     vlc_mutex_destroy( &p_intf->change_lock );
172
173     /* Free structure */
174     vlc_object_destroy( p_intf );
175 }
176
177 /* Following functions are local */
178
179 /*****************************************************************************
180  * Manager: helper thread for blocking interfaces
181  *****************************************************************************
182  * If the interface is launched in the main thread, it will not listen to
183  * p_vlc->b_die events because it is only supposed to listen to p_intf->b_die.
184  * This thread takes care of the matter.
185  *****************************************************************************/
186 static void Manager( intf_thread_t *p_intf )
187 {
188     while( !p_intf->b_die )
189     {
190         msleep( INTF_IDLE_SLEEP );
191
192         if( p_intf->p_vlc->b_die )
193         {
194             p_intf->b_die = VLC_TRUE;
195             return;
196         }
197     }
198 }
199