1/*
2 */
3
4/***********************************************************
5
6Copyright 1987, 1988, 1998  The Open Group
7
8Permission to use, copy, modify, distribute, and sell this software and its
9documentation for any purpose is hereby granted without fee, provided that
10the above copyright notice appear in all copies and that both that
11copyright notice and this permission notice appear in supporting
12documentation.
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of The Open Group shall not be
25used in advertising or otherwise to promote the sale, use or other dealings
26in this Software without prior written authorization from The Open Group.
27
28
29Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
30
31                        All Rights Reserved
32
33Permission to use, copy, modify, and distribute this software and its
34documentation for any purpose and without fee is hereby granted,
35provided that the above copyright notice appear in all copies and that
36both that copyright notice and this permission notice appear in
37supporting documentation, and that the name of Digital not be
38used in advertising or publicity pertaining to distribution of the
39software without specific, written prior permission.
40
41DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47SOFTWARE.
48
49******************************************************************/
50
51#ifdef HAVE_CONFIG_H
52#include <config.h>
53#endif
54#include "Xlibint.h"
55#include <X11/Xos.h>
56#include "Xresource.h"
57#include <stdio.h>
58
59#ifndef ERRORDB
60#ifndef XERRORDB
61#define ERRORDB "/usr/lib/X11/XErrorDB"
62#else
63#define ERRORDB XERRORDB
64#endif
65#endif
66
67/*
68 * descriptions of errors in Section 4 of Protocol doc (pp. 350-351); more
69 * verbose descriptions are given in the error database
70 */
71static const char _XErrorList[] =
72    /* No error */          "no error\0"
73    /* BadRequest */        "BadRequest\0"
74    /* BadValue */          "BadValue\0"
75    /* BadWindow */         "BadWindow\0"
76    /* BadPixmap */         "BadPixmap\0"
77    /* BadAtom */           "BadAtom\0"
78    /* BadCursor */         "BadCursor\0"
79    /* BadFont */           "BadFont\0"
80    /* BadMatch */          "BadMatch\0"
81    /* BadDrawable */       "BadDrawable\0"
82    /* BadAccess */         "BadAccess\0"
83    /* BadAlloc */          "BadAlloc\0"
84    /* BadColor */          "BadColor\0"
85    /* BadGC */             "BadGC\0"
86    /* BadIDChoice */       "BadIDChoice\0"
87    /* BadName */           "BadName\0"
88    /* BadLength */         "BadLength\0"
89    /* BadImplementation */ "BadImplementation"
90;
91
92/* offsets into _XErrorList */
93static const unsigned char _XErrorOffsets[] = {
94    0, 9, 20, 29, 39, 49, 57, 67, 75, 84, 96,
95    106, 115, 124, 130, 142, 150, 160
96};
97
98
99int
100XGetErrorText(
101    register Display *dpy,
102    register int code,
103    char *buffer,
104    int nbytes)
105{
106    char buf[150];
107    register _XExtension *ext;
108    _XExtension *bext = (_XExtension *)NULL;
109
110    if (nbytes == 0) return 0;
111    if (code <= BadImplementation && code > 0) {
112        snprintf(buf, sizeof(buf), "%d", code);
113        (void) XGetErrorDatabaseText(dpy, "XProtoError", buf,
114                                     _XErrorList + _XErrorOffsets[code],
115				     buffer, nbytes);
116    } else
117	buffer[0] = '\0';
118    /* call out to any extensions interested */
119    for (ext = dpy->ext_procs; ext; ext = ext->next) {
120 	if (ext->error_string)
121 	    (*ext->error_string)(dpy, code, &ext->codes, buffer, nbytes);
122	if (ext->codes.first_error &&
123	    ext->codes.first_error <= code &&
124	    (!bext || ext->codes.first_error > bext->codes.first_error))
125	    bext = ext;
126    }
127    if (!buffer[0] && bext) {
128	snprintf(buf, sizeof(buf), "%s.%d",
129                 bext->name, code - bext->codes.first_error);
130	(void) XGetErrorDatabaseText(dpy, "XProtoError", buf, "", buffer, nbytes);
131    }
132    if (!buffer[0])
133	snprintf(buffer, nbytes, "%d", code);
134    return 0;
135}
136
137int
138/*ARGSUSED*/
139XGetErrorDatabaseText(
140    Display *dpy,
141    register _Xconst char *name,
142    register _Xconst char *type,
143    _Xconst char *defaultp,
144    char *buffer,
145    int nbytes)
146{
147
148    static XrmDatabase db = NULL;
149    XrmString type_str;
150    XrmValue result;
151    char temp[BUFSIZ];
152    char* tptr;
153    unsigned long tlen;
154
155    if (nbytes == 0) return 0;
156
157    if (!db) {
158	/* the Xrm routines expect to be called with the global
159	   mutex unlocked. */
160	XrmDatabase temp_db;
161	int do_destroy;
162	const char *dbname;
163
164	XrmInitialize();
165#ifdef WIN32
166	dbname = getenv("XERRORDB");
167	if (!dbname)
168	    dbname = ERRORDB;
169#else
170    dbname = ERRORDB;
171#endif
172	temp_db = XrmGetFileDatabase(dbname);
173
174	_XLockMutex(_Xglobal_lock);
175	if (!db) {
176	    db = temp_db;
177	    do_destroy = 0;
178	} else
179	    do_destroy = 1;	/* we didn't need to get it after all */
180	_XUnlockMutex(_Xglobal_lock);
181
182	if (do_destroy)
183	    XrmDestroyDatabase(temp_db);
184    }
185
186    if (db)
187    {
188	tlen = strlen (name) + strlen (type) + 2;
189	if (tlen <= sizeof(temp))
190	    tptr = temp;
191	else
192	    tptr = Xmalloc (tlen);
193	if (tptr) {
194	    snprintf(tptr, tlen, "%s.%s", name, type);
195	    XrmGetResource(db, tptr, "ErrorType.ErrorNumber",
196	      &type_str, &result);
197	    if (tptr != temp)
198		Xfree (tptr);
199	} else {
200	    result.addr = (XPointer) NULL;
201	}
202    }
203    else
204	result.addr = (XPointer)NULL;
205    if (!result.addr) {
206	result.addr = (XPointer) defaultp;
207	result.size = (unsigned)strlen(defaultp) + 1;
208    }
209    (void) strncpy (buffer, (char *) result.addr, (size_t)nbytes);
210    if (result.size > nbytes) buffer[nbytes-1] = '\0';
211    return 0;
212}
213