Mercurial > hg > xemacs-beta
comparison src/objects-x.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 576fb035e263 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
1 /* X-specific Lisp objects. | 1 /* X-specific Lisp objects. |
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. | 2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Board of Trustees, University of Illinois. | 3 Copyright (C) 1995 Board of Trustees, University of Illinois. |
4 Copyright (C) 1995 Tinker Systems. | 4 Copyright (C) 1995 Tinker Systems. |
5 Copyright (C) 1995, 1996 Ben Wing. | 5 Copyright (C) 1995, 1996, 2000 Ben Wing. |
6 Copyright (C) 1995 Sun Microsystems, Inc. | 6 Copyright (C) 1995 Sun Microsystems, Inc. |
7 | 7 |
8 This file is part of XEmacs. | 8 This file is part of XEmacs. |
9 | 9 |
10 XEmacs is free software; you can redistribute it and/or modify it | 10 XEmacs is free software; you can redistribute it and/or modify it |
24 | 24 |
25 /* Synched up with: Not in FSF. */ | 25 /* Synched up with: Not in FSF. */ |
26 | 26 |
27 /* Authors: Jamie Zawinski, Chuck Thompson, Ben Wing */ | 27 /* Authors: Jamie Zawinski, Chuck Thompson, Ben Wing */ |
28 | 28 |
29 /* This file Mule-ized by Ben Wing, 7-10-00. */ | |
30 | |
29 #include <config.h> | 31 #include <config.h> |
30 #include "lisp.h" | 32 #include "lisp.h" |
31 #include <limits.h> | |
32 | 33 |
33 #include "console-x.h" | 34 #include "console-x.h" |
34 #include "objects-x.h" | 35 #include "objects-x.h" |
35 | 36 |
36 #include "buffer.h" | 37 #include "buffer.h" |
50 Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous | 51 Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous |
51 total failure which was due to a read/write colorcell being the nearest | 52 total failure which was due to a read/write colorcell being the nearest |
52 match - tries the next nearest... | 53 match - tries the next nearest... |
53 | 54 |
54 Return value is 1 for normal success, 2 for nearest color success, | 55 Return value is 1 for normal success, 2 for nearest color success, |
55 3 for Non-deallocable sucess. */ | 56 3 for Non-deallocable success. */ |
56 int | 57 int |
57 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual, | 58 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual, |
58 XColor *color_def) | 59 XColor *color_def) |
59 { | 60 { |
60 int status; | 61 int status; |
134 gr = color_def->green >> (8 - gbits); | 135 gr = color_def->green >> (8 - gbits); |
135 if (bbits > 8) | 136 if (bbits > 8) |
136 bl = color_def->blue << (bbits - 8); | 137 bl = color_def->blue << (bbits - 8); |
137 else | 138 else |
138 bl = color_def->blue >> (8 - bbits); | 139 bl = color_def->blue >> (8 - bbits); |
139 color_def->pixel = (rd << rshift) | (gr << gshift) | (bl << bshift); | 140 color_def->pixel = (rd << rshift) | (gr << gshift) | (bl << |
141 bshift); | |
140 status = 3; | 142 status = 3; |
141 } | 143 } |
142 } | 144 } |
143 } | 145 } |
144 else | 146 else |
161 int nearest; | 163 int nearest; |
162 long nearest_delta, trial_delta; | 164 long nearest_delta, trial_delta; |
163 int x; | 165 int x; |
164 | 166 |
165 if( cells == NULL ) | 167 if( cells == NULL ) |
166 { | 168 { |
167 cells = alloca_array (XColor, no_cells); | 169 cells = alloca_array (XColor, no_cells); |
168 for (x = 0; x < no_cells; x++) | 170 for (x = 0; x < no_cells; x++) |
169 cells[x].pixel = x; | 171 cells[x].pixel = x; |
170 | 172 |
171 /* read the current colormap */ | 173 /* read the current colormap */ |
172 XQueryColors (display, colormap, cells, no_cells); | 174 XQueryColors (display, colormap, cells, no_cells); |
173 } | 175 } |
174 | 176 |
175 nearest = 0; | 177 nearest = 0; |
176 /* I'm assuming CSE so I'm not going to condense this. */ | 178 /* I'm assuming CSE so I'm not going to condense this. */ |
177 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8)) | 179 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8)) |
178 * ((color_def->red >> 8) - (cells[0].red >> 8))) | 180 * ((color_def->red >> 8) - (cells[0].red >> 8))) |
179 + | 181 + |
180 (((color_def->green >> 8) - (cells[0].green >> 8)) | 182 (((color_def->green >> 8) - (cells[0].green >> 8)) |
181 * ((color_def->green >> 8) - (cells[0].green >> 8))) | 183 * ((color_def->green >> 8) - (cells[0].green >> |
184 8))) | |
182 + | 185 + |
183 (((color_def->blue >> 8) - (cells[0].blue >> 8)) | 186 (((color_def->blue >> 8) - (cells[0].blue >> 8)) |
184 * ((color_def->blue >> 8) - (cells[0].blue >> 8)))); | 187 * ((color_def->blue >> 8) - (cells[0].blue >> |
188 8)))); | |
185 for (x = 1; x < no_cells; x++) | 189 for (x = 1; x < no_cells; x++) |
186 { | 190 { |
187 trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8)) | 191 trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8)) |
188 * ((color_def->red >> 8) - (cells[x].red >> 8))) | 192 * ((color_def->red >> 8) - (cells[x].red >> 8))) |
189 + | 193 + |
190 (((color_def->green >> 8) - (cells[x].green >> 8)) | 194 (((color_def->green >> 8) - (cells[x].green >> 8)) |
191 * ((color_def->green >> 8) - (cells[x].green >> 8))) | 195 * ((color_def->green >> 8) - (cells[x].green >> |
196 8))) | |
192 + | 197 + |
193 (((color_def->blue >> 8) - (cells[x].blue >> 8)) | 198 (((color_def->blue >> 8) - (cells[x].blue >> 8)) |
194 * ((color_def->blue >> 8) - (cells[x].blue >> 8)))); | 199 * ((color_def->blue >> 8) - (cells[x].blue >> |
200 8)))); | |
195 | 201 |
196 /* less? Ignore cells marked as previously failing */ | 202 /* less? Ignore cells marked as previously failing */ |
197 if( (trial_delta < nearest_delta) && | 203 if( (trial_delta < nearest_delta) && |
198 (cells[x].pixel != ULONG_MAX) ) | 204 (cells[x].pixel != ULONG_MAX) ) |
199 { | 205 { |
203 } | 209 } |
204 color_def->red = cells[nearest].red; | 210 color_def->red = cells[nearest].red; |
205 color_def->green = cells[nearest].green; | 211 color_def->green = cells[nearest].green; |
206 color_def->blue = cells[nearest].blue; | 212 color_def->blue = cells[nearest].blue; |
207 if (XAllocColor (display, colormap, color_def) != 0) | 213 if (XAllocColor (display, colormap, color_def) != 0) |
208 status = 2; | 214 status = 2; |
209 else | 215 else |
210 /* LSK: Either the colour map has changed since | 216 /* LSK: Either the colour map has changed since |
211 * we read it, or the colour is allocated | 217 * we read it, or the colour is allocated |
212 * read/write... Mark this cmap entry so it's | 218 * read/write... Mark this cmap entry so it's |
213 * ignored in the next iteration. | 219 * ignored in the next iteration. |
214 */ | 220 */ |
215 cells[nearest].pixel = ULONG_MAX; | 221 cells[nearest].pixel = ULONG_MAX; |
216 } | 222 } |
217 } | 223 } |
218 return status; | 224 return status; |
219 } | 225 } |
220 | 226 |
221 int | 227 static int |
222 x_parse_nearest_color (struct device *d, XColor *color, Bufbyte *name, | 228 x_parse_nearest_color (struct device *d, XColor *color, Lisp_Object name, |
223 Bytecount len, Error_behavior errb) | 229 Error_behavior errb) |
224 { | 230 { |
225 Display *dpy = DEVICE_X_DISPLAY (d); | 231 Display *dpy = DEVICE_X_DISPLAY (d); |
226 Colormap cmap = DEVICE_X_COLORMAP (d); | 232 Colormap cmap = DEVICE_X_COLORMAP (d); |
227 Visual *visual = DEVICE_X_VISUAL (d); | 233 Visual *visual = DEVICE_X_VISUAL (d); |
228 int result; | 234 int result; |
229 | 235 |
230 xzero (*color); | 236 xzero (*color); |
231 { | 237 { |
232 CONST Extbyte *extname; | 238 const Extbyte *extname; |
233 Extcount extnamelen; | 239 |
234 | 240 LISP_STRING_TO_EXTERNAL (name, extname, Qx_color_name_encoding); |
235 TO_EXTERNAL_FORMAT (DATA, (name, len), | 241 result = XParseColor (dpy, cmap, extname, color); |
236 ALLOCA, (extname, extnamelen), | |
237 Qbinary); | |
238 result = XParseColor (dpy, cmap, (char *) extname, color); | |
239 } | 242 } |
240 if (!result) | 243 if (!result) |
241 { | 244 { |
242 maybe_signal_simple_error ("Unrecognized color", make_string (name, len), | 245 maybe_signal_simple_error ("Unrecognized color", name, Qcolor, errb); |
243 Qcolor, errb); | |
244 return 0; | 246 return 0; |
245 } | 247 } |
246 result = allocate_nearest_color (dpy, cmap, visual, color); | 248 result = allocate_nearest_color (dpy, cmap, visual, color); |
247 if (!result) | 249 if (!result) |
248 { | 250 { |
249 maybe_signal_simple_error ("Couldn't allocate color", | 251 maybe_signal_simple_error ("Couldn't allocate color", name, Qcolor, |
250 make_string (name, len), Qcolor, errb); | 252 errb); |
251 return 0; | 253 return 0; |
252 } | 254 } |
253 | 255 |
254 return result; | 256 return result; |
255 } | 257 } |
259 Lisp_Object device, Error_behavior errb) | 261 Lisp_Object device, Error_behavior errb) |
260 { | 262 { |
261 XColor color; | 263 XColor color; |
262 int result; | 264 int result; |
263 | 265 |
264 result = x_parse_nearest_color (XDEVICE (device), &color, | 266 result = x_parse_nearest_color (XDEVICE (device), &color, name, errb); |
265 XSTRING_DATA (name), | |
266 XSTRING_LENGTH (name), | |
267 errb); | |
268 | 267 |
269 if (!result) | 268 if (!result) |
270 return 0; | 269 return 0; |
271 | 270 |
272 /* Don't allocate the data until we're sure that we will succeed, | 271 /* Don't allocate the data until we're sure that we will succeed, |
283 static void | 282 static void |
284 x_print_color_instance (Lisp_Color_Instance *c, | 283 x_print_color_instance (Lisp_Color_Instance *c, |
285 Lisp_Object printcharfun, | 284 Lisp_Object printcharfun, |
286 int escapeflag) | 285 int escapeflag) |
287 { | 286 { |
288 char buf[100]; | 287 Bufbyte buf[100]; |
289 XColor color = COLOR_INSTANCE_X_COLOR (c); | 288 XColor color = COLOR_INSTANCE_X_COLOR (c); |
290 sprintf (buf, " %ld=(%X,%X,%X)", | 289 sprintf (buf, " %ld=(%X,%X,%X)", |
291 color.pixel, color.red, color.green, color.blue); | 290 color.pixel, color.red, color.green, color.blue); |
292 write_c_string (buf, printcharfun); | 291 write_c_string (buf, printcharfun); |
293 } | 292 } |
299 { | 298 { |
300 if (DEVICE_LIVE_P (XDEVICE (c->device))) | 299 if (DEVICE_LIVE_P (XDEVICE (c->device))) |
301 { | 300 { |
302 if (COLOR_INSTANCE_X_DEALLOC (c)) | 301 if (COLOR_INSTANCE_X_DEALLOC (c)) |
303 { | 302 { |
304 XFreeColors (DEVICE_X_DISPLAY (XDEVICE (c->device)), DEVICE_X_COLORMAP (XDEVICE (c->device)), | 303 XFreeColors (DEVICE_X_DISPLAY (XDEVICE (c->device)), |
304 DEVICE_X_COLORMAP (XDEVICE (c->device)), | |
305 &COLOR_INSTANCE_X_COLOR (c).pixel, 1, 0); | 305 &COLOR_INSTANCE_X_COLOR (c).pixel, 1, 0); |
306 } | 306 } |
307 } | 307 } |
308 xfree (c->data); | 308 xfree (c->data); |
309 c->data = 0; | 309 c->data = 0; |
347 x_valid_color_name_p (struct device *d, Lisp_Object color) | 347 x_valid_color_name_p (struct device *d, Lisp_Object color) |
348 { | 348 { |
349 XColor c; | 349 XColor c; |
350 Display *dpy = DEVICE_X_DISPLAY (d); | 350 Display *dpy = DEVICE_X_DISPLAY (d); |
351 Colormap cmap = DEVICE_X_COLORMAP (d); | 351 Colormap cmap = DEVICE_X_COLORMAP (d); |
352 | 352 const Extbyte *extname; |
353 CONST char *extname; | 353 |
354 | 354 LISP_STRING_TO_EXTERNAL (color, extname, Qx_color_name_encoding); |
355 TO_EXTERNAL_FORMAT (LISP_STRING, color, C_STRING_ALLOCA, extname, Qctext); | |
356 | 355 |
357 return XParseColor (dpy, cmap, extname, &c); | 356 return XParseColor (dpy, cmap, extname, &c); |
358 } | 357 } |
359 | 358 |
360 | 359 |
366 x_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name, | 365 x_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name, |
367 Lisp_Object device, Error_behavior errb) | 366 Lisp_Object device, Error_behavior errb) |
368 { | 367 { |
369 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | 368 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device)); |
370 XFontStruct *xf; | 369 XFontStruct *xf; |
371 CONST char *extname; | 370 const Extbyte *extname; |
372 | 371 |
373 TO_EXTERNAL_FORMAT (LISP_STRING, f->name, C_STRING_ALLOCA, extname, Qctext); | 372 LISP_STRING_TO_EXTERNAL (f->name, extname, Qx_font_name_encoding); |
374 xf = XLoadQueryFont (dpy, extname); | 373 xf = XLoadQueryFont (dpy, extname); |
375 | 374 |
376 if (!xf) | 375 if (!xf) |
377 { | 376 { |
378 maybe_signal_simple_error ("Couldn't load font", f->name, | 377 maybe_signal_simple_error ("Couldn't load font", f->name, |
465 static void | 464 static void |
466 x_print_font_instance (Lisp_Font_Instance *f, | 465 x_print_font_instance (Lisp_Font_Instance *f, |
467 Lisp_Object printcharfun, | 466 Lisp_Object printcharfun, |
468 int escapeflag) | 467 int escapeflag) |
469 { | 468 { |
470 char buf[200]; | 469 Bufbyte buf[200]; |
471 sprintf (buf, " 0x%lx", (unsigned long) FONT_INSTANCE_X_FONT (f)->fid); | 470 sprintf (buf, " 0x%lx", (unsigned long) FONT_INSTANCE_X_FONT (f)->fid); |
472 write_c_string (buf, printcharfun); | 471 write_c_string (buf, printcharfun); |
473 } | 472 } |
474 | 473 |
475 static void | 474 static void |
502 The MIT R5 server sometimes appears to be picking the lexicographically | 501 The MIT R5 server sometimes appears to be picking the lexicographically |
503 smallest font which matches the name (thus picking "adobe" fonts before | 502 smallest font which matches the name (thus picking "adobe" fonts before |
504 "bitstream" fonts even if the bitstream fonts are earlier in the path, and | 503 "bitstream" fonts even if the bitstream fonts are earlier in the path, and |
505 also picking 100dpi adobe fonts over 75dpi adobe fonts even though the | 504 also picking 100dpi adobe fonts over 75dpi adobe fonts even though the |
506 75dpi are in the path earlier) but sometimes appears to be doing something | 505 75dpi are in the path earlier) but sometimes appears to be doing something |
507 else entirely (for example, removing the bitsream fonts from the path will | 506 else entirely (for example, removing the bitstream fonts from the path will |
508 cause the 75dpi adobe fonts to be used instead of the 100dpi, even though | 507 cause the 75dpi adobe fonts to be used instead of the 100dpi, even though |
509 their relative positions in the path (and their names!) have not changed). | 508 their relative positions in the path (and their names!) have not changed). |
510 | 509 |
511 The documentation for XSetFontPath() seems to indicate that the order of | 510 The documentation for XSetFontPath() seems to indicate that the order of |
512 entries in the font path means something, but it's pretty noncommital about | 511 entries in the font path means something, but it's pretty noncommittal about |
513 it, and the spirit of the law is apparently not being obeyed... | 512 it, and the spirit of the law is apparently not being obeyed... |
514 | 513 |
515 All the fonts I've seen have a property named `FONT' which contains the | 514 All the fonts I've seen have a property named `FONT' which contains the |
516 truename of the font. However, there are two problems with using this: the | 515 truename of the font. However, there are two problems with using this: the |
517 first is that the X Protocol Document is quite explicit that all properties | 516 first is that the X Protocol Document is quite explicit that all properties |
569 | 568 |
570 If anyone has any better ideas how to do this, or any insights on what it is | 569 If anyone has any better ideas how to do this, or any insights on what it is |
571 that the various servers are actually doing, please let me know! -- jwz. */ | 570 that the various servers are actually doing, please let me know! -- jwz. */ |
572 | 571 |
573 static int | 572 static int |
574 valid_x_font_name_p (Display *dpy, char *name) | 573 valid_x_font_name_p (Display *dpy, Extbyte *name) |
575 { | 574 { |
576 /* Maybe this should be implemented by calling XLoadFont and trapping | 575 /* Maybe this should be implemented by calling XLoadFont and trapping |
577 the error. That would be a lot of work, and wasteful as hell, but | 576 the error. That would be a lot of work, and wasteful as hell, but |
578 might be more correct. | 577 might be more correct. |
579 */ | 578 */ |
580 int nnames = 0; | 579 int nnames = 0; |
581 char **names = 0; | 580 SExtbyte **names = 0; |
582 if (! name) | 581 if (! name) |
583 return 0; | 582 return 0; |
584 names = XListFonts (dpy, name, 1, &nnames); | 583 names = XListFonts (dpy, name, 1, &nnames); |
585 if (names) | 584 if (names) |
586 XFreeFontNames (names); | 585 XFreeFontNames (names); |
587 return (nnames != 0); | 586 return (nnames != 0); |
588 } | 587 } |
589 | 588 |
590 static char * | 589 static Extbyte * |
591 truename_via_FONT_prop (Display *dpy, XFontStruct *font) | 590 truename_via_FONT_prop (Display *dpy, XFontStruct *font) |
592 { | 591 { |
593 unsigned long value = 0; | 592 unsigned long value = 0; |
594 char *result = 0; | 593 Extbyte *result = 0; |
595 if (XGetFontProperty (font, XA_FONT, &value)) | 594 if (XGetFontProperty (font, XA_FONT, &value)) |
596 result = XGetAtomName (dpy, value); | 595 result = XGetAtomName (dpy, value); |
597 /* result is now 0, or the string value of the FONT property. */ | 596 /* result is now 0, or the string value of the FONT property. */ |
598 if (result) | 597 if (result) |
599 { | 598 { |
605 } | 604 } |
606 } | 605 } |
607 return result; /* this must be freed by caller if non-0 */ | 606 return result; /* this must be freed by caller if non-0 */ |
608 } | 607 } |
609 | 608 |
610 static char * | 609 static Extbyte * |
611 truename_via_random_props (Display *dpy, XFontStruct *font) | 610 truename_via_random_props (Display *dpy, XFontStruct *font) |
612 { | 611 { |
613 struct device *d = get_device_from_display (dpy); | 612 struct device *d = get_device_from_display (dpy); |
614 unsigned long value = 0; | 613 unsigned long value = 0; |
615 char *foundry, *family, *weight, *slant, *setwidth, *add_style; | 614 Extbyte *foundry, *family, *weight, *slant, *setwidth, *add_style; |
616 unsigned long pixel, point, res_x, res_y; | 615 unsigned long pixel, point, res_x, res_y; |
617 char *spacing; | 616 Extbyte *spacing; |
618 unsigned long avg_width; | 617 unsigned long avg_width; |
619 char *registry, *encoding; | 618 Extbyte *registry, *encoding; |
620 char composed_name [2048]; | 619 Extbyte composed_name [2048]; |
621 int ok = 0; | 620 int ok = 0; |
622 char *result; | 621 Extbyte *result; |
623 | 622 |
624 #define get_string(atom,var) \ | 623 #define get_string(atom,var) \ |
625 if (XGetFontProperty (font, (atom), &value)) \ | 624 if (XGetFontProperty (font, (atom), &value)) \ |
626 var = XGetAtomName (dpy, value); \ | 625 var = XGetAtomName (dpy, value); \ |
627 else { \ | 626 else { \ |
660 | 659 |
661 FAIL: | 660 FAIL: |
662 if (ok) | 661 if (ok) |
663 { | 662 { |
664 int L = strlen (composed_name) + 1; | 663 int L = strlen (composed_name) + 1; |
665 result = (char *) xmalloc (L); | 664 result = (Extbyte *) xmalloc (L); |
666 strncpy (result, composed_name, L); | 665 strncpy (result, composed_name, L); |
667 } | 666 } |
668 else | 667 else |
669 result = 0; | 668 result = 0; |
670 | 669 |
682 } | 681 } |
683 | 682 |
684 /* Unbounded, for sufficiently small values of infinity... */ | 683 /* Unbounded, for sufficiently small values of infinity... */ |
685 #define MAX_FONT_COUNT 5000 | 684 #define MAX_FONT_COUNT 5000 |
686 | 685 |
687 static char * | 686 static Extbyte * |
688 truename_via_XListFonts (Display *dpy, char *font_name) | 687 truename_via_XListFonts (Display *dpy, Extbyte *font_name) |
689 { | 688 { |
690 char *result = 0; | 689 Extbyte *result = 0; |
691 char **names; | 690 SExtbyte **names; |
692 int count = 0; | 691 int count = 0; |
693 | 692 |
694 #ifndef XOPENFONT_SORTS | 693 #ifndef XOPENFONT_SORTS |
695 /* In a sensible world, the first font returned by XListFonts() | 694 /* In a sensible world, the first font returned by XListFonts() |
696 would be the font that XOpenFont() would use. */ | 695 would be the font that XOpenFont() would use. */ |
698 if (count) result = names [0]; | 697 if (count) result = names [0]; |
699 #else | 698 #else |
700 /* But the world I live in is much more perverse. */ | 699 /* But the world I live in is much more perverse. */ |
701 names = XListFonts (dpy, font_name, MAX_FONT_COUNT, &count); | 700 names = XListFonts (dpy, font_name, MAX_FONT_COUNT, &count); |
702 while (count--) | 701 while (count--) |
702 /* !!#### Not Mule-friendly */ | |
703 /* If names[count] is lexicographically less than result, use it. | 703 /* If names[count] is lexicographically less than result, use it. |
704 (#### Should we be comparing case-insensitively?) */ | 704 (#### Should we be comparing case-insensitively?) */ |
705 if (result == 0 || (strcmp (result, names [count]) < 0)) | 705 if (result == 0 || (strcmp (result, names [count]) < 0)) |
706 result = names [count]; | 706 result = names [count]; |
707 #endif | 707 #endif |
713 | 713 |
714 return result; /* this must be freed by caller if non-0 */ | 714 return result; /* this must be freed by caller if non-0 */ |
715 } | 715 } |
716 | 716 |
717 static Lisp_Object | 717 static Lisp_Object |
718 x_font_truename (Display *dpy, char *name, XFontStruct *font) | 718 x_font_truename (Display *dpy, Extbyte *name, XFontStruct *font) |
719 { | 719 { |
720 char *truename_FONT = 0; | 720 Extbyte *truename_FONT = 0; |
721 char *truename_random = 0; | 721 Extbyte *truename_random = 0; |
722 char *truename = 0; | 722 Extbyte *truename = 0; |
723 | 723 |
724 /* The search order is: | 724 /* The search order is: |
725 - if FONT property exists, and is a valid name, return it. | 725 - if FONT property exists, and is a valid name, return it. |
726 - if the other props exist, and add up to a valid name, return it. | 726 - if the other props exist, and add up to a valid name, return it. |
727 - if we find a matching name with XListFonts, return it. | 727 - if we find a matching name with XListFonts, return it. |
762 if (truename_random && truename_random != truename) | 762 if (truename_random && truename_random != truename) |
763 XFree (truename_random); | 763 XFree (truename_random); |
764 | 764 |
765 if (truename) | 765 if (truename) |
766 { | 766 { |
767 Lisp_Object result = build_string (truename); | 767 Lisp_Object result = build_ext_string (truename, Qx_font_name_encoding); |
768 XFree (truename); | 768 XFree (truename); |
769 return result; | 769 return result; |
770 } | 770 } |
771 else | 771 else |
772 return Qnil; | 772 return Qnil; |
778 struct device *d = XDEVICE (f->device); | 778 struct device *d = XDEVICE (f->device); |
779 | 779 |
780 if (NILP (FONT_INSTANCE_X_TRUENAME (f))) | 780 if (NILP (FONT_INSTANCE_X_TRUENAME (f))) |
781 { | 781 { |
782 Display *dpy = DEVICE_X_DISPLAY (d); | 782 Display *dpy = DEVICE_X_DISPLAY (d); |
783 char *name = (char *) XSTRING_DATA (f->name); | |
784 { | 783 { |
784 Extbyte *nameext; | |
785 | |
786 LISP_STRING_TO_EXTERNAL (f->name, nameext, Qx_font_name_encoding); | |
785 FONT_INSTANCE_X_TRUENAME (f) = | 787 FONT_INSTANCE_X_TRUENAME (f) = |
786 x_font_truename (dpy, name, FONT_INSTANCE_X_FONT (f)); | 788 x_font_truename (dpy, nameext, FONT_INSTANCE_X_FONT (f)); |
787 } | 789 } |
788 if (NILP (FONT_INSTANCE_X_TRUENAME (f))) | 790 if (NILP (FONT_INSTANCE_X_TRUENAME (f))) |
789 { | 791 { |
790 Lisp_Object font_instance; | 792 Lisp_Object font_instance; |
791 XSETFONT_INSTANCE (font_instance, f); | 793 XSETFONT_INSTANCE (font_instance, f); |
792 | 794 |
793 maybe_signal_simple_error ("Couldn't determine font truename", | 795 maybe_signal_simple_error ("Couldn't determine font truename", |
794 font_instance, Qfont, errb); | 796 font_instance, Qfont, errb); |
795 /* Ok, just this once, return the font name as the truename. | 797 /* Ok, just this once, return the font name as the truename. |
796 (This is only used by Fequal() right now.) */ | 798 (This is only used by Fequal() right now.) */ |
797 return f->name; | 799 return f->name; |
798 } | 800 } |
799 } | 801 } |
811 | 813 |
812 dpy = DEVICE_X_DISPLAY (d); | 814 dpy = DEVICE_X_DISPLAY (d); |
813 props = FONT_INSTANCE_X_FONT (f)->properties; | 815 props = FONT_INSTANCE_X_FONT (f)->properties; |
814 for (i = FONT_INSTANCE_X_FONT (f)->n_properties - 1; i >= 0; i--) | 816 for (i = FONT_INSTANCE_X_FONT (f)->n_properties - 1; i >= 0; i--) |
815 { | 817 { |
816 char *name_str = 0; | |
817 char *val_str = 0; | |
818 Lisp_Object name, value; | 818 Lisp_Object name, value; |
819 Atom atom = props [i].name; | 819 Atom atom = props [i].name; |
820 name_str = XGetAtomName (dpy, atom); | 820 Bufbyte *name_str = 0; |
821 Extbyte *namestrext = XGetAtomName (dpy, atom); | |
822 | |
823 if (namestrext) | |
824 EXTERNAL_TO_C_STRING (namestrext, name_str, Qx_atom_name_encoding); | |
825 | |
821 name = (name_str ? intern (name_str) : Qnil); | 826 name = (name_str ? intern (name_str) : Qnil); |
822 if (name_str && | 827 if (name_str && |
823 (atom == XA_FONT || | 828 (atom == XA_FONT || |
824 atom == DEVICE_XATOM_FOUNDRY (d) || | 829 atom == DEVICE_XATOM_FOUNDRY (d) || |
825 atom == DEVICE_XATOM_FAMILY_NAME (d) || | 830 atom == DEVICE_XATOM_FAMILY_NAME (d) || |
840 !strcmp (name_str, "QUALITY") || | 845 !strcmp (name_str, "QUALITY") || |
841 !strcmp (name_str, "RELATIVE_SET") || | 846 !strcmp (name_str, "RELATIVE_SET") || |
842 !strcmp (name_str, "RELATIVE_WEIGHT") || | 847 !strcmp (name_str, "RELATIVE_WEIGHT") || |
843 !strcmp (name_str, "STYLE"))) | 848 !strcmp (name_str, "STYLE"))) |
844 { | 849 { |
845 val_str = XGetAtomName (dpy, props [i].card32); | 850 Extbyte *val_str = XGetAtomName (dpy, props [i].card32); |
846 value = (val_str ? build_string (val_str) : Qnil); | 851 |
852 value = (val_str ? build_ext_string (val_str, Qx_atom_name_encoding) | |
853 : Qnil); | |
847 } | 854 } |
848 else | 855 else |
849 value = make_int (props [i].card32); | 856 value = make_int (props [i].card32); |
850 if (name_str) XFree (name_str); | 857 if (namestrext) XFree (namestrext); |
851 result = Fcons (Fcons (name, value), result); | 858 result = Fcons (Fcons (name, value), result); |
852 } | 859 } |
853 return result; | 860 return result; |
854 } | 861 } |
855 | 862 |
856 static Lisp_Object | 863 static Lisp_Object |
857 x_list_fonts (Lisp_Object pattern, Lisp_Object device) | 864 x_list_fonts (Lisp_Object pattern, Lisp_Object device) |
858 { | 865 { |
859 char **names; | 866 SExtbyte **names; |
860 int count = 0; | 867 int count = 0; |
861 Lisp_Object result = Qnil; | 868 Lisp_Object result = Qnil; |
862 CONST char *patternext; | 869 const Extbyte *patternext; |
863 | 870 |
864 TO_EXTERNAL_FORMAT (LISP_STRING, pattern, | 871 LISP_STRING_TO_EXTERNAL (pattern, patternext, Qx_font_name_encoding); |
865 C_STRING_ALLOCA, patternext, | |
866 Qbinary); | |
867 | 872 |
868 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)), | 873 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)), |
869 patternext, MAX_FONT_COUNT, &count); | 874 patternext, MAX_FONT_COUNT, &count); |
870 while (count--) | 875 while (count--) |
871 result = Fcons (build_ext_string (names [count], Qbinary), result); | 876 result = Fcons (build_ext_string (names[count], Qx_font_name_encoding), |
877 result); | |
872 if (names) | 878 if (names) |
873 XFreeFontNames (names); | 879 XFreeFontNames (names); |
874 return result; | 880 return result; |
875 } | 881 } |
876 | 882 |
877 #ifdef MULE | 883 #ifdef MULE |
878 | 884 |
879 static int | 885 static int |
880 x_font_spec_matches_charset (struct device *d, Lisp_Object charset, | 886 x_font_spec_matches_charset (struct device *d, Lisp_Object charset, |
881 CONST Bufbyte *nonreloc, Lisp_Object reloc, | 887 const Bufbyte *nonreloc, Lisp_Object reloc, |
882 Bytecount offset, Bytecount length) | 888 Bytecount offset, Bytecount length) |
883 { | 889 { |
884 if (UNBOUNDP (charset)) | 890 if (UNBOUNDP (charset)) |
885 return 1; | 891 return 1; |
886 /* Hack! Short font names don't have the registry in them, | 892 /* Hack! Short font names don't have the registry in them, |
888 case of ASCII. For other charsets, you gotta give the | 894 case of ASCII. For other charsets, you gotta give the |
889 long form; sorry buster. | 895 long form; sorry buster. |
890 */ | 896 */ |
891 if (EQ (charset, Vcharset_ascii)) | 897 if (EQ (charset, Vcharset_ascii)) |
892 { | 898 { |
893 CONST Bufbyte *the_nonreloc = nonreloc; | 899 const Bufbyte *the_nonreloc = nonreloc; |
894 int i; | 900 int i; |
895 Bytecount the_length = length; | 901 Bytecount the_length = length; |
896 | 902 |
897 if (!the_nonreloc) | 903 if (!the_nonreloc) |
898 the_nonreloc = XSTRING_DATA (reloc); | 904 the_nonreloc = XSTRING_DATA (reloc); |
900 the_nonreloc += offset; | 906 the_nonreloc += offset; |
901 if (!memchr (the_nonreloc, '*', the_length)) | 907 if (!memchr (the_nonreloc, '*', the_length)) |
902 { | 908 { |
903 for (i = 0;; i++) | 909 for (i = 0;; i++) |
904 { | 910 { |
905 CONST Bufbyte *new_nonreloc = (CONST Bufbyte *) | 911 const Bufbyte *new_nonreloc = (const Bufbyte *) |
906 memchr (the_nonreloc, '-', the_length); | 912 memchr (the_nonreloc, '-', the_length); |
907 if (!new_nonreloc) | 913 if (!new_nonreloc) |
908 break; | 914 break; |
909 new_nonreloc++; | 915 new_nonreloc++; |
910 the_length -= new_nonreloc - the_nonreloc; | 916 the_length -= new_nonreloc - the_nonreloc; |
928 /* find a font spec that matches font spec FONT and also matches | 934 /* find a font spec that matches font spec FONT and also matches |
929 (the registry of) CHARSET. */ | 935 (the registry of) CHARSET. */ |
930 static Lisp_Object | 936 static Lisp_Object |
931 x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset) | 937 x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset) |
932 { | 938 { |
933 char **names; | 939 SExtbyte **names; |
934 int count = 0; | 940 int count = 0; |
935 Lisp_Object result = Qnil; | 941 Lisp_Object result = Qnil; |
936 CONST char *patternext; | 942 const Extbyte *patternext; |
937 int i; | 943 int i; |
938 | 944 |
939 TO_EXTERNAL_FORMAT (LISP_STRING, font, | 945 LISP_STRING_TO_EXTERNAL (font, patternext, Qx_font_name_encoding); |
940 C_STRING_ALLOCA, patternext, | |
941 Qbinary); | |
942 | 946 |
943 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)), | 947 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)), |
944 patternext, MAX_FONT_COUNT, &count); | 948 patternext, MAX_FONT_COUNT, &count); |
945 /* #### This code seems awfully bogus -- mrb */ | 949 /* #### This code seems awfully bogus -- mrb */ |
946 for (i = 0; i < count; i ++) | 950 for (i = 0; i < count; i ++) |
947 { | 951 { |
948 CONST char *intname; | 952 const Bufbyte *intname; |
949 | 953 |
950 TO_INTERNAL_FORMAT (C_STRING, names[i], | 954 EXTERNAL_TO_C_STRING (names[i], intname, Qx_font_name_encoding); |
951 C_STRING_ALLOCA, intname, | |
952 Qbinary); | |
953 if (x_font_spec_matches_charset (XDEVICE (device), charset, | 955 if (x_font_spec_matches_charset (XDEVICE (device), charset, |
954 (Bufbyte *) intname, Qnil, 0, -1)) | 956 intname, Qnil, 0, -1)) |
955 { | 957 { |
956 result = build_string (intname); | 958 result = build_string (intname); |
957 break; | 959 break; |
958 } | 960 } |
959 } | 961 } |