diff --git a/main.cpp b/main.cpp
index 9434a36d89..9f199638fc 100644
--- a/main.cpp
+++ b/main.cpp
@@ -67,6 +67,7 @@ along with this program. If not, see .
#include "sm.h"
#include "utils.h"
#include "effects.h"
+#include "xcbutils.h"
#define INT8 _X11INT8
#define INT32 _X11INT32
@@ -129,24 +130,22 @@ static QByteArray errorMessage(const XErrorEvent& event, Display* dpy)
// - Fetching it at startup means a bunch of roundtrips.
// KWin here explicitly uses known extensions.
- int nextensions;
- const char** extensions;
- int* majors;
- int* error_bases;
- Extensions::fillExtensionsData(extensions, nextensions, majors, error_bases);
XGetErrorText(dpy, event.error_code, tmp, 255);
int index = -1;
int base = 0;
- for (int i = 0; i < nextensions; ++i)
- if (error_bases[i] != 0 &&
- event.error_code >= error_bases[i] && (index == -1 || error_bases[i] > base)) {
+ QVector extensions = Xcb::Extensions::self()->extensions();
+ for (int i = 0; i < extensions.size(); ++i) {
+ const Xcb::ExtensionData &extension = extensions.at(i);
+ if (extension.errorBase != 0 &&
+ event.error_code >= extension.errorBase && (index == -1 || extension.errorBase > base)) {
index = i;
- base = error_bases[i];
+ base = extension.errorBase;
}
+ }
if (tmp == QString::number(event.error_code)) {
// XGetErrorText() failed or it has a bug that causes not finding all errors, check ourselves
if (index != -1) {
- snprintf(num, 255, "%s.%d", extensions[index], event.error_code - base);
+ snprintf(num, 255, "%s.%d", extensions.at(index).name.constData(), event.error_code - base);
XGetErrorDatabaseText(dpy, "XProtoError", num, "", tmp, 255);
} else
strcpy(tmp, "");
@@ -154,17 +153,17 @@ static QByteArray errorMessage(const XErrorEvent& event, Display* dpy)
if (char* paren = strchr(tmp, '('))
* paren = '\0';
if (index != -1)
- ret = QByteArray("error: ") + (const char*)(tmp) + '[' + (const char*)(extensions[index]) +
+ ret = QByteArray("error: ") + (const char*)(tmp) + '[' + extensions.at(index).name +
'+' + QByteArray::number(event.error_code - base) + ']';
else
ret = QByteArray("error: ") + (const char*)(tmp) + '[' + QByteArray::number(event.error_code) + ']';
tmp[0] = '\0';
- for (int i = 0; i < nextensions; ++i)
- if (majors[i] == event.request_code) {
- snprintf(num, 255, "%s.%d", extensions[i], event.minor_code);
+ for (int i = 0; i < extensions.size(); ++i)
+ if (extensions.at(i).majorOpcode == event.request_code) {
+ snprintf(num, 255, "%s.%d", extensions.at(i).name.constData(), event.minor_code);
XGetErrorDatabaseText(dpy, "XRequest", num, "", tmp, 255);
ret += QByteArray(", request: ") + (const char*)(tmp) + '[' +
- (const char*)(extensions[i]) + '+' + QByteArray::number(event.minor_code) + ']';
+ extensions.at(i).name + '+' + QByteArray::number(event.minor_code) + ']';
}
if (tmp[0] == '\0') // Not found?
ret += QByteArray(", request [") + QByteArray::number(event.request_code) + ':'
diff --git a/xcbutils.cpp b/xcbutils.cpp
index 97cdd45ae5..7eb0d1ebd2 100644
--- a/xcbutils.cpp
+++ b/xcbutils.cpp
@@ -51,6 +51,8 @@ static const int XFIXES_MAX_MINOR = 0;
ExtensionData::ExtensionData()
: version(0)
, eventBase(0)
+ , errorBase(0)
+ , majorOpcode(0)
, present(0)
{
}
@@ -98,6 +100,14 @@ void Extensions::init()
xcb_prefetch_extension_data(c, &xcb_render_id);
xcb_prefetch_extension_data(c, &xcb_sync_id);
+ m_shape.name = QByteArray("SHAPE");
+ m_randr.name = QByteArray("RANDR");
+ m_damage.name = QByteArray("DAMAGE");
+ m_composite.name = QByteArray("Composite");
+ m_fixes.name = QByteArray("XFIXES");
+ m_render.name = QByteArray("RENDER");
+ m_sync.name = QByteArray("SYNC");
+
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);
@@ -173,6 +183,8 @@ void Extensions::extensionQueryReply(const xcb_query_extension_reply_t *extensio
}
dataToFill->present = extension->present;
dataToFill->eventBase = extension->first_event;
+ dataToFill->errorBase = extension->first_error;
+ dataToFill->majorOpcode = extension->major_opcode;
}
int Extensions::damageNotifyEvent() const
@@ -223,5 +235,18 @@ int Extensions::syncAlarmNotifyEvent() const
return m_sync.eventBase + XCB_SYNC_ALARM_NOTIFY;
}
+QVector Extensions::extensions() const
+{
+ QVector extensions;
+ extensions << m_shape
+ << m_randr
+ << m_damage
+ << m_composite
+ << m_render
+ << m_fixes
+ << m_sync;
+ return extensions;
+}
+
} // namespace Xcb
} // namespace KWin
diff --git a/xcbutils.h b/xcbutils.h
index 4b66248b7b..950fd59aff 100644
--- a/xcbutils.h
+++ b/xcbutils.h
@@ -102,7 +102,10 @@ public:
ExtensionData();
int version;
int eventBase;
+ int errorBase;
+ int majorOpcode;
bool present;
+ QByteArray name;
};
class Extensions
@@ -137,6 +140,7 @@ public:
return m_sync.present;
}
int syncAlarmNotifyEvent() const;
+ QVector extensions() const;
static Extensions *self();
static void destroy();