stuff-from-scratch/src/windows/ui_interfaces/x11/XcbWindow.cpp
2022-11-14 15:31:38 +00:00

122 lines
3.6 KiB
C++

#include "XcbWindow.h"
#include "Window.h"
#include "XcbLayerInterface.h"
#include "XcbScreen.h"
#include "XcbImage.h"
#include "Screen.h"
#include "ImagePrimitives.h"
#include "XcbGlWindowInterface.h"
#include "DrawingContext.h"
#include <xcb/xcb.h>
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);
}
}
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)
{
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, xcbGlInterface);
const auto drawing_mode = xcbGlInterface ? DrawingMode::GRAPH : DrawingMode::RASTER;
window->setPlatformWindow(std::move(xcb_window), drawing_mode);
}
int XcbWindow::getHandle() const
{
return mHandle;
}
unsigned XcbWindow::getGraphicsContext() const
{
return mGraphicsContext;
}
void XcbWindow::show()
{
map();
}
void XcbWindow::beforePaint(mt::Screen* screen)
{
if (mGlInterface)
{
mGlInterface->initialize(mHandle);
}
else
{
auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen());
if (!mBackingImage)
{
mBackingImage = std::make_unique<XcbImage>(mConnection, mWindow, xcb_screen->GetNativeScreen());
}
}
}
void XcbWindow::afterPaint(mt::Screen* screen)
{
if (mGlInterface)
{
mGlInterface->afterPaint();
}
else
{
auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen());
mBackingImage->update(mWindow, xcb_screen->GetNativeScreen(), mConnection, xcb_screen->GetGraphicsContext());
xcb_copy_area(mConnection, mBackingImage->getPixMap(), mHandle, xcb_screen->GetGraphicsContext(), 0, 0 ,0 , 0, mWindow->getWidth(), mWindow->getHeight());
}
}
void XcbWindow::clear()
{
xcb_clear_area(mConnection, 1, mHandle, 0, 0, mWindow->getWidth(), mWindow->getHeight());
xcb_flush(mConnection);
}
void XcbWindow::map()
{
xcb_map_window(mConnection, mHandle);
xcb_flush(mConnection);
}
void XcbWindow::onResize(unsigned width, unsigned height)
{
if (mGlInterface)
{
mGlInterface->resizeViewPort(width, height);
}
}