Skip to content

Commit 46c0eb0

Browse files
committed
feature: implement xcb for windowing
Signed-off-by: Michael Pollind <mpollind@gmail.com>
1 parent 8148213 commit 46c0eb0

19 files changed

+1121
-14
lines changed

3rdparty/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ set(VOLK_PULL_IN_VULKAN OFF CACHE INTERNAL "" FORCE) # Needed to make sure vulka
3636

3737
if (WIN32)
3838
set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_WIN32_KHR)
39+
elseif(UNIX AND NOT ANDROID AND NOT APPLE)
40+
set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_XCB_KHR)
3941
endif()
4042
add_subdirectory(volk volk EXCLUDE_FROM_ALL)
4143

include/nbl/core/string/StringLiteral.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#ifndef _NBL_CORE_STRING_LITERAL_H_INCLUDED_
55
#define _NBL_CORE_STRING_LITERAL_H_INCLUDED_
66

7+
#include <algorithm>
8+
#include <cstddef>
9+
710
namespace nbl::core
811
{
912

@@ -15,6 +18,11 @@ struct StringLiteral
1518
std::copy_n(str, N, value);
1619
}
1720

21+
// the size includes the null terminator
22+
constexpr size_t size() const {
23+
return N;
24+
}
25+
1826
char value[N];
1927
};
2028

include/nbl/ui/CClipboardManagerXcb.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#ifndef _NBL_UI_C_CLIPBOARD_MANAGER_XCB_INCLUDED_
2+
#define _NBL_UI_C_CLIPBOARD_MANAGER_XCB_INCLUDED_
3+
4+
#include <string>
5+
#include <vector>
6+
#include <xcb/xproto.h>
7+
#ifdef _NBL_PLATFORM_LINUX_
8+
9+
#include "nbl/core/decl/Types.h"
10+
#include "nbl/ui/IClipboardManager.h"
11+
#include "nbl/ui/XcbConnection.h"
12+
13+
namespace nbl::ui
14+
{
15+
16+
// details on XCB clipboard protocol: https://tronche.com/gui/x/icccm/sec-2.html#s-2
17+
class NBL_API2 CClipboardManagerXcb final : public IClipboardManager
18+
{
19+
using base_t = IClipboardManager;
20+
public:
21+
inline CClipboardManagerXcb(core::smart_refctd_ptr<XcbConnection>&& connect):
22+
m_xcbConnection(std::move(connect)) {}
23+
24+
virtual std::string getClipboardText() override;
25+
virtual bool setClipboardText(const std::string_view& data) override;
26+
27+
void process(const IWindowXcb* window, xcb_generic_event_t* event);
28+
private:
29+
core::smart_refctd_ptr<XcbConnection> m_xcbConnection;
30+
31+
xcb_window_t getClipboardWindow();
32+
33+
struct {
34+
std::string m_data;
35+
std::vector<xcb_atom_t> m_formats;
36+
} m_stagedClipboard;
37+
38+
std::mutex m_clipboardMutex;
39+
std::condition_variable m_clipboardResponseCV;
40+
std::string m_clipboardResponse;
41+
// bool ready = false;
42+
43+
XcbConnection::XCBAtomToken<core::StringLiteral("CLIPBOARD")> m_CLIPBOARD;
44+
XcbConnection::XCBAtomToken<core::StringLiteral("TARGETS")> m_TARGETS;
45+
XcbConnection::XCBAtomToken<core::StringLiteral("INCR")> m_INCR;
46+
47+
48+
XcbConnection::XCBAtomToken<core::StringLiteral("UTF8_STRING")> m_formatUTF8_0;
49+
XcbConnection::XCBAtomToken<core::StringLiteral("text/plain;charset=utf-8")> m_formatUTF8_1;
50+
XcbConnection::XCBAtomToken<core::StringLiteral("text/plain;charset=UTF-8")> m_formatUTF8_2;
51+
XcbConnection::XCBAtomToken<core::StringLiteral("GTK_TEXT_BUFFER_CONTENTS")> m_formatGTK;
52+
XcbConnection::XCBAtomToken<core::StringLiteral("STRING")> m_formatString;
53+
XcbConnection::XCBAtomToken<core::StringLiteral("TEXT")> m_formatText;
54+
XcbConnection::XCBAtomToken<core::StringLiteral("text/plain")> m_formatTextPlain;
55+
56+
57+
};
58+
59+
}
60+
61+
#endif
62+
63+
#endif

