[Scummvm-git-logs] scummvm master -> 7552b0c008b6a5ca3e128ba2691f7319dc3b2349

criezy criezy at scummvm.org
Sun Dec 16 11:48:24 CET 2018


This automated email contains information about 12 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
952b12311c BACKENDS: Add base support for system dialogs
5fce1ae464 BACKENDS: Move OSX file browser into backend
fbc9c7d371 BACKENDS: Hook GUI browser to DialogManager
28e4d7bb43 OSX: Integrate system file browser into DialogManager
2f2555f728 WIN32: Move utility functions to a common wrapper
61070f6ce0 WIN32: Add DialogManager with system file browser support
7bff9176d5 WIN32: Fix incorrect Windows version check
fc504996d3 GUI: Allow user to opt between GUI browser and native browser
93695a9dcf WIN32: Fix dialog compilation under MinGW
9aef3dd8a7 WIN32: Respect browser_lastpath setting
ac957852c8 I18N: Update POTFILES
7552b0c008 GUI: Store title String instead of unsafe pointer


Commit: 952b12311cfbdc48ddae0dbc7b960cd17c8e2b1e
    https://github.com/scummvm/scummvm/commit/952b12311cfbdc48ddae0dbc7b960cd17c8e2b1e
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
BACKENDS: Add base support for system dialogs

Changed paths:
  A common/dialogs.h
    common/system.cpp
    common/system.h
    configure
    devtools/create_project/create_project.cpp


diff --git a/common/dialogs.h b/common/dialogs.h
new file mode 100644
index 0000000..70c4837
--- /dev/null
+++ b/common/dialogs.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef COMMON_DIALOG_MANAGER_H
+#define COMMON_DIALOG_MANAGER_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+
+#if defined(USE_SYSDIALOGS)
+
+namespace Common {
+
+/**
+ * The DialogManager allows GUI code to interact with native system dialogs.
+ */
+class DialogManager {
+public:
+	/**
+	 * Values representing the user response to a dialog
+	 */
+	enum DialogResult {
+		kDialogError = -1,	///< Dialog couldn't be displayed
+		kDialogCancel = 0,	///< User cancelled the dialog (Cancel/No/Close buttons)
+		kDialogOk = 1		///< User confirmed the dialog (OK/Yes buttons)
+	};
+
+	DialogManager() {}
+	virtual ~DialogManager() {}
+
+	/**
+	 * Displays a dialog for selecting a file or folder.
+	 */
+	virtual DialogResult showFileBrowser() { return kDialogError; }
+};
+
+} // End of namespace Common
+
+#endif
+
+#endif // COMMON_DIALOG_MANAGER_H
diff --git a/common/system.cpp b/common/system.cpp
index c8023c8..93cf98c 100644
--- a/common/system.cpp
+++ b/common/system.cpp
@@ -29,6 +29,7 @@
 #include "common/str.h"
 #include "common/taskbar.h"
 #include "common/updates.h"
+#include "common/dialogs.h"
 #include "common/textconsole.h"
 
 #include "backends/audiocd/default/default-audiocd.h"
@@ -48,6 +49,9 @@ OSystem::OSystem() {
 #if defined(USE_UPDATES)
 	_updateManager = nullptr;
 #endif
+#if defined(USE_SYSDIALOGS)
+	_dialogManager = nullptr;
+#endif
 	_fsFactory = nullptr;
 	_backendInitialized = false;
 }
