Mercurial > minori
annotate dep/animia/src/win/x11.cc @ 157:18c8eb5d1edc
x11: make it work
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Thu, 16 Nov 2023 16:51:34 -0500 |
parents | cdf79282d647 |
children | 80d6b28eb29f |
rev | line source |
---|---|
157 | 1 #include "animia/win/x11.h" |
2 #include "animia/win.h" | |
3 #include "animia.h" | |
4 | |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
5 #include <X11/Xlib.h> |
157 | 6 #include <X11/Xutil.h> |
7 #include <X11/Xatom.h> // XA_* | |
8 #include <cstdint> | |
9 #include <string> | |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
10 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
11 /* 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
|
12 (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
|
13 between Animia's types and X11's types */ |
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 namespace animia::internal::x11 { |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
16 |
157 | 17 /* should return UTF8_STRING or STRING */ |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
18 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
|
19 int format; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
20 unsigned long leftover_bytes, num_of_items; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
21 ::Atom type; |
157 | 22 unsigned char* data; |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
23 |
157 | 24 if (!::XGetWindowProperty(display, window, ::XInternAtom(display, atom, False), 0L, (~0L), False, reqtype, |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
25 &type, &format, &num_of_items, &leftover_bytes, &data)) |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
26 return false; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
27 |
157 | 28 result = std::string((char*)data, num_of_items); |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
29 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
30 ::XFree(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 return true; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
33 } |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
34 |
157 | 35 /* this should return CARDINAL, a 32-bit integer */ |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
36 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
|
37 int format; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
38 unsigned long leftover_bytes, num_of_items; |
157 | 39 ::Atom reqtype = XA_CARDINAL, atom = ::XInternAtom(display, "_NET_WM_PID", False), type; |
40 unsigned char* data; | |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
41 |
157 | 42 /* TODO: check the type for this */ |
43 if (!::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, | |
44 &type, &format, &num_of_items, &leftover_bytes, &data)) | |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
45 return false; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
46 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
47 result = static_cast<pid_t>(*(uint32_t*)data); |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
48 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
49 ::XFree(data); |
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 return true; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
52 } |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
53 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
54 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
|
55 /* TODO: Check if XInternAtom created None or not... */ |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
56 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
|
57 return true; |
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 /* Fallback to XGetWMName() */ |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
60 XTextProperty text; |
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 { |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
63 int status = ::XGetWMName(display, window, &text); |
157 | 64 if (!status || !text.value || !text.nitems) |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
65 return false; |
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 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
68 char** list; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
69 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
70 { |
157 | 71 int count; |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
72 |
157 | 73 int status = ::XmbTextPropertyToTextList(display, &text, &list, &count); |
74 if (status < Success || !count || !*list) | |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
75 return false; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
76 } |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
77 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
78 ::XFree(text.value); |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
79 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
80 result = *list; |
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 ::XFreeStringList(list); |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
83 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
84 return true; |
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 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
87 bool X11WinTools::EnumerateWindows(window_proc_t window_proc) { |
157 | 88 auto get_window_property = [&](::Display* display, ::Window window, ::Atom atom, unsigned long& num_of_items, unsigned char** data) -> int { |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
89 int format; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
90 unsigned long leftover_bytes; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
91 ::Atom realtype; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
92 |
157 | 93 return ::XGetWindowProperty(display, window, atom, 0L, (~0L), false, AnyPropertyType, |
94 &realtype, &format, &num_of_items, &leftover_bytes, data); | |
95 }; | |
156
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 ::Display* display = ::XOpenDisplay(nullptr); |
157 | 98 ::Window root = DefaultRootWindow(display); |
156
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 unsigned long num_windows; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
101 ::Window* windows = nullptr; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
102 |
157 | 103 int status = get_window_property(display, root, ::XInternAtom(display, "_NET_CLIENT_LIST", true), num_windows, (unsigned char**)&windows); |
156
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 if (status < Success) |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
106 return false; |
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 for (long k = 0; k < num_windows; k++) { |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
109 const ::Window window = windows[k]; |
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 Window win; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
112 win.id = (long)windows[k]; |
157 | 113 { |
114 ::XClassHint* hint = ::XAllocClassHint(); | |
115 if (::XGetClassHint(display, window, hint)) { | |
116 win.class_name = hint->res_class; | |
117 ::XFree(hint); | |
118 } | |
119 } | |
120 FetchName(display, windows[k], win.text); | |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
121 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
122 Process proc; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
123 GetWindowPID(display, window, proc.pid); |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
124 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
125 if (!window_proc(proc, win)) |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
126 return false; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
127 } |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
128 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
129 return true; |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
130 } |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
131 |
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
132 } |