[MPlayer-cvslog] r18919 - in trunk/Gui/win32: . Changelog README dialogs.c dialogs.h gui.c gui.h interface.c playlist.c playlist.h preferences.c skinload.c skinload.h widgetrender.c wincfg.c wincfg.h

vayne subversion at mplayerhq.hu
Thu Jul 6 04:07:06 CEST 2006


Author: vayne
Date: Thu Jul  6 04:07:03 2006
New Revision: 18919

Added:
   trunk/Gui/win32/
   trunk/Gui/win32/Changelog
   trunk/Gui/win32/README
   trunk/Gui/win32/dialogs.c
   trunk/Gui/win32/dialogs.h
   trunk/Gui/win32/gui.c
   trunk/Gui/win32/gui.h
   trunk/Gui/win32/interface.c
   trunk/Gui/win32/playlist.c
   trunk/Gui/win32/playlist.h
   trunk/Gui/win32/preferences.c
   trunk/Gui/win32/skinload.c
   trunk/Gui/win32/skinload.h
   trunk/Gui/win32/widgetrender.c
   trunk/Gui/win32/wincfg.c
   trunk/Gui/win32/wincfg.h

Log:
Initial win32 gui release.

Added: trunk/Gui/win32/Changelog
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/Changelog	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,317 @@
+HISTORY
+2006/06/30 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed display of wrong aspect ratios.
+
+2006/06/13 - Erik Augustson <erik_27can at yahoo.com>
+- Minor bugfixes.
+- Updated to current SVN
+
+2006/04/14 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed a crash bug.
+- Fixed a major fullscreen bug (WinID wasn't getting
+  reset when FS switching).
+
+2006/04/13 - Erik Augustson <erik_27can at yahoo.com>
+- More minor fixups
+
+2006/04/07 - Erik Augustson <erik_27can at yahoo.com>
+- Minor fixups to openurl and openfile from dialogs.c
+
+2006/04/06 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed IPC and drag&drop appending files to the
+  playlist instead of opening them right away.
+- Updated dvdnav patch.
+
+2006/04/03 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed a long pathnames issue with WM_COPYDATA.
+- Fixed a minor crash happening when rendering the
+  codec name.
+- Some code cleanup.
+
+2006/04/01 - Erik Augustson <erik_27can at yahoo.com>
+- Added ability to enable/disable videos displaying
+  in the sub window in preferences.
+- Small fix in update_subwindow() for coming out
+  of fullscreen when the sub window was minimized.
+
+2006/03/27 - Erik Augustson <erik_27can at yahoo.com>
+- Updated to current CVS.
+- Debug console now shows the extensions mplayer
+  was compiled with.
+
+2006/03/23 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed using -playlist and -shuffle.
+
+2006/03/22 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed a small bug with input events for dialogs.
+
+2006/03/16 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed left button mouse event in dvdnav patch.
+- More aspect fixes.
+- Fixed double-click in the playlist.
+- Fixed some drag&drop functionality.
+
+2006/03/14 - Erik Augustson <erik_27can at yahoo.com>
+- Simplified title/chapter selection dialog.
+- Code cleanup.
+
+2006/03/14 - Erik Augustson <erik_27can at yahoo.com>
+
+- Fixed resetting aspect on file ending in mplEnd()
+
+2006/03/13 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed double click events, forgot to add CS_DBLCLKS
+  to sub window's window style.
+- Fixed window focusing with drag&drop files.
+- Re-arranged some menu items, and added support for
+  runtime aspect switching. This adds 3 lines to
+  mplayer.c but is well worth it IMO.
+
+2006/03/12 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed window positioning for both windows.
+- Added more mouse button events.
+
+2006/03/10 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed mouse and sub window vanishing after coming
+  out of fullscreen by end of file.
+- Fixed sub window popping up when switching to
+  fullscreen and *not* using directx.
+- Added codec name to widgets to properly render
+  in some skins.
+- Middle and scroll wheel mouse event should work
+  now on the sub window.
+- #ifdef'd USE_DVDREAD to allow for compilation
+  when disabling mpdvdkit.
+- Updated license information.
+
+2006/03/08 - Erik Augustson <erik_27can at yahoo.com>
+- Removed unnecessary playerinfo struct
+- Fixed movies playing at wrong aspects
+- Minor bugfixes all around
+
+2006/03/07 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed some skin labels not displaying properly
+
+2006/03/06 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Temporaly fix crash if no vo_driver is specified
+  (interface.c:877)
+
+2006/02/28 - Erik Augustson <erik_27can at yahoo.com>
+- Added sub window. The sub window is the WinID
+  (-wid) when using the directx vo. The sub window
+  hides when the file is audio only, and as well
+  when the vo is not directx, and automatically
+  adjusts and maintains video aspect ratios
+- Minor fixups
+- TODO: Get WinID working when using gl2, and add
+  fix for both windows if going out of bounds on
+  right and bottom of screen.
+
+2006/01/30 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed playing movies from network drives.
+
+2006/01/27 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed a small annoyance when playing a network file
+  with file associations when mplayer wasn't running,
+  using GetLongPathNameA()
+
+2006/01/15 - Erik Augustson <erik_27can at yahoo.com>
+- Added some CD functionality if using libcdio.
+
+2005/12/02 - Erik Augustson <erik_27can at yahoo.com>
+- Fix to disable gui if running in slave mode.
+
+2005/11/14 - Erik Augustson <erik_27can at yahoo.com>
+- Implemented IPC with WM_COPYDATA to open new
+  files/playlists in the current running mplayer,
+  rather than having a new mplayer process spawn.
+
+2005/11/12 - Erik Augustson <erik_27can at yahoo.com>
+- Modified evMute to mute/unmute
+- Mute button should show as pressed when muted
+- Added evDecVolume and evIncVolume
+
+2005/11/09 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed screensaver issues
+
+2005/11/06 - Erik Augustson <erik_27can at yahoo.com>
+- Display fixes
+
+2005/09/18 - Erik Augustson <erik_27can at yahoo.com>
+- Playlist additions
+- Minor playlist bugfixes
+
+2005/09/16 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Code cleanup
+
+2005/09/05 - Erik Augustson <erik_27can at yahoo.com>
+- Updated to apply to current CVS
+
+2005/07/27 - Erik Augustson <erik_27can at yahoo.com>
+- Added initial evEqualizer for brightness, contrast,
+  hue and saturation of videos.
+
+2005/07/26 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed double click on playlist
+- Added support for screenshot video filter, vf_screenshot patch
+  is also needed
+
+2005/06/19 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Removed -console switch, moved console stuff out of mplayer main,
+  console option is handled in wincfg, it's switchable at runtime
+  from the gui and the state is saved
+
+2005/06/15 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed bugs with DVD chapter skipping
+- Title/chapter switching dialog works again :)
+- Fixed a bug with url's not working after playing a DVD
+- Removed fullscreen handling from mplayer.c. It's now
+  handled in interface.c
+- Disabled loading/saving playlists, and adding files/urls
+  while playing a DVD
+
+2005/06/12 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Added -console cmd line option to bring up a dos console
+  that displays mplayer messages
+
+2005/06/10 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed a bug with the audio filters not loading
+- Fixed bugs with the audio delay and stereo sliders
+- Added a few safety checks
+
+2005/06/08 - Erik Augustson <erik_27can at yahoo.com>
+- Added initial evPreferences
+- Fixed a bug with the load subtitle dialog
+- Some code cleanup and minor fixes here and there
+
+2005/06/02 - Erik Augustson <erik_27can at yahoo.com>
+- Fixed a bug with pathnames in the open url dialog
+
+2005/05/26 - Erik Augustson <erik_27can at yahoo.com>
+- Added "Add file" and "Add url" menu to the playlist
+- Fixed file skipping when double-clicking playlist entries
+
+2005/05/19 - Erik Augustson <erik_27can at yahoo.com>
+- added simple url history
+
+2005/05/12 - Erik Augustson <erik_27can at yahoo.com>
+- added load and save playlists options
+- fixed opening remote m3u and pls files in open url
+- no problems so far with evprev and evnext :)
+
+2005/05/10 - Erik Augustson <erik_27can at yahoo.com>
+- more evNext and evPrev fixes
+
+2005/05/06 - Erik Augustson <erik_27can at yahoo.com>
+- implemented mplEnd() for proper looping fix
+- fixed bugs in evNext and evPrev
+- re-organized the menus
+
+2005/03/02 - Gianluigi Tiesi <sherpya at netfarm.it>
+- adapted subtitle patch from Raul <zomps at mail.astar.ee>
+- readapted endless loop fix to not touch mp_msg.c
+Erik Augustson <erik_27can at yahoo.com>
+- small fixes, orginal endless loop fix
+
+2005/02/25 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Fixed exit stuff (I hope ;P)
+- Fixes to Erik's title/chapter selector
+Erik Augustson <erik_27can at yahoo.com>
+- Added additional gui events
+- Added evPrev and evNext dvd chapter switching
+
+2005/02/23 - Erik Augustson <erik_27can at yahoo.com>
+- added dvd title/chapter switching
+
+2005/02/20 - Gianluigi Tiesi <sherpya at netfarm.it>
+- fixed dvd stop and play
+Erik Augustson <erik_27can at yahoo.com>
+- imported some stuff from unix gui
+- fixed file play after dvd
+
+2005/02/18 - Erik Augustson <erik_27can at yahoo.com>
+- addons for dvd playing
+
+2005/02/16 - Gianluigi Tiesi <sherpya at netfarm.it>
+- renamed README to README.txt
+- retain window position even when switching the skin
+- converted all opendir calls to native win32 calls
+- adding filename as title without directory for all calls
+- more cleanups in skinloader/unloader
+- removed a lot of warnings
+- removed unused includes
+Erik Augustson <erik_27can at yahoo.com>
+- added online help menu
+
+2005/02/15 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Disabled access to gui when gui->mainwindow doesn't match hwnd passed to windproc
+- Fixed save position for main window gui
+- Cleanups in skinloader/unloader
+Erik Augustson erik_27can at yahoo.com
+- Added saving main window position to gui config
+- Fixes on playlist for vcd
+
+2005/02/13 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Fixed multithreaded (I hope ;P)
+- Skinbrowser window is closed when a skin is changed, this prevents crashes if multiple clicks
+- Playlist window is updated if files are added while playlist is visible
+- Removed patch on mplayer.rc, take icon using the included routine
+- SkinBrowser and Playlist dialogs can be opened/closed by clicking multiple times gui buttons
+- Added support for DVD, stop dvd + play is broken ;(
+- ifdef-ed a lot of debug stuff
+- Fixed systray icon removing
+- Added Erik and me to about dialog ;)
+Erik Augustson <erik_27can at yahoo.com>
+- Added key handling for the gui window
+- Small fixes on tray icon stuff
+
+2005/02/11 - Gianluigi Tiesi <sherpya at netfarm.it>
+- fixed sliders, balance is not 100% working, anyway dsound output driver doesn't support balanced audio
+- remade threaded
+- removed demuxer/avi patches, really needed ??
+- added a fake vo_init if opengl is not enabled
+Erik Augustson <erik_27can at yahoo.com>
+- fixes on traymenu play
+- added a base configuration reader/writer - only support for skin selection for now
+
+2005/02/10 - Gianluigi Tiesi <sherpya at netfarm.it>
+- fixed (workarounded) the NULL filename bug
+- moved add directory directly into gui.c
+- it starts to be usable :)
+Erik Augustson <erik_27can at yahoo.com>
+- Added systray support
+- Added skin browser option to menu (some skins don't show a skin browser button)
+
+2005/02/09 - Gianluigi Tiesi <sherpya at netfarm.it>
+- Fixed window disappearing bug
+- Made a patch compatible with current tree
+- Fixed icons in minor dialogs
+- Major cleanup and code reorganization
+
+2005/02/08 - Erik Augustson <erik_27can at yahoo.com>
+- Removed multi-threading, mplayer now runs in a single thread
+- Play directory now works as intended
+- Added a Skin browser, double-click skin names to switch skins
+- Still more things todo
+
+pre4
+- URL open
+- use windows native menus
+- Gui runs in a seperate thread now because some controls interupt playback :(
+
+pre 3
+- some of the previous features broken again
+- full font loading/display support
+- better integration into mplayer
+- seek bar, balance, volume control work
+
+pre 2
+- playlist
+- Drag 'N Drop support
+- fixed segfault when no skinfile found
+
+pre 1
+- initial revision
+- play/pause works
+- loads "blue" skin
+- still lot of things todo

Added: trunk/Gui/win32/README
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/README	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,17 @@
+MPlayer Windows GUI (c)
+2003 Sascha Sommer - <saschasommer at freenet.de>
+2006 Erik Augustson - <erik_27can at yahoo.com>
+2006 Gianluigi Tiesi - <sherpya at netfarm.it>
+
+This beta gui for win32 was originally written by Sascha Sommer and
+has since been heavily modified by myself (Erik Augustson) and Gianluigi
+Tiesi. It follows the same concept for the linux gui, and should be
+able to load all(most) of the current skins available for the linux gui.
+
+To compile, quite simply pass --enable-gui to configure, and it is highly
+recommended to also pass --enable-static="-mwindows" to link mplayer as
+a windows binary. NOTE: this will also link mencoder with -mwindows
+and thus link mencoder as a windows binary as well.
+
+Please send all bug reports/comments/requests/gripes to:
+<erik_27can at yahoo.com>

Added: trunk/Gui/win32/dialogs.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/dialogs.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,1142 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <commctrl.h>
+#include <interface.h>
+#include <mp_msg.h>
+#include <help_mp.h>
+#include <libmpdemux/stream.h>
+#include <libmpdemux/demuxer.h>
+#include <libmpdemux/stheader.h>
+#include "gui.h"
+#include "wincfg.h"
+#include "dialogs.h"
+
+WNDPROC OldUrlWndProc;
+LRESULT CALLBACK SubUrlWndProc(HWND, UINT, WPARAM, LPARAM);
+extern int vo_gamma_brightness;
+extern int vo_gamma_saturation;
+extern int vo_gamma_contrast;
+extern int vo_gamma_hue;
+extern int set_video_colors(sh_video_t *sh_video, char *item, int value);
+extern int get_video_colors(sh_video_t *sh_video, char *item, int *value);
+
+guiInterface_t guiIntfStruct;
+int addurl = 0;
+
+#ifdef USE_SUB
+extern mp_osd_obj_t* vo_osd_list;
+extern char **sub_name;
+
+void guiLoadSubtitle(char *name)
+{
+    if (!guiIntfStruct.Playing)
+    {
+        guiIntfStruct.SubtitleChanged = 1;
+        return;
+    }
+    if (subdata)
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_DeletingSubtitles);
+        sub_free(subdata);
+        subdata = NULL;
+        vo_sub = NULL;
+        if (vo_osd_list)
+        {
+            int len;
+            mp_osd_obj_t *osd = vo_osd_list;
+            while (osd)
+            {
+                if (osd->type == OSDTYPE_SUBTITLE) break;
+                osd = osd->next;
+            }
+            if (osd && osd->flags & OSDFLAG_VISIBLE)
+            {
+                len = osd->stride * (osd->bbox.y2 - osd->bbox.y1);
+                memset(osd->bitmap_buffer, 0, len);
+                memset(osd->alpha_buffer, 0, len);
+            }
+        }
+    }
+
+    if (name)
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_LoadingSubtitles, name);
+        subdata = sub_read_file(strdup(name), guiIntfStruct.FPS);
+        if (!subdata) mp_msg(MSGT_GPLAYER, MSGL_ERR, MSGTR_CantLoadSub,name);
+        sub_name = (malloc(2 * sizeof(char*))); /* when mplayer will be restarted */
+        sub_name[0] = strdup(name);               /* sub_name[0] will be read */
+        sub_name[1] = NULL;
+    }
+    update_set_of_subtitles();
+}
+#endif
+
+int display_openfilewindow(gui_t *gui, int add)
+{
+    OPENFILENAME fileopen;
+    int result = 0;
+    char filelist[MAXFILE];
+    char filename[MAX_PATH];
+    char directory[MAX_PATH];
+    char *filespec = NULL;
+    char *filepart = NULL;
+
+    memset(&fileopen, 0, sizeof(OPENFILENAME));
+    memset(filelist, 0, sizeof(filelist));
+
+    fileopen.lStructSize = sizeof(OPENFILENAME);
+    fileopen.hwndOwner = gui->mainwindow;
+    fileopen.hInstance = GetModuleHandle(NULL);
+    fileopen.lpstrFilter = "All Files (*.*)\0*.*\0"
+                           "Media Files (*.avi;*.asf;*.wmv;*.mpg;*.mpeg;*.m2v;*.mov;\
+                                         *.rmvb;*.rm;*.ogm;*.mp3;*.wav;*.wma;*.ra;*.ogg)\0\
+                                         *.avi;*.asf;*.wmv;*.mpg;*.mpeg;*.m2v;*.mov;\
+                                         *.rmvb;*.rm;*.ogm;*.mp3;*.wav;*.wma;*.ra;*.ogg\0"
+                           "Video Files (*.avi;*.mpg;*.mpeg;*.mov)\0*.avi;*.mpg;*.mpeg;*.mov\0"
+                           "Avisynth Scripts (*.avs)\0*.avs\0"
+                           "Audio Files (*.mp3;*.wav;*.ra)\0*.mp3;*.wav;*.ra\000";
+    fileopen.nFilterIndex = 0;
+    fileopen.lpstrTitle = "Add file(s)...";
+    fileopen.Flags = OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST| OFN_LONGNAMES | OFN_EXPLORER| OFN_READONLY | OFN_HIDEREADONLY;
+    fileopen.lpstrFile = filelist;
+    fileopen.lpstrCustomFilter = NULL;
+    fileopen.nMaxFile = MAXFILE;
+
+    if(GetOpenFileName(&fileopen))
+    {
+        /* clear playlist */
+        if(!add) gui->playlist->clear_playlist(gui->playlist);
+
+        memcpy(directory, fileopen.lpstrFile, fileopen.nFileOffset - 1);
+        directory[fileopen.nFileOffset - 1] = 0;
+
+        do
+        {
+            filespec = &fileopen.lpstrFile[fileopen.nFileOffset];
+            filename[0] = 0;
+            strcat(filename, directory);
+            strcat(filename, "\\");
+            strcat(filename, filespec);
+
+            if (GetFileAttributes(filename) & FILE_ATTRIBUTE_DIRECTORY)
+                mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] %s is a directory, skipping...\n", filename);
+            else
+            {
+                if (GetFullPathName(filename, MAX_PATH, filename, &filepart))
+                {
+                    if(!parse_filename(filename, playtree, mconfig, add? 0 : 1))
+                        gui->playlist->add_track(gui->playlist, filename, NULL, filepart, 0);
+                    mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Adding file: %s - path %s\n", filespec, filename);
+                    result++;
+                }
+            }
+            fileopen.nFileOffset += strlen(filespec) + 1;
+        } while (*filespec);
+    }
+    return result;
+}
+
+#ifdef USE_SUB
+void display_opensubtitlewindow(gui_t *gui)
+{
+    OPENFILENAME subtitleopen;
+    char subtitlefile[MAX_PATH];
+
+    /* Safety check */
+    if (guiIntfStruct.Playing == 0 || !guiIntfStruct.sh_video) return;
+
+    memset(&subtitleopen, 0, sizeof(OPENFILENAME));
+    memset(subtitlefile, 0, sizeof(subtitlefile));
+
+    subtitleopen.lStructSize = sizeof(OPENFILENAME);
+    subtitleopen.hwndOwner = gui->mainwindow;
+    subtitleopen.hInstance = GetModuleHandle(NULL);
+    subtitleopen.lpstrFilter = "All Files (*.*)\0*.*\0"
+                               "Subtitle Files (*.srt;*.txt;*.vob)\0*.srt;*.txt;*.vob\0";
+    subtitleopen.nFilterIndex = 0;
+    subtitleopen.lpstrTitle = "Add Subtitle...";
+    subtitleopen.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_READONLY | OFN_HIDEREADONLY;
+    subtitleopen.lpstrFile = subtitlefile;
+    subtitleopen.lpstrCustomFilter = NULL;
+    subtitleopen.nMaxFile = MAXFILE;
+
+    if(GetOpenFileName(&subtitleopen))
+        guiLoadSubtitle(subtitlefile);
+}
+#endif
+
+void display_loadplaylistwindow(gui_t *gui)
+{
+    OPENFILENAME playlistopen;
+    char playlistfile[MAX_PATH];
+
+    memset(&playlistopen, 0, sizeof(OPENFILENAME));
+    memset(playlistfile, 0, sizeof(playlistfile));
+
+    playlistopen.lStructSize = sizeof(OPENFILENAME);
+    playlistopen.hwndOwner = gui->mainwindow;
+    playlistopen.hInstance = GetModuleHandle(NULL);
+    playlistopen.lpstrFilter = "All Files (*.*)\0*.*\0"
+                               "Playlist Files (*.m3u;*.pls;*.txt)\0*.m3u;*.pls;*.txt\0";
+    playlistopen.nFilterIndex = 0;
+    playlistopen.lpstrTitle = "Load Playlist...";
+    playlistopen.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_READONLY | OFN_HIDEREADONLY;
+    playlistopen.lpstrFile = playlistfile;
+    playlistopen.lpstrCustomFilter = NULL;
+    playlistopen.nMaxFile = MAXFILE;
+
+    if(GetOpenFileName(&playlistopen))
+    {
+        if(parse_filename(playlistfile, playtree, mconfig, 1))
+            gui->startplay(gui);
+    }
+}
+
+void display_saveplaylistwindow(gui_t* gui)
+{
+    OPENFILENAME playlistsave;
+    static FILE *playlist_file = NULL;
+    char playlistname[MAX_PATH];
+
+    memset(&playlistsave, 0, sizeof(OPENFILENAME));
+    memset(playlistname, 0, sizeof(playlistname));
+
+    playlistsave.lStructSize = sizeof(OPENFILENAME);
+    playlistsave.hwndOwner = gui->mainwindow;
+    playlistsave.hInstance = GetModuleHandle(NULL);
+    playlistsave.lpstrFilter = "Playlist Files (*.pls)\0*.pls\0";
+    playlistsave.nFilterIndex = 0;
+    playlistsave.lpstrTitle = "Save Playlist...";
+    playlistsave.Flags = OFN_LONGNAMES | OFN_EXPLORER | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
+    playlistsave.lpstrFile = playlistname;
+    playlistsave.lpstrCustomFilter = NULL;
+    playlistsave.nMaxFile = MAXFILE;
+
+    if(GetSaveFileName(&playlistsave))
+    {
+        int i=0;
+        HANDLE my_playlist;
+
+        if(!strstr(playlistname, ".pls")) strcat(playlistname, ".pls");
+
+        my_playlist = CreateFile(playlistname,
+                                 GENERIC_WRITE,
+                                 0,
+                                 NULL,
+                                 CREATE_ALWAYS,
+                                 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+                                 NULL);
+
+        if(my_playlist != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle(my_playlist); /* close the file first so we can write to it */
+            playlist_file = fopen(playlistsave.lpstrFile, "w");
+            fprintf(playlist_file, "[playlist]\n");
+            fprintf(playlist_file, "numberofentries=%d\n", gui->playlist->trackcount);
+
+            for(i=0; i<(gui->playlist->trackcount); i++)
+            {
+                fprintf(playlist_file, "File%i=%s\n", i + 1, gui->playlist->tracks[i]->filename);
+                fprintf(playlist_file, "Length%i=-1\n", i + 1);
+            }
+            fclose(playlist_file);
+        }
+    }
+}
+
+static LRESULT CALLBACK OpenUrlWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    static HWND url;
+    HWND wdg;
+    FILE *f;
+    char *history = get_path("gui.url");
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    switch (iMsg)
+    {
+        case WM_CREATE:
+            wdg = CreateWindow("button", "Ok",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               4, 43, 80, 25, hwnd,
+                               (HMENU) ID_OK,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            wdg = CreateWindow("button", "Cancel",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               90, 43, 80, 25, hwnd,
+                               (HMENU) ID_CANCEL,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            url = wdg = CreateWindowEx(WS_EX_CLIENTEDGE,
+                               "edit", NULL,
+                               WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL,
+                               4, 10, 300, 25, hwnd,
+                               (HMENU) ID_URL,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+            SendMessage(wdg, EM_SETLIMITTEXT, MAX_PATH, 0);
+
+            /*subclass the edit box to capture the VK_RETURN key*/
+            OldUrlWndProc = (WNDPROC)SetWindowLongPtr(url, GWLP_WNDPROC, (LONG_PTR)SubUrlWndProc);
+
+            if((f = fopen(history, "r")))
+            {
+               char lasturl[MAX_PATH];
+               fgets(lasturl, MAX_PATH, f);
+               SendMessage(url, WM_SETTEXT, 0, (LPARAM) lasturl);
+               SendMessage(url, EM_SETSEL, 0, -1);
+               fclose(f);
+            }
+            break;
+        case WM_KEYDOWN:
+            switch (LOWORD(wParam))
+            {
+                case VK_RETURN:
+                    SendMessage(hwnd, WM_COMMAND, (WPARAM) ID_OK, 0);
+                    break;
+            }
+        case WM_COMMAND:
+        {
+            switch (LOWORD(wParam))
+            {
+                case ID_CANCEL:
+                    DestroyWindow(hwnd);
+                    return 0;
+                case ID_OK:
+                {
+                    char file[MAX_PATH];
+                    SendMessage(url, WM_GETTEXT, MAX_PATH, (LPARAM) file);
+                    mplSetFileName(NULL, file, STREAMTYPE_STREAM);
+                    if((f = fopen(history, "wt+")))
+                    {
+                        fprintf(f, file);
+                        fclose(f);
+                    }
+                    if(!parse_filename(file, playtree, mconfig, addurl? 0 : 1))
+                        gui->playlist->add_track(gui->playlist, file, NULL, NULL, 0);
+                    if(!addurl)
+                        gui->startplay(gui);
+                    else update_playlistwindow();
+                    DestroyWindow(hwnd);
+                }
+                break;
+            }
+        }
+        return 0;
+        case WM_DESTROY:
+        {
+            PostQuitMessage (0);
+            addurl = 0;
+            return 0;
+        }
+    }
+    return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}
+
+LRESULT CALLBACK SubUrlWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    switch(iMsg)
+    {
+        case WM_KEYDOWN:
+            switch (LOWORD(wParam))
+            {
+                case VK_RETURN:
+                    SendMessage(FindWindow(NULL, "MPlayer - Open URL..."), WM_COMMAND, (WPARAM) ID_OK, 0);
+                    break;
+            }
+    }
+    return CallWindowProc(OldUrlWndProc, hwnd, iMsg, wParam, lParam);
+}
+
+void display_openurlwindow(gui_t *gui, int add)
+{
+    if(add) addurl = 1;
+    HWND hWnd;
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    int x, y;
+    if(FindWindow(NULL, "MPlayer - Open URL...")) return;
+    wc.style         = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc   = OpenUrlWndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = 0;
+    wc.hInstance     = hInstance;
+    wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
+    wc.hIcon         = gui->icon;
+    wc.hbrBackground = SOLID_GREY2;
+    wc.lpszClassName = "MPlayer - URL";
+    wc.lpszMenuName  = NULL;
+    RegisterClass(&wc);
+    x = (GetSystemMetrics(SM_CXSCREEN) / 2) - (320 / 2);
+    y = (GetSystemMetrics(SM_CYSCREEN) / 2) - (100 / 2);
+    hWnd = CreateWindow("MPlayer - URL",
+                        "MPlayer - Open URL...",
+                        WS_POPUPWINDOW | WS_CAPTION,
+                        x,
+                        y,
+                        320,
+                        100,
+                        NULL,
+                        NULL,
+                        hInstance,
+                        NULL);
+   SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD) gui);
+   ShowWindow(hWnd, SW_SHOW);
+   UpdateWindow(hWnd);
+}
+
+static void create_playlistmenu(gui_t *gui)
+{
+    gui->playlistmenu = CreatePopupMenu();
+    AppendMenu(gui->playlistmenu, MF_STRING, ID_ADDFILE, "Add File...");
+    AppendMenu(gui->playlistmenu, MF_STRING, ID_ADDURL, "Add Url...");
+    AppendMenu(gui->playlistmenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->playlistmenu, MF_STRING, ID_REMOVE, "Remove Selected");
+    AppendMenu(gui->playlistmenu, MF_STRING, ID_CLEAR, "Clear Playlist");
+    AppendMenu(gui->playlistmenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->playlistmenu, MF_STRING, ID_CLOSE, "Close");
+}
+
+static void updatetracklist(HWND hwnd)
+{
+    int i=0;
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    HWND tracklist = GetDlgItem(hwnd, ID_TRACKLIST);
+    /* clear listbox */
+    SendMessage(tracklist, LB_RESETCONTENT, 0, 0);
+    for (i=0; i < gui->playlist->trackcount; i++)
+        if (gui->playlist->tracks[i]->title)
+            SendMessage(tracklist, LB_ADDSTRING, 0, (LPARAM)gui->playlist->tracks[i]->title);
+        else
+            SendMessage(tracklist, LB_ADDSTRING, 0, (LPARAM)gui->playlist->tracks[i]->filename);
+}
+
+static LRESULT CALLBACK PlayListWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    HWND wdg;
+    POINT cursor;
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    playlist_t *pl = gui ? gui->playlist : NULL;
+    switch (iMsg)
+    {
+        case WM_CREATE:
+        {
+            wdg = CreateWindow("button", "Play",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               4, 10, 80, 25, hwnd,
+                               (HMENU) ID_PLAY,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            wdg = CreateWindow ("button", "Up",
+                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                                4, 37, 80, 25, hwnd,
+                                (HMENU) ID_UP,
+                                ((LPCREATESTRUCT) lParam) -> hInstance,
+                                NULL);
+            SendMessage(wdg, WM_SETFONT,(WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            wdg = CreateWindow ("button", "Down",
+                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                                4, 64, 80, 25, hwnd,
+                                (HMENU) ID_DOWN,
+                                ((LPCREATESTRUCT) lParam) -> hInstance,
+                                NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT),0);
+
+            wdg = CreateWindow ("button", "Remove",
+                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                                4, 91, 80, 25, hwnd,
+                                (HMENU) ID_REMOVE,
+                                ((LPCREATESTRUCT) lParam) -> hInstance,
+                                NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT),0);
+
+            wdg = CreateWindow ("button", "Load",
+                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                                4, 118, 80, 25, hwnd,
+                                (HMENU) ID_PLAYLISTLOAD,
+                                ((LPCREATESTRUCT) lParam) -> hInstance,
+                                NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT),0);
+
+            wdg = CreateWindow ("button", "Save",
+                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                                4, 145, 80, 25, hwnd,
+                                (HMENU) ID_PLAYLISTSAVE,
+                                ((LPCREATESTRUCT) lParam) -> hInstance,
+                                NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT),0);
+
+            wdg = CreateWindow ("button", "Close",
+                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                                4, 193, 80, 25, hwnd,
+                                (HMENU) ID_CLOSE,
+                                ((LPCREATESTRUCT) lParam) -> hInstance,
+                                NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT),0);
+
+            wdg = CreateWindow ("listbox", "tracklist", WS_CHILD | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL |
+                               WS_HSCROLL | LBS_DISABLENOSCROLL, 92, 10, 300, 208, hwnd, (HMENU) ID_TRACKLIST,
+                               ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
+            SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+            SendMessage(wdg, LB_SETHORIZONTALEXTENT, MAX_PATH*4, 0);
+            break;
+        }
+        case WM_CONTEXTMENU:
+        {
+            GetCursorPos(&cursor);
+            SetForegroundWindow(hwnd);
+            TrackPopupMenu(gui->playlistmenu, 0, cursor.x, cursor.y, 0, hwnd, NULL);
+            break;
+        }
+        case WM_COMMAND:
+        {
+            HWND tracklist = GetDlgItem(hwnd, ID_TRACKLIST);
+            int selected = 0;
+            int i;
+            for (i=0; i<pl->trackcount; i++)
+                if(0 < SendMessage(tracklist, LB_GETSEL, i, 0)) selected = i + 1;
+            switch (LOWORD(wParam))
+            {
+                case ID_CLOSE:
+                    DestroyWindow(hwnd);
+                    return 0;
+                case ID_TRACKLIST:
+                    if(HIWORD(wParam) == LBN_DBLCLK)
+                    {
+                        if(selected) pl->current = selected - 1;
+                        mplGotoTheNext = 0;
+                        gui->startplay(gui);
+                    }
+                    return 0;
+                case ID_UP:
+                {
+                    if(selected) pl->moveup_track(pl, selected);
+                    selected--;
+                    break;
+                }
+                case ID_DOWN:
+                {
+                    if(selected) pl->movedown_track(pl, selected);
+                    selected++;
+                    break;
+                }
+                case ID_PLAY:
+                {
+                    if(selected) pl->current = selected - 1;
+                    mplGotoTheNext = 0;
+                    gui->startplay(gui);
+                    break;
+                }
+                case ID_REMOVE:
+                    if(selected) pl->remove_track(pl, selected);
+                    break;
+                case ID_ADDFILE:
+                {
+                    if(guiIntfStruct.StreamType == STREAMTYPE_DVD ||
+                       guiIntfStruct.StreamType == STREAMTYPE_DVDNAV) return 0;
+                    display_openfilewindow(gui, 1);
+                    break;
+                }
+                case ID_ADDURL:
+                {
+                    if(guiIntfStruct.StreamType == STREAMTYPE_DVD ||
+                       guiIntfStruct.StreamType == STREAMTYPE_DVDNAV) return 0;
+                    display_openurlwindow(gui, 1);
+                    break;
+                }
+                case ID_CLEAR:
+                {
+                    if(!gui->playlist->trackcount) return 0;
+                    gui->playlist->clear_playlist(gui->playlist);
+                    break;
+                }
+                case ID_PLAYLISTLOAD:
+                {
+                    if(guiIntfStruct.StreamType == STREAMTYPE_DVD ||
+                       guiIntfStruct.StreamType == STREAMTYPE_DVDNAV) return 0;
+                    display_loadplaylistwindow(gui);
+                    break;
+                }
+                case ID_PLAYLISTSAVE:
+                {
+                    /* no point saving an empty playlist */
+                    if(!gui->playlist->trackcount ||
+                        guiIntfStruct.StreamType == STREAMTYPE_DVD ||
+                        guiIntfStruct.StreamType == STREAMTYPE_DVDNAV)
+                        return 0;
+                    display_saveplaylistwindow(gui);
+                    break;
+                }
+            }
+            updatetracklist(hwnd);
+            if(selected < 1) selected = 1;
+            else if(selected>pl->trackcount) selected = pl->trackcount;
+            SendMessage(tracklist, LB_SETCURSEL, selected - 1, 0);
+            return 0;
+        }
+        case WM_DROPFILES:
+        {
+            char file[MAX_PATH];
+            int filecount = DragQueryFile((HDROP) wParam, -1, file, MAX_PATH);
+            int i;
+            for (i=0; i<filecount; i++)
+            {
+                DragQueryFile((HDROP) wParam, i, file, MAX_PATH);
+                if(!parse_filename(file, playtree, mconfig, 0))
+                    pl->add_track(pl, file, NULL, NULL, 0);
+            }
+            DragFinish((HDROP) wParam);
+            updatetracklist(hwnd);
+        }
+            break;
+        case WM_DESTROY:
+            PostQuitMessage(0);
+            return 0;
+    }
+    return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}
+
+void update_playlistwindow(void)
+{
+    HWND hWnd = FindWindow(NULL, "MPlayer Playlist");
+    if (hWnd) updatetracklist(hWnd);
+}
+
+void display_playlistwindow(gui_t *gui)
+{
+    HWND hWnd = FindWindow(NULL, "MPlayer Playlist");
+    if (hWnd)
+    {
+        SendMessage(hWnd, WM_CLOSE, 0, 0);
+        return;
+    }
+
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    int x, y;
+
+    wc.style         = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc   = PlayListWndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = 0;
+    wc.hInstance     = hInstance;
+    wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
+    wc.hIcon         = gui->icon;
+    wc.hbrBackground = SOLID_GREY2;
+    wc.lpszClassName = "MPlayer - Playlist";
+    wc.lpszMenuName  = NULL;
+    RegisterClass(&wc);
+    create_playlistmenu(gui);
+    x = (GetSystemMetrics(SM_CXSCREEN) / 2) - (400 / 2);   /* Erik: center popup window on screen */
+    y = (GetSystemMetrics(SM_CYSCREEN) / 2) - (254 / 2);
+    hWnd = CreateWindow("MPlayer - Playlist",
+                        "MPlayer Playlist",
+                        WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX,
+                        x,
+                        y,
+                        400,
+                        254,
+                        NULL,
+                        NULL,
+                        hInstance,
+                        NULL);
+   SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD)gui);
+   updatetracklist(hWnd);
+   DragAcceptFiles(hWnd,TRUE);
+   ShowWindow(hWnd, SW_SHOW);
+   UpdateWindow(hWnd);
+}
+
+static LRESULT CALLBACK SkinBrowserWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    static HWND listbox;
+    static char skinspath[MAX_PATH];
+    gui_t* gui = (gui_t*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    switch (iMsg)
+    {
+        case WM_CREATE:
+        {
+            listbox = CreateWindow("listbox", NULL,
+                                   WS_CHILD | WS_VISIBLE | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT |
+                                   LBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP,
+                                   4, 5, 166, 60, hwnd,
+                                   (HMENU) ID_DIR,
+                                   ((LPCREATESTRUCT) lParam) -> hInstance,
+                                   NULL);
+            SendMessage(listbox, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            /* This opens the skins directory, lists the directory names, and adds them to the listbox */
+            sprintf(skinspath, "%s/*.", get_path("skins"));
+
+            HANDLE skinHandle = INVALID_HANDLE_VALUE;
+            WIN32_FIND_DATA finddata;
+
+            skinHandle = FindFirstFile(skinspath, &finddata);
+            if (skinHandle != INVALID_HANDLE_VALUE)
+            {
+                do
+                {
+                    if (finddata.cFileName[0] == '.') continue;
+                    /* populate the listbox */
+                    capitalize(finddata.cFileName);
+                    SendDlgItemMessage(hwnd, ID_DIR, LB_ADDSTRING, 0, (LPARAM) finddata.cFileName);
+                } while (FindNextFile(skinHandle, &finddata));
+                FindClose(skinHandle);
+            }
+            else
+                mp_msg(MSGT_GPLAYER, MSGL_FATAL, "Error opening %s\n", get_path("skins"));
+            break;
+        }
+        case WM_COMMAND:
+        {
+            if ((HWND) lParam == listbox)
+            {
+                if(HIWORD(wParam) == LBN_DBLCLK)
+                {
+                    int index = SendMessage(listbox, LB_GETCURSEL, 0, 0);
+                    int len = SendMessage(listbox, LB_GETTEXTLEN, index, 0);
+                    if (len)
+                    {
+                        if (skinName) free(skinName);
+                        skinName = (char *) malloc(len+1);
+                        SendMessage(listbox, LB_GETTEXT, (WPARAM) index, (LPARAM) skinName);
+                        /* fill out the full pathname to the skin */
+                        strcpy(skinspath, get_path("skins"));
+                        strcat(skinspath, "\\");
+                        strcat(skinspath, skinName);
+                        ShowWindow(hwnd, SW_HIDE);
+                        Shell_NotifyIcon(NIM_DELETE, &nid);
+                        destroy_window(gui);
+                        create_window(gui, skinspath);
+                        create_subwindow(gui, skinspath);
+                        SendMessage(hwnd, WM_CLOSE, 0, 0); /* Avoid crashing when switching skin */
+                    }
+                }
+            }
+        }
+            return 0;
+        case WM_DESTROY:
+            PostQuitMessage(0);
+            return 0;
+    }
+    return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}
+
+void display_skinbrowser(gui_t* gui)
+{
+    HWND hWnd = FindWindow(NULL, "Skin Browser");
+    if (hWnd)
+    {
+        SendMessage(hWnd, WM_CLOSE, 0, 0);
+        return;
+    }
+
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    int x, y;
+
+    wc.style         = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc   = SkinBrowserWndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = 0;
+    wc.hInstance     = hInstance;
+    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
+    wc.hIcon         = gui->icon;
+    wc.hbrBackground = SOLID_GREY2;
+    wc.lpszClassName = "Skin Browser";
+    wc.lpszMenuName  = NULL;
+    RegisterClass(&wc);
+    x = (GetSystemMetrics(SM_CXSCREEN) / 2) - (180 / 2);
+    y = (GetSystemMetrics(SM_CYSCREEN) / 2) - (102 / 2);
+    hWnd = CreateWindow("Skin Browser",
+                        "Skin Browser",
+                        WS_POPUPWINDOW |WS_CAPTION,
+                        x,
+                        y,
+                        180,
+                        102,
+                        NULL,
+                        NULL,
+                        hInstance,
+                        NULL);
+   SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD) gui);
+   ShowWindow(hWnd, SW_SHOW);
+   UpdateWindow(hWnd);
+}
+
+#ifdef USE_DVDREAD
+static LRESULT CALLBACK TitleChapterWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    static HWND title;
+    static HWND chapter;
+    HWND wdg;
+    int i=0, j=0;
+    char titles[MAX_PATH] = "";
+    char chapters[MAX_PATH] = "";
+    switch (iMsg)
+    {
+        case WM_CREATE:
+            wdg = CreateWindow("button", "Ok",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               4, 43, 80, 25, hwnd,
+                               (HMENU) ID_OK,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+                              SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            wdg = CreateWindow("button", "Cancel",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               90, 43, 80, 25, hwnd,
+                               (HMENU) ID_CANCEL,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+                              SendMessage(wdg, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            title = CreateWindow("combobox", NULL,
+                                 CBS_DROPDOWNLIST | CB_SHOWDROPDOWN | CBS_NOINTEGRALHEIGHT | CBS_HASSTRINGS |
+                                 WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP,
+                                 4, 10, 80, 160, hwnd,
+                                 (HMENU) ID_TITLESEL,
+                                 ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+
+            SendMessage(title, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            chapter = CreateWindow("combobox", NULL,
+                                 CBS_DROPDOWNLIST | CB_SHOWDROPDOWN | CBS_NOINTEGRALHEIGHT | CBS_HASSTRINGS |
+                                 WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP,
+                                 90, 10, 80, 160, hwnd,
+                                 (HMENU) ID_CHAPTERSEL,
+                                 ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(chapter, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            for (i=0; i<guiIntfStruct.DVD.titles; i++)
+            {
+                /* we have to reverse the order here because of the way CB_INSERTSTRING adds items */
+                sprintf(&titles[i], "%d", guiIntfStruct.DVD.titles - i);
+                SendDlgItemMessage(hwnd, ID_TITLESEL, CB_INSERTSTRING, 0, (LPARAM) &titles[i]);
+            }
+            SendDlgItemMessage(hwnd, ID_TITLESEL, CB_SETCURSEL, dvd_title, 0);
+
+            for (j=0; j<guiIntfStruct.DVD.chapters; j++)
+            {
+                sprintf(&chapters[j], "%d", guiIntfStruct.DVD.chapters - j);
+                SendDlgItemMessage(hwnd, ID_CHAPTERSEL, CB_INSERTSTRING, 0, (LPARAM) &chapters[j]);
+            }
+            SendDlgItemMessage(hwnd, ID_CHAPTERSEL, CB_SETCURSEL, dvd_chapter, 0);
+
+            break;
+        case WM_COMMAND:
+        {
+            switch (LOWORD(wParam))
+            {
+                case ID_CANCEL:
+                    DestroyWindow(hwnd);
+                    return 0;
+                case ID_OK:
+                {
+                    guiIntfStruct.DVD.current_title = SendMessage(title, CB_GETCURSEL, 0, 0) + 1;
+                    guiIntfStruct.DVD.current_chapter = SendMessage(chapter, CB_GETCURSEL, 0, 0) + 1;
+
+                    if((guiIntfStruct.DVD.current_title != 0 || guiIntfStruct.DVD.current_chapter != 0))
+                    {
+                        mplGotoTheNext = 0;
+                        guiGetEvent(guiCEvent, (void *) guiSetStop);
+                        guiGetEvent(guiCEvent, (void *) guiSetPlay);
+                        DestroyWindow(hwnd);
+                    }
+                }
+                break;
+            }
+        }
+        return 0;
+        case WM_DESTROY:
+            PostQuitMessage (0);
+            return 0;
+    }
+    return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}
+
+void display_chapterselwindow(gui_t *gui)
+{
+    HWND hWnd;
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    int x, y;
+
+    if (guiIntfStruct.StreamType != STREAMTYPE_DVD) return;
+    if (FindWindow(NULL, "Select Title/Chapter...")) return;
+
+    wc.style         = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc   = TitleChapterWndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = 0;
+    wc.hInstance     = hInstance;
+    wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
+    wc.hIcon         = gui->icon;
+    wc.hbrBackground = SOLID_GREY2;
+    wc.lpszClassName = "Select Title/Chapter...";
+    wc.lpszMenuName  = NULL;
+    RegisterClass(&wc);
+    x = (GetSystemMetrics(SM_CXSCREEN) / 2) - (180 / 2);
+    y = (GetSystemMetrics(SM_CYSCREEN) / 2) - (100 / 2);
+    hWnd = CreateWindow("Select Title/Chapter...",
+                        "Select Title/Chapter...",
+                        WS_POPUPWINDOW | WS_CAPTION,
+                        x,
+                        y,
+                        180,
+                        100,
+                        NULL,
+                        NULL,
+                        hInstance,
+                        NULL);
+   SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD) gui);
+   ShowWindow(hWnd, SW_SHOW);
+   UpdateWindow(hWnd);
+}
+#endif
+
+static LRESULT CALLBACK EqWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    HWND btn, label, eq0, eq1, eq2, eq3;
+
+    switch (iMsg)
+    {
+        case WM_CREATE:
+        {
+            btn = CreateWindow("button", "Reset",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               157, 143, 80, 25, hwnd,
+                               (HMENU) ID_DEFAULTS,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Close",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               243, 143, 80, 25, hwnd,
+                               (HMENU) ID_CLOSE,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Brightness",
+                                 WS_CHILD | WS_VISIBLE,
+                                 12, 122, 70, 15, hwnd,
+                                 NULL,
+                                 ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Contrast",
+                                 WS_CHILD | WS_VISIBLE,
+                                 99, 122, 70, 15, hwnd,
+                                 NULL,
+                                 ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Hue",
+                                 WS_CHILD | WS_VISIBLE,
+                                 191, 122, 70, 15, hwnd,
+                                 NULL,
+                                 ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Saturation",
+                                 WS_CHILD | WS_VISIBLE,
+                                 260, 122, 70, 15, hwnd,
+                                 NULL,
+                                 ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            eq0 = CreateWindow(TRACKBAR_CLASS, "brightness",
+                               WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED |
+                               TBS_VERT | TBS_NOTICKS,
+                               30, 0, 20, 120, hwnd,
+                               (HMENU) ID_EQ0,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendDlgItemMessage(hwnd, ID_EQ0, TBM_SETRANGE, 1, MAKELONG(0, 200));
+
+            eq1 = CreateWindow(TRACKBAR_CLASS, "contrast",
+                               WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED |
+                               TBS_VERT | TBS_NOTICKS,
+                               112, 0, 20, 120, hwnd,
+                               (HMENU) ID_EQ1,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendDlgItemMessage(hwnd, ID_EQ1, TBM_SETRANGE, 1, MAKELONG(0, 200));
+
+            eq2 = CreateWindow(TRACKBAR_CLASS, "hue",
+                               WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED |
+                               TBS_VERT | TBS_NOTICKS,
+                               194, 0, 20, 120, hwnd,
+                               (HMENU) ID_EQ2,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendDlgItemMessage(hwnd, ID_EQ2, TBM_SETRANGE, 1, MAKELONG(0, 200));
+
+            eq3 = CreateWindow(TRACKBAR_CLASS, "saturation",
+                               WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_DISABLED |
+                               TBS_VERT | TBS_NOTICKS,
+                               276, 0, 20, 120, hwnd,
+                               (HMENU) ID_EQ3,
+                               ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
+            SendDlgItemMessage(hwnd, ID_EQ3, TBM_SETRANGE, 1, MAKELONG(0, 200));
+
+            if(guiIntfStruct.sh_video && guiIntfStruct.Playing)
+            {
+                EnableWindow(eq0, 1); EnableWindow(eq1, 1); EnableWindow(eq2, 1); EnableWindow(eq3, 1);
+                get_video_colors(guiIntfStruct.sh_video, "brightness", &vo_gamma_brightness);
+                get_video_colors(guiIntfStruct.sh_video, "contrast", &vo_gamma_contrast);
+                get_video_colors(guiIntfStruct.sh_video, "hue", &vo_gamma_hue);
+                get_video_colors(guiIntfStruct.sh_video, "saturation", &vo_gamma_saturation);
+            }
+            SendDlgItemMessage(hwnd, ID_EQ0, TBM_SETPOS, 1, (LPARAM)100 - vo_gamma_brightness);
+            SendDlgItemMessage(hwnd, ID_EQ1, TBM_SETPOS, 1, (LPARAM)100 - vo_gamma_contrast);
+            SendDlgItemMessage(hwnd, ID_EQ2, TBM_SETPOS, 1, (LPARAM)100 - vo_gamma_hue);
+            SendDlgItemMessage(hwnd, ID_EQ3, TBM_SETPOS, 1, (LPARAM)100 - vo_gamma_saturation);
+            break;
+        }
+        case WM_VSCROLL:
+        {
+            switch (LOWORD(wParam))
+            {
+                case TB_THUMBTRACK:
+                    if(guiIntfStruct.sh_video && guiIntfStruct.Playing)
+                    {
+                        vo_gamma_brightness = 100 - SendDlgItemMessage(hwnd, ID_EQ0, TBM_GETPOS, 0, 0);
+                        set_video_colors(guiIntfStruct.sh_video, "brightness", vo_gamma_brightness);
+
+                        vo_gamma_contrast = 100 - SendDlgItemMessage(hwnd, ID_EQ1, TBM_GETPOS, 0, 0);
+                        set_video_colors(guiIntfStruct.sh_video, "contrast", vo_gamma_contrast);
+
+                        vo_gamma_hue = 100 - SendDlgItemMessage(hwnd, ID_EQ2, TBM_GETPOS, 0, 0);
+                        set_video_colors(guiIntfStruct.sh_video, "hue", vo_gamma_hue);
+
+                        vo_gamma_saturation = 100 - SendDlgItemMessage(hwnd, ID_EQ3, TBM_GETPOS, 0, 0);
+                        set_video_colors(guiIntfStruct.sh_video, "saturation", vo_gamma_saturation);
+                    }
+                    else
+                    {
+                        EnableWindow(GetDlgItem(hwnd, ID_EQ0), 0);
+                        EnableWindow(GetDlgItem(hwnd, ID_EQ1), 0);
+                        EnableWindow(GetDlgItem(hwnd, ID_EQ2), 0);
+                        EnableWindow(GetDlgItem(hwnd, ID_EQ3), 0);
+                    }
+                    break;
+            }
+        }
+        case WM_CTLCOLORDLG:
+        case WM_CTLCOLORSTATIC:
+        {
+            HDC hdc = (HDC)wParam;
+            SetBkMode(hdc, TRANSPARENT);
+            return (INT_PTR)SOLID_GREY2;
+        }
+        break;
+        case WM_COMMAND:
+        {
+            switch (LOWORD(wParam))
+            {
+                case ID_CLOSE:
+                    DestroyWindow(hwnd);
+                    return 0;
+                case ID_DEFAULTS:
+                    if(guiIntfStruct.sh_video && guiIntfStruct.Playing)
+                    {
+                        vo_gamma_brightness=0;
+                        SendDlgItemMessage(hwnd, ID_EQ0, TBM_SETPOS, 1, (LPARAM)100);
+                        set_video_colors(guiIntfStruct.sh_video, "brightness", vo_gamma_brightness);
+
+                        vo_gamma_contrast=0;
+                        SendDlgItemMessage(hwnd, ID_EQ1, TBM_SETPOS, 1, (LPARAM)100);
+                        set_video_colors(guiIntfStruct.sh_video, "contrast", vo_gamma_contrast);
+
+                        vo_gamma_hue=0;
+                        SendDlgItemMessage(hwnd, ID_EQ2, TBM_SETPOS, 1, (LPARAM)100);
+                        set_video_colors(guiIntfStruct.sh_video, "hue", vo_gamma_hue);
+
+                        vo_gamma_saturation=0;
+                        SendDlgItemMessage(hwnd, ID_EQ3, TBM_SETPOS, 1, (LPARAM)100);
+                        set_video_colors(guiIntfStruct.sh_video, "saturation", vo_gamma_saturation);
+                    }
+                    break;
+            }
+        }
+        return 0;
+        case WM_DESTROY:
+            PostQuitMessage (0);
+            return 0;
+    }
+    return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}
+
+void display_eqwindow(gui_t *gui)
+{
+    if(!guiIntfStruct.sh_video) return;
+
+    HWND hWnd;
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    int x, y;
+    if(FindWindow(NULL, "MPlayer - Equalizer")) return;
+    wc.style         = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc   = EqWndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = 0;
+    wc.hInstance     = hInstance;
+    wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
+    wc.hIcon         = gui->icon;
+    wc.hbrBackground = SOLID_GREY2;
+    wc.lpszClassName = "MPlayer - Equalizer";
+    wc.lpszMenuName  = NULL;
+    RegisterClass(&wc);
+    x = (GetSystemMetrics(SM_CXSCREEN) / 2) - (332 / 2);
+    y = (GetSystemMetrics(SM_CYSCREEN) / 2) - (200 / 2);
+    hWnd = CreateWindow("MPlayer - Equalizer",
+                        "MPlayer - Equalizer",
+                        WS_POPUPWINDOW | WS_CAPTION,
+                        x,
+                        y,
+                        332,
+                        200,
+                        NULL,
+                        NULL,
+                        hInstance,
+                        NULL);
+   SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD) gui);
+   ShowWindow(hWnd, SW_SHOW);
+   UpdateWindow(hWnd);
+}

Added: trunk/Gui/win32/dialogs.h
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/dialogs.h	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,129 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _DIALOGS_H
+#define _DIALOGS_H
+
+#define TBS_TOOLTIPS   0x0100
+#define WM_SYSTRAY     (WM_USER+1)
+#define UDM_SETRANGE32 (WM_USER+111)
+#define UDM_GETRANGE32 (WM_USER+112)
+#define UDM_SETPOS32   (WM_USER+113)
+#define UDM_GETPOS32   (WM_USER+114)
+
+#define SOLID_GREY (HBRUSH) CreateSolidBrush(RGB(232, 232, 232))
+#define SOLID_GREY2 (HBRUSH) CreateSolidBrush(RGB(175, 175, 175))
+
+#define gfree free
+
+#define MAXFILE 1024
+
+#define COPYRIGHT   "               MPlayer GUI for Windows\n\n" \
+                    "     Copyright (c) 2003 Sascha Sommer\n" \
+                    "     Copyright (c) 2006 Erik Augustson\n" \
+                    "     Copyright (c) 2006 Gianluigi Tiesi"
+
+#define ONLINE_HELP_URL      "http://www.mplayerhq.hu/DOCS/HTML/en/index.html"
+
+#define ID_OK                12
+#define ID_APPLY             13
+#define ID_CANCEL            14
+#define ID_CLOSE             15
+#define ID_DEFAULTS          16
+#define ID_VO_DRIVER         17
+#define ID_AO_DRIVER         18
+#define ID_DOUBLE            19
+#define ID_DIRECT            20
+#define ID_FRAMEDROP         21
+#define ID_NORMALIZE         22
+#define ID_SOFTMIX           23
+#define ID_EXTRASTEREO       24
+#define ID_TRACKBAR1         25
+#define ID_TRACKBAR2         26
+#define ID_UPDOWN1           27
+#define ID_UPDOWN2           28
+#define ID_EDIT1             29
+#define ID_EDIT2             30
+#define ID_CACHE             31
+#define ID_AUTOSYNC          32
+#define ID_NONE              33
+#define ID_OSD1              34
+#define ID_OSD2              35
+#define ID_OSD3              36
+#define ID_DVDDEVICE         37
+#define ID_CDDEVICE          38
+#define ID_PRIO              39
+#define ID_URL               40
+#define ID_TITLESEL          41
+#define ID_UP                42
+#define ID_DOWN              43
+#define ID_REMOVE            44
+#define ID_ADDFILE           45
+#define ID_TRACKLIST         46
+#define ID_SUBTITLE          47
+#define ID_PLAYLISTLOAD      48
+#define ID_PLAYLISTSAVE      49
+#define ID_ADDURL            50
+#define ID_DIR               51
+#define ID_PLAY              52
+#define ID_STOP              53
+#define ID_SEEKF             54
+#define ID_SEEKB             55
+#define ID_NTRACK            56
+#define ID_PTRACK            57
+#define ID_PLAYLIST          58
+#define ID_CLEAR             59
+#define ID_SHOWHIDE          60
+#define ID_SKINBROWSER       61
+#define ID_KEYHELP           62
+#define ID_ONLINEHELP        63
+#define ID_CHAPTERSEL        64
+#define ID_PREFS             65
+#define TRAYMENU             66
+#define IDFILE_OPEN          67
+#define IDEXIT               68
+#define IDURL_OPEN           69
+#define IDDIR_OPEN           70
+#define IDFILE_NEW           71
+#define IDFILE_SAVE          72
+#define IDHELP_ABOUT         73
+#define IDSUBTITLE_OPEN      74
+#define IDPLAYDISK           75
+#define ID_CONSOLE           76
+#define ID_EQ0               77
+#define ID_EQ1               78
+#define ID_EQ2               79
+#define ID_EQ3               80
+#define IDSUB_TOGGLE         81
+#define IDSUB_CYCLE          82
+#define ID_ASPECT1           83
+#define ID_ASPECT2           84
+#define ID_ASPECT3           85
+#define ID_ASPECT4           86
+#define ID_SUBWINDOW         87
+
+/* gtk emulation */
+#define GTK_MB_FATAL         0x1
+#define GTK_MB_ERROR         0x2
+#define GTK_MB_WARNING       0x4
+#define GTK_MB_SIMPLE        0x8
+
+#endif

Added: trunk/Gui/win32/gui.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/gui.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,1555 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <shlobj.h>
+#include <version.h>
+#include <mplayer.h>
+#include <mp_msg.h>
+#include <help_mp.h>
+#include <cpudetect.h>
+#include <input/input.h>
+#include <input/mouse.h>
+#include <osdep/keycodes.h>
+#include <libmpdemux/stream.h>
+#include <libvo/video_out.h>
+#include <interface.h>
+#include "gui.h"
+#include "wincfg.h"
+#include "dialogs.h"
+
+#ifndef WM_XBUTTONDOWN
+# define WM_XBUTTONDOWN    0x020B
+# define WM_XBUTTONUP      0x020C
+# define WM_XBUTTONDBLCLK  0x020D
+#endif
+
+#define MP_TITLE "MPlayer " VERSION " (C) 2000-2006 MPlayer Team"
+
+/* Globals / Externs */
+extern void renderinfobox(skin_t *skin, window_priv_t *priv);
+extern void renderwidget(skin_t *skin, image *dest, widget *item, int state);
+extern void mplayer_put_key(int code);
+extern int WinID;
+float sub_aspect;
+
+DWORD oldtime;
+NOTIFYICONDATA nid;
+int console_state = 0;
+
+/* Sub window stuff */
+static HBRUSH    colorbrush = NULL;           //Handle to colorkey brush
+static COLORREF windowcolor = RGB(0,0,16);    //Windowcolor == colorkey
+
+/* vo_gl includes vo_init in w32_common.c, without gl this file is not included */
+#if !defined(GL_WIN32) && !defined(HAVE_GL)
+int vo_init(void)
+{
+    mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] dummy vo_init()\n");
+    return 1;
+}
+#endif
+
+void console_toggle(void)
+{
+    if (console_state)
+    {
+        FreeConsole();
+        console = 0;
+        console_state = 0;
+    }
+    else
+    {
+        /* This code comes from: http://dslweb.nwnexus.com/~ast/dload/guicon.htm */
+        CONSOLE_SCREEN_BUFFER_INFO coninfo;
+        FILE *fp;
+        HWND hwnd = NULL;
+        console = 1;
+        AllocConsole();
+        SetConsoleTitle(MP_TITLE);
+
+        /* disable the close button for now */
+        while (!hwnd)
+        {
+            hwnd = FindWindow(NULL, MP_TITLE);
+            Sleep(100);
+        }
+        DeleteMenu(GetSystemMenu(hwnd, 0), SC_CLOSE, MF_BYCOMMAND);
+
+        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
+        coninfo.dwSize.Y = 1000;
+        SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+        fp = freopen("con", "w", stdout);
+        *stdout = *fp;
+        setvbuf(stdout, NULL, _IONBF, 0);
+        fp = freopen("con", "r", stdin);
+        *stdin = *fp;
+        setvbuf(stdin, NULL, _IONBF, 0);
+        fp = freopen("con", "w", stdout);
+        *stderr = *fp;
+        setvbuf(stderr, NULL, _IONBF, 0);
+        mp_msg(MSGT_CPLAYER, MSGL_INFO, "%s\n", MP_TITLE);
+        GetCpuCaps(&gCpuCaps);
+#if defined(ARCH_X86) || defined(ARCH_X86_64)
+        mp_msg(MSGT_CPLAYER,MSGL_INFO,"CPUflags:  MMX: %d MMX2: %d 3DNow: %d 3DNow2: %d SSE: %d SSE2: %d\n",
+               gCpuCaps.hasMMX, gCpuCaps.hasMMX2,
+               gCpuCaps.has3DNow, gCpuCaps.has3DNowExt,
+               gCpuCaps.hasSSE, gCpuCaps.hasSSE2);
+#ifdef RUNTIME_CPUDETECT
+        mp_msg(MSGT_CPLAYER,MSGL_INFO, MSGTR_CompiledWithRuntimeDetection);
+#else
+        mp_msg(MSGT_CPLAYER,MSGL_INFO, MSGTR_CompiledWithCPUExtensions);
+#ifdef HAVE_MMX
+        mp_msg(MSGT_CPLAYER,MSGL_INFO," MMX");
+#endif
+#ifdef HAVE_MMX2
+        mp_msg(MSGT_CPLAYER,MSGL_INFO," MMX2");
+#endif
+#ifdef HAVE_3DNOW
+        mp_msg(MSGT_CPLAYER,MSGL_INFO," 3DNow");
+#endif
+#ifdef HAVE_3DNOWEX
+        mp_msg(MSGT_CPLAYER,MSGL_INFO," 3DNowEx");
+#endif
+#ifdef HAVE_SSE
+        mp_msg(MSGT_CPLAYER,MSGL_INFO," SSE");
+#endif
+#ifdef HAVE_SSE2
+        mp_msg(MSGT_CPLAYER,MSGL_INFO," SSE2");
+#endif
+        mp_msg(MSGT_CPLAYER,MSGL_INFO,"\n\n");
+#endif
+#endif
+        console_state = 1;
+    }
+}
+
+void capitalize(char *filename)
+{
+    unsigned int i;
+    BOOL cap = TRUE;
+    for (i=0; i < strlen(filename); i++)
+    {
+        if (cap)
+        {
+            cap = FALSE;
+            filename[i] = toupper(filename[i]);
+        }
+        else if (filename[i] == ' ')
+            cap = TRUE;
+        else
+            filename[i] = tolower(filename[i]);
+    }
+}
+
+static image *get_drawground(HWND hwnd)
+{
+    gui_t * gui = (gui_t *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    unsigned int i;
+    if(!gui) return NULL;
+    for(i=0; i<gui->window_priv_count; i++)
+        if(gui->window_priv[i]->hwnd==hwnd)
+            return &gui->window_priv[i]->img;
+    return NULL;
+}
+
+static HBITMAP get_bitmap(HWND hwnd)
+{
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    unsigned int i;
+    if(!gui) return NULL;
+    for(i=0; i<gui->window_priv_count; i++)
+        if(gui->window_priv[i]->hwnd == hwnd)
+            return gui->window_priv[i]->bitmap;
+    return NULL;
+}
+
+static int get_windowtype(HWND hwnd)
+{
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    unsigned int i;
+    if(!gui) return -1;
+    for(i=0; i<gui->window_priv_count; i++)
+        if(gui->window_priv[i]->hwnd == hwnd)
+            return gui->window_priv[i]->type;
+    return -1;
+}
+
+static void uninit(gui_t *gui)
+{
+    if(gui->skin) destroy_window(gui);
+    if(gui->playlist) gui->playlist->free_playlist(gui->playlist);
+    gui->playlist = NULL;
+}
+
+/*
+    the gui message handler
+    tries to handle the incoming messages
+    and passes them to the player's message handler if it can't handle them
+*/
+static void handlemsg(HWND hWnd, int msg)
+{
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+    if(msg == evNone) return;
+
+    switch(msg)
+    {
+        case evLoadPlay:
+        case evLoad:
+            if(display_openfilewindow(gui, 0) && (msg == evLoadPlay))
+                handlemsg(hWnd, evDropFile);
+            return;
+#ifdef USE_SUB
+        case evLoadSubtitle:
+            display_opensubtitlewindow(gui);
+            break;
+#endif
+        case evPreferences:
+            display_prefswindow(gui);
+            return;
+        case evPlayList:
+            display_playlistwindow(gui);
+            return;
+        case evSkinBrowser:
+            display_skinbrowser(gui);
+            break;
+        case evEqualizer:
+            display_eqwindow(gui);
+            break;
+        case evAbout:
+            MessageBox(hWnd, COPYRIGHT, "About", MB_OK);
+            break;
+        case evIconify:
+            ShowWindow(hWnd, SW_MINIMIZE);
+            break;
+        case evIncVolume:
+            mplayer_put_key(KEY_VOLUME_UP);
+            break;
+        case evDecVolume:
+            mplayer_put_key(KEY_VOLUME_DOWN);
+            break;
+        default:
+            mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] received msg %s (%i)\n", gui->skin->geteventname(msg), msg);
+            break;
+    }
+    gui->playercontrol(msg);
+}
+
+static widget *clickedinsidewidget(gui_t *gui, int window, int x, int y)
+{
+    unsigned int i;
+    widget *item;
+    for(i=0; i<gui->skin->widgetcount; i++)
+    {
+        item = gui->skin->widgets[i];
+        if((item->window == window) && (item->x <= x) && (item->x + item->width >= x) &&
+           (item->y <= y) && (item->y + item->height >= y))
+            return item;
+    }
+    return NULL;
+}
+
+/* updates sliders and the display */
+static void updatedisplay(gui_t *gui, HWND hwnd)
+{
+    if(!hwnd) return;
+
+    unsigned int i;
+    window_priv_t *priv = NULL;
+
+    /* load all potmeters hpotmeters */
+    for(i=0; i<gui->skin->widgetcount; i++)
+    {
+        if(gui->skin->widgets[i]->type == tyHpotmeter || gui->skin->widgets[i]->type == tyPotmeter)
+        {
+            if(gui->skin->widgets[i]->msg == evSetVolume)
+                gui->skin->widgets[i]->value = guiIntfStruct.Volume;
+            else if(gui->skin->widgets[i]->msg == evSetMoviePosition)
+                gui->skin->widgets[i]->value = guiIntfStruct.Position;
+            else if(gui->skin->widgets[i]->msg == evSetBalance)
+                gui->skin->widgets[i]->value = guiIntfStruct.Balance;
+            if(gui->skin->widgets[i]->window == get_windowtype(hwnd))
+                renderwidget(gui->skin, get_drawground(hwnd), gui->skin->widgets[i],
+                             gui->skin->widgets[i]->pressed ? 0 : 1);
+        }
+        /* update some buttons */
+        if(gui->skin->widgets[i]->type == tyButton && gui->skin->widgets[i]->window == get_windowtype(hwnd))
+        {
+            if(gui->skin->widgets[i]->msg == evPlaySwitchToPause)
+            {
+                gui->skin->widgets[i]->value = guiIntfStruct.Playing;
+                    renderwidget(gui->skin, get_drawground(hwnd), gui->skin->widgets[i],
+                                 guiIntfStruct.Playing == 1 ? 0 : 1);
+            }
+            if(gui->skin->widgets[i]->msg == evMute)
+            {
+                gui->skin->widgets[i]->value = guiIntfStruct.Volume;
+                    renderwidget(gui->skin, get_drawground(hwnd), gui->skin->widgets[i],
+                                 guiIntfStruct.Volume == 0.0f ? 0 : 1);
+            }
+        }
+    }
+
+    /* updating the display once a 100.second is enough imo */
+    DWORD time = timeGetTime();
+    if((time - oldtime) < 100) return;
+    oldtime=time;
+
+    for (i=0; i<gui->window_priv_count; i++)
+    {
+        if(gui->window_priv[i]->hwnd == hwnd)
+            priv=gui->window_priv[i];
+    }// Sherpya
+    /* display the status msgs */
+    renderinfobox(gui->skin, priv);
+    RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
+}
+
+static LRESULT CALLBACK SubProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+    if (gui && (gui->subwindow != hWnd)) return FALSE;
+
+    switch (message)
+    {
+        case WM_CLOSE:
+            handlemsg(hWnd, evExit);
+            return 0;
+        case WM_DESTROY:
+            PostQuitMessage(0);
+            return 0;
+        case WM_KEYDOWN:
+        {
+            switch(wParam)
+            {
+                case VK_LEFT:
+                    mplayer_put_key(KEY_LEFT);
+                    break;
+                case VK_UP:
+                    mplayer_put_key(KEY_UP);
+                    break;
+                case VK_RIGHT:
+                    mplayer_put_key(KEY_RIGHT);
+                    break;
+                case VK_DOWN:
+                    mplayer_put_key(KEY_DOWN);
+                    break;
+                case VK_TAB:
+                    mplayer_put_key(KEY_TAB);
+                    break;
+                case VK_BACK:
+                    mplayer_put_key(KEY_BS);
+                    break;
+                case VK_DELETE:
+                    mplayer_put_key(KEY_DELETE);
+                    break;
+                case VK_INSERT:
+                    mplayer_put_key(KEY_INSERT);
+                    break;
+                case VK_HOME:
+                    mplayer_put_key(KEY_HOME);
+                    break;
+                case VK_END:
+                    mplayer_put_key(KEY_END);
+                    break;
+                case VK_PRIOR:
+                    mplayer_put_key(KEY_PAGE_UP);
+                    break;
+                case VK_NEXT:
+                    mplayer_put_key(KEY_PAGE_DOWN);
+                    break;
+                case VK_ESCAPE:
+                    mplayer_put_key(KEY_ESC);
+                    break;
+            }
+            break;
+        }
+        case WM_COMMAND:
+        {
+            switch(LOWORD(wParam))
+            {
+                case IDEXIT:
+                    PostQuitMessage(0);
+                    handlemsg(hWnd, evExit);
+                    break;
+                case IDFILE_OPEN:
+                    handlemsg(hWnd, evLoadPlay);
+                    break;
+                case IDURL_OPEN:
+                    display_openurlwindow(gui, 0);
+                    break;
+                case IDDIR_OPEN:
+                {
+                    static char path[MAX_PATH];
+                    BROWSEINFO bi;
+                    memset(&bi, 0, sizeof(BROWSEINFO));
+                    bi.lpszTitle = "Choose a Directory...";
+                    LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
+                    if (SHGetPathFromIDList(pidl, path))
+                    {
+                        gui->playlist->clear_playlist(gui->playlist);
+                        adddirtoplaylist(gui->playlist, path, TRUE);
+                        gui->startplay(gui);
+                    }
+                    break;
+                }
+                case ID_PTRACK:
+                    handlemsg(hWnd, evPrev);
+                    break;
+                case ID_SEEKB:
+                    handlemsg(hWnd, evBackward10sec);
+                    break;
+                case ID_PLAY:
+                    handlemsg(hWnd, evPlaySwitchToPause);
+                    break;
+                case ID_STOP:
+                    handlemsg(hWnd, evStop);
+                    break;
+                case ID_SEEKF:
+                    handlemsg(hWnd, evForward10sec);
+                    break;
+                case ID_NTRACK:
+                    handlemsg(hWnd, evNext);
+                    break;
+#ifdef USE_DVDREAD
+                case ID_CHAPTERSEL:
+                    display_chapterselwindow(gui);
+                    break;
+#endif
+                case ID_ASPECT1:
+                    mp_input_queue_cmd(mp_input_parse_cmd("switch_ratio 1.777777"));
+                    break;
+                case ID_ASPECT2:
+                    mp_input_queue_cmd(mp_input_parse_cmd("switch_ratio 1.333333"));
+                    break;
+                case ID_ASPECT3:
+                    mp_input_queue_cmd(mp_input_parse_cmd("switch_ratio 2.35"));
+                    break;
+                case ID_ASPECT4:
+                    mp_input_queue_cmd(mp_input_parse_cmd("switch_ratio 0"));
+                    break;
+                case IDSUB_TOGGLE:
+                    mp_input_queue_cmd(mp_input_parse_cmd("sub_visibility"));
+                    break;
+                case IDSUB_CYCLE:
+                    mp_input_queue_cmd(mp_input_parse_cmd("sub_select"));
+                    break;
+            }
+            return 0;
+        }
+        case WM_CHAR:
+            mplayer_put_key(wParam);
+            break;
+        case WM_DROPFILES:
+        {
+            if(!lParam)
+            {
+                char file[MAX_PATH];
+                int filecount = DragQueryFile((HDROP) wParam, -1, file, MAX_PATH);
+                int i;
+                for(i=0; i<filecount; i++)
+                {
+                    DragQueryFile((HDROP) wParam, i, file, MAX_PATH);
+                    if(!parse_filename(file, playtree, mconfig, 1))
+                        gui->playlist->add_track(gui->playlist, file, NULL, NULL, 0);
+                }
+                DragFinish((HDROP) wParam);
+                handlemsg(hWnd, evDropFile);
+            }
+            else
+            {
+                gui->playlist->clear_playlist(gui->playlist);
+                gui->playlist->add_track(gui->playlist, (const char *) wParam, NULL, NULL, 0);
+                handlemsg(hWnd, evDropFile);
+            }
+            SetForegroundWindow(gui->subwindow);
+            return 0;
+        }
+        case WM_LBUTTONDOWN:
+        {
+            if(!vo_nomouse_input)
+               mplayer_put_key(MOUSE_BTN0);
+            break;
+        }
+        case WM_MBUTTONDOWN:
+        {
+            if(!vo_nomouse_input)
+               mplayer_put_key(MOUSE_BTN1);
+            break;
+        }
+        case WM_RBUTTONDOWN:
+        {
+            POINT point;
+            point.x = GET_X_LPARAM(lParam);
+            point.y = GET_Y_LPARAM(lParam);
+            ClientToScreen(hWnd, &point);
+            if(guiIntfStruct.StreamType == STREAMTYPE_DVD)
+                EnableMenuItem(gui->dvdmenu, ID_CHAPTERSEL, MF_BYCOMMAND | MF_ENABLED);
+            TrackPopupMenu(gui->submenu, 0, point.x, point.y, 0, hWnd, NULL);
+            return 0;
+        }
+        case WM_LBUTTONDBLCLK:
+        {
+            if(!vo_nomouse_input)
+                mplayer_put_key(MOUSE_BTN0_DBL);
+            break;
+        }
+        case WM_MBUTTONDBLCLK:
+        {
+            if(!vo_nomouse_input)
+                mplayer_put_key(MOUSE_BTN1_DBL);
+            break;
+        }
+        case WM_RBUTTONDBLCLK:
+        {
+            if(!vo_nomouse_input)
+                mplayer_put_key(MOUSE_BTN2_DBL);
+            break;
+        }
+        case WM_MOUSEWHEEL:
+        {
+            if(vo_nomouse_input)
+                break;
+            int x = GET_WHEEL_DELTA_WPARAM(wParam);
+            if (x > 0)
+                mplayer_put_key(MOUSE_BTN3);
+            else
+                mplayer_put_key(MOUSE_BTN4);
+            break;
+        }
+        case WM_XBUTTONDOWN:
+        {
+            if(vo_nomouse_input)
+                break;
+            if(HIWORD(wParam) == 1)
+                mplayer_put_key(MOUSE_BTN5);
+            else
+                mplayer_put_key(MOUSE_BTN6);
+            break;
+        }
+        case WM_XBUTTONDBLCLK:
+        {
+            if(vo_nomouse_input)
+                break;
+            if(HIWORD(wParam) == 1)
+                mplayer_put_key(MOUSE_BTN5_DBL);
+            else
+                mplayer_put_key(MOUSE_BTN6_DBL);
+            break;
+        }
+        case WM_WINDOWPOSCHANGED:
+        {
+            int tmpheight=0;
+            static uint32_t rect_width;
+            static uint32_t rect_height;
+            RECT rd;
+            POINT pt;
+            while(ShowCursor(TRUE) <= 0){}
+            pt.x = 0;
+            pt.y = 0;
+            GetClientRect(hWnd, &rd);
+            ClientToScreen(hWnd, &pt);
+
+            rect_width = rd.right - rd.left;
+            rect_height = rd.bottom - rd.top;
+
+            /* maintain our aspect ratio */
+            tmpheight = ((float)rect_width/sub_aspect);
+            tmpheight += tmpheight % 2;
+            if(tmpheight > rect_height)
+            {
+                rect_width = ((float)rect_height*sub_aspect);
+                rect_width += rect_width % 2;
+            }
+            else rect_height = tmpheight;
+
+            rd.right = rd.left + rect_width;
+            rd.bottom = rd.top + rect_height;
+
+            AdjustWindowRect(&rd, WS_OVERLAPPEDWINDOW | WS_SIZEBOX, 0);
+            SetWindowPos(hWnd, HWND_NOTOPMOST, pt.x+rd.left, pt.y+rd.top,
+                         rd.right-rd.left, rd.bottom-rd.top, SWP_NOOWNERZORDER);
+            return 0;
+        }
+        case WM_PAINT:
+        {
+            PAINTSTRUCT ps;
+            RECT rect;
+            HDC hdc = BeginPaint(hWnd, &ps);
+            HDC hMemDC = CreateCompatibleDC(hdc);
+            int width, height;
+            GetClientRect(hWnd, &rect);
+            width = rect.right - rect.left;
+            height = rect.bottom - rect.top;
+            if(guiIntfStruct.Playing == 0)
+            {
+                int i;
+                window *desc = NULL;
+
+                for (i=0; i<gui->skin->windowcount; i++)
+                    if(gui->skin->windows[i]->type == wiSub)
+                        desc = gui->skin->windows[i];
+
+                SelectObject(hMemDC, get_bitmap(hWnd));
+                StretchBlt(hdc, 0, 0, width, height, hMemDC, 0, 0, desc->base->bitmap[0]->width,
+                           desc->base->bitmap[0]->height, SRCCOPY);
+            }
+            DeleteDC(hMemDC);
+            EndPaint(hWnd, &ps);
+            return 0;
+        }
+    }
+    return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+/* Window Proc for the gui Window */
+static LRESULT CALLBACK EventProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    gui_t *gui = (gui_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+    /* Avoid processing when then window doesn't match gui mainwindow */
+    if (gui && (gui->mainwindow != hWnd)) return FALSE;
+
+    switch (message)
+    {
+        case WM_CLOSE:
+            handlemsg(hWnd, evExit);
+            return 0;
+        case WM_DESTROY:
+            PostQuitMessage(0);
+            return 0;
+        case WM_SYSTRAY:
+        {
+            switch(lParam)
+            {
+                POINT cursor;
+                case WM_RBUTTONDOWN:
+                {
+                    GetCursorPos(&cursor);
+                    SetForegroundWindow(hWnd);
+                    TrackPopupMenu(gui->traymenu, 0, cursor.x, cursor.y, 0, hWnd, NULL);
+                    break;
+                }
+                case WM_MBUTTONDBLCLK:
+                case WM_LBUTTONDBLCLK:
+                {
+                    if(IsWindowVisible(hWnd)) ShowWindow(hWnd, SW_HIDE);
+                    else { ShowWindow(hWnd, SW_SHOW); SetForegroundWindow(hWnd); }
+                    break;
+                }
+            }
+            break;
+        }
+        case WM_KEYDOWN:
+        {
+            switch(wParam)
+            {
+                case VK_LEFT:
+                    mplayer_put_key(KEY_LEFT);
+                    break;
+                case VK_UP:
+                    mplayer_put_key(KEY_UP);
+                    break;
+                case VK_RIGHT:
+                    mplayer_put_key(KEY_RIGHT);
+                    break;
+                case VK_DOWN:
+                    mplayer_put_key(KEY_DOWN);
+                    break;
+                case VK_TAB:
+                    mplayer_put_key(KEY_TAB);
+                    break;
+                case VK_BACK:
+                    mplayer_put_key(KEY_BS);
+                    break;
+                case VK_DELETE:
+                    mplayer_put_key(KEY_DELETE);
+                    break;
+                case VK_INSERT:
+                    mplayer_put_key(KEY_INSERT);
+                    break;
+                case VK_HOME:
+                    mplayer_put_key(KEY_HOME);
+                    break;
+                case VK_END:
+                    mplayer_put_key(KEY_END);
+                    break;
+                case VK_PRIOR:
+                    mplayer_put_key(KEY_PAGE_UP);
+                    break;
+                case VK_NEXT:
+                    mplayer_put_key(KEY_PAGE_DOWN);
+                    break;
+                case VK_ESCAPE:
+                    mplayer_put_key(KEY_ESC);
+                    break;
+            }
+            break;
+        }
+        case WM_CHAR:
+            mplayer_put_key(wParam);
+            break;
+        case WM_SYSCOMMAND:
+        {
+            switch(wParam)
+            {
+                case SC_SCREENSAVE:
+                case SC_MONITORPOWER:
+                    mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>killing screensaver\n" );
+                    return 0;
+            }
+            break;
+        }
+        case WM_COPYDATA:
+        {
+            if(lParam)
+            {
+                PCOPYDATASTRUCT cdData;
+                cdData = (PCOPYDATASTRUCT) lParam;
+                if(!parse_filename(cdData->lpData, playtree, mconfig, 1))
+                    gui->playlist->add_track(gui->playlist, cdData->lpData, NULL, NULL, 0);
+                gui->startplay(gui);
+            }
+            break;
+        }
+        case WM_DROPFILES:
+        {
+            if(!lParam)
+            {
+                char file[MAX_PATH];
+                int filecount = DragQueryFile((HDROP) wParam, -1, file, MAX_PATH);
+                int i;
+                for(i=0; i<filecount; i++)
+                {
+                    DragQueryFile((HDROP) wParam, i, file, MAX_PATH);
+                    if(!parse_filename(file, playtree, mconfig, 1))
+                        gui->playlist->add_track(gui->playlist, file, NULL, NULL, 0);
+                }
+                DragFinish((HDROP) wParam);
+                handlemsg(hWnd, evDropFile);
+            }
+            else
+            {
+                gui->playlist->clear_playlist(gui->playlist);
+                gui->playlist->add_track(gui->playlist, (const char *) wParam, NULL, NULL, 0);
+                handlemsg(hWnd, evDropFile);
+            }
+            SetForegroundWindow(gui->mainwindow);
+            return 0;
+        }
+        case WM_LBUTTONDOWN:
+        {
+            SetCapture(hWnd);
+            gui->mousex = GET_X_LPARAM(lParam);
+            gui->mousey = GET_Y_LPARAM(lParam);
+            /* inside a widget */
+            gui->activewidget = clickedinsidewidget(gui, get_windowtype(hWnd), gui->mousex, gui->mousey);
+            if(gui->activewidget)
+            {
+                gui->activewidget->pressed = 1;
+                gui->mousewx = gui->mousex - gui->activewidget->x;
+                gui->mousewy = gui->mousey - gui->activewidget->y;
+                renderwidget(gui->skin, get_drawground(hWnd), gui->activewidget, 0);
+                RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
+                handlemsg(hWnd, gui->activewidget->msg);
+            }
+            break;
+        }
+        case WM_CAPTURECHANGED:
+        {
+            if(gui->activewidget)
+            {
+                gui->activewidget->pressed = 0;
+                renderwidget(gui->skin, get_drawground(hWnd), gui->activewidget, 1);
+                RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
+                gui->activewidget = NULL;
+            }
+            break;
+        }
+        case WM_LBUTTONUP:
+        {
+            ReleaseCapture();
+            if(gui->activewidget)
+            {
+                gui->activewidget->pressed = 0;
+                renderwidget(gui->skin, get_drawground(hWnd), gui->activewidget, 1);
+                RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
+                gui->activewidget = NULL;
+            }
+            break;
+        }
+        case WM_RBUTTONDOWN:
+        {
+            POINT point;
+            char device[MAX_PATH];
+            char searchpath[MAX_PATH];
+            char searchpath2[MAX_PATH];
+#ifdef HAVE_LIBCDIO
+            char searchpath3[MAX_PATH];
+#endif
+            int len, pos = 0, cdromdrive = 0;
+            point.x = GET_X_LPARAM(lParam);
+            point.y = GET_Y_LPARAM(lParam);
+            ClientToScreen(hWnd, &point);
+            len = GetLogicalDriveStrings(MAX_PATH, device);
+            while(pos < len)
+            {
+                if(GetDriveType(device + pos) == DRIVE_CDROM)
+                {
+                    mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] checking %s for CD/VCD/SVCD/DVDs\n", device + pos);
+                    sprintf(searchpath, "%sVIDEO_TS", device + pos);
+                    sprintf(searchpath2, "%sMpegav", device + pos);
+#ifdef HAVE_LIBCDIO
+                    sprintf(searchpath3, "%sTrack01.cda", device + pos);
+#endif
+                    if(GetFileAttributes(searchpath) != INVALID_FILE_ATTRIBUTES)
+                        EnableMenuItem(gui->diskmenu, IDPLAYDISK + cdromdrive, MF_BYCOMMAND | MF_ENABLED);
+                    else if(GetFileAttributes(searchpath2) != INVALID_FILE_ATTRIBUTES)
+                        EnableMenuItem(gui->diskmenu, IDPLAYDISK + cdromdrive, MF_BYCOMMAND | MF_ENABLED);
+#ifdef HAVE_LIBCDIO
+                    else if(GetFileAttributes(searchpath3) != INVALID_FILE_ATTRIBUTES)
+                        EnableMenuItem(gui->diskmenu, IDPLAYDISK + cdromdrive, MF_BYCOMMAND | MF_ENABLED);
+#endif
+                    else EnableMenuItem(gui->diskmenu, IDPLAYDISK + cdromdrive, MF_BYCOMMAND | MF_GRAYED);
+                        cdromdrive++;
+                }
+                pos += strlen(device + pos) + 1;
+            }
+            TrackPopupMenu(gui->menu, 0, point.x, point.y, 0, hWnd, NULL);
+            return 0;
+        }
+        case WM_MOUSEMOVE:
+        {
+            if(wParam & MK_LBUTTON)
+            {
+                POINT point;
+                RECT rect;
+                if(gui->activewidget)
+                {
+                    widget *item = gui->activewidget;
+
+                    if(item->type == tyHpotmeter)
+                    {
+                        item->x = GET_X_LPARAM(lParam) - gui->mousewx;
+                        item->value = (float)((float)((item->x - item->wx) * 100.0f) / (float)(item->wwidth - item->width));
+                    }
+                    if(item->type == tyPotmeter)
+                    {
+                        gui->mousewx = GET_X_LPARAM(lParam) - gui->activewidget->x;
+                        item->value = (float) (gui->mousewx * 100.0f) / (float) item->wwidth;
+                    }
+
+                    if((item->type == tyPotmeter) || (item->type == tyHpotmeter) || (item->type == tyVpotmeter))
+                    {
+                        /* Bound checks */
+                        if(item->value > 100.0f)
+                            item->value = 100.0f;
+                        else if(item->value < 0.0f)
+                            item->value = 0.0f;
+
+                        if(item->msg == evSetVolume)
+                            guiIntfStruct.Volume = (float) item->value;
+                        else if(item->msg == evSetMoviePosition)
+                            guiIntfStruct.Position = (float) item->value;
+                        else if(item->msg == evSetBalance)
+                        {
+                            /* make the range for 50% a bit bigger, because the sliders for balance usually suck */
+                            if((item->value - 50.0f < 1.5f) && (item->value - 50.0f > -1.5f))
+                                item->value = 50.0f;
+                            guiIntfStruct.Balance = (float) item->value;
+                        }
+                        updatedisplay(gui, hWnd);
+                        handlemsg(hWnd, item->msg);
+                    }
+                    break;
+                }
+                point.x = GET_X_LPARAM(lParam);
+                point.y = GET_Y_LPARAM(lParam);
+                ClientToScreen(hWnd, &point);
+                GetWindowRect(hWnd, &rect);
+                MoveWindow(hWnd, point.x - gui->mousex, point.y - gui->mousey,
+                           rect.right-rect.left,rect.bottom-rect.top,TRUE);
+                break;
+            }
+            break;
+        }
+        case WM_COMMAND:
+        {
+            switch(LOWORD(wParam))
+            {
+                case IDEXIT:
+                    PostQuitMessage(0);
+                    handlemsg(hWnd, evExit);
+                    break;
+                case IDFILE_OPEN:
+                    handlemsg(hWnd, evLoadPlay);
+                    break;
+                case IDDIR_OPEN:
+                {
+                    static char path[MAX_PATH];
+                    BROWSEINFO bi;
+                    memset(&bi, 0, sizeof(BROWSEINFO));
+                    bi.lpszTitle = "Choose a Directory...";
+                    LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
+                    if (SHGetPathFromIDList(pidl, path))
+                    {
+                        gui->playlist->clear_playlist(gui->playlist);
+                        adddirtoplaylist(gui->playlist, path, TRUE);
+                        gui->startplay(gui);
+                    }
+                    break;
+                }
+                case ID_SKINBROWSER:
+                    handlemsg(hWnd, evSkinBrowser);
+                    break;
+                case IDURL_OPEN:
+                    display_openurlwindow(gui, 0);
+                    break;
+#ifdef USE_SUB
+                case IDSUBTITLE_OPEN:
+                    display_opensubtitlewindow(gui);
+                    break;
+#endif
+                case ID_PTRACK:
+                    handlemsg(hWnd, evPrev);
+                    break;
+                case ID_SEEKB:
+                    handlemsg(hWnd, evBackward10sec);
+                    break;
+                case ID_PLAY:
+                    handlemsg(hWnd, evPlaySwitchToPause);
+                    break;
+                case ID_STOP:
+                    handlemsg(hWnd, evStop);
+                    break;
+                case ID_SEEKF:
+                    handlemsg(hWnd, evForward10sec);
+                    break;
+                case ID_NTRACK:
+                    handlemsg(hWnd, evNext);
+                    break;
+                case ID_SHOWHIDE:
+                {
+                    if(IsWindowVisible(hWnd)) ShowWindow(hWnd, SW_HIDE);
+                    else ShowWindow(hWnd, SW_SHOW);
+                    break;
+                }
+                case ID_PLAYLIST:
+                    handlemsg(hWnd, evPlayList);
+                    break;
+                case ID_PREFS:
+                    handlemsg(hWnd, evPreferences);
+                    break;
+                case ID_CONSOLE:
+                    console_toggle();
+                    break;
+                case ID_ONLINEHELP:
+                    ShellExecute(NULL, "open", ONLINE_HELP_URL, NULL, NULL, SW_SHOWNORMAL);
+                    break;
+            }
+            if((IDPLAYDISK <= LOWORD(wParam)) && (LOWORD(wParam) < (IDPLAYDISK + 100)))
+            {
+                char device[MAX_PATH];
+                char searchpath[MAX_PATH];
+                char filename[MAX_PATH];
+                int len, pos = 0, cdromdrive = 0;
+                len = GetLogicalDriveStrings(MAX_PATH, device);
+                while(pos < len)
+                {
+                    if(GetDriveType(device + pos)==DRIVE_CDROM)
+                    {
+                        if(LOWORD(wParam) - IDPLAYDISK == cdromdrive)
+                        {
+#ifdef USE_DVDREAD
+                            sprintf(searchpath, "%sVIDEO_TS", device + pos);
+                            if(GetFileAttributes(searchpath) != INVALID_FILE_ATTRIBUTES)
+                            {
+                                if (dvd_device) free(dvd_device);
+                                dvd_device = strdup(device + pos);
+                                dvd_title = dvd_chapter = dvd_angle = 1;
+                                handlemsg(hWnd, evPlayDVD);
+                            }
+#endif
+#ifdef HAVE_LIBCDIO
+                            sprintf(searchpath, "%sTrack01.cda", device + pos);
+                            if(GetFileAttributes(searchpath) != INVALID_FILE_ATTRIBUTES)
+                            {
+                                if (cdrom_device) free(cdrom_device);
+                                cdrom_device = strdup(device + pos);
+                                /* mplayer doesn't seem to like the trailing \ after the device name */
+                                cdrom_device[2]=0;
+                                handlemsg(hWnd, evPlayCD);
+                            }
+#endif
+                            else
+                            {
+                                HANDLE searchhndl;
+                                WIN32_FIND_DATA finddata;
+                                sprintf(searchpath, "%smpegav\\*.dat", device + pos);
+                                if((searchhndl=FindFirstFile(searchpath, &finddata)) != INVALID_HANDLE_VALUE)
+                                {
+                                    mp_msg(MSGT_GPLAYER,MSGL_V, "Opening VCD/SVCD\n");
+                                    gui->playlist->clear_playlist(gui->playlist);
+                                    do
+                                    {
+                                        sprintf(filename, "%smpegav\\%s", device + pos, finddata.cFileName);
+                                        gui->playlist->add_track(gui->playlist, filename, NULL, NULL, 0);
+                                    }
+                                    while(FindNextFile(searchhndl, &finddata));
+                                    FindClose(searchhndl);
+                                }
+                                gui->startplay(gui);
+                            }
+                        }
+                        cdromdrive++;
+                    }
+                    pos += strlen(device + pos) + 1;
+                }
+            }
+            break;
+        }
+        case WM_PAINT:
+        {
+            PAINTSTRUCT ps;
+            RECT rd;
+            HDC hdc = BeginPaint(hWnd, &ps);
+            HDC hMemDC = CreateCompatibleDC(hdc);
+            int width, height;
+            GetClientRect(hWnd, &rd);
+            width = rd.right - rd.left;
+            height = rd.bottom - rd.top;
+            SelectObject(hMemDC, get_bitmap(hWnd));
+            BitBlt(hdc, 0, 0, width, height, hMemDC, 0, 0, SRCCOPY);
+            DeleteDC(hMemDC);
+            EndPaint(hWnd, &ps);
+            return 0;
+        }
+        return 0;
+    }
+    return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+inline void startplay(gui_t *gui)
+{
+    handlemsg(gui->mainwindow, evDropFile);
+}
+
+/* returns the bits per pixel of the desktop */
+/* the format is always in BGR byte order */
+static int GetDesktopBitsPerPixel(void)
+{
+    HWND desktop=GetDesktopWindow();
+    HDC dc=GetDC(desktop);
+    int bpp=GetDeviceCaps(dc, BITSPIXEL);
+    ReleaseDC(desktop, dc);
+    return bpp;
+}
+
+/* unloads a skin and destroys its windows */
+extern int destroy_window(gui_t *gui)
+{
+    RECT rd;
+    unsigned int i;
+
+    /* Save position: MSDN says don't pass workspace coordinates
+     * to CreateWindow() or SetWindowPos(), as both of which expect
+     * screen coordinates; resulting in the window appearing in the
+     * wrong location.
+     * -Erik
+     */
+
+    /* main window position */
+    if(IsIconic(gui->mainwindow))
+        ShowWindow(gui->mainwindow, SW_SHOWNORMAL);
+    GetWindowRect(gui->mainwindow, &rd);
+    gui_main_pos_x = rd.left;
+    gui_main_pos_y = rd.top;
+
+    /* sub window position */
+    if(IsIconic(gui->subwindow))
+        ShowWindow(gui->subwindow, SW_SHOWNORMAL);
+    GetWindowRect(gui->subwindow, &rd);
+    gui_sub_pos_x = rd.left;
+    gui_sub_pos_y = rd.top;
+
+    for(i=0; i<gui->window_priv_count; i++)
+    {
+        if(gui->window_priv[i]->bitmap)
+            DeleteObject(gui->window_priv[i]->bitmap);
+        free(gui->window_priv[i]);
+    }
+    free(gui->window_priv);
+    gui->window_priv = NULL;
+    gui->window_priv_count = 0;
+
+    /* destroy the main window */
+    if(gui->mainwindow)
+        DestroyWindow(gui->mainwindow);
+    gui->mainwindow = NULL;
+
+    /* destroy the sub window */
+    if(gui->subwindow)
+        DestroyWindow(gui->subwindow);
+    gui->subwindow = NULL;
+
+    UnregisterClass(gui->classname, 0);
+    DestroyIcon(gui->icon);
+
+    gui->skin->freeskin(gui->skin);
+    gui->skin = NULL;
+    return 0;
+}
+
+static void create_menu(gui_t *gui)
+{
+    char device[MAX_PATH];
+    char volname[MAX_PATH];
+    char menuitem[MAX_PATH];
+    int len, pos = 0, cdromdrive = 0;
+    gui->diskmenu = CreatePopupMenu();
+    len = GetLogicalDriveStrings(MAX_PATH, device);
+    while(pos < len)
+    {
+        if(GetDriveType(device + pos) == DRIVE_CDROM)
+        {
+            volname[0] = 0;
+            menuitem[0] = 0;
+            strcat(menuitem, device + pos);
+            menuitem[strlen(menuitem) - 1]=0;
+            GetVolumeInformation(device + pos, volname, MAX_PATH, NULL, NULL, NULL, NULL, 0);
+            if (strlen(volname))
+            {
+                capitalize(volname);
+                strcat(menuitem, " - ");
+                strcat(menuitem, volname);
+            }
+            AppendMenu(gui->diskmenu, MF_STRING, IDPLAYDISK + cdromdrive, menuitem);
+            cdromdrive++;
+        }
+        pos += strlen(device + pos) + 1;
+    }
+    gui->menu=CreatePopupMenu();
+    gui->trayplaymenu = CreatePopupMenu();
+    AppendMenu(gui->menu, MF_STRING | MF_POPUP, (UINT) gui->trayplaymenu, "Open...");
+    AppendMenu(gui->trayplaymenu, MF_STRING, IDFILE_OPEN, "File...");
+    AppendMenu(gui->trayplaymenu, MF_STRING, IDURL_OPEN, "Url...");
+    AppendMenu(gui->trayplaymenu, MF_STRING, IDDIR_OPEN, "Directory...");
+    AppendMenu(gui->menu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->menu, MF_STRING | MF_POPUP, (UINT) gui->diskmenu, "Play &CD/DVD/VCD/SVCD");
+    AppendMenu(gui->menu, MF_SEPARATOR, 0, 0);
+#ifdef USE_SUB
+    AppendMenu(gui->menu, MF_STRING, IDSUBTITLE_OPEN, "Open Subtitle");
+#endif
+    AppendMenu(gui->menu, MF_STRING, ID_SKINBROWSER, "Skin Browser");
+    AppendMenu(gui->menu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->menu, MF_STRING, ID_PREFS, "Preferences");
+    AppendMenu(gui->menu, MF_STRING, ID_CONSOLE, "Debug Console");
+    AppendMenu(gui->menu, MF_STRING, ID_ONLINEHELP, "Online Help");
+    AppendMenu(gui->menu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->menu, MF_STRING, IDEXIT, "&Exit");
+}
+
+static void create_traymenu(gui_t *gui)
+{
+    gui->traymenu = CreatePopupMenu();
+    gui->trayplaybackmenu = CreatePopupMenu();
+    AppendMenu(gui->traymenu, MF_STRING | MF_POPUP, (UINT) gui->trayplaymenu, "Open...");
+    AppendMenu(gui->traymenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->traymenu, MF_STRING | MF_POPUP, (UINT) gui->trayplaybackmenu, "Playback");
+    AppendMenu(gui->trayplaybackmenu, MF_STRING, ID_SEEKB, "Seek Backwards");
+    AppendMenu(gui->trayplaybackmenu, MF_STRING, ID_PTRACK, "Previous Track");
+    AppendMenu(gui->trayplaybackmenu, MF_STRING, ID_PLAY, "Play/Pause");
+    AppendMenu(gui->trayplaybackmenu, MF_STRING, ID_STOP, "Stop");
+    AppendMenu(gui->trayplaybackmenu, MF_STRING, ID_NTRACK, "Next Track");
+    AppendMenu(gui->trayplaybackmenu, MF_STRING, ID_SEEKF, "Seek Forwards");
+    AppendMenu(gui->traymenu, MF_SEPARATOR, 0, 0);
+#ifdef USE_SUB
+    AppendMenu(gui->traymenu, MF_STRING, IDSUBTITLE_OPEN, "Open Subtitle");
+#endif
+    AppendMenu(gui->traymenu, MF_STRING, ID_PLAYLIST, "Playlist");
+    AppendMenu(gui->traymenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->traymenu, MF_STRING, ID_SHOWHIDE, "Show/Hide");
+    AppendMenu(gui->traymenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->traymenu, MF_STRING, ID_PREFS, "Preferences");
+    AppendMenu(gui->traymenu, MF_STRING, ID_CONSOLE, "Debug Console");
+    AppendMenu(gui->traymenu, MF_STRING, ID_ONLINEHELP, "Online Help");
+    AppendMenu(gui->traymenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->traymenu, MF_STRING, IDEXIT, "&Exit");
+}
+
+static void create_submenu(gui_t *gui)
+{
+    gui->submenu = CreatePopupMenu();
+    gui->dvdmenu = CreatePopupMenu();
+    gui->aspectmenu = CreatePopupMenu();
+    gui->subtitlemenu = CreatePopupMenu();
+    AppendMenu(gui->submenu, MF_STRING | MF_POPUP, (UINT) gui->trayplaymenu, "Open...");
+    AppendMenu(gui->submenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->submenu, MF_STRING, ID_SEEKB, "Seek Backwards");
+    AppendMenu(gui->submenu, MF_STRING, ID_PTRACK, "Previous Track");
+    AppendMenu(gui->submenu, MF_STRING, ID_PLAY, "Play/Pause");
+    AppendMenu(gui->submenu, MF_STRING, ID_STOP, "Stop");
+    AppendMenu(gui->submenu, MF_STRING, ID_NTRACK, "Next Track");
+    AppendMenu(gui->submenu, MF_STRING, ID_SEEKF, "Seek Forwards");
+    AppendMenu(gui->submenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->submenu, MF_STRING | MF_POPUP, (UINT) gui->aspectmenu, "Aspect Ratio");
+    AppendMenu(gui->submenu, MF_STRING | MF_POPUP, (UINT) gui->subtitlemenu, "Subtitle Options");
+    AppendMenu(gui->submenu, MF_STRING | MF_POPUP, (UINT) gui->dvdmenu, "DVD Options");
+#ifdef USE_DVDREAD
+    AppendMenu(gui->dvdmenu, MF_STRING | MF_GRAYED, ID_CHAPTERSEL, "Select Title/Chapter...");
+#endif
+    AppendMenu(gui->subtitlemenu, MF_STRING, IDSUB_TOGGLE, "Subtitle Visibility On/Off");
+    AppendMenu(gui->subtitlemenu, MF_STRING, IDSUB_CYCLE, "Cycle Subtitle Languages");
+    AppendMenu(gui->aspectmenu, MF_STRING, ID_ASPECT1, "Set 16:9");
+    AppendMenu(gui->aspectmenu, MF_STRING, ID_ASPECT2, "Set 4:3");
+    AppendMenu(gui->aspectmenu, MF_STRING, ID_ASPECT3, "Set 2.35");
+    AppendMenu(gui->aspectmenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->aspectmenu, MF_STRING, ID_ASPECT4, "Original Aspect");
+    AppendMenu(gui->submenu, MF_SEPARATOR, 0, 0);
+    AppendMenu(gui->submenu, MF_STRING, IDEXIT, "&Exit");
+}
+
+static void maketransparent(HWND hwnd, COLORREF crTransparent)
+{
+    HDC mdc = GetDC(hwnd);
+    RECT rd;
+    HRGN crRgnres, crRgn, crRgnTmp;
+    int iX = 0, iY = 0, iLeftX = 0;
+    int width, height;
+    GetWindowRect(hwnd, &rd);
+    width = rd.right - rd.left;
+    height = rd.bottom - rd.top;
+
+    /* create an empty region */
+    crRgn = CreateRectRgn(0, 0, 0, 0);
+
+    /* Create a region from a bitmap with transparency colour of Purple */
+    for (iY = -1; iY < height; iY++)
+    {
+        do
+        {
+            /* skip over transparent pixels at start of lines */
+            while (iX <= width && GetPixel(mdc,iX, iY) == crTransparent) iX++;
+
+            /* remember this pixel */
+            iLeftX = iX;
+
+            /* now find first non transparent pixel */
+            while (iX <= width && GetPixel(mdc,iX, iY) != crTransparent) ++iX;
+
+            /* create a temp region on this info */
+            crRgnTmp = CreateRectRgn(iLeftX, iY, iX, iY+1);
+
+            /* combine into main region */
+            crRgnres = crRgn;
+            CombineRgn(crRgnres, crRgn, crRgnTmp, RGN_OR);
+            crRgn = crRgnres;
+
+            /* delete the temp region for next pass (otherwise you'll get an ASSERT) */
+            DeleteObject(crRgnTmp);
+        } while (iX < width);
+        iX = 0;
+    }
+    SetWindowRgn(hwnd, crRgn, TRUE);
+    DeleteObject(crRgn);
+    ReleaseDC(hwnd,mdc);
+}
+
+static int window_render(gui_t *gui, HWND hWnd, HDC hdc, window_priv_t *priv, window *desc, BITMAPINFO binfo)
+{
+    int i;
+    SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD) gui);
+    (gui->window_priv_count)++;
+    gui->window_priv = realloc(gui->window_priv, sizeof(window_priv_t *) * gui->window_priv_count);
+    priv = gui->window_priv[gui->window_priv_count - 1] = calloc(1, sizeof(window_priv_t));
+    priv->hwnd = hWnd;
+    priv->type = desc->type;
+    priv->background = desc->base->bitmap[0];
+    memcpy(&priv->img, desc->base->bitmap[0], sizeof(image));
+    hdc = GetDC(hWnd);
+    binfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    binfo.bmiHeader.biWidth = priv->img.width;
+    binfo.bmiHeader.biHeight = -priv->img.height;
+    binfo.bmiHeader.biPlanes = 1;
+    binfo.bmiHeader.biSizeImage = priv->img.width * priv->img.height * (gui->screenbpp / 8);
+    binfo.bmiHeader.biXPelsPerMeter = 0;
+    binfo.bmiHeader.biYPelsPerMeter = 0;
+    binfo.bmiHeader.biClrUsed = 0;
+    binfo.bmiHeader.biClrImportant = 0;
+    binfo.bmiHeader.biBitCount = gui->screenbpp;
+    binfo.bmiHeader.biCompression = BI_RGB;
+    priv->bitmap = CreateDIBSection(hdc, &binfo, DIB_RGB_COLORS, (void **) &priv->img.data, NULL, 0);
+    if(!priv->bitmap)
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_FATAL, "[GUI] unable to create bitmap for skinned window\n");
+        return 0;
+    }
+    memcpy(priv->img.data, desc->base->bitmap[0]->data, binfo.bmiHeader.biSizeImage);
+    ReleaseDC(hWnd,hdc);
+
+    for (i=0; i<gui->skin->widgetcount; i++)
+        if(gui->skin->widgets[i]->window == desc->type)
+            renderwidget(gui->skin, &priv->img, gui->skin->widgets[i], 1);
+
+    return 0;
+}
+
+/* creates the sub (AKA video) window,*/
+extern int create_subwindow(gui_t *gui, char *skindir)
+{
+    HINSTANCE instance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    RECT rect;
+    HWND hWnd;
+    DWORD style = 0;
+    HDC hdc = NULL;
+    BITMAPINFO binfo;
+    window_priv_t *priv = NULL;
+    window *desc = NULL;
+    int i, x = -1, y = -1;
+
+    for (i=0; i<gui->skin->windowcount; i++)
+        if(gui->skin->windows[i]->type == wiSub)
+            desc = gui->skin->windows[i];
+
+    if(!desc)
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_FATAL, "[GUI] Invalid skin description\n");
+        return 1;
+    }
+
+    windowcolor = vo_colorkey;
+    colorbrush = CreateSolidBrush(windowcolor);
+    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
+    wc.lpfnWndProc = SubProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = instance;
+    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+    wc.hIcon = gui->icon;
+    wc.hbrBackground = colorbrush;
+    wc.lpszClassName = "MPlayer Sub for Windows";
+    wc.lpszMenuName = NULL;
+    RegisterClass(&wc);
+
+    /* create the sub window menu */
+    create_submenu(gui);
+
+    rect.top = rect.left = 100;
+    rect.bottom = rect.top+desc->base->bitmap[0]->height;
+    rect.right = rect.left+desc->base->bitmap[0]->width;
+
+    /* our window aspect */
+    sub_aspect = (float)(rect.right-rect.left)/(rect.bottom-rect.top);
+
+    style = WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_MINIMIZEBOX;
+    AdjustWindowRect(&rect, style, 0);
+
+    if (gui_sub_pos_x >= 0)
+        x = gui_sub_pos_x;
+    if (gui_sub_pos_y >= 0)
+        y = gui_sub_pos_y;
+
+    /* out of bounds check */
+    if (x <= -1 || (x+(rect.right-rect.left) > GetSystemMetrics(SM_CXSCREEN)))
+        x = CW_USEDEFAULT;
+    if (y <= -1 || (y+(rect.bottom-rect.top) > GetSystemMetrics(SM_CYSCREEN)))
+        y = x;
+
+    hWnd = CreateWindowEx(0, "MPlayer Sub for Windows", "MPlayer for Windows", style,
+                          x, y, rect.right-rect.left, rect.bottom-rect.top,
+                          gui->subwindow, NULL, instance, NULL);
+
+    /* load all the window images */
+    window_render(gui, hWnd, hdc, priv, desc, binfo);
+
+    /* enable drag and drop support */
+    DragAcceptFiles(hWnd, TRUE);
+
+    gui->subwindow = hWnd;
+    if(sub_window)
+        WinID = gui->subwindow;
+    ShowWindow(gui->subwindow, SW_SHOW);
+    UpdateWindow(gui->subwindow);
+    return 0;
+}
+
+/* loads/updates a skin and creates windows for it */
+extern int create_window(gui_t *gui, char *skindir)
+{
+    HINSTANCE instance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    RECT rect;
+    DWORD style = 0;
+    HWND hwnd;
+    HDC hdc = NULL;
+    BITMAPINFO binfo;
+    window_priv_t *priv = NULL;
+    window *desc = NULL;
+    char dir[MAX_PATH];
+    unsigned int i;
+
+    /* destroy the current main window */
+    if(gui->skin) destroy_window(gui);
+
+    /* get screenproperties */
+    gui->screenbpp = GetDesktopBitsPerPixel();
+    gui->screenw = GetSystemMetrics(SM_CXSCREEN);
+    gui->screenh = GetSystemMetrics(SM_CYSCREEN);
+
+    /* load the new skin */
+    gui->skin = loadskin(skindir, gui->screenbpp);
+    if(!gui->skin)
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_FATAL, "[GUI] fatal error during skinload\n");
+        /* Set default Skin */
+        if (skinName) free(skinName);
+        skinName = strdup("Blue");
+        /* then force write conf */
+        cfg_write();
+        return 1;
+    }
+
+    /* find the description of the mainwindow */
+    for (i=0; i<gui->skin->windowcount; i++)
+        if(gui->skin->windows[i]->type == wiMain)
+            desc = gui->skin->windows[i];
+
+    if(!desc)
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_FATAL, "[GUI] Invalid skin description\n");
+        return 1;
+    }
+
+    /* load the icon from the executable */
+    GetModuleFileName(NULL, dir, MAX_PATH);
+    gui->icon = ExtractIcon(instance, dir, 0);
+    int x = -1, y = -1;
+
+    /* create the window class */
+    wc.style = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc = EventProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = instance;
+    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+    wc.hIcon = gui->icon;
+    wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
+    wc.lpszClassName = gui->classname = "MPlayer GUI for Windows";
+    wc.lpszMenuName = NULL;
+    RegisterClass(&wc);
+
+    /* create a context menu */
+    create_menu(gui);
+    /* create the systray menu */
+    create_traymenu(gui);
+
+    /* create the mainwindow */
+    /* TODO implement aligning as described in skin.html */
+    rect.top = rect.left = 100;
+    rect.bottom = rect.top+desc->base->bitmap[0]->height;
+    rect.right = rect.left+desc->base->bitmap[0]->width;
+    if(desc->decoration) style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+    else style = WS_POPUP | WS_SYSMENU;
+
+    AdjustWindowRect(&rect, style, 0);
+
+    /* Check if out of screen */
+    if (gui_main_pos_x >= 0)
+        x = gui_main_pos_x;
+    if (gui_main_pos_y >= 0)
+        y = gui_main_pos_y;
+
+    if (x <= -1 || (x+(rect.right-rect.left) > GetSystemMetrics(SM_CXFULLSCREEN)))
+    {
+        x = (GetSystemMetrics(SM_CXSCREEN) / 2) - ((rect.right-rect.left) / 2);
+        gui_main_pos_x = x;
+    }
+    if (y <= -1 || (y+(rect.bottom-rect.top) > GetSystemMetrics(SM_CYFULLSCREEN)))
+    {
+        y = ((GetSystemMetrics(SM_CYSCREEN)-40) - (rect.bottom-rect.top));
+        gui_main_pos_y = y;
+    }
+
+    hwnd = CreateWindowEx(0, gui->classname, "MPlayer for Windows", style,
+                          x, y, rect.right-rect.left, rect.bottom-rect.top,
+                          gui->mainwindow, NULL, instance, NULL);
+
+    /* set the systray icon properties */
+    nid.cbSize = sizeof(NOTIFYICONDATA);
+    nid.hWnd = hwnd;
+    nid.uID = 1;
+    nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+    nid.uCallbackMessage = WM_SYSTRAY;
+    nid.hIcon = gui->icon;
+    strcpy(nid.szTip, "MPlayer for Windows");
+
+    /* register the systray icon */
+    Shell_NotifyIcon(NIM_ADD, &nid);
+
+    /* load all the window images */
+    window_render(gui, hwnd, hdc, priv, desc, binfo);
+
+    /* enable drag and drop support */
+    DragAcceptFiles(hwnd, TRUE);
+
+    updatedisplay(gui, hwnd);
+    gui->mainwindow = hwnd;
+
+    /* display */
+    ShowWindow(gui->mainwindow, SW_SHOW);
+    UpdateWindow(gui->mainwindow);
+    maketransparent(gui->mainwindow, RGB(255, 0, 255));
+    return 0;
+}
+
+gui_t *create_gui(char *skindir, char *skinName, void (*playercontrol)(int event))
+{
+    gui_t *gui = calloc(1, sizeof(gui_t));
+
+    HWND runningmplayer = FindWindow("MPlayer GUI for Windows", "MPlayer for Windows");
+    if(runningmplayer)
+    {
+        free(gui);
+        return NULL;
+    }
+
+    gui->startplay = startplay;
+    gui->playercontrol = playercontrol;
+    gui->uninit = uninit;
+    gui->updatedisplay = updatedisplay;
+
+    /* create playlist */
+    gui->playlist = create_playlist();
+
+    if(!skinName) skinName = strdup("Blue");
+    char temp[MAX_PATH];
+    sprintf(temp, "%s\\%s", skindir, skinName);
+    if(create_window(gui, temp)) return NULL;
+    if(create_subwindow(gui, temp)) return NULL;
+    if(console) console_toggle();
+    return gui;
+}

