[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [ksnapshot/frameworks] /: use XCB to convert native handles
From:       Aaron Seigo <aseigo () kde ! org>
Date:       2014-09-15 8:16:03
Message-ID: E1XTRS7-0005kS-Dl () scm ! kde ! org
[Download RAW message or body]

Git commit fb5dde6604b0d82e69ce9912f7188383940609c7 by Aaron Seigo.
Committed on 15/09/2014 at 07:09.
Pushed by aseigo into branch 'frameworks'.

use XCB to convert native handles

adapted from patch by Martin Gräßlin

M  +54   -17   CMakeLists.txt
A  +31   -0    cmake/modules/FindX11_XCB.cmake
A  +238  -0    cmake/modules/FindXCB.cmake
M  +10   -4    config-ksnapshot.h.cmake
M  +23   -61   ksnapshot.cpp
M  +0    -1    ksnapshot.h
A  +178  -0    xcb/pixmaphelper.cpp     [License: GPL (v2+)]
A  +34   -0    xcb/pixmaphelper.h     [License: GPL (v2+)]
A  +209  -0    xcb/xcbutils.h     [License: GPL (v2)]

http://commits.kde.org/ksnapshot/fb5dde6604b0d82e69ce9912f7188383940609c7

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b2f2dc7..69d6fc9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,11 @@ set (QT_MIN_VERSION "5.2.0")
 #macro_optional_find_package(Kipi)
 
 find_package(ECM 1.1.0 REQUIRED NO_MODULE)
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
+
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
+                      ${CMAKE_MODULE_PATH}
+                      ${ECM_MODULE_PATH}
+                      ${ECM_KDE_MODULE_DIR})
 
 include(KDEInstallDirs)
 include(KDECMakeSettings)
@@ -34,21 +38,22 @@ add_definitions(-DQT_USE_FAST_CONCATENATION \
-DQT_USE_FAST_OPERATOR_PLUS)  find_package(X11)
 if (X11_FOUND)
     set(HAVE_X11 1)
+endif(X11_FOUND)
 
-    if (X11_Xshape_FOUND)
-        set(HAVE_X11_EXTENSIONS_SHAPE_H 1)
-    endif (X11_Xshape_FOUND)
+find_package(XCB MODULE COMPONENTS XCB SHAPE XFIXES)
+set_package_properties(XCB PROPERTIES DESCRIPTION "X protocol C-language Binding"
+                       URL "http://xcb.freedesktop.org"
+                       TYPE OPTIONAL)
+find_package(X11_XCB MODULE)
+set_package_properties(X11_XCB PROPERTIES DESCRIPTION "Xlib/XCB interface library"
+                       URL "http://xcb.freedesktop.org"
+                       TYPE OPTIONAL)
 
-    if (X11_Xfixes_FOUND)
-        set(HAVE_X11_EXTENSIONS_XFIXES_H 1)
-    endif (X11_Xfixes_FOUND)
-endif (X11_FOUND)
-#feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "X11 Fixes Extension (xfixes.h)" \
"Support for capturing the cursor" "http://www.x.org/" VAR \
HAVE_X11_EXTENSIONS_XFIXES_H) +#include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 if (KIPI_FOUND)
-        include_directories(${KIPI_INCLUDE_DIR})
+   include_directories(${KIPI_INCLUDE_DIR})
 endif (KIPI_FOUND)
-#macro_log_feature(KIPI_FOUND "KIPI plugins" "Provides various image export \
features, such as printing, emailing and uploading" "http://www.kipi-plugins.org/" \
FALSE "" "")  
 configure_file(config-ksnapshot.h.cmake \
${CMAKE_CURRENT_BINARY_DIR}/config-ksnapshot.h)  
@@ -65,6 +70,12 @@ set(ksnapshot_file_SRCS
    ksnapshotobject.cpp
    ksnapshotpreview.cpp)
 
+if (XCB_XCB_FOUND AND X11_XCB_FOUND)
+   set(ksnapshot_xcb_SRCS
+      #       windowgrabber_x11.cpp
+       xcb/pixmaphelper.cpp)
+endif (XCB_XCB_FOUND AND X11_XCB_FOUND)
+
 if (KIPI_FOUND)
     set(ksnapshot_kipi_SRCS
         kipiinterface.cpp
@@ -76,6 +87,7 @@ endif (KIPI_FOUND)
 set(ksnapshot_SRCS
    main.cpp
    ksnapshot.cpp 
+   ${ksnapshot_xcb_SRCS}
    ${ksnapshot_file_SRCS}
    ${ksnapshot_kipi_SRCS})
 
@@ -100,11 +112,21 @@ target_link_libraries(ksnapshot
    KF5::KIOWidgets
    KF5::WindowSystem
    KF5::XmlGui
-   ${X11_LIBRARIES})
-
-if (X11_Xfixes_FOUND)
-    target_link_libraries(ksnapshot ${X11_Xfixes_LIB})
-endif (X11_Xfixes_FOUND)
+   ${X11_LIBRARIES}
+   )
+
+if (X11_XCB_FOUND)
+    target_link_libraries(ksnapshot ${X11_XCB_LIBRARIES})
+endif ()
+if (XCB_XCB_FOUND)
+    target_link_libraries(ksnapshot ${XCB_XCB_LIBRARY})
+endif ()
+if (XCB_SHAPE_FOUND)
+    target_link_libraries(ksnapshot ${XCB_SHAPE_LIBRARY})
+endif ()
+if (XCB_XFIXES_FOUND)
+    target_link_libraries(ksnapshot ${XCB_XFIXES_LIBRARY})
+endif ()
 
 if (KIPI_FOUND)
     target_link_libraries(ksnapshot ${KIPI_LIBRARIES})
