Merge pull request #26 from Littleboy/taskbar

Taskbar integration
This commit is contained in:
Eugene Sandulenko 2011-06-22 13:35:37 -07:00
commit 33ce6e60fd
17 changed files with 961 additions and 7 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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();

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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.
*

133
common/taskbar.h Normal file
View File

@ -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

75
configure vendored
View File

@ -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"
@ -2965,6 +2980,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)
#
@ -3140,6 +3192,29 @@ EOF
fi
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
#

View File

@ -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

View File

@ -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
}

View File

@ -60,6 +60,7 @@ private:
int _dirsScanned;
int _oldGamesCount;
int _dirTotal;
Widget *_okButton;
StaticTextWidget *_dirProgressText;