Skip to content

Instantly share code, notes, and snippets.

@Python1320
Created January 8, 2022 16:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Python1320/c74e3340be9895ff822074cd521bb7fb to your computer and use it in GitHub Desktop.
Save Python1320/c74e3340be9895ff822074cd521bb7fb to your computer and use it in GitHub Desktop.
An extremely dirty hack to turn on Windows screen over MQTT with LuaJIT/Luapower/TINN
@rem hi
:restartthis
cd "C:\Users\display\Downloads\luapower-all-x86-x64-master"
"C:\Users\display\Downloads\luapower-all-x86-x64-master\bin\mingw32\luajit.exe" main.lua
GOTO restartthis
-- Things borrowed from TINN: https://github.com/Wiladams/TINN ( https://github.com/Wiladams/TINN/blob/296e56bdb05815d32c772a303b96dc0dc0601cbf/src/win32/UIOSimulator.lua ) until cleanup as dependency
-- Runs under https://luapower.com/
-- Requires:
-- https://mosquitto.org/download/
-- https://github.com/hwhw/ffi_libmosquitto
-- https://github.com/Wiladams/lj2win32
-- TODO: Extreme cleanup, use actual TINN library instead of copypaste
local Tag = 'screenwake'
local MYDEVICEID="test123"
local HOST="10.0.0.1"
----------------
local ffi = require "ffi"
local C = ffi.C
local mq = require"mosquitto"
io.stderr:write("libmosquitto version "..table.concat({mq.lib_version()}, ".").."\n")
local client = mq.new(Tag.."_"..MYDEVICEID)
local ffi = require ("ffi")
local C = ffi.C
local bit = require ("bit")
local band = bit.band
local bor = bit.bor
require("win32.wingdi")
local User32 = require ("win32.winuser")
--[[
typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
DWORD mouseData;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;
--]]
local UIOSimulator = {
ScreenWidth = C.GetSystemMetrics(C.SM_CXSCREEN);
ScreenHeight = C.GetSystemMetrics(C.SM_CYSCREEN);
}
UIOSimulator.MouseDown = function(x, y, which)
local dx = math.ceil(x*65536/UIOSimulator.ScreenWidth)
local dy = math.ceil(y*65536/UIOSimulator.ScreenHeight)
-- construct mouseinput structure
-- call sendinput
local minput = ffi.new("INPUT");
minput.type = ffi.C.INPUT_MOUSE;
minput.mi.dx = dx;
minput.mi.dy = dy;
minput.mi.mouseData = 0;
minput.mi.dwFlags = bor(ffi.C.MOUSEEVENTF_ABSOLUTE, ffi.C.MOUSEEVENTF_LEFTDOWN);
local written, err = C.SendInput(1, minput, ffi.sizeof(minput))
end
UIOSimulator.MouseUp = function(x, y, which)
--print("InjectMouseUp")
local dx = math.ceil(x*65536/UIOSimulator.ScreenWidth)
local dy = math.ceil(y*65536/UIOSimulator.ScreenHeight)
-- construct mouseinput structure
-- call sendinput
local minput = ffi.new("INPUT");
minput.type = ffi.C.INPUT_MOUSE;
minput.mi.dx = dx;
minput.mi.dy = dy;
minput.mi.mouseData = 0;
minput.mi.dwFlags = bor(ffi.C.MOUSEEVENTF_ABSOLUTE, ffi.C.MOUSEEVENTF_LEFTUP);
local written, err = C.SendInput(1, minput, ffi.sizeof(minput))
end
UIOSimulator.MouseMove = function(x, y)
local dx = math.ceil(x*65536/UIOSimulator.ScreenWidth)
local dy = math.ceil(y*65536/UIOSimulator.ScreenHeight)
-- construct mouseinput structure
-- call sendinput
local sinput = ffi.new("INPUT");
sinput.type = ffi.C.INPUT_MOUSE;
sinput.mi.dx = dx;
sinput.mi.dy = dy;
sinput.mi.mouseData = 0;
sinput.mi.dwFlags = bor(ffi.C.MOUSEEVENTF_ABSOLUTE, ffi.C.MOUSEEVENTF_MOVE);
local written, err = C.SendInput(1, sinput, ffi.sizeof(sinput))
--print(written, err);
end
--[[
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
--]]
UIOSimulator.KeyDown = function(code)
local sinput = ffi.new("INPUT");
sinput.type = ffi.C.INPUT_KEYBOARD;
sinput.ki.wVk = code;
sinput.ki.wScan = 0;
--sinput.ki.dwFlags = 0;
--sinput.ki.time = 0;
--sinput.ki.dwExtraInfo = nil;
local written, err = User32.SendInput(1, sinput, ffi.sizeof(sinput))
end
UIOSimulator.KeyUp = function(code)
local sinput = ffi.new("INPUT");
sinput.type = ffi.C.INPUT_KEYBOARD;
sinput.ki.wVk = code;
sinput.ki.wScan = 0;
sinput.ki.dwFlags = ffi.C.KEYEVENTF_KEYUP;
--sinput.ki.time = 0;
--sinput.ki.dwExtraInfo = nil;
local written, err = User32.SendInput(1, sinput, ffi.sizeof(sinput))
end
function UIOSimulator.InjectKeyboardActivity(flags, code)
local sinput = ffi.new("INPUT");
sinput.type = ffi.C.INPUT_KEYBOARD;
sinput.ki.wVk = code;
sinput.ki.wScan = 0;
sinput.ki.dwFlags = ffi.C.KEYEVENTF_SCANCODE;
--sinput.ki.time = 0;
--sinput.ki.dwExtraInfo = nil;
if band(flags, KBD_FLAGS_RELEASE) ~= 0 then
sinput.ki.dwFlags = bor(sinput.ki.dwFlags, C.KEYEVENTF_KEYUP);
end
if band(flags, KBD_FLAGS_EXTENDED) ~= 0 then
sinput.ki.dwFlags = bor(sinput.ki.dwFlags, C.KEYEVENTF_EXTENDEDKEY);
end
local written, err = C.SendInput(1, sinput, ffi.sizeof(sinput))
--print(written, err);
end
local ffi = require('ffi')
local uisim = UIOSimulator
--print("RECTL: ", ffi.typeof("RECTL"))
print("Size: ", uisim.ScreenWidth, uisim.ScreenHeight)
local log={notice=print}
local function dbg(...)
log.notice(...)
return true
end
local errs = {
SUCCESS = 0,
NOMEM = 1,
PROTOCOL = 2,
INVAL = 3,
NO_CONN = 4,
CONN_REFUSED = 5,
NOT_FOUND = 6,
CONN_LOST = 7,
TLS = 8,
PAYLOAD_SIZE = 9,
NOT_SUPPORTED = 10,
AUTH = 11,
ACL_DENIED = 12,
UNKNOWN = 13,
ERRNO = 14,
EAI = 15,
PROXY = 16,
EINVAL = 22,
EAGAIN = 35,
EHOSTUNREACH = 65,
ENOTSOCK = 38,
ENETDOWN = 50,
EPROTONOSUPPORT = 43,
ENOBUFS = 55,
ENETUNREACH = 51,
ENOTSUP = 45,
ETIMEDOUT = 60,
EADDRNOTAVAIL = 49,
EADDRINUSE = 48,
ECONNABORTED = 53,
EAFNOSUPPORT = 47,
ECONNREFUSED = 61,
ENOTCONN = 57,
EINPROGRESS = 36,
ECONNRESET = 54,
EMSGSIZE = 40
}
function mosquitto_error_str(errornumber)
for k, v in next, errs do
if v == errornumber then return k end
end
return "unknown: "..tostring(errornumber)
end
--client:username_pw_set(arg[4], arg[5])
local os=require'os'
client:connect(HOST)
client:log_callback_set_wrapper(function(...)
dbg(...)
end)
client:disconnect_callback_set_wrapper(function(code)
print("disconnected? ",mosquitto_error_str(code))
os.exit(1)
end)
client:reconnect_delay_set(3,30,false)
client:subscribe_message_callback(MYDEVICEID.."/monitor/all/power/command", nil, function(message)
dbg"turning on"
uisim.MouseMove(1,1)
uisim.MouseMove(2,2)
end)
print"loop..."
client:loop_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment