nuclear@11: #include nuclear@11: #include nuclear@9: #include nuclear@11: #include nuclear@11: #include nuclear@9: #include "xerr.h" nuclear@9: #include "logger.h" nuclear@9: nuclear@12: static int _XPrintDefaultError( Display *dpy, XErrorEvent *event); nuclear@11: nuclear@9: static std::stack func_stack; nuclear@9: nuclear@9: void push_xerr_handler(xerr_handler_type func) nuclear@9: { nuclear@12: xerr_handler_type prev = XSetErrorHandler(func); nuclear@12: if(func_stack.empty()) { nuclear@12: func_stack.push(prev); nuclear@12: } nuclear@9: func_stack.push(func); nuclear@9: } nuclear@9: nuclear@9: void pop_xerr_handler() nuclear@9: { nuclear@9: if(func_stack.empty()) { nuclear@9: log_error("attempt to pop_xerr_handler with an empty stack\n"); nuclear@9: return; nuclear@9: } nuclear@9: xerr_handler_type prev = func_stack.top(); nuclear@9: func_stack.pop(); nuclear@9: XSetErrorHandler(prev); nuclear@9: } nuclear@9: nuclear@9: int xerr_debug(Display *dpy, XErrorEvent *err) nuclear@9: { nuclear@12: _XPrintDefaultError(dpy, err); nuclear@9: return 0; nuclear@9: } nuclear@9: nuclear@9: int xerr_ignore(Display *dpy, XErrorEvent *err) nuclear@9: { nuclear@9: return 0; nuclear@9: } nuclear@11: nuclear@11: typedef struct _XExten _XExtension; nuclear@11: nuclear@12: static int _XPrintDefaultError(Display *dpy, XErrorEvent *event) nuclear@11: { nuclear@11: char buffer[BUFSIZ]; nuclear@11: char mesg[BUFSIZ]; nuclear@11: char number[32]; nuclear@11: const char *mtype = "XlibMessage"; nuclear@11: _XExtension *ext = (_XExtension *)NULL; nuclear@11: _XExtension *bext = (_XExtension *)NULL; nuclear@11: nuclear@11: XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); nuclear@11: XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); nuclear@12: log_error("%s: %s\n ", mesg, buffer); nuclear@11: XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", nuclear@11: mesg, BUFSIZ); nuclear@12: log_error(mesg, event->request_code); nuclear@11: if (event->request_code < 128) { nuclear@11: sprintf(number, "%d", event->request_code); nuclear@11: XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); nuclear@11: } else { nuclear@11: for (ext = dpy->ext_procs; nuclear@11: ext && (ext->codes.major_opcode != event->request_code); nuclear@11: ext = ext->next) nuclear@11: ; nuclear@11: if (ext) { nuclear@11: strncpy(buffer, ext->name, BUFSIZ); nuclear@11: buffer[BUFSIZ - 1] = '\0'; nuclear@11: } else nuclear@11: buffer[0] = '\0'; nuclear@11: } nuclear@12: log_error(" (%s)\n", buffer); nuclear@11: if (event->request_code >= 128) { nuclear@11: XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", nuclear@11: mesg, BUFSIZ); nuclear@12: log_error(" "); nuclear@12: log_error(mesg, event->minor_code); nuclear@11: if (ext) { nuclear@11: sprintf(mesg, "%s.%d", ext->name, event->minor_code); nuclear@11: XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); nuclear@12: log_error(" (%s)", buffer); nuclear@11: } nuclear@12: log_error("\n"); nuclear@11: } nuclear@11: if (event->error_code >= 128) { nuclear@11: /* kludge, try to find the extension that caused it */ nuclear@11: buffer[0] = '\0'; nuclear@11: for (ext = dpy->ext_procs; ext; ext = ext->next) { nuclear@11: if (ext->error_string) nuclear@11: (*ext->error_string)(dpy, event->error_code, &ext->codes, nuclear@11: buffer, BUFSIZ); nuclear@11: if (buffer[0]) { nuclear@11: bext = ext; nuclear@11: break; nuclear@11: } nuclear@11: if (ext->codes.first_error && nuclear@11: ext->codes.first_error < (int)event->error_code && nuclear@11: (!bext || ext->codes.first_error > bext->codes.first_error)) nuclear@11: bext = ext; nuclear@11: } nuclear@11: if (bext) nuclear@11: sprintf(buffer, "%s.%d", bext->name, nuclear@11: event->error_code - bext->codes.first_error); nuclear@11: else nuclear@11: strcpy(buffer, "Value"); nuclear@11: XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); nuclear@11: if (mesg[0]) { nuclear@12: log_error(" "); nuclear@12: log_error(mesg, event->resourceid); nuclear@12: log_error("\n"); nuclear@11: } nuclear@11: /* let extensions try to print the values */ nuclear@11: for (ext = dpy->ext_procs; ext; ext = ext->next) { nuclear@11: if (ext->error_values) nuclear@12: (*ext->error_values)(dpy, event, stderr); nuclear@11: } nuclear@11: } else if ((event->error_code == BadWindow) || nuclear@11: (event->error_code == BadPixmap) || nuclear@11: (event->error_code == BadCursor) || nuclear@11: (event->error_code == BadFont) || nuclear@11: (event->error_code == BadDrawable) || nuclear@11: (event->error_code == BadColor) || nuclear@11: (event->error_code == BadGC) || nuclear@11: (event->error_code == BadIDChoice) || nuclear@11: (event->error_code == BadValue) || nuclear@11: (event->error_code == BadAtom)) { nuclear@11: if (event->error_code == BadValue) nuclear@11: XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", nuclear@11: mesg, BUFSIZ); nuclear@11: else if (event->error_code == BadAtom) nuclear@11: XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", nuclear@11: mesg, BUFSIZ); nuclear@11: else nuclear@11: XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", nuclear@11: mesg, BUFSIZ); nuclear@12: log_error(" "); nuclear@12: log_error(mesg, event->resourceid); nuclear@12: log_error("\n"); nuclear@11: } nuclear@11: XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", nuclear@11: mesg, BUFSIZ); nuclear@12: log_error(" "); nuclear@12: log_error(mesg, event->serial); nuclear@11: XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", nuclear@11: mesg, BUFSIZ); nuclear@12: log_error("\n "); nuclear@12: log_error(mesg, dpy->request); nuclear@12: log_error("\n"); nuclear@11: if (event->error_code == BadImplementation) return 0; nuclear@11: return 1; nuclear@11: }