From 93695a9dcff544707ba1a02321c4a20034effc99 Mon Sep 17 00:00:00 2001 From: SupSuper Date: Thu, 22 Nov 2018 21:49:42 +0000 Subject: WIN32: Fix dialog compilation under MinGW --- backends/dialogs/win32/mingw-compat.h | 170 +++++++++++++++++++++++++++++++ backends/dialogs/win32/win32-dialogs.cpp | 47 +++++++-- 2 files changed, 210 insertions(+), 7 deletions(-) create mode 100644 backends/dialogs/win32/mingw-compat.h (limited to 'backends/dialogs/win32') diff --git a/backends/dialogs/win32/mingw-compat.h b/backends/dialogs/win32/mingw-compat.h new file mode 100644 index 0000000000..e9c55a106d --- /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 +#include +#include +#include +#include + +// 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 b7d41cfa01..4c2e908f3c 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 + #undef _WIN32_WINNT + #define _WIN32_WINNT _WIN32_WINNT_VISTA + + #define WIN32_LEAN_AND_MEAN + #include + #if defined(ARRAYSIZE) + #undef ARRAYSIZE + #endif +#endif -#include #include -#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 (&(dialog))); if (SUCCEEDED(hr)) { // If in fullscreen mode, switch to windowed mode -- cgit v1.2.3