changeset 155:d2bbb5773616

dep/animia: add quartz backend for windows
author Paper <mrpapersonic@gmail.com>
date Wed, 15 Nov 2023 15:24:39 -0500
parents d43d68408d3c
children cdf79282d647
files dep/animia/CMakeLists.txt dep/animia/include/animia/win/quartz.h dep/animia/src/animia.cc dep/animia/src/fd/xnu.cc dep/animia/src/win.cc dep/animia/src/win/quartz.mm
diffstat 6 files changed, 105 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/dep/animia/CMakeLists.txt	Wed Nov 15 14:14:17 2023 -0500
+++ b/dep/animia/CMakeLists.txt	Wed Nov 15 15:24:39 2023 -0500
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.9)
-project(animia)
+project(animia LANGUAGES CXX)
 set(SRC_FILES
 	# any non-platform-specific files go here
 	src/animia.cc
@@ -10,6 +10,8 @@
 	src/win.cc
 )
 
+set(LIBRARIES)
+
 # FD
 if(LINUX)
 	list(APPEND SRC_FILES
@@ -34,8 +36,15 @@
 		src/win/win32.cc
 		src/util/win32.cc
 	)
-else()
-	# soon x11 and apple stuff will be here...
+elseif(APPLE)
+	enable_language(OBJCXX)
+	list(APPEND SRC_FILES
+		src/win/quartz.mm
+	)
+	find_library(FOUNDATION_LIBRARY Foundation)
+	find_library(COREGRAPHICS_LIBRARY CoreGraphics)
+	find_library(APPKIT_LIBRARY AppKit)
+	list(APPEND LIBRARIES ${FOUNDATION_LIBRARY} ${COREGRAPHICS_LIBRARY} ${APPKIT_LIBRARY})
 endif()
 
 add_library(animia SHARED ${SRC_FILES})
@@ -56,3 +65,4 @@
 endif()
 
 target_include_directories(animia PRIVATE include)
+target_link_libraries(animia PUBLIC ${LIBRARIES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animia/include/animia/win/quartz.h	Wed Nov 15 15:24:39 2023 -0500
@@ -0,0 +1,15 @@
+#ifndef __animia__animia__fd__quartz_h
+#define __animia__animia__fd__quartz_h
+
+#include "animia/win.h"
+
+namespace animia::internal::quartz {
+
+class QuartzWinTools final : public BaseWinTools {
+	public:
+		bool EnumerateWindows(window_proc_t window_proc) override;
+};
+
+}
+
+#endif // __animia__animia__fd__quartz_h
--- a/dep/animia/src/animia.cc	Wed Nov 15 14:14:17 2023 -0500
+++ b/dep/animia/src/animia.cc	Wed Nov 15 15:24:39 2023 -0500
@@ -50,6 +50,8 @@
 bool GetResults(const std::vector<Player>& players, std::vector<Result>& results) {
 	/* Start out with file descriptors. */
 	auto process_proc = [&](const Process& process) -> bool {
+		std::cout << process.name << std::endl;
+
 		for (const auto& player : players) {
 			if (!internal::PlayerHasStrategy(player, Strategy::OpenFiles))
 				continue;
--- a/dep/animia/src/fd/xnu.cc	Wed Nov 15 14:14:17 2023 -0500
+++ b/dep/animia/src/fd/xnu.cc	Wed Nov 15 15:24:39 2023 -0500
@@ -25,8 +25,6 @@
 	if (st != PROC_PIDTBSDINFO_SIZE)
 		return "";
 
-	/* fixme: is this right? pbi_comm is an alternative, but it reduces the string size to
-	   16 chars. does pbi_name do the same, or is it different? */
 	return proc.pbi_name;
 }
 
--- a/dep/animia/src/win.cc	Wed Nov 15 14:14:17 2023 -0500
+++ b/dep/animia/src/win.cc	Wed Nov 15 15:24:39 2023 -0500
@@ -2,12 +2,16 @@
 
 #ifdef WIN32
 #	include "animia/win/win32.h"
+#elif MACOSX
+#	include "animia/win/quartz.h"
 #endif
 
 namespace animia::internal {
 
 #ifdef WIN32
 win32::Win32WinTools os_win;
+#elif MACOSX
+quartz::QuartzWinTools os_win;
 #else
 BaseWinTools os_win;
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animia/src/win/quartz.mm	Wed Nov 15 15:24:39 2023 -0500
@@ -0,0 +1,71 @@
+#include "animia/win/quartz.h"
+#include "animia.h"
+
+#include <Foundation/Foundation.h>
+#include <CoreGraphics/CoreGraphics.h>
+#include <AppKit/AppKit.h>
+
+namespace animia::internal::quartz {
+
+template<typename T>
+static bool IntegerFromNSNumber(NSNumber* num, T& result) {
+	if (!num)
+		return false;
+	result = [num intValue];
+	return true;
+}
+
+static bool GetWindowTitle(unsigned int wid, std::string& result) {
+	NSWindow* window = [NSApp windowWithWindowNumber: wid];
+	if (!window)
+		return false;
+
+	NSString* title = [window title];
+	if (!title)
+		return false;
+
+	result = [title UTF8String];
+
+	return true;
+}
+
+static bool StringFromNSString(NSString* string, std::string& result) {
+	if (!string)
+		return false;
+	result = [string UTF8String];
+	return true;
+}
+
+bool QuartzWinTools::EnumerateWindows(window_proc_t window_proc) {
+	if (!window_proc)
+		return false;
+
+	NSMutableArray* windows = (NSMutableArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
+	if (!windows)
+		return false;
+
+	for (NSDictionary* window in windows) {
+		if (!window)
+			continue;
+
+		Process proc;
+		{
+			IntegerFromNSNumber([window objectForKey:@"kCGWindowOwnerPID"], proc.pid);
+			StringFromNSString([window objectForKey:@"kCGWindowOwnerName"], proc.name);
+		}
+
+		Window win;
+		{
+			IntegerFromNSNumber([window objectForKey:@"kCGWindowNumber"], win.id);
+			StringFromNSString([window objectForKey:@"kCGWindowName"], win.class_name);
+			GetWindowTitle(win.id, win.text);
+		}
+
+		if (!window_proc(proc, win))
+			return false;
+	}
+
+	return true;
+}
+
+} // namespace animia::win::detail