@@ -72,6 +76,11 @@ OSystem::~OSystem() {
 	_updateManager = nullptr;
 #endif
 
+#if defined(USE_SYSDIALOGS)
+	delete _dialogManager;
+	_dialogManager = nullptr;
+#endif
+
 	delete _savefileManager;
 	_savefileManager = nullptr;
 
diff --git a/common/system.h b/common/system.h
index 405d6a9..01d436e 100644
--- a/common/system.h
+++ b/common/system.h
@@ -49,6 +49,9 @@ class TaskbarManager;
 #if defined(USE_UPDATES)
 class UpdateManager;
 #endif
+#if defined(USE_SYSDIALOGS)
+class DialogManager;
+#endif
 class TimerManager;
 class SeekableReadStream;
 class WriteStream;
@@ -179,6 +182,15 @@ protected:
 	Common::UpdateManager *_updateManager;
 #endif
 
+#if defined(USE_SYSDIALOGS)
+	/**
+	 * No default value is provided for _dialogManager by OSystem.
+	 *
+	 * @note _dialogManager is deleted by the OSystem destructor.
+	 */
+	Common::DialogManager *_dialogManager;
+#endif
+
 	/**
 	 * No default value is provided for _fsFactory by OSystem.
 	 *
@@ -1305,6 +1317,17 @@ public:
 	}
 #endif
 
+#if defined(USE_SYSDIALOGS)
+	/**
+	 * Returns the DialogManager, used to handle system dialogs.
+	 *
+	 * @return the DialogManager for the current architecture
+	 */
+	virtual Common::DialogManager *getDialogManager() {
+		return _dialogManager;
+	}
+#endif
+
 	/**
 	 * Returns the FilesystemFactory object, depending on the current architecture.
 	 *
diff --git a/configure b/configure
index 7a06616..44c7c09 100755
--- a/configure
+++ b/configure
@@ -163,6 +163,7 @@ _freetype2=auto
 _taskbar=auto
 _updates=no
 _libunity=auto
+_dialogs=auto
 # Default option behavior yes/no
 _debug_build=auto
 _release_build=auto
@@ -1003,6 +1004,7 @@ Optional Features:
   --disable-translation    don't build support for translated messages
   --disable-taskbar        don't build support for taskbar and launcher integration
   --disable-cloud          don't build cloud support
+  --disable-system-dialogs don't build support for system dialogs
   --enable-vkeybd          build virtual keyboard support
   --enable-keymapper       build key mapper support
   --enable-eventrecorder   enable event recording functionality
@@ -1197,6 +1199,8 @@ for ac_option in $@; do
 	--disable-freetype2)      _freetype2=no   ;;
 	--enable-taskbar)         _taskbar=yes    ;;
 	--disable-taskbar)        _taskbar=no     ;;
+	--enable-system-dialogs)  _dialogs=yes    ;;
+	--disable-system-dialogs) _dialogs=no     ;;
 	--enable-sdlnet)          _sdlnet=yes     ;;
 	--disable-sdlnet)         _sdlnet=no      ;;
 	--enable-libcurl)         _libcurl=yes     ;;
@@ -5139,6 +5143,31 @@ fi
 define_in_config_if_yes $_taskbar 'USE_TASKBAR'
 
 #
+# Check whether to build system dialogs support
+#
+echo_n "Building system dialogs support... "
+if test "$_dialogs" = "no"; then
+	echo "no"
+else
+	case $_host_os in
+	mingw*)
+		append_var LIBS "-lole32 -luuid"
+		echo "win32"
+		_dialogs=yes
+		;;
+	darwin*)
+		echo "osx"
+		_dialogs=yes
+		;;
+	*)
+		echo "no"
+		_dialogs=no
+		;;
+	esac
+fi
+define_in_config_if_yes $_dialogs 'USE_SYSDIALOGS'
+
+#
 # Check whether to build Bink video support
 #
 echo_n "Building Bink video support... "
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index 3dab08a..dd7eeba 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -1063,6 +1063,7 @@ const Feature s_features[] = {
 	{       "keymapper",     "ENABLE_KEYMAPPER",         "", false, "Keymapper support"},
 	{   "eventrecorder", "ENABLE_EVENTRECORDER",         "", false, "Event recorder support"},
 	{         "updates",          "USE_UPDATES",         "", false, "Updates support"},
+	{         "dialogs",       "USE_SYSDIALOGS",         "", true,  "System dialogs support"},
 	{      "langdetect",       "USE_DETECTLANG",         "", true,  "System language detection support" } // This feature actually depends on "translation", there
 	                                                                                                      // is just no current way of properly detecting this...
 };


Commit: 5fce1ae46400576c7d65a9ea63ff1c00952cf71c
    https://github.com/scummvm/scummvm/commit/5fce1ae46400576c7d65a9ea63ff1c00952cf71c
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
BACKENDS: Move OSX file browser into backend

Changed paths:
  A backends/dialogs/macosx/macosx-dialogs.mm
  R gui/browser_osx.mm
    backends/module.mk
    devtools/create_project/xcode.cpp
    gui/module.mk


diff --git a/backends/dialogs/macosx/macosx-dialogs.mm b/backends/dialogs/macosx/macosx-dialogs.mm
new file mode 100644
index 0000000..ffb64ee
--- /dev/null
+++ b/backends/dialogs/macosx/macosx-dialogs.mm
@@ -0,0 +1,215 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "gui/browser.h"
+
+#include "common/config-manager.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/algorithm.h"
+#include "common/translation.h"
+
+#include <AppKit/NSNibDeclarations.h>
+#include <AppKit/NSOpenPanel.h>
+#include <AppKit/NSApplication.h>
+#include <AppKit/NSButton.h>
+#include <Foundation/NSString.h>
+#include <Foundation/NSURL.h>
+#include <Foundation/NSAutoreleasePool.h>
+
+
+ at interface BrowserDialogPresenter : NSObject {
+ at public
+	NSURL *_url;
+ at private
+	NSOpenPanel *_panel;
+}
+- (id) init;
+- (void) dealloc;
+- (void) showOpenPanel: (NSOpenPanel*) panel;
+- (IBAction) showHiddenFiles : (id) sender;
+ at end
+
+ at implementation BrowserDialogPresenter
+
+- (id) init {
+	self = [super init];
+	_url = 0;
+	_panel = 0;
+	return self;
+}
+
+- (void) dealloc {
+	[_url release];
+	[super dealloc];
+}
+
+- (void) showOpenPanel: (NSOpenPanel*) panel {
+	_panel = panel;
+
+	NSButton *showHiddenFilesButton = 0;
+	if ([panel respondsToSelector:@selector(setShowsHiddenFiles:)]) {
+		showHiddenFilesButton = [[NSButton alloc] init];
+		[showHiddenFilesButton setButtonType:NSSwitchButton];
+
+#ifdef USE_TRANSLATION
+		CFStringRef encStr = CFStringCreateWithCString(NULL, TransMan.getCurrentCharset().c_str(), kCFStringEncodingASCII);
+		CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
+		CFRelease(encStr);
+#else
+		CFStringEncoding stringEncoding = kCFStringEncodingASCII;
+#endif
+		CFStringRef hiddenFilesString = CFStringCreateWithCString(0, _("Show hidden files"), stringEncoding);
+		[showHiddenFilesButton setTitle:(NSString*)hiddenFilesString];
+		CFRelease(hiddenFilesString);
+
+		[showHiddenFilesButton sizeToFit];
+		if (ConfMan.getBool("gui_browser_show_hidden", Common::ConfigManager::kApplicationDomain)) {
+			[showHiddenFilesButton setState:NSOnState];
+			[panel setShowsHiddenFiles: YES];
+		} else {
+			[showHiddenFilesButton setState:NSOffState];
+			[panel setShowsHiddenFiles: NO];
+		}
+		[panel setAccessoryView:showHiddenFilesButton];
+
+		[showHiddenFilesButton setTarget:self];
+		[showHiddenFilesButton setAction:@selector(showHiddenFiles:)];
+	}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= 1090
+	if ([panel runModal] == NSOKButton) {
+#else
+	if ([panel runModal] == NSModalResponseOK) {
+#endif
+		NSURL *url = [panel URL];
+		if ([url isFileURL]) {
+			_url = url;
+			[_url retain];
+		}
+	}
+
+	[showHiddenFilesButton release];
+	_panel = 0;
+}
+
+- (IBAction) showHiddenFiles : (id) sender {
+	if ([sender state] == NSOnState) {
+		[_panel setShowsHiddenFiles: YES];
+		ConfMan.setBool("gui_browser_show_hidden", true, Common::ConfigManager::kApplicationDomain);
+	} else {
+		[_panel setShowsHiddenFiles: NO];
+		ConfMan.setBool("gui_browser_show_hidden", false, Common::ConfigManager::kApplicationDomain);
+	}
+}
+
+ at end
+
+namespace GUI {
+
+BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
+	: Dialog("Browser") {
+
+	// remember whether this is a file browser or a directory browser.
+	_isDirBrowser = dirBrowser;
+
+	// Get current encoding
+#ifdef USE_TRANSLATION
+	CFStringRef encStr = CFStringCreateWithCString(NULL, TransMan.getCurrentCharset().c_str(), kCFStringEncodingASCII);
+	CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
+	CFRelease(encStr);
+#else
+	CFStringEncoding stringEncoding = kCFStringEncodingASCII;
+#endif
+
+	// Convert title to NSString
+	_titleRef = CFStringCreateWithCString(0, title, stringEncoding);
+
+	// Convert button text to NSString
+	_chooseRef = CFStringCreateWithCString(0, _("Choose"), stringEncoding);
+}
+
+BrowserDialog::~BrowserDialog() {
+	CFRelease(_titleRef);
+	CFRelease(_chooseRef);
+}
+
+int BrowserDialog::runModal() {
+	bool choiceMade = false;
+
+	// If in fullscreen mode, switch to windowed mode
+	bool wasFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
+	if (wasFullscreen) {
+		g_system->beginGFXTransaction();
+		g_system->setFeatureState(OSystem::kFeatureFullscreenMode, false);
+		g_system->endGFXTransaction();
+	}
+
+	// Temporarily show the real mouse
+	CGDisplayShowCursor(kCGDirectMainDisplay);
+
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+	NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];
+
+
+	NSOpenPanel *panel = [NSOpenPanel openPanel];
+	[panel setCanChooseFiles:!_isDirBrowser];
+	[panel setCanChooseDirectories:_isDirBrowser];
+	if (_isDirBrowser)
+		[panel setTreatsFilePackagesAsDirectories:true];
+	[panel setTitle:(NSString *)_titleRef];
+	[panel setPrompt:(NSString *)_chooseRef];
+
+	BrowserDialogPresenter* presenter = [[BrowserDialogPresenter alloc] init];
+	[presenter performSelectorOnMainThread:@selector(showOpenPanel:) withObject:panel waitUntilDone:YES];
+	if (presenter->_url) {
+		Common::String filename = [[presenter->_url path] UTF8String];
+		_choice = Common::FSNode(filename);
+		choiceMade = true;
+	}
+	[presenter release];
+
+	[pool release];
+	[keyWindow makeKeyAndOrderFront:nil];
+
+	// While the native macOS file browser is open, any input events (e.g. keypresses) are
+	// still received by the NSApplication. With SDL backend for example this results in the
+	// events beeing queued and processed after we return, thus dispatching events that were
+	// intended for the native file browser. For example: pressing Esc to cancel the native
+	// macOS file browser would cause the application to quit in addition to closing the
+	// file browser. To avoid this happening clear all pending events.
+	g_system->getEventManager()->getEventDispatcher()->clearEvents();
+
+	// If we were in fullscreen mode, switch back
+	if (wasFullscreen) {
+		g_system->beginGFXTransaction();
+		g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
+		g_system->endGFXTransaction();
+	}
+
+	return choiceMade;
+}
+
+} // End of namespace GUI
diff --git a/backends/module.mk b/backends/module.mk
index f7d6ad2..ad02481 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -179,6 +179,7 @@ endif
 ifdef MACOSX
 MODULE_OBJS += \
 	audiocd/macosx/macosx-audiocd.o \
+	dialogs/macosx/macosx-dialogs.o \
 	midi/coreaudio.o \
 	midi/coremidi.o \
 	updates/macosx/macosx-updates.o \
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index a04d250..ed6baf6 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -391,14 +391,6 @@ void XcodeProvider::writeFileListToProject(const FileNode &dir, std::ofstream &p
 		// for folders, we shouldn't add folders as file references, obviously.
 		if (node->children.empty()) {
 			group->addChildFile(node->name);
-
-			// HACK: Also add browser_osx.mm, since browser.cpp is added for
-			// iOS and browser_osx.mm for macOS, and create_project cannot
-			// deal with two competing exclusive ifdefs in module.mk going
-			// into one project
-			if (filePrefix.find("/gui/") == filePrefix.size() - 5 && node->name == "browser.cpp") {
-				group->addChildFile("browser_osx.mm");
-			}
 		}
 		// Process child nodes
 		if (!node->children.empty())
@@ -1121,11 +1113,6 @@ void XcodeProvider::setupAdditionalSources(std::string targetName, Property &fil
 	if (targetIsIOS(targetName)) {
 		const std::string absoluteCatalogPath = _projectRoot + "/dists/ios7/Images.xcassets";
 		ADD_SETTING_ORDER_NOVALUE(files, getHash(absoluteCatalogPath), "Image Asset Catalog", order++);
-	} else {
-		// HACK: browser_osx.mm needs to be added
-		const std::string browserPath = "gui/browser_osx.mm";
-		const std::string comment = "browser_osx.mm in Sources";
-		ADD_SETTING_ORDER_NOVALUE(files, getHash(browserPath), comment, order++);
 	}
 }
 
diff --git a/gui/browser_osx.mm b/gui/browser_osx.mm
deleted file mode 100644
index ffb64ee..0000000
--- a/gui/browser_osx.mm
+++ /dev/null
@@ -1,215 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// Disable symbol overrides so that we can use system headers
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
-#include "gui/browser.h"
-
-#include "common/config-manager.h"
-#include "common/system.h"
-#include "common/events.h"
-#include "common/algorithm.h"
-#include "common/translation.h"
-
-#include <AppKit/NSNibDeclarations.h>
-#include <AppKit/NSOpenPanel.h>
-#include <AppKit/NSApplication.h>
-#include <AppKit/NSButton.h>
-#include <Foundation/NSString.h>
-#include <Foundation/NSURL.h>
-#include <Foundation/NSAutoreleasePool.h>
-
-
- at interface BrowserDialogPresenter : NSObject {
- at public
-	NSURL *_url;
- at private
-	NSOpenPanel *_panel;
-}
-- (id) init;
-- (void) dealloc;
-- (void) showOpenPanel: (NSOpenPanel*) panel;
-- (IBAction) showHiddenFiles : (id) sender;
- at end
-
- at implementation BrowserDialogPresenter
-
-- (id) init {
-	self = [super init];
-	_url = 0;
-	_panel = 0;
-	return self;
-}
-
-- (void) dealloc {
-	[_url release];
-	[super dealloc];
-}
-
-- (void) showOpenPanel: (NSOpenPanel*) panel {
-	_panel = panel;
-
-	NSButton *showHiddenFilesButton = 0;
-	if ([panel respondsToSelector:@selector(setShowsHiddenFiles:)]) {
-		showHiddenFilesButton = [[NSButton alloc] init];
-		[showHiddenFilesButton setButtonType:NSSwitchButton];
-
-#ifdef USE_TRANSLATION
-		CFStringRef encStr = CFStringCreateWithCString(NULL, TransMan.getCurrentCharset().c_str(), kCFStringEncodingASCII);
-		CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
-		CFRelease(encStr);
-#else
-		CFStringEncoding stringEncoding = kCFStringEncodingASCII;
-#endif
-		CFStringRef hiddenFilesString = CFStringCreateWithCString(0, _("Show hidden files"), stringEncoding);
-		[showHiddenFilesButton setTitle:(NSString*)hiddenFilesString];
-		CFRelease(hiddenFilesString);
-
-		[showHiddenFilesButton sizeToFit];
-		if (ConfMan.getBool("gui_browser_show_hidden", Common::ConfigManager::kApplicationDomain)) {
-			[showHiddenFilesButton setState:NSOnState];
-			[panel setShowsHiddenFiles: YES];
-		} else {
-			[showHiddenFilesButton setState:NSOffState];
-			[panel setShowsHiddenFiles: NO];
-		}
-		[panel setAccessoryView:showHiddenFilesButton];
-
-		[showHiddenFilesButton setTarget:self];
-		[showHiddenFilesButton setAction:@selector(showHiddenFiles:)];
-	}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= 1090
-	if ([panel runModal] == NSOKButton) {
-#else
-	if ([panel runModal] == NSModalResponseOK) {
-#endif
-		NSURL *url = [panel URL];
-		if ([url isFileURL]) {
-			_url = url;
-			[_url retain];
-		}
-	}
-
-	[showHiddenFilesButton release];
-	_panel = 0;
-}
-
-- (IBAction) showHiddenFiles : (id) sender {
-	if ([sender state] == NSOnState) {
-		[_panel setShowsHiddenFiles: YES];
-		ConfMan.setBool("gui_browser_show_hidden", true, Common::ConfigManager::kApplicationDomain);
-	} else {
-		[_panel setShowsHiddenFiles: NO];
-		ConfMan.setBool("gui_browser_show_hidden", false, Common::ConfigManager::kApplicationDomain);
-	}
-}
-
- at end
-
-namespace GUI {
-
-BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
-	: Dialog("Browser") {
-
-	// remember whether this is a file browser or a directory browser.
-	_isDirBrowser = dirBrowser;
-
-	// Get current encoding
-#ifdef USE_TRANSLATION
-	CFStringRef encStr = CFStringCreateWithCString(NULL, TransMan.getCurrentCharset().c_str(), kCFStringEncodingASCII);
-	CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
-	CFRelease(encStr);
-#else
-	CFStringEncoding stringEncoding = kCFStringEncodingASCII;
-#endif
-
-	// Convert title to NSString
-	_titleRef = CFStringCreateWithCString(0, title, stringEncoding);
-
-	// Convert button text to NSString
-	_chooseRef = CFStringCreateWithCString(0, _("Choose"), stringEncoding);
-}
-
-BrowserDialog::~BrowserDialog() {
-	CFRelease(_titleRef);
-	CFRelease(_chooseRef);
-}
-
-int BrowserDialog::runModal() {
-	bool choiceMade = false;
-
-	// If in fullscreen mode, switch to windowed mode
-	bool wasFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
-	if (wasFullscreen) {
-		g_system->beginGFXTransaction();
-		g_system->setFeatureState(OSystem::kFeatureFullscreenMode, false);
-		g_system->endGFXTransaction();
-	}
-
-	// Temporarily show the real mouse
-	CGDisplayShowCursor(kCGDirectMainDisplay);
-
-	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-	NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];
-
-
-	NSOpenPanel *panel = [NSOpenPanel openPanel];
-	[panel setCanChooseFiles:!_isDirBrowser];
-	[panel setCanChooseDirectories:_isDirBrowser];
-	if (_isDirBrowser)
-		[panel setTreatsFilePackagesAsDirectories:true];
-	[panel setTitle:(NSString *)_titleRef];
-	[panel setPrompt:(NSString *)_chooseRef];
-
-	BrowserDialogPresenter* presenter = [[BrowserDialogPresenter alloc] init];
-	[presenter performSelectorOnMainThread:@selector(showOpenPanel:) withObject:panel waitUntilDone:YES];
-	if (presenter->_url) {
-		Common::String filename = [[presenter->_url path] UTF8String];
-		_choice = Common::FSNode(filename);
-		choiceMade = true;
-	}
-	[presenter release];
-
-	[pool release];
-	[keyWindow makeKeyAndOrderFront:nil];
-
-	// While the native macOS file browser is open, any input events (e.g. keypresses) are
-	// still received by the NSApplication. With SDL backend for example this results in the
-	// events beeing queued and processed after we return, thus dispatching events that were
-	// intended for the native file browser. For example: pressing Esc to cancel the native
-	// macOS file browser would cause the application to quit in addition to closing the
-	// file browser. To avoid this happening clear all pending events.
-	g_system->getEventManager()->getEventDispatcher()->clearEvents();
-
-	// If we were in fullscreen mode, switch back
-	if (wasFullscreen) {
-		g_system->beginGFXTransaction();
-		g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
-		g_system->endGFXTransaction();
-	}
-
-	return choiceMade;
-}
-
-} // End of namespace GUI
diff --git a/gui/module.mk b/gui/module.mk
index 0218e08..87f8dec 100644
--- a/gui/module.mk
+++ b/gui/module.mk
@@ -2,6 +2,7 @@ MODULE := gui
 
 MODULE_OBJS := \
 	about.o \
+	browser.o \
 	chooser.o \
 	console.o \
 	debugger.o \
@@ -38,19 +39,6 @@ MODULE_OBJS := \
 	widgets/scrollcontainer.o \
 	widgets/tab.o
 
-ifdef IPHONE
-MODULE_OBJS += \
-	browser.o
-else
-ifdef MACOSX
-MODULE_OBJS += \
-	browser_osx.o
-else
-MODULE_OBJS += \
-	browser.o
-endif
-endif
-
 ifdef USE_CLOUD
 ifdef USE_LIBCURL
 MODULE_OBJS += \


Commit: fbc9c7d371a4a123f3180ed54f26dfb5799fcc36
    https://github.com/scummvm/scummvm/commit/fbc9c7d371a4a123f3180ed54f26dfb5799fcc36
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
BACKENDS: Hook GUI browser to DialogManager

Changed paths:
    common/dialogs.h
    gui/browser.cpp
    gui/browser.h


diff --git a/common/dialogs.h b/common/dialogs.h
index 70c4837..76a5174 100644
--- a/common/dialogs.h
+++ b/common/dialogs.h
@@ -24,7 +24,7 @@
 #define COMMON_DIALOG_MANAGER_H
 
 #include "common/scummsys.h"
-#include "common/str.h"
+#include "common/fs.h"
 
 #if defined(USE_SYSDIALOGS)
 
@@ -48,9 +48,14 @@ public:
 	virtual ~DialogManager() {}
 
 	/**
-	 * Displays a dialog for selecting a file or folder.
+	 * Displays a dialog for selecting a file or folder in the filesystem.
+	 *
+	 * @param title The dialog title
+	 * @param choice The path selected by the user
+	 * @param isDirBrowser Restrict selection to directories
+	 * @return The dialog result
 	 */
-	virtual DialogResult showFileBrowser() { return kDialogError; }
+	virtual DialogResult showFileBrowser(const char *title, FSNode &choice, bool isDirBrowser = false) { return kDialogError; }
 };
 
 } // End of namespace Common
