Some window interface cleaning

This commit is contained in:
James Grogan 2022-11-11 10:35:41 +00:00
parent 1180e576fa
commit 02ebb9a54b
12 changed files with 169 additions and 141 deletions

View file

@ -1,12 +1,7 @@
#include "GuiApplication.h"
#include "Widget.h"
#ifdef __linux__
#include "XcbInterface.h"
#include "XcbKeyboard.h"
#else
#include "Win32UiInterface.h"
#endif
#include "UiInterfaceFactory.h"
#include "Window.h"
#include "TextElement.h"
#include "WindowManager.h"
@ -20,8 +15,6 @@
#include "HorizontalSpacer.h"
#include "FileLogger.h"
#include <iostream>
GuiApplication::GuiApplication()
: AbstractDesktopApp(),
mMainApplication(),
@ -81,32 +74,15 @@ void GuiApplication::Run()
auto mainWindow = mDesktopManager->GetWindowManager()->GetMainWindow();
SetUpWidget();
#ifdef __linux__
mDesktopManager->SetKeyboard(XcbKeyboard::Create());
bool useHardwareRendering = false;
XcbInterface window_interface;
window_interface.setUseHardwareRendering(useHardwareRendering);
window_interface.initialize(mDesktopManager.get());
window_interface.addWindow(mainWindow, mDesktopManager.get());
window_interface.showWindow(mainWindow);
if (useHardwareRendering)
{
window_interface.CreateOpenGlDrawable(mainWindow);
}
window_interface.loop(mDesktopManager.get());
window_interface.shutDown();
#else
mDesktopManager->SetKeyboard(Keyboard::Create());
MLOG_INFO("Creating Window Interface");
Win32UIInterface window_interface;
window_interface.AddWindow(mainWindow, mDesktopManager.get());
auto window_interface = UiInterfaceFactory::create(mDesktopManager.get());
window_interface.ShowWindow(mainWindow);
window_interface->initialize();
window_interface->addWindow(mainWindow);
window_interface->showWindow(mainWindow);
window_interface->loop();
window_interface->shutDown();
window_interface.Loop(mDesktopManager.get());
window_interface.ShutDown();
MLOG_INFO("Window Interface Shut Down");
#endif
}

View file

