From ccda10950be1b21c9128b40efec918978f9734fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 13 Dec 2012 03:02:20 +0100 Subject: [PATCH] Port OverlayWindow from XLib to XCB With this change KWin core no longer depends on the XLib based composite extension. REVIEW: 107685 --- CMakeLists.txt | 2 +- overlaywindow.cpp | 93 +++++++++++++++++++++++++++++------------------ overlaywindow.h | 12 +++--- 3 files changed, 65 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1269eaff59..62e9964a60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,7 +176,7 @@ qt4_add_dbus_interface( kwin_KDEINIT_SRCS qt4_add_resources( kwin_KDEINIT_SRCS resources.qrc ) -set(kwinLibs ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTDECLARATIVE_LIBRARY} ${KDECLARATIVE_LIBRARIES} kdecorations kwineffects ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${X11_Xcomposite_LIB} ${X11_Xdamage_LIB} ${X11_Xrender_LIB} ${X11_Xfixes_LIB} ${XCB_XCB_LIBRARIES} ${X11_XCB_LIBRARIES} ${XCB_XFIXES_LIBRARIES} ${XCB_DAMAGE_LIBRARIES} ${XCB_COMPOSITE_LIBRARIES}) +set(kwinLibs ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTDECLARATIVE_LIBRARY} ${KDECLARATIVE_LIBRARIES} kdecorations kwineffects ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${X11_Xdamage_LIB} ${X11_Xrender_LIB} ${X11_Xfixes_LIB} ${XCB_XCB_LIBRARIES} ${X11_XCB_LIBRARIES} ${XCB_XFIXES_LIBRARIES} ${XCB_DAMAGE_LIBRARIES} ${XCB_COMPOSITE_LIBRARIES} ${XCB_SHAPE_LIBRARIES}) find_library(XF86VM_LIBRARY Xxf86vm) if (XF86VM_LIBRARY) diff --git a/overlaywindow.cpp b/overlaywindow.cpp index 221118e8da..d6359c7829 100644 --- a/overlaywindow.cpp +++ b/overlaywindow.cpp @@ -20,18 +20,16 @@ along with this program. If not, see . #include "overlaywindow.h" -#include - #include "kwinglobals.h" +#include "utils.h" #include "assert.h" #include -#include - -#include -#if XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR >= 3 +#include +#include +#if XCB_COMPOSITE_MAJOR_VERSION > 0 || XCB_COMPOSITE_MINOR_VERSION >= 3 #define KWIN_HAVE_XCOMPOSITE_OVERLAY #endif @@ -39,7 +37,7 @@ namespace KWin { OverlayWindow::OverlayWindow() : m_visible(true) , m_shown(false) - , m_window(None) + , m_window(XCB_WINDOW_NONE) { } @@ -49,50 +47,69 @@ OverlayWindow::~OverlayWindow() bool OverlayWindow::create() { - assert(m_window == None); + assert(m_window == XCB_WINDOW_NONE); if (!Extensions::compositeOverlayAvailable()) return false; if (!Extensions::shapeInputAvailable()) // needed in setupOverlay() return false; #ifdef KWIN_HAVE_XCOMPOSITE_OVERLAY - m_window = XCompositeGetOverlayWindow(display(), rootWindow()); - if (m_window == None) + ScopedCPointer overlay = + xcb_composite_get_overlay_window_reply(connection(), + xcb_composite_get_overlay_window(connection(), rootWindow()), + NULL); + if (overlay.isNull()) { return false; - XResizeWindow(display(), m_window, displayWidth(), displayHeight()); + } + m_window = overlay->overlay_win; + if (m_window == XCB_WINDOW_NONE) + return false; + resize(QSize(displayWidth(), displayHeight())); return true; #else return false; #endif } -void OverlayWindow::setup(Window window) +void OverlayWindow::setup(xcb_window_t window) { - assert(m_window != None); + assert(m_window != XCB_WINDOW_NONE); assert(Extensions::shapeInputAvailable()); - XSetWindowBackgroundPixmap(display(), m_window, None); + setNoneBackgroundPixmap(m_window); m_shape = QRegion(); setShape(QRect(0, 0, displayWidth(), displayHeight())); - if (window != None) { - XSetWindowBackgroundPixmap(display(), window, None); - XShapeCombineRectangles(display(), window, ShapeInput, 0, 0, NULL, 0, ShapeSet, Unsorted); + if (window != XCB_WINDOW_NONE) { + setNoneBackgroundPixmap(window); + setupInputShape(window); } - XSelectInput(display(), m_window, VisibilityChangeMask); + const uint32_t eventMask = XCB_EVENT_MASK_VISIBILITY_CHANGE; + xcb_change_window_attributes(connection(), m_window, XCB_CW_EVENT_MASK, &eventMask); +} + +void OverlayWindow::setupInputShape(xcb_window_t window) +{ + xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, window, 0, 0, 0, NULL); +} + +void OverlayWindow::setNoneBackgroundPixmap(xcb_window_t window) +{ + const uint32_t mask = XCB_BACK_PIXMAP_NONE; + xcb_change_window_attributes(connection(), window, XCB_CW_BACK_PIXMAP, &mask); } void OverlayWindow::show() { - assert(m_window != None); + assert(m_window != XCB_WINDOW_NONE); if (m_shown) return; - XMapSubwindows(display(), m_window); - XMapWindow(display(), m_window); + xcb_map_subwindows(connection(), m_window); + xcb_map_window(connection(), m_window); m_shown = true; } void OverlayWindow::hide() { - assert(m_window != None); - XUnmapWindow(display(), m_window); + assert(m_window != XCB_WINDOW_NONE); + xcb_unmap_window(connection(), m_window); m_shown = false; setShape(QRect(0, 0, displayWidth(), displayHeight())); } @@ -104,7 +121,7 @@ void OverlayWindow::setShape(const QRegion& reg) if (reg == m_shape) return; QVector< QRect > rects = reg.rects(); - XRectangle* xrects = new XRectangle[ rects.count()]; + xcb_rectangle_t *xrects = new xcb_rectangle_t[rects.count()]; for (int i = 0; i < rects.count(); ++i) { @@ -113,17 +130,21 @@ void OverlayWindow::setShape(const QRegion& reg) xrects[ i ].width = rects[ i ].width(); xrects[ i ].height = rects[ i ].height(); } - XShapeCombineRectangles(display(), m_window, ShapeBounding, 0, 0, - xrects, rects.count(), ShapeSet, Unsorted); + xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + m_window, 0, 0, rects.count(), xrects); delete[] xrects; - XShapeCombineRectangles(display(), m_window, ShapeInput, 0, 0, NULL, 0, ShapeSet, Unsorted); + setupInputShape(m_window); m_shape = reg; } void OverlayWindow::resize(const QSize &size) { - assert(m_window != None); - XResizeWindow(display(), m_window, size.width(), size.height()); + assert(m_window != XCB_WINDOW_NONE); + const uint32_t geometry[2] = { + static_cast(size.width()), + static_cast(size.height()) + }; + xcb_configure_window(connection(), m_window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, geometry); setShape(QRegion(0, 0, size.width(), size.height())); } @@ -139,20 +160,20 @@ void OverlayWindow::setVisibility(bool visible) void OverlayWindow::destroy() { - if (m_window == None) + if (m_window == XCB_WINDOW_NONE) return; // reset the overlay shape - XRectangle rec = { 0, 0, static_cast(displayWidth()), static_cast(displayHeight()) }; - XShapeCombineRectangles(display(), m_window, ShapeBounding, 0, 0, &rec, 1, ShapeSet, Unsorted); - XShapeCombineRectangles(display(), m_window, ShapeInput, 0, 0, &rec, 1, ShapeSet, Unsorted); + xcb_rectangle_t rec = { 0, 0, static_cast(displayWidth()), static_cast(displayHeight()) }; + xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, m_window, 0, 0, 1, &rec); + xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, m_window, 0, 0, 1, &rec); #ifdef KWIN_HAVE_XCOMPOSITE_OVERLAY - XCompositeReleaseOverlayWindow(display(), m_window); + xcb_composite_release_overlay_window(connection(), m_window); #endif - m_window = None; + m_window = XCB_WINDOW_NONE; m_shown = false; } -Window OverlayWindow::window() const +xcb_window_t OverlayWindow::window() const { return m_window; } diff --git a/overlaywindow.h b/overlaywindow.h index d2d999523b..4d7b171a18 100644 --- a/overlaywindow.h +++ b/overlaywindow.h @@ -22,8 +22,8 @@ along with this program. If not, see . #define KWIN_OVERLAYWINDOW_H #include - -#include +// xcb +#include namespace KWin { class OverlayWindow { @@ -33,21 +33,23 @@ public: /// Creates XComposite overlay window, call initOverlay() afterwards bool create(); /// Init overlay and the destination window in it - void setup(Window window); + void setup(xcb_window_t window); void show(); void hide(); // hides and resets overlay window void setShape(const QRegion& reg); void resize(const QSize &size); /// Destroys XComposite overlay window void destroy(); - Window window() const; + xcb_window_t window() const; bool isVisible() const; void setVisibility(bool visible); private: + void setNoneBackgroundPixmap(xcb_window_t window); + void setupInputShape(xcb_window_t window); bool m_visible; bool m_shown; // For showOverlay() QRegion m_shape; - Window m_window; + xcb_window_t m_window; }; } // namespace