rainmeter-studio/Plugins/PluginPower/PowerPlugin.cpp

234 lines
5.3 KiB
C++
Raw Normal View History

2009-02-10 18:37:48 +00:00
/*
Copyright (C) 2002 Kimmo Pekkola
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.
2009-02-10 18:37:48 +00:00
*/
#include <windows.h>
2011-12-30 17:18:34 +00:00
#include <Powrprof.h>
2012-01-08 17:35:29 +00:00
#include <time.h>
#include <errno.h>
#include <crtdbg.h>
2013-12-24 11:20:19 +00:00
#include <stdlib.h>
2013-05-31 14:34:36 +00:00
#include "../../Common/RawString.h"
2011-02-03 18:09:24 +00:00
#include "../../Library/Export.h" // Rainmeter's exported functions
2011-03-29 19:21:57 +00:00
typedef struct _PROCESSOR_POWER_INFORMATION
{
ULONG Number;
ULONG MaxMhz;
ULONG CurrentMhz;
ULONG MhzLimit;
ULONG MaxIdleState;
ULONG CurrentIdleState;
2009-02-10 18:37:48 +00:00
} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
2012-01-08 17:35:29 +00:00
enum MeasureType
2009-02-10 18:37:48 +00:00
{
POWER_UNKNOWN,
POWER_ACLINE,
POWER_STATUS,
POWER_STATUS2,
POWER_LIFETIME,
POWER_PERCENT,
POWER_MHZ,
POWER_HZ
2009-02-10 18:37:48 +00:00
};
2012-01-08 17:35:29 +00:00
struct MeasureData
{
MeasureType type;
2013-05-31 14:18:52 +00:00
RawString format;
2012-01-08 17:35:29 +00:00
MeasureData() : type(POWER_UNKNOWN) {}
};
UINT g_NumOfProcessors = 0;
2009-02-10 18:37:48 +00:00
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, void* rm)
2011-12-30 17:18:34 +00:00
{
2012-01-08 17:35:29 +00:00
MeasureData* measure = new MeasureData;
*data = measure;
if (!g_NumOfProcessors)
{
2012-01-08 17:35:29 +00:00
SYSTEM_INFO si;
GetSystemInfo(&si);
g_NumOfProcessors = (UINT)si.dwNumberOfProcessors;
}
2012-01-08 17:35:29 +00:00
}
2012-01-08 17:35:29 +00:00
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
{
MeasureData* measure = (MeasureData*)data;
2011-12-30 17:18:34 +00:00
2012-01-08 17:35:29 +00:00
LPCWSTR value = RmReadString(rm, L"PowerState", L"");
if (_wcsicmp(L"ACLINE", value) == 0)
{
2012-01-08 17:35:29 +00:00
measure->type = POWER_ACLINE;
*maxValue = 1.0;
}
2012-01-08 17:35:29 +00:00
else if (_wcsicmp(L"STATUS", value) == 0)
{
2012-01-08 17:35:29 +00:00
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;
2009-02-10 18:37:48 +00:00
2012-01-08 17:35:29 +00:00
value = RmReadString(rm, L"Format", L"%H:%M");
measure->format = value;
2011-12-30 17:18:34 +00:00
2012-01-08 17:35:29 +00:00
SYSTEM_POWER_STATUS sps;
if (GetSystemPowerStatus(&sps))
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
*maxValue = sps.BatteryFullLifeTime;
2009-02-10 18:37:48 +00:00
}
}
2012-01-08 17:35:29 +00:00
else if (_wcsicmp(L"MHZ", value) == 0)
{
measure->type = POWER_MHZ;
}
else if (_wcsicmp(L"HZ", value) == 0)
{
measure->type = POWER_HZ;
}
else if (_wcsicmp(L"PERCENT", value) == 0)
{
measure->type = POWER_PERCENT;
*maxValue = 100.0;
}
2009-02-10 18:37:48 +00:00
}
2012-01-08 17:35:29 +00:00
PLUGIN_EXPORT double Update(void* data)
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
MeasureData* measure = (MeasureData*)data;
SYSTEM_POWER_STATUS sps;
if (GetSystemPowerStatus(&sps))
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
switch (measure->type)
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
case POWER_ACLINE:
return sps.ACLineStatus == 1 ? 1.0 : 0.0;
2009-02-10 18:37:48 +00:00
2012-01-08 17:35:29 +00:00
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;
2009-02-10 18:37:48 +00:00
2012-01-08 17:35:29 +00:00
case POWER_STATUS2:
return sps.BatteryFlag;
2009-02-10 18:37:48 +00:00
2012-01-08 17:35:29 +00:00
case POWER_LIFETIME:
return sps.BatteryLifeTime;
2009-02-10 18:37:48 +00:00
2012-01-08 17:35:29 +00:00
case POWER_PERCENT:
return sps.BatteryLifePercent == 255 ? 100.0 : sps.BatteryLifePercent;
2011-12-30 17:18:34 +00:00
2012-01-08 17:35:29 +00:00
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);
2013-05-31 14:28:39 +00:00
CallNtPowerInformation(ProcessorInformation, nullptr, 0, ppi, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors);
2012-01-08 17:35:29 +00:00
double value = (measure->type == POWER_MHZ) ? ppi[0].CurrentMhz : ppi[0].CurrentMhz * 1000000.0;
delete [] ppi;
return value;
2009-02-10 18:37:48 +00:00
}
}
}
2012-01-08 17:35:29 +00:00
return 0.0;
2009-02-10 18:37:48 +00:00
}
2012-01-08 17:35:29 +00:00
PLUGIN_EXPORT LPCWSTR GetString(void* data)
2009-02-10 18:37:48 +00:00
{
static WCHAR buffer[128];
2012-01-08 17:35:29 +00:00
MeasureData* measure = (MeasureData*)data;
if (measure->type == POWER_LIFETIME)
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
SYSTEM_POWER_STATUS sps;
if (GetSystemPowerStatus(&sps))
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
// Change it to time string
if (sps.BatteryLifeTime == -1)
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
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)
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
buffer[0] = L'\0';
2009-02-10 18:37:48 +00:00
}
2012-01-08 17:35:29 +00:00
_set_invalid_parameter_handler(oldHandler);
2012-01-08 17:35:29 +00:00
return buffer;
2009-02-10 18:37:48 +00:00
}
}
}
2011-12-30 17:18:34 +00:00
2013-05-31 14:28:39 +00:00
return nullptr;
2011-12-30 17:18:34 +00:00
}
2012-01-08 17:35:29 +00:00
PLUGIN_EXPORT void Finalize(void* data)
2009-02-10 18:37:48 +00:00
{
2012-01-08 17:35:29 +00:00
MeasureData* measure = (MeasureData*)data;
delete measure;
2009-02-10 18:37:48 +00:00
}