Prep for image support in windows.

This commit is contained in:
James Grogan 2022-11-11 15:51:37 +00:00
parent 53c98a227d
commit e7683cd94e
13 changed files with 172 additions and 135 deletions

View file

@ -33,7 +33,7 @@ target_include_directories(ui_elements PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/ui_events"
"${CMAKE_CURRENT_SOURCE_DIR}/desktop_elements"
)
target_link_libraries(ui_elements PUBLIC core geometry visual_elements)
target_link_libraries(ui_elements PUBLIC core geometry visual_elements image)
set_property(TARGET ui_elements PROPERTY FOLDER src)

View file

@ -2,10 +2,23 @@
#include <memory>
namespace mt
{
class Screen;
}
class IPlatformWindow
{
public:
virtual ~IPlatformWindow() = default;
virtual void show() const = 0;
virtual void map() const = 0;
virtual void clear() const = 0;
virtual void paint(mt::Screen* screen) const = 0;
};
using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>;

View file

@ -5,6 +5,8 @@
#include "MouseEvent.h"
#include "VisualLayer.h"
#include "KeyboardEvent.h"
#include "Image.h"
#include "Screen.h"
namespace mt
{
@ -12,6 +14,7 @@ namespace mt
Window::Window()
:mWidth(800),
mHeight(600),
mBackingImage(std::make_unique<Image>(mWidth, mHeight)),
mWidget(Widget::Create())
{
mWidget->setBounds(mWidth, mHeight);
@ -93,4 +96,41 @@ void Window::SetPlatformWindow(IPlatformWindowPtr window)
mPlatformWindow = std::move(window);
}
Image* Window::getBackingImage() const
{
return mBackingImage.get();
}
void Window::map()
{
if (mPlatformWindow)
{
mPlatformWindow->map();
}
}
void Window::show()
{
if (mPlatformWindow)
{
mPlatformWindow->show();
}
}
void Window::doPaint(mt::Screen* screen)
{
if (mPlatformWindow)
{
mPlatformWindow->paint(screen);
}
}
void Window::clear()
{
if (mPlatformWindow)
{
mPlatformWindow->clear();
}
}
}

View file

@ -9,12 +9,15 @@ class PaintEvent;
class MouseEvent;
class KeyboardEvent;
class VisualLayer;
class Image;
class IPlatformWindow;
using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>;
namespace mt
{
class Screen;
class Window
{
@ -48,12 +51,23 @@ public:
void SetPlatformWindow(IPlatformWindowPtr window);
Image* getBackingImage() const;
void map();
void show();
void doPaint(mt::Screen* screen);
void clear();
private:
int mHandle {-1};
WidgetUPtr mWidget {nullptr};
unsigned mWidth {800};
unsigned mHeight {600};
IPlatformWindowPtr mPlatformWindow {nullptr};
std::unique_ptr<Image> mBackingImage;
};
}

View file

@ -11,7 +11,7 @@ if(UNIX)
ui_interfaces/x11/XcbEventInterface.cpp
ui_interfaces/x11/XcbWindow.cpp
ui_interfaces/x11/XcbScreen.cpp
ui_interfaces/x11/XcbWindowInterface.cpp
ui_interfaces/x11/XcbImage.cpp
ui_interfaces/x11/XcbLayerInterface.cpp
ui_interfaces/x11/XcbTextInterface.cpp
ui_interfaces/x11/XcbKeyboard.cpp

View file

@ -0,0 +1,6 @@
#pragma once
class XcbImage
{
};

View file

