- More documentation
This commit is contained in:
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 ===============================================================================================
|
||||
|
||||
Reference in New Issue
Block a user