Fixed non-GL applications crashing when GLX/EGL initialization fails on xcb.
[profile/ivi/qtbase.git] / src / plugins / platforms / xcb / qxcbwindow.cpp
index a4ee2a4..7020e63 100644 (file)
@@ -64,6 +64,9 @@
 #include <xcb/xcb_icccm.h>
 #undef class
 #include <xcb/xfixes.h>
+#ifndef QT_NO_SHAPE
+#  include <xcb/shape.h>
+#endif // QT_NO_SHAPE
 
 // xcb-icccm 3.8 support
 #ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS
 #include <private/qwindow_p.h>
 
 #include <qpa/qplatformbackingstore.h>
-#include <QtGui/QWindowSystemInterface>
+#include <qpa/qwindowsysteminterface.h>
 
 #include <stdio.h>
 
 #ifdef XCB_USE_XLIB
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
-#ifndef QT_NO_SHAPE
-#  include <X11/extensions/shape.h>
-#endif // QT_NO_SHAPE
 #endif
 
-#ifdef XCB_USE_XINPUT2_MAEMO
+#if defined(XCB_USE_XINPUT2_MAEMO) || defined(XCB_USE_XINPUT2)
 #include <X11/extensions/XInput2.h>
 #endif
 
@@ -238,7 +238,7 @@ void QXcbWindow::create()
     {
 #if defined(XCB_USE_GLX)
         XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber(), &m_format);
-        if (!visualInfo)
+        if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
             qFatal("Could not initialize GLX");
 #elif defined(XCB_USE_EGL)
         EGLDisplay eglDisplay = connection()->egl_display();
@@ -254,26 +254,30 @@ void QXcbWindow::create()
         XVisualInfo *visualInfo;
         int matchingCount = 0;
         visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
-        if (!visualInfo)
+        if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
             qFatal("Could not initialize EGL");
 #endif //XCB_USE_GLX
-        m_depth = visualInfo->depth;
-        m_imageFormat = imageFormatForDepth(m_depth);
-        Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone);
+        if (visualInfo) {
+            m_depth = visualInfo->depth;
+            m_imageFormat = imageFormatForDepth(m_depth);
+            Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone);
 
-        XSetWindowAttributes a;
-        a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
-        a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
-        a.colormap = cmap;
+            XSetWindowAttributes a;
+            a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
+            a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
+            a.colormap = cmap;
 
-        m_visualId = visualInfo->visualid;
+            m_visualId = visualInfo->visualid;
 
-        m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
-                                  0, visualInfo->depth, InputOutput, visualInfo->visual,
-                                  CWBackPixel|CWBorderPixel|CWColormap, &a);
+            m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
+                                      0, visualInfo->depth, InputOutput, visualInfo->visual,
+                                      CWBackPixel|CWBorderPixel|CWColormap, &a);
 
-        XFree(visualInfo);
-    } else
+            XFree(visualInfo);
+        }
+    }
+
+    if (!m_window)
 #endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
     {
         m_window = xcb_generate_id(xcb_connection());
@@ -359,7 +363,7 @@ void QXcbWindow::create()
                                    1, &leader));
 
 #ifdef XCB_USE_XINPUT2_MAEMO
-    if (connection()->isUsingXInput2()) {
+    if (connection()->isUsingXInput2Maemo()) {
         XIEventMask xieventmask;
         uchar bitmask[2] = { 0, 0 };
 
@@ -373,6 +377,8 @@ void QXcbWindow::create()
 
         XISelectEvents(DISPLAY_FROM_XCB(this), m_window, &xieventmask, 1);
     }
+#elif defined(XCB_USE_XINPUT2)
+    connection()->xi2Select(m_window);
 #endif
 
     setWindowFlags(window()->windowFlags());
@@ -407,6 +413,7 @@ void QXcbWindow::destroy()
         }
         connection()->removeWindow(m_window);
         Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
+        m_window = 0;
     }
     m_mapped = false;
 
@@ -1693,7 +1700,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
         xev.data.data32[2] = left ? 6 : 4; // bottomleft/bottomright
     else
         xev.data.data32[2] = left ? 0 : 2; // topleft/topright
-    xev.data.data32[3] = Button1;
+    xev.data.data32[3] = XCB_BUTTON_INDEX_1;
     xev.data.data32[4] = 0;
     xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME);
     xcb_send_event(connection()->xcb_connection(), false, m_screen->root(),
@@ -1702,11 +1709,11 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
     return true;
 }
 
-#if defined(XCB_USE_XLIB) && !defined(QT_NO_SHAPE)
+#if !defined(QT_NO_SHAPE)
 
-static inline XRectangle qRectToX11Rectangle(const QRect &r)
+static inline xcb_rectangle_t qRectToXCBRectangle(const QRect &r)
 {
-    XRectangle result;
+    xcb_rectangle_t result;
     result.x = qMax(SHRT_MIN, r.x());
     result.y = qMax(SHRT_MIN, r.y());
     result.width = qMin((int)USHRT_MAX, r.width());
@@ -1714,42 +1721,23 @@ static inline XRectangle qRectToX11Rectangle(const QRect &r)
     return result;
 }
 
-static inline Region qRegionToX11Region(const QRegion &region)
-{
-    if (region.isEmpty())
-        return None;
-    Region result = XCreateRegion();
-    if (!result)
-        return None;
-    const QVector<QRect> rects = region.rects();
-    if (rects.size() == 1) {
-        XRectangle xrect = qRectToX11Rectangle(region.boundingRect());
-        XUnionRectWithRegion(&xrect, result, result);
-    } else {
-        foreach (const QRect &r, rects) {
-            XRectangle xrect = qRectToX11Rectangle(r);
-            XUnionRectWithRegion(&xrect, result, result);
-        }
-    }
-    return result;
-}
-
-
 void QXcbWindow::setMask(const QRegion &region)
 {
-
-    Display *display = (Display *)connection()->xlib_display();
+    if (!connection()->hasXShape())
+        return;
     if (region.isEmpty()) {
-        XShapeCombineMask(display, xcb_window(),
-                          ShapeBounding, 0, 0,
-                          None, ShapeSet);
+        xcb_shape_mask(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
+                       XCB_SHAPE_SK_BOUNDING, xcb_window(), 0, 0, XCB_NONE);
     } else {
-        XShapeCombineRegion(display, xcb_window(),
-                            ShapeBounding, 0, 0,
-                            qRegionToX11Region(region), ShapeSet);
+        QVector<xcb_rectangle_t> rects;
+        foreach (const QRect &r, region.rects())
+            rects.push_back(qRectToXCBRectangle(r));
+        xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
+                             XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
+                             xcb_window(), 0, 0, rects.size(), &rects[0]);
     }
 }
 
-#endif // XCB_USE_XLIB && !QT_NO_SHAPE
+#endif // !QT_NO_SHAPE
 
 QT_END_NAMESPACE