changeset 157:18c8eb5d1edc

x11: make it work
author Paper <mrpapersonic@gmail.com>
date Thu, 16 Nov 2023 16:51:34 -0500
parents cdf79282d647
children 80d6b28eb29f 900b5b530883
files dep/animia/src/fd/xnu.cc dep/animia/src/win.cc dep/animia/src/win/x11.cc
diffstat 3 files changed, 42 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/dep/animia/src/fd/xnu.cc	Wed Nov 15 18:04:04 2023 -0500
+++ b/dep/animia/src/fd/xnu.cc	Thu Nov 16 16:51:34 2023 -0500
@@ -19,13 +19,10 @@
 namespace animia::internal::xnu {
 
 static std::string GetProcessName(pid_t pid) {
-	struct proc_bsdinfo proc;
+	char name[2*MAXCOMLEN];
+	proc_name(pid, name, sizeof(name));
 
-	int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE);
-	if (st != PROC_PIDTBSDINFO_SIZE)
-		return "";
-
-	return (proc.pbi_name[0]) ? proc.pbi_name : proc.pbi_comm;
+	return name;
 }
 
 bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
@@ -38,8 +35,7 @@
 			return false;
 	}
 
-	for (int i = 0; i < size / sizeof(*pids); i++) {
-		const pid_t pid = pids[i].kp_proc.p_pid;
+	for (const auto& pid : pids) {
 		if (!process_proc({pid, GetProcessName(pid)}))
 			return false;
 	}
--- a/dep/animia/src/win.cc	Wed Nov 15 18:04:04 2023 -0500
+++ b/dep/animia/src/win.cc	Thu Nov 16 16:51:34 2023 -0500
@@ -12,6 +12,8 @@
 win32::Win32WinTools os_win;
 #elif MACOSX
 quartz::QuartzWinTools os_win;
+#elif X11
+x11::X11WinTools os_win;
 #else
 BaseWinTools os_win;
 #endif
--- a/dep/animia/src/win/x11.cc	Wed Nov 15 18:04:04 2023 -0500
+++ b/dep/animia/src/win/x11.cc	Thu Nov 16 16:51:34 2023 -0500
@@ -1,4 +1,12 @@
+#include "animia/win/x11.h"
+#include "animia/win.h"
+#include "animia.h"
+
 #include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h> // XA_*
+#include <cstdint>
+#include <string>
 
 /* The code for this is very fugly because X11 uses lots of generic type names
    (i.e., Window, Display), so I have to use :: when defining vars to distinguish
@@ -6,31 +14,34 @@
 
 namespace animia::internal::x11 {
 
+/* should return UTF8_STRING or STRING */
 static bool GetWindowPropertyAsString(::Display* display, ::Window window, const char* atom, std::string& result, ::Atom reqtype = AnyPropertyType) {
 	int format;
 	unsigned long leftover_bytes, num_of_items;
 	::Atom type;
-	void* data;
+	unsigned char* data;
 
-	if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype,
+	if (!::XGetWindowProperty(display, window, ::XInternAtom(display, atom, False), 0L, (~0L), False, reqtype,
 	                            &type, &format, &num_of_items, &leftover_bytes, &data))
 		return false;
 
-	result = std::string(data, num_of_items);
+	result = std::string((char*)data, num_of_items);
 
 	::XFree(data);
 
 	return true;
 }
 
+/* this should return CARDINAL, a 32-bit integer */
 static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) {
 	int format;
 	unsigned long leftover_bytes, num_of_items;
-	::Atom type;
-	void* data;
+	::Atom reqtype = XA_CARDINAL, atom = ::XInternAtom(display, "_NET_WM_PID", False), type;
+	unsigned char* data;
 
-	if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype,
-	                            &type, &format, &num_of_items, &leftover_bytes, &data))
+	/* TODO: check the type for this */
+	if (!::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype,
+	                          &type, &format, &num_of_items, &leftover_bytes, &data))
 		return false;
 
 	result = static_cast<pid_t>(*(uint32_t*)data);
@@ -50,17 +61,17 @@
 
 	{
 		int status = ::XGetWMName(display, window, &text);
-		if (!status || !text_prop.value || !text_prop.nitems)
+		if (!status || !text.value || !text.nitems)
 			return false;
 	}
 
 	char** list;
 
 	{
-		int num;
+		int count;
 
-		int status = ::XmbTextPropertyToTextList(display, &text, &list, &num);
-		if (status < Success || !num || !*list)
+		int status = ::XmbTextPropertyToTextList(display, &text, &list, &count);
+		if (status < Success || !count || !*list)
 			return false;
 	}
 
@@ -74,22 +85,22 @@
 }
 
 bool X11WinTools::EnumerateWindows(window_proc_t window_proc) {
-	auto get_window_property = [&](Display* display, Window window, Atom atom, unsigned long& num_of_items, void*& data) -> int {
+	auto get_window_property = [&](::Display* display, ::Window window, ::Atom atom, unsigned long& num_of_items, unsigned char** data) -> int {
 		int format;
 		unsigned long leftover_bytes;
 		::Atom realtype;
 
-		return ::XGetWindowProperty(display, root, atom, 0L, (~0L), false, AnyPropertyType,
-		                            &realtype, &format, &num_of_items, &leftover_bytes, &data);
-	}
+		return ::XGetWindowProperty(display, window, atom, 0L, (~0L), false, AnyPropertyType,
+		                            &realtype, &format, &num_of_items, &leftover_bytes, data);
+	};
 
 	::Display* display = ::XOpenDisplay(nullptr);
-	::Window root = ::DefaultRootWindow(display);
+	::Window root = DefaultRootWindow(display);
 
 	unsigned long num_windows;
 	::Window* windows = nullptr;
 
-	int status = get_window_property(display, root, ::XInternAtom(display, "_NET_CLIENT_LIST", true), num_windows, (void*)windows);
+	int status = get_window_property(display, root, ::XInternAtom(display, "_NET_CLIENT_LIST", true), num_windows, (unsigned char**)&windows);
 
 	if (status < Success)
 		return false;
@@ -99,8 +110,14 @@
 
 		Window win;
 		win.id = (long)windows[k];
-		GetWindowPropertyAsString(display, window, "_NET_ACTIVE_WINDOW", win.class_name, ::XInternAtom(display, "STRING", false));
-		win.title = FetchName(display, windows[k]);
+		{
+			::XClassHint* hint = ::XAllocClassHint();
+			if (::XGetClassHint(display, window, hint)) {
+				win.class_name = hint->res_class;
+				::XFree(hint);
+			}
+		}
+		FetchName(display, windows[k], win.text);
 
 		Process proc;
 		GetWindowPID(display, window, proc.pid);