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