aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/module.mk6
-rw-r--r--backends/platform/sdl/posix/posix.cpp11
-rw-r--r--backends/platform/sdl/sdl.cpp21
-rw-r--r--backends/platform/sdl/sdl.h4
-rw-r--r--backends/platform/sdl/win32/win32.cpp8
-rw-r--r--backends/taskbar/unity/unity-taskbar.cpp110
-rw-r--r--backends/taskbar/unity/unity-taskbar.h57
-rw-r--r--backends/taskbar/win32/mingw-compat.h142
-rw-r--r--backends/taskbar/win32/win32-taskbar.cpp272
-rw-r--r--backends/taskbar/win32/win32-taskbar.h66
-rw-r--r--common/system.cpp9
-rw-r--r--common/system.h24
-rw-r--r--common/taskbar.h133
-rwxr-xr-xconfigure75
-rw-r--r--devtools/create_project/create_project.cpp6
-rw-r--r--gui/massadd.cpp23
-rw-r--r--gui/massadd.h1
17 files changed, 961 insertions, 7 deletions
diff --git a/backends/module.mk b/backends/module.mk
index 8063bcf619..e568002d40 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -75,7 +75,8 @@ MODULE_OBJS += \
fs/posix/posix-fs.o \
fs/posix/posix-fs-factory.o \
plugins/posix/posix-provider.o \
- saves/posix/posix-saves.o
+ saves/posix/posix-saves.o \
+ taskbar/unity/unity-taskbar.o
endif
ifdef MACOSX
@@ -89,7 +90,8 @@ MODULE_OBJS += \
fs/windows/windows-fs.o \
fs/windows/windows-fs-factory.o \
midi/windows.o \
- plugins/win32/win32-provider.o
+ plugins/win32/win32-provider.o \
+ taskbar/win32/win32-taskbar.o
endif
ifdef AMIGAOS
diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp
index d757186134..05c779a4e0 100644
--- a/backends/platform/sdl/posix/posix.cpp
+++ b/backends/platform/sdl/posix/posix.cpp
@@ -33,6 +33,7 @@
#include "backends/platform/sdl/posix/posix.h"
#include "backends/saves/posix/posix-saves.h"
#include "backends/fs/posix/posix-fs-factory.h"
+#include "backends/taskbar/unity/unity-taskbar.h"
#include <errno.h>
#include <sys/stat.h>
@@ -49,6 +50,11 @@ void OSystem_POSIX::init() {
// Initialze File System Factory
_fsFactory = new POSIXFilesystemFactory();
+#if defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+ // Initialize taskbar manager
+ _taskbarManager = new UnityTaskbarManager();
+#endif
+
// Invoke parent implementation of this method
OSystem_SDL::init();
}
@@ -60,6 +66,11 @@ void OSystem_POSIX::initBackend() {
// Invoke parent implementation of this method
OSystem_SDL::initBackend();
+
+#if defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+ // Register the taskbar manager as an event source (this is necessary for the glib event loop to be run)
+ _eventManager->getEventDispatcher()->registerSource((UnityTaskbarManager *)_taskbarManager, false);
+#endif
}
bool OSystem_POSIX::hasFeature(Feature f) {
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index ecaeabf4e1..3f85b1a564 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -31,6 +31,7 @@
#include "backends/platform/sdl/sdl.h"
#include "common/config-manager.h"
#include "common/EventRecorder.h"
+#include "common/taskbar.h"
#include "common/textconsole.h"
#include "backends/saves/default/default-saves.h"
@@ -125,6 +126,11 @@ void OSystem_SDL::init() {
if (_timerManager == 0)
_timerManager = new SdlTimerManager();
+#if defined(USE_TASKBAR)
+ if (_taskbarManager == 0)
+ _taskbarManager = new Common::TaskbarManager();
+#endif
+
#ifdef USE_OPENGL
// Setup a list with both SDL and OpenGL graphics modes
setupGraphicsModes();
@@ -205,6 +211,21 @@ void OSystem_SDL::initBackend() {
}
+#if defined(USE_TASKBAR)
+void OSystem_SDL::engineInit() {
+ // Add the started engine to the list of recent tasks
+ _taskbarManager->addRecent(ConfMan.getActiveDomainName(), ConfMan.get("description"));
+
+ // Set the overlay icon the current running engine
+ _taskbarManager->setOverlayIcon(ConfMan.getActiveDomainName(), ConfMan.get("description"));
+}
+
+void OSystem_SDL::engineDone() {
+ // Remove overlay icon
+ _taskbarManager->setOverlayIcon("", "");
+}
+#endif
+
void OSystem_SDL::initSDL() {
// Check if SDL has not been initialized
if (!_initedSDL) {
diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h
index 707ad8bc55..395b2b3aac 100644
--- a/backends/platform/sdl/sdl.h
+++ b/backends/platform/sdl/sdl.h
@@ -54,6 +54,10 @@ public:
// Override functions from ModularBackend and OSystem
virtual void initBackend();
+#if defined(USE_TASKBAR)
+ virtual void engineInit();
+ virtual void engineDone();
+#endif
virtual Common::HardwareKeySet *getHardwareKeySet();
virtual void quit();
virtual void fatalError();
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 432f7077ae..5b02a20abc 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -36,6 +36,7 @@
#include "backends/platform/sdl/win32/win32.h"
#include "backends/fs/windows/windows-fs-factory.h"
+#include "backends/taskbar/win32/win32-taskbar.h"
#include "common/memstream.h"
@@ -81,9 +82,14 @@ void OSystem_Win32::init() {
}
#endif
- // Initialze File System Factory
+ // Initialize File System Factory
_fsFactory = new WindowsFilesystemFactory();
+#if defined(USE_TASKBAR)
+ // Initialize taskbar manager
+ _taskbarManager = new Win32TaskbarManager();
+#endif
+
// Invoke parent implementation of this method
OSystem_SDL::init();
}
diff --git a/backends/taskbar/unity/unity-taskbar.cpp b/backends/taskbar/unity/unity-taskbar.cpp
new file mode 100644
index 0000000000..49c56b746d
--- /dev/null
+++ b/backends/taskbar/unity/unity-taskbar.cpp
@@ -0,0 +1,110 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(UNIX) && defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+
+#include "backends/taskbar/unity/unity-taskbar.h"
+
+#include "common/textconsole.h"
+
+UnityTaskbarManager::UnityTaskbarManager() {
+ g_type_init();
+
+ _loop = g_main_loop_new(NULL, FALSE);
+
+ _launcher = unity_launcher_entry_get_for_desktop_id("scummvm.desktop");
+}
+
+UnityTaskbarManager::~UnityTaskbarManager() {
+ g_main_loop_unref(_loop);
+ _loop = NULL;
+}
+
+void UnityTaskbarManager::setProgressValue(int completed, int total) {
+ if (_launcher == NULL)
+ return;
+
+ double percentage = (double)completed / (double)total;
+ unity_launcher_entry_set_progress(_launcher, percentage);
+ unity_launcher_entry_set_progress_visible(_launcher, TRUE);
+}
+
+void UnityTaskbarManager::setProgressState(TaskbarProgressState state) {
+ if (_launcher == NULL)
+ return;
+
+ switch (state) {
+ default:
+ warning("[UnityTaskbarManager::setProgressState] Unknown state / Not implemented (%d)", state);
+ // fallback to noprogress state
+
+ case kTaskbarNoProgress:
+ unity_launcher_entry_set_progress_visible(_launcher, FALSE);
+ break;
+
+ // Unity only support two progress states as of 3.0: visible or not visible
+ // We show progress in all of those states
+ case kTaskbarIndeterminate:
+ case kTaskbarNormal:
+ case kTaskbarError:
+ case kTaskbarPaused:
+ unity_launcher_entry_set_progress_visible(_launcher, TRUE);
+ break;
+ }
+}
+
+void UnityTaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
+ warning("[UnityTaskbarManager::addRecent] Not implemented");
+}
+
+void UnityTaskbarManager::setCount(int count) {
+ if (_launcher == NULL)
+ return;
+
+ unity_launcher_entry_set_count(_launcher, count);
+
+ unity_launcher_entry_set_count_visible(_launcher, (count == 0) ? FALSE : TRUE);
+}
+
+// Unity requires the glib event loop to the run to function properly
+// as events are sent asynchronously
+bool UnityTaskbarManager::pollEvent(Common::Event &event) {
+ if (!_loop)
+ return false;
+
+ // Get context
+ GMainContext *context = g_main_loop_get_context(_loop);
+ if (!context)
+ return false;
+
+ // Dispatch events
+ g_main_context_iteration(context, FALSE);
+
+ return false;
+}
+
+#endif
diff --git a/backends/taskbar/unity/unity-taskbar.h b/backends/taskbar/unity/unity-taskbar.h
new file mode 100644
index 0000000000..9f14b44d8f
--- /dev/null
+++ b/backends/taskbar/unity/unity-taskbar.h
@@ -0,0 +1,57 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKEND_UNITY_TASKBAR_H
+#define BACKEND_UNITY_TASKBAR_H
+
+#if defined(UNIX) && defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+
+#include "common/events.h"
+#include "common/str.h"
+#include "common/taskbar.h"
+
+#include <unity.h>
+
+class UnityTaskbarManager : public Common::TaskbarManager, public Common::EventSource {
+public:
+ UnityTaskbarManager();
+ virtual ~UnityTaskbarManager();
+
+ virtual void setProgressValue(int completed, int total);
+ virtual void setProgressState(TaskbarProgressState state);
+ virtual void addRecent(const Common::String &name, const Common::String &description);
+ virtual void setCount(int count);
+
+ // Implementation of the EventSource interface
+ virtual bool pollEvent(Common::Event &event);
+
+private:
+ GMainLoop *_loop;
+ UnityLauncherEntry *_launcher;
+};
+
+#endif
+
+#endif // BACKEND_UNITY_TASKBAR_H
diff --git a/backends/taskbar/win32/mingw-compat.h b/backends/taskbar/win32/mingw-compat.h
new file mode 100644
index 0000000000..06968b62ff
--- /dev/null
+++ b/backends/taskbar/win32/mingw-compat.h
@@ -0,0 +1,142 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// TODO: Remove header when the latest changes to the Windows SDK have been integrated into MingW
+// For reference, the interface definitions here are imported the SDK headers and from the
+// EcWin7 project (https://code.google.com/p/dukto/)
+
+#ifndef BACKEND_WIN32_TASKBAR_MINGW_H
+#define BACKEND_WIN32_TASKBAR_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>
+#define CMIC_MASK_ASYNCOK SEE_MASK_ASYNCOK
+
+// Taskbar GUID definitions
+DEFINE_GUID(CLSID_TaskbarList,0x56fdf344,0xfd6d,0x11d0,0x95,0x8a,0x0,0x60,0x97,0xc9,0xa0,0x90);
+DEFINE_GUID(IID_ITaskbarList3,0xea1afb91,0x9e28,0x4b86,0x90,0xE9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf);
+DEFINE_GUID(IID_IPropertyStore,0x886d8eeb,0x8cf2,0x4446,0x8d,0x02,0xcd,0xba,0x1d,0xbd,0xcf,0x99);
+
+// Property key
+typedef struct _tagpropertykey {
+ GUID fmtid;
+ DWORD pid;
+} PROPERTYKEY;
+
+#define REFPROPERTYKEY const PROPERTYKEY &
+
+typedef struct tagPROPVARIANT PROPVARIANT;
+#define REFPROPVARIANT const PROPVARIANT &
+
+// Property store
+DECLARE_INTERFACE_(IPropertyStore, IUnknown) {
+ STDMETHOD (GetCount) (DWORD *cProps) PURE;
+ STDMETHOD (GetAt) (DWORD iProp, PROPERTYKEY *pkey) PURE;
+ STDMETHOD (GetValue) (REFPROPERTYKEY key, PROPVARIANT *pv) PURE;
+ STDMETHOD (SetValue) (REFPROPERTYKEY key, REFPROPVARIANT propvar) PURE;
+ STDMETHOD (Commit) (void) PURE;
+};
+typedef IPropertyStore *LPIPropertyStore;
+
+// Mingw-specific defines for taskbar integration
+typedef enum THUMBBUTTONMASK {
+ THB_BITMAP = 0x1,
+ THB_ICON = 0x2,
+ THB_TOOLTIP = 0x4,
+ THB_FLAGS = 0x8
+} THUMBBUTTONMASK;
+
+typedef enum THUMBBUTTONFLAGS {
+ THBF_ENABLED = 0,
+ THBF_DISABLED = 0x1,
+ THBF_DISMISSONCLICK = 0x2,
+ THBF_NOBACKGROUND = 0x4,
+ THBF_HIDDEN = 0x8,
+ THBF_NONINTERACTIVE = 0x10
+} THUMBBUTTONFLAGS;
+
+typedef struct THUMBBUTTON {
+ THUMBBUTTONMASK dwMask;
+ UINT iId;
+ UINT iBitmap;
+ HICON hIcon;
+ WCHAR szTip[260];
+ THUMBBUTTONFLAGS dwFlags;
+} THUMBBUTTON;
+typedef struct THUMBBUTTON *LPTHUMBBUTTON;
+
+typedef enum TBPFLAG {
+ TBPF_NOPROGRESS = 0,
+ TBPF_INDETERMINATE = 0x1,
+ TBPF_NORMAL = 0x2,
+ TBPF_ERROR = 0x4,
+ TBPF_PAUSED = 0x8
+} TBPFLAG;
+
+// Taskbar interface
+DECLARE_INTERFACE_(ITaskbarList3, IUnknown) {
+ // IUnknown
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
+ STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG,Release) (THIS) PURE;
+ // ITaskbarList
+ STDMETHOD(HrInit) (THIS) PURE;
+ STDMETHOD(AddTab) (THIS_ HWND hwnd) PURE;
+ STDMETHOD(DeleteTab) (THIS_ HWND hwnd) PURE;
+ STDMETHOD(ActivateTab) (THIS_ HWND hwnd) PURE;
+ STDMETHOD(SetActiveAlt) (THIS_ HWND hwnd) PURE;
+ STDMETHOD (MarkFullscreenWindow) (THIS_ HWND hwnd, int fFullscreen) PURE;
+ // ITaskbarList3
+ STDMETHOD (SetProgressValue) (THIS_ HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) PURE;
+ STDMETHOD (SetProgressState) (THIS_ HWND hwnd, TBPFLAG tbpFlags) PURE;
+ STDMETHOD (RegisterTab) (THIS_ HWND hwndTab, HWND hwndMDI) PURE;
+ STDMETHOD (UnregisterTab) (THIS_ HWND hwndTab) PURE;
+ STDMETHOD (SetTabOrder) (THIS_ HWND hwndTab, HWND hwndInsertBefore) PURE;
+ STDMETHOD (SetTabActive) (THIS_ HWND hwndTab, HWND hwndMDI, DWORD dwReserved) PURE;
+ STDMETHOD (ThumbBarAddButtons) (THIS_ HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) PURE;
+ STDMETHOD (ThumbBarUpdateButtons) (THIS_ HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) PURE;
+ STDMETHOD (ThumbBarSetImageList) (THIS_ HWND hwnd, HIMAGELIST himl) PURE;
+ STDMETHOD (SetOverlayIcon) (THIS_ HWND hwnd, HICON hIcon, LPCWSTR pszDescription) PURE;
+ STDMETHOD (SetThumbnailTooltip) (THIS_ HWND hwnd, LPCWSTR pszTip) PURE;
+ STDMETHOD (SetThumbnailClip) (THIS_ HWND hwnd, RECT *prcClip) PURE;
+};
+
+typedef ITaskbarList3 *LPITaskbarList3;
+
+#endif // __MINGW32__
+#endif // __GNUC__
+#endif // WIN32
+
+#endif // BACKEND_WIN32_TASKBAR_MINGW_H
diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp
new file mode 100644
index 0000000000..0cfd81e3f2
--- /dev/null
+++ b/backends/taskbar/win32/win32-taskbar.cpp
@@ -0,0 +1,272 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// 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_TASKBAR)
+
+// Needed for taskbar functions
+#if defined(__GNUC__)
+#ifdef __MINGW32__
+ #include "backends/taskbar/win32/mingw-compat.h"
+#else
+ #error Only compilation with MingW is supported
+#endif
+#else
+ // We need certain functions that are excluded by default
+ #undef NONLS
+ #undef NOICONS
+ #include <windows.h>
+ #if defined(ARRAYSIZE)
+ #undef ARRAYSIZE
+ #endif
+
+ // Default MSVC headers for ITaskbarList3 and IShellLink
+ #include <SDKDDKVer.h>
+#endif
+#include <shlobj.h>
+
+// For HWND
+#include <SDL_syswm.h>
+
+#include "common/scummsys.h"
+
+#include "backends/taskbar/win32/win32-taskbar.h"
+
+#include "common/config-manager.h"
+#include "common/textconsole.h"
+#include "common/file.h"
+
+// 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() {
+ // Do nothing if not running on Windows 7 or later
+ if (!isWin7OrLater())
+ return;
+
+ CoInitialize(NULL);
+
+ // Try creating instance (on fail, _taskbar will contain NULL)
+ HRESULT hr = CoCreateInstance(CLSID_TaskbarList,
+ 0,
+ CLSCTX_INPROC_SERVER,
+ IID_ITaskbarList3,
+ reinterpret_cast<void**> (&(_taskbar)));
+
+ if (SUCCEEDED(hr)) {
+ // Initialize taskbar object
+ if (FAILED(_taskbar->HrInit())) {
+ _taskbar->Release();
+ _taskbar = NULL;
+ }
+ } else {
+ warning("[Win32TaskbarManager::init] Cannot create taskbar instance");
+ }
+}
+
+Win32TaskbarManager::~Win32TaskbarManager() {
+ if (_taskbar)
+ _taskbar->Release();
+ _taskbar = NULL;
+
+ CoUninitialize();
+}
+
+void Win32TaskbarManager::setOverlayIcon(const Common::String &name, const Common::String &description) {
+ //warning("[Win32TaskbarManager::setOverlayIcon] Setting overlay icon to: %s (%s)", name.c_str(), description.c_str());
+
+ if (_taskbar == NULL)
+ return;
+
+ if (name.empty()) {
+ _taskbar->SetOverlayIcon(getHwnd(), NULL, L"");
+ return;
+ }
+
+ // Compute full icon path
+ Common::String path = getIconPath(name);
+ if (path.empty())
+ return;
+
+ HICON pIcon = (HICON)::LoadImage(NULL, path.c_str(), IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
+ if (!pIcon) {
+ warning("[Win32TaskbarManager::setOverlayIcon] Cannot load icon!");
+ return;
+ }
+
+ // Sets the overlay icon
+ LPWSTR desc = ansiToUnicode(description.c_str());
+ _taskbar->SetOverlayIcon(getHwnd(), pIcon, desc);
+
+ DestroyIcon(pIcon);
+
+ delete[] desc;
+}
+
+void Win32TaskbarManager::setProgressValue(int completed, int total) {
+ if (_taskbar == NULL)
+ return;
+
+ _taskbar->SetProgressValue(getHwnd(), completed, total);
+}
+
+void Win32TaskbarManager::setProgressState(TaskbarProgressState state) {
+ if (_taskbar == NULL)
+ return;
+
+ _taskbar->SetProgressState(getHwnd(), (TBPFLAG)state);
+}
+
+void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
+ //warning("[Win32TaskbarManager::addRecent] Adding recent list entry: %s (%s)", name.c_str(), description.c_str());
+
+ if (_taskbar == NULL)
+ return;
+
+ // ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface.
+ IShellLinkW *link;
+
+ // Get the ScummVM executable path.
+ WCHAR path[MAX_PATH];
+ GetModuleFileNameW(NULL, path, MAX_PATH);
+
+ // 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());
+
+ // Set link properties.
+ link->SetPath(path);
+ link->SetArguments(game);
+
+ Common::String iconPath = getIconPath(name);
+ if (iconPath.empty()) {
+ link->SetIconLocation(path, 0); // No game-specific icon available
+ } else {
+ LPWSTR icon = ansiToUnicode(iconPath.c_str());
+
+ link->SetIconLocation(icon, 0);
+
+ delete[] icon;
+ }
+
+ // The link's display name must be set via property store.
+ IPropertyStore* propStore;
+ HRESULT hr = link->QueryInterface(IID_IPropertyStore, reinterpret_cast<void**> (&(propStore)));
+ if (SUCCEEDED(hr)) {
+ PROPVARIANT pv;
+ pv.vt = VT_LPWSTR;
+ pv.pwszVal = desc;
+
+ hr = propStore->SetValue(PKEY_Title, pv);
+
+ propStore->Commit();
+ propStore->Release();
+ }
+
+ // SHAddToRecentDocs will cause the games to be added to the Recent list, allowing the user to pin them.
+ SHAddToRecentDocs(SHARD_LINK, link);
+ link->Release();
+ delete[] game;
+ delete[] desc;
+ }
+}
+
+Common::String Win32TaskbarManager::getIconPath(Common::String target) {
+ // We first try to look for a iconspath configuration variable then
+ // fallback to the extra path
+ //
+ // Icons can be either in a subfolder named "icons" or directly in the path
+
+ Common::String iconsPath = ConfMan.get("iconspath");
+ Common::String extraPath = ConfMan.get("extrapath");
+
+#define TRY_ICON_PATH(path) { \
+ Common::FSNode node((path)); \
+ if (node.exists()) \
+ return (path); \
+}
+
+ if (!iconsPath.empty()) {
+ TRY_ICON_PATH(iconsPath + "/" + target + ".ico");
+ TRY_ICON_PATH(iconsPath + "/" + ConfMan.get("gameid") + ".ico");
+ TRY_ICON_PATH(iconsPath + "/icons/" + target + ".ico");
+ TRY_ICON_PATH(iconsPath + "/icons/" + ConfMan.get("gameid") + ".ico");
+ }
+
+ if (!extraPath.empty()) {
+ TRY_ICON_PATH(extraPath + "/" + target + ".ico");
+ TRY_ICON_PATH(extraPath + "/" + ConfMan.get("gameid") + ".ico");
+ TRY_ICON_PATH(extraPath + "/icons/" + target + ".ico");
+ TRY_ICON_PATH(extraPath + "/icons/" + ConfMan.get("gameid") + ".ico");
+ }
+
+ return "";
+}
+
+bool Win32TaskbarManager::isWin7OrLater() {
+ OSVERSIONINFOEX versionInfo;
+ DWORDLONG conditionMask = 0;
+
+ ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
+ versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ versionInfo.dwMajorVersion = 6;
+ versionInfo.dwMinorVersion = 1;
+
+ VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+ VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
+
+ return VerifyVersionInfo(&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;
+ SDL_VERSION(&wmi.version);
+
+ if(!SDL_GetWMInfo(&wmi))
+ return NULL;
+
+ return wmi.window;
+}
+
+#endif
diff --git a/backends/taskbar/win32/win32-taskbar.h b/backends/taskbar/win32/win32-taskbar.h
new file mode 100644
index 0000000000..3415a79bd7
--- /dev/null
+++ b/backends/taskbar/win32/win32-taskbar.h
@@ -0,0 +1,66 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKEND_WIN32_TASKBAR_H
+#define BACKEND_WIN32_TASKBAR_H
+
+#if defined(WIN32) && defined(USE_TASKBAR)
+
+#include "common/str.h"
+#include "common/taskbar.h"
+
+struct ITaskbarList3;
+
+class Win32TaskbarManager : public Common::TaskbarManager {
+public:
+ Win32TaskbarManager();
+ virtual ~Win32TaskbarManager();
+
+ virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
+ virtual void setProgressValue(int completed, int total);
+ virtual void setProgressState(TaskbarProgressState state);
+ virtual void addRecent(const Common::String &name, const Common::String &description);
+
+private:
+ ITaskbarList3 *_taskbar;
+
+ /**
+ * Get the path to an icon for the game
+ *
+ * @param target The game target
+ *
+ * @return The icon path (or "" if no icon was found)
+ */
+ Common::String getIconPath(Common::String target);
+
+ // Helper functions
+ bool isWin7OrLater();
+ LPWSTR ansiToUnicode(const char *s);
+ HWND getHwnd();
+};
+
+#endif
+
+#endif // BACKEND_WIN32_TASKBAR_H
diff --git a/common/system.cpp b/common/system.cpp
index 1645a6be10..8d5bfd39cd 100644
--- a/common/system.cpp
+++ b/common/system.cpp
@@ -27,6 +27,7 @@
#include "common/fs.h"
#include "common/savefile.h"
#include "common/str.h"
+#include "common/taskbar.h"
#include "common/textconsole.h"
#include "backends/audiocd/default/default-audiocd.h"
@@ -40,6 +41,9 @@ OSystem::OSystem() {
_eventManager = 0;
_timerManager = 0;
_savefileManager = 0;
+#if defined(USE_TASKBAR)
+ _taskbarManager = 0;
+#endif
_fsFactory = 0;
}
@@ -53,6 +57,11 @@ OSystem::~OSystem() {
delete _timerManager;
_timerManager = 0;
+#if defined(USE_TASKBAR)
+ delete _taskbarManager;
+ _taskbarManager = 0;
+#endif
+
delete _savefileManager;
_savefileManager = 0;
diff --git a/common/system.h b/common/system.h
index 3e740ff0c1..15fbe386b1 100644
--- a/common/system.h
+++ b/common/system.h
@@ -42,6 +42,9 @@ struct Rect;
class SaveFileManager;
class SearchSet;
class String;
+#if defined(USE_TASKBAR)
+class TaskbarManager;
+#endif
class TimerManager;
class SeekableReadStream;
class WriteStream;
@@ -149,6 +152,15 @@ protected:
*/
Common::SaveFileManager *_savefileManager;
+#if defined(USE_TASKBAR)
+ /**
+ * No default value is provided for _savefileManager by OSystem.
+ *
+ * @note _savefileManager is deleted by the OSystem destructor.
+ */
+ Common::TaskbarManager *_taskbarManager;
+#endif
+
/**
* No default value is provided for _fsFactory by OSystem.
*
@@ -1047,6 +1059,18 @@ public:
return _savefileManager;
}
+#if defined(USE_TASKBAR)
+ /**
+ * Returns the TaskbarManager, used to handle progress bars,
+ * icon overlay, tasks and recent items list on the taskbar.
+ *
+ * @return the TaskbarManager for the current architecture
+ */
+ virtual Common::TaskbarManager *getTaskbarManager() {
+ return _taskbarManager;
+ }
+#endif
+
/**
* Returns the FilesystemFactory object, depending on the current architecture.
*
diff --git a/common/taskbar.h b/common/taskbar.h
new file mode 100644
index 0000000000..023227e5e0
--- /dev/null
+++ b/common/taskbar.h
@@ -0,0 +1,133 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef COMMON_TASKBAR_MANAGER_H
+#define COMMON_TASKBAR_MANAGER_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+
+#if defined(USE_TASKBAR)
+
+namespace Common {
+
+/**
+ * The TaskbarManager allows interaction with the ScummVM application icon:
+ * - in the taskbar on Windows 7 and later
+ * - in the launcher for Unity
+ * - in the dock on MacOSX
+ * - ...
+ *
+ * This allows GUI code and engines to display a progress bar, an overlay icon and/or count
+ * associated with the ScummVM icon as well as add the started engine to the recent items
+ * list (so that the user can start the engine directly in one click).
+ *
+ * Examples of use:
+ * - Track search progress and found engines when running the Mass Add dialog
+ * - Add an entry to the recent items when starting an engine
+ * - Show the current running engine icon as an overlay
+ *
+ * @note functionality will vary between supported platforms (due to API limitations)
+ * and some of the methods will just be no-ops or approximate the functionality
+ * as best as possible
+ */
+class TaskbarManager {
+public:
+ /**
+ * Values representing the taskbar progress state
+ */
+ enum TaskbarProgressState {
+ kTaskbarNoProgress = 0,
+ kTaskbarIndeterminate = 1,
+ kTaskbarNormal = 2,
+ kTaskbarError = 4,
+ kTaskbarPaused = 8
+ };
+
+ TaskbarManager() {}
+ virtual ~TaskbarManager() {}
+
+ /**
+ * Sets an overlay icon on the taskbar icon
+ *
+ * When an empty name is given, no icon is shown
+ * and the current overlay icon (if any) is removed
+ *
+ * @param name Path to the icon
+ * @param description The description
+ *
+ * @note on Windows, the icon should be an ICO file
+ */
+ virtual void setOverlayIcon(const String &name, const String &description) {}
+
+ /**
+ * Sets a progress value on the taskbar icon
+ *
+ * @param completed The current progress value.
+ * @param total The maximum progress value.
+ */
+ virtual void setProgressValue(int completed, int total) {}
+
+ /**
+ * Sets the progress state on the taskbar icon
+ *
+ * State can be any of the following:
+ * - NoProgress: disable display of progress state
+ * - Indeterminate
+ * - Normal
+ * - Error
+ * - Paused
+ *
+ * @param state The progress state
+ */
+ virtual void setProgressState(TaskbarProgressState state) {}
+
+ /**
+ * Sets the count number associated with the icon as an overlay
+ *
+ * @param count The count
+ *
+ * @note Setting a count of 0 will hide the count
+ */
+ virtual void setCount(int count) {}
+
+ /**
+ * Adds an engine to the recent items list
+ *
+ * Path is automatically set to the current executable path,
+ * an icon name is generated (with fallback to default icon)
+ * and the command line is set to start the engine on click.
+ *
+ * @param name The target name.
+ * @param description The description.
+ */
+ virtual void addRecent(const String &name, const String &description) {}
+
+};
+
+} // End of namespace Common
+
+#endif
+
+#endif // COMMON_TASKBAR_MANAGER_H
diff --git a/configure b/configure
index 0afdbfe7c8..04ca85ffb6 100755
--- a/configure
+++ b/configure
@@ -142,6 +142,8 @@ _fluidsynth=auto
_opengl=auto
_opengles=auto
_readline=auto
+_taskbar=yes
+_libunity=auto
# Default option behaviour yes/no
_debug_build=auto
_release_build=auto
@@ -767,6 +769,7 @@ Optional Features:
--disable-scalers exclude scalers
--disable-hq-scalers exclude HQ2x and HQ3x scalers
--disable-translation don't build support for translated messages
+ --disable-taskbar don't build support for taskbar and launcher integration
--enable-text-console use text console instead of graphical console
--enable-verbose-build enable regular echoing of commands during build
process
@@ -816,6 +819,9 @@ Optional Libraries:
--with-readline-prefix=DIR Prefix where readline is installed (optional)
--disable-readline disable readline support in text console [autodetect]
+ --with-libunity-prefix=DIR Prefix where libunity is installed (optional)
+ --disable-libunity disable Unity launcher integration [autodetect]
+
Some influential environment variables:
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
@@ -863,6 +869,10 @@ for ac_option in $@; do
--disable-fluidsynth) _fluidsynth=no ;;
--enable-readline) _readline=yes ;;
--disable-readline) _readline=no ;;
+ --enable-taskbar) _taskbar=yes ;;
+ --disable-taskbar) _taskbar=no ;;
+ --enable-libunity) _libunity=yes ;;
+ --disable-libunity) _libunity=no ;;
--enable-opengl) _opengl=yes ;;
--disable-opengl) _opengl=no ;;
--enable-verbose-build) _verbose_build=yes ;;
@@ -938,6 +948,11 @@ for ac_option in $@; do
READLINE_CFLAGS="-I$arg/include"
READLINE_LIBS="-L$arg/lib"
;;
+ --with-libunity-prefix=*)
+ arg=`echo $ac_option | cut -d '=' -f 2`
+ LIBUNITY_CFLAGS="-I$arg/include"
+ LIBUNITY_LIBS="-L$arg/lib"
+ ;;
--with-opengl-prefix=*)
arg=`echo $ac_option | cut -d '=' -f 2`
OPENGL_CFLAGS="-I$arg/include"
@@ -2966,6 +2981,43 @@ define_in_config_h_if_yes "$_readline" 'USE_READLINE'
define_in_config_h_if_yes "$_text_console" 'USE_TEXT_CONSOLE_FOR_DEBUGGER'
#
+# Check for Unity if taskbar integration is enabled
+#
+echocheck "libunity"
+if test "$_unix" = no || test "$_taskbar" = no; then
+ _libunity=no
+else
+if test "$_libunity" = auto ; then
+ case $_host_os in
+ mingw*)
+ # pkgconfig and unity are not supported on mingw
+ _libunity=no
+ ;;
+ *)
+ # Unity has a lots of dependencies, update the libs and cflags var with them
+ LIBUNITY_LIBS="$LIBUNITY_LIBS $(pkg-config --libs unity = 3.8.4)"
+ LIBUNITY_CFLAGS="$LIBUNITY_CFLAGS $(pkg-config --cflags unity = 3.8.4)"
+ _libunity=no
+ cat > $TMPC << EOF
+#include <unity.h>
+int main(void) {
+ unity_launcher_entry_get_for_desktop_id("scummvm.desktop");
+ return 0;
+}
+EOF
+ cc_check $LIBUNITY_CFLAGS $LIBUNITY_LIBS -lunity && _libunity=yes
+ ;;
+ esac
+fi
+if test "$_libunity" = yes ; then
+ LIBS="$LIBS $LIBUNITY_LIBS -lunity"
+ INCLUDES="$INCLUDES $LIBUNITY_CFLAGS"
+fi
+define_in_config_h_if_yes "$_libunity" 'USE_TASKBAR_UNITY'
+fi
+echo "$_libunity"
+
+#
# Check for OpenGL (ES)
#
echocheck "OpenGL"
@@ -3141,6 +3193,29 @@ EOF
fi
#
+# Check whether to build taskbar integration support
+#
+echo_n "Building taskbar integration support... "
+define_in_config_if_yes $_taskbar 'USE_TASKBAR'
+if test "$_taskbar" = yes; then
+ case $_host_os in
+ mingw*)
+ LIBS="$LIBS -lole32 -luuid"
+ echo "win32"
+ ;;
+ *)
+ if test "$_unity" = yes; then
+ echo "unity"
+ else
+ echo "$_taskbar"
+ fi
+ ;;
+ esac
+else
+ echo "$_taskbar"
+fi
+
+#
# Figure out installation directories
#
test "x$prefix" = xNONE && prefix=/usr/local
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index 29bc5bfcd5..35d08561bf 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -364,6 +364,11 @@ int main(int argc, char *argv[]) {
provider = new CreateProjectTool::CodeBlocksProvider(globalWarnings, projectWarnings);
+
+ // Those libraries are automatically added by MSVC, but we need to add them manually with mingw
+ setup.libraries.push_back("ole32");
+ setup.libraries.push_back("uuid");
+
break;
case kProjectMSVC:
@@ -774,6 +779,7 @@ const Feature s_features[] = {
{ "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" },
{ "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling.
{ "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" },
+ { "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" },
{ "translation", "USE_TRANSLATION", "", true, "Translation support" },
{ "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"},
{ "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there
diff --git a/gui/massadd.cpp b/gui/massadd.cpp
index b0adce3f47..70580e8b9c 100644
--- a/gui/massadd.cpp
+++ b/gui/massadd.cpp
@@ -24,6 +24,7 @@
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/system.h"
+#include "common/taskbar.h"
#include "common/translation.h"
#include "gui/launcher.h" // For addGameToConf()
@@ -60,6 +61,7 @@ MassAddDialog::MassAddDialog(const Common::FSNode &startDir)
: Dialog("MassAdd"),
_dirsScanned(0),
_oldGamesCount(0),
+ _dirTotal(0),
_okButton(0),
_dirProgressText(0),
_gameProgressText(0) {
@@ -69,14 +71,14 @@ MassAddDialog::MassAddDialog(const Common::FSNode &startDir)
// The dir we start our scan at
_scanStack.push(startDir);
-// Removed for now... Why would you put a title on mass add dialog called "Mass Add Dialog"?
-// new StaticTextWidget(this, "massadddialog_caption", "Mass Add Dialog");
+ // Removed for now... Why would you put a title on mass add dialog called "Mass Add Dialog"?
+ // new StaticTextWidget(this, "massadddialog_caption", "Mass Add Dialog");
_dirProgressText = new StaticTextWidget(this, "MassAdd.DirProgressText",
- _("... progress ..."));
+ _("... progress ..."));
_gameProgressText = new StaticTextWidget(this, "MassAdd.GameProgressText",
- _("... progress ..."));
+ _("... progress ..."));
_dirProgressText->setAlign(Graphics::kTextAlignCenter);
_gameProgressText->setAlign(Graphics::kTextAlignCenter);
@@ -130,6 +132,12 @@ struct GameDescLess {
void MassAddDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+#if defined(USE_TASKBAR)
+ // Remove progress bar and count from taskbar
+ g_system->getTaskbarManager()->setProgressState(Common::TaskbarManager::kTaskbarNoProgress);
+ g_system->getTaskbarManager()->setCount(0);
+#endif
+
// FIXME: It's a really bad thing that we use two arbitrary constants
if (cmd == kOkCmd) {
// Sort the detected games. This is not strictly necessary, but nice for
@@ -226,10 +234,17 @@ void MassAddDialog::handleTickle() {
for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) {
if (file->isDirectory()) {
_scanStack.push(*file);
+
+ _dirTotal++;
}
}
_dirsScanned++;
+
+#if defined(USE_TASKBAR)
+ g_system->getTaskbarManager()->setProgressValue(_dirsScanned, _dirTotal);
+ g_system->getTaskbarManager()->setCount(_games.size());
+#endif
}
diff --git a/gui/massadd.h b/gui/massadd.h
index 15cef7ba68..7350213835 100644
--- a/gui/massadd.h
+++ b/gui/massadd.h
@@ -60,6 +60,7 @@ private:
int _dirsScanned;
int _oldGamesCount;
+ int _dirTotal;
Widget *_okButton;
StaticTextWidget *_dirProgressText;