Added: trunk/Gui/win32/gui.h
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/gui.h	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,118 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _GUI_H
+#define _GUI_H
+#include <config.h>
+#include <playtree.h>
+#include <m_config.h>
+#include "skinload.h"
+#include "playlist.h"
+
+extern char *skinName;
+extern float sub_aspect;
+extern play_tree_t* playtree;
+extern m_config_t* mconfig;
+
+extern NOTIFYICONDATA nid;
+
+typedef struct window_priv_t window_priv_t;
+struct window_priv_t
+{
+    HWND hwnd;
+    image img;
+    image *background;
+    HBITMAP bitmap;
+    int type;
+};
+
+typedef struct gui_t gui_t;
+struct gui_t
+{
+    /* screenproperties */
+    int screenw, screenh, screenbpp;
+    /* window related stuff */
+    char *classname;
+    HICON icon;
+    unsigned int window_priv_count;
+    window_priv_t **window_priv;
+
+    HWND mainwindow;
+    HWND subwindow;
+
+    /* for event handling */
+    widget *activewidget;
+
+    int mousewx, mousewy; /* mousepos inside widget */
+    int mousex, mousey;
+
+    HMENU menu;
+    HMENU diskmenu;
+    HMENU traymenu;
+    HMENU trayplaymenu;
+    HMENU trayplaybackmenu;
+    HMENU submenu;
+    HMENU subtitlemenu;
+    HMENU aspectmenu;
+    HMENU dvdmenu;
+    HMENU playlistmenu;
+
+    int skinbrowserwindow;
+    int playlistwindow;
+    int aboutwindow;
+
+    skin_t *skin;
+    playlist_t *playlist;
+
+    void (*startplay)(gui_t *gui);
+    void (*updatedisplay)(gui_t *gui, HWND hwnd);
+    void (*playercontrol)(int event);   /* userdefine call back function */
+    void (*uninit)(gui_t *gui);
+};
+
+#define     wsShowWindow    8
+#define     wsHideWindow    16
+#define     wsShowFrame     1
+#define     wsMovable       2
+#define     wsSizeable      4
+
+extern gui_t *create_gui(char *skindir, char *skinName, void (*playercontrol)(int event));
+extern int destroy_window(gui_t *gui);
+extern int create_window(gui_t *gui, char *skindir);
+extern int create_subwindow(gui_t *gui, char *skindir);
+extern int parse_filename(char *file, play_tree_t *playtree, m_config_t *mconfig, int clear);
+extern void capitalize(char *filename);
+extern int import_playtree_playlist_into_gui(play_tree_t *my_playtree, m_config_t *config);
+
+/* Dialogs */
+extern void display_playlistwindow(gui_t *gui);
+extern void update_playlistwindow(void);
+extern int display_openfilewindow(gui_t *gui, int add);
+extern void display_openurlwindow(gui_t *gui, int add);
+extern void display_skinbrowser(gui_t *gui);
+extern void display_chapterselwindow(gui_t *gui);
+extern void display_eqwindow(gui_t *gui);
+extern void display_prefswindow(gui_t *gui);
+#ifdef USE_SUB
+extern void display_opensubtitlewindow(gui_t *gui);
+#endif
+
+#endif

