From 93e0fc1476757331d25b9fe2d357e930eda55331 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B8rgen=20Lind?= <jorgen.lind@nokia.com>
Date: Tue, 1 Mar 2011 10:06:31 +0100
Subject: Lighthouse: Xcb. implement dri2 context handling

---
 src/plugins/platforms/xcb/qdri2context.cpp    | 224 ++++++++++++++++++++++++++
 src/plugins/platforms/xcb/qdri2context.h      |  34 ++++
 src/plugins/platforms/xcb/qxcbconnection.cpp  | 131 ++++++++++++++-
 src/plugins/platforms/xcb/qxcbconnection.h    |  23 ++-
 src/plugins/platforms/xcb/qxcbintegration.cpp |   9 +-
 src/plugins/platforms/xcb/qxcbwindow.cpp      |  16 +-
 src/plugins/platforms/xcb/xcb.pro             |  48 +++---
 7 files changed, 460 insertions(+), 25 deletions(-)
 create mode 100644 src/plugins/platforms/xcb/qdri2context.cpp
 create mode 100644 src/plugins/platforms/xcb/qdri2context.h

diff --git a/src/plugins/platforms/xcb/qdri2context.cpp b/src/plugins/platforms/xcb/qdri2context.cpp
new file mode 100644
index 0000000..44b8fc2
--- /dev/null
+++ b/src/plugins/platforms/xcb/qdri2context.cpp
@@ -0,0 +1,224 @@
+#include "qdri2context.h"
+
+#include "qxcbwindow.h"
+#include "qxcbconnection.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/QWidget>
+
+#include <xcb/dri2.h>
+#include <xcb/xfixes.h>
+
+#define MESA_EGL_NO_X11_HEADERS
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#define GL_GLEXT_PROTOTYPES
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+class QDri2ContextPrivate
+{
+public:
+    QDri2ContextPrivate(QXcbWindow *window)
+        : qXcbWindow(window)
+        , windowFormat(window->widget()->platformWindowFormat())
+        , image(0)
+    {
+    }
+
+    xcb_window_t xcbWindow() { return qXcbWindow->window(); }
+    xcb_connection_t *xcbConnection() { return qXcbWindow->xcb_connection(); }
+
+    QXcbWindow *qXcbWindow;
+    QPlatformWindowFormat windowFormat;
+
+    EGLContext eglContext;
+
+    EGLImageKHR image;
+
+    GLuint fbo;
+    GLuint rbo;
+    GLuint depth;
+
+    QSize size;
+};
+
+QDri2Context::QDri2Context(QXcbWindow *window)
+    : d_ptr(new QDri2ContextPrivate(window))
+{
+    Q_D(QDri2Context);
+
+    static const EGLint contextAttribs[] = {
+            EGL_CONTEXT_CLIENT_VERSION, 2,
+            EGL_NONE
+    };
+
+    eglBindAPI(EGL_OPENGL_ES_API);
+
+    EGLContext shareContext = EGL_NO_CONTEXT;
+    if (window->widget()->platformWindowFormat().sharedGLContext()) {
+        QDri2Context *context = static_cast<QDri2Context *>(window->widget()->platformWindowFormat().sharedGLContext());
+        shareContext = context->d_func()->eglContext;
+    }
+    d->eglContext = eglCreateContext(EGL_DISPLAY_FROM_XCB(d->qXcbWindow), NULL,
+                                               shareContext, contextAttribs);
+
+    if (d->eglContext == EGL_NO_CONTEXT) {
+        qDebug() << "No eglContext!" << eglGetError();
+    }
+
+    EGLBoolean makeCurrentSuccess = eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,d->eglContext);
+    if (!makeCurrentSuccess) {
+        qDebug() << "eglMakeCurrent failed!" << eglGetError();
+    }
+
+    xcb_dri2_create_drawable (d->xcbConnection(), d->xcbWindow());
+
+    glGenFramebuffers(1,&d->fbo);
+    glBindFramebuffer(GL_FRAMEBUFFER,d->fbo);
+    glActiveTexture(GL_TEXTURE0);
+
+    glGenRenderbuffers(1, &d->rbo);
+    glBindRenderbuffer(GL_RENDERBUFFER, d->rbo);
+
+    glGenRenderbuffers(1,&d->depth);
+    glBindRenderbuffer(GL_RENDERBUFFER, d->depth);
+
+    resize(d->qXcbWindow->widget()->geometry().size());
+
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, d->rbo);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERER,d->depth);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERER,d->depth);
+
+    //restore the old current context
+    const QPlatformGLContext *currentContext = QPlatformGLContext::currentContext();
+    if (currentContext)
+        const_cast<QPlatformGLContext*>(currentContext)->makeCurrent();
+}
+
+QDri2Context::~QDri2Context()
+{
+    //cleanup
+}
+
+void QDri2Context::makeCurrent()
+{
+    QPlatformGLContext::makeCurrent();
+    Q_D(QDri2Context);
+
+    eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,d->eglContext);
+    glBindFramebuffer(GL_FRAMEBUFFER,d->fbo);
+
+}
+
+void QDri2Context::doneCurrent()
+{
+    QPlatformGLContext::doneCurrent();
+    Q_D(QDri2Context);
+    eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+}
+
+void QDri2Context::swapBuffers()
+{
+    Q_D(QDri2Context);
+    xcb_rectangle_t rectangle;
+    rectangle.x = 0;
+    rectangle.y = 0;
+    rectangle.width = d->qXcbWindow->widget()->geometry().width();
+    rectangle.height = d->qXcbWindow->widget()->geometry().height();
+
+    xcb_xfixes_region_t xfixesRegion = xcb_generate_id(d->xcbConnection());
+    xcb_xfixes_create_region(d->xcbConnection(), xfixesRegion,
+                             1, &rectangle);
+
+    xcb_dri2_copy_region_cookie_t cookie = xcb_dri2_copy_region_unchecked(d->xcbConnection(),
+                                                                          d->qXcbWindow->window(),
+                                                                          xfixesRegion,
+                                                                          XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
+                                                                          XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT);
+
+    xcb_dri2_copy_region_reply_t *reply = xcb_dri2_copy_region_reply(d->xcbConnection(),cookie,NULL);
+
+    //cleanup
+    delete reply;
+    xcb_xfixes_destroy_region(d->xcbConnection(), xfixesRegion);
+
+}
+
+void * QDri2Context::getProcAddress(const QString &procName)
+{
+    return (void *)eglGetProcAddress(qPrintable(procName));
+}
+
+void QDri2Context::resize(const QSize &size)
+{
+    Q_D(QDri2Context);
+    d->size= size;
+
+    glBindFramebuffer(GL_FRAMEBUFFER,d->fbo);
+
+    xcb_dri2_dri2_buffer_t *backBfr = backBuffer();
+
+    if (d->image) {
+        qDebug() << "destroing image";
+        eglDestroyImageKHR(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),d->image);
+    }
+
+    EGLint imgAttribs[] = {
+        EGL_WIDTH,                      d->size.width(),
+        EGL_HEIGHT,                     d->size.height(),
+        EGL_DRM_BUFFER_STRIDE_MESA,     backBfr->pitch /4,
+        EGL_DRM_BUFFER_FORMAT_MESA,     EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+        EGL_NONE
+    };
+
+    d->image = eglCreateImageKHR(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),
+                                EGL_NO_CONTEXT,
+                                EGL_DRM_BUFFER_MESA,
+                                (EGLClientBuffer) backBfr->name,
+                                imgAttribs);
+
+    glBindRenderbuffer(GL_RENDERBUFFER, d->rbo);
+    glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
+                                           d->image);
+
+    glBindRenderbuffer(GL_RENDERBUFFER, d->depth);
+    glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8_OES,d->size.width(), d->size.height());
+
+}
+
+QPlatformWindowFormat QDri2Context::platformWindowFormat() const
+{
+    Q_D(const QDri2Context);
+    return d->windowFormat;
+}
+
+xcb_dri2_dri2_buffer_t * QDri2Context::backBuffer()
+{
+    Q_D(QDri2Context);
+
+    unsigned int backBufferAttachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT;
+    xcb_dri2_get_buffers_cookie_t cookie = xcb_dri2_get_buffers_unchecked (d->xcbConnection(),
+                                                                           d->xcbWindow(),
+                                                                           1, 1, &backBufferAttachment);
+
+    xcb_dri2_get_buffers_reply_t *reply = xcb_dri2_get_buffers_reply (d->xcbConnection(), cookie, NULL);
+    if (!reply) {
+        qDebug() << "failed to get buffers reply";
+        return 0;
+    }
+
+    xcb_dri2_dri2_buffer_t *buffers = xcb_dri2_get_buffers_buffers (reply);
+    if (!buffers) {
+        qDebug() << "failed to get buffers";
+        return 0;
+    }
+
+    Q_ASSERT(reply->count == 1);
+
+    delete reply;
+
+    return buffers;
+}
diff --git a/src/plugins/platforms/xcb/qdri2context.h b/src/plugins/platforms/xcb/qdri2context.h
new file mode 100644
index 0000000..5646565
--- /dev/null
+++ b/src/plugins/platforms/xcb/qdri2context.h
@@ -0,0 +1,34 @@
+#ifndef QDRI2CONTEXT_H
+#define QDRI2CONTEXT_H
+
+#include <QtGui/QPlatformGLContext>
+
+class QXcbWindow;
+class QDri2ContextPrivate;
+
+struct xcb_dri2_dri2_buffer_t;
+
+class QDri2Context : public QPlatformGLContext
+{
+    Q_DECLARE_PRIVATE(QDri2Context);
+public:
+    QDri2Context(QXcbWindow *window);
+    ~QDri2Context();
+
+    void makeCurrent();
+    void doneCurrent();
+    void swapBuffers();
+    void* getProcAddress(const QString& procName);
+
+    void resize(const QSize &size);
+
+    QPlatformWindowFormat platformWindowFormat() const;
+
+protected:
+    xcb_dri2_dri2_buffer_t *backBuffer();
+    QScopedPointer<QDri2ContextPrivate> d_ptr;
+private:
+    Q_DISABLE_COPY(QDri2Context)
+};
+
+#endif // QDRI2CONTEXT_H
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 967aa4d..06e4d13 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -46,16 +46,38 @@
 
 #include <QtAlgorithms>
 #include <QSocketNotifier>
