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

List:       kde-commits
Subject:    [kwin] /: Print better error messages for XCB errors from extensions
From:       Martin_Gräßlin <mgraesslin () kde ! org>
Date:       2014-04-16 11:36:42
Message-ID: E1WaO8w-00021i-BE () scm ! kde ! org
[Download RAW message or body]

Git commit d2d89653b2eac1e3de57041d642f8f9319c667db by Martin Gräßlin.
Committed on 07/04/2014 at 13:05.
Pushed by graesslin into branch 'master'.

Print better error messages for XCB errors from extensions

Qt doesn't print proper error messages for any errors caused by
extensions. As KWin is a heavy user of extensions not of interest to Qt
(e.g. damage or composite) we do our own error code mapping.

The Xcb::ExtensionData is extended by a vector of OpCodes and ErrorNames.
In ::workspaceEvent it's checked whether the event is an error and if
that is the case KWin tries to map the error to one of the extensions.

If that is successful it prints a warning looking like Qt's one:
XCB error: 151 (BadDamage), sequence: 12534, resource id: 127926362, \
    major code: 143 (DAMAGE), minor code: 2 (Destroy)

and the event gets filtered out, so that the Qt error messages is not
printed in addition.

If the error is not from one of the extensions the error is not filtered
out and so the default Qt behavior gets applied.

REVIEW: 117421

M  +49   -0    events.cpp
M  +227  -0    xcbutils.cpp
M  +2    -0    xcbutils.h

http://commits.kde.org/kwin/d2d89653b2eac1e3de57041d642f8f9319c667db

diff --git a/events.cpp b/events.cpp
index a182f92..4f13abc 100644
--- a/events.cpp
+++ b/events.cpp
@@ -135,12 +135,61 @@ static xcb_window_t findEventWindow(xcb_generic_event_t *event)
     }
 }
 
