- More documentation

This commit is contained in:
2025-12-18 16:18:07 -05:00
parent 9e6f00eb60
commit 88e33bdcc8
50 changed files with 987 additions and 264 deletions

View File

@@ -58,80 +58,109 @@ class display_server : public type_registry<display_server, platform*> {
// Typedefs/Constants/Enums ============================================================================================
public:
enum feature_ : uint32_t {
feature_subwindows = 0,
feature_icon,
///
/// \brief enum representing features to test support for against the display server
enum feature_ : uint32_t {
feature_subwindows = 0, //!< sub window support
feature_icon, //!< icon support
feature_window_drag,
feature_window_drag, //!< window dragging support
feature_mouse,
feature_cursors,
feature_custom_cursors,
feature_mouse, //!< mouse support
feature_cursors, //!< multiple cursor type support
feature_custom_cursors, //!< custom cursor image support
feature_clipboard,
feature_clipboard_primary,
feature_virtual_keyboard,
feature_clipboard, //!< clipboard support
feature_clipboard_primary, //!< highlight support
feature_virtual_keyboard, //!< virtual keyboard support
feature_status_indicators,
feature_dialogues,
feature_input_dialogues,
feature_file_dialogues,
feature_filtered_file_dialogues,
feature_status_indicators, //!< taskbar status indicators
feature_dialogues, //!< popup dialog support
feature_input_dialogues, //!< popup dialog text input support
feature_file_dialogues, //!< file navigation support
feature_filtered_file_dialogues, //!< filtered file navigation support
feature_orientation,
feature_hidpi,
feature_hdr,
feature_swap_buffers,
feature_window_transparency,
feature_orientation, //!< display orientation support
feature_hidpi, //!< high dpi support
feature_hdr, //!< hdr support
feature_swap_buffers, //!< swap buffer support
feature_window_transparency, //!< window transparency support
feature_screen_reader,
feature_text_to_speech,
feature_touchscreen,
feature_system_theme,
feature_screen_reader, //!< screen reader support
feature_text_to_speech, //!< text to speech system support
feature_touchscreen, //!< touchscreen support
feature_system_theme, //!< system specified theming
feature_count,
feature_count, //!< number of features
};
using featureset_t = bitfield<feature_count>;
using window_id = uint32_t;
using window_pool = object_pool<unique_ptr<window>>;
using featureset_t = bitfield<feature_count>; //!< a bitset holding the supported feature set
// Public Members ======================================================================================================
platform* const platform;
platform* const platform; //!< the parent platform
///
/// \brief display server constructor
/// \param p the parent platform
explicit display_server(fennec::platform* p)
: platform(p) {
}
///
/// \brief base destructor
virtual ~display_server() {
}
///
/// \brief feature support checking function
/// \param feature the feature to check
/// \returns \f$true\f$ if the feature is supported, \f$false\f$ otherwise
bool has_feature(uint32_t feature) const {
return features.test(feature);
}
virtual window* create_window(const window::config&, window* = nullptr) = 0;
///
/// \brief create a new window with the specified configuration and parent
/// \param cfg the configuration
/// \param p the parent window
/// \returns the created window
virtual window* create_window(const window::config& cfg, window* p = nullptr) = 0;
///
/// \brief connect to the display server
virtual void connect() = 0;
///
/// \brief disconnect from the display server
virtual void disconnect() = 0;
///
/// \returns \f$true\f$ if connected to the display server, \f$false\f$ otherwise
virtual bool connected() const = 0;
///
/// \brief dispatch the current context to the display server
virtual void dispatch() = 0;
///
/// \returns the underlying native handle
virtual void* get_native_handle() = 0;
///
/// \returns the graphics context of the display connection
gfxcontext* get_gfx_context() {
return gfx_context.get();
}
protected:
featureset_t features;
unique_ptr<gfxcontext> gfx_context;
featureset_t features; //!< the feature set of the display server
unique_ptr<gfxcontext> gfx_context; //!< the graphics context of the display server
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE() {
}
#endif
};
///
@@ -139,12 +168,15 @@ protected:
template<typename DisplayT, typename WindowT>
class display_server_base : public display_server, public type_registry<gfxcontext, DisplayT*> {
public:
///
/// \brief display server constructor
/// \param p the parent platform
display_server_base(fennec::platform* p)
: display_server(p) {
}
using ctx_registry = type_registry<gfxcontext, DisplayT*>;
using window_t = WindowT;
using ctx_registry = type_registry<gfxcontext, DisplayT*>; //!< registry for graphics contexts
using window_t = WindowT; //!< the window type of the display server
};
}