+#include <QtGui/private/qapplication_p.h>
+
+#include <QtCore/QDebug>
 
 #include <stdio.h>
+#include <errno.h>
 
 #ifdef XCB_USE_XLIB
 #include <X11/Xlib.h>
 #include <X11/Xlib-xcb.h>
 #endif
 
+#ifdef XCB_USE_DRI2
+#include <xcb/dri2.h>
+#include <xcb/xfixes.h>
+extern "C" {
+#include <xf86drm.h>
+}
+#define MESA_EGL_NO_X11_HEADERS
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
 QXcbConnection::QXcbConnection(const char *displayName)
     : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
+#ifdef XCB_USE_DRI2
+    , m_dri2_major(0)
+    , m_dri2_minor(0)
+    , m_dri2_support_probed(false)
+    , m_has_support_for_dri2(false)
+#endif
 {
     int primaryScreen = 0;
 
@@ -67,8 +89,8 @@ QXcbConnection::QXcbConnection(const char *displayName)
     m_xlib_display = dpy;
 #else
     m_connection = xcb_connect(m_displayName.constData(), &primaryScreen);
-#endif
 
+#endif //XCB_USE_XLIB
     m_setup = xcb_get_setup(xcb_connection());
 
     xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
@@ -85,6 +107,10 @@ QXcbConnection::QXcbConnection(const char *displayName)
     m_keyboard = new QXcbKeyboard(this);
 
     initializeAllAtoms();
+
+#ifdef XCB_USE_DRI2
+    initializeDri2();
+#endif
 }
 
 QXcbConnection::~QXcbConnection()
