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