1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
local lgi = require "lgi"
local Gio = lgi.Gio
local GObject = lgi.GObject
local GLib = lgi.GLib
local gpcall = require "gears.protected_call"
local gtimer = require "gears.timer"
local methods = {}
local interface = Gio.DBusInterfaceInfo {
name = "com.twoexem.delta.Curious",
methods = {
Gio.DBusMethodInfo {
name = "Select",
out_args = {
Gio.DBusArgInfo {
name = "widget_tree",
signature = "av",
},
},
},
},
}
-- iterate with ipairs, get the length of the array, check if key value from pairs is a number lower than the length and if so, use as a dict key cause it's not gonna work with :add anyway
local function serialize(builder, t)
local array_length = 0
for i, _ in ipairs(t) do
array_length = i
end
for k, v in pairs(t) do
local _type = type(v)
local signature
local data
if _type == "number" then
signature = "d"
data = v
elseif _type == "string" then
signature = "s"
data = v
elseif _type == "boolean" then
signature = "b"
data = v
elseif _type == "thread" or _type == "function" or (_type == "userdata" and not getmetatable(v).__tostring) then
local address = tonumber(tostring(v):match "%a+: 0x(%w+)", 16)
signature = "(s(t))"
data = { _type, address }
elseif _type == "userdata" then
if getmetatable(v).emit_signal then -- One of the properties available on any awesome luaobject
local _, _, content = tostring(v):match "%a+/(.*)"
local stringified = tostring(v)
if content then
stringified = content
end
local type, extra, address = stringified:match "(%a+)(.*): 0x(%w+)"
if extra ~= "" then
extra:sub(2, -2)
signature = "(s(st))"
data = { type, extra, address }
else
signature = "(s(t))"
data = { type, address }
end
else
signature = "(s())"
data = { _type, {} }
end
end
if type(k) == "number" and k > array_length then
builder:add("v", GLib.Variant(signature, data))
else
print(type(signature), type(data))
local variant = GLib.Variant("{sd}", { "test", 4 })
builder:add_value(GLib.Variant("v", variant))
end
end
end
function methods.Select(parameters, invocation)
local builder = GLib.VariantBuilder(GLib.VariantType "av")
serialize(builder, { "test", some_key = "some_value" })
local tuple_builder = GLib.VariantBuilder(GLib.VariantType "(av)")
tuple_builder:add_value(builder:_end())
-- builder
-- invocation:return_value(GLib.Variant("(av)", { builder }))
invocation:return_value(tuple_builder:_end())
end
local function handle_call(_, _, _, _, method, parameters, invocation)
if not methods[method] then
print "invalid"
return
end
gpcall(methods[method], parameters, invocation)
end
local function acquire(connection)
connection:register_object("/com/twoexem/delta/Curious", interface, GObject.Closure(handle_call))
end
local connection = Gio.bus_own_name(
Gio.BusType.SESSION,
"com.twoexem.delta.Curious",
Gio.BusNameOwnerFlags.NONE,
GObject.Closure(acquire)
)
|