428
+ − 1 /* mswindows-specific glyph objects.
438
+ − 2 Copyright (C) 1998, 1999, 2000 Andy Piper.
434
+ − 3
428
+ − 4 This file is part of XEmacs.
+ − 5
+ − 6 XEmacs is free software; you can redistribute it and/or modify it
+ − 7 under the terms of the GNU General Public License as published by the
+ − 8 Free Software Foundation; either version 2, or (at your option) any
+ − 9 later version.
+ − 10
+ − 11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 14 for more details.
+ − 15
+ − 16 You should have received a copy of the GNU General Public License
+ − 17 along with XEmacs; see the file COPYING. If not, write to
+ − 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 19 Boston, MA 02111-1307, USA. */
+ − 20
+ − 21 /* Synched up with: Not in FSF. */
+ − 22
442
+ − 23 /* written by Andy Piper <andy@xemacs.org> plagiarising bits from
428
+ − 24 glyphs-x.c */
+ − 25
+ − 26 #include <config.h>
+ − 27 #include "lisp.h"
+ − 28 #include "lstream.h"
+ − 29
+ − 30 #define OEMRESOURCE /* Define OCR_ and friend constants */
+ − 31 #include "console-msw.h"
+ − 32 #include "glyphs-msw.h"
+ − 33 #include "objects-msw.h"
+ − 34
+ − 35 #include "window.h"
+ − 36 #include "elhash.h"
+ − 37 #include "buffer.h"
+ − 38 #include "frame.h"
+ − 39 #include "insdel.h"
+ − 40 #include "opaque.h"
+ − 41 #include "sysfile.h"
+ − 42 #include "faces.h"
+ − 43 #include "imgproc.h"
+ − 44
+ − 45 #ifdef FILE_CODING
+ − 46 #include "file-coding.h"
+ − 47 #endif
+ − 48 #include <stdio.h>
+ − 49 #include <ctype.h>
+ − 50 #ifdef HAVE_XFACE
+ − 51 #include <setjmp.h>
+ − 52 #endif
+ − 53
+ − 54 #define WIDGET_GLYPH_SLOT 0
+ − 55
+ − 56 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
+ − 57 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
+ − 58 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
+ − 59 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
+ − 60 #ifdef HAVE_JPEG
+ − 61 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
+ − 62 #endif
+ − 63 #ifdef HAVE_TIFF
+ − 64 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff);
434
+ − 65 #endif
428
+ − 66 #ifdef HAVE_PNG
+ − 67 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png);
434
+ − 68 #endif
428
+ − 69 #ifdef HAVE_GIF
+ − 70 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif);
434
+ − 71 #endif
428
+ − 72 #ifdef HAVE_XPM
+ − 73 DEFINE_DEVICE_IIFORMAT (mswindows, xpm);
442
+ − 74 DEFINE_DEVICE_IIFORMAT (msprinter, xpm);
428
+ − 75 #endif
+ − 76 DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
442
+ − 77 DEFINE_DEVICE_IIFORMAT (msprinter, xbm);
428
+ − 78 #ifdef HAVE_XFACE
+ − 79 DEFINE_DEVICE_IIFORMAT (mswindows, xface);
442
+ − 80 DEFINE_DEVICE_IIFORMAT (msprinter, xface);
428
+ − 81 #endif
442
+ − 82 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
+ − 83 DEFINE_DEVICE_IIFORMAT (mswindows, native_layout);
428
+ − 84 DEFINE_DEVICE_IIFORMAT (mswindows, button);
+ − 85 DEFINE_DEVICE_IIFORMAT (mswindows, edit_field);
+ − 86 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
+ − 87 DEFINE_DEVICE_IIFORMAT (mswindows, widget);
+ − 88 DEFINE_DEVICE_IIFORMAT (mswindows, label);
+ − 89 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
+ − 90 DEFINE_DEVICE_IIFORMAT (mswindows, combo_box);
+ − 91 DEFINE_DEVICE_IIFORMAT (mswindows, progress_gauge);
+ − 92 DEFINE_DEVICE_IIFORMAT (mswindows, tree_view);
+ − 93 DEFINE_DEVICE_IIFORMAT (mswindows, tab_control);
+ − 94
+ − 95 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
+ − 96 Lisp_Object Qbmp;
+ − 97 Lisp_Object Vmswindows_bitmap_file_path;
+ − 98 static COLORREF transparent_color = RGB (1,1,1);
+ − 99
+ − 100 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource);
+ − 101 Lisp_Object Q_resource_type, Q_resource_id;
+ − 102 Lisp_Object Qmswindows_resource;
+ − 103
+ − 104 static void
440
+ − 105 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
428
+ − 106 int slices,
+ − 107 enum image_instance_type type);
+ − 108 static void
440
+ − 109 mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
442
+ − 110 HDC hcdc);
+ − 111
+ − 112 /*
+ − 113 * Given device D, retrieve compatible device context. D can be either
+ − 114 * mswindows or an msprinter device.
+ − 115 */
+ − 116 inline static HDC
+ − 117 get_device_compdc (struct device *d)
+ − 118 {
+ − 119 if (DEVICE_MSWINDOWS_P (d))
+ − 120 return DEVICE_MSWINDOWS_HCDC (d);
+ − 121 else
+ − 122 return DEVICE_MSPRINTER_HCDC (d);
+ − 123 }
+ − 124
+ − 125 /*
+ − 126 * Initialize image instance pixel sizes in II. For a display bitmap,
+ − 127 * these will be same as real bitmap sizes. For a printer bitmap,
+ − 128 * these will be scaled up so that the bitmap is proportionally enlarged
+ − 129 * when output to printer. Redisplay code takes care of scaling, to
+ − 130 * conserve memory we do not really scale bitmaps. Set the watermark
+ − 131 * only here.
+ − 132 * #### Add support for unscalable bitmaps.
+ − 133 */
+ − 134 static void init_image_instance_geometry (Lisp_Image_Instance *ii)
+ − 135 {
+ − 136 struct device *d = DOMAIN_XDEVICE (ii->domain);
+ − 137
+ − 138 if (/* #### Scaleable && */ DEVICE_MSPRINTER_P (d))
+ − 139 {
+ − 140 HDC printer_dc = DEVICE_MSPRINTER_HCDC (d);
+ − 141 HDC display_dc = CreateCompatibleDC (NULL);
+ − 142 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
+ − 143 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
+ − 144 GetDeviceCaps (printer_dc, LOGPIXELSX),
+ − 145 GetDeviceCaps (display_dc, LOGPIXELSX));
+ − 146 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
+ − 147 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
+ − 148 GetDeviceCaps (printer_dc, LOGPIXELSY),
+ − 149 GetDeviceCaps (display_dc, LOGPIXELSY));
+ − 150 }
+ − 151 else
+ − 152 {
+ − 153 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
+ − 154 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii);
+ − 155 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
+ − 156 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii);
+ − 157 }
+ − 158 }
428
+ − 159
+ − 160 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
+ − 161
+ − 162 /************************************************************************/
+ − 163 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
+ − 164 /* proper display */
+ − 165 /************************************************************************/
+ − 166 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
+ − 167 int width, int height,
+ − 168 unsigned char *pic,
+ − 169 int *bit_count,
+ − 170 unsigned char** bmp_data)
+ − 171 {
+ − 172 struct device *d = XDEVICE (device);
+ − 173 int i,j;
+ − 174 RGBQUAD* colortbl;
+ − 175 int ncolors;
+ − 176 BITMAPINFO* bmp_info;
+ − 177 unsigned char *ip, *dp;
+ − 178
442
+ − 179 if (GetDeviceCaps (get_device_compdc (d), BITSPIXEL) > 0)
428
+ − 180 {
+ − 181 int bpline = BPLINE(width * 3);
+ − 182 /* FIXME: we can do this because 24bpp implies no color table, once
+ − 183 * we start palettizing this is no longer true. The X versions of
+ − 184 * this function quantises to 256 colors or bit masks down to a
+ − 185 * long. Windows can actually handle rgb triples in the raw so I
+ − 186 * don't see much point trying to optimize down to the best
+ − 187 * structure - unless it has memory / color allocation implications
+ − 188 * .... */
+ − 189 bmp_info=xnew_and_zero (BITMAPINFO);
434
+ − 190
428
+ − 191 if (!bmp_info)
+ − 192 {
+ − 193 return NULL;
+ − 194 }
+ − 195
+ − 196 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
+ − 197 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
434
+ − 198 bmp_info->bmiHeader.biSizeImage=width*height*3;
428
+ − 199
+ − 200 /* bitmap data needs to be in blue, green, red triples - in that
+ − 201 order, eimage is in RGB format so we need to convert */
+ − 202 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
+ − 203 *bit_count = bpline * height;
+ − 204
+ − 205 if (!bmp_data)
+ − 206 {
+ − 207 xfree (bmp_info);
+ − 208 return NULL;
+ − 209 }
+ − 210
+ − 211 ip = pic;
+ − 212 for (i = height-1; i >= 0; i--) {
+ − 213 dp = (*bmp_data) + (i * bpline);
+ − 214 for (j = 0; j < width; j++) {
+ − 215 dp[2] =*ip++;
+ − 216 dp[1] =*ip++;
+ − 217 *dp =*ip++;
+ − 218 dp += 3;
+ − 219 }
+ − 220 }
+ − 221 }
+ − 222 else /* scale to 256 colors */
+ − 223 {
+ − 224 int rd,gr,bl;
+ − 225 quant_table *qtable;
+ − 226 int bpline = BPLINE (width * 3);
+ − 227 /* Quantize the image and get a histogram while we're at it.
+ − 228 Do this first to save memory */
+ − 229 qtable = build_EImage_quantable(pic, width, height, 256);
+ − 230 if (qtable == NULL) return NULL;
+ − 231
+ − 232 /* use our quantize table to allocate the colors */
+ − 233 ncolors = qtable->num_active_colors;
434
+ − 234 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
428
+ − 235 sizeof(RGBQUAD) * ncolors);
+ − 236 if (!bmp_info)
+ − 237 {
+ − 238 xfree (qtable);
+ − 239 return NULL;
+ − 240 }
+ − 241
+ − 242 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
+ − 243
434
+ − 244 bmp_info->bmiHeader.biBitCount=8;
+ − 245 bmp_info->bmiHeader.biCompression=BI_RGB;
428
+ − 246 bmp_info->bmiHeader.biSizeImage=bpline*height;
434
+ − 247 bmp_info->bmiHeader.biClrUsed=ncolors;
+ − 248 bmp_info->bmiHeader.biClrImportant=ncolors;
+ − 249
428
+ − 250 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
+ − 251 *bit_count = bpline * height;
+ − 252
+ − 253 if (!*bmp_data)
+ − 254 {
+ − 255 xfree (qtable);
+ − 256 xfree (bmp_info);
+ − 257 return NULL;
+ − 258 }
434
+ − 259
428
+ − 260 /* build up an RGBQUAD colortable */
442
+ − 261 for (i = 0; i < qtable->num_active_colors; i++)
+ − 262 {
+ − 263 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
+ − 264 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
+ − 265 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
+ − 266 colortbl[i].rgbReserved = 0;
+ − 267 }
428
+ − 268
+ − 269 /* now build up the data. picture has to be upside-down and
+ − 270 back-to-front for msw bitmaps */
+ − 271 ip = pic;
442
+ − 272 for (i = height-1; i >= 0; i--)
+ − 273 {
+ − 274 dp = (*bmp_data) + (i * bpline);
+ − 275 for (j = 0; j < width; j++)
+ − 276 {
+ − 277 rd = *ip++;
+ − 278 gr = *ip++;
+ − 279 bl = *ip++;
+ − 280 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
+ − 281 }
428
+ − 282 }
+ − 283 xfree (qtable);
434
+ − 284 }
428
+ − 285 /* fix up the standard stuff */
+ − 286 bmp_info->bmiHeader.biWidth=width;
+ − 287 bmp_info->bmiHeader.biHeight=height;
+ − 288 bmp_info->bmiHeader.biPlanes=1;
+ − 289 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ − 290 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
434
+ − 291 bmp_info->bmiHeader.biYPelsPerMeter=0;
428
+ − 292
+ − 293 return bmp_info;
+ − 294 }
+ − 295
+ − 296 /* Given a pixmap filename, look through all of the "standard" places
+ − 297 where the file might be located. Return a full pathname if found;
+ − 298 otherwise, return Qnil. */
+ − 299
+ − 300 static Lisp_Object
+ − 301 mswindows_locate_pixmap_file (Lisp_Object name)
+ − 302 {
+ − 303 /* This function can GC if IN_REDISPLAY is false */
+ − 304 Lisp_Object found;
+ − 305
+ − 306 /* Check non-absolute pathnames with a directory component relative to
+ − 307 the search path; that's the way Xt does it. */
+ − 308 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
+ − 309 (XSTRING_BYTE (name, 0) == '.' &&
+ − 310 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
+ − 311 (XSTRING_BYTE (name, 1) == '.' &&
+ − 312 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
+ − 313 {
+ − 314 if (!NILP (Ffile_readable_p (name)))
440
+ − 315 return Fexpand_file_name (name, Qnil);
428
+ − 316 else
+ − 317 return Qnil;
+ − 318 }
+ − 319
+ − 320 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
+ − 321 {
+ − 322 Lisp_Object temp = list1 (Vdata_directory);
+ − 323 struct gcpro gcpro1;
+ − 324
+ − 325 GCPRO1 (temp);
+ − 326 locate_file (temp, name, Qnil, &found, R_OK);
+ − 327 UNGCPRO;
+ − 328 }
434
+ − 329
428
+ − 330 return found;
+ − 331 }
+ − 332
+ − 333
+ − 334 /* Initialize an image instance from a bitmap
+ − 335
+ − 336 DEST_MASK specifies the mask of allowed image types.
+ − 337
+ − 338 If this fails, signal an error. INSTANTIATOR is only used
+ − 339 in the error message. */
+ − 340
+ − 341 static void
440
+ − 342 init_image_instance_from_dibitmap (Lisp_Image_Instance *ii,
428
+ − 343 BITMAPINFO *bmp_info,
+ − 344 int dest_mask,
+ − 345 void *bmp_data,
+ − 346 int bmp_bits,
+ − 347 int slices,
434
+ − 348 Lisp_Object instantiator,
428
+ − 349 int x_hot, int y_hot,
+ − 350 int create_mask)
+ − 351 {
442
+ − 352 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii));
428
+ − 353 void* bmp_buf=0;
442
+ − 354 enum image_instance_type type;
428
+ − 355 HBITMAP bitmap;
+ − 356 HDC hdc;
+ − 357
+ − 358 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
+ − 359 type = IMAGE_COLOR_PIXMAP;
+ − 360 else if (dest_mask & IMAGE_POINTER_MASK)
+ − 361 type = IMAGE_POINTER;
434
+ − 362 else
428
+ − 363 incompatible_image_types (instantiator, dest_mask,
+ − 364 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
442
+ − 365
+ − 366 hdc = get_device_compdc (d);
+ − 367 bitmap = CreateDIBSection (hdc,
+ − 368 bmp_info,
+ − 369 DIB_RGB_COLORS,
+ − 370 &bmp_buf,
+ − 371 0, 0);
428
+ − 372
+ − 373 if (!bitmap || !bmp_buf)
+ − 374 signal_simple_error ("Unable to create bitmap", instantiator);
+ − 375
+ − 376 /* copy in the actual bitmap */
+ − 377 memcpy (bmp_buf, bmp_data, bmp_bits);
+ − 378
+ − 379 mswindows_initialize_dibitmap_image_instance (ii, slices, type);
+ − 380
+ − 381 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
+ − 382 find_keyword_in_vector (instantiator, Q_file);
+ − 383
+ − 384 /* Fixup a set of bitmaps. */
+ − 385 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
+ − 386
+ − 387 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
442
+ − 388 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
+ − 389 bmp_info->bmiHeader.biWidth;
+ − 390 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
+ − 391 bmp_info->bmiHeader.biHeight;
+ − 392 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
428
+ − 393 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
+ − 394 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
442
+ − 395 init_image_instance_geometry (ii);
428
+ − 396
+ − 397 if (create_mask)
+ − 398 {
442
+ − 399 mswindows_initialize_image_instance_mask (ii, hdc);
428
+ − 400 }
434
+ − 401
428
+ − 402 if (type == IMAGE_POINTER)
+ − 403 {
+ − 404 mswindows_initialize_image_instance_icon(ii, TRUE);
+ − 405 }
+ − 406 }
+ − 407
+ − 408 static void
440
+ − 409 image_instance_add_dibitmap (Lisp_Image_Instance *ii,
428
+ − 410 BITMAPINFO *bmp_info,
+ − 411 void *bmp_data,
+ − 412 int bmp_bits,
+ − 413 int slice,
+ − 414 Lisp_Object instantiator)
+ − 415 {
442
+ − 416 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii));
428
+ − 417 void* bmp_buf=0;
442
+ − 418
+ − 419 HBITMAP bitmap = CreateDIBSection (get_device_compdc (d),
428
+ − 420 bmp_info,
+ − 421 DIB_RGB_COLORS,
434
+ − 422 &bmp_buf,
428
+ − 423 0,0);
434
+ − 424
428
+ − 425 if (!bitmap || !bmp_buf)
+ − 426 signal_simple_error ("Unable to create bitmap", instantiator);
+ − 427
+ − 428 /* copy in the actual bitmap */
+ − 429 memcpy (bmp_buf, bmp_data, bmp_bits);
+ − 430 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (ii, slice) = bitmap;
+ − 431 }
+ − 432
+ − 433 static void
440
+ − 434 mswindows_init_image_instance_from_eimage (Lisp_Image_Instance *ii,
428
+ − 435 int width, int height,
+ − 436 int slices,
434
+ − 437 unsigned char *eimage,
428
+ − 438 int dest_mask,
+ − 439 Lisp_Object instantiator,
+ − 440 Lisp_Object domain)
+ − 441 {
+ − 442 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+ − 443 BITMAPINFO* bmp_info;
+ − 444 unsigned char* bmp_data;
+ − 445 int bmp_bits;
+ − 446 COLORREF bkcolor;
+ − 447 int slice;
434
+ − 448
442
+ − 449 CHECK_MSGDI_DEVICE (device);
428
+ − 450
+ − 451 /* this is a hack but MaskBlt and TransparentBlt are not supported
+ − 452 on most windows variants */
434
+ − 453 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
428
+ − 454 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
+ − 455
+ − 456 for (slice = 0; slice < slices; slice++)
+ − 457 {
+ − 458 /* build a bitmap from the eimage */
434
+ − 459 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height,
428
+ − 460 eimage + (width * height * 3 * slice),
+ − 461 &bmp_bits, &bmp_data)))
+ − 462 {
+ − 463 signal_simple_error ("EImage to DIBitmap conversion failed",
+ − 464 instantiator);
+ − 465 }
+ − 466
+ − 467 /* Now create the pixmap and set up the image instance */
+ − 468 if (slice == 0)
+ − 469 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
+ − 470 bmp_data, bmp_bits, slices, instantiator,
+ − 471 0, 0, 0);
+ − 472 else
+ − 473 image_instance_add_dibitmap (ii, bmp_info, bmp_data, bmp_bits, slice,
+ − 474 instantiator);
434
+ − 475
428
+ − 476 xfree (bmp_info);
+ − 477 xfree (bmp_data);
+ − 478 }
+ − 479 }
+ − 480
442
+ − 481 inline static void
+ − 482 set_mono_pixel (unsigned char* bits,
+ − 483 int bpline, int height,
+ − 484 int x, int y, int white)
434
+ − 485 {
438
+ − 486 int i;
442
+ − 487 unsigned char bitnum;
428
+ − 488 /* Find the byte on which this scanline begins */
438
+ − 489 i = (height - y - 1) * bpline;
428
+ − 490 /* Find the byte containing this pixel */
438
+ − 491 i += (x >> 3);
428
+ − 492 /* Which bit is it? */
442
+ − 493 bitnum = (unsigned char) (7 - (x & 7));
+ − 494 if (white) /* Turn it on */
+ − 495 bits[i] |= (1 << bitnum);
+ − 496 else /* Turn it off */
+ − 497 bits[i] &= ~(1 << bitnum);
434
+ − 498 }
428
+ − 499
+ − 500 static void
440
+ − 501 mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
442
+ − 502 HDC hcdc)
428
+ − 503 {
+ − 504 HBITMAP mask;
+ − 505 HGDIOBJ old = NULL;
442
+ − 506 unsigned char *dibits, *and_bits;
+ − 507 BITMAPINFO *bmp_info =
+ − 508 (BITMAPINFO*) xmalloc_and_zero (sizeof (BITMAPINFO) + sizeof (RGBQUAD));
428
+ − 509 int i, j;
442
+ − 510 int height = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (image);
+ − 511
+ − 512 int maskbpline = BPLINE ((IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) + 7) / 8);
+ − 513 int bpline = BPLINE (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) * 3);
428
+ − 514
+ − 515 if (!bmp_info)
+ − 516 return;
+ − 517
442
+ − 518 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
428
+ − 519 bmp_info->bmiHeader.biHeight = height;
442
+ − 520 bmp_info->bmiHeader.biPlanes = 1;
428
+ − 521 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
442
+ − 522 bmp_info->bmiHeader.biBitCount = 1;
+ − 523 bmp_info->bmiHeader.biCompression = BI_RGB;
434
+ − 524 bmp_info->bmiHeader.biClrUsed = 2;
+ − 525 bmp_info->bmiHeader.biClrImportant = 2;
+ − 526 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
428
+ − 527 bmp_info->bmiColors[0].rgbRed = 0;
+ − 528 bmp_info->bmiColors[0].rgbGreen = 0;
+ − 529 bmp_info->bmiColors[0].rgbBlue = 0;
+ − 530 bmp_info->bmiColors[0].rgbReserved = 0;
+ − 531 bmp_info->bmiColors[1].rgbRed = 255;
+ − 532 bmp_info->bmiColors[1].rgbGreen = 255;
+ − 533 bmp_info->bmiColors[1].rgbBlue = 255;
+ − 534 bmp_info->bmiColors[0].rgbReserved = 0;
434
+ − 535
+ − 536 if (!(mask = CreateDIBSection (hcdc,
428
+ − 537 bmp_info,
+ − 538 DIB_RGB_COLORS,
442
+ − 539 (void**)&and_bits,
428
+ − 540 0,0)))
+ − 541 {
+ − 542 xfree (bmp_info);
+ − 543 return;
+ − 544 }
+ − 545
+ − 546 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
+ − 547 /* build up an in-memory set of bits to mess with */
+ − 548 xzero (*bmp_info);
+ − 549
442
+ − 550 bmp_info->bmiHeader.biWidth = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
428
+ − 551 bmp_info->bmiHeader.biHeight = -height;
442
+ − 552 bmp_info->bmiHeader.biPlanes = 1;
+ − 553 bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ − 554 bmp_info->bmiHeader.biBitCount = 24;
+ − 555 bmp_info->bmiHeader.biCompression = BI_RGB;
434
+ − 556 bmp_info->bmiHeader.biClrUsed = 0;
+ − 557 bmp_info->bmiHeader.biClrImportant = 0;
428
+ − 558 bmp_info->bmiHeader.biSizeImage = height * bpline;
+ − 559
442
+ − 560 dibits = (unsigned char*) xmalloc_and_zero (bpline * height);
428
+ − 561 if (GetDIBits (hcdc,
+ − 562 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
+ − 563 0,
+ − 564 height,
+ − 565 dibits,
+ − 566 bmp_info,
+ − 567 DIB_RGB_COLORS) <= 0)
+ − 568 {
+ − 569 xfree (bmp_info);
+ − 570 return;
+ − 571 }
+ − 572
+ − 573 /* now set the colored bits in the mask and transparent ones to
+ − 574 black in the original */
442
+ − 575 for (i = 0; i < IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); i++)
434
+ − 576 {
442
+ − 577 for (j=0; j<height; j++)
434
+ − 578 {
428
+ − 579 unsigned char* idx = &dibits[j * bpline + i * 3];
+ − 580
442
+ − 581 if (RGB (idx[2], idx[1], idx[0]) == transparent_color)
434
+ − 582 {
428
+ − 583 idx[0] = idx[1] = idx[2] = 0;
442
+ − 584 set_mono_pixel (and_bits, maskbpline, height, i, j, TRUE);
428
+ − 585 }
434
+ − 586 else
+ − 587 {
442
+ − 588 set_mono_pixel (and_bits, maskbpline, height, i, j, FALSE);
428
+ − 589 }
+ − 590 }
+ − 591 }
+ − 592
+ − 593 SetDIBits (hcdc,
+ − 594 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
+ − 595 0,
+ − 596 height,
+ − 597 dibits,
+ − 598 bmp_info,
+ − 599 DIB_RGB_COLORS);
+ − 600
+ − 601 xfree (bmp_info);
+ − 602 xfree (dibits);
434
+ − 603
428
+ − 604 SelectObject(hcdc, old);
+ − 605
+ − 606 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
+ − 607 }
+ − 608
+ − 609 void
440
+ − 610 mswindows_initialize_image_instance_icon (Lisp_Image_Instance* image,
428
+ − 611 int cursor)
+ − 612 {
+ − 613 ICONINFO x_icon;
+ − 614
+ − 615 /* we rely on windows to do any resizing necessary */
+ − 616 x_icon.fIcon=cursor ? FALSE : TRUE;
+ − 617 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
+ − 618 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
+ − 619 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
+ − 620 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
434
+ − 621
428
+ − 622 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
+ − 623 CreateIconIndirect (&x_icon);
+ − 624 }
+ − 625
442
+ − 626 static HBITMAP
+ − 627 create_resized_bitmap (HBITMAP curbmp, struct frame *f,
+ − 628 int curx, int cury,
+ − 629 int newx, int newy)
428
+ − 630 {
+ − 631 HBITMAP newbmp;
+ − 632 HGDIOBJ old1, old2;
442
+ − 633
+ − 634 HDC hcdc = get_device_compdc (XDEVICE (FRAME_DEVICE (f)));
434
+ − 635 HDC hdcDst = CreateCompatibleDC (hcdc);
+ − 636
442
+ − 637 old1 = SelectObject (hcdc, curbmp);
434
+ − 638
428
+ − 639 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
+ − 640
+ − 641 old2 = SelectObject (hdcDst, newbmp);
434
+ − 642
428
+ − 643 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
434
+ − 644 hcdc, 0, 0,
442
+ − 645 curx,
+ − 646 cury,
428
+ − 647 SRCCOPY))
+ − 648 {
+ − 649 DeleteObject (newbmp);
+ − 650 DeleteDC (hdcDst);
+ − 651 return 0;
+ − 652 }
+ − 653
+ − 654 SelectObject (hdcDst, old2);
+ − 655 SelectObject (hcdc, old1);
+ − 656 DeleteDC (hdcDst);
+ − 657
+ − 658 return newbmp;
+ − 659 }
+ − 660
+ − 661 HBITMAP
442
+ − 662 mswindows_create_resized_bitmap (Lisp_Image_Instance* ii,
+ − 663 struct frame* f,
+ − 664 int newx, int newy)
+ − 665 {
+ − 666 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii),
+ − 667 f,
+ − 668 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
+ − 669 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
+ − 670 newx, newy);
+ − 671 }
+ − 672
+ − 673 HBITMAP
440
+ − 674 mswindows_create_resized_mask (Lisp_Image_Instance* ii,
428
+ − 675 struct frame* f,
+ − 676 int newx, int newy)
+ − 677 {
442
+ − 678 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii) == NULL)
+ − 679 return NULL;
+ − 680
+ − 681 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_MASK (ii),
+ − 682 f,
+ − 683 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
+ − 684 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
+ − 685 newx, newy);
428
+ − 686 }
+ − 687
442
+ − 688 #if 0 /* Currently unused */
+ − 689 /* #### Warning: This function is not correct anymore with
+ − 690 resizable printer bitmaps. If you uncomment it, clean it. --kkm */
428
+ − 691 int
440
+ − 692 mswindows_resize_dibitmap_instance (Lisp_Image_Instance* ii,
428
+ − 693 struct frame* f,
+ − 694 int newx, int newy)
+ − 695 {
+ − 696 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
+ − 697 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
+ − 698
+ − 699 if (!newbmp)
+ − 700 return FALSE;
434
+ − 701
428
+ − 702 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
+ − 703 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
+ − 704 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
+ − 705 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
+ − 706
+ − 707 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
+ − 708 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
+ − 709 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
+ − 710 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
+ − 711
+ − 712 return TRUE;
+ − 713 }
442
+ − 714 #endif
428
+ − 715
+ − 716 /**********************************************************************
+ − 717 * XPM *
+ − 718 **********************************************************************/
+ − 719
+ − 720 #ifdef HAVE_XPM
+ − 721
+ − 722 struct color_symbol
+ − 723 {
+ − 724 char* name;
+ − 725 COLORREF color;
+ − 726 };
+ − 727
+ − 728 static struct color_symbol*
+ − 729 extract_xpm_color_names (Lisp_Object device,
+ − 730 Lisp_Object domain,
+ − 731 Lisp_Object color_symbol_alist,
+ − 732 int* nsymbols)
+ − 733 {
+ − 734 /* This function can GC */
+ − 735 Lisp_Object rest;
+ − 736 Lisp_Object results = Qnil;
+ − 737 int i, j;
+ − 738 struct color_symbol *colortbl;
+ − 739 struct gcpro gcpro1, gcpro2;
+ − 740
+ − 741 GCPRO2 (results, device);
+ − 742
+ − 743 /* We built up results to be (("name" . #<color>) ...) so that if an
+ − 744 error happens we don't lose any malloc()ed data, or more importantly,
+ − 745 leave any pixels allocated in the server. */
+ − 746 i = 0;
+ − 747 LIST_LOOP (rest, color_symbol_alist)
+ − 748 {
+ − 749 Lisp_Object cons = XCAR (rest);
+ − 750 Lisp_Object name = XCAR (cons);
+ − 751 Lisp_Object value = XCDR (cons);
+ − 752 if (NILP (value))
+ − 753 continue;
+ − 754 if (STRINGP (value))
+ − 755 value =
+ − 756 Fmake_color_instance
+ − 757 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
+ − 758 else
+ − 759 {
+ − 760 assert (COLOR_SPECIFIERP (value));
+ − 761 value = Fspecifier_instance (value, domain, Qnil, Qnil);
+ − 762 }
+ − 763 if (NILP (value))
+ − 764 continue;
+ − 765 results = noseeum_cons (noseeum_cons (name, value), results);
+ − 766 i++;
+ − 767 }
+ − 768 UNGCPRO; /* no more evaluation */
+ − 769
+ − 770 *nsymbols=i;
+ − 771 if (i == 0) return 0;
+ − 772
+ − 773 colortbl = xnew_array_and_zero (struct color_symbol, i);
+ − 774
+ − 775 for (j=0; j<i; j++)
+ − 776 {
+ − 777 Lisp_Object cons = XCAR (results);
434
+ − 778 colortbl[j].color =
428
+ − 779 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
+ − 780
440
+ − 781 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (cons),
+ − 782 C_STRING_ALLOCA, colortbl[j].name,
+ − 783 Qnative);
428
+ − 784 colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
+ − 785 free_cons (XCONS (cons));
+ − 786 cons = results;
+ − 787 results = XCDR (results);
+ − 788 free_cons (XCONS (cons));
+ − 789 }
+ − 790 return colortbl;
+ − 791 }
+ − 792
442
+ − 793 static int xpm_to_eimage (Lisp_Object image, const Extbyte *buffer,
428
+ − 794 unsigned char** data,
+ − 795 int* width, int* height,
+ − 796 int* x_hot, int* y_hot,
+ − 797 int* transp,
+ − 798 struct color_symbol* color_symbols,
+ − 799 int nsymbols)
+ − 800 {
+ − 801 XpmImage xpmimage;
+ − 802 XpmInfo xpminfo;
+ − 803 int result, i, j, transp_idx, maskbpline;
+ − 804 unsigned char* dptr;
+ − 805 unsigned int* sptr;
+ − 806 COLORREF color; /* the american spelling virus hits again .. */
434
+ − 807 COLORREF* colortbl;
428
+ − 808
+ − 809 xzero (xpmimage);
+ − 810 xzero (xpminfo);
+ − 811 xpminfo.valuemask=XpmHotspot;
+ − 812 *transp=FALSE;
+ − 813
+ − 814 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
+ − 815 &xpmimage,
+ − 816 &xpminfo);
+ − 817 switch (result)
+ − 818 {
+ − 819 case XpmSuccess:
+ − 820 break;
+ − 821 case XpmFileInvalid:
+ − 822 {
+ − 823 signal_simple_error ("Invalid XPM data", image);
+ − 824 }
+ − 825 case XpmNoMemory:
+ − 826 {
+ − 827 signal_double_file_error ("Parsing pixmap data",
+ − 828 "out of memory", image);
+ − 829 }
+ − 830 default:
+ − 831 {
+ − 832 signal_double_file_error_2 ("Parsing pixmap data",
442
+ − 833 "unknown error",
428
+ − 834 make_int (result), image);
+ − 835 }
+ − 836 }
434
+ − 837
428
+ − 838 *width = xpmimage.width;
+ − 839 *height = xpmimage.height;
434
+ − 840 maskbpline = BPLINE ((~7UL & (unsigned long)(*width + 7)) / 8);
+ − 841
428
+ − 842 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
+ − 843
+ − 844 if (!*data)
+ − 845 {
+ − 846 XpmFreeXpmImage (&xpmimage);
+ − 847 XpmFreeXpmInfo (&xpminfo);
+ − 848 return 0;
+ − 849 }
+ − 850
+ − 851 /* build a color table to speed things up */
+ − 852 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
+ − 853 if (!colortbl)
+ − 854 {
+ − 855 xfree (*data);
+ − 856 XpmFreeXpmImage (&xpmimage);
+ − 857 XpmFreeXpmInfo (&xpminfo);
+ − 858 return 0;
+ − 859 }
+ − 860
+ − 861 for (i=0; i<xpmimage.ncolors; i++)
+ − 862 {
+ − 863 /* goto alert!!!! */
+ − 864 /* pick up symbolic colors in preference */
+ − 865 if (xpmimage.colorTable[i].symbolic)
+ − 866 {
+ − 867 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
+ − 868 ||
+ − 869 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
+ − 870 {
+ − 871 *transp=TRUE;
434
+ − 872 colortbl[i]=transparent_color;
428
+ − 873 transp_idx=i;
+ − 874 goto label_found_color;
+ − 875 }
+ − 876 else if (color_symbols)
+ − 877 {
+ − 878 for (j = 0; j<nsymbols; j++)
+ − 879 {
+ − 880 if (!strcmp (xpmimage.colorTable[i].symbolic,
+ − 881 color_symbols[j].name ))
+ − 882 {
+ − 883 colortbl[i]=color_symbols[j].color;
+ − 884 goto label_found_color;
+ − 885 }
+ − 886 }
+ − 887 }
+ − 888 else if (xpmimage.colorTable[i].c_color == 0)
+ − 889 {
+ − 890 goto label_no_color;
+ − 891 }
+ − 892 }
+ − 893 /* pick up transparencies */
+ − 894 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
+ − 895 {
+ − 896 *transp=TRUE;
434
+ − 897 colortbl[i]=transparent_color;
428
+ − 898 transp_idx=i;
+ − 899 goto label_found_color;
+ − 900 }
+ − 901 /* finally pick up a normal color spec */
+ − 902 if (xpmimage.colorTable[i].c_color)
+ − 903 {
+ − 904 colortbl[i]=
+ − 905 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
+ − 906 goto label_found_color;
+ − 907 }
434
+ − 908
428
+ − 909 label_no_color:
+ − 910 xfree (*data);
+ − 911 xfree (colortbl);
+ − 912 XpmFreeXpmImage (&xpmimage);
+ − 913 XpmFreeXpmInfo (&xpminfo);
+ − 914 return 0;
434
+ − 915
428
+ − 916 label_found_color:;
+ − 917 }
+ − 918
+ − 919 /* convert the image */
+ − 920 sptr=xpmimage.data;
+ − 921 dptr=*data;
+ − 922 for (i = 0; i< *width * *height; i++)
+ − 923 {
+ − 924 color = colortbl[*sptr++];
+ − 925
+ − 926 /* split out the 0x02bbggrr colorref into an rgb triple */
+ − 927 *dptr++=GetRValue (color); /* red */
+ − 928 *dptr++=GetGValue (color); /* green */
+ − 929 *dptr++=GetBValue (color); /* blue */
+ − 930 }
+ − 931
+ − 932 *x_hot=xpminfo.x_hotspot;
+ − 933 *y_hot=xpminfo.y_hotspot;
+ − 934
+ − 935 XpmFreeXpmImage (&xpmimage);
+ − 936 XpmFreeXpmInfo (&xpminfo);
+ − 937 xfree (colortbl);
+ − 938 return TRUE;
+ − 939 }
+ − 940
+ − 941 static void
+ − 942 mswindows_xpm_instantiate (Lisp_Object image_instance,
+ − 943 Lisp_Object instantiator,
+ − 944 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 945 int dest_mask, Lisp_Object domain)
+ − 946 {
440
+ − 947 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 948 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
442
+ − 949 const Extbyte *bytes;
428
+ − 950 Extcount len;
+ − 951 unsigned char *eimage;
+ − 952 int width, height, x_hot, y_hot;
+ − 953 BITMAPINFO* bmp_info;
+ − 954 unsigned char* bmp_data;
+ − 955 int bmp_bits;
+ − 956 int nsymbols=0, transp;
+ − 957 struct color_symbol* color_symbols=NULL;
434
+ − 958
428
+ − 959 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
+ − 960 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
+ − 961 Q_color_symbols);
+ − 962
442
+ − 963 CHECK_MSGDI_DEVICE (device);
428
+ − 964
+ − 965 assert (!NILP (data));
+ − 966
440
+ − 967 TO_EXTERNAL_FORMAT (LISP_STRING, data,
+ − 968 ALLOCA, (bytes, len),
+ − 969 Qbinary);
428
+ − 970
+ − 971 /* in case we have color symbols */
+ − 972 color_symbols = extract_xpm_color_names (device, domain,
+ − 973 color_symbol_alist, &nsymbols);
+ − 974
+ − 975 /* convert to an eimage to make processing easier */
+ − 976 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
+ − 977 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
+ − 978 {
434
+ − 979 signal_simple_error ("XPM to EImage conversion failed",
428
+ − 980 image_instance);
+ − 981 }
434
+ − 982
428
+ − 983 if (color_symbols)
+ − 984 {
+ − 985 while (nsymbols--)
+ − 986 {
+ − 987 xfree (color_symbols[nsymbols].name);
+ − 988 }
+ − 989 xfree(color_symbols);
+ − 990 }
434
+ − 991
428
+ − 992 /* build a bitmap from the eimage */
+ − 993 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
+ − 994 &bmp_bits, &bmp_data)))
+ − 995 {
+ − 996 signal_simple_error ("XPM to EImage conversion failed",
+ − 997 image_instance);
+ − 998 }
+ − 999 xfree (eimage);
+ − 1000
+ − 1001 /* Now create the pixmap and set up the image instance */
+ − 1002 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
+ − 1003 bmp_data, bmp_bits, 1, instantiator,
+ − 1004 x_hot, y_hot, transp);
+ − 1005
+ − 1006 xfree (bmp_info);
+ − 1007 xfree (bmp_data);
+ − 1008 }
+ − 1009 #endif /* HAVE_XPM */
+ − 1010
+ − 1011 /**********************************************************************
+ − 1012 * BMP *
+ − 1013 **********************************************************************/
+ − 1014
+ − 1015 static void
+ − 1016 bmp_validate (Lisp_Object instantiator)
+ − 1017 {
+ − 1018 file_or_data_must_be_present (instantiator);
+ − 1019 }
+ − 1020
+ − 1021 static Lisp_Object
442
+ − 1022 bmp_normalize (Lisp_Object inst, Lisp_Object console_type,
+ − 1023 Lisp_Object dest_mask)
428
+ − 1024 {
+ − 1025 return simple_image_type_normalize (inst, console_type, Qbmp);
+ − 1026 }
+ − 1027
+ − 1028 static int
+ − 1029 bmp_possible_dest_types (void)
+ − 1030 {
+ − 1031 return IMAGE_COLOR_PIXMAP_MASK;
+ − 1032 }
+ − 1033
+ − 1034 static void
+ − 1035 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ − 1036 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 1037 int dest_mask, Lisp_Object domain)
+ − 1038 {
440
+ − 1039 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 1040 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
442
+ − 1041 const Extbyte *bytes;
428
+ − 1042 Extcount len;
+ − 1043 BITMAPFILEHEADER* bmp_file_header;
+ − 1044 BITMAPINFO* bmp_info;
+ − 1045 void* bmp_data;
+ − 1046 int bmp_bits;
+ − 1047 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
+ − 1048
442
+ − 1049 CHECK_MSGDI_DEVICE (device);
428
+ − 1050
+ − 1051 assert (!NILP (data));
+ − 1052
440
+ − 1053 TO_EXTERNAL_FORMAT (LISP_STRING, data,
+ − 1054 ALLOCA, (bytes, len),
+ − 1055 Qbinary);
434
+ − 1056
428
+ − 1057 /* Then slurp the image into memory, decoding along the way.
+ − 1058 The result is the image in a simple one-byte-per-pixel
+ − 1059 format. */
434
+ − 1060
428
+ − 1061 bmp_file_header=(BITMAPFILEHEADER*)bytes;
+ − 1062 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
+ − 1063 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
+ − 1064 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
+ − 1065
+ − 1066 /* Now create the pixmap and set up the image instance */
+ − 1067 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
+ − 1068 bmp_data, bmp_bits, 1, instantiator,
+ − 1069 0, 0, 0);
+ − 1070 }
+ − 1071
+ − 1072
+ − 1073 /**********************************************************************
+ − 1074 * RESOURCES *
+ − 1075 **********************************************************************/
+ − 1076
+ − 1077 static void
+ − 1078 mswindows_resource_validate (Lisp_Object instantiator)
+ − 1079 {
434
+ − 1080 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
428
+ − 1081 &&
434
+ − 1082 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
428
+ − 1083 ||
+ − 1084 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
+ − 1085 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
+ − 1086 instantiator);
+ − 1087 }
+ − 1088
+ − 1089 static Lisp_Object
442
+ − 1090 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type,
+ − 1091 Lisp_Object dest_mask)
428
+ − 1092 {
+ − 1093 /* This function can call lisp */
+ − 1094 Lisp_Object file = Qnil;
+ − 1095 struct gcpro gcpro1, gcpro2;
+ − 1096 Lisp_Object alist = Qnil;
+ − 1097
+ − 1098 GCPRO2 (file, alist);
+ − 1099
434
+ − 1100 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
428
+ − 1101 console_type);
+ − 1102
+ − 1103 if (CONSP (file)) /* failure locating filename */
+ − 1104 signal_double_file_error ("Opening pixmap file",
+ − 1105 "no such file or directory",
+ − 1106 Fcar (file));
+ − 1107
+ − 1108 if (NILP (file)) /* no conversion necessary */
+ − 1109 RETURN_UNGCPRO (inst);
+ − 1110
+ − 1111 alist = tagged_vector_to_alist (inst);
+ − 1112
+ − 1113 {
+ − 1114 alist = remassq_no_quit (Q_file, alist);
+ − 1115 alist = Fcons (Fcons (Q_file, file), alist);
+ − 1116 }
+ − 1117
+ − 1118 {
+ − 1119 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
+ − 1120 free_alist (alist);
+ − 1121 RETURN_UNGCPRO (result);
+ − 1122 }
+ − 1123 }
+ − 1124
+ − 1125 static int
+ − 1126 mswindows_resource_possible_dest_types (void)
+ − 1127 {
+ − 1128 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
+ − 1129 }
+ − 1130
434
+ − 1131 typedef struct
428
+ − 1132 {
+ − 1133 char *name;
+ − 1134 int resource_id;
+ − 1135 } resource_t;
+ − 1136
+ − 1137 #ifndef OCR_ICOCUR
+ − 1138 #define OCR_ICOCUR 32647
+ − 1139 #define OIC_SAMPLE 32512
+ − 1140 #define OIC_HAND 32513
+ − 1141 #define OIC_QUES 32514
+ − 1142 #define OIC_BANG 32515
+ − 1143 #define OIC_NOTE 32516
+ − 1144 #define OIC_WINLOGO 32517
442
+ − 1145 #if defined (CYGWIN) && CYGWIN_VERSION_DLL_MAJOR < 21
428
+ − 1146 #define LR_SHARED 0x8000
+ − 1147 #endif
430
+ − 1148 #endif
428
+ − 1149
442
+ − 1150 static const resource_t bitmap_table[] =
428
+ − 1151 {
+ − 1152 /* bitmaps */
+ − 1153 { "close", OBM_CLOSE },
+ − 1154 { "uparrow", OBM_UPARROW },
+ − 1155 { "dnarrow", OBM_DNARROW },
+ − 1156 { "rgarrow", OBM_RGARROW },
+ − 1157 { "lfarrow", OBM_LFARROW },
+ − 1158 { "reduce", OBM_REDUCE },
+ − 1159 { "zoom", OBM_ZOOM },
+ − 1160 { "restore", OBM_RESTORE },
+ − 1161 { "reduced", OBM_REDUCED },
+ − 1162 { "zoomd", OBM_ZOOMD },
+ − 1163 { "restored", OBM_RESTORED },
+ − 1164 { "uparrowd", OBM_UPARROWD },
+ − 1165 { "dnarrowd", OBM_DNARROWD },
+ − 1166 { "rgarrowd", OBM_RGARROWD },
+ − 1167 { "lfarrowd", OBM_LFARROWD },
+ − 1168 { "mnarrow", OBM_MNARROW },
+ − 1169 { "combo", OBM_COMBO },
+ − 1170 { "uparrowi", OBM_UPARROWI },
+ − 1171 { "dnarrowi", OBM_DNARROWI },
+ − 1172 { "rgarrowi", OBM_RGARROWI },
+ − 1173 { "lfarrowi", OBM_LFARROWI },
+ − 1174 { "size", OBM_SIZE },
+ − 1175 { "btsize", OBM_BTSIZE },
+ − 1176 { "check", OBM_CHECK },
+ − 1177 { "checkboxes", OBM_CHECKBOXES },
+ − 1178 { "btncorners" , OBM_BTNCORNERS },
+ − 1179 {0}
+ − 1180 };
+ − 1181
442
+ − 1182 static const resource_t cursor_table[] =
428
+ − 1183 {
+ − 1184 /* cursors */
+ − 1185 { "normal", OCR_NORMAL },
+ − 1186 { "ibeam", OCR_IBEAM },
+ − 1187 { "wait", OCR_WAIT },
+ − 1188 { "cross", OCR_CROSS },
+ − 1189 { "up", OCR_UP },
+ − 1190 /* { "icon", OCR_ICON }, */
+ − 1191 { "sizenwse", OCR_SIZENWSE },
+ − 1192 { "sizenesw", OCR_SIZENESW },
+ − 1193 { "sizewe", OCR_SIZEWE },
+ − 1194 { "sizens", OCR_SIZENS },
+ − 1195 { "sizeall", OCR_SIZEALL },
+ − 1196 /* { "icour", OCR_ICOCUR }, */
+ − 1197 { "no", OCR_NO },
+ − 1198 { 0 }
+ − 1199 };
+ − 1200
442
+ − 1201 static const resource_t icon_table[] =
428
+ − 1202 {
+ − 1203 /* icons */
+ − 1204 { "sample", OIC_SAMPLE },
+ − 1205 { "hand", OIC_HAND },
+ − 1206 { "ques", OIC_QUES },
+ − 1207 { "bang", OIC_BANG },
+ − 1208 { "note", OIC_NOTE },
+ − 1209 { "winlogo", OIC_WINLOGO },
+ − 1210 {0}
+ − 1211 };
+ − 1212
+ − 1213 static int resource_name_to_resource (Lisp_Object name, int type)
+ − 1214 {
442
+ − 1215 const resource_t* res = (type == IMAGE_CURSOR ? cursor_table
434
+ − 1216 : type == IMAGE_ICON ? icon_table
428
+ − 1217 : bitmap_table);
+ − 1218
+ − 1219 if (INTP (name))
+ − 1220 {
+ − 1221 return XINT (name);
+ − 1222 }
+ − 1223 else if (!STRINGP (name))
+ − 1224 {
+ − 1225 signal_simple_error ("invalid resource identifier", name);
+ − 1226 }
434
+ − 1227
428
+ − 1228 do {
+ − 1229 Extbyte* nm=0;
440
+ − 1230 TO_EXTERNAL_FORMAT (LISP_STRING, name,
+ − 1231 C_STRING_ALLOCA, nm,
+ − 1232 Qnative);
428
+ − 1233 if (!strcasecmp ((char*)res->name, nm))
+ − 1234 return res->resource_id;
+ − 1235 } while ((++res)->name);
+ − 1236 return 0;
+ − 1237 }
+ − 1238
+ − 1239 static int
+ − 1240 resource_symbol_to_type (Lisp_Object data)
+ − 1241 {
+ − 1242 if (EQ (data, Qcursor))
+ − 1243 return IMAGE_CURSOR;
+ − 1244 else if (EQ (data, Qicon))
+ − 1245 return IMAGE_ICON;
+ − 1246 else if (EQ (data, Qbitmap))
+ − 1247 return IMAGE_BITMAP;
+ − 1248 else
+ − 1249 return 0;
+ − 1250 }
+ − 1251
+ − 1252 static void
502
+ − 1253 mswindows_resource_instantiate (Lisp_Object image_instance,
+ − 1254 Lisp_Object instantiator,
+ − 1255 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 1256 int dest_mask, Lisp_Object domain)
428
+ − 1257 {
440
+ − 1258 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 1259 unsigned int type = 0;
+ − 1260 HANDLE himage = NULL;
+ − 1261 LPCTSTR resid=0;
+ − 1262 HINSTANCE hinst = NULL;
+ − 1263 ICONINFO iconinfo;
442
+ − 1264 enum image_instance_type iitype;
428
+ − 1265 char* fname=0;
+ − 1266 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+ − 1267
+ − 1268 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
434
+ − 1269 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
428
+ − 1270 Q_resource_type);
434
+ − 1271 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
428
+ − 1272 Q_resource_id);
+ − 1273
+ − 1274 xzero (iconinfo);
+ − 1275
442
+ − 1276 CHECK_MSGDI_DEVICE (device);
428
+ − 1277
+ − 1278 type = resource_symbol_to_type (resource_type);
+ − 1279
+ − 1280 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
+ − 1281 iitype = IMAGE_POINTER;
+ − 1282 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
+ − 1283 iitype = IMAGE_COLOR_PIXMAP;
434
+ − 1284 else
428
+ − 1285 incompatible_image_types (instantiator, dest_mask,
+ − 1286 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
+ − 1287
+ − 1288 /* mess with the keyword info we were provided with */
+ − 1289 if (!NILP (file))
+ − 1290 {
+ − 1291 Extbyte* f=0;
440
+ − 1292 TO_EXTERNAL_FORMAT (LISP_STRING, file,
+ − 1293 C_STRING_ALLOCA, f,
+ − 1294 Qfile_name);
442
+ − 1295 #ifdef CYGWIN
428
+ − 1296 CYGWIN_WIN32_PATH (f, fname);
+ − 1297 #else
+ − 1298 fname = f;
+ − 1299 #endif
434
+ − 1300
428
+ − 1301 if (NILP (resource_id))
+ − 1302 resid = (LPCTSTR)fname;
+ − 1303 else
+ − 1304 {
+ − 1305 hinst = LoadLibraryEx (fname, NULL,
+ − 1306 LOAD_LIBRARY_AS_DATAFILE);
+ − 1307 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
+ − 1308 type));
434
+ − 1309
428
+ − 1310 if (!resid)
440
+ − 1311 TO_EXTERNAL_FORMAT (LISP_STRING, resource_id,
+ − 1312 C_STRING_ALLOCA, resid,
+ − 1313 Qnative);
428
+ − 1314 }
+ − 1315 }
+ − 1316 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
+ − 1317 type))))
+ − 1318 signal_simple_error ("Invalid resource identifier", resource_id);
434
+ − 1319
428
+ − 1320 /* load the image */
442
+ − 1321 if (xLoadImageA) /* not in NT 3.5 */
+ − 1322 {
+ − 1323 if (!(himage = xLoadImageA (hinst, resid, type, 0, 0,
+ − 1324 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
+ − 1325 LR_SHARED |
+ − 1326 (!NILP (file) ? LR_LOADFROMFILE : 0))))
+ − 1327 signal_simple_error ("Cannot load image", instantiator);
+ − 1328 }
+ − 1329 else
428
+ − 1330 {
442
+ − 1331 /* Is this correct? I don't really care. */
+ − 1332 switch (type)
+ − 1333 {
+ − 1334 case IMAGE_BITMAP:
+ − 1335 himage = LoadBitmap (hinst, resid);
+ − 1336 break;
+ − 1337 case IMAGE_CURSOR:
+ − 1338 himage = LoadCursor (hinst, resid);
+ − 1339 break;
+ − 1340 case IMAGE_ICON:
+ − 1341 himage = LoadIcon (hinst, resid);
+ − 1342 break;
+ − 1343 }
+ − 1344
+ − 1345 if (!himage)
+ − 1346 signal_simple_error ("Cannot load image", instantiator);
428
+ − 1347 }
+ − 1348
+ − 1349 if (hinst)
+ − 1350 FreeLibrary (hinst);
+ − 1351
+ − 1352 mswindows_initialize_dibitmap_image_instance (ii, 1, iitype);
+ − 1353
+ − 1354 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
442
+ − 1355 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
428
+ − 1356 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
442
+ − 1357 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
428
+ − 1358 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
+ − 1359 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
442
+ − 1360 init_image_instance_geometry (ii);
428
+ − 1361
+ − 1362 /* hey, we've got an icon type thing so we can reverse engineer the
+ − 1363 bitmap and mask */
+ − 1364 if (type != IMAGE_BITMAP)
+ − 1365 {
442
+ − 1366 GetIconInfo ((HICON)himage, &iconinfo);
428
+ − 1367 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
+ − 1368 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
+ − 1369 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
+ − 1370 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
442
+ − 1371 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (HICON) himage;
428
+ − 1372 }
+ − 1373 else
+ − 1374 {
+ − 1375 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
442
+ − 1376 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (HBITMAP) himage;
428
+ − 1377 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
+ − 1378 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
+ − 1379 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
+ − 1380 }
+ − 1381 }
+ − 1382
+ − 1383 static void
+ − 1384 check_valid_resource_symbol (Lisp_Object data)
+ − 1385 {
+ − 1386 CHECK_SYMBOL (data);
+ − 1387 if (!resource_symbol_to_type (data))
+ − 1388 signal_simple_error ("invalid resource type", data);
+ − 1389 }
+ − 1390
+ − 1391 static void
+ − 1392 check_valid_resource_id (Lisp_Object data)
+ − 1393 {
+ − 1394 if (!resource_name_to_resource (data, IMAGE_CURSOR)
+ − 1395 &&
+ − 1396 !resource_name_to_resource (data, IMAGE_ICON)
+ − 1397 &&
+ − 1398 !resource_name_to_resource (data, IMAGE_BITMAP))
+ − 1399 signal_simple_error ("invalid resource identifier", data);
+ − 1400 }
+ − 1401
+ − 1402 /**********************************************************************
+ − 1403 * XBM *
+ − 1404 **********************************************************************/
+ − 1405 #ifndef HAVE_X_WINDOWS
+ − 1406 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
+ − 1407
+ − 1408 /*
+ − 1409
+ − 1410 Copyright (c) 1988 X Consortium
+ − 1411
+ − 1412 Permission is hereby granted, free of charge, to any person obtaining a copy
+ − 1413 of this software and associated documentation files (the "Software"), to deal
+ − 1414 in the Software without restriction, including without limitation the rights
+ − 1415 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ − 1416 copies of the Software, and to permit persons to whom the Software is
+ − 1417 furnished to do so, subject to the following conditions:
+ − 1418
+ − 1419 The above copyright notice and this permission notice shall be included in
+ − 1420 all copies or substantial portions of the Software.
+ − 1421
+ − 1422 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ − 1423 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ − 1424 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ − 1425 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ − 1426 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ − 1427 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ − 1428
+ − 1429 Except as contained in this notice, the name of the X Consortium shall not be
+ − 1430 used in advertising or otherwise to promote the sale, use or other dealings
+ − 1431 in this Software without prior written authorization from the X Consortium.
+ − 1432
+ − 1433 */
+ − 1434
+ − 1435 /*
+ − 1436 * This file contains miscellaneous utility routines and is not part of the
+ − 1437 * Xlib standard.
+ − 1438 *
+ − 1439 * Public entry points:
+ − 1440 *
+ − 1441 * XmuReadBitmapData read data from FILE descriptor
+ − 1442 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
+ − 1443 * and return data
+ − 1444 *
+ − 1445 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
434
+ − 1446 * that way (but don't use common source code so that people can have one
428
+ − 1447 * without the other).
+ − 1448 */
+ − 1449
+ − 1450
+ − 1451 /*
+ − 1452 * Based on an optimized version provided by Jim Becker, August 5, 1988.
+ − 1453 */
+ − 1454 #ifndef BitmapSuccess
+ − 1455 #define BitmapSuccess 0
+ − 1456 #define BitmapOpenFailed 1
+ − 1457 #define BitmapFileInvalid 2
+ − 1458 #define BitmapNoMemory 3
+ − 1459 #endif
+ − 1460 #define MAX_SIZE 255
+ − 1461
+ − 1462 /* shared data for the image read/parse logic */
+ − 1463 static short hexTable[256]; /* conversion value */
+ − 1464 static int initialized = FALSE; /* easier to fill in at run time */
+ − 1465
+ − 1466 /*
+ − 1467 * Table index for the hex values. Initialized once, first time.
+ − 1468 * Used for translation value or delimiter significance lookup.
+ − 1469 */
442
+ − 1470 static void
+ − 1471 initHexTable (void)
428
+ − 1472 {
+ − 1473 /*
+ − 1474 * We build the table at run time for several reasons:
+ − 1475 *
+ − 1476 * 1. portable to non-ASCII machines.
+ − 1477 * 2. still reentrant since we set the init flag after setting table.
+ − 1478 * 3. easier to extend.
+ − 1479 * 4. less prone to bugs.
+ − 1480 */
+ − 1481 hexTable['0'] = 0; hexTable['1'] = 1;
+ − 1482 hexTable['2'] = 2; hexTable['3'] = 3;
+ − 1483 hexTable['4'] = 4; hexTable['5'] = 5;
+ − 1484 hexTable['6'] = 6; hexTable['7'] = 7;
+ − 1485 hexTable['8'] = 8; hexTable['9'] = 9;
+ − 1486 hexTable['A'] = 10; hexTable['B'] = 11;
+ − 1487 hexTable['C'] = 12; hexTable['D'] = 13;
+ − 1488 hexTable['E'] = 14; hexTable['F'] = 15;
+ − 1489 hexTable['a'] = 10; hexTable['b'] = 11;
+ − 1490 hexTable['c'] = 12; hexTable['d'] = 13;
+ − 1491 hexTable['e'] = 14; hexTable['f'] = 15;
+ − 1492
+ − 1493 /* delimiters of significance are flagged w/ negative value */
+ − 1494 hexTable[' '] = -1; hexTable[','] = -1;
+ − 1495 hexTable['}'] = -1; hexTable['\n'] = -1;
+ − 1496 hexTable['\t'] = -1;
434
+ − 1497
428
+ − 1498 initialized = TRUE;
+ − 1499 }
+ − 1500
+ − 1501 /*
+ − 1502 * read next hex value in the input stream, return -1 if EOF
+ − 1503 */
442
+ − 1504 static int
+ − 1505 NextInt (FILE *fstream)
428
+ − 1506 {
+ − 1507 int ch;
+ − 1508 int value = 0;
+ − 1509 int gotone = 0;
+ − 1510 int done = 0;
434
+ − 1511
428
+ − 1512 /* loop, accumulate hex value until find delimiter */
+ − 1513 /* skip any initial delimiters found in read stream */
+ − 1514
+ − 1515 while (!done) {
+ − 1516 ch = getc(fstream);
+ − 1517 if (ch == EOF) {
+ − 1518 value = -1;
+ − 1519 done++;
+ − 1520 } else {
+ − 1521 /* trim high bits, check type and accumulate */
+ − 1522 ch &= 0xff;
+ − 1523 if (isascii(ch) && isxdigit(ch)) {
+ − 1524 value = (value << 4) + hexTable[ch];
+ − 1525 gotone++;
+ − 1526 } else if ((hexTable[ch]) < 0 && gotone)
+ − 1527 done++;
+ − 1528 }
+ − 1529 }
+ − 1530 return value;
+ − 1531 }
+ − 1532
+ − 1533
+ − 1534 /*
+ − 1535 * The data returned by the following routine is always in left-most byte
+ − 1536 * first and left-most bit first. If it doesn't return BitmapSuccess then
+ − 1537 * its arguments won't have been touched. This routine should look as much
+ − 1538 * like the Xlib routine XReadBitmapfile as possible.
+ − 1539 */
442
+ − 1540 int read_bitmap_data (FILE* fstream, unsigned int *width,
+ − 1541 unsigned int *height, unsigned char **datap,
+ − 1542 int *x_hot, int *y_hot)
428
+ − 1543 {
+ − 1544 unsigned char *data = NULL; /* working variable */
+ − 1545 char line[MAX_SIZE]; /* input line from file */
+ − 1546 int size; /* number of bytes of data */
+ − 1547 char name_and_type[MAX_SIZE]; /* an input line */
+ − 1548 char *type; /* for parsing */
+ − 1549 int value; /* from an input line */
+ − 1550 int version10p; /* boolean, old format */
+ − 1551 int padding; /* to handle alignment */
+ − 1552 int bytes_per_line; /* per scanline of data */
+ − 1553 unsigned int ww = 0; /* width */
+ − 1554 unsigned int hh = 0; /* height */
+ − 1555 int hx = -1; /* x hotspot */
+ − 1556 int hy = -1; /* y hotspot */
+ − 1557
+ − 1558 #define Xmalloc(size) malloc(size)
+ − 1559
+ − 1560 /* first time initialization */
+ − 1561 if (initialized == FALSE) initHexTable();
+ − 1562
+ − 1563 /* error cleanup and return macro */
+ − 1564 #define RETURN(code) { if (data) free (data); return code; }
+ − 1565
+ − 1566 while (fgets(line, MAX_SIZE, fstream)) {
+ − 1567 if (strlen(line) == MAX_SIZE-1) {
+ − 1568 RETURN (BitmapFileInvalid);
+ − 1569 }
+ − 1570 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
+ − 1571 if (!(type = strrchr(name_and_type, '_')))
+ − 1572 type = name_and_type;
+ − 1573 else
+ − 1574 type++;
+ − 1575
+ − 1576 if (!strcmp("width", type))
+ − 1577 ww = (unsigned int) value;
+ − 1578 if (!strcmp("height", type))
+ − 1579 hh = (unsigned int) value;
+ − 1580 if (!strcmp("hot", type)) {
+ − 1581 if (type-- == name_and_type || type-- == name_and_type)
+ − 1582 continue;
+ − 1583 if (!strcmp("x_hot", type))
+ − 1584 hx = value;
+ − 1585 if (!strcmp("y_hot", type))
+ − 1586 hy = value;
+ − 1587 }
+ − 1588 continue;
+ − 1589 }
434
+ − 1590
428
+ − 1591 if (sscanf(line, "static short %s = {", name_and_type) == 1)
+ − 1592 version10p = 1;
+ − 1593 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
+ − 1594 version10p = 0;
+ − 1595 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
+ − 1596 version10p = 0;
+ − 1597 else
+ − 1598 continue;
+ − 1599
+ − 1600 if (!(type = strrchr(name_and_type, '_')))
+ − 1601 type = name_and_type;
+ − 1602 else
+ − 1603 type++;
+ − 1604
+ − 1605 if (strcmp("bits[]", type))
+ − 1606 continue;
434
+ − 1607
428
+ − 1608 if (!ww || !hh)
+ − 1609 RETURN (BitmapFileInvalid);
+ − 1610
+ − 1611 if ((ww % 16) && ((ww % 16) < 9) && version10p)
+ − 1612 padding = 1;
+ − 1613 else
+ − 1614 padding = 0;
+ − 1615
+ − 1616 bytes_per_line = (ww+7)/8 + padding;
+ − 1617
+ − 1618 size = bytes_per_line * hh;
+ − 1619 data = (unsigned char *) Xmalloc ((unsigned int) size);
434
+ − 1620 if (!data)
428
+ − 1621 RETURN (BitmapNoMemory);
+ − 1622
+ − 1623 if (version10p) {
+ − 1624 unsigned char *ptr;
+ − 1625 int bytes;
+ − 1626
+ − 1627 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
+ − 1628 if ((value = NextInt(fstream)) < 0)
+ − 1629 RETURN (BitmapFileInvalid);
+ − 1630 *(ptr++) = value;
+ − 1631 if (!padding || ((bytes+2) % bytes_per_line))
+ − 1632 *(ptr++) = value >> 8;
+ − 1633 }
+ − 1634 } else {
+ − 1635 unsigned char *ptr;
+ − 1636 int bytes;
+ − 1637
+ − 1638 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
434
+ − 1639 if ((value = NextInt(fstream)) < 0)
428
+ − 1640 RETURN (BitmapFileInvalid);
+ − 1641 *ptr=value;
+ − 1642 }
+ − 1643 }
+ − 1644 break;
+ − 1645 } /* end while */
+ − 1646
+ − 1647 if (data == NULL) {
+ − 1648 RETURN (BitmapFileInvalid);
+ − 1649 }
+ − 1650
+ − 1651 *datap = data;
+ − 1652 data = NULL;
+ − 1653 *width = ww;
+ − 1654 *height = hh;
+ − 1655 if (x_hot) *x_hot = hx;
+ − 1656 if (y_hot) *y_hot = hy;
+ − 1657
+ − 1658 RETURN (BitmapSuccess);
+ − 1659 }
+ − 1660
+ − 1661
442
+ − 1662 int read_bitmap_data_from_file (const char *filename, unsigned int *width,
428
+ − 1663 unsigned int *height, unsigned char **datap,
+ − 1664 int *x_hot, int *y_hot)
+ − 1665 {
+ − 1666 FILE *fstream;
+ − 1667 int status;
+ − 1668
+ − 1669 if ((fstream = fopen (filename, "r")) == NULL) {
+ − 1670 return BitmapOpenFailed;
+ − 1671 }
+ − 1672 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
+ − 1673 fclose (fstream);
+ − 1674 return status;
+ − 1675 }
+ − 1676 #endif /* HAVE_X_WINDOWS */
+ − 1677
+ − 1678 /* this table flips four bits around. */
+ − 1679 static int flip_table[] =
+ − 1680 {
+ − 1681 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
+ − 1682 };
+ − 1683
+ − 1684 /* the bitmap data comes in the following format: Widths are padded to
+ − 1685 a multiple of 8. Scan lines are stored in increasing byte order
+ − 1686 from left to right, little-endian within a byte. 0 = white, 1 =
+ − 1687 black. It must be converted to the following format: Widths are
+ − 1688 padded to a multiple of 16. Scan lines are stored in increasing
+ − 1689 byte order from left to right, big-endian within a byte. 0 =
+ − 1690 black, 1 = white. */
438
+ − 1691 static HBITMAP
428
+ − 1692 xbm_create_bitmap_from_data (HDC hdc, char *data,
+ − 1693 unsigned int width, unsigned int height,
+ − 1694 int mask, COLORREF fg, COLORREF bg)
+ − 1695 {
+ − 1696 int old_width = (width + 7)/8;
+ − 1697 int new_width = BPLINE (2*((width + 15)/16));
+ − 1698 unsigned char *offset;
+ − 1699 void *bmp_buf = 0;
+ − 1700 unsigned char *new_data, *new_offset;
+ − 1701 int i, j;
442
+ − 1702 BITMAPINFO *bmp_info =
+ − 1703 (BITMAPINFO*) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
428
+ − 1704 HBITMAP bitmap;
+ − 1705
+ − 1706 if (!bmp_info)
+ − 1707 return NULL;
434
+ − 1708
428
+ − 1709 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
434
+ − 1710
428
+ − 1711 if (!new_data)
+ − 1712 {
+ − 1713 xfree (bmp_info);
+ − 1714 return NULL;
+ − 1715 }
434
+ − 1716
428
+ − 1717 for (i=0; i<height; i++)
+ − 1718 {
+ − 1719 offset = data + i*old_width;
+ − 1720 new_offset = new_data + i*new_width;
+ − 1721
+ − 1722 for (j=0; j<old_width; j++)
+ − 1723 {
+ − 1724 int byte = offset[j];
+ − 1725 new_offset[j] = ~ (unsigned char)
+ − 1726 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
+ − 1727 }
+ − 1728 }
+ − 1729
+ − 1730 /* if we want a mask invert the bits */
+ − 1731 if (!mask)
+ − 1732 {
+ − 1733 new_offset = &new_data[height * new_width];
+ − 1734 while (new_offset-- != new_data)
+ − 1735 {
+ − 1736 *new_offset ^= 0xff;
+ − 1737 }
+ − 1738 }
+ − 1739
+ − 1740 bmp_info->bmiHeader.biWidth=width;
+ − 1741 bmp_info->bmiHeader.biHeight=-(LONG)height;
+ − 1742 bmp_info->bmiHeader.biPlanes=1;
+ − 1743 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
434
+ − 1744 bmp_info->bmiHeader.biBitCount=1;
428
+ − 1745 bmp_info->bmiHeader.biCompression=BI_RGB;
434
+ − 1746 bmp_info->bmiHeader.biClrUsed = 2;
+ − 1747 bmp_info->bmiHeader.biClrImportant = 2;
+ − 1748 bmp_info->bmiHeader.biSizeImage = height * new_width;
428
+ − 1749 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
+ − 1750 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
+ − 1751 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
+ − 1752 bmp_info->bmiColors[0].rgbReserved = 0;
+ − 1753 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
+ − 1754 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
+ − 1755 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
+ − 1756 bmp_info->bmiColors[1].rgbReserved = 0;
434
+ − 1757
+ − 1758 bitmap = CreateDIBSection (hdc,
428
+ − 1759 bmp_info,
+ − 1760 DIB_RGB_COLORS,
434
+ − 1761 &bmp_buf,
428
+ − 1762 0,0);
+ − 1763
+ − 1764 xfree (bmp_info);
434
+ − 1765
428
+ − 1766 if (!bitmap || !bmp_buf)
+ − 1767 {
+ − 1768 xfree (new_data);
+ − 1769 return NULL;
+ − 1770 }
434
+ − 1771
428
+ − 1772 /* copy in the actual bitmap */
+ − 1773 memcpy (bmp_buf, new_data, height * new_width);
+ − 1774 xfree (new_data);
+ − 1775
+ − 1776 return bitmap;
+ − 1777 }
+ − 1778
+ − 1779 /* Given inline data for a mono pixmap, initialize the given
+ − 1780 image instance accordingly. */
+ − 1781
+ − 1782 static void
440
+ − 1783 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
428
+ − 1784 int width, int height,
+ − 1785 /* Note that data is in ext-format! */
442
+ − 1786 const char *bits,
428
+ − 1787 Lisp_Object instantiator,
+ − 1788 Lisp_Object pointer_fg,
+ − 1789 Lisp_Object pointer_bg,
+ − 1790 int dest_mask,
+ − 1791 HBITMAP mask,
+ − 1792 Lisp_Object mask_filename)
+ − 1793 {
+ − 1794 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+ − 1795 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
+ − 1796 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
+ − 1797 enum image_instance_type type;
+ − 1798 COLORREF black = PALETTERGB (0,0,0);
+ − 1799 COLORREF white = PALETTERGB (255,255,255);
442
+ − 1800 HDC hdc;
+ − 1801
+ − 1802 CHECK_MSGDI_DEVICE (device);
+ − 1803
+ − 1804 hdc = get_device_compdc (XDEVICE (device));
428
+ − 1805
+ − 1806 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
+ − 1807 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
+ − 1808 {
+ − 1809 if (!NILP (foreground) || !NILP (background))
+ − 1810 type = IMAGE_COLOR_PIXMAP;
+ − 1811 else
+ − 1812 type = IMAGE_MONO_PIXMAP;
+ − 1813 }
+ − 1814 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
+ − 1815 type = IMAGE_MONO_PIXMAP;
+ − 1816 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
+ − 1817 type = IMAGE_COLOR_PIXMAP;
+ − 1818 else if (dest_mask & IMAGE_POINTER_MASK)
+ − 1819 type = IMAGE_POINTER;
+ − 1820 else
+ − 1821 incompatible_image_types (instantiator, dest_mask,
+ − 1822 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
+ − 1823 | IMAGE_POINTER_MASK);
+ − 1824
+ − 1825 mswindows_initialize_dibitmap_image_instance (ii, 1, type);
434
+ − 1826
428
+ − 1827 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
+ − 1828 find_keyword_in_vector (instantiator, Q_file);
442
+ − 1829 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = width;
+ − 1830 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = height;
428
+ − 1831 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
+ − 1832 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
+ − 1833 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
442
+ − 1834 init_image_instance_geometry (ii);
+ − 1835
428
+ − 1836 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
434
+ − 1837 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
428
+ − 1838 TRUE, black, white);
+ − 1839
+ − 1840 switch (type)
+ − 1841 {
+ − 1842 case IMAGE_MONO_PIXMAP:
434
+ − 1843 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
+ − 1844 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
428
+ − 1845 FALSE, black, black);
+ − 1846 break;
+ − 1847
+ − 1848 case IMAGE_COLOR_PIXMAP:
+ − 1849 {
+ − 1850 COLORREF fg = black;
+ − 1851 COLORREF bg = white;
+ − 1852
+ − 1853 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
+ − 1854 foreground =
+ − 1855 Fmake_color_instance (foreground, device,
+ − 1856 encode_error_behavior_flag (ERROR_ME));
+ − 1857
+ − 1858 if (COLOR_INSTANCEP (foreground))
+ − 1859 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
+ − 1860
+ − 1861 if (!NILP (background) && !COLOR_INSTANCEP (background))
+ − 1862 background =
+ − 1863 Fmake_color_instance (background, device,
+ − 1864 encode_error_behavior_flag (ERROR_ME));
+ − 1865
+ − 1866 if (COLOR_INSTANCEP (background))
+ − 1867 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
+ − 1868
+ − 1869 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
+ − 1870 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
+ − 1871
434
+ − 1872 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
+ − 1873 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
428
+ − 1874 FALSE, fg, black);
+ − 1875 }
+ − 1876 break;
+ − 1877
+ − 1878 case IMAGE_POINTER:
+ − 1879 {
+ − 1880 COLORREF fg = black;
+ − 1881 COLORREF bg = white;
+ − 1882
+ − 1883 if (NILP (foreground))
+ − 1884 foreground = pointer_fg;
+ − 1885 if (NILP (background))
+ − 1886 background = pointer_bg;
+ − 1887
434
+ − 1888 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
428
+ − 1889 find_keyword_in_vector (instantiator, Q_hotspot_x);
434
+ − 1890 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
428
+ − 1891 find_keyword_in_vector (instantiator, Q_hotspot_y);
+ − 1892 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
+ − 1893 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
+ − 1894 if (COLOR_INSTANCEP (foreground))
+ − 1895 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
+ − 1896 if (COLOR_INSTANCEP (background))
+ − 1897 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
+ − 1898
434
+ − 1899 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
+ − 1900 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
428
+ − 1901 TRUE, fg, black);
+ − 1902 mswindows_initialize_image_instance_icon (ii, TRUE);
+ − 1903 }
+ − 1904 break;
+ − 1905
+ − 1906 default:
+ − 1907 abort ();
+ − 1908 }
+ − 1909 }
+ − 1910
+ − 1911 static void
+ − 1912 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
+ − 1913 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 1914 int dest_mask, int width, int height,
+ − 1915 /* Note that data is in ext-format! */
442
+ − 1916 const char *bits)
428
+ − 1917 {
+ − 1918 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
+ − 1919 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
440
+ − 1920 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
442
+ − 1921 HDC hdc = get_device_compdc (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
428
+ − 1922 HBITMAP mask = 0;
+ − 1923
+ − 1924 if (!NILP (mask_data))
+ − 1925 {
442
+ − 1926 const char *ext_data;
440
+ − 1927
+ − 1928 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))),
+ − 1929 C_STRING_ALLOCA, ext_data,
+ − 1930 Qbinary);
+ − 1931 mask = xbm_create_bitmap_from_data (hdc,
+ − 1932 (unsigned char *) ext_data,
+ − 1933 XINT (XCAR (mask_data)),
+ − 1934 XINT (XCAR (XCDR (mask_data))),
+ − 1935 FALSE,
+ − 1936 PALETTERGB (0,0,0),
+ − 1937 PALETTERGB (255,255,255));
428
+ − 1938 }
+ − 1939
+ − 1940 init_image_instance_from_xbm_inline (ii, width, height, bits,
+ − 1941 instantiator, pointer_fg, pointer_bg,
+ − 1942 dest_mask, mask, mask_file);
+ − 1943 }
+ − 1944
+ − 1945 /* Instantiate method for XBM's. */
+ − 1946
+ − 1947 static void
434
+ − 1948 mswindows_xbm_instantiate (Lisp_Object image_instance,
428
+ − 1949 Lisp_Object instantiator,
+ − 1950 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 1951 int dest_mask, Lisp_Object domain)
+ − 1952 {
+ − 1953 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
442
+ − 1954 const char *ext_data;
428
+ − 1955
+ − 1956 assert (!NILP (data));
+ − 1957
440
+ − 1958 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))),
+ − 1959 C_STRING_ALLOCA, ext_data,
+ − 1960 Qbinary);
428
+ − 1961
+ − 1962 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
+ − 1963 pointer_bg, dest_mask, XINT (XCAR (data)),
440
+ − 1964 XINT (XCAR (XCDR (data))), ext_data);
428
+ − 1965 }
+ − 1966
+ − 1967 #ifdef HAVE_XFACE
+ − 1968 /**********************************************************************
+ − 1969 * X-Face *
+ − 1970 **********************************************************************/
+ − 1971 #if defined(EXTERN)
+ − 1972 /* This is about to get redefined! */
+ − 1973 #undef EXTERN
+ − 1974 #endif
+ − 1975 /* We have to define SYSV32 so that compface.h includes string.h
+ − 1976 instead of strings.h. */
+ − 1977 #define SYSV32
+ − 1978 #ifdef __cplusplus
+ − 1979 extern "C" {
+ − 1980 #endif
+ − 1981 #include <compface.h>
+ − 1982 #ifdef __cplusplus
+ − 1983 }
+ − 1984 #endif
+ − 1985 /* JMP_BUF cannot be used here because if it doesn't get defined
+ − 1986 to jmp_buf we end up with a conflicting type error with the
+ − 1987 definition in compface.h */
+ − 1988 extern jmp_buf comp_env;
+ − 1989 #undef SYSV32
+ − 1990
+ − 1991 static void
502
+ − 1992 mswindows_xface_instantiate (Lisp_Object image_instance,
+ − 1993 Lisp_Object instantiator,
428
+ − 1994 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 1995 int dest_mask, Lisp_Object domain)
+ − 1996 {
+ − 1997 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
+ − 1998 int i, stattis;
+ − 1999 char *p, *bits, *bp;
442
+ − 2000 const char * volatile emsg = 0;
+ − 2001 const char * volatile dstring;
428
+ − 2002
+ − 2003 assert (!NILP (data));
+ − 2004
440
+ − 2005 TO_EXTERNAL_FORMAT (LISP_STRING, data,
+ − 2006 C_STRING_ALLOCA, dstring,
+ − 2007 Qbinary);
428
+ − 2008
+ − 2009 if ((p = strchr (dstring, ':')))
+ − 2010 {
+ − 2011 dstring = p + 1;
+ − 2012 }
+ − 2013
+ − 2014 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
+ − 2015 if (!(stattis = setjmp (comp_env)))
+ − 2016 {
+ − 2017 UnCompAll ((char *) dstring);
+ − 2018 UnGenFace ();
+ − 2019 }
+ − 2020
+ − 2021 switch (stattis)
+ − 2022 {
+ − 2023 case -2:
+ − 2024 emsg = "uncompface: internal error";
+ − 2025 break;
+ − 2026 case -1:
+ − 2027 emsg = "uncompface: insufficient or invalid data";
+ − 2028 break;
+ − 2029 case 1:
+ − 2030 emsg = "uncompface: excess data ignored";
+ − 2031 break;
+ − 2032 }
+ − 2033
+ − 2034 if (emsg)
+ − 2035 signal_simple_error_2 (emsg, data, Qimage);
+ − 2036
+ − 2037 bp = bits = (char *) alloca (PIXELS / 8);
+ − 2038
+ − 2039 /* the compface library exports char F[], which uses a single byte per
+ − 2040 pixel to represent a 48x48 bitmap. Yuck. */
+ − 2041 for (i = 0, p = F; i < (PIXELS / 8); ++i)
+ − 2042 {
+ − 2043 int n, b;
+ − 2044 /* reverse the bit order of each byte... */
+ − 2045 for (b = n = 0; b < 8; ++b)
+ − 2046 {
+ − 2047 n |= ((*p++) << b);
+ − 2048 }
+ − 2049 *bp++ = (char) n;
+ − 2050 }
+ − 2051
+ − 2052 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
+ − 2053 pointer_bg, dest_mask, 48, 48, bits);
+ − 2054 }
+ − 2055 #endif /* HAVE_XFACE */
+ − 2056
+ − 2057
+ − 2058 /************************************************************************/
+ − 2059 /* image instance methods */
+ − 2060 /************************************************************************/
+ − 2061
+ − 2062 static void
440
+ − 2063 mswindows_print_image_instance (Lisp_Image_Instance *p,
428
+ − 2064 Lisp_Object printcharfun,
+ − 2065 int escapeflag)
+ − 2066 {
+ − 2067 char buf[100];
+ − 2068
+ − 2069 switch (IMAGE_INSTANCE_TYPE (p))
+ − 2070 {
+ − 2071 case IMAGE_MONO_PIXMAP:
+ − 2072 case IMAGE_COLOR_PIXMAP:
+ − 2073 case IMAGE_POINTER:
434
+ − 2074 sprintf (buf, " (0x%lx",
428
+ − 2075 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
+ − 2076 write_c_string (buf, printcharfun);
+ − 2077 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
+ − 2078 {
434
+ − 2079 sprintf (buf, "/0x%lx",
428
+ − 2080 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
+ − 2081 write_c_string (buf, printcharfun);
+ − 2082 }
+ − 2083 write_c_string (")", printcharfun);
+ − 2084 break;
+ − 2085
+ − 2086 default:
+ − 2087 break;
+ − 2088 }
+ − 2089 }
+ − 2090
+ − 2091 #ifdef DEBUG_WIDGETS
+ − 2092 extern int debug_widget_instances;
+ − 2093 #endif
+ − 2094
+ − 2095 static void
440
+ − 2096 mswindows_finalize_image_instance (Lisp_Image_Instance *p)
428
+ − 2097 {
442
+ − 2098 if (!p->data)
+ − 2099 return;
+ − 2100
+ − 2101 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
428
+ − 2102 {
442
+ − 2103 if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p))
+ − 2104 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
428
+ − 2105 {
+ − 2106 #ifdef DEBUG_WIDGETS
+ − 2107 debug_widget_instances--;
+ − 2108 stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
+ − 2109 #endif
+ − 2110 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
+ − 2111 {
+ − 2112 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
+ − 2113 DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p));
+ − 2114 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
+ − 2115 }
+ − 2116 }
+ − 2117 else if (p->data)
+ − 2118 {
+ − 2119 int i;
+ − 2120 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
+ − 2121 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
+ − 2122
+ − 2123 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p))
+ − 2124 {
+ − 2125 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
+ − 2126 {
+ − 2127 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i))
+ − 2128 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i));
+ − 2129 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0;
+ − 2130 }
+ − 2131 xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p));
+ − 2132 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0;
+ − 2133 }
+ − 2134 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
+ − 2135 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
+ − 2136 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
+ − 2137 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
+ − 2138 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
+ − 2139 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
+ − 2140 }
+ − 2141 }
+ − 2142
+ − 2143 if (p->data)
+ − 2144 {
+ − 2145 xfree (p->data);
+ − 2146 p->data = 0;
+ − 2147 }
+ − 2148 }
+ − 2149
+ − 2150 /************************************************************************/
+ − 2151 /* subwindow and widget support */
+ − 2152 /************************************************************************/
+ − 2153
440
+ − 2154 static HFONT
+ − 2155 mswindows_widget_hfont (Lisp_Image_Instance *p,
+ − 2156 Lisp_Object domain)
+ − 2157 {
+ − 2158 Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (p);
+ − 2159 int under = FACE_UNDERLINE_P (face, domain);
+ − 2160 int strike = FACE_STRIKETHRU_P (face, domain);
+ − 2161 Lisp_Object font = query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (p),
+ − 2162 face, domain);
+ − 2163
+ − 2164 return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike);
+ − 2165 }
+ − 2166
442
+ − 2167 static HDWP
+ − 2168 begin_defer_window_pos (struct frame *f)
+ − 2169 {
+ − 2170 #ifdef DEFER_WINDOW_POS
+ − 2171 if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0)
+ − 2172 FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10);
+ − 2173 #endif
+ − 2174 return FRAME_MSWINDOWS_DATA (f)->hdwp;
+ − 2175 }
+ − 2176
428
+ − 2177 /* unmap the image if it is a widget. This is used by redisplay via
+ − 2178 redisplay_unmap_subwindows */
+ − 2179 static void
440
+ − 2180 mswindows_unmap_subwindow (Lisp_Image_Instance *p)
428
+ − 2181 {
+ − 2182 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
+ − 2183 {
442
+ − 2184 #ifdef DEFER_WINDOW_POS
+ − 2185 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
+ − 2186 HDWP hdwp = begin_defer_window_pos (f);
+ − 2187 HDWP new_hdwp;
+ − 2188 new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
+ − 2189 NULL,
+ − 2190 0, 0, 0, 0,
+ − 2191 SWP_HIDEWINDOW | SWP_NOACTIVATE |
+ − 2192 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
+ − 2193 /* Setting this flag causes the call to
+ − 2194 DeferWindowPos to fail with
+ − 2195 "Invalid parameter". I don't understand
+ − 2196 why we bother to try and set this
+ − 2197 anyway. -- ben */
+ − 2198 /* | SWP_NOSENDCHANGING */
+ − 2199 );
+ − 2200 if (!new_hdwp)
+ − 2201 mswindows_output_last_error ("unmapping");
+ − 2202 else
+ − 2203 hdwp = new_hdwp;
+ − 2204 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
+ − 2205 #else
434
+ − 2206 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
+ − 2207 NULL,
428
+ − 2208 0, 0, 0, 0,
442
+ − 2209 SWP_HIDEWINDOW | SWP_NOACTIVATE |
+ − 2210 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER );
+ − 2211 #endif
440
+ − 2212 if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))
+ − 2213 SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
428
+ − 2214 }
+ − 2215 }
+ − 2216
+ − 2217 /* map the subwindow. This is used by redisplay via
+ − 2218 redisplay_output_subwindow */
+ − 2219 static void
440
+ − 2220 mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
428
+ − 2221 struct display_glyph_area* dga)
+ − 2222 {
442
+ − 2223 #ifdef DEFER_WINDOW_POS
+ − 2224 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
+ − 2225 HDWP hdwp = begin_defer_window_pos (f);
+ − 2226 HDWP new_hdwp;
+ − 2227 #endif
428
+ − 2228 /* move the window before mapping it ... */
+ − 2229 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
434
+ − 2230 NULL,
428
+ − 2231 x, y, dga->width, dga->height,
434
+ − 2232 SWP_NOZORDER
428
+ − 2233 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+ − 2234 /* ... adjust the child ... */
+ − 2235 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
434
+ − 2236 NULL,
428
+ − 2237 -dga->xoffset, -dga->yoffset, 0, 0,
+ − 2238 SWP_NOZORDER | SWP_NOSIZE
+ − 2239 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+ − 2240 /* ... now map it - we are not allowed to move it at the same time. */
442
+ − 2241 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
+ − 2242 {
+ − 2243 #ifdef DEFER_WINDOW_POS
+ − 2244 new_hdwp = DeferWindowPos
+ − 2245 (hdwp,
+ − 2246 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
+ − 2247 NULL, 0, 0, 0, 0,
+ − 2248 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
+ − 2249 | SWP_SHOWWINDOW
+ − 2250 /* | SWP_NOCOPYBITS */
+ − 2251 /* Setting this flag causes the call to
+ − 2252 DeferWindowPos to fail with
+ − 2253 "Invalid parameter". I don't understand
+ − 2254 why we bother to try and set this
+ − 2255 anyway. -- ben */
+ − 2256 /* | SWP_NOSENDCHANGING */
+ − 2257 | SWP_NOACTIVATE);
+ − 2258 if (!new_hdwp)
+ − 2259 mswindows_output_last_error ("mapping");
+ − 2260 else
+ − 2261 hdwp = new_hdwp;
+ − 2262 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
+ − 2263 #else
+ − 2264 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
+ − 2265 NULL,
+ − 2266 0, 0, 0, 0,
+ − 2267 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
+ − 2268 | SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE);
+ − 2269 #endif
+ − 2270 }
428
+ − 2271 }
+ − 2272
+ − 2273 /* resize the subwindow instance */
434
+ − 2274 static void
440
+ − 2275 mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
428
+ − 2276 {
+ − 2277 /* Set the size of the control .... */
442
+ − 2278 if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ − 2279 NULL,
+ − 2280 0, 0, w, h,
+ − 2281 SWP_NOZORDER | SWP_NOMOVE
+ − 2282 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING))
+ − 2283 mswindows_output_last_error ("resizing");
+ − 2284 }
+ − 2285
+ − 2286 /* Simply resize the window here. */
+ − 2287 static void
+ − 2288 mswindows_redisplay_subwindow (Lisp_Image_Instance *p)
+ − 2289 {
+ − 2290 mswindows_resize_subwindow (p,
+ − 2291 IMAGE_INSTANCE_WIDTH (p),
+ − 2292 IMAGE_INSTANCE_HEIGHT (p));
428
+ − 2293 }
+ − 2294
+ − 2295 /* when you click on a widget you may activate another widget this
+ − 2296 needs to be checked and all appropriate widgets updated */
+ − 2297 static void
442
+ − 2298 mswindows_redisplay_widget (Lisp_Image_Instance *p)
428
+ − 2299 {
442
+ − 2300 /* Possibly update the face font and colors. */
+ − 2301 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))
+ − 2302 && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
+ − 2303 || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
+ − 2304 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)))
428
+ − 2305 {
+ − 2306 /* set the widget font from the widget face */
+ − 2307 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
434
+ − 2308 WM_SETFONT,
440
+ − 2309 (WPARAM) mswindows_widget_hfont
442
+ − 2310 (p, IMAGE_INSTANCE_FRAME (p)),
428
+ − 2311 MAKELPARAM (TRUE, 0));
+ − 2312 }
442
+ − 2313 /* Possibly update the dimensions. */
+ − 2314 if (IMAGE_INSTANCE_SIZE_CHANGED (p))
+ − 2315 {
+ − 2316 mswindows_resize_subwindow (p,
+ − 2317 IMAGE_INSTANCE_WIDTH (p),
+ − 2318 IMAGE_INSTANCE_HEIGHT (p));
+ − 2319 }
+ − 2320 /* Possibly update the text in the widget. */
+ − 2321 if (IMAGE_INSTANCE_TEXT_CHANGED (p)
+ − 2322 && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)))
+ − 2323 {
+ − 2324 Extbyte* lparam=0;
+ − 2325 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p),
+ − 2326 C_STRING_ALLOCA, lparam,
+ − 2327 Qnative);
+ − 2328 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ − 2329 WM_SETTEXT, 0, (LPARAM)lparam);
+ − 2330 }
454
+ − 2331 /* Set active state. */
+ − 2332 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
+ − 2333 {
+ − 2334 Lisp_Object item = IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p);
+ − 2335 LONG style = GetWindowLong
+ − 2336 (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ − 2337 GWL_STYLE);
+ − 2338
+ − 2339 if (CONSP (item))
+ − 2340 item = XCAR (item);
+ − 2341
+ − 2342 if (gui_item_active_p (item))
+ − 2343 SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ − 2344 GWL_STYLE, style & ~WS_DISABLED);
+ − 2345 else
+ − 2346 SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ − 2347 GWL_STYLE, style | WS_DISABLED);
+ − 2348 }
428
+ − 2349 }
+ − 2350
442
+ − 2351 /* register widgets into our hashtable so that we can cope with the
428
+ − 2352 callbacks. The hashtable is weak so deregistration is handled
+ − 2353 automatically */
+ − 2354 static int
442
+ − 2355 mswindows_register_gui_item (Lisp_Object image_instance,
+ − 2356 Lisp_Object gui, Lisp_Object domain)
428
+ − 2357 {
442
+ − 2358 Lisp_Object frame = DOMAIN_FRAME (domain);
428
+ − 2359 struct frame* f = XFRAME (frame);
442
+ − 2360 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f),
428
+ − 2361 gui,
+ − 2362 WIDGET_GLYPH_SLOT);
442
+ − 2363 Fputhash (make_int (id), image_instance,
+ − 2364 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
+ − 2365 Fputhash (make_int (id), XGUI_ITEM (gui)->callback,
+ − 2366 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
+ − 2367 Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex,
+ − 2368 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
428
+ − 2369 return id;
+ − 2370 }
+ − 2371
+ − 2372 static int
+ − 2373 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
+ − 2374 {
442
+ − 2375 return mswindows_register_gui_item (instance,
+ − 2376 XIMAGE_INSTANCE_WIDGET_ITEM (instance),
428
+ − 2377 domain);
+ − 2378 }
+ − 2379
+ − 2380 static void
502
+ − 2381 mswindows_subwindow_instantiate (Lisp_Object image_instance,
+ − 2382 Lisp_Object instantiator,
+ − 2383 Lisp_Object pointer_fg,
+ − 2384 Lisp_Object pointer_bg,
428
+ − 2385 int dest_mask, Lisp_Object domain)
+ − 2386 {
440
+ − 2387 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 2388 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
442
+ − 2389 Lisp_Object frame = DOMAIN_FRAME (domain);
428
+ − 2390 HWND wnd;
+ − 2391
442
+ − 2392 CHECK_MSWINDOWS_DEVICE (device);
428
+ − 2393
+ − 2394 /* have to set the type this late in case there is no device
+ − 2395 instantiation for a widget */
+ − 2396 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
+ − 2397 /* Allocate space for the clip window */
+ − 2398 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
+ − 2399
+ − 2400 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
+ − 2401 = CreateWindowEx(
+ − 2402 0, /* EX flags */
+ − 2403 XEMACS_CONTROL_CLASS,
+ − 2404 0, /* text */
+ − 2405 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
+ − 2406 0, /* starting x position */
+ − 2407 0, /* starting y position */
+ − 2408 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+ − 2409 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+ − 2410 /* parent window */
+ − 2411 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+ − 2412 NULL, /* No menu */
+ − 2413 NULL, /* must be null for this class */
+ − 2414 NULL)) == NULL)
434
+ − 2415 signal_simple_error ("window creation failed with code",
428
+ − 2416 make_int (GetLastError()));
+ − 2417
434
+ − 2418 wnd = CreateWindow( "STATIC",
428
+ − 2419 "",
434
+ − 2420 WS_CHILD,
428
+ − 2421 0, /* starting x position */
+ − 2422 0, /* starting y position */
+ − 2423 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+ − 2424 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+ − 2425 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
+ − 2426 0,
434
+ − 2427 (HINSTANCE)
428
+ − 2428 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
434
+ − 2429 GWL_HINSTANCE),
428
+ − 2430 NULL);
+ − 2431
+ − 2432 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
+ − 2433 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
+ − 2434 }
+ − 2435
+ − 2436 static int
440
+ − 2437 mswindows_image_instance_equal (Lisp_Image_Instance *p1,
+ − 2438 Lisp_Image_Instance *p2, int depth)
428
+ − 2439 {
+ − 2440 switch (IMAGE_INSTANCE_TYPE (p1))
+ − 2441 {
+ − 2442 case IMAGE_MONO_PIXMAP:
+ − 2443 case IMAGE_COLOR_PIXMAP:
+ − 2444 case IMAGE_POINTER:
434
+ − 2445 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
428
+ − 2446 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
+ − 2447 return 0;
+ − 2448 break;
434
+ − 2449
428
+ − 2450 default:
+ − 2451 break;
+ − 2452 }
+ − 2453
+ − 2454 return 1;
+ − 2455 }
+ − 2456
+ − 2457 static unsigned long
440
+ − 2458 mswindows_image_instance_hash (Lisp_Image_Instance *p, int depth)
428
+ − 2459 {
+ − 2460 switch (IMAGE_INSTANCE_TYPE (p))
+ − 2461 {
+ − 2462 case IMAGE_MONO_PIXMAP:
+ − 2463 case IMAGE_COLOR_PIXMAP:
+ − 2464 case IMAGE_POINTER:
+ − 2465 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
434
+ − 2466
428
+ − 2467 default:
+ − 2468 return 0;
+ − 2469 }
+ − 2470 }
+ − 2471
+ − 2472 /* Set all the slots in an image instance structure to reasonable
+ − 2473 default values. This is used somewhere within an instantiate
+ − 2474 method. It is assumed that the device slot within the image
+ − 2475 instance is already set -- this is the case when instantiate
+ − 2476 methods are called. */
+ − 2477
+ − 2478 static void
440
+ − 2479 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
428
+ − 2480 int slices,
+ − 2481 enum image_instance_type type)
+ − 2482 {
+ − 2483 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
+ − 2484 IMAGE_INSTANCE_TYPE (ii) = type;
+ − 2485 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
+ − 2486 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
+ − 2487 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
+ − 2488 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
+ − 2489 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
+ − 2490 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
+ − 2491 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
434
+ − 2492 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) =
428
+ − 2493 xnew_array_and_zero (HBITMAP, slices);
+ − 2494 }
+ − 2495
+ − 2496
+ − 2497 #ifdef HAVE_WIDGETS
+ − 2498
+ − 2499 /************************************************************************/
+ − 2500 /* widgets */
+ − 2501 /************************************************************************/
+ − 2502 static void
502
+ − 2503 mswindows_widget_instantiate (Lisp_Object image_instance,
+ − 2504 Lisp_Object instantiator,
428
+ − 2505 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 2506 int dest_mask, Lisp_Object domain,
442
+ − 2507 const char* class, int flags, int exflags)
428
+ − 2508 {
+ − 2509 /* this function can call lisp */
440
+ − 2510 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 2511 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
442
+ − 2512 Lisp_Object frame = DOMAIN_FRAME (domain);
428
+ − 2513 Extbyte* nm=0;
+ − 2514 HWND wnd;
+ − 2515 int id = 0xffff;
+ − 2516 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
440
+ − 2517 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
428
+ − 2518
442
+ − 2519 CHECK_MSWINDOWS_DEVICE (device);
428
+ − 2520
+ − 2521 if (!gui_item_active_p (gui))
+ − 2522 flags |= WS_DISABLED;
+ − 2523
+ − 2524 style = pgui->style;
+ − 2525
442
+ − 2526 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex))
428
+ − 2527 {
+ − 2528 id = mswindows_register_widget_instance (image_instance, domain);
+ − 2529 }
438
+ − 2530
428
+ − 2531 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
440
+ − 2532 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii),
+ − 2533 C_STRING_ALLOCA, nm,
+ − 2534 Qnative);
428
+ − 2535
+ − 2536 /* allocate space for the clip window and then allocate the clip window */
+ − 2537 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
+ − 2538
+ − 2539 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
+ − 2540 = CreateWindowEx(
438
+ − 2541 WS_EX_CONTROLPARENT, /* EX flags */
428
+ − 2542 XEMACS_CONTROL_CLASS,
+ − 2543 0, /* text */
+ − 2544 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
+ − 2545 0, /* starting x position */
+ − 2546 0, /* starting y position */
+ − 2547 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+ − 2548 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+ − 2549 /* parent window */
442
+ − 2550 DOMAIN_MSWINDOWS_HANDLE (domain),
428
+ − 2551 (HMENU)id, /* No menu */
+ − 2552 NULL, /* must be null for this class */
+ − 2553 NULL)) == NULL)
434
+ − 2554 signal_simple_error ("window creation failed with code",
428
+ − 2555 make_int (GetLastError()));
+ − 2556
434
+ − 2557 if ((wnd = CreateWindowEx(
428
+ − 2558 exflags /* | WS_EX_NOPARENTNOTIFY*/,
434
+ − 2559 class,
428
+ − 2560 nm,
+ − 2561 flags | WS_CHILD | WS_VISIBLE,
+ − 2562 0, /* starting x position */
+ − 2563 0, /* starting y position */
+ − 2564 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+ − 2565 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+ − 2566 /* parent window */
+ − 2567 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
+ − 2568 (HMENU)id, /* No menu */
434
+ − 2569 (HINSTANCE)
+ − 2570 GetWindowLong
428
+ − 2571 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
434
+ − 2572 GWL_HINSTANCE),
428
+ − 2573 NULL)) == NULL)
434
+ − 2574 signal_simple_error ("window creation failed with code",
428
+ − 2575 make_int (GetLastError()));
+ − 2576
+ − 2577 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
+ − 2578 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
+ − 2579 /* set the widget font from the widget face */
442
+ − 2580 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+ − 2581 SendMessage (wnd, WM_SETFONT,
+ − 2582 (WPARAM) mswindows_widget_hfont (ii, domain),
+ − 2583 MAKELPARAM (TRUE, 0));
+ − 2584 #if 0
+ − 2585 /* #### doesn't work. need to investigate more closely. */
+ − 2586 if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (ii))
+ − 2587 SetFocus (wnd);
+ − 2588 #endif
+ − 2589 }
+ − 2590
+ − 2591 /* Instantiate a native layout widget. */
+ − 2592 static void
+ − 2593 mswindows_native_layout_instantiate (Lisp_Object image_instance,
+ − 2594 Lisp_Object instantiator,
502
+ − 2595 Lisp_Object pointer_fg,
+ − 2596 Lisp_Object pointer_bg,
442
+ − 2597 int dest_mask, Lisp_Object domain)
+ − 2598 {
+ − 2599 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ − 2600
+ − 2601 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+ − 2602 pointer_bg, dest_mask, domain, "STATIC",
+ − 2603 /* Approximation to styles available with
+ − 2604 an XEmacs layout. */
+ − 2605 (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
+ − 2606 Qetched_in) ||
+ − 2607 EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
+ − 2608 Qetched_out) ||
+ − 2609 GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
+ − 2610 ? SS_ETCHEDFRAME : SS_SUNKEN) | DS_CONTROL,
+ − 2611 0);
428
+ − 2612 }
+ − 2613
+ − 2614 /* Instantiate a button widget. Unfortunately instantiated widgets are
+ − 2615 particular to a frame since they need to have a parent. It's not
+ − 2616 like images where you just select the image into the context you
438
+ − 2617 want to display it in and BitBlt it. So image instances can have a
428
+ − 2618 many-to-one relationship with things you see, whereas widgets can
+ − 2619 only be one-to-one (i.e. per frame) */
+ − 2620 static void
502
+ − 2621 mswindows_button_instantiate (Lisp_Object image_instance,
+ − 2622 Lisp_Object instantiator,
428
+ − 2623 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 2624 int dest_mask, Lisp_Object domain)
+ − 2625 {
442
+ − 2626 /* This function can call lisp */
440
+ − 2627 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 2628 HWND wnd;
444
+ − 2629 int flags = WS_TABSTOP | BS_NOTIFY;
+ − 2630 /* BS_NOTIFY #### is needed to get exotic feedback only. Since we
+ − 2631 seem to want nothing beyond BN_CLICK, the style is perhaps not
+ − 2632 necessary -- kkm */
428
+ − 2633 Lisp_Object style;
+ − 2634 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
440
+ − 2635 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
428
+ − 2636 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
+ − 2637
+ − 2638 if (!NILP (glyph))
+ − 2639 {
+ − 2640 if (!IMAGE_INSTANCEP (glyph))
+ − 2641 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
+ − 2642
+ − 2643 if (IMAGE_INSTANCEP (glyph))
434
+ − 2644 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
428
+ − 2645 BS_BITMAP : BS_ICON;
+ − 2646 }
+ − 2647
+ − 2648 style = pgui->style;
+ − 2649
438
+ − 2650 /* #### consider using the default face for radio and toggle
+ − 2651 buttons. */
428
+ − 2652 if (EQ (style, Qradio))
+ − 2653 {
+ − 2654 flags |= BS_RADIOBUTTON;
+ − 2655 }
+ − 2656 else if (EQ (style, Qtoggle))
+ − 2657 {
+ − 2658 flags |= BS_AUTOCHECKBOX;
+ − 2659 }
+ − 2660 else
438
+ − 2661 {
+ − 2662 flags |= BS_DEFPUSHBUTTON;
+ − 2663 }
428
+ − 2664
+ − 2665 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
440
+ − 2666 pointer_bg, dest_mask, domain, "BUTTON",
438
+ − 2667 flags, 0);
428
+ − 2668
+ − 2669 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ − 2670 /* set the checked state */
+ − 2671 if (gui_item_selected_p (gui))
434
+ − 2672 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
428
+ − 2673 else
+ − 2674 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+ − 2675 /* add the image if one was given */
440
+ − 2676 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)
+ − 2677 &&
+ − 2678 IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph)))
428
+ − 2679 {
434
+ − 2680 SendMessage (wnd, BM_SETIMAGE,
+ − 2681 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
428
+ − 2682 IMAGE_BITMAP : IMAGE_ICON),
438
+ − 2683 (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
+ − 2684 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
+ − 2685 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
428
+ − 2686 }
+ − 2687 }
+ − 2688
442
+ − 2689 /* Update the state of a button. */
+ − 2690 static void
+ − 2691 mswindows_button_redisplay (Lisp_Object image_instance)
+ − 2692 {
+ − 2693 /* This function can GC if IN_REDISPLAY is false. */
+ − 2694 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ − 2695
+ − 2696 /* buttons checked or otherwise */
+ − 2697 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
+ − 2698 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ − 2699 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
+ − 2700 else
+ − 2701 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ − 2702 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+ − 2703 }
+ − 2704
428
+ − 2705 /* instantiate an edit control */
+ − 2706 static void
502
+ − 2707 mswindows_edit_field_instantiate (Lisp_Object image_instance,
+ − 2708 Lisp_Object instantiator,
+ − 2709 Lisp_Object pointer_fg,
+ − 2710 Lisp_Object pointer_bg,
+ − 2711 int dest_mask, Lisp_Object domain)
428
+ − 2712 {
+ − 2713 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
434
+ − 2714 pointer_bg, dest_mask, domain, "EDIT",
428
+ − 2715 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
438
+ − 2716 | WS_BORDER, WS_EX_CLIENTEDGE);
428
+ − 2717 }
+ − 2718
+ − 2719 /* instantiate a progress gauge */
+ − 2720 static void
502
+ − 2721 mswindows_progress_gauge_instantiate (Lisp_Object image_instance,
+ − 2722 Lisp_Object instantiator,
+ − 2723 Lisp_Object pointer_fg,
+ − 2724 Lisp_Object pointer_bg,
+ − 2725 int dest_mask, Lisp_Object domain)
428
+ − 2726 {
+ − 2727 HWND wnd;
440
+ − 2728 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
442
+ − 2729 Lisp_Object val;
428
+ − 2730 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
434
+ − 2731 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
438
+ − 2732 WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE);
428
+ − 2733 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ − 2734 /* set the colors */
502
+ − 2735 #if 0 /* #### fix this */
+ − 2736 SendMessage (wnd, PBM_SETBKCOLOR, 0,
434
+ − 2737 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
+ − 2738 (XCOLOR_INSTANCE
+ − 2739 (FACE_BACKGROUND
428
+ − 2740 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
442
+ − 2741 XIMAGE_INSTANCE_FRAME (ii))))));
502
+ − 2742 SendMessage (wnd, PBM_SETBARCOLOR, 0,
+ − 2743 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
434
+ − 2744 (XCOLOR_INSTANCE
+ − 2745 (FACE_FOREGROUND
428
+ − 2746 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
442
+ − 2747 XIMAGE_INSTANCE_FRAME (ii))))));
428
+ − 2748 #endif
442
+ − 2749 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEMS (ii))->value;
+ − 2750 CHECK_INT (val);
+ − 2751 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ − 2752 PBM_SETPOS, (WPARAM)XINT (val), 0);
428
+ − 2753 }
+ − 2754
+ − 2755 /* instantiate a tree view widget */
+ − 2756 static HTREEITEM add_tree_item (Lisp_Object image_instance,
+ − 2757 HWND wnd, HTREEITEM parent, Lisp_Object item,
+ − 2758 int children, Lisp_Object domain)
+ − 2759 {
+ − 2760 TV_INSERTSTRUCT tvitem;
+ − 2761 HTREEITEM ret;
+ − 2762
+ − 2763 tvitem.hParent = parent;
+ − 2764 tvitem.hInsertAfter = TVI_LAST;
+ − 2765 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
+ − 2766 tvitem.item.cChildren = children;
434
+ − 2767
428
+ − 2768 if (GUI_ITEMP (item))
+ − 2769 {
442
+ − 2770 tvitem.item.lParam = mswindows_register_gui_item (image_instance,
+ − 2771 item, domain);
428
+ − 2772 tvitem.item.mask |= TVIF_PARAM;
440
+ − 2773 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
+ − 2774 C_STRING_ALLOCA, tvitem.item.pszText,
+ − 2775 Qnative);
428
+ − 2776 }
+ − 2777 else
440
+ − 2778 TO_EXTERNAL_FORMAT (LISP_STRING, item,
+ − 2779 C_STRING_ALLOCA, tvitem.item.pszText,
+ − 2780 Qnative);
428
+ − 2781
+ − 2782 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
+ − 2783
434
+ − 2784 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
428
+ − 2785 0, (LPARAM)&tvitem)) == 0)
+ − 2786 signal_simple_error ("error adding tree view entry", item);
+ − 2787
+ − 2788 return ret;
+ − 2789 }
+ − 2790
+ − 2791 static void add_tree_item_list (Lisp_Object image_instance,
+ − 2792 HWND wnd, HTREEITEM parent, Lisp_Object list,
+ − 2793 Lisp_Object domain)
+ − 2794 {
+ − 2795 Lisp_Object rest;
+ − 2796
+ − 2797 /* get the first item */
+ − 2798 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
+ − 2799 /* recursively add items to the tree view */
+ − 2800 LIST_LOOP (rest, XCDR (list))
+ − 2801 {
+ − 2802 if (LISTP (XCAR (rest)))
+ − 2803 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
+ − 2804 else
+ − 2805 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
+ − 2806 }
+ − 2807 }
+ − 2808
+ − 2809 static void
502
+ − 2810 mswindows_tree_view_instantiate (Lisp_Object image_instance,
+ − 2811 Lisp_Object instantiator,
+ − 2812 Lisp_Object pointer_fg,
+ − 2813 Lisp_Object pointer_bg,
+ − 2814 int dest_mask, Lisp_Object domain)
428
+ − 2815 {
+ − 2816 Lisp_Object rest;
+ − 2817 HWND wnd;
+ − 2818 HTREEITEM parent;
440
+ − 2819 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 2820 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
434
+ − 2821 pointer_bg, dest_mask, domain, WC_TREEVIEW,
428
+ − 2822 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
+ − 2823 | TVS_HASLINES | TVS_HASBUTTONS,
438
+ − 2824 WS_EX_CLIENTEDGE);
428
+ − 2825
+ − 2826 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
434
+ − 2827
428
+ − 2828 /* define a root */
434
+ − 2829 parent = add_tree_item (image_instance, wnd, NULL,
+ − 2830 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
428
+ − 2831 TRUE, domain);
434
+ − 2832
428
+ − 2833 /* recursively add items to the tree view */
+ − 2834 /* add items to the tab */
+ − 2835 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+ − 2836 {
+ − 2837 if (LISTP (XCAR (rest)))
+ − 2838 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
+ − 2839 else
+ − 2840 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
+ − 2841 }
+ − 2842 }
+ − 2843
442
+ − 2844 /* Set the properties of a tree view. */
+ − 2845 static void
+ − 2846 mswindows_tree_view_redisplay (Lisp_Object image_instance)
+ − 2847 {
+ − 2848 /* This function can GC if IN_REDISPLAY is false. */
+ − 2849 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ − 2850
+ − 2851 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
+ − 2852 {
+ − 2853 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ − 2854 Lisp_Object rest;
+ − 2855 HTREEITEM parent;
+ − 2856 /* Delete previous items. */
+ − 2857 SendMessage (wnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
+ − 2858 /* define a root */
+ − 2859 parent = add_tree_item (image_instance, wnd, NULL,
+ − 2860 XCAR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)),
+ − 2861 TRUE, IMAGE_INSTANCE_DOMAIN (ii));
+ − 2862
+ − 2863 /* recursively add items to the tree view */
+ − 2864 /* add items to the tab */
+ − 2865 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
+ − 2866 {
+ − 2867 if (LISTP (XCAR (rest)))
+ − 2868 add_tree_item_list (image_instance, wnd, parent, XCAR (rest),
+ − 2869 IMAGE_INSTANCE_DOMAIN (ii));
+ − 2870 else
+ − 2871 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE,
+ − 2872 IMAGE_INSTANCE_DOMAIN (ii));
+ − 2873 }
+ − 2874 }
+ − 2875 }
+ − 2876
428
+ − 2877 /* instantiate a tab control */
442
+ − 2878 static int
+ − 2879 add_tab_item (Lisp_Object image_instance,
+ − 2880 HWND wnd, Lisp_Object item,
+ − 2881 Lisp_Object domain, int i)
428
+ − 2882 {
442
+ − 2883 TC_ITEM tvitem;
+ − 2884 int ret = 0;
428
+ − 2885
+ − 2886 tvitem.mask = TCIF_TEXT;
434
+ − 2887
428
+ − 2888 if (GUI_ITEMP (item))
+ − 2889 {
442
+ − 2890 tvitem.lParam = mswindows_register_gui_item (image_instance,
+ − 2891 item, domain);
428
+ − 2892 tvitem.mask |= TCIF_PARAM;
440
+ − 2893 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
+ − 2894 C_STRING_ALLOCA, tvitem.pszText,
+ − 2895 Qnative);
428
+ − 2896 }
+ − 2897 else
+ − 2898 {
+ − 2899 CHECK_STRING (item);
440
+ − 2900 TO_EXTERNAL_FORMAT (LISP_STRING, item,
+ − 2901 C_STRING_ALLOCA, tvitem.pszText,
+ − 2902 Qnative);
428
+ − 2903 }
+ − 2904
+ − 2905 tvitem.cchTextMax = strlen (tvitem.pszText);
+ − 2906
442
+ − 2907 if ((ret = SendMessage (wnd, TCM_INSERTITEM,
+ − 2908 i, (LPARAM)&tvitem)) < 0)
428
+ − 2909 signal_simple_error ("error adding tab entry", item);
+ − 2910
+ − 2911 return ret;
+ − 2912 }
+ − 2913
+ − 2914 static void
502
+ − 2915 mswindows_tab_control_instantiate (Lisp_Object image_instance,
+ − 2916 Lisp_Object instantiator,
+ − 2917 Lisp_Object pointer_fg,
+ − 2918 Lisp_Object pointer_bg,
+ − 2919 int dest_mask, Lisp_Object domain)
428
+ − 2920 {
442
+ − 2921 /* This function can call lisp */
428
+ − 2922 Lisp_Object rest;
+ − 2923 HWND wnd;
442
+ − 2924 int i = 0, selected = 0;
440
+ − 2925 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
438
+ − 2926 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
+ − 2927 unsigned int flags = WS_TABSTOP;
+ − 2928
+ − 2929 if (EQ (orient, Qleft) || EQ (orient, Qright))
+ − 2930 {
+ − 2931 flags |= TCS_VERTICAL | TCS_MULTILINE;
+ − 2932 }
+ − 2933 if (EQ (orient, Qright) || EQ (orient, Qbottom))
+ − 2934 {
+ − 2935 flags |= TCS_BOTTOM;
+ − 2936 }
+ − 2937
428
+ − 2938 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
434
+ − 2939 pointer_bg, dest_mask, domain, WC_TABCONTROL,
428
+ − 2940 /* borders don't suit tabs so well */
438
+ − 2941 flags, 0);
428
+ − 2942 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ − 2943 /* add items to the tab */
+ − 2944 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+ − 2945 {
442
+ − 2946 int idx = add_tab_item (image_instance, wnd, XCAR (rest), domain, i);
+ − 2947 assert (idx == i);
+ − 2948 if (gui_item_selected_p (XCAR (rest)))
+ − 2949 selected = i;
438
+ − 2950 i++;
428
+ − 2951 }
442
+ − 2952 SendMessage (wnd, TCM_SETCURSEL, selected, 0);
428
+ − 2953 }
+ − 2954
442
+ − 2955 /* Set the properties of a tab control. */
+ − 2956 static void
+ − 2957 mswindows_tab_control_redisplay (Lisp_Object image_instance)
428
+ − 2958 {
442
+ − 2959 /* This function can GC if IN_REDISPLAY is false. */
440
+ − 2960 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
442
+ − 2961 #ifdef DEBUG_WIDGET_OUTPUT
+ − 2962 stderr_out ("tab control %p redisplayed\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
+ − 2963 #endif
+ − 2964 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
+ − 2965 ||
+ − 2966 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
428
+ − 2967 {
+ − 2968 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
454
+ − 2969 int i = 0, selected_idx = 0;
428
+ − 2970 Lisp_Object rest;
442
+ − 2971
+ − 2972 assert (!NILP (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
+ − 2973
+ − 2974 /* If only the order has changed then simply select the first
+ − 2975 one. This stops horrendous rebuilding of the tabs each time
+ − 2976 you click on one. */
+ − 2977 if (tab_control_order_only_changed (image_instance))
428
+ − 2978 {
442
+ − 2979 Lisp_Object selected =
+ − 2980 gui_item_list_find_selected
+ − 2981 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
+ − 2982 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
+ − 2983 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
+ − 2984
+ − 2985 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+ − 2986 {
+ − 2987 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
+ − 2988 {
+ − 2989 Lisp_Object old_selected = gui_item_list_find_selected
+ − 2990 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
+ − 2991
+ − 2992 /* Pick up the new selected item. */
+ − 2993 XGUI_ITEM (old_selected)->selected =
+ − 2994 XGUI_ITEM (XCAR (rest))->selected;
+ − 2995 XGUI_ITEM (XCAR (rest))->selected =
+ − 2996 XGUI_ITEM (selected)->selected;
+ − 2997 /* We're not actually changing the items. */
+ − 2998 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
+ − 2999 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
+ − 3000
+ − 3001 SendMessage (wnd, TCM_SETCURSEL, i, 0);
+ − 3002 #ifdef DEBUG_WIDGET_OUTPUT
+ − 3003 stderr_out ("tab control %p selected item %d\n",
+ − 3004 IMAGE_INSTANCE_SUBWINDOW_ID (ii), i);
+ − 3005 #endif
+ − 3006 break;
+ − 3007 }
+ − 3008 i++;
+ − 3009 }
428
+ − 3010 }
442
+ − 3011 else
+ − 3012 {
+ − 3013 /* delete the pre-existing items */
+ − 3014 SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
+ − 3015
+ − 3016 /* add items to the tab */
+ − 3017 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
+ − 3018 {
+ − 3019 add_tab_item (image_instance, wnd, XCAR (rest),
+ − 3020 IMAGE_INSTANCE_FRAME (ii), i);
+ − 3021 if (gui_item_selected_p (XCAR (rest)))
454
+ − 3022 selected_idx = i;
442
+ − 3023 i++;
+ − 3024 }
454
+ − 3025 SendMessage (wnd, TCM_SETCURSEL, selected_idx, 0);
442
+ − 3026 }
428
+ − 3027 }
+ − 3028 }
+ − 3029
+ − 3030 /* instantiate a static control possible for putting other things in */
+ − 3031 static void
502
+ − 3032 mswindows_label_instantiate (Lisp_Object image_instance,
+ − 3033 Lisp_Object instantiator,
428
+ − 3034 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ − 3035 int dest_mask, Lisp_Object domain)
+ − 3036 {
+ − 3037 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
434
+ − 3038 pointer_bg, dest_mask, domain, "STATIC",
428
+ − 3039 0, WS_EX_STATICEDGE);
+ − 3040 }
+ − 3041
+ − 3042 /* instantiate a scrollbar control */
+ − 3043 static void
502
+ − 3044 mswindows_scrollbar_instantiate (Lisp_Object image_instance,
+ − 3045 Lisp_Object instantiator,
+ − 3046 Lisp_Object pointer_fg,
+ − 3047 Lisp_Object pointer_bg,
428
+ − 3048 int dest_mask, Lisp_Object domain)
+ − 3049 {
+ − 3050 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
434
+ − 3051 pointer_bg, dest_mask, domain, "SCROLLBAR",
438
+ − 3052 WS_TABSTOP, WS_EX_CLIENTEDGE);
428
+ − 3053 }
+ − 3054
+ − 3055 /* instantiate a combo control */
+ − 3056 static void
502
+ − 3057 mswindows_combo_box_instantiate (Lisp_Object image_instance,
+ − 3058 Lisp_Object instantiator,
+ − 3059 Lisp_Object pointer_fg,
+ − 3060 Lisp_Object pointer_bg,
+ − 3061 int dest_mask, Lisp_Object domain)
428
+ − 3062 {
440
+ − 3063 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
442
+ − 3064 HWND wnd;
428
+ − 3065 Lisp_Object rest;
442
+ − 3066 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
438
+ − 3067 int len, height;
428
+ − 3068
+ − 3069 /* Maybe ought to generalise this more but it may be very windows
+ − 3070 specific. In windows the window height of a combo box is the
+ − 3071 height when the combo box is open. Thus we need to set the height
+ − 3072 before creating the window and then reset it to a single line
+ − 3073 after the window is created so that redisplay does the right
+ − 3074 thing. */
438
+ − 3075 widget_instantiate (image_instance, instantiator, pointer_fg,
+ − 3076 pointer_bg, dest_mask, domain);
+ − 3077
+ − 3078 /* We now have everything right apart from the height. */
+ − 3079 default_face_font_info (domain, 0, 0, &height, 0, 0);
442
+ − 3080 GET_LIST_LENGTH (items, len);
438
+ − 3081
+ − 3082 height = (height + WIDGET_BORDER_HEIGHT * 2 ) * len;
+ − 3083 IMAGE_INSTANCE_HEIGHT (ii) = height;
440
+ − 3084
438
+ − 3085 /* Now create the widget. */
428
+ − 3086 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
434
+ − 3087 pointer_bg, dest_mask, domain, "COMBOBOX",
428
+ − 3088 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
434
+ − 3089 | CBS_AUTOHSCROLL
428
+ − 3090 | CBS_HASSTRINGS | WS_VSCROLL,
438
+ − 3091 WS_EX_CLIENTEDGE);
+ − 3092 /* Reset the height. layout will probably do this safely, but better make sure. */
440
+ − 3093 image_instance_layout (image_instance,
438
+ − 3094 IMAGE_UNSPECIFIED_GEOMETRY,
+ − 3095 IMAGE_UNSPECIFIED_GEOMETRY,
442
+ − 3096 IMAGE_UNCHANGED_GEOMETRY,
+ − 3097 IMAGE_UNCHANGED_GEOMETRY,
438
+ − 3098 domain);
+ − 3099
428
+ − 3100 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ − 3101 /* add items to the combo box */
+ − 3102 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
442
+ − 3103 LIST_LOOP (rest, items)
428
+ − 3104 {
+ − 3105 Extbyte* lparam;
440
+ − 3106 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (rest),
+ − 3107 C_STRING_ALLOCA, lparam,
+ − 3108 Qnative);
428
+ − 3109 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
+ − 3110 signal_simple_error ("error adding combo entries", instantiator);
+ − 3111 }
+ − 3112 }
+ − 3113
+ − 3114 /* get properties of a control */
+ − 3115 static Lisp_Object
+ − 3116 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
+ − 3117 {
440
+ − 3118 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
442
+ − 3119 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
428
+ − 3120 /* get the text from a control */
+ − 3121 if (EQ (prop, Q_text))
+ − 3122 {
+ − 3123 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
442
+ − 3124 Extbyte *buf = (Extbyte*) alloca (len+1);
434
+ − 3125
428
+ − 3126 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
440
+ − 3127 return build_ext_string (buf, Qnative);
428
+ − 3128 }
+ − 3129 return Qunbound;
+ − 3130 }
+ − 3131
+ − 3132 /* get properties of a button */
+ − 3133 static Lisp_Object
+ − 3134 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
+ − 3135 {
440
+ − 3136 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
442
+ − 3137 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
428
+ − 3138 /* check the state of a button */
+ − 3139 if (EQ (prop, Q_selected))
+ − 3140 {
+ − 3141 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
+ − 3142 return Qt;
+ − 3143 else
+ − 3144 return Qnil;
+ − 3145 }
+ − 3146 return Qunbound;
+ − 3147 }
+ − 3148
+ − 3149 /* get properties of a combo box */
+ − 3150 static Lisp_Object
+ − 3151 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
+ − 3152 {
440
+ − 3153 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
442
+ − 3154 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
428
+ − 3155 /* get the text from a control */
+ − 3156 if (EQ (prop, Q_text))
+ − 3157 {
+ − 3158 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
+ − 3159 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
442
+ − 3160 Extbyte* buf = (Extbyte*) alloca (len+1);
428
+ − 3161 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
440
+ − 3162 return build_ext_string (buf, Qnative);
428
+ − 3163 }
+ − 3164 return Qunbound;
+ − 3165 }
+ − 3166
442
+ − 3167 /* set the properties of a progress gauge */
+ − 3168 static void
+ − 3169 mswindows_progress_gauge_redisplay (Lisp_Object image_instance)
428
+ − 3170 {
440
+ − 3171 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
428
+ − 3172
442
+ − 3173 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
428
+ − 3174 {
442
+ − 3175 Lisp_Object val;
+ − 3176 #ifdef ERROR_CHECK_GLYPHS
+ − 3177 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
+ − 3178 #endif
+ − 3179 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
+ − 3180 #ifdef DEBUG_WIDGET_OUTPUT
+ − 3181 stderr_out ("progress gauge displayed value on %p updated to %ld\n",
+ − 3182 WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ − 3183 XINT(val));
+ − 3184 #endif
428
+ − 3185 CHECK_INT (val);
+ − 3186 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ − 3187 PBM_SETPOS, (WPARAM)XINT (val), 0);
+ − 3188 }
+ − 3189 }
+ − 3190
+ − 3191 LRESULT WINAPI
438
+ − 3192 mswindows_control_wnd_proc (HWND hwnd, UINT msg,
428
+ − 3193 WPARAM wParam, LPARAM lParam)
+ − 3194 {
438
+ − 3195 switch (msg)
428
+ − 3196 {
+ − 3197 case WM_NOTIFY:
+ − 3198 case WM_COMMAND:
+ − 3199 case WM_CTLCOLORBTN:
+ − 3200 case WM_CTLCOLORLISTBOX:
+ − 3201 case WM_CTLCOLOREDIT:
+ − 3202 case WM_CTLCOLORSTATIC:
+ − 3203 case WM_CTLCOLORSCROLLBAR:
+ − 3204
438
+ − 3205 return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam);
428
+ − 3206 default:
438
+ − 3207 return DefWindowProc (hwnd, msg, wParam, lParam);
428
+ − 3208 }
+ − 3209 }
+ − 3210
+ − 3211 #endif /* HAVE_WIDGETS */
+ − 3212
+ − 3213
+ − 3214 /************************************************************************/
+ − 3215 /* initialization */
+ − 3216 /************************************************************************/
+ − 3217
+ − 3218 void
+ − 3219 syms_of_glyphs_mswindows (void)
+ − 3220 {
+ − 3221 defkeyword (&Q_resource_id, ":resource-id");
+ − 3222 defkeyword (&Q_resource_type, ":resource-type");
+ − 3223 }
+ − 3224
+ − 3225 void
+ − 3226 console_type_create_glyphs_mswindows (void)
+ − 3227 {
442
+ − 3228 /* image methods - display */
428
+ − 3229 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
+ − 3230 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
+ − 3231 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
+ − 3232 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
442
+ − 3233 CONSOLE_HAS_METHOD (mswindows, redisplay_subwindow);
+ − 3234 CONSOLE_HAS_METHOD (mswindows, resize_subwindow);
+ − 3235 CONSOLE_HAS_METHOD (mswindows, redisplay_widget);
428
+ − 3236 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
+ − 3237 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
+ − 3238 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
+ − 3239 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
442
+ − 3240
+ − 3241 /* image methods - printer */
+ − 3242 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_image_instance);
+ − 3243 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_image_instance);
+ − 3244 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_equal);
+ − 3245 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_hash);
+ − 3246 CONSOLE_INHERITS_METHOD (msprinter, mswindows, init_image_instance_from_eimage);
+ − 3247 CONSOLE_INHERITS_METHOD (msprinter, mswindows, locate_pixmap_file);
428
+ − 3248 }
+ − 3249
+ − 3250 void
+ − 3251 image_instantiator_format_create_glyphs_mswindows (void)
+ − 3252 {
442
+ − 3253 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing);
+ − 3254 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string);
+ − 3255 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string);
+ − 3256 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit);
428
+ − 3257 /* image-instantiator types */
442
+ − 3258 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
+ − 3259 INITIALIZE_DEVICE_IIFORMAT (msprinter, xbm);
+ − 3260 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
+ − 3261 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xbm, instantiate);
428
+ − 3262 #ifdef HAVE_XPM
+ − 3263 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
442
+ − 3264 INITIALIZE_DEVICE_IIFORMAT (msprinter, xpm);
428
+ − 3265 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
442
+ − 3266 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xpm, instantiate);
428
+ − 3267 #endif
+ − 3268 #ifdef HAVE_XFACE
+ − 3269 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
442
+ − 3270 INITIALIZE_DEVICE_IIFORMAT (msprinter, xface);
428
+ − 3271 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
442
+ − 3272 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xface, instantiate);
428
+ − 3273 #endif
+ − 3274 #ifdef HAVE_JPEG
442
+ − 3275 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, jpeg);
428
+ − 3276 #endif
+ − 3277 #ifdef HAVE_TIFF
442
+ − 3278 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, tiff);
434
+ − 3279 #endif
428
+ − 3280 #ifdef HAVE_PNG
442
+ − 3281 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, png);
434
+ − 3282 #endif
428
+ − 3283 #ifdef HAVE_GIF
442
+ − 3284 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif);
434
+ − 3285 #endif
428
+ − 3286 #ifdef HAVE_WIDGETS
442
+ − 3287 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
+ − 3288 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
+ − 3289 /* layout widget */
+ − 3290 IIFORMAT_VALID_CONSOLE (mswindows, layout);
+ − 3291 INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout);
+ − 3292 IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate);
428
+ − 3293 /* button widget */
+ − 3294 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
+ − 3295 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
+ − 3296 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
442
+ − 3297 IIFORMAT_HAS_DEVMETHOD (mswindows, button, redisplay);
+ − 3298 /* edit-field widget */
428
+ − 3299 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
+ − 3300 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
442
+ − 3301 /* subwindow */
428
+ − 3302 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
+ − 3303 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
+ − 3304 /* label */
+ − 3305 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
+ − 3306 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
+ − 3307 /* combo box */
+ − 3308 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
+ − 3309 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
+ − 3310 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
+ − 3311 /* scrollbar */
+ − 3312 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
+ − 3313 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
+ − 3314 /* progress gauge */
+ − 3315 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
442
+ − 3316 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, redisplay);
428
+ − 3317 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
+ − 3318 /* tree view widget */
+ − 3319 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
+ − 3320 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
442
+ − 3321 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, redisplay);
428
+ − 3322 /* tab control widget */
+ − 3323 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
+ − 3324 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
442
+ − 3325 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, redisplay);
428
+ − 3326 #endif
+ − 3327 /* windows bitmap format */
+ − 3328 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
+ − 3329 IIFORMAT_HAS_METHOD (bmp, validate);
+ − 3330 IIFORMAT_HAS_METHOD (bmp, normalize);
+ − 3331 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
+ − 3332 IIFORMAT_HAS_METHOD (bmp, instantiate);
+ − 3333
+ − 3334 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
+ − 3335 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
442
+ − 3336 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, bmp);
428
+ − 3337
+ − 3338 /* mswindows resources */
+ − 3339 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
+ − 3340 "mswindows-resource");
+ − 3341
+ − 3342 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
+ − 3343 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
+ − 3344 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
+ − 3345 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
+ − 3346
434
+ − 3347 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
428
+ − 3348 check_valid_resource_symbol);
+ − 3349 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
+ − 3350 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
442
+ − 3351 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, mswindows_resource);
428
+ − 3352 }
+ − 3353
+ − 3354 void
+ − 3355 vars_of_glyphs_mswindows (void)
+ − 3356 {
+ − 3357 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
+ − 3358 A list of the directories in which mswindows bitmap files may be found.
+ − 3359 This is used by the `make-image-instance' function.
+ − 3360 */ );
+ − 3361 Vmswindows_bitmap_file_path = Qnil;
+ − 3362 }
+ − 3363
+ − 3364 void
+ − 3365 complex_vars_of_glyphs_mswindows (void)
+ − 3366 {
+ − 3367 }