* modules/*: sanitization of the modules description strings.
[vlc.git] / modules / gui / win32 / win32.cpp
1 /*****************************************************************************\r
2  * win32.cpp : Win32 interface plugin for vlc\r
3  *****************************************************************************\r
4  * Copyright (C) 2002-2003 VideoLAN\r
5  * $Id: win32.cpp,v 1.18 2003/03/30 18:14:38 gbazin Exp $\r
6  *\r
7  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>\r
8  *\r
9  * This program is free software; you can redistribute it and/or modify\r
10  * it under the terms of the GNU General Public License as published by\r
11  * the Free Software Foundation; either version 2 of the License, or\r
12  * (at your option) any later version.\r
13  *\r
14  * This program is distributed in the hope that it will be useful,\r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
17  * GNU General Public License for more details.\r
18  *\r
19  * You should have received a copy of the GNU General Public License\r
20  * along with this program; if not, write to the Free Software\r
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.\r
22  *****************************************************************************/\r
23 \r
24 /*****************************************************************************\r
25  * Preamble\r
26  *****************************************************************************/\r
27 #include <vcl.h>\r
28 #include <stdlib.h>                                      /* malloc(), free() */\r
29 #include <errno.h>                                                /* ENOMEM */\r
30 #include <string.h>\r
31 \r
32 #include <vlc/vlc.h>\r
33 #include <vlc/intf.h>\r
34 \r
35 #include "mainframe.h"\r
36 #include "menu.h"\r
37 #include "win32_common.h"\r
38 \r
39 /*****************************************************************************\r
40  * Exported interface functions.\r
41  *****************************************************************************/\r
42 extern "C" __declspec(dllexport)\r
43     int __VLC_SYMBOL( vlc_entry ) ( module_t *p_module );\r
44 \r
45 /*****************************************************************************\r
46  * Local prototypes.\r
47  *****************************************************************************/\r
48 static int  Open   ( vlc_object_t * );\r
49 static void Close  ( vlc_object_t * );\r
50 static void Run    ( intf_thread_t * );\r
51 \r
52 int Win32Manage( void *p_data );\r
53 \r
54 /*****************************************************************************\r
55  * Open: initialize interface\r
56  *****************************************************************************/\r
57 static int Open ( vlc_object_t *p_this )\r
58 {\r
59     intf_thread_t *p_intf = (intf_thread_t *)p_this;\r
60 \r
61     /* Allocate instance and initialize some members */\r
62     p_intf->p_sys = (intf_sys_t *) malloc( sizeof( intf_sys_t ) );\r
63     if( p_intf->p_sys == NULL )\r
64     {\r
65         msg_Err( p_intf, "out of memory" );\r
66         return( 1 );\r
67     };\r
68 \r
69     p_intf->pf_run = Run;\r
70 \r
71     p_intf->p_sys->p_sub = msg_Subscribe( p_intf );\r
72 \r
73     /* Initialize Win32 thread */\r
74     p_intf->p_sys->b_playing = 0;\r
75     p_intf->p_sys->b_popup_changed = 0;\r
76 \r
77     p_intf->p_sys->p_input = NULL;\r
78     p_intf->p_sys->i_playing = -1;\r
79     p_intf->p_sys->b_play_when_adding = VLC_TRUE;\r
80 \r
81     p_intf->p_sys->b_slider_free = 1;\r
82 \r
83     p_intf->p_sys->b_aout_update = VLC_FALSE;\r
84     p_intf->p_sys->b_vout_update = VLC_FALSE;\r
85     p_intf->p_sys->b_program_update = VLC_FALSE;\r
86     p_intf->p_sys->b_title_update = VLC_FALSE;\r
87     p_intf->p_sys->b_chapter_update = VLC_FALSE;\r
88     p_intf->p_sys->b_audio_update = VLC_FALSE;\r
89     p_intf->p_sys->b_spu_update = VLC_FALSE;\r
90 \r
91     return( 0 );\r
92 }\r
93 \r
94 /*****************************************************************************\r
95  * Close: destroy interface\r
96  *****************************************************************************/\r
97 static void Close ( vlc_object_t *p_this )\r
98 {\r
99     intf_thread_t *p_intf = (intf_thread_t *)p_this;\r
100 \r
101     if( p_intf->p_sys->p_input )\r
102     {\r
103         vlc_object_release( p_intf->p_sys->p_input );\r
104     }\r
105 \r
106     msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );\r
107 \r
108     /* Destroy structure */\r
109     free( p_intf->p_sys );\r
110 }\r
111 \r
112 /*****************************************************************************\r
113  * Run: main loop\r
114  *****************************************************************************/\r
115 static void Run( intf_thread_t *p_intf )\r
116 {\r
117     p_intf->p_sys->p_window = new TMainFrameDlg( NULL, p_intf );\r
118     p_intf->p_sys->p_playwin = new TPlaylistDlg( NULL, p_intf );\r
119     p_intf->p_sys->p_messages = new TMessagesDlg( NULL, p_intf );\r
120     p_intf->p_sys->p_menus = new TMenusGen( p_intf );\r
121 \r
122     /* show main window and wait until it is closed */\r
123     p_intf->p_sys->p_window->ShowModal();\r
124 \r
125     if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;\r
126     if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;\r
127     if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;\r
128     delete p_intf->p_sys->p_menus;\r
129     delete p_intf->p_sys->p_messages;\r
130     delete p_intf->p_sys->p_playwin;\r
131     delete p_intf->p_sys->p_window;\r
132 }\r
133 \r
134 /*****************************************************************************\r
135  * Win32Manage: manage main thread messages\r
136  *****************************************************************************\r
137  * In this function, called approx. 10 times a second, we check what the\r
138  * main program wanted to tell us.\r
139  *****************************************************************************/\r
140 int Win32Manage( intf_thread_t *p_intf )\r
141 {\r
142     vlc_mutex_lock( &p_intf->change_lock );\r
143 \r
144     /* If the "display popup" flag has changed */\r
145     if( p_intf->b_menu_change )\r
146     {\r
147         /* FIXME: It would be nice to close the popup when the user left-clicks\r
148         elsewhere, or to actualize the position when he right-clicks again,\r
149         but i couldn't find a way to close it :-( */\r
150         TPoint MousePos = Mouse->CursorPos;\r
151         p_intf->p_sys->p_window->PopupMenuMain->Popup( MousePos.x, MousePos.y );\r
152         p_intf->b_menu_change = 0;\r
153     }\r
154 \r
155     /* Update the log window */\r
156     p_intf->p_sys->p_messages->UpdateLog();\r
157 \r
158     /* Update the playlist */\r
159     p_intf->p_sys->p_playwin->Manage();\r
160 \r
161     /* Update the input */\r
162     if( p_intf->p_sys->p_input == NULL )\r
163     {\r
164         p_intf->p_sys->p_input = (input_thread_t *)\r
165             vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );\r
166     }\r
167     else if( p_intf->p_sys->p_input->b_dead )\r
168     {\r
169         vlc_object_release( p_intf->p_sys->p_input );\r
170         p_intf->p_sys->p_input = NULL;\r
171     }\r
172 \r
173     if( p_intf->p_sys->p_input != NULL && !p_intf->p_sys->p_input->b_die )\r
174     {\r
175         vlc_bool_t b_need_menus = VLC_FALSE;\r
176         input_thread_t  * p_input = p_intf->p_sys->p_input;\r
177         vlc_object_t * p_aout = NULL;\r
178         vlc_object_t * p_vout = NULL;\r
179 \r
180         vlc_mutex_lock( &p_input->stream.stream_lock );\r
181 \r
182         /* New input or stream map change */\r
183         if( p_input->stream.b_changed )\r
184         {\r
185             p_intf->p_sys->p_window->ModeManage();\r
186             b_need_menus = VLC_TRUE;\r
187             p_intf->p_sys->b_playing = 1;\r
188         }\r
189 \r
190         /* Manage the slider */\r
191         if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )\r
192         {\r
193             TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;\r
194             off_t NewValue = TrackBar->Position;\r
195 \r
196 #define p_area p_input->stream.p_selected_area\r
197             /* If the user hasn't touched the slider since the last time,\r
198              * then the input can safely change it */\r
199             if( NewValue == p_intf->p_sys->OldValue )\r
200             {\r
201                 /* Update the value */\r
202                 TrackBar->Position = p_intf->p_sys->OldValue =\r
203                     ( (off_t)SLIDER_MAX_VALUE * p_area->i_tell ) /\r
204                       p_area->i_size;\r
205             }\r
206             /* Otherwise, send message to the input if the user has\r
207              * finished dragging the slider */\r
208             else if( p_intf->p_sys->b_slider_free )\r
209             {\r
210                 off_t i_seek = ( NewValue * p_area->i_size ) /\r
211                                  (off_t)SLIDER_MAX_VALUE;\r
212 \r
213                 /* release the lock to be able to seek */\r
214                 vlc_mutex_unlock( &p_input->stream.stream_lock );\r
215                 input_Seek( p_input, i_seek, INPUT_SEEK_SET );\r
216                 vlc_mutex_lock( &p_input->stream.stream_lock );\r
217 \r
218                 /* Update the old value */\r
219                 p_intf->p_sys->OldValue = NewValue;\r
220             }\r
221 #    undef p_area\r
222 \r
223         }\r
224 \r
225         if( p_intf->p_sys->i_part != p_input->stream.p_selected_area->i_part )\r
226         {\r
227             p_intf->p_sys->b_chapter_update = 1;\r
228             b_need_menus = VLC_TRUE;\r
229         }\r
230 \r
231         /* Does the audio output require to update the menus ? */\r
232         p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,\r
233                                                   FIND_ANYWHERE );\r
234         if( p_aout != NULL )\r
235         {\r
236             vlc_value_t val;\r
237             if( var_Get( p_aout, "intf-change", &val ) >= 0\r
238                 && val.b_bool )\r
239             {\r
240                 p_intf->p_sys->b_aout_update = 1;\r
241                 b_need_menus = VLC_TRUE;\r
242             }\r
243 \r
244             vlc_object_release( p_aout );\r
245         }\r
246 \r
247         /* Does the video output require to update the menus ? */\r
248         p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,\r
249                                                    FIND_ANYWHERE );\r
250         if( p_vout != NULL )\r
251         {\r
252             vlc_value_t val;\r
253             if( var_Get( p_vout, "intf-change", &val ) >= 0\r
254                 && val.b_bool )\r
255             {\r
256                 p_intf->p_sys->b_vout_update = 1;\r
257                 b_need_menus = VLC_TRUE;\r
258             }\r
259 \r
260             if( var_Get( p_vout, "directx-on-top", &val ) >= 0 )\r
261             {\r
262                 p_intf->p_sys->p_window->MenuOnTop->Checked = val.b_bool;\r
263                 p_intf->p_sys->p_window->PopupOnTop->Checked = val.b_bool;\r
264             }\r
265 \r
266             vlc_object_release( p_vout );\r
267         }\r
268 \r
269         if( b_need_menus )\r
270         {\r
271             p_intf->p_sys->p_menus->SetupMenus();\r
272         }\r
273 \r
274         vlc_mutex_unlock( &p_input->stream.stream_lock );\r
275     }\r
276     else if( p_intf->p_sys->b_playing && !p_intf->b_die )\r
277     {\r
278         p_intf->p_sys->p_window->ModeManage();\r
279         p_intf->p_sys->b_playing = 0;\r
280     }\r
281 \r
282     if( p_intf->b_die )\r
283     {\r
284         vlc_mutex_unlock( &p_intf->change_lock );\r
285 \r
286         /* Prepare to die, young Skywalker */\r
287         p_intf->p_sys->p_window->ModalResult = mrOk;\r
288 \r
289         /* Just in case */\r
290         return( FALSE );\r
291     }\r
292 \r
293     vlc_mutex_unlock( &p_intf->change_lock );\r
294 \r
295     return( TRUE );\r
296 }\r
297 \r
298 /*****************************************************************************\r
299  * Module descriptor\r
300  *****************************************************************************/\r
301 \r
302 #define MAX_LINES_TEXT N_( "maximum number of lines in the log window" )\r
303 #define MAX_LINES_LONGTEXT N_( \\r
304     "You can set the maximum number of lines that the log window will display."\\r
305     " Enter -1 if you want to keep all messages." )\r
306 #define SHOW_CAPTIONS_TEXT N_( "display text under images in the toolbar" )\r
307 #define SHOW_CAPTIONS_LONGTEXT N_( \\r
308     "Check this option if you want to display the caption of the buttons in " \\r
309     "the toolbar. Beware, the display may be messed up" )\r
310 \r
311 vlc_module_begin();\r
312     add_category_hint( N_("Miscellaneous"), NULL, VLC_TRUE );\r
313     add_integer( "intfwin-max-lines", 500, NULL, MAX_LINES_TEXT,\r
314                  MAX_LINES_LONGTEXT, VLC_TRUE );\r
315     add_bool( "intfwin-show-captions", 0, NULL, SHOW_CAPTIONS_TEXT,\r
316               SHOW_CAPTIONS_LONGTEXT, VLC_FALSE );\r
317     set_description( _("Native Windows interface") );\r
318     set_capability( "interface", 100 );\r
319     set_callbacks( E_(Open), E_(Close) );\r
320     add_shortcut( "win" );\r
321     add_shortcut( "win32" );\r
322 vlc_module_end();\r