* modules/gui/wince/interface.cpp: include extra version information in the about...
[vlc.git] / modules / gui / wince / interface.cpp
1 /*****************************************************************************
2  * interface.cpp: WinCE gui plugin for VLC
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111,
23  * USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <vlc/vlc.h>
30 #include <vlc/aout.h>
31 #include <vlc/vout.h>
32 #include <vlc/intf.h>
33
34 #include "wince.h"
35
36 #include <windowsx.h>
37 #include <commctrl.h>
38 #include <commdlg.h>
39
40 #define NUMIMAGES     9   // Number of buttons in the toolbar           
41 #define IMAGEWIDTH    17   // Width of the buttons in the toolbar  
42 #define IMAGEHEIGHT   16   // Height of the buttons in the toolbar  
43 #define BUTTONWIDTH   0    // Width of the button images in the toolbar
44 #define BUTTONHEIGHT  0    // Height of the button images in the toolbar
45 #define ID_TOOLBAR    2000 // Identifier of the main tool bar
46
47 // Help strings
48 #define HELP_SIMPLE _T("Quick file open")
49 #define HELP_ADV    _T("Advanced open")
50 #define HELP_FILE   _T("Open a file")
51 #define HELP_DISC   _T("Open Disc Media")
52 #define HELP_NET    _T("Open a network stream")
53 #define HELP_SAT    _T("Open a satellite stream")
54 #define HELP_EJECT  _T("Eject the DVD/CD")
55 #define HELP_EXIT   _T("Exit this program")
56
57 #define HELP_OTHER _T("Open other types of inputs")
58
59 #define HELP_PLAYLIST   _T("Open the playlist")
60 #define HELP_LOGS       _T("Show the program logs")
61 #define HELP_FILEINFO   _T("Show information about the file being played")
62
63 #define HELP_PREFS _T("Go to the preferences menu")
64
65 #define HELP_ABOUT _T("About this program")
66
67 #define HELP_STOP _T("Stop")
68
69 #define HELP_PLAY _T("Play")
70 #define HELP_PAUSE _T("Pause")
71 #define HELP_PLO _T("Playlist")
72 #define HELP_PLP _T("Previous playlist item")
73 #define HELP_PLN _T("Next playlist item")
74 #define HELP_SLOW _T("Play slower")
75 #define HELP_FAST _T("Play faster")
76
77 // The TBBUTTON structure contains information the toolbar buttons.
78 static TBBUTTON tbButton[] =      
79 {
80   {0, ID_FILE_QUICKOPEN,        TBSTATE_ENABLED, TBSTYLE_BUTTON},
81   {1, ID_FILE_OPENNET,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
82   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
83   {2, StopStream_Event,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
84   {3, PlayStream_Event,        TBSTATE_ENABLED, TBSTYLE_BUTTON},
85   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
86   {4, ID_VIEW_PLAYLIST,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
87   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
88   {5, PrevStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
89   {6, NextStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
90   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
91   {7, SlowStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
92   {8, FastStream_Event,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
93 };
94
95 // Toolbar ToolTips
96 TCHAR * szToolTips[] = 
97 {
98     HELP_SIMPLE, HELP_NET, HELP_STOP, HELP_PLAY, HELP_PLO, HELP_PLP,
99     HELP_PLN, HELP_SLOW, HELP_FAST
100 };
101
102 /*****************************************************************************
103  * Constructor.
104  *****************************************************************************/
105 Interface::Interface( intf_thread_t *p_intf, CBaseWindow *p_parent,
106                       HINSTANCE h_inst )
107   : CBaseWindow( p_intf, p_parent, h_inst ),
108     hwndMain(0), hwndCB(0), hwndTB(0), hwndSlider(0), hwndLabel(0),
109     hwndVol(0), hwndSB(0), timer(0), video(0), b_volume_hold(0)
110 {
111 }
112
113 Interface::~Interface()
114 {
115     if( timer ) delete timer;
116     if( video ) delete video;
117 }
118
119 BOOL Interface::InitInstance()
120 {
121     /* Initializations */
122     i_old_playing_status = PAUSE_S;
123
124     int i_style = WS_VISIBLE;
125
126 #ifndef UNDER_CE
127     i_style |= WS_OVERLAPPEDWINDOW | WS_SIZEBOX;
128 #endif
129
130     // Create main window
131     hwndMain =
132         CreateWindow( _T("VLC WinCE"), _T("VLC media player"), i_style,
133                       0, MENU_HEIGHT, CW_USEDEFAULT, CW_USEDEFAULT,
134                       NULL, NULL, GetInstance(), (void *)this );
135
136     if( !hwndMain ) return FALSE;
137
138     ShowWindow( hwndMain, TRUE );
139     UpdateWindow( hwndMain );
140
141     return TRUE;
142 }
143
144 /***********************************************************************
145 FUNCTION: 
146   CreateMenuBar
147
148 PURPOSE: 
149   Creates a menu bar.
150 ***********************************************************************/
151 HWND Interface::CreateMenuBar( HWND hwnd, HINSTANCE hInst )
152 {
153     HMENU menu_file, menu_view;
154
155 #ifdef UNDER_CE
156     SHMENUBARINFO mbi;
157     memset( &mbi, 0, sizeof(SHMENUBARINFO) );
158     mbi.cbSize     = sizeof(SHMENUBARINFO);
159     mbi.hwndParent = hwnd;
160     mbi.hInstRes   = hInst;
161     mbi.nToolBarId = IDR_MENUBAR;
162
163     if( !SHCreateMenuBar( &mbi ) )
164     {
165         MessageBox(hwnd, _T("SHCreateMenuBar Failed"), _T("Error"), MB_OK);
166         return 0;
167     }
168
169     TBBUTTONINFO tbbi;
170     tbbi.cbSize = sizeof(tbbi);
171     tbbi.dwMask = TBIF_LPARAM;
172
173     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_FILE, (LPARAM)&tbbi );
174     menu_file = (HMENU)tbbi.lParam;
175     RemoveMenu( menu_file, 0, MF_BYPOSITION );
176     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_VIEW, (LPARAM)&tbbi );
177     menu_view = (HMENU)tbbi.lParam;
178     RemoveMenu( menu_view, 0, MF_BYPOSITION );
179     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_SETTINGS, (LPARAM)&tbbi );
180     menu_settings = (HMENU)tbbi.lParam;
181     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_VIDEO, (LPARAM)&tbbi );
182     menu_video = (HMENU)tbbi.lParam;
183     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_AUDIO, (LPARAM)&tbbi );
184     menu_audio = (HMENU)tbbi.lParam;
185     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_NAVIGATION, (LPARAM)&tbbi );
186     menu_navigation = (HMENU)tbbi.lParam;
187
188 #else
189     menu_file = CreatePopupMenu();
190     menu_view = CreatePopupMenu();
191     menu_settings = CreatePopupMenu();
192     menu_audio = CreatePopupMenu();
193     menu_video = CreatePopupMenu();
194     menu_navigation = CreatePopupMenu();
195 #endif
196
197     AppendMenu( menu_file, MF_STRING, ID_FILE_QUICKOPEN,
198                 _T("Quick &Open File...") );
199     AppendMenu( menu_file, MF_SEPARATOR, 0, 0 );
200     AppendMenu( menu_file, MF_STRING, ID_FILE_OPENFILE,
201                 _T("Open &File...") );
202     AppendMenu( menu_file, MF_STRING, ID_FILE_OPENDIR,
203                 _T("Open &Directory...") );
204     AppendMenu( menu_file, MF_STRING, ID_FILE_OPENNET,
205                 _T("Open &Network Stream...") );
206     AppendMenu( menu_file, MF_SEPARATOR, 0, 0 );
207     AppendMenu( menu_file, MF_STRING, ID_FILE_ABOUT,
208                 _T("About VLC") );
209     AppendMenu( menu_file, MF_STRING, ID_FILE_EXIT,
210                 _T("E&xit") );
211
212     AppendMenu( menu_view, MF_STRING, ID_VIEW_PLAYLIST,
213                 _T("&Playlist...") );
214     AppendMenu( menu_view, MF_STRING, ID_VIEW_MESSAGES,
215                 _T("&Messages...") );
216     AppendMenu( menu_view, MF_STRING, ID_VIEW_STREAMINFO,
217                 _T("Stream and Media &info...") );
218
219     AppendMenu( menu_settings, MF_STRING, ID_PREFERENCES,
220                 _T("&Preferences...") );
221
222
223 #ifdef UNDER_CE
224     return mbi.hwndMB;
225
226 #else
227     HMENU hmenu = CreateMenu();
228
229     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_file, _T("File") );
230     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_view, _T("View") );
231     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_settings,
232                 _T("Settings") );
233     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_audio, _T("Audio") );
234     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_video, _T("Video") );
235     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_navigation, _T("Nav") );
236
237     SetMenu( hwnd, hmenu );
238     return 0;
239
240 #endif
241 }
242
243 /***********************************************************************
244 FUNCTION: 
245   CreateToolBar
246
247 PURPOSE: 
248   Registers the TOOLBAR control class and creates a toolbar.
249 ***********************************************************************/
250 HWND CreateToolBar( HWND hwnd, HINSTANCE hInst )
251 {
252     DWORD dwStyle;
253     HWND hwndTB;
254     RECT rect, rectTB;
255
256     INITCOMMONCONTROLSEX iccex;
257     iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
258     iccex.dwICC = ICC_BAR_CLASSES;
259
260     // Registers TOOLBAR control classes from the common control dll
261     InitCommonControlsEx (&iccex);
262
263     //  Create the toolbar control
264     dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS |
265         WS_EX_OVERLAPPEDWINDOW | CCS_NOPARENTALIGN;
266
267     hwndTB = CreateToolbarEx( hwnd, dwStyle, 0, NUMIMAGES,
268         hInst, IDB_BITMAP1, tbButton, sizeof(tbButton) / sizeof(TBBUTTON),
269         BUTTONWIDTH, BUTTONHEIGHT, IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON) );
270
271     if( !hwndTB ) return NULL;
272   
273     // Add ToolTips to the toolbar.
274     SendMessage( hwndTB, TB_SETTOOLTIPS, (WPARAM)NUMIMAGES, 
275                  (LPARAM)szToolTips );
276
277     // Reposition the toolbar.
278     GetClientRect( hwnd, &rect );
279     GetWindowRect( hwndTB, &rectTB );
280     MoveWindow( hwndTB, rect.left, rect.bottom - rect.top - 2*MENU_HEIGHT, 
281                 rect.right - rect.left, MENU_HEIGHT, TRUE );
282
283     return hwndTB;
284 }
285
286 /***********************************************************************
287
288 FUNCTION: 
289   CreateSliderBar
290
291 PURPOSE: 
292   Registers the TRACKBAR_CLASS control class and creates a trackbar.
293
294 ***********************************************************************/
295 HWND CreateSliderBar( HWND hwnd, HINSTANCE hInst )
296 {
297     HWND hwndSlider;
298     RECT rect;
299
300     INITCOMMONCONTROLSEX iccex;
301     iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
302     iccex.dwICC = ICC_BAR_CLASSES;
303
304     // Registers TRACKBAR_CLASS control classes from the common control dll
305     InitCommonControlsEx( &iccex );
306
307     hwndSlider = CreateWindowEx( 0, TRACKBAR_CLASS, NULL,
308                 WS_CHILD | WS_VISIBLE | TBS_HORZ | WS_EX_OVERLAPPEDWINDOW |
309                 TBS_BOTTOM,  //|WS_CLIPSIBLINGS,
310                 0, 0, 0, 0, hwnd, NULL, hInst, NULL );
311
312     if( !hwndSlider ) return NULL;
313
314     SendMessage( hwndSlider, TBM_SETRANGEMIN, 1, 0 );
315     SendMessage( hwndSlider, TBM_SETRANGEMAX, 1, SLIDER_MAX_POS );
316     SendMessage( hwndSlider, TBM_SETPOS, 1, 0 );
317
318     // Reposition the trackbar
319     GetClientRect( hwnd, &rect );
320     MoveWindow( hwndSlider, rect.left, 
321                 rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT, 
322                 rect.right - rect.left - 40, 30, TRUE );
323
324     ShowWindow( hwndSlider, SW_HIDE );
325
326     return hwndSlider;
327 }
328
329 HWND CreateStaticText( HWND hwnd, HINSTANCE hInst )
330 {
331     HWND hwndLabel;
332     RECT rect;
333
334     hwndLabel = CreateWindowEx( 0, _T("STATIC"), _T("label"),
335                                 WS_CHILD | WS_VISIBLE | SS_CENTER ,
336                                 0, 0, 0, 0, hwnd, (HMENU)1980, hInst, NULL );
337
338     // Reposition the trackbar
339     GetClientRect( hwnd, &rect );
340
341     MoveWindow( hwndLabel, rect.left,
342                 rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT +30,
343                 rect.right - rect.left - 40,
344                 SLIDER_HEIGHT - 30, TRUE );
345
346     ShowWindow( hwndLabel, SW_HIDE );
347
348     return hwndLabel;
349 }
350
351 /***********************************************************************
352
353 FUNCTION: 
354   CreateVolTrackBar
355
356 PURPOSE: 
357   Registers the TRACKBAR_CLASS control class and creates a trackbar.
358
359 ***********************************************************************/
360 HWND CreateVolTrackBar( HWND hwnd, HINSTANCE hInst )
361 {
362     HWND hwndVol;
363     RECT rect;
364
365     INITCOMMONCONTROLSEX iccex;
366     iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
367     iccex.dwICC = ICC_BAR_CLASSES;
368
369     // Registers TRACKBAR_CLASS control classes from the common control dll
370     InitCommonControlsEx( &iccex );
371
372     hwndVol = CreateWindowEx( 0, TRACKBAR_CLASS, NULL,
373                 WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_RIGHT | TBS_AUTOTICKS |
374                 WS_EX_OVERLAPPEDWINDOW, //|WS_CLIPSIBLINGS,
375                 0, 0, 0, 0, hwnd, NULL, hInst, NULL );
376
377     if( !hwndVol ) return NULL;
378
379     SendMessage( hwndVol, TBM_SETRANGEMIN, 1, 0 );
380     SendMessage( hwndVol, TBM_SETRANGEMAX, 1, 200 );
381     SendMessage( hwndVol, TBM_SETPOS, 1, 100 );
382     SendMessage( hwndVol, TBM_SETTICFREQ, 50, 0 );  
383
384     // Reposition the trackbar
385     GetClientRect( hwnd, &rect );
386     MoveWindow( hwndVol, rect.right - rect.left - 40, 
387                 rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT, 
388                 40, SLIDER_HEIGHT, TRUE );
389
390     ShowWindow( hwndVol, SW_HIDE );
391
392     return hwndVol;
393 }
394
395 /***********************************************************************
396
397 FUNCTION: 
398   CreateStatusBar
399
400 PURPOSE: 
401   Registers the StatusBar control class and creates a Statusbar.
402
403 ***********************************************************************/
404 HWND CreateStatusBar( HWND hwnd, HINSTANCE hInst )
405 {
406     DWORD dwStyle;
407     HWND hwndSB;
408     RECT rect;
409
410     INITCOMMONCONTROLSEX iccex;
411     iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
412     iccex.dwICC = ICC_BAR_CLASSES;
413
414     // Registers Statusbar control classes from the common control dll
415     InitCommonControlsEx( &iccex );
416
417     // Create the statusbar control
418     dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS | CCS_NOPARENTALIGN;
419
420     hwndSB = CreateWindowEx( 0, STATUSCLASSNAME, NULL,
421                              WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_BOTTOM |
422                              TBS_RIGHT  |WS_CLIPSIBLINGS,
423                              0, 0, CW_USEDEFAULT, 50, hwnd, NULL, hInst, 0 );
424
425     if (!hwndSB ) return NULL;
426
427     // Get the coordinates of the parent window's client area. 
428     GetClientRect( hwnd, &rect );
429
430     // allocate memory for the panes of status bar
431     int nopanes = 2;
432     int *indicators = new int[nopanes];
433
434     // set width for the panes
435     indicators[0] = 3 * ( rect.right - rect.left ) / 4;
436     indicators[1] = rect.right - rect.left;
437
438     // call functions to set style
439     SendMessage( hwndSB, SB_SETPARTS, (WPARAM)nopanes, (LPARAM)indicators );
440
441     return hwndSB;
442 }
443
444 /***********************************************************************
445 FUNCTION: 
446   WndProc
447
448 PURPOSE: 
449   Processes messages sent to the main window.
450 ***********************************************************************/
451 LRESULT Interface::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
452 {
453     switch( msg )
454     {
455     case WM_CREATE:
456         hwndCB = CreateMenuBar( hwnd, hInst );
457         hwndTB = CreateToolBar( hwnd, hInst );
458         hwndSlider = CreateSliderBar( hwnd, hInst );
459         hwndLabel = CreateStaticText( hwnd, hInst );
460         hwndVol = CreateVolTrackBar( hwnd, hInst );
461 #ifdef UNDER_CE
462         hwndSB = CreateStatusBar( hwnd, hInst );
463 #endif
464
465         /* Video window */
466         if( config_GetInt( p_intf, "wince-embed" ) )
467             video = CreateVideoWindow( p_intf, hwnd );
468
469         timer = new Timer( p_intf, hwnd, this );
470         break;
471
472     case WM_COMMAND:
473         switch( GET_WM_COMMAND_ID(wp,lp) )
474         {
475         case ID_FILE_QUICKOPEN: 
476         case ID_FILE_OPENFILE: 
477         case ID_FILE_OPENDIR:
478         case ID_FILE_OPENNET:
479         case ID_VIEW_STREAMINFO:
480         case ID_VIEW_MESSAGES:
481         case ID_VIEW_PLAYLIST:
482         case ID_PREFERENCES:
483             OnShowDialog( GET_WM_COMMAND_ID(wp,lp) );
484             break;
485
486         case PlayStream_Event: OnPlayStream(); break;
487         case StopStream_Event: OnStopStream(); break;
488         case PrevStream_Event: OnPrevStream(); break;
489         case NextStream_Event: OnNextStream(); break;
490         case SlowStream_Event: OnSlowStream(); break;
491         case FastStream_Event: OnFastStream(); break;
492
493         case ID_FILE_ABOUT: 
494         {
495             string about = (string)"VLC media player " PACKAGE_VERSION +
496                 _("\n(WinCE interface)\n\n") +
497                 _("(c) 1996-2005 - the VideoLAN Team\n\n") +
498                 _("Compiled by ") + VLC_CompileBy() + "@" +
499                 VLC_CompileHost() + "." + VLC_CompileDomain() + ".\n" +
500                 _("Compiler: ") + VLC_Compiler() + ".\n" +
501                 _("Based on SVN revision: ") + VLC_Changeset() + ".\n\n" +
502                 _("The VideoLAN team <videolan@videolan.org>\n"
503                   "http://www.videolan.org/");
504
505             MessageBox( hwnd, _FROMMB(about.c_str()),
506                         _T("About VLC media player"), MB_OK );
507             break;
508         }
509
510         case ID_FILE_EXIT:
511             SendMessage( hwnd, WM_CLOSE, 0, 0 );
512             break;
513
514         default:
515             OnMenuEvent( p_intf, GET_WM_COMMAND_ID(wp,lp) );
516             // we should test if it is a menu command
517         }
518         break;
519   
520     case WM_TIMER:
521         timer->Notify();
522         break;
523
524     case WM_CTLCOLORSTATIC: 
525         if( ( (HWND)lp == hwndSlider ) || ( (HWND)lp == hwndVol ) )
526         { 
527             return( (LRESULT)::GetSysColorBrush(COLOR_3DFACE) ); 
528         }
529         if( (HWND)lp == hwndLabel )
530         {
531             SetBkColor( (HDC)wp, RGB (192, 192, 192) ); 
532             return( (LRESULT)::GetSysColorBrush(COLOR_3DFACE) ); 
533         }
534         break;
535
536     case WM_HSCROLL:
537         if( (HWND)lp == hwndSlider ) OnSliderUpdate( wp );
538         break;
539
540     case WM_VSCROLL:
541         if( (HWND)lp == hwndVol ) OnChange( wp );
542         break;
543
544     case WM_INITMENUPOPUP:
545         if( (HMENU)wp == menu_settings )
546             RefreshSettingsMenu( p_intf, menu_settings );
547         if( (HMENU)wp == menu_audio )
548             RefreshAudioMenu( p_intf, menu_audio );
549         if( (HMENU)wp == menu_video )
550             RefreshVideoMenu( p_intf, menu_video );
551         if( (HMENU)wp == menu_navigation )
552             RefreshNavigMenu( p_intf, menu_navigation );
553         /* Fall through */
554
555     case WM_KILLFOCUS:
556         SHFullScreen( hwnd, SHFS_SHOWSIPBUTTON );
557     case WM_ENTERMENULOOP:
558         if( video && video->hWnd )
559             SendMessage( video->hWnd, WM_KILLFOCUS, 0, 0 );
560         break;
561
562     case WM_SETFOCUS:
563         SHSipPreference( hwnd, SIP_DOWN ); 
564         SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
565     case WM_EXITMENULOOP:
566         if( video && video->hWnd )
567             SendMessage( video->hWnd, WM_SETFOCUS, 0, 0 );
568         break;
569
570     case WM_LBUTTONDOWN:
571         {
572             SHRGINFO shrg;
573             shrg.cbSize = sizeof( shrg );
574             shrg.hwndClient = hwnd;
575             shrg.ptDown.x = LOWORD(lp);
576             shrg.ptDown.y = HIWORD(lp);
577             shrg.dwFlags = SHRG_RETURNCMD ;
578
579             if( SHRecognizeGesture( &shrg ) == GN_CONTEXTMENU )
580                 PopupMenu( p_intf, hwnd, shrg.ptDown );
581         }
582         break;
583
584    case WM_RBUTTONUP:
585         {
586             POINT point;
587             point.x = LOWORD(lp);
588             point.y = HIWORD(lp);
589             PopupMenu( p_intf, hwnd, point );
590         }
591         break;
592
593     case WM_HELP:
594         MessageBox (hwnd, _T("Help"), _T("Help"), MB_OK);
595         break;
596
597     case WM_CLOSE:
598         if( hwndCB ) DestroyWindow( hwndCB );
599         DestroyWindow( hwnd );
600         break;
601
602     case WM_DESTROY:
603         PostQuitMessage( 0 );
604         break;
605     }
606
607     return DefWindowProc( hwnd, msg, wp, lp );
608 }
609
610 void Interface::OnShowDialog( int i_dialog_event )
611 {
612     int i_id;
613
614     switch( i_dialog_event )
615     {
616     case ID_FILE_QUICKOPEN: i_id = INTF_DIALOG_FILE_SIMPLE; break;
617     case ID_FILE_OPENFILE: i_id = INTF_DIALOG_FILE; break;
618     case ID_FILE_OPENDIR: i_id = INTF_DIALOG_DIRECTORY; break;
619     case ID_FILE_OPENNET: i_id = INTF_DIALOG_NET; break;
620     case ID_VIEW_PLAYLIST: i_id = INTF_DIALOG_PLAYLIST; break;
621     case ID_VIEW_MESSAGES: i_id = INTF_DIALOG_MESSAGES; break;
622     case ID_VIEW_STREAMINFO: i_id = INTF_DIALOG_FILEINFO; break;
623     case ID_PREFERENCES: i_id = INTF_DIALOG_PREFS; break;
624     default: i_id = INTF_DIALOG_FILE; break;
625     }
626
627     if( p_intf->p_sys->pf_show_dialog )
628         p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
629 }
630
631 void Interface::OnPlayStream( void )
632 {
633     playlist_t *p_playlist = (playlist_t *)
634         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
635     if( p_playlist == NULL ) return;
636
637     if( p_playlist->i_size && p_playlist->i_enabled )
638     {
639         vlc_value_t state;
640
641         input_thread_t *p_input = (input_thread_t *)
642             vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
643
644         if( p_input == NULL )
645         {
646             /* No stream was playing, start one */
647             playlist_Play( p_playlist );
648             TogglePlayButton( PLAYING_S );
649             vlc_object_release( p_playlist );
650             return;
651         }
652
653         var_Get( p_input, "state", &state );
654
655         if( state.i_int != PAUSE_S )
656         {
657             /* A stream is being played, pause it */
658             state.i_int = PAUSE_S;
659         }
660         else
661         {
662             /* Stream is paused, resume it */
663             state.i_int = PLAYING_S;
664         }
665         var_Set( p_input, "state", state );
666
667         TogglePlayButton( state.i_int );
668         vlc_object_release( p_input );
669         vlc_object_release( p_playlist );
670     }
671     else
672     {
673         /* If the playlist is empty, open a file requester instead */
674         vlc_object_release( p_playlist );
675         OnShowDialog( ID_FILE_QUICKOPEN );
676     }
677 }
678
679 void Interface::TogglePlayButton( int i_playing_status )
680 {
681     TBREPLACEBITMAP tbrb;
682     tbrb.hInstOld = tbrb.hInstNew = (HINSTANCE) hInst;
683     tbrb.nButtons = NUMIMAGES;
684
685     if( i_playing_status == i_old_playing_status ) return;
686
687     if( i_playing_status == PLAYING_S )
688     {
689         tbrb.nIDOld = IDB_BITMAP2;
690         tbrb.nIDNew = IDB_BITMAP1;
691
692         SendMessage( hwndTB, TB_REPLACEBITMAP, (WPARAM)0,
693                      (LPARAM)(LPTBREPLACEBITMAP)&tbrb );
694     }
695     else
696     {
697         tbrb.nIDOld = IDB_BITMAP1;
698         tbrb.nIDNew = IDB_BITMAP2;
699
700         SendMessage( hwndTB, TB_REPLACEBITMAP, (WPARAM)0,
701                      (LPARAM)(LPTBREPLACEBITMAP)&tbrb );
702     }
703
704     UpdateWindow( hwndTB );
705
706     i_old_playing_status = i_playing_status;
707 }
708
709 void Interface::OnVideoOnTop( void )
710 {
711     vlc_value_t val;
712
713     vout_thread_t *p_vout = (vout_thread_t *)
714         vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
715
716     if( p_vout == NULL ) return;
717
718     if( var_Get( (vlc_object_t *)p_vout, "video-on-top", &val ) < 0 )
719         return;
720
721     val.b_bool = !val.b_bool;
722     var_Set( (vlc_object_t *)p_vout, "video-on-top", val );
723
724     vlc_object_release( (vlc_object_t *)p_vout );
725 }
726
727 void Interface::OnSliderUpdate( int wp )
728 {
729     vlc_mutex_lock( &p_intf->change_lock );
730     input_thread_t *p_input = p_intf->p_sys->p_input;
731
732     int dwPos = SendMessage( hwndSlider, TBM_GETPOS, 0, 0 ); 
733
734     if( (int)LOWORD(wp) == SB_THUMBPOSITION ||
735         (int)LOWORD(wp) == SB_ENDSCROLL )
736     {
737         if( p_intf->p_sys->i_slider_pos != dwPos && p_input )
738         {
739             vlc_value_t pos;
740             pos.f_float = (float)dwPos / (float)SLIDER_MAX_POS;
741             var_Set( p_input, "position", pos );
742         }
743
744         p_intf->p_sys->b_slider_free = VLC_TRUE;
745     }
746     else
747     {
748         p_intf->p_sys->b_slider_free = VLC_FALSE;
749
750         if( p_input )
751         {
752             /* Update stream date */
753             char psz_time[ MSTRTIME_MAX_SIZE ], psz_total[ MSTRTIME_MAX_SIZE ];
754             mtime_t i_seconds;
755
756             i_seconds = var_GetTime( p_input, "length" ) / I64C(1000000 );
757             secstotimestr( psz_total, i_seconds );
758
759             i_seconds = var_GetTime( p_input, "time" ) / I64C(1000000 );
760             secstotimestr( psz_time, i_seconds );
761
762             SendMessage( hwndLabel, WM_SETTEXT, (WPARAM)1,
763                          (LPARAM)_FROMMB(psz_time) );
764         }
765     }
766
767     vlc_mutex_unlock( &p_intf->change_lock );
768 }
769
770 void Interface::OnChange( int wp )
771 {
772     DWORD dwPos = SendMessage( hwndVol, TBM_GETPOS, 0, 0 );
773
774     if( LOWORD(wp) == SB_THUMBPOSITION || LOWORD(wp) == SB_ENDSCROLL )
775     {
776         VolumeChange( 200 - (int)dwPos );
777         b_volume_hold = VLC_FALSE;
778     }
779     else
780     {
781         b_volume_hold = VLC_TRUE;
782     }
783 }
784
785 void Interface::VolumeChange( int i_volume )
786 {
787     aout_VolumeSet( p_intf, i_volume * AOUT_VOLUME_MAX / 200 / 2 );
788 }
789
790 void Interface::VolumeUpdate()
791 {
792     audio_volume_t i_volume;
793
794     if( b_volume_hold ) return;
795
796     aout_VolumeGet( p_intf, &i_volume );
797
798     int i_volume_ctrl = 200 - i_volume * 200 * 2 / AOUT_VOLUME_MAX;
799
800     DWORD dwPos = SendMessage( hwndVol, TBM_GETPOS, 0, 0 );
801     if( i_volume_ctrl == (int)dwPos ) return;
802
803     SendMessage( hwndVol, TBM_SETPOS, 1, i_volume_ctrl );
804 }
805
806 void Interface::OnStopStream( void )
807 {
808     playlist_t * p_playlist = (playlist_t *)
809         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
810     if( p_playlist == NULL ) return;
811
812     playlist_Stop( p_playlist );
813     TogglePlayButton( PAUSE_S );
814     vlc_object_release( p_playlist );
815 }
816
817 void Interface::OnPrevStream( void )
818 {
819     playlist_t * p_playlist = (playlist_t *)
820         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
821     if( p_playlist == NULL ) return;
822
823     playlist_Prev( p_playlist );
824     vlc_object_release( p_playlist );
825 }
826
827 void Interface::OnNextStream( void )
828 {
829     playlist_t * p_playlist = (playlist_t *)
830         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
831     if( p_playlist == NULL ) return;
832
833     playlist_Next( p_playlist );
834     vlc_object_release( p_playlist );
835 }
836
837 void Interface::OnSlowStream( void )
838 {
839     input_thread_t *p_input = (input_thread_t *)
840         vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
841
842     if( p_input == NULL ) return;
843
844     vlc_value_t val; val.b_bool = VLC_TRUE;
845     var_Set( p_input, "rate-slower", val );
846     vlc_object_release( p_input );
847 }
848
849 void Interface::OnFastStream( void )
850 {
851     input_thread_t *p_input = (input_thread_t *)
852         vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
853
854     if( p_input == NULL ) return;
855
856     vlc_value_t val; val.b_bool = VLC_TRUE;
857     var_Set( p_input, "rate-faster", val );
858     vlc_object_release( p_input );
859 }
860
861 void Interface::Update()
862 {
863     /* Misc updates */
864     VolumeUpdate();
865 }