+QVector<QByteArray> s_xcbEerrors({
+    QByteArrayLiteral("Success"),
+    QByteArrayLiteral("BadRequest"),
+    QByteArrayLiteral("BadValue"),
+    QByteArrayLiteral("BadWindow"),
+    QByteArrayLiteral("BadPixmap"),
+    QByteArrayLiteral("BadAtom"),
+    QByteArrayLiteral("BadCursor"),
+    QByteArrayLiteral("BadFont"),
+    QByteArrayLiteral("BadMatch"),
+    QByteArrayLiteral("BadDrawable"),
+    QByteArrayLiteral("BadAccess"),
+    QByteArrayLiteral("BadAlloc"),
+    QByteArrayLiteral("BadColor"),
+    QByteArrayLiteral("BadGC"),
+    QByteArrayLiteral("BadIDChoice"),
+    QByteArrayLiteral("BadName"),
+    QByteArrayLiteral("BadLength"),
+    QByteArrayLiteral("BadImplementation"),
+    QByteArrayLiteral("Unknown")});
 /*!
   Handles workspace specific XCB event
  */
 bool Workspace::workspaceEvent(xcb_generic_event_t *e)
 {
     const uint8_t eventType = e->response_type & ~0x80;
+    if (!eventType) {
+        // let's check whether it's an error from one of the extensions KWin uses
+        xcb_generic_error_t *error = reinterpret_cast<xcb_generic_error_t*>(e);
+        const QVector<Xcb::ExtensionData> extensions = \
Xcb::Extensions::self()->extensions(); +        for (const auto &extension : \
extensions) { +            if (error->major_code == extension.majorOpcode) {
+                QByteArray errorName;
+                if (error->error_code < s_xcbEerrors.size()) {
+                    errorName = s_xcbEerrors.at(error->error_code);
+                } else if (error->error_code >= extension.errorBase) {
+                    const int index = error->error_code - extension.errorBase;
+                    if (index >= 0 && index < extension.errorCodes.size()) {
+                        errorName = extension.errorCodes.at(index);
+                    }
+                }
+                if (errorName.isEmpty()) {
+                    errorName = QByteArrayLiteral("Unknown");
+                }
+                qWarning("XCB error: %d (%s), sequence: %d, resource id: %d, major \
code: %d (%s), minor code: %d (%s)", +                         \
int(error->error_code), errorName.constData(), +                         \
int(error->sequence), int(error->resource_id), +                         \
int(error->major_code), extension.name.constData(), +                         \
int(error->minor_code), +                         extension.opCodes.size() > \
error->minor_code ? extension.opCodes.at(error->minor_code).constData() : "Unknown"); \
+                return true; +            }
+        }
+        return false;
+    }
     if (effects && static_cast< EffectsHandlerImpl* >(effects)->hasKeyboardGrab()
             && (eventType == XCB_KEY_PRESS || eventType == XCB_KEY_RELEASE))
         return false; // let Qt process it, it'll be intercepted again in \
                eventFilter()
diff --git a/xcbutils.cpp b/xcbutils.cpp
index 5a24cb3..1ac3b09 100644
--- a/xcbutils.cpp
+++ b/xcbutils.cpp
@@ -51,6 +51,221 @@ static const int RENDER_MAX_MINOR = 11;
 static const int XFIXES_MAX_MAJOR = 5;
 static const int XFIXES_MAX_MINOR = 0;
 
+QVector<QByteArray> shapeOpCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/xextproto/shape.html
+    // extracted from <xcb/shape.h>
+    return QVector<QByteArray>({QByteArrayLiteral("QueryVersion"),
+                                QByteArrayLiteral("Rectangles"),
+                                QByteArrayLiteral("Mask"),
+                                QByteArrayLiteral("Combine"),
+                                QByteArrayLiteral("Offset"),
+                                QByteArrayLiteral("Extents"),
+                                QByteArrayLiteral("Input"),
+                                QByteArrayLiteral("InputSelected"),
+                                QByteArrayLiteral("GetRectangles")});
+}
+
+QVector<QByteArray> randrOpCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/randrproto/randrproto.txt
+    // extracted from <xcb/randr.h>
+    return QVector<QByteArray>({QByteArrayLiteral("QueryVersion"),
+                                QByteArray(""), // doesn't exist
+                                QByteArrayLiteral("SetScreenConfig"),
+                                QByteArray(""), // doesn't exits
+                                QByteArrayLiteral("SelectInput"),
+                                QByteArrayLiteral("GetScreenInfo"),
+                                QByteArrayLiteral("GetScreenSizeRange"),
+                                QByteArrayLiteral("SetScreenSize"),
+                                QByteArrayLiteral("GetScreenResources"),
+                                QByteArrayLiteral("GetOutputInfo"),
+                                QByteArrayLiteral("ListOutputProperties"),
+                                QByteArrayLiteral("QueryOutputProperty"),
+                                QByteArrayLiteral("ConfigureOutputProperty"),
+                                QByteArrayLiteral("ChangeOutputProperty"),
+                                QByteArrayLiteral("DeleteOutputProperty"),
+                                QByteArrayLiteral("GetOutputproperty"),
+                                QByteArrayLiteral("CreateMode"),
+                                QByteArrayLiteral("DestroyMode"),
+                                QByteArrayLiteral("AddOutputMode"),
+                                QByteArrayLiteral("DeleteOutputMode"),
+                                QByteArrayLiteral("GetCrtcInfo"),
+                                QByteArrayLiteral("SetCrtcConfig"),
+                                QByteArrayLiteral("GetCrtcGammaSize"),
+                                QByteArrayLiteral("GetCrtcGamma"),
+                                QByteArrayLiteral("SetCrtcGamma"),
+                                QByteArrayLiteral("GetScreenResourcesCurrent"),
+                                QByteArrayLiteral("SetCrtcTransform"),
+                                QByteArrayLiteral("GetCrtcTransform"),
+                                QByteArrayLiteral("GetPanning"),
+                                QByteArrayLiteral("SetPanning"),
+                                QByteArrayLiteral("SetOutputPrimary"),
+                                QByteArrayLiteral("GetOutputPrimary"),
+                                QByteArrayLiteral("GetProviders"),
+                                QByteArrayLiteral("GetProviderInfo"),
+                                QByteArrayLiteral("SetProviderOffloadSink"),
+                                QByteArrayLiteral("SetProviderOutputSource"),
+                                QByteArrayLiteral("ListProviderProperties"),
+                                QByteArrayLiteral("QueryProviderProperty"),
+                                QByteArrayLiteral("ConfigureProviderroperty"),
+                                QByteArrayLiteral("ChangeProviderProperty"),
+                                QByteArrayLiteral("DeleteProviderProperty"),
+                                QByteArrayLiteral("GetProviderProperty")});
+}
+
+QVector<QByteArray> randrErrorCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/randrproto/randrproto.txt
+    // extracted from <xcb/randr.h>
+    return QVector<QByteArray>({QByteArrayLiteral("BadOutput"),
+                                QByteArrayLiteral("BadCrtc"),
+                                QByteArrayLiteral("BadMode"),
+                                QByteArrayLiteral("BadProvider")});
+}
+
+QVector<QByteArray> damageOpCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/damageproto/damageproto.txt
+    // extracted from <xcb/damage.h>
+    return QVector<QByteArray>({QByteArrayLiteral("QueryVersion"),
+                                QByteArrayLiteral("Create"),
+                                QByteArrayLiteral("Destroy"),
+                                QByteArrayLiteral("Subtract"),
+                                QByteArrayLiteral("Add")});
+}
+
+QVector<QByteArray> damageErrorCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/damageproto/damageproto.txt
+    // extracted from <xcb/damage.h>
+    return QVector<QByteArray>({QByteArrayLiteral("BadDamage")});
+}
+
+QVector<QByteArray> compositeOpCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/compositeproto/compositeproto.txt
+    // extracted from <xcb/composite.h>
+    return QVector<QByteArray>({QByteArrayLiteral("QueryVersion"),
+                                QByteArrayLiteral("RedirectWindow"),
+                                QByteArrayLiteral("RedirectSubwindows"),
+                                QByteArrayLiteral("UnredirectWindow"),
+                                QByteArrayLiteral("UnredirectSubwindows"),
+                                QByteArrayLiteral("CreateRegionFromBorderClip"),
+                                QByteArrayLiteral("NameWindowPixmap"),
+                                QByteArrayLiteral("GetOverlayWindow"),
+                                QByteArrayLiteral("ReleaseOverlayWindow")});
+}
+
+QVector<QByteArray> fixesOpCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/fixesproto/fixesproto.txt
+    // extracted from <xcb/xfixes.h>
+    return QVector<QByteArray>({QByteArrayLiteral("QueryVersion"),
+                                QByteArrayLiteral("ChangeSaveSet"),
+                                QByteArrayLiteral("SelectSelectionInput"),
+                                QByteArrayLiteral("SelectCursorInput"),
+                                QByteArrayLiteral("GetCursorImage"),
+                                QByteArrayLiteral("CreateRegion"),
+                                QByteArrayLiteral("CreateRegionFromBitmap"),
+                                QByteArrayLiteral("CreateRegionFromWindow"),
+                                QByteArrayLiteral("CreateRegionFromGc"),
+                                QByteArrayLiteral("CreateRegionFromPicture"),
+                                QByteArrayLiteral("DestroyRegion"),
+                                QByteArrayLiteral("SetRegion"),
+                                QByteArrayLiteral("CopyRegion"),
+                                QByteArrayLiteral("UnionRegion"),
+                                QByteArrayLiteral("IntersectRegion"),
+                                QByteArrayLiteral("SubtractRegion"),
+                                QByteArrayLiteral("InvertRegion"),
+                                QByteArrayLiteral("TranslateRegion"),
+                                QByteArrayLiteral("RegionExtents"),
+                                QByteArrayLiteral("FetchRegion"),
+                                QByteArrayLiteral("SetGcClipRegion"),
+                                QByteArrayLiteral("SetWindowShapeRegion"),
+                                QByteArrayLiteral("SetPictureClipRegion"),
+                                QByteArrayLiteral("SetCursorName"),
+                                QByteArrayLiteral("GetCursorName"),
+                                QByteArrayLiteral("GetCursorImageAndName"),
+                                QByteArrayLiteral("ChangeCursor"),
+                                QByteArrayLiteral("ChangeCursorByName"),
+                                QByteArrayLiteral("ExpandRegion"),
+                                QByteArrayLiteral("HideCursor"),
+                                QByteArrayLiteral("ShowCursor"),
+                                QByteArrayLiteral("CreatePointerBarrier"),
+                                QByteArrayLiteral("DeletePointerBarrier")});
+}
+
+QVector<QByteArray> fixesErrorCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/fixesproto/fixesproto.txt
+    // extracted from <xcb/xfixes.h>
+    return QVector<QByteArray>({QByteArrayLiteral("BadRegion")});
+}
+
+QVector<QByteArray> renderOpCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/renderproto/renderproto.txt
+    // extracted from <xcb/render.h>
+    return QVector<QByteArray>({QByteArrayLiteral("QueryVersion"),
+                                QByteArrayLiteral("QueryPictFormats"),
+                                QByteArrayLiteral("QueryPictIndexValues"),
+                                QByteArrayLiteral("CreatePicture"),
+                                QByteArrayLiteral("ChangePicture"),
+                                QByteArrayLiteral("SetPictureClipRectangles"),
+                                QByteArrayLiteral("FreePicture"),
+                                QByteArrayLiteral("Composite"),
+                                QByteArrayLiteral("Trapezoids"),
+                                QByteArrayLiteral("Triangles"),
+                                QByteArrayLiteral("TriStrip"),
+                                QByteArrayLiteral("TriFan"),
+                                QByteArrayLiteral("CreateGlyphSet"),
+                                QByteArrayLiteral("ReferenceGlyphSet"),
+                                QByteArrayLiteral("FreeGlyphSet"),
+                                QByteArrayLiteral("AddGlyphs"),
+                                QByteArrayLiteral("FreeGlyphs"),
+                                QByteArrayLiteral("CompositeGlyphs8"),
+                                QByteArrayLiteral("CompositeGlyphs16"),
+                                QByteArrayLiteral("CompositeGlyphs32"),
+                                QByteArrayLiteral("FillRectangles"),
+                                QByteArrayLiteral("CreateCursor"),
+                                QByteArrayLiteral("SetPictureTransform"),
+                                QByteArrayLiteral("QueryFilters"),
+                                QByteArrayLiteral("SetPictureFilter"),
+                                QByteArrayLiteral("CreateAnimCursor"),
+                                QByteArrayLiteral("AddTraps"),
+                                QByteArrayLiteral("CreateSolidFill"),
+                                QByteArrayLiteral("CreateLinearGradient"),
+                                QByteArrayLiteral("CreateRadialGradient"),
+                                QByteArrayLiteral("CreateConicalGradient")});
+}
+
+QVector<QByteArray> syncOpCodes()
+{
+    // see http://www.x.org/releases/X11R7.7/doc/xextproto/sync.html
+    // extracted from <xcb/sync.h>
+    return QVector<QByteArray>({QByteArrayLiteral("Initialize"),
+                                QByteArrayLiteral("ListSystemCounters"),
+                                QByteArrayLiteral("CreateCounter"),
+                                QByteArrayLiteral("DestroyCounter"),
+                                QByteArrayLiteral("QueryCounter"),
+                                QByteArrayLiteral("Await"),
+                                QByteArrayLiteral("ChangeCounter"),
+                                QByteArrayLiteral("SetCounter"),
+                                QByteArrayLiteral("CreateAlarm"),
+                                QByteArrayLiteral("ChangeAlarm"),
+                                QByteArrayLiteral("DestroyAlarm"),
+                                QByteArrayLiteral("QueryAlarm"),
+                                QByteArrayLiteral("SetPriority"),
+                                QByteArrayLiteral("GetPriority"),
+                                QByteArrayLiteral("CreateFence"),
+                                QByteArrayLiteral("TriggerFence"),
+                                QByteArrayLiteral("ResetFence"),
+                                QByteArrayLiteral("DestroyFence"),
+                                QByteArrayLiteral("QueryFence"),
+                                QByteArrayLiteral("AwaitFence")});
+}
+
 ExtensionData::ExtensionData()
     : version(0)
     , eventBase(0)