@@ -129,7 +151,22 @@ target_link_libraries(kbackgroundsnapshot
                       KF5::I18n
                       KF5::KIOWidgets
                       KF5::WindowSystem
-                      ${X11_LIBRARIES})
+                      ${X11_LIBRARIES}
+                     )
+
+target_link_libraries(kbackgroundsnapshot ${KDE4_KIO_LIBS})
+
+if (X11_XCB_FOUND)
+    target_link_libraries(kbackgroundsnapshot ${X11_XCB_LIBRARIES})
+endif ()
+
+if (XCB_XCB_FOUND)
+    target_link_libraries(kbackgroundsnapshot ${XCB_XCB_LIBRARY})
+endif ()
+
+if (XCB_SHAPE_FOUND)
+    target_link_libraries(kbackgroundsnapshot ${XCB_SHAPE_LIBRARY})
+endif ()
 
 install(TARGETS kbackgroundsnapshot ${INSTALL_TARGETS_DEFAULT_ARGS})
 
diff --git a/cmake/modules/FindX11_XCB.cmake b/cmake/modules/FindX11_XCB.cmake
new file mode 100644
index 0000000..e2c18a9
--- /dev/null
+++ b/cmake/modules/FindX11_XCB.cmake
@@ -0,0 +1,31 @@
+# - Try to find libX11-xcb
+# Once done this will define
+#
+#  X11_XCB_FOUND       - system has libX11-xcb
+#  X11_XCB_LIBRARIES   - Link these to use libX11-xcb
+#  X11_XCB_INCLUDE_DIR - the libX11-xcb include dir
+#  X11_XCB_DEFINITIONS - compiler switches required for using libX11-xcb
+
+# Copyright (c) 2011 Fredrik Höglund <fredrik@kde.org>
+# Copyright (c) 2008 Helio Chissini de Castro, <helio@kde.org>
+# Copyright (c) 2007 Matthias Kretz, <kretz@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+IF (NOT WIN32)
+  # use pkg-config to get the directories and then use these values
+  # in the FIND_PATH() and FIND_LIBRARY() calls
+  FIND_PACKAGE(PkgConfig)
+  PKG_CHECK_MODULES(PKG_X11_XCB QUIET x11-xcb)
+
+  SET(X11_XCB_DEFINITIONS ${PKG_X11_XCB_CFLAGS})
+
+  FIND_PATH(X11_XCB_INCLUDE_DIR  NAMES X11/Xlib-xcb.h HINTS \
${PKG_X11_XCB_INCLUDE_DIRS}) +  FIND_LIBRARY(X11_XCB_LIBRARIES NAMES X11-xcb        \
HINTS ${PKG_X11_XCB_LIBRARY_DIRS}) +
+  include(FindPackageHandleStandardArgs)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(X11_XCB DEFAULT_MSG X11_XCB_LIBRARIES \
X11_XCB_INCLUDE_DIR) +
+  MARK_AS_ADVANCED(X11_XCB_INCLUDE_DIR X11_XCB_LIBRARIES)
+ENDIF (NOT WIN32)
diff --git a/cmake/modules/FindXCB.cmake b/cmake/modules/FindXCB.cmake
new file mode 100644
index 0000000..823d167
--- /dev/null
+++ b/cmake/modules/FindXCB.cmake
@@ -0,0 +1,238 @@
+# Try to find XCB on a Unix system
+#
+# This will define:
+#
+#   XCB_FOUND        - True if xcb is available
+#   XCB_LIBRARIES    - Link these to use xcb
+#   XCB_INCLUDE_DIRS - Include directory for xcb
+#   XCB_DEFINITIONS  - Compiler flags for using xcb
+#
+# In addition the following more fine grained variables will be defined:
+#
+#   XCB_XCB_FOUND        XCB_XCB_INCLUDE_DIR        XCB_XCB_LIBRARY
+#   XCB_UTIL_FOUND       XCB_UTIL_INCLUDE_DIR       XCB_UTIL_LIBRARY
+#   XCB_COMPOSITE_FOUND  XCB_COMPOSITE_INCLUDE_DIR  XCB_COMPOSITE_LIBRARY
+#   XCB_DAMAGE_FOUND     XCB_DAMAGE_INCLUDE_DIR     XCB_DAMAGE_LIBRARY
+#   XCB_XFIXES_FOUND     XCB_XFIXES_INCLUDE_DIR     XCB_XFIXES_LIBRARY
+#   XCB_RENDER_FOUND     XCB_RENDER_INCLUDE_DIR     XCB_RENDER_LIBRARY
+#   XCB_RANDR_FOUND      XCB_RANDR_INCLUDE_DIR      XCB_RANDR_LIBRARY
+#   XCB_SHAPE_FOUND      XCB_SHAPE_INCLUDE_DIR      XCB_SHAPE_LIBRARY
+#   XCB_DRI2_FOUND       XCB_DRI2_INCLUDE_DIR       XCB_DRI2_LIBRARY
+#   XCB_GLX_FOUND        XCB_GLX_INCLUDE_DIR        XCB_GLX_LIBRARY
+#   XCB_SHM_FOUND        XCB_SHM_INCLUDE_DIR        XCB_SHM_LIBRARY
+#   XCB_XV_FOUND         XCB_XV_INCLUDE_DIR         XCB_XV_LIBRARY
+#   XCB_SYNC_FOUND       XCB_SYNC_INCLUDE_DIR       XCB_SYNC_LIBRARY
+#   XCB_XTEST_FOUND      XCB_XTEST_INCLUDE_DIR      XCB_XTEST_LIBRARY
+#   XCB_ICCCM_FOUND      XCB_ICCCM_INCLUDE_DIR      XCB_ICCCM_LIBRARY
+#   XCB_EWMH_FOUND       XCB_EWMH_INCLUDE_DIR       XCB_EWMH_LIBRARY
+#   XCB_IMAGE_FOUND      XCB_IMAGE_INCLUDE_DIR      XCB_IMAGE_LIBRARY
+#   XCB_RENDERUTIL_FOUND XCB_RENDERUTIL_INCLUDE_DIR XCB_RENDERUTIL_LIBRARY
+#   XCB_KEYSYMS_FOUND    XCB_KEYSYMS_INCLUDE_DIR    XCB_KEYSYMS_LIBRARY
+#
+# Copyright (c) 2011 Fredrik Höglund <fredrik@kde.org>
+# Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+set(knownComponents XCB
+                    COMPOSITE
+                    DAMAGE
+                    DRI2
+                    EWMH
+                    GLX
+                    ICCCM
+                    IMAGE
+                    KEYSYMS
+                    RANDR
+                    RENDER
+                    RENDERUTIL
+                    SHAPE
+                    SHM
+                    SYNC
+                    UTIL
+                    XFIXES
+                    XTEST
+                    XV)
+
+unset(unknownComponents)
+
+set(pkgConfigModules)
+set(requiredComponents)
+
+if (XCB_FIND_COMPONENTS)
+  set(comps ${XCB_FIND_COMPONENTS})
+else()
+  set(comps ${knownComponents})
+endif()
+
+# iterate through the list of requested components, and check that we know them all.
+# If not, fail.
+foreach(comp ${comps})
+    list(FIND knownComponents ${comp} index )
+    if("${index}" STREQUAL "-1")
+        list(APPEND unknownComponents "${comp}")
+    else()
+        if("${comp}" STREQUAL "XCB")
+            list(APPEND pkgConfigModules "xcb")
+        elseif("${comp}" STREQUAL "COMPOSITE")
+            list(APPEND pkgConfigModules "xcb-composite")
+        elseif("${comp}" STREQUAL "DAMAGE")
+            list(APPEND pkgConfigModules "xcb-damage")
+        elseif("${comp}" STREQUAL "DRI2")
+            list(APPEND pkgConfigModules "xcb-dri2")
+        elseif("${comp}" STREQUAL "EWMH")
+            list(APPEND pkgConfigModules "xcb-ewmh")
+        elseif("${comp}" STREQUAL "GLX")
+            list(APPEND pkgConfigModules "xcb-glx")
+        elseif("${comp}" STREQUAL "ICCCM")
+            list(APPEND pkgConfigModules "xcb-icccm")
+        elseif("${comp}" STREQUAL "IMAGE")
+            list(APPEND pkgConfigModules "xcb-image")
+        elseif("${comp}" STREQUAL "KEYSYMS")
+            list(APPEND pkgConfigModules "xcb-keysyms")
+        elseif("${comp}" STREQUAL "RANDR")
+            list(APPEND pkgConfigModules "xcb-randr")
+        elseif("${comp}" STREQUAL "RENDER")
+            list(APPEND pkgConfigModules "xcb-render")
+        elseif("${comp}" STREQUAL "RENDERUTIL")
+            list(APPEND pkgConfigModules "xcb-renderutil")
+        elseif("${comp}" STREQUAL "SHAPE")
+            list(APPEND pkgConfigModules "xcb-shape")
+        elseif("${comp}" STREQUAL "SHM")
+            list(APPEND pkgConfigModules "xcb-shm")
+        elseif("${comp}" STREQUAL "SYNC")
+            list(APPEND pkgConfigModules "xcb-sync")
+        elseif("${comp}" STREQUAL "UTIL")
+            list(APPEND pkgConfigModules "xcb-util")
+        elseif("${comp}" STREQUAL "XFIXES")
+            list(APPEND pkgConfigModules "xcb-xfixes")
+        elseif("${comp}" STREQUAL "XTEST")
+            list(APPEND pkgConfigModules "xcb-xtest")
+        elseif("${comp}" STREQUAL "XV")
+            list(APPEND pkgConfigModules "xcb-xv")
+        endif()
+    endif()
+endforeach()
+
+
+if(DEFINED unknownComponents)
+   set(msgType STATUS)
+   if(XCB_FIND_REQUIRED)
+      set(msgType FATAL_ERROR)
+   endif()
+   if(NOT XCB_FIND_QUIETLY)
+      message(${msgType} "XCB: requested unknown components ${unknownComponents}")
+   endif()
+   return()
+endif()
+
+macro(_XCB_HANDLE_COMPONENT _comp)
+    set(_header )
+    set(_lib )
+    if("${_comp}" STREQUAL "XCB")
+        set(_header "xcb/xcb.h")
+        set(_lib "xcb")
+    elseif("${_comp}" STREQUAL "COMPOSITE")
+        set(_header "xcb/composite.h")
+        set(_lib "xcb-composite")
+    elseif("${_comp}" STREQUAL "DAMAGE")
+        set(_header "xcb/damage.h")
+        set(_lib "xcb-damage")
+    elseif("${_comp}" STREQUAL "DRI2")
+        set(_header "xcb/dri2.h")
+        set(_lib "xcb-dri2")
+    elseif("${_comp}" STREQUAL "EWMH")
+        set(_header "xcb/xcb_ewmh.h")
+        set(_lib "xcb-ewmh")
+    elseif("${_comp}" STREQUAL "GLX")
+        set(_header "xcb/glx.h")
+        set(_lib "xcb-glx")
+    elseif("${_comp}" STREQUAL "ICCCM")
+        set(_header "xcb/xcb_icccm.h")
+        set(_lib "xcb-icccm")
+    elseif("${_comp}" STREQUAL "IMAGE")
+        set(_header "xcb/xcb_image.h")
+        set(_lib "xcb-image")
+    elseif("${_comp}" STREQUAL "KEYSYMS")
+        set(_header "xcb/xcb_keysyms.h")
+        set(_lib "xcb-keysyms")
+    elseif("${_comp}" STREQUAL "RANDR")
+        set(_header "xcb/randr.h")
+        set(_lib "xcb-randr")
+    elseif("${_comp}" STREQUAL "RENDER")
+        set(_header "xcb/render.h")
+        set(_lib "xcb-render")
+    elseif("${_comp}" STREQUAL "RENDERUTIL")
+        set(_header "xcb/xcb_renderutil.h")
+        set(_lib "xcb-render-util")
+    elseif("${_comp}" STREQUAL "SHAPE")
+        set(_header "xcb/shape.h")
+        set(_lib "xcb-shape")
+    elseif("${_comp}" STREQUAL "SHM")
+        set(_header "xcb/shm.h")
+        set(_lib "xcb-shm")
+    elseif("${_comp}" STREQUAL "SYNC")
+        set(_header "xcb/sync.h")
+        set(_lib "xcb-sync")
+    elseif("${_comp}" STREQUAL "UTIL")
+        set(_header "xcb/xcb_util.h")
+        set(_lib "xcb-util")
+    elseif("${_comp}" STREQUAL "XFIXES")
+        set(_header "xcb/xfixes.h")
+        set(_lib "xcb-xfixes")
+    elseif("${_comp}" STREQUAL "XTEST")
+        set(_header "xcb/xtest.h")
+        set(_lib "xcb-xtest")
+    elseif("${_comp}" STREQUAL "XV")
+        set(_header "xcb/xv.h")
+        set(_lib "xcb-xv")
+    endif()
+
+    find_path(XCB_${_comp}_INCLUDE_DIR NAMES ${_header} HINTS \
${PKG_XCB_INCLUDE_DIRS}) +    find_library(XCB_${_comp}_LIBRARY NAMES ${_lib} HINTS \
${PKG_XCB_LIBRARY_DIRS}) +
+    if(XCB_${_comp}_INCLUDE_DIR AND XCB_${_comp}_LIBRARY)
+        list(APPEND XCB_INCLUDE_DIRS ${XCB_${_comp}_INCLUDE_DIR})
+        list(APPEND XCB_LIBRARIES ${XCB_${_comp}_LIBRARY})
+        if (NOT XCB_FIND_QUIETLY)
+            message(STATUS "XCB[${_comp}]: Found component ${_comp}")
+        endif()
+    endif()
+
+    if(XCB_FIND_REQUIRED_${_comp})
+        list(APPEND requiredComponents XCB_${_comp}_FOUND)
+    endif()
+
+    find_package_handle_standard_args(XCB_${_comp} DEFAULT_MSG XCB_${_comp}_LIBRARY \
XCB_${_comp}_INCLUDE_DIR) +
+    mark_as_advanced(XCB_${_comp}_LIBRARY XCB_${_comp}_INCLUDE_DIR)
+
+    # compatibility for old variable naming
+    set(XCB_${_comp}_INCLUDE_DIRS ${XCB_${_comp}_INCLUDE_DIR})
+    set(XCB_${_comp}_LIBRARIES ${XCB_${_comp}_LIBRARY})
+endmacro()
+
+IF (NOT WIN32)
+    include(FindPackageHandleStandardArgs)
+    # Use pkg-config to get the directories and then use these values
+    # in the FIND_PATH() and FIND_LIBRARY() calls
+    find_package(PkgConfig)
+    pkg_check_modules(PKG_XCB QUIET ${pkgConfigModules})
+
+    set(XCB_DEFINITIONS ${PKG_XCB_CFLAGS})
+
+    foreach(comp ${comps})
+        _xcb_handle_component(${comp})
+    endforeach()
+
+    if(XCB_INCLUDE_DIRS)
+        list(REMOVE_DUPLICATES XCB_INCLUDE_DIRS)
+    endif()
+
+    find_package_handle_standard_args(XCB DEFAULT_MSG XCB_LIBRARIES XCB_INCLUDE_DIRS \
${requiredComponents}) +
+    # compatibility for old variable naming
+    set(XCB_INCLUDE_DIR ${XCB_INCLUDE_DIRS})
+
+ENDIF (NOT WIN32)
diff --git a/config-ksnapshot.h.cmake b/config-ksnapshot.h.cmake
index a70b068..3514dd5 100644
--- a/config-ksnapshot.h.cmake
+++ b/config-ksnapshot.h.cmake
@@ -1,11 +1,17 @@
 /* Define to 1 if we are building with X11 */
 #cmakedefine01 HAVE_X11
 
