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}/ui_events"
"${CMAKE_CURRENT_SOURCE_DIR}/desktop_elements" "${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) set_property(TARGET ui_elements PROPERTY FOLDER src)

View file

@ -2,10 +2,23 @@
#include <memory> #include <memory>
namespace mt
{
class Screen;
}
class IPlatformWindow class IPlatformWindow
{ {
public: public:
virtual ~IPlatformWindow() = default; 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>; using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>;

View file

@ -5,6 +5,8 @@
#include "MouseEvent.h" #include "MouseEvent.h"
#include "VisualLayer.h" #include "VisualLayer.h"
#include "KeyboardEvent.h" #include "KeyboardEvent.h"
#include "Image.h"
#include "Screen.h"
namespace mt namespace mt
{ {
@ -12,6 +14,7 @@ namespace mt
Window::Window() Window::Window()
:mWidth(800), :mWidth(800),
mHeight(600), mHeight(600),
mBackingImage(std::make_unique<Image>(mWidth, mHeight)),
mWidget(Widget::Create()) mWidget(Widget::Create())
{ {
mWidget->setBounds(mWidth, mHeight); mWidget->setBounds(mWidth, mHeight);
@ -93,4 +96,41 @@ void Window::SetPlatformWindow(IPlatformWindowPtr window)
mPlatformWindow = std::move(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 MouseEvent;
class KeyboardEvent; class KeyboardEvent;
class VisualLayer; class VisualLayer;
class Image;
class IPlatformWindow; class IPlatformWindow;
using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>; using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>;
namespace mt namespace mt
{ {
class Screen;
class Window class Window
{ {
@ -48,12 +51,23 @@ public:
void SetPlatformWindow(IPlatformWindowPtr window); void SetPlatformWindow(IPlatformWindowPtr window);
Image* getBackingImage() const;
void map();
void show();
void doPaint(mt::Screen* screen);
void clear();
private: private:
int mHandle {-1}; int mHandle {-1};
WidgetUPtr mWidget {nullptr}; WidgetUPtr mWidget {nullptr};
unsigned mWidth {800}; unsigned mWidth {800};
unsigned mHeight {600}; unsigned mHeight {600};
IPlatformWindowPtr mPlatformWindow {nullptr}; IPlatformWindowPtr mPlatformWindow {nullptr};
std::unique_ptr<Image> mBackingImage;
}; };
} }

View file

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

View file

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

View file

@ -1,22 +1,80 @@
#include "XcbWindow.h" #include "XcbWindow.h"
XcbWindow::XcbWindow(int hwnd) #include "Window.h"
: mHandle(hwnd) #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; return mHandle;
} }
unsigned XcbWindow::GetGraphicsContext() const unsigned XcbWindow::getGraphicsContext() const
{ {
return mGraphicsContext; 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" #include "IPlatformWindow.h"
class XcbImage;
struct xcb_connection_t;
namespace mt
{
class Window;
}
class XcbWindow : public IPlatformWindow class XcbWindow : public IPlatformWindow
{ {
public: public:
XcbWindow(int hwnd); XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection);
virtual ~XcbWindow() = default; 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; int getHandle() const;
unsigned GetGraphicsContext() const; unsigned getGraphicsContext() const;
void show() const override;
void paint(mt::Screen* screen) const override;
void clear() const override;
void map() const override;
private: private:
int mHandle{-1}; int mHandle{-1};
unsigned mGraphicsContext {0}; unsigned mGraphicsContext {0};
mt::Window* mWindow{nullptr};
xcb_connection_t* mConnection{nullptr};
std::unique_ptr<XcbImage> mBackingImage;
}; };
using XcbWindowPtr = std::unique_ptr<XcbWindow>; 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>;