File indexing completed on 2024-04-21 03:59:22
0001 /* 0002 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> 0003 0004 SPDX-License-Identifier: MIT 0005 */ 0006 0007 #ifndef KXERRORHANDLER_H 0008 #define KXERRORHANDLER_H 0009 #include <config-kwindowsystem.h> 0010 0011 #include <QtGlobal> 0012 0013 #include <private/qtx11extras_p.h> 0014 0015 #include <X11/Xlib.h> 0016 0017 class KXErrorHandlerPrivate; 0018 /** 0019 * This class simplifies handling of X errors. It shouldn't be necessary to use 0020 * with Qt classes, as the toolkit should handle X errors itself, so this 0021 * class will be mainly used with direct Xlib usage, and some lowlevel classes 0022 * like NETWinInfo. 0023 * 0024 * The usual usage is to create a KXErrorHandler instance right before starting 0025 * operations that might cause X errors, and checking if there was an error 0026 * by calling error() after the operations are finished. The handlers 0027 * may be nested, but must be destroyed in reverse order they were created. 0028 * 0029 * There's no need to do X sync before creating an instance, every instance 0030 * will handle only errors for request issued after the instance was created. 0031 * Errors for older requests will be passed to previous error handler. 0032 * When checking for error by calling error() at the end, it is necessary 0033 * to sync with X, to catch all errors that were caused by requests issued 0034 * before the call to error(). This can be done by passing true to error() 0035 * to cause explicit XSync(), however, if the last X request needed a roundtrip 0036 * (e.g. XGetWindowAttributes(), XGetGeometry(), etc.), it is not required 0037 * to do an explicit sync. 0038 * 0039 * @author Lubos Lunak <l.lunak@kde.org> 0040 * @short Handler for X errors 0041 */ 0042 class KXErrorHandler 0043 { 0044 public: 0045 /** 0046 * Creates error handler that will set error flag after encountering 0047 * any X error. 0048 */ 0049 explicit KXErrorHandler(Display *dpy = QX11Info::display()); 0050 /** 0051 * This constructor takes pointer to a function whose prototype matches 0052 * the one that's used with the XSetErrorHandler() Xlib function. 0053 * NOTE: For the error flag to be set, the function must return a non-zero 0054 * value. 0055 */ 0056 explicit KXErrorHandler(int (*handler)(Display *, XErrorEvent *), Display *dpy = QX11Info::display()); 0057 /** 0058 * This function returns true if the error flag is set (i.e. no custom handler 0059 * function was used and there was any error, or the custom handler indicated 0060 * an error by its return value). 0061 * 0062 * @param sync if true, an explicit XSync() will be done. Not necessary 0063 * when the last X request required a roundtrip. 0064 */ 0065 bool error(bool sync) const; 0066 /** 0067 * This function returns the error event for the first X error that occurred. 0068 * The return value is useful only if error() returned true. 0069 * @since 4.0.1 0070 */ 0071 XErrorEvent errorEvent() const; 0072 /** 0073 * Returns error message for the given error. The error message is not translated, 0074 * as it is meant for debugging. 0075 * @since 4.0.1 0076 */ 0077 static QByteArray errorMessage(const XErrorEvent &e, Display *dpy = QX11Info::display()); 0078 ~KXErrorHandler(); 0079 0080 private: 0081 void addHandler(); 0082 int handle(Display *dpy, XErrorEvent *e); 0083 bool (*user_handler1)(int request, int error_code, unsigned long resource_id); 0084 int (*user_handler2)(Display *, XErrorEvent *); 0085 int (*old_handler)(Display *, XErrorEvent *); 0086 static int handler_wrapper(Display *, XErrorEvent *); 0087 static KXErrorHandler **handlers; 0088 static int pos; 0089 static int size; 0090 Q_DISABLE_COPY(KXErrorHandler) 0091 KXErrorHandlerPrivate *const d; 0092 }; 0093 0094 #endif