@@ -124,7 +150,7 @@ break;
 } \
 break;
 
-#define XCB_EVENT_DEBUG
+//#define XCB_EVENT_DEBUG
 
 void printXcbEvent(const char *message, xcb_generic_event_t *event)
 {
@@ -405,3 +431,104 @@ void QXcbConnection::initializeAllAtoms() {
     for (i = 0; i < QXcbAtom::NAtoms; ++i)
         m_allAtoms[i] = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0)->atom;
 }
+
+#ifdef XCB_USE_DRI2
+void QXcbConnection::initializeDri2()
+{
+    xcb_dri2_connect_cookie_t connect_cookie = xcb_dri2_connect_unchecked (m_connection,
+                                                                           m_screens[0]->root(),
+                                                                           XCB_DRI2_DRIVER_TYPE_DRI);
+
+    xcb_dri2_connect_reply_t *connect = xcb_dri2_connect_reply (m_connection,
+                                                                connect_cookie, NULL);
+
+    if (! connect || connect->driver_name_length + connect->device_name_length == 0) {
+        qDebug() << "Failed to connect to dri2";
+        return;
+    }
+
+    QString dri2DeviceName = QString::fromLocal8Bit(xcb_dri2_connect_device_name (connect),
+                                                    xcb_dri2_connect_device_name_length (connect));
+    delete connect;
+
+    int fd = open(qPrintable(dri2DeviceName), O_RDWR);
+    if (fd < 0) {
+        qDebug() << "InitializeDri2: Could'nt open device << dri2DeviceName";
+        return;
+    }
+
+    drm_magic_t magic;
+    if (drmGetMagic(fd, &magic)) {
+        qDebug() << "Failed to get drmMagic";
+        return;
+    }
+
+    xcb_dri2_authenticate_cookie_t authenticate_cookie = xcb_dri2_authenticate_unchecked(m_connection,
+                                                                                         m_screens[0]->root(), magic);
+    xcb_dri2_authenticate_reply_t *authenticate = xcb_dri2_authenticate_reply(m_connection,
+                                                                              authenticate_cookie, NULL);
+    if (authenticate == NULL || !authenticate->authenticated) {
+        fprintf(stderr, "DRI2: failed to authenticate\n");
+        free(authenticate);
+        return;
+    }
+
+    delete authenticate;
+
+    EGLDisplay display = eglGetDRMDisplayMESA(fd);
+    if (!display) {
+        fprintf(stderr, "failed to create display\n");
+        return;
+    }
+
+    m_egl_display = display;
+    EGLint major,minor;
+    if (!eglInitialize(display, &major, &minor)) {
+        fprintf(stderr, "failed to initialize display\n");
+        return;
+    }
+}
+
+bool QXcbConnection::hasSupportForDri2() const
+{
+    if (!m_dri2_support_probed) {
+        xcb_generic_error_t *error = 0;
+
+        xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
+        xcb_prefetch_extension_data (m_connection, &xcb_dri2_id);
+
+        xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
+                                                                                         XCB_XFIXES_MAJOR_VERSION,
+                                                                                         XCB_XFIXES_MINOR_VERSION);
+
+        xcb_dri2_query_version_cookie_t dri2_query_cookie = xcb_dri2_query_version (m_connection,
+                                                                                    XCB_DRI2_MAJOR_VERSION,
+                                                                                    XCB_DRI2_MINOR_VERSION);
+
+        xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
+                                                                                         xfixes_query_cookie, &error);
+        if (!xfixes_query || error || xfixes_query->major_version < 2) {
+            delete error;
+            delete xfixes_query;
+            return false;
+        }
+        delete xfixes_query;
+
+        xcb_dri2_query_version_reply_t *dri2_query = xcb_dri2_query_version_reply (m_connection,
+                                                                                   dri2_query_cookie, &error);
+        if (!dri2_query || error) {
+            delete error;
+            delete dri2_query;
+            return false;
+        }
+
+        QXcbConnection *that = const_cast<QXcbConnection *>(this);
+        that->m_dri2_major = dri2_query->major_version;
+        that->m_dri2_minor = dri2_query->minor_version;
+
+        that->m_has_support_for_dri2 = true;
+        that->m_dri2_support_probed = true;
+    }
+    return m_has_support_for_dri2;
+}
+#endif //XCB_USE_DRI2
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 6a472a7..3aa36db 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -236,11 +236,19 @@ public:
     void *xlib_display() const { return m_xlib_display; }
 #endif
 