diff --git a/gui/browser.cpp b/gui/browser.cpp
index 264f3a6..f317680 100644
--- a/gui/browser.cpp
+++ b/gui/browser.cpp
@@ -28,6 +28,9 @@
 #include "common/config-manager.h"
 #include "common/system.h"
 #include "common/algorithm.h"
+#if defined(USE_SYSDIALOGS)
+#include "common/dialogs.h"
+#endif
 
 #include "common/translation.h"
 
@@ -49,6 +52,7 @@ enum {
 BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
 	: Dialog("Browser") {
 
+	_title = title;
 	_isDirBrowser = dirBrowser;
 	_fileList = NULL;
 	_currentPath = NULL;
@@ -79,6 +83,21 @@ BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
 	new ButtonWidget(this, "Browser.Choose", _("Choose"), 0, kChooseCmd);
 }
 
+int BrowserDialog::runModal() {
+#if defined(USE_SYSDIALOGS)
+	// Try to use the backend browser
+	Common::DialogManager *dialogManager = g_system->getDialogManager();
+	if (dialogManager) {
+		Common::DialogManager::DialogResult result = dialogManager->showFileBrowser(_title, _choice, _isDirBrowser);
+		if (result != Common::DialogManager::kDialogError) {
+			return result;
+		}
+	}
+#endif
+	// If all else fails, use the GUI browser
+	return Dialog::runModal();
+}
+
 void BrowserDialog::open() {
 	// Call super implementation
 	Dialog::open();
diff --git a/gui/browser.h b/gui/browser.h
index 557563e..2ef9a9c 100644
--- a/gui/browser.h
+++ b/gui/browser.h
@@ -37,35 +37,26 @@ class BrowserDialog : public Dialog {
 public:
 	BrowserDialog(const char *title, bool dirBrowser);
 
-#ifdef MACOSX
-	~BrowserDialog();
 	virtual int runModal();
-#else
 	virtual void open();
-
 	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
-#endif
 
 	const Common::FSNode	&getResult() { return _choice; }
 
 protected:
-#ifdef MACOSX
-	const void *_titleRef;
-	const void *_chooseRef;
-#else
 	ListWidget		*_fileList;
 	EditTextWidget	*_currentPath;
 	Common::FSNode	_node;
-	Common::FSList			_nodeContent;
+	Common::FSList	_nodeContent;
+
 	bool _showHidden;
 	CheckboxWidget *_showHiddenWidget;
-#endif
+
 	Common::FSNode	_choice;
+	const char		*_title;
 	bool			_isDirBrowser;
 
-#ifndef MACOSX
 	void updateListing();
-#endif
 };
 
 } // End of namespace GUI


Commit: 28e4d7bb438d75526f700cd954da6f28ebc45a29
    https://github.com/scummvm/scummvm/commit/28e4d7bb438d75526f700cd954da6f28ebc45a29
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
OSX: Integrate system file browser into DialogManager

Changed paths:
  A backends/dialogs/macosx/macosx-dialogs.h
    backends/dialogs/macosx/macosx-dialogs.mm
    backends/platform/sdl/macosx/macosx.cpp


diff --git a/backends/dialogs/macosx/macosx-dialogs.h b/backends/dialogs/macosx/macosx-dialogs.h
new file mode 100644
index 0000000..351563e
--- /dev/null
+++ b/backends/dialogs/macosx/macosx-dialogs.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKEND_MACOSX_DIALOGS_H
+#define BACKEND_MACOSX_DIALOGS_H
+
+#if defined(MACOSX) && defined(USE_SYSDIALOGS)
+
+#include "common/fs.h"
+#include "common/dialogs.h"
+
+class MacOSXDialogManager : public Common::DialogManager {
+public:
+	virtual DialogResult showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser);
+};
+
+#endif
+
+#endif // BACKEND_MACOSX_DIALOGS_H
diff --git a/backends/dialogs/macosx/macosx-dialogs.mm b/backends/dialogs/macosx/macosx-dialogs.mm
index ffb64ee..f308d4c 100644
--- a/backends/dialogs/macosx/macosx-dialogs.mm
+++ b/backends/dialogs/macosx/macosx-dialogs.mm
@@ -22,8 +22,11 @@
 
 // Disable symbol overrides so that we can use system headers
 #define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/scummsys.h"
 
-#include "gui/browser.h"
+#if defined(MACOSX) && defined(USE_SYSDIALOGS)
+
+#include "backends/dialogs/macosx/macosx-dialogs.h"
 
 #include "common/config-manager.h"
 #include "common/system.h"
@@ -127,13 +130,9 @@
 
 @end
 