Added: trunk/Gui/win32/interface.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/interface.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,975 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <interface.h>
+#include <m_option.h>
+#include <mixer.h>
+#include <mp_msg.h>
+#include <help_mp.h>
+#include <codec-cfg.h>
+#include <libmpdemux/stream.h>
+#include <libmpdemux/demuxer.h>
+#include <libmpdemux/stheader.h>
+#ifdef USE_DVDREAD
+#include <libmpdemux/stream_dvd.h>
+#endif
+#include <input/input.h>
+#include <libvo/video_out.h>
+#include <libao2/audio_out.h>
+#include "gui.h"
+#include "dialogs.h"
+#include "wincfg.h"
+#ifdef HAVE_LIBCDIO
+#include <cdio/cdio.h>
+#endif
+
+extern m_obj_settings_t* vo_plugin_args;
+extern vo_functions_t *video_out;
+extern ao_functions_t *audio_out;
+extern void exit_player(char *how);
+extern char *filename;
+extern int abs_seek_pos;
+extern float rel_seek_secs;
+extern mixer_t mixer;
+extern int audio_id;
+extern int video_id;
+extern int dvdsub_id;
+extern int vobsub_id;
+extern int stream_cache_size;
+extern int autosync;
+extern int vcd_track;
+extern int dvd_title;
+extern float force_fps;
+extern af_cfg_t af_cfg;
+int guiWinID = 0;
+
+char *skinName = NULL;
+char *codecname = NULL;
+int mplGotoTheNext = 1;
+static gui_t *mygui = NULL;
+static int update_subwindow(void);
+
+/* test for playlist files, no need to specify -playlist on the commandline.
+ * add any conceivable playlist extensions here.
+ * - Erik
+ */
+int parse_filename(char *file, play_tree_t *playtree, m_config_t *mconfig, int clear)
+{
+    if(clear)
+        mygui->playlist->clear_playlist(mygui->playlist);
+
+    if(strstr(file, ".m3u") || strstr(file, ".pls"))
+    {
+        playtree = parse_playlist_file(file);
+        import_playtree_playlist_into_gui(playtree, mconfig);
+        return 1;
+    }
+    return 0;
+}
+
+/**
+ * \brief this actually creates a new list containing only one element...
+ */
+void gaddlist( char ***list, char *entry)
+{
+    int i;
+
+    if (*list)
+    {
+        for (i=0; (*list)[i]; i++) free((*list)[i]);
+        free(*list);
+    }
+
+    *list = malloc(2 * sizeof(char **));
+    (*list)[0] = gstrdup(entry);
+    (*list)[1] = NULL;
+}
+
+char *gstrdup(char *str)
+{
+    if (!str) return NULL;
+    return strdup(str);
+}
+
+/**
+ * \brief this replaces a string starting with search by replace.
+ * If not found, replace is appended.
+ */
+void greplace(char ***list, char *search, char *replace)
+{
+    int i = 0;
+    int len = (search) ? strlen(search) : 0;
+
+    if (*list)
+    {
+        for (i = 0; (*list)[i]; i++)
+        {
+            if (search && (!strncmp((*list)[i], search, len)))
+            {
+                free((*list)[i]);
+                (*list)[i] = gstrdup(replace);
+                return;
+            }
+        }
+    *list = realloc(*list, (i + 2) * sizeof(char *));
+    }
+    else
+        *list = malloc(2 * sizeof(char *));
+
+    (*list)[i] = gstrdup(replace);
+    (*list)[i + 1] = NULL;
+}
+
+/* this function gets called by the gui to update mplayer */
+static void guiSetEvent(int event)
+{
+    switch(event)
+    {
+        case evPlay:
+        case evPlaySwitchToPause:
+            mplPlay();
+            break;
+        case evPause:
+            mplPause();
+            break;
+#ifdef USE_DVDREAD
+        case evPlayDVD:
+        {
+            static char dvdname[MAX_PATH];
+            guiIntfStruct.DVD.current_title = dvd_title;
+            guiIntfStruct.DVD.current_chapter = dvd_chapter;
+            guiIntfStruct.DVD.current_angle = dvd_angle;
+            guiIntfStruct.DiskChanged = 1;
+
+            mplSetFileName(NULL, dvd_device, STREAMTYPE_DVD);
+            guiIntfStruct.Title = guiIntfStruct.DVD.current_title;
+            guiIntfStruct.Chapter = guiIntfStruct.DVD.current_chapter;
+            guiIntfStruct.Angle = guiIntfStruct.DVD.current_angle;
+
+            dvdname[0] = 0;
+            strcat(dvdname, "DVD Movie");
+            GetVolumeInformation(dvd_device, dvdname, MAX_PATH, NULL, NULL, NULL, NULL, 0);
+            capitalize(dvdname);
+            mp_msg(MSGT_GPLAYER, MSGL_V, "Opening DVD %s -> %s\n", dvd_device, dvdname);
+            guiGetEvent(guiSetParameters, (char *) STREAMTYPE_DVD);
+            mygui->playlist->clear_playlist(mygui->playlist);
+            mygui->playlist->add_track(mygui->playlist, filename, NULL, dvdname, 0);
+            mygui->startplay(mygui);
+            break;
+        }
+#endif
+#ifdef HAVE_LIBCDIO
+        case evPlayCD:
+        {
+            int i;
+            char track[10];
+            char trackname[10];
+            CdIo_t *p_cdio = cdio_open(NULL, DRIVER_UNKNOWN);
+            track_t i_tracks;
+
+            if(p_cdio == NULL) printf("Couldn't find a driver.\n");
+            i_tracks = cdio_get_num_tracks(p_cdio);
+
+            mygui->playlist->clear_playlist(mygui->playlist);
+            for(i=0;i<i_tracks;i++)
+            {
+                sprintf(track, "cdda://%d", i+1);
+                sprintf(trackname, "Track %d", i+1);
+                mygui->playlist->add_track(mygui->playlist, track, NULL, trackname, 0);
+            }
+            cdio_destroy(p_cdio);
+            mygui->startplay(mygui);
+            break;
+        }
+#endif
+        case evFullScreen:
+            mp_input_queue_cmd(mp_input_parse_cmd("vo_fullscreen"));
+            break;
+        case evExit:
+        {
+            /* We are asking mplayer to exit, later it will ask us after uninit is made
+               this should be the only safe way to quit */
+            mygui->activewidget = NULL;
+            mp_input_queue_cmd(mp_input_parse_cmd("quit"));
+            break;
+        }
+        case evStop:
+            if(guiIntfStruct.Playing)
+                guiGetEvent(guiCEvent, (void *) guiSetStop);
+            break;
+        case evSetMoviePosition:
+        {
+            rel_seek_secs = guiIntfStruct.Position / 100.0f;
+            abs_seek_pos = 3;
+            break;
+        }
+        case evForward10sec:
+        {
+            rel_seek_secs = 10.0f;
+            abs_seek_pos = 0;
+            break;
+        }
+        case evBackward10sec:
+        {
+            rel_seek_secs = -10.0f;
+            abs_seek_pos = 0;
+            break;
+        }
+        case evSetBalance:
+        case evSetVolume:
+        {
+            float l,r;
+
+            if (guiIntfStruct.Balance == 50.0f)
+                mixer_setvolume(&mixer, guiIntfStruct.Volume, guiIntfStruct.Volume);
+
+            l = guiIntfStruct.Volume * ((100.0f - guiIntfStruct.Balance) / 50.0f);
+            r = guiIntfStruct.Volume * ((guiIntfStruct.Balance) / 50.0f);
+
+            if (l > guiIntfStruct.Volume) l=guiIntfStruct.Volume;
+            if (r > guiIntfStruct.Volume) r=guiIntfStruct.Volume;
+            mixer_setvolume(&mixer, l, r);
+            /* Check for balance support on mixer - there is a better way ?? */
+            if (r != l)
+            {
+                mixer_getvolume(&mixer, &l, &r);
+                if (r == l)
+                {
+                    mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Mixer doesn't support balanced audio\n");
+                    mixer_setvolume(&mixer, guiIntfStruct.Volume, guiIntfStruct.Volume);
+                    guiIntfStruct.Balance = 50.0f;
+                }
+            }
+            break;
+        }
+        case evMute:
+        {
+            mp_cmd_t * cmd = (mp_cmd_t *)calloc(1, sizeof(*cmd));
+            cmd->id=MP_CMD_MUTE;
+            cmd->name=strdup("mute");
+            mp_input_queue_cmd(cmd);
+            break;
+        }
+        case evDropFile:
+        case evLoadPlay:
+        {
+            mplSetFileName(NULL, filename, STREAMTYPE_FILE);
+            guiIntfStruct.FilenameChanged = guiIntfStruct.NewPlay = 1;
+            update_playlistwindow();
+            guiGetEvent(guiCEvent, (void *) guiSetStop);
+            guiGetEvent(guiCEvent, (void *) guiSetPlay);
+            break;
+        }
+        case evNext:
+            mplNext();
+            break;
+        case evPrev:
+            mplPrev();
+            break;
+    }
+}
+
+void mplPlay( void )
+{
+   if((!guiIntfStruct.Filename ) || (guiIntfStruct.Filename[0] == 0))
+     return;
+
+   if(guiIntfStruct.Playing > 0)
+   {
+       mplPause();
+       return;
+   }
+   guiIntfStruct.NewPlay = 1;
+   guiGetEvent(guiCEvent, (void *) guiSetPlay);
+}
+
+void mplPause( void )
+{
+   if(!guiIntfStruct.Playing) return;
+
+   if(guiIntfStruct.Playing == 1)
+   {
+       mp_cmd_t * cmd = (mp_cmd_t *)calloc(1, sizeof(*cmd));
+       cmd->id=MP_CMD_PAUSE;
+       cmd->name=strdup("pause");
+       mp_input_queue_cmd(cmd);
+   } else guiIntfStruct.Playing = 1;
+}
+
+void mplNext(void)
+{
+    if(guiIntfStruct.Playing == 2) return;
+    switch(guiIntfStruct.StreamType)
+    {
+#ifdef USE_DVDREAD
+        case STREAMTYPE_DVD:
+            if(guiIntfStruct.DVD.current_chapter == (guiIntfStruct.DVD.chapters - 1))
+                return;
+            guiIntfStruct.DVD.current_chapter++;
+            break;
+#endif
+        default:
+            if(mygui->playlist->current == (mygui->playlist->trackcount - 1))
+                return;
+            mplSetFileName(NULL, mygui->playlist->tracks[(mygui->playlist->current)++]->filename,
+                           STREAMTYPE_STREAM);
+            break;
+    }
+    mplGotoTheNext = 0;
+    mygui->startplay(mygui);
+}
+
+void mplPrev(void)
+{
+    if(guiIntfStruct.Playing == 2) return;
+    switch(guiIntfStruct.StreamType)
+    {
+#ifdef USE_DVDREAD
+        case STREAMTYPE_DVD:
+            if(guiIntfStruct.DVD.current_chapter == 1)
+                return;
+            guiIntfStruct.DVD.current_chapter--;
+            break;
+#endif
+        default:
+            if(mygui->playlist->current == 0)
+                return;
+            mplSetFileName(NULL, mygui->playlist->tracks[(mygui->playlist->current)--]->filename,
+                           STREAMTYPE_STREAM);
+            break;
+    }
+    mplGotoTheNext = 0;
+    mygui->startplay(mygui);
+}
+
+void mplEnd( void )
+{
+    if(!mplGotoTheNext && guiIntfStruct.Playing)
+    {
+        mplGotoTheNext = 1;
+        return;
+    }
+
+    if(mplGotoTheNext && guiIntfStruct.Playing &&
+      (mygui->playlist->current < (mygui->playlist->trackcount - 1)) &&
+      guiIntfStruct.StreamType != STREAMTYPE_DVD &&
+      guiIntfStruct.StreamType != STREAMTYPE_DVDNAV)
+    {
+        /* we've finished this file, reset the aspect */
+        if(movie_aspect >= 0)
+            movie_aspect = -1;
+
+        mplGotoTheNext = guiIntfStruct.FilenameChanged = guiIntfStruct.NewPlay = 1;
+        mplSetFileName(NULL, mygui->playlist->tracks[(mygui->playlist->current)++]->filename, STREAMTYPE_STREAM);
+        //sprintf(guiIntfStruct.Filename, mygui->playlist->tracks[(mygui->playlist->current)++]->filename);
+    }
+
+    if(guiIntfStruct.FilenameChanged && guiIntfStruct.NewPlay)
+        return;
+
+    guiIntfStruct.TimeSec = 0;
+    guiIntfStruct.Position = 0;
+    guiIntfStruct.AudioType = 0;
+
+#ifdef USE_DVDREAD
+    guiIntfStruct.DVD.current_title = 1;
+    guiIntfStruct.DVD.current_chapter = 1;
+    guiIntfStruct.DVD.current_angle = 1;
+#endif
+
+    if (mygui->playlist->current == (mygui->playlist->trackcount - 1))
+        mygui->playlist->current = 0;
+
+    guiGetEvent(guiCEvent, (void *) guiSetStop);
+}
+
+void mplSetFileName(char *dir, char *name, int type)
+{
+    if(!name) return;
+    if(!dir)
+        guiSetFilename(guiIntfStruct.Filename, name)
+    else
+        guiSetDF(guiIntfStruct.Filename, dir, name);
+
+    guiIntfStruct.StreamType = type;
+    free((void **) &guiIntfStruct.AudioFile);
+    free((void **) &guiIntfStruct.Subtitlename);
+}
+
+static DWORD WINAPI GuiThread(void)
+{
+    MSG msg;
+
+    if(!skinName) skinName = strdup("Blue");
+    if(!mygui) mygui = create_gui(get_path("skins"), skinName, guiSetEvent);
+    if(!mygui) exit_player("Unable to load gui");
+
+    if(autosync && autosync != gtkAutoSync)
+    {
+       gtkAutoSyncOn = 1;
+       gtkAutoSync = autosync;
+    }
+
+    while(mygui)
+    {
+        GetMessage(&msg, NULL, 0, 0);
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+    fprintf(stderr, "[GUI] Gui Thread Terminated\n");
+    fflush(stderr);
+    return 0;
+}
+
+void guiInit(void)
+{
+    memset(&guiIntfStruct, 0, sizeof(guiIntfStruct));
+    /* Create The gui thread */
+    if (!mygui)
+        mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Creating GUI Thread 0x%04x\n",
+              (int) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) GuiThread, NULL, 0, NULL));
+
+    /* Wait until the gui is created */
+    while(!mygui) Sleep(100);
+    mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Gui Thread started\n");
+}
+
+void guiDone(void)
+{
+    if(mygui)
+    {
+        fprintf(stderr, "[GUI] Closed by main mplayer window\n");
+        fflush(stderr);
+        mygui->uninit(mygui);
+        free(mygui);
+        TerminateThread(GuiThread, 0);
+        mygui = NULL;
+    }
+    /* Remove tray icon */
+    Shell_NotifyIcon(NIM_DELETE, &nid);
+    cfg_write();
+}
+
+static void add_vop(char * str)
+{
+    mp_msg(MSGT_GPLAYER, MSGL_STATUS, MSGTR_AddingVideoFilter, str);
+    if (vo_plugin_args)
+    {
+        int i = 0;
+        while (vo_plugin_args[i].name)
+            if (!strcmp(vo_plugin_args[i++].name, str))
+            {
+                i = -1;
+                break;
+            }
+        if (i != -1)
+        {
+            vo_plugin_args = realloc(vo_plugin_args, (i + 2) * sizeof(m_obj_settings_t));
+            vo_plugin_args[i].name = strdup(str);
+            vo_plugin_args[i].attribs = NULL;
+            vo_plugin_args[i + 1].name = NULL;
+        }
+    }
+    else
+    {
+        vo_plugin_args = malloc(2 * sizeof(m_obj_settings_t));
+        vo_plugin_args[0].name = strdup(str);
+        vo_plugin_args[0].attribs = NULL;
+        vo_plugin_args[1].name = NULL;
+    }
+}
+
+static void remove_vop(char * str)
+{
+    int n = 0;
+    if (!vo_plugin_args ) return;
+
+    mp_msg(MSGT_GPLAYER,MSGL_STATUS, MSGTR_RemovingVideoFilter, str);
+
+    while (vo_plugin_args[n++].name);
+    n--;
+    if ( n > -1 )
+    {
+        int i = 0, m = -1;
+        while (vo_plugin_args[i].name)
+            if (!strcmp(vo_plugin_args[i++].name, str))
+            {
+                m = i - 1;
+                break;
+            }
+        i--;
+        if (m > -1)
+        {
+            if (n == 1)
+            {
+                free(vo_plugin_args[0].name);
+                free(vo_plugin_args[0].attribs);
+                free(vo_plugin_args);
+                vo_plugin_args=NULL;
+            }
+            else
+            {
+                free(vo_plugin_args[i].name);
+                free(vo_plugin_args[i].attribs);
+                memcpy(&vo_plugin_args[i], &vo_plugin_args[i + 1], (n - i) * sizeof(m_obj_settings_t));
+            }
+        }
+    }
+}
+
+/* this function gets called by mplayer to update the gui */
+int guiGetEvent(int type, char *arg)
+{
+    if(!mygui || !mygui->skin) return 0;
+
+    stream_t *stream = (stream_t *) arg;
+#ifdef USE_DVDREAD
+    dvd_priv_t *dvdp = (dvd_priv_t *) arg;
+#endif
+
+    switch (type)
+    {
+        case guiSetFileFormat:
+            guiIntfStruct.FileFormat = (int) arg;
+            break;
+        case guiSetParameters:
+        {
+            guiGetEvent(guiSetDefaults, NULL);
+            guiIntfStruct.DiskChanged = 0;
+            guiIntfStruct.FilenameChanged = 0;
+            guiIntfStruct.NewPlay = 0;
+            switch(guiIntfStruct.StreamType)
+            {
+                case STREAMTYPE_PLAYLIST:
+                    break;
+#ifdef USE_DVDREAD
+                case STREAMTYPE_DVD:
+                {
+                    char tmp[512];
+                    dvd_title = guiIntfStruct.DVD.current_title;
+                    dvd_chapter = guiIntfStruct.DVD.current_chapter;
+                    dvd_angle = guiIntfStruct.DVD.current_angle;
+                    sprintf(tmp,"dvd://%d", guiIntfStruct.Title);
+                    guiSetFilename(guiIntfStruct.Filename, tmp);
+                    break;
+                }
+#endif
+            }
+            if(guiIntfStruct.Filename)
+                filename = strdup(guiIntfStruct.Filename);
+            else if(filename)
+                strcpy(guiIntfStruct.Filename, filename);
+            break;
+        }
+        case guiSetAudioOnly:
+        {
+            guiIntfStruct.AudioOnly = (int) arg;
+            if(IsWindowVisible(mygui->subwindow))
+                ShowWindow(mygui->subwindow, SW_HIDE);
+            break;
+        }
+        case guiSetDemuxer:
+            guiIntfStruct.demuxer = (void *) arg;
+            break;
+        case guiSetValues:
+        {
+            guiIntfStruct.sh_video = arg;
+            if (arg)
+            {
+                sh_video_t *sh = (sh_video_t *)arg;
+                codecname = sh->codec->name;
+                guiIntfStruct.FPS = sh->fps;
+
+                /* we have video, show the subwindow */
+                if(!IsWindowVisible(mygui->subwindow) || IsIconic(mygui->subwindow))
+                    ShowWindow(mygui->subwindow, SW_SHOWNORMAL);
+                if(WinID == -1)
+                    update_subwindow();
+
+            }
+            break;
+        }
+        case guiSetShVideo:
+        {
+            guiIntfStruct.MovieWidth = vo_dwidth;
+            guiIntfStruct.MovieHeight = vo_dheight;
+
+            sub_aspect = (float)guiIntfStruct.MovieWidth/guiIntfStruct.MovieHeight;
+            if(WinID != -1)
+               update_subwindow();
+            break;
+        }
+        case guiSetStream:
+        {
+            guiIntfStruct.StreamType = stream->type;
+            switch(stream->type)
+            {
+#ifdef USE_DVDREAD
+                case STREAMTYPE_DVD:
+                    guiGetEvent(guiSetDVD, (char *) stream->priv);
+                    break;
+#endif
+            }
+            break;
+        }
+#ifdef USE_DVDREAD
+        case guiSetDVD:
+        {
+            guiIntfStruct.DVD.titles = dvdp->vmg_file->tt_srpt->nr_of_srpts;
+            guiIntfStruct.DVD.chapters = dvdp->vmg_file->tt_srpt->title[dvd_title].nr_of_ptts;
+            guiIntfStruct.DVD.angles = dvdp->vmg_file->tt_srpt->title[dvd_title].nr_of_angles;
+            guiIntfStruct.DVD.nr_of_audio_channels = dvdp->nr_of_channels;
+            memcpy(guiIntfStruct.DVD.audio_streams, dvdp->audio_streams, sizeof(dvdp->audio_streams));
+            guiIntfStruct.DVD.nr_of_subtitles = dvdp->nr_of_subtitles;
+            memcpy(guiIntfStruct.DVD.subtitles, dvdp->subtitles, sizeof(dvdp->subtitles));
+            guiIntfStruct.DVD.current_title = dvd_title + 1;
+            guiIntfStruct.DVD.current_chapter = dvd_chapter + 1;
+            guiIntfStruct.DVD.current_angle = dvd_angle + 1;
+            guiIntfStruct.Track = dvd_title + 1;
+            break;
+        }
+#endif
+        case guiReDraw:
+            mygui->updatedisplay(mygui, mygui->mainwindow);
+            break;
+        case guiSetAfilter:
+            guiIntfStruct.afilter = (void *) arg;
+            break;
+        case guiCEvent:
+        {
+            guiIntfStruct.Playing = (int) arg;
+            switch (guiIntfStruct.Playing)
+            {
+                case guiSetPlay:
+                {
+                    guiIntfStruct.Playing = 1;
+                    break;
+                }
+                case guiSetStop:
+                {
+                    guiIntfStruct.Playing = 0;
+                    if(movie_aspect >= 0)
+                        movie_aspect = -1;
+                    update_subwindow();
+                    break;
+                }
+                case guiSetPause:
+                    guiIntfStruct.Playing = 2;
+                    break;
+            }
+            break;
+        }
+        case guiIEvent:
+        {
+            mp_msg(MSGT_GPLAYER,MSGL_V, "cmd: %d\n", (int) arg);
+            /* MPlayer asks us to quit */
+            switch((int) arg)
+            {
+                case MP_CMD_GUI_FULLSCREEN:
+                {
+                    if(!guiIntfStruct.sh_video) break;
+                    video_out->control(VOCTRL_FULLSCREEN, 0);
+
+                    /* no WinID, keep the sub window hidden */
+                    if((video_driver_list && !strstr(video_driver_list[0], "directx")) || !sub_window)
+                        break;
+
+                    if(vo_fs)
+                    {
+                        WinID = -1;
+                        ShowWindow(mygui->subwindow, SW_HIDE);
+                        while(ShowCursor(FALSE) >= 0){}
+                    } else {
+                        WinID = mygui->subwindow;
+                        ShowWindow(mygui->subwindow, SW_SHOW);
+                        while(ShowCursor(TRUE) <= 0){}
+                    }
+                    break;
+                }
+                case MP_CMD_QUIT:
+                {
+                    mygui->uninit(mygui);
+                    free(mygui);
+                    mygui = NULL;
+                    exit_player("Done");
+                    return 0;
+                }
+                case MP_CMD_GUI_STOP:
+                    guiGetEvent(guiCEvent, (void *) guiSetStop);
+                    break;
+                case MP_CMD_GUI_PLAY:
+                    guiGetEvent(guiCEvent, (void *) guiSetPlay);
+                    break;
+                case MP_CMD_GUI_SKINBROWSER:
+                    if(vo_fs) guiSetEvent(evFullScreen);
+                    PostMessage(mygui->mainwindow, WM_COMMAND, (WPARAM) ID_SKINBROWSER, 0);
+                    break;
+                case MP_CMD_GUI_PLAYLIST:
+                    if(vo_fs) guiSetEvent(evFullScreen);
+                    PostMessage(mygui->mainwindow, WM_COMMAND, (WPARAM) ID_PLAYLIST, 0);
+                    break;
+                case MP_CMD_GUI_PREFERENCES:
+                    if(vo_fs) guiSetEvent(evFullScreen);
+                    PostMessage(mygui->mainwindow, WM_COMMAND, (WPARAM) ID_PREFS, 0);
+                    break;
+                case MP_CMD_GUI_LOADFILE:
+                    if(vo_fs) guiSetEvent(evFullScreen);
+                    PostMessage(mygui->mainwindow, WM_COMMAND, (WPARAM) IDFILE_OPEN, 0);
+                    break;
+#ifdef USE_SUB
+                case MP_CMD_GUI_LOADSUBTITLE:
+                    if(vo_fs) guiSetEvent(evFullScreen);
+                    PostMessage(mygui->mainwindow, WM_COMMAND, (WPARAM) IDSUBTITLE_OPEN, 0);
+                    break;
+#endif
+                default:
+                    break;
+            }
+            break;
+        }
+        case guiSetFileName:
+            if (arg) guiIntfStruct.Filename = (char *) arg;
+            break;
+        case guiSetDefaults:
+        {
+            audio_id = -1;
+            video_id = -1;
+            dvdsub_id = -1;
+            vobsub_id = -1;
+            stream_cache_size = -1;
+            autosync = 0;
+            vcd_track = 0;
+            dvd_title = 0;
+            force_fps = 0;
+            if(!mygui->playlist->tracks) return 0;
+            filename = guiIntfStruct.Filename = mygui->playlist->tracks[mygui->playlist->current]->filename;
+            guiIntfStruct.Track = mygui->playlist->current + 1;
+            if(gtkAONorm) greplace(&af_cfg.list, "volnorm", "volnorm");
+            if(gtkAOExtraStereo)
+            {
+                char *name = malloc(12 + 20 + 1);
+                snprintf(name, 12 + 20, "extrastereo=%f", gtkAOExtraStereoMul);
+                name[12 + 20] = 0;
+                greplace(&af_cfg.list, "extrastereo", name);
+                free(name);
+            }
+            if(gtkCacheOn) stream_cache_size = gtkCacheSize;
+            if(gtkAutoSyncOn) autosync = gtkAutoSync;
+            break;
+        }
+        case guiSetVolume:
+        {
+            if(audio_out)
+            {
+                /* Some audio_out drivers do not support balance e.g. dsound */
+                /* FIXME this algo is not correct */
+                float l, r;
+                mixer_getvolume(&mixer, &l, &r);
+                guiIntfStruct.Volume = (r > l ? r : l); /* max(r,l) */
+                if (r != l)
+                    guiIntfStruct.Balance = ((r-l) + 100.0f) * 0.5f;
+                else
+                    guiIntfStruct.Balance = 50.0f;
+            }
+            break;
+        }
+        default:
+            mp_msg(MSGT_GPLAYER, MSGL_ERR, "[GUI] GOT UNHANDLED EVENT %i\n", type);
+    }
+    return 0;
+}
+
+/* This function adds/inserts one file into the gui playlist */
+int import_file_into_gui(char *pathname, int insert)
+{
+    char filename[MAX_PATH];
+    char *filepart = filename;
+
+    if (strstr(pathname, "://"))
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Adding special %s\n", pathname);
+        mygui->playlist->add_track(mygui->playlist, pathname, NULL, NULL, 0);
+        return 1;
+    }
+    if (GetFullPathName(pathname, MAX_PATH, filename, &filepart))
+    {
+        if (!(GetFileAttributes(filename) & FILE_ATTRIBUTE_DIRECTORY))
+        {
+            mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Adding filename: %s - fullpath: %s\n", filepart, filename);
+            mygui->playlist->add_track(mygui->playlist, filename, NULL, filepart, 0);
+            return 1;
+        }
+        else
+            mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Cannot add %s\n", filename);
+    }
+
+    return 0;
+}
+
+/*  This function imports the initial playtree (based on cmd-line files) into the gui playlist
+    by either:
+    - overwriting gui pl (enqueue=0) */
+
+int import_initial_playtree_into_gui(play_tree_t *my_playtree, m_config_t *config, int enqueue)
+{
+    play_tree_iter_t *my_pt_iter = NULL;
+    int result = 0;
+
+    if(!mygui) guiInit();
+
+    if((my_pt_iter = pt_iter_create(&my_playtree, config)))
+    {
+        while ((filename = pt_iter_get_next_file(my_pt_iter)) != NULL)
+        {
+            if (parse_filename(filename, my_playtree, config, 0))
+                result = 1;
+            else if (import_file_into_gui(filename, 0)) /* Add it to end of list */
+                result = 1;
+        }
+    }
+    mplGotoTheNext = 1;
+
+    if (result)
+    {
+        mygui->playlist->current = 0;
+        filename = mygui->playlist->tracks[0]->filename;
+    }
+    return result;
+}
+
+/* This function imports and inserts an playtree, that is created "on the fly", for example by
+   parsing some MOV-Reference-File; or by loading an playlist with "File Open"
+   The file which contained the playlist is thereby replaced with it's contents. */
+
+int import_playtree_playlist_into_gui(play_tree_t *my_playtree, m_config_t *config)
+{
+    play_tree_iter_t *my_pt_iter = NULL;
+    int result = 0;
+
+    if((my_pt_iter = pt_iter_create(&my_playtree, config)))
+    {
+        while ((filename = pt_iter_get_next_file(my_pt_iter)) != NULL)
+            if (import_file_into_gui(filename, 1)) /* insert it into the list and set plCurrent = new item */
+                result = 1;
+        pt_iter_destroy(&my_pt_iter);
+    }
+    filename = NULL;
+    return result;
+}
+
+inline void gtkMessageBox(int type, const char *str)
+{
+    if (type & GTK_MB_FATAL)
+        MessageBox(NULL, str, "MPlayer GUI for Windows Error", MB_OK | MB_ICONERROR);
+
+    fprintf(stderr, "[GUI] MessageBox: %s\n", str);
+    fflush(stderr);
+}
+
+void guiMessageBox(int level, char *str)
+{
+    switch(level)
+    {
+        case MSGL_FATAL:
+            gtkMessageBox(GTK_MB_FATAL | GTK_MB_SIMPLE, str);
+            break;
+        case MSGL_ERR:
+            gtkMessageBox(GTK_MB_ERROR | GTK_MB_SIMPLE, str);
+            break;
+    }
+}
+
+static int update_subwindow(void)
+{
+    int x,y;
+    RECT rd;
+    WINDOWPOS wp;
+
+     /* it's not the best way to check if selected driver is directx,
+        if no driver is specified video_driver_list is null.
+        Right now I don't have a functional way to do this
+        - Sherpya */
+    if((video_driver_list && !strstr(video_driver_list[0], "directx")) || !sub_window)
+    {
+        WinID = -1; // so far only directx supports WinID in windows
+
+        if(IsWindowVisible(mygui->subwindow) && guiIntfStruct.sh_video && guiIntfStruct.Playing)
+        {
+            ShowWindow(mygui->subwindow, SW_HIDE);
+            return 0;
+        }
+        else if(guiIntfStruct.AudioOnly)
+            return 0;
+        else ShowWindow(mygui->subwindow, SW_SHOW);
+    }
+
+    /* we've come out of fullscreen at the end of file */
+    if((!IsWindowVisible(mygui->subwindow) || IsIconic(mygui->subwindow)) && !guiIntfStruct.AudioOnly)
+        ShowWindow(mygui->subwindow, SW_SHOWNORMAL);
+
+    /* get our current window coordinates */
+    GetWindowRect(mygui->subwindow, &rd);
+    x = rd.left;
+    y = rd.top;
+
+    if(!guiIntfStruct.Playing)
+    {
+        window *desc = NULL;
+        int i;
+
+        for (i=0; i<mygui->skin->windowcount; i++)
+            if(mygui->skin->windows[i]->type == wiSub)
+                desc = mygui->skin->windows[i];
+
+        rd.right = rd.left+desc->base->bitmap[0]->width;
+        rd.bottom = rd.top+desc->base->bitmap[0]->height;
+        sub_aspect = (float)(rd.right-rd.left)/(rd.bottom-rd.top);
+    }
+    else
+    {
+        rd.right = rd.left+guiIntfStruct.MovieWidth;
+        rd.bottom = rd.top+guiIntfStruct.MovieHeight;
+
+        if (movie_aspect > 0.0)       // forced aspect from the cmdline
+            sub_aspect = movie_aspect;
+    }
+
+    AdjustWindowRect(&rd, WS_OVERLAPPEDWINDOW | WS_SIZEBOX, 0);
+    SetWindowPos(mygui->subwindow, HWND_NOTOPMOST, x, y, rd.right-rd.left, rd.bottom-rd.top, SWP_NOOWNERZORDER);
+
+    wp.hwnd = mygui->subwindow;
+    wp.x = rd.left;
+    wp.y = rd.top;
+    wp.cx = rd.right-rd.left;
+    wp.cy = rd.bottom-rd.top;
+    wp.flags = SWP_NOOWNERZORDER | SWP_SHOWWINDOW;
+
+    /* erase the bitmap image if there's video */
+    if(guiIntfStruct.Playing != 0 && guiIntfStruct.sh_video)
+        SendMessage(mygui->subwindow, WM_ERASEBKGND, (WPARAM)GetDC(mygui->subwindow), 0);
+
+    /* reset the window aspect */
+    SendMessage(mygui->subwindow, WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
+    return 0;
+}
+
+void guiEventHandling(void) {}

Added: trunk/Gui/win32/playlist.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/playlist.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,154 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <mp_msg.h>
+#include "playlist.h"
+
+/* TODO: implement sort_playlist */
+
+BOOL adddirtoplaylist(playlist_t *playlist, const char *path, BOOL recursive)
+{
+    HANDLE findHandle = INVALID_HANDLE_VALUE;
+    WIN32_FIND_DATA finddata;
+    char findpath[MAX_PATH], filename[MAX_PATH];
+    char *filepart;
+
+    sprintf(findpath, "%s\\*.*", path);
+
+    findHandle = FindFirstFile(findpath, &finddata);
+
+    if (findHandle == INVALID_HANDLE_VALUE) return FALSE;
+    do
+    {
+        if (finddata.cFileName[0] == '.' || strstr(finddata.cFileName, "Thumbs.db")) continue;
+        sprintf(findpath, "%s\\%s", path, finddata.cFileName);
+
+        if (GetFileAttributes(findpath) & FILE_ATTRIBUTE_DIRECTORY)
+        {
+            if(recursive)
+                adddirtoplaylist(playlist, findpath, recursive);
+        }
+        else
+        {
+            if (GetFullPathName(findpath, MAX_PATH, filename, &filepart))
+                playlist->add_track(playlist, filename, NULL, filepart, 0);
+        }
+    } while (FindNextFile(findHandle, &finddata));
+    FindClose(findHandle);
+    return TRUE;
+}
+
+static void add_track(playlist_t *playlist, const char *filename, const char *artist, const char *title, int duration)
+{
+    (playlist->trackcount)++;
+    playlist->tracks = realloc(playlist->tracks, playlist->trackcount * sizeof(pl_track_t *));
+    playlist->tracks[playlist->trackcount - 1] = calloc(1, sizeof(pl_track_t));
+    if(filename) playlist->tracks[playlist->trackcount - 1]->filename = strdup(filename);
+    if(artist) playlist->tracks[playlist->trackcount - 1]->artist = strdup(artist);
+    if(title) playlist->tracks[playlist->trackcount - 1]->title = strdup(title);
+    if(duration) playlist->tracks[playlist->trackcount - 1]->duration = duration;
+}
+
+static void remove_track(playlist_t *playlist, int number)
+{
+    pl_track_t **tmp = calloc(1, playlist->trackcount * sizeof(pl_track_t *));
+    int i, p = 0;
+    memcpy(tmp, playlist->tracks, playlist->trackcount * sizeof(pl_track_t *));
+    (playlist->trackcount)--;
+    playlist->tracks = realloc(playlist->tracks, playlist->trackcount * sizeof(pl_track_t *));
+    for(i=0; i<playlist->trackcount + 1; i++)
+    {
+        if(i != (number - 1))
+        {
+            playlist->tracks[p] = tmp[i];
+            p++;
+        }
+        else
+        {
+            if(tmp[i]->filename) free(tmp[i]->filename);
+            if(tmp[i]->artist) free(tmp[i]->artist);
+            if(tmp[i]->title) free(tmp[i]->title);
+            free(tmp[i]);
+        }
+    }
+    free(tmp);
+}
+
+static void moveup_track(playlist_t *playlist, int number)
+{
+    pl_track_t *tmp;
+    if(number == 1) return; /* already first */
+    tmp = playlist->tracks[number - 2];
+    playlist->tracks[number - 2] = playlist->tracks[number - 1];
+    playlist->tracks[number - 1] = tmp;
+}
+
+static void movedown_track(playlist_t *playlist, int number)
+{
+    pl_track_t *tmp;
+    if(number == playlist->trackcount) return; /* already latest */
+    tmp = playlist->tracks[number];
+    playlist->tracks[number] = playlist->tracks[number - 1];
+    playlist->tracks[number - 1] = tmp;
+}
+
+static void sort_playlist(playlist_t *playlist, int opt) {}
+
+static void clear_playlist(playlist_t *playlist)
+{
+    while(playlist->trackcount) playlist->remove_track(playlist, 1);
+    playlist->tracks = NULL;
+    playlist->current = 0;
+}
+
+static void free_playlist(playlist_t *playlist)
+{
+    if(playlist->tracks) playlist->clear_playlist(playlist);
+    free(playlist);
+}
+
+static void dump_playlist(playlist_t *playlist)
+{
+    int i;
+    for (i=0; i<playlist->trackcount; i++)
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_V, "track %i %s ", i + 1, playlist->tracks[i]->filename);
+        if(playlist->tracks[i]->artist) mp_msg(MSGT_GPLAYER, MSGL_V, "%s ", playlist->tracks[i]->artist);
+        if(playlist->tracks[i]->title) mp_msg(MSGT_GPLAYER, MSGL_V, "- %s ", playlist->tracks[i]->title);
+        if(playlist->tracks[i]->duration) mp_msg(MSGT_GPLAYER, MSGL_V, "%i ", playlist->tracks[i]->duration);
+        mp_msg(MSGT_GPLAYER, MSGL_V, "\n");
+    }
+}
+
+playlist_t *create_playlist(void)
+{
+    playlist_t *playlist = calloc(1, sizeof(playlist_t));
+    playlist->add_track = add_track;
+    playlist->remove_track = remove_track;
+    playlist->moveup_track = moveup_track;
+    playlist->movedown_track = movedown_track;
+    playlist->dump_playlist = dump_playlist;
+    playlist->sort_playlist = sort_playlist;
+    playlist->clear_playlist = clear_playlist;
+    playlist->free_playlist = free_playlist;
+    return playlist;
+}