+#ifdef XCB_USE_DRI2
+    bool hasSupportForDri2() const;
+    void *egl_display() const { return m_egl_display; }
+#endif
+
 private slots:
     void eventDispatcher();
 
 private:
     void initializeAllAtoms();
+#ifdef XCB_USE_DRI2
+    void initializeDri2();
+#endif
 
     xcb_connection_t *m_connection;
     const xcb_setup_t *m_setup;
@@ -254,11 +262,24 @@ private:
 
     QXcbKeyboard *m_keyboard;
 
-#ifdef XCB_USE_XLIB
+#if defined(XCB_USE_XLIB)
     void *m_xlib_display;
 #endif
+
+#ifdef XCB_USE_DRI2
+    uint32_t m_dri2_major;
+    uint32_t m_dri2_minor;
+    bool m_dri2_support_probed;
+    bool m_has_support_for_dri2;
+    void *m_egl_display;
+#endif
+
 };
 
 #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
 
+#ifdef XCB_USE_DRI2
+#define EGL_DISPLAY_FROM_XCB(object) ((EGLDisplay)(object->connection()->egl_display()))
+#endif //endifXCB_USE_DRI2
+
 #endif
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 6dc5a5c..7f6d4c5 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -136,7 +136,12 @@ bool QXcbIntegration::hasOpenGL() const
         wasEglInitialized = eglInitialize(disp,&major,&minor);
     }
     return wasEglInitialized;
