diff --git a/Library/Export.cpp b/Library/Export.cpp deleted file mode 100644 index 3a627ff8..00000000 --- a/Library/Export.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* - Copyright (C) 2011 Birunthan Mohanathas, Peter Souza - - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "StdAfx.h" -#include "Rainmeter.h" -#include "Export.h" -#include "MeterWindow.h" -#include "Measure.h" -#include "MeasurePlugin.h" - -extern CRainmeter* Rainmeter; - -static std::wstring g_Buffer; - -BOOL LSLog(int nLevel, LPCWSTR unused, LPCWSTR pszMessage) -{ - // Ignore LOG_DEBUG messages from plugins unless in debug mode - if (nLevel != LOG_DEBUG || Rainmeter->GetDebug()) - { - Log(nLevel, pszMessage); - } - - return TRUE; -} - -LPCWSTR RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures) -{ - CMeasurePlugin* measure = (CMeasurePlugin*)rm; - CConfigParser& parser = measure->GetMeterWindow()->GetParser(); - return parser.ReadString(measure->GetName(), option, defValue, (bool)replaceMeasures).c_str(); -} - -double RmReadFormula(void* rm, LPCWSTR option, double defValue) -{ - CMeasurePlugin* measure = (CMeasurePlugin*)rm; - CConfigParser& parser = measure->GetMeterWindow()->GetParser(); - return parser.ReadFormula(measure->GetName(), option, defValue); -} - -LPCWSTR RmPathToAbsolute(void* rm, LPCWSTR relativePath) -{ - CMeasurePlugin* measure = (CMeasurePlugin*)rm; - g_Buffer = relativePath; - measure->GetMeterWindow()->MakePathAbsolute(g_Buffer); - return g_Buffer.c_str(); -} - -void* RmGet(void* rm, int type) -{ - CMeasurePlugin* measure = (CMeasurePlugin*)rm; - - switch (type) - { - case RMG_MEASURENAME: - { - return (void*)measure->GetName(); - } - - case RMG_SKIN: - { - return (void*)measure->GetMeterWindow(); - } - - case RMG_SETTINGSFILE: - { - g_Buffer = Rainmeter->GetSettingsPath(); - g_Buffer += L"Plugins.ini"; - return (void*)g_Buffer.c_str(); - } - } - - return NULL; -} - -void RmExecute(void* skin, LPCWSTR command) -{ - CMeterWindow* mw = (CMeterWindow*)skin; - - // Fake WM_COPYDATA message to deliver bang - COPYDATASTRUCT cds; - cds.cbData = 1; - cds.dwData = 1; - cds.lpData = (void*)command; - mw->OnCopyData(WM_COPYDATA, NULL, (LPARAM)&cds); -} - -// Deprecated! -LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue) -{ - // NULL checking - if (section == NULL) section = L""; - if (option == NULL) option = L""; - if (defValue == NULL) defValue = L""; - - CConfigParser* parser = Rainmeter->GetCurrentParser(); - if (parser) - { - return parser->ReadString(section, option, defValue, false).c_str(); - } - - return defValue; -} - -// Deprecated! -LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData) -{ - if (Rainmeter) - { - if (_sCommand == NULL || *_sCommand == L'\0') - { - return L"noop"; - } - - if (_sData == NULL) _sData = L""; - - std::wstring sCommand = _sCommand; - std::transform(sCommand.begin(), sCommand.end(), sCommand.begin(), ::towlower); - - // Command GetConfig - // Data unquoted full path and filename given to the plugin on initialize - // (note: this is CaSe-SeNsItIvE!) - // Execution none - // Result the config name if found or a blank string if not - if (sCommand == L"getconfig") - { - // returns the config name, lookup by INI file - - CMeterWindow *meterWindow = Rainmeter->GetMeterWindowByINI(_sData); - if (meterWindow) - { - g_Buffer = L"\""; - g_Buffer += meterWindow->GetSkinName(); - g_Buffer += L"\""; - return g_Buffer.c_str(); - } - - return L""; - } - - // Command GetWindow - // Data [the config name] - // Execution none - // Result the HWND to the specified config window if found, 'error' otherwise - if (sCommand == L"getwindow") - { - std::vector subStrings = CRainmeter::ParseString(_sData); - - if (subStrings.size() >= 1) - { - const std::wstring& config = subStrings[0]; - - CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config); - if (meterWindow) - { - WCHAR buf1[64]; - _snwprintf_s(buf1, _TRUNCATE, L"%lu", PtrToUlong(meterWindow->GetWindow())); - g_Buffer = buf1; - return g_Buffer.c_str(); - } - } - return L"error"; - } - - // Command GetVariable - // Data [the config name] - // Execution none - // Result the value of the variable - if (sCommand == L"getvariable") - { - std::vector subStrings = CRainmeter::ParseString(_sData); - - if (subStrings.size() >= 2) - { - const std::wstring& config = subStrings[0]; - - CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config); - if (meterWindow) - { - const std::wstring& variable = subStrings[1]; - std::wstring result_from_parser; - - if (meterWindow->GetParser().GetVariable(variable, result_from_parser)) - { - g_Buffer = result_from_parser; - return g_Buffer.c_str(); - } - } - } - - return L""; - } - - // Command SetVariable - // Data [the config name] [variable data] - // Execution the indicated variable is updated - // Result 'success' if the config was found, 'error' otherwise - if (sCommand == L"setvariable") - { - std::vector subStrings = CRainmeter::ParseString(_sData); - - if (subStrings.size() >= 2) - { - const std::wstring& config = subStrings[0]; - std::wstring arguments; - - for (size_t i = 1, isize = subStrings.size(); i < isize; ++i) - { - if (i != 1) arguments += L" "; - arguments += subStrings[i]; - } - - CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config); - if (meterWindow) - { - meterWindow->RunBang(BANG_SETVARIABLE, arguments.c_str()); - return L"success"; - } - } - return L"error"; - } - - return L"noop"; - } - - return L"error:no rainmeter!"; -} diff --git a/Library/Export.h b/Library/Export.h index cebff635..ed6125b6 100644 --- a/Library/Export.h +++ b/Library/Export.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Kimmo Pekkola, Birunthan Mohanathas + Copyright (C) 2004 Kimmo Pekkola This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -20,94 +20,28 @@ #define __EXPORT_H__ #ifdef LIBRARY_EXPORTS -#define DECLSPEC_LIBRARY __declspec(dllexport) +#define EXPORT_PLUGIN __declspec(dllexport) #else -#define DECLSPEC_LIBRARY __declspec(dllimport) -#endif // LIBRARY_EXPORTS - -#ifdef __cplusplus -#define LIBRARY_EXPORT extern "C" DECLSPEC_LIBRARY -#define PLUGIN_EXPORT extern "C" __declspec(dllexport) -#else -#define LIBRARY_EXPORT DECLSPEC_LIBRARY -#define PLUGIN_EXPORT __declspec(dllexport) -#endif // __cplusplus - -// -// Exported functions -// - -#ifdef __cplusplus -LIBRARY_EXPORT LPCWSTR RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures = TRUE); -#else -LIBRARY_EXPORT LPCWSTR RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures); -#endif // __cplusplus - -LIBRARY_EXPORT double RmReadFormula(void* rm, LPCWSTR option, double defValue); - -LIBRARY_EXPORT LPCWSTR RmPathToAbsolute(void* rm, LPCWSTR relativePath); - -LIBRARY_EXPORT void RmExecute(void* skin, LPCWSTR command); - -LIBRARY_EXPORT BOOL LSLog(int level, LPCWSTR unused, LPCWSTR message); - -LIBRARY_EXPORT void* RmGet(void* rm, int type); - -enum RMGTYPE -{ - RMG_MEASURENAME = 0, - RMG_SKIN = 1, - RMG_SETTINGSFILE = 2 -}; - -/* DEPRECATED */ LIBRARY_EXPORT __declspec(deprecated) LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue); - -/* DEPRECATED */ LIBRARY_EXPORT __declspec(deprecated) LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data); - -// -// Wrapper functions -// - -#ifndef LIBRARY_EXPORTS -__inline LPCWSTR RmReadPath(void* rm, LPCWSTR option, LPCWSTR defValue) -{ - LPCWSTR relativePath = RmReadString(rm, option, defValue, TRUE); - return RmPathToAbsolute(rm, relativePath); -} - -__inline int RmReadInt(void* rm, LPCWSTR option, int defValue) -{ - LPCWSTR value = RmReadString(rm, option, L"", TRUE); - return (*value) ? _wtoi(value) : defValue; -} - -__inline LPCWSTR RmGetMeasureName(void* rm) -{ - return (LPCWSTR)RmGet(rm, RMG_MEASURENAME); -} - -__inline LPCWSTR RmGetSettingsFile(void* rm) -{ - return (LPCWSTR)RmGet(rm, RMG_SETTINGSFILE); -} - -__inline void* RmGetSkin(void* rm) -{ - return (void*)RmGet(rm, RMG_SKIN); -} - -__inline void RmLog(int level, LPCWSTR message) -{ - LSLog(level, NULL, message); -} - -enum LOGLEVEL -{ - LOG_ERROR = 1, - LOG_WARNING = 2, - LOG_NOTICE = 3, - LOG_DEBUG = 4 -}; -#endif // LIBRARY_EXPORTS - +#define EXPORT_PLUGIN __declspec(dllimport) #endif + +// log level constants +#define LOG_ERROR 1 +#define LOG_WARNING 2 +#define LOG_NOTICE 3 +#define LOG_DEBUG 4 + +#ifdef __cplusplus +extern "C" +{ +#endif + + EXPORT_PLUGIN BOOL LSLog(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage); + EXPORT_PLUGIN LPCTSTR ReadConfigString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue); + EXPORT_PLUGIN LPCTSTR PluginBridge(LPCTSTR sCommand, LPCTSTR sData); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Library/Library.vcxproj b/Library/Library.vcxproj index 03543208..1059f33c 100644 --- a/Library/Library.vcxproj +++ b/Library/Library.vcxproj @@ -657,17 +657,6 @@ MaxSpeed Use - - Disabled - EnableFastChecks - Use - Disabled - EnableFastChecks - MaxSpeed - Use - MaxSpeed - Use - Create Create @@ -848,6 +837,7 @@ + @@ -883,7 +873,6 @@ - diff --git a/Library/Library.vcxproj.filters b/Library/Library.vcxproj.filters index 51b05101..7431d3a4 100644 --- a/Library/Library.vcxproj.filters +++ b/Library/Library.vcxproj.filters @@ -351,9 +351,6 @@ Source Files - - Source Files - @@ -365,6 +362,9 @@ Header Files + + Header Files + Header Files @@ -593,9 +593,6 @@ Header Files - - Header Files - diff --git a/Library/Litestep.h b/Library/Litestep.h index e2fbceb5..051888aa 100644 --- a/Library/Litestep.h +++ b/Library/Litestep.h @@ -23,14 +23,7 @@ #include #include #include "Error.h" - -enum LOGLEVEL -{ - LOG_ERROR = 1, - LOG_WARNING = 2, - LOG_NOTICE = 3, - LOG_DEBUG = 4 -}; +#include "Export.h" void InitalizeLitestep(); void FinalizeLitestep(); @@ -45,7 +38,7 @@ std::string ConvertToUTF8(LPCWSTR str); std::wstring ConvertUTF8ToWide(LPCSTR str); void Log(int nLevel, const WCHAR* message); -void LogWithArgs(int nLevel, const WCHAR* format, ...); +void LogWithArgs(int nLevel, const WCHAR* format, ... ); void LogError(CError& error); void RunCommand(HWND Owner, LPCTSTR szCommand, int nShowCmd, bool asAdmin = false); diff --git a/Library/MeasurePlugin.cpp b/Library/MeasurePlugin.cpp index e53aaa4e..d5704208 100644 --- a/Library/MeasurePlugin.cpp +++ b/Library/MeasurePlugin.cpp @@ -19,7 +19,6 @@ #include "StdAfx.h" #include "MeasurePlugin.h" #include "Rainmeter.h" -#include "Export.h" #include "System.h" #include "Error.h" @@ -33,11 +32,13 @@ extern CRainmeter* Rainmeter; */ CMeasurePlugin::CMeasurePlugin(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name), m_Plugin(), - m_ReloadFunc(), m_ID(), - m_UpdateFunc(), - m_GetStringFunc(), - m_ExecuteBangFunc() + InitializeFunc(), + UpdateFunc(), + UpdateFunc2(), + FinalizeFunc(), + GetStringFunc(), + ExecuteBangFunc() { m_MaxValue = 0.0; } @@ -52,16 +53,7 @@ CMeasurePlugin::~CMeasurePlugin() { if (m_Plugin) { - FARPROC finalizeFunc = GetProcAddress(m_Plugin, "Finalize"); - if (IsNewApi()) - { - ((NEWFINALIZE)finalizeFunc)(m_PluginData); - } - else if (finalizeFunc) - { - ((FINALIZE)finalizeFunc)(m_Plugin, m_ID); - } - + if (FinalizeFunc) FinalizeFunc(m_Plugin, m_ID); FreeLibrary(m_Plugin); } } @@ -76,20 +68,15 @@ bool CMeasurePlugin::Update() { if (!CMeasure::PreUpdate()) return false; - if (IsNewApi()) + if (UpdateFunc) { - m_Value = ((NEWUPDATE)m_UpdateFunc)(m_PluginData); + // Update the plugin + m_Value = UpdateFunc(m_ID); } - else if (m_UpdateFunc) + else if (UpdateFunc2) { - if (m_Update2) - { - m_Value = ((UPDATE2)m_UpdateFunc)(m_ID); - } - else - { - m_Value = ((UPDATE)m_UpdateFunc)(m_ID); - } + // Update the plugin + m_Value = UpdateFunc2(m_ID); } // Reset to default @@ -106,17 +93,13 @@ bool CMeasurePlugin::Update() */ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) { - static UINT id = 0; + static UINT id = 1; CMeasure::ReadConfig(parser, section); + if (m_Initialized) { - if (IsNewApi()) - { - ((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue); - } - - // DynamicVariables doesn't work with old plugins + // DynamicVariables doesn't work with plugins, so stop here. return; } @@ -135,9 +118,16 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) } m_PluginName.insert(0, Rainmeter->GetPluginPath()); - m_Plugin = CSystem::RmLoadLibrary(m_PluginName.c_str(), NULL); + DWORD err = 0; + m_Plugin = CSystem::RmLoadLibrary(m_PluginName.c_str(), &err); + if (m_Plugin == NULL) { + if (Rainmeter->GetDebug()) + { + LogWithArgs(LOG_ERROR, L"Plugin: Unable to load \"%s\" (%u)", m_PluginName.c_str(), err); + } + // Try to load from Rainmeter's folder pos = m_PluginName.rfind(L'\\'); if (pos != std::wstring::npos) @@ -145,7 +135,16 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) std::wstring pluginName = Rainmeter->GetPath(); pluginName.append(m_PluginName, pos + 1, m_PluginName.length() - (pos + 1)); - m_Plugin = CSystem::RmLoadLibrary(pluginName.c_str(), NULL); + err = 0; + m_Plugin = CSystem::RmLoadLibrary(pluginName.c_str(), &err); + + if (m_Plugin == NULL) + { + if (Rainmeter->GetDebug()) + { + LogWithArgs(LOG_ERROR, L"Plugin: Unable to load \"%s\" (%u)", pluginName.c_str(), err); + } + } } if (m_Plugin == NULL) @@ -156,50 +155,48 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) } } - FARPROC initializeFunc = GetProcAddress(m_Plugin, "Initialize"); - m_ReloadFunc = GetProcAddress(m_Plugin, "Reload"); - m_UpdateFunc = GetProcAddress(m_Plugin, "Update"); - m_GetStringFunc = GetProcAddress(m_Plugin, "GetString"); - m_ExecuteBangFunc = GetProcAddress(m_Plugin, "ExecuteBang"); + InitializeFunc = (INITIALIZE)GetProcAddress(m_Plugin, "Initialize"); + FinalizeFunc = (FINALIZE)GetProcAddress(m_Plugin, "Finalize"); + UpdateFunc = (UPDATE)GetProcAddress(m_Plugin, "Update"); + UpdateFunc2 = (UPDATE2)GetProcAddress(m_Plugin, "Update2"); + GetStringFunc = (GETSTRING)GetProcAddress(m_Plugin, "GetString"); + ExecuteBangFunc = (EXECUTEBANG)GetProcAddress(m_Plugin, "ExecuteBang"); - // Remove current directory from DLL search path - SetDllDirectory(L""); - - if (IsNewApi()) + if (UpdateFunc == NULL && UpdateFunc2 == NULL && GetStringFunc == NULL) { - ((NEWINITIALIZE)initializeFunc)(&m_PluginData); - ((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue); + FreeLibrary(m_Plugin); + + std::wstring error = L"Plugin: \"" + m_PluginName; + error += L"\" doesn't export Update() or GetString()"; + throw CError(error); } - else + + // Initialize the plugin + m_ID = id++; + if (InitializeFunc) { - m_ID = id; + // Remove current directory from DLL search path + SetDllDirectory(L""); - if (!m_UpdateFunc) - { - m_UpdateFunc = GetProcAddress(m_Plugin, "Update2"); - m_Update2 = true; - } + double maxValue; + maxValue = InitializeFunc(m_Plugin, parser.GetFilename().c_str(), section, m_ID); - double maxValue = ((INITIALIZE)initializeFunc)(m_Plugin, parser.GetFilename().c_str(), section, m_ID); + // Reset to default + SetDllDirectory(L""); + CSystem::ResetWorkingDirectory(); const std::wstring& szMaxValue = parser.ReadString(section, L"MaxValue", L""); if (szMaxValue.empty()) { m_MaxValue = maxValue; } - - if (m_MaxValue == 0) - { - m_MaxValue = 1; - m_LogMaxValue = true; - } } - // Reset to default - SetDllDirectory(L""); - CSystem::ResetWorkingDirectory(); - - ++id; + if (m_MaxValue == 0) + { + m_MaxValue = 1; + m_LogMaxValue = true; + } } /* @@ -210,18 +207,9 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) */ const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual) { - if (m_GetStringFunc) + if (GetStringFunc) { - const WCHAR* ret; - if (IsNewApi()) - { - ret = ((NEWGETSTRING)m_GetStringFunc)(m_PluginData); - } - else - { - ret = ((GETSTRING)m_GetStringFunc)(m_ID, 0); - } - + const WCHAR* ret = GetStringFunc(m_ID, 0); if (ret) return CheckSubstitute(ret); } @@ -236,19 +224,12 @@ const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, i */ void CMeasurePlugin::ExecuteBang(const WCHAR* args) { - if (m_ExecuteBangFunc) + if (ExecuteBangFunc) { - if (IsNewApi()) - { - ((NEWEXECUTEBANG)m_ExecuteBangFunc)(m_PluginData, args); - } - else - { - ((EXECUTEBANG)m_ExecuteBangFunc)(args, m_ID); - } + ExecuteBangFunc(args, m_ID); } else { CMeasure::ExecuteBang(args); } -} +} \ No newline at end of file diff --git a/Library/MeasurePlugin.h b/Library/MeasurePlugin.h index 229b0bb0..cfddafd9 100644 --- a/Library/MeasurePlugin.h +++ b/Library/MeasurePlugin.h @@ -21,20 +21,13 @@ #include "Measure.h" -typedef UINT (*INITIALIZE)(HMODULE, LPCTSTR, LPCTSTR, UINT); +typedef UINT (*INITIALIZE)(HMODULE, LPCTSTR, LPCTSTR, UINT); typedef VOID (*FINALIZE)(HMODULE, UINT); -typedef UINT (*UPDATE)(UINT); -typedef double (*UPDATE2)(UINT); -typedef LPCTSTR (*GETSTRING)(UINT, UINT); +typedef UINT (*UPDATE)(UINT); +typedef double (*UPDATE2)(UINT); +typedef LPCTSTR (*GETSTRING)(UINT, UINT); typedef void (*EXECUTEBANG)(LPCTSTR, UINT); -typedef void (*NEWINITIALIZE)(void*); -typedef void (*NEWRELOAD)(void*, void*, double*); -typedef void (*NEWFINALIZE)(void*); -typedef double (*NEWUPDATE)(void*); -typedef LPCWSTR (*NEWGETSTRING)(void*); -typedef void (*NEWEXECUTEBANG)(void*, const WCHAR*); - class CMeasurePlugin : public CMeasure { public: @@ -49,30 +42,16 @@ protected: virtual void ReadConfig(CConfigParser& parser, const WCHAR* section); private: - bool IsNewApi() { return m_ReloadFunc != NULL; } - std::wstring m_PluginName; HMODULE m_Plugin; + UINT m_ID; - void* m_ReloadFunc; - - union - { - struct - { - UINT m_ID; - bool m_Update2; - }; - - struct - { - void* m_PluginData; - }; - }; - - void* m_UpdateFunc; - void* m_GetStringFunc; - void* m_ExecuteBangFunc; + INITIALIZE InitializeFunc; + FINALIZE FinalizeFunc; + UPDATE UpdateFunc; + UPDATE2 UpdateFunc2; + GETSTRING GetStringFunc; + EXECUTEBANG ExecuteBangFunc; }; #endif diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index d3151cab..f655aef8 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -2110,6 +2110,8 @@ bool CMeterWindow::ReadSkin() MessageBox(m_Window, text.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); } + m_Author = m_Parser.ReadString(L"Rainmeter", L"Author", L""); + static const RECT defMargins = {0}; m_BackgroundMargins = m_Parser.ReadRECT(L"Rainmeter", L"BackgroundMargins", defMargins); m_DragMargins = m_Parser.ReadRECT(L"Rainmeter", L"DragMargins", defMargins); diff --git a/Library/MeterWindow.h b/Library/MeterWindow.h index fa02dfa1..2fbc1d97 100644 --- a/Library/MeterWindow.h +++ b/Library/MeterWindow.h @@ -200,6 +200,7 @@ public: CConfigParser& GetParser() { return m_Parser; } + const std::wstring& GetSkinAuthor() { return m_Author; } const std::wstring& GetSkinName() { return m_SkinName; } const std::wstring& GetSkinIniFile() { return m_SkinIniFile; } std::wstring GetSkinRootPath(); @@ -374,6 +375,7 @@ private: bool m_MouseOver; + std::wstring m_Author; // Skin's author std::wstring m_ConfigGroup; std::wstring m_BackgroundName; // Name of the background image RECT m_BackgroundMargins; diff --git a/Library/RawString.h b/Library/RawString.h deleted file mode 100644 index 361e62d8..00000000 --- a/Library/RawString.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2011 Birunthan Mohanathas - - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef __RAWSTRING_H__ -#define __RAWSTRING_H__ - -#include - -class CRawString -{ -public: - CRawString() : - m_String() - { - } - - CRawString(const WCHAR* str) : - m_String(_wcsdup(str)) - { - } - - ~CRawString() - { - if (m_String) free(m_String); - } - - CRawString& operator=(const WCHAR* rhs) - { - if (m_String) free(m_String); - m_String = _wcsdup(rhs); - return *this; - } - - CRawString& operator=(const CRawString& rhs) - { - if (&rhs != this) - { - if (m_String) free(m_String); - m_String = _wcsdup(rhs.m_String); - } - return *this; - } - - const WCHAR* c_str() const - { - return m_String; - } - - bool empty() const - { - return !(*m_String); - } - -private: - CRawString(const CRawString& p) - { - } - - WCHAR* m_String; -}; - -#endif diff --git a/Plugins/PluginPower/PluginPower.vcxproj b/Plugins/PluginPower/PluginPower.vcxproj index 756764c6..674ffcf7 100644 --- a/Plugins/PluginPower/PluginPower.vcxproj +++ b/Plugins/PluginPower/PluginPower.vcxproj @@ -120,8 +120,6 @@ .\x32/Debug/PowerPlugin.lib MachineX86 ..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories) - Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) - PowrProf.dll @@ -162,8 +160,6 @@ .\x64/Debug/PowerPlugin.lib MachineX64 ..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories) - Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) - PowrProf.dll @@ -199,7 +195,7 @@ 0x0409 - Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) + Rainmeter.lib;%(AdditionalDependencies) ../../TestBench/x32/Release/Plugins/PowerPlugin.dll true ..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories) @@ -210,7 +206,6 @@ .rdata=.text true true - PowrProf.dll @@ -246,7 +241,7 @@ /LTCG %(AdditionalOptions) - Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) + Rainmeter.lib;%(AdditionalDependencies) ../../TestBench/x64/Release/Plugins/PowerPlugin.dll true ..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories) @@ -256,7 +251,6 @@ .rdata=.text true true - PowrProf.dll diff --git a/Plugins/PluginPower/PowerPlugin.cpp b/Plugins/PluginPower/PowerPlugin.cpp index 12bcadf1..a7ecfb84 100644 --- a/Plugins/PluginPower/PowerPlugin.cpp +++ b/Plugins/PluginPower/PowerPlugin.cpp @@ -17,12 +17,13 @@ */ #include -#include +#include +#include +#include #include -#include -#include -#include "../../Library/RawString.h" +#include #include "../../Library/Export.h" // Rainmeter's exported functions + #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point typedef struct _PROCESSOR_POWER_INFORMATION @@ -35,7 +36,20 @@ typedef struct _PROCESSOR_POWER_INFORMATION ULONG CurrentIdleState; } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION; -enum MeasureType +typedef LONG (WINAPI *FPCALLNTPOWERINFORMATION)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); + +/* The exported functions */ +extern "C" +{ +__declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); +__declspec( dllexport ) void Finalize(HMODULE instance, UINT id); +__declspec( dllexport ) LPCTSTR GetString(UINT id, UINT flags); +__declspec( dllexport ) double Update2(UINT id); +__declspec( dllexport ) UINT GetPluginVersion(); +__declspec( dllexport ) LPCTSTR GetPluginAuthor(); +} + +enum POWER_STATE { POWER_UNKNOWN, POWER_ACLINE, @@ -47,187 +61,272 @@ enum MeasureType POWER_HZ }; -struct MeasureData -{ - MeasureType type; - CRawString format; - - MeasureData() : type(POWER_UNKNOWN) {} -}; - -UINT g_NumOfProcessors = 0; +std::map g_States; +std::map g_Formats; +HINSTANCE hDLL = NULL; +int g_Instances, g_NumOfProcessors = 0; +FPCALLNTPOWERINFORMATION fpCallNtPowerInformation = NULL; void NullCRTInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) { // Do nothing. } -PLUGIN_EXPORT void Initialize(void** data) +/* + This function is called when the measure is initialized. + The function must return the maximum value that can be measured. + The return value can also be 0, which means that Rainmeter will + track the maximum value automatically. The parameters for this + function are: + + instance The instance of this DLL + iniFile The name of the ini-file (usually Rainmeter.ini) + section The name of the section in the ini-file for this measure + id The identifier for the measure. This is used to identify the measures that use the same plugin. +*/ +UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) { - MeasureData* measure = new MeasureData; - *data = measure; - - if (!g_NumOfProcessors) + g_Instances++; + if (hDLL == NULL) { - SYSTEM_INFO si; - GetSystemInfo(&si); - g_NumOfProcessors = (UINT)si.dwNumberOfProcessors; - } -} - -PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) -{ - MeasureData* measure = (MeasureData*)data; - - LPCWSTR value = RmReadString(rm, L"PowerState", L""); - if (_wcsicmp(L"ACLINE", value) == 0) - { - measure->type = POWER_ACLINE; - *maxValue = 1.0; - } - else if (_wcsicmp(L"STATUS", value) == 0) - { - measure->type = POWER_STATUS; - *maxValue = 4.0; - } - else if (_wcsicmp(L"STATUS2", value) == 0) - { - measure->type = POWER_STATUS2; - *maxValue = 255.0; - } - else if (_wcsicmp(L"LIFETIME", value) == 0) - { - measure->type= POWER_LIFETIME; - - value = RmReadString(rm, L"Format", L"%H:%M"); - measure->format = value; - - SYSTEM_POWER_STATUS sps; - if (GetSystemPowerStatus(&sps)) + hDLL = LoadLibrary(L"powrprof.dll"); + if (hDLL) { - *maxValue = sps.BatteryFullLifeTime; + fpCallNtPowerInformation = (FPCALLNTPOWERINFORMATION)GetProcAddress(hDLL, "CallNtPowerInformation"); } } - else if (_wcsicmp(L"MHZ", value) == 0) + + POWER_STATE powerState = POWER_UNKNOWN; + + SYSTEM_INFO systemInfo = {0}; + GetSystemInfo(&systemInfo); + g_NumOfProcessors = (int)systemInfo.dwNumberOfProcessors; + + /* Read our own settings from the ini-file */ + LPCTSTR type = ReadConfigString(section, L"PowerState", L""); + if (type) { - measure->type = POWER_MHZ; + if (_wcsicmp(L"ACLINE", type) == 0) + { + powerState = POWER_ACLINE; + } + else if (_wcsicmp(L"STATUS", type) == 0) + { + powerState = POWER_STATUS; + } + else if (_wcsicmp(L"STATUS2", type) == 0) + { + powerState = POWER_STATUS2; + } + else if (_wcsicmp(L"LIFETIME", type) == 0) + { + powerState= POWER_LIFETIME; + + LPCTSTR format = ReadConfigString(section, L"Format", L"%H:%M"); + if (format) + { + g_Formats[id] = format; + } + } + else if (_wcsicmp(L"MHZ", type) == 0) + { + powerState= POWER_MHZ; + } + else if (_wcsicmp(L"HZ", type) == 0) + { + powerState= POWER_HZ; + } + else if (_wcsicmp(L"PERCENT", type) == 0) + { + powerState = POWER_PERCENT; + } + + g_States[id] = powerState; } - else if (_wcsicmp(L"HZ", value) == 0) + + switch(powerState) { - measure->type = POWER_HZ; - } - else if (_wcsicmp(L"PERCENT", value) == 0) - { - measure->type = POWER_PERCENT; - *maxValue = 100.0; + case POWER_ACLINE: + return 1; + + case POWER_STATUS: + return 4; + + case POWER_STATUS2: + return 255; + + case POWER_LIFETIME: + { + SYSTEM_POWER_STATUS status; + if (GetSystemPowerStatus(&status)) + { + return status.BatteryFullLifeTime; + } + } + break; + + case POWER_PERCENT: + return 100; } + + return 0; } -PLUGIN_EXPORT double Update(void* data) +/* + This function is called when new value should be measured. + The function returns the new value. +*/ +double Update2(UINT id) { - MeasureData* measure = (MeasureData*)data; - - SYSTEM_POWER_STATUS sps; - if (GetSystemPowerStatus(&sps)) + SYSTEM_POWER_STATUS status; + if (GetSystemPowerStatus(&status)) { - switch (measure->type) + std::map::iterator i = g_States.find(id); + if (i != g_States.end()) { - case POWER_ACLINE: - return sps.ACLineStatus == 1 ? 1.0 : 0.0; + switch ((*i).second) + { + case POWER_ACLINE: + return status.ACLineStatus == 1 ? 1 : 0; - case POWER_STATUS: - if (sps.BatteryFlag & 128) - { - return 0.0; // No battery - } - else if (sps.BatteryFlag & 8) - { - return 1.0; // Charging - } - else if (sps.BatteryFlag & 4) - { - return 2.0; // Critical - } - else if (sps.BatteryFlag & 2) - { - return 3.0; // Low - } - else if (sps.BatteryFlag & 1) - { - return 4.0; // High - } - break; + case POWER_STATUS: + if (status.BatteryFlag & 128) + { + return 0; // No battery + } + else if (status.BatteryFlag & 8) + { + return 1; // Charging + } + else if (status.BatteryFlag & 4) + { + return 2; // Critical + } + else if (status.BatteryFlag & 2) + { + return 3; // Low + } + else if (status.BatteryFlag & 1) + { + return 4; // High + } + break; - case POWER_STATUS2: - return sps.BatteryFlag; + case POWER_STATUS2: + return status.BatteryFlag; - case POWER_LIFETIME: - return sps.BatteryLifeTime; + case POWER_LIFETIME: + return status.BatteryLifeTime; - case POWER_PERCENT: - return sps.BatteryLifePercent == 255 ? 100.0 : sps.BatteryLifePercent; + case POWER_PERCENT: + return status.BatteryLifePercent > 100 ? 100 : status.BatteryLifePercent; - case POWER_MHZ: - case POWER_HZ: - if (g_NumOfProcessors > 0) - { - PROCESSOR_POWER_INFORMATION* ppi = new PROCESSOR_POWER_INFORMATION[g_NumOfProcessors]; - memset(ppi, 0, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); - CallNtPowerInformation(ProcessorInformation, NULL, 0, ppi, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); - double value = (measure->type == POWER_MHZ) ? ppi[0].CurrentMhz : ppi[0].CurrentMhz * 1000000.0; - delete [] ppi; - return value; + case POWER_MHZ: + case POWER_HZ: + if (fpCallNtPowerInformation && g_NumOfProcessors > 0) + { + PROCESSOR_POWER_INFORMATION* ppi = new PROCESSOR_POWER_INFORMATION[g_NumOfProcessors]; + memset(ppi, 0, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); + fpCallNtPowerInformation(ProcessorInformation, NULL, 0, ppi, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); + double value = ((*i).second == POWER_MHZ) ? ppi[0].CurrentMhz : ppi[0].CurrentMhz * 1000000.0; + delete [] ppi; + return value; + } } } } - return 0.0; + return 0; } -PLUGIN_EXPORT LPCWSTR GetString(void* data) +/* + This function is called when the value should be + returned as a string. +*/ +LPCTSTR GetString(UINT id, UINT flags) { static WCHAR buffer[128]; - MeasureData* measure = (MeasureData*)data; - - if (measure->type == POWER_LIFETIME) + std::map::iterator i = g_States.find(id); + if (i != g_States.end()) { - SYSTEM_POWER_STATUS sps; - if (GetSystemPowerStatus(&sps)) + if ((*i).second == POWER_LIFETIME) { - // Change it to time string - if (sps.BatteryLifeTime == -1) + SYSTEM_POWER_STATUS status; + if (GetSystemPowerStatus(&status)) { - return L"Unknown"; - } - else - { - tm time = {0}; - time.tm_sec = sps.BatteryLifeTime % 60; - time.tm_min = (sps.BatteryLifeTime / 60) % 60; - time.tm_hour = sps.BatteryLifeTime / 60 / 60; - - _invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(NullCRTInvalidParameterHandler); - _CrtSetReportMode(_CRT_ASSERT, 0); - - errno = 0; - wcsftime(buffer, 128, measure->format.c_str(), &time); - if (errno == EINVAL) + // Change it to time string + if (status.BatteryLifeTime == -1) { - buffer[0] = L'\0'; + return L"Unknown"; } + else + { + std::map::iterator iter = g_Formats.find(id); + if (iter != g_Formats.end()) + { + tm time = {0}; + time.tm_sec = status.BatteryLifeTime % 60; + time.tm_min = (status.BatteryLifeTime / 60) % 60; + time.tm_hour = status.BatteryLifeTime / 60 / 60; - _set_invalid_parameter_handler(oldHandler); + _invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(NullCRTInvalidParameterHandler); + _CrtSetReportMode(_CRT_ASSERT, 0); - return buffer; + errno = 0; + wcsftime(buffer, 128, (*iter).second.c_str(), &time); + if (errno == EINVAL) + { + buffer[0] = L'\0'; + } + + _set_invalid_parameter_handler(oldHandler); + } + else + { + wsprintf(buffer, L"%i:%02i:%02i", status.BatteryLifeTime / 60 / 60, (status.BatteryLifeTime / 60) % 60, status.BatteryLifeTime % 60); + } + return buffer; + } } } } - return NULL; } -PLUGIN_EXPORT void Finalize(void* data) +/* + If the measure needs to free resources before quitting. + The plugin can export Finalize function, which is called + when Rainmeter quits (or refreshes). +*/ +void Finalize(HMODULE instance, UINT id) { - MeasureData* measure = (MeasureData*)data; - delete measure; + std::map::iterator i = g_States.find(id); + if (i != g_States.end()) + { + g_States.erase(i); + } + + std::map::iterator i2 = g_Formats.find(id); + if (i2 != g_Formats.end()) + { + g_Formats.erase(i2); + } + + g_Instances--; + if (hDLL != NULL && g_Instances == 0) + { + FreeLibrary(hDLL); + hDLL = NULL; + fpCallNtPowerInformation = NULL; + } } + +UINT GetPluginVersion() +{ + return 1004; +} + +LPCTSTR GetPluginAuthor() +{ + return L"Rainy (rainy@iki.fi)"; +} \ No newline at end of file diff --git a/Plugins/PluginProcess/PluginProcess.cpp b/Plugins/PluginProcess/PluginProcess.cpp index f402113b..b60d9fbd 100644 --- a/Plugins/PluginProcess/PluginProcess.cpp +++ b/Plugins/PluginProcess/PluginProcess.cpp @@ -18,72 +18,117 @@ #include #include -#include -#include -#include "../../Library/RawString.h" +#include +#include #include "../../Library/Export.h" // Rainmeter's exported functions + #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point +/* The exported functions */ +extern "C" +{ +__declspec(dllexport) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); +__declspec(dllexport) void Finalize(HMODULE instance, UINT id); +__declspec(dllexport) UINT Update(UINT id); +__declspec(dllexport) UINT GetPluginVersion(); +__declspec(dllexport) LPCTSTR GetPluginAuthor(); +} + struct MeasureData { - CRawString processName; + std::wstring processName; bool isRunning; MeasureData() : isRunning(false) {} }; +static std::map g_Values; static UINT g_UpdateCount = 0; -static std::vector g_Measures; void CheckProcesses(); -PLUGIN_EXPORT void Initialize(void** data) +/* + This function is called when the measure is initialized. + The function must return the maximum value that can be measured. + The return value can also be 0, which means that Rainmeter will + track the maximum value automatically. The parameters for this + function are: + + instance The instance of this DLL + iniFile The name of the ini-file (usually Rainmeter.ini) + section The name of the section in the ini-file for this measure + id The identifier for the measure. This is used to identify the measures that use the same plugin. +*/ +UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) { - MeasureData* measure = new MeasureData; - g_Measures.push_back(measure); + MeasureData data; - *data = measure; -} - -PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) -{ - MeasureData* measure = (MeasureData*)data; - - LPCWSTR value = RmReadString(rm, L"ProcessName", L""); - measure->processName = value; -} - -PLUGIN_EXPORT double Update(void* data) -{ - MeasureData* measure = (MeasureData*)data; - - // Updates the measure only once per combined updates of all measures - ++g_UpdateCount; - if (g_UpdateCount >= g_Measures.size()) + const WCHAR* value = ReadConfigString(section, L"ProcessName", L""); + if (*value) { - CheckProcesses(); - g_UpdateCount = 0; + data.processName = value; + g_Values[id] = std::move(data); } - return (double)measure->isRunning; + return 1; } -PLUGIN_EXPORT void Finalize(void* data) +/* + This function is called when new value should be measured. + The function returns the new value. +*/ +UINT Update(UINT id) { - MeasureData* measure = (MeasureData*)data; - std::vector::iterator iter = std::find(g_Measures.begin(), g_Measures.end(), measure); - g_Measures.erase(iter); + UINT result = 0; - delete measure; + std::map::const_iterator iter = g_Values.find(id); + if (iter != g_Values.end()) + { + // Updates the measure only once per combined updates of all measures + ++g_UpdateCount; + if (g_UpdateCount >= g_Values.size()) + { + CheckProcesses(); + g_UpdateCount = 0; + } + + result = (UINT)(*iter).second.isRunning; + } + + return result; +} + +/* + If the measure needs to free resources before quitting. + The plugin can export Finalize function, which is called + when Rainmeter quits (or refreshes). +*/ +void Finalize(HMODULE instance, UINT id) +{ + std::map::iterator iter = g_Values.find(id); + if (iter != g_Values.end()) + { + g_Values.erase(iter); + } +} + +UINT GetPluginVersion() +{ + return 1000; +} + +LPCTSTR GetPluginAuthor() +{ + return L"Birunthan Mohanathas (poiru.net)"; } void CheckProcesses() { // Set everything to false - std::vector::iterator iter = g_Measures.begin(); - for ( ; iter != g_Measures.end(); ++iter) + std::map::iterator iter = g_Values.begin(); + for ( ; iter != g_Values.end(); ++iter) { - (*iter)->isRunning = false; + (*iter).second.isRunning = false; } int bufSize = 256; @@ -106,12 +151,12 @@ void CheckProcesses() WCHAR buffer[MAX_PATH]; if (GetModuleBaseName(hProcess, NULL, buffer, _countof(buffer))) { - iter = g_Measures.begin(); - for ( ; iter != g_Measures.end(); ++iter) + iter = g_Values.begin(); + for ( ; iter != g_Values.end(); ++iter) { - if (_wcsicmp(buffer, (*iter)->processName.c_str()) == 0) + if (_wcsicmp(buffer, (*iter).second.processName.c_str()) == 0) { - (*iter)->isRunning = true; + (*iter).second.isRunning = true; } } } diff --git a/Version.h b/Version.h index 33c9d946..e0a69502 100644 --- a/Version.h +++ b/Version.h @@ -1,13 +1,14 @@ -#pragma once -#define MAKE_VER(major, minor1, minor2) major * 1000000 + minor1 * 1000 + minor2 - -#define FILEVER 2,3,0,1088 -#define PRODUCTVER 2,3,0,1088 -#define STRFILEVER "2.3.0.1088" -#define STRPRODUCTVER "2.3.0.1088" - -#define APPVERSION L"2.3.0" -#define RAINMETER_VERSION MAKE_VER(2, 3, 0) - -const int revision_number = 1088; -const bool revision_beta = true; +#pragma once +#define MAKE_VER(major, minor1, minor2) major * 1000000 + minor1 * 1000 + minor2 + +#define FILEVER 2,2,0,960 +#define PRODUCTVER 2,2,0,960 +#define STRFILEVER "2.2.0.960" +#define STRPRODUCTVER "2.2.0.960" + +#define REVISION L"960" +#define APPVERSION L"2.2.0" +#define RAINMETER_VERSION MAKE_VER(2, 2, 0) + +const int revision_number = 960; +const bool revision_beta = true;