-namespace GUI {
-
-BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
-	: Dialog("Browser") {
+Common::DialogManager::DialogResult MacOSXDialogManager::showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser) {
 
-	// remember whether this is a file browser or a directory browser.
-	_isDirBrowser = dirBrowser;
+	DialogResult result = kDialogCancel;
 
 	// Get current encoding
 #ifdef USE_TRANSLATION
@@ -144,20 +143,9 @@ BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
 	CFStringEncoding stringEncoding = kCFStringEncodingASCII;
 #endif
 
-	// Convert title to NSString
-	_titleRef = CFStringCreateWithCString(0, title, stringEncoding);
-
-	// Convert button text to NSString
-	_chooseRef = CFStringCreateWithCString(0, _("Choose"), stringEncoding);
-}
-
-BrowserDialog::~BrowserDialog() {
-	CFRelease(_titleRef);
-	CFRelease(_chooseRef);
-}
-
-int BrowserDialog::runModal() {
-	bool choiceMade = false;
+	// Convert labels to NSString
+	CFStringRef titleRef = CFStringCreateWithCString(0, title, stringEncoding);
+	CFStringRef chooseRef = CFStringCreateWithCString(0, _("Choose"), stringEncoding);
 
 	// If in fullscreen mode, switch to windowed mode
 	bool wasFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
@@ -175,25 +163,28 @@ int BrowserDialog::runModal() {
 
 
 	NSOpenPanel *panel = [NSOpenPanel openPanel];
-	[panel setCanChooseFiles:!_isDirBrowser];
-	[panel setCanChooseDirectories:_isDirBrowser];
-	if (_isDirBrowser)
+	[panel setCanChooseFiles:!isDirBrowser];
+	[panel setCanChooseDirectories:isDirBrowser];
+	if (isDirBrowser)
 		[panel setTreatsFilePackagesAsDirectories:true];
-	[panel setTitle:(NSString *)_titleRef];
-	[panel setPrompt:(NSString *)_chooseRef];
+	[panel setTitle:(NSString *)titleRef];
+	[panel setPrompt:(NSString *)chooseRef];
 
 	BrowserDialogPresenter* presenter = [[BrowserDialogPresenter alloc] init];
 	[presenter performSelectorOnMainThread:@selector(showOpenPanel:) withObject:panel waitUntilDone:YES];
 	if (presenter->_url) {
 		Common::String filename = [[presenter->_url path] UTF8String];
-		_choice = Common::FSNode(filename);
-		choiceMade = true;
+		choice = Common::FSNode(filename);
+		result = kDialogOk;
 	}
 	[presenter release];
 
 	[pool release];
 	[keyWindow makeKeyAndOrderFront:nil];
 
+	CFRelease(titleRef);
+	CFRelease(chooseRef);
+
 	// While the native macOS file browser is open, any input events (e.g. keypresses) are
 	// still received by the NSApplication. With SDL backend for example this results in the
 	// events beeing queued and processed after we return, thus dispatching events that were
@@ -209,7 +200,7 @@ int BrowserDialog::runModal() {
 		g_system->endGFXTransaction();
 	}
 
-	return choiceMade;
+	return result;
 }
 
-} // End of namespace GUI
+#endif
diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp
index d83a8bc..fcfd93a 100644
--- a/backends/platform/sdl/macosx/macosx.cpp
+++ b/backends/platform/sdl/macosx/macosx.cpp
@@ -32,6 +32,7 @@
 #include "backends/platform/sdl/macosx/macosx.h"
 #include "backends/updates/macosx/macosx-updates.h"
 #include "backends/taskbar/macosx/macosx-taskbar.h"
+#include "backends/dialogs/macosx/macosx-dialogs.h"
 #include "backends/platform/sdl/macosx/macosx_wrapper.h"
 
 #include "common/archive.h"
@@ -60,6 +61,11 @@ void OSystem_MacOSX::init() {
 	_taskbarManager = new MacOSXTaskbarManager();
 #endif
 
+#if defined(USE_SYSDIALOGS)
+	// Initialize dialog manager
+	_dialogManager = new MacOSXDialogManager();
+#endif
+
 	// Invoke parent implementation of this method
 	OSystem_POSIX::init();
 }


Commit: 2f2555f728086873eb074af4ca6b46025f405f75
    https://github.com/scummvm/scummvm/commit/2f2555f728086873eb074af4ca6b46025f405f75
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
WIN32: Move utility functions to a common wrapper

Changed paths:
  A backends/platform/sdl/win32/win32_wrapper.cpp
  A backends/platform/sdl/win32/win32_wrapper.h
    backends/platform/sdl/module.mk
    backends/platform/sdl/win32/win32-window.cpp
    backends/platform/sdl/win32/win32-window.h
    backends/platform/sdl/win32/win32.cpp
    backends/taskbar/win32/win32-taskbar.cpp
    backends/taskbar/win32/win32-taskbar.h


diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk
index bb11aaa..c5036be 100644
--- a/backends/platform/sdl/module.mk
+++ b/backends/platform/sdl/module.mk
@@ -22,6 +22,7 @@ ifdef WIN32
 MODULE_OBJS += \
 	win32/win32-main.o \
 	win32/win32-window.o \
+	win32/win32_wrapper.o \
 	win32/win32.o
 endif
 
diff --git a/backends/platform/sdl/win32/win32-window.cpp b/backends/platform/sdl/win32/win32-window.cpp
index de10be6..8c01da0 100644
--- a/backends/platform/sdl/win32/win32-window.cpp
+++ b/backends/platform/sdl/win32/win32-window.cpp
@@ -35,14 +35,10 @@ void SdlWindow_Win32::setupIcon() {
 	HMODULE handle = GetModuleHandle(NULL);
 	HICON   ico    = LoadIcon(handle, MAKEINTRESOURCE(1001 /* IDI_ICON */));
 	if (ico) {
-		SDL_SysWMinfo wminfo;
-		if (getSDLWMInformation(&wminfo)) {
+		HWND hwnd = getHwnd();
+		if (hwnd) {
 			// Replace the handle to the icon associated with the window class by our custom icon
-#if SDL_VERSION_ATLEAST(2, 0, 0)
-			SetClassLongPtr(wminfo.info.win.window, GCLP_HICON, (ULONG_PTR)ico);
-#else
-			SetClassLongPtr(wminfo.window, GCLP_HICON, (ULONG_PTR)ico);
-#endif
+			SetClassLongPtr(hwnd, GCLP_HICON, (ULONG_PTR)ico);
 
 			// Since there wasn't any default icon, we can't use the return value from SetClassLong
 			// to check for errors (it would be 0 in both cases: error or no previous value for the
@@ -56,4 +52,16 @@ void SdlWindow_Win32::setupIcon() {
 	SdlWindow::setupIcon();
 }
 
+HWND SdlWindow_Win32::getHwnd() {
+	SDL_SysWMinfo wminfo;
+	if (getSDLWMInformation(&wminfo)) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+		return wminfo.info.win.window;
+#else
+		return wminfo.window;
+#endif
+	}
+	return NULL;
+}
+
 #endif
diff --git a/backends/platform/sdl/win32/win32-window.h b/backends/platform/sdl/win32/win32-window.h
index 3bda697..7498e3f 100644
--- a/backends/platform/sdl/win32/win32-window.h
+++ b/backends/platform/sdl/win32/win32-window.h
@@ -30,6 +30,7 @@
 class SdlWindow_Win32 : public SdlWindow {
 public:
 	virtual void setupIcon();
+	HWND getHwnd();
 };
 
 #endif
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 3de1b9b..936662e 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -61,7 +61,7 @@ void OSystem_Win32::init() {
 
 #if defined(USE_TASKBAR)
 	// Initialize taskbar manager
-	_taskbarManager = new Win32TaskbarManager(_window);
+	_taskbarManager = new Win32TaskbarManager((SdlWindow_Win32*)_window);
 #endif
 
 	// Invoke parent implementation of this method
diff --git a/backends/platform/sdl/win32/win32_wrapper.cpp b/backends/platform/sdl/win32/win32_wrapper.cpp
new file mode 100644
index 0000000..3ff00b6
--- /dev/null
+++ b/backends/platform/sdl/win32/win32_wrapper.cpp
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/scummsys.h"
+// We need certain functions that are excluded by default
+#undef NONLS
+#include <windows.h>
+#if defined(ARRAYSIZE)
+#undef ARRAYSIZE
+#endif
+
+#include "backends/platform/sdl/win32/win32_wrapper.h"
+
+// VerSetConditionMask and VerifyVersionInfo didn't appear until Windows 2000,
+// so we need to check for them at runtime
+LONGLONG VerSetConditionMaskFunc(ULONGLONG dwlConditionMask, DWORD dwTypeMask, BYTE dwConditionMask) {
+	typedef BOOL(WINAPI *VerSetConditionMaskFunction)(ULONGLONG conditionMask, DWORD typeMask, BYTE conditionOperator);
+
+	VerSetConditionMaskFunction verSetConditionMask = (VerSetConditionMaskFunction)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "VerSetConditionMask");
+	if (verSetConditionMask == NULL)
+		return 0;
+
+	return verSetConditionMask(dwlConditionMask, dwTypeMask, dwConditionMask);
+}
+
+BOOL VerifyVersionInfoFunc(LPOSVERSIONINFOEXA lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask) {
+	typedef BOOL(WINAPI *VerifyVersionInfoFunction)(LPOSVERSIONINFOEXA versionInformation, DWORD typeMask, DWORDLONG conditionMask);
+
+	VerifyVersionInfoFunction verifyVersionInfo = (VerifyVersionInfoFunction)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "VerifyVersionInfoA");
+	if (verifyVersionInfo == NULL)
+		return FALSE;
+
+	return verifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask);
+}
+
+namespace Win32 {
+
+bool confirmWindowsVersion(int majorVersion, int minorVersion) {
+	OSVERSIONINFOEX versionInfo;
+	DWORDLONG conditionMask = 0;
+
+	ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
+	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+	versionInfo.dwMajorVersion = majorVersion;
+	versionInfo.dwMinorVersion = minorVersion;
+
+	conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+	conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
+
+	return VerifyVersionInfoFunc(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
+}
+
+LPWSTR ansiToUnicode(const char *s) {
+	DWORD size = MultiByteToWideChar(0, 0, s, -1, NULL, 0);
+
+	if (size > 0) {
+		LPWSTR result = new WCHAR[size];
+		if (MultiByteToWideChar(0, 0, s, -1, result, size) != 0)
+			return result;
+	}
+
+	return NULL;
+}
+
+}
diff --git a/backends/platform/sdl/win32/win32_wrapper.h b/backends/platform/sdl/win32/win32_wrapper.h
new file mode 100644
index 0000000..5722d88
--- /dev/null
+++ b/backends/platform/sdl/win32/win32_wrapper.h
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PLATFORM_SDL_WIN32_WRAPPER_H
+#define PLATFORM_SDL_WIN32_WRAPPER_H
+
+// Helper functions
+namespace Win32 {
+
+/**
+ * Checks if the current running Windows version is greater or equal to the specified version.
+ * See: https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version
+ *
+ * @param majorVersion The major version number (x.0)
+ * @param minorVersion The minor version number (0.x)
+ */
+bool confirmWindowsVersion(int majorVersion, int minorVersion);
+/**
+ * Converts a C string into a Windows wide-character string.
+ * Used to interact with Win32 Unicode APIs with no ANSI fallback.
+ *
+ * @param s Source string
+ * @return Converted string
+ *
+ * @note Return value must be freed by the caller.
+ */
+wchar_t *ansiToUnicode(const char *s);
+
+}
+
+#endif
diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp
index b2810e5..1537859 100644
--- a/backends/taskbar/win32/win32-taskbar.cpp
+++ b/backends/taskbar/win32/win32-taskbar.cpp
@@ -50,20 +50,10 @@
 	// To assure that including the respective system headers gives us all
 	// required definitions we set Win7 as minimum version we target.
 	// See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745%28v=vs.85%29.aspx#macros_for_conditional_declarations
+	#include <sdkddkver.h>
 	#undef _WIN32_WINNT
 	#define _WIN32_WINNT _WIN32_WINNT_WIN7
 
-	// TODO: We might not need to include this file, the MSDN docs are
-	// not really helpful to decide whether we require it or not.
-	//
-	// Casing of the name is a bit of a mess. MinGW64 seems to use all
-	// lowercase, while MSDN docs suggest "SdkDdkVer.h". We are stuck with
-	// what MinGW64 uses...
-	#include <sdkddkver.h>
-
-	// We need certain functions that are excluded by default
-	#undef NONLS
-	#undef NOICONS
 	#include <windows.h>
 	#if defined(ARRAYSIZE)
 		#undef ARRAYSIZE
@@ -75,6 +65,8 @@
 #include "common/scummsys.h"
 
 #include "backends/taskbar/win32/win32-taskbar.h"
+#include "backends/platform/sdl/win32/win32-window.h"
+#include "backends/platform/sdl/win32/win32_wrapper.h"
 
 #include "common/config-manager.h"
 #include "common/textconsole.h"
@@ -83,9 +75,9 @@
 // System.Title property key, values taken from http://msdn.microsoft.com/en-us/library/bb787584.aspx
 const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 } }, /* propID = */ 2 };
 
