diff --git a/README.md b/README.md index 7e34b70..1863df1 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ sudo apt-get install libpng-dev #### Window rendering ```bash -sudo apt-get install libwayland-dev wayland-protocols libx11-dev libxkbcommon-dev libx11-xcb-dev +sudo apt-get install libwayland-dev wayland-protocols libx11-dev libxkbcommon-dev libx11-xcb-dev libxcb-image0-dev ``` We need to generate suitable xdg shell c code for wayland: diff --git a/src/image/Image.cpp b/src/image/Image.cpp index 6fa4d99..27d2802 100644 --- a/src/image/Image.cpp +++ b/src/image/Image.cpp @@ -19,7 +19,7 @@ Image::~Image() template void Image::initialize() { - mData = std::vector(getBytesPerRow()*mHeight, 0); + mData = std::vector(getBytesPerRow()*mHeight, 10); } template diff --git a/src/image/Image.h b/src/image/Image.h index c07f110..a699e72 100644 --- a/src/image/Image.h +++ b/src/image/Image.h @@ -29,12 +29,28 @@ public: void setBitDepth(unsigned bitDepth); void setNumChannels(unsigned numChannels); -private: void initialize(); + const T* getDataPtr() const + { + return mData.data(); + } + + const std::vector& getDataRef() const + { + return mData; + } + + std::vector getData() const + { + return mData; + } + +private: + unsigned mWidth{1}; unsigned mHeight{1}; unsigned mBitDepth{8}; - unsigned mNumChannels{1}; + unsigned mNumChannels{4}; std::vector mData; }; diff --git a/src/windows/CMakeLists.txt b/src/windows/CMakeLists.txt index be6135c..18fd72d 100644 --- a/src/windows/CMakeLists.txt +++ b/src/windows/CMakeLists.txt @@ -17,7 +17,7 @@ if(UNIX) ui_interfaces/x11/XcbKeyboard.cpp ui_interfaces/x11/GlxInterface.cpp ) - list(APPEND platform_LIBS ${X11_LIBRARIES} ${X11_xcb_LIB} ${X11_X11_xcb_LIB} ${X11_xkbcommon_LIB}) + list(APPEND platform_LIBS ${X11_LIBRARIES} ${X11_xcb_LIB} ${X11_X11_xcb_LIB} ${X11_xkbcommon_LIB} libxcb-image.so) list(APPEND X11_INCLUDE_DIRS ${X11_xkbcommon_INCLUDE_PATH}) else() message(STATUS "x11 development headers not found - skipping support") diff --git a/src/windows/ui_interfaces/x11/XcbImage.h b/src/windows/ui_interfaces/x11/XcbImage.h index b0ba112..8fa672d 100644 --- a/src/windows/ui_interfaces/x11/XcbImage.h +++ b/src/windows/ui_interfaces/x11/XcbImage.h @@ -1,6 +1,47 @@ #pragma once +#include + +#include "Window.h" +#include "XcbWindow.h" + class XcbImage { +public: + XcbImage(xcb_connection_t* connection, mt::Window* window, xcb_screen_t* screen) + { + mPixmap = xcb_generate_id(connection); + auto hwnd = dynamic_cast(window->GetPlatformWindow())->getHandle(); + const auto w = window->GetWidth(); + const auto h = window->GetHeight(); + xcb_create_pixmap(connection, screen->root_depth, mPixmap, hwnd, w, h); + } + void update(mt::Window* window, xcb_screen_t* screen, xcb_connection_t* connection, xcb_gcontext_t gc) + { + if (!mXImage) + { + auto backing_image = window->getBackingImage(); + + const auto w = window->GetWidth(); + const auto h = window->GetHeight(); + + //auto data = const_cast(backing_image->getDataPtr()); + auto data = backing_image->getData(); + unsigned char* converted = &data[0]; + mXImage = xcb_image_create_native(connection, w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, screen->root_depth, converted, w*h*4, converted); + + xcb_image_put(connection, mPixmap, gc, mXImage, 0, 0, 0); + //xcb_image_destroy(mXImage); + } + } + + xcb_pixmap_t getPixMap() const + { + return mPixmap; + } + +private: + xcb_pixmap_t mPixmap{0}; + xcb_image_t* mXImage{nullptr}; }; diff --git a/src/windows/ui_interfaces/x11/XcbWindow.cpp b/src/windows/ui_interfaces/x11/XcbWindow.cpp index 99423aa..b40a810 100644 --- a/src/windows/ui_interfaces/x11/XcbWindow.cpp +++ b/src/windows/ui_interfaces/x11/XcbWindow.cpp @@ -5,13 +5,13 @@ #include "XcbScreen.h" #include "XcbImage.h" #include "Screen.h" +#include "ImagePrimitives.h" #include XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection) : IPlatformWindow(window), mHandle(hwnd), - mBackingImage(std::make_unique()), mConnection(connection) { @@ -61,10 +61,25 @@ void XcbWindow::show() const void XcbWindow::paint(mt::Screen* screen) { auto xcb_screen = dynamic_cast(screen->GetPlatformScreen()); + + if (!mBackingImage) + { + mBackingImage = std::make_unique(mConnection, mWindow, xcb_screen->GetNativeScreen()); + } + + auto backing_image = mWindow->getBackingImage(); + backing_image->initialize(); + //ImagePrimitives::drawCheckerboard(const_cast(backing_image->getDataPtr()), backing_image->getWidth(), backing_image->getHeight(), 0); + + mBackingImage->update(mWindow, xcb_screen->GetNativeScreen(), mConnection, xcb_screen->GetGraphicsContext()); + + xcb_copy_area(mConnection, mBackingImage->getPixMap(), mHandle, xcb_screen->GetGraphicsContext(), 0, 0 ,0 , 0, backing_image->getWidth(), backing_image->getHeight()); +/* for(const auto& layer : mWindow->GetLayers()) { XcbLayerInterface::AddLayer(mConnection, xcb_screen->GetNativeScreen(), mHandle, xcb_screen->GetGraphicsContext(), layer); } + */ } void XcbWindow::clear() const