Added: trunk/Gui/win32/playlist.h
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/playlist.h	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,57 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PLAYLIST_H
+#define _PLAYLIST_H
+
+typedef struct
+{
+    char *filename;
+    char *artist;
+    char *title;
+    int duration;
+} pl_track_t;
+
+typedef struct playlist_t playlist_t;
+struct playlist_t
+{
+    int current;                  /* currently used track */
+    int trackcount;               /* number of tracknumber */
+    pl_track_t **tracks;             /* tracklist */
+    void (*add_track)(playlist_t* playlist, const char *filename, const char *artist, const char *title, int duration);
+    void (*remove_track)(playlist_t* playlist, int number);
+    void (*moveup_track)(playlist_t* playlist, int number);
+    void (*movedown_track)(playlist_t* playlist, int number);
+    void (*dump_playlist)(playlist_t* playlist);
+    void (*sort_playlist)(playlist_t* playlist, int opt);
+    void (*clear_playlist)(playlist_t* playlist);
+    void (*free_playlist)(playlist_t* playlist);
+};
+
+#define SORT_BYFILENAME     1
+#define SORT_BYARTIST       2
+#define SORT_BYTITLE        3
+#define SORT_BYDURATION     4
+
+extern playlist_t *create_playlist(void);
+extern BOOL adddirtoplaylist(playlist_t *playlist, const char* path, BOOL recursive);
+
+#endif

