Battery: add support for Windows

This commit is contained in:
李通洲
2022-10-06 01:23:28 +08:00
parent 8ea2014baf
commit bedd6a1d5d
5 changed files with 105 additions and 5 deletions
+2 -4
View File
@@ -1,10 +1,8 @@
#include "fastfetch.h"
#include "common/io.h"
#include "battery.h"
#include <dirent.h>
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) {
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
{
FF_UNUSED(instance, results)
return "Unimplemented";
}
+70
View File
@@ -0,0 +1,70 @@
extern "C" {
#include "battery.h"
}
#include "util/windows/wmi.hpp"
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
{
FF_UNUSED(instance);
//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery", nullptr);
if(!pEnumerator)
return "Query WMI service failed";
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0)
{
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
ffStrbufInit(&battery->manufacturer);
ffGetWmiObjValue(pclsObj, L"SystemName", &battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffGetWmiObjValue(pclsObj, L"Name", &battery->modelName);
int64_t chemistry;
ffGetWmiObjInteger(pclsObj, L"Chemistry", &chemistry);
switch(chemistry)
{
case 1: ffStrbufInitS(&battery->technology, "Other"); break;
case 2: ffStrbufInitS(&battery->technology, "Unknown"); break;
case 3: ffStrbufInitS(&battery->technology, "Lead Acid"); break;
case 4: ffStrbufInitS(&battery->technology, "Nickel Cadmium"); break;
case 5: ffStrbufInitS(&battery->technology, "Nickel Metal Hydride"); break;
case 6: ffStrbufInitS(&battery->technology, "Lithium-ion"); break;
case 7: ffStrbufInitS(&battery->technology, "Zinc air"); break;
case 8: ffStrbufInitS(&battery->technology, "Lithium Polymer"); break;
}
int64_t capacity;
ffGetWmiObjInteger(pclsObj, L"EstimatedChargeRemaining", &capacity);
ffStrbufInitF(&battery->capacity, "%d", (int)capacity);
int64_t batteryStatus;
ffGetWmiObjInteger(pclsObj, L"BatteryStatus", &batteryStatus);
switch(batteryStatus)
{
case 1: ffStrbufInitS(&battery->status, "Discharging"); break;
case 2: ffStrbufInitS(&battery->status, "AC Connected"); break;
case 3: ffStrbufInitS(&battery->status, "Fully Charged"); break;
case 4: ffStrbufInitS(&battery->status, "Low"); break;
case 5: ffStrbufInitS(&battery->status, "Critical"); break;
case 6: ffStrbufInitS(&battery->status, "Charging"); break;
case 7: ffStrbufInitS(&battery->status, "Charging and High"); break;
case 8: ffStrbufInitS(&battery->status, "Charging and Low"); break;
case 9: ffStrbufInitS(&battery->status, "Charging and Critical"); break;
case 10: ffStrbufInitS(&battery->status, "Undefined"); break;
case 11: ffStrbufInitS(&battery->status, "Partially Charged"); break;
}
battery->temperature = FF_BATTERY_TEMP_UNSET;
}
pclsObj->Release();
pEnumerator->Release();
return nullptr;
}
+31
View File
@@ -197,3 +197,34 @@ bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbu
VariantClear(&vtProp);
return result;
}
bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* integer)
{
bool result = true;
VARIANT vtProp;
VariantInit(&vtProp);
CIMTYPE type;
if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)))
{
result = false;
}
else
{
switch(type)
{
case CIM_SINT8: *integer = vtProp.cVal; break;
case CIM_SINT16: *integer = vtProp.iVal; break;
case CIM_SINT32: *integer = vtProp.intVal; break;
case CIM_SINT64: *integer = vtProp.llVal; break;
case CIM_UINT8: *integer = (int64_t)vtProp.bVal; break;
case CIM_UINT16: *integer = (int64_t)vtProp.uiVal; break;
case CIM_UINT32: *integer = (int64_t)vtProp.uintVal; break;
case CIM_UINT64: *integer = (int64_t)vtProp.ullVal; break;
default: result = false;
}
}
VariantClear(&vtProp);
return result;
}
+1
View File
@@ -34,6 +34,7 @@ void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf);
IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error);
bool ffGetWmiObjValue(IWbemClassObject* obj, const wchar_t* key, FFstrbuf* strbuf);
bool ffGetWmiObjInteger(IWbemClassObject* obj, const wchar_t* key, int64_t* result);
#else
// Win32 COM headers requires C++ compiler