7#include "kxerrorhandler_p.h"
8#include <config-kwindowsystem.h>
19class KXErrorHandlerPrivate
22 KXErrorHandlerPrivate(Display *dpy)
23 : first_request(XNextRequest(dpy))
28 unsigned long first_request;
31 XErrorEvent error_event;
34KXErrorHandler **KXErrorHandler::handlers =
nullptr;
35int KXErrorHandler::pos = 0;
36int KXErrorHandler::size = 0;
38KXErrorHandler::KXErrorHandler(Display *dpy)
39 : user_handler1(nullptr)
40 , user_handler2(nullptr)
41 , old_handler(XSetErrorHandler(handler_wrapper))
42 , d(new KXErrorHandlerPrivate(dpy))
47KXErrorHandler::KXErrorHandler(
int (*handler)(Display *, XErrorEvent *), Display *dpy)
48 : user_handler1(nullptr)
49 , user_handler2(handler)
50 , old_handler(XSetErrorHandler(handler_wrapper))
51 , d(new KXErrorHandlerPrivate(dpy))
56KXErrorHandler::~KXErrorHandler()
58 XSetErrorHandler(old_handler);
59 Q_ASSERT_X(
this == handlers[pos - 1],
"KXErrorHandler",
"out of order");
64void KXErrorHandler::addHandler()
68 handlers =
static_cast<KXErrorHandler **
>(realloc(handlers, size *
sizeof(KXErrorHandler *)));
70 handlers[pos++] =
this;
73bool KXErrorHandler::error(
bool sync)
const
76 XSync(d->display, False);
81XErrorEvent KXErrorHandler::errorEvent()
const
83 return d->error_event;
86int KXErrorHandler::handler_wrapper(Display *dpy, XErrorEvent *e)
89 int ret = handlers[pos]->handle(dpy, e);
94int KXErrorHandler::handle(Display *dpy, XErrorEvent *e)
102 if (user_handler1 !=
nullptr) {
103 if (user_handler1(e->request_code, e->error_code, e->resourceid)) {
106 }
else if (user_handler2 !=
nullptr) {
107 if (user_handler2(dpy, e) != 0) {
113 if (error && !d->was_error) {
121 return old_handler(dpy, e);
124QByteArray KXErrorHandler::errorMessage(
const XErrorEvent &event, Display *dpy)
131 if (
event.request_code < 128)
134 XGetErrorText(dpy,
event.error_code, tmp, 255);
135 if (
char *paren = strchr(tmp,
'(')) {
160 Display *dpy2 = XOpenDisplay(XDisplayString(dpy));
162 char **extensions = XListExtensions(dpy2, &nextensions);
163 int *majors =
nullptr;
164 int *error_bases =
nullptr;
165 if (extensions ==
nullptr) {
168 majors =
new int[ nextensions ];
169 error_bases =
new int[ nextensions ];
174 if (!XQueryExtension(dpy2, extensions[ i ], &majors[ i ], &dummy, &error_bases[ i ])) {
176 error_bases[ i ] = 0;
180 XGetErrorText(dpy,
event.error_code, tmp, 255);
186 if (error_bases[ i ] != 0
187 &&
event.error_code >= error_bases[ i ] && (index == -1 || error_bases[ i ] > base)) {
189 base = error_bases[ i ];
194 qsnprintf(num, 255,
"%s.%d", extensions[ index ],
event.error_code - base);
195 XGetErrorDatabaseText(dpy,
"XProtoError", num,
"<unknown>", tmp, 255);
197 strcpy(tmp,
"<unknown>");
200 if (
char *paren = strchr(tmp,
'(')) {
204 ret =
QByteArray(
"error: ") + (
const char *)tmp +
'[' + (
const char *)extensions[ index ]
213 if (majors[ i ] ==
event.request_code) {
214 qsnprintf(num, 255,
"%s.%d", extensions[ i ],
event.minor_code);
215 XGetErrorDatabaseText(dpy,
"XRequest", num,
"<unknown>", tmp, 255);
216 ret +=
QByteArray(
", request: ") + (
const char *)tmp +
'[' + (
const char *)extensions[ i ] +
'+'
219 if (tmp[ 0 ] ==
'\0')
222 if (
event.resourceid != 0) {
225 if (extensions !=
nullptr) {
226 XFreeExtensionList(extensions);
229 delete[] error_bases;
static int timestampCompare(unsigned long time1, unsigned long time2)
Compares two X timestamps, taking into account wrapping and 64bit architectures.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QByteArray number(double n, char format, int precision)
QString number(double n, char format, int precision)