@ -34,7 +34,7 @@ if(UNIX)
list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_EXTENSIONS_INCLUDE_DIR})
list(APPEND platform_INCLUDES
ui_interfaces/wayland/WaylandWindowInterface.cpp
ui_interfaces/wayland/WaylandInterface.cpp
ui_interfaces/wayland/WaylandSurface.cpp
ui_interfaces/wayland/WaylandBuffer.cpp
ui_interfaces/wayland/WaylandPointerInterface.cpp
@ -72,6 +72,7 @@ endif()
set(HAS_WAYLAND ${_HAS_WAYLAND} CACHE BOOL "Can build with Wayland")
list(APPEND windows_LIB_INCLUDES
ui_interfaces/UiInterfaceFactory.cpp
managers/WindowManager.cpp
managers/DesktopManager.cpp
managers/EventManager.cpp)

View file

@ -1,6 +1,5 @@
#pragma once
class DesktopManager;
namespace mt
{
class Window;
@ -11,15 +10,15 @@ class AbstractUIInterface
public:
virtual ~AbstractUIInterface() = default;
virtual void initialize(DesktopManager* desktopManager) = 0;
virtual void initialize() = 0;
virtual void loop(DesktopManager* desktopManager) = 0;
virtual void loop() = 0;
virtual void shutDown() = 0;
virtual void showWindow(mt::Window* window) = 0;
virtual void addWindow(mt::Window* window, DesktopManager* desktopManager) = 0;
virtual void addWindow(mt::Window* window) = 0;
void setUseHardwareRendering(bool useHardware)
{

View file

@ -0,0 +1,24 @@
#include "UiInterfaceFactory.h"
#ifdef __linux__
#include "XcbInterface.h"
#include "WaylandInterface.h"
#else
#include "Win32UiInterface.h"
#endif
std::unique_ptr<AbstractUIInterface> UiInterfaceFactory::create(DesktopManager* desktopManager, Backend backend)
{
#ifdef __linux__
if (backend == Backend::UNSET || backend == Backend::X11)
{
return std::make_unique<XcbInterface>(desktopManager);
}
else
{
return std::make_unique<WaylandInterface>(desktopManager);
}
#else
return std::make_unique<Win32UiInterface>();
#endif
}

View file

@ -0,0 +1,20 @@
#pragma once
#include "AbstractUiInterface.h"
#include <memory>
class DesktopManager;
class UiInterfaceFactory
{
public:
enum class Backend
{
UNSET,
X11,
WAYLAND
};
static std::unique_ptr<AbstractUIInterface> create(DesktopManager* desktopManager, Backend backend = Backend::UNSET);
};

View file

@ -1,4 +1,4 @@
#include "WaylandWindowInterface.h"
#include "WaylandInterface.h"
#include "FileLogger.h"
#include "WaylandSurface.h"
@ -9,10 +9,10 @@
#include <cstring>
#include <sstream>
void WaylandWindowInterface::registryHandleGlobalEvent(void *data, struct wl_registry *registry,
void WaylandInterface::registryHandleGlobalEvent(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version)
{
auto thisClass = static_cast<WaylandWindowInterface*>(data);
auto thisClass = static_cast<WaylandInterface*>(data);
std::stringstream sstrm;
sstrm << "interface: " << interface << " version " << version << " name " << name;
@ -36,25 +36,26 @@ void WaylandWindowInterface::registryHandleGlobalEvent(void *data, struct wl_reg
}
}
void WaylandWindowInterface::registryHandleGlobalRemoveEvent(void *data, struct wl_registry *registry, uint32_t name)
void WaylandInterface::registryHandleGlobalRemoveEvent(void *data, struct wl_registry *registry, uint32_t name)
{
}
WaylandWindowInterface::WaylandWindowInterface()
: mBuffer(std::make_shared<WaylandBuffer>())
WaylandInterface::WaylandInterface(DesktopManager* desktopManager)
: mDesktopManager(desktopManager),
mBuffer(std::make_shared<WaylandBuffer>())
{
mRegistryListener.global = registryHandleGlobalEvent;
mRegistryListener.global_remove = registryHandleGlobalRemoveEvent;
}
WaylandWindowInterface::~WaylandWindowInterface()
WaylandInterface::~WaylandInterface()
{
}
void WaylandWindowInterface::initialize(DesktopManager* desktopManager)
void WaylandInterface::initialize()
{
mDisplay = wl_display_connect(nullptr);
@ -81,45 +82,45 @@ void WaylandWindowInterface::initialize(DesktopManager* desktopManager)
}
}
void WaylandWindowInterface::setSeat(wl_seat* seat)
void WaylandInterface::setSeat(wl_seat* seat)
{
mSeatInterface = std::make_unique<WaylandSeatInterface>(seat);
}
void WaylandWindowInterface::setXdgBase(xdg_wm_base* xdg_base)
void WaylandInterface::setXdgBase(xdg_wm_base* xdg_base)
{
mXdgBase = xdg_base;
auto xdg_ping_handler = [](void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
{
auto thisClass = static_cast<WaylandWindowInterface*>(data);
auto thisClass = static_cast<WaylandInterface*>(data);
thisClass->doXdgPong(serial);
};
mXdgBaseListener.ping = xdg_ping_handler;
xdg_wm_base_add_listener(mXdgBase, &mXdgBaseListener, this);
}
void WaylandWindowInterface::setCompositor(wl_compositor* compositor)
void WaylandInterface::setCompositor(wl_compositor* compositor)
{
mCompositor = compositor;
}
void WaylandWindowInterface::setSharedMemory(wl_shm* shared_memory)
void WaylandInterface::setSharedMemory(wl_shm* shared_memory)
{
mBuffer->setSharedMemory(shared_memory);
}
void WaylandWindowInterface::doXdgPong(uint32_t serial)
void WaylandInterface::doXdgPong(uint32_t serial)
{
xdg_wm_base_pong(mXdgBase, serial);
}
void WaylandWindowInterface::addWindow(mt::Window* window, DesktopManager* desktopManager)
void WaylandInterface::addWindow(mt::Window* window)
{
auto surface = std::make_unique<WaylandSurface>(window);
mSurfaces.push_back(std::move(surface));
}
void WaylandWindowInterface::showWindow(mt::Window* window)
void WaylandInterface::showWindow(mt::Window* window)
{
if (mSurfaces.empty())
{
@ -129,7 +130,7 @@ void WaylandWindowInterface::showWindow(mt::Window* window)
mSurfaces[0]->initialize(mCompositor, mXdgBase, mBuffer, mEglInterface.get());
}
void WaylandWindowInterface::shutDown()
void WaylandInterface::shutDown()
{
if (mDisplay)
{
@ -137,7 +138,7 @@ void WaylandWindowInterface::shutDown()
}
}
void WaylandWindowInterface::loop(DesktopManager* desktopManager)
void WaylandInterface::loop()
{
while (wl_display_dispatch(mDisplay) != -1)
{

View file

@ -14,22 +14,23 @@ class WaylandSurface;
class WaylandBuffer;
class WaylandSeatInterface;
class WaylandEglInterface;
class DesktopManager;
class WaylandWindowInterface : public AbstractUIInterface
class WaylandInterface : public AbstractUIInterface
{
public:
WaylandWindowInterface();
WaylandInterface(DesktopManager* desktopManager);
~WaylandWindowInterface();
~WaylandInterface();
void loop(DesktopManager* desktopManager) override;
void loop() override;
void addWindow(mt::Window* window, DesktopManager* desktopManager) override;
void addWindow(mt::Window* window) override;
void showWindow(mt::Window* window) override;
void initialize(DesktopManager* desktopManager) override;
void initialize() override;
void shutDown() override;
@ -47,6 +48,8 @@ private:
void setXdgBase(xdg_wm_base* xdg_base);
DesktopManager* mDesktopManager{nullptr};
wl_display* mDisplay{nullptr};
wl_compositor* mCompositor{nullptr};
wl_registry_listener mRegistryListener;

View file

@ -20,8 +20,9 @@
#include "FileLogger.h"
XcbInterface::XcbInterface()
: mConnection(nullptr),
XcbInterface::XcbInterface(DesktopManager* desktopManager)
: mDesktopManager(desktopManager),
mConnection(nullptr),
mX11Display(),
mGlxInterface(),
mXcbEventInterface(XcbEventInterface::Create()),
@ -35,18 +36,20 @@ XcbInterface::~XcbInterface()
}
void XcbInterface::initialize(DesktopManager* desktopManager)
void XcbInterface::initialize()
{
Connect();
UpdateScreen(desktopManager);
CreateGraphicsContext(desktopManager);
connect();
updateScreen();
createGraphicsContext();
if (mUseHardwareRendering)
{
InitializeOpenGl();
}
initializeOpenGl();
}
void XcbInterface::Connect()
mDesktopManager->SetKeyboard(XcbKeyboard::Create());
}
void XcbInterface::connect()
{
if (mUseHardwareRendering)
{
@ -71,7 +74,7 @@ void XcbInterface::Connect()
}
}
void XcbInterface::UpdateScreen(DesktopManager* desktopManager)
void XcbInterface::updateScreen()
{
if (!mConnection)
{
@ -91,40 +94,43 @@ void XcbInterface::UpdateScreen(DesktopManager* desktopManager)
auto xcb_screen = XcbScreen::Create(screen_iter.data);
auto screen = mt::Screen::Create();
screen->SetPlatformScreen(std::move(xcb_screen));
desktopManager->AddScreen(std::move(screen));
mDesktopManager->AddScreen(std::move(screen));
}
void XcbInterface::InitializeOpenGl()
void XcbInterface::initializeOpenGl()
{
mGlxInterface = GlxInterface::Create();
const auto default_screen = DefaultScreen(mX11Display);
mGlxInterface->SetupContext(mX11Display, default_screen);
}
void XcbInterface::CreateOpenGlDrawable(mt::Window* window)
void XcbInterface::createOpenGlDrawable(mt::Window* window)
{
if (!mUseHardwareRendering or !window or !window->GetPlatformWindow())
{
return;
}
auto xcb_window = dynamic_cast<XcbWindow*>(window->GetPlatformWindow());
if (!xcb_window)
{
return;
}
if (!mGlxInterface->SetupWindow(mX11Display, xcb_window->GetHandle()))
{
MLOG_ERROR("Failed to set up OpenGL Drawable");
xcb_destroy_window(mConnection, xcb_window->GetHandle());
}
}
void XcbInterface::CreateGraphicsContext(DesktopManager* desktopManager)
void XcbInterface::createGraphicsContext()
{
if (!mConnection || desktopManager->GetDefaultScreen())
if (!mConnection || mDesktopManager->GetDefaultScreen())
{
return;
}
auto xcb_screen = dynamic_cast<XcbScreen*>(desktopManager->GetDefaultScreen()->GetPlatformScreen());
auto xcb_screen = dynamic_cast<XcbScreen*>(mDesktopManager->GetDefaultScreen()->GetPlatformScreen());
if (!xcb_screen)
{
return;
@ -138,7 +144,7 @@ void XcbInterface::CreateGraphicsContext(DesktopManager* desktopManager)
xcb_screen->SetGraphicsContext(gc);
}
void XcbInterface::MapWindow(mt::Window* window)
void XcbInterface::mapWindow(mt::Window* window)
{
mXcbWindowInterface->Map(window, mConnection);
}
@ -146,9 +152,14 @@ void XcbInterface::MapWindow(mt::Window* window)
void XcbInterface::showWindow(mt::Window* window)
{
mXcbWindowInterface->Show(window, mConnection);
if (mUseHardwareRendering)
{
createOpenGlDrawable(window);
}
}
uint32_t XcbInterface::GetEventMask()
uint32_t XcbInterface::getEventMask()
{
return XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS |
@ -156,23 +167,24 @@ uint32_t XcbInterface::GetEventMask()
XCB_EVENT_MASK_EXPOSURE;
}
void XcbInterface::addWindow(mt::Window* window, DesktopManager* desktopManager)
void XcbInterface::addWindow(mt::Window* window)
{
auto screen = desktopManager->GetDefaultScreen();
mXcbWindowInterface->Add(window, mConnection, screen, GetEventMask());
auto screen = mDesktopManager->GetDefaultScreen();
mXcbWindowInterface->Add(window, mConnection, screen, getEventMask());
}
void XcbInterface::onPaint(DesktopManager* desktopManager)
void XcbInterface::onPaint()
{
desktopManager->OnUiEvent(PaintEvent::Create());
auto mainWindow = desktopManager->GetWindowManager()->GetMainWindow();
auto defaultScreen = desktopManager->GetDefaultScreen();
mDesktopManager->OnUiEvent(PaintEvent::Create());
auto mainWindow = mDesktopManager->GetWindowManager()->GetMainWindow();
auto defaultScreen = mDesktopManager->GetDefaultScreen();
auto xcb_screen = dynamic_cast<XcbScreen*>(defaultScreen->GetPlatformScreen());
mXcbWindowInterface->Paint(mainWindow, mConnection,
xcb_screen->GetNativeScreen(), xcb_screen->GetGraphicsContext());
}
void XcbInterface::OnExposeEvent(xcb_expose_event_t* event, DesktopManager* desktopManager)
void XcbInterface::onExposeEvent(xcb_expose_event_t* event)
{
// Update the window
if (mUseHardwareRendering)
@ -184,12 +196,12 @@ void XcbInterface::OnExposeEvent(xcb_expose_event_t* event, DesktopManager* desk
{
//auto window = mWindows[event->window];
//window->SetSize(event->width, event->height);
onPaint(desktopManager);
onPaint();
xcb_flush(mConnection);
}
}
void XcbInterface::loop(DesktopManager* desktopManager)
void XcbInterface::loop()
{
if (!mConnection)
{
@ -202,44 +214,44 @@ void XcbInterface::loop(DesktopManager* desktopManager)
{
case XCB_EXPOSE:{
auto expose_event = reinterpret_cast<xcb_expose_event_t*>(event);
OnExposeEvent(expose_event, desktopManager);
onExposeEvent(expose_event);
break;
}
case XCB_KEY_PRESS: {
auto kp = reinterpret_cast<xcb_key_press_event_t*>(event);
auto ui_event = mXcbEventInterface->ConvertKeyPress(kp, desktopManager->GetKeyboard());
desktopManager->OnUiEvent(std::move(ui_event));
auto ui_event = mXcbEventInterface->ConvertKeyPress(kp, mDesktopManager->GetKeyboard());
mDesktopManager->OnUiEvent(std::move(ui_event));
break;
}
case XCB_KEY_RELEASE: {
auto kr = reinterpret_cast<xcb_key_release_event_t*>(event);
auto ui_event = mXcbEventInterface->ConvertKeyRelease(kr, desktopManager->GetKeyboard());
desktopManager->OnUiEvent(std::move(ui_event));
auto ui_event = mXcbEventInterface->ConvertKeyRelease(kr, mDesktopManager->GetKeyboard());
mDesktopManager->OnUiEvent(std::move(ui_event));
break;
}
case XCB_BUTTON_PRESS: {
auto press = reinterpret_cast<xcb_button_press_event_t*>(event);
auto ui_event = mXcbEventInterface->ConvertButtonPress(press);
desktopManager->OnUiEvent(std::move(ui_event));
mDesktopManager->OnUiEvent(std::move(ui_event));
break;
}
case XCB_BUTTON_RELEASE: {
auto release = reinterpret_cast<xcb_button_release_event_t*>(event);
auto ui_event = mXcbEventInterface->ConvertButtonRelease(release);
desktopManager->OnUiEvent(std::move(ui_event));
mDesktopManager->OnUiEvent(std::move(ui_event));
break;
}
default:
/* Unknown event type, ignore it */
break;
}
onEventsDispatched(desktopManager);
onEventsDispatched();
free(event);
}
OnLoopCompleted(desktopManager);
onLoopCompleted();
}
void XcbInterface::OnLoopCompleted(DesktopManager* desktopManagers)
void XcbInterface::onLoopCompleted()
{
if (mUseHardwareRendering)
{
@ -248,12 +260,12 @@ void XcbInterface::OnLoopCompleted(DesktopManager* desktopManagers)
}
}
void XcbInterface::onEventsDispatched(DesktopManager* desktopManager)
void XcbInterface::onEventsDispatched()
{
if (desktopManager->IsModified())
if (mDesktopManager->IsModified())
{
desktopManager->SetIsModified(false);
auto mainWindow = desktopManager->GetWindowManager()->GetMainWindow();
mDesktopManager->SetIsModified(false);
auto mainWindow = mDesktopManager->GetWindowManager()->GetMainWindow();
mXcbWindowInterface->Clear(mainWindow, mConnection);
}
}

View file

@ -3,7 +3,6 @@
#include "AbstractUiInterface.h"
#include <memory>
#include <map>
class DesktopManager;
class GlxInterface;
@ -27,43 +26,38 @@ namespace mt
class XcbInterface : public AbstractUIInterface
{
public:
XcbInterface();
XcbInterface(DesktopManager* desktopManager);
~XcbInterface();
void initialize(DesktopManager* desktopManager) override;
void initialize() override;
void loop(DesktopManager* desktopManager) override;
void loop() override;
void shutDown() override;
void showWindow(mt::Window* window) override;
void addWindow(mt::Window* window, DesktopManager* desktopManager) override;
void CreateOpenGlDrawable(mt::Window* window);
void addWindow(mt::Window* window) override;
private:
void onPaint(DesktopManager* desktopManager);
void onPaint();
void onEventsDispatched();
void onLoopCompleted();
void onExposeEvent(xcb_expose_event_t* event);
void InitializeOpenGl();
void initializeOpenGl();
void createGraphicsContext();
void createOpenGlDrawable(mt::Window* window);
void Connect();
void connect();
void updateScreen();
void mapWindow(mt::Window* window);
void UpdateScreen(DesktopManager* desktopManager);
void OnExposeEvent(xcb_expose_event_t* event, DesktopManager* desktopManager);
uint32_t GetEventMask();
void MapWindow(mt::Window* window);
void CreateGraphicsContext(DesktopManager* desktopManager);
void onEventsDispatched(DesktopManager* desktopManager);
void OnLoopCompleted(DesktopManager* desktopManagers);
uint32_t getEventMask();
private:
DesktopManager* mDesktopManager{nullptr};
xcb_connection_t* mConnection;
_XDisplay* mX11Display;
GlxInterfacePtr mGlxInterface;

View file

@ -18,14 +18,12 @@ public:
auto mainWindow = desktopManager->GetWindowManager()->GetMainWindow();
mainWindow->SetSize(800, 600);
bool useOpenGl = true;
XcbInterface window_interface;
XcbInterface window_interface(desktopManager.get());
window_interface.setUseHardwareRendering(true);
window_interface.initialize(desktopManager.get());
window_interface.addWindow(mainWindow, desktopManager.get());
window_interface.initialize();
window_interface.addWindow(mainWindow);
window_interface.showWindow(mainWindow);
window_interface.CreateOpenGlDrawable(mainWindow);
window_interface.loop(desktopManager.get());
window_interface.loop();
window_interface.shutDown();
return true;

View file

@ -1,4 +1,4 @@
#include "WaylandWindowInterface.h"
#include "WaylandInterface.h"
#include "Window.h"
#include "FileLogger.h"
@ -9,20 +9,20 @@ int main()
{
FileLogger::GetInstance().Open();
auto desktop_manager = std::make_unique<DesktopManager>();
auto desktop_manager = DesktopManager::Create();
WaylandWindowInterface window_interface;
window_interface.setUseHardwareRendering(true);
window_interface.initialize(desktop_manager.get());
auto window = mt::Window::Create();
auto window = desktop_manager->GetWindowManager()->GetMainWindow();
window->SetSize(800, 600);
window_interface.addWindow(window.get(), desktop_manager.get());
WaylandInterface window_interface(desktop_manager.get());
window_interface.setUseHardwareRendering(true);
window_interface.initialize();
window_interface.showWindow(window.get());
window_interface.addWindow(window);
window_interface.loop(desktop_manager.get());
window_interface.showWindow(window);
window_interface.loop();
window_interface.shutDown();
return 0;