Skip to content

Instantly share code, notes, and snippets.

@Zekfad
Last active April 28, 2021 11:00
Show Gist options
  • Save Zekfad/0eebadcaca0f8031241a6c0e7cbdf0a3 to your computer and use it in GitHub Desktop.
Save Zekfad/0eebadcaca0f8031241a6c0e7cbdf0a3 to your computer and use it in GitHub Desktop.
Listen for ROG notebook FN keystrokes.

What's that?

This tool will listen for ASUS notebook's FN keystrokes. And it will map ROG key to Scroll Lock and Fan key to Num Lock. (Ctrl + Num Lock = Pause key).

Compile and run

$ clang main.cpp -o rog.exe && rog.exe
// Introduce some shit (a.k.a. winapi)
#define UNICODE
#include <windows.h>
#pragma comment(lib, "user32")
// #include <fcntl.h>
#define _O_U16TEXT 0x00020000
#define _O_U8TEXT 0x00040000
#include <io.h>
#include <stdio.h>
enum ASUSKEYS : UINT {
ROG_KEY = 56,
FN_F10 = 107,
MUTE = 124,
FN_V = 138,
FN_C = 158,
FN_F5 = 174,
FN_LEFT = 178,
FN_RIGHT = 179,
FN_UP = 196,
FN_DOWN = 197,
// Aliases
FAN_KEY = FN_F5,
};
const wchar_t pClassName[] = L"ROGKeyRebind";
const wchar_t pWindowName[] = L"ROGKeyRebind";
UINT pAPCI = RegisterWindowMessageW(L"ACPI Notification through ATKHotkey from BIOS");
void SendScanCode(WORD scancode) {
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0;
ip.ki.dwExtraInfo = 0;
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
ip.ki.wScan = scancode;
SendInput(1, &ip, sizeof(INPUT));
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
return;
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg == pAPCI) {
switch (wParam) {
case ASUSKEYS::MUTE:
wprintf(L"Mute key\n");
break;
case ASUSKEYS::FAN_KEY:
wprintf(L"Fan key\n");
SendScanCode(0x45); // Send NumLock
break;
case ASUSKEYS::ROG_KEY:
wprintf(L"ROG key\n");
SendScanCode(0x46); // Send ScrollLock
break;
case ASUSKEYS::FN_F10:
wprintf(L"Fn + 10 key\n");
break;
case ASUSKEYS::FN_C:
wprintf(L"Fn + C key\n");
break;
case ASUSKEYS::FN_V:
wprintf(L"Fn + V key\n");
break;
case ASUSKEYS::FN_UP:
wprintf(L"Fn + Up Arrow key\n");
break;
case ASUSKEYS::FN_LEFT:
wprintf(L"Fn + Left Arrow key\n");
break;
case ASUSKEYS::FN_DOWN:
wprintf(L"Fn + Down Arrow key\n");
break;
case ASUSKEYS::FN_RIGHT:
wprintf(L"Fn + Right Arrow key\n");
break;
default:
wprintf(L"Unknown key: %d\n", wParam);
break;
}
} else {
switch (uMsg) {
case WM_DESTROY:
wprintf(L"Error window destroyed. Shutting down.\n");
PostQuitMessage(0);
ExitProcess(4);
break;
default:
break;
}
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
int main() {
_setmode(_fileno(stdout), _O_U16TEXT);
HMODULE hInst = GetModuleHandleW(nullptr);
if (hInst == 0) {
wprintf(L"Error getting module.\n");
return 2;
}
WNDCLASSEXW wc = {};
wc.lpfnWndProc = MainWndProc;
wc.hInstance = hInst;
wc.lpszClassName = pWindowName;
wc.cbSize = sizeof(wc);
RegisterClassEx(&wc);
HWND hWnd = CreateWindowExW(
0,
wc.lpszClassName,
pWindowName,
WS_VISIBLE,
-1, -1, 1, 1,
nullptr,
nullptr,
hInst,
nullptr
);
if (hWnd == 0) {
wprintf(L"Error spawning window.\n");
return 3;
}
ShowWindow(hWnd, SW_HIDE);
ChangeWindowMessageFilterEx(
hWnd,
pAPCI,
MSGFLT_ALLOW,
nullptr
);
wprintf(L"Listening for keys.\n");
MSG msg;
int bRet = -1;
while ((bRet = GetMessageW(&msg, hWnd, 0, 0)) != 0) {
if (bRet < 0) {
wprintf(L"Unknown error while getting message.");
return 1;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
wprintf(L"Shutting down.\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment