Mercurial > minori
view dep/animia/src/util/osx.cc @ 162:61b76c7b656a
dep/animia: add os x launchservices method
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Fri, 17 Nov 2023 16:49:57 -0500 |
parents | |
children | 44c5e6dd9488 |
line wrap: on
line source
/* 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; } }