annotate dep/animia/src/win/x11.cc @ 156:cdf79282d647

dep/animia: add VERY early x11 window stuff
author Paper <mrpapersonic@gmail.com>
date Wed, 15 Nov 2023 18:04:04 -0500
parents
children 18c8eb5d1edc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
1 #include <X11/Xlib.h>
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
2
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
3 /* The code for this is very fugly because X11 uses lots of generic type names
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
4 (i.e., Window, Display), so I have to use :: when defining vars to distinguish
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
5 between Animia's types and X11's types */
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
6
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
7 namespace animia::internal::x11 {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
8
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
9 static bool GetWindowPropertyAsString(::Display* display, ::Window window, const char* atom, std::string& result, ::Atom reqtype = AnyPropertyType) {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
10 int format;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
11 unsigned long leftover_bytes, num_of_items;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
12 ::Atom type;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
13 void* data;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
14
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
15 if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype,
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
16 &type, &format, &num_of_items, &leftover_bytes, &data))
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
17 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
18
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
19 result = std::string(data, num_of_items);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
20
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
21 ::XFree(data);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
22
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
23 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
24 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
25
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
26 static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
27 int format;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
28 unsigned long leftover_bytes, num_of_items;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
29 ::Atom type;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
30 void* data;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
31
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
32 if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype,
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
33 &type, &format, &num_of_items, &leftover_bytes, &data))
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
34 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
35
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
36 result = static_cast<pid_t>(*(uint32_t*)data);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
37
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
38 ::XFree(data);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
39
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
40 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
41 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
42
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
43 static bool FetchName(::Display* display, ::Window window, std::string& result) {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
44 /* TODO: Check if XInternAtom created None or not... */
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
45 if (GetWindowPropertyAsString(display, window, "_NET_WM_NAME", result, ::XInternAtom(display, "UTF8_STRING", false)))
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
46 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
47
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
48 /* Fallback to XGetWMName() */
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
49 XTextProperty text;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
50
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
51 {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
52 int status = ::XGetWMName(display, window, &text);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
53 if (!status || !text_prop.value || !text_prop.nitems)
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
54 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
55 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
56
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
57 char** list;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
58
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
59 {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
60 int num;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
61
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
62 int status = ::XmbTextPropertyToTextList(display, &text, &list, &num);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
63 if (status < Success || !num || !*list)
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
64 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
65 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
66
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
67 ::XFree(text.value);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
68
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
69 result = *list;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
70
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
71 ::XFreeStringList(list);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
72
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
73 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
74 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
75
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
76 bool X11WinTools::EnumerateWindows(window_proc_t window_proc) {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
77 auto get_window_property = [&](Display* display, Window window, Atom atom, unsigned long& num_of_items, void*& data) -> int {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
78 int format;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
79 unsigned long leftover_bytes;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
80 ::Atom realtype;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
81
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
82 return ::XGetWindowProperty(display, root, atom, 0L, (~0L), false, AnyPropertyType,
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
83 &realtype, &format, &num_of_items, &leftover_bytes, &data);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
84 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
85
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
86 ::Display* display = ::XOpenDisplay(nullptr);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
87 ::Window root = ::DefaultRootWindow(display);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
88
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
89 unsigned long num_windows;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
90 ::Window* windows = nullptr;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
91
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
92 int status = get_window_property(display, root, ::XInternAtom(display, "_NET_CLIENT_LIST", true), num_windows, (void*)windows);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
93
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
94 if (status < Success)
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
95 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
96
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
97 for (long k = 0; k < num_windows; k++) {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
98 const ::Window window = windows[k];
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
99
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
100 Window win;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
101 win.id = (long)windows[k];
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
102 GetWindowPropertyAsString(display, window, "_NET_ACTIVE_WINDOW", win.class_name, ::XInternAtom(display, "STRING", false));
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
103 win.title = FetchName(display, windows[k]);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
104
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
105 Process proc;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
106 GetWindowPID(display, window, proc.pid);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
107
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
108 if (!window_proc(proc, win))
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
109 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
110 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
111
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
112 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
113 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
114
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
115 }