Cleaning window managers for consistency.

This commit is contained in:
James Grogan 2022-11-12 15:34:54 +00:00
parent 5d984aa61d
commit 392a2b7889
28 changed files with 452 additions and 325 deletions

View file

@ -45,13 +45,8 @@ void GuiApplication::run()
MLOG_INFO("Creating Window Interface");
mUiInterface = UiInterfaceFactory::create(mDesktopManager.get(), mUiInterfaceBackend);
mUiInterface->initialize();
mUiInterface->addWindow(mainWindow);
mUiInterface->showWindow(mainWindow);
mUiInterface->loop();
mUiInterface->shutDown();
MLOG_INFO("Window Interface Shut Down");
mMainApplication->ShutDown();

View file

@ -26,11 +26,11 @@ public:
virtual ~IPlatformWindow() = default;
virtual void show() const = 0;
virtual void show() = 0;
virtual void map() const = 0;
virtual void map() = 0;
virtual void clear() const = 0;
virtual void clear() = 0;
protected:
mt::Window* mWindow{nullptr};
};

View file

@ -35,6 +35,12 @@ std::vector<VisualLayer*> Window::GetLayers()
return mWidget->getLayers();
}
void Window::clearPlatformWindow()
{
mPlatformWindow.reset();
}
void Window::OnMouseEvent(const MouseEvent* event)
{
mWidget->onMouseEvent(event);

View file

@ -62,6 +62,8 @@ public:
void clear();
void clearPlatformWindow();
private:
int mHandle {-1};
WidgetUPtr mWidget {nullptr};

View file

@ -15,7 +15,8 @@ if(UNIX)
ui_interfaces/x11/XcbLayerInterface.cpp
ui_interfaces/x11/XcbTextInterface.cpp
ui_interfaces/x11/XcbKeyboard.cpp
ui_interfaces/x11/GlxInterface.cpp
ui_interfaces/x11/XcbGlInterface.cpp
ui_interfaces/x11/XcbGlWindowInterface.cpp
)
list(APPEND platform_LIBS ${X11_LIBRARIES} ${X11_xcb_LIB} ${X11_X11_xcb_LIB} ${X11_xkbcommon_LIB} libxcb-image.so)
list(APPEND X11_INCLUDE_DIRS ${X11_xkbcommon_INCLUDE_PATH})

View file

@ -36,6 +36,14 @@ void WindowManager::AddWindow(WindowUPtr window)
mWindows.push_back(std::move(window));
}
void WindowManager::clearPlatformWindows()
{
for (auto& window : mWindows)
{
window->clearPlatformWindow();
}
}
mt::Window* WindowManager::GetMainWindow() const
{
if(mWindows.size()>0)

View file

@ -27,6 +27,18 @@ public:
void OnKeyboardEvent(const KeyboardEvent* event);
void clearPlatformWindows();
std::size_t getNumWindows() const
{
return mWindows.size();
}
mt::Window* getWindow(std::size_t idx) const
{
return mWindows[idx].get();
}
private:
std::vector<WindowUPtr> mWindows;
};

View file

@ -19,22 +19,18 @@ public:
virtual ~AbstractUIInterface() = default;
virtual void initialize() = 0;
virtual void loop() = 0;
virtual void shutDown() = 0;
virtual void showWindow(mt::Window* window) = 0;
virtual void addWindow(mt::Window* window) = 0;
void setUseHardwareRendering(bool useHardware)
{
mUseHardwareRendering = useHardware;
}
protected:
virtual void initialize() = 0;
virtual void shutDown() = 0;
virtual void initializeHardwareRendering() {};
DesktopManager* mDesktopManager{nullptr};
bool mUseHardwareRendering{false};
};

View file