Added: trunk/Gui/win32/preferences.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/preferences.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,714 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libvo/video_out.h>
+#include <libao2/audio_out.h>
+#include <mixer.h>
+#include "interface.h"
+#include "gui.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+#include "dialogs.h"
+#include "wincfg.h"
+
+extern int   vo_doublebuffering;
+extern int   vo_directrendering;
+extern int   frame_dropping;
+extern int   soft_vol;
+extern float audio_delay;
+extern int   osd_level;
+extern char  *dvd_device, *cdrom_device;
+extern char  *proc_priority;
+
+static void set_defaults(void);
+
+static LRESULT CALLBACK PrefsWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    HWND btn, label, edit1, edit2, edit3, updown1, updown2, track1, track2;
+    static HWND vo_driver, ao_driver, prio;
+    int i = 0, j = 0;
+    char dvddevice[MAX_PATH];
+    char cdromdevice[MAX_PATH];
+    char procprio[11];
+    float x = 10.0, y = 100.0, stereopos, delaypos;
+    stereopos = gtkAOExtraStereoMul * x;
+    delaypos = audio_delay * y;
+
+    switch (iMsg)
+    {
+        case WM_CREATE:
+        {
+            /* video and audio drivers */
+            label = CreateWindow("static", "Video Driver:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 10, 13, 70, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Audio Driver:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 190, 13, 70, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Extra stereo coefficient:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 10, 126, 115, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Audio delay:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 36, 165, 115, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "OSD level:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 10, 264, 115, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "DVD device:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 80, 363, 115, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "CD device:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 202, 363, 115, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            label = CreateWindow("static", "Priority:",
+                                 WS_CHILD | WS_VISIBLE,
+                                 217, 264, 115, 15, hwnd,
+                                 NULL, ((LPCREATESTRUCT) lParam) -> hInstance,
+                                 NULL);
+            SendMessage(label, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            vo_driver = CreateWindow("combobox", NULL,
+                                     CBS_DROPDOWNLIST | CB_SHOWDROPDOWN |
+                                     CBS_NOINTEGRALHEIGHT | CBS_HASSTRINGS |
+                                     WS_CHILD | WS_VISIBLE |
+                                     WS_VSCROLL | WS_TABSTOP,
+                                     80, 10, 100, 160, hwnd,
+                                     (HMENU) ID_VO_DRIVER,
+                                     ((LPCREATESTRUCT) lParam) -> hInstance,
+                                     NULL);
+
+            ao_driver = CreateWindow("combobox", NULL,
+                                     CBS_DROPDOWNLIST | CB_SHOWDROPDOWN |
+                                     CBS_NOINTEGRALHEIGHT | CBS_HASSTRINGS |
+                                     WS_CHILD | WS_VISIBLE |
+                                     WS_VSCROLL | WS_TABSTOP,
+                                     260, 10, 100, 160, hwnd,
+                                     (HMENU) ID_AO_DRIVER,
+                                     ((LPCREATESTRUCT) lParam) -> hInstance,
+                                     NULL);
+
+            prio = CreateWindow("combobox", NULL,
+                                CBS_DROPDOWNLIST | CB_SHOWDROPDOWN |
+                                CBS_NOINTEGRALHEIGHT | CBS_HASSTRINGS |
+                                WS_CHILD | WS_VISIBLE |
+                                WS_VSCROLL | WS_TABSTOP,
+                                260, 260, 100, 160, hwnd,
+                                (HMENU) ID_PRIO,
+                                ((LPCREATESTRUCT) lParam) -> hInstance,
+                                NULL);
+
+            /* checkboxes */
+            btn = CreateWindow("button", "Enable double buffering",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               25, 35, 150, 25,
+                               hwnd, (HMENU) ID_DOUBLE,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Enable direct rendering",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               25, 57, 150, 25,
+                               hwnd, (HMENU) ID_DIRECT,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Enable framedropping",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               25, 79, 150, 25,
+                               hwnd, (HMENU) ID_FRAMEDROP,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Normalize sound",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               205, 35, 150, 25,
+                               hwnd, (HMENU) ID_NORMALIZE,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Enable software mixer",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               205, 57, 150, 25,
+                               hwnd, (HMENU) ID_SOFTMIX,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Enable extra stereo",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               205, 79, 150, 25,
+                               hwnd, (HMENU) ID_EXTRASTEREO,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Enable cache",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               10, 200, 90, 25,
+                               hwnd, (HMENU) ID_CACHE,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Enable autosync",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               192, 200, 100, 25, hwnd,
+                               (HMENU) ID_AUTOSYNC,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Display videos in the sub window (directx only)",
+                               WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
+                               55, 227, 250, 25,
+                               hwnd, (HMENU) ID_SUBWINDOW,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            /* osd level */
+            btn = CreateWindow("button", "None",
+                               WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+                               95, 260, 100, 25, hwnd,
+                               (HMENU) ID_NONE,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Timer and indicators",
+                               WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+                               95, 280, 180, 25, hwnd,
+                               (HMENU) ID_OSD1,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Progress bar only",
+                               WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+                               95, 300, 180, 25, hwnd,
+                               (HMENU) ID_OSD2,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Timer, percentage, and total time",
+                               WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
+                               95, 320, 180, 25, hwnd,
+                               (HMENU) ID_OSD3,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Apply",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               199, 395, 80, 25, hwnd,
+                               (HMENU) ID_APPLY,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Cancel",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               285, 395, 80, 25, hwnd,
+                               (HMENU) ID_CANCEL,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            btn = CreateWindow("button", "Defaults",
+                               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+                               4, 395, 80, 25, hwnd,
+                               (HMENU) ID_DEFAULTS,
+                               ((LPCREATESTRUCT) lParam) -> hInstance,
+                               NULL);
+            SendMessage(btn, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            /* extra stereo coefficient trackbar */
+            track1 = CreateWindow(TRACKBAR_CLASS, "Coefficient",
+                                  WS_CHILD | WS_VISIBLE | WS_TABSTOP |
+                                  WS_DISABLED | TBS_HORZ |
+                                  TBS_BOTTOM | TBS_NOTICKS,
+                                  120, 120, 245, 35, hwnd,
+                                  (HMENU) ID_TRACKBAR1,
+                                  ((LPCREATESTRUCT) lParam) -> hInstance,
+                                  NULL);
+            SendDlgItemMessage(hwnd, ID_TRACKBAR1, TBM_SETRANGE, 1, MAKELONG(-100, 100));
+
+            /* audio delay */
+            track2 = CreateWindow(TRACKBAR_CLASS, "Audio delay",
+                                  WS_CHILD | WS_VISIBLE | WS_TABSTOP |
+                                  WS_DISABLED | TBS_HORZ |
+                                  TBS_BOTTOM | TBS_NOTICKS,
+                                  120, 160, 245, 35, hwnd,
+                                  (HMENU) ID_TRACKBAR2,
+                                  ((LPCREATESTRUCT) lParam) -> hInstance,
+                                  NULL);
+            SendDlgItemMessage(hwnd, ID_TRACKBAR2, TBM_SETRANGE, 1, MAKELONG(-1000, 1000));
+
+            /* cache */
+            edit1 = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "cache",
+                                   WS_CHILD | WS_VISIBLE | WS_DISABLED |
+                                   ES_LEFT | ES_AUTOHSCROLL,
+                                   105, 203, 40, 20, hwnd,
+                                   (HMENU) ID_EDIT1,
+                                   ((LPCREATESTRUCT) lParam) -> hInstance,
+                                   NULL);
+            SendMessage(edit1, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            updown1 = CreateUpDownControl(WS_CHILD | WS_VISIBLE |
+                                          WS_DISABLED | UDS_SETBUDDYINT |
+                                          UDS_ARROWKEYS | UDS_NOTHOUSANDS,
+                                          145, 203, 20, 20, hwnd,
+                                          ID_UPDOWN1,
+                                          ((LPCREATESTRUCT) lParam) -> hInstance,
+                                          (HWND)edit1, 0, 0, 0);
+            SendDlgItemMessage(hwnd, ID_UPDOWN1, UDM_SETRANGE32, (WPARAM)0, (LPARAM)65535);
+
+            /* autosync */
+            edit2 = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "autosync",
+                                   WS_CHILD | WS_VISIBLE | WS_DISABLED |
+                                   ES_LEFT | ES_AUTOHSCROLL,
+                                   300, 203, 40, 20, hwnd,
+                                   (HMENU) ID_EDIT2,
+                                   ((LPCREATESTRUCT) lParam) -> hInstance,
+                                   NULL);
+            SendMessage(edit2, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            updown2 = CreateUpDownControl(WS_CHILD | WS_VISIBLE |
+                                          WS_DISABLED | UDS_SETBUDDYINT |
+                                          UDS_ARROWKEYS | UDS_NOTHOUSANDS,
+                                          340, 203, 20, 20, hwnd,
+                                          ID_UPDOWN2,
+                                          ((LPCREATESTRUCT) lParam) -> hInstance,
+                                          (HWND)edit2, 0, 0, 0);
+            SendDlgItemMessage(hwnd, ID_UPDOWN2, UDM_SETRANGE32, (WPARAM)0, (LPARAM)10000);
+
+            /* dvd and cd devices */
+            edit3 = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", NULL,
+                                   WS_CHILD | WS_VISIBLE |
+                                   ES_LEFT | ES_AUTOHSCROLL,
+                                   145, 360, 20, 20, hwnd,
+                                   (HMENU) ID_DVDDEVICE,
+                                   ((LPCREATESTRUCT) lParam) -> hInstance,
+                                   NULL);
+            SendMessage(edit3, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            edit3 = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", NULL,
+                                   WS_CHILD | WS_VISIBLE |
+                                   ES_LEFT| ES_AUTOHSCROLL,
+                                   260, 360, 20, 20, hwnd,
+                                   (HMENU) ID_CDDEVICE,
+                                   ((LPCREATESTRUCT) lParam) -> hInstance,
+                                   NULL);
+            SendMessage(edit3, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            while(video_out_drivers[i])
+            {
+                const vo_info_t *info = video_out_drivers[i++]->info;
+                if(!video_driver_list) gaddlist(&video_driver_list, (char *)info->short_name);
+                    SendDlgItemMessage(hwnd, ID_VO_DRIVER, CB_ADDSTRING, 0, (LPARAM) info->short_name);
+            }
+            /* Special case for directx:noaccel */
+            SendDlgItemMessage(hwnd, ID_VO_DRIVER, CB_ADDSTRING, 0, (LPARAM) "directx:noaccel");
+            SendMessage(vo_driver, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            while(audio_out_drivers[j])
+            {
+                const ao_info_t *info = audio_out_drivers[j++]->info;
+                if(!audio_driver_list)
+                {
+                    gaddlist(&audio_driver_list, (char *)info->short_name);
+                    audio_driver_list[0] = "win32";
+                }
+                SendDlgItemMessage(hwnd, ID_AO_DRIVER, CB_ADDSTRING, 0, (LPARAM) info->short_name);
+            }
+            SendMessage(ao_driver, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            /* priority list, i'm leaving out realtime for safety's sake */
+            SendDlgItemMessage(hwnd, ID_PRIO, CB_INSERTSTRING, 0, (LPARAM) "low");
+            SendDlgItemMessage(hwnd, ID_PRIO, CB_INSERTSTRING, 0, (LPARAM) "belownormal");
+            SendDlgItemMessage(hwnd, ID_PRIO, CB_INSERTSTRING, 0, (LPARAM) "normal");
+            SendDlgItemMessage(hwnd, ID_PRIO, CB_INSERTSTRING, 0, (LPARAM) "abovenormal");
+            SendDlgItemMessage(hwnd, ID_PRIO, CB_INSERTSTRING, 0, (LPARAM) "high");
+            SendMessage(prio, WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
+
+            /* set our preferences on what we already have */
+            if(video_driver_list)
+                SendDlgItemMessage(hwnd, ID_VO_DRIVER, CB_SETCURSEL,
+                                   (WPARAM)SendMessage(vo_driver, CB_FINDSTRING, -1,
+                                   (LPARAM)video_driver_list[0]), 0);
+
+            if(audio_driver_list)
+                SendDlgItemMessage(hwnd, ID_AO_DRIVER, CB_SETCURSEL,
+                                   (WPARAM)SendMessage(ao_driver, CB_FINDSTRING, -1,
+                                   (LPARAM)audio_driver_list[0]), 0);
+
+            if(vo_doublebuffering)
+                SendDlgItemMessage(hwnd, ID_DOUBLE, BM_SETCHECK, 1, 0);
+            if(vo_directrendering)
+                SendDlgItemMessage(hwnd, ID_DIRECT, BM_SETCHECK, 1, 0);
+            if(frame_dropping)
+                SendDlgItemMessage(hwnd, ID_FRAMEDROP, BM_SETCHECK, 1, 0);
+            if(gtkAONorm)
+                SendDlgItemMessage(hwnd, ID_NORMALIZE, BM_SETCHECK, 1, 0);
+            if(soft_vol)
+                SendDlgItemMessage(hwnd, ID_SOFTMIX, BM_SETCHECK, 1, 0);
+            if(gtkAOExtraStereo)
+            {
+                SendDlgItemMessage(hwnd, ID_EXTRASTEREO, BM_SETCHECK, 1, 0);
+                if(!guiIntfStruct.Playing)
+                {
+                    EnableWindow(track1, 1);
+                    EnableWindow(track2, 1);
+                }
+            }
+            else gtkAOExtraStereoMul = 1.0;
+            SendDlgItemMessage(hwnd, ID_TRACKBAR1, TBM_SETPOS, 1, (LPARAM)stereopos);
+
+            if(audio_delay)
+                SendDlgItemMessage(hwnd, ID_TRACKBAR2, TBM_SETPOS, 1, (LPARAM)delaypos);
+
+            if(gtkCacheOn) {
+                SendDlgItemMessage(hwnd, ID_CACHE, BM_SETCHECK, 1, 0);
+                EnableWindow(edit1, 1);
+                EnableWindow(updown1, 1);
+            }
+            else gtkCacheSize = 2048;
+            SendDlgItemMessage(hwnd, ID_UPDOWN1, UDM_SETPOS32, 0, (LPARAM)gtkCacheSize);
+
+            if(gtkAutoSyncOn) {
+                SendDlgItemMessage(hwnd, ID_AUTOSYNC, BM_SETCHECK, 1, 0);
+                EnableWindow(edit2, 1);
+                EnableWindow(updown2, 1);
+            }
+            else gtkAutoSync = 0;
+            SendDlgItemMessage(hwnd, ID_UPDOWN2, UDM_SETPOS32, 0, (LPARAM)gtkAutoSync);
+
+            if(sub_window)
+                SendDlgItemMessage(hwnd, ID_SUBWINDOW, BM_SETCHECK, 1, 0);
+
+            if(!osd_level)
+                SendDlgItemMessage(hwnd, ID_NONE, BM_SETCHECK, 1, 0);
+            else if(osd_level == 1)
+                SendDlgItemMessage(hwnd, ID_OSD1, BM_SETCHECK, 1, 0);
+            else if(osd_level == 2)
+                SendDlgItemMessage(hwnd, ID_OSD2, BM_SETCHECK, 1, 0);
+            else if(osd_level == 3)
+                SendDlgItemMessage(hwnd, ID_OSD3, BM_SETCHECK, 1, 0);
+
+            if(dvd_device)
+                SendDlgItemMessage(hwnd, ID_DVDDEVICE, WM_SETTEXT, 0, (LPARAM)dvd_device);
+            else SendDlgItemMessage(hwnd, ID_DVDDEVICE, WM_SETTEXT, 0, (LPARAM)"D:");
+
+            if(cdrom_device)
+                SendDlgItemMessage(hwnd, ID_CDDEVICE, WM_SETTEXT, 0, (LPARAM)cdrom_device);
+            else SendDlgItemMessage(hwnd, ID_CDDEVICE, WM_SETTEXT, 0, (LPARAM)"D:");
+
+            if(proc_priority)
+                SendDlgItemMessage(hwnd, ID_PRIO, CB_SETCURSEL,
+                                   (WPARAM)SendMessage(prio, CB_FINDSTRING, -1,
+                                   (LPARAM)proc_priority), 0);
+
+            else SendDlgItemMessage(hwnd, ID_PRIO, CB_SETCURSEL, 2, 0);
+
+            break;
+        }
+        case WM_CTLCOLORDLG:
+        case WM_CTLCOLOREDIT:
+        case WM_CTLCOLORBTN:
+        case WM_CTLCOLORSTATIC:
+        {
+            HDC hdc = (HDC)wParam;
+            SetBkMode(hdc, TRANSPARENT);
+            return (INT_PTR)SOLID_GREY;
+        }
+        break;
+        case WM_COMMAND:
+        {
+            switch (LOWORD(wParam))
+            {
+                case ID_EXTRASTEREO:
+                {
+                    if(SendDlgItemMessage(hwnd, ID_EXTRASTEREO, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                    {
+                        EnableWindow(GetDlgItem(hwnd, ID_TRACKBAR1), 1);
+                        EnableWindow(GetDlgItem(hwnd, ID_TRACKBAR2), 1);
+                    } else {
+                        EnableWindow(GetDlgItem(hwnd, ID_TRACKBAR1), 0);
+                        EnableWindow(GetDlgItem(hwnd, ID_TRACKBAR2), 0);
+                        SendDlgItemMessage(hwnd, ID_TRACKBAR1, TBM_SETPOS, 1, (LPARAM)10.0);
+                        SendDlgItemMessage(hwnd, ID_TRACKBAR2, TBM_SETPOS, 1, (LPARAM)0);
+                    }
+                    break;
+                }
+                case ID_CACHE:
+                {
+                    if(SendDlgItemMessage(hwnd, ID_CACHE, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                    {
+                        EnableWindow(GetDlgItem(hwnd, ID_EDIT1), 1);
+                        EnableWindow(GetDlgItem(hwnd, ID_UPDOWN1), 1);
+                    } else {
+                        EnableWindow(GetDlgItem(hwnd, ID_EDIT1), 0);
+                        EnableWindow(GetDlgItem(hwnd, ID_UPDOWN1), 0);
+                        SendDlgItemMessage(hwnd, ID_UPDOWN1, UDM_SETPOS32, 1, (LPARAM)2048);
+                    }
+                    break;
+                }
+                case ID_AUTOSYNC:
+                {
+                    if(SendDlgItemMessage(hwnd, ID_AUTOSYNC, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                    {
+                        EnableWindow(GetDlgItem(hwnd, ID_EDIT2), 1);
+                        EnableWindow(GetDlgItem(hwnd, ID_UPDOWN2), 1);
+                    } else {
+                        EnableWindow(GetDlgItem(hwnd, ID_EDIT2), 0);
+                        EnableWindow(GetDlgItem(hwnd, ID_UPDOWN2), 0);
+                        SendDlgItemMessage(hwnd, ID_UPDOWN2, UDM_SETPOS32, 1, (LPARAM)0);
+                    }
+                    break;
+                }
+                case ID_DEFAULTS:
+                {
+                    set_defaults();
+                    SendDlgItemMessage(hwnd, ID_VO_DRIVER, CB_SETCURSEL,
+                                       (WPARAM)SendMessage(vo_driver, CB_FINDSTRING, -1, (LPARAM)"directx"), 0);
+
+                    SendDlgItemMessage(hwnd, ID_AO_DRIVER, CB_SETCURSEL,
+                                       (WPARAM)SendMessage(ao_driver, CB_FINDSTRING, -1, (LPARAM)"dsound"), 0);
+
+                    SendDlgItemMessage(hwnd, ID_PRIO, CB_SETCURSEL,
+                                       (WPARAM)SendMessage(prio, CB_FINDSTRING, -1, (LPARAM)proc_priority), 0);
+
+                    SendDlgItemMessage(hwnd, ID_TRACKBAR1, TBM_SETPOS, 1, (LPARAM)10.0);
+                    SendDlgItemMessage(hwnd, ID_TRACKBAR2, TBM_SETPOS, 1, (LPARAM)0.0);
+                    SendDlgItemMessage(hwnd, ID_UPDOWN1, UDM_SETPOS32, 0, (LPARAM)gtkCacheSize);
+                    SendDlgItemMessage(hwnd, ID_UPDOWN2, UDM_SETPOS32, 0, (LPARAM)gtkAutoSync);
+                    SendDlgItemMessage(hwnd, ID_DOUBLE, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_DIRECT, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_FRAMEDROP, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_NORMALIZE, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_SOFTMIX, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_EXTRASTEREO, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_CACHE, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_AUTOSYNC, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_SUBWINDOW, BM_SETCHECK, 1, 0);
+                    SendDlgItemMessage(hwnd, ID_NONE, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_OSD1, BM_SETCHECK, 1, 0);
+                    SendDlgItemMessage(hwnd, ID_OSD2, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_OSD3, BM_SETCHECK, 0, 0);
+                    SendDlgItemMessage(hwnd, ID_DVDDEVICE, WM_SETTEXT, 0, (LPARAM)"D:");
+                    SendDlgItemMessage(hwnd, ID_CDDEVICE, WM_SETTEXT, 0, (LPARAM)"D:");
+                    SendMessage(hwnd, WM_COMMAND, (WPARAM)ID_APPLY, 0);
+                    break;
+                }
+                case ID_CANCEL:
+                    DestroyWindow(hwnd);
+                    return 0;
+                case ID_APPLY:
+                {
+                    if(guiIntfStruct.Playing) guiGetEvent(guiCEvent, (void *)guiSetStop);
+
+                    /* Set the video driver */
+                    SendMessage(vo_driver, CB_GETLBTEXT, (WPARAM)SendMessage(vo_driver, CB_GETCURSEL, 0, 0),
+                                (LPARAM)video_driver_list[0]);
+
+                    /* Set the audio driver */
+                    SendMessage(ao_driver, CB_GETLBTEXT, (WPARAM)SendMessage(ao_driver, CB_GETCURSEL, 0, 0),
+                                (LPARAM)audio_driver_list[0]);
+
+                    /* Set the priority level */
+                    SendMessage(prio, CB_GETLBTEXT, (WPARAM)SendMessage(prio, CB_GETCURSEL, 0, 0), (LPARAM)procprio);
+                    proc_priority = strdup(procprio);
+
+                    /* double buffering */
+                    if(SendDlgItemMessage(hwnd, ID_DOUBLE, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        vo_doublebuffering = 1;
+                    else vo_doublebuffering = 0;
+
+                    /* direct rendering */
+                    if(SendDlgItemMessage(hwnd, ID_DIRECT, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        vo_directrendering = 1;
+                    else vo_directrendering = 0;
+
+                    /* frame dropping */
+                    if(SendDlgItemMessage(hwnd, ID_FRAMEDROP, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        frame_dropping = 1;
+                    else frame_dropping = 0;
+
+                    /* normalize */
+                    if(SendDlgItemMessage(hwnd, ID_NORMALIZE, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        gtkAONorm = 1;
+                    else gtkAONorm = 0;
+
+                    /* software mixer */
+                    if(SendDlgItemMessage(hwnd, ID_SOFTMIX, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        soft_vol = 1;
+                    else soft_vol = 0;
+
+                    /* extra stereo */
+                    if(SendDlgItemMessage(hwnd, ID_EXTRASTEREO, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        gtkAOExtraStereo = 1;
+                    else {
+                        gtkAOExtraStereo = 0;
+                        gtkAOExtraStereoMul = 10.0;
+                    }
+                    gtkAOExtraStereoMul = SendDlgItemMessage(hwnd, ID_TRACKBAR1, TBM_GETPOS, 0, 0) / 10.0;
+
+                    /* audio delay */
+                    audio_delay = SendDlgItemMessage(hwnd, ID_TRACKBAR2, TBM_GETPOS, 0, 0) / 100.0;
+
+                    /* cache */
+                    if(SendDlgItemMessage(hwnd, ID_CACHE, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        gtkCacheOn = 1;
+                    else gtkCacheOn = 0;
+                    gtkCacheSize = SendDlgItemMessage(hwnd, ID_UPDOWN1, UDM_GETPOS32, 0, 0);
+
+                    /* autosync */
+                    if(SendDlgItemMessage(hwnd, ID_AUTOSYNC, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        gtkAutoSyncOn = 1;
+                    else gtkAutoSyncOn = 0;
+                    gtkAutoSync = SendDlgItemMessage(hwnd, ID_UPDOWN2, UDM_GETPOS32, 0, 0);
+
+                    /* sub window */
+                    if(SendDlgItemMessage(hwnd, ID_SUBWINDOW, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        sub_window = 1;
+                    else sub_window = 0;
+
+                    /* osd level */
+                    if(SendDlgItemMessage(hwnd, ID_NONE, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        osd_level = 0;
+                    else if(SendDlgItemMessage(hwnd, ID_OSD1, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        osd_level = 1;
+                    else if(SendDlgItemMessage(hwnd, ID_OSD2, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        osd_level = 2;
+                    else if(SendDlgItemMessage(hwnd, ID_OSD3, BM_GETCHECK, 0, 0) == BST_CHECKED)
+                        osd_level = 3;
+
+                    /* dvd and cd devices */
+                    SendDlgItemMessage(hwnd, ID_DVDDEVICE, WM_GETTEXT, MAX_PATH, (LPARAM)dvddevice);
+                    dvd_device = strdup(dvddevice);
+                    SendDlgItemMessage(hwnd, ID_CDDEVICE, WM_GETTEXT, MAX_PATH, (LPARAM)cdromdevice);
+                    cdrom_device = strdup(cdromdevice);
+
+                    MessageBox(hwnd, "You must restart MPlayer for the changes to take effect.", "MPlayer - Info:", MB_OK);
+                    DestroyWindow(hwnd);
+                    break;
+                }
+            }
+            return 0;
+        }
+        case WM_DESTROY:
+            PostQuitMessage (0);
+            return 0;
+    }
+    return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}
+
+void display_prefswindow(gui_t *gui)
+{
+    HWND hWnd;
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    WNDCLASS wc;
+    int x, y;
+    if(FindWindow(NULL, "MPlayer - Preferences")) return;
+    wc.style         = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc   = PrefsWndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = 0;
+    wc.hInstance     = hInstance;
+    wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
+    wc.hIcon         = gui->icon;
+    wc.hbrBackground = SOLID_GREY;
+    wc.lpszClassName = "MPlayer - Preferences";
+    wc.lpszMenuName  = NULL;
+    RegisterClass(&wc);
+    x = (GetSystemMetrics(SM_CXSCREEN) / 2) - (375 / 2);
+    y = (GetSystemMetrics(SM_CYSCREEN) / 2) - (452 / 2);
+    hWnd = CreateWindow("MPlayer - Preferences",
+                        "MPlayer - Preferences",
+                        WS_POPUPWINDOW | WS_CAPTION,
+                        x,
+                        y,
+                        375,
+                        452,
+                        NULL,
+                        NULL,
+                        hInstance,
+                        NULL);
+   SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD) gui);
+   ShowWindow(hWnd, SW_SHOW);
+   UpdateWindow(hWnd);
+}
+
+static void set_defaults(void)
+{
+    proc_priority = "normal";
+    vo_doublebuffering = 1;
+    vo_directrendering = 0;
+    frame_dropping = 0;
+    soft_vol = 0;
+    gtkAONorm = 0;
+    gtkAOExtraStereo = 0;
+    gtkAOExtraStereoMul = 1.0;
+    audio_delay = 0.0;
+    sub_window = 1;
+    gtkCacheOn = 0;
+    gtkCacheSize = 2048;
+    gtkAutoSyncOn = 0;
+    gtkAutoSync = 0;
+}

Added: trunk/Gui/win32/skinload.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/skinload.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,809 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <windows.h>
+#include <png.h>
+
+#include <mp_msg.h>
+#include <cpudetect.h>
+#include <libswscale/rgb2rgb.h>
+#include <libswscale/swscale.h>
+
+#include "gui.h"
+
+#define MAX_LINESIZE 256
+
+typedef struct
+{
+    int msg;
+    char *name;
+} evName;
+
+static const evName evNames[] =
+{
+    {   evNone,                 "evNone"                },
+    {   evPlay,                 "evPlay"                },
+    {   evDropFile,             "evDropFile"            },
+    {   evStop,                 "evStop"                },
+    {   evPause,                "evPause"               },
+    {   evPrev,                 "evPrev"                },
+    {   evNext,                 "evNext"                },
+    {   evLoad,                 "evLoad"                },
+    {   evEqualizer,            "evEqualizer"           },
+    {   evEqualizer,            "evEqualeaser"          },
+    {   evPlayList,             "evPlaylist"            },
+    {   evExit,                 "evExit"                },
+    {   evIconify,              "evIconify"             },
+    {   evIncBalance,           "evIncBalance"          },
+    {   evDecBalance,           "evDecBalance"          },
+    {   evFullScreen,           "evFullScreen"          },
+    {   evFName,                "evFName"               },
+    {   evMovieTime,            "evMovieTime"           },
+    {   evAbout,                "evAbout"               },
+    {   evLoadPlay,             "evLoadPlay"            },
+    {   evPreferences,          "evPreferences"         },
+    {   evSkinBrowser,          "evSkinBrowser"         },
+    {   evBackward10sec,        "evBackward10sec"       },
+    {   evForward10sec,         "evForward10sec"        },
+    {   evBackward1min,         "evBackward1min"        },
+    {   evForward1min,          "evForward1min"         },
+    {   evBackward10min,        "evBackward10min"       },
+    {   evForward10min,         "evForward10min"        },
+    {   evIncVolume,            "evIncVolume"           },
+    {   evDecVolume,            "evDecVolume"           },
+    {   evMute,                 "evMute"                },
+    {   evIncAudioBufDelay,     "evIncAudioBufDelay"    },
+    {   evDecAudioBufDelay,     "evDecAudioBufDelay"    },
+    {   evPlaySwitchToPause,    "evPlaySwitchToPause"   },
+    {   evPauseSwitchToPlay,    "evPauseSwitchToPlay"   },
+    {   evNormalSize,           "evNormalSize"          },
+    {   evDoubleSize,           "evDoubleSize"          },
+    {   evSetMoviePosition,     "evSetMoviePosition"    },
+    {   evSetVolume,            "evSetVolume"           },
+    {   evSetBalance,           "evSetBalance"          },
+    {   evHelp,                 "evHelp"                },
+    {   evLoadSubtitle,         "evLoadSubtitle"        },
+    {   evPlayDVD,              "evPlayDVD"             },
+    {   evPlayVCD,              "evPlayVCD"             },
+    {   evSetURL,               "evSetURL"              },
+    {   evLoadAudioFile,        "evLoadAudioFile"       },
+    {   evDropSubtitle,         "evDropSubtitle"        },
+    {   evSetAspect,            "evSetAspect"           }
+};
+
+static const int evBoxs = sizeof(evNames) / sizeof(evName);
+
+static char *geteventname(int event)
+{
+    int i;
+    for(i=0; i<evBoxs; i++)
+        if(evNames[i].msg == event)
+            return evNames[i].name;
+    return NULL;
+}
+
+static inline int get_sws_cpuflags(void)
+{
+    return (gCpuCaps.hasMMX ? SWS_CPU_CAPS_MMX : 0) |
+           (gCpuCaps.hasMMX2 ? SWS_CPU_CAPS_MMX2 : 0) |
+           (gCpuCaps.has3DNow ? SWS_CPU_CAPS_3DNOW : 0);
+}
+
+/* reads a complete image as is into image buffer */
+static image *pngRead(skin_t *skin, unsigned char *fname)
+{
+    unsigned char header[8];
+    png_structp png;
+    png_infop info;
+    png_infop endinfo;
+    png_bytep *row_p;
+    int color, h;
+    png_uint_32 i;
+    int BPP;
+    char *img;
+    unsigned int imgsize;
+    image *bf;
+    char *filename;
+    FILE *fp;
+
+    if(!stricmp(fname, "NULL")) return 0;
+
+    /* find filename in order file file.png */
+    if(!(fp = fopen(fname, "rb")))
+    {
+        filename = calloc(1, strlen(skin->skindir) + strlen(fname) + 6);
+        sprintf(filename, "%s\\%s.png", skin->skindir, fname);
+        if(!(fp = fopen(filename, "rb")))
+        {
+            mp_msg(MSGT_GPLAYER, MSGL_ERR, "[png] cannot find image %s\n", filename);
+            free(filename);
+            return 0;
+        }
+        free(filename);
+    }
+
+    for (i=0; i < skin->imagecount; i++)
+        if(!strcmp(fname, skin->images[i]->name))
+        {
+#ifdef DEBUG
+            mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] skinfile %s already exists\n", fname);
+#endif
+            return skin->images[i];
+        }
+    (skin->imagecount)++;
+    skin->images = realloc(skin->images, sizeof(image *) * skin->imagecount);
+    bf = skin->images[(skin->imagecount) - 1] = calloc(1, sizeof(image));
+    bf->name = strdup(fname);
+    fread(header,1,8,fp);
+    if (!png_check_sig(header, 8)) return 0;
+    png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    info = png_create_info_struct(png);
+    endinfo = png_create_info_struct(png);
+
+    png_init_io(png, fp);
+    png_set_sig_bytes(png, 8);
+    png_read_info(png, info);
+    png_get_IHDR(png, info, (png_uint_32*) &bf->width, (png_uint_32*) &bf->height, &BPP, &color, NULL, NULL, NULL);
+
+    if(color & PNG_COLOR_MASK_ALPHA)
+    {
+        if(color & PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY_ALPHA ) BPP *= 2;
+        else BPP *= 4;
+    }
+    else
+    {
+        if(color & PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY ) BPP *= 1;
+        else BPP *= 3;
+    }
+    row_p = (png_bytep *) malloc (sizeof(png_bytep) * bf->height);
+    img = (png_bytep) calloc(png_get_rowbytes(png, info), bf->height);
+    for (h=0; h < bf->height; h++)
+        row_p[h] = &img[png_get_rowbytes(png, info) * h];
+    png_read_image(png, row_p);
+    free(row_p);
+
+    png_read_end(png, endinfo);
+    png_destroy_read_struct(&png, &info, &endinfo);
+    fclose(fp);
+    imgsize=bf->width * bf->height * (BPP / 8);
+
+#ifdef DEBUG
+    mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] loaded image %s\n", fname);
+    mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] size: %dx%d bits: %d\n", bf->width, bf->height, BPP);
+    mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] imagesize: %u\n", imgsize);
+#endif
+
+    bf->size = bf->width * bf->height * skin->desktopbpp / 8;
+    bf->data = malloc(bf->size);
+    if(skin->desktopbpp == 16 && BPP == 24) rgb24tobgr15(img, bf->data, imgsize);
+    else if(skin->desktopbpp == 16 && BPP == 32) rgb32tobgr15(img, bf->data, imgsize);
+    else if(skin->desktopbpp == 24 && BPP == 24) rgb24tobgr24(img, bf->data, imgsize);
+    else if(skin->desktopbpp == 24 && BPP == 32) rgb32tobgr24(img, bf->data, imgsize);
+    else if(skin->desktopbpp == 32 && BPP == 24) rgb24tobgr32(img, bf->data, imgsize);
+    else if(skin->desktopbpp == 32 && BPP == 32) rgb32tobgr32(img, bf->data, imgsize);
+    free(img);
+    return bf;
+}
+
+/* frees all skin images */
+static void freeimages(skin_t *skin)
+{
+    unsigned int i;
+    for (i=0; i<skin->imagecount; i++)
+    {
+        if(skin->images && skin->images[i])
+        {
+            if(skin->images[i]->data) free(skin->images[i]->data);
+            if(skin->images[i]->name) free(skin->images[i]->name);
+            free(skin->images[i]);
+        }
+    }
+    free(skin->images);
+}
+
+#ifdef DEBUG
+void dumpwidgets(skin_t *skin)
+{
+    unsigned int i;
+    for (i=0; i<skin->widgetcount; i++)
+        mp_msg(MSGT_GPLAYER, MSGL_V, "widget %p id %i\n", skin->widgets[i], skin->widgets[i]->id);
+}
+#endif
+
+static int counttonextchar(const char *s1, char c)
+{
+    unsigned int i;
+    for (i=0; i<strlen(s1); i++)
+        if(s1[i] == c) return i;
+    return 0;
+}
+
+static char *findnextstring(char *temp, const char *desc, int *base)
+{
+    int len = counttonextchar(*base + desc, ',');
+    memset(temp, 0, strlen(desc) + 1);
+    if(!len) len = strlen(desc);
+    memcpy(temp, *base + desc, len);
+    *base += (len+1);
+    return temp;
+}
+
+static void freeskin(skin_t *skin)
+{
+    unsigned int i;
+    if(skin->skindir)
+    {
+        free(skin->skindir);
+        skin->skindir = NULL;
+    }
+
+    for (i=1; i<=skin->lastusedid; i++)
+        skin->removewidget(skin, i);
+
+    if(skin->widgets)
+    {
+        free(skin->widgets);
+        skin->widgets = NULL;
+    }
+
+    freeimages(skin);
+    for(i=0; i<skin->windowcount; i++)
+    {
+        if(skin->windows[i]->name)
+        {
+            free(skin->windows[i]->name);
+            skin->windows[i]->name = NULL;
+        }
+        free(skin->windows[i]);
+    }
+
+    free(skin->windows);
+    skin->windows = NULL;
+
+    for (i=0; i<skin->fontcount; i++)
+    {
+        unsigned int x;
+        if(skin->fonts[i]->name)
+        {
+            free(skin->fonts[i]->name);
+            skin->fonts[i]->name = NULL;
+        }
+
+        if(skin->fonts[i]->id)
+        {
+            free(skin->fonts[i]->id);
+            skin->fonts[i]->id = NULL;
+        }
+
+        for (x=0; x<skin->fonts[i]->charcount; x++)
+        {
+            free(skin->fonts[i]->chars[x]);
+            skin->fonts[i]->chars[x] = NULL;
+        }
+
+        if(skin->fonts[i]->chars)
+        {
+            free(skin->fonts[i]->chars);
+            skin->fonts[i]->chars = NULL;
+        }
+
+        free(skin->fonts[i]);
+        skin->fonts[i] = NULL;
+    }
+    free(skin->fonts);
+    skin->fonts = NULL;
+#ifdef DEBUG
+    mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN FREE] skin freed\n");
+#endif
+    free(skin);
+    skin = NULL;
+}
+
+static void removewidget(skin_t *skin, int id)
+{
+    unsigned int i;
+    unsigned int pos=0;
+    widget **temp = calloc(skin->widgetcount - 1, sizeof(widget *));
+
+    for (i=0; i<skin->widgetcount; i++)
+    {
+        if(skin->widgets[i]->id == id)
+        {
+            if(skin->widgets[i]->label)
+                free(skin->widgets[i]->label);
+            free(skin->widgets[i]);
+            skin->widgets[i] = NULL;
+        }
+        else
+        {
+            temp[pos] = skin->widgets[i];
+            pos++;
+        }
+    }
+    if (pos != i)
+    {
+        (skin->widgetcount)--;
+        free(skin->widgets);
+        skin->widgets = temp;
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "removed widget %i\n", id);
+#endif
+        return;
+    }
+    free(temp);
+    mp_msg(MSGT_GPLAYER, MSGL_ERR, "widget %i not found\n", id);
+}
+
+static void addwidget(skin_t *skin, window *win, const char *desc)
+{
+    widget *mywidget;
+    char *temp = calloc(1, strlen(desc) + 1);
+    (skin->widgetcount)++;
+    (skin->lastusedid)++;
+    skin->widgets = realloc(skin->widgets, sizeof(widget *) * skin->widgetcount);
+    mywidget = skin->widgets[(skin->widgetcount) - 1] = calloc(1, sizeof(widget));
+    mywidget->id = skin->lastusedid;
+    mywidget->window = win->type;
+    /* parse and fill widget specific info */
+    if(!strncmp(desc, "base", 4))
+    {
+        int base = counttonextchar(desc, '=') + 1;
+        mywidget->type = tyBase;
+        mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+        mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+        mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+        mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
+        mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
+        win->base = mywidget;
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BASE] %s %i %i %i %i\n",
+              (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+               mywidget->x, mywidget->y, mywidget->width, mywidget->height);
+#endif
+    }
+    else if(!strncmp(desc, "button", 6))
+    {
+        int base = counttonextchar(desc, '=') + 1;
+        int i;
+        mywidget->type = tyButton;
+        mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+        mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+        mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+        mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
+        mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
+        findnextstring(temp, desc, &base);
+
+        /* Assign corresponding event to the widget */
+        mywidget->msg = evNone;
+        for (i=0; i<evBoxs; i++)
+        {
+            if(!strcmp(temp, evNames[i].name))
+            {
+                mywidget->msg = evNames[i].msg;
+                break;
+            }
+        }
+
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BUTTON] %s %i %i %i %i msg %i\n",
+              (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+               mywidget->x, mywidget->y, mywidget->width, mywidget->height, mywidget->msg);
+#endif
+    }
+    else if(!strncmp(desc, "hpotmeter", 9) || !strncmp(desc, "vpotmeter", 9))
+    {
+        int base = counttonextchar(desc, '=') + 1;
+        int i;
+        /* hpotmeter = button, bwidth, bheight, phases, numphases, default, X, Y, width, height, message */
+        if(!strncmp(desc, "hpotmeter", 9)) mywidget->type = tyHpotmeter;
+        else mywidget->type = tyVpotmeter;
+        mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+        mywidget->width = atoi(findnextstring(temp, desc, &base));
+        mywidget->height = atoi(findnextstring(temp, desc, &base));
+        mywidget->bitmap[1] = pngRead(skin, findnextstring(temp, desc, &base));
+        mywidget->phases = atoi(findnextstring(temp, desc, &base));
+        mywidget->value = atof(findnextstring(temp, desc, &base));
+        mywidget->x = mywidget->wx = atoi(findnextstring(temp, desc, &base));
+        mywidget->y = mywidget->wy = atoi(findnextstring(temp, desc, &base));
+        mywidget->wwidth = atoi(findnextstring(temp, desc, &base));
+        mywidget->wheight = atoi(findnextstring(temp, desc, &base));
+        findnextstring(temp, desc, &base);
+        mywidget->msg = evNone;
+        for (i=0; i<evBoxs; i++)
+        {
+            if(!strcmp(temp, evNames[i].name))
+            {
+                mywidget->msg = evNames[i].msg;
+                break;
+            }
+        }
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] %s %s %i %i %s %i %f %i %i %i %i msg %i\n",
+                (mywidget->type == tyHpotmeter) ? "[HPOTMETER]" : "[VPOTMETER]",
+                (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+                mywidget->width, mywidget->height,
+                (mywidget->bitmap[1]) ? mywidget->bitmap[1]->name : NULL,
+                mywidget->phases, mywidget->value,
+                mywidget->wx, mywidget->wy, mywidget->wwidth, mywidget->wwidth,
+                mywidget->msg);
+#endif
+    }
+    else if(!strncmp(desc, "potmeter", 8))
+    {
+        int base = counttonextchar(desc, '=') + 1;
+        int i;
+        /* potmeter = phases, numphases, default, X, Y, width, height, message */
+        mywidget->type = tyPotmeter;
+        mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+        mywidget->phases = atoi(findnextstring(temp, desc, &base));
+        mywidget->value = atof(findnextstring(temp, desc, &base));
+        mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+        mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+        mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
+        mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
+        findnextstring(temp, desc, &base);
+        mywidget->msg = evNone;
+        for (i=0; i<evBoxs; i++)
+        {
+            if(!strcmp(temp, evNames[i].name))
+            {
+                mywidget->msg=evNames[i].msg;
+                break;
+            }
+        }
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [POTMETER] %s %i %i %i %f %i %i msg %i\n",
+                (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+                mywidget->width, mywidget->height,
+                mywidget->phases, mywidget->value,
+                mywidget->x, mywidget->y,
+                mywidget->msg);
+#endif
+    }
+    else if(!strncmp(desc, "menu", 4))
+    {
+        int base = counttonextchar(desc, '=') + 1;
+        int i;
+        mywidget->type = tyMenu;
+        mywidget->wx=atoi(findnextstring(temp, desc, &base));
+        mywidget->x=0;
+        mywidget->wy=mywidget->y=atoi(findnextstring(temp, desc, &base));
+        mywidget->wwidth=mywidget->width=atoi(findnextstring(temp, desc, &base));
+        mywidget->wheight=mywidget->height=atoi(findnextstring(temp, desc, &base));
+        findnextstring(temp, desc, &base);
+        mywidget->msg = evNone;
+        for (i=0; i<evBoxs; i++)
+        {
+            if(!strcmp(temp, evNames[i].name))
+            {
+                mywidget->msg = evNames[i].msg;
+                break;
+            }
+        }
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [MENU] %i %i %i %i msg %i\n",
+               mywidget->x, mywidget->y, mywidget->width, mywidget->height, mywidget->msg);
+#endif
+    }
+    else if(!strncmp(desc, "selected", 8))
+    {
+        win->base->bitmap[1] = pngRead(skin, (char *) desc + 9);
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BASE] added image %s\n", win->base->bitmap[1]->name);
+#endif
+    }
+    else if(!strncmp(desc, "slabel",6))
+    {
+        int base = counttonextchar(desc, '=') + 1;
+        unsigned int i;
+        mywidget->type = tySlabel;
+        mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+        mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+        findnextstring(temp, desc, &base);
+        mywidget->font = NULL;
+        for (i=0; i<skin->fontcount; i++)
+        {
+            if(!strcmp(temp, skin->fonts[i]->name))
+            {
+                mywidget->font = skin->fonts[i];
+                break;
+            }
+        }
+        mywidget->label = strdup(findnextstring(temp, desc, &base));
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [SLABEL] %i %i %s %s\n",
+               mywidget->x, mywidget->y, mywidget->font->name, mywidget->label);
+#endif
+    }
+    else if(!strncmp(desc, "dlabel", 6))
+    {
+        int base = counttonextchar(desc, '=') + 1;
+        unsigned int i;
+        mywidget->type = tyDlabel;
+        mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+        mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+        mywidget->length = atoi(findnextstring(temp, desc, &base));
+        mywidget->align = atoi(findnextstring(temp, desc, &base));
+        findnextstring(temp, desc, &base);
+        mywidget->font = NULL;
+        for (i=0; i<skin->fontcount; i++)
+        {
+            if(!strcmp(temp, skin->fonts[i]->name))
+            {
+                mywidget->font=skin->fonts[i];
+                break;
+            }
+        }
+        mywidget->label=strdup(findnextstring(temp, desc, &base));
+#ifdef DEBUG
+        mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [DLABEL] %i %i %i %i %s \"%s\"\n",
+               mywidget->x, mywidget->y, mywidget->length, mywidget->align, mywidget->font->name, mywidget->label);
+#endif
+    }
+    free(temp);
+}
+
+static void loadfonts(skin_t* skin)
+{
+    unsigned int x;
+    for (x=0; x<skin->fontcount; x++)
+    {
+        FILE *fp;
+        int linenumber=0;
+        char *filename;
+        char *tmp = calloc(1, MAX_LINESIZE);
+        char *desc = calloc(1, MAX_LINESIZE);
+        filename = calloc(1, strlen(skin->skindir) + strlen(skin->fonts[x]->name) + 6);
+        sprintf(filename, "%s\\%s.fnt", skin->skindir, skin->fonts[x]->name);
+        if(!(fp = fopen(filename,"rb")))
+        {
+            mp_msg(MSGT_GPLAYER, MSGL_ERR, "[FONT LOAD] Font not found \"%s\"\n", skin->fonts[x]->name);
+            return;
+        }
+        while(!feof(fp))
+        {
+            int pos = 0;
+            unsigned int i;
+            fgets(tmp, MAX_LINESIZE, fp);
+            linenumber++;
+            memset(desc, 0, MAX_LINESIZE);
+            for (i=0; i<strlen(tmp); i++)
+            {
+                /* remove spaces and linebreaks */
+                if((tmp[i] == ' ') || (tmp[i] == '\n') || (tmp[i] == '\r')) continue;
+                /* remove comments */
+                if((tmp[i] == ';') &&  ((i < 1) || (tmp[i-1] != '\"')))
+                {
+#ifdef DEBUG
+                    mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT LOAD] Comment: %s", tmp + i + 1);
+#endif
+                    break;
+                }
+                desc[pos] = tmp[i];
+                pos++;
+            }
+            if(!strlen(desc)) continue;
+            /* now we have "readable" output -> parse it */
+            if(!strncmp(desc, "image", 5))
+            {
+                skin->fonts[x]->image = pngRead(skin, desc + 6);
+#ifdef DEBUG
+                mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT] [IMAGE] \"%s\"\n", desc + 6);
+#endif
+            }
+            else
+            {
+                int base = 4;
+                if(*desc != '"') break;
+                if(*(desc + 1) == 0) break;
+                (skin->fonts[x]->charcount)++;
+                skin->fonts[x]->chars = realloc(skin->fonts[x]->chars, sizeof(char_t *) *skin->fonts[x]->charcount);
+                skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]=calloc(1, sizeof(char_t));
+                skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->c = ((*(desc + 1) == '"') && (*(desc + 2) != '"')) ? ' ': *(desc + 1);
+                if((*(desc + 1) == '"') && (*(desc + 2) != '"')) base = 3;
+                skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->x = atoi(findnextstring(tmp, desc, &base));
+                skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->y = atoi(findnextstring(tmp, desc, &base));
+                skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->width = atoi(findnextstring(tmp, desc, &base));
+                skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->height = atoi(findnextstring(tmp, desc, &base));
+#ifdef DEBUG
+                mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT] [CHAR] %c %i %i %i %i\n",
+                        skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->c,
+                        skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->x,
+                        skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->y,
+                        skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->width,
+                        skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->height);
+#endif
+            }
+        }
+        free(desc);
+        free(filename);
+        free(tmp);
+        fclose(fp);
+    }
+}
+
+skin_t* loadskin(char* skindir, int desktopbpp)
+{
+    FILE *fp;
+    int reachedendofwindow = 0;
+    int linenumber = 0;
+    skin_t *skin = calloc(1, sizeof(skin_t));
+    char *filename;
+    char *tmp = calloc(1, MAX_LINESIZE);
+    char *desc = calloc(1, MAX_LINESIZE);
+    window* mywindow = NULL;
+
+    /* init swscaler */
+    sws_rgb2rgb_init(get_sws_cpuflags());
+    /* setup funcs */
+    skin->freeskin = freeskin;
+    skin->pngRead = pngRead;
+    skin->addwidget = addwidget;
+    skin->removewidget = removewidget;
+    skin->geteventname = geteventname;
+    skin->desktopbpp = desktopbpp;
+    skin->skindir = strdup(skindir);
+
+    filename = calloc(1, strlen(skin->skindir) + strlen("skin") + 2);
+    sprintf(filename, "%s\\skin", skin->skindir);
+    if(!(fp = fopen(filename, "rb")))
+    {
+        mp_msg(MSGT_GPLAYER, MSGL_FATAL, "[SKIN LOAD] Skin \"%s\" not found\n", skindir);
+        skin->freeskin(skin);
+        return NULL;
+    }
+
+    while(!feof(fp))
+    {
+        int pos = 0;
+        unsigned int i;
+        int insidequote = 0;
+        fgets(tmp, MAX_LINESIZE, fp);
+        linenumber++;
+        memset(desc, 0, MAX_LINESIZE);
+        for (i=0; i<strlen(tmp); i++)
+        {
+            if((tmp[i] == '"') && !insidequote) { insidequote=1; continue; }
+            else if((tmp[i] == '"') && insidequote) { insidequote=0 ; continue; }
+            /* remove spaces and linebreaks */
+            if((!insidequote && (tmp[i] == ' ')) || (tmp[i] == '\n') || (tmp[i] == '\r')) continue;
+            /* remove comments */
+            else if(tmp[i] == ';')
+            {
+#ifdef DEBUG
+                mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN LOAD] Comment: %s", tmp + i + 1);
+#endif
+                break;
+            }
+            desc[pos] = tmp[i];
+            pos++;
+        }
+
+        if(!strlen(desc)) continue;
+        /* now we have "readable" output -> parse it */
+        /* parse window specific info */
+        if(!strncmp(desc, "section", 7))
+        {
+#ifdef DEBUG
+            mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [SECTION] \"%s\"\n", desc + 8);
+#endif
+        }
+        else if(!strncmp(desc, "window", 6))
+        {
+#ifdef DEBUG
+            mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [WINDOW] \"%s\"\n", desc + 7);
+#endif
+            reachedendofwindow = 0;
+            (skin->windowcount)++;
+            skin->windows = realloc(skin->windows, sizeof(window *) * skin->windowcount);
+            mywindow = skin->windows[(skin->windowcount) - 1] = calloc(1, sizeof(window));
+            mywindow->name = strdup(desc + 7);
+            if(!strncmp(desc + 7, "main", 4)) mywindow->type = wiMain;
+            else if(!strncmp(desc+7, "sub", 3))
+            {
+                mywindow->type = wiSub;
+                mywindow->decoration = 1;
+            }
+            else if(!strncmp(desc + 7, "menu", 4)) mywindow->type = wiMenu;
+            else if(!strncmp(desc + 7, "playbar", 7)) mywindow->type = wiPlaybar;
+            else mp_msg(MSGT_GPLAYER, MSGL_V, "[SKIN] warning found unknown windowtype");
+        }
+        else if(!strncmp(desc, "decoration", 10) && !strncmp(desc + 11, "enable", 6))
+        {
+            mywindow->decoration = 1;
+#ifdef DEBUG
+            mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [DECORATION] enabled decoration for window \"%s\"\n", mywindow->name);
+#endif
+        }
+        else if(!strncmp(desc, "background", 10))
+        {
+            int base = counttonextchar(desc, '=') + 1;
+            char temp[MAX_LINESIZE];
+            mywindow->backgroundcolor[0] = atoi(findnextstring(temp, desc, &base));
+            mywindow->backgroundcolor[1] = atoi(findnextstring(temp, desc, &base));
+            mywindow->backgroundcolor[2] = atoi(findnextstring(temp, desc, &base));
+#ifdef DEBUG
+            mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [BACKGROUND] window \"%s\" has backgroundcolor (%i,%i,%i)\n", mywindow->name,
+                    mywindow->backgroundcolor[0],
+                    mywindow->backgroundcolor[1],
+                    mywindow->backgroundcolor[2]);
+#endif
+        }
+        else if(!strncmp(desc, "end", 3))
+        {
+            if(reachedendofwindow)
+            {
+#ifdef DEBUG
+                mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [END] of section\n");
+#endif
+            }
+            else
+            {
+                reachedendofwindow = 1;
+#ifdef DEBUG
+                mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [END] of window \"%s\"\n", mywindow->name);
+#endif
+            }
+        }
+        else if(!strncmp(desc, "font", 4))
+        {
+            unsigned int i;
+            int id = 0;
+            char temp[MAX_LINESIZE];
+            int base = counttonextchar(desc, '=')+1;
+            findnextstring(temp, desc, &base);
+            findnextstring(temp, desc, &base);
+            for (i=0; i<skin->fontcount; i++)
+                if(!strcmp(skin->fonts[i]->id, temp))
+                {
+                    id = i;
+                    break;
+                }
+            if(!id)
+            {
+                int base = counttonextchar(desc, '=') + 1;
+                findnextstring(temp, desc, &base);
+                id = skin->fontcount;
+                (skin->fontcount)++;
+                skin->fonts = realloc(skin->fonts, sizeof(font_t *) * skin->fontcount);
+                skin->fonts[id]=calloc(1, sizeof(font_t));
+                skin->fonts[id]->name = strdup(temp);
+                skin->fonts[id]->id = strdup(findnextstring(temp, desc, &base));
+            }
+#ifdef DEBUG
+            mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [FONT] id  \"%s\" name \"%s\"\n", skin->fonts[id]->name, skin->fonts[id]->id);
+#endif
+        }
+        else
+            skin->addwidget(skin, mywindow, desc);
+    }
+
+    free(desc);
+    free(filename);
+    free(tmp);
+    fclose(fp);
+    loadfonts(skin);
+    mp_msg(MSGT_GPLAYER, MSGL_V, "[SKIN LOAD] loaded skin \"%s\"\n", skin->skindir);
+    /* dumpwidgets(skin); */
+    return skin;
+}

Added: trunk/Gui/win32/skinload.h
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/skinload.h	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,213 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SKINLOAD_H
+#define _SKINLOAD_H
+
+typedef struct
+{
+    char *name;                  /* image name */
+    int size;                    /* image data size in bytes */
+    int width;                   /* image width */
+    int height;                  /* image height */
+    char *data;                  /* pointer to image data */
+} image;
+
+typedef struct
+{
+    char c;
+    int x;
+    int y;
+    int width;
+    int height;
+} char_t;
+
+typedef struct
+{
+    char *name;
+    char *id;
+    image *image;
+    unsigned int charcount;
+    char_t **chars;
+} font_t;
+
+typedef struct
+{
+    int id;                         /* widget id */
+    int type;                       /* widget type */
+    int window;                     /* the window it belongs to */
+    // ---
+    int x, y;                       /* x and y position the button */
+    int wx, wy;                     /* x and y postion of the widget */
+    int width, height;              /* width and height of the button */
+    int wwidth, wheight;            /* width and height of the widget */
+    // ---
+    // ---
+    int msg, msg2;
+    int pressed, tmp;
+    int key, key2;
+    int phases;
+    float value;
+    image *bitmap[2];               /* Associated image(s) in imagepool */
+    // ---
+    font_t *font;
+    int length;
+    int align;
+    char *label;
+    // ---
+    int event;
+} widget;
+
+typedef struct
+{
+    char *name;
+    int decoration;
+    int type;
+    widget *base;
+    int backgroundcolor[3];
+    void *priv;
+} window;
+
+typedef struct skin_t skin_t;
+struct skin_t
+{
+    char *skindir;
+    unsigned int widgetcount;       /* number of widgets */
+    unsigned int lastusedid;        /* which widget id was used last */
+    widget **widgets;               /* widget handle */
+    unsigned int imagecount;        /* number of images */
+    image **images;                 /* image handle */
+    int desktopbpp;                 /* image format of those images */
+    unsigned int fontcount;
+    font_t **fonts;
+
+    unsigned int windowcount;       /* number of windows */
+    window **windows;
+    void (*freeskin)(skin_t* skin);
+    void (*addwidget)(skin_t *skin, window *win, const char *desc);
+    void (*removewidget)(skin_t *skin, int id);
+    char *(*geteventname)(int event);
+    image *(*pngRead)(skin_t *skin, unsigned char *fname);
+};
+
+extern skin_t *loadskin(char *skindir, int desktopbpp);
+
+// --- Widget types ---
+
+#define tyBase          1
+#define tyButton        2
+#define tyHpotmeter     3
+#define tyVpotmeter     4
+#define tyPotmeter      5
+#define tyMenu          6
+#define tySlabel        7
+#define tyDlabel        8
+
+// --- Window types ---
+
+#define wiMain          1
+#define wiSub           2
+#define wiMenu          3
+#define wiPlaybar       4
+
+// --- User events ------
+
+#define evNone              0
+#define evPlay              1
+#define evStop              2
+#define evPause             3
+#define evPrev              6
+#define evNext              7
+#define evLoad              8
+#define evEqualizer         9
+#define evPlayList          10
+#define evIconify           11
+#define evAbout             12
+#define evLoadPlay          13
+#define evPreferences       14
+#define evSkinBrowser       15
+#define evPlaySwitchToPause 16
+#define evPauseSwitchToPlay 17
+
+#define evBackward10sec     18
+#define evForward10sec      19
+#define evBackward1min      20
+#define evForward1min       21
+#define evBackward10min     22
+#define evForward10min      23
+
+#define evNormalSize        24
+#define evDoubleSize        25
+#define evFullScreen        26
+
+#define evSetMoviePosition  27
+#define evSetVolume         28
+#define evSetBalance        29
+#define evMute              30
+
+#define evIncVolume         31
+#define evDecVolume         32
+#define evIncAudioBufDelay  33
+#define evDecAudioBufDelay  34
+#define evIncBalance        35
+#define evDecBalance        36
+
+#define evHelp              37
+
+#define evLoadSubtitle      38
+#define evDropSubtitle      43
+#define evPlayDVD           39
+#define evPlayVCD           40
+#define evPlayNetwork       41
+#define evLoadAudioFile     42
+#define evSetAspect         44
+#define evSetAudio          45
+#define evSetVideo          46
+#define evDropFile          47
+#define evPlayCD            48
+
+#define evExit              1000
+
+// --- General events ---
+
+#define evFileLoaded      5000
+#define evHideMouseCursor 5001
+#define evMessageBox      5002
+#define evGeneralTimer    5003
+#define evGtkIsOk         5004
+#define evShowPopUpMenu   5005
+#define evHidePopUpMenu   5006
+#define evSetDVDAudio     5007
+#define evSetDVDSubtitle  5008
+#define evSetDVDTitle     5009
+#define evSetDVDChapter   5010
+#define evSubtitleLoaded  5011
+#define evSetVCDTrack     5012
+#define evSetURL          5013
+
+#define evFName           7000
+#define evMovieTime       7001
+#define evRedraw          7002
+#define evHideWindow      7003
+#define evShowWindow      7004
+#define evFirstLoad       7005
+
+#endif

Added: trunk/Gui/win32/widgetrender.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/widgetrender.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,350 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <windows.h>
+#include <interface.h>
+#include "gui.h"
+
+extern char *codecname;
+#define MAX_LABELSIZE 250
+
+static void render(int bitsperpixel, image *dst, image *src, int x, int y, int sx, int sy, int sw, int sh, int transparent)
+{
+    int i;
+    int bpp = bitsperpixel / 8;
+    int offset = (dst->width * bpp * y) + (x * bpp);
+    int soffset = (src->width * bpp * sy) + (sx * bpp);
+
+    for(i=0; i<sh; i++)
+    {
+        int c;
+        for(c=0; c < (sw * bpp); c += bpp)
+        {
+            if(bpp == 2)
+            {
+                if(!transparent || (((src->data + soffset + (i * src->width * bpp) + c)[0] != 0x1f)
+                    && ((src->data + soffset + (i * src->width * bpp) + c)[1] != 0x7c)))
+                    memcpy(dst->data + offset + c, src->data + soffset + (i * src->width * bpp) + c, bpp);
+            }
+            else if(bpp > 2)
+            {
+                if(!transparent || *((unsigned int *) (src->data + soffset + (i * src->width * bpp) + c)) != 0x00ff00ff)
+                    memcpy(dst->data + offset + c, src->data + soffset + (i * src->width * bpp) + c, bpp);
+            }
+        }
+        offset += (dst->width * bpp);
+    }
+}
+
+static image *find_background(skin_t *skin, widget *item)
+{
+    unsigned int i;
+    for (i=0; i < skin->windowcount; i++)
+        if(skin->windows[i]->type == item->window)
+            return skin->windows[i]->base->bitmap[0];
+    return NULL;
+}
+
+/******************************************************************/
+/*                      FONT related functions                    */
+/******************************************************************/
+
+/* returns the pos of s2 inside s1 or -1 if  s1 doesn't contain s2 */
+static int strpos(char *s1, const char* s2)
+{
+    unsigned int i, x;
+    for (i=0; i < strlen(s1); i++)
+    {
+        if(s1[i] == s2[0])
+        {
+            if(strlen(s1 + i) >= strlen(s2))
+            {
+                for (x=0; x <strlen(s2); x++)
+                    if(s1[i + x] != s2[x]) break;
+                if(x == strlen(s2)) return i;
+            }
+        }
+    }
+    return -1;
+}
+
+/* replaces all occurences of what in dest with format */
+static void stringreplace(char *dest, const char *what, const char *format, ... )
+{
+    char tmp[MAX_LABELSIZE];
+    int offset=0;
+    va_list va;
+    va_start(va, format);
+    vsnprintf(tmp, MAX_LABELSIZE, format, va);
+    va_end(va);
+    /* no search string == replace the entire string */
+    if(!what)
+    {
+        memcpy(dest, tmp, strlen(tmp));
+        dest[strlen(tmp)] = 0;
+        return;
+    }
+    while((offset = strpos(dest, what)) != -1)
+    {
+        memmove(dest + offset + strlen(tmp), dest + offset + strlen(what), strlen(dest + offset + strlen(what)) + 1);
+        memcpy(dest + offset, tmp, strlen(tmp));
+    }
+}
+
+/* replaces the chars with special meaning with the associated data from the player info struct */
+static char *generatetextfromlabel(widget *item)
+{
+    char *text = malloc(MAX_LABELSIZE);
+    char tmp[MAX_LABELSIZE];
+    unsigned int i;
+    if(!item)
+    {
+        free(text);
+        return NULL;
+    }
+    strcpy(text, item->label);
+    if(item->type == tySlabel) return text;
+    stringreplace(text, "$1", "%.2i:%.2i:%.2i", guiIntfStruct.TimeSec / 3600,
+                 (guiIntfStruct.TimeSec / 60) % 60, guiIntfStruct.TimeSec % 60);
+    stringreplace(text, "$2", "%.4i:%.2i", guiIntfStruct.TimeSec / 60, guiIntfStruct.TimeSec % 60);
+    stringreplace(text, "$3", "%.2i", guiIntfStruct.TimeSec / 3600);
+    stringreplace(text, "$4", "%.2i", (guiIntfStruct.TimeSec / 60) % 60);
+    stringreplace(text, "$5", "%.2i", guiIntfStruct.TimeSec % 60);
+    stringreplace(text, "$6", "%.2i:%.2i:%.2i", guiIntfStruct.LengthInSec / 3600,
+                 (guiIntfStruct.LengthInSec / 60) % 60, guiIntfStruct.LengthInSec % 60);
+    stringreplace(text, "$7", "%.4i:%.2i", guiIntfStruct.LengthInSec / 60, guiIntfStruct.LengthInSec % 60);
+    stringreplace(text, "$8", "%i:%.2i:%.2i", guiIntfStruct.TimeSec / 3600,
+                 (guiIntfStruct.TimeSec / 60) % 60, guiIntfStruct.TimeSec % 60);
+    stringreplace(text, "$v", "%3.2f", guiIntfStruct.Volume);
+    stringreplace(text, "$V", "%3.1f", guiIntfStruct.Volume);
+    stringreplace(text, "$b", "%3.2f", guiIntfStruct.Balance);
+    stringreplace(text, "$B", "%3.1f", guiIntfStruct.Balance);
+    stringreplace(text, "$t", "%.2i", guiIntfStruct.Track);
+    stringreplace(text, "$o", "%s", guiIntfStruct.Filename);
+    stringreplace(text, "$x", "%i", guiIntfStruct.MovieWidth);
+    stringreplace(text, "$y", "%i", guiIntfStruct.MovieHeight);
+    stringreplace(text, "$C", "%s", guiIntfStruct.sh_video ? codecname : "");
+    stringreplace(text, "$$", "$");
+
+    if(!strcmp(text, "$p") || !strcmp(text, "$s") || !strcmp(text, "$e"))
+    {
+        if(guiIntfStruct.Playing == 0) stringreplace(text, NULL, "s");
+        else if(guiIntfStruct.Playing == 1) stringreplace(text, NULL, "p");
+        else if(guiIntfStruct.Playing == 2) stringreplace(text, NULL, "e");
+    }
+
+    if(guiIntfStruct.AudioType == 0) stringreplace(text, "$a", "n");
+    else if(guiIntfStruct.AudioType == 1) stringreplace(text, "$a", "m");
+    else stringreplace(text, "$a", "t");
+
+    if(guiIntfStruct.StreamType == 0)
+        stringreplace(text, "$T", "f");
+#ifdef USE_DVDREAD
+    else if(guiIntfStruct.StreamType == STREAMTYPE_DVD || guiIntfStruct.StreamType == STREAMTYPE_DVDNAV)
+        stringreplace(text, "$T", "d");
+#endif
+    else stringreplace(text, "$T", "u");
+
+    if(guiIntfStruct.Filename)
+    {
+        for (i=0; i<strlen(guiIntfStruct.Filename); i++)
+            tmp[i] = tolower(guiIntfStruct.Filename[i]);
+        stringreplace(text, "$f", tmp);
+
+        for (i=0; i<strlen(guiIntfStruct.Filename); i++)
+            tmp[i] = toupper(guiIntfStruct.Filename[i]);
+        stringreplace(text, "$F", tmp);
+    }
+
+    return text;
+}
+
+/* cuts text to buflen scrolling from right to left */
+static void scrolltext(char *text, unsigned int buflen, float *value)
+{
+    char *buffer = (char *) malloc(buflen + 1);
+    unsigned int x,i;
+    if(*value < buflen) x = 0;
+    else x = *value - buflen;
+    memset(buffer, ' ', buflen);
+    for (i = (*value>=buflen) ? 0 : buflen - *value; i<buflen; i++)
+    {
+        if(x < strlen(text))
+            buffer[i] = text[x];
+        x++;
+    }
+    buffer[buflen] = 0;
+    *value += 1.0f;
+    if(*value >= strlen(text) + buflen) *value = 0.0f;
+    strcpy(text, buffer);
+    free(buffer);
+}
+
+/* updates all dlabels and slabels */
+void renderinfobox(skin_t *skin, window_priv_t *priv)
+{
+    unsigned int i;
+    if (!priv) return;
+
+    /* repaint the area behind the text*/
+    /* we have to do this for all labels here, because they may overlap in buggy skins ;( */
+
+    for (i=0; i<skin->widgetcount; i++)
+        if((skin->widgets[i]->type == tyDlabel) || (skin->widgets[i]->type == tySlabel))
+        {
+            if(skin->widgets[i]->window == priv->type)
+                render(skin->desktopbpp,
+                       &priv->img,
+                       find_background(skin, skin->widgets[i]),
+                       skin->widgets[i]->x,
+                       skin->widgets[i]->y,
+                       skin->widgets[i]->x,
+                       skin->widgets[i]->y,
+                       skin->widgets[i]->length,
+                       skin->widgets[i]->font->chars[0]->height,
+                       1);
+        }
+
+    /* load all slabels and dlabels */
+    for (i=0; i<skin->widgetcount; i++)
+    {
+        widget *item = skin->widgets[i];
+        if(item->window != priv->type) continue;
+        if((i == skin->widgetcount) || (item->type == tyDlabel) || (item->type == tySlabel))
+        {
+            char *text = generatetextfromlabel(item);
+            unsigned int current, c;
+            int offset = 0;
+            unsigned int textlen;
+            if(!text) continue;
+            textlen = strlen(text);
+
+            /* render(win, win->background, gui->skin->widgets[i]->x, gui->skin->widgets[i]->y,
+                      gui->skin->widgets[i]->x, gui->skin->widgets[i]->y,
+                      gui->skin->widgets[i]->length, gui->skin->widgets[i]->font->chars[0]->height,1); */
+
+            /* calculate text size */
+            for (current=0; current<textlen; current++)
+            {
+                for (c=0; c<item->font->charcount; c++)
+                    if(item->font->chars[c]->c == text[current])
+                    {
+                        offset += item->font->chars[c]->width;
+                        break;
+                    }
+            }
+
+            /* labels can be scrolled if they are to big */
+            if((item->type == tyDlabel) && (item->length < offset))
+            {
+                int tomuch = (offset - item->length) / (offset /textlen);
+                scrolltext(text, textlen - tomuch - 1, &skin->widgets[i]->value);
+                textlen = strlen(text);
+            }
+
+            /* align the text */
+            if(item->align == 1)
+                offset = (item->length-offset) / 2;
+            else if(item->align == 2)
+                offset = item->length-offset;
+            else
+                offset = 0;
+
+            if(offset < 0) offset = 0;
+
+            /* render the text */
+            for (current=0; current<textlen; current++)
+            {
+                for (c=0; c<item->font->charcount; c++)
+                {
+                    char_t *cchar = item->font->chars[c];
+                    if(cchar->c == *(text + current))
+                    {
+                        render(skin->desktopbpp,
+                               &priv->img,
+                               item->font->image,
+                               item->x + offset,
+                               item->y,
+                               cchar->x,
+                               cchar->y,
+                               (cchar->width + offset > item->length) ? item->length - offset : cchar->width,
+                               cchar->height,
+                               1);
+                        offset += cchar->width;
+                    break;
+                    }
+                }
+            }
+            free(text);
+        }
+    }
+}
+
+/******************************************************************/
+/*                   WIDGET related functions                     */
+/******************************************************************/
+
+void renderwidget(skin_t *skin, image *dest, widget *item, int state)
+{
+    if(!dest) return;
+    image *img = NULL;
+    int height;
+    int y;
+    if((item->type == tyButton) || (item->type == tyHpotmeter) || (item->type == tyPotmeter))
+        img = item->bitmap[0];
+
+    if(!img) return;
+
+    y = item->y;
+    if(item->type == tyPotmeter)
+    {
+        height = img->height / item->phases;
+        y =  height * (int)(item->value * item->phases / 100);
+        if(y > img->height-height)
+            y = img->height - height;
+    }
+    else
+    {
+        height = img->height / 3;
+        y = state * height;
+    }
+
+    /* redraw background */
+    if(item->type == tyButton)
+        render(skin->desktopbpp, dest, find_background(skin,item), item->x, item->y, item->x, item->y, img->width, height, 1);
+
+    if((item->type == tyHpotmeter) || (item->type == tyPotmeter))
+    {
+        /* repaint the area behind the slider */
+        render(skin->desktopbpp, dest, find_background(skin, item), item->wx, item->wy, item->wx, item->wy, item->wwidth, item->height, 1);
+        item->x = item->value * (item->wwidth-item->width) / 100 + item->wx;
+        if((item->x + item->width) > (item->wx + item->wwidth))
+            item->x = item->wx + item->wwidth - item->width;
+        if(item->x < item->wx)
+            item->x = item->wx;
+        /* workaround for blue */
+        if(item->type == tyHpotmeter)
+            height = (item->height < img->height / 3) ? item->height : img->height / 3;
+    }
+    render(skin->desktopbpp, dest, img, item->x, item->y, 0, y, img->width, height, 1);
+}

Added: trunk/Gui/win32/wincfg.c
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/wincfg.c	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,143 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <mp_msg.h>
+#include <help_mp.h>
+
+#include <m_config.h>
+#include <m_option.h>
+#include <libvo/video_out.h>
+#include <mixer.h>
+#include "wincfg.h"
+#include "interface.h"
+
+/* params */
+int   gtkAONorm = 0;
+int   gtkAOExtraStereo = 0;
+float gtkAOExtraStereoMul = 1.0;
+int   gtkCacheOn = 0;
+int   gtkCacheSize = 2048;
+int   gtkAutoSyncOn = 0;
+int   gtkAutoSync = 0;
+
+int sub_window = 0;
+int console = 0;
+
+int gui_save_pos = 1;
+int gui_main_pos_x = -2;
+int gui_main_pos_y = -2;
+int gui_sub_pos_x = -1;
+int gui_sub_pos_y = -1;
+
+/* External functions */
+extern int frame_dropping;
+extern char *proc_priority;
+extern int m_config_parse_config_file(m_config_t *config, char *conffile);
+
+static m_config_t *gui_conf;
+static m_option_t gui_opts[] =
+{
+    {   "priority", &proc_priority, CONF_TYPE_STRING, 0, 0, 0, NULL},
+    {   "vo_driver", &video_driver_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL },
+    {   "v_framedrop", &frame_dropping, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL },
+    {   "vo_doublebuffering", &vo_doublebuffering, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+    {   "vo_direct_render", &vo_directrendering, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+    {   "ao_driver", &audio_driver_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL },
+    {   "ao_volnorm", &gtkAONorm, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+    {   "softvol", &soft_vol, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+    {   "ao_extra_stereo", &gtkAOExtraStereo, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+    {   "ao_extra_stereo_coefficient", &gtkAOExtraStereoMul, CONF_TYPE_FLOAT, CONF_RANGE, -10, 10, NULL },
+    {   "delay", &audio_delay, CONF_TYPE_FLOAT, CONF_RANGE, -100.0, 100.0, NULL},
+    {   "dvd_device", &dvd_device, CONF_TYPE_STRING, 0, 0, 0, NULL },
+    {   "cdrom_device", &cdrom_device, CONF_TYPE_STRING, 0, 0, 0, NULL },
+    {   "osd_level", &osd_level, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL },
+    {   "cache", &gtkCacheOn, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+    {   "cache_size", &gtkCacheSize, CONF_TYPE_INT, CONF_RANGE, -1, 65535, NULL },
+    {   "autosync", &gtkAutoSyncOn, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+    {   "autosync_size", &gtkAutoSync, CONF_TYPE_INT, CONF_RANGE, 0, 10000, NULL },
+    {   "gui_skin", &skinName, CONF_TYPE_STRING, 0, 0, 0, NULL },
+    {   "gui_main_pos_x", &gui_main_pos_x, CONF_TYPE_INT, 0, 0, 0, NULL },
+    {   "gui_main_pos_y", &gui_main_pos_y, CONF_TYPE_INT, 0, 0, 0, NULL },
+    {   "gui_sub_pos_x", &gui_sub_pos_x, CONF_TYPE_INT, 0, 0, 0, NULL },
+    {   "gui_sub_pos_y", &gui_sub_pos_y, CONF_TYPE_INT, 0, 0, 0, NULL },
+    {   "sub_window", &sub_window, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+    {   "console", &console, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+    {   NULL, NULL, 0, 0, 0, 0, NULL }
+};
+
+char *gfgets(char *str, int size, FILE *f)
+{
+    char *s = fgets(str, size, f);
+    char c;
+    if(s)
+    {
+        c = s[strlen(s) - 1];
+        if ((c == '\n') || (c == '\r'))
+            s[strlen(s) - 1]=0;
+        c = s[strlen(s) - 1];
+        if ((c == '\n') || (c == '\r'))
+            s[strlen(s) - 1]=0;
+    }
+    return s;
+}
+
+int cfg_read(void)
+{
+    char *cfg = get_path("gui.conf");
+
+    /* read configuration */
+    mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] [cfg] reading config file: %s\n", cfg);
+    gui_conf = m_config_new();
+    m_config_register_options(gui_conf, gui_opts);
+    if (m_config_parse_config_file(gui_conf, cfg) < 0)
+        mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_ConfigFileError);
+    free(cfg);
+    return 0;
+}
+
+int cfg_write(void)
+{
+    char *cfg = get_path("gui.conf");
+    FILE *f;
+    int i;
+
+    /* save configuration */
+    if ((f = fopen(cfg, "wt+")))
+    {
+        for (i=0; gui_opts[i].name; i++)
+        {
+            char *v = m_option_print(&gui_opts[i], gui_opts[i].p);
+            if(v)
+            {
+                fprintf(f, "%s = \"%s\"\n", gui_opts[i].name, v);
+                free(v);
+            }
+            else if((int) v == -1)
+                mp_msg(MSGT_GPLAYER, MSGL_WARN, MSGTR_UnableToSaveOption, gui_opts[i].name);
+        }
+        fclose(f);
+    }
+    free(cfg);
+    return 0;
+}

Added: trunk/Gui/win32/wincfg.h
==============================================================================
--- (empty file)
+++ trunk/Gui/win32/wincfg.h	Thu Jul  6 04:07:03 2006
@@ -0,0 +1,38 @@
+/*
+  MPlayer Gui for win32
+  Copyright (c) 2003 Sascha Sommer <saschasommer at freenet.de>
+  Copyright (c) 2006 Erik Augustson <erik_27can at yahoo.com>
+  Copyright (c) 2006 Gianluigi Tiesi <sherpya at netfarm.it>
+
+  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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _WINCFG_H
+#define _WINCFG_H
+
+extern char *skinName;
+extern int sub_window;
+extern int console;
+
+extern int gui_save_pos;
+extern int gui_main_pos_x;
+extern int gui_main_pos_y;
+extern int gui_sub_pos_x;
+extern int gui_sub_pos_y;
+
+extern int cfg_read(void);
+extern int cfg_write(void);
+
+#endif



More information about the MPlayer-cvslog mailing list