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