View File

@@ -65,26 +65,47 @@ namespace fennec
/// \brief Main platform class
class platform : public singleton<platform*> {
public:
using shared_object = struct shared_object;
using symbol = void*;
using shared_object = struct shared_object; //!< handle for shared object code
using symbol = void*; //!< handle for a symbol loaded from a shared object
///
/// \brief constructor
platform();
///
/// \brief destructor
virtual ~platform() = default;
platform(const platform&) = delete;
// Dynamically linked objects
///
/// \brief shared object linker
/// \param file the name of the shared object to link
/// \returns a reference to the shared object
virtual shared_object* load_object(const cstring& file) = 0;
///
/// \brief shared object release
/// \param obj the shared object to release
virtual void unload_object(shared_object* obj) = 0;
///
/// \brief shared object symbol locator
/// \param obj the shared object to search
/// \param name the name of the symbol to search for
/// \returns a reference to the symbol
virtual symbol find_symbol(shared_object* obj, const cstring& name) = 0;
virtual void initialize(); // Initialize Drivers and Contexts
virtual void shutdown(); // Close Drivers and Contexts
virtual void initialize(); //!< Initialize Drivers and Contexts
virtual void shutdown(); //!< Close Drivers and Contexts
protected:
unique_ptr<window_manager> wmanager;
unique_ptr<window_manager> wmanager; //!< the window manager
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE() {
}
#endif
};
}

View File