-Win32TaskbarManager::Win32TaskbarManager(SdlWindow *window) : _window(window), _taskbar(NULL), _count(0), _icon(NULL) {
+Win32TaskbarManager::Win32TaskbarManager(SdlWindow_Win32 *window) : _window(window), _taskbar(NULL), _count(0), _icon(NULL) {
 	// Do nothing if not running on Windows 7 or later
-	if (!confirmWindowsVersion(10, 0) && !confirmWindowsVersion(6, 1))
+	if (!Win32::confirmWindowsVersion(10, 0) && !Win32::confirmWindowsVersion(6, 1))
 		return;
 
 	CoInitialize(NULL);
@@ -126,7 +118,7 @@ void Win32TaskbarManager::setOverlayIcon(const Common::String &name, const Commo
 		return;
 
 	if (name.empty()) {
-		_taskbar->SetOverlayIcon(getHwnd(), NULL, L"");
+		_taskbar->SetOverlayIcon(_window->getHwnd(), NULL, L"");
 		return;
 	}
 
@@ -142,8 +134,8 @@ void Win32TaskbarManager::setOverlayIcon(const Common::String &name, const Commo
 	}
 
 	// Sets the overlay icon
-	LPWSTR desc = ansiToUnicode(description.c_str());
-	_taskbar->SetOverlayIcon(getHwnd(), pIcon, desc);
+	LPWSTR desc = Win32::ansiToUnicode(description.c_str());
+	_taskbar->SetOverlayIcon(_window->getHwnd(), pIcon, desc);
 
 	DestroyIcon(pIcon);
 
@@ -154,14 +146,14 @@ void Win32TaskbarManager::setProgressValue(int completed, int total) {
 	if (_taskbar == NULL)
 		return;
 
-	_taskbar->SetProgressValue(getHwnd(), completed, total);
+	_taskbar->SetProgressValue(_window->getHwnd(), completed, total);
 }
 
 void Win32TaskbarManager::setProgressState(TaskbarProgressState state) {
 	if (_taskbar == NULL)
 		return;
 
-	_taskbar->SetProgressState(getHwnd(), (TBPFLAG)state);
+	_taskbar->SetProgressState(_window->getHwnd(), (TBPFLAG)state);
 }
 
 void Win32TaskbarManager::setCount(int count) {
@@ -169,7 +161,7 @@ void Win32TaskbarManager::setCount(int count) {
 		return;
 
 	if (count == 0) {
-		_taskbar->SetOverlayIcon(getHwnd(), NULL, L"");
+		_taskbar->SetOverlayIcon(_window->getHwnd(), NULL, L"");
 		return;
 	}
 
@@ -276,8 +268,8 @@ void Win32TaskbarManager::setCount(int count) {
 	}
 
 	// Sets the overlay icon
-	LPWSTR desc = ansiToUnicode(Common::String::format("Found games: %d", count).c_str());
-	_taskbar->SetOverlayIcon(getHwnd(), _icon, desc);
+	LPWSTR desc = Win32::ansiToUnicode(Common::String::format("Found games: %d", count).c_str());
+	_taskbar->SetOverlayIcon(_window->getHwnd(), _icon, desc);
 	delete[] desc;
 }
 
@@ -297,8 +289,8 @@ void Win32TaskbarManager::addRecent(const Common::String &name, const Common::St
 	// Create a shell link.
 	if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_IShellLinkW, reinterpret_cast<void **> (&link)))) {
 		// Convert game name and description to Unicode.
-		LPWSTR game = ansiToUnicode(name.c_str());
-		LPWSTR desc = ansiToUnicode(description.c_str());
+		LPWSTR game = Win32::ansiToUnicode(name.c_str());
+		LPWSTR desc = Win32::ansiToUnicode(description.c_str());
 
 		// Set link properties.
 		link->SetPath(path);
@@ -308,7 +300,7 @@ void Win32TaskbarManager::addRecent(const Common::String &name, const Common::St
 		if (iconPath.empty()) {
 			link->SetIconLocation(path, 0); // No game-specific icon available
 		} else {
-			LPWSTR icon = ansiToUnicode(iconPath.c_str());
+			LPWSTR icon = Win32::ansiToUnicode(iconPath.c_str());
 
 			link->SetIconLocation(icon, 0);
 
@@ -378,66 +370,4 @@ Common::String Win32TaskbarManager::getIconPath(Common::String target) {
 	return "";
 }
 
-// VerSetConditionMask and VerifyVersionInfo didn't appear until Windows 2000,
-// so we need to check for them at runtime
-LONGLONG VerSetConditionMaskFunc(ULONGLONG dwlConditionMask, DWORD dwTypeMask, BYTE dwConditionMask) {
-	typedef BOOL (WINAPI *VerSetConditionMaskFunction)(ULONGLONG conditionMask, DWORD typeMask, BYTE conditionOperator);
-
-	VerSetConditionMaskFunction verSetConditionMask = (VerSetConditionMaskFunction)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "VerSetConditionMask");
-	if (verSetConditionMask == NULL)
-		return 0;
-
-	return verSetConditionMask(dwlConditionMask, dwTypeMask, dwConditionMask);
-}
-
-BOOL VerifyVersionInfoFunc(LPOSVERSIONINFOEXA lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask) {
-   typedef BOOL (WINAPI *VerifyVersionInfoFunction)(LPOSVERSIONINFOEXA versionInformation, DWORD typeMask, DWORDLONG conditionMask);
-
-   VerifyVersionInfoFunction verifyVersionInfo = (VerifyVersionInfoFunction)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "VerifyVersionInfoA");
-   if (verifyVersionInfo == NULL)
-      return FALSE;
-
-   return verifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask);
-}
-
-bool Win32TaskbarManager::confirmWindowsVersion(uint majorVersion, uint minorVersion) {
-	OSVERSIONINFOEX versionInfo;
-	DWORDLONG conditionMask = 0;
-
-	ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
-	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-	versionInfo.dwMajorVersion = majorVersion;
-	versionInfo.dwMinorVersion = minorVersion;
-
-	conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
-	conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
-
-	return VerifyVersionInfoFunc(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
-}
-
-LPWSTR Win32TaskbarManager::ansiToUnicode(const char *s) {
-	DWORD size = MultiByteToWideChar(0, 0, s, -1, NULL, 0);
-
-	if (size > 0) {
-		LPWSTR result = new WCHAR[size];
-		if (MultiByteToWideChar(0, 0, s, -1, result, size) != 0)
-			return result;
-	}
-
-	return NULL;
-}
-
-HWND Win32TaskbarManager::getHwnd() {
-	SDL_SysWMinfo wmi;
-	if (_window->getSDLWMInformation(&wmi)) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
-		return wmi.info.win.window;
-#else
-		return wmi.window;
-#endif
-	} else {
-		return NULL;
-	}
-}
-
 #endif
diff --git a/backends/taskbar/win32/win32-taskbar.h b/backends/taskbar/win32/win32-taskbar.h
index a5c024b..aa7b571 100644
--- a/backends/taskbar/win32/win32-taskbar.h
+++ b/backends/taskbar/win32/win32-taskbar.h
@@ -25,16 +25,15 @@
 
 #if defined(WIN32) && defined(USE_TASKBAR)
 
-#include "backends/platform/sdl/sdl-window.h"
-
 #include "common/str.h"
 #include "common/taskbar.h"
 
+class SdlWindow_Win32;
 struct ITaskbarList3;
 
 class Win32TaskbarManager : public Common::TaskbarManager {
 public:
-	Win32TaskbarManager(SdlWindow *window);
+	Win32TaskbarManager(SdlWindow_Win32 *window);
 	virtual ~Win32TaskbarManager();
 
 	virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
@@ -46,7 +45,7 @@ public:
 	virtual void clearError();
 
 private:
-	SdlWindow *_window;
+	SdlWindow_Win32 *_window;
 
 	ITaskbarList3 *_taskbar;
 
@@ -62,11 +61,6 @@ private:
 	 * @return	The icon path (or "" if no icon was found)
 	 */
 	Common::String getIconPath(Common::String target);
-
-	// Helper functions
-	bool confirmWindowsVersion(uint majorVersion, uint minorVersion);
-	LPWSTR ansiToUnicode(const char *s);
-	HWND getHwnd();
 };
 
 #endif


Commit: 61070f6ce0c15d3636f984c9aa00aa9c68cb25e1
    https://github.com/scummvm/scummvm/commit/61070f6ce0c15d3636f984c9aa00aa9c68cb25e1
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
WIN32: Add DialogManager with system file browser support

Changed paths:
  A backends/dialogs/win32/win32-dialogs.cpp
  A backends/dialogs/win32/win32-dialogs.h
    backends/module.mk
    backends/platform/sdl/win32/win32.cpp
    backends/platform/sdl/win32/win32_wrapper.cpp
    backends/platform/sdl/win32/win32_wrapper.h


diff --git a/backends/dialogs/win32/win32-dialogs.cpp b/backends/dialogs/win32/win32-dialogs.cpp
new file mode 100644
index 0000000..b7d41cf
--- /dev/null
+++ b/backends/dialogs/win32/win32-dialogs.cpp
@@ -0,0 +1,136 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(WIN32) && defined(USE_SYSDIALOGS)
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include <windows.h>
+#include <shlobj.h>
+#if defined(ARRAYSIZE)
+#undef ARRAYSIZE
+#endif
+
+#include "common/scummsys.h"
+
+#include "backends/dialogs/win32/win32-dialogs.h"
+#include "backends/platform/sdl/win32/win32_wrapper.h"
+#include "backends/platform/sdl/win32/win32-window.h"
+
+#include "common/config-manager.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/translation.h"
+
+Win32DialogManager::Win32DialogManager(SdlWindow_Win32 *window) : _window(window) {
+	CoInitialize(NULL);
+}
+
+Win32DialogManager::~Win32DialogManager() {
+	CoUninitialize();
+}
+
+Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser) {
+	DialogResult result = kDialogError;
+
+	// Do nothing if not running on Windows Vista or later
+	if (!Win32::confirmWindowsVersion(6, 0))
+		return result;
+
+	IFileOpenDialog *dialog = NULL;
+	HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog,
+	                              NULL,
+	                              CLSCTX_INPROC_SERVER,
+	                              IID_PPV_ARGS(&dialog));
+
+	if (SUCCEEDED(hr)) {
+		// If in fullscreen mode, switch to windowed mode
+		bool wasFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
+		if (wasFullscreen) {
+			g_system->beginGFXTransaction();
+			g_system->setFeatureState(OSystem::kFeatureFullscreenMode, false);
+			g_system->endGFXTransaction();
+		}
+
+		// Customize dialog
+		bool showHidden = ConfMan.getBool("gui_browser_show_hidden", Common::ConfigManager::kApplicationDomain);
+
+		DWORD dwOptions;
+		hr = dialog->GetOptions(&dwOptions);
+		if (SUCCEEDED(hr)) {
+			if (isDirBrowser)
+				dwOptions |= FOS_PICKFOLDERS;
+			if (showHidden)
+				dwOptions |= FOS_FORCESHOWHIDDEN;
+			hr = dialog->SetOptions(dwOptions);
+		}
+
+		LPWSTR str = Win32::ansiToUnicode(title);
+		hr = dialog->SetTitle(str);
+		delete[] str;
+
+		str = Win32::ansiToUnicode(_("Choose"));
+		hr = dialog->SetOkButtonLabel(str);
+		delete[] str;
+
+		// Show dialog
+		hr = dialog->Show(_window->getHwnd());
+
+		if (SUCCEEDED(hr)) {
+			IShellItem *selectedItem = NULL;
+			LPWSTR path = NULL;
+
+			// Get the selection from the user
+			hr = dialog->GetResult(&selectedItem);
+
+			if (SUCCEEDED(hr)) {
+				hr = selectedItem->GetDisplayName(SIGDN_FILESYSPATH, &path);
+
+				if (SUCCEEDED(hr)) {
+					char *str = Win32::unicodeToAnsi(path);
+					choice = Common::FSNode(str);
+					result = kDialogOk;
+					CoTaskMemFree(path);
+					delete[] str;
+				}
+
+				selectedItem->Release();
+			}
+		} else if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) {
+			result = kDialogCancel;
+		}
+
+		dialog->Release();
+
+		// If we were in fullscreen mode, switch back
+		if (wasFullscreen) {
+			g_system->beginGFXTransaction();
+			g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
+			g_system->endGFXTransaction();
+		}
+	}
+
+	return result;
+}
+
+#endif
diff --git a/backends/dialogs/win32/win32-dialogs.h b/backends/dialogs/win32/win32-dialogs.h
new file mode 100644
index 0000000..32454bd
--- /dev/null
+++ b/backends/dialogs/win32/win32-dialogs.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKEND_WIN32_DIALOGS_H
+#define BACKEND_WIN32_DIALOGS_H
+
+#if defined(WIN32) && defined(USE_SYSDIALOGS)
+
+#include "common/fs.h"
+#include "common/dialogs.h"
+
+class SdlWindow_Win32;
+
+class Win32DialogManager : public Common::DialogManager {
+public:
+	Win32DialogManager(SdlWindow_Win32 *window);
+	virtual ~Win32DialogManager();
+	virtual DialogResult showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser);
+
+private:
+	SdlWindow_Win32 *_window;
+};
+
+#endif
+
+#endif // BACKEND_WIN32_DIALOGS_H
diff --git a/backends/module.mk b/backends/module.mk
index ad02481..4d2bdc1 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -189,6 +189,7 @@ endif
 ifdef WIN32
 MODULE_OBJS += \
 	audiocd/win32/win32-audiocd.o \