@@ -111,6 +326,18 @@ void Extensions::init()
     m_render.name    = QByteArray("RENDER");
     m_sync.name      = QByteArray("SYNC");
 
+    m_shape.opCodes     = shapeOpCodes();
+    m_randr.opCodes     = randrOpCodes();
+    m_damage.opCodes    = damageOpCodes();
+    m_composite.opCodes = compositeOpCodes();
+    m_fixes.opCodes     = fixesOpCodes();
+    m_render.opCodes    = renderOpCodes();
+    m_sync.opCodes      = syncOpCodes();
+
+    m_randr.errorCodes  = randrErrorCodes();
+    m_damage.errorCodes = damageErrorCodes();
+    m_fixes.errorCodes  = fixesErrorCodes();
+
     extensionQueryReply(xcb_get_extension_data(c, &xcb_shape_id), &m_shape);
     extensionQueryReply(xcb_get_extension_data(c, &xcb_randr_id), &m_randr);
     extensionQueryReply(xcb_get_extension_data(c, &xcb_damage_id), &m_damage);
diff --git a/xcbutils.h b/xcbutils.h
index baa507f..3f2bd6c 100644
--- a/xcbutils.h
+++ b/xcbutils.h
@@ -341,6 +341,8 @@ public:
     int majorOpcode;
     bool present;
     QByteArray name;
+    QVector<QByteArray> opCodes;
+    QVector<QByteArray> errorCodes;
 };
 
 class Extensions


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

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