include/nbl/ui/CCursorControlXcb.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#ifndef __NBL_SYSTEM_C_CURSOR_CONTROL_XCB_H_INCLUDED__
2+
#define __NBL_SYSTEM_C_CURSOR_CONTROL_XCB_H_INCLUDED__
3+
4+
5+
#include "nbl/ui/ICursorControl.h"
6+
#include "nbl/ui/XcbConnection.h"
7+
8+
#ifdef _NBL_PLATFORM_LINUX_
9+
10+
namespace nbl::ui
11+
{
12+
class NBL_API2 CCursorControlXcb final : public ICursorControl
13+
{
14+
core::smart_refctd_ptr<XcbConnection> m_xcbConnection;
15+
16+
public:
17+
inline CCursorControlXcb(
18+
core::smart_refctd_ptr<XcbConnection>&& xcbConnection) :
19+
m_xcbConnection(std::move(xcbConnection)) {}
20+
21+
void setVisible(bool visible) override;
22+
bool isVisible() const override;
23+
24+
void setPosition(SPosition pos) override;
25+
void setRelativePosition(IWindow* window, SRelativePosition pos) override;
26+
27+
SPosition getPosition() override;
28+
SRelativePosition getRelativePosition(IWindow* window) override;
29+
};
30+
}
31+
32+
#endif
33+
34+
#endif

include/nbl/ui/CWindowManagerXcb.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#ifndef C_WINDOW_MANAGER_XCB
2+
#define C_WINDOW_MANAGER_XCB
3+
4+
#ifdef _NBL_PLATFORM_LINUX_
5+
#include "nbl/core/decl/Types.h"
6+
7+
#include "nbl/system/DefaultFuncPtrLoader.h"
8+
9+
#include "nbl/ui/IWindow.h"
10+
#include "nbl/ui/IWindowManager.h"
11+
12+
#include <functional>
13+
#include <memory>
14+
#include <string>
15+
16+
#include <xcb/xcb.h>
17+
#include <xcb/xcb_icccm.h>
18+
#include <xcb/xproto.h>
19+
20+
namespace nbl::ui
21+
{
22+
23+
NBL_SYSTEM_DECLARE_DYNAMIC_FUNCTION_CALLER_CLASS(Xcb, system::DefaultFuncPtrLoader,
24+
xcb_destroy_window,
25+
xcb_generate_id,
26+
xcb_create_window,
27+
xcb_connect,
28+
xcb_disconnect,
29+
xcb_map_window,
30+
xcb_get_setup,
31+
xcb_setup_roots_iterator,
32+
xcb_flush,
33+
xcb_intern_atom,
34+
xcb_intern_atom_reply,
35+
xcb_unmap_window,
36+
xcb_get_property,
37+
xcb_get_property_reply,
38+
xcb_get_property_value_length,
39+
xcb_change_property,
40+
xcb_configure_window_checked,
41+
xcb_get_property_value,
42+
xcb_wait_for_event,
43+
xcb_send_event,
44+
xcb_request_check,
45+
xcb_delete_property,
46+
xcb_change_window_attributes,
47+
xcb_warp_pointer,
48+
xcb_query_pointer,
49+
xcb_query_pointer_reply,
50+
xcb_get_selection_owner_reply,
51+
xcb_get_selection_owner
52+
);
53+
54+
NBL_SYSTEM_DECLARE_DYNAMIC_FUNCTION_CALLER_CLASS(XcbIcccm, system::DefaultFuncPtrLoader,
55+
xcb_icccm_set_wm_hints,
56+
xcb_icccm_size_hints_set_size,
57+
xcb_icccm_size_hints_set_min_size,
58+
xcb_icccm_size_hints_set_max_size,
59+
xcb_icccm_set_wm_normal_hints
60+
);
61+
62+
class CWindowManagerXcb : public IWindowManager
63+
{
64+
public:
65+
66+
virtual bool setWindowSize_impl(IWindow* window, uint32_t width, uint32_t height) override;
67+
virtual bool setWindowPosition_impl(IWindow* window, int32_t x, int32_t y) override;
68+
virtual bool setWindowRotation_impl(IWindow* window, bool landscape) override;
69+
virtual bool setWindowVisible_impl(IWindow* window, bool visible) override;
70+
virtual bool setWindowMaximized_impl(IWindow* window, bool maximized) override;
71+
72+
inline SDisplayInfo getPrimaryDisplayInfo() const override final {
73+
return SDisplayInfo();
74+
}
75+
76+
CWindowManagerXcb();
77+
~CWindowManagerXcb() override = default;
78+
79+
virtual core::smart_refctd_ptr<IWindow> createWindow(IWindow::SCreationParams&& creationParams) override;
80+
81+
virtual void destroyWindow(IWindow* wnd) override final {}
82+
83+
const Xcb& getXcbFunctionTable() const { return m_xcb; }
84+
const XcbIcccm& getXcbIcccmFunctionTable() const { return m_xcbIcccm; }
85+
86+
private:
87+
88+
Xcb m_xcb = Xcb("xcb"); // function tables
89+
XcbIcccm m_xcbIcccm = XcbIcccm("xcb-icccm");
90+
};
91+
92+
93+
}
94+
#endif
95+
#endif