@ -4,6 +4,11 @@
#include <wayland-egl.h>
WaylandEglInterface::WaylandEglInterface(wl_display* display)
{
initialize(display);
}
void WaylandEglInterface::initialize(wl_display* display)
{
mEglDisplay = eglGetDisplay((EGLNativeDisplayType) display);

View file

@ -7,8 +7,7 @@ struct wl_display;
class WaylandEglInterface
{
public:
void initialize(wl_display* display);
WaylandEglInterface(wl_display* display);
EGLDisplay getDisplay() const;
@ -17,6 +16,8 @@ public:
EGLContext getContext() const;
private:
void initialize(wl_display* display);
EGLDisplay mEglDisplay;
EGLConfig mEglConfig;
EGLContext mEglContext;

View file

@ -19,6 +19,6 @@ public:
private:
wl_egl_window* mEglWindow{nullptr};
EGLSurface mEglSurface;
EGLSurface mEglSurface{nullptr};
WaylandEglInterface* mEglInterface;
};

View file

@ -1,6 +1,9 @@
#include "WaylandInterface.h"
#include "FileLogger.h"
#include "DesktopManager.h"
#include "WindowManager.h"
#include "WaylandSurface.h"
#include "WaylandBuffer.h"
#include "WaylandSeatInterface.h"
@ -13,10 +16,9 @@ void WaylandInterface::registryHandleGlobalEvent(void *data, struct wl_registry
uint32_t name, const char *interface, uint32_t version)
{
auto thisClass = static_cast<WaylandInterface*>(data);
std::stringstream sstrm;
sstrm << "interface: " << interface << " version " << version << " name " << name;
MLOG_INFO(sstrm.str());
//MLOG_INFO(sstrm.str());
if (strcmp(interface, wl_compositor_interface.name) == 0)
{
@ -51,7 +53,7 @@ WaylandInterface::WaylandInterface(DesktopManager* desktopManager, bool useHardw
WaylandInterface::~WaylandInterface()
{
shutDown();
}
void WaylandInterface::initialize()
@ -76,9 +78,21 @@ void WaylandInterface::initialize()
if (mUseHardwareRendering)
{
mEglInterface = std::make_unique<WaylandEglInterface>();
mEglInterface->initialize(mDisplay);
initializeHardwareRendering();
}
const auto num_windows = mDesktopManager->GetWindowManager()->getNumWindows();
for(std::size_t idx=0; idx< num_windows; idx++)
{
addWindow(mDesktopManager->GetWindowManager()->getWindow(idx));
}
mDesktopManager->GetWindowManager()->GetMainWindow()->show();
}
void WaylandInterface::initializeHardwareRendering()
{
mEglInterface = std::make_unique<WaylandEglInterface>(mDisplay);
}
void WaylandInterface::setSeat(wl_seat* seat)
@ -115,18 +129,12 @@ void WaylandInterface::doXdgPong(uint32_t serial)
void WaylandInterface::addWindow(mt::Window* window)
{
auto surface = std::make_unique<WaylandSurface>(window);
mSurfaces.push_back(std::move(surface));
WaylandSurface::add(window, mCompositor, mXdgBase, mBuffer, mEglInterface.get());
}
void WaylandInterface::showWindow(mt::Window* window)
{
if (mSurfaces.empty())
{
return;
}
mSurfaces[0]->initialize(mCompositor, mXdgBase, mBuffer, mEglInterface.get());
window->show();
}
void WaylandInterface::shutDown()
@ -139,6 +147,8 @@ void WaylandInterface::shutDown()
void WaylandInterface::loop()
{
initialize();
while (wl_display_dispatch(mDisplay) != -1)
{
/* This space deliberately left blank */

View file

@ -10,7 +10,6 @@
#include <vector>
#include <memory>
class WaylandSurface;
class WaylandBuffer;
class WaylandSeatInterface;
class WaylandEglInterface;
@ -29,11 +28,13 @@ public:
void showWindow(mt::Window* window) override;
private:
void initialize() override;
void initializeHardwareRendering() override;
void shutDown() override;
private:
static void registryHandleGlobalEvent(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version);
static void registryHandleGlobalRemoveEvent(void *data, struct wl_registry *registry, uint32_t name);
@ -54,7 +55,6 @@ private:
xdg_wm_base* mXdgBase{nullptr};
xdg_wm_base_listener mXdgBaseListener;
std::vector<std::unique_ptr<WaylandSurface> > mSurfaces;
std::shared_ptr<WaylandBuffer> mBuffer;
std::unique_ptr<WaylandSeatInterface> mSeatInterface;
std::unique_ptr<WaylandEglInterface> mEglInterface;

View file

@ -3,10 +3,22 @@
#include "WaylandEglWindowInterface.h"
#include "ImagePrimitives.h"
WaylandSurface::WaylandSurface(mt::Window* window)
: IPlatformWindow(window)
void WaylandSurface::add(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer, WaylandEglInterface* eglInterface)
{
auto wayland_window = std::make_unique<WaylandSurface>(window, compositor, xdg_wm_base, buffer, eglInterface);
window->SetPlatformWindow(std::move(wayland_window));
}
WaylandSurface::WaylandSurface(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer, WaylandEglInterface* eglInterface)
: IPlatformWindow(window),
mCompositor(compositor),
mXdgWmBase(xdg_wm_base),
mBuffer(buffer)
{
if (eglInterface)
{
mEglWindowInterface = std::make_unique<WaylandEglWindowInterface>(eglInterface);
}
}
WaylandSurface::~WaylandSurface()
@ -14,16 +26,28 @@ WaylandSurface::~WaylandSurface()
}
void WaylandSurface::initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer, WaylandEglInterface* eglInterface)
void WaylandSurface::show()
{
mBuffer = buffer;
if (eglInterface)
{
mEglWindowInterface = std::make_unique<WaylandEglWindowInterface>(eglInterface);
map();
}
mSurface = wl_compositor_create_surface(compositor);
mXdgSurface = xdg_wm_base_get_xdg_surface(xdg_wm_base, mSurface);
void WaylandSurface::clear()
{
}
void WaylandSurface::map()
{
if (!mSurface)
{
initialize();
}
}
void WaylandSurface::initialize()
{
mSurface = wl_compositor_create_surface(mCompositor);
mXdgSurface = xdg_wm_base_get_xdg_surface(mXdgWmBase, mSurface);
auto xdg_surface_configure = [](void *data, struct xdg_surface *xdg_surface, uint32_t serial)
{
@ -37,7 +61,7 @@ void WaylandSurface::initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_b
mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface);
xdg_toplevel_set_title(mXdgTopLevel, "Example client");
auto region = wl_compositor_create_region(compositor);
auto region = wl_compositor_create_region(mCompositor);
wl_region_add(region, 0, 0, mWindow->GetWidth(), mWindow->GetHeight());
wl_surface_set_opaque_region(mSurface, region);
@ -47,25 +71,34 @@ void WaylandSurface::initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_b
void WaylandSurface::onConfigure(xdg_surface *xdg_surface, uint32_t serial)
{
xdg_surface_ack_configure(xdg_surface, serial);
paint(nullptr);
}
void WaylandSurface::paint(mt::Screen* screen)
{
if (mEglWindowInterface)
{
paintHardware();
}
else
{
paintSoftware();
}
}
void WaylandSurface::paintHardware()
{
mEglWindowInterface->initialize(mSurface, mWindow->GetWidth(), mWindow->GetHeight());
mEglWindowInterface->draw();
}
else
void WaylandSurface::paintSoftware()
{
auto buffer = drawFrame();
wl_surface_attach(mSurface, buffer, 0, 0);
//wl_surface_damage(mSurface, 0, 0, UINT32_MAX, UINT32_MAX);
wl_surface_commit(mSurface);
}
}
wl_buffer* WaylandSurface::drawFrame()
{

View file

@ -18,46 +18,45 @@ class WaylandEglWindowInterface;
class WaylandSurface : public IPlatformWindow
{
public:
WaylandSurface(mt::Window* window);
static void add(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer, WaylandEglInterface* eglInterface);
WaylandSurface(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer, WaylandEglInterface* eglInterface);
~WaylandSurface();
void initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr<WaylandBuffer> buffer, WaylandEglInterface* eglInterface);
void onConfigure(xdg_surface *xdg_surface, uint32_t serial);
void show();
void map();
void clear();
private:
void initialize();
void paint(mt::Screen* screen) override;
void paintHardware();
void paintSoftware();
wl_buffer* drawFrame();
void show() const
{
map();
}
void map() const
{
}
void clear() const
{
}
private:
void paint(mt::Screen* screen) override;
mt::Window* mWindow{nullptr};
wl_compositor* mCompositor{nullptr};
xdg_wm_base* mXdgWmBase{nullptr};
std::shared_ptr<WaylandBuffer> mBuffer;
std::unique_ptr<WaylandEglWindowInterface> mEglWindowInterface;
wl_surface* mSurface{nullptr};
xdg_surface* mXdgSurface{nullptr};
xdg_surface_listener mXdgSurfaceListener{nullptr};
xdg_surface_listener mXdgSurfaceListener;
xdg_toplevel* mXdgTopLevel{nullptr};
std::shared_ptr<WaylandBuffer> mBuffer;
std::unique_ptr<WaylandEglWindowInterface> mEglWindowInterface{nullptr};
};
using WaylandSurfacePtr = std::unique_ptr<WaylandSurface>;

View file

@ -1,106 +0,0 @@
#include "GlxInterface.h"
#include "OpenGlInterface.h"
#include "FileLogger.h"
#include <GL/gl.h>
GlxInterface::GlxInterface()
: mContext(),
mDrawable(),
mWindow(),
mConfig()
{
}
static int visual_attribs[] =
{
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, True,
//GLX_SAMPLE_BUFFERS , 1,
//GLX_SAMPLES , 4,
None
};
std::unique_ptr<GlxInterface> GlxInterface::Create()
{
return std::make_unique<GlxInterface>();
}
void GlxInterface::SetupContext(Display* display, int default_screen)
{
/* Query framebuffer configurations that match visual_attribs */
int num_fb_configs = 0;
GLXFBConfig* fb_configs = glXChooseFBConfig(display, default_screen, visual_attribs, &num_fb_configs);
if (!fb_configs || num_fb_configs == 0)
{
MLOG_ERROR("glXGetFBConfigs failed");
return;
}
/* Select first framebuffer config and query visualID */
int visualID = 0;
mConfig = fb_configs[0];
glXGetFBConfigAttrib(display, mConfig, GLX_VISUAL_ID, &visualID);
/* Create OpenGL context */
mContext = glXCreateNewContext(display, mConfig, GLX_RGBA_TYPE, 0, True);
if (!mContext)
{
MLOG_ERROR("glXCreateNewContext failed");
return;
}
}
void GlxInterface::SwapBuffers(Display* display)
{
glXSwapBuffers(display, mDrawable);
}
void GlxInterface::Draw()
{
OpenGlInterface::draw();
}
bool GlxInterface::SetupWindow(Display* display, xcb_window_t window)
{
/* Create GLX Window */
mWindow = glXCreateWindow(display, mConfig, window, 0);
if (!mWindow)
{
glXDestroyContext(display, mContext);
MLOG_ERROR("glXCreateWindow failed");
return false;
}
mDrawable = mWindow;
/* make OpenGL context current */
if (!glXMakeContextCurrent(display, mDrawable, mDrawable, mContext))
{
glXDestroyContext(display, mContext);
MLOG_ERROR("glXMakeContextCurrent failed");
return false;
}
return true;
}
void GlxInterface::DestroyWindow(Display* display)
{
glXDestroyWindow(display, mWindow);
}
void GlxInterface::DestroyContext(Display* display)
{
glXDestroyContext(display, mContext);
}

View file

@ -1,33 +0,0 @@
#pragma once
#include <GL/glx.h>
#include <xcb/xcb.h>
#include <memory>
class GlxInterface
{
public:
GlxInterface();
static std::unique_ptr<GlxInterface> Create();
void SetupContext(Display* display, int default_screen);
bool SetupWindow(Display* display, xcb_window_t window);
void DestroyWindow(Display* display);
void DestroyContext(Display* display);
void SwapBuffers(Display* display);
void Draw();
private:
GLXContext mContext;
GLXDrawable mDrawable;
GLXWindow mWindow;
GLXFBConfig mConfig;
};
using GlxInterfacePtr = std::unique_ptr<GlxInterface>;

View file

@ -0,0 +1,71 @@
#include "XcbGlInterface.h"
#include "FileLogger.h"
#include <GL/gl.h>
XcbGlInterface::XcbGlInterface(Display* display, int default_screen)
: mDisplay(display),
mContext(),
mConfig()
{
setupContext(default_screen);
}
XcbGlInterface::~XcbGlInterface()
{
destroyContext();
}
static int visual_attribs[] =
{
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, True,
//GLX_SAMPLE_BUFFERS , 1,
//GLX_SAMPLES , 4,
None
};
std::unique_ptr<XcbGlInterface> XcbGlInterface::Create(Display* display, int default_screen)
{
return std::make_unique<XcbGlInterface>(display, default_screen);
}
void XcbGlInterface::setupContext(int default_screen)
{
/* Query framebuffer configurations that match visual_attribs */
int num_fb_configs = 0;
GLXFBConfig* fb_configs = glXChooseFBConfig(mDisplay, default_screen, visual_attribs, &num_fb_configs);
if (!fb_configs || num_fb_configs == 0)
{
MLOG_ERROR("glXGetFBConfigs failed");
return;
}
/* Select first framebuffer config and query visualID */
int visualID = 0;
mConfig = fb_configs[0];
glXGetFBConfigAttrib(mDisplay, mConfig, GLX_VISUAL_ID, &visualID);
/* Create OpenGL context */
mContext = glXCreateNewContext(mDisplay, mConfig, GLX_RGBA_TYPE, 0, True);
if (!mContext)
{
MLOG_ERROR("glXCreateNewContext failed");
return;
}
}
void XcbGlInterface::destroyContext()
{
glXDestroyContext(mDisplay, mContext);
}

View file

@ -0,0 +1,39 @@
#pragma once
#include <GL/glx.h>
#include <memory>
class XcbGlInterface
{
public:
XcbGlInterface(Display* display, int default_screen);
~XcbGlInterface();
static std::unique_ptr<XcbGlInterface> Create(Display* display, int default_screen);
Display* getDisplay() const
{
return mDisplay;
}
GLXContext getContext() const
{
return mContext;
}
GLXFBConfig getConfig() const
{
return mConfig;
}
private:
void setupContext(int default_screen);
void destroyContext();
Display* mDisplay{nullptr};
GLXContext mContext;
GLXFBConfig mConfig;
};
using XcbGlInterfacePtr = std::unique_ptr<XcbGlInterface>;

View file

@ -0,0 +1,67 @@
#include "XcbGlWindowInterface.h"
#include "OpenGlInterface.h"
#include "XcbGlInterface.h"
#include "FileLogger.h"
#include <GL/gl.h>
XcbGlWindowInterface::XcbGlWindowInterface(XcbGlInterface* glInterface)
: mGlInterface(glInterface),
mDrawable(),
mWindow()
{
}
XcbGlWindowInterface::~XcbGlWindowInterface()
{
if (mWindow)
{
destroyWindow();
}
}
void XcbGlWindowInterface::draw()
{
OpenGlInterface::draw();
swapBuffers();
}
void XcbGlWindowInterface::swapBuffers()
{
glXSwapBuffers(mGlInterface->getDisplay(), mDrawable);
}
bool XcbGlWindowInterface::initialize(xcb_window_t window)
{
if (mWindow)
{
return true;
}
/* Create GLX Window */
mWindow = glXCreateWindow(mGlInterface->getDisplay(), mGlInterface->getConfig(), window, 0);
if (!mWindow)
{
glXDestroyContext(mGlInterface->getDisplay(), mGlInterface->getContext());
MLOG_ERROR("glXCreateWindow failed");
return false;
}
mDrawable = mWindow;
/* make OpenGL context current */
if (!glXMakeContextCurrent(mGlInterface->getDisplay(), mDrawable, mDrawable, mGlInterface->getContext()))
{
glXDestroyContext(mGlInterface->getDisplay(), mGlInterface->getContext());
MLOG_ERROR("glXMakeContextCurrent failed");
return false;
}
return true;
}
void XcbGlWindowInterface::destroyWindow()
{
glXDestroyWindow(mGlInterface->getDisplay(), mWindow);
}

View file

@ -0,0 +1,28 @@
#pragma once
#include <GL/glx.h>
#include <xcb/xcb.h>
#include <memory>
class XcbGlInterface;
class XcbGlWindowInterface
{
public:
XcbGlWindowInterface(XcbGlInterface* glInterface);
~XcbGlWindowInterface();
bool initialize(xcb_window_t window);
void draw();
private:
void destroyWindow();
void swapBuffers();
XcbGlInterface* mGlInterface{nullptr};
GLXDrawable mDrawable;
GLXWindow mWindow;
};
using XcbGlWindowInterfacePtr = std::unique_ptr<XcbGlWindowInterface>;

View file

@ -15,23 +15,20 @@
#include "XcbWindow.h"
#include "XcbLayerInterface.h"
#include "XcbEventInterface.h"
#include "GlxInterface.h"
#include "XcbGlInterface.h"
#include "FileLogger.h"
XcbInterface::XcbInterface(DesktopManager* desktopManager, bool useHardware)
: AbstractUIInterface(desktopManager, useHardware),
mConnection(nullptr),
mX11Display(),
mGlxInterface(),
mXcbEventInterface(XcbEventInterface::Create())
mEventInterface(XcbEventInterface::Create())
{
}
XcbInterface::~XcbInterface()
{
shutDown();
}
void XcbInterface::initialize()
@ -41,9 +38,17 @@ void XcbInterface::initialize()
createGraphicsContext();
if (mUseHardwareRendering)
{
initializeOpenGl();
initializeHardwareRendering();
}
mDesktopManager->SetKeyboard(XcbKeyboard::Create());
const auto num_windows = mDesktopManager->GetWindowManager()->getNumWindows();
for(std::size_t idx=0; idx< num_windows; idx++)
{
addWindow(mDesktopManager->GetWindowManager()->getWindow(idx));
}
mDesktopManager->GetWindowManager()->GetMainWindow()->show();
}
void XcbInterface::connect()
@ -94,31 +99,10 @@ void XcbInterface::updateScreen()
mDesktopManager->AddScreen(std::move(screen));
}
void XcbInterface::initializeOpenGl()
void XcbInterface::initializeHardwareRendering()
{
mGlxInterface = GlxInterface::Create();
const auto default_screen = DefaultScreen(mX11Display);
mGlxInterface->SetupContext(mX11Display, default_screen);
}
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());
}
mGlInterface = XcbGlInterface::Create(mX11Display, default_screen);
}
void XcbInterface::createGraphicsContext()
@ -149,11 +133,6 @@ void XcbInterface::mapWindow(mt::Window* window)
void XcbInterface::showWindow(mt::Window* window)
{
window->show();
if (mUseHardwareRendering)
{
createOpenGlDrawable(window);
}
}
uint32_t XcbInterface::getEventMask()
@ -167,7 +146,7 @@ uint32_t XcbInterface::getEventMask()
void XcbInterface::addWindow(mt::Window* window)
{
auto screen = mDesktopManager->GetDefaultScreen();
XcbWindow::add(window, mConnection, screen, getEventMask());
XcbWindow::add(window, mConnection, screen, getEventMask(), mGlInterface.get());
}
void XcbInterface::onPaint()
@ -181,28 +160,17 @@ void XcbInterface::onPaint()
}
void XcbInterface::onExposeEvent(xcb_expose_event_t* event)
{
// Update the window
if (mUseHardwareRendering)
{
mGlxInterface->Draw();
mGlxInterface->SwapBuffers(mX11Display);
}
else
{
//auto window = mWindows[event->window];
//window->SetSize(event->width, event->height);
onPaint();
xcb_flush(mConnection);
}
}
void XcbInterface::loop()
{
if (!mConnection)
{
return;
}
initialize();
xcb_generic_event_t *event;
while ((event = xcb_wait_for_event(mConnection)))
{
@ -215,25 +183,25 @@ void XcbInterface::loop()
}
case XCB_KEY_PRESS: {
auto kp = reinterpret_cast<xcb_key_press_event_t*>(event);
auto ui_event = mXcbEventInterface->ConvertKeyPress(kp, mDesktopManager->GetKeyboard());
auto ui_event = mEventInterface->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, mDesktopManager->GetKeyboard());
auto ui_event = mEventInterface->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);
auto ui_event = mEventInterface->ConvertButtonPress(press);
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);
auto ui_event = mEventInterface->ConvertButtonRelease(release);
mDesktopManager->OnUiEvent(std::move(ui_event));
break;
}
@ -244,16 +212,6 @@ void XcbInterface::loop()
onEventsDispatched();
free(event);
}
onLoopCompleted();
}
void XcbInterface::onLoopCompleted()
{
if (mUseHardwareRendering)
{
mGlxInterface->DestroyWindow(mX11Display);
mGlxInterface->DestroyContext(mX11Display);
}
}
void XcbInterface::onEventsDispatched()
@ -268,6 +226,8 @@ void XcbInterface::onEventsDispatched()
void XcbInterface::shutDown()
{
mDesktopManager->GetWindowManager()->clearPlatformWindows();
if (!mConnection)
{
return;

View file

@ -4,8 +4,8 @@
#include <memory>
class GlxInterface;
using GlxInterfacePtr = std::unique_ptr<GlxInterface>;
class XcbGlInterface;
using XcbGlInterfacePtr = std::unique_ptr<XcbGlInterface>;
class XcbEventInterface;
using XcbEventInterfacePtr = std::unique_ptr<XcbEventInterface>;
@ -29,35 +29,31 @@ public:
~XcbInterface();
void initialize() override;
void loop() override;
void shutDown() override;
void showWindow(mt::Window* window) override;
void addWindow(mt::Window* window) override;
void showWindow(mt::Window* window) override;
private:
void initialize() override;
void onPaint();
void onEventsDispatched();
void onLoopCompleted();
void onExposeEvent(xcb_expose_event_t* event);
void initializeOpenGl();
void initializeHardwareRendering() override;
void createGraphicsContext();
void createOpenGlDrawable(mt::Window* window);
void connect();
void updateScreen();
void mapWindow(mt::Window* window);
void shutDown() override;
uint32_t getEventMask();
private:
xcb_connection_t* mConnection;
_XDisplay* mX11Display;
GlxInterfacePtr mGlxInterface;
XcbEventInterfacePtr mXcbEventInterface {nullptr};
xcb_connection_t* mConnection{nullptr};
_XDisplay* mX11Display{nullptr};
XcbGlInterfacePtr mGlInterface;
XcbEventInterfacePtr mEventInterface;
};

View file

@ -6,18 +6,27 @@
#include "XcbImage.h"
#include "Screen.h"
#include "ImagePrimitives.h"
#include "XcbGlWindowInterface.h"
#include <xcb/xcb.h>
XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection)
XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection, XcbGlInterface* xcbGlInterface)
: IPlatformWindow(window),
mHandle(hwnd),
mConnection(connection)
{
if (xcbGlInterface)
{
mGlInterface = std::make_unique<XcbGlWindowInterface>(xcbGlInterface);
}
}
void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask)
XcbWindow::~XcbWindow()
{
xcb_destroy_window(mConnection, mHandle);
}
void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask, XcbGlInterface* xcbGlInterface)
{
if (!screen)
{
@ -39,7 +48,7 @@ void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen
xcb_screen->GetNativeScreen()->root_visual, /* visual */
mask, values ); /* masks */
auto xcb_window = std::make_unique<XcbWindow>(window, hwnd, connection);
auto xcb_window = std::make_unique<XcbWindow>(window, hwnd, connection, xcbGlInterface);
window->SetPlatformWindow(std::move(xcb_window));
}
@ -53,7 +62,7 @@ unsigned XcbWindow::getGraphicsContext() const
return mGraphicsContext;
}
void XcbWindow::show() const
void XcbWindow::show()
{
map();
}
@ -62,18 +71,39 @@ void XcbWindow::paint(mt::Screen* screen)
{
auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen());
if (mGlInterface)
{
paintHardware(xcb_screen);
}
else
{
paintSoftware(xcb_screen);
}
}
void XcbWindow::paintHardware(XcbScreen* screen)
{
if (mGlInterface)
{
mGlInterface->initialize(mHandle);
mGlInterface->draw();
}
}
void XcbWindow::paintSoftware(XcbScreen* screen)
{
if (!mBackingImage)
{
mBackingImage = std::make_unique<XcbImage>(mConnection, mWindow, xcb_screen->GetNativeScreen());
mBackingImage = std::make_unique<XcbImage>(mConnection, mWindow, screen->GetNativeScreen());
}
auto backing_image = mWindow->getBackingImage();
backing_image->initialize();
//ImagePrimitives::drawCheckerboard(const_cast<unsigned char*>(backing_image->getDataPtr()), backing_image->getWidth(), backing_image->getHeight(), 0);
mBackingImage->update(mWindow, xcb_screen->GetNativeScreen(), mConnection, xcb_screen->GetGraphicsContext());
mBackingImage->update(mWindow, screen->GetNativeScreen(), mConnection, screen->GetGraphicsContext());
xcb_copy_area(mConnection, mBackingImage->getPixMap(), mHandle, xcb_screen->GetGraphicsContext(), 0, 0 ,0 , 0, backing_image->getWidth(), backing_image->getHeight());
xcb_copy_area(mConnection, mBackingImage->getPixMap(), mHandle, screen->GetGraphicsContext(), 0, 0 ,0 , 0, backing_image->getWidth(), backing_image->getHeight());
/*
for(const auto& layer : mWindow->GetLayers())
{
@ -82,13 +112,13 @@ void XcbWindow::paint(mt::Screen* screen)
*/
}
void XcbWindow::clear() const
void XcbWindow::clear()
{
xcb_clear_area(mConnection, 1, mHandle, 0, 0, mWindow->GetWidth(), mWindow->GetHeight());
xcb_flush(mConnection);
}
void XcbWindow::map() const
void XcbWindow::map()
{
xcb_map_window(mConnection, mHandle);
xcb_flush(mConnection);

View file

@ -3,6 +3,9 @@
#include "IPlatformWindow.h"
class XcbImage;
class XcbScreen;
class XcbGlWindowInterface;
class XcbGlInterface;
struct xcb_connection_t;
namespace mt
@ -13,27 +16,31 @@ namespace mt
class XcbWindow : public IPlatformWindow
{
public:
XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection);
virtual ~XcbWindow() = default;
XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection, XcbGlInterface* xcbGlInterface);
virtual ~XcbWindow();
static void add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask);
static void add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask, XcbGlInterface* xcbGlInterface);
int getHandle() const;
unsigned getGraphicsContext() const;
void show() const override;
void show() override;
void paint(mt::Screen* screen) override;
void clear() const override;
void clear() override;
void map() const override;
void map() override;
private:
void paintHardware(XcbScreen* screen);
void paintSoftware(XcbScreen* screen);
int mHandle{-1};
unsigned mGraphicsContext {0};
xcb_connection_t* mConnection{nullptr};
std::unique_ptr<XcbImage> mBackingImage;
std::unique_ptr<XcbGlWindowInterface> mGlInterface;
};
using XcbWindowPtr = std::unique_ptr<XcbWindow>;

View file

@ -14,8 +14,8 @@ public:
{
auto app = std::make_unique<GuiApplication>();
//app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11);
app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11_RASTER);
app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11);
//app->setUiInterfaceBackend(UiInterfaceFactory::Backend::X11_RASTER);
app->run();
return true;

View file

@ -9,13 +9,13 @@ int main()
unsigned width = 200;
unsigned height = 200;
unsigned numChannels = 3;
auto image = Image::Create(width, height);
image->SetNumChannels(numChannels);
auto image = Image<unsigned char>::Create(width, height);
image->setNumChannels(numChannels);
std::vector<unsigned char> data(image->GetBytesPerRow()*height, 0);
std::vector<unsigned char> data(image->getBytesPerRow()*height, 0);
for(unsigned jdx=0;jdx<height;jdx++)
{
const auto heightOffset = jdx*image->GetBytesPerRow();
const auto heightOffset = jdx*image->getBytesPerRow();
for(unsigned idx=0;idx<width*numChannels;idx+=numChannels)
{
const auto index = heightOffset + idx;
@ -24,7 +24,7 @@ int main()
data[index+2] = 0;
}
}
image->SetData(data);
image->setData(data);
PngWriter writer;
writer.SetPath("test.png");