1 /* This file contains compatibility routines for systems without Xmu.
2 * You would be better served by installing Xmu on your machine or
3 * yelling at your vendor to ship it.
6 /* XEmacs changes: rindex -> strrchr */
8 /* Synched up with: Not in FSF. */
14 * Copyright 1989 Massachusetts Institute of Technology
16 * Permission to use, copy, modify, and distribute this software and its
17 * documentation for any purpose and without fee is hereby granted, provided
18 * that the above copyright notice appear in all copies and that both that
19 * copyright notice and this permission notice appear in supporting
20 * documentation, and that the name of M.I.T. not be used in advertising
21 * or publicity pertaining to distribution of the software without specific,
22 * written prior permission. M.I.T. makes no representations about the
23 * suitability of this software for any purpose. It is provided "as is"
24 * without express or implied warranty.
26 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
28 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
30 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
31 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33 #include <X11/cursorfont.h>
35 #include <X11/Xutil.h>
36 #include <X11/Intrinsic.h>
38 /* for XmuCopyISOLatin1Lowered */
40 #include <X11/keysymdef.h>
43 #if (XtSpecificationRelease >= 5)
45 * Don't know why, but this works with X11R5, not X11R4.
46 * Anyway, _XExtension is defined in Xlib.h in X11R4, so we do not need
47 * Xlibint in that case...
49 #include <X11/Xlibint.h>
51 #include <X11/Xproto.h>
55 int XmuCursorNameToIndex(const char *name)
57 static const struct _CursorName {
62 "x_cursor", XC_X_cursor}, {
64 "based_arrow_down", XC_based_arrow_down}, {
65 "based_arrow_up", XC_based_arrow_up}, {
67 "bogosity", XC_bogosity}, {
68 "bottom_left_corner", XC_bottom_left_corner}, {
69 "bottom_right_corner", XC_bottom_right_corner}, {
70 "bottom_side", XC_bottom_side}, {
71 "bottom_tee", XC_bottom_tee}, {
72 "box_spiral", XC_box_spiral}, {
73 "center_ptr", XC_center_ptr}, {
74 "circle", XC_circle}, {
76 "coffee_mug", XC_coffee_mug}, {
78 "cross_reverse", XC_cross_reverse}, {
79 "crosshair", XC_crosshair}, {
80 "diamond_cross", XC_diamond_cross}, {
82 "dotbox", XC_dotbox}, {
83 "double_arrow", XC_double_arrow}, {
84 "draft_large", XC_draft_large}, {
85 "draft_small", XC_draft_small}, {
86 "draped_box", XC_draped_box}, {
87 "exchange", XC_exchange}, {
89 "gobbler", XC_gobbler}, {
95 "iron_cross", XC_iron_cross}, {
96 "left_ptr", XC_left_ptr}, {
97 "left_side", XC_left_side}, {
98 "left_tee", XC_left_tee}, {
99 "leftbutton", XC_leftbutton}, {
100 "ll_angle", XC_ll_angle}, {
101 "lr_angle", XC_lr_angle}, {
103 "middlebutton", XC_middlebutton}, {
104 "mouse", XC_mouse}, {
105 "pencil", XC_pencil}, {
106 "pirate", XC_pirate}, {
108 "question_arrow", XC_question_arrow}, {
109 "right_ptr", XC_right_ptr}, {
110 "right_side", XC_right_side}, {
111 "right_tee", XC_right_tee}, {
112 "rightbutton", XC_rightbutton}, {
113 "rtl_logo", XC_rtl_logo}, {
114 "sailboat", XC_sailboat}, {
115 "sb_down_arrow", XC_sb_down_arrow}, {
116 "sb_h_double_arrow", XC_sb_h_double_arrow}, {
117 "sb_left_arrow", XC_sb_left_arrow}, {
118 "sb_right_arrow", XC_sb_right_arrow}, {
119 "sb_up_arrow", XC_sb_up_arrow}, {
120 "sb_v_double_arrow", XC_sb_v_double_arrow}, {
121 "shuttle", XC_shuttle}, {
122 "sizing", XC_sizing}, {
123 "spider", XC_spider}, {
124 "spraycan", XC_spraycan}, {
126 "target", XC_target}, {
127 "tcross", XC_tcross}, {
128 "top_left_arrow", XC_top_left_arrow}, {
129 "top_left_corner", XC_top_left_corner}, {
130 "top_right_corner", XC_top_right_corner}, {
131 "top_side", XC_top_side}, {
132 "top_tee", XC_top_tee}, {
134 "ul_angle", XC_ul_angle}, {
135 "umbrella", XC_umbrella}, {
136 "ur_angle", XC_ur_angle}, {
137 "watch", XC_watch}, {
138 "xterm", XC_xterm},};
139 const struct _CursorName *table;
143 if (strlen(name) >= sizeof tmp)
145 for (i = 0; i < strlen(name); i++)
146 if (isupper((unsigned char)name[i]))
147 tmp[i] = tolower((unsigned char)name[i]);
152 for (i = 0, table = cursor_names; i < XtNumber(cursor_names);
154 if (strcmp(tmp, table->name) == 0)
162 * Based on an optimized version provided by Jim Becker, August 5, 1988.
167 /* shared data for the image read/parse logic */
168 static short hexTable[256]; /* conversion value */
169 static int hex_initialized; /* easier to fill in at run time */
172 * Table index for the hex values. Initialized once, first time.
173 * Used for translation value or delimiter significance lookup.
175 static void initHexTable(void)
178 * We build the table at run time for several reasons:
180 * 1. portable to non-ASCII machines.
181 * 2. still reentrant since we set the init flag after setting table.
182 * 3. easier to extend.
183 * 4. less prone to bugs.
208 /* delimiters of significance are flagged w/ negative value */
219 * read next hex value in the input stream, return -1 if EOF
221 static int NextInt(FILE * fstream)
228 /* loop, accumulate hex value until find delimiter */
229 /* skip any initial delimiters found in read stream */
237 /* trim high bits, check type and accumulate */
239 if (isascii(ch) && isxdigit(ch)) {
240 value = (value << 4) + hexTable[ch];
242 } else if ((hexTable[ch]) < 0 && gotone)
250 * The data returned by the following routine is always in left-most byte
251 * first and left-most bit first. If it doesn't return BitmapSuccess then
252 * its arguments won't have been touched. This routine should look as much
253 * like the Xlib routine XReadBitmapfile as possible.
255 int XmuReadBitmapData(FILE * fstream, /* handle on file */
256 unsigned int *width, /* RETURNED */
257 unsigned int *height, /* RETURNED */
258 unsigned char **datap, /* RETURNED */
259 int *x_hot, int *y_hot)
261 unsigned char *data = NULL; /* working variable */
262 char line[MAX_SIZE]; /* input line from file */
263 int size; /* number of bytes of data */
264 char name_and_type[MAX_SIZE]; /* an input line */
265 char *type; /* for parsing */
266 int value; /* from an input line */
267 int version10p; /* boolean, old format */
268 int padding; /* to handle alignment */
269 int bytes_per_line; /* per scanline of data */
270 unsigned int ww = 0; /* width */
271 unsigned int hh = 0; /* height */
272 int hx = -1; /* x hotspot */
273 int hy = -1; /* y hotspot */
276 #define Xmalloc(size) malloc(size)
279 /* first time initialization */
280 if (!hex_initialized)
283 /* error cleanup and return macro */
284 #define RETURN(code) { if (data) free (data); return code; }
286 while (fgets(line, MAX_SIZE, fstream)) {
287 if (strlen(line) == MAX_SIZE - 1) {
288 RETURN(BitmapFileInvalid);
290 if (sscanf(line, "#define %s %d", name_and_type, &value) == 2) {
291 if (!(type = strrchr(name_and_type, '_')))
292 type = name_and_type;
296 if (!strcmp("width", type))
297 ww = (unsigned int)value;
298 if (!strcmp("height", type))
299 hh = (unsigned int)value;
300 if (!strcmp("hot", type)) {
301 if (type-- == name_and_type
302 || type-- == name_and_type)
304 if (!strcmp("x_hot", type))
306 if (!strcmp("y_hot", type))
312 if (sscanf(line, "static short %s = {", name_and_type) == 1)
315 (line, "static unsigned char %s = {",
318 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
323 if (!(type = strrchr(name_and_type, '_')))
324 type = name_and_type;
328 if (strcmp("bits[]", type))
332 RETURN(BitmapFileInvalid);
334 if ((ww % 16) && ((ww % 16) < 9) && version10p)
339 bytes_per_line = (ww + 7) / 8 + padding;
341 size = bytes_per_line * hh;
342 data = (unsigned char *)Xmalloc((unsigned int)size);
344 RETURN(BitmapNoMemory);
350 for (bytes = 0, ptr = data; bytes < size; (bytes += 2)) {
351 if ((value = NextInt(fstream)) < 0)
352 RETURN(BitmapFileInvalid);
354 if (!padding || ((bytes + 2) % bytes_per_line))
355 *(ptr++) = value >> 8;
361 for (bytes = 0, ptr = data; bytes < size;
363 if ((value = NextInt(fstream)) < 0)
364 RETURN(BitmapFileInvalid);
372 RETURN(BitmapFileInvalid);
384 RETURN(BitmapSuccess);
387 int XmuReadBitmapDataFromFile(const char *filename,
388 /* Remaining args are RETURNED */
390 unsigned int *height,
391 unsigned char **datap, int *x_hot, int *y_hot)
396 if ((fstream = fopen(filename, "r")) == NULL) {
397 return BitmapOpenFailed;
399 status = XmuReadBitmapData(fstream, width, height, datap, x_hot, y_hot);
405 * XmuPrintDefaultErrorMessage - print a nice error that looks like the usual
406 * message. Return 1 if the caller should consider exiting, else 0.
408 int XmuPrintDefaultErrorMessage(Display * dpy, XErrorEvent * event, FILE * fp)
413 char *mtype = "XlibMessage";
414 _XExtension *ext = (_XExtension *) NULL;
415 XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
416 XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
417 fprintf(fp, "%s: %s\n ", mesg, buffer);
418 XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
420 fprintf(fp, mesg, event->request_code);
421 if (event->request_code < 128) {
422 int sz = snprintf(number, sizeof(number), "%d", event->request_code);
423 assert(sz >= 0 && sz < sizeof(number));
424 XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer,
427 /* XXX this is non-portable */
428 for (ext = dpy->ext_procs;
429 ext && (ext->codes.major_opcode != event->request_code);
432 strncpy(buffer, ext->name, sizeof(buffer));
433 buffer[sizeof(buffer)-1] = '\0';
437 fprintf(fp, " (%s)", buffer);
439 #if (XtSpecificationRelease >= 5)
440 if (event->request_code >= 128) {
441 XGetErrorDatabaseText(dpy, mtype, "MinorCode",
442 "Request Minor code %d", mesg, BUFSIZ);
443 fprintf(fp, mesg, event->minor_code);
445 in sz = snprintf(mesg, sizeof(mesg), "%s.%d", ext->name,
447 assert(sz >= 0 && sz < sizeof(mesg));
448 XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer,
450 fprintf(fp, " (%s)", buffer);
454 if (event->error_code >= 128) {
455 /* let extensions try to print the values */
456 /* XXX this is non-portable code */
457 for (ext = dpy->ext_procs; ext; ext = ext->next) {
458 if (ext->error_values)
459 (*ext->error_values) (dpy, event, fp);
461 /* the rest is a fallback, providing a simple default */
462 /* kludge, try to find the extension that caused it */
464 for (ext = dpy->ext_procs; ext; ext = ext->next) {
465 if (ext->error_string)
466 (*ext->error_string) (dpy, event->error_code,
473 int sz = snprintf(buffer, sizeof(buffer), "%s.%d",
475 event->error_code - ext->codes.first_error);
476 assert(sz >= 0 && sz < sizeof(buffer));
478 strncpy(buffer, "Value", sizeof(buffer));
479 XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
481 fprintf(fp, mesg, event->resourceid);
484 } else if ((event->error_code == BadWindow) ||
485 (event->error_code == BadPixmap) ||
486 (event->error_code == BadCursor) ||
487 (event->error_code == BadFont) ||
488 (event->error_code == BadDrawable) ||
489 (event->error_code == BadColor) ||
490 (event->error_code == BadGC) ||
491 (event->error_code == BadIDChoice) ||
492 (event->error_code == BadValue) ||
493 (event->error_code == BadAtom)) {
494 if (event->error_code == BadValue)
495 XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
497 else if (event->error_code == BadAtom)
498 XGetErrorDatabaseText(dpy, mtype, "AtomID",
499 "AtomID 0x%x", mesg, BUFSIZ);
501 XGetErrorDatabaseText(dpy, mtype, "ResourceID",
502 "ResourceID 0x%x", mesg, BUFSIZ);
503 fprintf(fp, mesg, event->resourceid);
506 #elif (XtSpecificationRelease == 4)
507 XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
509 fprintf(fp, mesg, event->minor_code);
512 int sz = snprintf(mesg, sizeof(mesg), "%s.%d", ext->name, event->minor_code);
513 assert(sz >= 0 && sz < sizeof(mesg));
514 XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer,
516 fprintf(fp, " (%s)", buffer);
518 XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
520 fprintf(fp, mesg, event->resourceid);
523 ERROR ! Unsupported release of X11
525 XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
527 fprintf(fp, mesg, event->serial);
529 XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
531 fprintf(fp, mesg, NextRequest(dpy) - 1);
533 if (event->error_code == BadImplementation)
539 * XmuSimpleErrorHandler - ignore errors for XQueryTree, XGetWindowAttributes,
540 * and XGetGeometry; print a message for everything else. In all case, do
543 int XmuSimpleErrorHandler(Display * dpy, XErrorEvent * errorp)
545 switch (errorp->request_code) {
547 case X_GetWindowAttributes:
548 if (errorp->error_code == BadWindow)
552 if (errorp->error_code == BadDrawable)
556 /* got a "real" X error */
557 return XmuPrintDefaultErrorMessage(dpy, errorp, stderr);
560 void XmuCopyISOLatin1Lowered(char *dst, const char *src)
562 unsigned char *dest = (unsigned char *)dst;
563 unsigned char *source = (unsigned char *)src;
565 for (; *source; source++, dest++) {
566 if ((*source >= XK_A) && (*source <= XK_Z))
567 *dest = *source + (XK_a - XK_A);
568 else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis))
569 *dest = *source + (XK_agrave - XK_Agrave);
570 else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn))
571 *dest = *source + (XK_oslash - XK_Ooblique);
577 #endif /* !HAVE_XMU */