#include "core/application.hpp" #include "core/logger.hpp" #include #include #include #include #include #include #ifdef __linux__ #include // Keep a persistent X11 connection for emergency mouse release in signal handlers. // XOpenDisplay inside a signal handler is unreliable, so we open it once at startup. static Display* g_emergencyDisplay = nullptr; static void releaseMouseGrab() { if (g_emergencyDisplay) { XUngrabPointer(g_emergencyDisplay, CurrentTime); XUngrabKeyboard(g_emergencyDisplay, CurrentTime); XFlush(g_emergencyDisplay); } } #else static void releaseMouseGrab() {} #endif static void crashHandler(int sig) { releaseMouseGrab(); std::signal(sig, SIG_DFL); std::raise(sig); } static wowee::core::LogLevel readLogLevelFromEnv() { const char* raw = std::getenv("WOWEE_LOG_LEVEL"); if (!raw || !*raw) return wowee::core::LogLevel::WARNING; std::string level(raw); for (char& c : level) c = static_cast(std::tolower(static_cast(c))); if (level == "debug") return wowee::core::LogLevel::DEBUG; if (level == "info") return wowee::core::LogLevel::INFO; if (level == "warn" || level == "warning") return wowee::core::LogLevel::WARNING; if (level == "error") return wowee::core::kLogLevelError; if (level == "fatal") return wowee::core::LogLevel::FATAL; return wowee::core::LogLevel::WARNING; } int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { #ifdef __linux__ g_emergencyDisplay = XOpenDisplay(nullptr); #endif std::signal(SIGSEGV, crashHandler); std::signal(SIGABRT, crashHandler); std::signal(SIGFPE, crashHandler); std::signal(SIGTERM, crashHandler); std::signal(SIGINT, crashHandler); try { wowee::core::Logger::getInstance().setLogLevel(readLogLevelFromEnv()); LOG_INFO("=== Wowee Native Client ==="); LOG_INFO("Starting application..."); wowee::core::Application app; if (!app.initialize()) { LOG_FATAL("Failed to initialize application"); return 1; } app.run(); app.shutdown(); LOG_INFO("Application exited successfully"); #ifdef __linux__ if (g_emergencyDisplay) { XCloseDisplay(g_emergencyDisplay); g_emergencyDisplay = nullptr; } #endif return 0; } catch (const std::exception& e) { releaseMouseGrab(); LOG_FATAL("Unhandled exception: ", e.what()); return 1; } catch (...) { releaseMouseGrab(); LOG_FATAL("Unknown exception occurred"); return 1; } }