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