include/nbl/ui/CWindowXcb.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#ifndef __C_WINDOW_XCB_H_INCLUDED__
2+
#define __C_WINDOW_XCB_H_INCLUDED__
3+
4+
#include <cstdlib>
5+
6+
#include "nbl/core/decl/smart_refctd_ptr.h"
7+
#include "nbl/ui/CClipboardManagerXcb.h"
8+
#include "nbl/ui/IWindowXcb.h"
9+
#include "nbl/ui/XcbConnection.h"
10+
11+
namespace nbl::ui
12+
{
13+
14+
class CCursorControlXcb;
15+
class CWindowManagerXcb;
16+
class CClipboardManagerXcb;
17+
18+
class NBL_API2 CWindowXcb final : public IWindowXcb
19+
{
20+
21+
public:
22+
CWindowXcb(core::smart_refctd_ptr<CWindowManagerXcb>&& winManager, SCreationParams&& params);
23+
~CWindowXcb();
24+
25+
// Display* getDisplay() const override { return m_dpy; }
26+
xcb_window_t getXcbWindow() const override { return m_xcbWindow; }
27+
xcb_connection_t* getXcbConnection() const override {
28+
return m_xcbConnection->getRawConnection();
29+
}
30+
31+
virtual IClipboardManager* getClipboardManager() override;
32+
virtual ICursorControl* getCursorControl() override;
33+
virtual IWindowManager* getManager() override;
34+
35+
virtual bool setWindowSize_impl(uint32_t width, uint32_t height) override;
36+
virtual bool setWindowPosition_impl(int32_t x, int32_t y) override;
37+
virtual bool setWindowRotation_impl(bool landscape) override;
38+
virtual bool setWindowVisible_impl(bool visible) override;
39+
virtual bool setWindowMaximized_impl(bool maximized) override;
40+
41+
virtual void setCaption(const std::string_view& caption) override;
42+
43+
private:
44+
CWindowXcb(core::smart_refctd_ptr<system::ISystem>&& sys, uint32_t _w, uint32_t _h, E_CREATE_FLAGS _flags);
45+
46+
core::smart_refctd_ptr<CWindowManagerXcb> m_windowManager;
47+
core::smart_refctd_ptr<XcbConnection> m_xcbConnection;
48+
core::smart_refctd_ptr<CCursorControlXcb> m_cursorControl;
49+
core::smart_refctd_ptr<CClipboardManagerXcb> m_clipboardManager;
50+
51+
class CDispatchThread final : public system::IThreadHandler<CDispatchThread>
52+
{
53+
public:
54+
55+
inline CDispatchThread(CWindowXcb& window);
56+
inline ~CDispatchThread() {
57+
}
58+
59+
void init();
60+
void exit();
61+
void work(lock_t& lock);
62+
63+
inline bool wakeupPredicate() const { return true; }
64+
inline bool continuePredicate() const { return true; }
65+
private:
66+
CWindowXcb& m_window;
67+
// xcb_connection_t* m_connection = nullptr;
68+
friend class CWindowXcb;
69+
} m_dispatcher;
70+
71+
xcb_window_t m_xcbWindow = 0;
72+
73+
XcbConnection::XCBAtomToken<core::StringLiteral("WM_DELETE_WINDOW")> m_WM_DELETE_WINDOW;
74+
XcbConnection::XCBAtomToken<core::StringLiteral("WM_PROTOCOLS")> m_WM_PROTOCOLS;
75+
XcbConnection::XCBAtomToken<core::StringLiteral("_NET_WM_PING")> m_NET_WM_PING;
76+
77+
XcbConnection::XCBAtomToken<core::StringLiteral("_NET_WM_STATE_MAXIMIZED_VERT")> m_NET_WM_STATE_MAXIMIZED_VERT;
78+
XcbConnection::XCBAtomToken<core::StringLiteral("_NET_WM_STATE_MAXIMIZED_HORZ")> m_NET_WM_STATE_MAXIMIZED_HORZ;
79+
XcbConnection::XCBAtomToken<core::StringLiteral("_NET_WM_STATE_FULLSCREEN")> m_NET_WM_STATE_FULLSCREEN;
80+
81+
};
82+
83+
}
84+
85+
#endif

0 commit comments

Comments
 (0)