@ -15,7 +15,6 @@
#include "XcbWindow.h"
#include "XcbLayerInterface.h"
#include "XcbEventInterface.h"
#include "XcbWindowInterface.h"
#include "GlxInterface.h"
#include "FileLogger.h"
@ -25,8 +24,7 @@ XcbInterface::XcbInterface(DesktopManager* desktopManager, bool useHardware)
mConnection(nullptr),
mX11Display(),
mGlxInterface(),
mXcbEventInterface(XcbEventInterface::Create()),
mXcbWindowInterface(XcbWindowInterface::Create())
mXcbEventInterface(XcbEventInterface::Create())
{
}
@ -45,7 +43,6 @@ void XcbInterface::initialize()
{
initializeOpenGl();
}
mDesktopManager->SetKeyboard(XcbKeyboard::Create());
}
@ -117,10 +114,10 @@ void XcbInterface::createOpenGlDrawable(mt::Window* window)
return;
}
if (!mGlxInterface->SetupWindow(mX11Display, xcb_window->GetHandle()))
if (!mGlxInterface->SetupWindow(mX11Display, xcb_window->getHandle()))
{
MLOG_ERROR("Failed to set up OpenGL Drawable");
xcb_destroy_window(mConnection, xcb_window->GetHandle());
xcb_destroy_window(mConnection, xcb_window->getHandle());
}
}
@ -146,12 +143,12 @@ void XcbInterface::createGraphicsContext()
void XcbInterface::mapWindow(mt::Window* window)
{
mXcbWindowInterface->Map(window, mConnection);
window->map();
}
void XcbInterface::showWindow(mt::Window* window)
{
mXcbWindowInterface->Show(window, mConnection);
window->show();
if (mUseHardwareRendering)
{
@ -170,7 +167,7 @@ uint32_t XcbInterface::getEventMask()
void XcbInterface::addWindow(mt::Window* window)
{
auto screen = mDesktopManager->GetDefaultScreen();
mXcbWindowInterface->Add(window, mConnection, screen, getEventMask());
XcbWindow::add(window, mConnection, screen, getEventMask());
}
void XcbInterface::onPaint()
@ -179,8 +176,8 @@ void XcbInterface::onPaint()
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());
mainWindow->doPaint(defaultScreen);
}
void XcbInterface::onExposeEvent(xcb_expose_event_t* event)
@ -265,7 +262,7 @@ void XcbInterface::onEventsDispatched()
{
mDesktopManager->SetIsModified(false);
auto mainWindow = mDesktopManager->GetWindowManager()->GetMainWindow();
mXcbWindowInterface->Clear(mainWindow, mConnection);
mainWindow->clear();
}
}

View file

@ -60,5 +60,4 @@ private:
_XDisplay* mX11Display;
GlxInterfacePtr mGlxInterface;
XcbEventInterfacePtr mXcbEventInterface {nullptr};
XcbWindowInterfacePtr mXcbWindowInterface {nullptr};
};

View file

@ -1,22 +1,80 @@
#include "XcbWindow.h"
XcbWindow::XcbWindow(int hwnd)
: mHandle(hwnd)
#include "Window.h"
#include "XcbLayerInterface.h"
#include "XcbScreen.h"
#include "XcbImage.h"
#include "Screen.h"
#include <xcb/xcb.h>
XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection)
: mHandle(hwnd),
mWindow(window),
mBackingImage(std::make_unique<XcbImage>()),
mConnection(connection)
{
}
std::unique_ptr<XcbWindow> XcbWindow::Create(int hwnd)
void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask)
{
return std::make_unique<XcbWindow>(hwnd);
if (!screen)
{
return;
}
auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen());
const auto hwnd = xcb_generate_id(connection);
const uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
const uint32_t values[2] = {xcb_screen->GetNativeScreen()->white_pixel, eventMask};
xcb_create_window (connection, /* connection */
XCB_COPY_FROM_PARENT, /* depth */
hwnd, /* window Id */
xcb_screen->GetNativeScreen()->root, /* parent window */
0, 0, /* x, y */
window->GetWidth(), window->GetHeight(), /* width, height */
10, /* border_width */
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
xcb_screen->GetNativeScreen()->root_visual, /* visual */
mask, values ); /* masks */
auto xcb_window = std::make_unique<XcbWindow>(window, hwnd, connection);
window->SetPlatformWindow(std::move(xcb_window));
}
int XcbWindow::GetHandle() const
int XcbWindow::getHandle() const
{
return mHandle;
}
unsigned XcbWindow::GetGraphicsContext() const
unsigned XcbWindow::getGraphicsContext() const
{
return mGraphicsContext;
}
void XcbWindow::show() const
{
map();
}
void XcbWindow::paint(mt::Screen* screen) const
{
auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen());
for(const auto& layer : mWindow->GetLayers())
{
XcbLayerInterface::AddLayer(mConnection, xcb_screen->GetNativeScreen(), mHandle, xcb_screen->GetGraphicsContext(), layer);
}
}
void XcbWindow::clear() const
{
xcb_clear_area(mConnection, 1, mHandle, 0, 0, mWindow->GetWidth(), mWindow->GetHeight());
xcb_flush(mConnection);
}
void XcbWindow::map() const
{
xcb_map_window(mConnection, mHandle);
xcb_flush(mConnection);
}

