summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp38
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp35
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
6 files changed, 51 insertions, 29 deletions
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index e504d93fba..3f1c53b122 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -167,6 +167,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
, m_shareContext(0)
, m_format(format)
, m_isPBufferCurrent(false)
+ , m_swapInterval(-1)
{
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
m_format.setRenderableType(QSurfaceFormat::OpenGL);
@@ -326,19 +327,50 @@ QGLXContext::~QGLXContext()
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
{
+ bool success = false;
Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Display *dpy = DISPLAY_FROM_XCB(m_screen);
+ GLXDrawable glxDrawable = 0;
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
if (surfaceClass == QSurface::Window) {
m_isPBufferCurrent = false;
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
- return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), window->xcb_window(), m_context);
+ glxDrawable = window->xcb_window();
+ success = glXMakeCurrent(dpy, glxDrawable, m_context);
} else if (surfaceClass == QSurface::Offscreen) {
m_isPBufferCurrent = true;
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
- return glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), pbuffer->pbuffer(), pbuffer->pbuffer(), m_context);
+ glxDrawable = pbuffer->pbuffer();
+ success = glXMakeContextCurrent(dpy, glxDrawable, glxDrawable, m_context);
+ }
+
+ if (success) {
+ int interval = surface->format().swapInterval();
+ if (interval >= 0 && m_swapInterval != interval) {
+ m_swapInterval = interval;
+ typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
+ typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
+ static qt_glXSwapIntervalEXT glXSwapIntervalEXT = 0;
+ static qt_glXSwapIntervalMESA glXSwapIntervalMESA = 0;
+ static bool resolved = false;
+ if (!resolved) {
+ resolved = true;
+ QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(dpy,
+ m_screen->screenNumber())).split(' ');
+ if (glxExt.contains("GLX_EXT_swap_control"))
+ glXSwapIntervalEXT = (qt_glXSwapIntervalEXT) getProcAddress("glXSwapIntervalEXT");
+ if (glxExt.contains("GLX_MESA_swap_control"))
+ glXSwapIntervalMESA = (qt_glXSwapIntervalMESA) getProcAddress("glXSwapIntervalMESA");
+ }
+ if (glXSwapIntervalEXT)
+ glXSwapIntervalEXT(dpy, glxDrawable, interval);
+ else if (glXSwapIntervalMESA)
+ glXSwapIntervalMESA(interval);
+ }
}
- return false;
+
+ return success;
}
void QGLXContext::doneCurrent()
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index dcc7fe8855..00bba94ab3 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -81,7 +81,7 @@ private:
GLXContext m_shareContext;
QSurfaceFormat m_format;
bool m_isPBufferCurrent;
-
+ int m_swapInterval;
static bool m_queriedDummyContext;
static bool m_supportsThreading;
};
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index c00b4d551b..6fd2241f71 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -320,23 +320,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeXRandr();
updateScreens();
- m_connectionEventListener = xcb_generate_id(m_connection);
- xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
- m_connectionEventListener, m_screens.at(0)->root(),
- 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- m_screens.at(0)->screen()->root_visual, 0, 0);
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt xcb connection listener window");
- Q_XCB_CALL(xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_connectionEventListener,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData()));
-#endif
-
initializeGLX();
initializeXFixes();
initializeXRender();
@@ -373,9 +356,6 @@ QXcbConnection::~QXcbConnection()
#ifndef QT_NO_DRAGANDDROP
delete m_drag;
#endif
- // Delete screens in reverse order to avoid crash in case of multiple screens
- while (!m_screens.isEmpty())
- delete m_screens.takeLast();
#ifdef XCB_USE_XINPUT2_MAEMO
finalizeXInput2Maemo();
@@ -390,6 +370,10 @@ QXcbConnection::~QXcbConnection()
delete m_reader;
+ // Delete screens in reverse order to avoid crash in case of multiple screens
+ while (!m_screens.isEmpty())
+ delete m_screens.takeLast();
+
#ifdef XCB_USE_EGL
if (m_has_egl)
eglTerminate(m_egl_display);
@@ -1067,14 +1051,21 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
xcb_client_message_event_t event;
memset(&event, 0, sizeof(event));
+ const xcb_window_t eventListener = xcb_generate_id(m_connection);
+ Q_XCB_CALL(xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
+ eventListener, m_screens.at(0)->root(),
+ 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
+ m_screens.at(0)->screen()->root_visual, 0, 0));
+
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.sequence = 0;
- event.window = m_connectionEventListener;
+ event.window = eventListener;
event.type = atom(a);
event.data.data32[0] = id;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_destroy_window(m_connection, eventListener));
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index ff7a6dd606..3a71eb2574 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -521,8 +521,6 @@ private:
QByteArray m_displayName;
- xcb_window_t m_connectionEventListener;
-
QXcbKeyboard *m_keyboard;
#ifndef QT_NO_CLIPBOARD
QXcbClipboard *m_clipboard;
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index 9d81c8e224..8c10b134bd 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -50,6 +50,7 @@
#include <X11/SM/SMlib.h>
#include <errno.h> // ERANGE
+#include <cerrno> // ERANGE
class QSmSocketReceiver : public QObject
{
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index e2c6932992..806f948cc2 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -293,7 +293,7 @@ void QXcbWindow::create()
#elif defined(XCB_USE_EGL)
EGLDisplay eglDisplay = connection()->egl_display();
EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, m_format, true);
- m_format = q_glFormatFromConfig(eglDisplay, eglConfig);
+ m_format = q_glFormatFromConfig(eglDisplay, eglConfig, m_format);
VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);