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