aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/platform/sdl/win32/win32.cpp1
-rw-r--r--backends/taskbar/win32/win32-taskbar.cpp144
-rw-r--r--backends/taskbar/win32/win32-taskbar.h19
-rw-r--r--common/taskbar.h16
4 files changed, 164 insertions, 16 deletions
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 0fd2fbbd1d..bb254786d5 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -87,6 +87,7 @@ void OSystem_Win32::init() {
// Initialize task bar manager
_taskbarManager = new Win32TaskbarManager();
+ ((Win32TaskbarManager *)_taskbarManager)->init();
// Invoke parent implementation of this method
OSystem_SDL::init();
diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp
index 7f76791dfa..1ddbde10bc 100644
--- a/backends/taskbar/win32/win32-taskbar.cpp
+++ b/backends/taskbar/win32/win32-taskbar.cpp
@@ -25,30 +25,160 @@
* https://code.google.com/p/dukto/
*/
-#include "common/scummsys.h"
+#ifdef WIN32
-#include "common/textconsole.h"
+// Needed for taskbar functions
+#include <SDKDDKVer.h>
+#include <shlobj.h>
#include "backends/taskbar/win32/win32-taskbar.h"
+#include "common/config-manager.h"
+#include "common/textconsole.h"
+
+#include <SDL_syswm.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() {
+ _taskbar = NULL;
}
Win32TaskbarManager::~Win32TaskbarManager() {
+ if (_taskbar)
+ _taskbar->Release();
+ _taskbar = NULL;
+
+ CoUninitialize();
+}
+
+void Win32TaskbarManager::init() {
+ // Do nothing if not running on Windows 7 of 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");
+ }
}
void Win32TaskbarManager::setOverlayIcon(const Common::String &name, const Common::String &description) {
+ if (_taskbar == NULL)
+ return;
+
warning("[Win32TaskbarManager::setOverlayIcon] Not implemented");
}
-void Win32TaskbarManager::setProgressValue(int val, int max) {
- warning("[Win32TaskbarManager::setProgressValue] Not implemented");
+void Win32TaskbarManager::setProgressValue(int completed, int total) {
+ if (_taskbar == NULL)
+ return;
+
+ _taskbar->SetProgressValue(getHwnd(), completed, total);
}
void Win32TaskbarManager::setProgressState(TaskbarProgressState state) {
- warning("[Win32TaskbarManager::setProgressState] Not implemented");
+ if (_taskbar == NULL)
+ return;
+
+ _taskbar->SetProgressState(getHwnd(), (TBPFLAG)state);
}
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
- warning("[Win32TaskbarManager::addRecent] Not implemented");
-} \ No newline at end of file
+ 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_PPV_ARGS(&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);
+ link->SetIconLocation(path, 0); // There's no way to get a game-specific icon, is there?
+
+ // The link's display name must be set via property store.
+ IPropertyStore* propStore;
+ HRESULT hr = link->QueryInterface(&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;
+ }
+}
+
+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
index 20c1a8d383..d0871d36d2 100644
--- a/backends/taskbar/win32/win32-taskbar.h
+++ b/backends/taskbar/win32/win32-taskbar.h
@@ -28,18 +28,35 @@
#ifndef BACKEND_WIN32_TASKBAR_H
#define BACKEND_WIN32_TASKBAR_H
+#ifdef WIN32
+
#include "common/str.h"
#include "common/taskbar.h"
+struct ITaskbarList3;
+
class Win32TaskbarManager : public Common::TaskbarManager {
public:
Win32TaskbarManager();
virtual ~Win32TaskbarManager();
+ void init();
+
virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
- virtual void setProgressValue(int val, int max);
+ virtual void setProgressValue(int completed, int total);
virtual void setProgressState(TaskbarProgressState state);
virtual void addRecent(const Common::String &name, const Common::String &description);
+
+private:
+ HWND _hwnd;
+ ITaskbarList3 *_taskbar;
+
+ // Helper functions
+ bool isWin7OrLater();
+ LPWSTR ansiToUnicode(const char *s);
+ HWND getHwnd();
};
+#endif
+
#endif // BACKEND_WIN32_TASKBAR_H
diff --git a/common/taskbar.h b/common/taskbar.h
index e29fcdcb36..ea1d218724 100644
--- a/common/taskbar.h
+++ b/common/taskbar.h
@@ -35,11 +35,11 @@ public:
* Values representing the taskbar progress state
*/
enum TaskbarProgressState {
- NoProgress = 0,
- Indeterminate = 1,
- Normal = 2,
- Error = 4,
- Paused = 8
+ kTaskbarNoProgress = 0,
+ kTaskbarIndeterminate = 1,
+ kTaskbarNormal = 2,
+ kTaskbarError = 4,
+ kTaskbarPaused = 8
};
TaskbarManager() {}
@@ -61,10 +61,10 @@ public:
/**
* Sets a progress value on the taskbar icon
*
- * @param val The current progress value
- * @param max The maximum progress value
+ * @param completed The current progress value.
+ * @param total The maximum progress value.
*/
- virtual void setProgressValue(int val, int max) {}
+ virtual void setProgressValue(int completed, int total) {}
/**
* Sets the progress state on the taskbar icon