Mercurial > hg > xemacs-beta
comparison src/xmu.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 0293115a14e9 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
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. | |
4 */ | |
5 | |
6 /* XEmacs changes: rindex -> strrchr */ | |
7 | |
8 /* Synched up with: Not in FSF. */ | |
9 | |
10 #include <config.h> | |
11 | |
12 #ifndef HAVE_XMU | |
13 /* | |
14 * Copyright 1989 Massachusetts Institute of Technology | |
15 * | |
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. | |
25 * | |
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. | |
32 */ | |
33 #include <X11/cursorfont.h> | |
34 #include <X11/Xos.h> | |
35 #include <X11/Xlib.h> | |
36 #include <X11/Xutil.h> | |
37 #include <X11/Intrinsic.h> | |
38 | |
39 /* for XmuCopyISOLatin1Lowered */ | |
40 #define XK_LATIN1 | |
41 #include <X11/keysymdef.h> | |
42 #undef XK_LATIN1 | |
43 | |
44 #if (XtSpecificationRelease >= 5) | |
45 /* | |
46 * Don't know why, but this works with X11R5, not X11R4. | |
47 * Anyway, _XExtension is defined in Xlib.h in X11R4, so we do not need | |
48 * Xlibint in that case... | |
49 */ | |
50 #include <X11/Xlibint.h> | |
51 #endif | |
52 #include <X11/Xproto.h> | |
53 #include <stdio.h> | |
54 #include <ctype.h> | |
55 | |
56 | |
57 int XmuCursorNameToIndex (const char *name) | |
58 { | |
59 static const struct _CursorName { | |
60 const char *name; | |
61 unsigned int shape; | |
62 } cursor_names[] = { | |
63 {"x_cursor", XC_X_cursor}, | |
64 {"arrow", XC_arrow}, | |
65 {"based_arrow_down", XC_based_arrow_down}, | |
66 {"based_arrow_up", XC_based_arrow_up}, | |
67 {"boat", XC_boat}, | |
68 {"bogosity", XC_bogosity}, | |
69 {"bottom_left_corner", XC_bottom_left_corner}, | |
70 {"bottom_right_corner", XC_bottom_right_corner}, | |
71 {"bottom_side", XC_bottom_side}, | |
72 {"bottom_tee", XC_bottom_tee}, | |
73 {"box_spiral", XC_box_spiral}, | |
74 {"center_ptr", XC_center_ptr}, | |
75 {"circle", XC_circle}, | |
76 {"clock", XC_clock}, | |
77 {"coffee_mug", XC_coffee_mug}, | |
78 {"cross", XC_cross}, | |
79 {"cross_reverse", XC_cross_reverse}, | |
80 {"crosshair", XC_crosshair}, | |
81 {"diamond_cross", XC_diamond_cross}, | |
82 {"dot", XC_dot}, | |
83 {"dotbox", XC_dotbox}, | |
84 {"double_arrow", XC_double_arrow}, | |
85 {"draft_large", XC_draft_large}, | |
86 {"draft_small", XC_draft_small}, | |
87 {"draped_box", XC_draped_box}, | |
88 {"exchange", XC_exchange}, | |
89 {"fleur", XC_fleur}, | |
90 {"gobbler", XC_gobbler}, | |
91 {"gumby", XC_gumby}, | |
92 {"hand1", XC_hand1}, | |
93 {"hand2", XC_hand2}, | |
94 {"heart", XC_heart}, | |
95 {"icon", XC_icon}, | |
96 {"iron_cross", XC_iron_cross}, | |
97 {"left_ptr", XC_left_ptr}, | |
98 {"left_side", XC_left_side}, | |
99 {"left_tee", XC_left_tee}, | |
100 {"leftbutton", XC_leftbutton}, | |
101 {"ll_angle", XC_ll_angle}, | |
102 {"lr_angle", XC_lr_angle}, | |
103 {"man", XC_man}, | |
104 {"middlebutton", XC_middlebutton}, | |
105 {"mouse", XC_mouse}, | |
106 {"pencil", XC_pencil}, | |
107 {"pirate", XC_pirate}, | |
108 {"plus", XC_plus}, | |
109 {"question_arrow", XC_question_arrow}, | |
110 {"right_ptr", XC_right_ptr}, | |
111 {"right_side", XC_right_side}, | |
112 {"right_tee", XC_right_tee}, | |
113 {"rightbutton", XC_rightbutton}, | |
114 {"rtl_logo", XC_rtl_logo}, | |
115 {"sailboat", XC_sailboat}, | |
116 {"sb_down_arrow", XC_sb_down_arrow}, | |
117 {"sb_h_double_arrow", XC_sb_h_double_arrow}, | |
118 {"sb_left_arrow", XC_sb_left_arrow}, | |
119 {"sb_right_arrow", XC_sb_right_arrow}, | |
120 {"sb_up_arrow", XC_sb_up_arrow}, | |
121 {"sb_v_double_arrow", XC_sb_v_double_arrow}, | |
122 {"shuttle", XC_shuttle}, | |
123 {"sizing", XC_sizing}, | |
124 {"spider", XC_spider}, | |
125 {"spraycan", XC_spraycan}, | |
126 {"star", XC_star}, | |
127 {"target", XC_target}, | |
128 {"tcross", XC_tcross}, | |
129 {"top_left_arrow", XC_top_left_arrow}, | |
130 {"top_left_corner", XC_top_left_corner}, | |
131 {"top_right_corner", XC_top_right_corner}, | |
132 {"top_side", XC_top_side}, | |
133 {"top_tee", XC_top_tee}, | |
134 {"trek", XC_trek}, | |
135 {"ul_angle", XC_ul_angle}, | |
136 {"umbrella", XC_umbrella}, | |
137 {"ur_angle", XC_ur_angle}, | |
138 {"watch", XC_watch}, | |
139 {"xterm", XC_xterm}, | |
140 }; | |
141 const struct _CursorName *table; | |
142 int i; | |
143 char tmp[40]; | |
144 | |
145 if (strlen (name) >= sizeof tmp) return -1; | |
146 for (i=0; i<strlen(name); i++) | |
147 if (isupper((unsigned char) name[i])) | |
148 tmp[i] = tolower((unsigned char) name[i]); | |
149 else | |
150 tmp[i] = name[i]; | |
151 tmp[i] = 0; | |
152 | |
153 for (i=0, table=cursor_names; i < XtNumber(cursor_names); i++, table++ ) { | |
154 if (strcmp(tmp, table->name) == 0) return table->shape; | |
155 } | |
156 | |
157 return -1; | |
158 } | |
159 | |
160 | |
161 /* | |
162 * Based on an optimized version provided by Jim Becker, Auguest 5, 1988. | |
163 */ | |
164 | |
165 | |
166 #define MAX_SIZE 255 | |
167 | |
168 /* shared data for the image read/parse logic */ | |
169 static short hexTable[256]; /* conversion value */ | |
170 static Bool initialized = False; /* easier to fill in at run time */ | |
171 | |
172 | |
173 /* | |
174 * Table index for the hex values. Initialized once, first time. | |
175 * Used for translation value or delimiter significance lookup. | |
176 */ | |
177 static void initHexTable() | |
178 { | |
179 /* | |
180 * We build the table at run time for several reasons: | |
181 * | |
182 * 1. portable to non-ASCII machines. | |
183 * 2. still reentrant since we set the init flag after setting table. | |
184 * 3. easier to extend. | |
185 * 4. less prone to bugs. | |
186 */ | |
187 hexTable['0'] = 0; hexTable['1'] = 1; | |
188 hexTable['2'] = 2; hexTable['3'] = 3; | |
189 hexTable['4'] = 4; hexTable['5'] = 5; | |
190 hexTable['6'] = 6; hexTable['7'] = 7; | |
191 hexTable['8'] = 8; hexTable['9'] = 9; | |
192 hexTable['A'] = 10; hexTable['B'] = 11; | |
193 hexTable['C'] = 12; hexTable['D'] = 13; | |
194 hexTable['E'] = 14; hexTable['F'] = 15; | |
195 hexTable['a'] = 10; hexTable['b'] = 11; | |
196 hexTable['c'] = 12; hexTable['d'] = 13; | |
197 hexTable['e'] = 14; hexTable['f'] = 15; | |
198 | |
199 /* delimiters of significance are flagged w/ negative value */ | |
200 hexTable[' '] = -1; hexTable[','] = -1; | |
201 hexTable['}'] = -1; hexTable['\n'] = -1; | |
202 hexTable['\t'] = -1; | |
203 | |
204 initialized = True; | |
205 } | |
206 | |
207 /* | |
208 * read next hex value in the input stream, return -1 if EOF | |
209 */ | |
210 static int NextInt (fstream) | |
211 FILE *fstream; | |
212 { | |
213 int ch; | |
214 int value = 0; | |
215 int gotone = 0; | |
216 int done = 0; | |
217 | |
218 /* loop, accumulate hex value until find delimiter */ | |
219 /* skip any initial delimiters found in read stream */ | |
220 | |
221 while (!done) { | |
222 ch = getc(fstream); | |
223 if (ch == EOF) { | |
224 value = -1; | |
225 done++; | |
226 } else { | |
227 /* trim high bits, check type and accumulate */ | |
228 ch &= 0xff; | |
229 if (isascii(ch) && isxdigit(ch)) { | |
230 value = (value << 4) + hexTable[ch]; | |
231 gotone++; | |
232 } else if ((hexTable[ch]) < 0 && gotone) | |
233 done++; | |
234 } | |
235 } | |
236 return value; | |
237 } | |
238 | |
239 | |
240 /* | |
241 * The data returned by the following routine is always in left-most byte | |
242 * first and left-most bit first. If it doesn't return BitmapSuccess then | |
243 * its arguments won't have been touched. This routine should look as much | |
244 * like the Xlib routine XReadBitmapfile as possible. | |
245 */ | |
246 int XmuReadBitmapData (fstream, width, height, datap, x_hot, y_hot) | |
247 FILE *fstream; /* handle on file */ | |
248 unsigned int *width, *height; /* RETURNED */ | |
249 unsigned char **datap; /* RETURNED */ | |
250 int *x_hot, *y_hot; /* RETURNED */ | |
251 { | |
252 unsigned char *data = NULL; /* working variable */ | |
253 char line[MAX_SIZE]; /* input line from file */ | |
254 int size; /* number of bytes of data */ | |
255 char name_and_type[MAX_SIZE]; /* an input line */ | |
256 char *type; /* for parsing */ | |
257 int value; /* from an input line */ | |
258 int version10p; /* boolean, old format */ | |
259 int padding; /* to handle alignment */ | |
260 int bytes_per_line; /* per scanline of data */ | |
261 unsigned int ww = 0; /* width */ | |
262 unsigned int hh = 0; /* height */ | |
263 int hx = -1; /* x hotspot */ | |
264 int hy = -1; /* y hotspot */ | |
265 | |
266 #ifndef Xmalloc | |
267 #define Xmalloc(size) malloc(size) | |
268 #endif | |
269 | |
270 /* first time initialization */ | |
271 if (initialized == False) initHexTable(); | |
272 | |
273 /* error cleanup and return macro */ | |
274 #define RETURN(code) { if (data) free (data); return code; } | |
275 | |
276 while (fgets(line, MAX_SIZE, fstream)) { | |
277 if (strlen(line) == MAX_SIZE-1) { | |
278 RETURN (BitmapFileInvalid); | |
279 } | |
280 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { | |
281 if (!(type = strrchr(name_and_type, '_'))) | |
282 type = name_and_type; | |
283 else | |
284 type++; | |
285 | |
286 if (!strcmp("width", type)) | |
287 ww = (unsigned int) value; | |
288 if (!strcmp("height", type)) | |
289 hh = (unsigned int) value; | |
290 if (!strcmp("hot", type)) { | |
291 if (type-- == name_and_type || type-- == name_and_type) | |
292 continue; | |
293 if (!strcmp("x_hot", type)) | |
294 hx = value; | |
295 if (!strcmp("y_hot", type)) | |
296 hy = value; | |
297 } | |
298 continue; | |
299 } | |
300 | |
301 if (sscanf(line, "static short %s = {", name_and_type) == 1) | |
302 version10p = 1; | |
303 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) | |
304 version10p = 0; | |
305 else if (sscanf(line, "static char %s = {", name_and_type) == 1) | |
306 version10p = 0; | |
307 else | |
308 continue; | |
309 | |
310 if (!(type = strrchr(name_and_type, '_'))) | |
311 type = name_and_type; | |
312 else | |
313 type++; | |
314 | |
315 if (strcmp("bits[]", type)) | |
316 continue; | |
317 | |
318 if (!ww || !hh) | |
319 RETURN (BitmapFileInvalid); | |
320 | |
321 if ((ww % 16) && ((ww % 16) < 9) && version10p) | |
322 padding = 1; | |
323 else | |
324 padding = 0; | |
325 | |
326 bytes_per_line = (ww+7)/8 + padding; | |
327 | |
328 size = bytes_per_line * hh; | |
329 data = (unsigned char *) Xmalloc ((unsigned int) size); | |
330 if (!data) | |
331 RETURN (BitmapNoMemory); | |
332 | |
333 if (version10p) { | |
334 unsigned char *ptr; | |
335 int bytes; | |
336 | |
337 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) { | |
338 if ((value = NextInt(fstream)) < 0) | |
339 RETURN (BitmapFileInvalid); | |
340 *(ptr++) = value; | |
341 if (!padding || ((bytes+2) % bytes_per_line)) | |
342 *(ptr++) = value >> 8; | |
343 } | |
344 } else { | |
345 unsigned char *ptr; | |
346 int bytes; | |
347 | |
348 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) { | |
349 if ((value = NextInt(fstream)) < 0) | |
350 RETURN (BitmapFileInvalid); | |
351 *ptr=value; | |
352 } | |
353 } | |
354 break; | |
355 } /* end while */ | |
356 | |
357 if (data == NULL) { | |
358 RETURN (BitmapFileInvalid); | |
359 } | |
360 | |
361 *datap = data; | |
362 data = NULL; | |
363 *width = ww; | |
364 *height = hh; | |
365 if (x_hot) *x_hot = hx; | |
366 if (y_hot) *y_hot = hy; | |
367 | |
368 RETURN (BitmapSuccess); | |
369 } | |
370 | |
371 | |
372 #if NeedFunctionPrototypes | |
373 int XmuReadBitmapDataFromFile (const char *filename, unsigned int *width, | |
374 unsigned int *height, unsigned char **datap, | |
375 int *x_hot, int *y_hot) | |
376 #else | |
377 int XmuReadBitmapDataFromFile (filename, width, height, datap, x_hot, y_hot) | |
378 char *filename; | |
379 unsigned int *width, *height; /* RETURNED */ | |
380 unsigned char **datap; /* RETURNED */ | |
381 int *x_hot, *y_hot; /* RETURNED */ | |
382 #endif | |
383 { | |
384 FILE *fstream; | |
385 int status; | |
386 | |
387 if ((fstream = fopen (filename, "r")) == NULL) { | |
388 return BitmapOpenFailed; | |
389 } | |
390 status = XmuReadBitmapData (fstream, width, height, datap, x_hot, y_hot); | |
391 fclose (fstream); | |
392 return status; | |
393 } | |
394 | |
395 /* | |
396 * XmuPrintDefaultErrorMessage - print a nice error that looks like the usual | |
397 * message. Returns 1 if the caller should consider exitting else 0. | |
398 */ | |
399 int XmuPrintDefaultErrorMessage (dpy, event, fp) | |
400 Display *dpy; | |
401 XErrorEvent *event; | |
402 FILE *fp; | |
403 { | |
404 char buffer[BUFSIZ]; | |
405 char mesg[BUFSIZ]; | |
406 char number[32]; | |
407 char *mtype = "XlibMessage"; | |
408 _XExtension *ext = (_XExtension *)NULL; | |
409 XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); | |
410 XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); | |
411 (void) fprintf(fp, "%s: %s\n ", mesg, buffer); | |
412 XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", | |
413 mesg, BUFSIZ); | |
414 (void) fprintf(fp, mesg, event->request_code); | |
415 if (event->request_code < 128) { | |
416 sprintf(number, "%d", event->request_code); | |
417 XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); | |
418 } else { | |
419 /* XXX this is non-portable */ | |
420 for (ext = dpy->ext_procs; | |
421 ext && (ext->codes.major_opcode != event->request_code); | |
422 ext = ext->next) | |
423 ; | |
424 if (ext) | |
425 strcpy(buffer, ext->name); | |
426 else | |
427 buffer[0] = '\0'; | |
428 } | |
429 (void) fprintf(fp, " (%s)", buffer); | |
430 fputs("\n ", fp); | |
431 #if (XtSpecificationRelease >= 5) | |
432 if (event->request_code >= 128) { | |
433 XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", | |
434 mesg, BUFSIZ); | |
435 (void) fprintf(fp, mesg, event->minor_code); | |
436 if (ext) { | |
437 sprintf(mesg, "%s.%d", ext->name, event->minor_code); | |
438 XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); | |
439 (void) fprintf(fp, " (%s)", buffer); | |
440 } | |
441 fputs("\n ", fp); | |
442 } | |
443 if (event->error_code >= 128) { | |
444 /* let extensions try to print the values */ | |
445 /* XXX this is non-portable code */ | |
446 for (ext = dpy->ext_procs; ext; ext = ext->next) { | |
447 if (ext->error_values) | |
448 (*ext->error_values)(dpy, event, fp); | |
449 } | |
450 /* the rest is a fallback, providing a simple default */ | |
451 /* kludge, try to find the extension that caused it */ | |
452 buffer[0] = '\0'; | |
453 for (ext = dpy->ext_procs; ext; ext = ext->next) { | |
454 if (ext->error_string) | |
455 (*ext->error_string)(dpy, event->error_code, &ext->codes, | |
456 buffer, BUFSIZ); | |
457 if (buffer[0]) | |
458 break; | |
459 } | |
460 if (buffer[0]) | |
461 sprintf(buffer, "%s.%d", ext->name, | |
462 event->error_code - ext->codes.first_error); | |
463 else | |
464 strcpy(buffer, "Value"); | |
465 XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); | |
466 if (*mesg) { | |
467 (void) fprintf(fp, mesg, event->resourceid); | |
468 fputs("\n ", fp); | |
469 } | |
470 } else if ((event->error_code == BadWindow) || | |
471 (event->error_code == BadPixmap) || | |
472 (event->error_code == BadCursor) || | |
473 (event->error_code == BadFont) || | |
474 (event->error_code == BadDrawable) || | |
475 (event->error_code == BadColor) || | |
476 (event->error_code == BadGC) || | |
477 (event->error_code == BadIDChoice) || | |
478 (event->error_code == BadValue) || | |
479 (event->error_code == BadAtom)) { | |
480 if (event->error_code == BadValue) | |
481 XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", | |
482 mesg, BUFSIZ); | |
483 else if (event->error_code == BadAtom) | |
484 XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", | |
485 mesg, BUFSIZ); | |
486 else | |
487 XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", | |
488 mesg, BUFSIZ); | |
489 (void) fprintf(fp, mesg, event->resourceid); | |
490 fputs("\n ", fp); | |
491 } | |
492 #elif (XtSpecificationRelease == 4) | |
493 XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", | |
494 mesg, BUFSIZ); | |
495 (void) fprintf(fp, mesg, event->minor_code); | |
496 fputs("\n ", fp); | |
497 if (ext) { | |
498 sprintf(mesg, "%s.%d", ext->name, event->minor_code); | |
499 XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); | |
500 (void) fprintf(fp, " (%s)", buffer); | |
501 } | |
502 XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", | |
503 mesg, BUFSIZ); | |
504 (void) fprintf(fp, mesg, event->resourceid); | |
505 fputs("\n ", fp); | |
506 #else | |
507 ERROR! Unsupported release of X11 | |
508 #endif | |
509 XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", | |
510 mesg, BUFSIZ); | |
511 (void) fprintf(fp, mesg, event->serial); | |
512 fputs("\n ", fp); | |
513 XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", | |
514 mesg, BUFSIZ); | |
515 (void) fprintf(fp, mesg, NextRequest(dpy)-1); | |
516 fputs("\n", fp); | |
517 if (event->error_code == BadImplementation) return 0; | |
518 return 1; | |
519 } | |
520 | |
521 | |
522 /* | |
523 * XmuSimpleErrorHandler - ignore errors for XQueryTree, XGetWindowAttributes, | |
524 * and XGetGeometry; print a message for everything else. In all case, do | |
525 * not exit. | |
526 */ | |
527 int XmuSimpleErrorHandler (dpy, errorp) | |
528 Display *dpy; | |
529 XErrorEvent *errorp; | |
530 { | |
531 switch (errorp->request_code) { | |
532 case X_QueryTree: | |
533 case X_GetWindowAttributes: | |
534 if (errorp->error_code == BadWindow) return 0; | |
535 break; | |
536 case X_GetGeometry: | |
537 if (errorp->error_code == BadDrawable) return 0; | |
538 break; | |
539 } | |
540 /* got a "real" X error */ | |
541 return XmuPrintDefaultErrorMessage (dpy, errorp, stderr); | |
542 } | |
543 | |
544 void XmuCopyISOLatin1Lowered(char *dst, char *src) | |
545 { | |
546 unsigned char *dest, *source; | |
547 | |
548 for (dest = (unsigned char *)dst, source = (unsigned char *)src; | |
549 *source; | |
550 source++, dest++) | |
551 { | |
552 if ((*source >= XK_A) && (*source <= XK_Z)) | |
553 *dest = *source + (XK_a - XK_A); | |
554 else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis)) | |
555 *dest = *source + (XK_agrave - XK_Agrave); | |
556 else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn)) | |
557 *dest = *source + (XK_oslash - XK_Ooblique); | |
558 else | |
559 *dest = *source; | |
560 } | |
561 *dest = '\0'; | |
562 } | |
563 #endif /* !HAVE_XMU */ |