New example: Dump colormap
[luaxcb.git] / examples / ShowProps.lua
blobe17cd6852b47dac8e7818ef363f0e21e045a68d3
1 require("lxcb")
3 function printf(...)
4 io.output():write(string.format(...))
5 end
7 local atom = {}
8 local atomname = {}
10 function internatom(this, name)
11 local id = c:intern_atom_reply(c:intern_atom(false, string.len(name), name)).atom
12 this[name] = id
13 atomname[id] = name
14 return id
15 end
17 function getatomname(this, id)
18 local name = string.char(unpack(c:get_atom_name_reply(c:get_atom_name(id)).name))
19 this[id] = name
20 atom[name] = id
21 return name
22 end
24 setmetatable(atom, { __index = internatom })
25 setmetatable(atomname, { __index = getatomname })
28 function FontCursor(c, id)
29 local font = c:generate_id()
30 local cursor = c:generate_id()
31 local fn = "cursor"
32 c:open_font(font, string.len(fn), fn)
33 c:create_glyph_cursor(cursor, font, font, id, id+1, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0)
34 c:close_font(font)
36 return cursor
37 end
39 -- Routine to let user select a window using the mouse
40 function Select_Window(c)
41 local status
42 local cursor
43 local event
44 local target_win = 0
45 local root = c:get_setup().roots[screen+1].root
46 local buttons = 0
48 -- Make the target cursor
49 cursor = FontCursor(c, 34); -- XC_crosshair
51 -- Grab the pointer using target cursor, letting it room all over
52 local grabreq = c:grab_pointer(false, root,
53 c.EVENT_MASK.BUTTON_PRESS + c.EVENT_MASK.BUTTON_RELEASE,
54 c.GRAB_MODE.SYNC, c.GRAB_MODE.ASYNC,
55 root, cursor, 0) -- CurrentTime)
56 status = c:grab_pointer_reply(grabreq).status
57 if (status ~= c.GRAB_STATUS.SUCCESS) then
58 printf("Can't grab the mouse.\n")
59 return 0;
60 end
62 -- Let the user select a window...
63 while ((target_win == 0) or (buttons ~= 0)) do
64 -- allow one more event
65 c:allow_events(c.ALLOW.SYNC_POINTER, 0) -- CurrentTime)
67 c:flush() -- wait_for_event doesn't automatically flush.
68 event = c:wait_for_event()
70 if (event.response_type == 4) -- "ButtonPress")
71 then
72 if (target_win == 0) then
73 target_win = event.child -- window selected
74 if (target_win == 0) then target_win = event.event end
75 if (target_win == 0) then target_win = event.root end
76 end
77 buttons = buttons + 1
78 elseif (event.response_type == 5) -- "ButtonRelease")
79 then
80 if (buttons > 0) then -- there may have been some down before we started
81 buttons = buttons - 1
82 end
83 end
84 end
86 c:ungrab_pointer(0) -- CurrentTime) -- Done with pointer
88 printf("target_win = 0x%08X\n", target_win)
89 return target_win
90 end
92 function string2int(s)
93 -- assume we're running on an LSB machine
94 local multiplier = 1;
95 local value = 0;
96 local bytes = { string.byte(s, 1, #s) }
97 for k,v in ipairs(bytes) do
98 value = value + v * multiplier
99 multiplier = multiplier * 0x100
101 return value
104 local dumper = {
105 STRING = function(prop) printf(" = %s", prop) end,
106 UTF8_STRING = function(prop) printf(" = %s", prop) end,
107 CARDINAL = function(prop) printf(" = 0x%X", string2int(prop)) end,
108 ATOM = function(prop)
109 printf(" = ")
110 while (#prop >= 4) do
111 local atom = string2int(string.sub(prop, 1, 4))
112 prop = string.sub(prop, 5);
113 printf("%s, ", atomname[atom])
115 end,
119 function DumpProps(c, id)
120 local list = c:list_properties_reply(c:list_properties(id)).atoms;
121 for k, v in ipairs(list) do
122 local name = atomname[v]
123 printf(" %s: ",name);
124 local prop = c:get_property_reply(c:get_property(false, id, v, c.GET_PROPERTY_TYPE.ANY, 0, 100))
125 if (prop) then
126 local typename = atomname[prop.type]
127 printf("%s", typename)
128 if (dumper[typename]) then dumper[typename](prop.value) end
130 printf("\n");
134 local root
135 c, screen = lxcb.connect()
137 if (not c) then
138 print("Error: Cannot open default display.")
139 return 1;
142 if (#arg >= 1) then
143 root = tonumber(arg[1])
144 if (not root) then
145 print("Usage: ShowProps [window]")
146 return 1;
148 else
149 root = Select_Window(c)
152 DumpProps(c, root)
154 c = nil
156 return 0