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