@@ -44,38 +44,46 @@
namespace fennec
{
///
/// \brief base window interface
class window {
// Structures & Typedefs ===============================================================================================
// Definitions =========================================================================================================
public:
static constexpr size_t nullid = -1;
///
/// \brief window mode
enum mode_ : uint8_t {
mode_windowed = 0,
mode_minimized,
mode_maximized,
mode_fullscreen,
mode_exclusive_fullscreen,
mode_windowed = 0, //!< normal window mode
mode_minimized, //!< minimized to the taskbar
mode_maximized, //!< maximized to take up the whole screen
mode_fullscreen, //!< window surface takes the whole screen without border decorations
mode_exclusive_fullscreen, //!< takes exclusive control of the display
};
///
/// \brief vsync mode
enum vsync_ : uint8_t {
vsync_disabled = 0,
vsync_enabled,
vsync_adaptive
vsync_disabled = 0, //!< no vertical sync
vsync_enabled, //!< enabled vertical sync
vsync_adaptive //!< adaptive sync
};
///
/// \brief window behaviour flags
enum flag_ : uint8_t {
flag_always_on_top = 0, // Window always appears on top level
flag_borderless, // Window has no border decorations
flag_modal, // Window always appears above parent and blocks input going to parent
flag_pass_mouse, // Mouse interaction passes to next underlying window in the application
flag_popup, // Window does not show in taskbar and closes when loses focus
flag_resizable, // Window can be resized through functions defined by Desktop Environment
flag_transparent, // Window has an alpha value
flag_no_focus, // Window can be focused
flag_always_on_top = 0, //!< Window always appears on top level
flag_borderless, //!< Window has no border decorations
flag_modal, //!< Window always appears above parent and blocks input going to parent
flag_pass_mouse, //!< Mouse interaction passes to next underlying window in the application
flag_popup, //!< Window does not show in taskbar and closes when loses focus
flag_resizable, //!< Window can be resized through functions defined by Desktop Environment
flag_transparent, //!< Window has an alpha value
flag_no_focus, //!< Window can be focused
flag_count
flag_count //!< the number of flags
};
///
/// \brief window state flags
enum state_ : uint8_t {
state_running = 0, // Window is running
state_child, // Window is a child
@@ -85,104 +93,270 @@ public:
state_count
};
using flags_t = bitfield<flag_count>;
using state_t = bitfield<state_count>;
using flags_t = bitfield<flag_count>; //!< flag bitset
using state_t = bitfield<state_count>; //!< state bitset
///
/// \brief accessibility information
struct accessibility {
string name, description;
string name; //!< the name of the window provided to accessibility features
string description; //!< the description of the window provided to accessibility features
};
///
/// \brief window configuration
struct config {
string title;
flags_t flags;
uint8_t mode;
string title; //!< title of the window
flags_t flags; //!< window behaviour flags
uint8_t mode; //!< the window mode
size_t parent;
irect rect;
irect rect; //!< the bounds of the window
double_t fractional_scaling;
double_t fractional_scaling; //!< fractional scaling factor
accessibility accessibility;
accessibility accessibility; //!< accessibility info
};
///
/// \brief window state info
struct state {
uint8_t mode;
irect rect;
state_t flags;
int_t buffer_scale;
double_t fractional_scaling;
uint8_t mode; //!< the current window mode
irect rect; //!< the current bounds of the window
state_t flags; //!< the current behaviour flags of the window
int_t buffer_scale; //!< buffer scaling
double_t fractional_scaling; //!< current fractional scaling factor
};
// Constructors & Destructor ===========================================================================================
///
/// \brief window constructor
/// \param server the display server the window belongs to
/// \param conf the configuration to construct the window with
/// \param parent a reference to the parent window
window(display_server* server, const config& conf, window* parent);
///
/// \brief base destructor
virtual ~window();
// Properties ==========================================================================================================
///
/// \returns the current configuration of the window
const config& get_config() const { return cfg; }
///
/// \returns the parent window
window* get_parent() const { return parent; }
///
/// \returns the nearest top-level window in the hierarchy
window* get_root() const { return root; }
///
/// \returns the underlying handle of the window
virtual void* get_native_handle() = 0;
// Positional Info =====================================================================================================
///
/// \returns the size of the window
const ivec2& get_size() const { return state.rect.size; }
///
/// \returns the position of the window
const ivec2& get_position() const { return state.rect.position; }
///
/// \returns the width of the window
int get_width() const { return state.rect.size.x; }
///
/// \returns the height of the window
int get_height() const { return state.rect.size.y; }
///
/// \returns the x position of the window
int get_pos_x() const { return state.rect.position.x; }
///
/// \returns the y position of the window
int get_pos_y() const { return state.rect.position.y; }
// Status ==============================================================================================================
///
/// \brief tests if the window is visible
/// \returns \f$true\f$ if the window is visible, \f$false\f$ otherwise
bool is_visible() const { return state.flags.test(state_visible); }
///
/// \brief tests if the window is a child
/// \returns \f$true\f$ if the window is a child, \f$false\f$ otherwise
bool is_child() const { return state.flags.test(state_child); }
///
/// \brief tests if the window is running
/// \returns \f$true\f$ if the window is running, \f$false\f$ otherwise
bool is_running() const { return state.flags.test(state_running); }
///
/// \brief tests if the window is suspended
/// \returns \f$true\f$ if the window is suspended, \f$false\f$ otherwise
bool is_suspended() const { return state.flags.test(state_suspended); }
// Behaviour ===========================================================================================================
///
/// \brief tests a specific flag
/// \param flag the flag from `window::flag_`
/// \returns \f$true\f$ if the flag is set, \f$false\f$ otherwise
bool get_flag(uint8_t flag) const { return cfg.flags.test(flag); }
///
/// \brief check if the window is flagged to always be on top of other windows
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_always_on_top() const { return get_flag(flag_always_on_top); }
///
/// \brief check if the window is flagged to have no window decorations
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_borderless() const { return get_flag(flag_borderless); }
///
/// \brief check if the window is flagged to be modal
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_modal() const { return get_flag(flag_modal); }
///
/// \brief check if the window is flagged to pass mouse input to windows underneath from the same application
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_passing_mouse() const { return get_flag(flag_pass_mouse); }
///
/// \brief check if the window is flagged as a popup
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_popup() const { return get_flag(flag_popup); }
///
/// \brief check if the window is flagged to be resizable
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_resizable() const { return get_flag(flag_resizable); }
///
/// \brief check if the window is flagged to be transparent
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_transparent() const { return get_flag(flag_transparent); }
///
/// \brief check if the window is flagged to be unfocusable
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_no_focus() const { return get_flag(flag_no_focus); }
///
/// \brief sets a specific flag
/// \param flag the flag from `window::flag_`
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
virtual bool set_flag(uint8_t flag, bool val) = 0;
///
/// \brief sets whether to always be on top of other windows
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_always_on_top(bool val) { return set_flag(flag_always_on_top, val); }
///
/// \brief sets whether to have no window decorations
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_borderless(bool val) { return set_flag(flag_borderless, val); }
///
/// \brief sets whether to be modal
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_modal(bool val) { return set_flag(flag_modal, val); }
///
/// \brief sets whether to pass mouse input to windows underneath from the same application
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_passing_mouse(bool val) { return set_flag(flag_pass_mouse, val); }
///
/// \brief sets whether the window is a popup
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_popup(bool val) { return set_flag(flag_popup, val); }
///
/// \brief sets whether to be resizable
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_resizable(bool val) { return set_flag(flag_resizable, val); }
///
/// \brief sets whetherto be transparent
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_transparent(bool val) { return set_flag(flag_transparent, val); }
///
/// \brief sets whether to be unfocusable
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_no_focus(bool val) { return set_flag(flag_no_focus, val); }
virtual void initialize() = 0;
virtual void shutdown() = 0;
virtual void begin_frame();
virtual void end_frame();
virtual void* get_native_handle() = 0;
// Window Management Functions =========================================================================================
virtual void initialize() = 0; //!< initialization function
virtual void shutdown() = 0; //!< shutdown function
virtual void begin_frame(); //!< start a frame for the window, setting the correct graphics context
virtual void end_frame(); //!< end a frame for the window, swapping the underlying buffers
protected:
display_server* const server;
window* const parent;
config cfg;
state state;
window* root;
unique_ptr<gfxsurface> gfx_surface;
display_server* const server; //!< the display server the window belongs to
window* const parent; //!< the parent window
config cfg; //!< the current configuration
state state; //!< the current state
window* root; //!< the nearest top-level window in the hierarchy
unique_ptr<gfxsurface> gfx_surface; //!< the corresponding graphics surface
};
///
/// \brief Interface resembling the API for a window of a display server
template<typename DisplayT>
class window_base : public window {
public:
///
/// \brief constructor
/// \param display the display server
/// \param conf the configuration
/// \param parent the parent window
window_base(display_server* display, const config& conf, window* parent)
: window(display, conf, parent) {
}
using display_t = DisplayT;
using display_t = DisplayT; //!< corresponding display server type
};
}

