-- Minimal second-window process for src/render/DesktopScreen.lua. local DesktopCompanion = {} function DesktopCompanion.install(config) local enet = require("enet") local host = assert(enet.host_create()) local peer = assert(host:connect(("127.0.0.1:%d"):format(config.port), 2)) local image, sourceW, sourceH, preference local background = { 0, 0, 0, 1 } local connected, commandedQuit = false, false local pointerDown = false local started = love.timer.getTime() local lastContact = started local function send(kind, payload) if not connected then return end pcall(peer.send, peer, kind .. config.token .. (payload or ""), 1, "reliable") end local function receiveFrame(data) local prefix = "F" .. config.token .. "\n" if data:sub(1, #prefix) ~= prefix then return end local split = data:find("\n", #prefix + 1, true) if not split then return end local w, h, rgb, mode = data:sub(#prefix + 1, split - 1) :match("^(%d+),(%d+),(%d+),([%w_:.-]+)$") w, h, rgb = tonumber(w), tonumber(h), tonumber(rgb) if not w or not h or w < 1 or h < 1 or w > 4096 or h > 4096 then return end local ok, raw = pcall(love.data.decompress, "string", "lz4", data:sub(split + 1)) if not ok or type(raw) ~= "string" or #raw ~= w * h * 4 then return end local made, pixels = pcall(love.image.newImageData, w, h, "rgba8", raw) if not made then return end if not image or sourceW ~= w or sourceH ~= h then if image and image.release then image:release() end image = love.graphics.newImage(pixels) else image:replacePixels(pixels) end sourceW, sourceH, preference = w, h, mode image:setFilter(mode:find("cover", 1, true) and "linear" or "nearest", mode:find("cover", 1, true) and "linear" or "nearest") background = { math.floor(rgb / 0x10000) % 0x100 / 255, math.floor(rgb / 0x100) % 0x100 / 255, rgb % 0x100 / 255, 1, } end local function service() while true do local event = host:service(0) if not event then break end if event.type == "connect" then connected, lastContact = true, love.timer.getTime() send("H") elseif event.type == "receive" then lastContact = love.timer.getTime() if event.data == "Q" .. config.token then commandedQuit = true love.event.quit() elseif event.data ~= "P" .. config.token then receiveFrame(event.data) end elseif event.type == "disconnect" then love.event.quit() end end end local function placement() if not image then return 0, 0, 1 end local ww, wh = love.graphics.getDimensions() local cover = preference and preference:find("cover", 1, true) local scale = (cover and math.max or math.min)(ww / sourceW, wh / sourceH) return (ww - sourceW * scale) / 2, (wh - sourceH * scale) / 2, scale end local function input(action, x, y) if not image then return false end local dx, dy, scale = placement() local sx, sy = math.floor((x - dx) / scale), math.floor((y - dy) / scale) if sx < 0 or sy < 0 or sx >= sourceW or sy >= sourceH then return false end send("I", ("\n%s,%d,%d"):format(action, sx, sy)) return true end function love.update() service() local t = love.timer.getTime() if (not connected and t - started > 5) or t - lastContact > 5 then love.event.quit() end end function love.draw() love.graphics.clear(background[1], background[2], background[3], background[4]) if not image then return end local x, y, scale = placement() love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(image, x, y, 0, scale, scale) end function love.mousepressed(x, y, button) if button == 1 then pointerDown = input("down", x, y) end end function love.mousereleased(x, y, button) if button == 1 and pointerDown then if not input("up", x, y) then send("I", "\ncancel,0,0") end pointerDown = false end end function love.touchpressed(_, x, y) input("down", x, y) end function love.touchreleased(_, x, y) input("up", x, y) end function love.keypressed(key) if key == "escape" then love.event.quit() end end function love.quit() if not commandedQuit then send("C") end pcall(peer.disconnect_now, peer) end end return DesktopCompanion