Mercurial > minori
changeset 162:61b76c7b656a
dep/animia: add os x launchservices method
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Fri, 17 Nov 2023 16:49:57 -0500 |
parents | 71752dcbb49f |
children | 44c5e6dd9488 |
files | dep/animia/CMakeLists.txt dep/animia/include/animia/util/osx.h dep/animia/src/animia.cc dep/animia/src/fd/xnu.cc dep/animia/src/util/osx.cc |
diffstat | 5 files changed, 131 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/dep/animia/CMakeLists.txt Fri Nov 17 13:09:20 2023 -0500 +++ b/dep/animia/CMakeLists.txt Fri Nov 17 16:49:57 2023 -0500 @@ -10,6 +10,8 @@ src/win.cc ) +include(CheckLanguage) + set(LIBRARIES) set(INCLUDE_DIRS) set(DEFINES) @@ -20,6 +22,14 @@ # xnu stuff src/fd/xnu.cc ) + + include(CheckIncludeFile) + check_include_file("CoreFoundation/CoreFoundation.h" HAVE_COREFOUNDATION) + if (HAVE_COREFOUNDATION) + list(APPEND DEFINES HAVE_COREFOUNDATION) + list(APPEND SRC_FILES src/util/osx.cc) + endif() + check_language(OBJCXX) if(CMAKE_OBJCXX_COMPILER) enable_language(OBJCXX)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/include/animia/util/osx.h Fri Nov 17 16:49:57 2023 -0500 @@ -0,0 +1,13 @@ +#ifndef __animia__animia__util__osx_h +#define __animia__animia__util__osx_h + +#include "animia/types.h" +#include <string> + +namespace animia::internal::osx::util { + +bool LaunchServicesGetProcessName(pid_t pid, std::string& result); + +} + +#endif // __animia__animia__util__osx_h
--- a/dep/animia/src/animia.cc Fri Nov 17 13:09:20 2023 -0500 +++ b/dep/animia/src/animia.cc Fri Nov 17 16:49:57 2023 -0500 @@ -72,11 +72,6 @@ We should set the PID of the process if we can get it, but that'll be for when I can actually be arsed to implement the X11 backend. */ auto window_proc = [&](const Process& process, const Window& window) -> bool { - std::cout << "Window ID: " << window.id << "\n" - << "\tClass name: " << window.class_name << "\n" - << "\tTitle text: " << window.text << "\n" - << "\tProcess info: " << "\n" - << "\t\tPID: " << process.pid << "\n"; for (const auto& player : players) { if (!internal::PlayerHasStrategy(player, Strategy::WindowTitle)) continue;
--- a/dep/animia/src/fd/xnu.cc Fri Nov 17 13:09:20 2023 -0500 +++ b/dep/animia/src/fd/xnu.cc Fri Nov 17 16:49:57 2023 -0500 @@ -1,8 +1,11 @@ /* -** fd/xnu.cpp +** fd/xnu.cc ** - provides support for XNU (part of Darwin) */ #include "animia/fd/xnu.h" +#ifdef HAVE_COREFOUNDATION +# include "animia/util/osx.h" +#endif #include "animia.h" #include <cassert> @@ -28,18 +31,22 @@ /* Get the initial size of the array */ size_t size; - int ret = sysctl((int*)mib, mib_size, nullptr, &size, nullptr, 0); - if (ret) - return false; + { + int ret = sysctl((int*)mib, mib_size, nullptr, &size, nullptr, 0); + if (ret) + return false; + } /* Reserve the space for it in a std::string */ std::string args; args.resize(size); /* Get the contents of argc and argv */ - ret = sysctl((int*)mib, mib_size, &args.front(), &size, NULL, 0); - if (ret) - return false; + { + int ret = sysctl((int*)mib, mib_size, &args.front(), &size, NULL, 0); + if (ret) + return false; + } /* Is the size big enough to hold at least argc? */ if (size < sizeof(int)) @@ -51,8 +58,7 @@ int argc; memcpy(&argc, &args.front(), sizeof(argc)); - /* Check for a condition that, realistically, would never happen, - but better to be safe than sorry */ + /* Do we even have argv[0]? */ if (argc < 1) return false; @@ -81,7 +87,13 @@ } static bool GetProcessName(pid_t pid, std::string& result) { - /* First try parsing the arguments, this prevents the process name being + /* Use LaunchServices */ +#ifdef HAVE_COREFOUNDATION + if (osx::util::LaunchServicesGetProcessName(pid, result)) + return true; +#endif + + /* Try parsing the arguments, this prevents the process name being cut off to 2*MAXCOMLEN (32 chars) */ if (GetProcessNameFromArgs(pid, result)) return true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/src/util/osx.cc Fri Nov 17 16:49:57 2023 -0500 @@ -0,0 +1,86 @@ +/* A wrapper around multiple LaunchServices things */ + +#include "animia/util/osx.h" + +#include <CoreFoundation/CoreFoundation.h> + +#include <iostream> + +namespace animia::internal::osx::util { + +#define RDSymbolNameStr(symbol) (CFSTR("_"#symbol)) + +static constexpr int kLaunchServicesMagicConstant = -2; // or -1, dunno the difference + +typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t); +typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef); + +static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr; +static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr; + +static CFStringRef (kLSDisplayNameKey) = nullptr; +static CFStringRef (kLSPIDKey) = nullptr; + +static CFStringRef (kLaunchServicesBundleID) = CFSTR("com.apple.LaunchServices"); + +static bool FindLaunchServicesPrivateSymbols() { + CFBundleRef launch_services_bundle = CFBundleGetBundleWithIdentifier(kLaunchServicesBundleID); + if (!launch_services_bundle) + return false; + + LSCopyApplicationInformation = (LSCopyApplicationInformationSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, RDSymbolNameStr(LSCopyApplicationInformation)); + if (!LSCopyApplicationInformation) + return false; + + LSASNCreateWithPid = (LSASNCreateWithPidSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, RDSymbolNameStr(LSASNCreateWithPid)); + if (!LSASNCreateWithPid) + return false; + + kLSDisplayNameKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, RDSymbolNameStr(kLSDisplayNameKey)); + if (!kLSDisplayNameKey) + return false; + + kLSPIDKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, RDSymbolNameStr(kLSPIDKey)); + if (!kLSPIDKey) + return false; + + return true; +} + +bool LaunchServicesGetProcessName(pid_t pid, std::string& result) { + if (!LSCopyApplicationInformation || !LSASNCreateWithPid) + if (!FindLaunchServicesPrivateSymbols()) + return false; + + CFTypeRef asn = LSASNCreateWithPid(kCFAllocatorDefault, pid); + + CFArrayRef request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL); + + CFDictionaryRef dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array); + + CFRelease(request_array); + if (!dictionary) + return false; + + CFStringRef str; + if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&str) || !str) { + CFRelease(dictionary); + return false; + } + CFRetain(str); + + CFRelease(dictionary); + + result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1); + + if (!CFStringGetCString(str, &result.front(), result.length(), result.length())) { + CFRelease(str); + return false; + } + + CFRelease(str); + + return true; +} + +}