]> git.sesse.net Git - vlc/blob - modules/gui/wince/interface.cpp
* modules/gui/wince: fixed bunch of bugs and memory leaks.
[vlc] / modules / gui / wince / interface.cpp
1 /*****************************************************************************
2  * interface.cpp: WinCE gui plugin for VLC
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
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 <winuser.h>
37 #include <windows.h>
38 #include <windowsx.h>
39 #include <commctrl.h>
40 #include <commdlg.h>
41
42 #define NUMIMAGES     9   // Number of buttons in the toolbar           
43 #define IMAGEWIDTH    17   // Width of the buttons in the toolbar  
44 #define IMAGEHEIGHT   16   // Height of the buttons in the toolbar  
45 #define BUTTONWIDTH   0    // Width of the button images in the toolbar
46 #define BUTTONHEIGHT  0    // Height of the button images in the toolbar
47 #define ID_TOOLBAR    2000 // Identifier of the main tool bar
48
49 // Help strings
50 #define HELP_SIMPLE _T("Quick file open")
51 #define HELP_ADV    _T("Advanced open")
52 #define HELP_FILE   _T("Open a file")
53 #define HELP_DISC   _T("Open Disc Media")
54 #define HELP_NET    _T("Open a network stream")
55 #define HELP_SAT    _T("Open a satellite stream")
56 #define HELP_EJECT  _T("Eject the DVD/CD")
57 #define HELP_EXIT   _T("Exit this program")
58
59 #define HELP_OTHER _T("Open other types of inputs")
60
61 #define HELP_PLAYLIST   _T("Open the playlist")
62 #define HELP_LOGS       _T("Show the program logs")
63 #define HELP_FILEINFO   _T("Show information about the file being played")
64
65 #define HELP_PREFS _T("Go to the preferences menu")
66
67 #define HELP_ABOUT _T("About this program")
68
69 #define HELP_STOP _T("Stop")
70
71 #define HELP_PLAY _T("Play")
72 #define HELP_PAUSE _T("Pause")
73 #define HELP_PLO _T("Playlist")
74 #define HELP_PLP _T("Previous playlist item")
75 #define HELP_PLN _T("Next playlist item")
76 #define HELP_SLOW _T("Play slower")
77 #define HELP_FAST _T("Play faster")
78
79 // The TBBUTTON structure contains information the toolbar buttons.
80 static TBBUTTON tbButton[] =      
81 {
82   {0, ID_FILE_QUICKOPEN,        TBSTATE_ENABLED, TBSTYLE_BUTTON},
83   {1, ID_FILE_OPENNET,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
84   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
85   {2, StopStream_Event,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
86   {3, PlayStream_Event,        TBSTATE_ENABLED, TBSTYLE_BUTTON},
87   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
88   {4, ID_VIEW_PLAYLIST,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
89   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
90   {5, PrevStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
91   {6, NextStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
92   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
93   {7, SlowStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
94   {8, FastStream_Event,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
95 };
96
97 // Toolbar ToolTips
98 TCHAR * szToolTips[] = 
99 {
100     HELP_SIMPLE, HELP_NET, HELP_STOP, HELP_PLAY, HELP_PLO, HELP_PLP,
101     HELP_PLN, HELP_SLOW, HELP_FAST
102 };
103
104 /*****************************************************************************
105  * Constructor.
106  *****************************************************************************/
107 Interface::Interface()
108   : hwndMain(0), hwndCB(0), hwndTB(0), hwndSlider(0), hwndLabel(0),
109     hwndVol(0), hwndSB(0),
110     fileinfo(0), messages(0), preferences(0), playlist(0),
111     timer(0), open(0), video(0)
112 {
113 }
114
115 Interface::~Interface()
116 {
117     if( timer ) delete timer;
118     if( video ) delete video;
119 }
120
121 BOOL Interface::InitInstance( HINSTANCE hInstance, intf_thread_t *_p_intf )
122 {
123     /* Initializations */
124     p_intf = _p_intf;
125     i_old_playing_status = PAUSE_S;
126
127     hInst = hInstance; // Store instance handle in our global variable
128
129     // Register window class
130     WNDCLASS wc;
131     wc.style = CS_HREDRAW | CS_VREDRAW ;
132     wc.lpfnWndProc = (WNDPROC)BaseWndProc;
133     wc.cbClsExtra = 0;
134     wc.cbWndExtra = 0;
135     wc.hIcon = NULL;
136     wc.hInstance = hInstance;
137     wc.hCursor = NULL;
138     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
139     wc.lpszMenuName = NULL;
140     wc.lpszClassName = _T("VLC WinCE");
141     if( !RegisterClass( &wc ) ) return FALSE;
142
143     int i_style = WS_VISIBLE;
144
145 #ifndef UNDER_CE
146     i_style |= WS_OVERLAPPEDWINDOW | WS_SIZEBOX;
147 #endif
148
149     // Create main window
150     hwndMain =
151         CreateWindow( _T("VLC WinCE"), _T("VLC media player"), i_style,
152                       0, MENU_HEIGHT, CW_USEDEFAULT, CW_USEDEFAULT,
153                       NULL, NULL, hInstance, (void *)this );
154
155     if( !hwndMain ) return FALSE;
156
157     ShowWindow( hwndMain, TRUE );
158     UpdateWindow( hwndMain );
159
160     return TRUE;
161 }
162
163 /***********************************************************************
164 FUNCTION: 
165   CreateMenuBar
166
167 PURPOSE: 
168   Creates a menu bar.
169 ***********************************************************************/
170 HWND Interface::CreateMenuBar( HWND hwnd, HINSTANCE hInst )
171 {
172     HMENU menu_file, menu_view;
173
174 #ifdef UNDER_CE
175     SHMENUBARINFO mbi;
176     memset( &mbi, 0, sizeof(SHMENUBARINFO) );
177     mbi.cbSize     = sizeof(SHMENUBARINFO);
178     mbi.hwndParent = hwnd;
179     mbi.hInstRes   = hInst;
180     mbi.nToolBarId = IDR_MENUBAR;
181
182     if( !SHCreateMenuBar( &mbi ) )
183     {
184         MessageBox(hwnd, _T("SHCreateMenuBar Failed"), _T("Error"), MB_OK);
185         return 0;
186     }
187
188     TBBUTTONINFO tbbi;
189     tbbi.cbSize = sizeof(tbbi);
190     tbbi.dwMask = TBIF_LPARAM;
191
192     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_FILE, (LPARAM)&tbbi );
193     menu_file = (HMENU)tbbi.lParam;
194     RemoveMenu( hmenu_file, 0, MF_BYPOSITION );
195     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_VIEW, (LPARAM)&tbbi );
196     menu_view = (HMENU)tbbi.lParam;
197     RemoveMenu( hmenu_view, 0, MF_BYPOSITION );
198     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_SETTINGS, (LPARAM)&tbbi );
199     menu_settings = (HMENU)tbbi.lParam;
200     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_VIDEO, (LPARAM)&tbbi );
201     menu_video = (HMENU)tbbi.lParam;
202     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_AUDIO, (LPARAM)&tbbi );
203     menu_audio = (HMENU)tbbi.lParam;
204     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_NAVIGATION, (LPARAM)&tbbi );
205     menu_navigation = (HMENU)tbbi.lParam;
206
207 #else
208     menu_file = CreatePopupMenu();
209     menu_view = CreatePopupMenu();
210     menu_settings = CreatePopupMenu();
211     menu_audio = CreatePopupMenu();
212     menu_video = CreatePopupMenu();
213     menu_navigation = CreatePopupMenu();
214 #endif
215
216     AppendMenu( menu_file, MF_STRING, ID_FILE_QUICKOPEN,
217                 _T("Quick &Open File...") );
218     AppendMenu( menu_file, MF_SEPARATOR, 0, 0 );
219     AppendMenu( menu_file, MF_STRING, ID_FILE_OPENFILE,
220                 _T("Open &File...") );
221     AppendMenu( menu_file, MF_STRING, ID_FILE_OPENNET,
222                 _T("Open &Network Stream...") );
223     AppendMenu( menu_file, MF_SEPARATOR, 0, 0 );
224     AppendMenu( menu_file, MF_STRING, ID_FILE_ABOUT,
225                 _T("About VLC") );
226     AppendMenu( menu_file, MF_STRING, ID_FILE_EXIT,
227                 _T("E&xit") );
228
229     AppendMenu( menu_view, MF_STRING, ID_VIEW_PLAYLIST,
230                 _T("&Playlist...") );
231     AppendMenu( menu_view, MF_STRING, ID_VIEW_MESSAGES,
232                 _T("&Messages...") );
233     AppendMenu( menu_view, MF_STRING, ID_VIEW_STREAMINFO,
234                 _T("Stream and Media &info...") );
235
236     AppendMenu( menu_settings, MF_STRING, ID_PREFERENCES,
237                 _T("&Preferences...") );
238
239
240 #ifdef UNDER_CE
241     return mbi.hwndMB;
242
243 #else
244     HMENU hmenu = CreateMenu();
245
246     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_file, _T("File") );
247     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_view, _T("View") );
248     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_settings,
249                 _T("Settings") );
250     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_audio, _T("Audio") );
251     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_video, _T("Video") );
252     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)menu_navigation, _T("Nav") );
253
254     SetMenu( hwnd, hmenu );
255     return 0;
256
257 #endif
258 }
259
260 /***********************************************************************
261 FUNCTION: 
262   CreateToolBar
263
264 PURPOSE: 
265   Registers the TOOLBAR control class and creates a toolbar.
266 ***********************************************************************/
267 HWND CreateToolBar( HWND hwnd, HINSTANCE hInst )
268 {
269     DWORD dwStyle;
270     HWND hwndTB;
271     RECT rect, rectTB;
272
273     INITCOMMONCONTROLSEX iccex;
274     iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
275     iccex.dwICC = ICC_BAR_CLASSES;
276
277     // Registers TOOLBAR control classes from the common control dll
278     InitCommonControlsEx (&iccex);
279
280     //  Create the toolbar control
281     dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS |
282         WS_EX_OVERLAPPEDWINDOW | CCS_NOPARENTALIGN;
283
284     hwndTB = CreateToolbarEx( hwnd, dwStyle, 0, NUMIMAGES,
285         hInst, IDB_BITMAP1, tbButton, sizeof(tbButton) / sizeof(TBBUTTON),
286         BUTTONWIDTH, BUTTONHEIGHT, IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON) );
287
288     if( !hwndTB ) return NULL;
289   
290     // Add ToolTips to the toolbar.
291     SendMessage( hwndTB, TB_SETTOOLTIPS, (WPARAM)NUMIMAGES, 
292                  (LPARAM)szToolTips );
293
294     // Reposition the toolbar.
295     GetClientRect( hwnd, &rect );
296     GetWindowRect( hwndTB, &rectTB );
297     MoveWindow( hwndTB, rect.left, rect.bottom - rect.top - 2*MENU_HEIGHT, 
298                 rect.right - rect.left, MENU_HEIGHT, TRUE );
299
300     return hwndTB;
301 }
302
303 /***********************************************************************
304
305 FUNCTION: 
306   CreateSliderBar
307
308 PURPOSE: 
309   Registers the TRACKBAR_CLASS control class and creates a trackbar.
310
311 ***********************************************************************/
312 HWND CreateSliderBar( HWND hwnd, HINSTANCE hInst )
313 {
314     HWND hwndSlider;
315     RECT rect;
316
317     INITCOMMONCONTROLSEX iccex;
318     iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
319     iccex.dwICC = ICC_BAR_CLASSES;
320
321     // Registers TRACKBAR_CLASS control classes from the common control dll
322     InitCommonControlsEx( &iccex );
323
324     hwndSlider = CreateWindowEx( 0, TRACKBAR_CLASS, NULL,
325                 WS_CHILD | WS_VISIBLE | TBS_HORZ | WS_EX_OVERLAPPEDWINDOW |
326                 TBS_BOTTOM,  //|WS_CLIPSIBLINGS,
327                 0, 0, 0, 0, hwnd, NULL, hInst, NULL );
328
329     if( !hwndSlider ) return NULL;
330
331     SendMessage( hwndSlider, TBM_SETRANGEMIN, 1, 0 );
332     SendMessage( hwndSlider, TBM_SETRANGEMAX, 1, SLIDER_MAX_POS );
333     SendMessage( hwndSlider, TBM_SETPOS, 1, 0 );
334
335     // Reposition the trackbar
336     GetClientRect( hwnd, &rect );
337     MoveWindow( hwndSlider, rect.left, 
338                 rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT, 
339                 rect.right - rect.left - 40, 30, TRUE );
340
341     ShowWindow( hwndSlider, SW_HIDE );
342
343     return hwndSlider;
344 }
345
346 HWND CreateStaticText( HWND hwnd, HINSTANCE hInst )
347 {
348     HWND hwndLabel;
349     RECT rect;
350
351     hwndLabel = CreateWindowEx( 0, _T("STATIC"), _T("label"),
352                                 WS_CHILD | WS_VISIBLE | SS_CENTER ,
353                                 0, 0, 0, 0, hwnd, (HMENU)1980, hInst, NULL );
354
355     // Reposition the trackbar
356     GetClientRect( hwnd, &rect );
357
358     MoveWindow( hwndLabel, rect.left,
359                 rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT +30,
360                 rect.right - rect.left - 40,
361                 SLIDER_HEIGHT - 30, TRUE );
362
363     ShowWindow( hwndLabel, SW_HIDE );
364
365     return hwndLabel;
366 }
367
368 /***********************************************************************
369
370 FUNCTION: 
371   CreateVolTrackBar
372
373 PURPOSE: 
374   Registers the TRACKBAR_CLASS control class and creates a trackbar.
375
376 ***********************************************************************/
377 HWND CreateVolTrackBar( HWND hwnd, HINSTANCE hInst )
378 {
379     HWND hwndVol;
380     RECT rect;
381
382     INITCOMMONCONTROLSEX iccex;
383     iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
384     iccex.dwICC = ICC_BAR_CLASSES;
385
386     // Registers TRACKBAR_CLASS control classes from the common control dll
387     InitCommonControlsEx( &iccex );
388
389     hwndVol = CreateWindowEx( 0, TRACKBAR_CLASS, NULL,
390                 WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_RIGHT | TBS_AUTOTICKS |
391                 WS_EX_OVERLAPPEDWINDOW, //|WS_CLIPSIBLINGS,
392                 0, 0, 0, 0, hwnd, NULL, hInst, NULL );
393
394     if( !hwndVol ) return NULL;
395
396     SendMessage( hwndVol, TBM_SETRANGEMIN, 1, 0 );
397     SendMessage( hwndVol, TBM_SETRANGEMAX, 1, 200 );
398     SendMessage( hwndVol, TBM_SETPOS, 1, 100 );
399     SendMessage( hwndVol, TBM_SETTICFREQ, 50, 0 );  
400
401     // Reposition the trackbar
402     GetClientRect( hwnd, &rect );
403     MoveWindow( hwndVol, rect.right - rect.left - 40, 
404                 rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT, 
405                 40, SLIDER_HEIGHT, TRUE );
406
407     ShowWindow( hwndVol, SW_HIDE );
408
409     return hwndVol;
410 }
411
412 /***********************************************************************
413
414 FUNCTION: 
415   CreateStatusBar
416
417 PURPOSE: 
418   Registers the StatusBar control class and creates a Statusbar.
419
420 ***********************************************************************/
421 HWND CreateStatusBar( HWND hwnd, HINSTANCE hInst )
422 {
423     DWORD dwStyle;
424     HWND hwndSB;
425     RECT rect;
426
427     INITCOMMONCONTROLSEX iccex;
428     iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
429     iccex.dwICC = ICC_BAR_CLASSES;
430
431     // Registers Statusbar control classes from the common control dll
432     InitCommonControlsEx( &iccex );
433
434     // Create the statusbar control
435     dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS | CCS_NOPARENTALIGN;
436
437     hwndSB = CreateWindowEx( 0, STATUSCLASSNAME, NULL,
438                              WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_BOTTOM |
439                              TBS_RIGHT  |WS_CLIPSIBLINGS,
440                              0, 0, CW_USEDEFAULT, 50, hwnd, NULL, hInst, 0 );
441
442     if (!hwndSB ) return NULL;
443
444     // Get the coordinates of the parent window's client area. 
445     GetClientRect( hwnd, &rect );
446
447     // allocate memory for the panes of status bar
448     int nopanes = 2;
449     int *indicators = new int[nopanes];
450
451     // set width for the panes
452     indicators[0] = 3 * ( rect.right - rect.left ) / 4;
453     indicators[1] = rect.right - rect.left;
454
455     // call functions to set style
456     SendMessage( hwndSB, SB_SETPARTS, (WPARAM)nopanes, (LPARAM)indicators );
457
458     return hwndSB;
459 }
460
461 /***********************************************************************
462 FUNCTION:
463   CreateDialogBox
464
465 PURPOSE:
466   Creates a Dialog Box.
467 ***********************************************************************/
468 int CBaseWindow::CreateDialogBox( HWND hwnd, CBaseWindow *p_obj )
469 {
470     uint8_t p_buffer[sizeof(DLGTEMPLATE) + sizeof(WORD) * 4];
471     DLGTEMPLATE *p_dlg_template = (DLGTEMPLATE *)p_buffer;
472     memset( p_dlg_template, 0, sizeof(DLGTEMPLATE) + sizeof(WORD) * 4 );
473
474     // these values are arbitrary, they won't be used normally anyhow
475     p_dlg_template->x  = 0; p_dlg_template->y  = 0;
476     p_dlg_template->cx = 300; p_dlg_template->cy = 300;
477     p_dlg_template->style =
478         DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX;
479
480     return DialogBoxIndirectParam( GetModuleHandle(0), p_dlg_template, hwnd,
481                                    (DLGPROC)p_obj->BaseWndProc, (LPARAM)p_obj );
482 }
483
484 /***********************************************************************
485 FUNCTION: 
486   BaseWndProc
487
488 PURPOSE: 
489   Processes messages sent to the main window.
490 ***********************************************************************/
491 LRESULT CALLBACK CBaseWindow::BaseWndProc( HWND hwnd, UINT msg, WPARAM wParam,
492                                            LPARAM lParam )
493 {
494     CBaseWindow *p_obj;
495
496     // check to see if a copy of the 'this' pointer needs to be saved
497     if( msg == WM_CREATE )
498     {
499         p_obj = (CBaseWindow *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
500         SetWindowLong( hwnd, GWL_USERDATA,
501                        (LONG)((LPCREATESTRUCT)lParam)->lpCreateParams );
502
503         p_obj->hWnd = hwnd;
504     }
505
506     if( msg == WM_INITDIALOG )
507     {
508         p_obj = (CBaseWindow *)lParam;
509         SetWindowLong( hwnd, GWL_USERDATA, lParam );
510         p_obj->hWnd = hwnd;
511     }
512
513     // Retrieve the pointer
514     p_obj = (CBaseWindow *)GetWindowLong( hwnd, GWL_USERDATA );
515
516     if( !p_obj ) return DefWindowProc( hwnd, msg, wParam, lParam );
517
518     // Filter message through child classes
519     return p_obj->WndProc( hwnd, msg, wParam, lParam );
520 }
521
522 /***********************************************************************
523 FUNCTION: 
524   WndProc
525
526 PURPOSE: 
527   Processes messages sent to the main window.
528 ***********************************************************************/
529 LRESULT Interface::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
530 {
531     switch( msg )
532     {
533     case WM_CREATE:
534         hwndCB = CreateMenuBar( hwnd, hInst );
535         hwndTB = CreateToolBar( hwnd, hInst );
536         hwndSlider = CreateSliderBar( hwnd, hInst );
537         hwndLabel = CreateStaticText( hwnd, hInst );
538         hwndVol = CreateVolTrackBar( hwnd, hInst );
539 #ifdef UNDER_CE
540         hwndSB = CreateStatusBar( hwnd, hInst );
541 #endif
542
543         /* Video window */
544         if( config_GetInt( p_intf, "wince-embed" ) )
545             video = CreateVideoWindow( p_intf, hwnd );
546
547         timer = new Timer( p_intf, hwnd, this );
548
549         // Hide the SIP button (WINCE only)
550         SetForegroundWindow( hwnd );
551         SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
552         break;
553
554     case WM_COMMAND:
555         switch( GET_WM_COMMAND_ID(wp,lp) )
556         {
557         case ID_FILE_QUICKOPEN: 
558             OnOpenFileSimple();
559             break;
560
561         case ID_FILE_OPENFILE: 
562             open = new OpenDialog( p_intf, hInst, FILE_ACCESS,
563                                    ID_FILE_OPENFILE, OPEN_NORMAL );
564             CreateDialogBox( hwnd, open );
565             delete open;
566             break;
567
568         case ID_FILE_OPENNET:
569             open = new OpenDialog( p_intf, hInst, NET_ACCESS, ID_FILE_OPENNET,
570                                    OPEN_NORMAL );
571             CreateDialogBox( hwnd, open );
572             delete open;
573             break;
574
575         case PlayStream_Event: 
576             OnPlayStream();
577             break;
578
579         case StopStream_Event: 
580             OnStopStream();
581             break;
582
583         case PrevStream_Event: 
584             OnPrevStream();
585             break;
586
587         case NextStream_Event: 
588             OnNextStream();
589             break;
590
591         case SlowStream_Event: 
592             OnSlowStream();
593             break;
594
595         case FastStream_Event: 
596             OnFastStream();
597             break;
598
599         case ID_FILE_ABOUT: 
600         {
601             string about = (string)"VLC media player " PACKAGE_VERSION +
602                 _("\n(WinCE interface)\n\n") +
603                 _("(c) 1996-2005 - the VideoLAN Team\n\n") +
604                 _("The VideoLAN team <videolan@videolan.org>\n"
605                   "http://www.videolan.org/\n\n");
606
607             MessageBox( hwnd, _FROMMB(about.c_str()),
608                         _T("About VLC media player"), MB_OK );
609             break;
610         }
611
612         case ID_FILE_EXIT:
613             SendMessage( hwnd, WM_CLOSE, 0, 0 );
614             break;
615
616         case ID_VIEW_STREAMINFO:
617             fileinfo = new FileInfo( p_intf, hInst );
618             CreateDialogBox( hwnd, fileinfo );
619             delete fileinfo;
620             break;
621
622         case ID_VIEW_MESSAGES:
623             messages = new Messages( p_intf, hInst );
624             CreateDialogBox( hwnd, messages );
625             delete messages;
626             break;
627
628         case ID_VIEW_PLAYLIST:
629             playlist = new Playlist( p_intf, hInst );
630             CreateDialogBox( hwnd, playlist );
631             delete playlist;
632             break;
633
634         case ID_PREFERENCES:
635             preferences = new PrefsDialog( p_intf, hInst );
636             CreateDialogBox( hwnd, preferences );
637             delete preferences;
638             break;
639                   
640         default:
641             OnMenuEvent( p_intf, GET_WM_COMMAND_ID(wp,lp) );
642             // we should test if it is a menu command
643         }
644         break;
645   
646     case WM_TIMER:
647         timer->Notify();
648         break;
649
650     case WM_CTLCOLORSTATIC: 
651         if( ( (HWND)lp == hwndSlider ) || ( (HWND)lp == hwndVol ) )
652         { 
653             return( (LRESULT)::GetSysColorBrush(COLOR_3DFACE) ); 
654         }
655         if( (HWND)lp == hwndLabel )
656         {
657             SetBkColor( (HDC)wp, RGB (192, 192, 192) ); 
658             return( (LRESULT)::GetSysColorBrush(COLOR_3DFACE) ); 
659         }
660         break;
661
662     case WM_HSCROLL:
663         if( (HWND)lp == hwndSlider ) OnSliderUpdate( wp );
664         break;
665
666     case WM_VSCROLL:
667         if( (HWND)lp == hwndVol ) OnChange( wp );
668         break;
669
670     case WM_INITMENUPOPUP:
671         RefreshSettingsMenu( p_intf, menu_settings );
672         RefreshAudioMenu( p_intf, menu_audio );
673         RefreshVideoMenu( p_intf, menu_video );
674         RefreshNavigMenu( p_intf, menu_navigation );
675         /* Fall through */
676
677     case WM_ENTERMENULOOP:
678     case WM_KILLFOCUS:
679         if( video && video->hWnd )
680             SendMessage( video->hWnd, WM_KILLFOCUS, 0, 0 );
681         break;
682
683     case WM_EXITMENULOOP:
684     case WM_SETFOCUS:
685         if( video && video->hWnd )
686             SendMessage( video->hWnd, WM_SETFOCUS, 0, 0 );
687         break;
688
689     case WM_LBUTTONDOWN:
690         {
691             SHRGINFO shrg;
692             shrg.cbSize = sizeof( shrg );
693             shrg.hwndClient = hwnd;
694             shrg.ptDown.x = LOWORD(lp);
695             shrg.ptDown.y = HIWORD(lp);
696             shrg.dwFlags = SHRG_RETURNCMD ;
697
698             if( SHRecognizeGesture( &shrg ) == GN_CONTEXTMENU )
699                 PopupMenu( p_intf, hwnd, shrg.ptDown );
700         }
701         break;
702
703    case WM_RBUTTONUP:
704         {
705             POINT point;
706             point.x = LOWORD(lp);
707             point.y = HIWORD(lp);
708             PopupMenu( p_intf, hwnd, point );
709         }
710         break;
711
712     case WM_HELP:
713         MessageBox (hwnd, _T("Help"), _T("Help"), MB_OK);
714         break;
715
716     case WM_CLOSE:
717         if( hwndCB ) DestroyWindow( hwndCB );
718         DestroyWindow( hwnd );
719         break;
720
721     case WM_DESTROY:
722         PostQuitMessage( 0 );
723         break;
724     }
725
726     return DefWindowProc( hwnd, msg, wp, lp );
727 }
728
729 void Interface::OnOpenFileSimple( void )
730 {
731     OPENFILENAME ofn;
732     TCHAR DateiName[80+1] = _T("\0");
733     static TCHAR szFilter[] = _T("All (*.*)\0*.*\0");
734
735     playlist_t *p_playlist = (playlist_t *)
736         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
737     if( p_playlist == NULL ) return;
738
739     memset( &ofn, 0, sizeof(OPENFILENAME) );
740     ofn.lStructSize = sizeof(OPENFILENAME);
741     ofn.hwndOwner = NULL;
742     ofn.hInstance = hInst;
743     ofn.lpstrFilter = szFilter;
744     ofn.lpstrCustomFilter = NULL;
745     ofn.nMaxCustFilter = 0;
746     ofn.nFilterIndex = 1;     
747     ofn.lpstrFile = (LPTSTR)DateiName; 
748     ofn.nMaxFile = 80;
749     ofn.lpstrFileTitle = NULL; 
750     ofn.nMaxFileTitle = 40;
751     ofn.lpstrInitialDir = NULL;
752     ofn.lpstrTitle = _T("Quick Open File");
753     ofn.Flags = 0; 
754     ofn.nFileOffset = 0;
755     ofn.nFileExtension = 0;
756     ofn.lpstrDefExt = NULL;
757     ofn.lCustData = 0L;
758     ofn.lpfnHook = NULL;
759     ofn.lpTemplateName = NULL;
760
761     SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
762
763     if( GetOpenFile( &ofn ) )
764     {
765         char *psz_filename = _TOMB(ofn.lpstrFile);
766         playlist_Add( p_playlist, psz_filename, psz_filename,
767                       PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
768     }
769
770     vlc_object_release( p_playlist );
771 }
772
773 void Interface::OnPlayStream( void )
774 {
775     playlist_t *p_playlist = (playlist_t *)
776         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
777     if( p_playlist == NULL ) return;
778
779     if( p_playlist->i_size && p_playlist->i_enabled )
780     {
781         vlc_value_t state;
782
783         input_thread_t *p_input = (input_thread_t *)
784             vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
785
786         if( p_input == NULL )
787         {
788             /* No stream was playing, start one */
789             playlist_Play( p_playlist );
790             TogglePlayButton( PLAYING_S );
791             vlc_object_release( p_playlist );
792             return;
793         }
794
795         var_Get( p_input, "state", &state );
796
797         if( state.i_int != PAUSE_S )
798         {
799             /* A stream is being played, pause it */
800             state.i_int = PAUSE_S;
801         }
802         else
803         {
804             /* Stream is paused, resume it */
805             state.i_int = PLAYING_S;
806         }
807         var_Set( p_input, "state", state );
808
809         TogglePlayButton( state.i_int );
810         vlc_object_release( p_input );
811         vlc_object_release( p_playlist );
812     }
813     else
814     {
815         /* If the playlist is empty, open a file requester instead */
816         vlc_object_release( p_playlist );
817         OnOpenFileSimple();
818     }
819 }
820
821 void Interface::TogglePlayButton( int i_playing_status )
822 {
823     TBREPLACEBITMAP tbrb;
824     tbrb.hInstOld = tbrb.hInstNew = (HINSTANCE) hInst;
825     tbrb.nButtons = NUMIMAGES;
826
827     if( i_playing_status == i_old_playing_status ) return;
828
829     if( i_playing_status == PLAYING_S )
830     {
831         tbrb.nIDOld = IDB_BITMAP2;
832         tbrb.nIDNew = IDB_BITMAP1;
833
834         SendMessage( hwndTB, TB_REPLACEBITMAP, (WPARAM)0,
835                      (LPARAM)(LPTBREPLACEBITMAP)&tbrb );
836     }
837     else
838     {
839         tbrb.nIDOld = IDB_BITMAP1;
840         tbrb.nIDNew = IDB_BITMAP2;
841
842         SendMessage( hwndTB, TB_REPLACEBITMAP, (WPARAM)0,
843                      (LPARAM)(LPTBREPLACEBITMAP)&tbrb );
844     }
845
846     UpdateWindow( hwndTB );
847
848     i_old_playing_status = i_playing_status;
849 }
850
851 void Interface::OnVideoOnTop( void )
852 {
853     vlc_value_t val;
854
855     vout_thread_t *p_vout = (vout_thread_t *)
856         vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
857
858     if( p_vout == NULL ) return;
859
860     if( var_Get( (vlc_object_t *)p_vout, "video-on-top", &val ) < 0 )
861         return;
862
863     val.b_bool = !val.b_bool;
864     var_Set( (vlc_object_t *)p_vout, "video-on-top", val );
865
866     vlc_object_release( (vlc_object_t *)p_vout );
867 }
868
869 void Interface::OnSliderUpdate( int wp )
870 {
871     vlc_mutex_lock( &p_intf->change_lock );
872     input_thread_t *p_input = p_intf->p_sys->p_input;
873
874     int dwPos = SendMessage( hwndSlider, TBM_GETPOS, 0, 0 ); 
875
876     if( (int)LOWORD(wp) == SB_THUMBPOSITION ||
877         (int)LOWORD(wp) == SB_ENDSCROLL )
878     {
879         if( p_intf->p_sys->i_slider_pos != dwPos && p_input )
880         {
881             vlc_value_t pos;
882             pos.f_float = (float)dwPos / (float)SLIDER_MAX_POS;
883             var_Set( p_input, "position", pos );
884         }
885
886         p_intf->p_sys->b_slider_free = VLC_TRUE;
887     }
888     else
889     {
890         p_intf->p_sys->b_slider_free = VLC_FALSE;
891
892         if( p_input )
893         {
894             /* Update stream date */
895             char psz_time[ MSTRTIME_MAX_SIZE ], psz_total[ MSTRTIME_MAX_SIZE ];
896             mtime_t i_seconds;
897
898             i_seconds = var_GetTime( p_input, "length" ) / I64C(1000000 );
899             secstotimestr( psz_total, i_seconds );
900
901             i_seconds = var_GetTime( p_input, "time" ) / I64C(1000000 );
902             secstotimestr( psz_time, i_seconds );
903
904             SendMessage( hwndLabel, WM_SETTEXT, (WPARAM)1,
905                          (LPARAM)_FROMMB(psz_time) );
906         }
907     }
908
909     vlc_mutex_unlock( &p_intf->change_lock );
910 }
911
912 void Interface::OnChange( int wp )
913 {
914     DWORD dwPos = SendMessage( hwndVol, TBM_GETPOS, 0, 0 );
915
916     if( LOWORD(wp) == SB_THUMBPOSITION || LOWORD(wp) == SB_ENDSCROLL )
917     {
918         Change( 200 - (int)dwPos );
919     }
920 }
921
922 void Interface::Change( int i_volume )
923 {
924     aout_VolumeSet( p_intf, i_volume * AOUT_VOLUME_MAX / 200 / 2 );
925 #if 0
926     SetToolTip( wxString::Format((wxString)wxU(_("Volume")) + wxT(" %d"),
927                 i_volume ) );
928 #endif
929 }
930
931 void Interface::OnStopStream( void )
932 {
933     playlist_t * p_playlist = (playlist_t *)
934         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
935     if( p_playlist == NULL ) return;
936
937     playlist_Stop( p_playlist );
938     TogglePlayButton( PAUSE_S );
939     vlc_object_release( p_playlist );
940 }
941
942 void Interface::OnPrevStream( void )
943 {
944     playlist_t * p_playlist = (playlist_t *)
945         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
946     if( p_playlist == NULL ) return;
947
948     playlist_Prev( p_playlist );
949     vlc_object_release( p_playlist );
950 }
951
952 void Interface::OnNextStream( void )
953 {
954     playlist_t * p_playlist = (playlist_t *)
955         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
956     if( p_playlist == NULL ) return;
957
958     playlist_Next( p_playlist );
959     vlc_object_release( p_playlist );
960 }
961
962 void Interface::OnSlowStream( void )
963 {
964     input_thread_t *p_input = (input_thread_t *)
965         vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
966
967     if( p_input == NULL ) return;
968
969     vlc_value_t val; val.b_bool = VLC_TRUE;
970     var_Set( p_input, "rate-slower", val );
971     vlc_object_release( p_input );
972 }
973
974 void Interface::OnFastStream( void )
975 {
976     input_thread_t *p_input = (input_thread_t *)
977         vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
978
979     if( p_input == NULL ) return;
980
981     vlc_value_t val; val.b_bool = VLC_TRUE;
982     var_Set( p_input, "rate-faster", val );
983     vlc_object_release( p_input );
984 }