+	dialogs/win32/win32-dialogs.o \
 	fs/windows/windows-fs.o \
 	fs/windows/windows-fs-factory.o \
 	midi/windows.o \
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 936662e..b94c6bb7 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -47,6 +47,7 @@
 #include "backends/fs/windows/windows-fs-factory.h"
 #include "backends/taskbar/win32/win32-taskbar.h"
 #include "backends/updates/win32/win32-updates.h"
+#include "backends/dialogs/win32/win32-dialogs.h"
 
 #include "common/memstream.h"
 
@@ -64,6 +65,11 @@ void OSystem_Win32::init() {
 	_taskbarManager = new Win32TaskbarManager((SdlWindow_Win32*)_window);
 #endif
 
+#if defined(USE_SYSDIALOGS)
+	// Initialize dialog manager
+	_dialogManager = new Win32DialogManager((SdlWindow_Win32*)_window);
+#endif
+
 	// Invoke parent implementation of this method
 	OSystem_SDL::init();
 }
diff --git a/backends/platform/sdl/win32/win32_wrapper.cpp b/backends/platform/sdl/win32/win32_wrapper.cpp
index 3ff00b6..d199ce8 100644
--- a/backends/platform/sdl/win32/win32_wrapper.cpp
+++ b/backends/platform/sdl/win32/win32_wrapper.cpp
@@ -20,16 +20,10 @@
  *
  */
 
-// Disable symbol overrides so that we can use system headers.
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
 #include "common/scummsys.h"
 // We need certain functions that are excluded by default
 #undef NONLS
 #include <windows.h>
-#if defined(ARRAYSIZE)
-#undef ARRAYSIZE
-#endif
 
 #include "backends/platform/sdl/win32/win32_wrapper.h"
 
