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;
34std::mutex KXErrorHandler::s_lock;
35KXErrorHandler **KXErrorHandler::handlers =
nullptr;
36int KXErrorHandler::pos = 0;
37int KXErrorHandler::size = 0;
39KXErrorHandler::KXErrorHandler(Display *dpy)
40 : user_handler1(nullptr)
41 , user_handler2(nullptr)
42 , old_handler(XSetErrorHandler(handler_wrapper))
43 , d(new KXErrorHandlerPrivate(dpy))
48KXErrorHandler::KXErrorHandler(
int (*handler)(Display *, XErrorEvent *), Display *dpy)
49 : user_handler1(nullptr)
50 , user_handler2(handler)
51 , old_handler(XSetErrorHandler(handler_wrapper))
52 , d(new KXErrorHandlerPrivate(dpy))
57KXErrorHandler::~KXErrorHandler()
59 std::lock_guard lock(s_lock);
60 XSetErrorHandler(old_handler);
61 Q_ASSERT_X(
this == handlers[pos - 1],
"KXErrorHandler",
"out of order");
66void KXErrorHandler::addHandler()
68 std::lock_guard lock(s_lock);
71 handlers =
static_cast<KXErrorHandler **
>(realloc(handlers, size *
sizeof(KXErrorHandler *)));
73 handlers[pos++] =
this;
76bool KXErrorHandler::error(
bool sync)
const
79 XSync(d->display, False);
84XErrorEvent KXErrorHandler::errorEvent()
const
86 return d->error_event;
89int KXErrorHandler::handler_wrapper(Display *dpy, XErrorEvent *e)
91 std::lock_guard lock(s_lock);
93 int ret = handlers[pos]->handle(dpy, e);
98int KXErrorHandler::handle(Display *dpy, XErrorEvent *e)
100 if (dpy == d->display
106 if (user_handler1 !=
nullptr) {
107 if (user_handler1(e->request_code, e->error_code, e->resourceid)) {
110 }
else if (user_handler2 !=
nullptr) {
111 if (user_handler2(dpy, e) != 0) {
117 if (error && !d->was_error) {
125 return old_handler(dpy, e);
128QByteArray KXErrorHandler::errorMessage(
const XErrorEvent &event, Display *dpy)
135 if (
event.request_code < 128)
138 XGetErrorText(dpy,
event.error_code, tmp, 255);
139 if (
char *paren = strchr(tmp,
'(')) {
164 Display *dpy2 = XOpenDisplay(XDisplayString(dpy));
166 char **extensions = XListExtensions(dpy2, &nextensions);
167 int *majors =
nullptr;
168 int *error_bases =
nullptr;
169 if (extensions ==
nullptr) {
172 majors =
new int[ nextensions ];
173 error_bases =
new int[ nextensions ];
178 if (!XQueryExtension(dpy2, extensions[ i ], &majors[ i ], &dummy, &error_bases[ i ])) {
180 error_bases[ i ] = 0;
184 XGetErrorText(dpy,
event.error_code, tmp, 255);
190 if (error_bases[ i ] != 0
191 &&
event.error_code >= error_bases[ i ] && (index == -1 || error_bases[ i ] > base)) {
193 base = error_bases[ i ];
198 qsnprintf(num, 255,
"%s.%d", extensions[ index ],
event.error_code - base);
199 XGetErrorDatabaseText(dpy,
"XProtoError", num,
"<unknown>", tmp, 255);
201 strcpy(tmp,
"<unknown>");
204 if (
char *paren = strchr(tmp,
'(')) {
208 ret =
QByteArray(
"error: ") + (
const char *)tmp +
'[' + (
const char *)extensions[ index ]
217 if (majors[ i ] ==
event.request_code) {
218 qsnprintf(num, 255,
"%s.%d", extensions[ i ],
event.minor_code);
219 XGetErrorDatabaseText(dpy,
"XRequest", num,
"<unknown>", tmp, 255);
220 ret +=
QByteArray(
", request: ") + (
const char *)tmp +
'[' + (
const char *)extensions[ i ] +
'+'
223 if (tmp[ 0 ] ==
'\0')
226 if (
event.resourceid != 0) {
229 if (extensions !=
nullptr) {
230 XFreeExtensionList(extensions);
233 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)