xglcomp

annotate src/xerr.cc @ 11:cb636a23f4f2

lifted X error reporting from Xlib
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 04 Feb 2016 04:15:15 +0200
parents be18500d76d1
children 1c0d056ec360
rev   line source
nuclear@11 1 #include <stdio.h>
nuclear@11 2 #include <string.h>
nuclear@9 3 #include <stack>
nuclear@11 4 #include <X11/Xlib.h>
nuclear@11 5 #include <X11/Xlibint.h>
nuclear@9 6 #include "xerr.h"
nuclear@9 7 #include "logger.h"
nuclear@9 8
nuclear@11 9 static int _XPrintDefaultError( Display *dpy, XErrorEvent *event, FILE *fp);
nuclear@11 10
nuclear@9 11 static std::stack<xerr_handler_type> func_stack;
nuclear@9 12
nuclear@9 13 void push_xerr_handler(xerr_handler_type func)
nuclear@9 14 {
nuclear@9 15 func_stack.push(func);
nuclear@9 16 XSetErrorHandler(func);
nuclear@9 17 }
nuclear@9 18
nuclear@9 19 void pop_xerr_handler()
nuclear@9 20 {
nuclear@9 21 if(func_stack.empty()) {
nuclear@9 22 log_error("attempt to pop_xerr_handler with an empty stack\n");
nuclear@9 23 return;
nuclear@9 24 }
nuclear@9 25 xerr_handler_type prev = func_stack.top();
nuclear@9 26 func_stack.pop();
nuclear@9 27 XSetErrorHandler(prev);
nuclear@9 28 }
nuclear@9 29
nuclear@9 30 int xerr_debug(Display *dpy, XErrorEvent *err)
nuclear@9 31 {
nuclear@11 32 _XPrintDefaultError(dpy, err, stderr);
nuclear@9 33 return 0;
nuclear@9 34 }
nuclear@9 35
nuclear@9 36 int xerr_ignore(Display *dpy, XErrorEvent *err)
nuclear@9 37 {
nuclear@9 38 return 0;
nuclear@9 39 }
nuclear@11 40
nuclear@11 41 typedef struct _XExten _XExtension;
nuclear@11 42
nuclear@11 43 static int _XPrintDefaultError( Display *dpy, XErrorEvent *event, FILE *fp)
nuclear@11 44 {
nuclear@11 45 char buffer[BUFSIZ];
nuclear@11 46 char mesg[BUFSIZ];
nuclear@11 47 char number[32];
nuclear@11 48 const char *mtype = "XlibMessage";
nuclear@11 49 _XExtension *ext = (_XExtension *)NULL;
nuclear@11 50 _XExtension *bext = (_XExtension *)NULL;
nuclear@11 51
nuclear@11 52 XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
nuclear@11 53 XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
nuclear@11 54 (void) fprintf(fp, "%s: %s\n ", mesg, buffer);
nuclear@11 55 XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
nuclear@11 56 mesg, BUFSIZ);
nuclear@11 57 (void) fprintf(fp, mesg, event->request_code);
nuclear@11 58 if (event->request_code < 128) {
nuclear@11 59 sprintf(number, "%d", event->request_code);
nuclear@11 60 XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
nuclear@11 61 } else {
nuclear@11 62 for (ext = dpy->ext_procs;
nuclear@11 63 ext && (ext->codes.major_opcode != event->request_code);
nuclear@11 64 ext = ext->next)
nuclear@11 65 ;
nuclear@11 66 if (ext) {
nuclear@11 67 strncpy(buffer, ext->name, BUFSIZ);
nuclear@11 68 buffer[BUFSIZ - 1] = '\0';
nuclear@11 69 } else
nuclear@11 70 buffer[0] = '\0';
nuclear@11 71 }
nuclear@11 72 (void) fprintf(fp, " (%s)\n", buffer);
nuclear@11 73 if (event->request_code >= 128) {
nuclear@11 74 XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
nuclear@11 75 mesg, BUFSIZ);
nuclear@11 76 fputs(" ", fp);
nuclear@11 77 (void) fprintf(fp, mesg, event->minor_code);
nuclear@11 78 if (ext) {
nuclear@11 79 sprintf(mesg, "%s.%d", ext->name, event->minor_code);
nuclear@11 80 XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
nuclear@11 81 (void) fprintf(fp, " (%s)", buffer);
nuclear@11 82 }
nuclear@11 83 fputs("\n", fp);
nuclear@11 84 }
nuclear@11 85 if (event->error_code >= 128) {
nuclear@11 86 /* kludge, try to find the extension that caused it */
nuclear@11 87 buffer[0] = '\0';
nuclear@11 88 for (ext = dpy->ext_procs; ext; ext = ext->next) {
nuclear@11 89 if (ext->error_string)
nuclear@11 90 (*ext->error_string)(dpy, event->error_code, &ext->codes,
nuclear@11 91 buffer, BUFSIZ);
nuclear@11 92 if (buffer[0]) {
nuclear@11 93 bext = ext;
nuclear@11 94 break;
nuclear@11 95 }
nuclear@11 96 if (ext->codes.first_error &&
nuclear@11 97 ext->codes.first_error < (int)event->error_code &&
nuclear@11 98 (!bext || ext->codes.first_error > bext->codes.first_error))
nuclear@11 99 bext = ext;
nuclear@11 100 }
nuclear@11 101 if (bext)
nuclear@11 102 sprintf(buffer, "%s.%d", bext->name,
nuclear@11 103 event->error_code - bext->codes.first_error);
nuclear@11 104 else
nuclear@11 105 strcpy(buffer, "Value");
nuclear@11 106 XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
nuclear@11 107 if (mesg[0]) {
nuclear@11 108 fputs(" ", fp);
nuclear@11 109 (void) fprintf(fp, mesg, event->resourceid);
nuclear@11 110 fputs("\n", fp);
nuclear@11 111 }
nuclear@11 112 /* let extensions try to print the values */
nuclear@11 113 for (ext = dpy->ext_procs; ext; ext = ext->next) {
nuclear@11 114 if (ext->error_values)
nuclear@11 115 (*ext->error_values)(dpy, event, fp);
nuclear@11 116 }
nuclear@11 117 } else if ((event->error_code == BadWindow) ||
nuclear@11 118 (event->error_code == BadPixmap) ||
nuclear@11 119 (event->error_code == BadCursor) ||
nuclear@11 120 (event->error_code == BadFont) ||
nuclear@11 121 (event->error_code == BadDrawable) ||
nuclear@11 122 (event->error_code == BadColor) ||
nuclear@11 123 (event->error_code == BadGC) ||
nuclear@11 124 (event->error_code == BadIDChoice) ||
nuclear@11 125 (event->error_code == BadValue) ||
nuclear@11 126 (event->error_code == BadAtom)) {
nuclear@11 127 if (event->error_code == BadValue)
nuclear@11 128 XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
nuclear@11 129 mesg, BUFSIZ);
nuclear@11 130 else if (event->error_code == BadAtom)
nuclear@11 131 XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
nuclear@11 132 mesg, BUFSIZ);
nuclear@11 133 else
nuclear@11 134 XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
nuclear@11 135 mesg, BUFSIZ);
nuclear@11 136 fputs(" ", fp);
nuclear@11 137 (void) fprintf(fp, mesg, event->resourceid);
nuclear@11 138 fputs("\n", fp);
nuclear@11 139 }
nuclear@11 140 XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
nuclear@11 141 mesg, BUFSIZ);
nuclear@11 142 fputs(" ", fp);
nuclear@11 143 (void) fprintf(fp, mesg, event->serial);
nuclear@11 144 XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
nuclear@11 145 mesg, BUFSIZ);
nuclear@11 146 fputs("\n ", fp);
nuclear@11 147 (void) fprintf(fp, mesg, dpy->request);
nuclear@11 148 fputs("\n", fp);
nuclear@11 149 if (event->error_code == BadImplementation) return 0;
nuclear@11 150 return 1;
nuclear@11 151 }