diff --git a/Code/Editor/Core/QtEditorApplication_linux.cpp b/Code/Editor/Core/QtEditorApplication_linux.cpp index 175bef0238..2fd4ef629e 100644 --- a/Code/Editor/Core/QtEditorApplication_linux.cpp +++ b/Code/Editor/Core/QtEditorApplication_linux.cpp @@ -9,7 +9,7 @@ #include "QtEditorApplication.h" #ifdef PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB -#include +#include #endif namespace Editor @@ -19,7 +19,7 @@ namespace Editor if (GetIEditor()->IsInGameMode()) { #ifdef PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - AzFramework::LinuxXcbEventHandlerBus::Broadcast(&AzFramework::LinuxXcbEventHandler::HandleXcbEvent, static_cast(message)); + AzFramework::XcbEventHandlerBus::Broadcast(&AzFramework::XcbEventHandler::HandleXcbEvent, static_cast(message)); #endif return true; } diff --git a/Code/Framework/AzFramework/CMakeLists.txt b/Code/Framework/AzFramework/CMakeLists.txt index 6f6e47855e..f6851f0ab8 100644 --- a/Code/Framework/AzFramework/CMakeLists.txt +++ b/Code/Framework/AzFramework/CMakeLists.txt @@ -95,4 +95,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) endif() -endif() \ No newline at end of file +endif() diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.cpp b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.cpp index aaab67b2a1..7cbd9ae0e2 100644 --- a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.cpp +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.cpp @@ -6,29 +6,26 @@ * */ -#include -#include -#include "Application_Linux_xcb.h" +#include +#include -//////////////////////////////////////////////////////////////////////////////////////////////////// namespace AzFramework { -#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB //////////////////////////////////////////////////////////////////////////////////////////////// - class LinuxXcbConnectionManagerImpl - : public LinuxXcbConnectionManagerBus::Handler + class XcbConnectionManagerImpl + : public XcbConnectionManagerBus::Handler { public: - LinuxXcbConnectionManagerImpl() + XcbConnectionManagerImpl() { m_xcbConnection = xcb_connect(nullptr, nullptr); - AZ_Error("ApplicationLinux", m_xcbConnection != nullptr, "Unable to connect to X11 Server."); - LinuxXcbConnectionManagerBus::Handler::BusConnect(); + AZ_Error("Application", m_xcbConnection != nullptr, "Unable to connect to X11 Server."); + XcbConnectionManagerBus::Handler::BusConnect(); } - ~LinuxXcbConnectionManagerImpl() + ~XcbConnectionManagerImpl() override { - LinuxXcbConnectionManagerBus::Handler::BusDisconnect(); + XcbConnectionManagerBus::Handler::BusDisconnect(); xcb_disconnect(m_xcbConnection); } @@ -42,53 +39,51 @@ namespace AzFramework }; //////////////////////////////////////////////////////////////////////////////////////////////// - ApplicationLinux_xcb::ApplicationLinux_xcb() + XcbApplication::XcbApplication() { LinuxLifecycleEvents::Bus::Handler::BusConnect(); - m_xcbConnectionManager = AZStd::make_unique(); - if (LinuxXcbConnectionManagerInterface::Get() == nullptr) + m_xcbConnectionManager = AZStd::make_unique(); + if (XcbConnectionManagerInterface::Get() == nullptr) { - LinuxXcbConnectionManagerInterface::Register(m_xcbConnectionManager.get()); + XcbConnectionManagerInterface::Register(m_xcbConnectionManager.get()); } } //////////////////////////////////////////////////////////////////////////////////////////////// - ApplicationLinux_xcb::~ApplicationLinux_xcb() + XcbApplication::~XcbApplication() { - if (LinuxXcbConnectionManagerInterface::Get() == m_xcbConnectionManager.get()) + if (XcbConnectionManagerInterface::Get() == m_xcbConnectionManager.get()) { - LinuxXcbConnectionManagerInterface::Unregister(m_xcbConnectionManager.get()); + XcbConnectionManagerInterface::Unregister(m_xcbConnectionManager.get()); } m_xcbConnectionManager.reset(); LinuxLifecycleEvents::Bus::Handler::BusDisconnect(); } //////////////////////////////////////////////////////////////////////////////////////////////// - void ApplicationLinux_xcb::PumpSystemEventLoopOnce() + void XcbApplication::PumpSystemEventLoopOnce() { if (xcb_connection_t* xcbConnection = m_xcbConnectionManager->GetXcbConnection()) { if (xcb_generic_event_t* event = xcb_poll_for_event(xcbConnection)) { - LinuxXcbEventHandlerBus::Broadcast(&LinuxXcbEventHandlerBus::Events::HandleXcbEvent, event); + XcbEventHandlerBus::Broadcast(&XcbEventHandlerBus::Events::HandleXcbEvent, event); free(event); } } } //////////////////////////////////////////////////////////////////////////////////////////////// - void ApplicationLinux_xcb::PumpSystemEventLoopUntilEmpty() + void XcbApplication::PumpSystemEventLoopUntilEmpty() { if (xcb_connection_t* xcbConnection = m_xcbConnectionManager->GetXcbConnection()) { while (xcb_generic_event_t* event = xcb_poll_for_event(xcbConnection)) { - LinuxXcbEventHandlerBus::Broadcast(&LinuxXcbEventHandlerBus::Events::HandleXcbEvent, event); + XcbEventHandlerBus::Broadcast(&XcbEventHandlerBus::Events::HandleXcbEvent, event); free(event); } } } -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - } // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.h b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.h index fbd7f165d3..f27b5dd680 100644 --- a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.h +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbApplication.h @@ -5,27 +5,24 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ + #pragma once #include #include +#include -//////////////////////////////////////////////////////////////////////////////////////////////////// namespace AzFramework { - -#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - - //////////////////////////////////////////////////////////////////////////////////////////////// - class ApplicationLinux_xcb + class XcbApplication : public Application::Implementation , public LinuxLifecycleEvents::Bus::Handler { public: //////////////////////////////////////////////////////////////////////////////////////////// - AZ_CLASS_ALLOCATOR(ApplicationLinux_xcb, AZ::SystemAllocator, 0); - ApplicationLinux_xcb(); - ~ApplicationLinux_xcb() override; + AZ_CLASS_ALLOCATOR(XcbApplication, AZ::SystemAllocator, 0); + XcbApplication(); + ~XcbApplication() override; //////////////////////////////////////////////////////////////////////////////////////////// // Application::Implementation @@ -33,9 +30,6 @@ namespace AzFramework void PumpSystemEventLoopUntilEmpty() override; private: - AZStd::unique_ptr m_xcbConnectionManager; + AZStd::unique_ptr m_xcbConnectionManager; }; - -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - } // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbConnectionManager.h b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbConnectionManager.h new file mode 100644 index 0000000000..daa5bf35af --- /dev/null +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbConnectionManager.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +#include + +namespace AzFramework +{ + class XcbConnectionManager + { + public: + AZ_RTTI(XcbConnectionManager, "{1F756E14-8D74-42FD-843C-4863307710DB}"); + + virtual ~XcbConnectionManager() = default; + + virtual xcb_connection_t* GetXcbConnection() const = 0; + }; + + class XcbConnectionManagerBusTraits + : public AZ::EBusTraits + { + public: + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + ////////////////////////////////////////////////////////////////////////// + }; + + using XcbConnectionManagerBus = AZ::EBus; + using XcbConnectionManagerInterface = AZ::Interface; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbEventHandler.h b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbEventHandler.h new file mode 100644 index 0000000000..c6307755a7 --- /dev/null +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbEventHandler.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include + +#include + +namespace AzFramework +{ + class XcbEventHandler + { + public: + AZ_RTTI(XcbEventHandler, "{3F756E14-8D74-42FD-843C-4863307710DB}"); + + virtual ~XcbEventHandler() = default; + + virtual void HandleXcbEvent(xcb_generic_event_t* event) = 0; + }; + + class XcbEventHandlerBusTraits + : public AZ::EBusTraits + { + public: + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + ////////////////////////////////////////////////////////////////////////// + }; + + using XcbEventHandlerBus = AZ::EBus; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInputDeviceKeyboard.cpp b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInputDeviceKeyboard.cpp index 8ff4c72d42..c971c3b793 100644 --- a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInputDeviceKeyboard.cpp +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInputDeviceKeyboard.cpp @@ -6,9 +6,10 @@ * */ -#include -#include #include +#include +#include +#include #define explicit ExplicitIsACXXKeyword #include @@ -19,275 +20,252 @@ namespace AzFramework { - class InputDeviceKeyboardXcb - : public InputDeviceKeyboard::Implementation - , public LinuxXcbEventHandlerBus::Handler + XcbInputDeviceKeyboard::XcbInputDeviceKeyboard(InputDeviceKeyboard& inputDevice) + : InputDeviceKeyboard::Implementation(inputDevice) { - public: - AZ_CLASS_ALLOCATOR(InputDeviceKeyboardXcb, AZ::SystemAllocator, 0); + XcbEventHandlerBus::Handler::BusConnect(); - using InputDeviceKeyboard::Implementation::Implementation; - InputDeviceKeyboardXcb(InputDeviceKeyboard& inputDevice) - : InputDeviceKeyboard::Implementation(inputDevice) + auto* interface = AzFramework::XcbConnectionManagerInterface::Get(); + if (!interface) { - LinuxXcbEventHandlerBus::Handler::BusConnect(); - - auto* interface = AzFramework::LinuxXcbConnectionManagerInterface::Get(); - if (!interface) - { - AZ_Warning("ApplicationLinux", false, "XCB interface not available"); - return; - } - - auto* connection = AzFramework::LinuxXcbConnectionManagerInterface::Get()->GetXcbConnection(); - if (!connection) - { - AZ_Warning("ApplicationLinux", false, "XCB connection not available"); - return; - } - - AZStd::unique_ptr> xkbUseExtensionReply{ - xcb_xkb_use_extension_reply(connection, xcb_xkb_use_extension(connection, 1, 0), nullptr) - }; - if (!xkbUseExtensionReply) - { - AZ_Warning("ApplicationLinux", false, "Failed to initialize the xkb extension"); - return; - } - if (!xkbUseExtensionReply->supported) - { - AZ_Warning("ApplicationLinux", false, "The X server does not support the xkb extension"); - return; - } - - m_coreDeviceId = xkb_x11_get_core_keyboard_device_id(connection); - - m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS)); - m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), connection, m_coreDeviceId, XKB_KEYMAP_COMPILE_NO_FLAGS)); - m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), connection, m_coreDeviceId)); - - m_initialized = true; + AZ_Warning("ApplicationLinux", false, "XCB interface not available"); + return; } - bool IsConnected() const override + auto* connection = interface->GetXcbConnection(); + if (!connection) { - return m_initialized; + AZ_Warning("ApplicationLinux", false, "XCB connection not available"); + return; } - bool HasTextEntryStarted() const override + XcbStdFreePtr xkbUseExtensionReply{ + xcb_xkb_use_extension_reply(connection, xcb_xkb_use_extension(connection, 1, 0), nullptr) + }; + if (!xkbUseExtensionReply) { - return false; + AZ_Warning("ApplicationLinux", false, "Failed to initialize the xkb extension"); + return; } - - void TextEntryStart(const InputDeviceKeyboard::VirtualKeyboardOptions& options) override + if (!xkbUseExtensionReply->supported) { + AZ_Warning("ApplicationLinux", false, "The X server does not support the xkb extension"); + return; } - void TextEntryStop() override - { - } + m_coreDeviceId = xkb_x11_get_core_keyboard_device_id(connection); + + m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS)); + m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), connection, m_coreDeviceId, XKB_KEYMAP_COMPILE_NO_FLAGS)); + m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), connection, m_coreDeviceId)); - void TickInputDevice() override + m_initialized = true; + } + + bool XcbInputDeviceKeyboard::IsConnected() const + { + auto* connection = AzFramework::XcbConnectionManagerInterface::Get()->GetXcbConnection(); + return connection && !xcb_connection_has_error(connection); + } + + bool XcbInputDeviceKeyboard::HasTextEntryStarted() const + { + return false; + } + + void XcbInputDeviceKeyboard::TextEntryStart(const InputDeviceKeyboard::VirtualKeyboardOptions& options) + { + } + + void XcbInputDeviceKeyboard::TextEntryStop() + { + } + + void XcbInputDeviceKeyboard::TickInputDevice() + { + ProcessRawEventQueues(); + } + + void XcbInputDeviceKeyboard::HandleXcbEvent(xcb_generic_event_t* event) + { + if (!m_initialized) { - ProcessRawEventQueues(); + return; } - void HandleXcbEvent(xcb_generic_event_t* event) override + switch (event->response_type & ~0x80) { - if (!IsConnected()) - { - return; - } - - switch (event->response_type & ~0x80) - { - case XCB_KEY_PRESS: - { - auto* keyPress = reinterpret_cast(event); + case XCB_KEY_PRESS: + { + auto* keyPress = reinterpret_cast(event); - const InputChannelId* key = InputChannelFromKeyEvent(keyPress->detail); - if (key) - { - QueueRawKeyEvent(*key, true); - } - break; - } - case XCB_KEY_RELEASE: + const InputChannelId* key = InputChannelFromKeyEvent(keyPress->detail); + if (key) { - auto* keyRelease = reinterpret_cast(event); - - const InputChannelId* key = InputChannelFromKeyEvent(keyRelease->detail); - if (key) - { - QueueRawKeyEvent(*key, false); - } - break; - } + QueueRawKeyEvent(*key, true); } + break; } - - private: - [[nodiscard]] const InputChannelId* InputChannelFromKeyEvent(xcb_keycode_t code) const + case XCB_KEY_RELEASE: { - const xcb_keysym_t keysym = xkb_state_key_get_one_sym(m_xkbState.get(), code); + auto* keyRelease = reinterpret_cast(event); - switch(keysym) + const InputChannelId* key = InputChannelFromKeyEvent(keyRelease->detail); + if (key) { - case XKB_KEY_0: return &InputDeviceKeyboard::Key::Alphanumeric0; - case XKB_KEY_1: return &InputDeviceKeyboard::Key::Alphanumeric1; - case XKB_KEY_2: return &InputDeviceKeyboard::Key::Alphanumeric2; - case XKB_KEY_3: return &InputDeviceKeyboard::Key::Alphanumeric3; - case XKB_KEY_4: return &InputDeviceKeyboard::Key::Alphanumeric4; - case XKB_KEY_5: return &InputDeviceKeyboard::Key::Alphanumeric5; - case XKB_KEY_6: return &InputDeviceKeyboard::Key::Alphanumeric6; - case XKB_KEY_7: return &InputDeviceKeyboard::Key::Alphanumeric7; - case XKB_KEY_8: return &InputDeviceKeyboard::Key::Alphanumeric8; - case XKB_KEY_9: return &InputDeviceKeyboard::Key::Alphanumeric9; - case XKB_KEY_A: - case XKB_KEY_a: return &InputDeviceKeyboard::Key::AlphanumericA; - case XKB_KEY_B: - case XKB_KEY_b: return &InputDeviceKeyboard::Key::AlphanumericB; - case XKB_KEY_C: - case XKB_KEY_c: return &InputDeviceKeyboard::Key::AlphanumericC; - case XKB_KEY_D: - case XKB_KEY_d: return &InputDeviceKeyboard::Key::AlphanumericD; - case XKB_KEY_E: - case XKB_KEY_e: return &InputDeviceKeyboard::Key::AlphanumericE; - case XKB_KEY_F: - case XKB_KEY_f: return &InputDeviceKeyboard::Key::AlphanumericF; - case XKB_KEY_G: - case XKB_KEY_g: return &InputDeviceKeyboard::Key::AlphanumericG; - case XKB_KEY_H: - case XKB_KEY_h: return &InputDeviceKeyboard::Key::AlphanumericH; - case XKB_KEY_I: - case XKB_KEY_i: return &InputDeviceKeyboard::Key::AlphanumericI; - case XKB_KEY_J: - case XKB_KEY_j: return &InputDeviceKeyboard::Key::AlphanumericJ; - case XKB_KEY_K: - case XKB_KEY_k: return &InputDeviceKeyboard::Key::AlphanumericK; - case XKB_KEY_L: - case XKB_KEY_l: return &InputDeviceKeyboard::Key::AlphanumericL; - case XKB_KEY_M: - case XKB_KEY_m: return &InputDeviceKeyboard::Key::AlphanumericM; - case XKB_KEY_N: - case XKB_KEY_n: return &InputDeviceKeyboard::Key::AlphanumericN; - case XKB_KEY_O: - case XKB_KEY_o: return &InputDeviceKeyboard::Key::AlphanumericO; - case XKB_KEY_P: - case XKB_KEY_p: return &InputDeviceKeyboard::Key::AlphanumericP; - case XKB_KEY_Q: - case XKB_KEY_q: return &InputDeviceKeyboard::Key::AlphanumericQ; - case XKB_KEY_R: - case XKB_KEY_r: return &InputDeviceKeyboard::Key::AlphanumericR; - case XKB_KEY_S: - case XKB_KEY_s: return &InputDeviceKeyboard::Key::AlphanumericS; - case XKB_KEY_T: - case XKB_KEY_t: return &InputDeviceKeyboard::Key::AlphanumericT; - case XKB_KEY_U: - case XKB_KEY_u: return &InputDeviceKeyboard::Key::AlphanumericU; - case XKB_KEY_V: - case XKB_KEY_v: return &InputDeviceKeyboard::Key::AlphanumericV; - case XKB_KEY_W: - case XKB_KEY_w: return &InputDeviceKeyboard::Key::AlphanumericW; - case XKB_KEY_X: - case XKB_KEY_x: return &InputDeviceKeyboard::Key::AlphanumericX; - case XKB_KEY_Y: - case XKB_KEY_y: return &InputDeviceKeyboard::Key::AlphanumericY; - case XKB_KEY_Z: - case XKB_KEY_z: return &InputDeviceKeyboard::Key::AlphanumericZ; - case XKB_KEY_BackSpace: return &InputDeviceKeyboard::Key::EditBackspace; - case XKB_KEY_Caps_Lock: return &InputDeviceKeyboard::Key::EditCapsLock; - case XKB_KEY_Return: return &InputDeviceKeyboard::Key::EditEnter; - case XKB_KEY_space: return &InputDeviceKeyboard::Key::EditSpace; - case XKB_KEY_Tab: return &InputDeviceKeyboard::Key::EditTab; - case XKB_KEY_Escape: return &InputDeviceKeyboard::Key::Escape; - case XKB_KEY_F1: return &InputDeviceKeyboard::Key::Function01; - case XKB_KEY_F2: return &InputDeviceKeyboard::Key::Function02; - case XKB_KEY_F3: return &InputDeviceKeyboard::Key::Function03; - case XKB_KEY_F4: return &InputDeviceKeyboard::Key::Function04; - case XKB_KEY_F5: return &InputDeviceKeyboard::Key::Function05; - case XKB_KEY_F6: return &InputDeviceKeyboard::Key::Function06; - case XKB_KEY_F7: return &InputDeviceKeyboard::Key::Function07; - case XKB_KEY_F8: return &InputDeviceKeyboard::Key::Function08; - case XKB_KEY_F9: return &InputDeviceKeyboard::Key::Function09; - case XKB_KEY_F10: return &InputDeviceKeyboard::Key::Function10; - case XKB_KEY_F11: return &InputDeviceKeyboard::Key::Function11; - case XKB_KEY_F12: return &InputDeviceKeyboard::Key::Function12; - case XKB_KEY_F13: return &InputDeviceKeyboard::Key::Function13; - case XKB_KEY_F14: return &InputDeviceKeyboard::Key::Function14; - case XKB_KEY_F15: return &InputDeviceKeyboard::Key::Function15; - case XKB_KEY_F16: return &InputDeviceKeyboard::Key::Function16; - case XKB_KEY_F17: return &InputDeviceKeyboard::Key::Function17; - case XKB_KEY_F18: return &InputDeviceKeyboard::Key::Function18; - case XKB_KEY_F19: return &InputDeviceKeyboard::Key::Function19; - case XKB_KEY_F20: return &InputDeviceKeyboard::Key::Function20; - case XKB_KEY_Alt_L: return &InputDeviceKeyboard::Key::ModifierAltL; - case XKB_KEY_Alt_R: return &InputDeviceKeyboard::Key::ModifierAltR; - case XKB_KEY_Control_L: return &InputDeviceKeyboard::Key::ModifierCtrlL; - case XKB_KEY_Control_R: return &InputDeviceKeyboard::Key::ModifierCtrlR; - case XKB_KEY_Shift_L: return &InputDeviceKeyboard::Key::ModifierShiftL; - case XKB_KEY_Shift_R: return &InputDeviceKeyboard::Key::ModifierShiftR; - case XKB_KEY_Super_L: return &InputDeviceKeyboard::Key::ModifierSuperL; - case XKB_KEY_Super_R: return &InputDeviceKeyboard::Key::ModifierSuperR; - case XKB_KEY_Down: return &InputDeviceKeyboard::Key::NavigationArrowDown; - case XKB_KEY_Left: return &InputDeviceKeyboard::Key::NavigationArrowLeft; - case XKB_KEY_Right: return &InputDeviceKeyboard::Key::NavigationArrowRight; - case XKB_KEY_Up: return &InputDeviceKeyboard::Key::NavigationArrowUp; - case XKB_KEY_Delete: return &InputDeviceKeyboard::Key::NavigationDelete; - case XKB_KEY_End: return &InputDeviceKeyboard::Key::NavigationEnd; - case XKB_KEY_Home: return &InputDeviceKeyboard::Key::NavigationHome; - case XKB_KEY_Insert: return &InputDeviceKeyboard::Key::NavigationInsert; - case XKB_KEY_Page_Down: return &InputDeviceKeyboard::Key::NavigationPageDown; - case XKB_KEY_Page_Up: return &InputDeviceKeyboard::Key::NavigationPageUp; - case XKB_KEY_Num_Lock: return &InputDeviceKeyboard::Key::NumLock; - case XKB_KEY_KP_0: return &InputDeviceKeyboard::Key::NumPad0; - case XKB_KEY_KP_1: return &InputDeviceKeyboard::Key::NumPad1; - case XKB_KEY_KP_2: return &InputDeviceKeyboard::Key::NumPad2; - case XKB_KEY_KP_3: return &InputDeviceKeyboard::Key::NumPad3; - case XKB_KEY_KP_4: return &InputDeviceKeyboard::Key::NumPad4; - case XKB_KEY_KP_5: return &InputDeviceKeyboard::Key::NumPad5; - case XKB_KEY_KP_6: return &InputDeviceKeyboard::Key::NumPad6; - case XKB_KEY_KP_7: return &InputDeviceKeyboard::Key::NumPad7; - case XKB_KEY_KP_8: return &InputDeviceKeyboard::Key::NumPad8; - case XKB_KEY_KP_9: return &InputDeviceKeyboard::Key::NumPad9; - case XKB_KEY_KP_Add: return &InputDeviceKeyboard::Key::NumPadAdd; - case XKB_KEY_KP_Decimal: return &InputDeviceKeyboard::Key::NumPadDecimal; - case XKB_KEY_KP_Divide: return &InputDeviceKeyboard::Key::NumPadDivide; - case XKB_KEY_KP_Enter: return &InputDeviceKeyboard::Key::NumPadEnter; - case XKB_KEY_KP_Multiply: return &InputDeviceKeyboard::Key::NumPadMultiply; - case XKB_KEY_KP_Subtract: return &InputDeviceKeyboard::Key::NumPadSubtract; - case XKB_KEY_apostrophe: return &InputDeviceKeyboard::Key::PunctuationApostrophe; - case XKB_KEY_backslash: return &InputDeviceKeyboard::Key::PunctuationBackslash; - case XKB_KEY_bracketleft: return &InputDeviceKeyboard::Key::PunctuationBracketL; - case XKB_KEY_bracketright: return &InputDeviceKeyboard::Key::PunctuationBracketR; - case XKB_KEY_comma: return &InputDeviceKeyboard::Key::PunctuationComma; - case XKB_KEY_equal: return &InputDeviceKeyboard::Key::PunctuationEquals; - case XKB_KEY_hyphen: return &InputDeviceKeyboard::Key::PunctuationHyphen; - case XKB_KEY_period: return &InputDeviceKeyboard::Key::PunctuationPeriod; - case XKB_KEY_semicolon: return &InputDeviceKeyboard::Key::PunctuationSemicolon; - case XKB_KEY_slash: return &InputDeviceKeyboard::Key::PunctuationSlash; - case XKB_KEY_grave: - case XKB_KEY_asciitilde: return &InputDeviceKeyboard::Key::PunctuationTilde; - case XKB_KEY_ISO_Group_Shift: return &InputDeviceKeyboard::Key::SupplementaryISO; - case XKB_KEY_Pause: return &InputDeviceKeyboard::Key::WindowsSystemPause; - case XKB_KEY_Print: return &InputDeviceKeyboard::Key::WindowsSystemPrint; - case XKB_KEY_Scroll_Lock: return &InputDeviceKeyboard::Key::WindowsSystemScrollLock; - default: return nullptr; + QueueRawKeyEvent(*key, false); } + break; } + } + } - template - using DeleterForFreeFn = AZStd::integral_constant; - - AZStd::unique_ptr> m_xkbContext; - AZStd::unique_ptr> m_xkbKeymap; - AZStd::unique_ptr> m_xkbState; - int m_coreDeviceId{-1}; - bool m_initialized{false}; - }; - - InputDeviceKeyboard::Implementation* InputDeviceKeyboard::Implementation::Create(InputDeviceKeyboard& inputDevice) + [[nodiscard]] const InputChannelId* XcbInputDeviceKeyboard::InputChannelFromKeyEvent(xcb_keycode_t code) const { - return aznew InputDeviceKeyboardXcb(inputDevice); + const xcb_keysym_t keysym = xkb_state_key_get_one_sym(m_xkbState.get(), code); + + switch(keysym) + { + case XKB_KEY_0: return &InputDeviceKeyboard::Key::Alphanumeric0; + case XKB_KEY_1: return &InputDeviceKeyboard::Key::Alphanumeric1; + case XKB_KEY_2: return &InputDeviceKeyboard::Key::Alphanumeric2; + case XKB_KEY_3: return &InputDeviceKeyboard::Key::Alphanumeric3; + case XKB_KEY_4: return &InputDeviceKeyboard::Key::Alphanumeric4; + case XKB_KEY_5: return &InputDeviceKeyboard::Key::Alphanumeric5; + case XKB_KEY_6: return &InputDeviceKeyboard::Key::Alphanumeric6; + case XKB_KEY_7: return &InputDeviceKeyboard::Key::Alphanumeric7; + case XKB_KEY_8: return &InputDeviceKeyboard::Key::Alphanumeric8; + case XKB_KEY_9: return &InputDeviceKeyboard::Key::Alphanumeric9; + case XKB_KEY_A: + case XKB_KEY_a: return &InputDeviceKeyboard::Key::AlphanumericA; + case XKB_KEY_B: + case XKB_KEY_b: return &InputDeviceKeyboard::Key::AlphanumericB; + case XKB_KEY_C: + case XKB_KEY_c: return &InputDeviceKeyboard::Key::AlphanumericC; + case XKB_KEY_D: + case XKB_KEY_d: return &InputDeviceKeyboard::Key::AlphanumericD; + case XKB_KEY_E: + case XKB_KEY_e: return &InputDeviceKeyboard::Key::AlphanumericE; + case XKB_KEY_F: + case XKB_KEY_f: return &InputDeviceKeyboard::Key::AlphanumericF; + case XKB_KEY_G: + case XKB_KEY_g: return &InputDeviceKeyboard::Key::AlphanumericG; + case XKB_KEY_H: + case XKB_KEY_h: return &InputDeviceKeyboard::Key::AlphanumericH; + case XKB_KEY_I: + case XKB_KEY_i: return &InputDeviceKeyboard::Key::AlphanumericI; + case XKB_KEY_J: + case XKB_KEY_j: return &InputDeviceKeyboard::Key::AlphanumericJ; + case XKB_KEY_K: + case XKB_KEY_k: return &InputDeviceKeyboard::Key::AlphanumericK; + case XKB_KEY_L: + case XKB_KEY_l: return &InputDeviceKeyboard::Key::AlphanumericL; + case XKB_KEY_M: + case XKB_KEY_m: return &InputDeviceKeyboard::Key::AlphanumericM; + case XKB_KEY_N: + case XKB_KEY_n: return &InputDeviceKeyboard::Key::AlphanumericN; + case XKB_KEY_O: + case XKB_KEY_o: return &InputDeviceKeyboard::Key::AlphanumericO; + case XKB_KEY_P: + case XKB_KEY_p: return &InputDeviceKeyboard::Key::AlphanumericP; + case XKB_KEY_Q: + case XKB_KEY_q: return &InputDeviceKeyboard::Key::AlphanumericQ; + case XKB_KEY_R: + case XKB_KEY_r: return &InputDeviceKeyboard::Key::AlphanumericR; + case XKB_KEY_S: + case XKB_KEY_s: return &InputDeviceKeyboard::Key::AlphanumericS; + case XKB_KEY_T: + case XKB_KEY_t: return &InputDeviceKeyboard::Key::AlphanumericT; + case XKB_KEY_U: + case XKB_KEY_u: return &InputDeviceKeyboard::Key::AlphanumericU; + case XKB_KEY_V: + case XKB_KEY_v: return &InputDeviceKeyboard::Key::AlphanumericV; + case XKB_KEY_W: + case XKB_KEY_w: return &InputDeviceKeyboard::Key::AlphanumericW; + case XKB_KEY_X: + case XKB_KEY_x: return &InputDeviceKeyboard::Key::AlphanumericX; + case XKB_KEY_Y: + case XKB_KEY_y: return &InputDeviceKeyboard::Key::AlphanumericY; + case XKB_KEY_Z: + case XKB_KEY_z: return &InputDeviceKeyboard::Key::AlphanumericZ; + case XKB_KEY_BackSpace: return &InputDeviceKeyboard::Key::EditBackspace; + case XKB_KEY_Caps_Lock: return &InputDeviceKeyboard::Key::EditCapsLock; + case XKB_KEY_Return: return &InputDeviceKeyboard::Key::EditEnter; + case XKB_KEY_space: return &InputDeviceKeyboard::Key::EditSpace; + case XKB_KEY_Tab: return &InputDeviceKeyboard::Key::EditTab; + case XKB_KEY_Escape: return &InputDeviceKeyboard::Key::Escape; + case XKB_KEY_F1: return &InputDeviceKeyboard::Key::Function01; + case XKB_KEY_F2: return &InputDeviceKeyboard::Key::Function02; + case XKB_KEY_F3: return &InputDeviceKeyboard::Key::Function03; + case XKB_KEY_F4: return &InputDeviceKeyboard::Key::Function04; + case XKB_KEY_F5: return &InputDeviceKeyboard::Key::Function05; + case XKB_KEY_F6: return &InputDeviceKeyboard::Key::Function06; + case XKB_KEY_F7: return &InputDeviceKeyboard::Key::Function07; + case XKB_KEY_F8: return &InputDeviceKeyboard::Key::Function08; + case XKB_KEY_F9: return &InputDeviceKeyboard::Key::Function09; + case XKB_KEY_F10: return &InputDeviceKeyboard::Key::Function10; + case XKB_KEY_F11: return &InputDeviceKeyboard::Key::Function11; + case XKB_KEY_F12: return &InputDeviceKeyboard::Key::Function12; + case XKB_KEY_F13: return &InputDeviceKeyboard::Key::Function13; + case XKB_KEY_F14: return &InputDeviceKeyboard::Key::Function14; + case XKB_KEY_F15: return &InputDeviceKeyboard::Key::Function15; + case XKB_KEY_F16: return &InputDeviceKeyboard::Key::Function16; + case XKB_KEY_F17: return &InputDeviceKeyboard::Key::Function17; + case XKB_KEY_F18: return &InputDeviceKeyboard::Key::Function18; + case XKB_KEY_F19: return &InputDeviceKeyboard::Key::Function19; + case XKB_KEY_F20: return &InputDeviceKeyboard::Key::Function20; + case XKB_KEY_Alt_L: return &InputDeviceKeyboard::Key::ModifierAltL; + case XKB_KEY_Alt_R: return &InputDeviceKeyboard::Key::ModifierAltR; + case XKB_KEY_Control_L: return &InputDeviceKeyboard::Key::ModifierCtrlL; + case XKB_KEY_Control_R: return &InputDeviceKeyboard::Key::ModifierCtrlR; + case XKB_KEY_Shift_L: return &InputDeviceKeyboard::Key::ModifierShiftL; + case XKB_KEY_Shift_R: return &InputDeviceKeyboard::Key::ModifierShiftR; + case XKB_KEY_Super_L: return &InputDeviceKeyboard::Key::ModifierSuperL; + case XKB_KEY_Super_R: return &InputDeviceKeyboard::Key::ModifierSuperR; + case XKB_KEY_Down: return &InputDeviceKeyboard::Key::NavigationArrowDown; + case XKB_KEY_Left: return &InputDeviceKeyboard::Key::NavigationArrowLeft; + case XKB_KEY_Right: return &InputDeviceKeyboard::Key::NavigationArrowRight; + case XKB_KEY_Up: return &InputDeviceKeyboard::Key::NavigationArrowUp; + case XKB_KEY_Delete: return &InputDeviceKeyboard::Key::NavigationDelete; + case XKB_KEY_End: return &InputDeviceKeyboard::Key::NavigationEnd; + case XKB_KEY_Home: return &InputDeviceKeyboard::Key::NavigationHome; + case XKB_KEY_Insert: return &InputDeviceKeyboard::Key::NavigationInsert; + case XKB_KEY_Page_Down: return &InputDeviceKeyboard::Key::NavigationPageDown; + case XKB_KEY_Page_Up: return &InputDeviceKeyboard::Key::NavigationPageUp; + case XKB_KEY_Num_Lock: return &InputDeviceKeyboard::Key::NumLock; + case XKB_KEY_KP_0: return &InputDeviceKeyboard::Key::NumPad0; + case XKB_KEY_KP_1: return &InputDeviceKeyboard::Key::NumPad1; + case XKB_KEY_KP_2: return &InputDeviceKeyboard::Key::NumPad2; + case XKB_KEY_KP_3: return &InputDeviceKeyboard::Key::NumPad3; + case XKB_KEY_KP_4: return &InputDeviceKeyboard::Key::NumPad4; + case XKB_KEY_KP_5: return &InputDeviceKeyboard::Key::NumPad5; + case XKB_KEY_KP_6: return &InputDeviceKeyboard::Key::NumPad6; + case XKB_KEY_KP_7: return &InputDeviceKeyboard::Key::NumPad7; + case XKB_KEY_KP_8: return &InputDeviceKeyboard::Key::NumPad8; + case XKB_KEY_KP_9: return &InputDeviceKeyboard::Key::NumPad9; + case XKB_KEY_KP_Add: return &InputDeviceKeyboard::Key::NumPadAdd; + case XKB_KEY_KP_Decimal: return &InputDeviceKeyboard::Key::NumPadDecimal; + case XKB_KEY_KP_Divide: return &InputDeviceKeyboard::Key::NumPadDivide; + case XKB_KEY_KP_Enter: return &InputDeviceKeyboard::Key::NumPadEnter; + case XKB_KEY_KP_Multiply: return &InputDeviceKeyboard::Key::NumPadMultiply; + case XKB_KEY_KP_Subtract: return &InputDeviceKeyboard::Key::NumPadSubtract; + case XKB_KEY_apostrophe: return &InputDeviceKeyboard::Key::PunctuationApostrophe; + case XKB_KEY_backslash: return &InputDeviceKeyboard::Key::PunctuationBackslash; + case XKB_KEY_bracketleft: return &InputDeviceKeyboard::Key::PunctuationBracketL; + case XKB_KEY_bracketright: return &InputDeviceKeyboard::Key::PunctuationBracketR; + case XKB_KEY_comma: return &InputDeviceKeyboard::Key::PunctuationComma; + case XKB_KEY_equal: return &InputDeviceKeyboard::Key::PunctuationEquals; + case XKB_KEY_hyphen: return &InputDeviceKeyboard::Key::PunctuationHyphen; + case XKB_KEY_period: return &InputDeviceKeyboard::Key::PunctuationPeriod; + case XKB_KEY_semicolon: return &InputDeviceKeyboard::Key::PunctuationSemicolon; + case XKB_KEY_slash: return &InputDeviceKeyboard::Key::PunctuationSlash; + case XKB_KEY_grave: + case XKB_KEY_asciitilde: return &InputDeviceKeyboard::Key::PunctuationTilde; + case XKB_KEY_ISO_Group_Shift: return &InputDeviceKeyboard::Key::SupplementaryISO; + case XKB_KEY_Pause: return &InputDeviceKeyboard::Key::WindowsSystemPause; + case XKB_KEY_Print: return &InputDeviceKeyboard::Key::WindowsSystemPrint; + case XKB_KEY_Scroll_Lock: return &InputDeviceKeyboard::Key::WindowsSystemScrollLock; + default: return nullptr; + } } } // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInputDeviceKeyboard.h b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInputDeviceKeyboard.h new file mode 100644 index 0000000000..de65941a67 --- /dev/null +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInputDeviceKeyboard.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +#include +#include + +namespace AzFramework +{ + class XcbInputDeviceKeyboard + : public InputDeviceKeyboard::Implementation + , public XcbEventHandlerBus::Handler + { + public: + AZ_CLASS_ALLOCATOR(XcbInputDeviceKeyboard, AZ::SystemAllocator, 0); + + using InputDeviceKeyboard::Implementation::Implementation; + XcbInputDeviceKeyboard(InputDeviceKeyboard& inputDevice); + + bool IsConnected() const override; + + bool HasTextEntryStarted() const override; + void TextEntryStart(const InputDeviceKeyboard::VirtualKeyboardOptions& options) override; + void TextEntryStop() override; + void TickInputDevice() override; + + void HandleXcbEvent(xcb_generic_event_t* event) override; + + private: + [[nodiscard]] const InputChannelId* InputChannelFromKeyEvent(xcb_keycode_t code) const; + + XcbUniquePtr m_xkbContext; + XcbUniquePtr m_xkbKeymap; + XcbUniquePtr m_xkbState; + int m_coreDeviceId{-1}; + bool m_initialized{false}; + }; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInterface.h b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInterface.h new file mode 100644 index 0000000000..838048b174 --- /dev/null +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbInterface.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +#include + +namespace AzFramework +{ + // @brief Wrap a function pointer in a type + // This serves as a convenient way to wrap a function pointer in a given + // type. That type can then be used in a `unique_ptr` or `shared_ptr`. + // Using a type instead of a function pointer by value prevents the need to + // copy the pointer when copying the smart poiner. + template + struct XcbDeleterFreeFunctionWrapper + { + using value_type = decltype(Callable); + static constexpr value_type s_value = Callable; + constexpr operator value_type() const noexcept + { + return s_value; + } + }; + + template + using XcbUniquePtr = AZStd::unique_ptr>; + + template + using XcbStdFreePtr = XcbUniquePtr; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp index cfc0222214..6ab97fd616 100644 --- a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp @@ -6,41 +6,37 @@ * */ -#include #include #include -#include +#include +#include -#include "NativeWindow_Linux_xcb.h" +#include namespace AzFramework { -#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - - [[maybe_unused]] const char LinuxXcbErrorWindow[] = "NativeWindow_Linux_xcb"; + [[maybe_unused]] const char XcbErrorWindow[] = "XcbNativeWindow"; static constexpr uint8_t s_XcbFormatDataSize = 32; // Format indicator for xcb for client messages static constexpr uint16_t s_DefaultXcbWindowBorderWidth = 4; // The default border with in pixels if a border was specified static constexpr uint8_t s_XcbResponseTypeMask = 0x7f; // Mask to extract the specific event type from an xcb event //////////////////////////////////////////////////////////////////////////////////////////////// - NativeWindowImpl_Linux_xcb::NativeWindowImpl_Linux_xcb() + XcbNativeWindow::XcbNativeWindow() : NativeWindow::Implementation() { - if (auto xcbConnectionManager = AzFramework::LinuxXcbConnectionManagerInterface::Get(); + if (auto xcbConnectionManager = AzFramework::XcbConnectionManagerInterface::Get(); xcbConnectionManager != nullptr) { m_xcbConnection = xcbConnectionManager->GetXcbConnection(); } - AZ_Error(LinuxXcbErrorWindow, m_xcbConnection != nullptr, "Unable to get XCB Connection"); + AZ_Error(XcbErrorWindow, m_xcbConnection != nullptr, "Unable to get XCB Connection"); } //////////////////////////////////////////////////////////////////////////////////////////////// - NativeWindowImpl_Linux_xcb::~NativeWindowImpl_Linux_xcb() - { - } + XcbNativeWindow::~XcbNativeWindow() = default; //////////////////////////////////////////////////////////////////////////////////////////////// - void NativeWindowImpl_Linux_xcb::InitWindow(const AZStd::string& title, + void XcbNativeWindow::InitWindow(const AZStd::string& title, const WindowGeometry& geometry, const WindowStyleMasks& styleMasks) { @@ -98,13 +94,13 @@ namespace AzFramework xcb_intern_atom_cookie_t cookieProtocol = xcb_intern_atom(m_xcbConnection, 1, strlen(wmProtocolString), wmProtocolString); xcb_intern_atom_reply_t* replyProtocol = xcb_intern_atom_reply(m_xcbConnection, cookieProtocol, nullptr); - AZ_Error(LinuxXcbErrorWindow, replyProtocol != nullptr, "Unable to query xcb '%s' atom", wmProtocolString); + AZ_Error(XcbErrorWindow, replyProtocol != nullptr, "Unable to query xcb '%s' atom", wmProtocolString); m_xcbAtomProtocols = replyProtocol->atom; const static char* wmDeleteWindowString = "WM_DELETE_WINDOW"; xcb_intern_atom_cookie_t cookieDeleteWindow = xcb_intern_atom(m_xcbConnection, 0, strlen(wmDeleteWindowString), wmDeleteWindowString); xcb_intern_atom_reply_t* replyDeleteWindow = xcb_intern_atom_reply(m_xcbConnection, cookieDeleteWindow, nullptr); - AZ_Error(LinuxXcbErrorWindow, replyDeleteWindow != nullptr, "Unable to query xcb '%s' atom", wmDeleteWindowString); + AZ_Error(XcbErrorWindow, replyDeleteWindow != nullptr, "Unable to query xcb '%s' atom", wmDeleteWindowString); m_xcbAtomDeleteWindow = replyDeleteWindow->atom; xcbCheckResult = xcb_change_property_checked(m_xcbConnection, @@ -123,9 +119,9 @@ namespace AzFramework } //////////////////////////////////////////////////////////////////////////////////////////////// - void NativeWindowImpl_Linux_xcb::Activate() + void XcbNativeWindow::Activate() { - LinuxXcbEventHandlerBus::Handler::BusConnect(); + XcbEventHandlerBus::Handler::BusConnect(); if (!m_activated) // nothing to do if window was already activated { @@ -137,7 +133,7 @@ namespace AzFramework } //////////////////////////////////////////////////////////////////////////////////////////////// - void NativeWindowImpl_Linux_xcb::Deactivate() + void XcbNativeWindow::Deactivate() { if (m_activated) // nothing to do if window was already deactivated { @@ -148,17 +144,17 @@ namespace AzFramework xcb_unmap_window(m_xcbConnection, m_xcbWindow); xcb_flush(m_xcbConnection); } - LinuxXcbEventHandlerBus::Handler::BusDisconnect(); + XcbEventHandlerBus::Handler::BusDisconnect(); } //////////////////////////////////////////////////////////////////////////////////////////////// - NativeWindowHandle NativeWindowImpl_Linux_xcb::GetWindowHandle() const + NativeWindowHandle XcbNativeWindow::GetWindowHandle() const { return reinterpret_cast(m_xcbWindow); } //////////////////////////////////////////////////////////////////////////////////////////////// - void NativeWindowImpl_Linux_xcb::SetWindowTitle(const AZStd::string& title) + void XcbNativeWindow::SetWindowTitle(const AZStd::string& title) { xcb_void_cookie_t xcbCheckResult; xcbCheckResult = xcb_change_property(m_xcbConnection, @@ -173,7 +169,7 @@ namespace AzFramework } //////////////////////////////////////////////////////////////////////////////////////////////// - void NativeWindowImpl_Linux_xcb::ResizeClientArea(WindowSize clientAreaSize) + void XcbNativeWindow::ResizeClientArea(WindowSize clientAreaSize) { const uint32_t values[] = { clientAreaSize.m_width, clientAreaSize.m_height }; @@ -184,7 +180,7 @@ namespace AzFramework } //////////////////////////////////////////////////////////////////////////////////////////////// - uint32_t NativeWindowImpl_Linux_xcb::GetDisplayRefreshRate() const + uint32_t XcbNativeWindow::GetDisplayRefreshRate() const { // [GFX TODO][GHI - 2678] // Using 60 for now until proper support is added @@ -192,7 +188,7 @@ namespace AzFramework } //////////////////////////////////////////////////////////////////////////////////////////////// - bool NativeWindowImpl_Linux_xcb::ValidateXcbResult(xcb_void_cookie_t cookie) + bool XcbNativeWindow::ValidateXcbResult(xcb_void_cookie_t cookie) { bool result = true; if (xcb_generic_error_t* error = xcb_request_check(m_xcbConnection, cookie)) @@ -204,7 +200,7 @@ namespace AzFramework } //////////////////////////////////////////////////////////////////////////////////////////////// - void NativeWindowImpl_Linux_xcb::HandleXcbEvent(xcb_generic_event_t* event) + void XcbNativeWindow::HandleXcbEvent(xcb_generic_event_t* event) { switch (event->response_type & s_XcbResponseTypeMask) { @@ -233,7 +229,7 @@ namespace AzFramework } //////////////////////////////////////////////////////////////////////////////////////////////// - void NativeWindowImpl_Linux_xcb::WindowSizeChanged(const uint32_t width, const uint32_t height) + void XcbNativeWindow::WindowSizeChanged(const uint32_t width, const uint32_t height) { if (m_width != width || m_height != height) { @@ -246,7 +242,4 @@ namespace AzFramework } } } - -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - } // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.h b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.h index 40181395e4..36737e24e8 100644 --- a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.h +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.h @@ -5,24 +5,25 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ + #pragma once -#include #include #include +#include + #include namespace AzFramework { -#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - class NativeWindowImpl_Linux_xcb final + class XcbNativeWindow final : public NativeWindow::Implementation - , public LinuxXcbEventHandlerBus::Handler + , public XcbEventHandlerBus::Handler { public: - AZ_CLASS_ALLOCATOR(NativeWindowImpl_Linux_xcb, AZ::SystemAllocator, 0); - NativeWindowImpl_Linux_xcb(); - ~NativeWindowImpl_Linux_xcb() override; + AZ_CLASS_ALLOCATOR(XcbNativeWindow, AZ::SystemAllocator, 0); + XcbNativeWindow(); + ~XcbNativeWindow() override; //////////////////////////////////////////////////////////////////////////////////////////// // NativeWindow::Implementation @@ -37,7 +38,7 @@ namespace AzFramework uint32_t GetDisplayRefreshRate() const override; //////////////////////////////////////////////////////////////////////////////////////////// - // LinuxXcbEventHandlerBus::Handler + // XcbEventHandlerBus::Handler void HandleXcbEvent(xcb_generic_event_t* event) override; private: @@ -49,6 +50,4 @@ namespace AzFramework xcb_atom_t m_xcbAtomProtocols; xcb_atom_t m_xcbAtomDeleteWindow; }; -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - } // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/azframework_xcb_files.cmake b/Code/Framework/AzFramework/Platform/Common/Xcb/azframework_xcb_files.cmake new file mode 100644 index 0000000000..68de710fa1 --- /dev/null +++ b/Code/Framework/AzFramework/Platform/Common/Xcb/azframework_xcb_files.cmake @@ -0,0 +1,18 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + AzFramework/XcbApplication.cpp + AzFramework/XcbApplication.h + AzFramework/XcbConnectionManager.h + AzFramework/XcbInputDeviceKeyboard.cpp + AzFramework/XcbInputDeviceKeyboard.h + AzFramework/XcbInterface.h + AzFramework/XcbNativeWindow.cpp + AzFramework/XcbNativeWindow.h +) diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h b/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h index 833f4019f8..adf3ee0bdd 100644 --- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/API/ApplicationAPI_Linux.h @@ -12,10 +12,6 @@ #include #include -#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB -#include -#endif // LY_COMPILE_DEFINITIONS - namespace AzFramework { class LinuxLifecycleEvents @@ -30,54 +26,4 @@ namespace AzFramework using Bus = AZ::EBus; }; - -#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - class LinuxXcbConnectionManager - { - public: - AZ_RTTI(LinuxXcbConnectionManager, "{1F756E14-8D74-42FD-843C-4863307710DB}"); - - virtual ~LinuxXcbConnectionManager() = default; - - virtual xcb_connection_t* GetXcbConnection() const = 0; - }; - - class LinuxXcbConnectionManagerBusTraits - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - }; - - using LinuxXcbConnectionManagerBus = AZ::EBus; - using LinuxXcbConnectionManagerInterface = AZ::Interface; - - class LinuxXcbEventHandler - { - public: - AZ_RTTI(LinuxXcbEventHandler, "{3F756E14-8D74-42FD-843C-4863307710DB}"); - - virtual ~LinuxXcbEventHandler() = default; - - virtual void HandleXcbEvent(xcb_generic_event_t* event) = 0; - }; - - class LinuxXcbEventHandlerBusTraits - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - }; - - using LinuxXcbEventHandlerBus = AZ::EBus; - -#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB } // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Application/Application_Linux.cpp b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Application/Application_Linux.cpp index 59602fe788..158240210e 100644 --- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Application/Application_Linux.cpp +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Application/Application_Linux.cpp @@ -8,7 +8,9 @@ #include -#include "Application_Linux_xcb.h" +#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB +#include +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// namespace AzFramework @@ -17,7 +19,7 @@ namespace AzFramework Application::Implementation* Application::Implementation::Create() { #if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - return aznew ApplicationLinux_xcb(); + return aznew XcbApplication(); #elif PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND #error "Linux Window Manager Wayland not supported." return nullptr; diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Linux.cpp b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Linux.cpp new file mode 100644 index 0000000000..d1f90c3052 --- /dev/null +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Linux.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB +#include +#endif + +namespace AzFramework +{ + InputDeviceKeyboard::Implementation* InputDeviceKeyboard::Implementation::Create(InputDeviceKeyboard& inputDevice) + { +#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB + return aznew XcbInputDeviceKeyboard(inputDevice); +#elif PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND + #error "Linux Window Manager Wayland not supported." + return nullptr; +#else + #error "Linux Window Manager not recognized." + return nullptr; +#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB + } +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp index 2950f8dcfc..ba3e761974 100644 --- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp @@ -6,14 +6,16 @@ * */ -#include "NativeWindow_Linux_xcb.h" +#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB +#include +#endif namespace AzFramework { NativeWindow::Implementation* NativeWindow::Implementation::Create() { #if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB - return aznew NativeWindowImpl_Linux_xcb(); + return aznew XcbNativeWindow(); #elif PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND #error "Linux Window Manager Wayland not supported." return nullptr; @@ -22,5 +24,4 @@ namespace AzFramework return nullptr; #endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB } - } // namespace AzFramework diff --git a/Code/Framework/AzFramework/Platform/Linux/platform_linux.cmake b/Code/Framework/AzFramework/Platform/Linux/platform_linux.cmake index 5c8ca8392f..b08c3b310d 100644 --- a/Code/Framework/AzFramework/Platform/Linux/platform_linux.cmake +++ b/Code/Framework/AzFramework/Platform/Linux/platform_linux.cmake @@ -10,6 +10,14 @@ # Only 'xcb' and 'wayland' are recognized if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb") + set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) + set(LY_INCLUDE_DIRECTORIES + PUBLIC + Platform/Common/Xcb + ) + set(LY_FILES_CMAKE + Platform/Common/Xcb/azframework_xcb_files.cmake + ) set(LY_BUILD_DEPENDENCIES PRIVATE 3rdParty::X11::xcb @@ -18,8 +26,6 @@ if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb") 3rdParty::X11::xkbcommon_X11 ) - set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB) - elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "wayland") set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND) diff --git a/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake b/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake index 93767322b2..4f06aa5c57 100644 --- a/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake +++ b/Code/Framework/AzFramework/Platform/Linux/platform_linux_files.cmake @@ -12,8 +12,6 @@ set(FILES AzFramework/API/ApplicationAPI_Platform.h AzFramework/API/ApplicationAPI_Linux.h AzFramework/Application/Application_Linux.cpp - AzFramework/Application/Application_Linux_xcb.h - AzFramework/Application/Application_Linux_xcb.cpp AzFramework/Asset/AssetSystemComponentHelper_Linux.cpp AzFramework/Process/ProcessWatcher_Linux.cpp AzFramework/Process/ProcessCommon.h @@ -22,10 +20,8 @@ set(FILES ../Common/Unimplemented/AzFramework/StreamingInstall/StreamingInstall_Unimplemented.cpp ../Common/Default/AzFramework/TargetManagement/TargetManagementComponent_Default.cpp AzFramework/Windowing/NativeWindow_Linux.cpp - AzFramework/Windowing/NativeWindow_Linux_xcb.h - AzFramework/Windowing/NativeWindow_Linux_xcb.cpp ../Common/Unimplemented/AzFramework/Input/Devices/Gamepad/InputDeviceGamepad_Unimplemented.cpp - AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_xcb.cpp + AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Linux.cpp ../Common/Unimplemented/AzFramework/Input/Devices/Motion/InputDeviceMotion_Unimplemented.cpp ../Common/Unimplemented/AzFramework/Input/Devices/Mouse/InputDeviceMouse_Unimplemented.cpp ../Common/Unimplemented/AzFramework/Input/Devices/Touch/InputDeviceTouch_Unimplemented.cpp diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Linux/RHI/WSISurface_Linux.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Linux/RHI/WSISurface_Linux.cpp index a818599b0d..7d70d0245f 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Linux/RHI/WSISurface_Linux.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Linux/RHI/WSISurface_Linux.cpp @@ -10,6 +10,10 @@ #include #include +#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB +#include +#endif + namespace AZ { namespace Vulkan @@ -21,7 +25,7 @@ namespace AZ #if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB xcb_connection_t* xcb_connection = nullptr; - if (auto xcbConnectionManager = AzFramework::LinuxXcbConnectionManagerInterface::Get(); + if (auto xcbConnectionManager = AzFramework::XcbConnectionManagerInterface::Get(); xcbConnectionManager != nullptr) { xcb_connection = xcbConnectionManager->GetXcbConnection();