lua-api: Add custom modelines

This commit is contained in:
Ottatop 2024-06-04 10:48:34 -05:00
parent bc8ec3d5a6
commit ad81b553c8
5 changed files with 156 additions and 3 deletions

1
Cargo.lock generated
View file

@ -2388,6 +2388,7 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "smithay"
version = "0.3.0"
source = "git+https://github.com/Smithay/smithay?rev=900b938#900b938970081cb525dc94ff083d76aa07c60e54"
dependencies = [
"appendlist",
"ash",

View file

@ -34,9 +34,9 @@ dircpy = "0.3.16"
tempfile = "3.10.1"
[workspace.dependencies.smithay]
# git = "https://github.com/Smithay/smithay"
# rev = "900b938"
path = "../../git/smithay"
git = "https://github.com/Smithay/smithay"
rev = "900b938"
# path = "../../git/smithay"
default-features = false
features = [
"desktop",

View file

@ -65,6 +65,20 @@ local pinnacle_output_v0alpha1_Transform = {
---@field pixel_height integer?
---@field refresh_rate_millihz integer?
---@class pinnacle.output.v0alpha1.SetModelineRequest
---@field output_name string?
---@field clock number?
---@field hdisplay integer?
---@field hsync_start integer?
---@field hsync_end integer?
---@field htotal integer?
---@field vdisplay integer?
---@field vsync_start integer?
---@field vsync_end integer?
---@field vtotal integer?
---@field hsync_pos boolean?
---@field vsync_pos boolean?
---@class pinnacle.output.v0alpha1.SetScaleRequest
---@field output_name string?
---@field absolute number?
@ -476,6 +490,13 @@ defs.pinnacle = {
response = "google.protobuf.Empty",
},
---@type GrpcRequestArgs
SetModeline = {
service = "pinnacle.output.v0alpha1.OutputService",
method = "SetModeline",
request = "pinnacle.output.v0alpha1.SetModelineRequest",
response = "google.protobuf.Empty",
},
---@type GrpcRequestArgs
SetScale = {
service = "pinnacle.output.v0alpha1.OutputService",
method = "SetScale",

View file

@ -813,6 +813,54 @@ function OutputHandle:set_mode(pixel_width, pixel_height, refresh_rate_millihz)
})
end
---@class Modeline
---@field clock number
---@field hdisplay integer
---@field hsync_start integer
---@field hsync_end integer
---@field htotal integer
---@field vdisplay integer
---@field vsync_start integer
---@field vsync_end integer
---@field vtotal integer
---@field hsync boolean
---@field vsync boolean
---Set a custom modeline for this output.
---
---This accepts a `Modeline` table or a string of the modeline.
---
---@param modeline string|Modeline
function OutputHandle:set_modeline(modeline)
if type(modeline) == "string" then
local ml, err = require("pinnacle.util").output.parse_modeline(modeline)
if ml then
modeline = ml
else
print("invalid modeline: " .. tostring(err))
return
end
end
---@type pinnacle.output.v0alpha1.SetModelineRequest
local request = {
output_name = self.name,
clock = modeline.clock,
hdisplay = modeline.hdisplay,
hsync_start = modeline.hsync_start,
hsync_end = modeline.hsync_end,
htotal = modeline.htotal,
vdisplay = modeline.vdisplay,
vsync_start = modeline.vsync_start,
vsync_end = modeline.vsync_end,
vtotal = modeline.vtotal,
hsync_pos = modeline.hsync,
vsync_pos = modeline.vsync,
}
client.unary_request(output_service.SetModeline, request)
end
---Set this output's scaling factor.
---
---@param scale number

View file

@ -118,10 +118,93 @@ function rectangle.new(x, y, width, height)
return self
end
---Parse a modeline string.
---
---@param modeline string
---
---@return Modeline|nil modeline A modeline if successful
---@return string|nil error An error message if any
local function parse_modeline(modeline)
local args = modeline:gmatch("[^%s]+")
local targs = {}
for arg in args do
table.insert(targs, arg)
end
local clock = tonumber(targs[1])
local hdisplay = tonumber(targs[2])
local hsync_start = tonumber(targs[3])
local hsync_end = tonumber(targs[4])
local htotal = tonumber(targs[5])
local vdisplay = tonumber(targs[6])
local vsync_start = tonumber(targs[7])
local vsync_end = tonumber(targs[8])
local vtotal = tonumber(targs[9])
local hsync = targs[10]
local vsync = targs[11]
if
not (
clock
and hdisplay
and hsync_start
and hsync_end
and htotal
and vdisplay
and vsync_start
and vsync_end
and vtotal
and hsync
and vsync
)
then
return nil, "one or more fields was missing"
end
local hsync_lower = string.lower(hsync)
local vsync_lower = string.lower(vsync)
if hsync_lower == "+hsync" then
hsync = true
elseif hsync_lower == "-hsync" then
hsync = false
else
return nil, "invalid hsync: " .. hsync
end
if vsync_lower == "+vsync" then
vsync = true
elseif vsync_lower == "-vsync" then
vsync = false
else
return nil, "invalid vsync: " .. vsync
end
---@type Modeline
return {
clock = clock,
hdisplay = hdisplay,
hsync_start = hsync_start,
hsync_end = hsync_end,
htotal = htotal,
vdisplay = vdisplay,
vsync_start = vsync_start,
vsync_end = vsync_end,
vtotal = vtotal,
hsync = hsync,
vsync = vsync,
}
end
---Utility functions.
---@class Util
local util = {
rectangle = rectangle,
output = {
parse_modeline = parse_modeline,
},
}
---Batch a set of requests that will be sent to the compositor all at once.