@@ -72,7 +66,7 @@ bool confirmWindowsVersion(int majorVersion, int minorVersion) {
 	return VerifyVersionInfoFunc(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
 }
 
-LPWSTR ansiToUnicode(const char *s) {
+wchar_t *ansiToUnicode(const char *s) {
 	DWORD size = MultiByteToWideChar(0, 0, s, -1, NULL, 0);
 
 	if (size > 0) {
@@ -84,4 +78,16 @@ LPWSTR ansiToUnicode(const char *s) {
 	return NULL;
 }
 
+char *unicodeToAnsi(const wchar_t *s) {
+	DWORD size = WideCharToMultiByte(0, 0, s, -1, NULL, 0, 0, 0);
+
+	if (size > 0) {
+		char *result = new char[size];
+		if (WideCharToMultiByte(0, 0, s, -1, result, size, 0, 0) != 0)
+			return result;
+	}
+
+	return NULL;
+}
+
 }
diff --git a/backends/platform/sdl/win32/win32_wrapper.h b/backends/platform/sdl/win32/win32_wrapper.h
index 5722d88..91cbe3a 100644
--- a/backends/platform/sdl/win32/win32_wrapper.h
+++ b/backends/platform/sdl/win32/win32_wrapper.h
@@ -44,6 +44,16 @@ bool confirmWindowsVersion(int majorVersion, int minorVersion);
  * @note Return value must be freed by the caller.
  */
 wchar_t *ansiToUnicode(const char *s);
+/**
+ * Converts a Windows wide-character string into a C string.
+ * Used to interact with Win32 Unicode APIs with no ANSI fallback.
+ *
+ * @param s Source string
+ * @return Converted string
+ *
+ * @note Return value must be freed by the caller.
+ */
+char *unicodeToAnsi(const wchar_t *s);
 
 }
 


Commit: 7bff9176d582c9c59a341d1a6fbe8ddb4f04e575
    https://github.com/scummvm/scummvm/commit/7bff9176d582c9c59a341d1a6fbe8ddb4f04e575
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
WIN32: Fix incorrect Windows version check

There's no point in testing for Windows 10 since the comparison is already "greater than or equals", and it identifies itself as 6.2 for backwards compatibility. Likely it was failing before because the return type was wrong.

Version checks are unreliable anyways, should use feature checks, but "if it ain't broke don't fix it".

Changed paths:
    backends/platform/sdl/win32/win32_wrapper.cpp
    backends/taskbar/win32/win32-taskbar.cpp


diff --git a/backends/platform/sdl/win32/win32_wrapper.cpp b/backends/platform/sdl/win32/win32_wrapper.cpp
index d199ce8..b61098a 100644
--- a/backends/platform/sdl/win32/win32_wrapper.cpp
+++ b/backends/platform/sdl/win32/win32_wrapper.cpp
@@ -29,8 +29,8 @@
 
 // VerSetConditionMask and VerifyVersionInfo didn't appear until Windows 2000,
 // so we need to check for them at runtime
-LONGLONG VerSetConditionMaskFunc(ULONGLONG dwlConditionMask, DWORD dwTypeMask, BYTE dwConditionMask) {
-	typedef BOOL(WINAPI *VerSetConditionMaskFunction)(ULONGLONG conditionMask, DWORD typeMask, BYTE conditionOperator);
+ULONGLONG VerSetConditionMaskFunc(ULONGLONG dwlConditionMask, DWORD dwTypeMask, BYTE dwConditionMask) {
+	typedef ULONGLONG(WINAPI *VerSetConditionMaskFunction)(ULONGLONG conditionMask, DWORD typeMask, BYTE conditionOperator);
 
 	VerSetConditionMaskFunction verSetConditionMask = (VerSetConditionMaskFunction)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "VerSetConditionMask");
 	if (verSetConditionMask == NULL)
@@ -52,11 +52,11 @@ BOOL VerifyVersionInfoFunc(LPOSVERSIONINFOEXA lpVersionInformation, DWORD dwType
 namespace Win32 {
 
 bool confirmWindowsVersion(int majorVersion, int minorVersion) {
-	OSVERSIONINFOEX versionInfo;
+	OSVERSIONINFOEXA versionInfo;
 	DWORDLONG conditionMask = 0;
 
-	ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
-	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+	ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEXA));
+	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
 	versionInfo.dwMajorVersion = majorVersion;
 	versionInfo.dwMinorVersion = minorVersion;
 
diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp
index 1537859..f6706de 100644
--- a/backends/taskbar/win32/win32-taskbar.cpp
+++ b/backends/taskbar/win32/win32-taskbar.cpp
@@ -77,7 +77,7 @@ const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0
 
 Win32TaskbarManager::Win32TaskbarManager(SdlWindow_Win32 *window) : _window(window), _taskbar(NULL), _count(0), _icon(NULL) {
 	// Do nothing if not running on Windows 7 or later
-	if (!Win32::confirmWindowsVersion(10, 0) && !Win32::confirmWindowsVersion(6, 1))
+	if (!Win32::confirmWindowsVersion(6, 1))
 		return;
 
 	CoInitialize(NULL);


Commit: fc504996d3ecb828b4f47477911c9449ae8779a6
    https://github.com/scummvm/scummvm/commit/fc504996d3ecb828b4f47477911c9449ae8779a6
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
GUI: Allow user to opt between GUI browser and native browser

Changed paths:
    base/commandLine.cpp
    gui/browser.cpp


diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 3019998..b4a9174 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -284,6 +284,7 @@ void registerDefaults() {
 	ConfMan.registerDefault("gui_saveload_last_pos", "0");
 
 	ConfMan.registerDefault("gui_browser_show_hidden", false);
+	ConfMan.registerDefault("gui_browser_native", true);
 	ConfMan.registerDefault("game", "");
 
 #ifdef USE_FLUIDSYNTH
diff --git a/gui/browser.cpp b/gui/browser.cpp
index f317680..4c8f0d1 100644
--- a/gui/browser.cpp
+++ b/gui/browser.cpp
@@ -88,9 +88,11 @@ int BrowserDialog::runModal() {
 	// Try to use the backend browser
 	Common::DialogManager *dialogManager = g_system->getDialogManager();
 	if (dialogManager) {
-		Common::DialogManager::DialogResult result = dialogManager->showFileBrowser(_title, _choice, _isDirBrowser);
-		if (result != Common::DialogManager::kDialogError) {
-			return result;
+		if (ConfMan.getBool("gui_browser_native", Common::ConfigManager::kApplicationDomain)) {
+			Common::DialogManager::DialogResult result = dialogManager->showFileBrowser(_title, _choice, _isDirBrowser);
+			if (result != Common::DialogManager::kDialogError) {
+				return result;
+			}
 		}
 	}
 #endif


Commit: 93695a9dcff544707ba1a02321c4a20034effc99
    https://github.com/scummvm/scummvm/commit/93695a9dcff544707ba1a02321c4a20034effc99
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
WIN32: Fix dialog compilation under MinGW

Changed paths:
  A backends/dialogs/win32/mingw-compat.h
    backends/dialogs/win32/win32-dialogs.cpp


diff --git a/backends/dialogs/win32/mingw-compat.h b/backends/dialogs/win32/mingw-compat.h
new file mode 100644
index 0000000..e9c55a1
--- /dev/null
+++ b/backends/dialogs/win32/mingw-compat.h
@@ -0,0 +1,170 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// TODO: Remove header when the latest changes to the Windows SDK have been integrated into MingW
+//       For reference, the interface definitions here are imported from the SDK headers and MingW-w64
+
+#ifndef BACKEND_WIN32_DIALOGS_MINGW_H
+#define BACKEND_WIN32_DIALOGS_MINGW_H
+
+#if defined(WIN32)
+#if defined(__GNUC__)
+#ifdef __MINGW32__
+
+#ifdef _WIN32_WINNT
+	#undef _WIN32_WINNT
+#endif
+#define _WIN32_WINNT 0x0501
+#include <windows.h>
+#include <commctrl.h>
+#include <initguid.h>
+#include <shlwapi.h>
+#include <shlguid.h>
+
+// MinGW does not understand COM interfaces
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+
+// Dialog GUID definitions
+DEFINE_GUID(CLSID_FileOpenDialog, 0xdc1c5a9c, 0xe88a, 0x4dde, 0xa5,0xa1, 0x60,0xf8,0x2a,0x20,0xae,0xf7);
+DEFINE_GUID(IID_IFileOpenDialog, 0xd57c7288, 0xd4ad, 0x4768, 0xbe,0x02, 0x9d,0x96,0x95,0x32,0xd9,0x60);
+DEFINE_GUID(IID_IShellItem, 0x43826d1e, 0xe718, 0x42ee, 0xbc,0x55, 0xa1,0xe2,0x61,0xc3,0x7b,0xfe);
+
+typedef enum _SIGDN {
+	SIGDN_NORMALDISPLAY	= 0,
+	SIGDN_PARENTRELATIVEPARSING	= 0x80018001,
+	SIGDN_DESKTOPABSOLUTEPARSING	= 0x80028000,
+	SIGDN_PARENTRELATIVEEDITING	= 0x80031001,
+	SIGDN_DESKTOPABSOLUTEEDITING	= 0x8004c000,
+	SIGDN_FILESYSPATH	= 0x80058000,
+	SIGDN_URL	= 0x80068000,
+	SIGDN_PARENTRELATIVEFORADDRESSBAR	= 0x8007c001,
+	SIGDN_PARENTRELATIVE	= 0x80080001,
+	SIGDN_PARENTRELATIVEFORUI	= 0x80094001
+} 	SIGDN;
+
+enum _SICHINTF {
+	SICHINT_DISPLAY	= 0,
+	SICHINT_ALLFIELDS	= 0x80000000,
+	SICHINT_CANONICAL	= 0x10000000,
+	SICHINT_TEST_FILESYSPATH_IF_NOT_EQUAL	= 0x20000000
+} ;
+typedef DWORD SICHINTF;
+
+// Shell item
+#define INTERFACE IShellItem
+DECLARE_INTERFACE_(IShellItem, IUnknown) {	
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
+	STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG,Release) (THIS) PURE;
+	STDMETHOD (BindToHandler) (IBindCtx *pbc, REFGUID bhid, REFIID riid, void **ppv) PURE;
+	STDMETHOD (GetParent) (IShellItem **ppsi) PURE;
+	STDMETHOD (GetDisplayName) (SIGDN sigdnName, LPWSTR *ppszName) PURE;
+	STDMETHOD (GetAttributes) (SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) PURE;
+	STDMETHOD (Compare) (IShellItem *psi, SICHINTF hint, int *piOrder) PURE;
+};
+#undef INTERFACE
+
+// Mingw-specific defines for dialog integration
+typedef struct _COMDLG_FILTERSPEC {
+	LPCWSTR pszName;
+	LPCWSTR pszSpec;
+} COMDLG_FILTERSPEC;
+
+typedef enum FDAP {
+	FDAP_BOTTOM	= 0,
+	FDAP_TOP	= 1
+} 	FDAP;
+
+enum _FILEOPENDIALOGOPTIONS {
+	FOS_OVERWRITEPROMPT	= 0x2,
+	FOS_STRICTFILETYPES	= 0x4,
+	FOS_NOCHANGEDIR	= 0x8,
+	FOS_PICKFOLDERS	= 0x20,
+	FOS_FORCEFILESYSTEM	= 0x40,
+	FOS_ALLNONSTORAGEITEMS	= 0x80,
+	FOS_NOVALIDATE	= 0x100,
+	FOS_ALLOWMULTISELECT	= 0x200,
+	FOS_PATHMUSTEXIST	= 0x800,
+	FOS_FILEMUSTEXIST	= 0x1000,
+	FOS_CREATEPROMPT	= 0x2000,
+	FOS_SHAREAWARE	= 0x4000,
+	FOS_NOREADONLYRETURN	= 0x8000,
+	FOS_NOTESTFILECREATE	= 0x10000,
+	FOS_HIDEMRUPLACES	= 0x20000,
+	FOS_HIDEPINNEDPLACES	= 0x40000,
+	FOS_NODEREFERENCELINKS	= 0x100000,
+	FOS_DONTADDTORECENT	= 0x2000000,
+	FOS_FORCESHOWHIDDEN	= 0x10000000,
+	FOS_DEFAULTNOMINIMODE	= 0x20000000,
+	FOS_FORCEPREVIEWPANEON	= 0x40000000,
+	FOS_SUPPORTSTREAMABLEITEMS	= 0x80000000
+};
+typedef DWORD FILEOPENDIALOGOPTIONS;
+
+// TODO: Need to implement these if they ever get used
+typedef interface IFileDialogEvents IFileDialogEvents;
+typedef interface IShellItemFilter IShellItemFilter;
+typedef interface IShellItemArray IShellItemArray;
+
+// Open dialog interface
+#define INTERFACE IFileOpenDialog
+DECLARE_INTERFACE_(IFileOpenDialog, IUnknown) {
+	// IUnknown
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
+	STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG,Release) (THIS) PURE;
+	// IModalWindow
+	STDMETHOD (Show) (THIS_ HWND hwndOwner) PURE;
+	// IFileDialog
+	STDMETHOD (SetFileTypes) (THIS_ UINT cFileTypes, const COMDLG_FILTERSPEC *rgFilterSpec) PURE;
+	STDMETHOD (SetFileTypeIndex) (THIS_ UINT iFileType) PURE;
+	STDMETHOD (GetFileTypeIndex) (THIS_ UINT *piFileType) PURE;
+	STDMETHOD (Advise) (THIS_ IFileDialogEvents *pfde, DWORD *pdwCookie) PURE;
+	STDMETHOD (Unadvise) (THIS_ DWORD dwCookie) PURE;
+	STDMETHOD (SetOptions) (THIS_ FILEOPENDIALOGOPTIONS fos) PURE;
+	STDMETHOD (GetOptions) (THIS_ FILEOPENDIALOGOPTIONS *pfos) PURE;
+	STDMETHOD (SetDefaultFolder) (THIS_ IShellItem *psi) PURE;
+	STDMETHOD (SetFolder) (THIS_ IShellItem *psi) PURE;
+	STDMETHOD (GetFolder) (THIS_ IShellItem **ppsi) PURE;
+	STDMETHOD (GetCurrentSelection) (THIS_ IShellItem **ppsi) PURE;
+	STDMETHOD (SetFileName) (THIS_ LPCWSTR pszName) PURE;
+	STDMETHOD (GetFileName) (THIS_ LPWSTR *pszName) PURE;
+	STDMETHOD (SetTitle) (THIS_ LPCWSTR pszTitle) PURE;
+	STDMETHOD (SetOkButtonLabel) (THIS_ LPCWSTR pszText) PURE;
+	STDMETHOD (SetFileNameLabel) (THIS_ LPCWSTR pszLabel) PURE;
+	STDMETHOD (GetResult) (THIS_ IShellItem **ppsi) PURE;
+	STDMETHOD (AddPlace) (THIS_ IShellItem *psi, FDAP fdap) PURE;
+	STDMETHOD (SetDefaultExtension) (THIS_ LPCWSTR pszDefaultExtension) PURE;
+	STDMETHOD (Close) (THIS_ HRESULT hr) PURE;
+	STDMETHOD (SetClientGuid) (THIS_ REFGUID guid) PURE;
+	STDMETHOD (ClearClientData) (THIS) PURE;
+	STDMETHOD (SetFilter) (THIS_ IShellItemFilter *pFilter) PURE;
+	// IFileOpenDialog
+	STDMETHOD (GetResults) (THIS_ IShellItemArray **ppenum) PURE;
+	STDMETHOD (GetSelectedItems) (THIS_ IShellItemArray **ppsai) PURE;
+};
+#undef INTERFACE
+
+#endif // __MINGW32__
+#endif // __GNUC__
+#endif // WIN32
+
+#endif // BACKEND_WIN32_DIALOGS_MINGW_H
diff --git a/backends/dialogs/win32/win32-dialogs.cpp b/backends/dialogs/win32/win32-dialogs.cpp
index b7d41cf..4c2e908 100644
--- a/backends/dialogs/win32/win32-dialogs.cpp
+++ b/backends/dialogs/win32/win32-dialogs.cpp
@@ -20,16 +20,48 @@
  *
  */
 
+// We cannot use common/scummsys.h directly as it will include
+// windows.h and we need to do it by hand to allow excluded functions
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
 #if defined(WIN32) && defined(USE_SYSDIALOGS)
 
-// Disable symbol overrides so that we can use system headers.
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
+// HACK: To get __MINGW64_VERSION_foo defines we need to manually include
+// _mingw.h in this file because we do not include any system headers at this
+// point on purpose. The defines are required to detect whether this is a
+// classic MinGW toolchain or a MinGW-w64 based one.
+#if defined(__MINGW32__)
+#include <_mingw.h>
+#endif
+
+// Needed for dialog functions
+// HACK: MinGW-w64 based toolchains include the symbols we require in their
+// headers. The 32 bit incarnation only defines __MINGW32__. This leads to
+// build breakage due to clashes with our compat header. Luckily MinGW-w64
+// based toolchains define __MINGW64_VERSION_foo macros inside _mingw.h,
+// which is included from all system headers. Thus we abuse that to detect
+// them.
+#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+	#include "backends/dialogs/win32/mingw-compat.h"
+#else
+	// We use functionality introduced with Vista in this file.
+	// To assure that including the respective system headers gives us all
+	// required definitions we set Vista as minimum version we target.
+	// See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745%28v=vs.85%29.aspx#macros_for_conditional_declarations
+	#include <sdkddkver.h>
+	#undef _WIN32_WINNT
+	#define _WIN32_WINNT _WIN32_WINNT_VISTA
+
+	#define WIN32_LEAN_AND_MEAN
+	#include <windows.h>
+	#if defined(ARRAYSIZE)
+		#undef ARRAYSIZE
+	#endif
+#endif
 
-#include <windows.h>
 #include <shlobj.h>
-#if defined(ARRAYSIZE)
-#undef ARRAYSIZE
-#endif
 
 #include "common/scummsys.h"
 
@@ -61,7 +93,8 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch
 	HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog,
 	                              NULL,
 	                              CLSCTX_INPROC_SERVER,
-	                              IID_PPV_ARGS(&dialog));
+	                              IID_IFileOpenDialog,
+	                              reinterpret_cast<void **> (&(dialog)));
 
 	if (SUCCEEDED(hr)) {
 		// If in fullscreen mode, switch to windowed mode


Commit: 9aef3dd8a7988b94d9e5cae6dae11a9ec6320930
    https://github.com/scummvm/scummvm/commit/9aef3dd8a7988b94d9e5cae6dae11a9ec6320930
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
WIN32: Respect browser_lastpath setting

Changed paths:
    backends/dialogs/win32/win32-dialogs.cpp


diff --git a/backends/dialogs/win32/win32-dialogs.cpp b/backends/dialogs/win32/win32-dialogs.cpp
index 4c2e908..e34a08c 100644
--- a/backends/dialogs/win32/win32-dialogs.cpp
+++ b/backends/dialogs/win32/win32-dialogs.cpp
@@ -20,8 +20,8 @@
  *
  */
 
-// We cannot use common/scummsys.h directly as it will include
-// windows.h and we need to do it by hand to allow excluded functions
+ // We cannot use common/scummsys.h directly as it will include
+ // windows.h and we need to do it by hand to allow excluded functions
 #if defined(HAVE_CONFIG_H)
 #include "config.h"
 #endif
@@ -44,21 +44,21 @@
 // which is included from all system headers. Thus we abuse that to detect
 // them.
 #if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
-	#include "backends/dialogs/win32/mingw-compat.h"
+#include "backends/dialogs/win32/mingw-compat.h"
 #else
 	// We use functionality introduced with Vista in this file.
 	// To assure that including the respective system headers gives us all
 	// required definitions we set Vista as minimum version we target.
 	// See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745%28v=vs.85%29.aspx#macros_for_conditional_declarations
-	#include <sdkddkver.h>
-	#undef _WIN32_WINNT
-	#define _WIN32_WINNT _WIN32_WINNT_VISTA
-
-	#define WIN32_LEAN_AND_MEAN
-	#include <windows.h>
-	#if defined(ARRAYSIZE)
-		#undef ARRAYSIZE
-	#endif
+#include <sdkddkver.h>
+#undef _WIN32_WINNT
+#define _WIN32_WINNT _WIN32_WINNT_VISTA
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#if defined(ARRAYSIZE)
+#undef ARRAYSIZE
+#endif
 #endif
 
 #include <shlobj.h>
@@ -82,6 +82,29 @@ Win32DialogManager::~Win32DialogManager() {
 	CoUninitialize();
 }
 
+// Wrapper for old Windows versions
+HRESULT winCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) {
+	typedef HRESULT(WINAPI *SHFunc)(PCWSTR, IBindCtx *, REFIID, void **);
+
+	SHFunc func = (SHFunc)GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "SHCreateItemFromParsingName");
+	if (func == NULL)
+		return E_NOTIMPL;
+
+	return func(pszPath, pbc, riid, ppv);
+}
+
+HRESULT getShellPath(IShellItem *item, Common::String &path) {
+	LPWSTR name = NULL;
+	HRESULT hr = item->GetDisplayName(SIGDN_FILESYSPATH, &name);
+	if (SUCCEEDED(hr)) {
+		char *str = Win32::unicodeToAnsi(name);
+		path = Common::String(str);
+		CoTaskMemFree(name);
+		delete[] str;
+	}
+	return hr;
+}
+
 Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser) {
 	DialogResult result = kDialogError;
 
@@ -91,10 +114,10 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch
 
 	IFileOpenDialog *dialog = NULL;
 	HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog,
-	                              NULL,
-	                              CLSCTX_INPROC_SERVER,
-	                              IID_IFileOpenDialog,
-	                              reinterpret_cast<void **> (&(dialog)));
+		NULL,
+		CLSCTX_INPROC_SERVER,
+		IID_IFileOpenDialog,
+		reinterpret_cast<void **> (&(dialog)));
 
 	if (SUCCEEDED(hr)) {
 		// If in fullscreen mode, switch to windowed mode
@@ -126,30 +149,46 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch
 		hr = dialog->SetOkButtonLabel(str);
 		delete[] str;
 
+		if (ConfMan.hasKey("browser_lastpath")) {
+			str = Win32::ansiToUnicode(ConfMan.get("browser_lastpath").c_str());
+			IShellItem *item = NULL;
+			hr = winCreateItemFromParsingName(str, NULL, IID_IShellItem, reinterpret_cast<void **> (&(item)));
+			if (SUCCEEDED(hr)) {
+				hr = dialog->SetDefaultFolder(item);
+			}
+			delete[] str;
+		}
+
 		// Show dialog
 		hr = dialog->Show(_window->getHwnd());
 
 		if (SUCCEEDED(hr)) {
-			IShellItem *selectedItem = NULL;
-			LPWSTR path = NULL;
-
 			// Get the selection from the user
+			IShellItem *selectedItem = NULL;
 			hr = dialog->GetResult(&selectedItem);
-
 			if (SUCCEEDED(hr)) {
-				hr = selectedItem->GetDisplayName(SIGDN_FILESYSPATH, &path);
-
+				Common::String path;
+				hr = getShellPath(selectedItem, path);
 				if (SUCCEEDED(hr)) {
-					char *str = Win32::unicodeToAnsi(path);
-					choice = Common::FSNode(str);
+					choice = Common::FSNode(path);
 					result = kDialogOk;
-					CoTaskMemFree(path);
-					delete[] str;
 				}
-
 				selectedItem->Release();
 			}
-		} else if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) {
+
+			// Save last path
+			IShellItem *lastFolder = NULL;
+			hr = dialog->GetFolder(&lastFolder);
+			if (SUCCEEDED(hr)) {
+				Common::String path;
+				hr = getShellPath(lastFolder, path);
+				if (SUCCEEDED(hr)) {
+					ConfMan.set("browser_lastpath", path);
+				}
+				lastFolder->Release();
+			}
+		}
+		else if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) {
 			result = kDialogCancel;
 		}
 


