ASUS TUF Aura Core port (WMI)
Commit amended to move files to Windows-specific section of Qt project by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
parent
08718044d0
commit
e4a819913a
7 changed files with 522 additions and 5 deletions
|
|
@ -0,0 +1,48 @@
|
|||
#ifdef _WIN32
|
||||
|
||||
#include "RGBController_AsusTUFLaptopWMI.h"
|
||||
|
||||
#include "acpiwmi.h"
|
||||
#include "Detector.h"
|
||||
#include "wmi.h"
|
||||
#include <string>
|
||||
|
||||
static void DetectAsusTUFLaptopWMIControllers(std::vector<RGBController*>&)
|
||||
{
|
||||
// Try to retrieve ProductID / Device name from WMI; Possibly can be rewritten to use wmi.cpp
|
||||
// IF you encounter false detection ( e.g. if your laptop keyboard backlight uses USB interface
|
||||
// instead of ACPI WMI) please add a WHITELIST by checking the
|
||||
// `name` variable for model substrings like "FX505DU"
|
||||
// For now, checking for "TUF Gaming" should suffice
|
||||
|
||||
Wmi wmi;
|
||||
wmi.init();
|
||||
|
||||
std::vector<QueryObj> systemProduct;
|
||||
if (wmi.query("SELECT * FROM Win32_ComputerSystemProduct", systemProduct))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// There should only be one, a cycle is a precaution
|
||||
if(systemProduct.size() != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string& name = systemProduct[0]["Name"];
|
||||
if(name.find("TUF Gaming") == name.npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(AsWMI_Open())
|
||||
{
|
||||
RGBController* new_controller = new RGBController_AsusTUFLaptopWMI();
|
||||
ResourceManager::get()->RegisterRGBController(new_controller);
|
||||
// Success! No more if's
|
||||
}
|
||||
} /* DetectFaustusControllers() */
|
||||
|
||||
REGISTER_DETECTOR("TUF Laptop WMI", DetectAsusTUFLaptopWMIControllers);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
#ifdef _WIN32
|
||||
|
||||
#include "RGBController_AsusTUFLaptopWMI.h"
|
||||
|
||||
#include "acpiwmi.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "Detector.h"
|
||||
#include "wmi.h"
|
||||
#include <string>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
RGBController_AsusTUFLaptopWMI::RGBController_AsusTUFLaptopWMI()
|
||||
{
|
||||
name = "ASUS TUF Keyboard";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "WMI Device";
|
||||
location = "\\\\.\\ATKACPI";
|
||||
|
||||
modes.resize(5);
|
||||
modes[0].name = "Direct";
|
||||
modes[0].value = 4;
|
||||
modes[0].flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
modes[0].color_mode = MODE_COLORS_PER_LED;
|
||||
|
||||
modes[1].name = "Static";
|
||||
modes[1].value = 0;
|
||||
modes[1].flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
modes[1].color_mode = MODE_COLORS_PER_LED;
|
||||
|
||||
modes[2].name = "Breathing";
|
||||
modes[2].value = 1;
|
||||
modes[2].flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
modes[2].speed_min = 0;
|
||||
modes[2].speed_max = 2;
|
||||
modes[2].color_mode = MODE_COLORS_PER_LED;
|
||||
modes[2].speed = 1;
|
||||
|
||||
modes[3].name = "Color Cycle";
|
||||
modes[3].value = 2;
|
||||
modes[3].flags = MODE_FLAG_HAS_SPEED;
|
||||
modes[3].speed_min = 0;
|
||||
modes[3].speed_max = 2;
|
||||
modes[3].color_mode = MODE_COLORS_NONE;
|
||||
modes[3].speed = 1;
|
||||
|
||||
modes[4].name = "Strobe";
|
||||
modes[4].value = 0x0A;
|
||||
modes[4].flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
modes[4].color_mode = MODE_COLORS_PER_LED;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_AsusTUFLaptopWMI::~RGBController_AsusTUFLaptopWMI()
|
||||
{
|
||||
AsWMI_Close();
|
||||
}
|
||||
|
||||
void RGBController_AsusTUFLaptopWMI::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zones.resize(1);
|
||||
zones[0].type = ZONE_TYPE_SINGLE;
|
||||
zones[0].name = "Keyboard Backlight zone";
|
||||
zones[0].leds_min = 1;
|
||||
zones[0].leds_max = 1;
|
||||
zones[0].leds_count = 1;
|
||||
zones[0].matrix_map = NULL;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LED |
|
||||
\*---------------------------------------------------------*/
|
||||
leds.resize(1);
|
||||
leds[0].name = "Keyboard Backlight LED";
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AsusTUFLaptopWMI::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_AsusTUFLaptopWMI::DeviceUpdateLEDs()
|
||||
{
|
||||
uint8_t red = RGBGetRValue(colors[0]);
|
||||
uint8_t green = RGBGetGValue(colors[0]);
|
||||
uint8_t blue = RGBGetBValue(colors[0]);
|
||||
uint8_t speed_byte = 0;
|
||||
uint8_t mode = modes[active_mode].value;
|
||||
uint8_t inv = 0;
|
||||
if(mode == 4)
|
||||
{
|
||||
mode = 1;
|
||||
inv = 4; // Any invalid mode, i.e. anything other than 0, 1, 2 and 10
|
||||
}
|
||||
if(mode == 1 || mode == 2)
|
||||
{
|
||||
switch(modes[active_mode].speed)
|
||||
{
|
||||
case 0: speed_byte = 0xE1; break;
|
||||
case 1: speed_byte = 0xEB; break;
|
||||
case 2: speed_byte = 0xF5; break;
|
||||
}
|
||||
}
|
||||
int high = ((mode | ((red | (green << 8)) << 8)) << 8) | 0xB3;
|
||||
int low = blue | (speed_byte << 8);
|
||||
AsWMI_NB_DeviceControl_2arg(0x100056, high, low);
|
||||
if(inv)
|
||||
{
|
||||
//std::this_thread::sleep_for(10ms);
|
||||
high = ((inv | ((red | (green << 8)) << 8)) << 8) | 0xB3;
|
||||
AsWMI_NB_DeviceControl_2arg(0x100056, high, low);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_AsusTUFLaptopWMI::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AsusTUFLaptopWMI::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AsusTUFLaptopWMI::SetCustomMode()
|
||||
{
|
||||
SetMode(0);
|
||||
}
|
||||
|
||||
void RGBController_AsusTUFLaptopWMI::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
|
||||
#define RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
class RGBController_AsusTUFLaptopWMI : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AsusTUFLaptopWMI();
|
||||
virtual ~RGBController_AsusTUFLaptopWMI();
|
||||
|
||||
void SetupZones() override;
|
||||
|
||||
void ResizeZone(int zone, int new_size) override;
|
||||
|
||||
void DeviceUpdateLEDs() override;
|
||||
void UpdateZoneLEDs(int zone) override;
|
||||
void UpdateSingleLED(int led) override;
|
||||
|
||||
void DeviceUpdateMode() override;
|
||||
|
||||
void SetCustomMode() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
|
||||
|
|
@ -33,11 +33,8 @@ RGBController_Faustus::RGBController_Faustus(const std::string& dev_path)
|
|||
|
||||
modes[3].name = "Strobe";
|
||||
modes[3].value = FAUSTUS_MODE_STROBE;
|
||||
modes[3].flags = MODE_FLAG_HAS_SPEED;
|
||||
modes[3].speed_min = FAUSTUS_SPEED_SLOWEST;
|
||||
modes[3].speed_max = FAUSTUS_SPEED_FASTEST;
|
||||
modes[3].color_mode = MODE_COLORS_NONE;
|
||||
modes[3].speed = FAUSTUS_SPEED_NORMAL;
|
||||
modes[3].flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
modes[3].color_mode = MODE_COLORS_PER_LED;
|
||||
|
||||
SetupZones();
|
||||
|
||||
|
|
|
|||
|
|
@ -524,6 +524,7 @@ win32:INCLUDEPATH +=
|
|||
dependencies/NVFC \
|
||||
dependencies/openrazer-win32 \
|
||||
wmi/ \
|
||||
Controllers/AsusTUFLaptopController \
|
||||
|
||||
win32:SOURCES += \
|
||||
# dependencies/hidapi/hidapi.c \
|
||||
|
|
@ -535,6 +536,9 @@ win32:SOURCES +=
|
|||
i2c_smbus/i2c_smbus_piix4.cpp \
|
||||
serial_port/find_usb_serial_port_win.cpp \
|
||||
wmi/wmi.cpp \
|
||||
wmi/acpiwmi.cpp \
|
||||
Controllers/AsusTUFLaptopController/AsusTUFLaptopWMIDetect.cpp \
|
||||
Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.cpp \
|
||||
Controllers/OpenRazerController/OpenRazerWindowsDetect.cpp \
|
||||
Controllers/OpenRazerController/RGBController_OpenRazerWindows.cpp \
|
||||
|
||||
|
|
@ -549,6 +553,8 @@ win32:HEADERS +=
|
|||
i2c_smbus/i2c_smbus_nvapi.h \
|
||||
i2c_smbus/i2c_smbus_piix4.h \
|
||||
wmi/wmi.h \
|
||||
wmi/acpiwmi.h \
|
||||
Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.h \
|
||||
Controllers/OpenRazerController/RGBController_OpenRazerWindows.h \
|
||||
|
||||
win32:contains(QMAKE_TARGET.arch, x86_64) {
|
||||
|
|
|
|||
278
wmi/acpiwmi.cpp
Normal file
278
wmi/acpiwmi.cpp
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <Objbase.h>
|
||||
#include <setupapi.h>
|
||||
#include <comdef.h>
|
||||
#include <Wbemidl.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
static bool IsWOW64 = false;
|
||||
static HANDLE hDevice = 0;
|
||||
static bool WMI_Notebook = 0;
|
||||
static bool coInitialized = 0;
|
||||
|
||||
static GUID CLSID_GUID_DEVCLASS_SYSTEM = { 0x4D36E97D, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
|
||||
|
||||
static int CheckWMIType()
|
||||
{
|
||||
int n;
|
||||
signed int v3;
|
||||
int v4;
|
||||
signed int v5;
|
||||
int v6;
|
||||
int result;
|
||||
struct _SP_DEVINFO_DATA DeviceInfoData;
|
||||
wchar_t PropertyBuffer[260];
|
||||
|
||||
HDEVINFO devinfo = SetupDiGetClassDevsW(&CLSID_GUID_DEVCLASS_SYSTEM, 0, 0, 2u);
|
||||
if ( devinfo == HDEVINFO(-1) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
n = 0;
|
||||
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
|
||||
v3 = 1;
|
||||
result = 0;
|
||||
while ( SetupDiEnumDeviceInfo(devinfo, n, &DeviceInfoData) ) // Invalid buffer
|
||||
{
|
||||
if ( !SetupDiGetDeviceRegistryPropertyW(devinfo, &DeviceInfoData, 0x16u, 0, PBYTE(PropertyBuffer), 0x208u, 0) )
|
||||
{
|
||||
v5 = 0;
|
||||
v4 = wcscmp(PropertyBuffer, L"ACPI");
|
||||
if ( v4 )
|
||||
{
|
||||
v4 = -(v4 < 0) | 1;
|
||||
v5 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
v5 = 1;
|
||||
}
|
||||
}
|
||||
if ( v5 )
|
||||
{
|
||||
memset(PropertyBuffer, 0, 0x208u);
|
||||
if ( SetupDiGetDeviceInstanceIdW(devinfo, &DeviceInfoData, PropertyBuffer, 0x104u, 0) )
|
||||
{
|
||||
_wcsupr_s(PropertyBuffer, 0x104u);
|
||||
if ( wcsstr(PropertyBuffer, L"ACPI\\ATK0100") )
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
v6 = wcscmp(PropertyBuffer, L"ACPI\\PNP0C14\\ATK");
|
||||
if ( v6 )
|
||||
v6 = -(v6 < 0) | 1;
|
||||
if ( !v6 )
|
||||
{
|
||||
result = 2;
|
||||
v3 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
++n;
|
||||
if ( !v3 )
|
||||
break;
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(devinfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool OpenNotebook()
|
||||
{
|
||||
HMODULE kernelHandler; // eax
|
||||
void (__stdcall *IsWow64Process)(HANDLE, int *); // esi
|
||||
int wow64; // [esp+4h] [ebp-4h]
|
||||
|
||||
wow64 = 0;
|
||||
kernelHandler = GetModuleHandleW(L"kernel32");
|
||||
IsWow64Process = (void (__stdcall *)(HANDLE, int *))GetProcAddress(kernelHandler, "IsWow64Process");
|
||||
if ( IsWow64Process )
|
||||
{
|
||||
int iswow;
|
||||
IsWow64Process(GetCurrentProcess(), &iswow);
|
||||
IsWOW64 = iswow;
|
||||
}
|
||||
hDevice = CreateFileW(L"\\\\.\\ATKACPI", 0xC0000000, 3u, 0, 3u, 0, 0);
|
||||
return (hDevice != HANDLE(-1));
|
||||
}
|
||||
|
||||
bool AsWMI_Open()
|
||||
{
|
||||
HRESULT init = CoInitializeEx(0, 2u);
|
||||
if ( init < 0 && init != -2147417850 )
|
||||
return 0;
|
||||
coInitialized = 1;
|
||||
int type = CheckWMIType();
|
||||
if ( type == 2 )
|
||||
{
|
||||
OpenNotebook();
|
||||
WMI_Notebook = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AsWMI_Close()
|
||||
{
|
||||
if ( WMI_Notebook )
|
||||
{
|
||||
if ( hDevice && hDevice != (HANDLE)-1 )
|
||||
{
|
||||
CloseHandle(hDevice);
|
||||
hDevice = 0;
|
||||
}
|
||||
}
|
||||
if ( coInitialized )
|
||||
{
|
||||
CoUninitialize();
|
||||
coInitialized = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool DeviceIoControlWrapper(const void *dataIn, int commandIndex, int dataSizeIn, void *dataOut, int *dataSizeOut)
|
||||
{
|
||||
size_t BytesReturned;
|
||||
char OutBuffer[1024];
|
||||
|
||||
LPDWORD inBuffer = (LPDWORD)(malloc(dataSizeIn + 8));
|
||||
inBuffer[0] = commandIndex;
|
||||
inBuffer[1] = dataSizeIn;
|
||||
memmove(inBuffer + 2, dataIn, dataSizeIn);
|
||||
memset(OutBuffer, 0, 0x400u);
|
||||
BytesReturned = 0;
|
||||
bool result = DeviceIoControl(
|
||||
hDevice,
|
||||
0x22240Cu,
|
||||
inBuffer,
|
||||
dataSizeIn + 8,
|
||||
OutBuffer,
|
||||
0x400u,
|
||||
LPDWORD(&BytesReturned),
|
||||
0);
|
||||
if ( result )
|
||||
{
|
||||
if ( *dataSizeOut < BytesReturned )
|
||||
BytesReturned = *dataSizeOut;
|
||||
memmove(dataOut, OutBuffer, BytesReturned);
|
||||
}
|
||||
free(inBuffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AsWMI_NB_DeviceControl(int a1, int a2)
|
||||
{
|
||||
unsigned int data[2];
|
||||
|
||||
if ( WMI_Notebook )
|
||||
{
|
||||
if ( hDevice )
|
||||
{
|
||||
if ( hDevice != (HANDLE)-1 )
|
||||
{
|
||||
data[0] = a1;
|
||||
data[1] = a2;
|
||||
int result;
|
||||
int outBufSize = 4;
|
||||
if ( DeviceIoControlWrapper(&data, 1398162756, 8, &result, &outBufSize) )
|
||||
{
|
||||
if(outBufSize < 4)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
if ( result == 1 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AsWMI_NB_DeviceControl_2arg(int a1, int a2, int a3)
|
||||
{
|
||||
unsigned int data[3];
|
||||
data[0] = a1;
|
||||
data[1] = a2;
|
||||
data[2] = a3;
|
||||
int outBuf;
|
||||
int outBufSize = 4;
|
||||
|
||||
if ( WMI_Notebook )
|
||||
{
|
||||
if ( hDevice )
|
||||
{
|
||||
if ( hDevice != (HANDLE)-1 )
|
||||
{
|
||||
if ( DeviceIoControlWrapper(data, 0x53564544, 12, &outBuf, &outBufSize) )
|
||||
{
|
||||
if(outBufSize < 4)
|
||||
{
|
||||
outBuf = 0;
|
||||
}
|
||||
if ( outBuf == 1 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char AsWMI_NB_GetDeviceStatus(int a1, int *out)
|
||||
{
|
||||
int status;
|
||||
int statusSize = 4;
|
||||
|
||||
if ( !WMI_Notebook )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !hDevice || hDevice == HANDLE(-1) || (!DeviceIoControlWrapper(&a1, 1398035268, 4, &status, &statusSize)) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(statusSize < 4)
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
*out = status;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool AsWMI_NB_GetDeviceStatus_MoreBYTE(int a1, int a2, int *status1, int *status2, int* status3)
|
||||
{
|
||||
if ( !WMI_Notebook )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int commandData[2];
|
||||
commandData[0] = a1;
|
||||
commandData[1] = a2;
|
||||
int statusBuffer[3];
|
||||
int statusSize = 12;
|
||||
if ( hDevice
|
||||
&& hDevice != HANDLE(-1)
|
||||
&& DeviceIoControlWrapper(commandData, 1398035268, 8, statusBuffer, &statusSize) )
|
||||
{
|
||||
*status1 = statusBuffer[0];
|
||||
*status2 = statusBuffer[1];
|
||||
*status3 = statusBuffer[2];
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
17
wmi/acpiwmi.h
Normal file
17
wmi/acpiwmi.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef ACPIWMI_H
|
||||
#define ACPIWMI_H
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
bool AsWMI_CheckSupport();
|
||||
bool AsWMI_Open();
|
||||
void AsWMI_Close();
|
||||
bool AsWMI_NB_RegisterEvent();
|
||||
bool AsWMI_NB_DeviceControl(int a1, int a2);
|
||||
bool AsWMI_NB_DeviceControl_2arg(int a1, int a2, int a3);
|
||||
char AsWMI_NB_GetDeviceStatus(int a1, int *out);
|
||||
bool AsWMI_NB_GetDeviceStatus_MoreBYTE(int a1, int a2, int *status1, int *status2, int* status3);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // ACPIWMI_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue