Mercurial > minori
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 |
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 } |