Commit: ac957852c824ae16bfd07a57f1dacc4ba571ab78
    https://github.com/scummvm/scummvm/commit/ac957852c824ae16bfd07a57f1dacc4ba571ab78
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
I18N: Update POTFILES

Add new DialogManager files

Changed paths:
    po/POTFILES


diff --git a/po/POTFILES b/po/POTFILES
index df71f61..c49b8f8 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -2,7 +2,6 @@
 
 gui/about.cpp
 gui/browser.cpp
-gui/browser_osx.mm
 gui/chooser.cpp
 gui/downloaddialog.cpp
 gui/editgamedialog.cpp
@@ -52,6 +51,8 @@ audio/softsynth/pcspk.cpp
 audio/softsynth/sid.cpp
 
 backends/cloud/storage.cpp
+backends/dialogs/macosx/macosx-dialogs.mm
+backends/dialogs/win32/win32-dialogs.cpp
 backends/events/default/default-events.cpp
 backends/events/gph/gph-events.cpp
 backends/events/maemosdl/maemosdl-events.cpp


Commit: 7552b0c008b6a5ca3e128ba2691f7319dc3b2349
    https://github.com/scummvm/scummvm/commit/7552b0c008b6a5ca3e128ba2691f7319dc3b2349
Author: SupSuper (supsuper at gmail.com)
Date: 2018-12-16T10:48:13Z

Commit Message:
GUI: Store title String instead of unsafe pointer

Changed paths:
    gui/browser.cpp
    gui/browser.h


diff --git a/gui/browser.cpp b/gui/browser.cpp
index 4c8f0d1..820e773 100644
--- a/gui/browser.cpp
+++ b/gui/browser.cpp
@@ -89,7 +89,7 @@ int BrowserDialog::runModal() {
 	Common::DialogManager *dialogManager = g_system->getDialogManager();
 	if (dialogManager) {
 		if (ConfMan.getBool("gui_browser_native", Common::ConfigManager::kApplicationDomain)) {
-			Common::DialogManager::DialogResult result = dialogManager->showFileBrowser(_title, _choice, _isDirBrowser);
+			Common::DialogManager::DialogResult result = dialogManager->showFileBrowser(_title.c_str(), _choice, _isDirBrowser);
 			if (result != Common::DialogManager::kDialogError) {
 				return result;
 			}
diff --git a/gui/browser.h b/gui/browser.h
index 2ef9a9c..37e18d3 100644
--- a/gui/browser.h
+++ b/gui/browser.h
@@ -25,6 +25,7 @@
 
 #include "gui/dialog.h"
 #include "common/fs.h"
+#include "common/str.h"
 
 namespace GUI {
 
@@ -53,7 +54,7 @@ protected:
 	CheckboxWidget *_showHiddenWidget;
 
 	Common::FSNode	_choice;
-	const char		*_title;
+	Common::String	_title;
 	bool			_isDirBrowser;
 
 	void updateListing();





More information about the Scummvm-git-logs mailing list