View file

@ -2,20 +2,40 @@
#include "IPlatformWindow.h"
class XcbImage;
struct xcb_connection_t;
namespace mt
{
class Window;
}
class XcbWindow : public IPlatformWindow
{
public:
XcbWindow(int hwnd);
XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection);
virtual ~XcbWindow() = default;
static std::unique_ptr<XcbWindow> Create(int hwnd);
static void add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask);
int GetHandle() const;
unsigned GetGraphicsContext() const;
int getHandle() const;
unsigned getGraphicsContext() const;
void show() const override;
void paint(mt::Screen* screen) const override;
void clear() const override;
void map() const override;
private:
int mHandle{-1};
unsigned mGraphicsContext {0};
mt::Window* mWindow{nullptr};
xcb_connection_t* mConnection{nullptr};
std::unique_ptr<XcbImage> mBackingImage;
};
using XcbWindowPtr = std::unique_ptr<XcbWindow>;

View file

@ -1,80 +0,0 @@
#include "XcbWindowInterface.h"
#include "Window.h"
#include "XcbWindow.h"
#include "Screen.h"
#include "XcbScreen.h"
#include "XcbLayerInterface.h"
#include <xcb/xcb.h>
std::unique_ptr<XcbWindowInterface> XcbWindowInterface::Create()
{
return std::make_unique<XcbWindowInterface>();
}
void XcbWindowInterface::Add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask) const
{
if (!connection || !screen || !window)
{
return;
}
auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen());
auto hwnd = xcb_generate_id(connection);
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t values[2] = {xcb_screen->GetNativeScreen()->white_pixel, eventMask};
xcb_create_window (connection, /* connection */
XCB_COPY_FROM_PARENT, /* depth */
hwnd, /* window Id */
xcb_screen->GetNativeScreen()->root, /* parent window */
0, 0, /* x, y */
window->GetWidth(), window->GetHeight(), /* width, height */
10, /* border_width */
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
xcb_screen->GetNativeScreen()->root_visual, /* visual */
mask, values ); /* masks */
auto xcb_window = XcbWindow::Create(hwnd);
window->SetPlatformWindow(std::move(xcb_window));
}
void XcbWindowInterface::Show(mt::Window* window, xcb_connection_t* connection) const
{
Map(window, connection);
}
void XcbWindowInterface::Paint(mt::Window* window, xcb_connection_t* connection, xcb_screen_t* screen, unsigned gc) const
{
if (!window)
{
return;
}
auto xcb_window = dynamic_cast<XcbWindow*>(window->GetPlatformWindow());
for(const auto& layer : window->GetLayers())
{
XcbLayerInterface::AddLayer(connection, screen, xcb_window->GetHandle(), gc, layer);
}
}
void XcbWindowInterface::Clear(mt::Window* window, xcb_connection_t* connection) const
{
if (!window)
{
return;
}
auto xcb_window = dynamic_cast<XcbWindow*>(window->GetPlatformWindow());
xcb_clear_area(connection, 1, xcb_window->GetHandle(), 0, 0, window->GetWidth(), window->GetHeight());
xcb_flush(connection);
}
void XcbWindowInterface::Map(mt::Window* window, xcb_connection_t* connection) const
{
if (!connection or !window)
{
return;
}
auto xcb_window = dynamic_cast<XcbWindow*>(window->GetPlatformWindow());
xcb_map_window(connection, xcb_window->GetHandle());
xcb_flush(connection);
}

View file

@ -1,30 +0,0 @@
#pragma once
#include <memory>
namespace mt
{
class Window;
class Screen;
}
struct xcb_connection_t;
struct xcb_screen_t;
class XcbWindowInterface
{
public:
static std::unique_ptr<XcbWindowInterface> Create();
void Add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask) const;
void Show(mt::Window* window, xcb_connection_t* connection) const;
void Paint(mt::Window* window, xcb_connection_t* connection, xcb_screen_t* screen, unsigned gc) const;
void Clear(mt::Window* window, xcb_connection_t* connection) const;
void Map(mt::Window* window, xcb_connection_t* connection) const;
};
using XcbWindowInterfacePtr = std::unique_ptr<XcbWindowInterface>;