xglcomp

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