rainmeter-studio/Plugins/PluginSpeedFan/SpeedFanPlugin.cpp

287 lines
6.6 KiB
C++
Raw Normal View History

2009-02-10 18:37:48 +00:00
/*
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
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 <windows.h>
#include <math.h>
#include <string>
#include <map>
2011-02-03 18:09:24 +00:00
#include "../../Library/Export.h" // Rainmeter's exported functions
2009-02-10 18:37:48 +00:00
2011-02-03 18:09:24 +00:00
#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point
2009-02-10 18:37:48 +00:00
/* 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 ) double Update2(UINT id);
__declspec( dllexport ) UINT GetPluginVersion();
__declspec( dllexport ) LPCTSTR GetPluginAuthor();
}
#pragma pack(1)
2011-03-29 19:21:57 +00:00
struct SpeedFanData
2009-02-10 18:37:48 +00:00
{
WORD version;
WORD flags;
INT MemSize;
DWORD handle;
WORD NumTemps;
WORD NumFans;
WORD NumVolts;
INT temps[32];
INT fans[32];
INT volts[32];
};
2011-03-29 19:21:57 +00:00
enum SensorType
2009-02-10 18:37:48 +00:00
{
TYPE_TEMP,
TYPE_FAN,
TYPE_VOLT
};
enum TempScale
{
SCALE_SOURCE,
SCALE_CENTIGRADE,
SCALE_FARENHEIT,
SCALE_KELVIN
};
bool ReadSharedData(SensorType type, TempScale scale, UINT number, double* value);
2009-02-10 18:37:48 +00:00
static std::map<UINT, SensorType> g_Types;
static std::map<UINT, TempScale> g_Scales;
2009-02-10 18:37:48 +00:00
static std::map<UINT, UINT> g_Numbers;
/*
This function is called when the measure is initialized.
2011-03-29 19:21:57 +00:00
The function must return the maximum value that can be measured.
2009-02-10 18:37:48 +00:00
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)
{
/* Read our own settings from the ini-file */
LPCTSTR type = ReadConfigString(section, L"SpeedFanType", L"TEMPERATURE");
if (type)
{
2010-09-17 08:47:22 +00:00
if (_wcsicmp(L"TEMPERATURE", type) == 0)
2009-02-10 18:37:48 +00:00
{
g_Types[id] = TYPE_TEMP;
LPCTSTR scale = ReadConfigString(section, L"SpeedFanScale", L"C");
if (scale)
{
2010-09-17 08:47:22 +00:00
if (_wcsicmp(L"C", scale) == 0)
{
g_Scales[id] = SCALE_CENTIGRADE;
2011-03-29 19:21:57 +00:00
}
2010-09-17 08:47:22 +00:00
else if (_wcsicmp(L"F", scale) == 0)
{
g_Scales[id] = SCALE_FARENHEIT;
2011-03-29 19:21:57 +00:00
}
2010-09-17 08:47:22 +00:00
else if (_wcsicmp(L"K", scale) == 0)
{
g_Scales[id] = SCALE_KELVIN;
2011-03-29 19:21:57 +00:00
}
else
{
std::wstring error = L"SpeedFanScale=";
error += scale;
2010-09-23 08:49:43 +00:00
error += L" is not valid in measure [";
error += section;
error += L"].";
2010-09-21 11:09:36 +00:00
MessageBox(NULL, error.c_str(), L"Rainmeter", MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
}
}
2011-03-29 19:21:57 +00:00
}
2010-09-17 08:47:22 +00:00
else if (_wcsicmp(L"FAN", type) == 0)
2009-02-10 18:37:48 +00:00
{
g_Types[id] = TYPE_FAN;
2011-03-29 19:21:57 +00:00
}
2010-09-17 08:47:22 +00:00
else if (_wcsicmp(L"VOLTAGE", type) == 0)
2009-02-10 18:37:48 +00:00
{
g_Types[id] = TYPE_VOLT;
2011-03-29 19:21:57 +00:00
}
2009-02-10 18:37:48 +00:00
else
{
std::wstring error = L"SpeedFanType=";
2009-02-10 18:37:48 +00:00
error += type;
2010-09-23 08:49:43 +00:00
error += L" is not valid in measure [";
error += section;
error += L"].";
2010-09-21 11:09:36 +00:00
MessageBox(NULL, error.c_str(), L"Rainmeter", MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
2009-02-10 18:37:48 +00:00
}
}
2011-03-29 19:21:57 +00:00
2009-02-10 18:37:48 +00:00
LPCTSTR data = ReadConfigString(section, L"SpeedFanNumber", L"0");
if (data)
{
g_Numbers[id] = _wtoi(data);
}
return 0;
}
/*
This function is called when new value should be measured.
The function returns the new value.
*/
double Update2(UINT id)
{
2011-03-29 19:21:57 +00:00
double value = 0.0;
std::map<UINT, SensorType>::const_iterator type = g_Types.find(id);
std::map<UINT, TempScale>::const_iterator scale = g_Scales.find(id);
std::map<UINT, UINT>::const_iterator number = g_Numbers.find(id);
2011-03-29 19:21:57 +00:00
if (type == g_Types.end() || number == g_Numbers.end())
2009-02-10 18:37:48 +00:00
{
return 0.0; // No id in the map. How this can be ????
2009-02-10 18:37:48 +00:00
}
if ((*type).second == TYPE_TEMP)
{
if (scale != g_Scales.end() &&
ReadSharedData((*type).second, (*scale).second, (*number).second, &value))
{
return value;
}
}
else
2009-02-10 18:37:48 +00:00
{
if (ReadSharedData((*type).second, SCALE_SOURCE, (*number).second, &value))
{
return value;
}
2009-02-10 18:37:48 +00:00
}
2011-03-29 19:21:57 +00:00
return 0.0;
2009-02-10 18:37:48 +00:00
}
/*
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, SensorType>::iterator i1 = g_Types.find(id);
if (i1 != g_Types.end())
{
g_Types.erase(i1);
}
std::map<UINT, UINT>::iterator i2 = g_Numbers.find(id);
if (i2 != g_Numbers.end())
{
g_Numbers.erase(i2);
}
std::map<UINT, TempScale>::iterator i3 = g_Scales.find(id);
if (i3 != g_Scales.end())
{
g_Scales.erase(i3);
}
2009-02-10 18:37:48 +00:00
}
/*
Get the data from shared memory.
*/
bool ReadSharedData(SensorType type, TempScale scale, UINT number, double* value)
2009-02-10 18:37:48 +00:00
{
SpeedFanData* ptr;
HANDLE hData;
2011-03-29 19:21:57 +00:00
2009-02-10 18:37:48 +00:00
hData = OpenFileMapping(FILE_MAP_READ, FALSE, L"SFSharedMemory_ALM");
if (hData == NULL) return false;
2011-03-29 19:21:57 +00:00
2009-02-10 18:37:48 +00:00
ptr = (SpeedFanData*)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0);
if (ptr == 0)
{
CloseHandle(hData);
return false;
}
if (ptr->version == 1)
{
2011-03-29 19:21:57 +00:00
switch(type)
2009-02-10 18:37:48 +00:00
{
case TYPE_TEMP:
if (number < ptr->NumTemps)
{
*value = ptr->temps[number];
*value /= 100.0;
if (scale == SCALE_FARENHEIT)
{
*value *= 1.8;
*value += 32.0;
}
else if (scale == SCALE_KELVIN)
{
*value += 273.15;
}
2009-02-10 18:37:48 +00:00
}
break;
case TYPE_FAN:
if (number < ptr->NumTemps)
{
*value = ptr->fans[number];
}
break;
case TYPE_VOLT:
if (number < ptr->NumVolts)
{
*value = ptr->volts[number];
*value /= 100.0;
}
break;
}
}
else
{
LSLog(LOG_WARNING, L"Rainmeter", L"SpeedFanPlugin: The shared memory has incorrect version.");
2009-02-10 18:37:48 +00:00
}
UnmapViewOfFile(ptr);
CloseHandle(hData);
2011-03-29 19:21:57 +00:00
2009-02-10 18:37:48 +00:00
return true;
}
UINT GetPluginVersion()
{
return 1002;
2009-02-10 18:37:48 +00:00
}
LPCTSTR GetPluginAuthor()
{
return L"Rainy (rainy@iki.fi)";
}