#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 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(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(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(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(screen->GetPlatformScreen()); if (!mBackingImage) { mBackingImage = std::make_unique(mConnection, mWindow, xcb_screen->GetNativeScreen()); } } } void XcbWindow::afterPaint(mt::Screen* screen) { if (mGlInterface) { mGlInterface->afterPaint(); } else { auto xcb_screen = dynamic_cast(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); } }