Mercurial > hg > xemacs-beta
annotate src/glyphs-x.c @ 5044:e84a30b0e4a2
remove duplicative code in change_frame_size()
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-15 Ben Wing <ben@xemacs.org>
* frame.c (change_frame_size_1):
Simplify the logic in this function.
(1) Don't allow 0 as the value of height or width. The old code
that tried to allow this was totally broken, anyway, so obviously
this never happens any more.
(2) Don't duplicate the code in frame_conversion_internal() that
converts displayable pixel size to total pixel size -- just call
that function.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Mon, 15 Feb 2010 22:58:10 -0600 |
parents | 3c3c1d139863 |
children | 6f2158fa75ed |
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 | |
2959 | 5 Copyright (C) 1995, 1996, 2001, 2002, 2003, 2004, 2005 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" |
872 | 72 #include "objects-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. */ | |
1338 if (! XAllocColor (dpy, cmap, &color)) | |
2500 | 1339 ABORT (); /* it must be allocable since we're just duplicating it */ |
428 | 1340 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1341 |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1342 symbols[i].name = LISP_STRING_TO_EXTERNAL_MALLOC (XCAR (cons), Qctext); |
771 | 1343 symbols[i].pixel = color.pixel; |
1344 symbols[i].value = 0; | |
853 | 1345 free_cons (cons); |
428 | 1346 cons = results; |
1347 results = XCDR (results); | |
853 | 1348 free_cons (cons); |
428 | 1349 } |
1350 return symbols; | |
1351 } | |
1352 | |
1353 static void | |
1354 xpm_free (XpmAttributes *xpmattrs) | |
1355 { | |
1356 /* Could conceivably lose if XpmXXX returned an error without first | |
1357 initializing this structure, if we didn't know that initializing it | |
1358 to all zeros was ok (and also that it's ok to call XpmFreeAttributes() | |
1359 multiple times, since it zeros slots as it frees them...) */ | |
1360 XpmFreeAttributes (xpmattrs); | |
1361 } | |
1362 | |
1363 static void | |
1364 x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
438 | 1365 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1366 int dest_mask, Lisp_Object domain) | |
428 | 1367 { |
1368 /* This function can GC */ | |
440 | 1369 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1370 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1371 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1372 Display *dpy; | |
1373 Screen *xs; | |
1374 Colormap cmap; | |
1375 int depth; | |
1376 Visual *visual; | |
1377 Pixmap pixmap; | |
1378 Pixmap mask = 0; | |
1379 XpmAttributes xpmattrs; | |
1380 int result; | |
1381 XpmColorSymbol *color_symbols; | |
1382 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator, | |
1383 Q_color_symbols); | |
1384 enum image_instance_type type; | |
1385 int force_mono; | |
647 | 1386 int w, h; |
428 | 1387 |
1388 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 1389 gui_error ("Not an X device", device); |
428 | 1390 |
1391 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
1392 xs = DefaultScreenOfDisplay (dpy); | |
1393 | |
1394 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
1395 type = IMAGE_COLOR_PIXMAP; | |
1396 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK) | |
1397 type = IMAGE_MONO_PIXMAP; | |
1398 else if (dest_mask & IMAGE_POINTER_MASK) | |
1399 type = IMAGE_POINTER; | |
1400 else | |
1401 incompatible_image_types (instantiator, dest_mask, | |
1402 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | |
1403 | IMAGE_POINTER_MASK); | |
1404 force_mono = (type != IMAGE_COLOR_PIXMAP); | |
1405 | |
1406 #if 1 | |
1407 /* Although I haven't found it documented yet, it appears that pointers are | |
1408 always colored via the default window colormap... Sigh. */ | |
1409 if (type == IMAGE_POINTER) | |
1410 { | |
2959 | 1411 cmap = DefaultColormap (dpy, DefaultScreen (dpy)); |
428 | 1412 depth = DefaultDepthOfScreen (xs); |
1413 visual = DefaultVisualOfScreen (xs); | |
1414 } | |
1415 else | |
1416 { | |
2959 | 1417 cmap = DEVICE_X_COLORMAP (XDEVICE (device)); |
1418 depth = DEVICE_X_DEPTH (XDEVICE (device)); | |
1419 visual = DEVICE_X_VISUAL (XDEVICE (device)); | |
428 | 1420 } |
1421 #else | |
2959 | 1422 cmap = DEVICE_X_COLORMAP (XDEVICE (device)); |
1423 depth = DEVICE_X_DEPTH (XDEVICE (device)); | |
1424 visual = DEVICE_X_VISUAL (XDEVICE (device)); | |
428 | 1425 #endif |
1426 | |
1427 x_initialize_pixmap_image_instance (ii, 1, type); | |
1428 | |
1429 assert (!NILP (data)); | |
1430 | |
1431 retry: | |
1432 | |
1433 xzero (xpmattrs); /* want XpmInitAttributes() */ | |
1434 xpmattrs.valuemask = XpmReturnPixels; | |
1435 if (force_mono) | |
1436 { | |
1437 /* Without this, we get a 1-bit version of the color image, which | |
1438 isn't quite right. With this, we get the mono image, which might | |
1439 be very different looking. */ | |
1440 xpmattrs.valuemask |= XpmColorKey; | |
1441 xpmattrs.color_key = XPM_MONO; | |
1442 xpmattrs.depth = 1; | |
1443 xpmattrs.valuemask |= XpmDepth; | |
1444 } | |
1445 else | |
1446 { | |
1447 xpmattrs.closeness = 65535; | |
1448 xpmattrs.valuemask |= XpmCloseness; | |
1449 xpmattrs.depth = depth; | |
1450 xpmattrs.valuemask |= XpmDepth; | |
1451 xpmattrs.visual = visual; | |
1452 xpmattrs.valuemask |= XpmVisual; | |
1453 xpmattrs.colormap = cmap; | |
1454 xpmattrs.valuemask |= XpmColormap; | |
1455 } | |
1456 | |
1457 color_symbols = extract_xpm_color_names (&xpmattrs, device, domain, | |
1458 color_symbol_alist); | |
1459 | |
771 | 1460 { |
1461 Extbyte *dataext; | |
1462 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1463 dataext = LISP_STRING_TO_EXTERNAL (data, Qctext); |
771 | 1464 |
1465 result = | |
1466 XpmCreatePixmapFromBuffer (dpy, | |
1467 XtWindow | |
1468 (DEVICE_XT_APP_SHELL (XDEVICE(device))), | |
1469 dataext, &pixmap, &mask, &xpmattrs); | |
1470 } | |
428 | 1471 |
1472 if (color_symbols) | |
1473 { | |
771 | 1474 int i; |
1475 | |
1476 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
|
1477 xfree (color_symbols[i].name); |
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1478 xfree (color_symbols); |
428 | 1479 xpmattrs.colorsymbols = 0; /* in case XpmFreeAttr is too smart... */ |
1480 xpmattrs.numsymbols = 0; | |
1481 } | |
1482 | |
1483 switch (result) | |
1484 { | |
1485 case XpmSuccess: | |
1486 break; | |
1487 case XpmFileInvalid: | |
1488 { | |
1489 xpm_free (&xpmattrs); | |
1490 signal_image_error ("invalid XPM data", data); | |
1491 } | |
1492 case XpmColorFailed: | |
1493 case XpmColorError: | |
1494 { | |
1495 xpm_free (&xpmattrs); | |
1496 if (force_mono) | |
1497 { | |
1498 /* second time; blow out. */ | |
563 | 1499 gui_error ("XPM color allocation failed", data); |
428 | 1500 } |
1501 else | |
1502 { | |
563 | 1503 /* second time; blow out. */ |
428 | 1504 if (! (dest_mask & IMAGE_MONO_PIXMAP_MASK)) |
563 | 1505 gui_error ("XPM color allocation failed", data); |
428 | 1506 force_mono = 1; |
1507 IMAGE_INSTANCE_TYPE (ii) = IMAGE_MONO_PIXMAP; | |
1508 goto retry; | |
1509 } | |
1510 } | |
1511 case XpmNoMemory: | |
1512 { | |
1513 xpm_free (&xpmattrs); | |
563 | 1514 out_of_memory ("Parsing pixmap data", data); |
428 | 1515 } |
1516 default: | |
1517 { | |
1518 xpm_free (&xpmattrs); | |
563 | 1519 signal_error_2 (Qgui_error, |
1520 "Parsing pixmap data: unknown error code", | |
1521 make_int (result), data); | |
428 | 1522 } |
1523 } | |
1524 | |
1525 w = xpmattrs.width; | |
1526 h = xpmattrs.height; | |
1527 | |
1528 { | |
1529 int npixels = xpmattrs.npixels; | |
1530 Pixel *pixels; | |
1531 | |
1532 if (npixels != 0) | |
1533 { | |
1534 pixels = xnew_array (Pixel, npixels); | |
1535 memcpy (pixels, xpmattrs.pixels, npixels * sizeof (Pixel)); | |
1536 } | |
1537 else | |
1538 pixels = NULL; | |
1539 | |
1540 IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap; | |
1541 IMAGE_INSTANCE_PIXMAP_MASK (ii) = (void*)mask; | |
1542 IMAGE_INSTANCE_X_COLORMAP (ii) = cmap; | |
1543 IMAGE_INSTANCE_X_PIXELS (ii) = pixels; | |
1544 IMAGE_INSTANCE_X_NPIXELS (ii) = npixels; | |
1545 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = w; | |
1546 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = h; | |
1547 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
1548 find_keyword_in_vector (instantiator, Q_file); | |
1549 } | |
1550 | |
1551 switch (type) | |
1552 { | |
1553 case IMAGE_MONO_PIXMAP: | |
1554 break; | |
1555 | |
1556 case IMAGE_COLOR_PIXMAP: | |
2959 | 1557 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth; |
428 | 1558 break; |
1559 | |
1560 case IMAGE_POINTER: | |
2959 | 1561 if (xpmattrs.valuemask & XpmHotspot) |
1562 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (xpmattrs.x_hotspot); | |
1563 if (xpmattrs.valuemask & XpmHotspot) | |
1564 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (xpmattrs.y_hotspot); | |
4252 | 1565 |
2959 | 1566 image_instance_convert_to_pointer (ii, instantiator, pointer_fg, |
1567 pointer_bg); | |
428 | 1568 break; |
1569 | |
1570 default: | |
2500 | 1571 ABORT (); |
428 | 1572 } |
1573 | |
1574 xpm_free (&xpmattrs); /* after we've read pixels and hotspot */ | |
1575 } | |
1576 | |
1577 #endif /* HAVE_XPM */ | |
1578 | |
1579 | |
1580 #ifdef HAVE_XFACE | |
1581 | |
1582 /********************************************************************** | |
1583 * X-Face * | |
1584 **********************************************************************/ | |
1585 #if defined(EXTERN) | |
1586 /* This is about to get redefined! */ | |
1587 #undef EXTERN | |
1588 #endif | |
1589 /* We have to define SYSV32 so that compface.h includes string.h | |
1590 instead of strings.h. */ | |
1591 #define SYSV32 | |
1743 | 1592 BEGIN_C_DECLS |
428 | 1593 #include <compface.h> |
1743 | 1594 END_C_DECLS |
1595 | |
428 | 1596 /* JMP_BUF cannot be used here because if it doesn't get defined |
1597 to jmp_buf we end up with a conflicting type error with the | |
1598 definition in compface.h */ | |
1599 extern jmp_buf comp_env; | |
1600 #undef SYSV32 | |
1601 | |
1602 static void | |
1603 x_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1604 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1605 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1606 { |
1607 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1608 int i, stattis; | |
2367 | 1609 Binbyte *p, *bits, *bp; |
867 | 1610 const CIbyte * volatile emsg = 0; |
2367 | 1611 const Binbyte * volatile dstring; |
428 | 1612 |
1613 assert (!NILP (data)); | |
1614 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1615 dstring = (const Binbyte *) LISP_STRING_TO_EXTERNAL (data, Qbinary); |
853 | 1616 |
2367 | 1617 if ((p = (Binbyte *) strchr ((char *) dstring, ':'))) |
428 | 1618 { |
1619 dstring = p + 1; | |
1620 } | |
1621 | |
1622 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */ | |
1623 if (!(stattis = setjmp (comp_env))) | |
1624 { | |
853 | 1625 UnCompAll ((char *) dstring); |
428 | 1626 UnGenFace (); |
1627 } | |
1628 | |
1629 switch (stattis) | |
1630 { | |
1631 case -2: | |
1632 emsg = "uncompface: internal error"; | |
1633 break; | |
1634 case -1: | |
1635 emsg = "uncompface: insufficient or invalid data"; | |
1636 break; | |
1637 case 1: | |
1638 emsg = "uncompface: excess data ignored"; | |
1639 break; | |
1640 } | |
1641 | |
1642 if (emsg) | |
853 | 1643 signal_image_error_2 (emsg, data, Qimage); |
1644 | |
2367 | 1645 bp = bits = alloca_binbytes (PIXELS / 8); |
428 | 1646 |
1647 /* the compface library exports char F[], which uses a single byte per | |
1648 pixel to represent a 48x48 bitmap. Yuck. */ | |
2367 | 1649 for (i = 0, p = (Binbyte *) F; i < (PIXELS / 8); ++i) |
428 | 1650 { |
1651 int n, b; | |
1652 /* reverse the bit order of each byte... */ | |
1653 for (b = n = 0; b < 8; ++b) | |
1654 { | |
1655 n |= ((*p++) << b); | |
1656 } | |
2367 | 1657 *bp++ = (Binbyte) n; |
428 | 1658 } |
1659 | |
1660 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, | |
2367 | 1661 pointer_bg, dest_mask, 48, 48, (CBinbyte *) bits); |
428 | 1662 } |
1663 | |
1664 #endif /* HAVE_XFACE */ | |
1665 | |
1666 | |
1667 /********************************************************************** | |
1668 * Autodetect * | |
1669 **********************************************************************/ | |
1670 | |
1671 static void | |
1672 autodetect_validate (Lisp_Object instantiator) | |
1673 { | |
1674 data_must_be_present (instantiator); | |
1675 } | |
1676 | |
1677 static Lisp_Object | |
1678 autodetect_normalize (Lisp_Object instantiator, | |
442 | 1679 Lisp_Object console_type, |
2286 | 1680 Lisp_Object UNUSED (dest_mask)) |
428 | 1681 { |
1682 Lisp_Object file = find_keyword_in_vector (instantiator, Q_data); | |
1683 Lisp_Object filename = Qnil; | |
1684 Lisp_Object data = Qnil; | |
1685 struct gcpro gcpro1, gcpro2, gcpro3; | |
1686 Lisp_Object alist = Qnil; | |
1687 | |
1688 GCPRO3 (filename, data, alist); | |
1689 | |
1690 if (NILP (file)) /* no conversion necessary */ | |
1691 RETURN_UNGCPRO (instantiator); | |
1692 | |
1693 alist = tagged_vector_to_alist (instantiator); | |
1694 | |
1695 filename = locate_pixmap_file (file); | |
1696 if (!NILP (filename)) | |
1697 { | |
1698 int xhot, yhot; | |
1699 /* #### Apparently some versions of XpmReadFileToData, which is | |
1700 called by pixmap_to_lisp_data, don't return an error value | |
1701 if the given file is not a valid XPM file. Instead, they | |
1702 just seg fault. It is definitely caused by passing a | |
1703 bitmap. To try and avoid this we check for bitmaps first. */ | |
1704 | |
1705 data = bitmap_to_lisp_data (filename, &xhot, &yhot, 1); | |
1706 | |
1707 if (!EQ (data, Qt)) | |
1708 { | |
1709 alist = remassq_no_quit (Q_data, alist); | |
1710 alist = Fcons (Fcons (Q_file, filename), | |
1711 Fcons (Fcons (Q_data, data), alist)); | |
1712 if (xhot != -1) | |
1713 alist = Fcons (Fcons (Q_hotspot_x, make_int (xhot)), | |
1714 alist); | |
1715 if (yhot != -1) | |
1716 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)), | |
1717 alist); | |
1718 | |
4252 | 1719 alist = xbm_mask_file_munging (alist, filename, Qt, console_type); |
428 | 1720 |
1721 { | |
1722 Lisp_Object result = alist_to_tagged_vector (Qxbm, alist); | |
1723 free_alist (alist); | |
1724 RETURN_UNGCPRO (result); | |
1725 } | |
1726 } | |
1727 | |
1728 #ifdef HAVE_XPM | |
1729 data = pixmap_to_lisp_data (filename, 1); | |
1730 | |
1731 if (!EQ (data, Qt)) | |
1732 { | |
1733 alist = remassq_no_quit (Q_data, alist); | |
1734 alist = Fcons (Fcons (Q_file, filename), | |
1735 Fcons (Fcons (Q_data, data), alist)); | |
1736 alist = Fcons (Fcons (Q_color_symbols, | |
1737 evaluate_xpm_color_symbols ()), | |
1738 alist); | |
1739 { | |
1740 Lisp_Object result = alist_to_tagged_vector (Qxpm, alist); | |
1741 free_alist (alist); | |
1742 RETURN_UNGCPRO (result); | |
1743 } | |
1744 } | |
1745 #endif | |
1746 } | |
1747 | |
1748 /* If we couldn't convert it, just put it back as it is. | |
1749 We might try to further frob it later as a cursor-font | |
1750 specification. (We can't do that now because we don't know | |
1751 what dest-types it's going to be instantiated into.) */ | |
1752 { | |
1753 Lisp_Object result = alist_to_tagged_vector (Qautodetect, alist); | |
1754 free_alist (alist); | |
1755 RETURN_UNGCPRO (result); | |
1756 } | |
1757 } | |
1758 | |
1759 static int | |
1760 autodetect_possible_dest_types (void) | |
1761 { | |
1762 return | |
1763 IMAGE_MONO_PIXMAP_MASK | | |
1764 IMAGE_COLOR_PIXMAP_MASK | | |
1765 IMAGE_POINTER_MASK | | |
1766 IMAGE_TEXT_MASK; | |
1767 } | |
1768 | |
1769 static void | |
1770 autodetect_instantiate (Lisp_Object image_instance, | |
438 | 1771 Lisp_Object instantiator, |
1772 Lisp_Object pointer_fg, | |
1773 Lisp_Object pointer_bg, | |
1774 int dest_mask, Lisp_Object domain) | |
428 | 1775 { |
1776 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1777 struct gcpro gcpro1, gcpro2, gcpro3; | |
1778 Lisp_Object alist = Qnil; | |
1779 Lisp_Object result = Qnil; | |
1780 int is_cursor_font = 0; | |
1781 | |
1782 GCPRO3 (data, alist, result); | |
1783 | |
1784 alist = tagged_vector_to_alist (instantiator); | |
1785 if (dest_mask & IMAGE_POINTER_MASK) | |
1786 { | |
442 | 1787 const char *name_ext; |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1788 LISP_PATHNAME_CONVERT_OUT (data, name_ext); |
428 | 1789 if (XmuCursorNameToIndex (name_ext) != -1) |
4252 | 1790 { |
1791 result = alist_to_tagged_vector (Qcursor_font, alist); | |
1792 is_cursor_font = 1; | |
1793 } | |
428 | 1794 } |
1795 | |
1796 if (!is_cursor_font) | |
1797 result = alist_to_tagged_vector (Qstring, alist); | |
1798 free_alist (alist); | |
1799 | |
1800 if (is_cursor_font) | |
1801 cursor_font_instantiate (image_instance, result, pointer_fg, | |
1802 pointer_bg, dest_mask, domain); | |
1803 else | |
1804 string_instantiate (image_instance, result, pointer_fg, | |
1805 pointer_bg, dest_mask, domain); | |
1806 | |
1807 UNGCPRO; | |
1808 } | |
1809 | |
1810 | |
1811 /********************************************************************** | |
1812 * Font * | |
1813 **********************************************************************/ | |
1814 | |
1815 static void | |
1816 font_validate (Lisp_Object instantiator) | |
1817 { | |
1818 data_must_be_present (instantiator); | |
1819 } | |
1820 | |
1821 /* XmuCvtStringToCursor is bogus in the following ways: | |
1822 | |
1823 - When it can't convert the given string to a real cursor, it will | |
1824 sometimes return a "success" value, after triggering a BadPixmap | |
1825 error. It then gives you a cursor that will itself generate BadCursor | |
1826 errors. So we install this error handler to catch/notice the X error | |
1827 and take that as meaning "couldn't convert." | |
1828 | |
1829 - When you tell it to find a cursor file that doesn't exist, it prints | |
1830 an error message on stderr. You can't make it not do that. | |
1831 | |
1832 - Also, using Xmu means we can't properly hack Lisp_Image_Instance | |
1833 objects, or XPM files, or $XBMLANGPATH. | |
1834 */ | |
1835 | |
1836 /* Duplicate the behavior of XmuCvtStringToCursor() to bypass its bogusness. */ | |
1837 | |
1838 static int XLoadFont_got_error; | |
1839 | |
1840 static int | |
2286 | 1841 XLoadFont_error_handler (Display *UNUSED (dpy), XErrorEvent *UNUSED (xerror)) |
428 | 1842 { |
1843 XLoadFont_got_error = 1; | |
1844 return 0; | |
1845 } | |
1846 | |
1847 static Font | |
867 | 1848 safe_XLoadFont (Display *dpy, Ibyte *name) |
428 | 1849 { |
1850 Font font; | |
1851 int (*old_handler) (Display *, XErrorEvent *); | |
771 | 1852 |
428 | 1853 XLoadFont_got_error = 0; |
1854 XSync (dpy, 0); | |
1855 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
|
1856 font = XLoadFont (dpy, ITEXT_TO_EXTERNAL (name, Qfile_name)); |
428 | 1857 XSync (dpy, 0); |
1858 XSetErrorHandler (old_handler); | |
1859 if (XLoadFont_got_error) return 0; | |
1860 return font; | |
1861 } | |
1862 | |
1863 static int | |
1864 font_possible_dest_types (void) | |
1865 { | |
1866 return IMAGE_POINTER_MASK; | |
1867 } | |
1868 | |
1869 static void | |
1870 font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1871 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1872 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1873 { |
1874 /* This function can GC */ | |
1875 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
440 | 1876 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1877 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1878 Display *dpy; | |
1879 XColor fg, bg; | |
1880 Font source, mask; | |
2421 | 1881 Ibyte source_name[PATH_MAX_INTERNAL], mask_name[PATH_MAX_INTERNAL], dummy; |
428 | 1882 int source_char, mask_char; |
1883 int count; | |
1884 Lisp_Object foreground, background; | |
1885 | |
1886 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 1887 gui_error ("Not an X device", device); |
428 | 1888 |
1889 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
1890 | |
1891 if (!STRINGP (data) || | |
1892 strncmp ("FONT ", (char *) XSTRING_DATA (data), 5)) | |
563 | 1893 invalid_argument ("Invalid font-glyph instantiator", |
428 | 1894 instantiator); |
1895 | |
1896 if (!(dest_mask & IMAGE_POINTER_MASK)) | |
1897 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK); | |
1898 | |
1899 foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1900 if (NILP (foreground)) | |
1901 foreground = pointer_fg; | |
1902 background = find_keyword_in_vector (instantiator, Q_background); | |
1903 if (NILP (background)) | |
1904 background = pointer_bg; | |
1905 | |
1906 generate_cursor_fg_bg (device, &foreground, &background, &fg, &bg); | |
1907 | |
1908 count = sscanf ((char *) XSTRING_DATA (data), | |
1909 "FONT %s %d %s %d %c", | |
1910 source_name, &source_char, | |
1911 mask_name, &mask_char, &dummy); | |
1912 /* Allow "%s %d %d" as well... */ | |
771 | 1913 if (count == 3 && (1 == sscanf ((char *) mask_name, "%d %c", &mask_char, |
1914 &dummy))) | |
428 | 1915 count = 4, mask_name[0] = 0; |
1916 | |
1917 if (count != 2 && count != 4) | |
563 | 1918 syntax_error ("invalid cursor specification", data); |
428 | 1919 source = safe_XLoadFont (dpy, source_name); |
1920 if (! source) | |
563 | 1921 signal_error_2 (Qgui_error, |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1922 "couldn't load font", build_istring (source_name), data); |
428 | 1923 if (count == 2) |
1924 mask = 0; | |
1925 else if (!mask_name[0]) | |
1926 mask = source; | |
1927 else | |
1928 { | |
1929 mask = safe_XLoadFont (dpy, mask_name); | |
1930 if (!mask) | |
563 | 1931 signal_continuable_error_2 (Qgui_error, |
1932 "couldn't load font", | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1933 build_istring (mask_name), data); |
428 | 1934 } |
1935 if (!mask) | |
1936 mask_char = 0; | |
1937 | |
1938 /* #### call XQueryTextExtents() and check_pointer_sizes() here. */ | |
1939 | |
1940 x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); | |
1941 IMAGE_INSTANCE_X_CURSOR (ii) = | |
1942 XCreateGlyphCursor (dpy, source, mask, source_char, mask_char, | |
1943 &fg, &bg); | |
1944 XIMAGE_INSTANCE_PIXMAP_FG (image_instance) = foreground; | |
1945 XIMAGE_INSTANCE_PIXMAP_BG (image_instance) = background; | |
1946 XUnloadFont (dpy, source); | |
1947 if (mask && mask != source) XUnloadFont (dpy, mask); | |
1948 } | |
1949 | |
1950 | |
1951 /********************************************************************** | |
1952 * Cursor-Font * | |
1953 **********************************************************************/ | |
1954 | |
1955 static void | |
1956 cursor_font_validate (Lisp_Object instantiator) | |
1957 { | |
1958 data_must_be_present (instantiator); | |
1959 } | |
1960 | |
1961 static int | |
1962 cursor_font_possible_dest_types (void) | |
1963 { | |
1964 return IMAGE_POINTER_MASK; | |
1965 } | |
1966 | |
1967 static void | |
1968 cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1969 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1970 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1971 { |
1972 /* This function can GC */ | |
1973 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
440 | 1974 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1975 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1976 Display *dpy; | |
1977 int i; | |
771 | 1978 const Extbyte *name_ext; |
428 | 1979 Lisp_Object foreground, background; |
1980 | |
1981 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 1982 gui_error ("Not an X device", device); |
428 | 1983 |
1984 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
1985 | |
1986 if (!(dest_mask & IMAGE_POINTER_MASK)) | |
1987 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK); | |
1988 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1989 LISP_PATHNAME_CONVERT_OUT (data, name_ext); |
428 | 1990 if ((i = XmuCursorNameToIndex (name_ext)) == -1) |
563 | 1991 invalid_argument ("Unrecognized cursor-font name", data); |
428 | 1992 |
1993 x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); | |
1994 IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i); | |
1995 foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1996 if (NILP (foreground)) | |
1997 foreground = pointer_fg; | |
1998 background = find_keyword_in_vector (instantiator, Q_background); | |
1999 if (NILP (background)) | |
2000 background = pointer_bg; | |
2001 maybe_recolor_cursor (image_instance, foreground, background); | |
2002 } | |
2003 | |
2004 static int | |
2005 x_colorize_image_instance (Lisp_Object image_instance, | |
2006 Lisp_Object foreground, Lisp_Object background) | |
2007 { | |
440 | 2008 Lisp_Image_Instance *p; |
428 | 2009 |
2010 p = XIMAGE_INSTANCE (image_instance); | |
2011 | |
2012 switch (IMAGE_INSTANCE_TYPE (p)) | |
2013 { | |
2014 case IMAGE_MONO_PIXMAP: | |
2015 IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP; | |
2016 /* Make sure there aren't two pointers to the same mask, causing | |
2017 it to get freed twice. */ | |
2018 IMAGE_INSTANCE_PIXMAP_MASK (p) = 0; | |
2019 break; | |
2020 | |
2021 default: | |
2022 return 0; | |
2023 } | |
2024 | |
2025 { | |
2026 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (IMAGE_INSTANCE_DEVICE (p))); | |
2027 Drawable draw = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))); | |
2028 Dimension d = DEVICE_X_DEPTH (XDEVICE (IMAGE_INSTANCE_DEVICE (p))); | |
2959 | 2029 Pixmap new_ = XCreatePixmap (dpy, draw, |
428 | 2030 IMAGE_INSTANCE_PIXMAP_WIDTH (p), |
2031 IMAGE_INSTANCE_PIXMAP_HEIGHT (p), d); | |
2032 XColor color; | |
2033 XGCValues gcv; | |
2034 GC gc; | |
2035 color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (foreground)); | |
2036 gcv.foreground = color.pixel; | |
2037 color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (background)); | |
2038 gcv.background = color.pixel; | |
2959 | 2039 gc = XCreateGC (dpy, new_, GCBackground|GCForeground, &gcv); |
2040 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), new_, gc, 0, 0, | |
428 | 2041 IMAGE_INSTANCE_PIXMAP_WIDTH (p), |
2042 IMAGE_INSTANCE_PIXMAP_HEIGHT (p), | |
2043 0, 0, 1); | |
2044 XFreeGC (dpy, gc); | |
2959 | 2045 IMAGE_INSTANCE_X_PIXMAP (p) = new_; |
428 | 2046 IMAGE_INSTANCE_PIXMAP_DEPTH (p) = d; |
2047 IMAGE_INSTANCE_PIXMAP_FG (p) = foreground; | |
2048 IMAGE_INSTANCE_PIXMAP_BG (p) = background; | |
2049 return 1; | |
2050 } | |
2051 } | |
2052 | |
2053 | |
2054 /************************************************************************/ | |
2055 /* subwindow and widget support */ | |
2056 /************************************************************************/ | |
2057 | |
2058 /* unmap the image if it is a widget. This is used by redisplay via | |
2059 redisplay_unmap_subwindows */ | |
2060 static void | |
440 | 2061 x_unmap_subwindow (Lisp_Image_Instance *p) |
428 | 2062 { |
2063 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) | |
2064 { | |
438 | 2065 XUnmapWindow |
2066 (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
428 | 2067 IMAGE_INSTANCE_X_CLIPWINDOW (p)); |
914 | 2068 XUnmapSubwindows |
2069 (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2070 IMAGE_INSTANCE_X_CLIPWINDOW (p)); | |
428 | 2071 } |
2072 else /* must be a widget */ | |
2073 { | |
450 | 2074 /* Since we are being unmapped we want the enclosing frame to |
2075 get focus. The losing with simple scrolling but is the safest | |
2076 thing to do. */ | |
4252 | 2077 emacs_Xt_handle_widget_losing_focus |
450 | 2078 ( XFRAME (IMAGE_INSTANCE_FRAME (p)), |
2079 IMAGE_INSTANCE_X_WIDGET_ID (p)); | |
428 | 2080 XtUnmapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); |
2081 } | |
2082 } | |
2083 | |
2084 /* map the subwindow. This is used by redisplay via | |
2085 redisplay_output_subwindow */ | |
2086 static void | |
440 | 2087 x_map_subwindow (Lisp_Image_Instance *p, int x, int y, |
428 | 2088 struct display_glyph_area* dga) |
2089 { | |
448 | 2090 assert (dga->width > 0 && dga->height > 0); |
428 | 2091 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) |
2092 { | |
2093 Window subwindow = IMAGE_INSTANCE_X_SUBWINDOW_ID (p); | |
2094 XMoveResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
438 | 2095 IMAGE_INSTANCE_X_CLIPWINDOW (p), |
428 | 2096 x, y, dga->width, dga->height); |
2097 XMoveWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2098 subwindow, -dga->xoffset, -dga->yoffset); | |
442 | 2099 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) |
914 | 2100 { |
2101 XMapWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2102 IMAGE_INSTANCE_X_CLIPWINDOW (p)); | |
2103 XMapSubwindows (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2104 IMAGE_INSTANCE_X_CLIPWINDOW (p)); | |
2105 } | |
428 | 2106 } |
2107 else /* must be a widget */ | |
2108 { | |
438 | 2109 XtConfigureWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p), |
428 | 2110 x + IMAGE_INSTANCE_X_WIDGET_XOFFSET (p), |
2111 y + IMAGE_INSTANCE_X_WIDGET_YOFFSET (p), | |
2112 dga->width, dga->height, 0); | |
2113 XtMoveWidget (IMAGE_INSTANCE_X_WIDGET_ID (p), | |
2114 -dga->xoffset, -dga->yoffset); | |
442 | 2115 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) |
2116 XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); | |
863 | 2117 /* See comments in glyphs-msw.c about keyboard focus. */ |
1111 | 2118 if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (p)) |
2119 { | |
2120 /* #### FIXME to pop-up the find dialog we map the text-field | |
2121 seven times! This doesn't show on a fast linux box but does | |
2122 under X on windows. */ | |
2123 emacs_Xt_enqueue_focus_event (IMAGE_INSTANCE_X_WIDGET_ID (p), | |
2124 IMAGE_INSTANCE_FRAME (p), 1); | |
2125 } | |
428 | 2126 } |
2127 } | |
2128 | |
2129 /* when you click on a widget you may activate another widget this | |
2130 needs to be checked and all appropriate widgets updated */ | |
2131 static void | |
442 | 2132 x_redisplay_subwindow (Lisp_Image_Instance *p) |
2133 { | |
2134 /* Update the subwindow size if necessary. */ | |
2135 if (IMAGE_INSTANCE_SIZE_CHANGED (p)) | |
2136 { | |
2137 XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2138 IMAGE_INSTANCE_X_SUBWINDOW_ID (p), | |
2139 IMAGE_INSTANCE_WIDTH (p), | |
2140 IMAGE_INSTANCE_HEIGHT (p)); | |
2141 } | |
2142 } | |
2143 | |
2144 /* Update all attributes that have changed. Lwlib actually does most | |
2145 of this for us. */ | |
2146 static void | |
2147 x_redisplay_widget (Lisp_Image_Instance *p) | |
428 | 2148 { |
442 | 2149 /* This function can GC if IN_REDISPLAY is false. */ |
771 | 2150 #ifdef HAVE_X_WIDGETS |
442 | 2151 widget_value* wv = 0; |
2152 | |
2153 /* First get the items if they have changed since this is a | |
2154 structural change. As such it will nuke all added values so we | |
2155 need to update most other things after the items have changed.*/ | |
2156 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
2157 { | |
793 | 2158 Lisp_Object image_instance = wrap_image_instance (p); |
2159 | |
442 | 2160 wv = gui_items_to_widget_values |
2161 (image_instance, IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p), | |
2162 /* #### this is not right; we need to keep track of which widgets | |
2163 want accelerators and which don't */ 0); | |
2164 wv->change = STRUCTURAL_CHANGE; | |
2165 } | |
2166 else | |
428 | 2167 { |
442 | 2168 /* Assume the lotus position, breath deeply and chant to |
2169 yourself lwlibsux, lwlibsux ... lw_get_all_values returns a | |
2170 reference to the real values rather than a copy thus any | |
2171 changes we make to the values we get back will look like they | |
2172 have already been applied. If we rebuild the widget tree then | |
444 | 2173 we may lose properties. */ |
4252 | 2174 wv = copy_widget_value_tree (lw_get_all_values |
442 | 2175 (IMAGE_INSTANCE_X_WIDGET_LWID (p)), |
2176 NO_CHANGE); | |
2177 } | |
2178 | |
2179 /* Possibly update the colors and font */ | |
2180 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) | |
2181 || | |
454 | 2182 /* #### This is not sufficient because it will not cope with widgets |
2183 that are not currently visible. Once redisplay has done the | |
2184 visible ones it will clear this flag so that when new ones | |
2185 become visible they will not be updated. */ | |
442 | 2186 XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed |
2187 || | |
454 | 2188 XFRAME (IMAGE_INSTANCE_FRAME (p))->frame_changed |
2189 || | |
442 | 2190 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) |
2191 { | |
2192 update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p)); | |
2193 } | |
2194 | |
2195 /* Possibly update the text. */ | |
2196 if (IMAGE_INSTANCE_TEXT_CHANGED (p)) | |
2197 { | |
771 | 2198 Extbyte* str; |
442 | 2199 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
|
2200 str = LISP_STRING_TO_EXTERNAL (val, Qlwlib_encoding); |
442 | 2201 wv->value = str; |
2202 } | |
2203 | |
2204 /* Possibly update the size. */ | |
2205 if (IMAGE_INSTANCE_SIZE_CHANGED (p) | |
2206 || | |
2207 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p) | |
2208 || | |
2209 IMAGE_INSTANCE_TEXT_CHANGED (p)) | |
2210 { | |
2211 assert (IMAGE_INSTANCE_X_WIDGET_ID (p) && | |
2212 IMAGE_INSTANCE_X_CLIPWIDGET (p)) ; | |
2213 | |
2214 if (IMAGE_INSTANCE_X_WIDGET_ID (p)->core.being_destroyed | |
2215 || !XtIsManaged(IMAGE_INSTANCE_X_WIDGET_ID (p))) | |
428 | 2216 { |
793 | 2217 Lisp_Object sw = wrap_image_instance (p); |
2218 | |
563 | 2219 signal_error (Qinternal_error, |
2220 "XEmacs bug: subwindow is deleted", sw); | |
434 | 2221 } |
442 | 2222 |
2223 lw_add_widget_value_arg (wv, XtNwidth, | |
2224 (Dimension)IMAGE_INSTANCE_WIDTH (p)); | |
2225 lw_add_widget_value_arg (wv, XtNheight, | |
2226 (Dimension)IMAGE_INSTANCE_HEIGHT (p)); | |
428 | 2227 } |
442 | 2228 |
448 | 2229 /* Adjust offsets within the frame. */ |
450 | 2230 if (XFRAME (IMAGE_INSTANCE_FRAME (p))->size_changed) |
448 | 2231 { |
2232 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
|
2233 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
|
2234 Xt_SET_ARG (al [1], XtNy, &IMAGE_INSTANCE_X_WIDGET_YOFFSET (p)); |
4252 | 2235 XtGetValues (FRAME_X_TEXT_WIDGET |
448 | 2236 (XFRAME (IMAGE_INSTANCE_FRAME (p))), al, 2); |
2237 } | |
2238 | |
442 | 2239 /* now modify the widget */ |
1346 | 2240 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), wv, True); |
442 | 2241 free_widget_value_tree (wv); |
1346 | 2242 gcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p)); |
428 | 2243 #endif |
2244 } | |
2245 | |
2246 /* instantiate and x type subwindow */ | |
2247 static void | |
2286 | 2248 x_subwindow_instantiate (Lisp_Object image_instance, |
2249 Lisp_Object UNUSED (instantiator), | |
2250 Lisp_Object UNUSED (pointer_fg), | |
2251 Lisp_Object UNUSED (pointer_bg), | |
2252 int UNUSED (dest_mask), Lisp_Object domain) | |
428 | 2253 { |
2254 /* This function can GC */ | |
440 | 2255 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2256 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
442 | 2257 Lisp_Object frame = DOMAIN_FRAME (domain); |
428 | 2258 struct frame* f = XFRAME (frame); |
2259 Display *dpy; | |
2260 Screen *xs; | |
2261 Window pw, win; | |
2262 XSetWindowAttributes xswa; | |
2263 Mask valueMask = 0; | |
647 | 2264 int w = IMAGE_INSTANCE_WIDTH (ii), h = IMAGE_INSTANCE_HEIGHT (ii); |
428 | 2265 |
2266 if (!DEVICE_X_P (XDEVICE (device))) | |
563 | 2267 gui_error ("Not an X device", device); |
428 | 2268 |
2269 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); | |
2270 xs = DefaultScreenOfDisplay (dpy); | |
2271 | |
2272 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW; | |
2273 | |
2274 pw = XtWindow (FRAME_X_TEXT_WIDGET (f)); | |
2275 | |
2276 ii->data = xnew_and_zero (struct x_subwindow_data); | |
2277 | |
2278 IMAGE_INSTANCE_X_SUBWINDOW_PARENT (ii) = pw; | |
2279 IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii) = DisplayOfScreen (xs); | |
2280 | |
2281 xswa.backing_store = Always; | |
2282 valueMask |= CWBackingStore; | |
2283 xswa.colormap = DefaultColormapOfScreen (xs); | |
2284 valueMask |= CWColormap; | |
438 | 2285 |
428 | 2286 /* Create a window for clipping */ |
438 | 2287 IMAGE_INSTANCE_X_CLIPWINDOW (ii) = |
428 | 2288 XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent, |
2289 InputOutput, CopyFromParent, valueMask, | |
2290 &xswa); | |
2291 | |
2292 /* Now put the subwindow inside the clip window. */ | |
2293 win = XCreateWindow (dpy, IMAGE_INSTANCE_X_CLIPWINDOW (ii), | |
2294 0, 0, w, h, 0, CopyFromParent, | |
2295 InputOutput, CopyFromParent, valueMask, | |
2296 &xswa); | |
438 | 2297 |
428 | 2298 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win; |
2299 } | |
2300 | |
863 | 2301 /* Account for some of the limitations with widget images. */ |
2302 static int | |
2303 x_widget_border_width (void) | |
2304 { | |
2305 return DEFAULT_WIDGET_BORDER_WIDTH * 2; | |
2306 } | |
2307 | |
2308 | |
428 | 2309 #if 0 |
2310 /* #### Should this function exist? If there's any doubt I'm not implementing it --andyp */ | |
2311 DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /* | |
2312 For the given SUBWINDOW, set PROPERTY to DATA, which is a string. | |
2313 Subwindows are not currently implemented. | |
2314 */ | |
2315 (subwindow, property, data)) | |
2316 { | |
2317 Atom property_atom; | |
440 | 2318 Lisp_Subwindow *sw; |
428 | 2319 Display *dpy; |
771 | 2320 Extbyte *propext, *dataext; |
2321 Bytecount datalen; | |
428 | 2322 |
2323 CHECK_SUBWINDOW (subwindow); | |
2324 CHECK_STRING (property); | |
2325 CHECK_STRING (data); | |
2326 | |
2327 sw = XSUBWINDOW (subwindow); | |
2328 dpy = DisplayOfScreen (LISP_DEVICE_TO_X_SCREEN | |
2329 (FRAME_DEVICE (XFRAME (sw->frame)))); | |
2330 | |
771 | 2331 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
|
2332 LISP_STRING_TO_SIZED_EXTERNAL (data, dataext, datalen, Qctext); |
771 | 2333 property_atom = XInternAtom (dpy, propext, False); |
428 | 2334 XChangeProperty (dpy, sw->subwindow, property_atom, XA_STRING, 8, |
771 | 2335 PropModeReplace, dataext, datalen); |
428 | 2336 return property; |
2337 } | |
2338 #endif | |
2339 | |
2340 | |
771 | 2341 #ifdef HAVE_X_WIDGETS |
428 | 2342 |
2343 /************************************************************************/ | |
2344 /* widgets */ | |
2345 /************************************************************************/ | |
2346 | |
2347 static void | |
440 | 2348 update_widget_face (widget_value* wv, Lisp_Image_Instance *ii, |
434 | 2349 Lisp_Object domain) |
428 | 2350 { |
2351 #ifdef LWLIB_WIDGETS_MOTIF | |
2352 XmFontList fontList; | |
2353 #endif | |
438 | 2354 /* Update the foreground. */ |
2355 Lisp_Object pixel = FACE_FOREGROUND | |
428 | 2356 (IMAGE_INSTANCE_WIDGET_FACE (ii), |
434 | 2357 domain); |
438 | 2358 XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)), bcolor; |
434 | 2359 lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel); |
438 | 2360 |
2361 /* Update the background. */ | |
2362 pixel = FACE_BACKGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), | |
2363 domain); | |
2364 bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); | |
2365 lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel); | |
2366 | |
3094 | 2367 { |
2368 Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (ii); | |
2369 Lisp_Font_Instance *fi = | |
2370 XFONT_INSTANCE (query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (ii), | |
2371 face, | |
2372 domain)); | |
2373 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
|
2374 #ifdef HAVE_XFT |
3094 | 2375 XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi); |
2376 | |
2377 if (rf) | |
2378 { | |
2379 /* #### What to do about Motif? */ | |
4932 | 2380 lw_add_widget_value_arg (wv, (String) XtNxftFont, (XtArgVal) rf); |
3094 | 2381 } |
2382 #endif | |
2383 | |
2384 if (fs) | |
2385 { | |
428 | 2386 #ifdef LWLIB_WIDGETS_MOTIF |
3094 | 2387 fontList = XmFontListCreate (fs, XmSTRING_DEFAULT_CHARSET); |
2388 lw_add_widget_value_arg (wv, XmNfontList, (XtArgVal) fontList); | |
428 | 2389 #endif |
3094 | 2390 lw_add_widget_value_arg (wv, XtNfont, (XtArgVal) fs); |
2391 } | |
2392 | |
4916
a6c778975d7d
split USE_XFT into HAVE_XFT/USE_XFT
Ben Wing <ben@xemacs.org>
parents:
4834
diff
changeset
|
2393 #ifdef HAVE_XFT |
3094 | 2394 /* #### sanity check, should wrap in appropriate ERROR_CHECK macro */ |
2395 if (!rf && !fs) | |
2396 warn_when_safe_lispobj | |
2397 (intern ("xft"), Qdebug, | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
2398 Fcons (build_msg_string ("missing font in update_widget_face"), |
3094 | 2399 Fface_name (face))); |
2400 #endif | |
2401 } | |
442 | 2402 wv->change = VISIBLE_CHANGE; |
2403 /* #### Megahack - but its just getting too complicated to do this | |
2404 in the right place. */ | |
2405 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qtab_control)) | |
2406 update_tab_widget_face (wv, ii, domain); | |
434 | 2407 } |
2408 | |
2409 static void | |
440 | 2410 update_tab_widget_face (widget_value* wv, Lisp_Image_Instance *ii, |
434 | 2411 Lisp_Object domain) |
2412 { | |
2413 if (wv->contents) | |
2414 { | |
2415 widget_value* val = wv->contents, *cur; | |
438 | 2416 |
434 | 2417 /* Give each child label the correct foreground color. */ |
438 | 2418 Lisp_Object pixel = FACE_FOREGROUND |
434 | 2419 (IMAGE_INSTANCE_WIDGET_FACE (ii), |
2420 domain); | |
2421 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
|
2422 lw_add_widget_value_arg (val, (String) XtNtabForeground, fcolor.pixel); |
442 | 2423 wv->change = VISIBLE_CHANGE; |
2424 val->change = VISIBLE_CHANGE; | |
434 | 2425 |
2426 for (cur = val->next; cur; cur = cur->next) | |
2427 { | |
442 | 2428 cur->change = VISIBLE_CHANGE; |
434 | 2429 if (cur->value) |
2430 { | |
2431 lw_copy_widget_value_args (val, cur); | |
2432 } | |
2433 } | |
2434 } | |
428 | 2435 } |
2436 | |
2437 static void | |
2286 | 2438 x_widget_instantiate (Lisp_Object image_instance, |
2439 Lisp_Object UNUSED (instantiator), | |
2440 Lisp_Object UNUSED (pointer_fg), | |
2441 Lisp_Object UNUSED (pointer_bg), | |
2442 int UNUSED (dest_mask), Lisp_Object domain, | |
442 | 2443 const char* type, widget_value* wv) |
428 | 2444 { |
440 | 2445 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2446 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), pixel; |
2447 struct device* d = XDEVICE (device); | |
442 | 2448 Lisp_Object frame = DOMAIN_FRAME (domain); |
428 | 2449 struct frame* f = XFRAME (frame); |
2450 char* nm=0; | |
2451 Widget wid; | |
2452 Arg al [32]; | |
2453 int ac = 0; | |
2454 int id = new_lwlib_id (); | |
2455 widget_value* clip_wv; | |
2456 XColor fcolor, bcolor; | |
2457 | |
2458 if (!DEVICE_X_P (d)) | |
563 | 2459 gui_error ("Not an X device", device); |
428 | 2460 |
2461 /* have to set the type this late in case there is no device | |
2462 instantiation for a widget. But we can go ahead and do it without | |
2463 checking because there is always a generic instantiator. */ | |
2464 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET; | |
2465 | |
2466 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
|
2467 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
|
2468 Qlwlib_encoding); |
428 | 2469 |
2470 ii->data = xnew_and_zero (struct x_subwindow_data); | |
2471 | |
2472 /* Create a clip window to contain the subwidget. Incredibly the | |
2473 XEmacs manager seems to be the most appropriate widget for | |
2474 this. Nothing else is simple enough and yet does what is | |
2475 required. */ | |
2476 clip_wv = xmalloc_widget_value (); | |
2477 | |
434 | 2478 lw_add_widget_value_arg (clip_wv, XtNresize, False); |
438 | 2479 lw_add_widget_value_arg (clip_wv, XtNwidth, |
442 | 2480 (Dimension)IMAGE_INSTANCE_WIDTH (ii)); |
438 | 2481 lw_add_widget_value_arg (clip_wv, XtNheight, |
442 | 2482 (Dimension)IMAGE_INSTANCE_HEIGHT (ii)); |
428 | 2483 clip_wv->enabled = True; |
434 | 2484 |
428 | 2485 clip_wv->name = xstrdup ("clip-window"); |
2486 clip_wv->value = xstrdup ("clip-window"); | |
2487 | |
2488 IMAGE_INSTANCE_X_CLIPWIDGET (ii) | |
2489 = lw_create_widget ("clip-window", "clip-window", new_lwlib_id (), | |
2490 clip_wv, FRAME_X_CONTAINER_WIDGET (f), | |
2491 False, 0, 0, 0); | |
2492 | |
2493 free_widget_value_tree (clip_wv); | |
2494 | |
863 | 2495 /* create a sensible name. */ |
2496 if (wv->name == 0 || strcmp(wv->name, "") == 0) | |
2497 wv->name = xstrdup (type); | |
2498 | |
428 | 2499 /* copy any args we were given */ |
2500 ac = 0; | |
434 | 2501 lw_add_value_args_to_args (wv, al, &ac); |
428 | 2502 |
2503 /* Fixup the colors. We have to do this *before* the widget gets | |
2504 created so that Motif will fix up the shadow colors | |
2505 correctly. Once the widget is created Motif won't do this | |
2506 anymore...*/ | |
438 | 2507 pixel = FACE_FOREGROUND |
428 | 2508 (IMAGE_INSTANCE_WIDGET_FACE (ii), |
442 | 2509 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2510 fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); |
2511 | |
2512 pixel = FACE_BACKGROUND | |
2513 (IMAGE_INSTANCE_WIDGET_FACE (ii), | |
442 | 2514 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2515 bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); |
2516 | |
434 | 2517 lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel); |
2518 lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel); | |
428 | 2519 /* we cannot allow widgets to resize themselves */ |
434 | 2520 lw_add_widget_value_arg (wv, XtNresize, False); |
438 | 2521 lw_add_widget_value_arg (wv, XtNwidth, |
442 | 2522 (Dimension)IMAGE_INSTANCE_WIDTH (ii)); |
438 | 2523 lw_add_widget_value_arg (wv, XtNheight, |
442 | 2524 (Dimension)IMAGE_INSTANCE_HEIGHT (ii)); |
434 | 2525 /* update the font. */ |
2526 update_widget_face (wv, ii, domain); | |
428 | 2527 |
1318 | 2528 wid = lw_create_widget (type, wv->name, id, wv, |
2529 IMAGE_INSTANCE_X_CLIPWIDGET (ii), | |
428 | 2530 False, 0, popup_selection_callback, 0); |
2531 | |
2532 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; | |
2533 IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id; | |
2534 /* because the EmacsManager is the widgets parent we have to | |
2535 offset the redisplay of the widget by the amount the text | |
2536 widget is inside the manager. */ | |
2537 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
|
2538 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
|
2539 Xt_SET_ARG (al [ac], XtNy, &IMAGE_INSTANCE_X_WIDGET_YOFFSET (ii)); ac++; |
428 | 2540 XtGetValues (FRAME_X_TEXT_WIDGET (f), al, ac); |
2541 | |
436 | 2542 XtSetMappedWhenManaged (wid, TRUE); |
428 | 2543 |
2544 free_widget_value_tree (wv); | |
442 | 2545 /* A kludgy but simple way to make sure the callback for a widget |
2546 doesn't get deleted. */ | |
2547 gcpro_popup_callbacks (id); | |
428 | 2548 } |
2549 | |
2550 /* get properties of a control */ | |
2551 static Lisp_Object | |
2552 x_widget_property (Lisp_Object image_instance, Lisp_Object prop) | |
2553 { | |
440 | 2554 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2555 /* get the text from a control */ |
2556 if (EQ (prop, Q_text)) | |
2557 { | |
2558 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
|
2559 return build_extstring (wv->value, Qlwlib_encoding); |
428 | 2560 } |
2561 return Qunbound; | |
2562 } | |
2563 | |
442 | 2564 /* Instantiate a layout control for putting other widgets in. */ |
2565 static void | |
771 | 2566 x_native_layout_instantiate (Lisp_Object image_instance, |
2567 Lisp_Object instantiator, | |
442 | 2568 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2569 int dest_mask, Lisp_Object domain) | |
2570 { | |
2571 x_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2572 pointer_bg, dest_mask, domain, "layout", 0); | |
2573 } | |
2574 | |
428 | 2575 /* Instantiate a button widget. Unfortunately instantiated widgets are |
2576 particular to a frame since they need to have a parent. It's not | |
2577 like images where you just select the image into the context you | |
2578 want to display it in and BitBlt it. So images instances can have a | |
2579 many-to-one relationship with things you see, whereas widgets can | |
2580 only be one-to-one (i.e. per frame) */ | |
2581 static void | |
2582 x_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2583 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2584 int dest_mask, Lisp_Object domain) | |
2585 { | |
440 | 2586 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2587 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
2588 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); | |
442 | 2589 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 1); |
428 | 2590 |
2591 if (!NILP (glyph)) | |
2592 { | |
2593 if (!IMAGE_INSTANCEP (glyph)) | |
2594 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1); | |
2595 } | |
2596 | |
2597 x_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2598 pointer_bg, dest_mask, domain, "button", wv); | |
2599 | |
2600 /* add the image if one was given */ | |
440 | 2601 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph) |
2602 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph))) | |
428 | 2603 { |
2604 Arg al [2]; | |
2605 int ac =0; | |
2606 #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
|
2607 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
|
2608 Xt_SET_ARG (al [ac], XmNlabelPixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph)); |
1318 | 2609 ac++; |
428 | 2610 #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
|
2611 Xt_SET_ARG (al [ac], XtNpixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph)); ac++; |
428 | 2612 #endif |
2613 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac); | |
2614 } | |
2615 } | |
2616 | |
442 | 2617 /* Update a button's clicked state. |
2618 | |
2619 #### This is overkill, but it works. Right now this causes all | |
2620 button instances to flash for some reason buried deep in lwlib. In | |
2621 theory this should be the Right Thing to do since lwlib should only | |
2622 merge in changed values - and if nothing has changed then nothing | |
2623 should get done. This may be because of the args stuff, | |
2624 i.e. although the arg contents may be the same the args look | |
2625 different and so are re-applied to the widget. */ | |
2626 static void | |
2627 x_button_redisplay (Lisp_Object image_instance) | |
2628 { | |
2629 /* This function can GC if IN_REDISPLAY is false. */ | |
2630 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | |
2631 widget_value* wv = | |
2632 gui_items_to_widget_values (image_instance, | |
2633 IMAGE_INSTANCE_WIDGET_ITEMS (p), 1); | |
2634 | |
2635 /* now modify the widget */ | |
1346 | 2636 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), wv, True); |
442 | 2637 free_widget_value_tree (wv); |
1346 | 2638 gcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p)); |
442 | 2639 } |
2640 | |
428 | 2641 /* get properties of a button */ |
2642 static Lisp_Object | |
2643 x_button_property (Lisp_Object image_instance, Lisp_Object prop) | |
2644 { | |
440 | 2645 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2646 /* check the state of a button */ |
2647 if (EQ (prop, Q_selected)) | |
2648 { | |
2649 widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); | |
2650 | |
2651 if (wv->selected) | |
2652 return Qt; | |
2653 else | |
2654 return Qnil; | |
2655 } | |
2656 return Qunbound; | |
2657 } | |
2658 | |
2659 /* instantiate a progress gauge */ | |
2660 static void | |
1318 | 2661 x_progress_gauge_instantiate (Lisp_Object image_instance, |
2662 Lisp_Object instantiator, | |
2663 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2664 int dest_mask, Lisp_Object domain) | |
428 | 2665 { |
440 | 2666 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2667 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
442 | 2668 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0); |
428 | 2669 |
2670 x_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2671 pointer_bg, dest_mask, domain, "progress", wv); | |
2672 } | |
2673 | |
442 | 2674 /* set the properties of a progress gauge */ |
2675 static void | |
2676 x_progress_gauge_redisplay (Lisp_Object image_instance) | |
428 | 2677 { |
639 | 2678 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
2679 | |
2680 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
428 | 2681 { |
442 | 2682 Lisp_Object val; |
639 | 2683 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
|
2684 Xt_SET_VALUE (IMAGE_INSTANCE_X_WIDGET_ID (p), XtNvalue, XINT (val)); |
428 | 2685 } |
2686 } | |
2687 | |
2688 /* instantiate an edit control */ | |
2689 static void | |
2690 x_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
771 | 2691 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2692 int dest_mask, Lisp_Object domain) | |
428 | 2693 { |
440 | 2694 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2695 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
442 | 2696 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0); |
438 | 2697 |
428 | 2698 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2699 pointer_bg, dest_mask, domain, "text-field", wv); | |
2700 } | |
2701 | |
2702 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 | |
2703 /* instantiate a combo control */ | |
2704 static void | |
2705 x_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
771 | 2706 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2707 int dest_mask, Lisp_Object domain) | |
428 | 2708 { |
440 | 2709 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2710 widget_value * wv = 0; |
2711 /* This is not done generically because of sizing problems under | |
2712 mswindows. */ | |
438 | 2713 widget_instantiate (image_instance, instantiator, pointer_fg, |
2714 pointer_bg, dest_mask, domain); | |
428 | 2715 |
442 | 2716 wv = gui_items_to_widget_values (image_instance, |
2717 IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0); | |
438 | 2718 |
428 | 2719 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2720 pointer_bg, dest_mask, domain, "combo-box", wv); | |
2721 } | |
2722 #endif | |
2723 | |
2724 static void | |
1318 | 2725 x_tab_control_instantiate (Lisp_Object image_instance, |
2726 Lisp_Object instantiator, | |
428 | 2727 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2728 int dest_mask, Lisp_Object domain) | |
2729 { | |
440 | 2730 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
438 | 2731 widget_value * wv = |
442 | 2732 gui_items_to_widget_values (image_instance, |
2733 IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0); | |
438 | 2734 update_tab_widget_face (wv, ii, |
442 | 2735 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2736 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2737 pointer_bg, dest_mask, domain, "tab-control", wv); | |
2738 } | |
2739 | |
442 | 2740 /* Set the properties of a tab control */ |
2741 static void | |
2742 x_tab_control_redisplay (Lisp_Object image_instance) | |
428 | 2743 { |
440 | 2744 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
438 | 2745 |
1318 | 2746 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) || |
442 | 2747 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)) |
428 | 2748 { |
442 | 2749 /* If only the order has changed then simply select the first |
2750 one of the pending set. This stops horrendous rebuilding - | |
2751 and hence flicker - of the tabs each time you click on | |
2752 one. */ | |
2753 if (tab_control_order_only_changed (image_instance)) | |
2754 { | |
2755 Lisp_Object rest, selected = | |
2756 gui_item_list_find_selected | |
2757 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ? | |
2758 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) : | |
2759 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); | |
2760 | |
2761 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
2762 { | |
1913 | 2763 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) |
442 | 2764 { |
2765 /* There may be an encapsulated way of doing this, | |
2766 but I couldn't find it. */ | |
1318 | 2767 Lisp_Object old_selected = |
2768 gui_item_list_find_selected | |
442 | 2769 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); |
2770 char* name; | |
2771 unsigned int num_children, i; | |
2772 Widget* children; | |
2773 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2774 name = |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
2775 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
|
2776 Qlwlib_encoding); |
442 | 2777 /* The name may contain a `.' which confuses |
2778 XtNameToWidget, so we do it ourselves. */ | |
1318 | 2779 children = |
2780 XtCompositeChildren (IMAGE_INSTANCE_X_WIDGET_ID (ii), | |
2781 &num_children); | |
442 | 2782 for (i = 0; i < num_children; i++) |
2783 { | |
2784 if (!strcmp (XtName (children [i]), name)) | |
2785 { | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2786 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
|
2787 XtNtopWidget, children [i]); |
442 | 2788 break; |
2789 } | |
2790 } | |
2791 /* Pick up the new selected item. */ | |
2792 XGUI_ITEM (old_selected)->selected = | |
2793 XGUI_ITEM (XCAR (rest))->selected; | |
2794 XGUI_ITEM (XCAR (rest))->selected = | |
2795 XGUI_ITEM (selected)->selected; | |
2796 /* We're not actually changing the items anymore. */ | |
2797 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; | |
2798 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; | |
2799 break; | |
2800 } | |
2801 } | |
2802 } | |
2803 } | |
2804 /* Possibly update the face. */ | |
2805 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) | |
2806 || | |
2807 XFRAME (IMAGE_INSTANCE_FRAME (ii))->faces_changed | |
2808 || | |
2809 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) | |
2810 { | |
2811 /* See previous comments on the brokeness of lwlib. | |
2812 | |
2813 #### There's actually not much point in doing this here | |
2814 since, colors will have been set appropriately by | |
2815 x_redisplay_widget. */ | |
2816 widget_value* wv =copy_widget_value_tree | |
2817 (lw_get_all_values | |
2818 (IMAGE_INSTANCE_X_WIDGET_LWID (ii)), | |
2819 NO_CHANGE); | |
438 | 2820 |
2821 update_tab_widget_face (wv, ii, | |
442 | 2822 IMAGE_INSTANCE_FRAME (ii)); |
428 | 2823 |
2824 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True); | |
2825 free_widget_value_tree (wv); | |
1346 | 2826 gcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); |
428 | 2827 } |
2828 } | |
2829 | |
2830 /* instantiate a static control possible for putting other things in */ | |
2831 static void | |
2832 x_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2833 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2834 int dest_mask, Lisp_Object domain) | |
2835 { | |
440 | 2836 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2837 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); |
442 | 2838 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0); |
438 | 2839 |
428 | 2840 x_widget_instantiate (image_instance, instantiator, pointer_fg, |
2841 pointer_bg, dest_mask, domain, "button", wv); | |
2842 } | |
771 | 2843 #endif /* HAVE_X_WIDGETS */ |
428 | 2844 |
2845 | |
2846 /************************************************************************/ | |
2847 /* initialization */ | |
2848 /************************************************************************/ | |
2849 | |
2850 void | |
2851 syms_of_glyphs_x (void) | |
2852 { | |
2853 #if 0 | |
2854 DEFSUBR (Fchange_subwindow_property); | |
2855 #endif | |
2856 } | |
2857 | |
2858 void | |
2859 console_type_create_glyphs_x (void) | |
2860 { | |
2861 /* image methods */ | |
2862 | |
2863 CONSOLE_HAS_METHOD (x, print_image_instance); | |
2864 CONSOLE_HAS_METHOD (x, finalize_image_instance); | |
2865 CONSOLE_HAS_METHOD (x, image_instance_equal); | |
2866 CONSOLE_HAS_METHOD (x, image_instance_hash); | |
2867 CONSOLE_HAS_METHOD (x, colorize_image_instance); | |
2868 CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage); | |
2869 CONSOLE_HAS_METHOD (x, locate_pixmap_file); | |
2870 CONSOLE_HAS_METHOD (x, unmap_subwindow); | |
2871 CONSOLE_HAS_METHOD (x, map_subwindow); | |
442 | 2872 CONSOLE_HAS_METHOD (x, redisplay_widget); |
2873 CONSOLE_HAS_METHOD (x, redisplay_subwindow); | |
863 | 2874 CONSOLE_HAS_METHOD (x, widget_border_width); |
428 | 2875 } |
2876 | |
2877 void | |
2878 image_instantiator_format_create_glyphs_x (void) | |
2879 { | |
2880 IIFORMAT_VALID_CONSOLE (x, nothing); | |
2881 IIFORMAT_VALID_CONSOLE (x, string); | |
771 | 2882 #ifdef HAVE_X_WIDGETS |
428 | 2883 IIFORMAT_VALID_CONSOLE (x, layout); |
442 | 2884 #endif |
428 | 2885 IIFORMAT_VALID_CONSOLE (x, formatted_string); |
2886 IIFORMAT_VALID_CONSOLE (x, inherit); | |
2887 #ifdef HAVE_XPM | |
2888 INITIALIZE_DEVICE_IIFORMAT (x, xpm); | |
2889 IIFORMAT_HAS_DEVMETHOD (x, xpm, instantiate); | |
2890 #endif | |
2891 #ifdef HAVE_JPEG | |
2892 IIFORMAT_VALID_CONSOLE (x, jpeg); | |
2893 #endif | |
2894 #ifdef HAVE_TIFF | |
2895 IIFORMAT_VALID_CONSOLE (x, tiff); | |
438 | 2896 #endif |
428 | 2897 #ifdef HAVE_PNG |
2898 IIFORMAT_VALID_CONSOLE (x, png); | |
438 | 2899 #endif |
428 | 2900 #ifdef HAVE_GIF |
2901 IIFORMAT_VALID_CONSOLE (x, gif); | |
438 | 2902 #endif |
428 | 2903 INITIALIZE_DEVICE_IIFORMAT (x, xbm); |
2904 IIFORMAT_HAS_DEVMETHOD (x, xbm, instantiate); | |
2905 | |
2906 INITIALIZE_DEVICE_IIFORMAT (x, subwindow); | |
2907 IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate); | |
771 | 2908 #ifdef HAVE_X_WIDGETS |
442 | 2909 /* layout widget */ |
2910 INITIALIZE_DEVICE_IIFORMAT (x, native_layout); | |
2911 IIFORMAT_HAS_DEVMETHOD (x, native_layout, instantiate); | |
428 | 2912 /* button widget */ |
2913 INITIALIZE_DEVICE_IIFORMAT (x, button); | |
2914 IIFORMAT_HAS_DEVMETHOD (x, button, property); | |
2915 IIFORMAT_HAS_DEVMETHOD (x, button, instantiate); | |
442 | 2916 IIFORMAT_HAS_DEVMETHOD (x, button, redisplay); |
2917 /* general widget methods. */ | |
428 | 2918 INITIALIZE_DEVICE_IIFORMAT (x, widget); |
2919 IIFORMAT_HAS_DEVMETHOD (x, widget, property); | |
2920 /* progress gauge */ | |
2921 INITIALIZE_DEVICE_IIFORMAT (x, progress_gauge); | |
442 | 2922 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, redisplay); |
428 | 2923 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, instantiate); |
2924 /* text field */ | |
2925 INITIALIZE_DEVICE_IIFORMAT (x, edit_field); | |
2926 IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate); | |
2927 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 | |
2928 /* combo box */ | |
2929 INITIALIZE_DEVICE_IIFORMAT (x, combo_box); | |
2930 IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate); | |
442 | 2931 IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, redisplay, tab_control); |
428 | 2932 #endif |
2933 /* tab control widget */ | |
2934 INITIALIZE_DEVICE_IIFORMAT (x, tab_control); | |
2935 IIFORMAT_HAS_DEVMETHOD (x, tab_control, instantiate); | |
442 | 2936 IIFORMAT_HAS_DEVMETHOD (x, tab_control, redisplay); |
428 | 2937 /* label */ |
2938 INITIALIZE_DEVICE_IIFORMAT (x, label); | |
2939 IIFORMAT_HAS_DEVMETHOD (x, label, instantiate); | |
2940 #endif | |
2941 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font"); | |
2942 IIFORMAT_VALID_CONSOLE (x, cursor_font); | |
2943 | |
2944 IIFORMAT_HAS_METHOD (cursor_font, validate); | |
2945 IIFORMAT_HAS_METHOD (cursor_font, possible_dest_types); | |
2946 IIFORMAT_HAS_METHOD (cursor_font, instantiate); | |
2947 | |
2948 IIFORMAT_VALID_KEYWORD (cursor_font, Q_data, check_valid_string); | |
2949 IIFORMAT_VALID_KEYWORD (cursor_font, Q_foreground, check_valid_string); | |
2950 IIFORMAT_VALID_KEYWORD (cursor_font, Q_background, check_valid_string); | |
2951 | |
2952 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (font, "font"); | |
2953 | |
2954 IIFORMAT_HAS_METHOD (font, validate); | |
2955 IIFORMAT_HAS_METHOD (font, possible_dest_types); | |
2956 IIFORMAT_HAS_METHOD (font, instantiate); | |
2957 IIFORMAT_VALID_CONSOLE (x, font); | |
2958 | |
2959 IIFORMAT_VALID_KEYWORD (font, Q_data, check_valid_string); | |
2960 IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string); | |
2961 IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string); | |
2962 | |
2963 #ifdef HAVE_XFACE | |
2964 INITIALIZE_DEVICE_IIFORMAT (x, xface); | |
2965 IIFORMAT_HAS_DEVMETHOD (x, xface, instantiate); | |
2966 #endif | |
2967 | |
2968 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect, | |
2969 "autodetect"); | |
2970 | |
2971 IIFORMAT_HAS_METHOD (autodetect, validate); | |
2972 IIFORMAT_HAS_METHOD (autodetect, normalize); | |
2973 IIFORMAT_HAS_METHOD (autodetect, possible_dest_types); | |
4252 | 2974 /* #### autodetect is flawed IMO: |
446 | 2975 1. It makes the assumption that you can detect whether the user |
2976 wanted a cursor or a string based on the data, since the data is a | |
2977 string you have to prioritise cursors. Instead we will force users | |
2978 to pick the appropriate image type, this is what we do under | |
2979 MS-Windows anyway. | |
2980 2. It doesn't fit with the new domain model - you cannot tell which | |
2981 domain it needs to be instantiated in until you've actually | |
2982 instantiated it, which mucks up caching. | |
2983 3. It only copes with cursors and strings which seems bogus. */ | |
2984 IIFORMAT_HAS_SHARED_METHOD (autodetect, governing_domain, subwindow); | |
428 | 2985 IIFORMAT_HAS_METHOD (autodetect, instantiate); |
2986 IIFORMAT_VALID_CONSOLE (x, autodetect); | |
2987 | |
2988 IIFORMAT_VALID_KEYWORD (autodetect, Q_data, check_valid_string); | |
2989 } | |
2990 | |
2991 void | |
2992 vars_of_glyphs_x (void) | |
2993 { | |
2994 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path /* | |
2995 A list of the directories in which X bitmap files may be found. | |
2996 If nil, this is initialized from the "*bitmapFilePath" resource. | |
2997 This is used by the `make-image-instance' function (however, note that if | |
2998 the environment variable XBMLANGPATH is set, it is consulted first). | |
2999 */ ); | |
3000 Vx_bitmap_file_path = Qnil; | |
3001 } | |
3002 | |
3003 void | |
3004 complex_vars_of_glyphs_x (void) | |
3005 { | |
3006 #define BUILD_GLYPH_INST(variable, name) \ | |
3007 Fadd_spec_to_specifier \ | |
3008 (GLYPH_IMAGE (XGLYPH (variable)), \ | |
3009 vector3 (Qxbm, Q_data, \ | |
3010 list3 (make_int (name##_width), \ | |
3011 make_int (name##_height), \ | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
3012 make_extstring ((Extbyte *) name##_bits, \ |
428 | 3013 sizeof (name##_bits), \ |
440 | 3014 Qbinary))), \ |
428 | 3015 Qglobal, Qx, Qnil) |
3016 | |
3017 BUILD_GLYPH_INST (Vtruncation_glyph, truncator); | |
3018 BUILD_GLYPH_INST (Vcontinuation_glyph, continuer); | |
3019 BUILD_GLYPH_INST (Vxemacs_logo, xemacs); | |
3020 BUILD_GLYPH_INST (Vhscroll_glyph, hscroll); | |
3021 | |
3022 #undef BUILD_GLYPH_INST | |
3023 } |