From cf1a0aea8080c06d70bba5984743c2948d4215c3 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Sun, 31 Aug 2025 21:48:29 +0800 Subject: Bootstrap xcb. --- include/cru/platform/gui/UiApplication.h | 4 +- include/cru/platform/gui/xcb/Base.h | 23 ++++++++++ include/cru/platform/gui/xcb/UiApplication.h | 64 ++++++++++++++++++++++++++++ include/cru/platform/gui/xcb/Window.h | 10 +++++ src/platform/CMakeLists.txt | 1 + src/platform/gui/xcb/CMakeLists.txt | 8 ++++ src/platform/gui/xcb/UiApplication.cpp | 20 +++++++++ src/platform/gui/xcb/Window.cpp | 1 + 8 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 include/cru/platform/gui/xcb/Base.h create mode 100644 include/cru/platform/gui/xcb/UiApplication.h create mode 100644 include/cru/platform/gui/xcb/Window.h create mode 100644 src/platform/gui/xcb/CMakeLists.txt create mode 100644 src/platform/gui/xcb/UiApplication.cpp create mode 100644 src/platform/gui/xcb/Window.cpp diff --git a/include/cru/platform/gui/UiApplication.h b/include/cru/platform/gui/UiApplication.h index 88aa3e20..3f36c26c 100644 --- a/include/cru/platform/gui/UiApplication.h +++ b/include/cru/platform/gui/UiApplication.h @@ -64,12 +64,12 @@ struct CRU_PLATFORM_GUI_API IUiApplication : public virtual IPlatformResource { virtual IMenu* GetApplicationMenu(); /** - * \todo Implement on Windows. + * \todo Implement on Windows/X11. */ virtual std::optional ShowSaveDialog(SaveDialogOptions options); /** - * \todo Implement on Windows. + * \todo Implement on Windows/X11. */ virtual std::optional> ShowOpenDialog( OpenDialogOptions options); diff --git a/include/cru/platform/gui/xcb/Base.h b/include/cru/platform/gui/xcb/Base.h new file mode 100644 index 00000000..f3bcfd01 --- /dev/null +++ b/include/cru/platform/gui/xcb/Base.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "../../Resource.h" + +namespace cru::platform::gui::xcb { +class XcbResource : public Object, public virtual IPlatformResource { + public: + static String kPlatformId; + + protected: + XcbResource() = default; + + public: + String GetPlatformId() const final { return kPlatformId; } +}; + +class XcbException : public PlatformException { + public: + using PlatformException::PlatformException; +}; +} // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/xcb/UiApplication.h b/include/cru/platform/gui/xcb/UiApplication.h new file mode 100644 index 00000000..a58a538f --- /dev/null +++ b/include/cru/platform/gui/xcb/UiApplication.h @@ -0,0 +1,64 @@ +#pragma once +#include "../UiApplication.h" +#include "Base.h" + +#include + +namespace cru::platform::gui::xcb { +class XcbUiApplication : public XcbResource, public virtual IUiApplication { + public: + XcbUiApplication(); + ~XcbUiApplication(); + + void CheckXcbConnectionError(); + + virtual int Run() = 0; + + // Post a quit message with given quit code. + virtual void RequestQuit(int quit_code) = 0; + + virtual void AddOnQuitHandler(std::function handler) = 0; + + virtual bool IsQuitOnAllWindowClosed() = 0; + virtual void SetQuitOnAllWindowClosed(bool quit_on_all_window_closed) = 0; + + // Timer id should always be positive (not 0) and never the same. So it's ok + // to use negative value (or 0) to represent no timer. + virtual long long SetImmediate(std::function action) = 0; + virtual long long SetTimeout(std::chrono::milliseconds milliseconds, + std::function action) = 0; + virtual long long SetInterval(std::chrono::milliseconds milliseconds, + std::function action) = 0; + // Implementation should guarantee calls on timer id already canceled have no + // effects and do not crash. Also canceling negative id or 0 should always + // result in no-op. + virtual void CancelTimer(long long id) = 0; + + virtual std::vector GetAllWindow() = 0; + + virtual INativeWindow* CreateWindow() = 0; + + virtual cru::platform::graphics::IGraphicsFactory* GetGraphicsFactory() = 0; + + virtual ICursorManager* GetCursorManager() = 0; + + virtual IClipboard* GetClipboard() = 0; + + // If return nullptr, it means the menu is not supported. + virtual IMenu* GetApplicationMenu(); + + /** + * \todo Implement on Windows. + */ + virtual std::optional ShowSaveDialog(SaveDialogOptions options); + + /** + * \todo Implement on Windows. + */ + virtual std::optional> ShowOpenDialog( + OpenDialogOptions options); + + private: + xcb_connection_t* xcb_; +}; +} // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/xcb/Window.h b/include/cru/platform/gui/xcb/Window.h new file mode 100644 index 00000000..94f5d350 --- /dev/null +++ b/include/cru/platform/gui/xcb/Window.h @@ -0,0 +1,10 @@ + +#pragma once +#include "../Window.h" +#include "Base.h" + +namespace cru::platform::gui::xcb { +class XcbWindow : public XcbResource, public virtual INativeWindow { + +}; +} // namespace cru::platform::gui::x11 diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 3044df08..63ef9058 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -26,6 +26,7 @@ elseif (EMSCRIPTEN) add_subdirectory(graphics/web_canvas) elseif (UNIX) add_subdirectory(graphics/cairo) + add_subdirectory(gui/xcb) endif() add_subdirectory(bootstrap) diff --git a/src/platform/gui/xcb/CMakeLists.txt b/src/platform/gui/xcb/CMakeLists.txt new file mode 100644 index 00000000..2ef675a3 --- /dev/null +++ b/src/platform/gui/xcb/CMakeLists.txt @@ -0,0 +1,8 @@ +find_library(LIBRARY_CAIRO cairo REQUIRED) +find_library(LIBRARY_XCB xcb REQUIRED) +add_library(CruPlatformGuiX11 + UiApplication.cpp + Window.cpp +) +target_link_libraries(CruPlatformGuiX11 PUBLIC CruPlatformGui ${LIBRARY_XCB} ${LIBRARY_CAIRO}) + diff --git a/src/platform/gui/xcb/UiApplication.cpp b/src/platform/gui/xcb/UiApplication.cpp new file mode 100644 index 00000000..baa36abe --- /dev/null +++ b/src/platform/gui/xcb/UiApplication.cpp @@ -0,0 +1,20 @@ +#include +#include + +namespace cru::platform::gui::xcb { +XcbUiApplication::XcbUiApplication() { + int screen_num; + xcb_connection_t *connection = xcb_connect(NULL, &screen_num); + this->CheckXcbConnectionError(); + const xcb_setup_t *setup = xcb_get_setup(connection); + xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); + xcb_screen_t *screen = iter.data; +} + +XcbUiApplication::~XcbUiApplication() { xcb_disconnect(this->xcb_); } + +void XcbUiApplication::CheckXcbConnectionError() { +if (xcb_connection_has_error(this->xcb_)) { + throw XcbException(); +}} +} // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/Window.cpp b/src/platform/gui/xcb/Window.cpp new file mode 100644 index 00000000..92772acf --- /dev/null +++ b/src/platform/gui/xcb/Window.cpp @@ -0,0 +1 @@ +#include -- cgit v1.2.3