comparison src/objects-x.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children 11054d720c21
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
43 /* color instances */ 43 /* color instances */
44 /************************************************************************/ 44 /************************************************************************/
45 45
46 /* Replacement for XAllocColor() that tries to return the nearest 46 /* Replacement for XAllocColor() that tries to return the nearest
47 available color if the colormap is full. Original was from FSFmacs, 47 available color if the colormap is full. Original was from FSFmacs,
48 but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 48 but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 */
49 Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous 49
50 total failure which was due to a read/write colorcell being the nearest 50 /* Return value is 1 for normal success, 2 for nearest color success,
51 match - tries the next nearest... 51 3 for Non-deallocable sucess, and 0 for absolute failure (shouldn't
52 52 happen?) */
53 Return value is 1 for normal success, 2 for nearest color success,
54 3 for Non-deallocable sucess. */
55 int 53 int
56 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual, 54 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
57 XColor *color_def) 55 XColor *color_def)
58 { 56 {
59 int status; 57 int status;
66 } 64 }
67 else 65 else
68 { 66 {
69 /* We're dealing with a TrueColor/DirectColor visual, so play games 67 /* We're dealing with a TrueColor/DirectColor visual, so play games
70 with the RGB values in the XColor struct. */ 68 with the RGB values in the XColor struct. */
71 /* #### JH: I'm not sure how a call to XAllocColor can fail in a 69 /* ### JH: I'm not sure how a call to XAllocColor can fail in a
72 TrueColor or DirectColor visual, so I will just reformat the 70 TrueColor or DirectColor visual, so I will just reformat the
73 request to match the requirements of the visual, and re-issue 71 request to match the requirements of the visual, and re-issue
74 the request. If this fails for anybody, I wanna know about it 72 the request. If this fails for anybody, I wanna know about it
75 so I can come up with a better plan */ 73 so I can come up with a better plan */
76 74
115 if (XAllocColor (display, colormap, color_def) != 0) 113 if (XAllocColor (display, colormap, color_def) != 0)
116 status = 1; 114 status = 1;
117 else 115 else
118 { 116 {
119 int rd, gr, bl; 117 int rd, gr, bl;
120 /* #### JH: I'm punting here, knowing that doing this will at 118 /* ### JH: I'm punting here, knowing that doing this will at
121 least draw the color correctly. However, unless we convert 119 least draw the color correctly. However, unless we convert
122 all of the functions that allocate colors (graphics 120 all of the functions that allocate colors (graphics
123 libraries, etc) to use this function doing this is very 121 libraries, etc) to use this function doing this is very
124 likely to cause problems later... */ 122 likely to cause problems later... */
125 123
140 } 138 }
141 } 139 }
142 } 140 }
143 else 141 else
144 { 142 {
145 XColor *cells = NULL;
146 /* JH: I can't believe there's no way to go backwards from a
147 colormap ID and get its visual and number of entries, but X
148 apparently isn't built that way... */
149 int no_cells = visual->map_entries;
150 status = 0;
151
152 if (XAllocColor (display, colormap, color_def) != 0) 143 if (XAllocColor (display, colormap, color_def) != 0)
153 status = 1; 144 status = 1;
154 else while( status != 2 ) 145 else
155 { 146 {
156 /* If we got to this point, the colormap is full, so we're 147 /* If we got to this point, the colormap is full, so we're
157 going to try and get the next closest color. The algorithm used 148 going to try and get the next closest color. The algorithm used
158 is a least-squares matching, which is what X uses for closest 149 is a least-squares matching, which is what X uses for closest
159 color matching with StaticColor visuals. */ 150 color matching with StaticColor visuals. */
151 XColor *cells;
152 /* JH: I can't believe there's no way to go backwards from a
153 colormap ID and get its visual and number of entries, but X
154 apparently isn't built that way... */
155 int no_cells = visual->map_entries;
160 int nearest; 156 int nearest;
161 long nearest_delta, trial_delta; 157 long nearest_delta, trial_delta;
162 int x; 158 int x;
163 159
164 if( cells == NULL ) 160 cells = alloca_array (XColor, no_cells);
165 { 161
166 cells = alloca_array (XColor, no_cells); 162 for (x = 0; x < no_cells; x++)
167 for (x = 0; x < no_cells; x++) 163 cells[x].pixel = x;
168 cells[x].pixel = x; 164
169 165 /* read the current colormap */
170 /* read the current colormap */ 166 XQueryColors (display, colormap, cells, no_cells);
171 XQueryColors (display, colormap, cells, no_cells);
172 }
173
174 nearest = 0; 167 nearest = 0;
175 /* I'm assuming CSE so I'm not going to condense this. */ 168 /* I'm assuming CSE so I'm not going to condense this. */
176 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8)) 169 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
177 * ((color_def->red >> 8) - (cells[0].red >> 8))) 170 * ((color_def->red >> 8) - (cells[0].red >> 8)))
178 + 171 +
189 (((color_def->green >> 8) - (cells[x].green >> 8)) 182 (((color_def->green >> 8) - (cells[x].green >> 8))
190 * ((color_def->green >> 8) - (cells[x].green >> 8))) 183 * ((color_def->green >> 8) - (cells[x].green >> 8)))
191 + 184 +
192 (((color_def->blue >> 8) - (cells[x].blue >> 8)) 185 (((color_def->blue >> 8) - (cells[x].blue >> 8))
193 * ((color_def->blue >> 8) - (cells[x].blue >> 8)))); 186 * ((color_def->blue >> 8) - (cells[x].blue >> 8))));
194 187 if (trial_delta < nearest_delta)
195 /* less? Ignore cells marked as previously failing */
196 if( (trial_delta < nearest_delta) &&
197 (cells[x].pixel != ULONG_MAX) )
198 { 188 {
199 nearest = x; 189 nearest = x;
200 nearest_delta = trial_delta; 190 nearest_delta = trial_delta;
201 } 191 }
202 } 192 }
203 color_def->red = cells[nearest].red; 193 color_def->red = cells[nearest].red;
204 color_def->green = cells[nearest].green; 194 color_def->green = cells[nearest].green;
205 color_def->blue = cells[nearest].blue; 195 color_def->blue = cells[nearest].blue;
206 if (XAllocColor (display, colormap, color_def) != 0) 196 if (XAllocColor (display, colormap, color_def) != 0) {
207 status = 2; 197 status = 2;
208 else 198 } else {
209 /* LSK: Either the colour map has changed since 199 status = 0; /* JH: how does this happen??? DOES this happen??? */
210 * we read it, or the colour is allocated 200 fprintf(stderr,"allocate_nearest_color returned 0!!!\n");
211 * read/write... Mark this cmap entry so it's 201 }
212 * ignored in the next iteration.
213 */
214 cells[nearest].pixel = ULONG_MAX;
215 } 202 }
216 } 203 }
217 return status; 204 return status;
218 } 205 }
219 206
220 int 207 int
221 x_parse_nearest_color (struct device *d, XColor *color, Bufbyte *name, 208 x_parse_nearest_color (struct device *d, XColor *color, Bufbyte *name,
222 Bytecount len, Error_behavior errb) 209 Bytecount len, Error_behavior errb)
223 { 210 {
224 Display *dpy = DEVICE_X_DISPLAY (d); 211 Display *dpy;
225 Colormap cmap = DEVICE_X_COLORMAP (d); 212 Colormap cmap;
226 Visual *visual = DEVICE_X_VISUAL (d); 213 Visual *visual;
227 int result; 214 int result;
215
216 dpy = DEVICE_X_DISPLAY (d);
217 cmap = DEVICE_X_COLORMAP(d);
218 visual = DEVICE_X_VISUAL (d);
228 219
229 xzero (*color); 220 xzero (*color);
230 { 221 {
231 const Extbyte *extname; 222 CONST Extbyte *extname;
232 Extcount extnamelen; 223 Extcount extnamelen;
233 224
234 TO_EXTERNAL_FORMAT (DATA, (name, len), 225 GET_CHARPTR_EXT_BINARY_DATA_ALLOCA (name, len, extname, extnamelen);
235 ALLOCA, (extname, extnamelen),
236 Qbinary);
237 result = XParseColor (dpy, cmap, (char *) extname, color); 226 result = XParseColor (dpy, cmap, (char *) extname, color);
238 } 227 }
239 if (!result) 228 if (!result)
240 { 229 {
241 maybe_signal_simple_error ("Unrecognized color", make_string (name, len), 230 maybe_signal_simple_error ("Unrecognized color", make_string (name, len),
252 241
253 return result; 242 return result;
254 } 243 }
255 244
256 static int 245 static int
257 x_initialize_color_instance (Lisp_Color_Instance *c, Lisp_Object name, 246 x_initialize_color_instance (struct Lisp_Color_Instance *c, Lisp_Object name,
258 Lisp_Object device, Error_behavior errb) 247 Lisp_Object device, Error_behavior errb)
259 { 248 {
260 XColor color; 249 XColor color;
261 int result; 250 int result;
262 251
278 COLOR_INSTANCE_X_COLOR (c) = color; 267 COLOR_INSTANCE_X_COLOR (c) = color;
279 return 1; 268 return 1;
280 } 269 }
281 270
282 static void 271 static void
283 x_print_color_instance (Lisp_Color_Instance *c, 272 x_print_color_instance (struct Lisp_Color_Instance *c,
284 Lisp_Object printcharfun, 273 Lisp_Object printcharfun,
285 int escapeflag) 274 int escapeflag)
286 { 275 {
287 char buf[100]; 276 char buf[100];
288 XColor color = COLOR_INSTANCE_X_COLOR (c); 277 XColor color = COLOR_INSTANCE_X_COLOR (c);
290 color.pixel, color.red, color.green, color.blue); 279 color.pixel, color.red, color.green, color.blue);
291 write_c_string (buf, printcharfun); 280 write_c_string (buf, printcharfun);
292 } 281 }
293 282
294 static void 283 static void
295 x_finalize_color_instance (Lisp_Color_Instance *c) 284 x_finalize_color_instance (struct Lisp_Color_Instance *c)
296 { 285 {
297 if (c->data) 286 if (c->data)
298 { 287 {
299 if (DEVICE_LIVE_P (XDEVICE (c->device))) 288 if (DEVICE_LIVE_P (XDEVICE (c->device)))
300 { 289 {
313 screen (have the same RGB values). I imagine that 302 screen (have the same RGB values). I imagine that
314 "same RGB values" == "same cell in the colormap." Arguably we should 303 "same RGB values" == "same cell in the colormap." Arguably we should
315 be comparing their names or pixel values instead. */ 304 be comparing their names or pixel values instead. */
316 305
317 static int 306 static int
318 x_color_instance_equal (Lisp_Color_Instance *c1, 307 x_color_instance_equal (struct Lisp_Color_Instance *c1,
319 Lisp_Color_Instance *c2, 308 struct Lisp_Color_Instance *c2,
320 int depth) 309 int depth)
321 { 310 {
322 XColor color1 = COLOR_INSTANCE_X_COLOR (c1); 311 XColor color1 = COLOR_INSTANCE_X_COLOR (c1);
323 XColor color2 = COLOR_INSTANCE_X_COLOR (c2); 312 XColor color2 = COLOR_INSTANCE_X_COLOR (c2);
324 return ((color1.red == color2.red) && 313 return ((color1.red == color2.red) &&
325 (color1.green == color2.green) && 314 (color1.green == color2.green) &&
326 (color1.blue == color2.blue)); 315 (color1.blue == color2.blue));
327 } 316 }
328 317
329 static unsigned long 318 static unsigned long
330 x_color_instance_hash (Lisp_Color_Instance *c, int depth) 319 x_color_instance_hash (struct Lisp_Color_Instance *c, int depth)
331 { 320 {
332 XColor color = COLOR_INSTANCE_X_COLOR (c); 321 XColor color = COLOR_INSTANCE_X_COLOR (c);
333 return HASH3 (color.red, color.green, color.blue); 322 return HASH3 (color.red, color.green, color.blue);
334 } 323 }
335 324
336 static Lisp_Object 325 static Lisp_Object
337 x_color_instance_rgb_components (Lisp_Color_Instance *c) 326 x_color_instance_rgb_components (struct Lisp_Color_Instance *c)
338 { 327 {
339 XColor color = COLOR_INSTANCE_X_COLOR (c); 328 XColor color = COLOR_INSTANCE_X_COLOR (c);
340 return (list3 (make_int (color.red), 329 return (list3 (make_int (color.red),
341 make_int (color.green), 330 make_int (color.green),
342 make_int (color.blue))); 331 make_int (color.blue)));
347 { 336 {
348 XColor c; 337 XColor c;
349 Display *dpy = DEVICE_X_DISPLAY (d); 338 Display *dpy = DEVICE_X_DISPLAY (d);
350 Colormap cmap = DEVICE_X_COLORMAP (d); 339 Colormap cmap = DEVICE_X_COLORMAP (d);
351 340
352 const char *extname; 341 CONST char *extname;
353 342
354 TO_EXTERNAL_FORMAT (LISP_STRING, color, C_STRING_ALLOCA, extname, Qctext); 343 GET_C_STRING_CTEXT_DATA_ALLOCA (color, extname);
355 344
356 return XParseColor (dpy, cmap, extname, &c); 345 return XParseColor (dpy, cmap,
346 extname, &c);
357 } 347 }
358 348
359 349
360 /************************************************************************/ 350 /************************************************************************/
361 /* font instances */ 351 /* font instances */
362 /************************************************************************/ 352 /************************************************************************/
363 353
364 static int 354 static int
365 x_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name, 355 x_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name,
366 Lisp_Object device, Error_behavior errb) 356 Lisp_Object device, Error_behavior errb)
367 { 357 {
368 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device)); 358 Display *dpy;
369 XFontStruct *xf; 359 XFontStruct *xf;
370 const char *extname; 360 CONST char *extname;
371 361
372 TO_EXTERNAL_FORMAT (LISP_STRING, f->name, C_STRING_ALLOCA, extname, Qctext); 362 dpy = DEVICE_X_DISPLAY (XDEVICE (device));
363 GET_C_STRING_CTEXT_DATA_ALLOCA (f->name, extname);
373 xf = XLoadQueryFont (dpy, extname); 364 xf = XLoadQueryFont (dpy, extname);
374 365
375 if (!xf) 366 if (!xf)
376 { 367 {
377 maybe_signal_simple_error ("Couldn't load font", f->name, 368 maybe_signal_simple_error ("Couldn't load font", f->name,
454 445
455 return 1; 446 return 1;
456 } 447 }
457 448
458 static void 449 static void
459 x_mark_font_instance (Lisp_Font_Instance *f) 450 x_mark_font_instance (struct Lisp_Font_Instance *f,
460 { 451 void (*markobj) (Lisp_Object))
461 mark_object (FONT_INSTANCE_X_TRUENAME (f)); 452 {
453 markobj (FONT_INSTANCE_X_TRUENAME (f));
462 } 454 }
463 455
464 static void 456 static void
465 x_print_font_instance (Lisp_Font_Instance *f, 457 x_print_font_instance (struct Lisp_Font_Instance *f,
466 Lisp_Object printcharfun, 458 Lisp_Object printcharfun,
467 int escapeflag) 459 int escapeflag)
468 { 460 {
469 char buf[200]; 461 char buf[200];
470 sprintf (buf, " 0x%lx", (unsigned long) FONT_INSTANCE_X_FONT (f)->fid); 462 sprintf (buf, " 0x%lx", (unsigned long) FONT_INSTANCE_X_FONT (f)->fid);
471 write_c_string (buf, printcharfun); 463 write_c_string (buf, printcharfun);
472 } 464 }
473 465
474 static void 466 static void
475 x_finalize_font_instance (Lisp_Font_Instance *f) 467 x_finalize_font_instance (struct Lisp_Font_Instance *f)
476 { 468 {
477 469
478 if (f->data) 470 if (f->data)
479 { 471 {
480 if (DEVICE_LIVE_P (XDEVICE (f->device))) 472 if (DEVICE_LIVE_P (XDEVICE (f->device)))
770 else 762 else
771 return Qnil; 763 return Qnil;
772 } 764 }
773 765
774 static Lisp_Object 766 static Lisp_Object
775 x_font_instance_truename (Lisp_Font_Instance *f, Error_behavior errb) 767 x_font_instance_truename (struct Lisp_Font_Instance *f, Error_behavior errb)
776 { 768 {
777 struct device *d = XDEVICE (f->device); 769 struct device *d = XDEVICE (f->device);
778 770
779 if (NILP (FONT_INSTANCE_X_TRUENAME (f))) 771 if (NILP (FONT_INSTANCE_X_TRUENAME (f)))
780 { 772 {
798 } 790 }
799 return (FONT_INSTANCE_X_TRUENAME (f)); 791 return (FONT_INSTANCE_X_TRUENAME (f));
800 } 792 }
801 793
802 static Lisp_Object 794 static Lisp_Object
803 x_font_instance_properties (Lisp_Font_Instance *f) 795 x_font_instance_properties (struct Lisp_Font_Instance *f)
804 { 796 {
805 struct device *d = XDEVICE (f->device); 797 struct device *d = XDEVICE (f->device);
806 int i; 798 int i;
807 Lisp_Object result = Qnil; 799 Lisp_Object result = Qnil;
808 XFontProp *props; 800 XFontProp *props;
856 x_list_fonts (Lisp_Object pattern, Lisp_Object device) 848 x_list_fonts (Lisp_Object pattern, Lisp_Object device)
857 { 849 {
858 char **names; 850 char **names;
859 int count = 0; 851 int count = 0;
860 Lisp_Object result = Qnil; 852 Lisp_Object result = Qnil;
861 const char *patternext; 853 CONST char *patternext;
862 854
863 TO_EXTERNAL_FORMAT (LISP_STRING, pattern, 855 GET_C_STRING_BINARY_DATA_ALLOCA (pattern, patternext);
864 C_STRING_ALLOCA, patternext,
865 Qbinary);
866 856
867 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)), 857 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)),
868 patternext, MAX_FONT_COUNT, &count); 858 patternext, MAX_FONT_COUNT, &count);
869 while (count--) 859 while (count--)
870 result = Fcons (build_ext_string (names [count], Qbinary), result); 860 result = Fcons (build_ext_string (names [count], FORMAT_BINARY), result);
871 if (names) 861 if (names)
872 XFreeFontNames (names); 862 XFreeFontNames (names);
873 return result; 863 return result;
874 } 864 }
875 865
876 #ifdef MULE 866 #ifdef MULE
877 867
878 static int 868 static int
879 x_font_spec_matches_charset (struct device *d, Lisp_Object charset, 869 x_font_spec_matches_charset (struct device *d, Lisp_Object charset,
880 const Bufbyte *nonreloc, Lisp_Object reloc, 870 CONST Bufbyte *nonreloc, Lisp_Object reloc,
881 Bytecount offset, Bytecount length) 871 Bytecount offset, Bytecount length)
882 { 872 {
883 if (UNBOUNDP (charset)) 873 if (UNBOUNDP (charset))
884 return 1; 874 return 1;
885 /* Hack! Short font names don't have the registry in them, 875 /* Hack! Short font names don't have the registry in them,
887 case of ASCII. For other charsets, you gotta give the 877 case of ASCII. For other charsets, you gotta give the
888 long form; sorry buster. 878 long form; sorry buster.
889 */ 879 */
890 if (EQ (charset, Vcharset_ascii)) 880 if (EQ (charset, Vcharset_ascii))
891 { 881 {
892 const Bufbyte *the_nonreloc = nonreloc; 882 CONST Bufbyte *the_nonreloc = nonreloc;
893 int i; 883 int i;
894 Bytecount the_length = length; 884 Bytecount the_length = length;
895 885
896 if (!the_nonreloc) 886 if (!the_nonreloc)
897 the_nonreloc = XSTRING_DATA (reloc); 887 the_nonreloc = XSTRING_DATA (reloc);
899 the_nonreloc += offset; 889 the_nonreloc += offset;
900 if (!memchr (the_nonreloc, '*', the_length)) 890 if (!memchr (the_nonreloc, '*', the_length))
901 { 891 {
902 for (i = 0;; i++) 892 for (i = 0;; i++)
903 { 893 {
904 const Bufbyte *new_nonreloc = (const Bufbyte *) 894 CONST Bufbyte *new_nonreloc = (CONST Bufbyte *)
905 memchr (the_nonreloc, '-', the_length); 895 memchr (the_nonreloc, '-', the_length);
906 if (!new_nonreloc) 896 if (!new_nonreloc)
907 break; 897 break;
908 new_nonreloc++; 898 new_nonreloc++;
909 the_length -= new_nonreloc - the_nonreloc; 899 the_length -= new_nonreloc - the_nonreloc;
930 x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset) 920 x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset)
931 { 921 {
932 char **names; 922 char **names;
933 int count = 0; 923 int count = 0;
934 Lisp_Object result = Qnil; 924 Lisp_Object result = Qnil;
935 const char *patternext; 925 CONST char *patternext;
936 int i; 926 int i;
937 927
938 TO_EXTERNAL_FORMAT (LISP_STRING, font, 928 GET_C_STRING_BINARY_DATA_ALLOCA (font, patternext);
939 C_STRING_ALLOCA, patternext,
940 Qbinary);
941 929
942 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)), 930 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)),
943 patternext, MAX_FONT_COUNT, &count); 931 patternext, MAX_FONT_COUNT, &count);
944 /* #### This code seems awfully bogus -- mrb */ 932 /* ### This code seems awfully bogus -- mrb */
945 for (i = 0; i < count; i ++) 933 for (i = 0; i < count; i ++)
946 { 934 {
947 const char *intname; 935 CONST Bufbyte *intname;
948 936
949 TO_INTERNAL_FORMAT (C_STRING, names[i], 937 GET_C_CHARPTR_INT_BINARY_DATA_ALLOCA (names[i], intname);
950 C_STRING_ALLOCA, intname,
951 Qbinary);
952 if (x_font_spec_matches_charset (XDEVICE (device), charset, 938 if (x_font_spec_matches_charset (XDEVICE (device), charset,
953 (Bufbyte *) intname, Qnil, 0, -1)) 939 intname, Qnil, 0, -1))
954 { 940 {
955 result = build_string (intname); 941 result = build_string ((char *) intname);
956 break; 942 break;
957 } 943 }
958 } 944 }
959 945
960 if (names) 946 if (names)