27 #ifdef Q_WS_X11 //FIXME
33 class KXErrorHandlerPrivate
36 KXErrorHandlerPrivate( Display* dpy ) :
37 first_request( XNextRequest( dpy )),
42 unsigned long first_request;
45 XErrorEvent error_event;
49 int KXErrorHandler::pos = 0;
50 int KXErrorHandler::size = 0;
53 : user_handler1( NULL ),
54 user_handler2( NULL ),
55 old_handler( XSetErrorHandler( handler_wrapper )),
56 d( new KXErrorHandlerPrivate(dpy) )
61 #ifndef KDE_NO_DEPRECATED
63 : user_handler1( handler ),
64 user_handler2( NULL ),
65 old_handler( XSetErrorHandler( handler_wrapper )),
66 d( new KXErrorHandlerPrivate(dpy) )
73 : user_handler1( NULL ),
74 user_handler2( handler ),
75 old_handler( XSetErrorHandler( handler_wrapper )),
76 d( new KXErrorHandlerPrivate(dpy) )
83 XSetErrorHandler( old_handler );
84 Q_ASSERT_X(
this == handlers[ pos-1 ],
"KXErrorHandler",
"out of order" );
89 void KXErrorHandler::addHandler()
96 handlers[ pos++ ] =
this;
102 XSync( d->display, False );
108 return d->error_event;
111 int KXErrorHandler::handler_wrapper( Display* dpy, XErrorEvent* e )
114 int ret = handlers[ pos ]->handle( dpy, e );
119 int KXErrorHandler::handle( Display* dpy, XErrorEvent* e )
121 if( dpy == d->display
127 if( user_handler1 != NULL )
129 if( user_handler1( e->request_code, e->error_code, e->resourceid ))
132 else if( user_handler2 != NULL )
134 if( user_handler2( dpy, e ) != 0 )
139 if( error && !d->was_error )
147 return old_handler( dpy, e );
156 if( event.request_code < 128 )
159 XGetErrorText( dpy, event.error_code, tmp, 255 );
160 if(
char*
paren = strchr( tmp,
'(' ))
163 ret = QByteArray(
"error: " ) + (
const char*)tmp +
'[' + QByteArray::number( event.error_code ) +
']';
164 sprintf( num,
"%d", event.request_code );
165 XGetErrorDatabaseText( dpy,
"XRequest", num,
"<unknown>", tmp, 256 );
166 ret += QByteArray(
", request: " ) + (
const char*)tmp +
'[' + QByteArray::number( event.request_code ) +
']';
167 if( event.resourceid != 0 )
168 ret += QByteArray(
", resource: 0x" ) + QByteArray::number( (qlonglong)event.resourceid, 16 );
182 Display* dpy2 = XOpenDisplay( XDisplayString( dpy ));
184 char** extensions = XListExtensions( dpy2, &nextensions );
186 int* error_bases = NULL;
187 if( extensions == NULL )
191 majors =
new int[ nextensions ];
192 error_bases =
new int[ nextensions ];
198 if( !XQueryExtension( dpy2, extensions[ i ], &majors[ i ], &dummy, &error_bases[ i ] ))
201 error_bases[ i ] = 0;
205 XGetErrorText( dpy, event.error_code, tmp, 255 );
211 if( error_bases[ i ] != 0
212 && event.error_code >= error_bases[ i ] && ( index == -1 || error_bases[ i ] > base ))
215 base = error_bases[ i ];
217 if( tmp == QString::number( event.error_code ))
221 snprintf( num, 255,
"%s.%d", extensions[ index ], event.error_code - base );
222 XGetErrorDatabaseText( dpy,
"XProtoError", num,
"<unknown>", tmp, 255 );
225 strcpy( tmp,
"<unknown>" );
227 if(
char*
paren = strchr( tmp,
'(' ))
230 ret = QByteArray(
"error: " ) + (
const char*)tmp +
'[' + (
const char*)extensions[ index ]
231 +
'+' + QByteArray::number( event.error_code - base ) +
']';
233 ret = QByteArray(
"error: " ) + (
const char*)tmp +
'[' + QByteArray::number( event.error_code ) +
']';
238 if( majors[ i ] == event.request_code )
240 snprintf( num, 255,
"%s.%d", extensions[ i ], event.minor_code );
241 XGetErrorDatabaseText( dpy,
"XRequest", num,
"<unknown>", tmp, 255 );
242 ret += QByteArray(
", request: " ) + (
const char*)tmp +
'[' + (
const char*)extensions[ i ] +
'+'
243 + QByteArray::number( event.minor_code ) +
']';
245 if( tmp[ 0 ] ==
'\0' )
246 ret += QByteArray(
", request <unknown> [" ) + QByteArray::number( event.request_code ) +
':'
247 + QByteArray::number( event.minor_code ) +
']';
248 if( event.resourceid != 0 )
249 ret += QByteArray(
", resource: 0x" ) + QByteArray::number( (qlonglong)event.resourceid, 16 );
250 if( extensions != NULL )
251 XFreeExtensionList( extensions );
253 delete[] error_bases;
254 XCloseDisplay( dpy2 );
bool error(bool sync) const
This function returns true if the error flag is set (i.e.
XErrorEvent errorEvent() const
This function returns the error event for the first X error that occurred.
static int timestampCompare(unsigned long time1, unsigned long time2)
Compares two X timestamps, taking into account wrapping and 64bit architectures.
This class simplifies handling of X errors.
static QByteArray errorMessage(const XErrorEvent &e, Display *dpy=QX11Info::display())
Returns error message for the given error.
KXErrorHandler(Display *dpy=QX11Info::display())
Creates error handler that will set error flag after encountering any X error.