-/* Define to 1 if you have the <X11/extensions/shape.h> header file. */
-#cmakedefine01 HAVE_X11_EXTENSIONS_SHAPE_H
+/* Define to 1 if you have xcb */
+#cmakedefine XCB_XCB_FOUND 1
 
-/* Define to 1 if you have the <X11/extensions/Xfixes.h> header file. */
-#cmakedefine01 HAVE_X11_EXTENSIONS_XFIXES_H
+/* Define to 1 if you have x11-xcb */
+#cmakedefine X11_XCB_FOUND 1
+
+/* Define to 1 if you have xfixes */
+#cmakedefine XCB_XFIXES_FOUND 1
+
+/* Define to 1 if you have shape */
+#cmakedefine XCB_SHAPE_FOUND 1
 
 /* Define to 1 if you have libkipi */
 #cmakedefine KIPI_FOUND
diff --git a/ksnapshot.cpp b/ksnapshot.cpp
index fd9a2ad..2bc458e 100644
--- a/ksnapshot.cpp
+++ b/ksnapshot.cpp
@@ -84,12 +84,16 @@
 #include <KAction>
 #endif
 
-#if HAVE_X11_EXTENSIONS_XFIXES_H
-#include <X11/extensions/Xfixes.h>
+#if HAVE_X11
 #include <X11/Xatom.h>
+#include <X11/Xlib.h>
 #include <QX11Info>
 #endif
 
+#if XCB_XCB_FOUND
+#include <xcb/pixmaphelper.h>
+#endif
+
 class KSnapshotWidget : public QWidget, public Ui::KSnapshotWidget
 {
 public:
@@ -105,8 +109,7 @@ KSnapshot::KSnapshot(QWidget *parent,  \
KSnapshotObject::CaptureMode mode)  : QDialog(parent),
       KSnapshotObject(),
       m_modified(true),
-      m_savedPosition(QPoint(-1, -1)),
-      m_haveXFixes(false)
+      m_savedPosition(QPoint(-1, -1))
 {
     // TEMPORARY Make sure "untitled" enters the string freeze for 4.6,
     // as explained in \
http://lists.kde.org/?l=kde-graphics-devel&m=128942871430175&w=2 @@ -197,32 +200,19 \
@@ KSnapshot::KSnapshot(QWidget *parent,  KSnapshotObject::CaptureMode mode)  \
KConfigGroup conf(KSharedConfig::openConfig(), "GENERAL");  
 #ifdef KIPI_FOUND
-#if(KIPI_VERSION >= 0x020000)
-    m_pluginLoader = new KIPI::PluginLoader();
-    m_pluginLoader->setInterface(new KIPIInterface(this));
-    m_pluginLoader->init();
-#else
-    m_pluginLoader = new KIPI::PluginLoader(QStringList(), new KIPIInterface(this), \
                "");
-#endif
+    #if(KIPI_VERSION >= 0x020000)
+        m_pluginLoader = new KIPI::PluginLoader();
+        m_pluginLoader->setInterface(new KIPIInterface(this));
+        m_pluginLoader->init();
+    #else
+        m_pluginLoader = new KIPI::PluginLoader(QStringList(), new \
KIPIInterface(this), ""); +    #endif
 #endif
 
-#if HAVE_X11_EXTENSIONS_XFIXES_H
+#if HAVE_X11
     {
-        int tmp1, tmp2;
-        //Check whether the XFixes extension is available
+        // prevent KWin from animating the window in the compositor
         Display *dpy = QX11Info::display();
-        if (!XFixesQueryExtension(dpy, &tmp1, &tmp2)) {
-            m_snapshotWidget->cbIncludePointer->hide();
-            m_snapshotWidget->lblIncludePointer->hide();
-        } else {
-            m_haveXFixes = true;
-        }
-
-        // actually not depending on XFixes, but to simplify the ifdefs put here
-        // we can safely assume that XFixes is present for this functionality
-        // it's supposed to prevent that KWin animates the window in the compositor
-        // and XFixes is a requirement for the compositor. So if XFixes is not \
                present
-        // KWin cannot be compiled at all.
         Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SKIP_CLOSE_ANIMATION", False);
         long d = 1;
         XChangeProperty(dpy, winId(), atom, XA_CARDINAL, 32,
@@ -620,13 +610,8 @@ void KSnapshot::slotWindowGrabbed(const QPixmap &pix)
 
 void KSnapshot::slotScreenshotReceived(qulonglong handle)
 {
-#if HAVE_X11
-    //FIXME: there is no fromX11Pixmap anymore and nothing there to replace it
-    //       may have to write our own thing? want to look around a bit more
-    //       to see if anyone has beaten us to that. i mean, screen shotting
-    //       is *not* an uncommon task. Since this comes from kwin, perhaps
-    //       discuss with kwin developers.
-    //slotWindowGrabbed( QPixmap::fromX11Pixmap( handle ) );
+#if XCB_XCB_FOUND
+    slotWindowGrabbed(PixmapHelperXCB::grabWindow(handle));
 #else
     Q_UNUSED(handle)
 #endif
@@ -803,39 +788,16 @@ void KSnapshot::performGrab()
     show();
 }
 
-// Uses the X11_EXTENSIONS_XFIXES_H extension to grab the pointer image, and \
overlays it onto the snapshot. +// Grabs the pointer image if there is platform \
support for it, and overlays it onto the snapshot.  void \
KSnapshot::grabPointerImage(int offsetx, int offsety)  {
-#if HAVE_X11_EXTENSIONS_XFIXES_H
-    if (!m_haveXFixes || !includePointer()) {
-        return;
-    }
-
-    XFixesCursorImage *xcursorimg = XFixesGetCursorImage(QX11Info::display());
-    if (!xcursorimg) {
-        return;
-    }
-
-    //Annoyingly, xfixes specifies the data to be 32bit, but places it in an \
                unsigned long *
-    //which can be 64 bit.  So we need to iterate over a 64bit structure to put it \
                in a 32bit
-    //structure.
-    QVarLengthArray< quint32 > pixels(xcursorimg->width * xcursorimg->height);
-    for (int i = 0; i < xcursorimg->width * xcursorimg->height; ++i) {
-        pixels[i] = xcursorimg->pixels[i] & 0xffffffff;
-    }
-
-    QImage qcursorimg((uchar *) pixels.data(), xcursorimg->width, \
                xcursorimg->height,
-                      QImage::Format_ARGB32_Premultiplied);
-
-    QPainter painter(&m_snapshot);
-    painter.drawImage(QPointF(xcursorimg->x - xcursorimg->xhot - offsetx, \
                xcursorimg->y - xcursorimg ->yhot - offsety), qcursorimg);
-
-    XFree(xcursorimg);
-#else // HAVE_X11_EXTENSIONS_XFIXES_H
+#if XCB_XFIXES_FOUND
+    PixmapHelperXCB::compositePointer(offsetx, offsety, m_snapshot);
+#else
     Q_UNUSED(offsetx);
     Q_UNUSED(offsety);
     return;
-#endif // HAVE_X11_EXTENSIONS_XFIXES_H
+#endif
 }
 
 void KSnapshot::setTime(int newTime)
diff --git a/ksnapshot.h b/ksnapshot.h
index 3c71ce9..51836bc 100644
--- a/ksnapshot.h
+++ b/ksnapshot.h
@@ -142,7 +142,6 @@ private:
     KSnapshotWidget *m_snapshotWidget;
     bool m_modified;
     QPoint m_savedPosition;
-    bool m_haveXFixes;
     bool m_includeAlpha;
     QPolygon m_lastFreeRegion;
     QRect m_lastRegion;
diff --git a/xcb/pixmaphelper.cpp b/xcb/pixmaphelper.cpp
new file mode 100644
index 0000000..4060e98
--- /dev/null
+++ b/xcb/pixmaphelper.cpp
@@ -0,0 +1,178 @@
+/*
+  Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or ( at your option ) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this library; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+*/
+
+#include "xcb/pixmaphelper.h"
+
+#include <stdint.h>
+
+#include <xcb/xfixes.h>
+
+#include <QPainter>
+
+#include "xcb/xcbutils.h"
+
+namespace PixmapHelperXCB
+{
+
+void compositePointer(int offsetx, int offsety, QPixmap &snapshot)
+{
+    Xcb::ScopedCPointer<xcb_xfixes_get_cursor_image_reply_t> cursor(
+            xcb_xfixes_get_cursor_image_reply(Xcb::connection(),
+                                              \
xcb_xfixes_get_cursor_image_unchecked(Xcb::connection()), +                           \
NULL)); +
+    if (cursor.isNull()) {
+        return;
+    }
+
+    QImage qcursorimg((uchar *) \
xcb_xfixes_get_cursor_image_cursor_image(cursor.data()), +                      \
cursor->width, cursor->height, +                      \
QImage::Format_ARGB32_Premultiplied); +
+    QPainter painter(&snapshot);
+    painter.drawImage(QPointF(cursor->x - cursor->xhot - offsetx, cursor->y - cursor \
->yhot - offsety), qcursorimg); +}
+
+QPixmap grabWindow(WId id, int x, int y, int width, int height)
+{
+    xcb_connection_t *c = Xcb::connection();
+    Xcb::WindowGeometry geo(id);
+    if (geo.isNull()) {
+        return QPixmap();
+    }
+    if (width < 0 || width > geo->width) {
+        width = geo->width;
+    }
+    if (width + x > geo->width) {
+        width = width + x - geo->width;
+    }
+    if (height < 0 || height > geo->height) {
+        height = geo->height;
+    }
+    if (height + y > geo->height) {
+        height = height + y - geo->height;
+    }
+    Xcb::ScopedCPointer<xcb_get_image_reply_t> xImage(xcb_get_image_reply(
+        c, xcb_get_image_unchecked(c, XCB_IMAGE_FORMAT_Z_PIXMAP, id, x, y, width, \
height, ~0), NULL)); +    if (xImage.isNull()) {
+        return QPixmap();
+    }
+    QImage::Format format = QImage::Format_ARGB32_Premultiplied;
+    switch (xImage->depth) {
+    case 1:
+        format = QImage::Format_MonoLSB;
+        break;
+    case 30: {
+        // Qt doesn't have a matching image format. We need to convert manually
+        uint32_t *pixels = reinterpret_cast<uint32_t \
*>(xcb_get_image_data(xImage.data())); +        for (uint32_t i = 0; i < \
xImage.data()->length; ++i) { +            int r = (pixels[i] >> 22) & 0xff;
+            int g = (pixels[i] >> 12) & 0xff;
+            int b = (pixels[i] >>  2) & 0xff;
+
+            pixels[i] = qRgba(r, g, b, 0xff);
+        }
+        QImage image(reinterpret_cast<uchar *>(pixels), geo->width, geo->height,
+                     xcb_get_image_data_length(xImage.data()) / geo->height, \
QImage::Format_ARGB32_Premultiplied); +        if (image.isNull()) {
+            return QPixmap();
+        }
+        return QPixmap::fromImage(image);
+    }
+    case 32:
+        format = QImage::Format_ARGB32_Premultiplied;
+        break;
+    default:
+        if (xImage->depth == defaultDepth()) {
+            format = findFormat();
+            if (format == QImage::Format_Invalid) {
+                return QPixmap();
+            }
+        } else {
+            // we don't know
+            return QPixmap();
+        }
+    }
+    QImage image(xcb_get_image_data(xImage.data()), width, height,
+                 xcb_get_image_data_length(xImage.data()) / height, format);
+    if (image.isNull()) {
+        return QPixmap();
+    }
+    if (image.format() == QImage::Format_MonoLSB) {
+        // work around an abort in QImage::color
+        image.setColorCount(2);
+        image.setColor(0, QColor(Qt::white).rgb());
+        image.setColor(1, QColor(Qt::black).rgb());
+    }
+    return QPixmap::fromImage(image);
+}
+
+uint8_t defaultDepth()
+{
+    xcb_connection_t *c = Xcb::connection();
+    int screen = QX11Info::appScreen();
+
+    xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(c));
+    for (; it.rem; --screen, xcb_screen_next(&it)) {
+        if (screen == 0) {
+            return it.data->root_depth;
+        }
+    }
+    return 0;
+}
+
+QImage::Format findFormat()
+{
+    xcb_connection_t *c = Xcb::connection();
+    int screen = QX11Info::appScreen();
+
+    xcb_screen_iterator_t screenIt = xcb_setup_roots_iterator(xcb_get_setup(c));
+    for (; screenIt.rem; --screen, xcb_screen_next(&screenIt)) {
+        if (screen != 0) {
+            continue;
+        }
+        xcb_depth_iterator_t depthIt = \
xcb_screen_allowed_depths_iterator(screenIt.data); +        for (; depthIt.rem; \
xcb_depth_next(&depthIt)) { +            xcb_visualtype_iterator_t visualIt = \
xcb_depth_visuals_iterator(depthIt.data); +            for (; visualIt.rem; \
xcb_visualtype_next(&visualIt)) { +                if (screenIt.data->root_visual != \
visualIt.data->visual_id) { +                    continue;
+                }
+                xcb_visualtype_t *visual = visualIt.data;
+                if ((depthIt.data->depth == 24 || depthIt.data->depth == 32) &&
+                        visual->red_mask   == 0x00ff0000 &&
+                        visual->green_mask == 0x0000ff00 &&
+                        visual->blue_mask  == 0x000000ff) {
+                    return QImage::Format_ARGB32_Premultiplied;
+                }
+                if (depthIt.data->depth == 16 &&
+                        visual->red_mask   == 0xf800 &&
+                        visual->green_mask == 0x07e0 &&
+                        visual->blue_mask  == 0x001f) {
+                    return QImage::Format_RGB16;
+                }
+                break;
+            }
+        }
+    }
+    return QImage::Format_Invalid;
+}
+
+} // namespace PixmapHelperXCB
+
diff --git a/xcb/pixmaphelper.h b/xcb/pixmaphelper.h
new file mode 100644
index 0000000..9dfddff
--- /dev/null
+++ b/xcb/pixmaphelper.h
@@ -0,0 +1,34 @@
+/*
+  Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or ( at your option ) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this library; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+*/
+#ifndef PIXMAPHELPER_XCB_H
+#define PIXMAPHELPER_XCB_H
+
+#include <QPixmap>
+#include <QImage>
+
+namespace PixmapHelperXCB
+{
+    void compositePointer(int offsetX, int offsetY, QPixmap &snapshot);
+    QPixmap grabWindow(WId window, int x = 0, int y = 0, int width = -1, int height \
= -1); +
+    uint8_t defaultDepth();
+    QImage::Format findFormat();
+};
+
+#endif
diff --git a/xcb/xcbutils.h b/xcb/xcbutils.h
new file mode 100644
index 0000000..b57b692
--- /dev/null
+++ b/xcb/xcbutils.h
@@ -0,0 +1,209 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2012, 2013 Martin Gräßlin <mgraesslin@kde.org>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#ifndef XCBUTILS_H
+#define XCBUTILS_H
+
+// Qt
+#include <QScopedPointer>
+#include <QRect>
+#include <QX11Info>
+
+// xcb
+#include <X11/Xlib-xcb.h>
+#include <fixx11h.h>
+#include <xcb/xcb.h>
+
+namespace Xcb
+{
+
+inline xcb_connection_t *connection()
+{
+    return XGetXCBConnection(QX11Info::display());
+}
+
+class ServerGrabber
+{
+public:
+    ServerGrabber() {
+        xcb_grab_server(connection());
+    }
+    ~ServerGrabber() {
+        xcb_ungrab_server(connection());
+    }
+};
+
+template <typename T>
+class ScopedCPointer : public QScopedPointer<T, QScopedPointerPodDeleter>
+{
+public:
+    ScopedCPointer(T *p = 0) : QScopedPointer<T, QScopedPointerPodDeleter>(p) {}
+};
+
+template <typename Reply,
+    typename Cookie,
+    Reply *(*replyFunc)(xcb_connection_t*, Cookie, xcb_generic_error_t**),
+    Cookie (*requestFunc)(xcb_connection_t*, xcb_window_t)>
+class Wrapper
+{
+public:
+    Wrapper()
+        : m_retrieved(false)
+        , m_window(XCB_WINDOW_NONE)
+        , m_reply(NULL)
+        {
+            m_cookie.sequence = 0;
+        }
+    explicit Wrapper(xcb_window_t window)
+        : m_retrieved(false)
+        , m_cookie(requestFunc(connection(), window))
+        , m_window(window)
+        , m_reply(NULL)
+    {
+    }
+    explicit Wrapper(const Wrapper &other)
+        : m_retrieved(other.m_retrieved)
+        , m_cookie(other.m_cookie)
+        , m_window(other.m_window)
+        , m_reply(NULL)
+    {
+        takeFromOther(const_cast<Wrapper&>(other));
+    }
+    virtual ~Wrapper() {
+        cleanup();
+    }
+    inline Wrapper &operator=(const Wrapper &other) {
+        if (this != &other) {
+            // if we had managed a reply, free it
+            cleanup();
+            // copy members
+            m_retrieved = other.m_retrieved;
+            m_cookie = other.m_cookie;
+            m_window = other.m_window;
+            m_reply = other.m_reply;
+            // take over the responsibility for the reply pointer
+            takeFromOther(const_cast<Wrapper&>(other));
+        }
+        return *this;
+    }
+
+    inline const Reply *operator->() {
+        getReply();
+        return m_reply;
+    }
+    inline bool isNull() {
+        getReply();
+        return m_reply == NULL;
+    }
+    inline operator bool() {
+        return !isNull();
+    }
+    inline const Reply *data() {
+        getReply();
+        return m_reply;
+    }
+    inline xcb_window_t window() const {
+        return m_window;
+    }
+    inline bool isRetrieved() const {
+        return m_retrieved;
+    }
+    /**
+     * Returns the value of the reply pointer referenced by this object. The reply \
pointer of +     * this object will be reset to null. Calling any method which \
requires the reply to be valid +     * will crash.
+     *
+     * Callers of this function take ownership of the pointer.
+     **/
+    inline Reply *take() {
+        getReply();
+        Reply *ret = m_reply;
+        m_reply = NULL;
+        m_window = XCB_WINDOW_NONE;
+        return ret;
+    }
+
+protected:
+    void getReply() {
+        if (m_retrieved || !m_cookie.sequence) {
+            return;
+        }
+        m_reply = replyFunc(connection(), m_cookie, NULL);
+        m_retrieved = true;
+    }
+
+private:
+    inline void cleanup() {
+        if (!m_retrieved && m_cookie.sequence) {
+            xcb_discard_reply(connection(), m_cookie.sequence);
+        } else if (m_reply) {
+            free(m_reply);
+        }
+    }
+    inline void takeFromOther(Wrapper &other) {
+        if (m_retrieved) {
+            m_reply = other.take();
+        } else {
+            //ensure that other object doesn't try to get the reply or discards it \
in the dtor +            other.m_retrieved = true;
+            other.m_window = XCB_WINDOW_NONE;
+        }
+    }
+    bool m_retrieved;
+    Cookie m_cookie;
+    xcb_window_t m_window;
+    Reply *m_reply;
+};
+
+typedef Wrapper<xcb_get_window_attributes_reply_t, \
xcb_get_window_attributes_cookie_t, &xcb_get_window_attributes_reply, \
&xcb_get_window_attributes_unchecked> WindowAttributes; +
+
+class WindowGeometry : public Wrapper<xcb_get_geometry_reply_t, \
xcb_get_geometry_cookie_t, &xcb_get_geometry_reply, &xcb_get_geometry_unchecked> +{
+public:
+    WindowGeometry() : Wrapper<xcb_get_geometry_reply_t, xcb_get_geometry_cookie_t, \
&xcb_get_geometry_reply, &xcb_get_geometry_unchecked>() {} +    explicit \
WindowGeometry(xcb_window_t window) : Wrapper<xcb_get_geometry_reply_t, \
xcb_get_geometry_cookie_t, &xcb_get_geometry_reply, \
&xcb_get_geometry_unchecked>(window) {} +
+    inline QRect rect() {
+        const xcb_get_geometry_reply_t *geometry = data();
+        if (!geometry) {
+            return QRect();
+        }
+        return QRect(geometry->x, geometry->y, geometry->width, geometry->height);
+    }
+};
+
+class Tree : public Wrapper<xcb_query_tree_reply_t, xcb_query_tree_cookie_t, \
&xcb_query_tree_reply, &xcb_query_tree_unchecked> +{
+public:
+    explicit Tree(xcb_window_t window) : Wrapper<xcb_query_tree_reply_t, \
xcb_query_tree_cookie_t, &xcb_query_tree_reply, &xcb_query_tree_unchecked>(window) {} \
+ +    inline xcb_window_t *children() {
+        return xcb_query_tree_children(data());
+    }
+    inline xcb_window_t parent() {
+        if (isNull())
+            return XCB_WINDOW_NONE;
+        return (*this)->parent;
+    }
+};
+
+} // namespace
+
+#endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic