1 /* 2 */ 3 4 /*********************************************************** 5 6 Copyright 1987, 1988, 1998 The Open Group 7 8 Permission to use, copy, modify, distribute, and sell this software and its 9 documentation for any purpose is hereby granted without fee, provided that 10 the above copyright notice appear in all copies and that both that 11 copyright notice and this permission notice appear in supporting 12 documentation. 13 14 The above copyright notice and this permission notice shall be included in 15 all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 Except as contained in this notice, the name of The Open Group shall not be 25 used in advertising or otherwise to promote the sale, use or other dealings 26 in this Software without prior written authorization from The Open Group. 27 28 29 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 30 31 All Rights Reserved 32 33 Permission to use, copy, modify, and distribute this software and its 34 documentation for any purpose and without fee is hereby granted, 35 provided that the above copyright notice appear in all copies and that 36 both that copyright notice and this permission notice appear in 37 supporting documentation, and that the name of Digital not be 38 used in advertising or publicity pertaining to distribution of the 39 software without specific, written prior permission. 40 41 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 42 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 43 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 44 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 45 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 46 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 47 SOFTWARE. 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 */ 71 static 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 */ 93 static 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 99 int 100 XGetErrorText( 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 137 int 138 /*ARGSUSED*/ 139 XGetErrorDatabaseText( 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