diff --git a/CMakeLists.txt b/CMakeLists.txt
index d7b0a9d844..70541ab458 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -280,11 +280,11 @@ set(kwin_XCB_LIBS
${XCB_RENDER_LIBRARY}
${XCB_RANDR_LIBRARY}
${XCB_KEYSYMS_LIBRARY}
+ ${XCB_SHM_LIBRARY}
)
set(kwin_WAYLAND_LIBS
${WAYLAND_CLIENT_LIBRARIES}
- ${XCB_SHM_LIBRARY}
${XCB_XTEST_LIBRARY}
)
diff --git a/egl_wayland_backend.cpp b/egl_wayland_backend.cpp
index fcca068dcc..4d4e0a5298 100644
--- a/egl_wayland_backend.cpp
+++ b/egl_wayland_backend.cpp
@@ -22,15 +22,13 @@ along with this program. If not, see .
// kwin
#include "options.h"
#include "wayland_backend.h"
+#include "xcbutils.h"
// kwin libs
#include
// KDE
#include
// Qt
#include
-// system
-#include
-#include
namespace KWin
{
@@ -327,10 +325,10 @@ void EglWaylandBackend::doneCurrent()
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
-Shm *EglWaylandBackend::shm()
+Xcb::Shm *EglWaylandBackend::shm()
{
if (m_shm.isNull()) {
- m_shm.reset(new Shm);
+ m_shm.reset(new Xcb::Shm);
}
return m_shm.data();
}
@@ -380,7 +378,7 @@ bool EglWaylandTexture::loadTexture(const Pixmap &pix, const QSize &size, int de
return false;
m_referencedPixmap = pix;
- Shm *shm = m_backend->shm();
+ Xcb::Shm *shm = m_backend->shm();
if (!shm->isValid()) {
return false;
}
@@ -418,7 +416,7 @@ bool EglWaylandTexture::update(const QRegion &damage)
return false;
}
- Shm *shm = m_backend->shm();
+ Xcb::Shm *shm = m_backend->shm();
if (!shm->isValid()) {
return false;
}
@@ -446,60 +444,4 @@ bool EglWaylandTexture::update(const QRegion &damage)
return true;
}
-Shm::Shm()
- : m_shmId(-1)
- , m_buffer(NULL)
- , m_segment(XCB_NONE)
- , m_valid(false)
-{
- m_valid = init();
-}
-
-Shm::~Shm()
-{
- if (m_valid) {
- xcb_shm_detach(connection(), m_segment);
- shmdt(m_buffer);
- }
-}
-
-bool Shm::init()
-{
- const xcb_query_extension_reply_t *ext = xcb_get_extension_data(connection(), &xcb_shm_id);
- if (!ext || !ext->present) {
- qDebug() << "SHM extension not available";
- return false;
- }
- ScopedCPointer version(xcb_shm_query_version_reply(connection(),
- xcb_shm_query_version_unchecked(connection()), NULL));
- if (version.isNull()) {
- qDebug() << "Failed to get SHM extension version information";
- return false;
- }
- const int MAXSIZE = 4096 * 2048 * 4; // TODO check there are not larger windows
- m_shmId = shmget(IPC_PRIVATE, MAXSIZE, IPC_CREAT | 0600);
- if (m_shmId < 0) {
- qDebug() << "Failed to allocate SHM segment";
- return false;
- }
- m_buffer = shmat(m_shmId, NULL, 0 /*read/write*/);
- if (-1 == reinterpret_cast(m_buffer)) {
- qDebug() << "Failed to attach SHM segment";
- shmctl(m_shmId, IPC_RMID, NULL);
- return false;
- }
- shmctl(m_shmId, IPC_RMID, NULL);
-
- m_segment = xcb_generate_id(connection());
- const xcb_void_cookie_t cookie = xcb_shm_attach_checked(connection(), m_segment, m_shmId, false);
- ScopedCPointer error(xcb_request_check(connection(), cookie));
- if (!error.isNull()) {
- qDebug() << "xcb_shm_attach error: " << error->error_code;
- shmdt(m_buffer);
- return false;
- }
-
- return true;
-}
-
} // namespace
diff --git a/egl_wayland_backend.h b/egl_wayland_backend.h
index 84eace92c6..6c5ac39d53 100644
--- a/egl_wayland_backend.h
+++ b/egl_wayland_backend.h
@@ -22,8 +22,6 @@ along with this program. If not, see .
#include "scene_opengl.h"
// wayland
#include
-// xcb
-#include
class QTemporaryFile;
struct wl_buffer;
@@ -36,7 +34,9 @@ namespace Wayland {
class WaylandBackend;
}
-class Shm;
+namespace Xcb {
+ class Shm;
+}
/**
* @brief OpenGL Backend using Egl on a Wayland surface.
@@ -66,7 +66,7 @@ public:
virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion);
virtual bool makeCurrent() override;
virtual void doneCurrent() override;
- Shm *shm();
+ Xcb::Shm *shm();
protected:
virtual void present();
@@ -87,7 +87,7 @@ private:
int m_bufferAge;
Wayland::WaylandBackend *m_wayland;
wl_egl_window *m_overlay;
- QScopedPointer m_shm;
+ QScopedPointer m_shm;
friend class EglWaylandTexture;
};
@@ -114,51 +114,6 @@ private:
xcb_pixmap_t m_referencedPixmap;
};
-/**
- * @brief Small helper class to encapsulate SHM related functionality.
- *
- */
-class Shm
-{
-public:
- Shm();
- ~Shm();
- int shmId() const;
- void *buffer() const;
- xcb_shm_seg_t segment() const;
- bool isValid() const;
-private:
- bool init();
- int m_shmId;
- void *m_buffer;
- xcb_shm_seg_t m_segment;
- bool m_valid;
-};
-
-inline
-void *Shm::buffer() const
-{
- return m_buffer;
-}
-
-inline
-bool Shm::isValid() const
-{
- return m_valid;
-}
-
-inline
-xcb_shm_seg_t Shm::segment() const
-{
- return m_segment;
-}
-
-inline
-int Shm::shmId() const
-{
- return m_shmId;
-}
-
} // namespace
#endif // KWIN_EGL_ON_X_BACKEND_H
diff --git a/xcbutils.cpp b/xcbutils.cpp
index a287c3ca38..5bff1de8f2 100644
--- a/xcbutils.cpp
+++ b/xcbutils.cpp
@@ -30,6 +30,9 @@ along with this program. If not, see .
#include
#include
#include
+// system
+#include
+#include
namespace KWin {
@@ -254,5 +257,64 @@ QVector Extensions::extensions() const
return extensions;
}
+//****************************************
+// Shm
+//****************************************
+Shm::Shm()
+ : m_shmId(-1)
+ , m_buffer(NULL)
+ , m_segment(XCB_NONE)
+ , m_valid(false)
+{
+ m_valid = init();
+}
+
+Shm::~Shm()
+{
+ if (m_valid) {
+ xcb_shm_detach(connection(), m_segment);
+ shmdt(m_buffer);
+ }
+}
+
+bool Shm::init()
+{
+ const xcb_query_extension_reply_t *ext = xcb_get_extension_data(connection(), &xcb_shm_id);
+ if (!ext || !ext->present) {
+ qDebug() << "SHM extension not available";
+ return false;
+ }
+ ScopedCPointer version(xcb_shm_query_version_reply(connection(),
+ xcb_shm_query_version_unchecked(connection()), NULL));
+ if (version.isNull()) {
+ qDebug() << "Failed to get SHM extension version information";
+ return false;
+ }
+ const int MAXSIZE = 4096 * 2048 * 4; // TODO check there are not larger windows
+ m_shmId = shmget(IPC_PRIVATE, MAXSIZE, IPC_CREAT | 0600);
+ if (m_shmId < 0) {
+ qDebug() << "Failed to allocate SHM segment";
+ return false;
+ }
+ m_buffer = shmat(m_shmId, NULL, 0 /*read/write*/);
+ if (-1 == reinterpret_cast(m_buffer)) {
+ qDebug() << "Failed to attach SHM segment";
+ shmctl(m_shmId, IPC_RMID, NULL);
+ return false;
+ }
+ shmctl(m_shmId, IPC_RMID, NULL);
+
+ m_segment = xcb_generate_id(connection());
+ const xcb_void_cookie_t cookie = xcb_shm_attach_checked(connection(), m_segment, m_shmId, false);
+ ScopedCPointer error(xcb_request_check(connection(), cookie));
+ if (!error.isNull()) {
+ qDebug() << "xcb_shm_attach error: " << error->error_code;
+ shmdt(m_buffer);
+ return false;
+ }
+
+ return true;
+}
+
} // namespace Xcb
} // namespace KWin
diff --git a/xcbutils.h b/xcbutils.h
index 6c44920be0..4ce56eac25 100644
--- a/xcbutils.h
+++ b/xcbutils.h
@@ -31,6 +31,8 @@ along with this program. If not, see .
#include
#include
+#include
+
namespace KWin {
namespace Xcb {
@@ -908,6 +910,51 @@ void selectInput(xcb_window_t window, uint32_t events)
xcb_change_window_attributes(connection(), window, XCB_CW_EVENT_MASK, &events);
}
+/**
+ * @brief Small helper class to encapsulate SHM related functionality.
+ *
+ */
+class Shm
+{
+public:
+ Shm();
+ ~Shm();
+ int shmId() const;
+ void *buffer() const;
+ xcb_shm_seg_t segment() const;
+ bool isValid() const;
+private:
+ bool init();
+ int m_shmId;
+ void *m_buffer;
+ xcb_shm_seg_t m_segment;
+ bool m_valid;
+};
+
+inline
+void *Shm::buffer() const
+{
+ return m_buffer;
+}
+
+inline
+bool Shm::isValid() const
+{
+ return m_valid;
+}
+
+inline
+xcb_shm_seg_t Shm::segment() const
+{
+ return m_segment;
+}
+
+inline
+int Shm::shmId() const
+{
+ return m_shmId;
+}
+
} // namespace X11
} // namespace KWin