* modules/gui/wince/*: New Windows CE interface by Cedric Marodon <cedric_marodon...
authorGildas Bazin <gbazin@videolan.org>
Thu, 6 Jan 2005 23:52:00 +0000 (23:52 +0000)
committerGildas Bazin <gbazin@videolan.org>
Thu, 6 Jan 2005 23:52:00 +0000 (23:52 +0000)
20 files changed:
modules/gui/wince/Modules.am [new file with mode: 0644]
modules/gui/wince/bitmaps/toolbar1.bmp [new file with mode: 0644]
modules/gui/wince/bitmaps/toolbar2.bmp [new file with mode: 0644]
modules/gui/wince/bitmaps/toolbar3.bmp [new file with mode: 0644]
modules/gui/wince/bitmaps/vlc16x16.ico [new file with mode: 0644]
modules/gui/wince/fileinfo.cpp [new file with mode: 0644]
modules/gui/wince/interface.cpp [new file with mode: 0644]
modules/gui/wince/iteminfo.cpp [new file with mode: 0644]
modules/gui/wince/menus.cpp [new file with mode: 0644]
modules/gui/wince/messages.cpp [new file with mode: 0644]
modules/gui/wince/open.cpp [new file with mode: 0644]
modules/gui/wince/playlist.cpp [new file with mode: 0644]
modules/gui/wince/preferences.cpp [new file with mode: 0644]
modules/gui/wince/preferences_widgets.cpp [new file with mode: 0644]
modules/gui/wince/preferences_widgets.h [new file with mode: 0644]
modules/gui/wince/subtitles.cpp [new file with mode: 0644]
modules/gui/wince/timer.cpp [new file with mode: 0644]
modules/gui/wince/video.cpp [new file with mode: 0644]
modules/gui/wince/wince.cpp [new file with mode: 0644]
modules/gui/wince/wince.h [new file with mode: 0644]

diff --git a/modules/gui/wince/Modules.am b/modules/gui/wince/Modules.am
new file mode 100644 (file)
index 0000000..98848f1
--- /dev/null
@@ -0,0 +1,24 @@
+SOURCES_wince = \
+       wince.cpp \
+       wince.h \
+       interface.cpp \
+       menus.cpp \
+       open.cpp \
+       playlist.cpp \
+       fileinfo.cpp \
+       iteminfo.cpp \
+       messages.cpp \
+       preferences.cpp \
+       preferences_widgets.cpp \
+       preferences_widgets.h \
+       subtitles.cpp \
+       timer.cpp \
+       video.cpp \
+       wince.rc \
+       $(NULL)
+
+EXTRA_DIST += \
+       bitmaps/vlc16x16.ico \
+       bitmaps/toolbar1.bmp \
+       bitmaps/toolbar2.bmp \
+       bitmaps/toolbar3.bmp
diff --git a/modules/gui/wince/bitmaps/toolbar1.bmp b/modules/gui/wince/bitmaps/toolbar1.bmp
new file mode 100644 (file)
index 0000000..104bfed
Binary files /dev/null and b/modules/gui/wince/bitmaps/toolbar1.bmp differ
diff --git a/modules/gui/wince/bitmaps/toolbar2.bmp b/modules/gui/wince/bitmaps/toolbar2.bmp
new file mode 100644 (file)
index 0000000..4d0aa8c
Binary files /dev/null and b/modules/gui/wince/bitmaps/toolbar2.bmp differ
diff --git a/modules/gui/wince/bitmaps/toolbar3.bmp b/modules/gui/wince/bitmaps/toolbar3.bmp
new file mode 100644 (file)
index 0000000..09c1c33
Binary files /dev/null and b/modules/gui/wince/bitmaps/toolbar3.bmp differ
diff --git a/modules/gui/wince/bitmaps/vlc16x16.ico b/modules/gui/wince/bitmaps/vlc16x16.ico
new file mode 100644 (file)
index 0000000..86a9213
Binary files /dev/null and b/modules/gui/wince/bitmaps/vlc16x16.ico differ
diff --git a/modules/gui/wince/fileinfo.cpp b/modules/gui/wince/fileinfo.cpp
new file mode 100644 (file)
index 0000000..a1d2b52
--- /dev/null
@@ -0,0 +1,239 @@
+/*****************************************************************************
+ * fileinfo.cpp : WinCE gui plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <string.h>
+
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <winuser.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <commdlg.h>
+
+#include "wince.h"
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+FileInfo::FileInfo( intf_thread_t *_p_intf, HINSTANCE _hInst )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+    hInst = _hInst;
+    hwnd_fileinfo = hwndTV = NULL;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  CreateTreeView
+
+PURPOSE: 
+  Registers the TreeView control class and creates a TreeView.
+
+***********************************************************************/
+BOOL FileInfo::CreateTreeView(HWND hwnd)
+{
+    DWORD dwStyle;
+    RECT rect;
+
+    INITCOMMONCONTROLSEX iccex;
+    iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
+    iccex.dwICC = ICC_TREEVIEW_CLASSES;
+
+    // Registers Statusbar control classes from the common control dll
+    InitCommonControlsEx( &iccex );
+
+    // Get the coordinates of the parent window's client area
+    GetClientRect( hwnd, &rect );
+
+    // Assign the window styles for the tree view.
+    dwStyle = WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_LINESATROOT | 
+                         TVS_HASBUTTONS;
+
+    // Create the tree-view control.
+    hwndTV = CreateWindowEx( 0, WC_TREEVIEW, NULL, dwStyle, 0, MENU_HEIGHT,
+                            rect.right-rect.left,
+                            rect.bottom-rect.top-MENU_HEIGHT,
+                            hwnd, NULL, hInst, NULL );
+
+    // Be sure that the tree view actually was created.
+    if( !hwndTV ) return FALSE;
+
+    UpdateFileInfo( hwndTV );
+
+    return TRUE;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  UpdateFileInfo
+
+PURPOSE: 
+  Update the TreeView with file information.
+
+***********************************************************************/
+void FileInfo::UpdateFileInfo(HWND hwnd)
+{
+    TVITEM tvi = {0}; 
+    TVINSERTSTRUCT tvins = {0}; 
+    HTREEITEM hPrev = (HTREEITEM)TVI_FIRST; 
+    HTREEITEM hPrevRootItem = NULL; 
+    HTREEITEM hPrevLev2Item = NULL; 
+
+    p_intf->p_sys->p_input = (input_thread_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+
+    input_thread_t *p_input = p_intf->p_sys->p_input;
+
+    if( !p_input ) return;
+
+    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; 
+
+    // Set the text of the item.
+    tvi.pszText = _FROMMB( p_input->input.p_item->psz_name );
+    tvi.cchTextMax = _tcslen( tvi.pszText );
+
+    // Save the heading level in the item's application-defined data area
+    tvi.lParam = (LPARAM)1;
+    tvins.item = tvi; 
+    //tvins.hInsertAfter = TVI_LAST;
+    tvins.hInsertAfter = hPrev; 
+    tvins.hParent = TVI_ROOT; 
+
+    // Add the item to the tree-view control. 
+    hPrev = (HTREEITEM)TreeView_InsertItem( hwnd, &tvins );
+
+    hPrevRootItem = hPrev; 
+
+    vlc_mutex_lock( &p_input->input.p_item->lock );
+    for( int i = 0; i < p_input->input.p_item->i_categories; i++ )
+    {
+        info_category_t *p_cat = p_input->input.p_item->pp_categories[i];
+
+        // Set the text of the item. 
+       tvi.pszText = _FROMMB( p_input->input.p_item->psz_name );
+       tvi.cchTextMax = _tcslen( tvi.pszText );
+       
+       // Save the heading level in the item's application-defined data area
+       tvi.lParam = (LPARAM)2; // level 2
+       tvins.item = tvi; 
+       tvins.hInsertAfter = hPrev; 
+       tvins.hParent = hPrevRootItem;
+
+       // Add the item to the tree-view control. 
+       hPrev = (HTREEITEM)TreeView_InsertItem( hwnd, &tvins );
+
+       hPrevLev2Item = hPrev;
+
+        for( int j = 0; j < p_cat->i_infos; j++ )
+        {
+            info_t *p_info = p_cat->pp_infos[j];
+
+           // Set the text of the item. 
+           string szAnsi = (string)p_info->psz_name;
+           szAnsi += ": ";
+           szAnsi += p_info->psz_value;
+           tvi.pszText = _FROMMB( szAnsi.c_str() );
+           tvi.cchTextMax = _tcslen( tvi.pszText );
+           tvi.lParam = (LPARAM)3; // level 3
+           tvins.item = tvi; 
+           tvins.hInsertAfter = hPrev; 
+           tvins.hParent = hPrevLev2Item;
+    
+           // Add the item to the tree-view control. 
+           hPrev = (HTREEITEM)TreeView_InsertItem( hwnd, &tvins );
+        }
+
+       TreeView_Expand( hwnd, hPrevLev2Item, TVE_EXPANDPARTIAL |TVE_EXPAND );
+    }
+    vlc_mutex_unlock( &p_input->input.p_item->lock );
+
+    TreeView_Expand( hwnd, hPrevRootItem, TVE_EXPANDPARTIAL |TVE_EXPAND );
+
+    return;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT FileInfo::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                          PBOOL pbProcessed  )
+{
+    SHINITDLGINFO shidi;
+
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    case WM_INITDIALOG: 
+        shidi.dwMask = SHIDIM_FLAGS;
+        shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
+           SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
+        shidi.hDlg = hwnd;
+        SHInitDialog( &shidi );
+       CreateTreeView( hwnd );
+       UpdateWindow( hwnd );
+       SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+       return lResult;
+
+    case WM_COMMAND:
+        if ( LOWORD(wp) == IDOK )
+        {
+            EndDialog( hwnd, LOWORD( wp ) );
+            return TRUE;
+         }
+         *pbProcessed = bWasProcessed;
+         lResult = FALSE;
+         return lResult;
+
+    default:
+         // the message was not processed
+         // indicate if the base class handled it
+         *pbProcessed = bWasProcessed;
+         lResult = FALSE;
+         return lResult;
+    }
+
+    return lResult;
+}
diff --git a/modules/gui/wince/interface.cpp b/modules/gui/wince/interface.cpp
new file mode 100644 (file)
index 0000000..8721246
--- /dev/null
@@ -0,0 +1,924 @@
+/*****************************************************************************
+ * interface.cpp: WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111,
+ * USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/aout.h>
+#include <vlc/vout.h>
+#include <vlc/intf.h>
+
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <winuser.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <commdlg.h> // common dialogs -> fileopen.lib ?
+
+#include "wince.h"
+
+#define NUMIMAGES     9   // Number of buttons in the toolbar           
+#define IMAGEWIDTH    17   // Width of the buttons in the toolbar  
+#define IMAGEHEIGHT   16   // Height of the buttons in the toolbar  
+#define BUTTONWIDTH   0    // Width of the button images in the toolbar
+#define BUTTONHEIGHT  0    // Height of the button images in the toolbar
+#define ID_TOOLBAR    2000 // Identifier of the main tool bar
+#define dwTBFontStyle TBSTYLE_BUTTON | TBSTYLE_CHECK | TBSTYLE_GROUP // style for toolbar buttons
+
+// Help strings
+#define HELP_SIMPLE _T("Quick file open")
+#define HELP_ADV    _T("Advanced open")
+#define HELP_FILE   _T("Open a file")
+#define HELP_DISC   _T("Open Disc Media")
+#define HELP_NET    _T("Open a network stream")
+#define HELP_SAT    _T("Open a satellite stream")
+#define HELP_EJECT  _T("Eject the DVD/CD")
+#define HELP_EXIT   _T("Exit this program")
+
+#define HELP_OTHER _T("Open other types of inputs")
+
+#define HELP_PLAYLIST   _T("Open the playlist")
+#define HELP_LOGS       _T("Show the program logs")
+#define HELP_FILEINFO   _T("Show information about the file being played")
+
+#define HELP_PREFS _T("Go to the preferences menu")
+#define EXTRA_PREFS _T("Shows the extended GUI")
+
+#define HELP_ABOUT _T("About this program")
+
+#define HELP_STOP _T("Stop")
+
+#define HELP_PLAY _T("Play")
+#define HELP_PAUSE _T("Pause")
+#define HELP_PLO _T("Playlist")
+#define HELP_PLP _T("Previous playlist item")
+#define HELP_PLN _T("Next playlist item")
+#define HELP_SLOW _T("Play slower")
+#define HELP_FAST _T("Play faster")
+
+// The TBBUTTON structure contains information the toolbar buttons.
+static TBBUTTON tbButton[] =      
+{
+  {0, ID_FILE_QUICKOPEN,        TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {1, ID_FILE_OPENNET,       TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {2, StopStream_Event,       TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {3, PlayStream_Event,        TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {4, ID_VIEW_PLAYLIST,       TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {5, PrevStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {6, NextStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {7, SlowStream_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {8, FastStream_Event,       TBSTATE_ENABLED, TBSTYLE_BUTTON,   0, -1},
+};
+
+// Toolbar ToolTips
+TCHAR * szToolTips[] = 
+{
+    HELP_SIMPLE, HELP_NET, HELP_STOP, HELP_PLAY, HELP_PLO, HELP_PLP,
+    HELP_PLN, HELP_SLOW, HELP_FAST
+};
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+BOOL Interface::InitInstance( HINSTANCE hInstance, intf_thread_t *_p_intf )
+{
+    /* Initializations */
+    pIntf = _p_intf;
+    hwndMain = hwndCB = hwndTB = hwndSlider = hwndLabel = hwndVol = hwndSB = 0;
+    i_old_playing_status = PAUSE_S;
+
+    hInst = hInstance; // Store instance handle in our global variable
+
+    // Check if the application is running.
+    // If it's running then focus its window.
+    hwndMain = FindWindow( _T("VLC WinCE"), _T("VLC media player") );  
+    if( hwndMain ) 
+    {
+        SetForegroundWindow( hwndMain );
+        return TRUE;
+    }
+
+    // Register window class
+    WNDCLASS wc;
+    wc.style = CS_HREDRAW | CS_VREDRAW ;
+    wc.lpfnWndProc = (WNDPROC)BaseWndProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hIcon = NULL;
+    wc.hInstance = hInstance;
+    wc.hCursor = NULL;
+    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+    wc.lpszMenuName = NULL;
+    wc.lpszClassName = _T("VLC WinCE");
+    if( !RegisterClass( &wc ) ) return FALSE;
+
+    // Create main window
+    hwndMain =
+        CreateWindow( _T("VLC WinCE"), _T("VLC media player"), WS_VISIBLE,
+                      0, MENU_HEIGHT, CW_USEDEFAULT, CW_USEDEFAULT,
+                      NULL, NULL, hInstance, (void *)this );
+
+    if( !hwndMain ) return FALSE;
+
+    ShowWindow( hwndMain, TRUE );
+    UpdateWindow( hwndMain );
+
+    return TRUE;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  CreateToolbar
+
+PURPOSE: 
+  Registers the TOOLBAR control class and creates a toolbar.
+
+***********************************************************************/
+HWND WINAPI Interface::CreateToolbar( HWND hwnd )
+{
+    DWORD dwStyle;
+    HWND hwndTB;
+    RECT rect, rectTB;
+
+    INITCOMMONCONTROLSEX iccex;
+    iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    iccex.dwICC = ICC_BAR_CLASSES;
+
+    // Registers TOOLBAR control classes from the common control dll
+    InitCommonControlsEx (&iccex);
+
+    //  Create the toolbar control
+    dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS |
+        WS_EX_OVERLAPPEDWINDOW | CCS_NOPARENTALIGN;
+
+    hwndTB = CreateToolbarEx( hwnd, dwStyle, NULL, NUMIMAGES,
+        hInst, IDB_BITMAP1, tbButton, sizeof(tbButton) / sizeof(TBBUTTON),
+        BUTTONWIDTH, BUTTONHEIGHT, IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON) );
+
+    if( !hwndTB ) return NULL;
+  
+    // Add ToolTips to the toolbar.
+    SendMessage( hwndTB, TB_SETTOOLTIPS, (WPARAM)NUMIMAGES, 
+                 (LPARAM)szToolTips );
+
+    // Reposition the toolbar.
+    GetClientRect( hwnd, &rect );
+    GetWindowRect( hwndTB, &rectTB );
+    MoveWindow( hwndTB, rect.left, rect.bottom - rect.top - 2*MENU_HEIGHT, 
+                rect.right - rect.left, MENU_HEIGHT, TRUE );
+
+    return hwndTB;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  CreateSliderbar
+
+PURPOSE: 
+  Registers the TRACKBAR_CLASS control class and creates a trackbar.
+
+***********************************************************************/
+HWND WINAPI Interface::CreateSliderbar( HWND hwnd )
+{
+    HWND hwndSlider;
+    RECT rect;
+
+    INITCOMMONCONTROLSEX iccex;
+    iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
+    iccex.dwICC = ICC_BAR_CLASSES;
+
+    // Registers TRACKBAR_CLASS control classes from the common control dll
+    InitCommonControlsEx( &iccex );
+
+    hwndSlider = CreateWindowEx( NULL, TRACKBAR_CLASS, NULL,
+                WS_CHILD | WS_VISIBLE | TBS_HORZ | WS_EX_OVERLAPPEDWINDOW |
+                TBS_BOTTOM,  //|WS_CLIPSIBLINGS,
+                0, 0, 0, 0, hwnd, NULL, hInst, NULL );
+
+    if( !hwndSlider ) return NULL;
+
+    SendMessage( hwndSlider, TBM_SETRANGEMIN, 1, 0 );
+    SendMessage( hwndSlider, TBM_SETRANGEMAX, 1, SLIDER_MAX_POS );
+    SendMessage( hwndSlider, TBM_SETPOS, 1, 0 );
+
+    // Reposition the trackbar
+    GetClientRect( hwnd, &rect );
+    MoveWindow( hwndSlider, rect.left, 
+                rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT, 
+                rect.right - rect.left - 40, 30, TRUE );
+
+    ShowWindow( hwndSlider, SW_HIDE );
+
+    return hwndSlider;
+}
+
+HWND WINAPI Interface::CreateStaticText( HWND hwnd )
+{
+    HWND hwndLabel;
+    RECT rect;
+
+    hwndLabel = CreateWindowEx( 0, _T("STATIC"), _T("label"),
+                                WS_CHILD | WS_VISIBLE | SS_CENTER ,
+                                0, 0, 0, 0, hwnd, (HMENU)1980, hInst, NULL );
+
+    // Reposition the trackbar
+    GetClientRect( hwnd, &rect );
+
+    MoveWindow( hwndLabel, rect.left,
+                rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT +30,
+                rect.right - rect.left - 40,
+                SLIDER_HEIGHT - 30, TRUE );
+
+    ShowWindow( hwndLabel, SW_HIDE );
+
+    return hwndLabel;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  CreateVolTrackbar
+
+PURPOSE: 
+  Registers the TRACKBAR_CLASS control class and creates a trackbar.
+
+***********************************************************************/
+HWND WINAPI Interface::CreateVolTrackbar( HWND hwnd )
+{
+    HWND hwndVol;
+    RECT rect;
+
+    INITCOMMONCONTROLSEX iccex;
+    iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
+    iccex.dwICC = ICC_BAR_CLASSES;
+
+    // Registers TRACKBAR_CLASS control classes from the common control dll
+    InitCommonControlsEx( &iccex );
+
+    hwndVol = CreateWindowEx( NULL, TRACKBAR_CLASS, NULL,
+                WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_RIGHT | TBS_AUTOTICKS |
+                WS_EX_OVERLAPPEDWINDOW, //|WS_CLIPSIBLINGS,
+                0, 0, 0, 0, hwnd, NULL, hInst, NULL );
+
+    if( !hwndVol ) return NULL;
+
+    SendMessage( hwndVol, TBM_SETRANGEMIN, 1, 0 );
+    SendMessage( hwndVol, TBM_SETRANGEMAX, 1, 200 );
+    SendMessage( hwndVol, TBM_SETPOS, 1, 100 );
+    SendMessage( hwndVol, TBM_SETTICFREQ, 50, 0 );  
+
+    // Reposition the trackbar
+    GetClientRect( hwnd, &rect );
+    MoveWindow( hwndVol, rect.right - rect.left - 40, 
+                rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT, 
+                40, SLIDER_HEIGHT, TRUE );
+
+    ShowWindow( hwndVol, SW_HIDE );
+
+    return hwndVol;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  CreateStatusbar
+
+PURPOSE: 
+  Registers the StatusBar control class and creates a Statusbar.
+
+***********************************************************************/
+HWND WINAPI Interface::CreateStatusbar( HWND hwnd )
+{
+    DWORD dwStyle;
+    HWND hwndSB;
+    RECT rect;
+
+    INITCOMMONCONTROLSEX iccex;
+    iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
+    iccex.dwICC = ICC_BAR_CLASSES;
+
+    // Registers Statusbar control classes from the common control dll
+    InitCommonControlsEx( &iccex );
+
+    // Create the statusbar control
+    dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS | CCS_NOPARENTALIGN;
+
+    hwndSB = CreateWindowEx( NULL, STATUSCLASSNAME, NULL,
+                             WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_BOTTOM |
+                             TBS_RIGHT  |WS_CLIPSIBLINGS,
+                             0, 0, CW_USEDEFAULT, 50, hwnd, NULL, hInst, 0 );
+
+    if (!hwndSB ) return NULL;
+
+    // Get the coordinates of the parent window's client area. 
+    GetClientRect( hwnd, &rect );
+
+    // allocate memory for the panes of status bar
+    int nopanes = 2;
+    int *indicators = new int[nopanes];
+
+    // set width for the panes
+    indicators[0] = 3 * ( rect.right - rect.left ) / 4;
+    indicators[1] = rect.right - rect.left;
+
+    // call functions to set style
+    SendMessage( hwndSB, SB_SETPARTS, (WPARAM)nopanes, (LPARAM)indicators );
+
+    return hwndSB;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  BaseWndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT CALLBACK CBaseWindow::BaseWndProc( HWND hwnd, UINT msg, WPARAM wParam,
+                                           LPARAM lParam )
+{
+    // check to see if a copy of the 'this' pointer needs to be saved
+    if( msg == WM_CREATE )
+    {
+        CBaseWindow *pObj = reinterpret_cast<CBaseWindow *>
+            ((long)((LPCREATESTRUCT)lParam)->lpCreateParams);
+        ::SetWindowLong( hwnd, GWL_USERDATA,
+                         (LONG)((LPCREATESTRUCT)lParam)->lpCreateParams );
+
+        pObj->DlgFlag = FALSE;
+        pObj->hWnd = hwnd; // videowindow
+    }
+
+    if( msg == WM_INITDIALOG )
+    {
+        CBaseWindow *pObj = reinterpret_cast<CBaseWindow *>(lParam);
+        ::SetWindowLong( hwnd, GWL_USERDATA, lParam );
+        pObj->DlgFlag = TRUE;
+        pObj->hWnd = hwnd; //streamout
+    }
+
+    BOOL bProcessed = FALSE;
+    LRESULT lResult;
+
+    // Retrieve the pointer
+    CBaseWindow *pObj =
+        reinterpret_cast<CBaseWindow *>(::GetWindowLong( hwnd, GWL_USERDATA ));
+
+    // Filter message through child classes
+    if( pObj )
+        lResult = pObj->WndProc( hwnd, msg, wParam, lParam, &bProcessed );
+    else
+        return ( pObj->DlgFlag ? FALSE : TRUE ); // message not processed
+
+    if( pObj->DlgFlag )
+        return bProcessed; // processing a dialog message return TRUE if processed
+    else if( !bProcessed )
+        // If message was unprocessed and not a dialog, send it back to Windows
+        lResult = DefWindowProc( hwnd, msg, wParam, lParam );
+
+    return lResult; // processing a window message return FALSE if processed
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT CALLBACK Interface::WndProc( HWND hwnd, UINT msg, WPARAM wp,
+                                     LPARAM lp, PBOOL pbProcessed )
+{
+    SHMENUBARINFO mbi;
+
+    // call the base class first
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    case WM_CREATE:
+        //Create the menubar
+        memset( &mbi, 0, sizeof(SHMENUBARINFO) );
+        mbi.cbSize     = sizeof(SHMENUBARINFO);
+        mbi.hwndParent = hwnd;
+        mbi.nToolBarId = IDR_MENUBAR;
+        mbi.hInstRes   = hInst;
+        mbi.nBmpId     = 0;
+        mbi.cBmpImages = 0;
+
+        if( !SHCreateMenuBar(&mbi) )
+        {
+            MessageBox(hwnd, L"SHCreateMenuBar Failed", L"Error", MB_OK);
+            //return -1;
+        }
+    
+        hwndCB = mbi.hwndMB;
+
+        // Creates the toolbar
+        hwndTB = CreateToolbar( hwnd );
+
+        // Creates the sliderbar
+        hwndSlider = CreateSliderbar( hwnd );
+
+        // Creates the time label
+        hwndLabel = CreateStaticText( hwnd );
+
+        // Creates the volume trackbar
+        hwndVol = CreateVolTrackbar( hwnd );
+
+        // Creates the statusbar
+        hwndSB = CreateStatusbar( hwnd );
+
+        /* Video window */
+        video = CreateVideoWindow( pIntf, hInst, hwnd );
+
+        ti = new Timer(pIntf, hwnd, this);
+
+        // Hide the SIP button (WINCE only)
+        SetForegroundWindow( hwnd );
+        SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+
+        return lResult;
+
+    case WM_COMMAND:
+        switch( GET_WM_COMMAND_ID(wp,lp) )
+        {
+        case ID_FILE_QUICKOPEN: 
+            OnOpenFileSimple();
+            return lResult;
+
+        case ID_FILE_OPENFILE: 
+            open = new OpenDialog( pIntf, hInst, FILE_ACCESS,
+                                   ID_FILE_OPENFILE, OPEN_NORMAL );
+            DialogBoxParam( hInst, (LPCTSTR)IDD_DUMMY, hwnd,
+                            (DLGPROC)open->BaseWndProc, (long)open );
+            delete open;
+            return lResult;
+
+        case ID_FILE_OPENNET:
+            open = new OpenDialog( pIntf, hInst, NET_ACCESS, ID_FILE_OPENNET,
+                                   OPEN_NORMAL );
+            DialogBoxParam( hInst, (LPCTSTR)IDD_DUMMY, hwnd,
+                            (DLGPROC)open->BaseWndProc, (long)open );
+            delete open;
+            return lResult;
+
+        case PlayStream_Event: 
+            OnPlayStream();
+            return lResult;
+
+        case StopStream_Event: 
+            OnStopStream();
+            return lResult;
+
+        case PrevStream_Event: 
+            OnPrevStream();
+            return lResult;
+
+        case NextStream_Event: 
+            OnNextStream();
+            return lResult;
+
+        case SlowStream_Event: 
+            OnSlowStream();
+            return lResult;
+
+        case FastStream_Event: 
+            OnFastStream();
+            return lResult;
+
+        case ID_FILE_ABOUT: 
+        {
+            string about = (string)"VLC media player " PACKAGE_VERSION +
+                _("\n(WinCE interface)\n\n") +
+                _("(c) 1996-2005 - the VideoLAN Team\n\n") +
+                _("The VideoLAN team <videolan@videolan.org>\n"
+                  "http://www.videolan.org/\n\n");
+
+            MessageBox( hwnd, _FROMMB(about.c_str()),
+                        _T("About VLC media player"), MB_OK );
+            return lResult;
+        }
+
+        case ID_FILE_EXIT:
+            SendMessage( hwnd, WM_CLOSE, 0, 0 );
+            return lResult;
+
+        case ID_VIEW_STREAMINFO:
+            fi = new FileInfo( pIntf, hInst );
+            DialogBoxParam( hInst, (LPCTSTR)IDD_DUMMY, hwnd,
+                            (DLGPROC)fi->BaseWndProc, (long)fi );
+            delete fi;
+            return lResult;
+
+        case ID_VIEW_MESSAGES:
+            hmsg = new Messages( pIntf, hInst );
+            DialogBoxParam( hInst, (LPCTSTR)IDD_MESSAGES, hwnd,
+                            (DLGPROC)hmsg->BaseWndProc, (long)hmsg );
+            delete hmsg;
+            return lResult;
+
+        case ID_VIEW_PLAYLIST:
+            pl = new Playlist( pIntf, hInst );
+            DialogBoxParam( hInst, (LPCTSTR)IDD_DUMMY, hwnd,
+                            (DLGPROC)pl->BaseWndProc, (long)pl );
+            delete pl;
+            return lResult;
+
+        case ID_SETTINGS_PREF:
+            pref = new PrefsDialog( pIntf, hInst );
+            DialogBoxParam( hInst, (LPCTSTR)IDD_DUMMY, hwnd,
+                            (DLGPROC)pref->BaseWndProc, (long)pref );
+            delete pref;
+            return lResult;
+                  
+        default:
+            OnMenuEvent( pIntf, GET_WM_COMMAND_ID(wp,lp) );
+            // we should test if it is a menu command
+        }
+        break;
+  
+    case WM_TIMER:
+        ti->Notify();
+        return lResult;
+
+    case WM_CTLCOLORSTATIC: 
+        if( ( (HWND)lp == hwndSlider ) || ( (HWND)lp == hwndVol ) )
+        { 
+            return( (LRESULT)::GetSysColorBrush(COLOR_3DFACE) ); 
+        }
+        if( (HWND)lp == hwndLabel )
+        {
+            SetBkColor( (HDC)wp, RGB (192, 192, 192) ); 
+            return( (LRESULT)::GetSysColorBrush(COLOR_3DFACE) ); 
+        }
+        break;
+
+    case WM_HSCROLL:
+        if( (HWND)lp == hwndSlider )
+        {
+            OnSliderUpdate( wp );
+            return lResult;
+        }
+        break;
+
+    case WM_VSCROLL:
+        if( (HWND)lp == hwndVol )
+        {
+            OnChange( wp );
+            return lResult;
+        }
+        break;
+
+    case WM_INITMENUPOPUP:
+      msg_Err( pIntf, "WM_INITMENUPOPUP" );
+        RefreshSettingsMenu( pIntf,
+            (HMENU)SendMessage( hwndCB, SHCMBM_GETSUBMENU, (WPARAM)0,
+                                (LPARAM)IDM_SETTINGS ) );
+        RefreshAudioMenu( pIntf,
+            (HMENU)SendMessage( hwndCB, SHCMBM_GETSUBMENU, (WPARAM)0,
+                                (LPARAM)IDM_AUDIO ) );
+        RefreshVideoMenu( pIntf,
+            (HMENU)SendMessage( hwndCB, SHCMBM_GETSUBMENU, (WPARAM)0,
+                                (LPARAM)IDM_VIDEO ) );
+        RefreshNavigMenu( pIntf,
+            (HMENU)SendMessage( hwndCB, SHCMBM_GETSUBMENU, (WPARAM)0,
+                                (LPARAM)IDM_NAVIGATION ) );
+
+      msg_Err( pIntf, "WM_MEND" );
+#if 0
+        // Undo the video display because menu is opened
+        // due to GAPI, menu top display is not assumed
+        // FIXME verify if p_child_window exits
+        SendMessage( pIntf->p_sys->p_video_window->p_child_window,
+                     WM_INITMENUPOPUP, wp, lp );
+#endif
+
+        //refresh screen
+        /* InvalidateRect(hwnd, NULL, TRUE);
+           /UpdateWindow(hwndCB); //  NULL*/
+        break;
+
+#if 0
+    case WM_NOTIFY:
+        // Redo the video display because menu can be closed
+        // FIXME verify if p_child_window exits
+        if( (((NMHDR *)lp)->code) == NM_CUSTOMDRAW )
+            SendMessage( pIntf->p_sys->p_video_window->p_child_window,
+                         WM_NOTIFY, wp, lp );
+        return lResult;
+#endif
+
+    case WM_HELP:
+        MessageBox (hwnd, _T("Help"), _T("Help"), MB_OK);
+        return lResult;
+
+    case WM_CLOSE:
+        DestroyWindow( hwndCB );
+        DestroyWindow( hwnd );
+        return lResult;
+
+    case WM_DESTROY:
+      PostQuitMessage( 0 );
+      return lResult;
+    }
+
+    return DefWindowProc( hwnd, msg, wp, lp );
+}
+
+void Interface::OnOpenFileSimple( void )
+{
+    OPENFILENAME ofn;
+    TCHAR DateiName[80+1] = _T("\0");
+    static TCHAR szFilter[] = _T("All (*.*)\0*.*\0");
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    memset( &ofn, 0, sizeof(OPENFILENAME) );
+    ofn.lStructSize = sizeof(OPENFILENAME);
+    ofn.hwndOwner = NULL;
+    ofn.hInstance = hInst;
+    ofn.lpstrFilter = szFilter;
+    ofn.lpstrCustomFilter = NULL;
+    ofn.nMaxCustFilter = 0;
+    ofn.nFilterIndex = 1;     
+    ofn.lpstrFile = (LPTSTR)DateiName; 
+    ofn.nMaxFile = 80;
+    ofn.lpstrFileTitle = NULL; 
+    ofn.nMaxFileTitle = 40;
+    ofn.lpstrInitialDir = NULL;
+    ofn.lpstrTitle = _T("Quick Open File");
+    ofn.Flags = NULL; 
+    ofn.nFileOffset = 0;
+    ofn.nFileExtension = 0;
+    ofn.lpstrDefExt = NULL;
+    ofn.lCustData = 0L;
+    ofn.lpfnHook = NULL;
+    ofn.lpTemplateName = NULL;
+
+    SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+
+    if( GetOpenFileName( (LPOPENFILENAME)&ofn ) )
+    {
+        char *psz_filename = _TOMB(ofn.lpstrFile);
+        playlist_Add( p_playlist, psz_filename, psz_filename,
+                      PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
+    }
+
+    vlc_object_release( p_playlist );
+}
+
+void Interface::OnPlayStream( void )
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    if( p_playlist->i_size && p_playlist->i_enabled )
+    {
+        vlc_value_t state;
+
+        input_thread_t *p_input = (input_thread_t *)
+            vlc_object_find( pIntf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+
+        if( p_input == NULL )
+        {
+            /* No stream was playing, start one */
+            playlist_Play( p_playlist );
+            TogglePlayButton( PLAYING_S );
+            vlc_object_release( p_playlist );
+            return;
+        }
+
+        var_Get( p_input, "state", &state );
+
+        if( state.i_int != PAUSE_S )
+        {
+            /* A stream is being played, pause it */
+            state.i_int = PAUSE_S;
+        }
+        else
+        {
+            /* Stream is paused, resume it */
+            state.i_int = PLAYING_S;
+        }
+        var_Set( p_input, "state", state );
+
+        TogglePlayButton( state.i_int );
+        vlc_object_release( p_input );
+        vlc_object_release( p_playlist );
+    }
+    else
+    {
+        /* If the playlist is empty, open a file requester instead */
+        vlc_object_release( p_playlist );
+        OnOpenFileSimple();
+    }
+}
+
+void Interface::TogglePlayButton( int i_playing_status )
+{
+    TBREPLACEBITMAP tbrb;
+    tbrb.hInstOld = tbrb.hInstNew = (HINSTANCE) hInst;
+    tbrb.nButtons = NUMIMAGES;
+
+    if( i_playing_status == i_old_playing_status ) return;
+
+    if( i_playing_status == PLAYING_S )
+    {
+        tbrb.nIDOld = IDB_BITMAP2;
+        tbrb.nIDNew = IDB_BITMAP1;
+
+        SendMessage( hwndTB, TB_REPLACEBITMAP, (WPARAM)0,
+                     (LPARAM)(LPTBREPLACEBITMAP)&tbrb );
+    }
+    else
+    {
+        tbrb.nIDOld = IDB_BITMAP1;
+        tbrb.nIDNew = IDB_BITMAP2;
+
+        SendMessage( hwndTB, TB_REPLACEBITMAP, (WPARAM)0,
+                     (LPARAM)(LPTBREPLACEBITMAP)&tbrb );
+    }
+
+    UpdateWindow( hwndTB );
+
+    i_old_playing_status = i_playing_status;
+}
+
+void Interface::OnVideoOnTop( void )
+{
+    vlc_value_t val;
+
+    vout_thread_t *p_vout = (vout_thread_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
+
+    if( p_vout == NULL ) return;
+
+    if( var_Get( (vlc_object_t *)p_vout, "video-on-top", &val ) < 0 )
+        return;
+
+    val.b_bool = !val.b_bool;
+    var_Set( (vlc_object_t *)p_vout, "video-on-top", val );
+
+    vlc_object_release( (vlc_object_t *)p_vout );
+}
+
+void Interface::OnSliderUpdate( int wp )
+{
+    vlc_mutex_lock( &pIntf->change_lock );
+    input_thread_t *p_input = pIntf->p_sys->p_input;
+
+    DWORD dwPos = SendMessage( hwndSlider, TBM_GETPOS, 0, 0 ); 
+
+    if( (int)LOWORD(wp) == SB_THUMBPOSITION ||
+        (int)LOWORD(wp) == SB_ENDSCROLL )
+    {
+        if( pIntf->p_sys->i_slider_pos != dwPos && p_input )
+        {
+            vlc_value_t pos;
+            pos.f_float = (float)dwPos / (float)SLIDER_MAX_POS;
+            var_Set( p_input, "position", pos );
+        }
+
+        pIntf->p_sys->b_slider_free = VLC_TRUE;
+    }
+    else
+    {
+        pIntf->p_sys->b_slider_free = VLC_FALSE;
+
+        if( p_input )
+        {
+            /* Update stream date */
+            char psz_time[ MSTRTIME_MAX_SIZE ], psz_total[ MSTRTIME_MAX_SIZE ];
+            mtime_t i_seconds;
+
+            i_seconds = var_GetTime( p_input, "length" ) / I64C(1000000 );
+            secstotimestr( psz_total, i_seconds );
+
+            i_seconds = var_GetTime( p_input, "time" ) / I64C(1000000 );
+            secstotimestr( psz_time, i_seconds );
+
+            SendMessage( hwndLabel, WM_SETTEXT, (WPARAM)1,
+                         (LPARAM)_FROMMB(psz_time) );
+        }
+    }
+
+    vlc_mutex_unlock( &pIntf->change_lock );
+}
+
+void Interface::OnChange( int wp )
+{
+    DWORD dwPos = SendMessage( hwndVol, TBM_GETPOS, 0, 0 );
+
+    if( LOWORD(wp) == SB_THUMBPOSITION || LOWORD(wp) == SB_ENDSCROLL )
+    {
+        Change( 200 - (int)dwPos );
+    }
+}
+
+void Interface::Change( int i_volume )
+{
+    aout_VolumeSet( pIntf, i_volume * AOUT_VOLUME_MAX / 200 / 2 );
+#if 0
+    SetToolTip( wxString::Format((wxString)wxU(_("Volume")) + wxT(" %d"),
+                i_volume ) );
+#endif
+}
+
+void Interface::OnStopStream( void )
+{
+    playlist_t * p_playlist = (playlist_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    playlist_Stop( p_playlist );
+    TogglePlayButton( PAUSE_S );
+    vlc_object_release( p_playlist );
+}
+
+void Interface::OnPrevStream( void )
+{
+    playlist_t * p_playlist = (playlist_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    playlist_Prev( p_playlist );
+    vlc_object_release( p_playlist );
+}
+
+void Interface::OnNextStream( void )
+{
+    playlist_t * p_playlist = (playlist_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    playlist_Next( p_playlist );
+    vlc_object_release( p_playlist );
+}
+
+void Interface::OnSlowStream( void )
+{
+    input_thread_t *p_input = (input_thread_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+
+    if( p_input == NULL ) return;
+
+    vlc_value_t val; val.b_bool = VLC_TRUE;
+    var_Set( p_input, "rate-slower", val );
+    vlc_object_release( p_input );
+}
+
+void Interface::OnFastStream( void )
+{
+    input_thread_t *p_input = (input_thread_t *)
+        vlc_object_find( pIntf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+
+    if( p_input == NULL ) return;
+
+    vlc_value_t val; val.b_bool = VLC_TRUE;
+    var_Set( p_input, "rate-faster", val );
+    vlc_object_release( p_input );
+}
diff --git a/modules/gui/wince/iteminfo.cpp b/modules/gui/wince/iteminfo.cpp
new file mode 100644 (file)
index 0000000..2bdf1db
--- /dev/null
@@ -0,0 +1,315 @@
+/*****************************************************************************
+ * iteminfo.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <string.h>
+
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <winuser.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <commdlg.h>
+
+#include "wince.h"
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+ItemInfoDialog::ItemInfoDialog( intf_thread_t *_p_intf,
+                                HINSTANCE _hInst,
+                                playlist_item_t *_p_item )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+    hInst = _hInst;
+    p_item = _p_item;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT ItemInfoDialog::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                                 PBOOL pbProcessed  )
+{
+    SHINITDLGINFO shidi;
+    SHMENUBARINFO mbi;
+    INITCOMMONCONTROLSEX iccex;
+    RECT rcClient;
+
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    case WM_INITDIALOG: 
+        shidi.dwMask = SHIDIM_FLAGS;
+        shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
+            SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
+        shidi.hDlg = hwnd;
+        SHInitDialog( &shidi );
+
+        //Create the menubar.
+        memset( &mbi, 0, sizeof (SHMENUBARINFO) );
+        mbi.cbSize     = sizeof (SHMENUBARINFO);
+        mbi.hwndParent = hwnd;
+        mbi.nToolBarId = IDR_DUMMYMENU;
+        mbi.hInstRes   = hInst;
+        mbi.nBmpId     = 0;
+        mbi.cBmpImages = 0;  
+
+        if( !SHCreateMenuBar(&mbi) )
+        {
+            MessageBox( hwnd, L"SHCreateMenuBar Failed", L"Error", MB_OK );
+            //return -1;
+        }
+
+        hwndCB = mbi.hwndMB;
+
+        // Get the client area rect to put the panels in
+        GetClientRect( hwnd, &rcClient );
+
+        /* URI Textbox */
+        uri_label = CreateWindow( _T("STATIC"), _T("URI:"),
+                        WS_CHILD | WS_VISIBLE | SS_RIGHT,
+                        0, 10, 60, 15, hwnd, NULL, hInst, NULL);
+
+        uri_text = CreateWindow( _T("EDIT"), _FROMMB(p_item->input.psz_uri),
+            WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+            70, 10 - 3, rcClient.right - 70 - 10, 15 + 6, hwnd, 0, hInst, 0 );
+
+        /* Name Textbox */
+        name_label = CreateWindow( _T("STATIC"), _T("Name:"),
+                                   WS_CHILD | WS_VISIBLE | SS_RIGHT ,
+                                   0, 10 + 15 + 10, 60, 15,
+                                   hwnd, NULL, hInst, NULL);
+
+        name_text = CreateWindow( _T("EDIT"),
+            _FROMMB(p_item->input.psz_name),
+            WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+            70, 10 + 15 + 10 - 3, rcClient.right - 70 - 10, 15 + 6,
+            hwnd, NULL, hInst, NULL);
+
+        /* Author Textbox */
+        author_label = CreateWindow( _T("STATIC"), _T("Author:"),
+                         WS_CHILD | WS_VISIBLE | SS_RIGHT ,
+                         0, 10 + 2*( 15 + 10 ), 60, 15,
+                         hwnd, NULL, hInst, NULL);
+
+        author_text = CreateWindow( _T("EDIT"),
+            _FROMMB(playlist_ItemGetInfo( p_item, _("General"), _("Author") )),
+            WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+            70, 10 + 2*( 15 + 10 ) - 3, rcClient.right - 70 - 10, 15 + 6,
+            hwnd, NULL, hInst, NULL );
+
+        /* CheckBox */
+        checkbox_label = CreateWindow( _T("STATIC"), _T("Item Enabled:"),
+            WS_CHILD | WS_VISIBLE | SS_RIGHT ,
+            rcClient.right - 15 - 10 - 90 - 10, 10 + 4*( 15 + 10 ) + 5, 90, 15,
+            hwnd, NULL, hInst, NULL );
+
+        enabled_checkbox = CreateWindow( _T("BUTTON"), _T("Item Enabled"),
+            WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+            rcClient.right - 15 - 10, 10 + 4*( 15 + 10 ) + 5, 15, 15,
+            hwnd, NULL, hInst, NULL );
+
+        SendMessage( enabled_checkbox, BM_SETCHECK, 
+                     p_item->b_enabled ? BST_CHECKED : BST_UNCHECKED, 0 );
+
+        /* Treeview */
+        iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
+        iccex.dwICC = ICC_TREEVIEW_CLASSES;
+        InitCommonControlsEx( &iccex );
+
+        // Create the tree-view control.
+        info_tree = CreateWindowEx( 0, WC_TREEVIEW, NULL,
+            WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES |
+            TVS_LINESATROOT | TVS_HASBUTTONS,
+            0, rcClient.bottom/2, rcClient.right,
+            rcClient.bottom - rcClient.bottom/2 - MENU_HEIGHT + 2, // +2 to fix
+            hwnd, NULL, hInst, NULL );
+
+        UpdateInfo();
+        return lResult;
+
+    case WM_COMMAND:
+        if( LOWORD(wp) == IDOK )
+        {
+            OnOk();
+            EndDialog( hwnd, LOWORD( wp ) );
+            return TRUE;
+        }
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+
+    default:
+        // the message was not processed
+        // indicate if the base class handled it
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+    }
+
+    return lResult;
+}
+
+/*****************************************************************************
+ * Private methods.
+ *****************************************************************************/
+ void ItemInfoDialog::UpdateInfo()
+{
+    TVITEM tvi = {0}; 
+    TVINSERTSTRUCT tvins = {0}; 
+    HTREEITEM hPrev = (HTREEITEM)TVI_FIRST; 
+    HTREEITEM hPrevRootItem = NULL; 
+    HTREEITEM hPrevLev2Item = NULL; 
+
+    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; 
+
+    // Set the text of the item. 
+    tvi.pszText = _FROMMB(p_item->input.psz_name);
+    tvi.cchTextMax = _tcslen(tvi.pszText);
+
+    // Save the heading level in the item's application-defined data area 
+    tvi.lParam = (LPARAM)1; // root level
+    tvins.item = tvi; 
+    tvins.hInsertAfter = hPrev; 
+    tvins.hParent = TVI_ROOT; 
+
+    // Add the item to the tree-view control. 
+    hPrev = (HTREEITEM)TreeView_InsertItem( info_tree, &tvins );
+    hPrevRootItem = hPrev; 
+
+    /* Rebuild the tree */
+    vlc_mutex_lock( &p_item->input.lock );
+    for( int i = 0; i < p_item->input.i_categories; i++ )
+    {
+        info_category_t *p_cat = p_item->input.pp_categories[i];
+
+        // Set the text of the item. 
+        tvi.pszText = _FROMMB( p_item->input.psz_name );
+        tvi.cchTextMax = _tcslen( tvi.pszText );
+        
+        // Save the heading level in the item's application-defined data area
+        tvi.lParam = (LPARAM)2; // level 2
+        tvins.item = tvi; 
+        tvins.hInsertAfter = hPrev; 
+        tvins.hParent = hPrevRootItem;
+
+        // Add the item to the tree-view control. 
+        hPrev = (HTREEITEM)TreeView_InsertItem( info_tree, &tvins );
+
+        hPrevLev2Item = hPrev;
+
+        for( int j = 0; j < p_cat->i_infos; j++ )
+        {
+            info_t *p_info = p_cat->pp_infos[j];
+
+            // Set the text of the item. 
+            string szAnsi = (string)p_info->psz_name;
+            szAnsi += ": ";
+            szAnsi += p_info->psz_value;
+            tvi.pszText = _FROMMB( szAnsi.c_str() );
+            tvi.cchTextMax = _tcslen( tvi.pszText );
+            tvi.lParam = (LPARAM)3; // level 3
+            tvins.item = tvi; 
+            tvins.hInsertAfter = hPrev; 
+            tvins.hParent = hPrevLev2Item;
+    
+            // Add the item to the tree-view control. 
+            hPrev = (HTREEITEM)TreeView_InsertItem( info_tree, &tvins );
+        }
+
+        TreeView_Expand( info_tree, hPrevLev2Item,
+                         TVE_EXPANDPARTIAL |TVE_EXPAND );
+    }
+    vlc_mutex_unlock( &p_item->input.lock );
+
+    TreeView_Expand( info_tree, hPrevRootItem, TVE_EXPANDPARTIAL |TVE_EXPAND );
+}
+
+/*****************************************************************************
+ * Events methods.
+ *****************************************************************************/
+void ItemInfoDialog::OnOk()
+{
+    int b_state, i_item;
+
+    vlc_mutex_lock( &p_item->input.lock );
+
+    TCHAR psz_name[MAX_PATH];
+    Edit_GetText( name_text, psz_name, MAX_PATH );
+    if( p_item->input.psz_name ) free( p_item->input.psz_name );
+    p_item->input.psz_name = strdup( _TOMB(psz_name) );
+
+    TCHAR psz_uri[MAX_PATH];
+    Edit_GetText( uri_text, psz_uri, MAX_PATH );
+    if( p_item->input.psz_uri ) free( p_item->input.psz_uri );
+    p_item->input.psz_uri = strdup( _TOMB(psz_uri) );
+
+    TCHAR psz_author[MAX_PATH];
+    Edit_GetText( author_text, psz_author, MAX_PATH );
+    playlist_ItemAddInfo( p_item, "General", "Author", _TOMB(psz_author) );
+
+    vlc_bool_t b_old_enabled = p_item->b_enabled;
+
+    playlist_t * p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist != NULL )
+    {
+        b_state = SendMessage( enabled_checkbox, BM_GETCHECK, 0, 0 );
+        if( b_old_enabled == VLC_FALSE && (b_state & BST_CHECKED) )
+            p_playlist->i_enabled ++;
+        else if( b_old_enabled == VLC_TRUE && (b_state & BST_UNCHECKED) )
+            p_playlist->i_enabled --;
+
+        vlc_object_release( p_playlist );
+    }
+
+    p_item->b_enabled = (b_state & BST_CHECKED) ? VLC_TRUE : VLC_FALSE ;
+
+    vlc_mutex_unlock( &p_item->input.lock );
+}
diff --git a/modules/gui/wince/menus.cpp b/modules/gui/wince/menus.cpp
new file mode 100644 (file)
index 0000000..dc8e69c
--- /dev/null
@@ -0,0 +1,643 @@
+/*****************************************************************************
+ * menus.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>                                            /* strerror() */
+#include <stdio.h>
+
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+
+#include "wince.h"
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/* IDs for the controls and the menu commands */
+enum
+{
+    /* menu items */
+    MenuDummy_Event = 1000,
+    OpenFileSimple_Event = 1100,
+    OpenFile_Event,
+    OpenDisc_Event,
+    OpenNet_Event,
+    FirstAutoGenerated_Event = 1999,
+    SettingsMenu_Events = 2000,
+    AudioMenu_Events = 3000,
+    VideoMenu_Events = 4000,
+    NavigMenu_Events = 5000,
+    PopupMenu_Events = 6000
+};
+
+void RefreshAudioMenu( intf_thread_t *p_intf, HMENU hMenu )
+{
+#define MAX_AUDIO_ITEMS 10
+
+    vlc_object_t *p_object;
+    char *ppsz_varnames[MAX_AUDIO_ITEMS];
+    int pi_objects[MAX_AUDIO_ITEMS];
+    vector<MenuItemExt*>::iterator iter;
+    int i;
+
+    /* Delete old menu */
+    int count = wce_GetMenuItemCount( hMenu );
+    for( i = 0; i <= count; i++ ) RemoveMenu( hMenu, 0, MF_BYPOSITION );
+        
+    if( p_intf->p_sys->p_audio_menu )
+    {
+        for( iter = p_intf->p_sys->p_audio_menu->begin();
+             iter != p_intf->p_sys->p_audio_menu->end(); iter++ )
+            delete *iter;
+        p_intf->p_sys->p_audio_menu->clear();
+    }
+    else p_intf->p_sys->p_audio_menu = new vector<MenuItemExt*>;
+
+    /* Initializations */
+    memset( pi_objects, 0, MAX_AUDIO_ITEMS * sizeof(int) );
+    i = 0;
+
+    p_object = (vlc_object_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+    if( p_object != NULL )
+    {
+        ppsz_varnames[i] = "audio-es";
+        pi_objects[i++] = p_object->i_object_id;
+        vlc_object_release( p_object );
+    }
+
+    p_object = (vlc_object_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_AOUT, FIND_ANYWHERE );
+    if( p_object != NULL )
+    {
+        ppsz_varnames[i] = "audio-device";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "audio-channels";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "visual";
+        pi_objects[i++] = p_object->i_object_id;
+        vlc_object_release( p_object );
+    }
+
+    /* Build menu */
+    RefreshMenu( p_intf, p_intf->p_sys->p_audio_menu,
+                 hMenu, i, ppsz_varnames, pi_objects, AudioMenu_Events );
+}
+
+void RefreshVideoMenu( intf_thread_t *p_intf, HMENU hMenu )
+{
+#define MAX_VIDEO_ITEMS 15
+
+    vlc_object_t *p_object;
+    char *ppsz_varnames[MAX_VIDEO_ITEMS];
+    int pi_objects[MAX_VIDEO_ITEMS];
+    vector<MenuItemExt*>::iterator iter;
+    int i;
+
+    /* Delete old menu */
+    int count = wce_GetMenuItemCount( hMenu );
+    for( i = 0; i <= count; i++ ) RemoveMenu( hMenu, 0, MF_BYPOSITION );
+        
+    if( p_intf->p_sys->p_video_menu )
+    {
+        for( iter = p_intf->p_sys->p_video_menu->begin();
+             iter != p_intf->p_sys->p_video_menu->end(); iter++ )
+            delete *iter;
+        p_intf->p_sys->p_video_menu->clear();
+    }
+    else p_intf->p_sys->p_video_menu = new vector<MenuItemExt*>;
+        
+    /* Initializations */
+    memset( pi_objects, 0, MAX_VIDEO_ITEMS * sizeof(int) );
+    i = 0;
+
+    p_object = (vlc_object_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+    if( p_object != NULL )
+    {
+        ppsz_varnames[i] = "video-es";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "spu-es";
+        pi_objects[i++] = p_object->i_object_id;
+        vlc_object_release( p_object );
+    }
+
+    p_object = (vlc_object_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
+    if( p_object != NULL )
+    {
+        vlc_object_t *p_dec_obj;
+
+        ppsz_varnames[i] = "fullscreen";
+        pi_objects[i++] = p_object->i_object_id;
+#ifdef WINCE
+        ppsz_varnames[i] = "transform";
+        pi_objects[i++] = p_object->i_object_id;
+#endif
+        ppsz_varnames[i] = "zoom";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "deinterlace";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "aspect-ratio";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "crop";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "directx-on-top";
+        pi_objects[i++] = p_object->i_object_id;
+
+        p_dec_obj = (vlc_object_t *)
+            vlc_object_find( p_object, VLC_OBJECT_DECODER, FIND_PARENT );
+        if( p_dec_obj != NULL )
+        {
+            ppsz_varnames[i] = "ffmpeg-pp-q";
+            pi_objects[i++] = p_dec_obj->i_object_id;
+            vlc_object_release( p_dec_obj );
+        }
+
+        vlc_object_release( p_object );
+    }
+
+    /* Build menu */
+    RefreshMenu( p_intf, p_intf->p_sys->p_video_menu, hMenu, i,
+                 ppsz_varnames, pi_objects, VideoMenu_Events );
+}
+
+void RefreshNavigMenu( intf_thread_t *p_intf, HMENU hMenu )
+{
+#define MAX_NAVIG_ITEMS 10
+
+    vlc_object_t *p_object;
+    char *ppsz_varnames[MAX_NAVIG_ITEMS];
+    int pi_objects[MAX_NAVIG_ITEMS];
+    vector<MenuItemExt*>::iterator iter;
+    int i;
+
+    /* Delete old menu */
+    int count = wce_GetMenuItemCount( hMenu );
+    for( i = 0; i <= count; i++ ) RemoveMenu( hMenu, 0, MF_BYPOSITION );
+        
+    if( p_intf->p_sys->p_navig_menu )
+    {
+        for( iter = p_intf->p_sys->p_navig_menu->begin();
+             iter != p_intf->p_sys->p_navig_menu->end(); iter++ )
+            delete *iter;
+        p_intf->p_sys->p_navig_menu->clear();
+    }
+    else p_intf->p_sys->p_navig_menu = new vector<MenuItemExt*>;
+
+    /* Initializations */
+    memset( pi_objects, 0, MAX_NAVIG_ITEMS * sizeof(int) );
+    i = 0;
+
+    p_object = (vlc_object_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
+    if( p_object != NULL )
+    {
+        ppsz_varnames[i] = "title";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "chapter";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "program";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "navigation";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "dvd_menus";
+        pi_objects[i++] = p_object->i_object_id;
+
+        ppsz_varnames[i] = "prev-title";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "next-title";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "prev-chapter";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "next-chapter";
+        pi_objects[i++] = p_object->i_object_id;
+
+        vlc_object_release( p_object );
+    }
+
+    /* Build menu */
+    RefreshMenu( p_intf, p_intf->p_sys->p_navig_menu, hMenu, i,
+                 ppsz_varnames, pi_objects, NavigMenu_Events );
+}
+
+void RefreshSettingsMenu( intf_thread_t *p_intf, HMENU hMenu )
+{
+#define MAX_SETTINGS_ITEMS 10
+
+    vlc_object_t *p_object;
+    char *ppsz_varnames[MAX_SETTINGS_ITEMS];
+    int pi_objects[MAX_SETTINGS_ITEMS];
+    vector<MenuItemExt*>::iterator iter;
+    int i;
+
+    /* Delete old menu */
+    int count = wce_GetMenuItemCount( hMenu );
+    for( i = 0; i <= count; i++ ) RemoveMenu( hMenu, 0, MF_BYPOSITION );
+
+    if( p_intf->p_sys->p_settings_menu )
+    {
+        for( iter = p_intf->p_sys->p_settings_menu->begin();
+             iter != p_intf->p_sys->p_settings_menu->end(); iter++ )
+            delete(*iter);
+        p_intf->p_sys->p_settings_menu->clear();
+    }
+    else p_intf->p_sys->p_settings_menu = new vector<MenuItemExt*>;
+
+    /* Initializations */
+    memset( pi_objects, 0, MAX_SETTINGS_ITEMS * sizeof(int) );
+    i = 0;
+
+    AppendMenu( hMenu, MF_STRING, ID_SETTINGS_EXTEND, _T("&Extended GUI") );
+    AppendMenu( hMenu, MF_STRING, ID_SETTINGS_PREF, _T("&Preferences...") );
+
+    p_object = (vlc_object_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_INTF, FIND_PARENT );
+    if( p_object != NULL )
+    {
+        ppsz_varnames[i] = "intf-switch";
+        pi_objects[i++] = p_object->i_object_id;
+        ppsz_varnames[i] = "intf-add";
+        pi_objects[i++] = p_object->i_object_id;
+        vlc_object_release( p_object );
+    }
+
+    /* Build menu */
+    RefreshMenu( p_intf, p_intf->p_sys->p_settings_menu, hMenu, i,
+                 ppsz_varnames, pi_objects, SettingsMenu_Events );
+}
+
+/*****************************************************************************
+ * Refresh the menu.
+ *****************************************************************************/
+void RefreshMenu( intf_thread_t *p_intf, vector<MenuItemExt*> *_p_menuList,
+                  HMENU hMenu , int i_count, char **ppsz_varnames, 
+                  int *pi_objects, int i_start_id )
+{
+    vlc_object_t *p_object;
+    vlc_bool_t b_section_empty = VLC_FALSE;
+    int i;
+
+    /* Initializations */
+    int i_item_id = i_start_id;
+
+    for( i = 0; i < i_count; i++ )
+    {
+        if( !ppsz_varnames[i] )
+        {
+            if( b_section_empty )
+            {
+                AppendMenu( hMenu, MF_GRAYED | MF_STRING,
+                            MenuDummy_Event + i, _T("Empty") );
+            }
+
+            AppendMenu( hMenu, MF_SEPARATOR, 0, _T("") );
+            b_section_empty = VLC_TRUE;
+            continue;
+        }
+
+        if( !pi_objects[i] )
+        {
+            AppendMenu( hMenu, MF_GRAYED | MF_STRING,
+                        MenuDummy_Event, _FROMMB(ppsz_varnames[i]) );
+
+            b_section_empty = VLC_FALSE;
+            continue;
+        }
+
+        p_object = (vlc_object_t *)vlc_object_get( p_intf, pi_objects[i] );
+        if( p_object == NULL ) continue;
+
+        b_section_empty = VLC_FALSE;
+        CreateMenuItem( p_intf, _p_menuList, hMenu, ppsz_varnames[i],
+                        p_object, &i_item_id );
+        vlc_object_release( p_object );
+    }
+
+    /* Special case for empty menus */
+    if( wce_GetMenuItemCount(hMenu) == 0 || b_section_empty )
+    {
+        AppendMenu( hMenu, MF_GRAYED | MF_STRING,
+                    MenuDummy_Event + i, _T("Empty") );
+    }
+}
+
+/*****************************************************************************
+ * Private methods.
+ *****************************************************************************/
+void CreateMenuItem( intf_thread_t *p_intf, vector<MenuItemExt*> *_p_menuList,
+                     HMENU hMenu, char *psz_var, vlc_object_t *p_object,
+                     int *pi_item_id )
+{
+    MenuItemExt *pMenuItemExt;
+    HMENU hMenuItem;
+    vlc_value_t val, text;
+    int i_type;
+
+    /* Check the type of the object variable */
+    i_type = var_Type( p_object, psz_var );
+
+    switch( i_type & VLC_VAR_TYPE )
+    {
+    case VLC_VAR_VOID:
+    case VLC_VAR_BOOL:
+    case VLC_VAR_VARIABLE:
+    case VLC_VAR_STRING:
+    case VLC_VAR_INTEGER:
+    case VLC_VAR_FLOAT:
+        break;
+    default:
+        /* Variable doesn't exist or isn't handled */
+        return;
+    }
+
+    /* Make sure we want to display the variable */
+    if( i_type & VLC_VAR_HASCHOICE )
+    {
+        var_Change( p_object, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL );
+        if( val.i_int == 0 ) return;
+        if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 )
+            return;
+    }
+
+    /* Get the descriptive name of the variable */
+    var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL );
+
+    var_Get( p_object, psz_var, &val );
+
+    if( i_type & VLC_VAR_HASCHOICE )
+    {
+        hMenuItem = CreateChoicesMenu( p_intf, _p_menuList, psz_var,
+                                       p_object, pi_item_id );
+        AppendMenu( hMenu, MF_STRING | MF_POPUP, (UINT)hMenuItem,
+                    _FROMMB(text.psz_string ? text.psz_string : psz_var) );
+        if( text.psz_string ) free( text.psz_string );
+        return;
+    }
+
+    switch( i_type & VLC_VAR_TYPE )
+    {
+    case VLC_VAR_VOID:
+        AppendMenu( hMenu, MF_STRING , ++(*pi_item_id),
+                    _FROMMB(text.psz_string ? text.psz_string : psz_var) );
+        pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var,
+                                        p_object->i_object_id, val, i_type );
+        _p_menuList->push_back( pMenuItemExt );
+        break;
+
+    case VLC_VAR_BOOL:
+        val.b_bool = !val.b_bool;
+        AppendMenu( hMenu, MF_STRING | MF_CHECKED, ++(*pi_item_id),
+                    _FROMMB(text.psz_string ? text.psz_string : psz_var) );
+        pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var,
+                                        p_object->i_object_id, val, i_type );
+        _p_menuList->push_back( pMenuItemExt );
+        CheckMenuItem( hMenu, *pi_item_id ,
+                       ( val.b_bool ? MF_UNCHECKED : MF_CHECKED ) |
+                       MF_BYCOMMAND ); 
+        break;
+
+    default:
+        if( text.psz_string ) free( text.psz_string );
+        return;
+    }
+
+    if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
+    if( text.psz_string ) free( text.psz_string );
+}
+
+HMENU CreateChoicesMenu( intf_thread_t *p_intf,
+                         vector<MenuItemExt*> *_p_menuList, char *psz_var, 
+                         vlc_object_t *p_object, int *pi_item_id )
+{
+    MenuItemExt *pMenuItemExt;
+    vlc_value_t val, val_list, text_list;
+    int i_type, i;
+    HMENU hSubMenu = CreatePopupMenu();
+
+    /* Check the type of the object variable */
+    i_type = var_Type( p_object, psz_var );
+
+    /* Make sure we want to display the variable */
+    if( i_type & VLC_VAR_HASCHOICE )
+    {
+        var_Change( p_object, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL );
+        if( val.i_int == 0 ) return NULL;
+        if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 )
+            return NULL;
+    }
+    else
+    {
+        return NULL;
+    }
+
+    switch( i_type & VLC_VAR_TYPE )
+    {
+    case VLC_VAR_VOID:
+    case VLC_VAR_BOOL:
+    case VLC_VAR_VARIABLE:
+    case VLC_VAR_STRING:
+    case VLC_VAR_INTEGER:
+        break;
+    default:
+        /* Variable doesn't exist or isn't handled */
+        return NULL;
+    }
+
+    if( var_Get( p_object, psz_var, &val ) < 0 ) return NULL;
+
+    if( var_Change( p_object, psz_var, VLC_VAR_GETLIST,
+                    &val_list, &text_list ) < 0 )
+    {
+        if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
+        return NULL;
+    }
+
+    for( i = 0; i < val_list.p_list->i_count; i++ )
+    {
+        vlc_value_t another_val;
+        HMENU hMenuItem;
+        char *psz_tmp;
+
+        switch( i_type & VLC_VAR_TYPE )
+        {
+        case VLC_VAR_VARIABLE:
+            hMenuItem = CreateChoicesMenu( p_intf, _p_menuList,
+              val_list.p_list->p_values[i].psz_string, p_object, pi_item_id );
+            AppendMenu( hSubMenu, MF_STRING | MF_POPUP, (UINT)hMenuItem,
+                        _FROMMB(text_list.p_list->p_values[i].psz_string ?
+                          text_list.p_list->p_values[i].psz_string :
+                          val_list.p_list->p_values[i].psz_string) );
+            break;
+
+        case VLC_VAR_STRING:
+            another_val.psz_string =
+                strdup(val_list.p_list->p_values[i].psz_string);
+            AppendMenu( hSubMenu, MF_STRING, ++(*pi_item_id),
+                        _FROMMB(text_list.p_list->p_values[i].psz_string ?
+                          text_list.p_list->p_values[i].psz_string :
+                          val_list.p_list->p_values[i].psz_string) );
+            pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var,
+                          p_object->i_object_id, another_val, i_type );
+            _p_menuList->push_back( pMenuItemExt );
+
+            if( !(i_type & VLC_VAR_ISCOMMAND) && val.psz_string &&
+                !strcmp( val.psz_string,
+                         val_list.p_list->p_values[i].psz_string ) )
+              CheckMenuItem( hSubMenu, *pi_item_id, MF_CHECKED | MF_BYCOMMAND);
+            break;
+
+        case VLC_VAR_INTEGER:
+            asprintf( &psz_tmp, "%d", val_list.p_list->p_values[i].i_int );
+            AppendMenu( hSubMenu, MF_STRING, ++(*pi_item_id),
+                        _FROMMB(text_list.p_list->p_values[i].psz_string ?
+                          text_list.p_list->p_values[i].psz_string : psz_tmp));
+            pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var,
+                p_object->i_object_id, val_list.p_list->p_values[i], i_type );
+            _p_menuList->push_back( pMenuItemExt );
+
+            if( val_list.p_list->p_values[i].i_int == val.i_int )
+              CheckMenuItem( hSubMenu, *pi_item_id, MF_CHECKED | MF_BYCOMMAND);
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    /* Clean up everything */
+    if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
+    var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list, &text_list );
+
+    return hSubMenu;
+}
+
+int wce_GetMenuItemCount(HMENU hMenu)
+{
+    const int MAX_NUM_ITEMS = 256;
+    int iPos, iCount;
+
+    MENUITEMINFO mii;
+    memset( (char *)&mii, 0, sizeof(MENUITEMINFO) );
+    mii.cbSize = sizeof(MENUITEMINFO);
+
+    iCount = 0;
+    for( iPos = 0; iPos < MAX_NUM_ITEMS; iPos++ )
+    {
+        if( !GetMenuItemInfo(hMenu, (UINT)iPos, TRUE, &mii) ) break;
+        iCount++;
+    }
+
+    return iCount;
+}
+
+void OnMenuEvent( intf_thread_t *p_intf, int id )
+{
+    MenuItemExt *p_menuitemext = NULL;
+    vector<MenuItemExt*>::iterator iter;
+
+    for( iter = p_intf->p_sys->p_settings_menu->begin();
+         iter != p_intf->p_sys->p_settings_menu->end(); iter++ )
+        if( (*iter)->id == id )
+        {
+            p_menuitemext = *iter;
+            break;
+        }
+    for( iter = p_intf->p_sys->p_audio_menu->begin();
+         iter != p_intf->p_sys->p_audio_menu->end(); iter++ ) 
+        if( (*iter)->id == id )
+        {
+            p_menuitemext = *iter;
+            break;
+        }
+    for( iter = p_intf->p_sys->p_video_menu->begin();
+         iter != p_intf->p_sys->p_video_menu->end(); iter++ )
+        if( (*iter)->id == id )
+        {
+            p_menuitemext = *iter;
+            break;
+        }
+    for( iter = p_intf->p_sys->p_navig_menu->begin();
+         iter != p_intf->p_sys->p_navig_menu->end(); iter++ )
+        if( (*iter)->id == id )
+        {
+            p_menuitemext = *iter;
+            break;
+        }
+
+    if( p_menuitemext )
+    {
+        vlc_object_t *p_object = (vlc_object_t *)
+            vlc_object_get( p_intf, p_menuitemext->i_object_id );
+        if( p_object == NULL ) return;
+
+        var_Set( p_object, p_menuitemext->psz_var, p_menuitemext->val );
+        int i_type = var_Type( p_object, p_menuitemext->psz_var );
+        switch( i_type & VLC_VAR_TYPE )
+        {
+        case VLC_VAR_VOID:
+        case VLC_VAR_BOOL:
+        case VLC_VAR_VARIABLE:
+        case VLC_VAR_STRING:
+        case VLC_VAR_INTEGER:
+            break;
+        default:
+            /* Variable doesn't exist or isn't handled */
+            return;
+        }
+
+        vlc_object_release( p_object );
+    }
+}
+
+/*****************************************************************************
+ * A small helper class which encapsulate wxMenuitem with some other useful
+ * things.
+ *****************************************************************************/
+MenuItemExt::MenuItemExt( intf_thread_t *p_intf, int _id, char *_psz_var,
+                          int _i_object_id, vlc_value_t _val, int _i_val_type )
+{
+    /* Initializations */
+    id = _id;
+    p_intf = p_intf;
+    psz_var = strdup( _psz_var );
+    i_val_type = _i_val_type;
+    i_object_id = _i_object_id;
+    val = _val;
+};
+
+MenuItemExt::~MenuItemExt()
+{
+    if( psz_var ) free( psz_var );
+    if( ((i_val_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
+        && val.psz_string ) free( val.psz_string );
+};
diff --git a/modules/gui/wince/messages.cpp b/modules/gui/wince/messages.cpp
new file mode 100644 (file)
index 0000000..3e4e863
--- /dev/null
@@ -0,0 +1,254 @@
+/*****************************************************************************
+ * messages.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <string.h>
+
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <winuser.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <commdlg.h>
+
+#include "wince.h"
+
+#ifndef NMAXFILE
+#define NMAXFILE 512 // at least 256
+#endif
+
+#ifndef TEXTMAXBUF
+#define TEXTMAXBUF 512 // at least 500
+#endif
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+
+Messages::Messages( intf_thread_t *_p_intf, HINSTANCE _hInst )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+    hInst = _hInst;
+    hListView = NULL;
+    b_verbose = VLC_FALSE;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+
+***********************************************************************/
+LRESULT Messages::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                           PBOOL pbProcessed  )
+{
+    SHINITDLGINFO shidi;
+
+    TCHAR psz_text[TEXTMAXBUF];
+    OPENFILENAME ofn;
+    int i_dummy;
+    HANDLE fichier;
+    int nList=0;
+
+
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch (msg)
+    {
+    case WM_INITDIALOG: 
+        shidi.dwMask = SHIDIM_FLAGS;
+        shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
+            SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
+        shidi.hDlg = hwnd;
+        SHInitDialog( &shidi );
+
+        RECT rect; 
+        GetClientRect( hwnd, &rect );
+        hListView = CreateWindow( WC_LISTVIEW, NULL,
+                                  WS_VISIBLE | WS_CHILD | LVS_REPORT |
+                                  LVS_SHOWSELALWAYS | WS_VSCROLL | WS_HSCROLL |
+                                  WS_BORDER /*| LVS_NOCOLUMNHEADER */,
+                                  rect.left + 20, rect.top + 50, 
+                                  rect.right - rect.left - ( 2 * 20 ), 
+                                  rect.bottom - rect.top - 50 - 20, 
+                                  hwnd, NULL, hInst, NULL );            
+        ListView_SetExtendedListViewStyle( hListView, LVS_EX_FULLROWSELECT );
+
+        LVCOLUMN lv;
+        lv.mask = LVCF_WIDTH | LVCF_FMT | LVCF_TEXT;
+        lv.fmt = LVCFMT_LEFT ;
+        GetClientRect( hwnd, &rect );
+        lv.cx = rect.right - rect.left;
+        lv.pszText = _T("Messages");
+        lv.cchTextMax = 9;
+        ListView_InsertColumn( hListView, 0, &lv);
+
+        SetTimer( hwnd, 1, 500 /*milliseconds*/, NULL );
+
+        SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+        return lResult;
+
+    case WM_TIMER:
+        UpdateLog();
+        return lResult;
+
+    case WM_COMMAND:
+        switch( LOWORD(wp) )
+        {
+        case IDOK:
+            EndDialog( hwnd, LOWORD( wp ) );
+            return TRUE;
+
+        case IDCLEAR:
+            ListView_DeleteAllItems( hListView );
+            return TRUE;
+
+        case IDSAVEAS:  
+            memset( &(ofn), 0, sizeof(ofn) );
+            ofn.lStructSize = sizeof(ofn);
+            ofn.hwndOwner = hwnd;
+            ofn.lpstrFile = _T("");
+            ofn.nMaxFile = NMAXFILE;    
+            ofn.lpstrFilter = _T("Text (*.txt)\0*.txt\0");
+            ofn.lpstrTitle = _T("Save File As");
+            ofn.Flags = OFN_HIDEREADONLY; 
+            ofn.lpstrDefExt = _T("txt");
+
+            if( GetSaveFileName( (LPOPENFILENAME)&ofn ) )
+            {
+                fichier = CreateFile( ofn.lpstrFile, GENERIC_WRITE,
+                                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                                      NULL, CREATE_ALWAYS,
+                                      FILE_ATTRIBUTE_NORMAL, NULL );
+
+                if( fichier != INVALID_HANDLE_VALUE )
+                {
+                    int n;
+
+                    //SetFilePointer( fichier, 0, NULL, FILE_END );
+                    for( n = 0; n < ListView_GetItemCount( hListView ); n++ )
+                    {
+                        ListView_GetItemText( hListView, n, 0, psz_text,
+                                              TEXTMAXBUF );
+                        string text_out = (string)_TOMB(psz_text) + "\n";
+                        WriteFile( fichier, text_out.c_str(), text_out.size(),
+                                   (LPDWORD)&i_dummy, NULL );
+                    }
+                    FlushFileBuffers( fichier );
+                    CloseHandle(fichier);
+                }
+            }
+
+            SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+            return TRUE;
+
+        default:
+            *pbProcessed = bWasProcessed;
+            lResult = FALSE;
+            return lResult;
+        }
+
+    default:
+         // the message was not processed
+         // indicate if the base class handled it
+         *pbProcessed = bWasProcessed;
+         lResult = FALSE;
+         return lResult;
+    }
+
+    return lResult;
+}
+
+void Messages::UpdateLog()
+{
+    msg_subscription_t *p_sub = p_intf->p_sys->p_sub;
+    string debug;
+    int i_start, i_stop;
+
+    vlc_mutex_lock( p_sub->p_lock );
+    i_stop = *p_sub->pi_stop;
+    vlc_mutex_unlock( p_sub->p_lock );
+
+    if( p_sub->i_start != i_stop )
+    {
+        for( i_start = p_sub->i_start; i_start != i_stop;
+             i_start = (i_start+1) % VLC_MSG_QSIZE )
+        {
+            if( !b_verbose && VLC_MSG_ERR != p_sub->p_msg[i_start].i_type )
+                continue;
+
+            /* Append all messages to log window */
+            debug = p_sub->p_msg[i_start].psz_module;
+        
+            switch( p_sub->p_msg[i_start].i_type )
+            {
+            case VLC_MSG_INFO:
+                debug += ": ";
+                break;
+            case VLC_MSG_ERR:
+                debug += " error: ";
+                break;
+            case VLC_MSG_WARN:
+                debug += " warning: ";
+                break;
+            case VLC_MSG_DBG:
+            default:
+                debug += " debug: ";
+                break;
+            }
+
+            /* Add message */
+            debug += p_sub->p_msg[i_start].psz_msg;
+
+            LVITEM lv;
+            lv.mask = LVIF_TEXT;
+            lv.pszText = TEXT("");
+            lv.cchTextMax = 1;
+            lv.iSubItem = 0;
+            lv.iItem = ListView_GetItemCount( hListView );
+            ListView_InsertItem( hListView, &lv );
+            ListView_SetItemText( hListView, lv.iItem, 0,
+                                  _FROMMB(debug.c_str()) );
+        }
+
+        vlc_mutex_lock( p_sub->p_lock );
+        p_sub->i_start = i_start;
+        vlc_mutex_unlock( p_sub->p_lock );
+    }
+}
diff --git a/modules/gui/wince/open.cpp b/modules/gui/wince/open.cpp
new file mode 100644 (file)
index 0000000..dba02a1
--- /dev/null
@@ -0,0 +1,957 @@
+/*****************************************************************************
+ * open.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <string.h>
+
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <winuser.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <commdlg.h>
+
+#include "wince.h"
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/* IDs for the controls and the menu commands */
+enum
+{
+    Notebook_Event = 1000,
+    MRL_Event,
+
+    FileBrowse_Event,
+    FileName_Event,
+
+    DiscType_Event,
+    DiscDevice_Event,
+    DiscTitle_Event,
+    DiscChapter_Event,
+
+    NetType_Event,
+    NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
+    NetPort1_Event, NetPort2_Event, NetPort3_Event,
+    NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
+
+    SubsFileEnable_Event,
+    SubsFileSettings_Event,
+};
+
+/*****************************************************************************
+ * AutoBuiltPanel.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+OpenDialog::OpenDialog( intf_thread_t *_p_intf, HINSTANCE _hInst,
+                        int _i_access_method, int _i_arg, int _i_method )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+    hInst = _hInst;
+    i_current_access_method = _i_access_method;
+    i_open_arg = _i_arg;
+    i_method = _i_method;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT OpenDialog::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                             PBOOL pbProcessed  )
+{
+    SHINITDLGINFO shidi;
+    SHMENUBARINFO mbi;
+    INITCOMMONCONTROLSEX  iccex;  // INITCOMMONCONTROLSEX structure    
+    RECT rcClient;
+    TC_ITEM tcItem;
+
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    case WM_INITDIALOG: 
+        shidi.dwMask = SHIDIM_FLAGS;
+        shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
+            SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
+        shidi.hDlg = hwnd;
+        SHInitDialog( &shidi );
+
+        //Create the menubar.
+        memset( &mbi, 0, sizeof(SHMENUBARINFO) );
+        mbi.cbSize     = sizeof(SHMENUBARINFO);
+        mbi.hwndParent = hwnd;
+        mbi.nToolBarId = IDR_DUMMYMENU;
+        mbi.hInstRes   = hInst;
+        mbi.nBmpId     = 0;
+        mbi.cBmpImages = 0;  
+
+        if( !SHCreateMenuBar( &mbi ) )
+        {
+            MessageBox( hwnd, _T("SHCreateMenuBar failed"),
+                        _T("Error"), MB_OK );
+            //return -1;
+        }
+
+        hwndCB = mbi.hwndMB;
+
+        // Get the client area rect to put the panels in
+        GetClientRect( hwnd, &rcClient );
+
+        /* Create MRL combobox */
+        mrl_box = CreateWindow( _T("STATIC"),
+                                _FROMMB(_("Media Resource Locator (MRL)")),
+                                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                                5, 10, rcClient.right, 15, hwnd, 0, hInst, 0 );
+
+        mrl_label = CreateWindow( _T("STATIC"), _FROMMB(_("Open:")),
+                                  WS_CHILD | WS_VISIBLE | SS_LEFT,
+                                  5, 10 + 15 + 10, 40, 15, hwnd, 0, hInst, 0 );
+
+        mrl_combo = CreateWindow( _T("COMBOBOX"), _T(""),
+                                  WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL |
+                                  CBS_SORT | WS_VSCROLL, 45, 10 + 15 + 10 - 3,
+                                  rcClient.right - 50 - 5, 5*15 + 6, hwnd,
+                                  0, hInst, 0 );
+
+        // No tooltips for ComboBox
+
+        label = CreateWindow( _T("STATIC"),
+                              _FROMMB(_("Alternatively, you can build an MRL "
+                                       "using one of the following predefined "
+                                       "targets:" )),
+                              WS_CHILD | WS_VISIBLE | SS_LEFT,
+                              5, 10 + 2*(15 + 10), rcClient.right - 2*5, 2*15,
+                              hwnd, 0, hInst, 0 );
+
+        /* Create notebook */
+        iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
+        iccex.dwSize = ICC_TAB_CLASSES;
+        InitCommonControlsEx (&iccex);
+
+        notebook = CreateWindowEx( 0, WC_TABCONTROL, NULL,
+            WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE,
+            5, 10 + 4*15 + 2*10, rcClient.right - 2*5,
+            rcClient.bottom - MENU_HEIGHT - 15 - 10 - 10 - (10 + 4*15 + 2*10),
+            hwnd, NULL, hInst, NULL );
+
+        tcItem.mask = TCIF_TEXT;
+        tcItem.pszText = _T("File");
+        TabCtrl_InsertItem( notebook, 0, &tcItem );
+        tcItem.pszText = _T("Network");
+        TabCtrl_InsertItem( notebook, 1, &tcItem );
+
+        switch( i_current_access_method )
+        {
+        case FILE_ACCESS:
+            TabCtrl_SetCurSel( notebook, 0 );
+            break;
+        case NET_ACCESS:
+            TabCtrl_SetCurSel( notebook, 1 );
+            break;
+        }
+
+        FilePanel( hwnd );
+        NetPanel( hwnd );
+
+        OnPageChange();
+
+        return lResult;
+
+    case WM_COMMAND:
+        if( LOWORD(wp) == IDOK )
+        {
+            OnOk();
+            EndDialog( hwnd, LOWORD( wp ) );
+            return TRUE;
+        }
+        if( HIWORD(wp) == BN_CLICKED )
+        {
+            if( (HWND)lp == net_radios[0] )
+            {
+                OnNetTypeChange( NetRadio1_Event );
+                return TRUE;
+            } else if( (HWND)lp == net_radios[1] )
+            {
+                OnNetTypeChange( NetRadio2_Event );
+                return TRUE;
+            } else if( (HWND)lp == net_radios[2] )
+            {
+                OnNetTypeChange( NetRadio3_Event );
+                return TRUE;
+            } else if( (HWND)lp == net_radios[3] )
+            {
+                OnNetTypeChange( NetRadio4_Event );
+                return TRUE;
+            } else if( (HWND)lp == subsfile_checkbox )
+            {
+                OnSubsFileEnable();
+                return TRUE;
+            } else if( (HWND)lp == subsfile_button )
+            {
+                OnSubsFileSettings( hwnd );
+                return TRUE;
+            } else if( (HWND)lp == browse_button )
+            {
+                SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+                OnFileBrowse();
+                return TRUE;
+            } 
+        }
+        if( HIWORD(wp) == EN_CHANGE )
+        {
+            if( (HWND)lp == net_addrs[1] )
+            {
+                OnNetPanelChange( NetAddr2_Event );
+            } else if( (HWND)lp == net_addrs[2] )
+            {
+                OnNetPanelChange( NetAddr3_Event );
+            } else if( (HWND)lp == net_addrs[3] )
+            {
+                OnNetPanelChange( NetAddr4_Event );
+            } else if( (HWND)lp == net_ports[0] )
+            {
+                OnNetPanelChange( NetPort1_Event );
+            } else if( (HWND)lp == net_ports[1] )
+            {
+                OnNetPanelChange( NetPort2_Event );
+            }
+        }
+        if( HIWORD(wp) == CBN_EDITUPDATE )
+        {
+            if ((HWND)lp == file_combo)
+            {
+                OnFilePanelChange();
+            }
+        }
+
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+
+    case WM_NOTIFY:
+        if( (((NMHDR *)lp)->code) == TCN_SELCHANGE )
+        {
+            OnPageChange();
+            return TRUE;
+        }
+
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+
+    default:
+        // the message was not processed
+        // indicate if the base class handled it
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+    }
+
+    return lResult;
+}
+
+/*****************************************************************************
+ * Private methods.
+ *****************************************************************************/
+void OpenDialog::FilePanel( HWND hwnd )
+{
+    RECT rc;    
+    GetWindowRect( notebook, &rc);
+
+    /* Create browse file line */
+    file_combo = CreateWindow( _T("COMBOBOX"), _T(""),
+        WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL,
+        rc.left + 10, rc.top + 10 - 3, rc.right - 10 - (rc.left + 10),
+        5*15 + 6, hwnd, NULL, hInst, NULL );
+
+    browse_button = CreateWindow( _T("BUTTON"), _T("Browse..."),
+        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+        rc.left + 10, rc.top + 10 + 15 + 10 - 3, 80, 15 + 6,
+        hwnd, NULL, hInst, NULL );
+
+    /* Create Subtitles File checkox */
+    subsfile_checkbox = CreateWindow( _T("BUTTON"), _T("Subtitle options"),
+        WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+        rc.left + 10, rc.top + 10 + 2*(15 + 10), 15, 15,
+        hwnd, NULL, hInst, NULL );
+    SendMessage( subsfile_checkbox, BM_SETCHECK, BST_UNCHECKED, 0 );
+
+    subsfile_label = CreateWindow( _T("STATIC"), _T("Subtitle options"),
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                rc.left + 10 + 15 + 10, rc.top + 10 + 2*(15 + 10), 100, 15,
+                hwnd, NULL, hInst, NULL);
+
+    subsfile_button = CreateWindow( _T("BUTTON"), _T("Settings..."),
+                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
+                rc.right - 80 - 10, rc.top + 10 + 2*(15 + 10) - 3, 80, 15 + 6,
+                hwnd, NULL, hInst, NULL );
+
+    char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
+    if( psz_subsfile && *psz_subsfile )
+    {
+        SendMessage( subsfile_checkbox, BM_SETCHECK, BST_CHECKED, 0 );
+        EnableWindow( subsfile_button, TRUE );
+        string sz_subsfile = "sub-file=";
+        sz_subsfile += psz_subsfile;
+        subsfile_mrl.push_back( sz_subsfile );
+    }
+    if( psz_subsfile ) free( psz_subsfile );
+}
+
+void OpenDialog::NetPanel( HWND hwnd )
+{  
+    INITCOMMONCONTROLSEX ic;
+    LPWSTR wUnicode;
+
+    struct net_type
+    {
+        LPWSTR szAnsi;
+        int length;
+    };
+
+    static struct net_type net_type_array[] =
+    {
+        { _T("UDP/RTP"), 82 },
+        { _T("UDP/RTP Multicast"), 140 },
+        { _T("HTTP/FTP/MMS"), 90 },
+        { _T("RTSP"), 30 }
+    };
+
+    RECT rc;    
+    GetWindowRect( notebook, &rc);
+
+    /* UDP/RTP row */
+    net_radios[0] = CreateWindow( _T("BUTTON"), net_type_array[0].szAnsi,
+                WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+                rc.left + 5, rc.top + 10, 15, 15,
+                hwnd, NULL, hInst, NULL);
+        
+    net_label[0] = CreateWindow( _T("STATIC"), net_type_array[0].szAnsi,
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                rc.left + 5 + 15 + 5, rc.top + 10, net_type_array[0].length, 15,
+                hwnd, NULL, hInst, NULL);
+
+    i_net_ports[0] = config_GetInt( p_intf, "server-port" );
+        
+    net_port_label[0] = CreateWindow( _T("STATIC"), _T("Port"),
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                rc.left + 5 , rc.top + 10 + 2*(15 + 10), 30, 15,
+                hwnd, NULL, hInst, NULL);
+        
+    wUnicode = new WCHAR[80];
+    swprintf( wUnicode, _T("%d"), i_net_ports[0] );
+    net_ports[0] = CreateWindow( _T("EDIT"), wUnicode,
+    WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+    rc.left + 5 + 30 + 5, rc.top + 10 + 2*(15 + 10) - 3,
+    rc.right - 5 - (rc.left + 5 + 30 + 5), 15 + 6, hwnd, NULL, hInst, NULL );
+    free( wUnicode );
+
+    ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    ic.dwICC = ICC_UPDOWN_CLASS;
+    InitCommonControlsEx(&ic);
+        
+    hUpdown[0] = CreateUpDownControl(
+                WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ALIGNRIGHT |
+                UDS_SETBUDDYINT | UDS_NOTHOUSANDS,
+                0, 0, 0, 0, hwnd, NULL, hInst,
+                net_ports[0], 16000, 0, i_net_ports[0]);
+
+    /* UDP/RTP Multicast row */
+    net_radios[1] = CreateWindow( _T("BUTTON"), net_type_array[1].szAnsi,
+                WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+                rc.left + 5, rc.top + 10 + 15 + 10, 15, 15,
+                hwnd, NULL, hInst, NULL);
+
+    net_label[1] = CreateWindow( _T("STATIC"), net_type_array[1].szAnsi,
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                rc.left + 5 + 15 + 5, rc.top + 10 + 15 + 10,
+                net_type_array[1].length, 15, hwnd, NULL, hInst, NULL );
+
+    net_addrs_label[1] = CreateWindow( _T("STATIC"), _T("Address"),
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                rc.left + 5 , rc.top + 10 + 2*(15 + 10), 50, 15,
+                hwnd, NULL, hInst, NULL);
+
+    net_addrs[1] = CreateWindow( _T("EDIT"), _T(""),
+                WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+                rc.left + 5 + 50 + 5, rc.top + 10 + 2*(15 + 10) - 3,
+                rc.right - 5 - (rc.left + 5 + 50 + 5), 15 + 6,
+                hwnd, NULL, hInst, NULL);
+
+    net_port_label[1] = CreateWindow( _T("STATIC"), _T("Port"),
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                rc.left + 5 , rc.top + 10 + 3*(15 + 10), 30, 15,
+                hwnd, NULL, hInst, NULL);
+
+    i_net_ports[1] = i_net_ports[0];
+
+    wUnicode = new WCHAR[80];
+    swprintf( wUnicode, _T("%d"), i_net_ports[1] );
+    net_ports[1] = CreateWindow( _T("EDIT"), wUnicode,
+                WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+                rc.left + 5 + 30 + 5, rc.top + 10 + 3*(15 + 10) - 3,
+                rc.right - 5 -(rc.left + 5 + 30 + 5), 15 + 6,
+                hwnd, NULL, hInst, NULL );
+    free( wUnicode );
+
+    ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    ic.dwICC = ICC_UPDOWN_CLASS;
+    InitCommonControlsEx(&ic);
+
+    hUpdown[1] = CreateUpDownControl( WS_CHILD | WS_VISIBLE | WS_BORDER |
+        UDS_ALIGNRIGHT | UDS_SETBUDDYINT | UDS_NOTHOUSANDS,
+        0, 0, 0, 0, hwnd, NULL, hInst,
+        net_ports[1], 16000, 0, i_net_ports[1] );
+
+    /* HTTP and RTSP rows */
+    net_radios[2] = CreateWindow( _T("BUTTON"), net_type_array[2].szAnsi,
+        WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+        rc.left + 5 + 15 + 5 + net_type_array[0].length + 5,
+        rc.top + 10, 15, 15, hwnd, NULL, hInst, NULL );
+        
+    net_label[2] = CreateWindow( _T("STATIC"), net_type_array[2].szAnsi,
+        WS_CHILD | WS_VISIBLE | SS_LEFT,
+        rc.left + 5 + 15 + 5 + net_type_array[0].length + 5 + 15 + 5,
+        rc.top + 10, net_type_array[2].length, 15,
+        hwnd, NULL, hInst, NULL );
+
+    net_addrs_label[2] = CreateWindow( _T("STATIC"), _T("URL"),
+        WS_CHILD | WS_VISIBLE | SS_LEFT,
+        rc.left + 5 , rc.top + 10 + 2*(15 + 10), 30, 15,
+        hwnd, NULL, hInst, NULL );
+
+    net_addrs[2] = CreateWindow( _T("EDIT"), _T(""),
+        WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+        rc.left + 5 + 30 + 5, rc.top + 10 + 2*(15 + 10) - 3,
+        rc.right - 5 - (rc.left + 5 + 30 + 5), 15 + 6,
+        hwnd, NULL, hInst, NULL);
+
+    net_radios[3] = CreateWindow( _T("BUTTON"), net_type_array[3].szAnsi,
+        WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+        rc.left + 5 + 15 + 5 + net_type_array[1].length + 5,
+        rc.top + 10 + 15 + 10, 15, 15, hwnd, NULL, hInst, NULL );
+
+    net_label[3] = CreateWindow( _T("STATIC"), net_type_array[3].szAnsi,
+        WS_CHILD | WS_VISIBLE | SS_LEFT,
+        rc.left + 5 + 15 + 5 + net_type_array[1].length + 5 + 15 + 5,
+        rc.top + 10 + 15 + 10, net_type_array[3].length, 15,
+        hwnd, NULL, hInst, NULL );
+
+    net_addrs_label[3] = CreateWindow( _T("STATIC"), _T("URL"),
+        WS_CHILD | WS_VISIBLE | SS_LEFT,
+        rc.left + 5 , rc.top + 10 + 2*(15 + 10), 30, 15,
+        hwnd, NULL, hInst, NULL );
+
+    net_addrs[3] = CreateWindow( _T("EDIT"), _T("rtsp://"),
+        WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+        rc.left + 5 + 30 + 5, rc.top + 10 + 2*(15 + 10) - 3,
+        rc.right - 5 - (rc.left + 5 + 30 + 5), 15 + 6,
+        hwnd, NULL, hInst, NULL );
+
+    SendMessage( net_radios[0], BM_SETCHECK, BST_CHECKED, 0 );
+}
+
+void OpenDialog::UpdateMRL()
+{
+    UpdateMRL( i_current_access_method );
+}
+
+void OpenDialog::UpdateMRL( int i_access_method )
+{
+    string demux, mrltemp;
+
+    int size;
+    BOOL bTemp;
+    LPSTR szAnsi;
+    LPWSTR wUnicode;
+
+    i_current_access_method = i_access_method;
+
+    switch( i_access_method )
+    {
+    case FILE_ACCESS:
+        //mrltemp = wxT("file") + demux + wxT(":") + file_combo->GetValue();
+        size = GetWindowTextLength( file_combo ) + 1;
+        wUnicode = new WCHAR[ size ];
+        GetWindowText( file_combo, wUnicode, size );
+        mrltemp = _TOMB(wUnicode);
+        break;
+    case NET_ACCESS:
+        switch( i_net_type )
+        {
+        case 0:
+            mrltemp = "udp" + demux + "://";
+            if( i_net_ports[0] !=
+                config_GetInt( p_intf, "server-port" ) )
+            {
+                szAnsi = new char[50];
+                sprintf( szAnsi, "@:%d", i_net_ports[0] );
+                mrltemp += szAnsi;
+                delete [] szAnsi;
+            }
+            break;
+
+        case 1:
+            mrltemp = "udp" + demux + "://@";
+            size = Edit_GetTextLength( net_addrs[1] );  
+            wUnicode = new WCHAR[size + 1]; //Add 1 for the NULL
+            Edit_GetText( net_addrs[1], wUnicode, size + 1);
+            mrltemp += _TOMB(wUnicode);
+            delete [] wUnicode;
+            if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
+            {
+                szAnsi = new char[50];
+                sprintf( szAnsi, ":%d", i_net_ports[1] );
+                mrltemp += szAnsi;
+                delete [] szAnsi;
+            }
+            break;
+
+        case 2:
+            /* http access */
+            size = Edit_GetTextLength( net_addrs[2] );  
+            wUnicode = new WCHAR[size + 1]; //Add 1 for the NULL
+            Edit_GetText( net_addrs[2], wUnicode, size + 1);
+            size = WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, NULL, 0, NULL, &bTemp );
+            szAnsi = new char[size];
+            WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, szAnsi, size, NULL, &bTemp );
+            free( wUnicode );
+            if( !strstr( szAnsi, "http://" ) )
+            {
+                mrltemp = "http" + demux + "://";
+            }
+            mrltemp += szAnsi;
+            free( szAnsi );
+            break;
+
+        case 3:
+            /* RTSP access */
+            size = Edit_GetTextLength( net_addrs[3] );  
+            wUnicode = new WCHAR[size + 1]; //Add 1 for the NULL
+            Edit_GetText( net_addrs[3], wUnicode, size + 1);
+            size = WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, NULL, 0, NULL, &bTemp );
+            szAnsi = new char[size];
+            WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, szAnsi, size, NULL, &bTemp );
+            free( wUnicode );
+            if( !strstr( szAnsi, "rtsp://" ) )
+            {
+                mrltemp = "rtsp" + demux + "://";
+            }
+            mrltemp += szAnsi;
+            free( szAnsi );
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+    SetWindowText( mrl_combo, _FROMMB(mrltemp.c_str()) );
+}
+
+void OpenDialog::OnPageChange()
+{
+    if( TabCtrl_GetCurSel( notebook ) == 0 )
+    {
+        for( int i=0; i<4; i++ )
+        {
+            SetWindowPos( net_radios[i], HWND_BOTTOM, 0, 0, 0, 0,
+                          SWP_NOMOVE | SWP_NOSIZE );
+            SetWindowPos( net_label[i], HWND_BOTTOM, 0, 0, 0, 0,
+                          SWP_NOMOVE | SWP_NOSIZE );
+        }
+        DisableNETCtrl();
+
+        SetWindowPos( file_combo, HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( browse_button, HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( subsfile_checkbox, HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( subsfile_label, HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( subsfile_button, HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+
+        i_current_access_method = FILE_ACCESS;
+    }
+    else if ( TabCtrl_GetCurSel( notebook ) == 1 )
+    {
+        SetWindowPos( file_combo, HWND_BOTTOM, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( browse_button, HWND_BOTTOM, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( subsfile_checkbox, HWND_BOTTOM, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( subsfile_label, HWND_BOTTOM, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( subsfile_button, HWND_BOTTOM, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+
+        for( int i=0; i<4; i++ )
+        {
+            SetWindowPos( net_radios[i], HWND_TOP, 0, 0, 0, 0,
+                          SWP_NOMOVE | SWP_NOSIZE );
+            SendMessage( net_radios[i], BM_SETCHECK, BST_UNCHECKED, 0 );
+            SetWindowPos( net_label[i], HWND_TOP, 0, 0, 0, 0,
+                          SWP_NOMOVE | SWP_NOSIZE );
+        }
+        SetWindowPos( net_port_label[0], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( net_ports[0], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( hUpdown[0], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+
+        SendMessage( net_radios[0], BM_SETCHECK, BST_CHECKED, 0 );
+
+        i_current_access_method = NET_ACCESS;
+    }
+
+    UpdateMRL();
+}
+
+void OpenDialog::OnOk()
+{
+    int size;
+    LPWSTR wUnicode;
+
+    size = GetWindowTextLength( mrl_combo ) + 1;
+    wUnicode = new WCHAR[ size ];
+    GetWindowText( mrl_combo, wUnicode, size ); // a remplacer par ComboBox_GetText( mrl_combo, wUnicode, size )
+    mrl = SeparateEntries( wUnicode );
+    ComboBox_AddString( mrl_combo, wUnicode );
+    if( ComboBox_GetCount( mrl_combo ) > 10 ) 
+        ComboBox_DeleteString( mrl_combo, 0 );
+    ComboBox_SetCurSel( mrl_combo, ComboBox_GetCount( mrl_combo ) - 1 );
+    delete [] wUnicode;
+
+    /* Update the playlist */
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    for( int i = 0; i < (int)mrl.size(); i++ )
+    {
+        vlc_bool_t b_start = !i && i_open_arg;
+        playlist_item_t *p_item =
+            playlist_ItemNew( p_intf, (const char*)mrl[i].c_str(),
+                              (const char *)mrl[i].c_str() );
+
+        /* Insert options */
+        while( i + 1 < (int)mrl.size() &&
+               ((const char *)mrl[i + 1].c_str())[0] == ':' )
+        {
+            playlist_ItemAddOption( p_item, mrl[i + 1].c_str() );
+            i++;
+        }
+
+        /* Get the options from the subtitles dialog */
+        if( (SendMessage( subsfile_checkbox, BM_GETCHECK, 0, 0 ) & BST_CHECKED)
+            && subsfile_mrl.size() )
+        {
+            for( int j = 0; j < (int)subsfile_mrl.size(); j++ )
+            {
+                playlist_ItemAddOption( p_item, subsfile_mrl[j].c_str() );
+            }
+        }
+
+        int i_id = playlist_AddItem( p_playlist, p_item,
+                                     PLAYLIST_APPEND, PLAYLIST_END );
+
+        if( b_start )
+        {
+            playlist_Control( p_playlist, PLAYLIST_ITEMPLAY , p_item );
+        }
+    }
+
+    //TogglePlayButton( PLAYING_S );
+
+    vlc_object_release( p_playlist );
+}
+
+/*****************************************************************************
+ * File panel event methods.
+ *****************************************************************************/
+void OpenDialog::OnFilePanelChange()
+{
+    UpdateMRL( FILE_ACCESS );
+}
+
+void OpenDialog::OnFileBrowse()
+{       
+    OPENFILENAME ofn;
+    TCHAR DateiName[80+1] = _T("\0");
+    static TCHAR szFilter[] = _T("All (*.*)\0*.*\0");
+    LPSTR psz_filename;
+    BOOL bTemp;
+    string path;
+    int size;
+
+    memset(&ofn, 0, sizeof(OPENFILENAME));
+    ofn.lStructSize = sizeof (OPENFILENAME);
+    ofn.hwndOwner = NULL;
+    ofn.hInstance = hInst;
+    ofn.lpstrFilter = szFilter;
+    ofn.lpstrCustomFilter = NULL;
+    ofn.nMaxCustFilter = 0;
+    ofn.nFilterIndex = 1;     
+    ofn.lpstrFile = (LPTSTR) DateiName; 
+    ofn.nMaxFile = 80;
+    ofn.lpstrFileTitle = NULL; 
+    ofn.nMaxFileTitle = 40;
+    ofn.lpstrInitialDir = NULL;
+    ofn.lpstrTitle = _T("Open File");
+    ofn.Flags = NULL; 
+    ofn.nFileOffset = 0;
+    ofn.nFileExtension = 0;
+    ofn.lpstrDefExt = NULL;
+    ofn.lCustData = 0L;
+    ofn.lpfnHook = NULL;
+    ofn.lpTemplateName = NULL;
+    if( GetOpenFileName((LPOPENFILENAME) &ofn) )
+    {
+        size = WideCharToMultiByte( CP_ACP, 0, ofn.lpstrFile, -1, NULL,
+                                    0, NULL, &bTemp );
+        psz_filename = ( char * )malloc( size );
+        WideCharToMultiByte( CP_ACP, 0, ofn.lpstrFile, -1, psz_filename,
+                             size, NULL, &bTemp );
+
+        if( strchr( psz_filename, ' ' ) )
+        {
+            path = "\"";
+            path += psz_filename;
+            path += "\"";
+        }
+        else
+            path = psz_filename;
+
+        SetWindowText( file_combo, _FROMMB(path.c_str()) );
+        ComboBox_AddString( file_combo, _FROMMB(path.c_str()) );
+        if( ComboBox_GetCount( file_combo ) > 10 ) 
+            ComboBox_DeleteString( file_combo, 0 );
+
+        UpdateMRL( FILE_ACCESS );
+    }
+}
+
+/*****************************************************************************
+ * Net panel event methods.
+ *****************************************************************************/
+void OpenDialog::OnNetPanelChange( int event )
+{
+    int port;
+    int size;
+    LPWSTR wUnicode;
+
+    if( event >= NetPort1_Event && event <= NetPort2_Event )
+    {
+        size = Edit_GetTextLength( net_ports[event - NetPort1_Event] );
+        wUnicode = new WCHAR[size + 1]; //Add 1 for the NULL
+        Edit_GetText( net_ports[event - NetPort1_Event], wUnicode, size + 1);
+        swscanf( wUnicode, _T("%d"), &port );
+        i_net_ports[event - NetPort1_Event] = port;
+        delete[] wUnicode;
+    }
+
+    UpdateMRL( NET_ACCESS );
+}
+
+void OpenDialog::OnNetTypeChange( int event )
+{
+    DisableNETCtrl();
+
+    i_net_type = event - NetRadio1_Event;
+
+    if( event == NetRadio1_Event )
+    {
+        SetWindowPos( net_port_label[0], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( net_ports[0], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( hUpdown[0], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+    } 
+    else if( event == NetRadio2_Event )
+    {
+        SetWindowPos( net_addrs_label[1], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( net_addrs[1], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( net_port_label[1], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( net_ports[1], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( hUpdown[1], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+    } 
+    else if( event == NetRadio3_Event )
+    {
+        SetWindowPos( net_addrs_label[2], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( net_addrs[2], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+    } 
+    else if( event == NetRadio4_Event )
+    {
+        SetWindowPos( net_addrs_label[3], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( net_addrs[3], HWND_TOP, 0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE );
+    }
+        
+    UpdateMRL( NET_ACCESS );
+}
+
+void OpenDialog::DisableNETCtrl()
+{
+        for( int i=0; i<4; i++ )
+    {
+                SetWindowPos( net_port_label[i], HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+                SetWindowPos( net_ports[i], HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+                SetWindowPos( hUpdown[i], HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+                
+                SetWindowPos( net_addrs_label[i], HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+                SetWindowPos( net_addrs[i], HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+    }
+
+    UpdateMRL( FILE_ACCESS );
+}
+
+/*****************************************************************************
+ * Subtitles file event methods.
+ *****************************************************************************/
+void OpenDialog::OnSubsFileEnable()
+{
+    EnableWindow( subsfile_button, ( SendMessage( subsfile_checkbox,
+                  BM_GETCHECK, 0, 0 ) & BST_CHECKED ) ? TRUE : FALSE );
+}
+
+void OpenDialog::OnSubsFileSettings( HWND hwnd )
+{
+
+    /* Show/hide the open dialog */
+    SubsFileDialog *subsfile_dialog = new SubsFileDialog( p_intf, hInst );
+    DialogBoxParam( hInst, (LPCTSTR)IDD_DUMMY, hwnd,
+                    (DLGPROC)subsfile_dialog->BaseWndProc,
+                    (long)subsfile_dialog );
+
+    subsfile_mrl.clear();
+
+    for( int i = 0; i < subsfile_dialog->subsfile_mrl.size(); i++ )
+        subsfile_mrl.push_back( subsfile_dialog->subsfile_mrl[i] );
+
+    delete subsfile_dialog;
+}
+
+/*****************************************************************************
+ * Utility functions.
+ *****************************************************************************/
+vector<string> SeparateEntries( LPWSTR entries )
+{
+    int length;
+    vlc_bool_t b_quotes_mode = VLC_FALSE;
+    vector<string> entries_array;
+    LPWSTR entry = new TCHAR[ wcslen(entries) + 1 ];
+
+    LPWSTR strToken = entries;
+    length = wcscspn( strToken, _T(" \t\r\n\"") );
+    swprintf( entry, _T("") );
+
+    while( strToken - entries < wcslen(entries) )
+    { 
+        wcsncat( entry, strToken, length );
+
+        wcsncat( entry, strToken + length, 1 );
+
+        if( !b_quotes_mode && strToken[length] == _T('\"') )
+        {
+            /* Enters quotes mode */
+            entry[ wcslen(entry) - 1 ] = NULL;
+            b_quotes_mode = VLC_TRUE;
+        }
+        else if( b_quotes_mode && strToken[length] == _T('\"') )
+        {
+            /* Finished the quotes mode */
+            entry[ wcslen(entry) - 1 ] = NULL;
+            if( wcscmp( entry, _T("") ) != 0 )
+            {
+                entries_array.push_back( _TOMB(entry) );
+            }
+            swprintf( entry, _T("") );
+            b_quotes_mode = VLC_FALSE;
+        }
+        else if( !b_quotes_mode && strToken[length] != _T('\"') )
+        {
+            /* we found a non-quoted standalone string */
+            if( strToken + length - entries < wcslen(entries) ||/*token.HasMoreTokens() ||*/ //FIX ME IF YOU CAN
+                strToken[length] == _T(' ') ||
+                strToken[length] == _T('\t') ||
+                strToken[length] == _T('\r') ||
+                strToken[length] == _T('\n') )
+              entry[ wcslen(entry) - 1 ]/*strToken[length]*/ = NULL;
+            if( wcscmp( entry, _T("") ) != 0 )
+            {
+                entries_array.push_back( _TOMB(entry) );
+            }
+            swprintf( entry, _T("") );
+        }
+        else
+        {;}
+
+        strToken += length + 1;
+        length = wcscspn( strToken, _T(" \t\r\n\"") );
+    }
+
+    if( wcscmp( entry, _T("") ) != 0 )
+    {
+        entries_array.push_back( _TOMB(entry) );
+    }
+
+    return entries_array;
+}
diff --git a/modules/gui/wince/playlist.cpp b/modules/gui/wince/playlist.cpp
new file mode 100644 (file)
index 0000000..0ee1553
--- /dev/null
@@ -0,0 +1,1142 @@
+/*****************************************************************************
+ * playlist.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <commdlg.h>
+
+#include <newmenu.h>
+
+#ifndef NMAXFILE
+#define NMAXFILE 512 // at least 256
+#endif
+
+#ifndef TEXTMAXBUF
+#define TEXTMAXBUF 512 // at least 500
+#endif
+
+#define LONG2POINT(l, pt)  ((pt).x = (SHORT)LOWORD(l), (pt).y = (SHORT)HIWORD(l))
+
+#include "wince.h"
+
+#include <aygshell.h>
+
+#define NUMIMAGES     11   // Number of buttons in the toolbar           
+#define IMAGEWIDTH    16   // Width of the buttons in the toolbar  
+#define IMAGEHEIGHT   16   // Height of the buttons in the toolbar  
+#define BUTTONWIDTH   0    // Width of the button images in the toolbar
+#define BUTTONHEIGHT  0    // Height of the button images in the toolbar
+#define ID_TOOLBAR    2000 // Identifier of the main tool bar
+#define dwTBFontStyle TBSTYLE_BUTTON | TBSTYLE_CHECK | TBSTYLE_GROUP // style for toolbar buttons
+
+enum      
+{
+  Infos_Event = 1000,
+  Up_Event,
+  Down_Event,
+  Random_Event,
+  Loop_Event,
+  Repeat_Event,
+  PopupPlay_Event,
+  PopupDel_Event,
+  PopupEna_Event,
+  PopupInfo_Event  
+};
+
+// Help strings
+#define HELP_OPENPL _T("Open playlist")
+#define HELP_SAVEPL _T("Save playlist")
+#define HELP_SIMPLEADD _T("Simple Add")
+#define HELP_ADDMRL _T("Add MRL")
+#define HELP_DELETE _T("Delete selection")
+#define HELP_INFOS _T("Item info")
+#define HELP_UP _T("Up")
+#define HELP_DOWN _T("Down")
+#define HELP_RANDOM _T("Random")
+#define HELP_LOOP _T("Repeat all")
+#define HELP_REPEAT _T("Repeat one")
+
+// The TBBUTTON structure contains information the toolbar buttons.
+static TBBUTTON tbButton2[] =      
+{
+  {0, ID_MANAGE_OPENPL,        TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {1, ID_MANAGE_SAVEPL,       TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {2, ID_MANAGE_SIMPLEADD,       TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {3, ID_MANAGE_ADDMRL,        TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {4, ID_SEL_DELETE,       TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {5, Infos_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {6, Up_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {7, Down_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON,  0, -1},
+  {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP,     0, -1},
+  {8, Random_Event,      TBSTATE_ENABLED, TBSTYLE_CHECK,  0, -1},
+  {9, Loop_Event,       TBSTATE_ENABLED, TBSTYLE_CHECK,   0, -1},
+  {10, Repeat_Event,       TBSTATE_ENABLED, TBSTYLE_CHECK,   0, -1}
+};
+
+// Toolbar ToolTips
+TCHAR * szToolTips2[] = 
+{
+    HELP_OPENPL,
+        HELP_SAVEPL,
+        HELP_SIMPLEADD,
+        HELP_ADDMRL,
+        HELP_DELETE,
+        HELP_INFOS,
+        HELP_UP,
+        HELP_DOWN,
+        HELP_RANDOM,
+        HELP_LOOP,
+        HELP_REPEAT
+};
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+Playlist::Playlist( intf_thread_t *_p_intf, HINSTANCE _hInst )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+        hInst = _hInst;
+        hListView = NULL;
+
+    i_title_sorted = 1;
+    i_author_sorted = 1;
+
+    b_need_update = VLC_TRUE;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT Playlist::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                           PBOOL pbProcessed )
+{
+    SHINITDLGINFO shidi;
+    SHMENUBARINFO mbi;
+
+    int bState;
+    playlist_t *p_playlist;
+
+    DWORD dwStyle;
+    RECT rect, rectTB;
+
+    INITCOMMONCONTROLSEX iccex;
+
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    case WM_INITDIALOG: 
+        shidi.dwMask = SHIDIM_FLAGS;
+        shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
+            SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
+        shidi.hDlg = hwnd;
+        SHInitDialog( &shidi );
+
+        //Create the menubar.
+        memset( &mbi, 0, sizeof (SHMENUBARINFO) );
+        mbi.cbSize     = sizeof (SHMENUBARINFO);
+        mbi.hwndParent = hwnd;
+        mbi.dwFlags    = SHCMBF_HMENU;
+        mbi.nToolBarId = IDR_MENUBAR2;
+        mbi.hInstRes   = hInst;
+        mbi.nBmpId     = 0;
+        mbi.cBmpImages = 0;  
+
+        if( !SHCreateMenuBar(&mbi) )
+        {
+            MessageBox(hwnd, L"SHCreateMenuBar Failed", L"Error", MB_OK);
+            //return -1;
+        }
+
+        hwndCB = mbi.hwndMB;
+
+        iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
+        iccex.dwICC = ICC_BAR_CLASSES;
+
+        // Registers TOOLBAR control classes from the common control dll
+        InitCommonControlsEx (&iccex);
+
+        //  Create the toolbar control.
+        dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS |
+            WS_EX_OVERLAPPEDWINDOW | CCS_NOPARENTALIGN;
+
+        hwndTB = CreateToolbarEx( hwnd, dwStyle, NULL, NUMIMAGES,
+                                  hInst, IDB_BITMAP3, tbButton2,
+                                  sizeof (tbButton2) / sizeof (TBBUTTON),
+                                  BUTTONWIDTH, BUTTONHEIGHT,
+                                  IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON) );
+        if( !hwndTB )
+        {
+            *pbProcessed = bWasProcessed;
+            lResult = FALSE;
+            return lResult;
+        }
+  
+        // Add ToolTips to the toolbar.
+        SendMessage( hwndTB, TB_SETTOOLTIPS, (WPARAM) NUMIMAGES,
+                     (LPARAM)szToolTips2 );
+
+        // Reposition the toolbar.
+        GetClientRect( hwnd, &rect );
+        GetWindowRect( hwndTB, &rectTB );
+        MoveWindow( hwndTB, rect.left, rect.top - 2, rect.right - rect.left, 
+                    MENU_HEIGHT /*rectTB.bottom - rectTB.top */, TRUE);
+
+        // random, loop, repeat buttons states
+        vlc_value_t val; 
+        p_playlist = (playlist_t *)
+            vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+        if( p_playlist == NULL )
+        {
+            *pbProcessed = bWasProcessed;
+            lResult = FALSE;
+            return lResult;
+        }
+        var_Get( p_playlist , "random", &val );
+        bState = val.b_bool ? TBSTATE_CHECKED : 0;
+        SendMessage( hwndTB, TB_SETSTATE, Random_Event,
+                     MAKELONG(bState | TBSTATE_ENABLED, 0) );
+        var_Get( p_playlist , "loop", &val );
+        bState = val.b_bool ? TBSTATE_CHECKED : 0;
+        SendMessage( hwndTB, TB_SETSTATE, Loop_Event,
+                     MAKELONG(bState | TBSTATE_ENABLED, 0) );
+        var_Get( p_playlist , "repeat", &val );
+        bState = val.b_bool ? TBSTATE_CHECKED : 0;
+        SendMessage( hwndTB, TB_SETSTATE, Repeat_Event,
+                     MAKELONG(bState | TBSTATE_ENABLED, 0) );
+        vlc_object_release( p_playlist );
+
+        GetClientRect( hwnd, &rect );
+        hListView = CreateWindow( WC_LISTVIEW, NULL, WS_VISIBLE | WS_CHILD |
+            LVS_REPORT | LVS_SHOWSELALWAYS | WS_VSCROLL | WS_HSCROLL,
+            rect.left, rect.top + 2*(MENU_HEIGHT+1), rect.right - rect.left, 
+            rect.bottom - ( rect.top + 2*MENU_HEIGHT) - MENU_HEIGHT, 
+            hwnd, NULL, hInst, NULL );
+        ListView_SetExtendedListViewStyle( hListView, LVS_EX_FULLROWSELECT );
+
+        LVCOLUMN lv;
+        lv.mask = LVCF_WIDTH | LVCF_FMT | LVCF_TEXT;
+        lv.fmt = LVCFMT_LEFT ;
+        GetClientRect( hwnd, &rect );
+        lv.cx = 120;
+        lv.pszText = _T("Name");
+        lv.cchTextMax = 9;
+        ListView_InsertColumn( hListView, 0, &lv);
+        lv.cx = 55;
+        lv.pszText = _T("Author");
+        lv.cchTextMax = 9;
+        ListView_InsertColumn( hListView, 1, &lv);
+        lv.cx = rect.right - rect.left - 180;
+        lv.pszText = _T("Duration");
+        lv.cchTextMax = 9;
+        ListView_InsertColumn( hListView, 2, &lv);
+
+        SetTimer( hwnd, 1, 500 /*milliseconds*/, NULL );
+
+        SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+
+        return lResult;
+
+    case WM_TIMER:
+        UpdatePlaylist();
+        return lResult;
+
+    case WM_COMMAND:    
+        switch( LOWORD(wp) )
+        {
+        case IDOK:
+            EndDialog( hwnd, LOWORD( wp ) );
+            return TRUE;
+
+        case ID_MANAGE_OPENPL:
+            OnOpen();
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case ID_MANAGE_SAVEPL:
+            SHFullScreen( GetForegroundWindow(), SHFS_SHOWSIPBUTTON );
+            OnSave();
+            SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+            return TRUE;
+
+        case ID_MANAGE_SIMPLEADD:
+            SHFullScreen( GetForegroundWindow(), SHFS_SHOWSIPBUTTON );
+            OnAddFile();
+            SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case ID_MANAGE_ADDMRL:
+            SHFullScreen( GetForegroundWindow(), SHFS_SHOWSIPBUTTON );
+            OnAddMRL();
+            SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case ID_SEL_DELETE:
+            OnDeleteSelection();
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case Infos_Event:
+            SHFullScreen( GetForegroundWindow(), SHFS_SHOWSIPBUTTON );
+            OnPopupInfo( hwnd );
+            SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case Up_Event:
+            OnUp();
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case Down_Event:
+            OnDown();
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case Random_Event:
+            OnRandom();
+            return TRUE;
+
+        case Loop_Event:
+            OnLoop();
+            return TRUE;
+
+        case Repeat_Event:
+            OnRepeat();
+            return TRUE;
+
+        case ID_SORT_TITLE:
+            OnSort( ID_SORT_TITLE );
+            return TRUE;
+
+        case ID_SORT_RTITLE:
+            OnSort( ID_SORT_RTITLE );
+            return TRUE;
+
+        case ID_SORT_AUTHOR:
+            OnSort( ID_SORT_AUTHOR );
+            return TRUE;
+
+        case ID_SORT_RAUTHOR:
+            OnSort( ID_SORT_RAUTHOR );
+            return TRUE;
+
+        case ID_SORT_SHUFFLE:
+            OnSort( ID_SORT_SHUFFLE );
+            return TRUE;
+
+        case ID_SEL_ENABLE:
+            OnEnableSelection();
+            return TRUE;
+
+        case ID_SEL_DISABLE:
+            OnDisableSelection();
+            return TRUE;
+
+        case ID_SEL_INVERT:
+            OnInvertSelection();
+            return TRUE;
+
+        case ID_SEL_SELECTALL:
+            OnSelectAll();
+            return TRUE;
+
+        case PopupPlay_Event:
+            OnPopupPlay();
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case PopupDel_Event:
+            OnPopupDel();
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case PopupEna_Event:
+            OnPopupEna();
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        case PopupInfo_Event:
+            OnPopupInfo( hwnd );
+            SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+            b_need_update = VLC_TRUE;
+            return TRUE;
+
+        default:
+            *pbProcessed = bWasProcessed;
+            lResult = FALSE;
+            return lResult;
+        }
+
+    case WM_NOTIFY:
+        if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
+            ( ((LPNMHDR)lp)->code == NM_CUSTOMDRAW ) )
+        {
+            SetWindowLong( hwnd, DWL_MSGRESULT,
+                           (LONG)ProcessCustomDraw(lp) );
+            return TRUE;
+        }
+        else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
+                 ( ((LPNMHDR)lp)->code == GN_CONTEXTMENU  ) )
+        {                       
+            HandlePopupMenu( hwnd, ((PNMRGINFO)lp)->ptAction );
+            return TRUE;
+        }
+        else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
+                 ( ((LPNMHDR)lp)->code == LVN_COLUMNCLICK  ) )
+        {
+            OnColSelect( ((LPNMLISTVIEW)lp)->iSubItem );
+            return TRUE;
+        }
+        else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
+                 ( ((LPNMHDR)lp)->code == LVN_ITEMACTIVATE  ) )
+        {
+            OnActivateItem( ((LPNMLISTVIEW)lp)->iSubItem );
+            return TRUE;
+        }
+
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+
+    default:
+         // the message was not processed
+         // indicate if the base class handled it
+         *pbProcessed = bWasProcessed;
+         lResult = FALSE;
+         return lResult;
+    }
+
+    return lResult;
+}
+
+LRESULT Playlist::ProcessCustomDraw( LPARAM lParam )
+{
+    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
+
+    switch( lplvcd->nmcd.dwDrawStage )
+    {
+    case CDDS_PREPAINT : //Before the paint cycle begins
+        //request notifications for individual listview items
+        return CDRF_NOTIFYITEMDRAW;
+
+    case CDDS_ITEMPREPAINT: //Before an item is drawn
+        playlist_t *p_playlist = (playlist_t *)
+            vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+        if( p_playlist == NULL ) return CDRF_DODEFAULT;
+        if( (int)lplvcd->nmcd.dwItemSpec == p_playlist->i_index )
+        {
+            lplvcd->clrText = RGB(255,0,0);
+            vlc_object_release(p_playlist);
+            return CDRF_NEWFONT;
+        }
+        
+        playlist_item_t *p_item = playlist_ItemGetByPos( p_playlist,
+                                        (int)lplvcd->nmcd.dwItemSpec );
+        if( !p_item )
+        {
+            vlc_object_release(p_playlist);
+            return CDRF_DODEFAULT;
+        }
+        if( p_item->b_enabled == VLC_FALSE )
+        {
+            lplvcd->clrText = RGB(192,192,192);
+            vlc_object_release(p_playlist);
+            return CDRF_NEWFONT;
+        }
+    }
+
+    return CDRF_DODEFAULT;
+}
+
+/**********************************************************************
+ * Handles the display of the "floating" popup
+ **********************************************************************/
+void Playlist::HandlePopupMenu( HWND hwnd, POINT point )
+{
+    HMENU hMenuTrackPopup;
+
+    // Create the popup menu.
+    hMenuTrackPopup = CreatePopupMenu();
+
+    // Append some items.
+    AppendMenu( hMenuTrackPopup, MF_STRING, PopupPlay_Event, _T("Play") );
+    AppendMenu( hMenuTrackPopup, MF_STRING, PopupDel_Event, _T("Delete") );
+    AppendMenu( hMenuTrackPopup, MF_STRING, PopupEna_Event,
+                _T("Toggle enabled") );
+    AppendMenu( hMenuTrackPopup, MF_STRING, PopupInfo_Event, _T("Info") );
+
+    /* Draw and track the "floating" popup */
+    TrackPopupMenu( hMenuTrackPopup, 0, point.x, point.y, 0, hwnd, NULL );
+
+    /* Destroy the menu since were are done with it. */
+    DestroyMenu( hMenuTrackPopup );
+}
+
+/**********************************************************************
+ * Update the playlist
+ **********************************************************************/
+void Playlist::UpdatePlaylist()
+{
+    if( b_need_update )
+    {
+        Rebuild();
+        b_need_update = VLC_FALSE;
+    }
+        
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+        
+    /* Update the colour of items */
+
+    vlc_mutex_lock( &p_playlist->object_lock );
+    if( p_intf->p_sys->i_playing != p_playlist->i_index )
+    {
+        // p_playlist->i_index in RED
+        Rebuild();
+
+        // if exists, p_intf->p_sys->i_playing in BLACK
+        p_intf->p_sys->i_playing = p_playlist->i_index;
+    }
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    vlc_object_release( p_playlist );
+}
+
+/**********************************************************************
+ * Rebuild the playlist
+ **********************************************************************/
+void Playlist::Rebuild()
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    int i_focused =
+        ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
+
+    /* Clear the list... */
+    ListView_DeleteAllItems( hListView );
+
+    /* ...and rebuild it */
+    vlc_mutex_lock( &p_playlist->object_lock );
+    for( int i = 0; i < p_playlist->i_size; i++ )
+    {
+        LVITEM lv;
+        lv.mask = LVIF_TEXT;
+        lv.pszText = _T("");
+        lv.cchTextMax = 1;
+        lv.iSubItem = 0;
+        lv.iItem = i;
+        ListView_InsertItem( hListView, &lv );
+        ListView_SetItemText( hListView, lv.iItem, 0,
+            _FROMMB(p_playlist->pp_items[i]->input.psz_name) );
+        UpdateItem( i );
+    }
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    if ( i_focused )
+        ListView_SetItemState( hListView, i_focused, LVIS_FOCUSED |
+                               LVIS_SELECTED, LVIS_STATEIMAGEMASK )
+    else
+        ListView_SetItemState( hListView, i_focused, LVIS_FOCUSED,
+                               LVIS_STATEIMAGEMASK );
+
+    vlc_object_release( p_playlist );
+}
+
+/**********************************************************************
+ * Update one playlist item
+ **********************************************************************/
+void Playlist::UpdateItem( int i )
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+
+    if( p_playlist == NULL ) return;
+
+    playlist_item_t *p_item = playlist_ItemGetByPos( p_playlist, i );
+
+    if( !p_item )
+    {
+        vlc_object_release(p_playlist);
+        return;
+    }
+
+    ListView_SetItemText( hListView, i, 0, _FROMMB(p_item->input.psz_name) );
+    ListView_SetItemText( hListView, i, 1,
+                          _FROMMB( playlist_ItemGetInfo( p_item,
+                                   _("General") , _("Author") ) ) );
+
+    char psz_duration[MSTRTIME_MAX_SIZE];
+    mtime_t dur = p_item->input.i_duration;
+    if( dur != -1 ) secstotimestr( psz_duration, dur/1000000 );
+    else memcpy( psz_duration , "-:--:--", sizeof("-:--:--") );
+
+    ListView_SetItemText( hListView, i, 3, _FROMMB(psz_duration) );
+
+    vlc_object_release(p_playlist);
+}
+
+/**********************************************************************
+ * Private functions
+ **********************************************************************/
+void Playlist::DeleteItem( int item )
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    playlist_Delete( p_playlist, item );
+    ListView_DeleteItem( hListView, item );
+
+    vlc_object_release( p_playlist );
+}
+
+/**********************************************************************
+ * I/O functions
+ **********************************************************************/
+void Playlist::OnOpen()
+{
+    OPENFILENAME ofn;
+    TCHAR DateiName[80+1] = _T("\0");
+    static TCHAR szFilter[] = _T("All playlists (*.pls;*.m3u;*.asx;*.b4s|M3U files|*.m3u)\0*.pls;*.m3u;*.asx;*.b4s|M3U files|*.m3u\0");
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    memset( &ofn, 0, sizeof(OPENFILENAME) );
+    ofn.lStructSize = sizeof (OPENFILENAME);
+    ofn.hwndOwner = NULL;
+    ofn.hInstance = hInst;
+    ofn.lpstrFilter = szFilter;
+    ofn.lpstrCustomFilter = NULL;
+    ofn.nMaxCustFilter = 0;
+    ofn.nFilterIndex = 1;     
+    ofn.lpstrFile = (LPTSTR) DateiName; 
+    ofn.nMaxFile = 80;
+    ofn.lpstrFileTitle = NULL; 
+    ofn.nMaxFileTitle = 40;
+    ofn.lpstrInitialDir = NULL;
+    ofn.lpstrTitle = _T("Open playlist");
+    ofn.Flags = 0; 
+    ofn.nFileOffset = 0;
+    ofn.nFileExtension = 0;
+    ofn.lpstrDefExt = NULL;
+    ofn.lCustData = 0L;
+    ofn.lpfnHook = NULL;
+    ofn.lpTemplateName = NULL;
+
+    if( GetOpenFileName((LPOPENFILENAME)&ofn) )
+    {
+        playlist_Import( p_playlist, _TOMB(ofn.lpstrFile) );
+    }
+
+    vlc_object_release( p_playlist );
+}
+
+void Playlist::OnSave()
+{
+    TCHAR szFile[NMAXFILE] = _T("\0");
+    OPENFILENAME ofn;
+
+    LPWSTR wUnicode;
+    int len;
+
+    struct {
+        TCHAR *psz_desc;
+        TCHAR *psz_filter;
+        char *psz_module;
+    } formats[] = {{ _T("M3U file"), _T("*.m3u"), "export-m3u" },       
+                { _T("PLS file"), _T("*.pls"), "export-pls" }};
+    wUnicode = new TCHAR[100];
+    wcscpy( wUnicode, _T("") );
+    len = 0;
+
+    for( unsigned int i = 0; i < sizeof(formats)/sizeof(formats[0]); i++)
+    {
+        wcscpy( &wUnicode[len], formats[i].psz_desc );
+                len = len + wcslen( formats[i].psz_desc );
+        wUnicode[len] = '\0';
+                len++;
+        wcscpy( &wUnicode[len], formats[i].psz_filter );
+                len = len + wcslen( formats[i].psz_filter );
+        wUnicode[len] = '\0';
+                len++;
+    }
+    wUnicode[len] = '\0';
+
+    memset( &(ofn), 0, sizeof(ofn));
+    ofn.lStructSize     = sizeof(ofn);
+    ofn.hwndOwner = NULL;
+    ofn.lpstrFile = szFile;
+    ofn.nMaxFile = NMAXFILE;    
+    ofn.lpstrFilter = wUnicode;
+    ofn.lpstrTitle = _T("Save playlist");
+    ofn.Flags = OFN_HIDEREADONLY; 
+    free( wUnicode );
+
+    if( GetSaveFileName((LPOPENFILENAME) &ofn) )
+    {
+        playlist_t * p_playlist = (playlist_t *)
+            vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+
+        if( p_playlist && ofn.lpstrFile )
+        {
+            playlist_Export( p_playlist, _TOMB(ofn.lpstrFile),
+                             formats[ofn.nFilterIndex ?
+                                     ofn.nFilterIndex - 1 : 0].psz_module );
+        }
+
+        if( p_playlist ) vlc_object_release( p_playlist );
+    }
+}
+
+void Playlist::OnAddFile()
+{
+    // Same code as in Interface
+    OPENFILENAME ofn;
+    TCHAR DateiName[80+1] = _T("\0");
+    static TCHAR szFilter[] = _T("All (*.*)\0*.*\0");
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    memset( &ofn, 0, sizeof(OPENFILENAME) );
+    ofn.lStructSize = sizeof(OPENFILENAME);
+    ofn.hwndOwner = NULL;
+    ofn.hInstance = hInst;
+    ofn.lpstrFilter = szFilter;
+    ofn.lpstrCustomFilter = NULL;
+    ofn.nMaxCustFilter = 0;
+    ofn.nFilterIndex = 1;     
+    ofn.lpstrFile = (LPTSTR)DateiName; 
+    ofn.nMaxFile = 80;
+    ofn.lpstrFileTitle = NULL; 
+    ofn.nMaxFileTitle = 40;
+    ofn.lpstrInitialDir = NULL;
+    ofn.lpstrTitle = _T("Quick Open File");
+    ofn.Flags = NULL; 
+    ofn.nFileOffset = 0;
+    ofn.nFileExtension = 0;
+    ofn.lpstrDefExt = NULL;
+    ofn.lCustData = 0L;
+    ofn.lpfnHook = NULL;
+    ofn.lpTemplateName = NULL;
+
+    SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+
+    if( GetOpenFileName( (LPOPENFILENAME)&ofn ) )
+    {
+        char *psz_filename = _TOMB(ofn.lpstrFile);
+        playlist_Add( p_playlist, psz_filename, psz_filename,
+                      PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
+    }
+
+    vlc_object_release( p_playlist );
+}
+
+void Playlist::OnAddMRL()
+{
+}
+
+/**********************************************************************
+ * Selection functions
+ **********************************************************************/
+void Playlist::OnDeleteSelection()
+{
+    /* Delete from the end to the beginning, to avoid a shift of indices */
+    for( long item = ((int) ListView_GetItemCount( hListView ) - 1);
+         item >= 0; item-- )
+    {
+        if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
+        {
+            DeleteItem( item );
+        }
+    }
+}
+
+void Playlist::OnInvertSelection()
+{
+    UINT iState;
+
+    for( long item = 0; item < ListView_GetItemCount( hListView ); item++ )
+    {
+        iState = ListView_GetItemState( hListView, item, LVIS_STATEIMAGEMASK );
+        ListView_SetItemState( hListView, item, iState ^ LVIS_SELECTED,
+                               LVIS_STATEIMAGEMASK );
+    }
+}
+
+void Playlist::OnEnableSelection()
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    for( long item = ListView_GetItemCount( hListView ) - 1;
+         item >= 0; item-- )
+    {
+        if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
+        {
+            playlist_item_t *p_item =
+                playlist_ItemGetByPos( p_playlist, item );
+            playlist_Enable( p_playlist, p_item );
+            UpdateItem( item );
+        }
+    }
+    vlc_object_release( p_playlist);
+}
+
+void Playlist::OnDisableSelection()
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    for( long item = ListView_GetItemCount( hListView ) - 1;
+         item >= 0; item-- )
+    {
+        if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
+        {
+            /*XXX*/
+            playlist_item_t *p_item =
+                playlist_ItemGetByPos( p_playlist, item );
+            playlist_Disable( p_playlist, p_item );
+            UpdateItem( item );
+        }
+    }
+    vlc_object_release( p_playlist);
+}
+
+void Playlist::OnSelectAll()
+{
+    for( long item = 0; item < ListView_GetItemCount( hListView ); item++ )
+    {
+        ListView_SetItemState( hListView, item, LVIS_FOCUSED | LVIS_SELECTED,
+                               LVIS_STATEIMAGEMASK );
+    }
+}
+
+void Playlist::OnActivateItem( int i_item )
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    playlist_Goto( p_playlist, i_item );
+
+    vlc_object_release( p_playlist );
+}
+
+void Playlist::ShowInfos( HWND hwnd, int i_item )
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    vlc_mutex_lock( &p_playlist->object_lock);
+    playlist_item_t *p_item = playlist_ItemGetByPos( p_playlist, i_item );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    if( p_item )
+    {
+        ItemInfoDialog *iteminfo_dialog =
+            new ItemInfoDialog( p_intf, hInst, p_item );
+        DialogBoxParam( hInst, (LPCTSTR)IDD_DUMMY, hwnd,
+                        (DLGPROC)iteminfo_dialog->BaseWndProc,
+                        (long)iteminfo_dialog );                
+        UpdateItem( i_item );
+        delete iteminfo_dialog;
+    }
+
+    vlc_object_release( p_playlist );
+}
+
+/********************************************************************
+ * Move functions
+ ********************************************************************/
+void Playlist::OnUp()
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    /* We use the first selected item, so find it */
+    long i_item =
+        ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
+
+    if( i_item > 0 && i_item < p_playlist->i_size )
+    {
+        playlist_Move( p_playlist , i_item, i_item - 1);
+        if( i_item > 1 )
+        {
+            ListView_SetItemState( hListView, i_item - 1, LVIS_FOCUSED,
+                                   LVIS_STATEIMAGEMASK );
+        }
+        else
+        {
+            ListView_SetItemState( hListView, 0, LVIS_FOCUSED,
+                                   LVIS_STATEIMAGEMASK );
+        }
+    }
+    vlc_object_release( p_playlist );
+
+    return;
+}
+
+void Playlist::OnDown()
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    /* We use the first selected item, so find it */
+    long i_item =
+        ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
+
+    if( i_item >= 0 && i_item < p_playlist->i_size - 1 )
+    {
+        playlist_Move( p_playlist , i_item, i_item + 2 );
+        ListView_SetItemState( hListView, i_item + 1, LVIS_FOCUSED,
+                               LVIS_STATEIMAGEMASK );
+    }
+    vlc_object_release( p_playlist );
+
+    return;
+}
+
+/**********************************************************************
+ * Playlist mode functions
+ **********************************************************************/
+void Playlist::OnRandom()
+{
+    vlc_value_t val;
+    int bState = SendMessage( hwndTB, TB_GETSTATE, Random_Event, 0 ); 
+    val.b_bool = (bState & TBSTATE_CHECKED) ? VLC_TRUE : VLC_FALSE;
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    var_Set( p_playlist , "random", val );
+    vlc_object_release( p_playlist );
+}
+
+void Playlist::OnLoop ()
+{
+    vlc_value_t val;
+    int bState = SendMessage( hwndTB, TB_GETSTATE, Loop_Event, 0 ); 
+    val.b_bool = (bState & TBSTATE_CHECKED) ? VLC_TRUE : VLC_FALSE;
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    var_Set( p_playlist , "loop", val );
+    vlc_object_release( p_playlist );
+}
+
+void Playlist::OnRepeat ()
+{
+    vlc_value_t val;
+    int bState = SendMessage( hwndTB, TB_GETSTATE, Repeat_Event, 0 );  
+    val.b_bool = (bState & TBSTATE_CHECKED) ? VLC_TRUE : VLC_FALSE;
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    var_Set( p_playlist , "repeat", val );
+    vlc_object_release( p_playlist );
+}
+
+/********************************************************************
+ * Sorting functions
+ ********************************************************************/
+void Playlist::OnSort( UINT event )
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    switch( event )
+    {
+    case ID_SORT_TITLE:
+        playlist_SortTitle( p_playlist , ORDER_NORMAL );
+        break;
+    case ID_SORT_RTITLE:
+        playlist_SortTitle( p_playlist , ORDER_REVERSE );
+        break;
+    case ID_SORT_AUTHOR:
+        playlist_SortAuthor(p_playlist , ORDER_NORMAL );
+        break;
+    case ID_SORT_RAUTHOR:
+        playlist_SortAuthor( p_playlist , ORDER_REVERSE );
+        break;
+    case ID_SORT_SHUFFLE:
+        playlist_Sort( p_playlist , SORT_RANDOM, ORDER_NORMAL );
+        break;
+    }
+
+    vlc_object_release( p_playlist );
+
+    b_need_update = VLC_TRUE;
+
+    return;
+}
+
+void Playlist::OnColSelect( int iSubItem )
+{
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    switch( iSubItem )
+    {
+    case 0:
+        if( i_title_sorted != 1 )
+        {
+            playlist_SortTitle( p_playlist, ORDER_NORMAL );
+            i_title_sorted = 1;
+        }
+        else
+        {
+            playlist_SortTitle( p_playlist, ORDER_REVERSE );
+            i_title_sorted = -1;
+        }
+        break;
+    case 1:
+        if( i_author_sorted != 1 )
+        {
+            playlist_SortAuthor( p_playlist, ORDER_NORMAL );
+            i_author_sorted = 1;
+        }
+        else
+        {
+            playlist_SortAuthor( p_playlist, ORDER_REVERSE );
+            i_author_sorted = -1;
+        }
+        break;
+    default:
+        break;
+    }
+
+    vlc_object_release( p_playlist );
+
+    b_need_update = VLC_TRUE;
+
+    return;
+}
+
+/*****************************************************************************
+ * Popup management functions
+ *****************************************************************************/
+void Playlist::OnPopupPlay()
+{
+    int i_popup_item =
+        ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    if( i_popup_item != -1 )
+    {
+        playlist_Goto( p_playlist, i_popup_item );
+    }
+
+    vlc_object_release( p_playlist );
+}
+
+void Playlist::OnPopupDel()
+{
+    int i_popup_item =
+        ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
+
+    DeleteItem( i_popup_item );
+}
+
+void Playlist::OnPopupEna()
+{
+    int i_popup_item =
+        ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
+
+    playlist_t *p_playlist = (playlist_t *)
+        vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    playlist_item_t *p_item =
+        playlist_ItemGetByPos( p_playlist, i_popup_item );
+
+    if( p_playlist->pp_items[i_popup_item]->b_enabled )
+        //playlist_IsEnabled( p_playlist, i_popup_item ) )
+    {
+        playlist_Disable( p_playlist, p_item );
+    }
+    else
+    {
+        playlist_Enable( p_playlist, p_item );
+    }
+
+    vlc_object_release( p_playlist);
+    UpdateItem( i_popup_item );
+}
+
+void Playlist::OnPopupInfo( HWND hwnd )
+{
+    int i_popup_item =
+        ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
+
+    ShowInfos( hwnd, i_popup_item );
+}
diff --git a/modules/gui/wince/preferences.cpp b/modules/gui/wince/preferences.cpp
new file mode 100644 (file)
index 0000000..742cd0b
--- /dev/null
@@ -0,0 +1,869 @@
+/*****************************************************************************
+ * preferences.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <string.h>
+
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <winuser.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <commdlg.h>
+
+#include <vlc_config_cat.h>
+
+#include "wince.h"
+#include "preferences_widgets.h"
+
+#define GENERAL_ID 1242
+#define PLUGIN_ID 1243
+#define CAPABILITY_ID 1244
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/* IDs for the controls and the menu commands */
+enum
+{
+    Notebook_Event,
+    MRL_Event,
+    ResetAll_Event,
+    Advanced_Event
+};
+
+/*****************************************************************************
+ * Classes declarations.
+ *****************************************************************************/
+class ConfigTreeData;
+class PrefsTreeCtrl
+{
+public:
+
+    PrefsTreeCtrl() { }
+    PrefsTreeCtrl( intf_thread_t *_p_intf, PrefsDialog *p_prefs_dialog, HWND hwnd, HINSTANCE _hInst );
+    virtual ~PrefsTreeCtrl();
+
+    void ApplyChanges();
+    /*void CleanChanges();*/
+
+    void OnSelectTreeItem( LPNM_TREEVIEW pnmtv, HWND parent, HINSTANCE hInst );
+        
+    ConfigTreeData *FindModuleConfig( ConfigTreeData *config_data );
+
+    HWND hwndTV;
+
+private:
+    intf_thread_t *p_intf;
+    PrefsDialog *p_prefs_dialog;
+    vlc_bool_t b_advanced;
+
+    HTREEITEM root_item;
+    HTREEITEM general_item;
+    HTREEITEM plugins_item;
+};
+
+class PrefsPanel
+{
+public:
+
+    PrefsPanel() { }
+    PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
+                PrefsDialog *, int i_object_id, char *, char * );
+    virtual ~PrefsPanel() {}
+
+    void Hide();
+    void Show();
+
+    HWND config_window;
+
+    int oldvalue;
+    int maxvalue;
+
+    void ApplyChanges();
+
+private:
+    intf_thread_t *p_intf;
+    PrefsDialog *p_prefs_dialog;
+
+    vlc_bool_t b_advanced;
+
+    HWND label;
+
+    vector<ConfigControl *> config_array;
+};
+
+class ConfigTreeData
+{
+public:
+
+    ConfigTreeData() { b_submodule = 0; panel = NULL; psz_section = NULL;
+                       psz_help = NULL; }
+    virtual ~ConfigTreeData() { if( panel ) delete panel;
+                                if( psz_section) free(psz_section);
+                                if( psz_help) free(psz_help); }
+
+    vlc_bool_t b_submodule;
+
+    PrefsPanel *panel;
+    int i_object_id;
+    char *psz_section;
+    char *psz_help;
+};
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+PrefsDialog::PrefsDialog( intf_thread_t *_p_intf, HINSTANCE _hInst )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+    hInst = _hInst;
+    prefs_tree = NULL;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT PrefsDialog::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                              PBOOL pbProcessed  )
+{
+    SHINITDLGINFO shidi;
+    SHMENUBARINFO mbi;
+    RECT rcClient;
+
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    case WM_INITDIALOG: 
+        shidi.dwMask = SHIDIM_FLAGS;
+        shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
+            SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
+        shidi.hDlg = hwnd;
+        SHInitDialog( &shidi );
+
+        //Create the menubar
+        memset( &mbi, 0, sizeof (SHMENUBARINFO) );
+        mbi.cbSize     = sizeof (SHMENUBARINFO);
+        mbi.hwndParent = hwnd;
+        mbi.nToolBarId = IDR_DUMMYMENU;
+        mbi.hInstRes   = hInst;
+        mbi.nBmpId     = 0;
+        mbi.cBmpImages = 0;  
+
+        if( !SHCreateMenuBar(&mbi) )
+        {
+            MessageBox(hwnd, L"SHCreateMenuBar Failed", L"Error", MB_OK);
+            //return -1;
+        }
+
+        hwndCB = mbi.hwndMB;
+
+        // Get the client area rect to put the panels in
+        GetClientRect(hwnd, &rcClient);
+
+        /* Create the buttons */                
+        advanced_checkbox =
+            CreateWindow( _T("BUTTON"), _T("Advanced options"),
+                        WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                        5, 10, 15, 15, hwnd, NULL, hInst, NULL );
+        SendMessage( advanced_checkbox, BM_SETCHECK, BST_UNCHECKED, 0 );
+
+        advanced_label = CreateWindow( _T("STATIC"), _T("Advanced options"),
+                        WS_CHILD | WS_VISIBLE | SS_LEFT,
+                        5 + 15 + 5, 10, 110, 15,
+                        hwnd, NULL, hInst, NULL);
+
+        if( config_GetInt( p_intf, "advanced" ) )
+        {
+            SendMessage( advanced_checkbox, BM_SETCHECK, BST_CHECKED, 0 );
+            /*dummy_event.SetInt(TRUE);
+              OnAdvanced( dummy_event );*/
+        }
+
+        reset_button = CreateWindow( _T("BUTTON"), _T("Reset All"),
+                        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                        rcClient.right - 5 - 80, 10 - 3, 80, 15 + 6,
+                        hwnd, NULL, hInst, NULL );
+
+        /* Create the preferences tree control */
+        prefs_tree = new PrefsTreeCtrl( p_intf, this, hwnd, hInst );
+
+        UpdateWindow( hwnd );
+        return lResult;
+
+    case WM_COMMAND:
+        if( LOWORD(wp) == IDOK )
+        {
+            OnOk();
+            EndDialog( hwnd, LOWORD( wp ) );
+            return TRUE;
+        }
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+
+    case WM_NOTIFY:
+
+        if ( ( ((LPNMHDR)lp)->hwndFrom == prefs_tree->hwndTV ) &&
+             ( ((LPNMHDR)lp)->code == TVN_SELCHANGED  ) )
+        {
+            prefs_tree->OnSelectTreeItem( (NM_TREEVIEW FAR *)(LPNMHDR)lp,
+                                          hwnd, hInst );
+            return TRUE;
+        }
+
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+
+    case WM_VSCROLL:
+    {
+        TVITEM tvi = {0};
+        tvi.mask = TVIF_PARAM;
+        tvi.hItem = TreeView_GetSelection( prefs_tree->hwndTV );
+        TreeView_GetItem( prefs_tree->hwndTV, &tvi );
+        ConfigTreeData *config_data = prefs_tree->FindModuleConfig( (ConfigTreeData *)tvi.lParam );
+        if ( hwnd == config_data->panel->config_window ) 
+        {
+            int dy;
+            RECT rc;
+            GetWindowRect( hwnd, &rc);
+            int newvalue = config_data->panel->oldvalue;
+            switch ( GET_WM_VSCROLL_CODE(wp,lp) ) 
+            {
+            case SB_BOTTOM       : newvalue = 0; break;
+            case SB_TOP          : newvalue = config_data->panel->maxvalue; break;
+            case SB_LINEDOWN     : newvalue += 10; break;
+            case SB_PAGEDOWN     : newvalue += rc.bottom - rc.top - 25; break; // faux ! une page c'est la longueur réelle de notebook
+            case SB_LINEUP       : newvalue -= 10; break;
+            case SB_PAGEUP       : newvalue -= rc.bottom - rc.top - 25; break;
+            case SB_THUMBPOSITION:
+            case SB_THUMBTRACK   : newvalue = GET_WM_VSCROLL_POS(wp,lp); break;
+            }
+            newvalue = max(0,min(config_data->panel->maxvalue,newvalue));
+            SetScrollPos( hwnd,SB_VERT,newvalue,TRUE);//SB_CTL si hwnd=hwndScrollBar, SB_VERT si window
+            dy = config_data->panel->oldvalue - newvalue;
+
+            ScrollWindowEx( hwnd, 0, dy, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN );
+            UpdateWindow ( hwnd);
+
+            config_data->panel->oldvalue = newvalue;                                
+        }
+    }
+    *pbProcessed = bWasProcessed;
+    lResult = FALSE;
+    return lResult;
+
+    default:
+        // the message was not processed
+        // indicate if the base class handled it
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+    }
+
+    return lResult;
+}
+
+/*****************************************************************************
+ * Private methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Events methods.
+ *****************************************************************************/
+void PrefsDialog::OnOk( void )
+{
+    prefs_tree->ApplyChanges();
+    config_SaveConfigFile( p_intf, NULL );
+}
+
+/*****************************************************************************
+ * PrefsTreeCtrl class definition.
+ *****************************************************************************/
+PrefsTreeCtrl::PrefsTreeCtrl( intf_thread_t *_p_intf,
+                              PrefsDialog *_p_prefs_dialog, HWND hwnd,
+                              HINSTANCE hInst )
+{
+    vlc_list_t      *p_list;
+    module_t        *p_module;
+    module_config_t *p_item;
+    int i_index;
+
+    INITCOMMONCONTROLSEX iccex;
+    RECT rcClient;
+
+    int size;
+    char *szAnsi;
+    LPWSTR wUnicode;
+    BOOL bTemp;
+    TVITEM tvi = {0}; 
+    TVINSERTSTRUCT tvins = {0}; 
+    HTREEITEM hPrev;
+
+    size_t i_capability_count = 0;
+    size_t i_child_index;
+
+    HTREEITEM capability_item;
+
+    /* Initializations */
+    p_intf = _p_intf;
+    p_prefs_dialog = _p_prefs_dialog;
+    b_advanced = VLC_FALSE;
+
+    /* Create a tree view */
+    // Initialize the INITCOMMONCONTROLSEX structure.
+    iccex.dwSize = sizeof( INITCOMMONCONTROLSEX );
+    iccex.dwICC = ICC_TREEVIEW_CLASSES;
+
+    // Registers Statusbar control classes from the common control dll
+    InitCommonControlsEx( &iccex );
+
+    // Get the client area rect to put the tv in
+    GetClientRect(hwnd, &rcClient);
+
+    // Create the tree-view control.
+    hwndTV = CreateWindowEx( 0, WC_TREEVIEW, NULL,
+        WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES |
+        TVS_LINESATROOT | TVS_HASBUTTONS,
+        5, 10 + 2*(15 + 10) + 105 + 5, rcClient.right - 5 - 5, 6*15,
+        hwnd, NULL, hInst, NULL );
+
+    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; 
+    tvi.pszText = _T("root");
+    tvi.cchTextMax = lstrlen(_T("root"));
+    tvi.lParam = (LPARAM) 1; // root level
+    tvins.item = tvi;
+    tvins.hInsertAfter = TVI_FIRST; 
+    tvins.hParent = TVI_ROOT; 
+
+    // Add the item to the tree-view control. 
+    hPrev = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins );
+    root_item = hPrev;
+
+    /* List the plugins */
+    p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+    if( !p_list ) return;
+
+    /*
+     * Build a tree of the main options
+     */
+    ConfigTreeData *config_data = new ConfigTreeData;
+    config_data->i_object_id = GENERAL_ID;
+    config_data->psz_help = strdup("nothing");//strdup( GENERAL_HELP );
+    config_data->psz_section = strdup( GENERAL_TITLE );
+    tvi.pszText = _T("General settings");
+    tvi.cchTextMax = lstrlen(_T("General settings"));
+    tvi.lParam = (long) config_data;
+    tvins.item = tvi;
+    tvins.hInsertAfter = hPrev;
+    tvins.hParent = root_item; //level 2
+
+    // Add the item to the tree-view control.
+    hPrev = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
+    general_item = hPrev;
+
+    for( i_index = 0; i_index < p_list->i_count; i_index++ )
+    {
+        p_module = (module_t *)p_list->p_values[i_index].p_object;
+        if( !strcmp( p_module->psz_object_name, "main" ) )
+            break;
+    }
+    if( i_index < p_list->i_count )
+    {
+        /* We found the main module */
+
+        /* Enumerate config categories and store a reference so we can
+         * generate their config panel them when it is asked by the user. */
+        p_item = p_module->p_config;
+
+        if( p_item ) do
+        {
+            switch( p_item->i_type )
+            {
+            case CONFIG_HINT_CATEGORY:
+                ConfigTreeData *config_data = new ConfigTreeData;
+                config_data->psz_section = strdup( p_item->psz_text );
+                if( p_item->psz_longtext )
+                {
+                    config_data->psz_help =
+                        strdup( p_item->psz_longtext );
+                }
+                else
+                {
+                    config_data->psz_help = NULL;
+                }
+                config_data->i_object_id = p_module->i_object_id;
+
+                /* Add the category to the tree */
+                // Set the text of the item. 
+                tvi.pszText = _FROMMB(p_item->psz_text); 
+                tvi.cchTextMax = _tcslen(tvi.pszText);
+                tvi.lParam = (long)config_data;
+                tvins.item = tvi;
+                tvins.hInsertAfter = hPrev; 
+                tvins.hParent = general_item; //level 3
+    
+                // Add the item to the tree-view control. 
+                hPrev = (HTREEITEM)TreeView_InsertItem( hwndTV, &tvins );
+
+                break;
+            }
+        }
+        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
+
+        TreeView_SortChildren( hwndTV, general_item, 0 );
+    }
+        
+    /*
+     * Build a tree of all the plugins
+     */
+    config_data = new ConfigTreeData;
+    config_data->i_object_id = PLUGIN_ID;
+    config_data->psz_help = strdup("nothing");//strdup( PLUGIN_HELP );
+    config_data->psz_section = strdup("nothing");//strdup( PLUGIN_TITLE );
+    tvi.pszText = _T("Modules");
+    tvi.cchTextMax = lstrlen(_T("Modules"));
+    tvi.lParam = (long) config_data;
+    tvins.item = tvi;
+    tvins.hInsertAfter = hPrev;
+    tvins.hParent = root_item;// level 2
+
+    // Add the item to the tree-view control.
+    hPrev = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
+    plugins_item = hPrev;
+
+    i_capability_count = 0;
+    for( i_index = 0; i_index < p_list->i_count; i_index++ )
+    {
+        i_child_index = 0;
+
+        p_module = (module_t *)p_list->p_values[i_index].p_object;
+
+        /* Exclude the main module */
+        if( !strcmp( p_module->psz_object_name, "main" ) )
+            continue;
+
+        /* Exclude empty plugins (submodules don't have config options, they
+         * are stored in the parent module) */
+        if( p_module->b_submodule )
+            p_item = ((module_t *)p_module->p_parent)->p_config;
+        else
+            p_item = p_module->p_config;
+
+        if( !p_item ) continue;
+        do
+        {
+            if( p_item->i_type & CONFIG_ITEM )
+                break;
+        }
+        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
+        if( p_item->i_type == CONFIG_HINT_END ) continue;
+
+        /* Find the capability child item */
+        /*long cookie; size_t i_child_index;*/
+        capability_item = TreeView_GetChild( hwndTV, plugins_item );
+        while( capability_item != 0 )
+        {
+            TVITEM capability_tvi = {0};
+
+            i_child_index++;
+
+            capability_tvi.mask = TVIF_TEXT;
+            capability_tvi.pszText = new WCHAR[200];
+            capability_tvi.cchTextMax = 200;
+            capability_tvi.hItem = capability_item;
+            TreeView_GetItem( hwndTV, &capability_tvi );
+            size = WideCharToMultiByte( CP_ACP, 0, capability_tvi.pszText, -1, NULL, 0, NULL, &bTemp );
+            szAnsi = new char[size];
+            WideCharToMultiByte( CP_ACP, 0, capability_tvi.pszText, -1, szAnsi, size, NULL, &bTemp );       
+            if( !strcmp( szAnsi, p_module->psz_capability ) )
+            {
+                free( szAnsi );
+                free( capability_tvi.pszText );
+                break;
+            }
+            free( szAnsi );
+            free( capability_tvi.pszText );
+
+            capability_item = TreeView_GetNextSibling( hwndTV, capability_item );
+        }
+
+        if( i_child_index == i_capability_count &&
+            p_module->psz_capability && *p_module->psz_capability )
+        {
+            /* We didn't find it, add it */
+            ConfigTreeData *config_data = new ConfigTreeData;
+            config_data->psz_section =
+                strdup( GetCapabilityHelp( p_module->psz_capability , 1 ) );
+            config_data->psz_help =
+                strdup( GetCapabilityHelp( p_module->psz_capability , 2 ) );
+            config_data->i_object_id = CAPABILITY_ID;
+            tvi.pszText = _FROMMB(p_module->psz_capability);
+            tvi.cchTextMax = _tcslen(tvi.pszText);
+            tvi.lParam = (long) config_data;
+            tvins.item = tvi;
+            tvins.hInsertAfter = plugins_item; 
+            tvins.hParent = plugins_item;// level 3
+
+            // Add the item to the tree-view control. 
+            capability_item = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
+
+            i_capability_count++;
+        }
+
+        /* Add the plugin to the tree */
+        ConfigTreeData *config_data = new ConfigTreeData;
+        config_data->b_submodule = p_module->b_submodule;
+        config_data->i_object_id = p_module->b_submodule ?
+            ((module_t *)p_module->p_parent)->i_object_id :
+            p_module->i_object_id;
+        config_data->psz_help = NULL;
+        tvi.pszText = _FROMMB(p_module->psz_object_name);
+        tvi.cchTextMax = _tcslen(tvi.pszText);
+        tvi.lParam = (long) config_data;
+        tvins.item = tvi;
+        tvins.hInsertAfter = capability_item; 
+        tvins.hParent = capability_item;// level 4
+
+        // Add the item to the tree-view control. 
+        TreeView_InsertItem( hwndTV, &tvins);
+    }
+
+    /* Sort all this mess */
+    /*long cookie; size_t i_child_index;*/
+    TreeView_SortChildren( hwndTV, plugins_item, 0 );
+    capability_item = TreeView_GetChild( hwndTV, plugins_item );
+    while( capability_item != 0 )
+    {
+        TreeView_SortChildren( hwndTV, capability_item, 0 );
+        capability_item = TreeView_GetNextSibling( hwndTV, capability_item );
+    }
+
+    /* Clean-up everything */
+    vlc_list_release( p_list );
+
+    TreeView_Expand( hwndTV, root_item, TVE_EXPANDPARTIAL |TVE_EXPAND );
+    TreeView_Expand( hwndTV, general_item, TVE_EXPANDPARTIAL |TVE_EXPAND );
+}
+
+PrefsTreeCtrl::~PrefsTreeCtrl()
+{
+}
+
+void PrefsTreeCtrl::ApplyChanges()
+{
+    /*long cookie, cookie2;*/
+    ConfigTreeData *config_data;
+
+    /* Apply changes to the main module */
+    HTREEITEM item = TreeView_GetChild( hwndTV, general_item );
+    while( item != 0 )
+    {
+        TVITEM tvi = {0};
+        tvi.mask = TVIF_PARAM;
+        tvi.hItem = item;
+        TreeView_GetItem( hwndTV, &tvi );
+        config_data = (ConfigTreeData *)tvi.lParam;
+        if( config_data && config_data->panel )
+        {
+            config_data->panel->ApplyChanges();
+        }
+
+        item = TreeView_GetNextSibling( hwndTV, item );
+    }
+
+    /* Apply changes to the plugins */
+    item = TreeView_GetChild( hwndTV, plugins_item );
+    while( item != 0 )
+    {
+        HTREEITEM item2 = TreeView_GetChild( hwndTV, item );
+        while( item2 != 0 )
+        {       
+            TVITEM tvi = {0};
+            tvi.mask = TVIF_PARAM;
+            tvi.hItem = item2;
+            TreeView_GetItem( hwndTV, &tvi );
+            config_data = (ConfigTreeData *)tvi.lParam;
+            if( config_data && config_data->panel )
+            {
+                config_data->panel->ApplyChanges();
+            }
+            item2 = TreeView_GetNextSibling( hwndTV, item2 );
+        }
+        item = TreeView_GetNextSibling( hwndTV, item );
+    }
+}
+
+ConfigTreeData *PrefsTreeCtrl::FindModuleConfig( ConfigTreeData *config_data )
+{
+    /* We need this complexity because submodules don't have their own config
+     * options. They use the parent module ones. */
+
+    if( !config_data || !config_data->b_submodule )
+    {
+        return config_data;
+    }
+
+    /*long cookie, cookie2;*/
+    ConfigTreeData *config_new;
+    HTREEITEM item = TreeView_GetChild( hwndTV, plugins_item );
+    while( item != 0 )
+    {
+        HTREEITEM item2 = TreeView_GetChild( hwndTV, item );
+        while( item2 != 0 )
+        {       
+            TVITEM tvi = {0};
+            tvi.mask = TVIF_PARAM;
+            tvi.hItem = item2;
+            TreeView_GetItem( hwndTV, &tvi );
+            config_new = (ConfigTreeData *)tvi.lParam;
+            if( config_new && !config_new->b_submodule &&
+                config_new->i_object_id == config_data->i_object_id )
+            {
+                return config_new;
+            }
+            item2 = TreeView_GetNextSibling( hwndTV, item2 );
+        }
+        item = TreeView_GetNextSibling( hwndTV, item );
+    }
+
+    /* Found nothing */
+    return NULL;
+}
+
+void PrefsTreeCtrl::OnSelectTreeItem( LPNM_TREEVIEW pnmtv, HWND parent,
+                                      HINSTANCE hInst )
+{
+    ConfigTreeData *config_data = NULL;
+
+    if( pnmtv->itemOld.hItem )
+        config_data = FindModuleConfig( (ConfigTreeData *)pnmtv->itemOld.lParam );
+
+    if( config_data && config_data->panel )
+    {
+        config_data->panel->Hide();
+    }
+
+    /* Don't use event.GetItem() because we also send fake events */
+    TVITEM tvi = {0};
+    tvi.mask = TVIF_PARAM;
+    tvi.hItem = TreeView_GetSelection( hwndTV );
+    TreeView_GetItem( hwndTV, &tvi );
+    config_data = FindModuleConfig( (ConfigTreeData *)tvi.lParam );
+    if( config_data )
+    {
+        if( !config_data->panel )
+        {
+            /* The panel hasn't been created yet. Let's do it. */
+            config_data->panel =
+                new PrefsPanel( parent, hInst, p_intf, p_prefs_dialog,
+                                config_data->i_object_id,
+                                config_data->psz_section,
+                                config_data->psz_help );
+        }
+        else
+        {
+            config_data->panel->Show();
+        }
+    }
+}
+
+/*****************************************************************************
+ * PrefsPanel class definition.
+ *****************************************************************************/
+PrefsPanel::PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
+                        PrefsDialog *_p_prefs_dialog,
+                        int i_object_id, char *psz_section, char *psz_help )
+{
+    module_config_t *p_item;
+    module_t *p_module = NULL;
+
+    /* Initializations */
+    p_intf = _p_intf;
+    p_prefs_dialog = _p_prefs_dialog;
+
+    b_advanced = VLC_TRUE;
+
+    if( i_object_id == PLUGIN_ID || i_object_id == GENERAL_ID ||
+        i_object_id == CAPABILITY_ID )
+    {
+        label = CreateWindow( _T("STATIC"), _FROMMB(psz_section),
+                              WS_CHILD | WS_VISIBLE | SS_LEFT,
+                              5, 10 + (15 + 10), 200, 15,
+                              parent, NULL, hInst, NULL );
+        config_window = NULL;
+    }
+    else
+    {
+        /* Get a pointer to the module */
+        p_module = (module_t *)vlc_object_get( p_intf,  i_object_id );
+        if( p_module->i_object_type != VLC_OBJECT_MODULE )
+        {
+            /* 0OOoo something went really bad */
+            return;
+        }
+
+        /* Enumerate config options and add corresponding config boxes
+         * (submodules don't have config options, they are stored in the
+         *  parent module) */
+        if( p_module->b_submodule )
+            p_item = ((module_t *)p_module->p_parent)->p_config;
+        else
+            p_item = p_module->p_config;
+
+        /* Find the category if it has been specified */
+        if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
+        {
+            while( !p_item->i_type == CONFIG_HINT_CATEGORY ||
+                   strcmp( psz_section, p_item->psz_text ) )
+            {
+                if( p_item->i_type == CONFIG_HINT_END )
+                    break;
+                p_item++;
+            }
+        }
+
+        /* Add a head title to the panel */
+        label = CreateWindow( _T("STATIC"), _FROMMB(psz_section ?
+                        p_item->psz_text : p_module->psz_longname),
+                        WS_CHILD | WS_VISIBLE | SS_LEFT,
+                        5, 10 + (15 + 10), 250, 15,
+                        parent, NULL, hInst, NULL );
+
+        WNDCLASS wc;
+        memset( &wc, 0, sizeof(wc) );
+        wc.style          = CS_HREDRAW | CS_VREDRAW;
+        wc.lpfnWndProc    = (WNDPROC) _p_prefs_dialog->BaseWndProc;
+        wc.cbClsExtra     = 0;
+        wc.cbWndExtra     = 0;
+        wc.hInstance      = hInst;
+        wc.hIcon          = 0;
+        wc.hCursor        = 0;
+        wc.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
+        wc.lpszMenuName   = 0;
+        wc.lpszClassName  = _T("PrefsPanelClass");
+        RegisterClass(&wc);
+
+        RECT rc;
+        GetWindowRect( parent, &rc);
+        config_window = CreateWindow( _T("PrefsPanelClass"),
+                        _T("config_window"),
+                        WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER,
+                        5, 10 + 2*(15 + 10), rc.right - 5 - 7, 105,
+                        parent, NULL, hInst, (void *) _p_prefs_dialog );
+
+        int y_pos = 5;
+        if( p_item ) do
+        {
+            /* If a category has been specified, check we finished the job */
+            if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY &&
+                strcmp( psz_section, p_item->psz_text ) )
+                break;
+
+            ConfigControl *control =
+                CreateConfigControl( VLC_OBJECT(p_intf),
+                                     p_item, config_window,
+                                     hInst, &y_pos );
+
+            /* Don't add items that were not recognized */
+            if( control == NULL ) continue;
+
+            /* Add the config data to our array so we can keep a trace of it */
+            config_array.push_back( control );
+        }
+        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
+                
+        GetWindowRect( config_window, &rc);
+        maxvalue = y_pos - (rc.bottom - rc.top) + 5;
+        oldvalue = 0;
+        SetScrollRange( config_window, SB_VERT, 0, maxvalue, TRUE );
+    }
+}
+
+void PrefsPanel::Hide()
+{
+    ShowWindow( label, SW_HIDE );
+    if( config_window ) ShowWindow( config_window, SW_HIDE );
+}
+
+void PrefsPanel::Show()
+{
+    ShowWindow( label, SW_SHOW );
+    if( config_window ) ShowWindow( config_window, SW_SHOW );
+}
+
+void PrefsPanel::ApplyChanges()
+{
+    vlc_value_t val;
+
+    for( size_t i = 0; i < config_array.size(); i++ )
+    {
+        ConfigControl *control = config_array[i];
+
+        switch( control->GetType() )
+        {
+        case CONFIG_ITEM_STRING:
+        case CONFIG_ITEM_FILE:
+        case CONFIG_ITEM_DIRECTORY:
+        case CONFIG_ITEM_MODULE:
+            config_PutPsz( p_intf, control->GetName(),
+                           control->GetPszValue() );
+            break;
+        case CONFIG_ITEM_KEY:
+            /* So you don't need to restart to have the changes take effect */
+            val.i_int = control->GetIntValue();
+            var_Set( p_intf->p_vlc, control->GetName(), val );
+        case CONFIG_ITEM_INTEGER:
+        case CONFIG_ITEM_BOOL:
+            config_PutInt( p_intf, control->GetName(),
+                           control->GetIntValue() );
+            break;
+        case CONFIG_ITEM_FLOAT:
+            config_PutFloat( p_intf, control->GetName(),
+                             control->GetFloatValue() );
+            break;
+        }
+    }
+}
diff --git a/modules/gui/wince/preferences_widgets.cpp b/modules/gui/wince/preferences_widgets.cpp
new file mode 100644 (file)
index 0000000..1dabec9
--- /dev/null
@@ -0,0 +1,801 @@
+/*****************************************************************************
+ * preferences_widgets.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>                                            /* strerror() */
+#include <stdio.h>
+#include <string>
+using namespace std;
+
+#include <windows.h>
+#include <windowsx.h>
+#include <winuser.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+
+#include "wince.h"
+#include "preferences_widgets.h"
+
+/*****************************************************************************
+ * CreateConfigControl wrapper
+ *****************************************************************************/
+ConfigControl *CreateConfigControl( vlc_object_t *p_this,
+                                    module_config_t *p_item,
+                                    HWND parent, HINSTANCE hInst,
+                                    int *py_pos )
+{
+    ConfigControl *p_control = NULL;
+
+    switch( p_item->i_type )
+    {
+    case CONFIG_ITEM_MODULE:
+        p_control = new ModuleConfigControl( p_this, p_item, parent, hInst, py_pos );
+        break;
+
+    case CONFIG_ITEM_STRING:
+        if( !p_item->i_list )
+        {
+            p_control = new StringConfigControl( p_this, p_item, parent, hInst, py_pos );
+        }
+        /*else
+        {
+            p_control = new StringListConfigControl( p_this, p_item, parent, hInst, py_pos );
+        }*/
+        break;
+/*
+    case CONFIG_ITEM_FILE:
+    case CONFIG_ITEM_DIRECTORY:
+        p_control = new FileConfigControl( p_this, p_item, parent, hInst, py_pos );
+        break;
+
+    case CONFIG_ITEM_INTEGER:
+        if( p_item->i_list )
+        {
+            p_control = new IntegerListConfigControl( p_this, p_item, parent, hInst, py_pos );
+        }
+        else if( p_item->i_min != 0 || p_item->i_max != 0 )
+        {
+            p_control = new RangedIntConfigControl( p_this, p_item, parent, hInst, py_pos );
+        }
+        else
+        {
+            p_control = new IntegerConfigControl( p_this, p_item, parent, hInst, py_pos );
+        }
+        break;
+*/
+    case CONFIG_ITEM_KEY:
+        p_control = new KeyConfigControl( p_this, p_item, parent, hInst, py_pos  );
+        break;
+
+    case CONFIG_ITEM_FLOAT:
+        p_control = new FloatConfigControl( p_this, p_item, parent, hInst, py_pos );
+        break;
+
+    case CONFIG_ITEM_BOOL:
+        p_control = new BoolConfigControl( p_this, p_item, parent, hInst, py_pos );
+        break;
+
+    default:
+        break;
+    }
+
+    return p_control;
+}
+
+/*****************************************************************************
+ * ConfigControl implementation
+ *****************************************************************************/
+ConfigControl::ConfigControl( vlc_object_t *_p_this,
+                              module_config_t *p_item,
+                              HWND parent, HINSTANCE hInst )
+  : parent( parent ), p_this( _p_this ),
+    pf_update_callback( NULL ), p_update_data( NULL ),
+    name( p_item->psz_name ), i_type( p_item->i_type ),
+    b_advanced( p_item->b_advanced )
+
+{
+    /*sizer = new wxBoxSizer( wxHORIZONTAL );*/
+}
+
+ConfigControl::~ConfigControl()
+{
+}
+
+/*wxSizer *ConfigControl::Sizer()
+{
+    return sizer;
+}*/
+
+char *ConfigControl::GetName()
+{
+    return name;
+}
+
+int ConfigControl::GetType()
+{
+    return i_type;
+}
+
+vlc_bool_t ConfigControl::IsAdvanced()
+{
+    return b_advanced;
+}
+
+void ConfigControl::SetUpdateCallback( void (*p_callback)( void * ),
+                                             void *p_data )
+{
+    pf_update_callback = p_callback;
+    p_update_data = p_data;
+}
+
+void ConfigControl::OnUpdate( UINT event )
+{
+    if( pf_update_callback )
+    {
+        pf_update_callback( p_update_data );
+    }
+}
+
+/*****************************************************************************
+ * KeyConfigControl implementation
+ *****************************************************************************/
+string *KeyConfigControl::m_keysList = NULL;
+
+KeyConfigControl::KeyConfigControl( vlc_object_t *p_this,
+                                    module_config_t *p_item,
+                                    HWND parent, HINSTANCE hInst,
+                                    int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    // Number of keys descriptions
+    unsigned int i_keys = sizeof(vlc_keys)/sizeof(key_descriptor_t);
+
+    // Init the keys decriptions array
+    if( m_keysList == NULL )
+    {
+        m_keysList = new string[i_keys];
+        for( unsigned int i = 0; i < i_keys; i++ )
+        {
+            m_keysList[i] = vlc_keys[i].psz_key_string;
+        }
+    }
+
+    label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
+                WS_CHILD | WS_VISIBLE | SS_LEFT, 5, *py_pos, 200, 15,
+                parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+
+    alt = CreateWindow( _T("BUTTON"), _T("Alt"),
+                        WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                        20, *py_pos, 15, 15, parent, NULL, hInst, NULL );
+    Button_SetCheck( alt, p_item->i_value & KEY_MODIFIER_ALT ? BST_CHECKED :
+                     BST_UNCHECKED );
+
+    alt_label = CreateWindow( _T("STATIC"), _T("Alt"),
+                WS_CHILD | WS_VISIBLE | SS_LEFT, 20 + 15 + 5, *py_pos, 30, 15,
+                parent, NULL, hInst, NULL );
+
+    ctrl = CreateWindow( _T("BUTTON"), _T("Ctrl"),
+                WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                20 + 15 + 5 + 30 + 5, *py_pos, 15, 15,
+                parent, NULL, hInst, NULL );
+    Button_SetCheck( ctrl, p_item->i_value & KEY_MODIFIER_CTRL ? BST_CHECKED :
+                     BST_UNCHECKED );
+
+    ctrl_label = CreateWindow( _T("STATIC"), _T("Ctrl"),
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                20 + 15 + 5 + 30 + 5 + 15 + 5, *py_pos, 30, 15,
+                parent, NULL, hInst, NULL );
+
+    shift = CreateWindow( _T("BUTTON"), _T("Shift"),
+                WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                20 + 15 + 5 + 2*(30 + 5) + 15 + 5, *py_pos, 15, 15,
+                parent, NULL, hInst, NULL );
+    Button_SetCheck( shift, p_item->i_value & KEY_MODIFIER_SHIFT ?
+                     BST_CHECKED : BST_UNCHECKED );
+
+    shift_label = CreateWindow( _T("STATIC"), _T("Shift"),
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                20 + 15 + 5 + 2*(30 + 5) + 2*(15 + 5), *py_pos, 30, 15,
+                parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+
+    combo = CreateWindow( _T("COMBOBOX"), _T(""),
+                WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST |
+                CBS_SORT | WS_VSCROLL, 20, *py_pos, 130, 5*15 + 6,
+                parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+
+    for( unsigned int i = 0; i < i_keys ; i++ )
+    {
+        ComboBox_AddString( combo, _FROMMB(m_keysList[i].c_str()) );
+        ComboBox_SetItemData( combo, i, (void*)vlc_keys[i].i_key_code );
+        if( (unsigned int)vlc_keys[i].i_key_code ==
+            ( ((unsigned int)p_item->i_value) & ~KEY_MODIFIER ) )
+        {
+            ComboBox_SetCurSel( combo, i );
+            ComboBox_SetText( combo, _FROMMB(m_keysList[i].c_str()) );
+        }
+    }
+}
+
+KeyConfigControl::~KeyConfigControl()
+{
+    if( m_keysList )
+    {
+        delete[] m_keysList;
+        m_keysList = NULL;
+    }
+}
+
+int KeyConfigControl::GetIntValue()
+{
+    int result = 0;
+    if( Button_GetCheck( alt ) )
+    {
+        result |= KEY_MODIFIER_ALT;
+    }
+    if( Button_GetCheck( ctrl ) )
+    {
+        result |= KEY_MODIFIER_CTRL;
+    }
+    if( Button_GetCheck( shift ) )
+    {
+        result |= KEY_MODIFIER_SHIFT;
+    }
+    int selected = ComboBox_GetCurSel( combo );
+    if( selected != -1 )
+    {
+        result |= (int)ComboBox_GetItemData( combo, selected );
+    }
+    return result;
+}
+
+/*****************************************************************************
+ * ModuleConfigControl implementation
+ *****************************************************************************/
+ModuleConfigControl::ModuleConfigControl( vlc_object_t *p_this,
+                                          module_config_t *p_item,
+                                          HWND parent, HINSTANCE hInst,
+                                          int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    vlc_list_t *p_list;
+    module_t *p_parser;
+
+    label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
+                          WS_CHILD | WS_VISIBLE | SS_LEFT,
+                          5, *py_pos, 200, 15,
+                          parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+
+    combo = CreateWindow( _T("COMBOBOX"), _T(""),
+                          WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL |
+                          CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL,
+                          20, *py_pos, 180, 5*15 + 6,
+                          parent, NULL, hInst, NULL);
+
+    *py_pos += 15 + 10;
+
+    /* build a list of available modules */
+    p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+    ComboBox_AddString( combo, _T("Default") );
+    ComboBox_SetItemData( combo, 0, (void *)NULL );
+    ComboBox_SetCurSel( combo, 0 );
+    //ComboBox_SetText( combo, _T("Default") );
+    for( int i_index = 0; i_index < p_list->i_count; i_index++ )
+    {
+        p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+
+        if( !strcmp( p_parser->psz_capability, p_item->psz_type ) )
+        {
+            ComboBox_AddString( combo, _FROMMB(p_parser->psz_longname) );
+            ComboBox_SetItemData( combo, i_index,
+                                  (void*)p_parser->psz_object_name );
+            if( p_item->psz_value && !strcmp(p_item->psz_value,
+                                             p_parser->psz_object_name) )
+            {
+                ComboBox_SetCurSel( combo, i_index );
+                //ComboBox_SetText( combo, _FROMMB(p_parser->psz_longname) );
+            }
+        }
+    }
+    vlc_list_release( p_list );
+}
+
+ModuleConfigControl::~ModuleConfigControl()
+{
+    ;
+}
+
+char *ModuleConfigControl::GetPszValue()
+{
+    int selected = ComboBox_GetCurSel( combo );
+    if( selected != -1 )
+        return (char *)ComboBox_GetItemData( combo, selected );
+    else return NULL;
+}
+
+/*****************************************************************************
+ * StringConfigControl implementation
+ *****************************************************************************/
+StringConfigControl::StringConfigControl( vlc_object_t *p_this,
+                                          module_config_t *p_item,
+                                          HWND parent, HINSTANCE hInst,
+                                          int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
+                          WS_CHILD | WS_VISIBLE | SS_LEFT,
+                          5, *py_pos, 200, 15,
+                          parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+
+    textctrl = CreateWindow( _T("EDIT"), p_item->psz_value ?
+                             _FROMMB(p_item->psz_value) : _T(""),
+                             WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT |
+                             ES_AUTOHSCROLL, 20, *py_pos - 3, 180, 15 + 3,
+                             parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+}
+
+StringConfigControl::~StringConfigControl()
+{
+    ;
+}
+
+char *StringConfigControl::GetPszValue()
+{
+    int i_size;
+    char *psz_result;
+    TCHAR *psz_string;
+
+    i_size = Edit_GetTextLength( textctrl );
+    psz_string = (TCHAR *)malloc( (i_size + 1) * sizeof(TCHAR) );
+    Edit_GetText( textctrl, psz_string, i_size + 1 );
+    psz_result = strdup( _TOMB(psz_string) );
+    free( psz_string );
+    return psz_result;
+}
+
+#if 0
+/*****************************************************************************
+ * StringListConfigControl implementation
+ *****************************************************************************/
+StringListConfigControl::StringListConfigControl( vlc_object_t *p_this,
+                                                  module_config_t *p_item,
+                                                  HWND parent, HINSTANCE hInst,
+                                                  int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    label = new wxStaticText(this, -1, wxU(p_item->psz_text));
+    sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+    combo = new wxComboBox( this, -1, wxT(""),
+                            wxDefaultPosition, wxDefaultSize,
+                            0, NULL, wxCB_READONLY );
+    UpdateCombo( p_item );
+
+    combo->SetToolTip( wxU(p_item->psz_longtext) );
+    sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+
+    for( int i = 0; i < p_item->i_action; i++ )
+    {
+        wxButton *button =
+            new wxButton( this, wxID_HIGHEST+i,
+                          wxU(p_item->ppsz_action_text[i]) );
+        sizer->Add( button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+    }
+
+    sizer->Layout();
+    this->SetSizerAndFit( sizer );
+}
+
+StringListConfigControl::~StringListConfigControl()
+{
+}
+
+void StringListConfigControl::UpdateCombo( module_config_t *p_item )
+{
+    /* build a list of available options */
+    for( int i_index = 0; i_index < p_item->i_list; i_index++ )
+    {
+        combo->Append( ( p_item->ppsz_list_text &&
+                         p_item->ppsz_list_text[i_index] ) ?
+                       wxU(p_item->ppsz_list_text[i_index]) :
+                       wxL2U(p_item->ppsz_list[i_index]) );
+        combo->SetClientData( i_index, (void *)p_item->ppsz_list[i_index] );
+        if( ( p_item->psz_value &&
+              !strcmp( p_item->psz_value, p_item->ppsz_list[i_index] ) ) ||
+             ( !p_item->psz_value && !*p_item->ppsz_list[i_index] ) )
+        {
+            combo->SetSelection( i_index );
+            combo->SetValue( ( p_item->ppsz_list_text &&
+                               p_item->ppsz_list_text[i_index] ) ?
+                             wxU(p_item->ppsz_list_text[i_index]) :
+                             wxL2U(p_item->ppsz_list[i_index]) );
+        }
+    }
+}
+
+BEGIN_EVENT_TABLE(StringListConfigControl, wxPanel)
+    /* Button events */
+    EVT_BUTTON(-1, StringListConfigControl::OnAction)
+
+    /* Text events */
+    EVT__T(-1, StringListConfigControl::OnUpdate)
+END_EVENT_TABLE()
+
+void StringListConfigControl::OnAction( wxCommandEvent& event )
+{
+    int i_action = event.GetId() - wxID_HIGHEST;
+
+    module_config_t *p_item = config_FindConfig( p_this, GetName().mb_str() );
+    if( !p_item ) return;
+
+    if( i_action < 0 || i_action >= p_item->i_action ) return;
+
+    vlc_value_t val;
+    wxString value = GetPszValue();
+    (const char *)val.psz_string = value.mb_str();
+    p_item->ppf_action[i_action]( p_this, GetName().mb_str(), val, val, 0 );
+
+    if( p_item->b_dirty )
+    {
+        combo->Clear();
+        UpdateCombo( p_item );
+        p_item->b_dirty = VLC_FALSE;
+    }
+}
+
+wxString StringListConfigControl::GetPszValue()
+{
+    int selected = combo->GetSelection();
+    if( selected != -1 )
+    {
+        return wxL2U((char *)combo->GetClientData( selected ));
+    }
+    return wxString();
+}
+
+/*****************************************************************************
+ * FileConfigControl implementation
+ *****************************************************************************/
+FileConfigControl::FileConfigControl( vlc_object_t *p_this,
+                                      module_config_t *p_item,
+                                      HWND parent, HINSTANCE hInst,
+                                      int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    directory = p_item->i_type == CONFIG_ITEM_DIRECTORY;
+    label = new wxStaticText(this, -1, wxU(p_item->psz_text));
+    sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+    textctrl = new wxTextCtrl( this, -1,
+                               wxL2U(p_item->psz_value),
+                               wxDefaultPosition,
+                               wxDefaultSize,
+                               wxTE_PROCESS_ENTER);
+    textctrl->SetToolTip( wxU(p_item->psz_longtext) );
+    sizer->Add( textctrl, 1, wxALL, 5 );
+    browse = new wxButton( this, wxID_HIGHEST, wxU(_("Browse...")) );
+    sizer->Add( browse, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+    sizer->Layout();
+    this->SetSizerAndFit( sizer );
+}
+
+BEGIN_EVENT_TABLE(FileConfigControl, wxPanel)
+    /* Button events */
+    EVT_BUTTON(wxID_HIGHEST, FileConfigControl::OnBrowse)
+END_EVENT_TABLE()
+
+void FileConfigControl::OnBrowse( wxCommandEvent& event )
+{
+    if( directory )
+    {
+        wxDirDialog dialog( this, wxU(_("Choose directory")) );
+
+        if( dialog.ShowModal() == wxID_OK )
+        {
+            textctrl->SetValue( dialog.GetPath() );
+        }
+    }
+    else
+    {
+        wxFileDialog dialog( this, wxU(_("Choose file")),
+                             wxT(""), wxT(""), wxT("*.*"),
+#if defined( __WXMSW__ )
+                             wxOPEN
+#else
+                             wxOPEN | wxSAVE
+#endif
+                           );
+        if( dialog.ShowModal() == wxID_OK )
+        {
+            textctrl->SetValue( dialog.GetPath() );
+        }
+    }
+}
+
+FileConfigControl::~FileConfigControl()
+{
+    ;
+}
+
+wxString FileConfigControl::GetPszValue()
+{
+    return textctrl->GetValue();
+}
+
+/*****************************************************************************
+ * IntegerConfigControl implementation
+ *****************************************************************************/
+IntegerConfigControl::IntegerConfigControl( vlc_object_t *p_this,
+                                            module_config_t *p_item,
+                                            HWND parent, HINSTANCE hInst,
+                                            int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    label = new wxStaticText(this, -1, wxU(p_item->psz_text));
+    spin = new wxSpinCtrl( this, -1,
+                           wxString::Format(wxT("%d"),
+                                            p_item->i_value),
+                           wxDefaultPosition, wxDefaultSize,
+                           wxSP_ARROW_KEYS,
+                           -10000000, 10000000, p_item->i_value);
+    spin->SetToolTip( wxU(p_item->psz_longtext) );
+    sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+    sizer->Add( spin, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+    sizer->Layout();
+    this->SetSizerAndFit( sizer );
+}
+
+IntegerConfigControl::~IntegerConfigControl()
+{
+    ;
+}
+
+int IntegerConfigControl::GetIntValue()
+{
+    return spin->GetValue();
+}
+
+/*****************************************************************************
+ * IntegerListConfigControl implementation
+ *****************************************************************************/
+IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *p_this,
+                                                    module_config_t *p_item,
+                                                    HWND parent,
+                                                    HINSTANCE hInst,
+                                                    int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    label = new wxStaticText(this, -1, wxU(p_item->psz_text));
+    sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+    combo = new wxComboBox( this, -1, wxT(""),
+                            wxDefaultPosition, wxDefaultSize,
+                            0, NULL, wxCB_READONLY );
+
+    UpdateCombo( p_item );
+
+    combo->SetToolTip( wxU(p_item->psz_longtext) );
+    sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+
+    sizer->Layout();
+    this->SetSizerAndFit( sizer );
+}
+
+IntegerListConfigControl::~IntegerListConfigControl()
+{
+}
+
+void IntegerListConfigControl::UpdateCombo( module_config_t *p_item )
+{
+    /* build a list of available options */
+    for( int i_index = 0; i_index < p_item->i_list; i_index++ )
+    {
+        if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
+        {
+            combo->Append( wxU(p_item->ppsz_list_text[i_index]) );
+        }
+        else
+        {
+            combo->Append( wxString::Format(wxT("%i"),
+                                            p_item->pi_list[i_index]) );
+        }
+        combo->SetClientData( i_index, (void *)p_item->pi_list[i_index] );
+        if( p_item->i_value == p_item->pi_list[i_index] )
+        {
+            combo->SetSelection( i_index );
+            if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
+            {
+                combo->SetValue( wxU(p_item->ppsz_list_text[i_index]) );
+            }
+            else
+            {
+                combo->SetValue( wxString::Format(wxT("%i"),
+                                                  p_item->pi_list[i_index]) );
+            }
+        }
+    }
+}
+
+BEGIN_EVENT_TABLE(IntegerListConfigControl, wxPanel)
+    /* Button events */
+    EVT_BUTTON(-1, IntegerListConfigControl::OnAction)
+END_EVENT_TABLE()
+
+void IntegerListConfigControl::OnAction( wxCommandEvent& event )
+{
+    int i_action = event.GetId() - wxID_HIGHEST;
+
+    module_config_t *p_item;
+    p_item = config_FindConfig( p_this, GetName().mb_str() );
+    if( !p_item ) return;
+
+    if( i_action < 0 || i_action >= p_item->i_action ) return;
+
+    vlc_value_t val;
+    val.i_int = GetIntValue();
+    p_item->ppf_action[i_action]( p_this, GetName().mb_str(), val, val, 0 );
+
+    if( p_item->b_dirty )
+    {
+        combo->Clear();
+        UpdateCombo( p_item );
+        p_item->b_dirty = VLC_FALSE;
+    }
+}
+
+int IntegerListConfigControl::GetIntValue()
+{
+    int selected = combo->GetSelection();
+    if( selected != -1 )
+    {
+        return (int)combo->GetClientData( selected );
+    }
+    return -1;
+}
+
+/*****************************************************************************
+ * RangedIntConfigControl implementation
+ *****************************************************************************/
+RangedIntConfigControl::RangedIntConfigControl( vlc_object_t *p_this,
+                                                module_config_t *p_item, 
+                                                HWND parent, HINSTANCE hInst,
+                                                int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    label = new wxStaticText(this, -1, wxU(p_item->psz_text));
+    slider = new wxSlider( this, -1, p_item->i_value, p_item->i_min,
+                           p_item->i_max, wxDefaultPosition, wxDefaultSize,
+                           wxSL_LABELS | wxSL_HORIZONTAL );
+    slider->SetToolTip( wxU(p_item->psz_longtext) );
+    sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+    sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+    sizer->Layout();
+    this->SetSizerAndFit( sizer );
+}
+
+RangedIntConfigControl::~RangedIntConfigControl()
+{
+    ;
+}
+
+int RangedIntConfigControl::GetIntValue()
+{
+    return slider->GetValue();
+}
+
+#endif
+/*****************************************************************************
+ * FloatConfigControl implementation
+ *****************************************************************************/
+FloatConfigControl::FloatConfigControl( vlc_object_t *p_this,
+                                        module_config_t *p_item,
+                                        HWND parent, HINSTANCE hInst,
+                                        int *py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
+                          WS_CHILD | WS_VISIBLE | SS_LEFT,
+                          5, *py_pos, 200, 15,
+                          parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+
+    TCHAR psz_string[100];
+    _stprintf( psz_string, _T("%f"), p_item->f_value );
+    textctrl = CreateWindow( _T("EDIT"), psz_string,
+        WS_CHILD | WS_VISIBLE | WS_BORDER | SS_RIGHT | ES_AUTOHSCROLL,
+        20, *py_pos - 3, 70, 15 + 3, parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+}
+
+FloatConfigControl::~FloatConfigControl()
+{
+    ;
+}
+
+float FloatConfigControl::GetFloatValue()
+{
+    float f_value;
+
+    int i_size = Edit_GetTextLength( textctrl );  
+    TCHAR *psz_string = (TCHAR *)malloc( (i_size + 1) * sizeof(TCHAR) );
+    Edit_GetText( textctrl, psz_string, i_size + 1 );
+
+    if( _tscanf( psz_string, _T("%f"), &f_value ) == 1 )
+    {
+        free( psz_string );
+        return f_value;
+    }
+
+    free( psz_string );
+    return 0.0;
+}
+
+/*****************************************************************************
+ * BoolConfigControl implementation
+ *****************************************************************************/
+BoolConfigControl::BoolConfigControl( vlc_object_t *p_this,
+                                      module_config_t *p_item, HWND parent,
+                                      HINSTANCE hInst, int * py_pos )
+  : ConfigControl( p_this, p_item, parent, hInst )
+{
+    checkbox = CreateWindow( _T("BUTTON"), _T(""),
+                             WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                             5, *py_pos, 15, 15,
+                             parent, NULL, hInst, NULL );
+    Button_SetCheck( checkbox, p_item->i_value ? BST_CHECKED : BST_UNCHECKED );
+
+    checkbox_label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
+                                   WS_CHILD | WS_VISIBLE | SS_LEFT,
+                                   5 + 15 + 5, *py_pos, 180, 15,
+                                   parent, NULL, hInst, NULL );
+
+    *py_pos += 15 + 10;
+}
+
+BoolConfigControl::~BoolConfigControl()
+{
+    ;
+}
+
+int BoolConfigControl::GetIntValue()
+{
+    if( Button_GetCheck( checkbox ) ) return 1;
+    else return 0;
+}
diff --git a/modules/gui/wince/preferences_widgets.h b/modules/gui/wince/preferences_widgets.h
new file mode 100644 (file)
index 0000000..cb0af46
--- /dev/null
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * preferences_widgets.h : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2003 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+class ConfigControl
+{
+public:
+    ConfigControl( vlc_object_t *, module_config_t *, HWND, HINSTANCE );
+    ~ConfigControl();
+    /*wxSizer *Sizer();*/
+
+    virtual int GetIntValue() {return 0;}
+    virtual float GetFloatValue() {return 0;}
+    virtual char *GetPszValue() {return GetName();} // faux retourne nom associé à parent
+        // mettre dans constructeur et dans private le nom du panel associé à HWND
+
+    char *GetName();
+    int GetType();
+    vlc_bool_t IsAdvanced();
+
+    void SetUpdateCallback( void (*)( void * ), void * );
+
+protected:
+    /*wxBoxSizer *sizer;*/
+    HWND label;
+    vlc_object_t *p_this;
+
+    void (*pf_update_callback)( void * );
+    void *p_update_data;
+
+    void OnUpdate( UINT );
+
+private:
+    HWND parent;
+
+    char *name;
+    int i_type;
+    vlc_bool_t b_advanced;
+};
+
+ConfigControl *CreateConfigControl( vlc_object_t *,
+                                    module_config_t *, HWND, HINSTANCE,
+                                    int * );
+
+class KeyConfigControl: public ConfigControl
+{
+public:
+    KeyConfigControl( vlc_object_t *, module_config_t *, HWND,
+                      HINSTANCE, int * );
+    ~KeyConfigControl();
+    virtual int GetIntValue();
+private:
+    HWND alt;
+    HWND alt_label;
+    HWND ctrl;
+    HWND ctrl_label;
+    HWND shift;
+    HWND shift_label;
+    HWND combo;
+
+    // Array of key descriptions, for the ComboBox
+    static string *m_keysList;
+};
+
+class ModuleConfigControl: public ConfigControl
+{
+public:
+    ModuleConfigControl( vlc_object_t *, module_config_t *, HWND,
+                         HINSTANCE, int * );
+    ~ModuleConfigControl();
+    virtual char *GetPszValue();
+private:
+    HWND combo;
+};
+
+class StringConfigControl: public ConfigControl
+{
+public:
+    StringConfigControl( vlc_object_t *, module_config_t *, HWND,
+                         HINSTANCE, int * );
+    ~StringConfigControl();
+    virtual char *GetPszValue();
+private:
+    HWND textctrl;
+};
+
+class StringListConfigControl: public ConfigControl
+{
+public:
+    StringListConfigControl( vlc_object_t *, module_config_t *, HWND,
+                             HINSTANCE, int * );
+    ~StringListConfigControl();
+    virtual char *GetPszValue();
+private:
+};
+
+class FileConfigControl: public ConfigControl
+{
+public:
+    FileConfigControl( vlc_object_t *, module_config_t *, HWND,
+                       HINSTANCE, int * );
+    ~FileConfigControl();
+    void OnBrowse( UINT );
+    virtual char *GetPszValue();
+private:
+};
+
+class IntegerConfigControl: public ConfigControl
+{
+public:
+    IntegerConfigControl( vlc_object_t *, module_config_t *, HWND,
+                          HINSTANCE, int * );
+    ~IntegerConfigControl();
+    virtual int GetIntValue();
+private:
+};
+
+class IntegerListConfigControl: public ConfigControl
+{
+public:
+    IntegerListConfigControl( vlc_object_t *, module_config_t *, HWND,
+                              HINSTANCE, int * );
+    ~IntegerListConfigControl();
+    virtual int GetIntValue();
+private:
+};
+
+class RangedIntConfigControl: public ConfigControl
+{
+public:
+    RangedIntConfigControl( vlc_object_t *, module_config_t *, HWND,
+                            HINSTANCE, int * );
+    ~RangedIntConfigControl();
+    virtual int GetIntValue();
+private:
+};
+
+class FloatConfigControl: public ConfigControl
+{
+public:
+    FloatConfigControl( vlc_object_t *, module_config_t *, HWND,
+                        HINSTANCE, int * );
+    ~FloatConfigControl();
+    virtual float GetFloatValue();
+private:
+    HWND textctrl;
+};
+
+class BoolConfigControl: public ConfigControl
+{
+public:
+    BoolConfigControl( vlc_object_t *, module_config_t *, HWND,
+                       HINSTANCE, int * );
+    ~BoolConfigControl();
+    virtual int GetIntValue();
+private:
+    HWND checkbox;
+    HWND checkbox_label;
+};
diff --git a/modules/gui/wince/subtitles.cpp b/modules/gui/wince/subtitles.cpp
new file mode 100644 (file)
index 0000000..ee166a1
--- /dev/null
@@ -0,0 +1,390 @@
+/*****************************************************************************
+ * subtitles.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2001 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <string.h>
+
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string>
+#include <stdio.h>
+using namespace std;
+
+#include <winuser.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <aygshell.h>
+
+#include <commdlg.h>
+
+#include "wince.h"
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+SubsFileDialog::SubsFileDialog( intf_thread_t *_p_intf, HINSTANCE _hInst )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+    hInst = _hInst;
+}
+
+/***********************************************************************
+
+FUNCTION: 
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+  
+***********************************************************************/
+LRESULT SubsFileDialog::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                                 PBOOL pbProcessed  )
+{
+    SHINITDLGINFO shidi;
+    SHMENUBARINFO mbi;
+    INITCOMMONCONTROLSEX ic;
+    RECT rcClient;
+
+    int size;
+    LPWSTR wUnicode;
+
+    char *psz_subsfile;
+
+    float f_fps;
+    int i_delay;
+    module_config_t *p_item;
+
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    case WM_INITDIALOG:
+        shidi.dwMask = SHIDIM_FLAGS;
+        shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
+        shidi.hDlg = hwnd;
+        SHInitDialog( &shidi );
+
+        //Create the menubar.
+        memset (&mbi, 0, sizeof (SHMENUBARINFO));
+        mbi.cbSize     = sizeof (SHMENUBARINFO);
+        mbi.hwndParent = hwnd;
+        mbi.nToolBarId = IDR_DUMMYMENU;
+        mbi.hInstRes   = hInst;
+        mbi.nBmpId     = 0;
+        mbi.cBmpImages = 0;
+
+        if (!SHCreateMenuBar(&mbi))
+        {
+            MessageBox(hwnd, L"SHCreateMenuBar Failed", L"Error", MB_OK);
+            //return -1;
+        }
+
+        hwndCB = mbi.hwndMB;
+
+        // Get the client area rect to put the panels in
+        GetClientRect(hwnd, &rcClient);
+
+        /* Create the subtitles file textctrl */
+        file_box = CreateWindow( _T("STATIC"), _T("Subtitles file"),
+                                 WS_CHILD | WS_VISIBLE | SS_LEFT,
+                                 5, 10, rcClient.right - 2*5, 15,
+                                 hwnd, NULL, hInst, NULL );
+
+        psz_subsfile = config_GetPsz( p_intf, "sub-file" );
+        if( !psz_subsfile ) psz_subsfile = strdup("");
+        size = MultiByteToWideChar( CP_ACP, 0, psz_subsfile, -1, NULL, 0 );
+        wUnicode = new WCHAR[size];
+        MultiByteToWideChar( CP_ACP, 0, psz_subsfile, -1, wUnicode, size );
+
+        file_combo = CreateWindow( _T("COMBOBOX"), wUnicode,
+            WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL,
+            10, 10 + 15 + 10 - 3, rcClient.right - 2*10, 5*15 + 6,
+            hwnd, NULL, hInst, NULL );
+
+        free( wUnicode );
+        if( psz_subsfile ) free( psz_subsfile );
+
+        browse_button = CreateWindow( _T("BUTTON"), _T("Browse..."),
+                        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                        10, 10 + 2*(15 + 10) - 3, 80, 15 + 6,
+                        hwnd, NULL, hInst, NULL);
+
+        /* Subtitles encoding */
+        encoding_combo = NULL;
+        p_item =
+            config_FindConfig( VLC_OBJECT(p_intf), "subsdec-encoding" );
+        if( p_item )
+         {
+             enc_box = CreateWindow( _T("STATIC"), _T("Subtitles encoding"),
+                        WS_CHILD | WS_VISIBLE | SS_LEFT,
+                        5, 10 + 3*(15 + 10), rcClient.right - 2*5, 15,
+                        hwnd, NULL, hInst, NULL );
+
+             size = MultiByteToWideChar( CP_ACP, 0, p_item->psz_text, -1, NULL, 0 );
+             wUnicode = new WCHAR[size];
+             MultiByteToWideChar( CP_ACP, 0, p_item->psz_text, -1, wUnicode, size );
+
+             enc_label = CreateWindow( _T("STATIC"), wUnicode,
+                WS_CHILD | WS_VISIBLE | SS_LEFT,
+                10, 10 + 4*(15 + 10), rcClient.right - 2*10, 15,
+                hwnd, NULL, hInst, NULL );
+
+             free( wUnicode );
+
+             size = MultiByteToWideChar( CP_ACP, 0, p_item->psz_value, -1, NULL, 0 );
+             wUnicode = new WCHAR[size];
+             MultiByteToWideChar( CP_ACP, 0, p_item->psz_value, -1, wUnicode, size );
+
+             encoding_combo = CreateWindow( _T("COMBOBOX"), wUnicode,
+                WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | LBS_SORT  | WS_VSCROLL,
+                rcClient.right - 150 - 10, 10 + 5*(15 + 10) - 3, 150, 5*15 + 6,
+                hwnd, NULL, hInst, NULL );
+
+             free( wUnicode );
+
+             /* build a list of available options */
+             for( int i_index = 0; p_item->ppsz_list &&
+                    p_item->ppsz_list[i_index]; i_index++ )
+             {
+                 size = MultiByteToWideChar( CP_ACP, 0, p_item->ppsz_list[i_index], -1, NULL, 0 );
+                 wUnicode = new WCHAR[size];
+                 MultiByteToWideChar( CP_ACP, 0, p_item->ppsz_list[i_index], -1, wUnicode, size );
+
+                 ComboBox_AddString( encoding_combo, wUnicode );
+
+                 free( wUnicode );
+
+                 if( p_item->psz_value && !strcmp( p_item->psz_value,
+                                                   p_item->ppsz_list[i_index] ) )
+                   ComboBox_SetCurSel( encoding_combo, i_index );
+             }
+
+             if( p_item->psz_value )
+             {
+                 size = MultiByteToWideChar( CP_ACP, 0, p_item->psz_value, -1, NULL, 0 );
+                 wUnicode = new WCHAR[size];
+                 MultiByteToWideChar( CP_ACP, 0, p_item->psz_value, -1, wUnicode, size );
+
+                 ComboBox_SelectString( encoding_combo, 0, wUnicode );
+
+                 free( wUnicode );
+             }
+         }
+
+        /* Misc Subtitles options */
+        misc_box = CreateWindow( _T("STATIC"), _T("Subtitles options"),
+                                 WS_CHILD | WS_VISIBLE | SS_LEFT,
+                                 5, 10 + 6*(15 + 10), rcClient.right - 2*5, 15,
+                                 hwnd, NULL, hInst, NULL );
+
+        delay_label = CreateWindow( _T("STATIC"), _T("Delay subtitles (in 1/10s)"),
+                                    WS_CHILD | WS_VISIBLE | SS_LEFT,
+                                    10, 10 + 7*(15 + 10), rcClient.right - 70 - 2*10, 15,
+                                    hwnd, NULL, hInst, NULL );
+
+        i_delay = config_GetInt( p_intf, "sub-delay" );
+        wUnicode = new WCHAR[80];
+        swprintf( wUnicode, _T("%d"), i_delay );
+
+        delay_edit = CreateWindow( _T("EDIT"), wUnicode,
+                        WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+                        rcClient.right - 70 - 10, 10 + 7*(15 + 10) - 3, 70, 15 + 6,
+                        hwnd, NULL, hInst, NULL);
+
+        free( wUnicode );
+
+        ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
+        ic.dwICC = ICC_UPDOWN_CLASS;
+        InitCommonControlsEx(&ic);
+
+        delay_spinctrl = CreateUpDownControl(
+                        WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ALIGNRIGHT | UDS_SETBUDDYINT | UDS_NOTHOUSANDS,
+                        0, 0, 0, 0,     hwnd, NULL,     hInst,
+                        delay_edit, 650000, -650000, i_delay );
+
+        fps_label = CreateWindow( _T("STATIC"), _T("Frames per second"),
+                        WS_CHILD | WS_VISIBLE | SS_LEFT,
+                        10, 10 + 8*(15 + 10), rcClient.right - 70 - 2*10, 15,
+                        hwnd, NULL, hInst, NULL );
+
+        f_fps = config_GetFloat( p_intf, "sub-fps" );
+        wUnicode = new WCHAR[80];
+        swprintf( wUnicode, _T("%d"), (int)f_fps );
+
+        fps_edit = CreateWindow( _T("EDIT"), wUnicode,
+                        WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT | ES_AUTOHSCROLL,
+                        rcClient.right - 70 - 10, 10 + 8*(15 + 10) - 3, 70, 15 + 6,
+                        hwnd, NULL, hInst, NULL);
+
+        free( wUnicode );
+
+        ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
+        ic.dwICC = ICC_UPDOWN_CLASS;
+        InitCommonControlsEx(&ic);
+
+        fps_spinctrl = CreateUpDownControl(
+                        WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ALIGNRIGHT | UDS_SETBUDDYINT | UDS_NOTHOUSANDS,
+                        0, 0, 0, 0,     hwnd, NULL,     hInst,
+                        fps_edit, 16000, 0, (int)f_fps );
+
+        return lResult;
+
+    case WM_COMMAND:
+        if ( LOWORD(wp) == IDOK )
+        {
+            int size;
+            BOOL bTemp;
+            LPSTR szAnsi;
+            LPWSTR wUnicode;
+
+            subsfile_mrl.clear();
+
+            string szFileCombo = "sub-file=";
+            size = GetWindowTextLength( file_combo ) + 1;
+            wUnicode = new WCHAR[ size ];
+            GetWindowText( file_combo, wUnicode, size );
+            size = WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, NULL, 0, NULL, &bTemp );
+            szAnsi = new char[size];
+            WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, szAnsi, size, NULL, &bTemp );
+            szFileCombo += szAnsi;
+            free( wUnicode ); free( szAnsi );
+            subsfile_mrl.push_back( szFileCombo );
+
+            if( GetWindowTextLength( encoding_combo ) != 0 )
+            {
+                string szEncoding = "subsdec-encoding=";
+                size = GetWindowTextLength( encoding_combo ) + 1;
+                wUnicode = new WCHAR[ size ];
+                GetWindowText( encoding_combo, wUnicode, size );
+                size = WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, NULL, 0, NULL, &bTemp );
+                szAnsi = new char[size];
+                WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, szAnsi, size, NULL, &bTemp );
+                szEncoding += szAnsi;
+                free( wUnicode ); free( szAnsi );
+                subsfile_mrl.push_back( szEncoding );
+            }
+
+            string szDelay = "sub-delay=";
+            size = Edit_GetTextLength( delay_edit );
+            wUnicode = new WCHAR[size + 1]; //Add 1 for the NULL
+            Edit_GetText( delay_edit, wUnicode, size + 1);
+            size = WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, NULL, 0, NULL, &bTemp );
+            szAnsi = new char[size];
+            WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, szAnsi, size, NULL, &bTemp );
+            szDelay += szAnsi;
+            free( wUnicode ); free( szAnsi );
+            subsfile_mrl.push_back( szDelay );
+
+            string szFps = "sub-fps=";
+            size = Edit_GetTextLength( fps_edit );
+            wUnicode = new WCHAR[size + 1]; //Add 1 for the NULL
+            Edit_GetText( fps_edit, wUnicode, size + 1);
+            size = WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, NULL, 0, NULL, &bTemp );
+            szAnsi = new char[size];
+            WideCharToMultiByte( CP_ACP, 0, wUnicode, -1, szAnsi, size, NULL, &bTemp );
+            szFps += szAnsi;
+            free( wUnicode ); free( szAnsi );
+            subsfile_mrl.push_back( szFps );
+
+            EndDialog( hwnd, LOWORD( wp ) );
+            return TRUE;
+        }
+        if( HIWORD(wp) == BN_CLICKED )
+        {
+            if ((HWND)lp == browse_button)
+            {
+                SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
+                OnFileBrowse();
+                return TRUE;
+            } 
+        }
+
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+
+    default:
+        // the message was not processed
+        // indicate if the base class handled it
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+    }
+
+    return lResult;
+}
+
+/*****************************************************************************
+ * Private methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Events methods.
+ *****************************************************************************/
+void SubsFileDialog::OnFileBrowse()
+{
+    OPENFILENAME ofn;
+    TCHAR DateiName[80+1] = _T("\0");
+    static TCHAR szFilter[] = _T("All (*.*)\0*.*\0");
+
+    memset(&ofn, 0, sizeof(OPENFILENAME));
+    ofn.lStructSize = sizeof (OPENFILENAME);
+    ofn.hwndOwner = NULL;
+    ofn.hInstance = hInst;
+    ofn.lpstrFilter = szFilter;
+    ofn.lpstrCustomFilter = NULL;
+    ofn.nMaxCustFilter = 0;
+    ofn.nFilterIndex = 1;
+    ofn.lpstrFile = (LPTSTR) DateiName;
+    ofn.nMaxFile = 80;
+    ofn.lpstrFileTitle = NULL;
+    ofn.nMaxFileTitle = 40;
+    ofn.lpstrInitialDir = NULL;
+    ofn.lpstrTitle = _T("Open File");
+    ofn.Flags = NULL;
+    ofn.nFileOffset = 0;
+    ofn.nFileExtension = 0;
+    ofn.lpstrDefExt = NULL;
+    ofn.lCustData = 0L;
+    ofn.lpfnHook = NULL;
+    ofn.lpTemplateName = NULL;
+    if( GetOpenFileName((LPOPENFILENAME) &ofn) )
+    {
+        SetWindowText( file_combo, ofn.lpstrFile );
+        ComboBox_AddString( file_combo, ofn.lpstrFile );
+        if( ComboBox_GetCount( file_combo ) > 10 )
+            ComboBox_DeleteString( file_combo, 0 );
+    }
+}
diff --git a/modules/gui/wince/timer.cpp b/modules/gui/wince/timer.cpp
new file mode 100644 (file)
index 0000000..7a85340
--- /dev/null
@@ -0,0 +1,274 @@
+/*****************************************************************************
+ * timer.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2003 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>                                            /* strerror() */
+#include <stdio.h>
+
+#include <string>
+#include <stdio.h>
+using namespace std; 
+
+#include <vlc/vlc.h>
+#include <vlc/aout.h>
+#include <vlc/intf.h>
+
+#include <commctrl.h>
+
+#include "wince.h"
+
+/* Callback prototype */
+static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
+                        vlc_value_t old_val, vlc_value_t new_val, void *param );
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+Timer::Timer( intf_thread_t *_p_intf, HWND hwnd, Interface *_p_main_interface)//, Interface *_p_main_interface )
+{
+    p_intf = _p_intf;
+    p_main_interface = _p_main_interface;
+    i_old_playing_status = PAUSE_S;
+    i_old_rate = INPUT_RATE_DEFAULT;
+
+    /* Register callback for the intf-popupmenu variable */
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist != NULL )
+    {
+        var_AddCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
+        vlc_object_release( p_playlist );
+    }
+
+    SetTimer( hwnd, 1, 200 /*milliseconds*/, NULL );
+}
+
+Timer::~Timer()
+{
+    /* Unregister callback */
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist != NULL )
+    {
+        var_DelCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
+        vlc_object_release( p_playlist );
+    }
+}
+
+/*****************************************************************************
+ * Private methods.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Manage: manage main thread messages
+ *****************************************************************************
+ * In this function, called approx. 10 times a second, we check what the
+ * main program wanted to tell us.
+ *****************************************************************************/
+void Timer::Notify( void )
+{
+    int size;
+    vlc_value_t val;
+    char *shortname;
+    LPWSTR wUnicode;
+
+    vlc_mutex_lock( &p_intf->change_lock );
+
+    /* Update the input */
+    if( p_intf->p_sys->p_input == NULL )
+    {
+        p_intf->p_sys->p_input =
+            (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
+                                               FIND_ANYWHERE );
+
+        /* Show slider */
+        if( p_intf->p_sys->p_input )
+        {
+            ShowWindow( p_main_interface->hwndSlider, SW_SHOW);
+            ShowWindow( p_main_interface->hwndLabel, SW_SHOW);
+            ShowWindow( p_main_interface->hwndVol, SW_SHOW);
+
+            // only for local file, check if works well with net url
+            shortname = strrchr( p_intf->p_sys->p_input->input.p_item->psz_name, '\\' );
+            if (! shortname)
+                shortname = p_intf->p_sys->p_input->input.p_item->psz_name;
+            else
+                shortname++;
+                        
+            size = MultiByteToWideChar (CP_ACP, 0, shortname, -1, NULL, 0);
+            wUnicode = new WCHAR[size+1];
+            MultiByteToWideChar (CP_ACP, 0, shortname, -1, wUnicode + 1, size) ;
+            wUnicode[0] = L'\t';
+
+            SendMessage( p_main_interface->hwndSB, SB_SETTEXT, 
+                         (WPARAM) 0, (LPARAM)(LPCTSTR) wUnicode);
+            free( wUnicode );
+
+            p_main_interface->TogglePlayButton( PLAYING_S );
+            i_old_playing_status = PLAYING_S;
+
+            /* Take care of the volume */
+            audio_volume_t i_volume;
+            aout_VolumeGet( p_intf, &i_volume );                        
+            SendMessage( p_main_interface->hwndVol, TBM_SETPOS, 1,
+                         200 - (i_volume * 200 * 2 / AOUT_VOLUME_MAX ) );
+        }
+    }
+    else if( p_intf->p_sys->p_input->b_dead )
+    {
+        /* Hide slider */
+        ShowWindow( p_main_interface->hwndSlider, SW_HIDE);
+        ShowWindow( p_main_interface->hwndLabel, SW_HIDE);
+        ShowWindow( p_main_interface->hwndVol, SW_HIDE);
+
+        p_main_interface->TogglePlayButton( PAUSE_S );
+        i_old_playing_status = PAUSE_S;
+
+        SendMessage( p_main_interface->hwndSB, SB_SETTEXT, 
+                     (WPARAM) 0, (LPARAM)(LPCTSTR) TEXT(""));
+
+        vlc_object_release( p_intf->p_sys->p_input );
+        p_intf->p_sys->p_input = NULL;
+    }
+
+    if( p_intf->p_sys->p_input )
+    {
+        input_thread_t *p_input = p_intf->p_sys->p_input;
+
+        if( !p_input->b_die )
+        {
+            /* New input or stream map change */
+            p_intf->p_sys->b_playing = 1;
+
+            /* Manage the slider */
+            if( /*p_input->stream.b_seekable &&*/ p_intf->p_sys->b_playing )
+            {
+                /* Update the slider if the user isn't dragging it. */
+                if( p_intf->p_sys->b_slider_free )
+                {
+                    vlc_value_t pos;
+                    char psz_time[ MSTRTIME_MAX_SIZE ];
+                    vlc_value_t time;
+                    mtime_t i_seconds;
+
+                    /* Update the value */
+                    var_Get( p_input, "position", &pos );
+                    if( pos.f_float >= 0.0 )
+                    {
+                        p_intf->p_sys->i_slider_pos =
+                            (int)(SLIDER_MAX_POS * pos.f_float);
+
+                        SendMessage( p_main_interface->hwndSlider,TBM_SETPOS, 
+                                     1, p_intf->p_sys->i_slider_pos );
+
+                        var_Get( p_intf->p_sys->p_input, "time", &time );
+                        i_seconds = time.i_time / 1000000;
+
+                        secstotimestr ( psz_time, i_seconds );
+
+                        size = MultiByteToWideChar (CP_ACP, 0, psz_time, -1, NULL, 0);
+                        wUnicode = new WCHAR[size];
+                        MultiByteToWideChar (CP_ACP, 0, psz_time, -1, wUnicode, size) ;
+                        SendMessage( p_main_interface->hwndLabel, WM_SETTEXT, 
+                                     (WPARAM) 1, (LPARAM)(LPCTSTR) wUnicode );
+                        free( wUnicode );
+                    }
+                }
+            }
+
+            /* Manage Playing status */
+            var_Get( p_input, "state", &val );
+            if( i_old_playing_status != val.i_int )
+            {
+                if( val.i_int == PAUSE_S )
+                {
+                    p_main_interface->TogglePlayButton( PAUSE_S );
+                }
+                else
+                {
+                    p_main_interface->TogglePlayButton( PLAYING_S );
+                }
+                i_old_playing_status = val.i_int;
+            }
+
+            /* Manage Speed status */
+            var_Get( p_input, "rate", &val );
+            if( i_old_rate != val.i_int )
+            {
+                wUnicode = new WCHAR[10];
+                swprintf( wUnicode + 2, TEXT("x%.2f"), 1000.0 / val.i_int );
+                wUnicode[0] = L'\t';
+                wUnicode[1] = L'\t';
+
+                SendMessage( p_main_interface->hwndSB, SB_SETTEXT, 
+                             (WPARAM) 1, (LPARAM)(LPCTSTR) wUnicode);
+
+                free(wUnicode); 
+
+                i_old_rate = val.i_int;
+            }
+        }
+    }
+    else if( p_intf->p_sys->b_playing && !p_intf->b_die )
+    {
+        p_intf->p_sys->b_playing = 0;
+        p_main_interface->TogglePlayButton( PAUSE_S );
+        i_old_playing_status = PAUSE_S;
+    }
+
+    if( p_intf->b_die )
+    {
+        vlc_mutex_unlock( &p_intf->change_lock );
+
+        /* Prepare to die, young Skywalker */
+/*        p_main_interface->Close(TRUE);*/
+        return;
+    }
+
+    vlc_mutex_unlock( &p_intf->change_lock );
+}
+
+/*****************************************************************************
+ * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
+ *  We don't show the menu directly here because we don't want the
+ *  caller to block for a too long time.
+ *****************************************************************************/
+static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
+                        vlc_value_t old_val, vlc_value_t new_val, void *param )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)param;
+
+    if( p_intf->p_sys->pf_show_dialog )
+    {
+        p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
+                                       new_val.b_bool, 0 );
+    }
+
+    return VLC_SUCCESS;
+}
diff --git a/modules/gui/wince/video.cpp b/modules/gui/wince/video.cpp
new file mode 100644 (file)
index 0000000..c784e22
--- /dev/null
@@ -0,0 +1,267 @@
+/*****************************************************************************
+ * video.cpp : WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2000-2004, 2003 VideoLAN
+ * $Id$
+ *
+ * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/intf.h>
+
+#include "wince.h"
+
+static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *,
+                        int *pi_x_hint, int *pi_y_hint,
+                        unsigned int *pi_width_hint,
+                        unsigned int *pi_height_hint );
+static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
+
+static int ControlWindow( intf_thread_t *p_intf, void *p_window,
+                          int i_query, va_list args );
+
+/* IDs for the controls and the menu commands */
+enum
+{
+    UpdateSize_Event = 1000 + 1,
+    UpdateHide_Event
+};
+
+/* Video Window */
+class VideoWindow : public CBaseWindow
+{
+public:
+    /* Constructor */
+    VideoWindow( intf_thread_t *_p_intf, HINSTANCE _hInst, HWND _p_parent );
+    virtual ~VideoWindow();
+
+    void *GetWindow( vout_thread_t *, int *, int *, unsigned int *,
+                     unsigned int * );
+    void ReleaseWindow( void * );
+    int  ControlWindow( void *, int, va_list );
+       
+    HWND p_child_window; // public because of menu
+
+private:
+    intf_thread_t *p_intf;
+    vout_thread_t *p_vout;
+    HWND p_parent;
+    vlc_mutex_t lock;
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                            WPARAM wParam, LPARAM lParam, PBOOL pbProcessed );
+};
+
+/*****************************************************************************
+ * Public methods.
+ *****************************************************************************/
+CBaseWindow *CreateVideoWindow( intf_thread_t *p_intf, HINSTANCE hInst,
+                               HWND p_parent )
+{
+    return new VideoWindow( p_intf, hInst, p_parent );
+}
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+VideoWindow::VideoWindow( intf_thread_t *_p_intf, HINSTANCE _hInst,
+                          HWND _p_parent )
+{
+    RECT rect;
+    WNDCLASS wc;
+
+    /* Initializations */
+    p_intf = _p_intf;
+    p_parent = _p_parent;
+    p_child_window = NULL;
+
+    vlc_mutex_init( p_intf, &lock );
+
+    p_vout = NULL;
+
+    p_intf->pf_request_window = ::GetWindow;
+    p_intf->pf_release_window = ::ReleaseWindow;
+
+    p_intf->p_sys->p_video_window = this;
+
+    GetClientRect( p_parent, &rect );
+
+    wc.style = CS_HREDRAW | CS_VREDRAW ;
+    wc.lpfnWndProc = (WNDPROC)BaseWndProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hIcon = NULL;
+    wc.hInstance = _hInst;
+    wc.hCursor = NULL;
+    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+    wc.lpszMenuName = NULL;
+    wc.lpszClassName = _T("VIDEOWINDOW");
+    RegisterClass( &wc );
+
+    p_child_window = CreateWindow (
+        _T("VIDEOWINDOW"), _T(""), WS_CHILD | WS_VISIBLE | WS_BORDER,
+        0, 20, rect.right - rect.left,
+        rect.bottom - rect.top - 2*(MENU_HEIGHT-1) - SLIDER_HEIGHT - 20,
+        p_parent, NULL, _hInst, (void *)this );
+
+    // ShowWindow( p_child_window, 1 );
+    UpdateWindow( p_child_window );
+
+    ReleaseWindow( (void*)p_child_window );
+}
+
+VideoWindow::~VideoWindow()
+{
+    vlc_mutex_destroy( &lock );
+}
+
+/*****************************************************************************
+ * Private methods.
+ *****************************************************************************/
+static void *GetWindow( intf_thread_t *p_intf,  vout_thread_t *p_vout,
+                        int *pi_x_hint, int *pi_y_hint,
+                        unsigned int *pi_width_hint,
+                        unsigned int *pi_height_hint )
+{
+    return p_intf->p_sys->p_video_window->GetWindow( p_vout, pi_x_hint,
+                                    pi_y_hint, pi_width_hint, pi_height_hint );
+}
+
+void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
+                              int *pi_x_hint, int *pi_y_hint,
+                              unsigned int *pi_width_hint,
+                              unsigned int *pi_height_hint )
+{
+    vlc_mutex_lock( &lock );
+
+    if( p_vout )
+    {
+        vlc_mutex_unlock( &lock );
+        msg_Dbg( p_intf, "Video window already in use" );
+        return NULL;
+    }
+
+    p_vout = _p_vout;
+
+    vlc_mutex_unlock( &lock );
+
+    return p_child_window;
+}
+
+static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
+{
+    p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
+}
+
+void VideoWindow::ReleaseWindow( void *p_window )
+{
+    vlc_mutex_lock( &lock );
+
+    p_vout = NULL;
+    ShowWindow( (HWND)p_window, SW_HIDE );
+
+    vlc_mutex_unlock( &lock );
+}
+
+/***********************************************************************
+
+FUNCTION:
+  WndProc
+
+PURPOSE: 
+  Processes messages sent to the main window.
+
+***********************************************************************/
+LRESULT VideoWindow::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                              PBOOL pbProcessed  )
+{
+    LRESULT lResult = CBaseWindow::WndProc( hwnd, msg, wp, lp, pbProcessed );
+    BOOL bWasProcessed = *pbProcessed;
+    *pbProcessed = TRUE;
+
+    switch( msg )
+    {
+    default:
+        // the message was not processed
+        // indicate if the base class handled it
+        *pbProcessed = bWasProcessed;
+        lResult = FALSE;
+        return lResult;
+    }
+
+    return lResult;
+}
+
+static int ControlWindow( intf_thread_t *p_intf, void *p_window,
+                          int i_query, va_list args )
+{
+    return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
+                                                         args );
+}
+
+int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
+{
+    int i_ret = VLC_EGENERIC;
+
+    vlc_mutex_lock( &lock );
+
+    switch( i_query )
+    {
+        case VOUT_SET_ZOOM:
+        {
+            double f_arg = va_arg( args, double );
+
+#if 0
+            /* Update dimensions */
+            wxSizeEvent event( wxSize((int)(p_vout->i_window_width * f_arg),
+                                      (int)(p_vout->i_window_height * f_arg)),
+                               UpdateSize_Event );
+            AddPendingEvent( event );
+#endif
+
+            i_ret = VLC_SUCCESS;
+        }
+        break;
+
+        case VOUT_SET_STAY_ON_TOP:
+        {
+            int i_arg = va_arg( args, int );
+#if 0
+            wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
+            event.SetInt( i_arg );
+            AddPendingEvent( event );
+#endif
+
+            i_ret = VLC_SUCCESS;
+        }
+        break;
+
+        default:
+            msg_Dbg( p_intf, "control query not supported" );
+            break;
+    }
+
+    vlc_mutex_unlock( &lock );
+
+    return i_ret;
+}
diff --git a/modules/gui/wince/wince.cpp b/modules/gui/wince/wince.cpp
new file mode 100644 (file)
index 0000000..e9826a1
--- /dev/null
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * wince.cpp: WinCE gui plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id$
+ *
+ * Author: Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111,
+ * USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+
+#include "wince.h"
+
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
+static int  Open   ( vlc_object_t * );
+static void Close  ( vlc_object_t * );
+static void Run    ( intf_thread_t * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+    set_description( (char *) _("WinCE interface module") );
+    set_capability( "interface", 200 );
+    set_callbacks( Open, Close );
+    add_shortcut( "wince" );
+    set_program( "wcevlc" );
+vlc_module_end();
+
+HINSTANCE hInstance = 0;
+
+#if !defined(__BUILTIN__)
+extern "C" BOOL WINAPI
+DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
+{
+    hInstance = (HINSTANCE)hModule;
+    return TRUE;
+}
+#endif
+
+/*****************************************************************************
+ * Open: initialize interface
+ *****************************************************************************/
+static int Open ( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+
+    // Allocate instance and initialize some members
+    p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        msg_Err( p_intf, "out of memory" );
+        return VLC_EGENERIC;
+    }
+
+    // Suscribe to messages bank
+    p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
+
+    // Misc init
+    p_intf->p_sys->p_audio_menu = NULL;
+    p_intf->p_sys->p_video_menu = NULL;
+    p_intf->p_sys->p_navig_menu = NULL;
+    p_intf->p_sys->p_settings_menu = NULL;
+
+    p_intf->pf_run = Run;
+
+    p_intf->p_sys->p_input = NULL;
+    p_intf->p_sys->b_playing = 0;
+    p_intf->p_sys->i_playing = -1;
+    p_intf->p_sys->b_slider_free = 1;
+    p_intf->p_sys->i_slider_pos = p_intf->p_sys->i_slider_oldpos = 0;
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Close: destroy interface
+ *****************************************************************************/
+static void Close ( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+
+    if( p_intf->p_sys->p_input )
+    {
+        vlc_object_release( p_intf->p_sys->p_input );
+    }
+
+    // Unsuscribe to messages bank
+    msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
+
+    // Destroy structure
+    free( p_intf->p_sys );
+}
+
+/*****************************************************************************
+ * Run: main loop
+ *****************************************************************************/
+static void Run( intf_thread_t *p_intf )
+{
+    MSG msg;
+    Interface *pInterface = new Interface();
+
+    if( !pInterface->InitInstance( hInstance, p_intf ) ) return;
+
+    // Main message loop
+    int status;
+    while( ( status = GetMessage( &msg, NULL, 0, 0 ) ) != 0 )
+    {
+        if( status == -1 ) return;
+        TranslateMessage( &msg );
+        DispatchMessage( &msg );
+    }
+}
diff --git a/modules/gui/wince/wince.h b/modules/gui/wince/wince.h
new file mode 100644 (file)
index 0000000..38dc261
--- /dev/null
@@ -0,0 +1,658 @@
+/*****************************************************************************
+ * wince.h: private WinCE interface descriptor
+ *****************************************************************************
+ * Copyright (C) 1999-2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Gildas Bazin <gbazin@videolan.org>
+ *          Marodon Cedric <cedric_marodon@yahoo.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#ifndef WINCE_RESOURCE
+
+#define MENU_HEIGHT 26
+#define SLIDER_HEIGHT 50
+
+#define SLIDER_MAX_POS 10000
+
+#define FILE_ACCESS 1
+#define NET_ACCESS 2
+
+#define OPEN_NORMAL 0
+#define OPEN_STREAM 1
+
+#include "vlc_keys.h"
+
+#include <stdio.h>
+#include <string>
+#include <vector>
+using namespace std; 
+
+vector<string> SeparateEntries( LPWSTR entries );
+
+class MenuItemExt;
+class VideoWindow;
+
+/*****************************************************************************
+ * intf_sys_t: description and status of wxwindows interface
+ *****************************************************************************/
+struct intf_sys_t
+{
+    /* special actions */
+    vlc_bool_t          b_playing;
+
+    /* The input thread */
+    input_thread_t *    p_input;
+
+    /* The slider */
+    int                 i_slider_pos;                     /* slider position */
+    int                 i_slider_oldpos;                /* previous position */
+    vlc_bool_t          b_slider_free;                      /* slider status */
+
+    /* The messages window */
+    msg_subscription_t* p_sub;                  /* message bank subscription */
+
+    /* Playlist management */
+    int                 i_playing;                 /* playlist selected item */
+
+    /* Send an event to show a dialog */
+    void (*pf_show_dialog) ( intf_thread_t *p_intf, int i_dialog, int i_arg,
+                             intf_dialog_args_t *p_arg );
+
+    /* Dynamic Menu management */
+    vector<MenuItemExt*> *p_audio_menu;
+    vector<MenuItemExt*> *p_video_menu;
+    vector<MenuItemExt*> *p_navig_menu;
+    vector<MenuItemExt*> *p_settings_menu;
+
+    VideoWindow          *p_video_window;
+};
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+class CBaseWindow
+{
+public:
+   CBaseWindow(){ hInst = 0; }
+   virtual ~CBaseWindow() {};
+
+   HWND hWnd;                // The main window handle
+   BOOL DlgFlag;             // True if object is a dialog window
+
+   static LRESULT CALLBACK BaseWndProc( HWND hwnd, UINT msg,
+                                        WPARAM wParam, LPARAM lParam );
+
+protected:
+
+   HINSTANCE       hInst;               // The current instance
+   HWND            hwndCB;              // The command bar handle
+
+   HINSTANCE       GetInstance () const { return hInst; }
+   virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                            WPARAM wParam, LPARAM lParam,
+                            PBOOL pbProcessed ){*pbProcessed = FALSE; return 0;}
+};
+
+class FileInfo;
+class Messages;
+class Playlist;
+class Timer;
+class OpenDialog;
+class PrefsDialog;
+
+CBaseWindow *CreateVideoWindow( intf_thread_t *, HINSTANCE, HWND );
+
+/* Main Interface */
+class Interface : public CBaseWindow
+{
+public:
+    /* Constructor */
+    Interface(){}
+    ~Interface(){}
+
+    BOOL InitInstance( HINSTANCE hInstance, intf_thread_t *_pIntf );
+
+    void TogglePlayButton( int i_playing_status );
+
+    HWND hwndMain;      // Handle to the main window.
+
+    HWND hwndCB;        // Handle to the command bar (contains menu)
+    HWND hwndTB;        // Handle to the toolbar.
+    HWND hwndSlider;       // Handle to the Sliderbar.
+    HWND hwndLabel;
+    HWND hwndVol;          // Handle to the volume trackbar.
+    HWND hwndSB;        // Handle to the status bar.
+    HMENU hPopUpMenu;
+    HMENU hMenu;
+    FileInfo *fi; // pas besoin de la plupart de ses attributs
+    Messages *hmsg;
+    PrefsDialog *pref;
+    Playlist *pl;
+    Timer *ti;
+    OpenDialog *open;
+    CBaseWindow *video;
+    HWND hwndVideo;
+
+protected:
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
+                             PBOOL pbProcessed );
+
+    HWND WINAPI CreateToolbar( HWND );
+    HWND WINAPI CreateSliderbar( HWND );
+    HWND WINAPI CreateStaticText( HWND );
+    HWND WINAPI CreateVolTrackbar( HWND );
+    HWND WINAPI CreateStatusbar( HWND );
+
+    void OnOpenFileSimple( void );
+    void OnPlayStream( void );
+    void OnVideoOnTop( void );
+
+    void OnSliderUpdate( int wp );
+    void OnChange( int wp );
+    void Change( int i_volume );
+    void OnStopStream( void );
+    void OnPrevStream( void );
+    void OnNextStream( void );
+    void OnSlowStream( void );
+    void OnFastStream( void );
+
+    intf_thread_t *pIntf;
+
+    int i_old_playing_status;
+};
+
+/* File Info */
+class FileInfo : public CBaseWindow
+{
+public:
+    /* Constructor */
+    FileInfo( intf_thread_t *_p_intf, HINSTANCE _hInst );
+    virtual ~FileInfo(){};
+
+protected:
+
+    HWND hwnd_fileinfo;                 // handle to fileinfo window
+    HWND hwndTV;                                // handle to tree-view control 
+    intf_thread_t *p_intf;
+
+    TCHAR szFileInfoClassName[100];     // Main window class name
+    TCHAR szFileInfoTitle[100];         // Main window name
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                             WPARAM wParam, LPARAM lParam, PBOOL pbProcessed );
+    void UpdateFileInfo( HWND );
+    BOOL CreateTreeView( HWND );
+};
+
+/* Messages */
+class Messages : public CBaseWindow
+{
+public:
+    /* Constructor */
+    Messages( intf_thread_t *_p_intf, HINSTANCE _hInst );
+    virtual ~Messages(){};
+
+protected:
+
+    intf_thread_t *p_intf;
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                             WPARAM wParam, LPARAM lParam,
+                             PBOOL pbProcessed );
+
+    HWND hListView;
+    void UpdateLog(void);
+
+    vlc_bool_t b_verbose;
+};
+
+/* ItemInfo Dialog */
+class ItemInfoDialog : public CBaseWindow
+{
+public:
+    /* Constructor */
+    ItemInfoDialog( intf_thread_t *, HINSTANCE, playlist_item_t * );
+    virtual ~ItemInfoDialog(){};
+
+protected:
+
+    intf_thread_t *p_intf;
+    HWND hwndCB;        // Handle to the command bar (but no menu)
+
+    playlist_item_t *p_item;
+
+    /* Event handlers (these functions should _not_ be virtual) */
+    void OnOk();
+    void UpdateInfo();
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                             WPARAM wParam, LPARAM lParam,
+                             PBOOL pbProcessed );
+
+    /* Controls for the iteminfo dialog box */
+    HWND uri_label;
+    HWND uri_text;
+
+    HWND name_label;
+    HWND name_text;
+
+    HWND author_label;
+    HWND author_text;
+
+    HWND checkbox_label;
+    HWND enabled_checkbox;
+
+    HWND info_tree;
+};
+
+/* Open Dialog */
+class SubsFileDialog;
+class OpenDialog : public CBaseWindow
+{
+public:
+    /* Constructor */
+    OpenDialog( intf_thread_t *_p_intf, HINSTANCE _hInst,
+                int _i_access_method, int _i_arg, int _i_method );
+    virtual ~OpenDialog(){};
+
+    void UpdateMRL();
+    void UpdateMRL( int i_access_method );
+
+protected:
+
+    intf_thread_t *p_intf;
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                             WPARAM wParam, LPARAM lParam,
+                             PBOOL pbProcessed );
+
+    HWND mrl_box;
+    HWND mrl_label;
+    HWND mrl_combo;
+    HWND label;
+
+    HWND notebook;
+
+    HWND file_combo;
+    HWND browse_button;
+    HWND subsfile_checkbox;
+    HWND subsfile_label;
+    HWND subsfile_button;
+    SubsFileDialog *subsfile_dialog;
+
+    HWND net_radios[4];
+    HWND net_label[4];
+
+    HWND net_port_label[4];
+    HWND net_ports[4];
+    HWND hUpdown[4];
+    int i_net_ports[4];
+
+    HWND net_addrs_label[4];
+    HWND net_addrs[4];
+        
+    int i_current_access_method;
+    int i_method; /* Normal or for the stream dialog ? */
+    int i_open_arg;
+    int i_net_type;
+        
+    void FilePanel( HWND hwnd );
+    void NetPanel( HWND hwnd );
+
+    void OnSubsFileEnable();
+    void OnSubsFileSettings( HWND hwnd );
+
+    void OnPageChange();
+
+    void OnFilePanelChange();
+    void OnFileBrowse();
+    void OnNetPanelChange( int event );
+    void OnNetTypeChange( int event );
+    void DisableNETCtrl();
+
+    void OnOk();
+
+    vector<string> mrl;
+    vector<string> subsfile_mrl;
+};
+
+/* Subtitles File Dialog */
+class SubsFileDialog: public CBaseWindow
+{
+public:
+    /* Constructor */
+    SubsFileDialog( intf_thread_t *_p_intf, HINSTANCE _hInst );
+    virtual ~SubsFileDialog(){};
+
+    vector<string> subsfile_mrl;
+
+protected:
+    friend class OpenDialog;
+
+    intf_thread_t *p_intf;
+
+    HWND file_box;
+    HWND file_combo;
+    HWND browse_button;
+
+    HWND enc_box;
+    HWND enc_label;
+    HWND encoding_combo;
+
+    HWND misc_box;
+    HWND delay_label;
+    HWND delay_edit;
+    HWND delay_spinctrl;
+    HWND fps_label;
+    HWND fps_edit;
+    HWND fps_spinctrl;
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                             WPARAM wParam, LPARAM lParam,
+                             PBOOL pbProcessed );
+
+    /* Event handlers (these functions should _not_ be virtual) */
+    void OnFileBrowse();
+};
+
+/* Playlist */
+class Playlist : public CBaseWindow
+{
+public:
+    /* Constructor */
+    Playlist( intf_thread_t *_p_intf, HINSTANCE _hInst );
+    virtual ~Playlist(){};
+
+protected:
+
+    bool b_need_update;
+    vlc_mutex_t lock;
+
+    int i_title_sorted;
+    int i_author_sorted;
+
+    intf_thread_t *p_intf;
+    HWND hwndCB;        // Handle to the command bar (contains menu)
+    HWND hwndTB;        // Handle to the toolbar.
+    HWND hListView;
+
+    void UpdatePlaylist();
+    void Rebuild();
+    void UpdateItem( int );
+    LRESULT ProcessCustomDraw( LPARAM lParam );
+    void HandlePopupMenu( HWND hwnd, POINT point);
+
+    void DeleteItem( int item );
+
+    void OnOpen();
+    void OnSave();
+    void OnAddFile();
+    void OnAddMRL();
+
+    void OnDeleteSelection();
+    void OnInvertSelection();
+    void OnEnableSelection();
+    void OnDisableSelection();
+    void OnSelectAll();
+    void OnActivateItem( int i_item );
+    void ShowInfos( HWND hwnd, int i_item );
+
+    void OnUp();
+    void OnDown();
+
+    void OnRandom();
+    void OnLoop();
+    void OnRepeat();
+
+    void OnSort( UINT event );
+    void OnColSelect( int iSubItem );
+
+    void OnPopupPlay();
+    void OnPopupDel();
+    void OnPopupEna();
+    void OnPopupInfo( HWND hwnd );
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                             WPARAM wParam, LPARAM lParam,
+                             PBOOL pbProcessed );
+};
+
+/* Timer */
+class Timer
+{
+public:
+    /* Constructor */
+    Timer( intf_thread_t *p_intf, HWND hwnd, Interface *_p_main_interface);
+    virtual ~Timer();
+    void Notify( void ); 
+
+private:
+    intf_thread_t *p_intf;
+    Interface *p_main_interface;
+    //Interface *p_main_interface;
+    int i_old_playing_status;
+    int i_old_rate;
+};
+
+/* Menus */
+void RefreshSettingsMenu( intf_thread_t *_p_intf, HMENU hMenu );
+void RefreshAudioMenu( intf_thread_t *_p_intf, HMENU hMenu );
+void RefreshVideoMenu( intf_thread_t *_p_intf, HMENU hMenu );
+void RefreshNavigMenu( intf_thread_t *_p_intf, HMENU hMenu );
+void RefreshMenu( intf_thread_t *, vector<MenuItemExt*> *, HMENU, int,
+                  char **, int *, int );
+int wce_GetMenuItemCount( HMENU );
+void CreateMenuItem( intf_thread_t *, vector<MenuItemExt*> *, HMENU, char *,
+                     vlc_object_t *, int * );
+HMENU CreateChoicesMenu( intf_thread_t *, vector<MenuItemExt*> *, char *, 
+                         vlc_object_t *, int * );
+void OnMenuEvent( intf_thread_t *, int );
+
+/*****************************************************************************
+ * A small helper class which encapsulate wxMenuitem with some other useful
+ * things.
+ *****************************************************************************/
+class MenuItemExt
+{
+public:
+    /* Constructor */
+    MenuItemExt( intf_thread_t *_p_intf, int _id, char *_psz_var,
+                 int _i_object_id, vlc_value_t _val, int _i_val_type );
+
+    virtual ~MenuItemExt();
+
+    int id;
+    intf_thread_t *p_intf;
+    char *psz_var;
+    int  i_val_type;
+    int  i_object_id;
+    vlc_value_t val;
+
+private:
+
+};
+
+
+/* Preferences Dialog */
+/* Preferences Dialog */
+class PrefsTreeCtrl;
+class PrefsDialog: public CBaseWindow
+{
+public:
+    /* Constructor */
+    PrefsDialog( intf_thread_t *_p_intf, HINSTANCE _hInst );
+    virtual ~PrefsDialog(){};
+
+protected:
+
+    intf_thread_t *p_intf;
+
+    /* Event handlers (these functions should _not_ be virtual) */
+    void OnOk( void );
+    /*void OnCancel( UINT event );
+    void OnSave( UINT event );
+    void OnResetAll( UINT event );
+    void OnAdvanced( UINT event );*/
+
+    HWND save_button;
+    HWND reset_button;
+    HWND advanced_checkbox;
+    HWND advanced_label;
+
+    PrefsTreeCtrl *prefs_tree;
+
+    virtual LRESULT WndProc( HWND hwnd, UINT msg,
+                             WPARAM wParam, LPARAM lParam,
+                             PBOOL pbProcessed );
+};
+
+/*****************************************************************************
+ * A small helper function for utf8 <-> unicode conversions
+ *****************************************************************************/
+#ifdef UNICODE
+    static wchar_t pwsz_mbtow[2048];
+    static char psz_wtomb[2048];
+    static inline wchar_t *_FROMMB( const char *psz_in )
+    {
+        mbstowcs( pwsz_mbtow, psz_in, 2048 );
+        pwsz_mbtow[2048] = 0;
+        return pwsz_mbtow;
+    }
+    static inline char *_TOMB( const wchar_t *pwsz_in )
+    {
+        wcstombs( psz_wtomb, pwsz_in, 2048 );
+        psz_wtomb[2048] = 0;
+        return psz_wtomb;
+    }
+#else
+#   define _FROMMB(a)
+#   define _TOMB(a)
+#endif
+
+#if defined( ENABLE_NLS ) && defined( ENABLE_UTF8 )
+#   define ISUTF8 1
+#else // ENABLE_NLS && ENABLE_UTF8
+#   define ISUTF8 0
+#endif
+
+#endif //WINCE_RESOURCE
+
+#define IDD_ABOUT                       101
+#define IDI_ICON1                       102
+#define IDB_BITMAP1                     103
+#define IDB_BITMAP2                     111
+#define IDR_MENUBAR1                    113
+#define IDR_ACCELERATOR1                116
+#define IDD_FILEINFO                    118
+#define IDD_DUMMY                       118
+#define IDD_MESSAGES                    119
+#define IDR_MENUBAR                     120
+#define IDR_MENUBAR2                    121
+#define IDD_PLAYLIST                    122
+#define IDB_BITMAP3                     123
+#define IDD_ITEMINFO                    124
+#define IDR_DUMMYMENU                   126
+#define IDCLEAR                         1001
+#define IDSAVEAS                        1002
+#define IDC_TEXTCTRL                    1004
+#define IDC_CUSTOM1                     1012
+#define IDS_MAIN_MENUITEM1              40001
+#define IDS_TITLE                       40002
+#define IDS_CLASSNAME                   40003
+#define IDS_CAP_QUICKFILEOPEN           40006
+#define IDS_CAP_VIEW                    40009
+#define IDS_CAP_SETTINGS                40012
+#define IDS_CAP_AUDIO                   40015
+#define IDS_CAP_VIDEO                   40018
+#define IDS_CAP_HELP                    40021
+#define IDS_CAP_Navigation              40024
+#define IDS_CAP_FILE                    40025
+#define ID_COLOR_OPTIONS                40026
+#define IDS_DYNAMENU                    40027
+#define ID_FILE                         40028
+#define IDS_BLACK                       40028
+#define IDS_LTGRAY                      40029
+#define ID_VIEW                         40030
+#define IDS_DKGRAY                      40030
+#define IDS_WHITE                       40031
+#define ID_SETTINGS                     40032
+#define ID_AUDIO                        40034
+#define ID_EMPTY                        40034
+#define ID_VIDEO                        40036
+#define ID_NAVIGATION                   40038
+#define IDM_FILE                        40042
+#define IDM_VIEW                        40044
+#define IDM_SETTINGS                    40046
+#define IDM_AUDIO                       40048
+#define IDM_VIDEO                       40050
+#define IDM_NAVIGATION                  40053
+#define ID_FILE_QUICK_OPEN              40056
+#define ID_FILE_OPENFILE                40057
+#define ID_FILE_QUICKOPEN               40058
+#define ID_FILE_OPENNETWORKSTREAM       40059
+#define ID_FILE_OPENNET                 40060
+#define ID_FILE_EXIT                    40061
+#define ID_VIEW_PLAYLIST                40063
+#define ID_VIEW_MESSAGES                40064
+#define ID_VIEW_MEDIAINFO               40065
+#define ID_VIEW_STREAMINFO              40066
+#define IDS_CAP_NAV                     40067
+#define ID_FILE_ABOUT                   40069
+#define ID_SETTINGS_PREF                40071
+#define ID_SETTINGS_EXTEND              40072
+#define IDS_CAP_XXX                     40084
+#define IDM_MANAGE                      40087
+#define IDM_SORT                        40088
+#define IDM_SEL                         40089
+#define ID_SORT_AUTHOR                  40091
+#define ID_SORT_RAUTHOR                 40092
+#define ID_SORT_SHUFFLE                 40095
+#define ID_SEL_INVERT                   40096
+#define ID_SEL_DELETE                   40097
+#define ID_SEL_SELECTALL                40098
+#define ID_SEL_ENABLE                   40100
+#define ID_SEL_DISABLE                  40101
+#define ID_SORT_TITLE                   40102
+#define ID_SORT_RTITLE                  40103
+#define ID_MANAGE_SIMPLEADD             40104
+#define ID_MANAGE_OPENPL                40105
+#define ID_MANAGE_ADDMRL                40106
+#define ID_MANAGE_SAVEPL                40107
+#define ID_MENUITEM40108                40108
+#define IDS_CAP_MENUITEM40109           40110
+#define IDS_STOP                        57601
+#define StopStream_Event                57601
+#define IDS_PLAY                        57602
+#define PlayStream_Event                57602
+#define PrevStream_Event                57603
+#define NextStream_Event                57604
+#define SlowStream_Event                57605
+#define FastStream_Event                57606
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        128
+#define _APS_NEXT_COMMAND_VALUE         40111
+#define _APS_NEXT_CONTROL_VALUE         1013
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif