1/*
2 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
3
4 SPDX-License-Identifier: MIT
5*/
6
7#ifndef KXERRORHANDLER_H
8#define KXERRORHANDLER_H
9#include <config-kwindowsystem.h>
10
11#include <mutex>
12
13#include <QtGlobal>
14
15#include <private/qtx11extras_p.h>
16
17#include <X11/Xlib.h>
18
19class KXErrorHandlerPrivate;
20/*!
21 * This class simplifies handling of X errors. It shouldn't be necessary to use
22 * with Qt classes, as the toolkit should handle X errors itself, so this
23 * class will be mainly used with direct Xlib usage, and some lowlevel classes
24 * like NETWinInfo.
25 *
26 * The usual usage is to create a KXErrorHandler instance right before starting
27 * operations that might cause X errors, and checking if there was an error
28 * by calling error() after the operations are finished. The handlers
29 * may be nested, but must be destroyed in reverse order they were created.
30 *
31 * There's no need to do X sync before creating an instance, every instance
32 * will handle only errors for request issued after the instance was created.
33 * Errors for older requests will be passed to previous error handler.
34 * When checking for error by calling error() at the end, it is necessary
35 * to sync with X, to catch all errors that were caused by requests issued
36 * before the call to error(). This can be done by passing true to error()
37 * to cause explicit XSync(), however, if the last X request needed a roundtrip
38 * (e.g. XGetWindowAttributes(), XGetGeometry(), etc.), it is not required
39 * to do an explicit sync.
40 *
41 * \internal
42 */
43class KXErrorHandler
44{
45public:
46 /*!
47 * Creates error handler that will set error flag after encountering
48 * any X error.
49 */
50 explicit KXErrorHandler(Display *dpy = QX11Info::display());
51 /*!
52 * This constructor takes pointer to a function whose prototype matches
53 * the one that's used with the XSetErrorHandler() Xlib function.
54 * NOTE: For the error flag to be set, the function must return a non-zero
55 * value.
56 */
57 explicit KXErrorHandler(int (*handler)(Display *, XErrorEvent *), Display *dpy = QX11Info::display());
58 /*!
59 * This function returns true if the error flag is set (i.e. no custom handler
60 * function was used and there was any error, or the custom handler indicated
61 * an error by its return value).
62 *
63 * \a sync if true, an explicit XSync() will be done. Not necessary
64 * when the last X request required a roundtrip.
65 */
66 bool error(bool sync) const;
67 /*!
68 * This function returns the error event for the first X error that occurred.
69 * The return value is useful only if error() returned true.
70 * \since 4.0.1
71 */
72 XErrorEvent errorEvent() const;
73 /*!
74 * Returns error message for the given error. The error message is not translated,
75 * as it is meant for debugging.
76 * \since 4.0.1
77 */
78 static QByteArray errorMessage(const XErrorEvent &e, Display *dpy = QX11Info::display());
79 ~KXErrorHandler();
80
81private:
82 void addHandler();
83 int handle(Display *dpy, XErrorEvent *e);
84 bool (*user_handler1)(int request, int error_code, unsigned long resource_id);
85 int (*user_handler2)(Display *, XErrorEvent *);
86 int (*old_handler)(Display *, XErrorEvent *);
87 static int handler_wrapper(Display *, XErrorEvent *);
88 static std::mutex s_lock;
89 static KXErrorHandler **handlers;
90 static int pos;
91 static int size;
92 Q_DISABLE_COPY(KXErrorHandler)
93 KXErrorHandlerPrivate *const d;
94};
95
96#endif
97

source code of kwindowsystem/src/platforms/xcb/kxerrorhandler_p.h