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