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