aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorEugene Sandulenko2011-06-22 13:35:37 -0700
committerEugene Sandulenko2011-06-22 13:35:37 -0700
commit33ce6e60fd98ea67e1e6606bfc7d693b27359bd7 (patch)
tree84caf43ce3848e1105a59539f2133471790ce760 /backends
parentafdfff02f1415f66856f273fcf9f30d7621d8953 (diff)
parent154c584d44d689f0a7b521b49c5ce245a52fb992 (diff)
downloadscummvm-rg350-33ce6e60fd98ea67e1e6606bfc7d693b27359bd7.tar.gz
scummvm-rg350-33ce6e60fd98ea67e1e6606bfc7d693b27359bd7.tar.bz2
scummvm-rg350-33ce6e60fd98ea67e1e6606bfc7d693b27359bd7.zip
Merge pull request #26 from Littleboy/taskbar
Taskbar integration
Diffstat (limited to 'backends')
-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
10 files changed, 694 insertions, 3 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