Mercurial > minori
changeset 156:cdf79282d647
dep/animia: add VERY early x11 window stuff
line wrap: on
line diff
--- a/dep/animia/CMakeLists.txt Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/CMakeLists.txt Wed Nov 15 18:04:04 2023 -0500 @@ -12,18 +12,27 @@ set(LIBRARIES) +set(INCLUDE_DIRS + include +) + +set(DEFINES) + # FD if(LINUX) + list(APPEND DEFINES LINUX) list(APPEND SRC_FILES # linux src/fd/linux.cc ) elseif(APPLE) # this won't run on Linux + list(APPEND DEFINES MACOSX) list(APPEND SRC_FILES # xnu stuff src/fd/xnu.cc ) elseif(WIN32) + list(APPEND DEFINES WIN32) list(APPEND SRC_FILES # win32 src/fd/win32.cc @@ -45,6 +54,20 @@ find_library(COREGRAPHICS_LIBRARY CoreGraphics) find_library(APPKIT_LIBRARY AppKit) list(APPEND LIBRARIES ${FOUNDATION_LIBRARY} ${COREGRAPHICS_LIBRARY} ${APPKIT_LIBRARY}) +else() + find_package(X11::X11) + if (X11_FOUND) + list(APPEND DEFINES X11) + list(APPEND SRC_FILES + src/win/x11.cc + ) + list(APPEND INCLUDE_DIRS + ${X11_INCLUDE_DIR} + ) + list(APPEND LIBRARIES + ${X11_LIBRARIES} + ) + endif() endif() add_library(animia SHARED ${SRC_FILES})
--- a/dep/animia/include/animia.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia.h Wed Nov 15 18:04:04 2023 -0500 @@ -13,22 +13,22 @@ }; struct Process { - internal::pid_t pid = 0; - std::string name; + internal::pid_t pid = 0; + std::string name; }; struct Window { - unsigned int id = 0; - std::string class_name; - std::string text; // title bar text + unsigned int id = 0; + std::string class_name; + std::string text; // title bar text }; struct Result { - ResultType type; - Player player; - Process process; // unused when using window_title. it's dumb, blame X11 - Window window; // unused with file descriptors - std::vector<Media> media; + ResultType type; + Player player; + Process process; // unused when using window_title. it's dumb, blame X11 + Window window; // unused with file descriptors + std::vector<Media> media; }; bool GetResults(const std::vector<Player>& players, std::vector<Result>& results);
--- a/dep/animia/include/animia/fd.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/fd.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,9 +1,9 @@ #ifndef __animia__animia__fd_h #define __animia__animia__fd_h +#include <functional> #include <set> #include <string> -#include <functional> #include "animia/types.h" @@ -14,8 +14,8 @@ namespace internal { struct OpenFile { - pid_t pid = 0; - std::string path; + pid_t pid = 0; + std::string path; }; using process_proc_t = std::function<bool(const Process&)>;
--- a/dep/animia/include/animia/fd/linux.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/fd/linux.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,15 +1,15 @@ #ifndef __animia__animia__fd__linux_h #define __animia__animia__fd__linux_h +#include <set> #include <string> -#include <set> +#include "animia/fd.h" #include "animia/types.h" -#include "animia/fd.h" /* Russian warship, go fuck yourself */ #ifdef linux -#undef linux +# undef linux #endif namespace animia::internal::linux { @@ -20,6 +20,6 @@ bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override; }; -} +} // namespace animia::internal::linux #endif // __animia__animia__fd__linux_h
--- a/dep/animia/include/animia/fd/win32.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/fd/win32.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,13 +1,13 @@ #ifndef __animia__animia__fd__win32_h #define __animia__animia__fd__win32_h +#include <set> #include <string> -#include <set> #include <windows.h> +#include "animia/fd.h" #include "animia/types.h" -#include "animia/fd.h" namespace animia::internal::win32 { @@ -17,6 +17,6 @@ bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override; }; -} +} // namespace animia::internal::win32 #endif // __animia__animia__fd__win32_h
--- a/dep/animia/include/animia/fd/xnu.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/fd/xnu.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,11 +1,11 @@ #ifndef __animia__animia__fd__xnu_h #define __animia__animia__fd__xnu_h +#include <set> #include <string> -#include <set> +#include "animia/fd.h" #include "animia/types.h" -#include "animia/fd.h" namespace animia::internal::xnu { @@ -15,6 +15,6 @@ bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override; }; -} +} // namespace animia::internal::xnu #endif // __animia__animia__fd__xnu_h
--- a/dep/animia/include/animia/media.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/media.h Wed Nov 15 18:04:04 2023 -0500 @@ -19,14 +19,14 @@ }; struct MediaInfo { - MediaInfoType type = MediaInfoType::Unknown; - std::string value; + MediaInfoType type = MediaInfoType::Unknown; + std::string value; }; struct Media { - std::vector<MediaInfo> information; + std::vector<MediaInfo> information; }; -} // namespace animia +} // namespace animia #endif // __animia__animia__media_h
--- a/dep/animia/include/animia/player.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/player.h Wed Nov 15 18:04:04 2023 -0500 @@ -18,12 +18,12 @@ }; struct Player { - PlayerType type = PlayerType::Default; - std::string name; - std::string window_title_format; - std::vector<std::string> windows; - std::vector<std::string> executables; - std::vector<Strategy> strategies; + PlayerType type = PlayerType::Default; + std::string name; + std::string window_title_format; + std::vector<std::string> windows; + std::vector<std::string> executables; + std::vector<Strategy> strategies; }; bool ParsePlayersData(const std::string& data, std::vector<Player>& players);
--- a/dep/animia/include/animia/types.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/types.h Wed Nov 15 18:04:04 2023 -0500 @@ -5,13 +5,13 @@ don't force the user to include <windows.h> or <IntBase.h> */ #ifdef _WIN32 namespace animia::internal { - typedef unsigned long pid_t; +typedef unsigned long pid_t; } #else /* <sys/types.h> shouldn't be that big, right? */ # include <sys/types.h> namespace animia::internal { - typedef ::pid_t pid_t; +typedef ::pid_t pid_t; } #endif
--- a/dep/animia/include/animia/util.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/util.h Wed Nov 15 18:04:04 2023 -0500 @@ -12,6 +12,6 @@ bool TrimLeft(std::string& str, const char* chars); bool TrimRight(std::string& str, const char* chars); -} +} // namespace animia::internal::util #endif // __animia__animia__util_h \ No newline at end of file
--- a/dep/animia/include/animia/util/win32.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/util/win32.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,14 +1,17 @@ +#ifndef __animia__animia__util__win32_h +#define __animia__animia__util__win32_h + #include <windows.h> #include <subauth.h> +#include <memory> #include <string> -#include <memory> namespace animia::internal::win32 { struct HandleDeconstructor { - using pointer = HANDLE; - void operator()(pointer t) const { ::CloseHandle(t); }; + using pointer = HANDLE; + void operator()(pointer t) const { ::CloseHandle(t); }; }; using Handle = std::unique_ptr<HANDLE, HandleDeconstructor>; @@ -25,4 +28,6 @@ bool IsSystemDirectory(const std::string& path); bool IsSystemDirectory(std::wstring path); -} \ No newline at end of file +} // namespace animia::internal::win32 + +#endif // __animia__animia__util__win32_h \ No newline at end of file
--- a/dep/animia/include/animia/win.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/win.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,8 +1,8 @@ #ifndef __animia__animia__win_h #define __animia__animia__win_h +#include <functional> #include <string> -#include <functional> namespace animia { @@ -15,7 +15,10 @@ class BaseWinTools { public: - virtual bool EnumerateWindows(window_proc_t window_proc) { return false; (void)window_proc; } + virtual bool EnumerateWindows(window_proc_t window_proc) { + return false; + (void)window_proc; + } }; extern BaseWinTools& win;
--- a/dep/animia/include/animia/win/quartz.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/win/quartz.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,5 +1,5 @@ -#ifndef __animia__animia__fd__quartz_h -#define __animia__animia__fd__quartz_h +#ifndef __animia__animia__win__quartz_h +#define __animia__animia__win__quartz_h #include "animia/win.h" @@ -10,6 +10,6 @@ bool EnumerateWindows(window_proc_t window_proc) override; }; -} +} // namespace animia::internal::quartz -#endif // __animia__animia__fd__quartz_h +#endif // __animia__animia__win__quartz_h
--- a/dep/animia/include/animia/win/win32.h Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/include/animia/win/win32.h Wed Nov 15 18:04:04 2023 -0500 @@ -1,5 +1,5 @@ -#ifndef __animia__animia__fd__win32_h -#define __animia__animia__fd__win32_h +#ifndef __animia__animia__win__win32_h +#define __animia__animia__win__win32_h #include "animia/win.h" @@ -10,6 +10,6 @@ bool EnumerateWindows(window_proc_t window_proc) override; }; -} +} // namespace animia::internal::win32 -#endif // __animia__animia__fd__win32_h +#endif // __animia__animia__win__win32_h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/include/animia/win/x11.h Wed Nov 15 18:04:04 2023 -0500 @@ -0,0 +1,15 @@ +#ifndef __animia__animia__win__x11_h +#define __animia__animia__win__x11_h + +#include "animia/win.h" + +namespace animia::internal::x11 { + +class X11WinTools final : public BaseWinTools { + public: + bool EnumerateWindows(window_proc_t window_proc) override; +}; + +} // namespace animia::internal::x11 + +#endif // __animia__animia__win__x11_h
--- a/dep/animia/src/animia.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/animia.cc Wed Nov 15 18:04:04 2023 -0500 @@ -1,15 +1,13 @@ +#include "animia.h" +#include "animia/fd.h" +#include "animia/strategies.h" +#include "animia/types.h" +#include "animia/util.h" +#include "animia/win.h" + +#include <set> #include <string> #include <vector> -#include <set> - -#include "animia.h" -#include "animia/util.h" -#include "animia/strategies.h" -#include "animia/types.h" -#include "animia/fd.h" -#include "animia/win.h" - -#include <iostream> namespace animia { @@ -50,8 +48,6 @@ 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; @@ -93,4 +89,4 @@ return internal::ApplyStrategies(results); } -} +} // namespace animia
--- a/dep/animia/src/fd.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/fd.cc Wed Nov 15 18:04:04 2023 -0500 @@ -22,4 +22,4 @@ BaseFdTools& fd = os_fd; -} +} // namespace animia::internal
--- a/dep/animia/src/fd/linux.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/fd/linux.cc Wed Nov 15 18:04:04 2023 -0500 @@ -1,18 +1,18 @@ -#include "animia/util.h" #include "animia/fd/linux.h" #include "animia.h" +#include "animia/util.h" #include <algorithm> +#include <cstring> #include <filesystem> #include <fstream> #include <sstream> #include <string> #include <unordered_map> #include <vector> -#include <cstring> +#include <dirent.h> #include <fcntl.h> -#include <dirent.h> #include <sys/stat.h> #include <unistd.h> @@ -58,7 +58,7 @@ if (!util::ReadFile(path, data)) return false; buffer << data; - } + } int flags = 0; for (std::string line; std::getline(buffer, line);) { @@ -75,7 +75,7 @@ static std::string GetFilenameFromFd(std::string link) { /* gets around stupid linux limitation where /proc doesn't give actual filesize readings */ - size_t exe_size = 1024; + size_t exe_size = 1024; ssize_t exe_used; std::string ret;
--- a/dep/animia/src/fd/win32.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/fd/win32.cc Wed Nov 15 18:04:04 2023 -0500 @@ -85,7 +85,7 @@ /* we should really put a cap on this */ ULONG cb = 1 << 19; - for (NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH; status == STATUS_INFO_LENGTH_MISMATCH; ) { + for (NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH; status == STATUS_INFO_LENGTH_MISMATCH;) { /* why are we doing this? */ status = STATUS_NO_MEMORY;
--- a/dep/animia/src/fd/xnu.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/fd/xnu.cc Wed Nov 15 18:04:04 2023 -0500 @@ -5,16 +5,16 @@ #include "animia/fd/xnu.h" #include "animia.h" +#include <cassert> +#include <string> #include <unordered_map> #include <vector> -#include <string> -#include <cassert> #include <fcntl.h> +#include <libproc.h> #include <sys/sysctl.h> #include <sys/types.h> #include <sys/user.h> -#include <libproc.h> namespace animia::internal::xnu { @@ -25,36 +25,21 @@ if (st != PROC_PIDTBSDINFO_SIZE) return ""; - return proc.pbi_name; + return (proc.pbi_name[0]) ? proc.pbi_name : proc.pbi_comm; } -/* this is a cleaned up version of a function from... Apple? - ...anyway, what it essentially does is gets the size and stuff from - sysctl() and reserves the space in a vector to store the PIDs */ bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { - struct kinfo_proc* result = NULL; - size_t length = 0; - static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; + std::vector<pid_t> pids; + pids.reserve(1024); - /* get appropriate length from sysctl() - note: the reason this isn't checked is actually because this will - *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */ - sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); - - result = (struct kinfo_proc*)malloc(length); - if (result == NULL) - return false; - - /* TODO: this might actually return ENOMEM if the amount of file handles changes between the - original sysctl() call and this one, which is technically possible */ - if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { - assert(result != NULL); - free(result); - return false; + for (int returned_size = pids.capacity(); pids.capacity() > returned_size; pids.reserve(pids.capacity() * 2)) { + returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.data(), pids.capacity() * sizeof(pid_t)); + if (returned_size == -1) + return false; } - for (int i = 0; i < length / sizeof(*result); i++) { - const pid_t pid = result[i].kp_proc.p_pid; + for (int i = 0; i < size / sizeof(*pids); i++) { + const pid_t pid = pids[i].kp_proc.p_pid; if (!process_proc({pid, GetProcessName(pid)})) return false; } @@ -81,13 +66,14 @@ if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { struct vnode_fdinfowithpath vnodeInfo; - int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE); + int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, + PROC_PIDFDVNODEPATHINFO_SIZE); if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) return false; /* this doesn't work! if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) - continue; + continue; */ if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) @@ -99,4 +85,4 @@ return true; } -} // namespace animia::internal::unix +} // namespace animia::internal::xnu
--- a/dep/animia/src/player.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/player.cc Wed Nov 15 18:04:04 2023 -0500 @@ -1,11 +1,11 @@ +#include "animia/player.h" +#include "animia/util.h" + #include <map> #include <sstream> #include <string> #include <vector> -#include "animia/player.h" -#include "animia/util.h" - namespace animia { namespace internal::parser { @@ -24,34 +24,26 @@ return line.find_first_not_of('\t'); } -bool HandleIndentation(const size_t current, - const std::vector<Player>& players, - State& state) { +bool HandleIndentation(const size_t current, const std::vector<Player>& players, State& state) { // Each state has a definitive expected indentation const auto expected = [&state]() -> size_t { switch (state) { default: - case State::ExpectPlayerName: - return 0; - case State::ExpectSection: - return 1; + case State::ExpectPlayerName: return 0; + case State::ExpectSection: return 1; case State::ExpectWindow: case State::ExpectExecutable: case State::ExpectStrategy: - case State::ExpectType: - return 2; - case State::ExpectWindowTitle: - return 3; + case State::ExpectType: return 2; + case State::ExpectWindowTitle: return 3; } }(); if (current > expected) - return false; // Disallow excessive indentation + return false; // Disallow excessive indentation if (current < expected) { - auto fix_state = [&]() { - state = !current ? State::ExpectPlayerName : State::ExpectSection; - }; + auto fix_state = [&]() { state = !current ? State::ExpectPlayerName : State::ExpectSection; }; switch (state) { case State::ExpectWindow: if (players.back().windows.empty()) @@ -68,11 +60,8 @@ return false; fix_state(); break; - case State::ExpectType: - fix_state(); - break; - case State::ExpectWindowTitle: - return false; + case State::ExpectType: fix_state(); break; + case State::ExpectWindowTitle: return false; } } @@ -89,10 +78,10 @@ case State::ExpectSection: { static const std::map<std::string, State> sections = { - {"windows", State::ExpectWindow}, - {"executables", State::ExpectExecutable}, - {"strategies", State::ExpectStrategy}, - {"type", State::ExpectType}, + {"windows", State::ExpectWindow }, + {"executables", State::ExpectExecutable}, + {"strategies", State::ExpectStrategy }, + {"type", State::ExpectType }, }; util::TrimRight(line, ":"); const auto it = sections.find(line); @@ -102,19 +91,15 @@ break; } - case State::ExpectWindow: - players.back().windows.push_back(line); - break; + case State::ExpectWindow: players.back().windows.push_back(line); break; - case State::ExpectExecutable: - players.back().executables.push_back(line); - break; + case State::ExpectExecutable: players.back().executables.push_back(line); break; case State::ExpectStrategy: { static const std::map<std::string, Strategy> strategies = { - {"window_title", Strategy::WindowTitle}, - {"open_files", Strategy::OpenFiles}, - {"ui_automation", Strategy::UiAutomation}, + {"window_title", Strategy::WindowTitle }, + {"open_files", Strategy::OpenFiles }, + {"ui_automation", Strategy::UiAutomation}, }; util::TrimRight(line, ":"); const auto it = strategies.find(line); @@ -123,17 +108,15 @@ const auto strategy = it->second; players.back().strategies.push_back(strategy); switch (strategy) { - case Strategy::WindowTitle: - state = State::ExpectWindowTitle; - break; + case Strategy::WindowTitle: state = State::ExpectWindowTitle; break; } break; } case State::ExpectType: { static const std::map<std::string, PlayerType> types = { - {"default", PlayerType::Default}, - {"web_browser", PlayerType::WebBrowser}, + {"default", PlayerType::Default }, + {"web_browser", PlayerType::WebBrowser}, }; const auto it = types.find(line); if (it == types.end()) @@ -151,7 +134,7 @@ return true; } -} // namespace internal::parser +} // namespace internal::parser //////////////////////////////////////////////////////////////////////////////// @@ -166,7 +149,7 @@ while (std::getline(stream, line, '\n')) { if (line.empty()) - continue; // Ignore empty lines + continue; // Ignore empty lines indentation = internal::parser::GetIndentation(line); @@ -174,7 +157,7 @@ internal::util::TrimRight(line, "\n\r"); if (line.empty() || line.front() == '#') - continue; // Ignore empty lines and comments + continue; // Ignore empty lines and comments if (!internal::parser::HandleIndentation(indentation, players, state)) return false; @@ -195,4 +178,4 @@ return ParsePlayersData(data, players); } -} // namespace animia +} // namespace animia
--- a/dep/animia/src/strategist.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/strategist.cc Wed Nov 15 18:04:04 2023 -0500 @@ -1,11 +1,9 @@ +#include <regex> + +#include "animia.h" +#include "animia/fd.h" #include "animia/strategies.h" #include "animia/util.h" -#include "animia/fd.h" -#include "animia.h" - -#include <iostream> - -#include <regex> namespace animia::internal { @@ -28,12 +26,8 @@ bool success = false; switch (result_.type) { - case ResultType::Process: - success |= ApplyOpenFilesStrategy(); - break; - case ResultType::Window: - success |= ApplyWindowTitleStrategy(); - break; + case ResultType::Process: success |= ApplyOpenFilesStrategy(); break; + case ResultType::Window: success |= ApplyWindowTitleStrategy(); break; } return success; @@ -80,8 +74,7 @@ static MediaInfoType InferMediaInformationType(const std::string& str) { const std::regex path_pattern(R"(^(?:[A-Za-z]:[/\\]|\\\\)[^<>:"/\\|?*]+)"); - return (std::regex_search(str, path_pattern)) - ? MediaInfoType::File : MediaInfoType::Unknown; + return (std::regex_search(str, path_pattern)) ? MediaInfoType::File : MediaInfoType::Unknown; } bool Strategist::ApplyWindowTitleStrategy() { @@ -119,4 +112,4 @@ return true; } -} +} // namespace animia::internal
--- a/dep/animia/src/util.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/util.cc Wed Nov 15 18:04:04 2023 -0500 @@ -1,10 +1,8 @@ #include <algorithm> #include <fstream> +#include <regex> #include <sstream> #include <string> -#include <regex> - -#include <iostream> #include "animia/util.h" @@ -28,13 +26,9 @@ /* this assumes ASCII... which really should be the case for what we need, anyway */ bool EqualStrings(const std::string& str1, const std::string& str2) { - auto tolower = [](const char c) -> char { - return ('A' <= c && c <= 'Z') ? c + ('a' - 'A') : c; - }; + auto tolower = [](const char c) -> char { return ('A' <= c && c <= 'Z') ? c + ('a' - 'A') : c; }; - auto equal_chars = [&tolower](const char c1, const char c2) -> bool { - return tolower(c1) == tolower(c2); - }; + auto equal_chars = [&tolower](const char c1, const char c2) -> bool { return tolower(c1) == tolower(c2); }; return str1.length() == str2.length() && std::equal(str1.begin(), str1.end(), str2.begin(), equal_chars); } @@ -90,4 +84,4 @@ return true; } -} // namespace anisthesia::detail::util +} // namespace animia::internal::util
--- a/dep/animia/src/util/win32.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/util/win32.cc Wed Nov 15 18:04:04 2023 -0500 @@ -1,8 +1,8 @@ #include "animia/util/win32.h" +#include <shlobj.h> /* SHGetKnownFolderPath */ +#include <subauth.h> /* UNICODE_STRING */ #include <windows.h> -#include <shlobj.h> /* SHGetKnownFolderPath */ -#include <subauth.h> /* UNICODE_STRING */ namespace animia::internal::win32 { @@ -14,7 +14,6 @@ if (string.empty()) return std::string(); - long size = ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), nullptr, 0, nullptr, nullptr); std::string ret = std::string(size, '\0'); ::WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), &ret.front(), ret.length(), nullptr, nullptr); @@ -87,4 +86,4 @@ return path.find(windir) == 4; } -} +} // namespace animia::internal::win32
--- a/dep/animia/src/win.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/win.cc Wed Nov 15 18:04:04 2023 -0500 @@ -18,4 +18,4 @@ BaseWinTools& win = os_win; -} +} // namespace animia::internal
--- a/dep/animia/src/win/quartz.mm Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/win/quartz.mm Wed Nov 15 18:04:04 2023 -0500 @@ -11,36 +11,32 @@ static bool IntegerFromNSNumber(NSNumber* num, T& result) { if (!num) return false; + result = [num intValue]; return true; } +static bool StringFromNSString(NSString* string, std::string& result) { + if (!string) + return false; + + result = [string UTF8String]; + 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; + return StringFromNSString([window title], result); } bool QuartzWinTools::EnumerateWindows(window_proc_t window_proc) { if (!window_proc) return false; - NSMutableArray* windows = (NSMutableArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID); + NSMutableArray* windows = reinterpret_cast<NSMutableArray*>(CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID)); if (!windows) return false;
--- a/dep/animia/src/win/win32.cc Wed Nov 15 15:24:39 2023 -0500 +++ b/dep/animia/src/win/win32.cc Wed Nov 15 18:04:04 2023 -0500 @@ -1,7 +1,7 @@ #include "animia/win/win32.h" +#include "animia.h" #include "animia/util/win32.h" #include "animia/win.h" -#include "animia.h" #include <set> #include <string> @@ -48,8 +48,7 @@ // Note that if we requested PROCESS_QUERY_INFORMATION access right instead // of PROCESS_QUERY_LIMITED_INFORMATION, this function would fail when used // to open an elevated process. - Handle process_handle(::OpenProcess( - PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id)); + Handle process_handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id)); if (!process_handle) return std::wstring(); @@ -72,12 +71,8 @@ const auto window_style = ::GetWindowLong(hwnd, GWL_STYLE); const auto window_ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); - auto has_style = [&window_style](DWORD style) { - return (window_style & style) != 0; - }; - auto has_ex_style = [&window_ex_style](DWORD ex_style) { - return (window_ex_style & ex_style) != 0; - }; + auto has_style = [&window_style](DWORD style) { return (window_style & style) != 0; }; + auto has_ex_style = [&window_ex_style](DWORD ex_style) { return (window_ex_style & ex_style) != 0; }; // Toolbars, tooltips and similar topmost windows if (has_style(WS_POPUP) && has_ex_style(WS_EX_TOOLWINDOW)) @@ -90,18 +85,18 @@ static bool VerifyClassName(const std::wstring& name) { static const std::set<std::wstring> invalid_names = { - // System classes - L"#32770", // Dialog box - L"CabinetWClass", // Windows Explorer - L"ComboLBox", - L"DDEMLEvent", - L"DDEMLMom", - L"DirectUIHWND", - L"GDI+ Hook Window Class", - L"IME", - L"Internet Explorer_Hidden", - L"MSCTFIME UI", - L"tooltips_class32", + // System classes + L"#32770", // Dialog box + L"CabinetWClass", // Windows Explorer + L"ComboLBox", + L"DDEMLEvent", + L"DDEMLMom", + L"DirectUIHWND", + L"GDI+ Hook Window Class", + L"IME", + L"Internet Explorer_Hidden", + L"MSCTFIME UI", + L"tooltips_class32", }; return !name.empty() && !invalid_names.count(name); @@ -113,12 +108,12 @@ static bool VerifyProcessFileName(const std::wstring& name) { static const std::set<std::wstring> invalid_names = { - // System files - L"explorer", // Windows Explorer - L"taskeng", // Task Scheduler Engine - L"taskhost", // Host Process for Windows Tasks - L"taskhostex", // Host Process for Windows Tasks - L"Taskmgr", // Task Manager + // System files + L"explorer", // Windows Explorer + L"taskeng", // Task Scheduler Engine + L"taskhost", // Host Process for Windows Tasks + L"taskhostex", // Host Process for Windows Tasks + L"Taskmgr", // Task Manager }; return !name.empty() && !invalid_names.count(name); @@ -176,4 +171,4 @@ return ::EnumWindows(EnumWindowsProc, param) != FALSE; } -} // namespace animia::win::detail \ No newline at end of file +} // namespace animia::internal::win32 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/src/win/x11.cc Wed Nov 15 18:04:04 2023 -0500 @@ -0,0 +1,115 @@ +#include <X11/Xlib.h> + +/* 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 + between Animia's types and X11's types */ + +namespace animia::internal::x11 { + +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; + + if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype, + &type, &format, &num_of_items, &leftover_bytes, &data)) + return false; + + result = std::string(data, num_of_items); + + ::XFree(data); + + return true; +} + +static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) { + int format; + unsigned long leftover_bytes, num_of_items; + ::Atom type; + void* data; + + if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype, + &type, &format, &num_of_items, &leftover_bytes, &data)) + return false; + + result = static_cast<pid_t>(*(uint32_t*)data); + + ::XFree(data); + + return true; +} + +static bool FetchName(::Display* display, ::Window window, std::string& result) { + /* TODO: Check if XInternAtom created None or not... */ + if (GetWindowPropertyAsString(display, window, "_NET_WM_NAME", result, ::XInternAtom(display, "UTF8_STRING", false))) + return true; + + /* Fallback to XGetWMName() */ + XTextProperty text; + + { + int status = ::XGetWMName(display, window, &text); + if (!status || !text_prop.value || !text_prop.nitems) + return false; + } + + char** list; + + { + int num; + + int status = ::XmbTextPropertyToTextList(display, &text, &list, &num); + if (status < Success || !num || !*list) + return false; + } + + ::XFree(text.value); + + result = *list; + + ::XFreeStringList(list); + + return true; +} + +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 { + 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); + } + + ::Display* display = ::XOpenDisplay(nullptr); + ::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); + + if (status < Success) + return false; + + for (long k = 0; k < num_windows; k++) { + const ::Window window = windows[k]; + + 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]); + + Process proc; + GetWindowPID(display, window, proc.pid); + + if (!window_proc(proc, win)) + return false; + } + + return true; +} + +}