122 lines
3.6 KiB
C++
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);
|
|
}
|
|
}
|