View File

@@ -25,16 +25,18 @@ namespace fennec
class linux_platform : public unix_platform {
public:
/// \brief constructor
linux_platform()
: unix_platform() {
}
void initialize() override;
void shutdown() override;
void initialize() override; //!< platform initialization
void shutdown() override; //!< platform shutdown
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(unix_platform) {
}
#endif
};
}

View File

@@ -37,17 +37,28 @@
namespace fennec
{
///
/// \brief wayland egl context
class wayland_eglcontext : public eglcontext {
public:
/// \brief constructor
/// \param display the display server
explicit wayland_eglcontext(display_server* display);
/// \brief destructor
~wayland_eglcontext();
/// \brief create a surface for a window
/// \param window the window
/// \returns a new surface for the window
gfxsurface* create_surface(window* window) override;
private:
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(eglcontext) {
wayland_server::ctx_registry::register_type<wayland_eglcontext>();
}
#endif
};
}

View File

@@ -38,11 +38,20 @@
namespace fennec
{
///
/// \brief wayland egl surface
class wayland_eglsurface : public eglsurface {
public:
/// \brief constructor
/// \param win the wayland window
/// \param ctx the egl context
wayland_eglsurface(wayland_window* win, eglcontext* ctx);
/// \brief destructor
~wayland_eglsurface();
/// \brief resize the surface
/// \param size the new size
void resize(const ivec2& size) override;
private:

View File

@@ -38,6 +38,7 @@
#include <fennec/platform/linux/wayland/libdecor/libdecor.h>
#endif
#ifndef FENNEC_DOXYGEN
// forward defs to avoid flooding global namespace
struct wl_display;
struct wl_shm;
@@ -47,6 +48,7 @@ struct wl_seat;
struct wp_viewporter;
struct xdg_wm_base;
#endif
namespace fennec
{
@@ -55,17 +57,26 @@ namespace fennec
/// \brief Class for handling the Wayland Display Server
class wayland_server : public display_server_base<wayland_server, wayland_window> {
public:
/// \brief constructor
/// \param p the platform
explicit wayland_server(fennec::platform* p);
/// \brief destructor
~wayland_server() override;
void connect() override;
void disconnect() override;
bool connected() const override;
void connect() override; //!< connect to wayland
void disconnect() override; //!< disconnect from wayland
bool connected() const override; //!< check if connected to wayland \returns \f$true\f$ if connected, \f$false\f$ otherwise
void dispatch() override;
void dispatch() override; //!< dispatch the current context
/// \brief create a window
/// \param conf the configuration
/// \param parent the parent window
/// \returns a new window with the provided configuration and parent
window* create_window(const window::config& conf, window* parent) override;
/// \returns the native wl_display handle
void* get_native_handle() override { return display; }
@@ -98,9 +109,11 @@ private:
static void _libdecor_on_error(struct libdecor*, libdecor_error error, const char* message);
#endif
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(display_server) {
display_server::register_type<wayland_server>(1);
}
#endif
friend class wayland_window;
};

View File

@@ -34,6 +34,7 @@
#include <fennec/platform/linux/wayland/fwd.h>
#include <fennec/platform/interface/window.h>
#ifndef FENNEC_DOXYGEN
struct wl_array;
struct wl_callback;
struct wl_output;
@@ -42,22 +43,39 @@ struct wl_surface;
struct xdg_surface;
struct xdg_toplevel;
#if FENNEC_HAS_LIBDECOR
struct libdecor_frame;
struct libdecor_configuration;
#endif
#endif
namespace fennec
{
///
/// \brief Class for handling a Wayland window
class wayland_window : public window_base<wayland_server> {
public:
/// \brief constructor
/// \param server the display server
/// \param cfg the configuration
/// \param parent the parent window
wayland_window(display_server* server, const config& cfg, window* parent);
/// \brief destructor
~wayland_window();
void initialize() override;
void shutdown() override;
void initialize() override; //!< initialize the window
void shutdown() override; //!< shutdown the window
/// \returns the native wl_surface handle
void* get_native_handle() override;
///
/// \brief sets a specific flag
/// \param flag the flag from `window::flag_`
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_flag(uint8_t flag, bool val) override;

View File

@@ -41,11 +41,17 @@
namespace fennec
{
/// \brief base egl context with platform-independent behaviour
class eglcontext : public glcontext {
public:
/// \brief constructor
/// \param display the corresponding display server
eglcontext(display_server* display);
/// \brief destructor
~eglcontext();
/// \returns \f$true\f$ if the context is valid, \f$false\f$ otherwise
bool is_valid() override;
private:
@@ -55,8 +61,10 @@ private:
EGLint _eglvmajor, _eglvminor, _eglctype;
cstring _extensions;
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(glcontext) {
}
#endif
friend class eglsurface;
};

View File

@@ -35,6 +35,9 @@
#include <EGL/egl.h>
#include <fennec/string/cstring.h>
/// \brief convert egl error to a readable string
/// \param err the error code
/// \returns the error string corresponding to \f$err\f$
inline fennec::cstring eglErrorString(EGLint err) {
switch (err) {
case EGL_SUCCESS: return "None";

View File

@@ -40,18 +40,22 @@
namespace fennec
{
/// \brief base egl surface with platform-independent behaviour
class eglsurface : public gfxsurface {
public:
/// \brief constructor
/// \param win the associated window
/// \param ctx the associated context
/// \param eglwindow the create egl window
eglsurface(fennec::window* win, eglcontext* ctx, void* eglwindow);
~eglsurface();
void make_current() override;
void swap() override;
void make_current() override; //!< makes this surface the current target of the context
void swap() override; //!< swaps the front and back buffers
protected:
void* _eglwindow;
EGLSurface _eglsurface;
void* _eglwindow; //!< the underlying handle to the window
EGLSurface _eglsurface; //!< the handle for the surface
};
} // fennec

View File

@@ -23,21 +23,38 @@
namespace fennec
{
/// \brief base unix platform for generic unix functionality
class unix_platform : public platform {
public:
///
/// \brief constructor
explicit unix_platform()
: platform() {
}
///
/// \brief shared object linker
/// \param file the name of the shared object to link
/// \returns a reference to the shared object
shared_object* load_object(const cstring& file) override;
///
/// \brief shared object release
/// \param obj the shared object to release
void unload_object(shared_object* obj) override;
///
/// \brief shared object symbol locator
/// \param obj the shared object to search
/// \param name the name of the symbol to search for
/// \returns a reference to the symbol
symbol find_symbol(shared_object* obj, const cstring& name) override;
private:
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(platform) {
}
#endif
};
}

View File

@@ -1,91 +0,0 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/window_manager.h>
#include <fennec/core/logger.h>
#include <fennec/platform/interface/platform.h>
#include <fennec/platform/interface/display_server.h>
#include <fennec/platform/interface/window.h>
namespace fennec {
window_manager::window_manager(platform* platform)
: _platform(platform) {
}
window_manager::~window_manager() {
shutdown();
}
void window_manager::initialize() {
if (_display) {
return;
}
// Get the list of registered display servers
display_server::entrylist_t display_servers = display_server::get_type_list();
// Find first valid server
while (not display_servers.empty()) {
display_server::entry it = display_servers.front();
display_servers.pop();
unique_ptr<display_server> server = unique_ptr(it.ctor(_platform));
server->connect();
if (server->connected()) {
logger::log(format("Selected {} for the display server.", server->get_type().name()));
_display = move(server);
break;
}
}
assertf(_display, "Failed to select a display server!");
_thread = thread::current();
logger::log(format("Initializing Window Manager on thread: {:#016x}.", _thread));
}
void window_manager::shutdown() {
if (not _display) {
return;
}
assertf(_thread == thread::current(), "Attempted to shutdown Window Manager on a different thread!");
// Cleanup Windows
for (auto& window : _windows) {
window->shutdown();
window.reset();
}
_windows.clear();
// Cleanup Display Server
_display->disconnect();
_display.reset();
}
void window_manager::dispatch() {
assertf(_thread == thread::current(), "Attempted to shutdown Window Manager on a different thread!");
_display->dispatch();
}
} // fennec

View File

@@ -41,6 +41,8 @@
namespace fennec
{
///
/// \brief class for handling display servers and windows
class window_manager {
// Definitions =========================================================================================================
private:
@@ -51,7 +53,13 @@ private:
// Constructors & Destructor ===========================================================================================
public:
///
/// \brief constructor
/// \param platform the platform
window_manager(platform* platform);
///
/// \brief destructor
~window_manager();
window_manager(const window_manager&) = delete;
@@ -59,9 +67,9 @@ public:
// Thread-Specific Functions ===========================================================================================
void initialize();
void shutdown();
void dispatch();
void initialize(); //!< initialize the window system
void shutdown(); //!< shutdown the window system
void dispatch(); //!< dispatch the commands to the system
// Thread-Safe Functions ===============================================================================================