DefErrMsg.c revision 6c321187
1/* $Xorg: DefErrMsg.c,v 1.4 2001/02/09 02:03:52 xorgcvs Exp $ */
2
3/*
4
5Copyright 1988, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings
25in this Software without prior written authorization from The Open Group.
26
27*/
28/* $XFree86: xc/lib/Xmu/DefErrMsg.c,v 1.7 2001/01/17 19:42:54 dawes Exp $ */
29
30#ifdef HAVE_CONFIG_H
31#include <config.h>
32#endif
33#include <stdio.h>
34#define NEED_EVENTS
35#include <X11/Xlibint.h>
36#include <X11/Xproto.h>
37#include <X11/Xmu/Error.h>
38#include <X11/Xmu/SysUtil.h>
39
40/*
41 * XmuPrintDefaultErrorMessage - print a nice error that looks like the usual
42 * message.  Returns 1 if the caller should consider exitting else 0.
43 */
44int
45XmuPrintDefaultErrorMessage(Display *dpy, XErrorEvent *event, FILE *fp)
46{
47    char buffer[BUFSIZ];
48    char mesg[BUFSIZ];
49    char number[32];
50    char *mtype = "XlibMessage";
51    register _XExtension *ext = (_XExtension *)NULL;
52    _XExtension *bext = (_XExtension *)NULL;
53    XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
54    XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
55    (void) fprintf(fp, "%s:  %s\n  ", mesg, buffer);
56    XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
57	mesg, BUFSIZ);
58    (void) fprintf(fp, mesg, event->request_code);
59    if (event->request_code < 128) {
60	XmuSnprintf(number, sizeof(number), "%d", event->request_code);
61	XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
62    } else {
63	/* XXX this is non-portable */
64	for (ext = dpy->ext_procs;
65	     ext && (ext->codes.major_opcode != event->request_code);
66	     ext = ext->next)
67	  ;
68	if (ext)
69	  XmuSnprintf(buffer, sizeof(buffer), "%s", ext->name);
70	else
71	    buffer[0] = '\0';
72    }
73    (void) fprintf(fp, " (%s)", buffer);
74    fputs("\n  ", fp);
75    if (event->request_code >= 128) {
76	XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
77			      mesg, BUFSIZ);
78	(void) fprintf(fp, mesg, event->minor_code);
79	if (ext) {
80	    XmuSnprintf(mesg, sizeof(mesg),
81			"%s.%d", ext->name, event->minor_code);
82	    XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
83	    (void) fprintf(fp, " (%s)", buffer);
84	}
85	fputs("\n  ", fp);
86    }
87    if (event->error_code >= 128) {
88	/* kludge, try to find the extension that caused it */
89	buffer[0] = '\0';
90	for (ext = dpy->ext_procs; ext; ext = ext->next) {
91	    if (ext->error_string)
92		(*ext->error_string)(dpy, event->error_code, &ext->codes,
93				     buffer, BUFSIZ);
94	    if (buffer[0]) {
95		bext = ext;
96		break;
97	    }
98	    if (ext->codes.first_error &&
99		ext->codes.first_error < event->error_code &&
100		(!bext || ext->codes.first_error > bext->codes.first_error))
101		bext = ext;
102	}
103	if (bext)
104	    XmuSnprintf(buffer, sizeof(buffer), "%s.%d", bext->name,
105			event->error_code - bext->codes.first_error);
106	else
107	    strcpy(buffer, "Value");
108	XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
109	if (mesg[0]) {
110	    fputs("  ", fp);
111	    (void) fprintf(fp, mesg, event->resourceid);
112	    fputs("\n", fp);
113	}
114	/* let extensions try to print the values */
115	for (ext = dpy->ext_procs; ext; ext = ext->next) {
116	    if (ext->error_values)
117		(*ext->error_values)(dpy, event, fp);
118	}
119    } else if ((event->error_code == BadWindow) ||
120	       (event->error_code == BadPixmap) ||
121	       (event->error_code == BadCursor) ||
122	       (event->error_code == BadFont) ||
123	       (event->error_code == BadDrawable) ||
124	       (event->error_code == BadColor) ||
125	       (event->error_code == BadGC) ||
126	       (event->error_code == BadIDChoice) ||
127	       (event->error_code == BadValue) ||
128	       (event->error_code == BadAtom)) {
129	if (event->error_code == BadValue)
130	    XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
131				  mesg, BUFSIZ);
132	else if (event->error_code == BadAtom)
133	    XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
134				  mesg, BUFSIZ);
135	else
136	    XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
137				  mesg, BUFSIZ);
138	(void) fprintf(fp, mesg, event->resourceid);
139	fputs("\n  ", fp);
140    }
141    XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
142	mesg, BUFSIZ);
143    (void) fprintf(fp, mesg, event->serial);
144    fputs("\n  ", fp);
145    XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
146	mesg, BUFSIZ);
147    (void) fprintf(fp, mesg, NextRequest(dpy)-1);
148    fputs("\n", fp);
149    if (event->error_code == BadImplementation) return 0;
150    return 1;
151}
152
153
154/*
155 * XmuSimpleErrorHandler - ignore errors for XQueryTree, XGetWindowAttributes,
156 * and XGetGeometry; print a message for everything else.  In all case, do
157 * not exit.
158 */
159int
160XmuSimpleErrorHandler(Display *dpy, XErrorEvent *errorp)
161{
162    switch (errorp->request_code) {
163      case X_QueryTree:
164      case X_GetWindowAttributes:
165        if (errorp->error_code == BadWindow) return 0;
166	break;
167      case X_GetGeometry:
168	if (errorp->error_code == BadDrawable) return 0;
169	break;
170    }
171    /* got a "real" X error */
172    return XmuPrintDefaultErrorMessage (dpy, errorp, stderr);
173}
174