-#else
-    return false;
+#elif defined(XCB_USE_DRI2)
+    if (m_connection->hasSupportForDri2()) {
+        return true;
+    }
 #endif
+    return false;
+}
+
 }
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index bb856f2..005aa0e 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -43,6 +43,9 @@
 
 #include "qxcbconnection.h"
 #include "qxcbscreen.h"
+#ifdef XCB_USE_DRI2
+#include "qdri2context.h"
+#endif
 
 #include <xcb/xcb_icccm.h>
 
@@ -137,7 +140,7 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
                 qFatal("no window!");
             }
     } else
-#endif
+#endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
     {
         m_window = xcb_generate_id(xcb_connection());
 
@@ -437,6 +440,12 @@ QPlatformGLContext *QXcbWindow::glContext() const
         QXcbWindow *that = const_cast<QXcbWindow *>(this);
         that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
     }
+#elif defined(XCB_USE_DRI2)
+    if (!m_context) {
+        QXcbWindow *that = const_cast<QXcbWindow *>(this);
+        that->m_context = new QDri2Context(that);
+    }
+
 #endif
     return m_context;
 }
@@ -474,6 +483,11 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
     QPlatformWindow::setGeometry(rect);
 
     QWindowSystemInterface::handleGeometryChange(widget(), rect);
+
+#if XCB_USE_DRI2
+    if (m_context)
+        static_cast<QDri2Context *>(m_context)->resize(rect.size());
+#endif
 }
 
 static Qt::MouseButtons translateMouseButtons(int s)
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index b5850e4..9a3f735 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -23,26 +23,36 @@ HEADERS = \
 
 contains(QT_CONFIG, opengl) {
     QT += opengl
-    DEFINES += XCB_USE_XLIB
-    LIBS += -lX11 -lX11-xcb
-
-    contains(QT_CONFIG, opengles2) {
-        DEFINES += XCB_USE_EGL
-        HEADERS += \
-            ../eglconvenience/qeglplatformcontext.h \
-            ../eglconvenience/qeglconvenience.h \
-            ../eglconvenience/qxlibeglintegration.h
-
-        SOURCES += \
-            ../eglconvenience/qeglplatformcontext.cpp \
-            ../eglconvenience/qeglconvenience.cpp \
-            ../eglconvenience/qxlibeglintegration.cpp
-
-        LIBS += -lEGL
+
+    DEFINES += XCB_USE_DRI2
+    contains(DEFINES, XCB_USE_DRI2) {
+        LIBS += -lxcb-dri2 -lxcb-xfixes -lEGL
+
+        HEADERS += qdri2context.h
+        SOURCES += qdri2context.cpp
+
     } else {
-        DEFINES += XCB_USE_GLX
-        HEADERS += qglxintegration.h
-        SOURCES += qglxintegration.cpp
+        DEFINES += XCB_USE_XLIB
+        LIBS += -lX11 -lX11-xcb
+
+        contains(QT_CONFIG, opengles2) {
+            DEFINES += XCB_USE_EGL
+            HEADERS += \
+                ../eglconvenience/qeglplatformcontext.h \
+                ../eglconvenience/qeglconvenience.h \
+                ../eglconvenience/qxlibeglintegration.h
+
+            SOURCES += \
+                ../eglconvenience/qeglplatformcontext.cpp \
+                ../eglconvenience/qeglconvenience.cpp \
+                ../eglconvenience/qxlibeglintegration.cpp
+
+            LIBS += -lEGL
+        } else {
+            DEFINES += XCB_USE_GLX
+            HEADERS += qglxintegration.h
+            SOURCES += qglxintegration.cpp
+        }
     }
 }
 
-- 
cgit v0.12