Mercurial > minori
comparison dep/animia/src/win/x11.cc @ 202:71832ffe425a
animia: re-add kvm fd source
this is all being merged from my wildly out-of-date laptop. SORRY!
in other news, I edited the CI file to install the wayland client
as well, so the linux CI build might finally get wayland stuff.
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Tue, 02 Jan 2024 06:05:06 -0500 |
parents | 9f3534f6b8c4 |
children | 58e81b42a0d6 |
comparison
equal
deleted
inserted
replaced
201:8f6f8dd2eb23 | 202:71832ffe425a |
---|---|
3 #include "animia.h" | 3 #include "animia.h" |
4 | 4 |
5 #include <X11/Xlib.h> | 5 #include <X11/Xlib.h> |
6 #include <X11/Xutil.h> | 6 #include <X11/Xutil.h> |
7 #include <X11/Xatom.h> // XA_* | 7 #include <X11/Xatom.h> // XA_* |
8 #ifdef HAVE_XRES | |
9 #include <X11/extensions/XRes.h> | |
10 #endif | |
8 | 11 |
9 #include <cstdint> | 12 #include <cstdint> |
10 #include <string> | 13 #include <string> |
11 #include <set> | 14 #include <set> |
12 | 15 |
14 (i.e., Window, Display), so I have to use :: when defining vars to distinguish | 17 (i.e., Window, Display), so I have to use :: when defining vars to distinguish |
15 between Animia's types and X11's types */ | 18 between Animia's types and X11's types */ |
16 | 19 |
17 namespace animia::internal::x11 { | 20 namespace animia::internal::x11 { |
18 | 21 |
22 /* specify that these are X types. */ | |
23 typedef ::Window XWindow; | |
24 typedef ::Display XDisplay; | |
25 typedef ::Atom XAtom; | |
26 | |
19 /* should return UTF8_STRING or STRING */ | 27 /* should return UTF8_STRING or STRING */ |
20 static bool GetWindowPropertyAsString(::Display* display, ::Window window, ::Atom atom, std::string& result, ::Atom reqtype = AnyPropertyType) { | 28 static bool GetWindowPropertyAsString(XDisplay* display, XWindow window, XAtom atom, std::string& result, XAtom reqtype = AnyPropertyType) { |
21 int format; | 29 int format; |
22 unsigned long leftover_bytes, num_of_items; | 30 unsigned long leftover_bytes, num_of_items; |
23 ::Atom type; | 31 XAtom type; |
24 unsigned char* data; | 32 unsigned char* data; |
25 | 33 |
26 int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, | 34 int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, |
27 &type, &format, &num_of_items, &leftover_bytes, &data); | 35 &type, &format, &num_of_items, &leftover_bytes, &data); |
28 if (status != Success || !(reqtype == AnyPropertyType || type == reqtype) || !num_of_items) | 36 if (status != Success || !(reqtype == AnyPropertyType || type == reqtype) || !num_of_items) |
34 | 42 |
35 return true; | 43 return true; |
36 } | 44 } |
37 | 45 |
38 /* this should return CARDINAL, a 32-bit integer */ | 46 /* this should return CARDINAL, a 32-bit integer */ |
39 static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) { | 47 static bool GetWindowPID(XDisplay* display, XWindow window, pid_t& result) { |
48 #ifdef HAVE_XRES | |
49 { | |
50 long num_ids; | |
51 XResClientIdValue *client_ids; | |
52 XResClientIdSpec spec = { | |
53 .client = window, | |
54 .mask = XRES_CLIENT_ID_PID_MASK | |
55 }; | |
56 | |
57 ::XResQueryClientIds(display, 1, &spec, &num_ids, &client_ids); | |
58 | |
59 for (long i = 0; i < num_ids; i++) { | |
60 if (client_ids[i].spec.mask == XRES_CLIENT_ID_PID_MASK) { | |
61 result = ::XResGetClientPid(&client_ids[i]); | |
62 ::XResClientIdsDestroy(num_ids, client_ids); | |
63 return true; | |
64 } | |
65 } | |
66 | |
67 ::XResClientIdsDestroy(num_ids, client_ids); | |
68 | |
69 return false; | |
70 } | |
71 #endif | |
72 | |
40 int format; | 73 int format; |
41 unsigned long leftover_bytes, num_of_items; | 74 unsigned long leftover_bytes, num_of_items; |
42 ::Atom atom = ::XInternAtom(display, "_NET_WM_PID", False), type; | 75 XAtom atom = ::XInternAtom(display, "_NET_WM_PID", False), type; |
43 unsigned char* data; | 76 unsigned char* data; |
44 | 77 |
45 int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, XA_CARDINAL, | 78 int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, XA_CARDINAL, |
46 &type, &format, &num_of_items, &leftover_bytes, &data); | 79 &type, &format, &num_of_items, &leftover_bytes, &data); |
47 if (status != Success || type != XA_CARDINAL || num_of_items < 1) | 80 if (status != Success || type != XA_CARDINAL || num_of_items < 1) |
48 return false; | 81 return false; |
49 | 82 |
50 result = static_cast<pid_t>(*(uint32_t*)data); | 83 result = static_cast<pid_t>(*reinterpret_cast<uint32_t*>(data)); |
51 | 84 |
52 ::XFree(data); | 85 ::XFree(data); |
53 | 86 |
54 return true; | 87 return true; |
55 } | 88 } |
56 | 89 |
57 static bool FetchName(::Display* display, ::Window window, std::string& result) { | 90 static bool FetchName(XDisplay* display, XWindow window, std::string& result) { |
58 /* TODO: Check if XInternAtom created None or not... */ | 91 /* TODO: Check if XInternAtom created None or not... */ |
59 if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "_NET_WM_NAME", False), | 92 if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "_NET_WM_NAME", False), |
60 result, ::XInternAtom(display, "UTF8_STRING", False))) | 93 result, ::XInternAtom(display, "UTF8_STRING", False))) |
61 return true; | 94 return true; |
62 | 95 |
90 ::XFreeStringList(list); | 123 ::XFreeStringList(list); |
91 | 124 |
92 return true; | 125 return true; |
93 } | 126 } |
94 | 127 |
95 static bool WalkWindows(::Display* display, std::set<::Window>& children, const std::set<::Window>& windows) { | 128 static bool WalkWindows(XDisplay* display, std::set<XWindow>& children, const std::set<XWindow>& windows) { |
129 /* This can take a VERY long time if many windows are open. */ | |
96 if (windows.empty()) | 130 if (windows.empty()) |
97 return false; | 131 return false; |
98 | 132 |
99 for (const ::Window& window : windows) { | 133 for (const XWindow& window : windows) { |
100 unsigned int num_children = 0; | 134 unsigned int num_children = 0; |
101 ::Window* children_arr = nullptr; | 135 XWindow* children_arr = nullptr; |
102 | 136 |
103 ::Window root_return; | 137 XWindow root_return; |
104 ::Window parent_return; | 138 XWindow parent_return; |
105 | 139 |
106 int status = ::XQueryTree(display, window, &root_return, &parent_return, &children_arr, &num_children); | 140 int status = ::XQueryTree(display, window, &root_return, &parent_return, &children_arr, &num_children); |
107 if (!status || !children_arr) | 141 if (!status || !children_arr) |
108 continue; | 142 continue; |
109 | 143 |
116 if (!children.count(children_arr[i])) | 150 if (!children.count(children_arr[i])) |
117 children.insert(children_arr[i]); | 151 children.insert(children_arr[i]); |
118 | 152 |
119 ::XFree(children_arr); | 153 ::XFree(children_arr); |
120 | 154 |
121 std::set<::Window> children_children; | 155 std::set<XWindow> children_children; |
122 | 156 |
123 if (WalkWindows(display, children_children, children)) | 157 if (WalkWindows(display, children_children, children)) |
124 children.insert(children_children.begin(), children_children.end()); | 158 children.insert(children_children.begin(), children_children.end()); |
125 } | 159 } |
126 | 160 |
127 return true; | 161 return true; |
128 } | 162 } |
129 | 163 |
130 bool X11WinTools::EnumerateWindows(window_proc_t window_proc) { | 164 bool EnumerateWindows(window_proc_t window_proc) { |
131 if (!window_proc) | 165 if (!window_proc) |
132 return false; | 166 return false; |
133 | 167 |
134 ::Display* display = ::XOpenDisplay(nullptr); | 168 XDisplay* display = ::XOpenDisplay(nullptr); |
135 if (!display) | 169 if (!display) |
136 return false; | 170 return false; |
137 | 171 |
138 ::Window root = DefaultRootWindow(display); | 172 XWindow root = ::XDefaultRootWindow(display); |
139 | 173 |
140 std::set<::Window> windows; | 174 std::set<XWindow> windows; |
141 WalkWindows(display, windows, {root}); | 175 WalkWindows(display, windows, {root}); |
142 | 176 |
143 for (const auto& window : windows) { | 177 for (const auto& window : windows) { |
144 Window win; | 178 Window win; |
145 win.id = window; | 179 win.id = window; |