Reverted trunk to r1085.

This commit is contained in:
Birunthan Mohanathas 2011-12-30 17:18:34 +00:00
parent 9856b5138a
commit 71b8d6395d
14 changed files with 454 additions and 756 deletions

View File

@ -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<std::wstring> 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<std::wstring> 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<std::wstring> 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!";
}

View File

@ -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
#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
#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
extern "C"
{
#endif
//
// Exported functions
//
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
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
#endif
#endif

View File

@ -657,17 +657,6 @@
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Export.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="StdAfx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
@ -848,6 +837,7 @@
<ClInclude Include="DialogAbout.h" />
<ClInclude Include="DisableThreadLibraryCalls.h" />
<ClInclude Include="Error.h" />
<ClInclude Include="Export.h" />
<ClInclude Include="Group.h" />
<ClInclude Include="Litestep.h" />
<ClInclude Include="DialogManage.h" />
@ -883,7 +873,6 @@
<ClInclude Include="pcre-8.10\pcre_internal.h" />
<ClInclude Include="pcre-8.10\ucp.h" />
<ClInclude Include="Rainmeter.h" />
<ClInclude Include="Export.h" />
<ClInclude Include="RainmeterQuery.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="StdAfx.h" />

View File

@ -351,9 +351,6 @@
<ClCompile Include="DialogManage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Export.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ConfigParser.h">
@ -365,6 +362,9 @@
<ClInclude Include="Error.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Export.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Group.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -593,9 +593,6 @@
<ClInclude Include="DialogManage.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Export.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Library.rc">

View File

@ -23,14 +23,7 @@
#include <comdef.h>
#include <string>
#include "Error.h"
enum LOGLEVEL
{
LOG_ERROR = 1,
LOG_WARNING = 2,
LOG_NOTICE = 3,
LOG_DEBUG = 4
};
#include "Export.h"
void InitalizeLitestep();
void FinalizeLitestep();

View File

@ -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,37 +155,42 @@ 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");
if (UpdateFunc == NULL && UpdateFunc2 == NULL && GetStringFunc == NULL)
{
FreeLibrary(m_Plugin);
std::wstring error = L"Plugin: \"" + m_PluginName;
error += L"\" doesn't export Update() or GetString()";
throw CError(error);
}
// Initialize the plugin
m_ID = id++;
if (InitializeFunc)
{
// Remove current directory from DLL search path
SetDllDirectory(L"");
if (IsNewApi())
{
((NEWINITIALIZE)initializeFunc)(&m_PluginData);
((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue);
}
else
{
m_ID = id;
double maxValue;
maxValue = InitializeFunc(m_Plugin, parser.GetFilename().c_str(), section, m_ID);
if (!m_UpdateFunc)
{
m_UpdateFunc = GetProcAddress(m_Plugin, "Update2");
m_Update2 = true;
}
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)
{
@ -195,13 +199,6 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
}
}
// Reset to default
SetDllDirectory(L"");
CSystem::ResetWorkingDirectory();
++id;
}
/*
** GetStringValue
**
@ -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,16 +224,9 @@ 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
{

View File

@ -28,13 +28,6 @@ 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;
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

View File

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

View File

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

View File

@ -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 <windows.h>
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

View File

@ -120,8 +120,6 @@
<ImportLibrary>.\x32/Debug/PowerPlugin.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalLibraryDirectories>..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -162,8 +160,6 @@
<ImportLibrary>.\x64/Debug/PowerPlugin.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
<AdditionalLibraryDirectories>..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -199,7 +195,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Rainmeter.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../TestBench/x32/Release/Plugins/PowerPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -210,7 +206,6 @@
<MergeSections>.rdata=.text</MergeSections>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -246,7 +241,7 @@
</ResourceCompile>
<Link>
<AdditionalOptions>/LTCG %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Rainmeter.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../TestBench/x64/Release/Plugins/PowerPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -256,7 +251,6 @@
<MergeSections>.rdata=.text</MergeSections>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View File

@ -17,12 +17,13 @@
*/
#include <windows.h>
#include <Powrprof.h>
#include <math.h>
#include <map>
#include <string>
#include <time.h>
#include <errno.h>
#include <crtdbg.h>
#include "../../Library/RawString.h"
#include <Powrprof.h>
#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<UINT, POWER_STATE> g_States;
std::map<UINT, std::wstring> 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)
{
MeasureData* measure = new MeasureData;
*data = measure;
/*
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:
if (!g_NumOfProcessors)
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)
{
SYSTEM_INFO si;
GetSystemInfo(&si);
g_NumOfProcessors = (UINT)si.dwNumberOfProcessors;
g_Instances++;
if (hDLL == NULL)
{
hDLL = LoadLibrary(L"powrprof.dll");
if (hDLL)
{
fpCallNtPowerInformation = (FPCALLNTPOWERINFORMATION)GetProcAddress(hDLL, "CallNtPowerInformation");
}
}
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
{
MeasureData* measure = (MeasureData*)data;
POWER_STATE powerState = POWER_UNKNOWN;
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;
SYSTEM_INFO systemInfo = {0};
GetSystemInfo(&systemInfo);
g_NumOfProcessors = (int)systemInfo.dwNumberOfProcessors;
value = RmReadString(rm, L"Format", L"%H:%M");
measure->format = value;
/* Read our own settings from the ini-file */
LPCTSTR type = ReadConfigString(section, L"PowerState", L"");
if (type)
{
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;
SYSTEM_POWER_STATUS sps;
if (GetSystemPowerStatus(&sps))
LPCTSTR format = ReadConfigString(section, L"Format", L"%H:%M");
if (format)
{
*maxValue = sps.BatteryFullLifeTime;
g_Formats[id] = format;
}
}
else if (_wcsicmp(L"MHZ", value) == 0)
else if (_wcsicmp(L"MHZ", type) == 0)
{
measure->type = POWER_MHZ;
powerState= POWER_MHZ;
}
else if (_wcsicmp(L"HZ", value) == 0)
else if (_wcsicmp(L"HZ", type) == 0)
{
measure->type = POWER_HZ;
powerState= POWER_HZ;
}
else if (_wcsicmp(L"PERCENT", value) == 0)
else if (_wcsicmp(L"PERCENT", type) == 0)
{
measure->type = POWER_PERCENT;
*maxValue = 100.0;
}
powerState = POWER_PERCENT;
}
PLUGIN_EXPORT double Update(void* data)
{
MeasureData* measure = (MeasureData*)data;
g_States[id] = powerState;
}
SYSTEM_POWER_STATUS sps;
if (GetSystemPowerStatus(&sps))
{
switch (measure->type)
switch(powerState)
{
case POWER_ACLINE:
return sps.ACLineStatus == 1 ? 1.0 : 0.0;
return 1;
case POWER_STATUS:
if (sps.BatteryFlag & 128)
return 4;
case POWER_STATUS2:
return 255;
case POWER_LIFETIME:
{
return 0.0; // No battery
SYSTEM_POWER_STATUS status;
if (GetSystemPowerStatus(&status))
{
return status.BatteryFullLifeTime;
}
else if (sps.BatteryFlag & 8)
{
return 1.0; // Charging
}
else if (sps.BatteryFlag & 4)
{
return 2.0; // Critical
break;
case POWER_PERCENT:
return 100;
}
else if (sps.BatteryFlag & 2)
{
return 3.0; // Low
return 0;
}
else if (sps.BatteryFlag & 1)
/*
This function is called when new value should be measured.
The function returns the new value.
*/
double Update2(UINT id)
{
return 4.0; // High
SYSTEM_POWER_STATUS status;
if (GetSystemPowerStatus(&status))
{
std::map<UINT, POWER_STATE>::iterator i = g_States.find(id);
if (i != g_States.end())
{
switch ((*i).second)
{
case POWER_ACLINE:
return status.ACLineStatus == 1 ? 1 : 0;
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;
return status.BatteryFlag;
case POWER_LIFETIME:
return sps.BatteryLifeTime;
return status.BatteryLifeTime;
case POWER_PERCENT:
return sps.BatteryLifePercent == 255 ? 100.0 : sps.BatteryLifePercent;
return status.BatteryLifePercent > 100 ? 100 : status.BatteryLifePercent;
case POWER_MHZ:
case POWER_HZ:
if (g_NumOfProcessors > 0)
if (fpCallNtPowerInformation && 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;
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;
}
PLUGIN_EXPORT LPCWSTR GetString(void* data)
return 0;
}
/*
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<UINT, POWER_STATE>::iterator i = g_States.find(id);
if (i != g_States.end())
{
SYSTEM_POWER_STATUS sps;
if (GetSystemPowerStatus(&sps))
if ((*i).second == POWER_LIFETIME)
{
SYSTEM_POWER_STATUS status;
if (GetSystemPowerStatus(&status))
{
// Change it to time string
if (sps.BatteryLifeTime == -1)
if (status.BatteryLifeTime == -1)
{
return L"Unknown";
}
else
{
std::map<UINT, std::wstring>::iterator iter = g_Formats.find(id);
if (iter != g_Formats.end())
{
tm time = {0};
time.tm_sec = sps.BatteryLifeTime % 60;
time.tm_min = (sps.BatteryLifeTime / 60) % 60;
time.tm_hour = sps.BatteryLifeTime / 60 / 60;
time.tm_sec = status.BatteryLifeTime % 60;
time.tm_min = (status.BatteryLifeTime / 60) % 60;
time.tm_hour = status.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);
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<UINT, POWER_STATE>::iterator i = g_States.find(id);
if (i != g_States.end())
{
g_States.erase(i);
}
std::map<UINT, std::wstring>::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)";
}

View File

@ -18,72 +18,117 @@
#include <windows.h>
#include <Psapi.h>
#include <algorithm>
#include <vector>
#include "../../Library/RawString.h"
#include <string>
#include <map>
#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<UINT, MeasureData> g_Values;
static UINT g_UpdateCount = 0;
static std::vector<MeasureData*> g_Measures;
void CheckProcesses();
PLUGIN_EXPORT void Initialize(void** data)
{
MeasureData* measure = new MeasureData;
g_Measures.push_back(measure);
/*
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:
*data = measure;
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 data;
const WCHAR* value = ReadConfigString(section, L"ProcessName", L"");
if (*value)
{
data.processName = value;
g_Values[id] = std::move(data);
}
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
{
MeasureData* measure = (MeasureData*)data;
LPCWSTR value = RmReadString(rm, L"ProcessName", L"");
measure->processName = value;
return 1;
}
PLUGIN_EXPORT double Update(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;
UINT result = 0;
std::map<UINT, MeasureData>::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_Measures.size())
if (g_UpdateCount >= g_Values.size())
{
CheckProcesses();
g_UpdateCount = 0;
}
return (double)measure->isRunning;
result = (UINT)(*iter).second.isRunning;
}
PLUGIN_EXPORT void Finalize(void* data)
{
MeasureData* measure = (MeasureData*)data;
std::vector<MeasureData*>::iterator iter = std::find(g_Measures.begin(), g_Measures.end(), measure);
g_Measures.erase(iter);
return result;
}
delete measure;
/*
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<UINT, MeasureData>::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<MeasureData*>::iterator iter = g_Measures.begin();
for ( ; iter != g_Measures.end(); ++iter)
std::map<UINT, MeasureData>::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;
}
}
}

View File

@ -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 FILEVER 2,2,0,960
#define PRODUCTVER 2,2,0,960
#define STRFILEVER "2.2.0.960"
#define STRPRODUCTVER "2.2.0.960"
#define APPVERSION L"2.3.0"
#define RAINMETER_VERSION MAKE_VER(2, 3, 0)
#define REVISION L"960"
#define APPVERSION L"2.2.0"
#define RAINMETER_VERSION MAKE_VER(2, 2, 0)
const int revision_number = 1088;
const int revision_number = 960;
const bool revision_beta = true;