Mercurial > hg > xemacs-beta
annotate src/glyphs-x.c @ 5518:3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
2011-06-03 Aidan Kehoe <kehoea@parhasard.net>
* gnuslib.c (connect_to_unix_server):
Retry with /tmp as a directory in which to search for Unix sockets
if an attempt to connect with some other directory failed (which
may be because gnuclient and gnuserv don't share an environment
value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR
turned off).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Fri, 03 Jun 2011 18:40:57 +0100 |
parents | 308d34e9f07d |
children | 56144c8593a8 |
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 | |
752 if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii))) | |
753 xhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)); | |
754 if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii))) | |
755 yhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)); | |
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)) ? | |
1204 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) : 0, | |
1205 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) ? | |
1206 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) : 0); | |
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), |
1233 XINT (XCAR (mask_data)), | |
1234 XINT (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, | |
1258 pointer_bg, dest_mask, XINT (XCAR (data)), | |
440 | 1259 XINT (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", | |
1519 make_int (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) |
1560 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (xpmattrs.x_hotspot); | |
1561 if (xpmattrs.valuemask & XpmHotspot) | |
1562 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (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) | |
1711 alist = Fcons (Fcons (Q_hotspot_x, make_int (xhot)), | |
1712 alist); | |
1713 if (yhot != -1) | |
1714 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)), | |
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; |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2682 Xt_SET_VALUE (IMAGE_INSTANCE_X_WIDGET_ID (p), XtNvalue, XINT (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, \ | |
3008 list3 (make_int (name##_width), \ | |
3009 make_int (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 } |