Mercurial > hg > xemacs-beta
annotate src/glyphs-x.c @ 5313:5ed261fd2bd9
Unrool a load-time loop at macro expansion time, cl-macs.el
2010-12-29 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el (inline-side-effect-free-compiler-macros):
Unroll a loop here at macro-expansion time, so these compiler
macros are compiled. Use #'eql instead of #'eq in a couple of
places for better style.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Wed, 29 Dec 2010 23:43:10 +0000 |
parents | 8b2f75cecb89 |
children | 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* X-specific Lisp objects. |
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
4 Copyright (C) 1995 Tinker Systems | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4982
diff
changeset
|
5 Copyright (C) 1995, 1996, 2001, 2002, 2003, 2004, 2005, 2010 Ben Wing |
428 | 6 Copyright (C) 1995 Sun Microsystems |
863 | 7 Copyright (C) 1999, 2000, 2002 Andy Piper |
428 | 8 |
9 This file is part of XEmacs. | |
10 | |
11 XEmacs is free software; you can redistribute it and/or modify it | |
12 under the terms of the GNU General Public License as published by the | |
13 Free Software Foundation; either version 2, or (at your option) any | |
14 later version. | |
15 | |
16 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
19 for more details. | |
20 You should have received a copy of the GNU General Public License | |
21 along with XEmacs; see the file COPYING. If not, write to | |
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
23 Boston, MA 02111-1307, USA. */ | |
24 | |
25 /* Synched up with: Not in FSF. */ | |
26 | |
1204 | 27 /* 7-8-00 This file is more or less Mule-ized. */ |
442 | 28 |
428 | 29 /* Original author: Jamie Zawinski for 19.8 |
30 font-truename stuff added by Jamie Zawinski for 19.10 | |
31 subwindow support added by Chuck Thompson | |
32 additional XPM support added by Chuck Thompson | |
33 initial X-Face support added by Stig | |
34 rewritten/restructured by Ben Wing for 19.12/19.13 | |
35 GIF/JPEG support added by Ben Wing for 19.14 | |
36 PNG support added by Bill Perry for 19.14 | |
37 Improved GIF/JPEG support added by Bill Perry for 19.14 | |
38 Cleanup/simplification of error handling by Ben Wing for 19.14 | |
39 Pointer/icon overhaul, more restructuring by Ben Wing for 19.14 | |
40 GIF support changed to external GIFlib 3.1 by Jareth Hein for 21.0 | |
41 Many changes for color work and optimizations by Jareth Hein for 21.0 | |
42 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0 | |
43 TIFF code by Jareth Hein for 21.0 | |
44 GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c by Andy Piper for 21.0 | |
45 Subwindow and Widget support by Andy Piper for 21.2 | |
46 | |
47 TODO: | |
430 | 48 Support the GrayScale, StaticColor and StaticGray visual classes. |
428 | 49 Convert images.el to C and stick it in here? |
50 */ | |
51 | |
771 | 52 /* Mule-ized last 6-22-00 */ |
53 | |
428 | 54 #include <config.h> |
55 #include "lisp.h" | |
800 | 56 |
57 #include "buffer.h" | |
872 | 58 #include "device-impl.h" |
800 | 59 #include "faces.h" |
60 #include "file-coding.h" | |
872 | 61 #include "frame-impl.h" |
800 | 62 #include "gui.h" |
63 #include "imgproc.h" | |
64 #include "insdel.h" | |
428 | 65 #include "lstream.h" |
800 | 66 #include "opaque.h" |
872 | 67 #include "process.h" /* egetenv() */ |
800 | 68 #include "window.h" |
69 | |
872 | 70 #include "console-x-impl.h" |
428 | 71 #include "glyphs-x.h" |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5050
diff
changeset
|
72 #include "fontcolor-x-impl.h" |
428 | 73 |
74 #include "sysfile.h" | |
771 | 75 #include "sysproc.h" /* for qxe_getpid() */ |
428 | 76 |
77 #include <setjmp.h> | |
78 | |
79 #ifdef LWLIB_WIDGETS_MOTIF | |
1315 | 80 #include "xmotif.h" |
639 | 81 #include <Xm/Scale.h> |
428 | 82 #endif |
83 #include <X11/IntrinsicP.h> | |
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
84 #include <X11/Xmu/CurUtil.h> |
428 | 85 |
86 #define LISP_DEVICE_TO_X_SCREEN(dev) XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev))) | |
87 | |
88 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); | |
89 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); | |
90 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); | |
91 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); | |
92 #ifdef HAVE_JPEG | |
93 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg); | |
94 #endif | |
95 #ifdef HAVE_TIFF | |
96 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff); | |
438 | 97 #endif |
428 | 98 #ifdef HAVE_PNG |
99 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png); | |
438 | 100 #endif |
428 | 101 #ifdef HAVE_GIF |
102 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif); | |
438 | 103 #endif |
428 | 104 #ifdef HAVE_XPM |
105 DEFINE_DEVICE_IIFORMAT (x, xpm); | |
106 #endif | |
107 DEFINE_DEVICE_IIFORMAT (x, xbm); | |
108 DEFINE_DEVICE_IIFORMAT (x, subwindow); | |
109 #ifdef HAVE_XFACE | |
110 DEFINE_DEVICE_IIFORMAT (x, xface); | |
111 #endif | |
112 | |
113 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); | |
114 Lisp_Object Qcursor_font; | |
115 | |
116 DEFINE_IMAGE_INSTANTIATOR_FORMAT (font); | |
117 | |
118 DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect); | |
119 | |
771 | 120 #ifdef HAVE_X_WIDGETS |
442 | 121 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); |
428 | 122 DEFINE_DEVICE_IIFORMAT (x, widget); |
442 | 123 DEFINE_DEVICE_IIFORMAT (x, native_layout); |
428 | 124 DEFINE_DEVICE_IIFORMAT (x, button); |
125 DEFINE_DEVICE_IIFORMAT (x, progress_gauge); | |
126 DEFINE_DEVICE_IIFORMAT (x, edit_field); | |
127 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 | |
128 DEFINE_DEVICE_IIFORMAT (x, combo_box); | |
129 #endif | |
130 DEFINE_DEVICE_IIFORMAT (x, tab_control); | |
131 DEFINE_DEVICE_IIFORMAT (x, label); | |
132 #endif | |
133 | |
134 static void cursor_font_instantiate (Lisp_Object image_instance, | |
135 Lisp_Object instantiator, | |
136 Lisp_Object pointer_fg, | |
137 Lisp_Object pointer_bg, | |
138 int dest_mask, | |
139 Lisp_Object domain); | |
140 | |
771 | 141 #ifdef HAVE_X_WIDGETS |
1111 | 142 static void update_widget_face (widget_value* wv, |
143 Lisp_Image_Instance* ii, Lisp_Object domain); | |
144 static void update_tab_widget_face (widget_value* wv, | |
145 Lisp_Image_Instance* ii, | |
146 Lisp_Object domain); | |
428 | 147 #endif |
1111 | 148 void emacs_Xt_handle_widget_losing_focus (struct frame* f, |
149 Widget losing_widget); | |
150 void emacs_Xt_enqueue_focus_event (Widget wants_it, Lisp_Object frame, | |
151 int in_p); | |
428 | 152 |
153 #include "bitmaps.h" | |
154 | |
155 | |
156 /************************************************************************/ | |
157 /* image instance methods */ | |
158 /************************************************************************/ | |
159 | |
160 /************************************************************************/ | |
161 /* convert from a series of RGB triples to an XImage formated for the */ | |
4252 | 162 /* proper display */ |
428 | 163 /************************************************************************/ |
164 static XImage * | |
165 convert_EImage_to_XImage (Lisp_Object device, int width, int height, | |
2367 | 166 Binbyte *pic, unsigned long **pixtbl, |
428 | 167 int *npixels) |
168 { | |
169 Display *dpy; | |
170 Colormap cmap; | |
171 Visual *vis; | |
172 XImage *outimg; | |
173 int depth, bitmap_pad, bits_per_pixel, byte_cnt, i, j; | |
174 int rd,gr,bl,q; | |
2367 | 175 Binbyte *data, *ip, *dp; |
428 | 176 quant_table *qtable = 0; |
177 union { | |
826 | 178 UINT_32_BIT val; |
428 | 179 char cp[4]; |
180 } conv; | |
181 | |
182 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
183 cmap = DEVICE_X_COLORMAP (XDEVICE(device)); | |
184 vis = DEVICE_X_VISUAL (XDEVICE(device)); | |
185 depth = DEVICE_X_DEPTH(XDEVICE(device)); | |
186 | |
1204 | 187 if (vis->X_CLASSFIELD == GrayScale || vis->X_CLASSFIELD == StaticColor || |
188 vis->X_CLASSFIELD == StaticGray) | |
430 | 189 { |
190 /* #### Implement me!!! */ | |
191 return NULL; | |
192 } | |
193 | |
1204 | 194 if (vis->X_CLASSFIELD == PseudoColor) |
428 | 195 { |
196 /* Quantize the image and get a histogram while we're at it. | |
197 Do this first to save memory */ | |
198 qtable = build_EImage_quantable(pic, width, height, 256); | |
199 if (qtable == NULL) return NULL; | |
200 } | |
201 | |
202 bitmap_pad = ((depth > 16) ? 32 : | |
203 (depth > 8) ? 16 : | |
204 8); | |
205 | |
206 outimg = XCreateImage (dpy, vis, | |
207 depth, ZPixmap, 0, 0, width, height, | |
208 bitmap_pad, 0); | |
209 if (!outimg) return NULL; | |
210 | |
211 bits_per_pixel = outimg->bits_per_pixel; | |
212 byte_cnt = bits_per_pixel >> 3; | |
213 | |
2367 | 214 data = xnew_binbytes (outimg->bytes_per_line * height); |
428 | 215 if (!data) |
216 { | |
217 XDestroyImage (outimg); | |
218 return NULL; | |
219 } | |
220 outimg->data = (char *) data; | |
221 | |
1204 | 222 if (vis->X_CLASSFIELD == PseudoColor) |
428 | 223 { |
224 unsigned long pixarray[256]; | |
225 int pixcount, n; | |
226 /* use our quantize table to allocate the colors */ | |
227 pixcount = 32; | |
228 *pixtbl = xnew_array (unsigned long, pixcount); | |
229 *npixels = 0; | |
230 | |
440 | 231 /* #### should implement a sort by popularity to assure proper allocation */ |
428 | 232 n = *npixels; |
233 for (i = 0; i < qtable->num_active_colors; i++) | |
234 { | |
235 XColor color; | |
236 int res; | |
237 | |
238 color.red = qtable->rm[i] ? qtable->rm[i] << 8 : 0; | |
239 color.green = qtable->gm[i] ? qtable->gm[i] << 8 : 0; | |
240 color.blue = qtable->bm[i] ? qtable->bm[i] << 8 : 0; | |
241 color.flags = DoRed | DoGreen | DoBlue; | |
3094 | 242 res = x_allocate_nearest_color (dpy, cmap, vis, &color); |
428 | 243 if (res > 0 && res < 3) |
244 { | |
245 DO_REALLOC(*pixtbl, pixcount, n+1, unsigned long); | |
246 (*pixtbl)[n] = color.pixel; | |
247 n++; | |
248 } | |
249 pixarray[i] = color.pixel; | |
250 } | |
251 *npixels = n; | |
252 ip = pic; | |
253 for (i = 0; i < height; i++) | |
254 { | |
255 dp = data + (i * outimg->bytes_per_line); | |
256 for (j = 0; j < width; j++) | |
257 { | |
258 rd = *ip++; | |
259 gr = *ip++; | |
260 bl = *ip++; | |
261 conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)]; | |
442 | 262 #ifdef WORDS_BIGENDIAN |
428 | 263 if (outimg->byte_order == MSBFirst) |
264 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; | |
265 else | |
266 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q]; | |
267 #else | |
268 if (outimg->byte_order == MSBFirst) | |
269 for (q = byte_cnt-1; q >= 0; q--) *dp++ = conv.cp[q]; | |
270 else | |
271 for (q = 0; q < byte_cnt; q++) *dp++ = conv.cp[q]; | |
272 #endif | |
273 } | |
274 } | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
275 xfree (qtable); |
428 | 276 } else { |
277 unsigned long rshift,gshift,bshift,rbits,gbits,bbits,junk; | |
278 junk = vis->red_mask; | |
279 rshift = 0; | |
280 while ((junk & 0x1) == 0) | |
281 { | |
282 junk = junk >> 1; | |
283 rshift ++; | |
284 } | |
285 rbits = 0; | |
286 while (junk != 0) | |
287 { | |
288 junk = junk >> 1; | |
289 rbits++; | |
290 } | |
291 junk = vis->green_mask; | |
292 gshift = 0; | |
293 while ((junk & 0x1) == 0) | |
294 { | |
295 junk = junk >> 1; | |
296 gshift ++; | |
297 } | |
298 gbits = 0; | |
299 while (junk != 0) | |
300 { | |
301 junk = junk >> 1; | |
302 gbits++; | |
303 } | |
304 junk = vis->blue_mask; | |
305 bshift = 0; | |
306 while ((junk & 0x1) == 0) | |
307 { | |
308 junk = junk >> 1; | |
309 bshift ++; | |
310 } | |
311 bbits = 0; | |
312 while (junk != 0) | |
313 { | |
314 junk = junk >> 1; | |
315 bbits++; | |
316 } | |
317 ip = pic; | |
318 for (i = 0; i < height; i++) | |
319 { | |
320 dp = data + (i * outimg->bytes_per_line); | |
321 for (j = 0; j < width; j++) | |
322 { | |
323 if (rbits > 8) | |
324 rd = *ip++ << (rbits - 8); | |
325 else | |
326 rd = *ip++ >> (8 - rbits); | |
327 if (gbits > 8) | |
328 gr = *ip++ << (gbits - 8); | |
329 else | |
330 gr = *ip++ >> (8 - gbits); | |
331 if (bbits > 8) | |
332 bl = *ip++ << (bbits - 8); | |
333 else | |
334 bl = *ip++ >> (8 - bbits); | |
335 | |
336 conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift); | |
442 | 337 #ifdef WORDS_BIGENDIAN |
428 | 338 if (outimg->byte_order == MSBFirst) |
339 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; | |
340 else | |
341 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q]; | |
342 #else | |
343 if (outimg->byte_order == MSBFirst) | |
344 for (q = byte_cnt-1; q >= 0; q--) *dp++ = conv.cp[q]; | |
345 else | |
346 for (q = 0; q < byte_cnt; q++) *dp++ = conv.cp[q]; | |
347 #endif | |
348 } | |
349 } | |
350 } | |
351 return outimg; | |
352 } | |
353 | |
354 | |
355 | |
356 static void | |
440 | 357 x_print_image_instance (Lisp_Image_Instance *p, |
428 | 358 Lisp_Object printcharfun, |
2286 | 359 int UNUSED (escapeflag)) |
428 | 360 { |
361 switch (IMAGE_INSTANCE_TYPE (p)) | |
362 { | |
363 case IMAGE_MONO_PIXMAP: | |
364 case IMAGE_COLOR_PIXMAP: | |
365 case IMAGE_POINTER: | |
800 | 366 write_fmt_string (printcharfun, " (0x%lx", |
367 (unsigned long) IMAGE_INSTANCE_X_PIXMAP (p)); | |
428 | 368 if (IMAGE_INSTANCE_X_MASK (p)) |
369 { | |
800 | 370 write_fmt_string (printcharfun, "/0x%lx", |
371 (unsigned long) IMAGE_INSTANCE_X_MASK (p)); | |
428 | 372 } |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
373 write_ascstring (printcharfun, ")"); |
428 | 374 break; |
375 default: | |
376 break; | |
377 } | |
378 } | |
379 | |
380 #ifdef DEBUG_WIDGETS | |
381 extern int debug_widget_instances; | |
382 #endif | |
383 | |
384 static void | |
440 | 385 x_finalize_image_instance (Lisp_Image_Instance *p) |
428 | 386 { |
387 if (!p->data) | |
388 return; | |
389 | |
442 | 390 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))) |
428 | 391 { |
442 | 392 Display *dpy = DEVICE_X_DISPLAY |
393 (XDEVICE (IMAGE_INSTANCE_DEVICE (p))); | |
394 if (0) | |
395 ; | |
771 | 396 #ifdef HAVE_X_WIDGETS |
442 | 397 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) |
428 | 398 { |
399 if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) | |
400 { | |
401 #ifdef DEBUG_WIDGETS | |
402 debug_widget_instances--; | |
403 stderr_out ("widget destroyed, %d left\n", debug_widget_instances); | |
404 #endif | |
405 lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p)); | |
406 lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); | |
442 | 407 |
408 /* We can release the callbacks again. */ | |
409 ungcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p)); | |
410 | |
411 IMAGE_INSTANCE_X_WIDGET_ID (p) = 0; | |
412 IMAGE_INSTANCE_X_CLIPWIDGET (p) = 0; | |
428 | 413 } |
414 } | |
442 | 415 #endif |
428 | 416 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) |
417 { | |
418 if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) | |
419 XDestroyWindow (dpy, IMAGE_INSTANCE_X_SUBWINDOW_ID (p)); | |
420 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; | |
421 } | |
422 else | |
423 { | |
424 int i; | |
425 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)) | |
426 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)); | |
427 | |
428 if (IMAGE_INSTANCE_X_MASK (p) && | |
429 IMAGE_INSTANCE_X_MASK (p) != IMAGE_INSTANCE_X_PIXMAP (p)) | |
430 XFreePixmap (dpy, IMAGE_INSTANCE_X_MASK (p)); | |
431 IMAGE_INSTANCE_PIXMAP_MASK (p) = 0; | |
438 | 432 |
428 | 433 if (IMAGE_INSTANCE_X_PIXMAP_SLICES (p)) |
434 { | |
435 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++) | |
436 if (IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i)) | |
437 { | |
438 XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i)); | |
439 IMAGE_INSTANCE_X_PIXMAP_SLICE (p, i) = 0; | |
440 } | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
441 xfree (IMAGE_INSTANCE_X_PIXMAP_SLICES (p)); |
428 | 442 IMAGE_INSTANCE_X_PIXMAP_SLICES (p) = 0; |
443 } | |
444 | |
445 if (IMAGE_INSTANCE_X_CURSOR (p)) | |
446 { | |
447 XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p)); | |
448 IMAGE_INSTANCE_X_CURSOR (p) = 0; | |
449 } | |
438 | 450 |
428 | 451 if (IMAGE_INSTANCE_X_NPIXELS (p) != 0) |
452 { | |
453 XFreeColors (dpy, | |
454 IMAGE_INSTANCE_X_COLORMAP (p), | |
455 IMAGE_INSTANCE_X_PIXELS (p), | |
456 IMAGE_INSTANCE_X_NPIXELS (p), 0); | |
457 IMAGE_INSTANCE_X_NPIXELS (p) = 0; | |
458 } | |
459 } | |
460 } | |
461 /* You can sometimes have pixels without a live device. I forget | |
462 why, but that's why we free them here if we have a pixmap type | |
463 image instance. It probably means that we might also get a memory | |
464 leak with widgets. */ | |
465 if (IMAGE_INSTANCE_TYPE (p) != IMAGE_WIDGET | |
466 && IMAGE_INSTANCE_TYPE (p) != IMAGE_SUBWINDOW | |
467 && IMAGE_INSTANCE_X_PIXELS (p)) | |
468 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
469 xfree (IMAGE_INSTANCE_X_PIXELS (p)); |
428 | 470 IMAGE_INSTANCE_X_PIXELS (p) = 0; |
471 } | |
472 | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
473 xfree (p->data); |
428 | 474 p->data = 0; |
475 } | |
476 | |
477 static int | |
440 | 478 x_image_instance_equal (Lisp_Image_Instance *p1, |
2286 | 479 Lisp_Image_Instance *p2, int UNUSED (depth)) |
428 | 480 { |
481 switch (IMAGE_INSTANCE_TYPE (p1)) | |
482 { | |
483 case IMAGE_MONO_PIXMAP: | |
484 case IMAGE_COLOR_PIXMAP: | |
485 case IMAGE_POINTER: | |
486 if (IMAGE_INSTANCE_X_COLORMAP (p1) != IMAGE_INSTANCE_X_COLORMAP (p2) || | |
487 IMAGE_INSTANCE_X_NPIXELS (p1) != IMAGE_INSTANCE_X_NPIXELS (p2)) | |
488 return 0; | |
489 break; | |
490 default: | |
491 break; | |
492 } | |
493 | |
494 return 1; | |
495 } | |
496 | |
665 | 497 static Hashcode |
2286 | 498 x_image_instance_hash (Lisp_Image_Instance *p, int UNUSED (depth)) |
428 | 499 { |
500 switch (IMAGE_INSTANCE_TYPE (p)) | |
501 { | |
502 case IMAGE_MONO_PIXMAP: | |
503 case IMAGE_COLOR_PIXMAP: | |
504 case IMAGE_POINTER: | |
505 return IMAGE_INSTANCE_X_NPIXELS (p); | |
506 default: | |
507 return 0; | |
508 } | |
509 } | |
510 | |
511 /* Set all the slots in an image instance structure to reasonable | |
512 default values. This is used somewhere within an instantiate | |
513 method. It is assumed that the device slot within the image | |
514 instance is already set -- this is the case when instantiate | |
515 methods are called. */ | |
516 | |
517 static void | |
440 | 518 x_initialize_pixmap_image_instance (Lisp_Image_Instance *ii, |
428 | 519 int slices, |
520 enum image_instance_type type) | |
521 { | |
522 ii->data = xnew_and_zero (struct x_image_instance_data); | |
523 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices; | |
438 | 524 IMAGE_INSTANCE_X_PIXMAP_SLICES (ii) = |
428 | 525 xnew_array_and_zero (Pixmap, slices); |
526 IMAGE_INSTANCE_TYPE (ii) = type; | |
527 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil; | |
528 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil; | |
529 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil; | |
530 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil; | |
531 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil; | |
532 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil; | |
533 } | |
534 | |
535 | |
536 /************************************************************************/ | |
537 /* pixmap file functions */ | |
538 /************************************************************************/ | |
539 | |
540 /* Where bitmaps are; initialized from resource database */ | |
541 Lisp_Object Vx_bitmap_file_path; | |
542 | |
543 #ifndef BITMAPDIR | |
544 #define BITMAPDIR "/usr/include/X11/bitmaps" | |
545 #endif | |
546 | |
547 #define USE_XBMLANGPATH | |
548 | |
549 /* Given a pixmap filename, look through all of the "standard" places | |
550 where the file might be located. Return a full pathname if found; | |
551 otherwise, return Qnil. */ | |
552 | |
4226 | 553 /* #### FIXME: when Qnil is returned, the caller can't make a difference |
554 #### between a non existing X device, an unreadable file, or an actual | |
555 #### failure to locate the file, so the issued message is really not | |
556 #### informative. -- dvl */ | |
428 | 557 static Lisp_Object |
558 x_locate_pixmap_file (Lisp_Object name) | |
559 { | |
560 /* This function can GC if IN_REDISPLAY is false */ | |
561 Display *display; | |
562 | |
563 /* #### Unix-specific */ | |
4226 | 564 if (string_byte (name, 0) == '~' || |
565 string_byte (name, 0) == '/' || | |
826 | 566 (string_byte (name, 0) == '.' && |
567 (string_byte (name, 1) == '/' || | |
568 (string_byte (name, 1) == '.' && | |
569 (string_byte (name, 2) == '/'))))) | |
428 | 570 { |
571 if (!NILP (Ffile_readable_p (name))) | |
440 | 572 return Fexpand_file_name (name, Qnil); |
428 | 573 else |
574 return Qnil; | |
575 } | |
576 | |
4226 | 577 /* Check non-absolute pathnames with a directory component relative to |
578 the search path; that's the way Xt does it. */ | |
872 | 579 { |
580 Lisp_Object defx = get_default_device (Qx); | |
581 if (NILP (defx)) | |
582 /* This may occur during initialization. */ | |
583 return Qnil; | |
584 else | |
585 /* We only check the bitmapFilePath resource on the original X device. */ | |
586 display = DEVICE_X_DISPLAY (XDEVICE (defx)); | |
587 } | |
428 | 588 |
589 #ifdef USE_XBMLANGPATH | |
590 { | |
867 | 591 Ibyte *path = egetenv ("XBMLANGPATH"); |
940 | 592 if (path) |
428 | 593 { |
4252 | 594 Extbyte *pathext; |
940 | 595 SubstitutionRec subs[1]; |
596 subs[0].match = 'B'; | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
597 LISP_PATHNAME_CONVERT_OUT (name, subs[0].substitution); |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
598 pathext = ITEXT_TO_EXTERNAL (path, Qfile_name); |
940 | 599 /* #### Motif uses a big hairy default if $XBMLANGPATH isn't set. |
4252 | 600 We don't. If you want it used, set it. */ |
940 | 601 if (pathext && |
602 (pathext = XtResolvePathname (display, "bitmaps", 0, 0, pathext, | |
603 subs, XtNumber (subs), 0))) | |
4252 | 604 { |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
605 name = build_extstring (pathext, Qfile_name); |
940 | 606 XtFree (pathext); |
607 return (name); | |
608 } | |
428 | 609 } |
610 } | |
611 #endif | |
612 | |
613 if (NILP (Vx_bitmap_file_path)) | |
614 { | |
615 char *type = 0; | |
616 XrmValue value; | |
617 if (XrmGetResource (XtDatabase (display), | |
618 "bitmapFilePath", "BitmapFilePath", &type, &value) | |
619 && !strcmp (type, "String")) | |
771 | 620 { |
867 | 621 Ibyte *path; |
771 | 622 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
623 path = EXTERNAL_TO_ITEXT (value.addr, Qfile_name); |
771 | 624 Vx_bitmap_file_path = split_env_path (0, path); |
625 } | |
428 | 626 Vx_bitmap_file_path = nconc2 (Vx_bitmap_file_path, |
771 | 627 (split_external_path (BITMAPDIR))); |
428 | 628 } |
629 | |
630 { | |
631 Lisp_Object found; | |
632 if (locate_file (Vx_bitmap_file_path, name, Qnil, &found, R_OK) < 0) | |
633 { | |
634 Lisp_Object temp = list1 (Vdata_directory); | |
635 struct gcpro gcpro1; | |
636 | |
637 GCPRO1 (temp); | |
638 locate_file (temp, name, Qnil, &found, R_OK); | |
639 UNGCPRO; | |
640 } | |
641 | |
642 return found; | |
643 } | |
644 } | |
645 | |
646 static Lisp_Object | |
647 locate_pixmap_file (Lisp_Object name) | |
648 { | |
649 return x_locate_pixmap_file (name); | |
650 } | |
651 | |
652 | |
653 /************************************************************************/ | |
654 /* cursor functions */ | |
655 /************************************************************************/ | |
656 | |
657 /* Check that this server supports cursors of size WIDTH * HEIGHT. If | |
658 not, signal an error. INSTANTIATOR is only used in the error | |
659 message. */ | |
660 | |
661 static void | |
647 | 662 check_pointer_sizes (Screen *xs, int width, int height, |
428 | 663 Lisp_Object instantiator) |
664 { | |
665 unsigned int best_width, best_height; | |
666 if (! XQueryBestCursor (DisplayOfScreen (xs), RootWindowOfScreen (xs), | |
667 width, height, &best_width, &best_height)) | |
668 /* this means that an X error of some sort occurred (we trap | |
669 these so they're not fatal). */ | |
563 | 670 gui_error ("XQueryBestCursor() failed?", instantiator); |
428 | 671 |
647 | 672 if (width > (int) best_width || height > (int) best_height) |
563 | 673 signal_ferror_with_frob (Qgui_error, instantiator, |
674 "pointer too large (%dx%d): " | |
675 "server requires %dx%d or smaller", | |
676 width, height, best_width, best_height); | |
428 | 677 } |
678 | |
679 | |
680 static void | |
681 generate_cursor_fg_bg (Lisp_Object device, Lisp_Object *foreground, | |
682 Lisp_Object *background, XColor *xfg, XColor *xbg) | |
683 { | |
684 if (!NILP (*foreground) && !COLOR_INSTANCEP (*foreground)) | |
685 *foreground = | |
686 Fmake_color_instance (*foreground, device, | |
687 encode_error_behavior_flag (ERROR_ME)); | |
688 if (COLOR_INSTANCEP (*foreground)) | |
689 *xfg = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (*foreground)); | |
690 else | |
691 { | |
692 xfg->pixel = 0; | |
693 xfg->red = xfg->green = xfg->blue = 0; | |
694 } | |
695 | |
696 if (!NILP (*background) && !COLOR_INSTANCEP (*background)) | |
697 *background = | |
698 Fmake_color_instance (*background, device, | |
699 encode_error_behavior_flag (ERROR_ME)); | |
700 if (COLOR_INSTANCEP (*background)) | |
701 *xbg = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (*background)); | |
702 else | |
703 { | |
704 xbg->pixel = 0; | |
460 | 705 xbg->red = xbg->green = xbg->blue = USHRT_MAX; |
428 | 706 } |
707 } | |
708 | |
709 static void | |
710 maybe_recolor_cursor (Lisp_Object image_instance, Lisp_Object foreground, | |
711 Lisp_Object background) | |
712 { | |
713 Lisp_Object device = XIMAGE_INSTANCE_DEVICE (image_instance); | |
714 XColor xfg, xbg; | |
715 | |
716 generate_cursor_fg_bg (device, &foreground, &background, &xfg, &xbg); | |
717 if (!NILP (foreground) || !NILP (background)) | |
718 { | |
719 XRecolorCursor (DEVICE_X_DISPLAY (XDEVICE (device)), | |
720 XIMAGE_INSTANCE_X_CURSOR (image_instance), | |
721 &xfg, &xbg); | |
722 XIMAGE_INSTANCE_PIXMAP_FG (image_instance) = foreground; | |
723 XIMAGE_INSTANCE_PIXMAP_BG (image_instance) = background; | |
724 } | |
725 } | |
726 | |
727 | |
728 /************************************************************************/ | |
729 /* color pixmap functions */ | |
730 /************************************************************************/ | |
731 | |
2959 | 732 /* Create a pointer from a color pixmap. */ |
733 | |
734 static void | |
735 image_instance_convert_to_pointer (Lisp_Image_Instance *ii, | |
736 Lisp_Object instantiator, | |
737 Lisp_Object pointer_fg, | |
738 Lisp_Object pointer_bg) | |
739 { | |
740 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
741 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
742 Screen *xs = DefaultScreenOfDisplay (dpy); | |
743 int npixels = IMAGE_INSTANCE_X_NPIXELS (ii); | |
744 unsigned long *pixels = IMAGE_INSTANCE_X_PIXELS (ii); | |
745 Pixmap pixmap = IMAGE_INSTANCE_X_PIXMAP (ii); | |
746 Pixmap mask = (Pixmap) IMAGE_INSTANCE_PIXMAP_MASK (ii); | |
747 Colormap cmap; | |
748 XColor fg, bg; | |
749 int i; | |
750 int xhot = 0, yhot = 0; | |
751 int w, h; | |
752 | |
753 if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii))) | |
754 xhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)); | |
755 if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii))) | |
756 yhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)); | |
757 w = IMAGE_INSTANCE_PIXMAP_WIDTH (ii); | |
758 h = IMAGE_INSTANCE_PIXMAP_HEIGHT (ii); | |
759 | |
760 #if 1 | |
761 /* Although I haven't found it documented yet, it appears that pointers are | |
762 always colored via the default window colormap... Sigh. */ | |
763 cmap = DefaultColormap (dpy, DefaultScreen (dpy)); | |
764 IMAGE_INSTANCE_X_COLORMAP (ii) = cmap; | |
765 #else | |
766 cmap = IMAGE_INSTANCE_X_COLORMAP (ii); | |
767 #endif | |
768 | |
769 check_pointer_sizes (xs, w, h, instantiator); | |
770 | |
771 /* If the loaded pixmap has colors allocated (meaning it came from an | |
772 XPM file), then use those as the default colors for the cursor we | |
773 create. Otherwise, default to pointer_fg and pointer_bg. | |
774 */ | |
775 if (npixels >= 2) | |
776 { | |
777 /* With an XBM file, it's obvious which bit is foreground | |
778 and which is background, or rather, it's implicit: in | |
779 an XBM file, a 1 bit is foreground, and a 0 bit is | |
780 background. | |
781 | |
782 XCreatePixmapCursor() assumes this property of the | |
783 pixmap it is called with as well; the `foreground' | |
784 color argument is used for the 1 bits. | |
785 | |
786 With an XPM file, it's tricker, since the elements of | |
787 the pixmap don't represent FG and BG, but are actual | |
788 pixel values. So we need to figure out which of those | |
789 pixels is the foreground color and which is the | |
790 background. We do it by comparing RGB and assuming | |
791 that the darker color is the foreground. This works | |
792 with the result of xbmtopbm|ppmtoxpm, at least. | |
793 | |
794 It might be nice if there was some way to tag the | |
795 colors in the XPM file with whether they are the | |
796 foreground - perhaps with logical color names somehow? | |
797 | |
798 Once we have decided which color is the foreground, we | |
799 need to ensure that that color corresponds to a `1' bit | |
800 in the Pixmap. The XPM library wrote into the (1-bit) | |
801 pixmap with XPutPixel, which will ignore all but the | |
802 least significant bit. | |
803 | |
804 This means that a 1 bit in the image corresponds to | |
805 `fg' only if `fg.pixel' is odd. | |
806 | |
807 (This also means that the image will be all the same | |
808 color if both `fg' and `bg' are odd or even, but we can | |
809 safely assume that that won't happen if the XPM file is | |
810 sensible I think.) | |
811 | |
812 The desired result is that the image use `1' to | |
813 represent the foreground color, and `0' to represent | |
814 the background color. So, we may need to invert the | |
815 image to accomplish this; we invert if fg is | |
816 odd. (Remember that WhitePixel and BlackPixel are not | |
817 necessarily 1 and 0 respectively, though I think it | |
818 might be safe to assume that one of them is always 1 | |
819 and the other is always 0. We also pretty much need to | |
820 assume that one is even and the other is odd.) | |
821 */ | |
822 | |
823 fg.pixel = pixels[0]; /* pick a pixel at random. */ | |
824 bg.pixel = fg.pixel; | |
825 for (i = 1; i < npixels; i++) /* Look for an "other" pixel value.*/ | |
826 { | |
827 bg.pixel = pixels[i]; | |
828 if (fg.pixel != bg.pixel) | |
829 break; | |
830 } | |
831 | |
832 /* If (fg.pixel == bg.pixel) then probably something has | |
833 gone wrong, but I don't think signalling an error would | |
834 be appropriate. */ | |
835 | |
836 XQueryColor (dpy, cmap, &fg); | |
837 XQueryColor (dpy, cmap, &bg); | |
838 | |
839 /* If the foreground is lighter than the background, swap them. | |
840 (This occurs semi-randomly, depending on the ordering of the | |
841 color list in the XPM file.) | |
842 */ | |
843 { | |
844 unsigned short fg_total = ((fg.red / 3) + (fg.green / 3) | |
845 + (fg.blue / 3)); | |
846 unsigned short bg_total = ((bg.red / 3) + (bg.green / 3) | |
847 + (bg.blue / 3)); | |
848 if (fg_total > bg_total) | |
849 { | |
850 XColor swap; | |
851 swap = fg; | |
852 fg = bg; | |
853 bg = swap; | |
854 } | |
855 } | |
856 | |
857 /* If the fg pixel corresponds to a `0' in the bitmap, invert it. | |
858 (This occurs (only?) on servers with Black=0, White=1.) | |
859 */ | |
860 if ((fg.pixel & 1) == 0) | |
861 { | |
862 XGCValues gcv; | |
863 GC gc; | |
864 gcv.function = GXxor; | |
865 gcv.foreground = 1; | |
866 gc = XCreateGC (dpy, pixmap, (GCFunction | GCForeground), | |
867 &gcv); | |
868 XFillRectangle (dpy, pixmap, gc, 0, 0, w, h); | |
869 XFreeGC (dpy, gc); | |
870 } | |
871 } | |
872 else | |
873 { | |
874 generate_cursor_fg_bg (device, &pointer_fg, &pointer_bg, | |
875 &fg, &bg); | |
876 IMAGE_INSTANCE_PIXMAP_FG (ii) = pointer_fg; | |
877 IMAGE_INSTANCE_PIXMAP_BG (ii) = pointer_bg; | |
878 } | |
879 | |
880 IMAGE_INSTANCE_X_CURSOR (ii) = | |
881 XCreatePixmapCursor | |
882 (dpy, pixmap, mask, &fg, &bg, xhot, yhot); | |
883 } | |
884 | |
428 | 885 /* Initialize an image instance from an XImage. |
886 | |
887 DEST_MASK specifies the mask of allowed image types. | |
888 | |
889 PIXELS and NPIXELS specify an array of pixels that are used in | |
890 the image. These need to be kept around for the duration of the | |
891 image. When the image instance is freed, XFreeColors() will | |
892 automatically be called on all the pixels specified here; thus, | |
893 you should have allocated the pixels yourself using XAllocColor() | |
894 or the like. The array passed in is used directly without | |
895 being copied, so it should be heap data created with xmalloc(). | |
896 It will be freed using xfree() when the image instance is | |
897 destroyed. | |
898 | |
899 If this fails, signal an error. INSTANTIATOR is only used | |
900 in the error message. | |
2959 | 901 */ |
428 | 902 |
903 static void | |
440 | 904 init_image_instance_from_x_image (Lisp_Image_Instance *ii, |
428 | 905 XImage *ximage, |
906 int dest_mask, | |
907 Colormap cmap, | |
908 unsigned long *pixels, | |
909 int npixels, | |
910 int slices, | |
2959 | 911 Lisp_Object instantiator, |
912 Lisp_Object pointer_fg, | |
913 Lisp_Object pointer_bg) | |
428 | 914 { |
915 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
916 Display *dpy; | |
917 GC gc; | |
918 Drawable d; | |
919 Pixmap pixmap; | |
2959 | 920 enum image_instance_type type; |
428 | 921 |
922 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 923 gui_error ("Not an X device", device); |
428 | 924 |
925 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
2959 | 926 d = XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))); |
927 | |
928 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
929 type = IMAGE_COLOR_PIXMAP; | |
930 else if (dest_mask & IMAGE_POINTER_MASK) | |
931 type = IMAGE_POINTER; | |
932 else | |
428 | 933 incompatible_image_types (instantiator, dest_mask, |
2959 | 934 IMAGE_COLOR_PIXMAP_MASK |
935 | IMAGE_POINTER_MASK); | |
428 | 936 |
937 pixmap = XCreatePixmap (dpy, d, ximage->width, | |
938 ximage->height, ximage->depth); | |
939 if (!pixmap) | |
563 | 940 gui_error ("Unable to create pixmap", instantiator); |
428 | 941 |
942 gc = XCreateGC (dpy, pixmap, 0, NULL); | |
943 if (!gc) | |
944 { | |
945 XFreePixmap (dpy, pixmap); | |
563 | 946 gui_error ("Unable to create GC", instantiator); |
428 | 947 } |
948 | |
949 XPutImage (dpy, pixmap, gc, ximage, 0, 0, 0, 0, | |
950 ximage->width, ximage->height); | |
951 | |
952 XFreeGC (dpy, gc); | |
953 | |
954 x_initialize_pixmap_image_instance (ii, slices, IMAGE_COLOR_PIXMAP); | |
955 | |
956 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
957 find_keyword_in_vector (instantiator, Q_file); | |
958 | |
959 /* Fixup a set of pixmaps. */ | |
960 IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap; | |
961 | |
962 IMAGE_INSTANCE_PIXMAP_MASK (ii) = 0; | |
963 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = ximage->width; | |
964 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = ximage->height; | |
965 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = ximage->depth; | |
966 IMAGE_INSTANCE_X_COLORMAP (ii) = cmap; | |
967 IMAGE_INSTANCE_X_PIXELS (ii) = pixels; | |
968 IMAGE_INSTANCE_X_NPIXELS (ii) = npixels; | |
2959 | 969 |
970 if (type == IMAGE_POINTER) | |
971 image_instance_convert_to_pointer (ii, instantiator, pointer_fg, | |
972 pointer_bg); | |
428 | 973 } |
974 | |
975 static void | |
440 | 976 image_instance_add_x_image (Lisp_Image_Instance *ii, |
428 | 977 XImage *ximage, |
978 int slice, | |
979 Lisp_Object instantiator) | |
980 { | |
981 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
982 Display *dpy; | |
983 GC gc; | |
984 Drawable d; | |
985 Pixmap pixmap; | |
986 | |
987 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
988 d = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (device))); | |
989 | |
990 pixmap = XCreatePixmap (dpy, d, ximage->width, | |
991 ximage->height, ximage->depth); | |
992 if (!pixmap) | |
563 | 993 gui_error ("Unable to create pixmap", instantiator); |
428 | 994 |
995 gc = XCreateGC (dpy, pixmap, 0, NULL); | |
996 if (!gc) | |
997 { | |
998 XFreePixmap (dpy, pixmap); | |
563 | 999 gui_error ("Unable to create GC", instantiator); |
428 | 1000 } |
1001 | |
1002 XPutImage (dpy, pixmap, gc, ximage, 0, 0, 0, 0, | |
1003 ximage->width, ximage->height); | |
1004 | |
1005 XFreeGC (dpy, gc); | |
1006 | |
1007 IMAGE_INSTANCE_X_PIXMAP_SLICE (ii, slice) = pixmap; | |
1008 } | |
1009 | |
1010 static void | |
440 | 1011 x_init_image_instance_from_eimage (Lisp_Image_Instance *ii, |
428 | 1012 int width, int height, |
1013 int slices, | |
2367 | 1014 Binbyte *eimage, |
428 | 1015 int dest_mask, |
1016 Lisp_Object instantiator, | |
2959 | 1017 Lisp_Object pointer_fg, |
1018 Lisp_Object pointer_bg, | |
2286 | 1019 Lisp_Object UNUSED (domain)) |
428 | 1020 { |
1021 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
1022 Colormap cmap = DEVICE_X_COLORMAP (XDEVICE(device)); | |
1023 unsigned long *pixtbl = NULL; | |
1024 int npixels = 0; | |
1025 int slice; | |
1026 XImage* ximage; | |
1027 | |
1028 for (slice = 0; slice < slices; slice++) | |
1029 { | |
438 | 1030 ximage = convert_EImage_to_XImage (device, width, height, |
428 | 1031 eimage + (width * height * 3 * slice), |
1032 &pixtbl, &npixels); | |
1033 if (!ximage) | |
1034 { | |
1726 | 1035 if (pixtbl) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1036 xfree (pixtbl); |
2959 | 1037 signal_image_error ("EImage to XImage conversion failed", |
1038 instantiator); | |
428 | 1039 } |
1040 | |
1041 /* Now create the pixmap and set up the image instance */ | |
1042 if (slice == 0) | |
1043 init_image_instance_from_x_image (ii, ximage, dest_mask, | |
1044 cmap, pixtbl, npixels, slices, | |
2959 | 1045 instantiator, pointer_fg, |
1046 pointer_bg); | |
428 | 1047 else |
1048 image_instance_add_x_image (ii, ximage, slice, instantiator); | |
1049 | |
1050 if (ximage) | |
1051 { | |
1052 if (ximage->data) | |
1053 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1054 xfree (ximage->data); |
428 | 1055 ximage->data = 0; |
1056 } | |
1057 XDestroyImage (ximage); | |
1058 ximage = 0; | |
1059 } | |
1060 } | |
1061 } | |
1062 | |
1063 /* Given inline data for a mono pixmap, create and return the | |
1064 corresponding X object. */ | |
1065 | |
1066 static Pixmap | |
1067 pixmap_from_xbm_inline (Lisp_Object device, int width, int height, | |
2367 | 1068 CBinbyte *bits) |
428 | 1069 { |
771 | 1070 return XCreatePixmapFromBitmapData (DEVICE_X_DISPLAY (XDEVICE (device)), |
1071 XtWindow (DEVICE_XT_APP_SHELL | |
1072 (XDEVICE (device))), | |
1073 bits, width, height, | |
1074 1, 0, 1); | |
428 | 1075 } |
1076 | |
1077 /* Given inline data for a mono pixmap, initialize the given | |
1078 image instance accordingly. */ | |
1079 | |
1080 static void | |
440 | 1081 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii, |
428 | 1082 int width, int height, |
2367 | 1083 CBinbyte *bits, |
428 | 1084 Lisp_Object instantiator, |
1085 Lisp_Object pointer_fg, | |
1086 Lisp_Object pointer_bg, | |
1087 int dest_mask, | |
1088 Pixmap mask, | |
2286 | 1089 Lisp_Object UNUSED (mask_filename)) |
428 | 1090 { |
1091 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
1092 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1093 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background); | |
1094 Display *dpy; | |
1095 Screen *scr; | |
1096 Drawable draw; | |
1097 enum image_instance_type type; | |
1098 | |
1099 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 1100 gui_error ("Not an X device", device); |
428 | 1101 |
1102 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
1103 draw = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (device))); | |
1104 scr = DefaultScreenOfDisplay (dpy); | |
1105 | |
1106 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) && | |
1107 (dest_mask & IMAGE_COLOR_PIXMAP_MASK)) | |
1108 { | |
1109 if (!NILP (foreground) || !NILP (background)) | |
1110 type = IMAGE_COLOR_PIXMAP; | |
1111 else | |
1112 type = IMAGE_MONO_PIXMAP; | |
1113 } | |
1114 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK) | |
1115 type = IMAGE_MONO_PIXMAP; | |
1116 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
1117 type = IMAGE_COLOR_PIXMAP; | |
1118 else if (dest_mask & IMAGE_POINTER_MASK) | |
1119 type = IMAGE_POINTER; | |
1120 else | |
1121 incompatible_image_types (instantiator, dest_mask, | |
1122 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | |
1123 | IMAGE_POINTER_MASK); | |
1124 | |
1125 x_initialize_pixmap_image_instance (ii, 1, type); | |
1126 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width; | |
1127 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height; | |
1128 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
1129 find_keyword_in_vector (instantiator, Q_file); | |
1130 | |
1131 switch (type) | |
1132 { | |
1133 case IMAGE_MONO_PIXMAP: | |
1134 { | |
1135 IMAGE_INSTANCE_X_PIXMAP (ii) = | |
771 | 1136 pixmap_from_xbm_inline (device, width, height, bits); |
428 | 1137 } |
1138 break; | |
1139 | |
1140 case IMAGE_COLOR_PIXMAP: | |
1141 { | |
1142 Dimension d = DEVICE_X_DEPTH (XDEVICE(device)); | |
1143 unsigned long fg = BlackPixelOfScreen (scr); | |
1144 unsigned long bg = WhitePixelOfScreen (scr); | |
1145 | |
1146 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground)) | |
1147 foreground = | |
1148 Fmake_color_instance (foreground, device, | |
1149 encode_error_behavior_flag (ERROR_ME)); | |
1150 | |
1151 if (COLOR_INSTANCEP (foreground)) | |
1152 fg = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (foreground)).pixel; | |
1153 | |
1154 if (!NILP (background) && !COLOR_INSTANCEP (background)) | |
1155 background = | |
1156 Fmake_color_instance (background, device, | |
1157 encode_error_behavior_flag (ERROR_ME)); | |
1158 | |
1159 if (COLOR_INSTANCEP (background)) | |
1160 bg = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (background)).pixel; | |
1161 | |
1162 /* We used to duplicate the pixels using XAllocColor(), to protect | |
1163 against their getting freed. Just as easy to just store the | |
1164 color instances here and GC-protect them, so this doesn't | |
1165 happen. */ | |
1166 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; | |
1167 IMAGE_INSTANCE_PIXMAP_BG (ii) = background; | |
1168 IMAGE_INSTANCE_X_PIXMAP (ii) = | |
1169 XCreatePixmapFromBitmapData (dpy, draw, | |
2367 | 1170 (CBinbyte *) bits, width, height, |
428 | 1171 fg, bg, d); |
1172 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = d; | |
1173 } | |
1174 break; | |
1175 | |
1176 case IMAGE_POINTER: | |
1177 { | |
1178 XColor fg_color, bg_color; | |
1179 Pixmap source; | |
1180 | |
1181 check_pointer_sizes (scr, width, height, instantiator); | |
1182 | |
1183 source = | |
1184 XCreatePixmapFromBitmapData (dpy, draw, | |
2367 | 1185 (CBinbyte *) bits, width, height, |
428 | 1186 1, 0, 1); |
1187 | |
1188 if (NILP (foreground)) | |
1189 foreground = pointer_fg; | |
1190 if (NILP (background)) | |
1191 background = pointer_bg; | |
1192 generate_cursor_fg_bg (device, &foreground, &background, | |
1193 &fg_color, &bg_color); | |
1194 | |
1195 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; | |
1196 IMAGE_INSTANCE_PIXMAP_BG (ii) = background; | |
1197 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = | |
1198 find_keyword_in_vector (instantiator, Q_hotspot_x); | |
1199 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = | |
1200 find_keyword_in_vector (instantiator, Q_hotspot_y); | |
1201 IMAGE_INSTANCE_X_CURSOR (ii) = | |
1202 XCreatePixmapCursor | |
1203 (dpy, source, mask, &fg_color, &bg_color, | |
1204 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) ? | |
1205 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) : 0, | |
1206 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) ? | |
1207 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) : 0); | |
1208 } | |
1209 break; | |
1210 | |
1211 default: | |
2500 | 1212 ABORT (); |
428 | 1213 } |
1214 } | |
1215 | |
1216 static void | |
1217 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, | |
1218 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
1219 int dest_mask, int width, int height, | |
2367 | 1220 CBinbyte *bits) |
428 | 1221 { |
1222 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data); | |
1223 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file); | |
440 | 1224 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1225 Pixmap mask = 0; |
1226 | |
1227 if (!NILP (mask_data)) | |
1228 { | |
2367 | 1229 CBinbyte *ext_data; |
771 | 1230 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1231 ext_data = LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (mask_data))), |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1232 Qbinary); |
440 | 1233 mask = pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii), |
1234 XINT (XCAR (mask_data)), | |
1235 XINT (XCAR (XCDR (mask_data))), | |
444 | 1236 ext_data); |
428 | 1237 } |
1238 | |
1239 init_image_instance_from_xbm_inline (ii, width, height, bits, | |
1240 instantiator, pointer_fg, pointer_bg, | |
1241 dest_mask, mask, mask_file); | |
1242 } | |
1243 | |
1244 /* Instantiate method for XBM's. */ | |
1245 | |
1246 static void | |
1247 x_xbm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1248 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1249 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1250 { |
1251 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 1252 CBinbyte *ext_data; |
428 | 1253 |
1254 assert (!NILP (data)); | |
1255 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1256 ext_data = LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (data))), Qbinary); |
428 | 1257 |
1258 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, | |
1259 pointer_bg, dest_mask, XINT (XCAR (data)), | |
440 | 1260 XINT (XCAR (XCDR (data))), ext_data); |
428 | 1261 } |
1262 | |
1263 | |
1264 #ifdef HAVE_XPM | |
1265 | |
1266 /********************************************************************** | |
1267 * XPM * | |
1268 **********************************************************************/ | |
1269 /* xpm 3.2g and better has XpmCreatePixmapFromBuffer()... | |
1270 There was no version number in xpm.h before 3.3, but this should do. | |
1271 */ | |
1272 #if (XpmVersion >= 3) || defined(XpmExactColors) | |
1273 # define XPM_DOES_BUFFERS | |
1274 #endif | |
1275 | |
1276 #ifndef XPM_DOES_BUFFERS | |
1277 Your version of XPM is too old. You cannot compile with it. | |
1278 Upgrade to version 3.2g or better or compile with --with-xpm=no. | |
1279 #endif /* !XPM_DOES_BUFFERS */ | |
1280 | |
1281 static XpmColorSymbol * | |
1282 extract_xpm_color_names (XpmAttributes *xpmattrs, Lisp_Object device, | |
1283 Lisp_Object domain, | |
1284 Lisp_Object color_symbol_alist) | |
1285 { | |
1286 /* This function can GC */ | |
1287 Display *dpy = DEVICE_X_DISPLAY (XDEVICE(device)); | |
1288 Colormap cmap = DEVICE_X_COLORMAP (XDEVICE(device)); | |
1289 XColor color; | |
1290 Lisp_Object rest; | |
1291 Lisp_Object results = Qnil; | |
1292 int i; | |
1293 XpmColorSymbol *symbols; | |
1294 struct gcpro gcpro1, gcpro2; | |
1295 | |
1296 GCPRO2 (results, device); | |
1297 | |
1298 /* We built up results to be (("name" . #<color>) ...) so that if an | |
1299 error happens we don't lose any malloc()ed data, or more importantly, | |
1300 leave any pixels allocated in the server. */ | |
1301 i = 0; | |
1302 LIST_LOOP (rest, color_symbol_alist) | |
1303 { | |
1304 Lisp_Object cons = XCAR (rest); | |
1305 Lisp_Object name = XCAR (cons); | |
1306 Lisp_Object value = XCDR (cons); | |
1307 if (NILP (value)) | |
1308 continue; | |
1309 if (STRINGP (value)) | |
1310 value = | |
1311 Fmake_color_instance | |
793 | 1312 (value, device, encode_error_behavior_flag (ERROR_ME_DEBUG_WARN)); |
428 | 1313 else |
4252 | 1314 { |
1315 assert (COLOR_SPECIFIERP (value)); | |
1316 value = Fspecifier_instance (value, domain, Qnil, Qnil); | |
1317 } | |
428 | 1318 if (NILP (value)) |
4252 | 1319 continue; |
428 | 1320 results = noseeum_cons (noseeum_cons (name, value), results); |
1321 i++; | |
1322 } | |
1323 UNGCPRO; /* no more evaluation */ | |
1324 | |
1325 if (i == 0) return 0; | |
1326 | |
1327 symbols = xnew_array (XpmColorSymbol, i); | |
1328 xpmattrs->valuemask |= XpmColorSymbols; | |
1329 xpmattrs->colorsymbols = symbols; | |
1330 xpmattrs->numsymbols = i; | |
1331 | |
1332 while (--i >= 0) | |
1333 { | |
1334 Lisp_Object cons = XCAR (results); | |
1335 color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (XCDR (cons))); | |
1336 /* Duplicate the pixel value so that we still have a lock on it if | |
1337 the pixel we were passed is later freed. */ | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4982
diff
changeset
|
1338 assert (XAllocColor (dpy, cmap, &color)); /* it must be allocable since we're just duplicating it */ |
428 | 1339 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1340 |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1341 symbols[i].name = LISP_STRING_TO_EXTERNAL_MALLOC (XCAR (cons), Qctext); |
771 | 1342 symbols[i].pixel = color.pixel; |
1343 symbols[i].value = 0; | |
853 | 1344 free_cons (cons); |
428 | 1345 cons = results; |
1346 results = XCDR (results); | |
853 | 1347 free_cons (cons); |
428 | 1348 } |
1349 return symbols; | |
1350 } | |
1351 | |
1352 static void | |
1353 xpm_free (XpmAttributes *xpmattrs) | |
1354 { | |
1355 /* Could conceivably lose if XpmXXX returned an error without first | |
1356 initializing this structure, if we didn't know that initializing it | |
1357 to all zeros was ok (and also that it's ok to call XpmFreeAttributes() | |
1358 multiple times, since it zeros slots as it frees them...) */ | |
1359 XpmFreeAttributes (xpmattrs); | |
1360 } | |
1361 | |
1362 static void | |
1363 x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
438 | 1364 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1365 int dest_mask, Lisp_Object domain) | |
428 | 1366 { |
1367 /* This function can GC */ | |
440 | 1368 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1369 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1370 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1371 Display *dpy; | |
1372 Screen *xs; | |
1373 Colormap cmap; | |
1374 int depth; | |
1375 Visual *visual; | |
1376 Pixmap pixmap; | |
1377 Pixmap mask = 0; | |
1378 XpmAttributes xpmattrs; | |
1379 int result; | |
1380 XpmColorSymbol *color_symbols; | |
1381 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator, | |
1382 Q_color_symbols); | |
1383 enum image_instance_type type; | |
1384 int force_mono; | |
647 | 1385 int w, h; |
428 | 1386 |
1387 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 1388 gui_error ("Not an X device", device); |
428 | 1389 |
1390 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
1391 xs = DefaultScreenOfDisplay (dpy); | |
1392 | |
1393 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
1394 type = IMAGE_COLOR_PIXMAP; | |
1395 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK) | |
1396 type = IMAGE_MONO_PIXMAP; | |
1397 else if (dest_mask & IMAGE_POINTER_MASK) | |
1398 type = IMAGE_POINTER; | |
1399 else | |
1400 incompatible_image_types (instantiator, dest_mask, | |
1401 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | |
1402 | IMAGE_POINTER_MASK); | |
1403 force_mono = (type != IMAGE_COLOR_PIXMAP); | |
1404 | |
1405 #if 1 | |
1406 /* Although I haven't found it documented yet, it appears that pointers are | |
1407 always colored via the default window colormap... Sigh. */ | |
1408 if (type == IMAGE_POINTER) | |
1409 { | |
2959 | 1410 cmap = DefaultColormap (dpy, DefaultScreen (dpy)); |
428 | 1411 depth = DefaultDepthOfScreen (xs); |
1412 visual = DefaultVisualOfScreen (xs); | |
1413 } | |
1414 else | |
1415 { | |
2959 | 1416 cmap = DEVICE_X_COLORMAP (XDEVICE (device)); |
1417 depth = DEVICE_X_DEPTH (XDEVICE (device)); | |
1418 visual = DEVICE_X_VISUAL (XDEVICE (device)); | |
428 | 1419 } |
1420 #else | |
2959 | 1421 cmap = DEVICE_X_COLORMAP (XDEVICE (device)); |
1422 depth = DEVICE_X_DEPTH (XDEVICE (device)); | |
1423 visual = DEVICE_X_VISUAL (XDEVICE (device)); | |
428 | 1424 #endif |
1425 | |
1426 x_initialize_pixmap_image_instance (ii, 1, type); | |
1427 | |
1428 assert (!NILP (data)); | |
1429 | |
1430 retry: | |
1431 | |
1432 xzero (xpmattrs); /* want XpmInitAttributes() */ | |
1433 xpmattrs.valuemask = XpmReturnPixels; | |
1434 if (force_mono) | |
1435 { | |
1436 /* Without this, we get a 1-bit version of the color image, which | |
1437 isn't quite right. With this, we get the mono image, which might | |
1438 be very different looking. */ | |
1439 xpmattrs.valuemask |= XpmColorKey; | |
1440 xpmattrs.color_key = XPM_MONO; | |
1441 xpmattrs.depth = 1; | |
1442 xpmattrs.valuemask |= XpmDepth; | |
1443 } | |
1444 else | |
1445 { | |
1446 xpmattrs.closeness = 65535; | |
1447 xpmattrs.valuemask |= XpmCloseness; | |
1448 xpmattrs.depth = depth; | |
1449 xpmattrs.valuemask |= XpmDepth; | |
1450 xpmattrs.visual = visual; | |
1451 xpmattrs.valuemask |= XpmVisual; | |
1452 xpmattrs.colormap = cmap; | |
1453 xpmattrs.valuemask |= XpmColormap; | |
1454 } | |
1455 | |
1456 color_symbols = extract_xpm_color_names (&xpmattrs, device, domain, | |
1457 color_symbol_alist); | |
1458 | |
771 | 1459 { |
1460 Extbyte *dataext; | |
1461 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1462 dataext = LISP_STRING_TO_EXTERNAL (data, Qctext); |
771 | 1463 |
1464 result = | |
1465 XpmCreatePixmapFromBuffer (dpy, | |
1466 XtWindow | |
1467 (DEVICE_XT_APP_SHELL (XDEVICE(device))), | |
1468 dataext, &pixmap, &mask, &xpmattrs); | |
1469 } | |
428 | 1470 |
1471 if (color_symbols) | |
1472 { | |
771 | 1473 int i; |
1474 | |
1475 for (i = 0; i < (int) xpmattrs.numsymbols; i++) | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1476 xfree (color_symbols[i].name); |
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1477 xfree (color_symbols); |
428 | 1478 xpmattrs.colorsymbols = 0; /* in case XpmFreeAttr is too smart... */ |
1479 xpmattrs.numsymbols = 0; | |
1480 } | |
1481 | |
1482 switch (result) | |
1483 { | |
1484 case XpmSuccess: | |
1485 break; | |
1486 case XpmFileInvalid: | |
1487 { | |
1488 xpm_free (&xpmattrs); | |
1489 signal_image_error ("invalid XPM data", data); | |
1490 } | |
1491 case XpmColorFailed: | |
1492 case XpmColorError: | |
1493 { | |
1494 xpm_free (&xpmattrs); | |
1495 if (force_mono) | |
1496 { | |
1497 /* second time; blow out. */ | |
563 | 1498 gui_error ("XPM color allocation failed", data); |
428 | 1499 } |
1500 else | |
1501 { | |
563 | 1502 /* second time; blow out. */ |
428 | 1503 if (! (dest_mask & IMAGE_MONO_PIXMAP_MASK)) |
563 | 1504 gui_error ("XPM color allocation failed", data); |
428 | 1505 force_mono = 1; |
1506 IMAGE_INSTANCE_TYPE (ii) = IMAGE_MONO_PIXMAP; | |
1507 goto retry; | |
1508 } | |
1509 } | |
1510 case XpmNoMemory: | |
1511 { | |
1512 xpm_free (&xpmattrs); | |
563 | 1513 out_of_memory ("Parsing pixmap data", data); |
428 | 1514 } |
1515 default: | |
1516 { | |
1517 xpm_free (&xpmattrs); | |
563 | 1518 signal_error_2 (Qgui_error, |
1519 "Parsing pixmap data: unknown error code", | |
1520 make_int (result), data); | |
428 | 1521 } |
1522 } | |
1523 | |
1524 w = xpmattrs.width; | |
1525 h = xpmattrs.height; | |
1526 | |
1527 { | |
1528 int npixels = xpmattrs.npixels; | |
1529 Pixel *pixels; | |
1530 | |
1531 if (npixels != 0) | |
1532 { | |
1533 pixels = xnew_array (Pixel, npixels); | |
1534 memcpy (pixels, xpmattrs.pixels, npixels * sizeof (Pixel)); | |
1535 } | |
1536 else | |
1537 pixels = NULL; | |
1538 | |
1539 IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap; | |
1540 IMAGE_INSTANCE_PIXMAP_MASK (ii) = (void*)mask; | |
1541 IMAGE_INSTANCE_X_COLORMAP (ii) = cmap; | |
1542 IMAGE_INSTANCE_X_PIXELS (ii) = pixels; | |
1543 IMAGE_INSTANCE_X_NPIXELS (ii) = npixels; | |
1544 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = w; | |
1545 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = h; | |
1546 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
1547 find_keyword_in_vector (instantiator, Q_file); | |
1548 } | |
1549 | |
1550 switch (type) | |
1551 { | |
1552 case IMAGE_MONO_PIXMAP: | |
1553 break; | |
1554 | |
1555 case IMAGE_COLOR_PIXMAP: | |
2959 | 1556 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth; |
428 | 1557 break; |
1558 | |
1559 case IMAGE_POINTER: | |
2959 | 1560 if (xpmattrs.valuemask & XpmHotspot) |
1561 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (xpmattrs.x_hotspot); | |
1562 if (xpmattrs.valuemask & XpmHotspot) | |
1563 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (xpmattrs.y_hotspot); | |
4252 | 1564 |
2959 | 1565 image_instance_convert_to_pointer (ii, instantiator, pointer_fg, |
1566 pointer_bg); | |
428 | 1567 break; |
1568 | |
1569 default: | |
2500 | 1570 ABORT (); |
428 | 1571 } |
1572 | |
1573 xpm_free (&xpmattrs); /* after we've read pixels and hotspot */ | |
1574 } | |
1575 | |
1576 #endif /* HAVE_XPM */ | |
1577 | |
1578 | |
1579 #ifdef HAVE_XFACE | |
1580 | |
1581 /********************************************************************** | |
1582 * X-Face * | |
1583 **********************************************************************/ | |
1584 #if defined(EXTERN) | |
1585 /* This is about to get redefined! */ | |
1586 #undef EXTERN | |
1587 #endif | |
1588 /* We have to define SYSV32 so that compface.h includes string.h | |
1589 instead of strings.h. */ | |
1590 #define SYSV32 | |
1743 | 1591 BEGIN_C_DECLS |
428 | 1592 #include <compface.h> |
1743 | 1593 END_C_DECLS |
1594 | |
428 | 1595 /* JMP_BUF cannot be used here because if it doesn't get defined |
1596 to jmp_buf we end up with a conflicting type error with the | |
1597 definition in compface.h */ | |
1598 extern jmp_buf comp_env; | |
1599 #undef SYSV32 | |
1600 | |
1601 static void | |
1602 x_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1603 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1604 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1605 { |
1606 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1607 int i, stattis; | |
2367 | 1608 Binbyte *p, *bits, *bp; |
867 | 1609 const CIbyte * volatile emsg = 0; |
2367 | 1610 const Binbyte * volatile dstring; |
428 | 1611 |
1612 assert (!NILP (data)); | |
1613 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1614 dstring = (const Binbyte *) LISP_STRING_TO_EXTERNAL (data, Qbinary); |
853 | 1615 |
2367 | 1616 if ((p = (Binbyte *) strchr ((char *) dstring, ':'))) |
428 | 1617 { |
1618 dstring = p + 1; | |
1619 } | |
1620 | |
1621 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */ | |
1622 if (!(stattis = setjmp (comp_env))) | |
1623 { | |
853 | 1624 UnCompAll ((char *) dstring); |
428 | 1625 UnGenFace (); |
1626 } | |
1627 | |
1628 switch (stattis) | |
1629 { | |
1630 case -2: | |
1631 emsg = "uncompface: internal error"; | |
1632 break; | |
1633 case -1: | |
1634 emsg = "uncompface: insufficient or invalid data"; | |
1635 break; | |
1636 case 1: | |
1637 emsg = "uncompface: excess data ignored"; | |
1638 break; | |
1639 } | |
1640 | |
1641 if (emsg) | |
853 | 1642 signal_image_error_2 (emsg, data, Qimage); |
1643 | |
2367 | 1644 bp = bits = alloca_binbytes (PIXELS / 8); |
428 | 1645 |
1646 /* the compface library exports char F[], which uses a single byte per | |
1647 pixel to represent a 48x48 bitmap. Yuck. */ | |
2367 | 1648 for (i = 0, p = (Binbyte *) F; i < (PIXELS / 8); ++i) |
428 | 1649 { |
1650 int n, b; | |
1651 /* reverse the bit order of each byte... */ | |
1652 for (b = n = 0; b < 8; ++b) | |
1653 { | |
1654 n |= ((*p++) << b); | |
1655 } | |
2367 | 1656 *bp++ = (Binbyte) n; |
428 | 1657 } |
1658 | |
1659 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, | |
2367 | 1660 pointer_bg, dest_mask, 48, 48, (CBinbyte *) bits); |
428 | 1661 } |
1662 | |
1663 #endif /* HAVE_XFACE */ | |
1664 | |
1665 | |
1666 /********************************************************************** | |
1667 * Autodetect * | |
1668 **********************************************************************/ | |
1669 | |
1670 static void | |
1671 autodetect_validate (Lisp_Object instantiator) | |
1672 { | |
1673 data_must_be_present (instantiator); | |
1674 } | |
1675 | |
1676 static Lisp_Object | |
1677 autodetect_normalize (Lisp_Object instantiator, | |
442 | 1678 Lisp_Object console_type, |
2286 | 1679 Lisp_Object UNUSED (dest_mask)) |
428 | 1680 { |
1681 Lisp_Object file = find_keyword_in_vector (instantiator, Q_data); | |
1682 Lisp_Object filename = Qnil; | |
1683 Lisp_Object data = Qnil; | |
1684 struct gcpro gcpro1, gcpro2, gcpro3; | |
1685 Lisp_Object alist = Qnil; | |
1686 | |
1687 GCPRO3 (filename, data, alist); | |
1688 | |
1689 if (NILP (file)) /* no conversion necessary */ | |
1690 RETURN_UNGCPRO (instantiator); | |
1691 | |
1692 alist = tagged_vector_to_alist (instantiator); | |
1693 | |
1694 filename = locate_pixmap_file (file); | |
1695 if (!NILP (filename)) | |
1696 { | |
1697 int xhot, yhot; | |
1698 /* #### Apparently some versions of XpmReadFileToData, which is | |
1699 called by pixmap_to_lisp_data, don't return an error value | |
1700 if the given file is not a valid XPM file. Instead, they | |
1701 just seg fault. It is definitely caused by passing a | |
1702 bitmap. To try and avoid this we check for bitmaps first. */ | |
1703 | |
1704 data = bitmap_to_lisp_data (filename, &xhot, &yhot, 1); | |
1705 | |
1706 if (!EQ (data, Qt)) | |
1707 { | |
1708 alist = remassq_no_quit (Q_data, alist); | |
1709 alist = Fcons (Fcons (Q_file, filename), | |
1710 Fcons (Fcons (Q_data, data), alist)); | |
1711 if (xhot != -1) | |
1712 alist = Fcons (Fcons (Q_hotspot_x, make_int (xhot)), | |
1713 alist); | |
1714 if (yhot != -1) | |
1715 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)), | |
1716 alist); | |
1717 | |
4252 | 1718 alist = xbm_mask_file_munging (alist, filename, Qt, console_type); |
428 | 1719 |
1720 { | |
1721 Lisp_Object result = alist_to_tagged_vector (Qxbm, alist); | |
1722 free_alist (alist); | |
1723 RETURN_UNGCPRO (result); | |
1724 } | |
1725 } | |
1726 | |
1727 #ifdef HAVE_XPM | |
1728 data = pixmap_to_lisp_data (filename, 1); | |
1729 | |
1730 if (!EQ (data, Qt)) | |
1731 { | |
1732 alist = remassq_no_quit (Q_data, alist); | |
1733 alist = Fcons (Fcons (Q_file, filename), | |
1734 Fcons (Fcons (Q_data, data), alist)); | |
1735 alist = Fcons (Fcons (Q_color_symbols, | |
1736 evaluate_xpm_color_symbols ()), | |
1737 alist); | |
1738 { | |
1739 Lisp_Object result = alist_to_tagged_vector (Qxpm, alist); | |
1740 free_alist (alist); | |
1741 RETURN_UNGCPRO (result); | |
1742 } | |
1743 } | |
1744 #endif | |
1745 } | |
1746 | |
1747 /* If we couldn't convert it, just put it back as it is. | |
1748 We might try to further frob it later as a cursor-font | |
1749 specification. (We can't do that now because we don't know | |
1750 what dest-types it's going to be instantiated into.) */ | |
1751 { | |
1752 Lisp_Object result = alist_to_tagged_vector (Qautodetect, alist); | |
1753 free_alist (alist); | |
1754 RETURN_UNGCPRO (result); | |
1755 } | |
1756 } | |
1757 | |
1758 static int | |
1759 autodetect_possible_dest_types (void) | |
1760 { | |
1761 return | |
1762 IMAGE_MONO_PIXMAP_MASK | | |
1763 IMAGE_COLOR_PIXMAP_MASK | | |
1764 IMAGE_POINTER_MASK | | |
1765 IMAGE_TEXT_MASK; | |
1766 } | |
1767 | |
1768 static void | |
1769 autodetect_instantiate (Lisp_Object image_instance, | |
438 | 1770 Lisp_Object instantiator, |
1771 Lisp_Object pointer_fg, | |
1772 Lisp_Object pointer_bg, | |
1773 int dest_mask, Lisp_Object domain) | |
428 | 1774 { |
1775 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1776 struct gcpro gcpro1, gcpro2, gcpro3; | |
1777 Lisp_Object alist = Qnil; | |
1778 Lisp_Object result = Qnil; | |
1779 int is_cursor_font = 0; | |
1780 | |
1781 GCPRO3 (data, alist, result); | |
1782 | |
1783 alist = tagged_vector_to_alist (instantiator); | |
1784 if (dest_mask & IMAGE_POINTER_MASK) | |
1785 { | |
442 | 1786 const char *name_ext; |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1787 LISP_PATHNAME_CONVERT_OUT (data, name_ext); |
428 | 1788 if (XmuCursorNameToIndex (name_ext) != -1) |
4252 | 1789 { |
1790 result = alist_to_tagged_vector (Qcursor_font, alist); | |
1791 is_cursor_font = 1; | |
1792 } | |
428 | 1793 } |
1794 | |
1795 if (!is_cursor_font) | |
1796 result = alist_to_tagged_vector (Qstring, alist); | |
1797 free_alist (alist); | |
1798 | |
1799 if (is_cursor_font) | |
1800 cursor_font_instantiate (image_instance, result, pointer_fg, | |
1801 pointer_bg, dest_mask, domain); | |
1802 else | |
1803 string_instantiate (image_instance, result, pointer_fg, | |
1804 pointer_bg, dest_mask, domain); | |
1805 | |
1806 UNGCPRO; | |
1807 } | |
1808 | |
1809 | |
1810 /********************************************************************** | |
1811 * Font * | |
1812 **********************************************************************/ | |
1813 | |
1814 static void | |
1815 font_validate (Lisp_Object instantiator) | |
1816 { | |
1817 data_must_be_present (instantiator); | |
1818 } | |
1819 | |
1820 /* XmuCvtStringToCursor is bogus in the following ways: | |
1821 | |
1822 - When it can't convert the given string to a real cursor, it will | |
1823 sometimes return a "success" value, after triggering a BadPixmap | |
1824 error. It then gives you a cursor that will itself generate BadCursor | |
1825 errors. So we install this error handler to catch/notice the X error | |
1826 and take that as meaning "couldn't convert." | |
1827 | |
1828 - When you tell it to find a cursor file that doesn't exist, it prints | |
1829 an error message on stderr. You can't make it not do that. | |
1830 | |
1831 - Also, using Xmu means we can't properly hack Lisp_Image_Instance | |
1832 objects, or XPM files, or $XBMLANGPATH. | |
1833 */ | |
1834 | |
1835 /* Duplicate the behavior of XmuCvtStringToCursor() to bypass its bogusness. */ | |
1836 | |
1837 static int XLoadFont_got_error; | |
1838 | |
1839 static int | |
2286 | 1840 XLoadFont_error_handler (Display *UNUSED (dpy), XErrorEvent *UNUSED (xerror)) |
428 | 1841 { |
1842 XLoadFont_got_error = 1; | |
1843 return 0; | |
1844 } | |
1845 | |
1846 static Font | |
867 | 1847 safe_XLoadFont (Display *dpy, Ibyte *name) |
428 | 1848 { |
1849 Font font; | |
1850 int (*old_handler) (Display *, XErrorEvent *); | |
771 | 1851 |
428 | 1852 XLoadFont_got_error = 0; |
1853 XSync (dpy, 0); | |
1854 old_handler = XSetErrorHandler (XLoadFont_error_handler); | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1855 font = XLoadFont (dpy, ITEXT_TO_EXTERNAL (name, Qfile_name)); |
428 | 1856 XSync (dpy, 0); |
1857 XSetErrorHandler (old_handler); | |
1858 if (XLoadFont_got_error) return 0; | |
1859 return font; | |
1860 } | |
1861 | |
1862 static int | |
1863 font_possible_dest_types (void) | |
1864 { | |
1865 return IMAGE_POINTER_MASK; | |
1866 } | |
1867 | |
1868 static void | |
1869 font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1870 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1871 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1872 { |
1873 /* This function can GC */ | |
1874 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
440 | 1875 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1876 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1877 Display *dpy; | |
1878 XColor fg, bg; | |
1879 Font source, mask; | |
2421 | 1880 Ibyte source_name[PATH_MAX_INTERNAL], mask_name[PATH_MAX_INTERNAL], dummy; |
428 | 1881 int source_char, mask_char; |
1882 int count; | |
1883 Lisp_Object foreground, background; | |
1884 | |
1885 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 1886 gui_error ("Not an X device", device); |
428 | 1887 |
1888 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
1889 | |
1890 if (!STRINGP (data) || | |
1891 strncmp ("FONT ", (char *) XSTRING_DATA (data), 5)) | |
563 | 1892 invalid_argument ("Invalid font-glyph instantiator", |
428 | 1893 instantiator); |
1894 | |
1895 if (!(dest_mask & IMAGE_POINTER_MASK)) | |
1896 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK); | |
1897 | |
1898 foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1899 if (NILP (foreground)) | |
1900 foreground = pointer_fg; | |
1901 background = find_keyword_in_vector (instantiator, Q_background); | |
1902 if (NILP (background)) | |
1903 background = pointer_bg; | |
1904 | |
1905 generate_cursor_fg_bg (device, &foreground, &background, &fg, &bg); | |
1906 | |
1907 count = sscanf ((char *) XSTRING_DATA (data), | |
1908 "FONT %s %d %s %d %c", | |
1909 source_name, &source_char, | |
1910 mask_name, &mask_char, &dummy); | |
1911 /* Allow "%s %d %d" as well... */ | |
771 | 1912 if (count == 3 && (1 == sscanf ((char *) mask_name, "%d %c", &mask_char, |
1913 &dummy))) | |
428 | 1914 count = 4, mask_name[0] = 0; |
1915 | |
1916 if (count != 2 && count != 4) | |
563 | 1917 syntax_error ("invalid cursor specification", data); |
428 | 1918 source = safe_XLoadFont (dpy, source_name); |
1919 if (! source) | |
563 | 1920 signal_error_2 (Qgui_error, |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1921 "couldn't load font", build_istring (source_name), data); |
428 | 1922 if (count == 2) |
1923 mask = 0; | |
1924 else if (!mask_name[0]) | |
1925 mask = source; | |
1926 else | |
1927 { | |
1928 mask = safe_XLoadFont (dpy, mask_name); | |
1929 if (!mask) | |
563 | 1930 signal_continuable_error_2 (Qgui_error, |
1931 "couldn't load font", | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1932 build_istring (mask_name), data); |
428 | 1933 } |
1934 if (!mask) | |
1935 mask_char = 0; | |
1936 | |
1937 /* #### call XQueryTextExtents() and check_pointer_sizes() here. */ | |
1938 | |
1939 x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); | |
1940 IMAGE_INSTANCE_X_CURSOR (ii) = | |
1941 XCreateGlyphCursor (dpy, source, mask, source_char, mask_char, | |
1942 &fg, &bg); | |
1943 XIMAGE_INSTANCE_PIXMAP_FG (image_instance) = foreground; | |
1944 XIMAGE_INSTANCE_PIXMAP_BG (image_instance) = background; | |
1945 XUnloadFont (dpy, source); | |
1946 if (mask && mask != source) XUnloadFont (dpy, mask); | |
1947 } | |
1948 | |
1949 | |
1950 /********************************************************************** | |
1951 * Cursor-Font * | |
1952 **********************************************************************/ | |
1953 | |
1954 static void | |
1955 cursor_font_validate (Lisp_Object instantiator) | |
1956 { | |
1957 data_must_be_present (instantiator); | |
1958 } | |
1959 | |
1960 static int | |
1961 cursor_font_possible_dest_types (void) | |
1962 { | |
1963 return IMAGE_POINTER_MASK; | |
1964 } | |
1965 | |
1966 static void | |
1967 cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1968 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1969 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1970 { |
1971 /* This function can GC */ | |
1972 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
440 | 1973 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1974 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1975 Display *dpy; | |
1976 int i; | |
771 | 1977 const Extbyte *name_ext; |
428 | 1978 Lisp_Object foreground, background; |
1979 | |
1980 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 1981 gui_error ("Not an X device", device); |
428 | 1982 |
1983 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
1984 | |
1985 if (!(dest_mask & IMAGE_POINTER_MASK)) | |
1986 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK); | |
1987 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1988 LISP_PATHNAME_CONVERT_OUT (data, name_ext); |
428 | 1989 if ((i = XmuCursorNameToIndex (name_ext)) == -1) |
563 | 1990 invalid_argument ("Unrecognized cursor-font name", data); |
428 | 1991 |
1992 x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); | |
1993 IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i); | |
1994 foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1995 if (NILP (foreground)) | |
1996 foreground = pointer_fg; | |
1997 background = find_keyword_in_vector (instantiator, Q_background); | |
1998 if (NILP (background)) | |
1999 background = pointer_bg; | |
2000 maybe_recolor_cursor (image_instance, foreground, background); | |
2001 } | |
2002 | |
2003 static int | |
2004 x_colorize_image_instance (Lisp_Object image_instance, | |
2005 Lisp_Object foreground, Lisp_Object background) | |
2006 { | |
440 | 2007 Lisp_Image_Instance *p; |
428 | 2008 |
2009 p = XIMAGE_INSTANCE (image_instance); | |
2010 | |
2011 switch (IMAGE_INSTANCE_TYPE (p)) | |
2012 { | |
2013 case IMAGE_MONO_PIXMAP: | |
2014 IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP; | |
2015 /* Make sure there aren't two pointers to the same mask, causing | |
2016 it to get freed twice. */ | |
2017 IMAGE_INSTANCE_PIXMAP_MASK (p) = 0; | |
2018 break; | |
2019 | |
2020 default: | |
2021 return 0; | |
2022 } | |
2023 | |
2024 { | |
2025 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (IMAGE_INSTANCE_DEVICE (p))); | |
2026 Drawable draw = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))); | |
2027 Dimension d = DEVICE_X_DEPTH (XDEVICE (IMAGE_INSTANCE_DEVICE (p))); | |
2959 | 2028 Pixmap new_ = XCreatePixmap (dpy, draw, |
428 | 2029 IMAGE_INSTANCE_PIXMAP_WIDTH (p), |
2030 IMAGE_INSTANCE_PIXMAP_HEIGHT (p), d); | |
2031 XColor color; | |
2032 XGCValues gcv; | |
2033 GC gc; | |
2034 color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (foreground)); | |
2035 gcv.foreground = color.pixel; | |
2036 color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (background)); | |
2037 gcv.background = color.pixel; | |
2959 | 2038 gc = XCreateGC (dpy, new_, GCBackground|GCForeground, &gcv); |
2039 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), new_, gc, 0, 0, | |
428 | 2040 IMAGE_INSTANCE_PIXMAP_WIDTH (p), |
2041 IMAGE_INSTANCE_PIXMAP_HEIGHT (p), | |
2042 0, 0, 1); | |
2043 XFreeGC (dpy, gc); | |
2959 | 2044 IMAGE_INSTANCE_X_PIXMAP (p) = new_; |
428 | 2045 IMAGE_INSTANCE_PIXMAP_DEPTH (p) = d; |
2046 IMAGE_INSTANCE_PIXMAP_FG (p) = foreground; | |
2047 IMAGE_INSTANCE_PIXMAP_BG (p) = background; | |
2048 return 1; | |
2049 } | |
2050 } | |
2051 | |
2052 | |
2053 /************************************************************************/ | |
2054 /* subwindow and widget support */ | |
2055 /************************************************************************/ | |
2056 | |
2057 /* unmap the image if it is a widget. This is used by redisplay via | |
2058 redisplay_unmap_subwindows */ | |
2059 static void | |
440 | 2060 x_unmap_subwindow (Lisp_Image_Instance *p) |
428 | 2061 { |
2062 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) | |
2063 { | |
438 | 2064 XUnmapWindow |
2065 (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
428 | 2066 IMAGE_INSTANCE_X_CLIPWINDOW (p)); |
914 | 2067 XUnmapSubwindows |
2068 (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2069 IMAGE_INSTANCE_X_CLIPWINDOW (p)); | |
428 | 2070 } |
2071 else /* must be a widget */ | |
2072 { | |
450 | 2073 /* Since we are being unmapped we want the enclosing frame to |
2074 get focus. The losing with simple scrolling but is the safest | |
2075 thing to do. */ | |
4252 | 2076 emacs_Xt_handle_widget_losing_focus |
450 | 2077 ( XFRAME (IMAGE_INSTANCE_FRAME (p)), |
2078 IMAGE_INSTANCE_X_WIDGET_ID (p)); | |
428 | 2079 XtUnmapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); |
2080 } | |
2081 } | |
2082 | |
2083 /* map the subwindow. This is used by redisplay via | |
2084 redisplay_output_subwindow */ | |
2085 static void | |
440 | 2086 x_map_subwindow (Lisp_Image_Instance *p, int x, int y, |
428 | 2087 struct display_glyph_area* dga) |
2088 { | |
448 | 2089 assert (dga->width > 0 && dga->height > 0); |
428 | 2090 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) |
2091 { | |
2092 Window subwindow = IMAGE_INSTANCE_X_SUBWINDOW_ID (p); | |
2093 XMoveResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
438 | 2094 IMAGE_INSTANCE_X_CLIPWINDOW (p), |
428 | 2095 x, y, dga->width, dga->height); |
2096 XMoveWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2097 subwindow, -dga->xoffset, -dga->yoffset); | |
442 | 2098 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) |
914 | 2099 { |
2100 XMapWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2101 IMAGE_INSTANCE_X_CLIPWINDOW (p)); | |
2102 XMapSubwindows (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2103 IMAGE_INSTANCE_X_CLIPWINDOW (p)); | |
2104 } | |
428 | 2105 } |
2106 else /* must be a widget */ | |
2107 { | |
438 | 2108 XtConfigureWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p), |
428 | 2109 x + IMAGE_INSTANCE_X_WIDGET_XOFFSET (p), |
2110 y + IMAGE_INSTANCE_X_WIDGET_YOFFSET (p), | |
2111 dga->width, dga->height, 0); | |
2112 XtMoveWidget (IMAGE_INSTANCE_X_WIDGET_ID (p), | |
2113 -dga->xoffset, -dga->yoffset); | |
442 | 2114 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) |
2115 XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); | |
863 | 2116 /* See comments in glyphs-msw.c about keyboard focus. */ |
1111 | 2117 if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (p)) |
2118 { | |
2119 /* #### FIXME to pop-up the find dialog we map the text-field | |
2120 seven times! This doesn't show on a fast linux box but does | |
2121 under X on windows. */ | |
2122 emacs_Xt_enqueue_focus_event (IMAGE_INSTANCE_X_WIDGET_ID (p), | |
2123 IMAGE_INSTANCE_FRAME (p), 1); | |
2124 } | |
428 | 2125 } |
2126 } | |
2127 | |
2128 /* when you click on a widget you may activate another widget this | |
2129 needs to be checked and all appropriate widgets updated */ | |
2130 static void | |
442 | 2131 x_redisplay_subwindow (Lisp_Image_Instance *p) |
2132 { | |
2133 /* Update the subwindow size if necessary. */ | |
2134 if (IMAGE_INSTANCE_SIZE_CHANGED (p)) | |
2135 { | |
2136 XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2137 IMAGE_INSTANCE_X_SUBWINDOW_ID (p), | |
2138 IMAGE_INSTANCE_WIDTH (p), | |
2139 IMAGE_INSTANCE_HEIGHT (p)); | |
2140 } | |
2141 } | |
2142 | |
2143 /* Update all attributes that have changed. Lwlib actually does most | |
2144 of this for us. */ | |
2145 static void | |
2146 x_redisplay_widget (Lisp_Image_Instance *p) | |
428 | 2147 { |
442 | 2148 /* This function can GC if IN_REDISPLAY is false. */ |
771 | 2149 #ifdef HAVE_X_WIDGETS |
442 | 2150 widget_value* wv = 0; |
2151 | |
2152 /* First get the items if they have changed since this is a | |
2153 structural change. As such it will nuke all added values so we | |
2154 need to update most other things after the items have changed.*/ | |
2155 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
2156 { | |
793 | 2157 Lisp_Object image_instance = wrap_image_instance (p); |
2158 | |
442 | 2159 wv = gui_items_to_widget_values |
2160 (image_instance, IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p), | |
2161 /* #### this is not right; we need to keep track of which widgets | |
2162 want accelerators and which don't */ 0); | |
2163 wv->change = STRUCTURAL_CHANGE; | |
2164 } | |
2165 else | |
428 | 2166 { |
442 | 2167 /* Assume the lotus position, breath deeply and chant to |
2168 yourself lwlibsux, lwlibsux ... lw_get_all_values returns a | |
2169 reference to the real values rather than a copy thus any | |
2170 changes we make to the values we get back will look like they | |
2171 have already been applied. If we rebuild the widget tree then | |
444 | 2172 we may lose properties. */ |
4252 | 2173 wv = copy_widget_value_tree (lw_get_all_values |
442 | 2174 (IMAGE_INSTANCE_X_WIDGET_LWID (p)), |
2175 NO_CHANGE); | |
2176 } | |
2177 | |
2178 /* Possibly update the colors and font */ | |
2179 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) | |
2180 || | |
454 | 2181 /* #### This is not sufficient because it will not cope with widgets |
2182 that are not currently visible. Once redisplay has done the | |
2183 visible ones it will clear this flag so that when new ones | |
2184 become visible they will not be updated. */ | |
442 | 2185 XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed |
2186 || | |
454 | 2187 XFRAME (IMAGE_INSTANCE_FRAME (p))->frame_changed |
2188 || | |
442 | 2189 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) |
2190 { | |
2191 update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p)); | |
2192 } | |
2193 | |
2194 /* Possibly update the text. */ | |
2195 if (IMAGE_INSTANCE_TEXT_CHANGED (p)) | |
2196 { | |
771 | 2197 Extbyte* str; |
442 | 2198 Lisp_Object val = IMAGE_INSTANCE_WIDGET_TEXT (p); |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2199 str = LISP_STRING_TO_EXTERNAL (val, Qlwlib_encoding); |
442 | 2200 wv->value = str; |
2201 } | |
2202 | |
2203 /* Possibly update the size. */ | |
2204 if (IMAGE_INSTANCE_SIZE_CHANGED (p) | |
2205 || | |
2206 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p) | |
2207 || | |
2208 IMAGE_INSTANCE_TEXT_CHANGED (p)) | |
2209 { | |
2210 assert (IMAGE_INSTANCE_X_WIDGET_ID (p) && | |
2211 IMAGE_INSTANCE_X_CLIPWIDGET (p)) ; | |
2212 | |
2213 if (IMAGE_INSTANCE_X_WIDGET_ID (p)->core.being_destroyed | |
2214 || !XtIsManaged(IMAGE_INSTANCE_X_WIDGET_ID (p))) | |
428 | 2215 { |
793 | 2216 Lisp_Object sw = wrap_image_instance (p); |
2217 | |
563 | 2218 signal_error (Qinternal_error, |
2219 "XEmacs bug: subwindow is deleted", sw); | |
434 | 2220 } |
442 | 2221 |
2222 lw_add_widget_value_arg (wv, XtNwidth, | |
2223 (Dimension)IMAGE_INSTANCE_WIDTH (p)); | |
2224 lw_add_widget_value_arg (wv, XtNheight, | |
2225 (Dimension)IMAGE_INSTANCE_HEIGHT (p)); | |
428 | 2226 } |
442 | 2227 |
448 | 2228 /* Adjust offsets within the frame. */ |
450 | 2229 if (XFRAME (IMAGE_INSTANCE_FRAME (p))->size_changed) |
448 | 2230 { |
2231 Arg al[2]; | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2232 Xt_SET_ARG (al [0], XtNx, &IMAGE_INSTANCE_X_WIDGET_XOFFSET (p)); |
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2233 Xt_SET_ARG (al [1], XtNy, &IMAGE_INSTANCE_X_WIDGET_YOFFSET (p)); |
4252 | 2234 XtGetValues (FRAME_X_TEXT_WIDGET |
448 | 2235 (XFRAME (IMAGE_INSTANCE_FRAME (p))), al, 2); |
2236 } | |
2237 | |
442 | 2238 /* now modify the widget */ |
1346 | 2239 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), wv, True); |
442 | 2240 free_widget_value_tree (wv); |
1346 | 2241 gcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p)); |
428 | 2242 #endif |
2243 } | |
2244 | |
2245 /* instantiate and x type subwindow */ | |
2246 static void | |
2286 | 2247 x_subwindow_instantiate (Lisp_Object image_instance, |
2248 Lisp_Object UNUSED (instantiator), | |
2249 Lisp_Object UNUSED (pointer_fg), | |
2250 Lisp_Object UNUSED (pointer_bg), | |
2251 int UNUSED (dest_mask), Lisp_Object domain) | |
428 | 2252 { |
2253 /* This function can GC */ | |
440 | 2254 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2255 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
442 | 2256 Lisp_Object frame = DOMAIN_FRAME (domain); |
428 | 2257 struct frame* f = XFRAME (frame); |
2258 Display *dpy; | |
2259 Screen *xs; | |
2260 Window pw, win; | |
2261 XSetWindowAttributes xswa; | |
2262 Mask valueMask = 0; | |
647 | 2263 int w = IMAGE_INSTANCE_WIDTH (ii), h = IMAGE_INSTANCE_HEIGHT (ii); |
428 | 2264 |
2265 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 2266 gui_error ("Not an X device", device); |
428 | 2267 |
2268 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
2269 xs = DefaultScreenOfDisplay (dpy); | |
2270 | |
2271 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW; | |
2272 | |
2273 pw = XtWindow (FRAME_X_TEXT_WIDGET (f)); | |
2274 | |
2275 ii->data = xnew_and_zero (struct x_subwindow_data); | |
2276 | |
2277 IMAGE_INSTANCE_X_SUBWINDOW_PARENT (ii) = pw; | |
2278 IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii) = DisplayOfScreen (xs); | |
2279 | |
2280 xswa.backing_store = Always; | |
2281 valueMask |= CWBackingStore; | |
2282 xswa.colormap = DefaultColormapOfScreen (xs); | |
2283 valueMask |= CWColormap; | |
438 | 2284 |
428 | 2285 /* Create a window for clipping */ |
438 | 2286 IMAGE_INSTANCE_X_CLIPWINDOW (ii) = |
428 | 2287 XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent, |
2288 InputOutput, CopyFromParent, valueMask, | |
2289 &xswa); | |
2290 | |
2291 /* Now put the subwindow inside the clip window. */ | |
2292 win = XCreateWindow (dpy, IMAGE_INSTANCE_X_CLIPWINDOW (ii), | |
2293 0, 0, w, h, 0, CopyFromParent, | |
2294 InputOutput, CopyFromParent, valueMask, | |
2295 &xswa); | |
438 | 2296 |
428 | 2297 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win; |
2298 } | |
2299 | |
863 | 2300 /* Account for some of the limitations with widget images. */ |
2301 static int | |
2302 x_widget_border_width (void) | |
2303 { | |
2304 return DEFAULT_WIDGET_BORDER_WIDTH * 2; | |
2305 } | |
2306 | |
2307 | |
428 | 2308 #if 0 |
2309 /* #### Should this function exist? If there's any doubt I'm not implementing it --andyp */ | |
2310 DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /* | |
2311 For the given SUBWINDOW, set PROPERTY to DATA, which is a string. | |
2312 Subwindows are not currently implemented. | |
2313 */ | |
2314 (subwindow, property, data)) | |
2315 { | |
2316 Atom property_atom; | |
440 | 2317 Lisp_Subwindow *sw; |
428 | 2318 Display *dpy; |
771 | 2319 Extbyte *propext, *dataext; |
2320 Bytecount datalen; | |
428 | 2321 |
2322 CHECK_SUBWINDOW (subwindow); | |
2323 CHECK_STRING (property); | |
2324 CHECK_STRING (data); | |
2325 | |
2326 sw = XSUBWINDOW (subwindow); | |
2327 dpy = DisplayOfScreen (LISP_DEVICE_TO_X_SCREEN | |
2328 (FRAME_DEVICE (XFRAME (sw->frame)))); | |
2329 | |
771 | 2330 LISP_TO_EXTERNAL (property, propext, Qctext); |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2331 LISP_STRING_TO_SIZED_EXTERNAL (data, dataext, datalen, Qctext); |
771 | 2332 property_atom = XInternAtom (dpy, propext, False); |
428 | 2333 XChangeProperty (dpy, sw->subwindow, property_atom, XA_STRING, 8, |
771 | 2334 PropModeReplace, dataext, datalen); |
428 | 2335 return property; |
2336 } | |
2337 #endif | |
2338 | |
2339 | |
771 | 2340 #ifdef HAVE_X_WIDGETS |
428 | 2341 |
2342 /************************************************************************/ | |
2343 /* widgets */ | |
2344 /************************************************************************/ | |
2345 | |
2346 static void | |
440 | 2347 update_widget_face (widget_value* wv, Lisp_Image_Instance *ii, |
434 | 2348 Lisp_Object domain) |
428 | 2349 { |
2350 #ifdef LWLIB_WIDGETS_MOTIF | |
2351 XmFontList fontList; | |
2352 #endif | |
438 | 2353 /* Update the foreground. */ |
2354 Lisp_Object pixel = FACE_FOREGROUND | |
428 | 2355 (IMAGE_INSTANCE_WIDGET_FACE (ii), |
434 | 2356 domain); |
438 | 2357 XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)), bcolor; |
434 | 2358 lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel); |
438 | 2359 |
2360 /* Update the background. */ | |
2361 pixel = FACE_BACKGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), | |
2362 domain); | |
2363 bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); | |
2364 lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel); | |
2365 | |
3094 | 2366 { |
2367 Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (ii); | |
2368 Lisp_Font_Instance *fi = | |
2369 XFONT_INSTANCE (query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
2370 face, | |
2371 domain)); | |
2372 XFontStruct *fs = FONT_INSTANCE_X_FONT (fi); | |
4916
a6c778975d7d
split USE_XFT into HAVE_XFT/USE_XFT
Ben Wing <ben@xemacs.org>
parents:
4834
diff
changeset
|
2373 #ifdef HAVE_XFT |
3094 | 2374 XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi); |
2375 | |
2376 if (rf) | |
2377 { | |
2378 /* #### What to do about Motif? */ | |
4932 | 2379 lw_add_widget_value_arg (wv, (String) XtNxftFont, (XtArgVal) rf); |
3094 | 2380 } |
2381 #endif | |
2382 | |
2383 if (fs) | |
2384 { | |
428 | 2385 #ifdef LWLIB_WIDGETS_MOTIF |
3094 | 2386 fontList = XmFontListCreate (fs, XmSTRING_DEFAULT_CHARSET); |
2387 lw_add_widget_value_arg (wv, XmNfontList, (XtArgVal) fontList); | |
428 | 2388 #endif |
3094 | 2389 lw_add_widget_value_arg (wv, XtNfont, (XtArgVal) fs); |
2390 } | |
2391 | |
4916
a6c778975d7d
split USE_XFT into HAVE_XFT/USE_XFT
Ben Wing <ben@xemacs.org>
parents:
4834
diff
changeset
|
2392 #ifdef HAVE_XFT |
3094 | 2393 /* #### sanity check, should wrap in appropriate ERROR_CHECK macro */ |
2394 if (!rf && !fs) | |
2395 warn_when_safe_lispobj | |
2396 (intern ("xft"), Qdebug, | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
2397 Fcons (build_msg_string ("missing font in update_widget_face"), |
3094 | 2398 Fface_name (face))); |
2399 #endif | |
2400 } | |
442 | 2401 wv->change = VISIBLE_CHANGE; |
2402 /* #### Megahack - but its just getting too complicated to do this | |
2403 in the right place. */ | |
2404 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qtab_control)) | |
2405 update_tab_widget_face (wv, ii, domain); | |
434 | 2406 } |
2407 | |
2408 static void | |
440 | 2409 update_tab_widget_face (widget_value* wv, Lisp_Image_Instance *ii, |
434 | 2410 Lisp_Object domain) |
2411 { | |
2412 if (wv->contents) | |
2413 { | |
2414 widget_value* val = wv->contents, *cur; | |
438 | 2415 |
434 | 2416 /* Give each child label the correct foreground color. */ |
438 | 2417 Lisp_Object pixel = FACE_FOREGROUND |
434 | 2418 (IMAGE_INSTANCE_WIDGET_FACE (ii), |
2419 domain); | |
2420 XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2421 lw_add_widget_value_arg (val, (String) XtNtabForeground, fcolor.pixel); |
442 | 2422 wv->change = VISIBLE_CHANGE; |
2423 val->change = VISIBLE_CHANGE; | |
434 | 2424 |
2425 for (cur = val->next; cur; cur = cur->next) | |
2426 { | |
442 | 2427 cur->change = VISIBLE_CHANGE; |
434 | 2428 if (cur->value) |
2429 { | |
2430 lw_copy_widget_value_args (val, cur); | |
2431 } | |
2432 } | |
2433 } | |
428 | 2434 } |
2435 | |
2436 static void | |
2286 | 2437 x_widget_instantiate (Lisp_Object image_instance, |
2438 Lisp_Object UNUSED (instantiator), | |
2439 Lisp_Object UNUSED (pointer_fg), | |
2440 Lisp_Object UNUSED (pointer_bg), | |
2441 int UNUSED (dest_mask), Lisp_Object domain, | |
442 | 2442 const char* type, widget_value* wv) |
428 | 2443 { |
440 | 2444 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2445 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), pixel; |
2446 struct device* d = XDEVICE (device); | |
442 | 2447 Lisp_Object frame = DOMAIN_FRAME (domain); |
428 | 2448 struct frame* f = XFRAME (frame); |
2449 char* nm=0; | |
2450 Widget wid; | |
2451 Arg al [32]; | |
2452 int ac = 0; | |
2453 int id = new_lwlib_id (); | |
2454 widget_value* clip_wv; | |
2455 XColor fcolor, bcolor; | |
2456 | |
2457 if (!DEVICE_X_P (d)) | |
563 | 2458 gui_error ("Not an X device", device); |
428 | 2459 |
2460 /* have to set the type this late in case there is no device | |
2461 instantiation for a widget. But we can go ahead and do it without | |
2462 checking because there is always a generic instantiator. */ | |
2463 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET; | |
2464 | |
2465 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2466 nm = LISP_STRING_TO_EXTERNAL (IMAGE_INSTANCE_WIDGET_TEXT (ii), |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2467 Qlwlib_encoding); |
428 | 2468 |
2469 ii->data = xnew_and_zero (struct x_subwindow_data); | |
2470 | |
2471 /* Create a clip window to contain the subwidget. Incredibly the | |
2472 XEmacs manager seems to be the most appropriate widget for | |
2473 this. Nothing else is simple enough and yet does what is | |
2474 required. */ | |
2475 clip_wv = xmalloc_widget_value (); | |
2476 | |
434 | 2477 lw_add_widget_value_arg (clip_wv, XtNresize, False); |
438 | 2478 lw_add_widget_value_arg (clip_wv, XtNwidth, |
442 | 2479 (Dimension)IMAGE_INSTANCE_WIDTH (ii)); |
438 | 2480 lw_add_widget_value_arg (clip_wv, XtNheight, |
442 | 2481 (Dimension)IMAGE_INSTANCE_HEIGHT (ii)); |
428 | 2482 clip_wv->enabled = True; |
434 | 2483 |
428 | 2484 clip_wv->name = xstrdup ("clip-window"); |
2485 clip_wv->value = xstrdup ("clip-window"); | |
2486 | |
2487 IMAGE_INSTANCE_X_CLIPWIDGET (ii) | |
2488 = lw_create_widget ("clip-window", "clip-window", new_lwlib_id (), | |
2489 clip_wv, FRAME_X_CONTAINER_WIDGET (f), | |
2490 False, 0, 0, 0); | |
2491 | |
2492 free_widget_value_tree (clip_wv); | |
2493 | |
863 | 2494 /* create a sensible name. */ |
2495 if (wv->name == 0 || strcmp(wv->name, "") == 0) | |
2496 wv->name = xstrdup (type); | |
2497 | |
428 | 2498 /* copy any args we were given */ |
2499 ac = 0; | |
434 | 2500 lw_add_value_args_to_args (wv, al, &ac); |
428 | 2501 |
2502 /* Fixup the colors. We have to do this *before* the widget gets | |
2503 created so that Motif will fix up the shadow colors | |
2504 correctly. Once the widget is created Motif won't do this | |
2505 anymore...*/ | |
438 | 2506 pixel = FACE_FOREGROUND |
428 | 2507 (IMAGE_INSTANCE_WIDGET_FACE (ii), |
442 | 2508 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2509 fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); |
2510 | |
2511 pixel = FACE_BACKGROUND | |
2512 (IMAGE_INSTANCE_WIDGET_FACE (ii), | |
442 | 2513 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2514 bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); |
2515 | |
434 | 2516 lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel); |
2517 lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel); | |
428 | 2518 /* we cannot allow widgets to resize themselves */ |
434 | 2519 lw_add_widget_value_arg (wv, XtNresize, False); |
438 | 2520 lw_add_widget_value_arg (wv, XtNwidth, |
442 | 2521 (Dimension)IMAGE_INSTANCE_WIDTH (ii)); |
438 | 2522 lw_add_widget_value_arg (wv, XtNheight, |
442 | 2523 (Dimension)IMAGE_INSTANCE_HEIGHT (ii)); |
434 | 2524 /* update the font. */ |
2525 update_widget_face (wv, ii, domain); | |
428 | 2526 |
1318 | 2527 wid = lw_create_widget (type, wv->name, id, wv, |
2528 IMAGE_INSTANCE_X_CLIPWIDGET (ii), | |
428 | 2529 False, 0, popup_selection_callback, 0); |
2530 | |
2531 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; | |
2532 IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id; | |
2533 /* because the EmacsManager is the widgets parent we have to | |
2534 offset the redisplay of the widget by the amount the text | |
2535 widget is inside the manager. */ | |
2536 ac = 0; | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2537 Xt_SET_ARG (al [ac], XtNx, &IMAGE_INSTANCE_X_WIDGET_XOFFSET (ii)); ac++; |
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2538 Xt_SET_ARG (al [ac], XtNy, &IMAGE_INSTANCE_X_WIDGET_YOFFSET (ii)); ac++; |
428 | 2539 XtGetValues (FRAME_X_TEXT_WIDGET (f), al, ac); |
2540 | |
436 | 2541 XtSetMappedWhenManaged (wid, TRUE); |
428 | 2542 |
2543 free_widget_value_tree (wv); | |
442 | 2544 /* A kludgy but simple way to make sure the callback for a widget |
2545 doesn't get deleted. */ | |
2546 gcpro_popup_callbacks (id); | |
428 | 2547 } |
2548 | |
2549 /* get properties of a control */ | |
2550 static Lisp_Object | |
2551 x_widget_property (Lisp_Object image_instance, Lisp_Object prop) | |
2552 { | |
440 | 2553 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2554 /* get the text from a control */ |
2555 if (EQ (prop, Q_text)) | |
2556 { | |
2557 widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2558 return build_extstring (wv->value, Qlwlib_encoding); |
428 | 2559 } |
2560 return Qunbound; | |
2561 } | |
2562 | |
442 | 2563 /* Instantiate a layout control for putting other widgets in. */ |
2564 static void | |
771 | 2565 x_native_layout_instantiate (Lisp_Object image_instance, |
2566 Lisp_Object instantiator, | |
442 | 2567 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2568 int dest_mask, Lisp_Object domain) | |
2569 { | |
2570 x_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2571 pointer_bg, dest_mask, domain, "layout", 0); | |
2572 } | |
2573 | |
428 | 2574 /* Instantiate a button widget. Unfortunately instantiated widgets are |
2575 particular to a frame since they need to have a parent. It's not | |
2576 like images where you just select the image into the context you | |
2577 want to display it in and BitBlt it. So images instances can have a | |
2578 many-to-one relationship with things you see, whereas widgets can | |
2579 only be one-to-one (i.e. per frame) */ | |
2580 static void | |
2581 x_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2582 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2583 int dest_mask, Lisp_Object domain) | |
2584 { | |
440 | 2585 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2586 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
2587 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); | |
442 | 2588 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 1); |
428 | 2589 |
2590 if (!NILP (glyph)) | |
2591 { | |
2592 if (!IMAGE_INSTANCEP (glyph)) | |
2593 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1); | |
2594 } | |
2595 | |
2596 x_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2597 pointer_bg, dest_mask, domain, "button", wv); | |
2598 | |
2599 /* add the image if one was given */ | |
440 | 2600 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph) |
2601 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph))) | |
428 | 2602 { |
2603 Arg al [2]; | |
2604 int ac =0; | |
2605 #ifdef LWLIB_WIDGETS_MOTIF | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2606 Xt_SET_ARG (al [ac], XmNlabelType, XmPIXMAP); ac++; |
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2607 Xt_SET_ARG (al [ac], XmNlabelPixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph)); |
1318 | 2608 ac++; |
428 | 2609 #else |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2610 Xt_SET_ARG (al [ac], XtNpixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph)); ac++; |
428 | 2611 #endif |
2612 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac); | |
2613 } | |
2614 } | |
2615 | |
442 | 2616 /* Update a button's clicked state. |
2617 | |
2618 #### This is overkill, but it works. Right now this causes all | |
2619 button instances to flash for some reason buried deep in lwlib. In | |
2620 theory this should be the Right Thing to do since lwlib should only | |
2621 merge in changed values - and if nothing has changed then nothing | |
2622 should get done. This may be because of the args stuff, | |
2623 i.e. although the arg contents may be the same the args look | |
2624 different and so are re-applied to the widget. */ | |
2625 static void | |
2626 x_button_redisplay (Lisp_Object image_instance) | |
2627 { | |
2628 /* This function can GC if IN_REDISPLAY is false. */ | |
2629 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | |
2630 widget_value* wv = | |
2631 gui_items_to_widget_values (image_instance, | |
2632 IMAGE_INSTANCE_WIDGET_ITEMS (p), 1); | |
2633 | |
2634 /* now modify the widget */ | |
1346 | 2635 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), wv, True); |
442 | 2636 free_widget_value_tree (wv); |
1346 | 2637 gcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p)); |
442 | 2638 } |
2639 | |
428 | 2640 /* get properties of a button */ |
2641 static Lisp_Object | |
2642 x_button_property (Lisp_Object image_instance, Lisp_Object prop) | |
2643 { | |
440 | 2644 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2645 /* check the state of a button */ |
2646 if (EQ (prop, Q_selected)) | |
2647 { | |
2648 widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); | |
2649 | |
2650 if (wv->selected) | |
2651 return Qt; | |
2652 else | |
2653 return Qnil; | |
2654 } | |
2655 return Qunbound; | |
2656 } | |
2657 | |
2658 /* instantiate a progress gauge */ | |
2659 static void | |
1318 | 2660 x_progress_gauge_instantiate (Lisp_Object image_instance, |
2661 Lisp_Object instantiator, | |
2662 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2663 int dest_mask, Lisp_Object domain) | |
428 | 2664 { |
440 | 2665 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2666 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
442 | 2667 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0); |
428 | 2668 |
2669 x_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2670 pointer_bg, dest_mask, domain, "progress", wv); | |
2671 } | |
2672 | |
442 | 2673 /* set the properties of a progress gauge */ |
2674 static void | |
2675 x_progress_gauge_redisplay (Lisp_Object image_instance) | |
428 | 2676 { |
639 | 2677 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
2678 | |
2679 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
428 | 2680 { |
442 | 2681 Lisp_Object val; |
639 | 2682 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p))->value; |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2683 Xt_SET_VALUE (IMAGE_INSTANCE_X_WIDGET_ID (p), XtNvalue, XINT (val)); |
428 | 2684 } |
2685 } | |
2686 | |
2687 /* instantiate an edit control */ | |
2688 static void | |
2689 x_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
771 | 2690 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2691 int dest_mask, Lisp_Object domain) | |
428 | 2692 { |
440 | 2693 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2694 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
442 | 2695 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0); |
438 | 2696 |
428 | 2697 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2698 pointer_bg, dest_mask, domain, "text-field", wv); | |
2699 } | |
2700 | |
2701 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 | |
2702 /* instantiate a combo control */ | |
2703 static void | |
2704 x_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
771 | 2705 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2706 int dest_mask, Lisp_Object domain) | |
428 | 2707 { |
440 | 2708 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2709 widget_value * wv = 0; |
2710 /* This is not done generically because of sizing problems under | |
2711 mswindows. */ | |
438 | 2712 widget_instantiate (image_instance, instantiator, pointer_fg, |
2713 pointer_bg, dest_mask, domain); | |
428 | 2714 |
442 | 2715 wv = gui_items_to_widget_values (image_instance, |
2716 IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0); | |
438 | 2717 |
428 | 2718 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2719 pointer_bg, dest_mask, domain, "combo-box", wv); | |
2720 } | |
2721 #endif | |
2722 | |
2723 static void | |
1318 | 2724 x_tab_control_instantiate (Lisp_Object image_instance, |
2725 Lisp_Object instantiator, | |
428 | 2726 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2727 int dest_mask, Lisp_Object domain) | |
2728 { | |
440 | 2729 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
438 | 2730 widget_value * wv = |
442 | 2731 gui_items_to_widget_values (image_instance, |
2732 IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0); | |
438 | 2733 update_tab_widget_face (wv, ii, |
442 | 2734 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2735 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2736 pointer_bg, dest_mask, domain, "tab-control", wv); | |
2737 } | |
2738 | |
442 | 2739 /* Set the properties of a tab control */ |
2740 static void | |
2741 x_tab_control_redisplay (Lisp_Object image_instance) | |
428 | 2742 { |
440 | 2743 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
438 | 2744 |
1318 | 2745 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) || |
442 | 2746 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)) |
428 | 2747 { |
442 | 2748 /* If only the order has changed then simply select the first |
2749 one of the pending set. This stops horrendous rebuilding - | |
2750 and hence flicker - of the tabs each time you click on | |
2751 one. */ | |
2752 if (tab_control_order_only_changed (image_instance)) | |
2753 { | |
2754 Lisp_Object rest, selected = | |
2755 gui_item_list_find_selected | |
2756 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ? | |
2757 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) : | |
2758 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); | |
2759 | |
2760 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
2761 { | |
1913 | 2762 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) |
442 | 2763 { |
2764 /* There may be an encapsulated way of doing this, | |
2765 but I couldn't find it. */ | |
1318 | 2766 Lisp_Object old_selected = |
2767 gui_item_list_find_selected | |
442 | 2768 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); |
2769 char* name; | |
2770 unsigned int num_children, i; | |
2771 Widget* children; | |
2772 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2773 name = |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2774 LISP_STRING_TO_EXTERNAL (XGUI_ITEM (XCAR (rest))->name, |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2775 Qlwlib_encoding); |
442 | 2776 /* The name may contain a `.' which confuses |
2777 XtNameToWidget, so we do it ourselves. */ | |
1318 | 2778 children = |
2779 XtCompositeChildren (IMAGE_INSTANCE_X_WIDGET_ID (ii), | |
2780 &num_children); | |
442 | 2781 for (i = 0; i < num_children; i++) |
2782 { | |
2783 if (!strcmp (XtName (children [i]), name)) | |
2784 { | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2785 Xt_SET_VALUE (IMAGE_INSTANCE_X_WIDGET_ID (ii), |
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2786 XtNtopWidget, children [i]); |
442 | 2787 break; |
2788 } | |
2789 } | |
2790 /* Pick up the new selected item. */ | |
2791 XGUI_ITEM (old_selected)->selected = | |
2792 XGUI_ITEM (XCAR (rest))->selected; | |
2793 XGUI_ITEM (XCAR (rest))->selected = | |
2794 XGUI_ITEM (selected)->selected; | |
2795 /* We're not actually changing the items anymore. */ | |
2796 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; | |
2797 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; | |
2798 break; | |
2799 } | |
2800 } | |
2801 } | |
2802 } | |
2803 /* Possibly update the face. */ | |
2804 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) | |
2805 || | |
2806 XFRAME (IMAGE_INSTANCE_FRAME (ii))->faces_changed | |
2807 || | |
2808 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) | |
2809 { | |
2810 /* See previous comments on the brokeness of lwlib. | |
2811 | |
2812 #### There's actually not much point in doing this here | |
2813 since, colors will have been set appropriately by | |
2814 x_redisplay_widget. */ | |
2815 widget_value* wv =copy_widget_value_tree | |
2816 (lw_get_all_values | |
2817 (IMAGE_INSTANCE_X_WIDGET_LWID (ii)), | |
2818 NO_CHANGE); | |
438 | 2819 |
2820 update_tab_widget_face (wv, ii, | |
442 | 2821 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2822 |
2823 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True); | |
2824 free_widget_value_tree (wv); | |
1346 | 2825 gcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); |
428 | 2826 } |
2827 } | |
2828 | |
2829 /* instantiate a static control possible for putting other things in */ | |
2830 static void | |
2831 x_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2832 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2833 int dest_mask, Lisp_Object domain) | |
2834 { | |
440 | 2835 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2836 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
442 | 2837 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0); |
438 | 2838 |
428 | 2839 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2840 pointer_bg, dest_mask, domain, "button", wv); | |
2841 } | |
771 | 2842 #endif /* HAVE_X_WIDGETS */ |
428 | 2843 |
2844 | |
2845 /************************************************************************/ | |
2846 /* initialization */ | |
2847 /************************************************************************/ | |
2848 | |
2849 void | |
2850 syms_of_glyphs_x (void) | |
2851 { | |
2852 #if 0 | |
2853 DEFSUBR (Fchange_subwindow_property); | |
2854 #endif | |
2855 } | |
2856 | |
2857 void | |
2858 console_type_create_glyphs_x (void) | |
2859 { | |
2860 /* image methods */ | |
2861 | |
2862 CONSOLE_HAS_METHOD (x, print_image_instance); | |
2863 CONSOLE_HAS_METHOD (x, finalize_image_instance); | |
2864 CONSOLE_HAS_METHOD (x, image_instance_equal); | |
2865 CONSOLE_HAS_METHOD (x, image_instance_hash); | |
2866 CONSOLE_HAS_METHOD (x, colorize_image_instance); | |
2867 CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage); | |
2868 CONSOLE_HAS_METHOD (x, locate_pixmap_file); | |
2869 CONSOLE_HAS_METHOD (x, unmap_subwindow); | |
2870 CONSOLE_HAS_METHOD (x, map_subwindow); | |
442 | 2871 CONSOLE_HAS_METHOD (x, redisplay_widget); |
2872 CONSOLE_HAS_METHOD (x, redisplay_subwindow); | |
863 | 2873 CONSOLE_HAS_METHOD (x, widget_border_width); |
428 | 2874 } |
2875 | |
2876 void | |
2877 image_instantiator_format_create_glyphs_x (void) | |
2878 { | |
2879 IIFORMAT_VALID_CONSOLE (x, nothing); | |
2880 IIFORMAT_VALID_CONSOLE (x, string); | |
771 | 2881 #ifdef HAVE_X_WIDGETS |
428 | 2882 IIFORMAT_VALID_CONSOLE (x, layout); |
442 | 2883 #endif |
428 | 2884 IIFORMAT_VALID_CONSOLE (x, formatted_string); |
2885 IIFORMAT_VALID_CONSOLE (x, inherit); | |
2886 #ifdef HAVE_XPM | |
2887 INITIALIZE_DEVICE_IIFORMAT (x, xpm); | |
2888 IIFORMAT_HAS_DEVMETHOD (x, xpm, instantiate); | |
2889 #endif | |
2890 #ifdef HAVE_JPEG | |
2891 IIFORMAT_VALID_CONSOLE (x, jpeg); | |
2892 #endif | |
2893 #ifdef HAVE_TIFF | |
2894 IIFORMAT_VALID_CONSOLE (x, tiff); | |
438 | 2895 #endif |
428 | 2896 #ifdef HAVE_PNG |
2897 IIFORMAT_VALID_CONSOLE (x, png); | |
438 | 2898 #endif |
428 | 2899 #ifdef HAVE_GIF |
2900 IIFORMAT_VALID_CONSOLE (x, gif); | |
438 | 2901 #endif |
428 | 2902 INITIALIZE_DEVICE_IIFORMAT (x, xbm); |
2903 IIFORMAT_HAS_DEVMETHOD (x, xbm, instantiate); | |
2904 | |
2905 INITIALIZE_DEVICE_IIFORMAT (x, subwindow); | |
2906 IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate); | |
771 | 2907 #ifdef HAVE_X_WIDGETS |
442 | 2908 /* layout widget */ |
2909 INITIALIZE_DEVICE_IIFORMAT (x, native_layout); | |
2910 IIFORMAT_HAS_DEVMETHOD (x, native_layout, instantiate); | |
428 | 2911 /* button widget */ |
2912 INITIALIZE_DEVICE_IIFORMAT (x, button); | |
2913 IIFORMAT_HAS_DEVMETHOD (x, button, property); | |
2914 IIFORMAT_HAS_DEVMETHOD (x, button, instantiate); | |
442 | 2915 IIFORMAT_HAS_DEVMETHOD (x, button, redisplay); |
2916 /* general widget methods. */ | |
428 | 2917 INITIALIZE_DEVICE_IIFORMAT (x, widget); |
2918 IIFORMAT_HAS_DEVMETHOD (x, widget, property); | |
2919 /* progress gauge */ | |
2920 INITIALIZE_DEVICE_IIFORMAT (x, progress_gauge); | |
442 | 2921 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, redisplay); |
428 | 2922 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, instantiate); |
2923 /* text field */ | |
2924 INITIALIZE_DEVICE_IIFORMAT (x, edit_field); | |
2925 IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate); | |
2926 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 | |
2927 /* combo box */ | |
2928 INITIALIZE_DEVICE_IIFORMAT (x, combo_box); | |
2929 IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate); | |
442 | 2930 IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, redisplay, tab_control); |
428 | 2931 #endif |
2932 /* tab control widget */ | |
2933 INITIALIZE_DEVICE_IIFORMAT (x, tab_control); | |
2934 IIFORMAT_HAS_DEVMETHOD (x, tab_control, instantiate); | |
442 | 2935 IIFORMAT_HAS_DEVMETHOD (x, tab_control, redisplay); |
428 | 2936 /* label */ |
2937 INITIALIZE_DEVICE_IIFORMAT (x, label); | |
2938 IIFORMAT_HAS_DEVMETHOD (x, label, instantiate); | |
2939 #endif | |
2940 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font"); | |
2941 IIFORMAT_VALID_CONSOLE (x, cursor_font); | |
2942 | |
2943 IIFORMAT_HAS_METHOD (cursor_font, validate); | |
2944 IIFORMAT_HAS_METHOD (cursor_font, possible_dest_types); | |
2945 IIFORMAT_HAS_METHOD (cursor_font, instantiate); | |
2946 | |
2947 IIFORMAT_VALID_KEYWORD (cursor_font, Q_data, check_valid_string); | |
2948 IIFORMAT_VALID_KEYWORD (cursor_font, Q_foreground, check_valid_string); | |
2949 IIFORMAT_VALID_KEYWORD (cursor_font, Q_background, check_valid_string); | |
2950 | |
2951 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (font, "font"); | |
2952 | |
2953 IIFORMAT_HAS_METHOD (font, validate); | |
2954 IIFORMAT_HAS_METHOD (font, possible_dest_types); | |
2955 IIFORMAT_HAS_METHOD (font, instantiate); | |
2956 IIFORMAT_VALID_CONSOLE (x, font); | |
2957 | |
2958 IIFORMAT_VALID_KEYWORD (font, Q_data, check_valid_string); | |
2959 IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string); | |
2960 IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string); | |
2961 | |
2962 #ifdef HAVE_XFACE | |
2963 INITIALIZE_DEVICE_IIFORMAT (x, xface); | |
2964 IIFORMAT_HAS_DEVMETHOD (x, xface, instantiate); | |
2965 #endif | |
2966 | |
2967 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect, | |
2968 "autodetect"); | |
2969 | |
2970 IIFORMAT_HAS_METHOD (autodetect, validate); | |
2971 IIFORMAT_HAS_METHOD (autodetect, normalize); | |
2972 IIFORMAT_HAS_METHOD (autodetect, possible_dest_types); | |
4252 | 2973 /* #### autodetect is flawed IMO: |
446 | 2974 1. It makes the assumption that you can detect whether the user |
2975 wanted a cursor or a string based on the data, since the data is a | |
2976 string you have to prioritise cursors. Instead we will force users | |
2977 to pick the appropriate image type, this is what we do under | |
2978 MS-Windows anyway. | |
2979 2. It doesn't fit with the new domain model - you cannot tell which | |
2980 domain it needs to be instantiated in until you've actually | |
2981 instantiated it, which mucks up caching. | |
2982 3. It only copes with cursors and strings which seems bogus. */ | |
2983 IIFORMAT_HAS_SHARED_METHOD (autodetect, governing_domain, subwindow); | |
428 | 2984 IIFORMAT_HAS_METHOD (autodetect, instantiate); |
2985 IIFORMAT_VALID_CONSOLE (x, autodetect); | |
2986 | |
2987 IIFORMAT_VALID_KEYWORD (autodetect, Q_data, check_valid_string); | |
2988 } | |
2989 | |
2990 void | |
2991 vars_of_glyphs_x (void) | |
2992 { | |
2993 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path /* | |
2994 A list of the directories in which X bitmap files may be found. | |
2995 If nil, this is initialized from the "*bitmapFilePath" resource. | |
2996 This is used by the `make-image-instance' function (however, note that if | |
2997 the environment variable XBMLANGPATH is set, it is consulted first). | |
2998 */ ); | |
2999 Vx_bitmap_file_path = Qnil; | |
3000 } | |
3001 | |
3002 void | |
3003 complex_vars_of_glyphs_x (void) | |
3004 { | |
3005 #define BUILD_GLYPH_INST(variable, name) \ | |
3006 Fadd_spec_to_specifier \ | |
3007 (GLYPH_IMAGE (XGLYPH (variable)), \ | |
3008 vector3 (Qxbm, Q_data, \ | |
3009 list3 (make_int (name##_width), \ | |
3010 make_int (name##_height), \ | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
3011 make_extstring ((Extbyte *) name##_bits, \ |
428 | 3012 sizeof (name##_bits), \ |
440 | 3013 Qbinary))), \ |
428 | 3014 Qglobal, Qx, Qnil) |
3015 | |
3016 BUILD_GLYPH_INST (Vtruncation_glyph, truncator); | |
3017 BUILD_GLYPH_INST (Vcontinuation_glyph, continuer); | |
3018 BUILD_GLYPH_INST (Vxemacs_logo, xemacs); | |
3019 BUILD_GLYPH_INST (Vhscroll_glyph, hscroll); | |
3020 | |
3021 #undef BUILD_GLYPH_INST | |
3022 } |