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

@ -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()
@ -182,27 +161,16 @@ 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);
}
//auto window = mWindows[event->window];
//window->SetSize(event->width, event->height);
onPaint();
}
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>;