1 /* mswindows-specific glyph objects.
2 Copyright (C) 1998, 1999, 2000 Andy Piper.
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Synched up with: Not in FSF. */
23 /* written by Andy Piper <andy@xemacs.org> plagiarising bits from
30 #define OEMRESOURCE /* Define OCR_ and friend constants */
31 #include "console-msw.h"
32 #include "glyphs-msw.h"
33 #include "objects-msw.h"
46 #include "file-coding.h"
54 #define WIDGET_GLYPH_SLOT 0
56 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
57 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
58 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
59 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
61 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
64 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff);
67 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png);
70 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif);
73 DEFINE_DEVICE_IIFORMAT (mswindows, xpm);
74 DEFINE_DEVICE_IIFORMAT (msprinter, xpm);
76 DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
77 DEFINE_DEVICE_IIFORMAT (msprinter, xbm);
79 DEFINE_DEVICE_IIFORMAT (mswindows, xface);
80 DEFINE_DEVICE_IIFORMAT (msprinter, xface);
82 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
83 DEFINE_DEVICE_IIFORMAT (mswindows, native_layout);
84 DEFINE_DEVICE_IIFORMAT (mswindows, button);
85 DEFINE_DEVICE_IIFORMAT (mswindows, edit_field);
86 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
87 DEFINE_DEVICE_IIFORMAT (mswindows, widget);
88 DEFINE_DEVICE_IIFORMAT (mswindows, label);
89 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
90 DEFINE_DEVICE_IIFORMAT (mswindows, combo_box);
91 DEFINE_DEVICE_IIFORMAT (mswindows, progress_gauge);
92 DEFINE_DEVICE_IIFORMAT (mswindows, tree_view);
93 DEFINE_DEVICE_IIFORMAT (mswindows, tab_control);
95 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
97 Lisp_Object Vmswindows_bitmap_file_path;
98 static COLORREF transparent_color = RGB (1,1,1);
100 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource);
101 Lisp_Object Q_resource_type, Q_resource_id;
102 Lisp_Object Qmswindows_resource;
105 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
107 enum image_instance_type type);
109 mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
113 * Given device D, retrieve compatible device context. D can be either
114 * mswindows or an msprinter device.
117 get_device_compdc (struct device *d)
119 if (DEVICE_MSWINDOWS_P (d))
120 return DEVICE_MSWINDOWS_HCDC (d);
122 return DEVICE_MSPRINTER_HCDC (d);
126 * Initialize image instance pixel sizes in II. For a display bitmap,
127 * these will be same as real bitmap sizes. For a printer bitmap,
128 * these will be scaled up so that the bitmap is proportionally enlarged
129 * when output to printer. Redisplay code takes care of scaling, to
130 * conserve memory we do not really scale bitmaps. Set the watermark
132 * #### Add support for unscalable bitmaps.
134 static void init_image_instance_geometry (Lisp_Image_Instance *ii)
136 struct device *d = DOMAIN_XDEVICE (ii->domain);
138 if (/* #### Scaleable && */ DEVICE_MSPRINTER_P (d))
140 HDC printer_dc = DEVICE_MSPRINTER_HCDC (d);
141 HDC display_dc = CreateCompatibleDC (NULL);
142 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
143 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
144 GetDeviceCaps (printer_dc, LOGPIXELSX),
145 GetDeviceCaps (display_dc, LOGPIXELSX));
146 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
147 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
148 GetDeviceCaps (printer_dc, LOGPIXELSY),
149 GetDeviceCaps (display_dc, LOGPIXELSY));
153 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
154 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii);
155 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
156 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii);
160 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
162 /************************************************************************/
163 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
165 /************************************************************************/
166 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
167 int width, int height,
170 unsigned char** bmp_data)
172 struct device *d = XDEVICE (device);
176 BITMAPINFO* bmp_info;
177 unsigned char *ip, *dp;
179 if (GetDeviceCaps (get_device_compdc (d), BITSPIXEL) > 0)
181 int bpline = BPLINE(width * 3);
182 /* FIXME: we can do this because 24bpp implies no color table, once
183 * we start palettizing this is no longer true. The X versions of
184 * this function quantises to 256 colors or bit masks down to a
185 * long. Windows can actually handle rgb triples in the raw so I
186 * don't see much point trying to optimize down to the best
187 * structure - unless it has memory / color allocation implications
189 bmp_info=xnew_and_zero (BITMAPINFO);
196 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
197 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
198 bmp_info->bmiHeader.biSizeImage=width*height*3;
200 /* bitmap data needs to be in blue, green, red triples - in that
201 order, eimage is in RGB format so we need to convert */
202 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
203 *bit_count = bpline * height;
212 for (i = height-1; i >= 0; i--) {
213 dp = (*bmp_data) + (i * bpline);
214 for (j = 0; j < width; j++) {
222 else /* scale to 256 colors */
226 int bpline = BPLINE (width * 3);
227 /* Quantize the image and get a histogram while we're at it.
228 Do this first to save memory */
229 qtable = build_EImage_quantable(pic, width, height, 256);
230 if (qtable == NULL) return NULL;
232 /* use our quantize table to allocate the colors */
233 ncolors = qtable->num_active_colors;
234 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
235 sizeof(RGBQUAD) * ncolors);
242 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
244 bmp_info->bmiHeader.biBitCount=8;
245 bmp_info->bmiHeader.biCompression=BI_RGB;
246 bmp_info->bmiHeader.biSizeImage=bpline*height;
247 bmp_info->bmiHeader.biClrUsed=ncolors;
248 bmp_info->bmiHeader.biClrImportant=ncolors;
250 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
251 *bit_count = bpline * height;
260 /* build up an RGBQUAD colortable */
261 for (i = 0; i < qtable->num_active_colors; i++)
263 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
264 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
265 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
266 colortbl[i].rgbReserved = 0;
269 /* now build up the data. picture has to be upside-down and
270 back-to-front for msw bitmaps */
272 for (i = height-1; i >= 0; i--)
274 dp = (*bmp_data) + (i * bpline);
275 for (j = 0; j < width; j++)
280 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
285 /* fix up the standard stuff */
286 bmp_info->bmiHeader.biWidth=width;
287 bmp_info->bmiHeader.biHeight=height;
288 bmp_info->bmiHeader.biPlanes=1;
289 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
290 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
291 bmp_info->bmiHeader.biYPelsPerMeter=0;
296 /* Given a pixmap filename, look through all of the "standard" places
297 where the file might be located. Return a full pathname if found;
298 otherwise, return Qnil. */
301 mswindows_locate_pixmap_file (Lisp_Object name)
303 /* This function can GC if IN_REDISPLAY is false */
306 /* Check non-absolute pathnames with a directory component relative to
307 the search path; that's the way Xt does it. */
308 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
309 (XSTRING_BYTE (name, 0) == '.' &&
310 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
311 (XSTRING_BYTE (name, 1) == '.' &&
312 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
314 if (!NILP (Ffile_readable_p (name)))
315 return Fexpand_file_name (name, Qnil);
320 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
322 Lisp_Object temp = list1 (Vdata_directory);
326 locate_file (temp, name, Qnil, &found, R_OK);
334 /* Initialize an image instance from a bitmap
336 DEST_MASK specifies the mask of allowed image types.
338 If this fails, signal an error. INSTANTIATOR is only used
339 in the error message. */
342 init_image_instance_from_dibitmap (Lisp_Image_Instance *ii,
343 BITMAPINFO *bmp_info,
348 Lisp_Object instantiator,
349 int x_hot, int y_hot,
352 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii));
354 enum image_instance_type type;
358 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
359 type = IMAGE_COLOR_PIXMAP;
360 else if (dest_mask & IMAGE_POINTER_MASK)
361 type = IMAGE_POINTER;
363 incompatible_image_types (instantiator, dest_mask,
364 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
366 hdc = get_device_compdc (d);
367 bitmap = CreateDIBSection (hdc,
373 if (!bitmap || !bmp_buf)
374 signal_simple_error ("Unable to create bitmap", instantiator);
376 /* copy in the actual bitmap */
377 memcpy (bmp_buf, bmp_data, bmp_bits);
379 mswindows_initialize_dibitmap_image_instance (ii, slices, type);
381 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
382 find_keyword_in_vector (instantiator, Q_file);
384 /* Fixup a set of bitmaps. */
385 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
387 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
388 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
389 bmp_info->bmiHeader.biWidth;
390 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
391 bmp_info->bmiHeader.biHeight;
392 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
393 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
394 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
395 init_image_instance_geometry (ii);
399 mswindows_initialize_image_instance_mask (ii, hdc);
402 if (type == IMAGE_POINTER)
404 mswindows_initialize_image_instance_icon(ii, TRUE);
409 image_instance_add_dibitmap (Lisp_Image_Instance *ii,
410 BITMAPINFO *bmp_info,
414 Lisp_Object instantiator)
416 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii));
419 HBITMAP bitmap = CreateDIBSection (get_device_compdc (d),
425 if (!bitmap || !bmp_buf)
426 signal_simple_error ("Unable to create bitmap", instantiator);
428 /* copy in the actual bitmap */
429 memcpy (bmp_buf, bmp_data, bmp_bits);
430 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (ii, slice) = bitmap;
434 mswindows_init_image_instance_from_eimage (Lisp_Image_Instance *ii,
435 int width, int height,
437 unsigned char *eimage,
439 Lisp_Object instantiator,
442 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
443 BITMAPINFO* bmp_info;
444 unsigned char* bmp_data;
449 CHECK_MSGDI_DEVICE (device);
451 /* this is a hack but MaskBlt and TransparentBlt are not supported
452 on most windows variants */
453 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
454 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
456 for (slice = 0; slice < slices; slice++)
458 /* build a bitmap from the eimage */
459 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height,
460 eimage + (width * height * 3 * slice),
461 &bmp_bits, &bmp_data)))
463 signal_simple_error ("EImage to DIBitmap conversion failed",
467 /* Now create the pixmap and set up the image instance */
469 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
470 bmp_data, bmp_bits, slices, instantiator,
473 image_instance_add_dibitmap (ii, bmp_info, bmp_data, bmp_bits, slice,
482 set_mono_pixel (unsigned char* bits,
483 int bpline, int height,
484 int x, int y, int white)
487 unsigned char bitnum;
488 /* Find the byte on which this scanline begins */
489 i = (height - y - 1) * bpline;
490 /* Find the byte containing this pixel */
492 /* Which bit is it? */
493 bitnum = (unsigned char) (7 - (x & 7));
494 if (white) /* Turn it on */
495 bits[i] |= (1 << bitnum);
496 else /* Turn it off */
497 bits[i] &= ~(1 << bitnum);
501 mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
506 unsigned char *dibits, *and_bits;
507 BITMAPINFO *bmp_info =
508 (BITMAPINFO*) xmalloc_and_zero (sizeof (BITMAPINFO) + sizeof (RGBQUAD));
510 int height = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (image);
512 int maskbpline = BPLINE ((IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) + 7) / 8);
513 int bpline = BPLINE (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) * 3);
518 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
519 bmp_info->bmiHeader.biHeight = height;
520 bmp_info->bmiHeader.biPlanes = 1;
521 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
522 bmp_info->bmiHeader.biBitCount = 1;
523 bmp_info->bmiHeader.biCompression = BI_RGB;
524 bmp_info->bmiHeader.biClrUsed = 2;
525 bmp_info->bmiHeader.biClrImportant = 2;
526 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
527 bmp_info->bmiColors[0].rgbRed = 0;
528 bmp_info->bmiColors[0].rgbGreen = 0;
529 bmp_info->bmiColors[0].rgbBlue = 0;
530 bmp_info->bmiColors[0].rgbReserved = 0;
531 bmp_info->bmiColors[1].rgbRed = 255;
532 bmp_info->bmiColors[1].rgbGreen = 255;
533 bmp_info->bmiColors[1].rgbBlue = 255;
534 bmp_info->bmiColors[0].rgbReserved = 0;
536 if (!(mask = CreateDIBSection (hcdc,
546 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
547 /* build up an in-memory set of bits to mess with */
550 bmp_info->bmiHeader.biWidth = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
551 bmp_info->bmiHeader.biHeight = -height;
552 bmp_info->bmiHeader.biPlanes = 1;
553 bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
554 bmp_info->bmiHeader.biBitCount = 24;
555 bmp_info->bmiHeader.biCompression = BI_RGB;
556 bmp_info->bmiHeader.biClrUsed = 0;
557 bmp_info->bmiHeader.biClrImportant = 0;
558 bmp_info->bmiHeader.biSizeImage = height * bpline;
560 dibits = (unsigned char*) xmalloc_and_zero (bpline * height);
562 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
567 DIB_RGB_COLORS) <= 0)
573 /* now set the colored bits in the mask and transparent ones to
574 black in the original */
575 for (i = 0; i < IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); i++)
577 for (j=0; j<height; j++)
579 unsigned char* idx = &dibits[j * bpline + i * 3];
581 if (RGB (idx[2], idx[1], idx[0]) == transparent_color)
583 idx[0] = idx[1] = idx[2] = 0;
584 set_mono_pixel (and_bits, maskbpline, height, i, j, TRUE);
588 set_mono_pixel (and_bits, maskbpline, height, i, j, FALSE);
594 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
604 SelectObject(hcdc, old);
606 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
610 mswindows_initialize_image_instance_icon (Lisp_Image_Instance* image,
615 /* we rely on windows to do any resizing necessary */
616 x_icon.fIcon=cursor ? FALSE : TRUE;
617 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
618 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
619 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
620 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
622 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
623 CreateIconIndirect (&x_icon);
627 create_resized_bitmap (HBITMAP curbmp, struct frame *f,
634 HDC hcdc = get_device_compdc (XDEVICE (FRAME_DEVICE (f)));
635 HDC hdcDst = CreateCompatibleDC (hcdc);
637 old1 = SelectObject (hcdc, curbmp);
639 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
641 old2 = SelectObject (hdcDst, newbmp);
643 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
649 DeleteObject (newbmp);
654 SelectObject (hdcDst, old2);
655 SelectObject (hcdc, old1);
662 mswindows_create_resized_bitmap (Lisp_Image_Instance* ii,
666 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii),
668 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
669 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
674 mswindows_create_resized_mask (Lisp_Image_Instance* ii,
678 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii) == NULL)
681 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_MASK (ii),
683 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
684 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
688 #if 0 /* Currently unused */
689 /* #### Warning: This function is not correct anymore with
690 resizable printer bitmaps. If you uncomment it, clean it. --kkm */
692 mswindows_resize_dibitmap_instance (Lisp_Image_Instance* ii,
696 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
697 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
702 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
703 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
704 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
705 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
707 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
708 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
709 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
710 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
716 /**********************************************************************
718 **********************************************************************/
728 static struct color_symbol*
729 extract_xpm_color_names (Lisp_Object device,
731 Lisp_Object color_symbol_alist,
734 /* This function can GC */
736 Lisp_Object results = Qnil;
738 struct color_symbol *colortbl;
739 struct gcpro gcpro1, gcpro2;
741 GCPRO2 (results, device);
743 /* We built up results to be (("name" . #<color>) ...) so that if an
744 error happens we don't lose any malloc()ed data, or more importantly,
745 leave any pixels allocated in the server. */
747 LIST_LOOP (rest, color_symbol_alist)
749 Lisp_Object cons = XCAR (rest);
750 Lisp_Object name = XCAR (cons);
751 Lisp_Object value = XCDR (cons);
757 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
760 assert (COLOR_SPECIFIERP (value));
761 value = Fspecifier_instance (value, domain, Qnil, Qnil);
765 results = noseeum_cons (noseeum_cons (name, value), results);
768 UNGCPRO; /* no more evaluation */
771 if (i == 0) return 0;
773 colortbl = xnew_array_and_zero (struct color_symbol, i);
777 Lisp_Object cons = XCAR (results);
779 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
781 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (cons),
782 C_STRING_ALLOCA, colortbl[j].name,
784 colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
785 free_cons (XCONS (cons));
787 results = XCDR (results);
788 free_cons (XCONS (cons));
793 static int xpm_to_eimage (Lisp_Object image, const Extbyte *buffer,
794 unsigned char** data,
795 int* width, int* height,
796 int* x_hot, int* y_hot,
798 struct color_symbol* color_symbols,
803 int result, i, j, transp_idx, maskbpline;
806 COLORREF color; /* the american spelling virus hits again .. */
811 xpminfo.valuemask=XpmHotspot;
814 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
823 signal_simple_error ("Invalid XPM data", image);
827 signal_double_file_error ("Parsing pixmap data",
828 "out of memory", image);
832 signal_double_file_error_2 ("Parsing pixmap data",
834 make_int (result), image);
838 *width = xpmimage.width;
839 *height = xpmimage.height;
840 maskbpline = BPLINE ((~7UL & (unsigned long)(*width + 7)) / 8);
842 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
846 XpmFreeXpmImage (&xpmimage);
847 XpmFreeXpmInfo (&xpminfo);
851 /* build a color table to speed things up */
852 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
856 XpmFreeXpmImage (&xpmimage);
857 XpmFreeXpmInfo (&xpminfo);
861 for (i=0; i<xpmimage.ncolors; i++)
864 /* pick up symbolic colors in preference */
865 if (xpmimage.colorTable[i].symbolic)
867 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
869 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
872 colortbl[i]=transparent_color;
874 goto label_found_color;
876 else if (color_symbols)
878 for (j = 0; j<nsymbols; j++)
880 if (!strcmp (xpmimage.colorTable[i].symbolic,
881 color_symbols[j].name ))
883 colortbl[i]=color_symbols[j].color;
884 goto label_found_color;
888 else if (xpmimage.colorTable[i].c_color == 0)
893 /* pick up transparencies */
894 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
897 colortbl[i]=transparent_color;
899 goto label_found_color;
901 /* finally pick up a normal color spec */
902 if (xpmimage.colorTable[i].c_color)
905 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
906 goto label_found_color;
912 XpmFreeXpmImage (&xpmimage);
913 XpmFreeXpmInfo (&xpminfo);
919 /* convert the image */
922 for (i = 0; i< *width * *height; i++)
924 color = colortbl[*sptr++];
926 /* split out the 0x02bbggrr colorref into an rgb triple */
927 *dptr++=GetRValue (color); /* red */
928 *dptr++=GetGValue (color); /* green */
929 *dptr++=GetBValue (color); /* blue */
932 *x_hot=xpminfo.x_hotspot;
933 *y_hot=xpminfo.y_hotspot;
935 XpmFreeXpmImage (&xpmimage);
936 XpmFreeXpmInfo (&xpminfo);
942 mswindows_xpm_instantiate (Lisp_Object image_instance,
943 Lisp_Object instantiator,
944 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
945 int dest_mask, Lisp_Object domain)
947 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
948 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
949 const Extbyte *bytes;
951 unsigned char *eimage;
952 int width, height, x_hot, y_hot;
953 BITMAPINFO* bmp_info;
954 unsigned char* bmp_data;
956 int nsymbols=0, transp;
957 struct color_symbol* color_symbols=NULL;
959 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
960 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
963 CHECK_MSGDI_DEVICE (device);
965 assert (!NILP (data));
967 TO_EXTERNAL_FORMAT (LISP_STRING, data,
968 ALLOCA, (bytes, len),
971 /* in case we have color symbols */
972 color_symbols = extract_xpm_color_names (device, domain,
973 color_symbol_alist, &nsymbols);
975 /* convert to an eimage to make processing easier */
976 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
977 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
979 signal_simple_error ("XPM to EImage conversion failed",
987 xfree (color_symbols[nsymbols].name);
989 xfree(color_symbols);
992 /* build a bitmap from the eimage */
993 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
994 &bmp_bits, &bmp_data)))
996 signal_simple_error ("XPM to EImage conversion failed",
1001 /* Now create the pixmap and set up the image instance */
1002 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
1003 bmp_data, bmp_bits, 1, instantiator,
1004 x_hot, y_hot, transp);
1009 #endif /* HAVE_XPM */
1011 /**********************************************************************
1013 **********************************************************************/
1016 bmp_validate (Lisp_Object instantiator)
1018 file_or_data_must_be_present (instantiator);
1022 bmp_normalize (Lisp_Object inst, Lisp_Object console_type,
1023 Lisp_Object dest_mask)
1025 return simple_image_type_normalize (inst, console_type, Qbmp);
1029 bmp_possible_dest_types (void)
1031 return IMAGE_COLOR_PIXMAP_MASK;
1035 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1036 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1037 int dest_mask, Lisp_Object domain)
1039 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1040 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1041 const Extbyte *bytes;
1043 BITMAPFILEHEADER* bmp_file_header;
1044 BITMAPINFO* bmp_info;
1047 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1049 CHECK_MSGDI_DEVICE (device);
1051 assert (!NILP (data));
1053 TO_EXTERNAL_FORMAT (LISP_STRING, data,
1054 ALLOCA, (bytes, len),
1057 /* Then slurp the image into memory, decoding along the way.
1058 The result is the image in a simple one-byte-per-pixel
1061 bmp_file_header=(BITMAPFILEHEADER*)bytes;
1062 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
1063 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
1064 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
1066 /* Now create the pixmap and set up the image instance */
1067 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
1068 bmp_data, bmp_bits, 1, instantiator,
1073 /**********************************************************************
1075 **********************************************************************/
1078 mswindows_resource_validate (Lisp_Object instantiator)
1080 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
1082 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
1084 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
1085 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
1090 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type,
1091 Lisp_Object dest_mask)
1093 /* This function can call lisp */
1094 Lisp_Object file = Qnil;
1095 struct gcpro gcpro1, gcpro2;
1096 Lisp_Object alist = Qnil;
1098 GCPRO2 (file, alist);
1100 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1103 if (CONSP (file)) /* failure locating filename */
1104 signal_double_file_error ("Opening pixmap file",
1105 "no such file or directory",
1108 if (NILP (file)) /* no conversion necessary */
1109 RETURN_UNGCPRO (inst);
1111 alist = tagged_vector_to_alist (inst);
1114 alist = remassq_no_quit (Q_file, alist);
1115 alist = Fcons (Fcons (Q_file, file), alist);
1119 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
1121 RETURN_UNGCPRO (result);
1126 mswindows_resource_possible_dest_types (void)
1128 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1138 #define OCR_ICOCUR 32647
1139 #define OIC_SAMPLE 32512
1140 #define OIC_HAND 32513
1141 #define OIC_QUES 32514
1142 #define OIC_BANG 32515
1143 #define OIC_NOTE 32516
1144 #define OIC_WINLOGO 32517
1145 #if defined (CYGWIN) && CYGWIN_VERSION_DLL_MAJOR < 21
1146 #define LR_SHARED 0x8000
1150 static const resource_t bitmap_table[] =
1153 { "close", OBM_CLOSE },
1154 { "uparrow", OBM_UPARROW },
1155 { "dnarrow", OBM_DNARROW },
1156 { "rgarrow", OBM_RGARROW },
1157 { "lfarrow", OBM_LFARROW },
1158 { "reduce", OBM_REDUCE },
1159 { "zoom", OBM_ZOOM },
1160 { "restore", OBM_RESTORE },
1161 { "reduced", OBM_REDUCED },
1162 { "zoomd", OBM_ZOOMD },
1163 { "restored", OBM_RESTORED },
1164 { "uparrowd", OBM_UPARROWD },
1165 { "dnarrowd", OBM_DNARROWD },
1166 { "rgarrowd", OBM_RGARROWD },
1167 { "lfarrowd", OBM_LFARROWD },
1168 { "mnarrow", OBM_MNARROW },
1169 { "combo", OBM_COMBO },
1170 { "uparrowi", OBM_UPARROWI },
1171 { "dnarrowi", OBM_DNARROWI },
1172 { "rgarrowi", OBM_RGARROWI },
1173 { "lfarrowi", OBM_LFARROWI },
1174 { "size", OBM_SIZE },
1175 { "btsize", OBM_BTSIZE },
1176 { "check", OBM_CHECK },
1177 { "checkboxes", OBM_CHECKBOXES },
1178 { "btncorners" , OBM_BTNCORNERS },
1182 static const resource_t cursor_table[] =
1185 { "normal", OCR_NORMAL },
1186 { "ibeam", OCR_IBEAM },
1187 { "wait", OCR_WAIT },
1188 { "cross", OCR_CROSS },
1190 /* { "icon", OCR_ICON }, */
1191 { "sizenwse", OCR_SIZENWSE },
1192 { "sizenesw", OCR_SIZENESW },
1193 { "sizewe", OCR_SIZEWE },
1194 { "sizens", OCR_SIZENS },
1195 { "sizeall", OCR_SIZEALL },
1196 /* { "icour", OCR_ICOCUR }, */
1201 static const resource_t icon_table[] =
1204 { "sample", OIC_SAMPLE },
1205 { "hand", OIC_HAND },
1206 { "ques", OIC_QUES },
1207 { "bang", OIC_BANG },
1208 { "note", OIC_NOTE },
1209 { "winlogo", OIC_WINLOGO },
1213 static int resource_name_to_resource (Lisp_Object name, int type)
1215 const resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1216 : type == IMAGE_ICON ? icon_table
1223 else if (!STRINGP (name))
1225 signal_simple_error ("invalid resource identifier", name);
1230 TO_EXTERNAL_FORMAT (LISP_STRING, name,
1231 C_STRING_ALLOCA, nm,
1233 if (!strcasecmp ((char*)res->name, nm))
1234 return res->resource_id;
1235 } while ((++res)->name);
1240 resource_symbol_to_type (Lisp_Object data)
1242 if (EQ (data, Qcursor))
1243 return IMAGE_CURSOR;
1244 else if (EQ (data, Qicon))
1246 else if (EQ (data, Qbitmap))
1247 return IMAGE_BITMAP;
1253 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1254 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1255 int dest_mask, Lisp_Object domain)
1257 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1258 unsigned int type = 0;
1259 HANDLE himage = NULL;
1261 HINSTANCE hinst = NULL;
1263 enum image_instance_type iitype;
1265 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1267 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1268 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1270 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1275 CHECK_MSGDI_DEVICE (device);
1277 type = resource_symbol_to_type (resource_type);
1279 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1280 iitype = IMAGE_POINTER;
1281 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1282 iitype = IMAGE_COLOR_PIXMAP;
1284 incompatible_image_types (instantiator, dest_mask,
1285 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1287 /* mess with the keyword info we were provided with */
1291 TO_EXTERNAL_FORMAT (LISP_STRING, file,
1295 CYGWIN_WIN32_PATH (f, fname);
1300 if (NILP (resource_id))
1301 resid = (LPCTSTR)fname;
1304 hinst = LoadLibraryEx (fname, NULL,
1305 LOAD_LIBRARY_AS_DATAFILE);
1306 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1310 TO_EXTERNAL_FORMAT (LISP_STRING, resource_id,
1311 C_STRING_ALLOCA, resid,
1315 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1317 signal_simple_error ("Invalid resource identifier", resource_id);
1319 /* load the image */
1320 if (xLoadImageA) /* not in NT 3.5 */
1322 if (!(himage = xLoadImageA (hinst, resid, type, 0, 0,
1323 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1325 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1326 signal_simple_error ("Cannot load image", instantiator);
1330 /* Is this correct? I don't really care. */
1334 himage = LoadBitmap (hinst, resid);
1337 himage = LoadCursor (hinst, resid);
1340 himage = LoadIcon (hinst, resid);
1345 signal_simple_error ("Cannot load image", instantiator);
1349 FreeLibrary (hinst);
1351 mswindows_initialize_dibitmap_image_instance (ii, 1, iitype);
1353 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1354 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
1355 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1356 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
1357 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1358 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1359 init_image_instance_geometry (ii);
1361 /* hey, we've got an icon type thing so we can reverse engineer the
1363 if (type != IMAGE_BITMAP)
1365 GetIconInfo ((HICON)himage, &iconinfo);
1366 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1367 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1368 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1369 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1370 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (HICON) himage;
1374 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1375 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (HBITMAP) himage;
1376 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1377 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1378 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1383 check_valid_resource_symbol (Lisp_Object data)
1385 CHECK_SYMBOL (data);
1386 if (!resource_symbol_to_type (data))
1387 signal_simple_error ("invalid resource type", data);
1391 check_valid_resource_id (Lisp_Object data)
1393 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1395 !resource_name_to_resource (data, IMAGE_ICON)
1397 !resource_name_to_resource (data, IMAGE_BITMAP))
1398 signal_simple_error ("invalid resource identifier", data);
1401 /**********************************************************************
1403 **********************************************************************/
1404 #ifndef HAVE_X_WINDOWS
1405 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1409 Copyright (c) 1988 X Consortium
1411 Permission is hereby granted, free of charge, to any person obtaining a copy
1412 of this software and associated documentation files (the "Software"), to deal
1413 in the Software without restriction, including without limitation the rights
1414 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1415 copies of the Software, and to permit persons to whom the Software is
1416 furnished to do so, subject to the following conditions:
1418 The above copyright notice and this permission notice shall be included in
1419 all copies or substantial portions of the Software.
1421 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1422 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1423 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1424 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1425 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1426 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1428 Except as contained in this notice, the name of the X Consortium shall not be
1429 used in advertising or otherwise to promote the sale, use or other dealings
1430 in this Software without prior written authorization from the X Consortium.
1435 * This file contains miscellaneous utility routines and is not part of the
1438 * Public entry points:
1440 * XmuReadBitmapData read data from FILE descriptor
1441 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1444 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1445 * that way (but don't use common source code so that people can have one
1446 * without the other).
1451 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1453 #ifndef BitmapSuccess
1454 #define BitmapSuccess 0
1455 #define BitmapOpenFailed 1
1456 #define BitmapFileInvalid 2
1457 #define BitmapNoMemory 3
1459 #define MAX_SIZE 255
1461 /* shared data for the image read/parse logic */
1462 static short hexTable[256]; /* conversion value */
1463 static int initialized = FALSE; /* easier to fill in at run time */
1466 * Table index for the hex values. Initialized once, first time.
1467 * Used for translation value or delimiter significance lookup.
1473 * We build the table at run time for several reasons:
1475 * 1. portable to non-ASCII machines.
1476 * 2. still reentrant since we set the init flag after setting table.
1477 * 3. easier to extend.
1478 * 4. less prone to bugs.
1480 hexTable['0'] = 0; hexTable['1'] = 1;
1481 hexTable['2'] = 2; hexTable['3'] = 3;
1482 hexTable['4'] = 4; hexTable['5'] = 5;
1483 hexTable['6'] = 6; hexTable['7'] = 7;
1484 hexTable['8'] = 8; hexTable['9'] = 9;
1485 hexTable['A'] = 10; hexTable['B'] = 11;
1486 hexTable['C'] = 12; hexTable['D'] = 13;
1487 hexTable['E'] = 14; hexTable['F'] = 15;
1488 hexTable['a'] = 10; hexTable['b'] = 11;
1489 hexTable['c'] = 12; hexTable['d'] = 13;
1490 hexTable['e'] = 14; hexTable['f'] = 15;
1492 /* delimiters of significance are flagged w/ negative value */
1493 hexTable[' '] = -1; hexTable[','] = -1;
1494 hexTable['}'] = -1; hexTable['\n'] = -1;
1495 hexTable['\t'] = -1;
1501 * read next hex value in the input stream, return -1 if EOF
1504 NextInt (FILE *fstream)
1511 /* loop, accumulate hex value until find delimiter */
1512 /* skip any initial delimiters found in read stream */
1520 /* trim high bits, check type and accumulate */
1522 if (isascii(ch) && isxdigit(ch)) {
1523 value = (value << 4) + hexTable[ch];
1525 } else if ((hexTable[ch]) < 0 && gotone)
1534 * The data returned by the following routine is always in left-most byte
1535 * first and left-most bit first. If it doesn't return BitmapSuccess then
1536 * its arguments won't have been touched. This routine should look as much
1537 * like the Xlib routine XReadBitmapfile as possible.
1539 int read_bitmap_data (FILE* fstream, unsigned int *width,
1540 unsigned int *height, unsigned char **datap,
1541 int *x_hot, int *y_hot)
1543 unsigned char *data = NULL; /* working variable */
1544 char line[MAX_SIZE]; /* input line from file */
1545 int size; /* number of bytes of data */
1546 char name_and_type[MAX_SIZE]; /* an input line */
1547 char *type; /* for parsing */
1548 int value; /* from an input line */
1549 int version10p; /* boolean, old format */
1550 int padding; /* to handle alignment */
1551 int bytes_per_line; /* per scanline of data */
1552 unsigned int ww = 0; /* width */
1553 unsigned int hh = 0; /* height */
1554 int hx = -1; /* x hotspot */
1555 int hy = -1; /* y hotspot */
1557 #define Xmalloc(size) malloc(size)
1559 /* first time initialization */
1560 if (initialized == FALSE) initHexTable();
1562 /* error cleanup and return macro */
1563 #define RETURN(code) { if (data) free (data); return code; }
1565 while (fgets(line, MAX_SIZE, fstream)) {
1566 if (strlen(line) == MAX_SIZE-1) {
1567 RETURN (BitmapFileInvalid);
1569 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1570 if (!(type = strrchr(name_and_type, '_')))
1571 type = name_and_type;
1575 if (!strcmp("width", type))
1576 ww = (unsigned int) value;
1577 if (!strcmp("height", type))
1578 hh = (unsigned int) value;
1579 if (!strcmp("hot", type)) {
1580 if (type-- == name_and_type || type-- == name_and_type)
1582 if (!strcmp("x_hot", type))
1584 if (!strcmp("y_hot", type))
1590 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1592 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1594 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1599 if (!(type = strrchr(name_and_type, '_')))
1600 type = name_and_type;
1604 if (strcmp("bits[]", type))
1608 RETURN (BitmapFileInvalid);
1610 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1615 bytes_per_line = (ww+7)/8 + padding;
1617 size = bytes_per_line * hh;
1618 data = (unsigned char *) Xmalloc ((unsigned int) size);
1620 RETURN (BitmapNoMemory);
1626 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1627 if ((value = NextInt(fstream)) < 0)
1628 RETURN (BitmapFileInvalid);
1630 if (!padding || ((bytes+2) % bytes_per_line))
1631 *(ptr++) = value >> 8;
1637 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1638 if ((value = NextInt(fstream)) < 0)
1639 RETURN (BitmapFileInvalid);
1647 RETURN (BitmapFileInvalid);
1654 if (x_hot) *x_hot = hx;
1655 if (y_hot) *y_hot = hy;
1657 RETURN (BitmapSuccess);
1661 int read_bitmap_data_from_file (const char *filename, unsigned int *width,
1662 unsigned int *height, unsigned char **datap,
1663 int *x_hot, int *y_hot)
1668 if ((fstream = fopen (filename, "r")) == NULL) {
1669 return BitmapOpenFailed;
1671 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1675 #endif /* HAVE_X_WINDOWS */
1677 /* this table flips four bits around. */
1678 static int flip_table[] =
1680 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1683 /* the bitmap data comes in the following format: Widths are padded to
1684 a multiple of 8. Scan lines are stored in increasing byte order
1685 from left to right, little-endian within a byte. 0 = white, 1 =
1686 black. It must be converted to the following format: Widths are
1687 padded to a multiple of 16. Scan lines are stored in increasing
1688 byte order from left to right, big-endian within a byte. 0 =
1689 black, 1 = white. */
1691 xbm_create_bitmap_from_data (HDC hdc, char *data,
1692 unsigned int width, unsigned int height,
1693 int mask, COLORREF fg, COLORREF bg)
1695 int old_width = (width + 7)/8;
1696 int new_width = BPLINE (2*((width + 15)/16));
1697 unsigned char *offset;
1699 unsigned char *new_data, *new_offset;
1701 BITMAPINFO *bmp_info =
1702 (BITMAPINFO*) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1708 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
1716 for (i=0; i<height; i++)
1718 offset = data + i*old_width;
1719 new_offset = new_data + i*new_width;
1721 for (j=0; j<old_width; j++)
1723 int byte = offset[j];
1724 new_offset[j] = ~ (unsigned char)
1725 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1729 /* if we want a mask invert the bits */
1732 new_offset = &new_data[height * new_width];
1733 while (new_offset-- != new_data)
1735 *new_offset ^= 0xff;
1739 bmp_info->bmiHeader.biWidth=width;
1740 bmp_info->bmiHeader.biHeight=-(LONG)height;
1741 bmp_info->bmiHeader.biPlanes=1;
1742 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1743 bmp_info->bmiHeader.biBitCount=1;
1744 bmp_info->bmiHeader.biCompression=BI_RGB;
1745 bmp_info->bmiHeader.biClrUsed = 2;
1746 bmp_info->bmiHeader.biClrImportant = 2;
1747 bmp_info->bmiHeader.biSizeImage = height * new_width;
1748 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1749 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1750 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1751 bmp_info->bmiColors[0].rgbReserved = 0;
1752 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1753 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1754 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1755 bmp_info->bmiColors[1].rgbReserved = 0;
1757 bitmap = CreateDIBSection (hdc,
1765 if (!bitmap || !bmp_buf)
1771 /* copy in the actual bitmap */
1772 memcpy (bmp_buf, new_data, height * new_width);
1778 /* Given inline data for a mono pixmap, initialize the given
1779 image instance accordingly. */
1782 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
1783 int width, int height,
1784 /* Note that data is in ext-format! */
1786 Lisp_Object instantiator,
1787 Lisp_Object pointer_fg,
1788 Lisp_Object pointer_bg,
1791 Lisp_Object mask_filename)
1793 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1794 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1795 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1796 enum image_instance_type type;
1797 COLORREF black = PALETTERGB (0,0,0);
1798 COLORREF white = PALETTERGB (255,255,255);
1801 CHECK_MSGDI_DEVICE (device);
1803 hdc = get_device_compdc (XDEVICE (device));
1805 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1806 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1808 if (!NILP (foreground) || !NILP (background))
1809 type = IMAGE_COLOR_PIXMAP;
1811 type = IMAGE_MONO_PIXMAP;
1813 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1814 type = IMAGE_MONO_PIXMAP;
1815 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1816 type = IMAGE_COLOR_PIXMAP;
1817 else if (dest_mask & IMAGE_POINTER_MASK)
1818 type = IMAGE_POINTER;
1820 incompatible_image_types (instantiator, dest_mask,
1821 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1822 | IMAGE_POINTER_MASK);
1824 mswindows_initialize_dibitmap_image_instance (ii, 1, type);
1826 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1827 find_keyword_in_vector (instantiator, Q_file);
1828 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = width;
1829 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = height;
1830 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1831 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1832 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1833 init_image_instance_geometry (ii);
1835 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1836 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1837 TRUE, black, white);
1841 case IMAGE_MONO_PIXMAP:
1842 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1843 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1844 FALSE, black, black);
1847 case IMAGE_COLOR_PIXMAP:
1849 COLORREF fg = black;
1850 COLORREF bg = white;
1852 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1854 Fmake_color_instance (foreground, device,
1855 encode_error_behavior_flag (ERROR_ME));
1857 if (COLOR_INSTANCEP (foreground))
1858 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1860 if (!NILP (background) && !COLOR_INSTANCEP (background))
1862 Fmake_color_instance (background, device,
1863 encode_error_behavior_flag (ERROR_ME));
1865 if (COLOR_INSTANCEP (background))
1866 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1868 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1869 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1871 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1872 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1879 COLORREF fg = black;
1880 COLORREF bg = white;
1882 if (NILP (foreground))
1883 foreground = pointer_fg;
1884 if (NILP (background))
1885 background = pointer_bg;
1887 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1888 find_keyword_in_vector (instantiator, Q_hotspot_x);
1889 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1890 find_keyword_in_vector (instantiator, Q_hotspot_y);
1891 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1892 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1893 if (COLOR_INSTANCEP (foreground))
1894 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1895 if (COLOR_INSTANCEP (background))
1896 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1898 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1899 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1901 mswindows_initialize_image_instance_icon (ii, TRUE);
1911 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1912 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1913 int dest_mask, int width, int height,
1914 /* Note that data is in ext-format! */
1917 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1918 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1919 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1920 HDC hdc = get_device_compdc (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
1923 if (!NILP (mask_data))
1925 const char *ext_data;
1927 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))),
1928 C_STRING_ALLOCA, ext_data,
1930 mask = xbm_create_bitmap_from_data (hdc,
1931 (unsigned char *) ext_data,
1932 XINT (XCAR (mask_data)),
1933 XINT (XCAR (XCDR (mask_data))),
1936 PALETTERGB (255,255,255));
1939 init_image_instance_from_xbm_inline (ii, width, height, bits,
1940 instantiator, pointer_fg, pointer_bg,
1941 dest_mask, mask, mask_file);
1944 /* Instantiate method for XBM's. */
1947 mswindows_xbm_instantiate (Lisp_Object image_instance,
1948 Lisp_Object instantiator,
1949 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1950 int dest_mask, Lisp_Object domain)
1952 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1953 const char *ext_data;
1955 assert (!NILP (data));
1957 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))),
1958 C_STRING_ALLOCA, ext_data,
1961 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1962 pointer_bg, dest_mask, XINT (XCAR (data)),
1963 XINT (XCAR (XCDR (data))), ext_data);
1967 /**********************************************************************
1969 **********************************************************************/
1971 /* This is about to get redefined! */
1974 /* We have to define SYSV32 so that compface.h includes string.h
1975 instead of strings.h. */
1980 #include <compface.h>
1984 /* JMP_BUF cannot be used here because if it doesn't get defined
1985 to jmp_buf we end up with a conflicting type error with the
1986 definition in compface.h */
1987 extern jmp_buf comp_env;
1991 mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1992 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1993 int dest_mask, Lisp_Object domain)
1995 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1997 char *p, *bits, *bp;
1998 const char * volatile emsg = 0;
1999 const char * volatile dstring;
2001 assert (!NILP (data));
2003 TO_EXTERNAL_FORMAT (LISP_STRING, data,
2004 C_STRING_ALLOCA, dstring,
2007 if ((p = strchr (dstring, ':')))
2012 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
2013 if (!(stattis = setjmp (comp_env)))
2015 UnCompAll ((char *) dstring);
2022 emsg = "uncompface: internal error";
2025 emsg = "uncompface: insufficient or invalid data";
2028 emsg = "uncompface: excess data ignored";
2033 signal_simple_error_2 (emsg, data, Qimage);
2035 bp = bits = (char *) alloca (PIXELS / 8);
2037 /* the compface library exports char F[], which uses a single byte per
2038 pixel to represent a 48x48 bitmap. Yuck. */
2039 for (i = 0, p = F; i < (PIXELS / 8); ++i)
2042 /* reverse the bit order of each byte... */
2043 for (b = n = 0; b < 8; ++b)
2050 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
2051 pointer_bg, dest_mask, 48, 48, bits);
2053 #endif /* HAVE_XFACE */
2056 /************************************************************************/
2057 /* image instance methods */
2058 /************************************************************************/
2061 mswindows_print_image_instance (Lisp_Image_Instance *p,
2062 Lisp_Object printcharfun,
2067 switch (IMAGE_INSTANCE_TYPE (p))
2069 case IMAGE_MONO_PIXMAP:
2070 case IMAGE_COLOR_PIXMAP:
2072 sprintf (buf, " (0x%lx",
2073 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
2074 write_c_string (buf, printcharfun);
2075 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2077 sprintf (buf, "/0x%lx",
2078 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2079 write_c_string (buf, printcharfun);
2081 write_c_string (")", printcharfun);
2089 #ifdef DEBUG_WIDGETS
2090 extern int debug_widget_instances;
2094 mswindows_finalize_image_instance (Lisp_Image_Instance *p)
2099 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
2101 if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p))
2102 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
2104 #ifdef DEBUG_WIDGETS
2105 debug_widget_instances--;
2106 stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
2108 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2110 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
2111 DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p));
2112 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
2118 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
2119 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
2121 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p))
2123 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
2125 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i))
2126 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i));
2127 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0;
2129 xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p));
2130 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0;
2132 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2133 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2134 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
2135 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
2136 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
2137 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2148 /************************************************************************/
2149 /* subwindow and widget support */
2150 /************************************************************************/
2153 mswindows_widget_hfont (Lisp_Image_Instance *p,
2156 Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (p);
2157 int under = FACE_UNDERLINE_P (face, domain);
2158 int strike = FACE_STRIKETHRU_P (face, domain);
2159 Lisp_Object font = query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (p),
2162 return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike);
2166 begin_defer_window_pos (struct frame *f)
2168 #ifdef DEFER_WINDOW_POS
2169 if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0)
2170 FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10);
2172 return FRAME_MSWINDOWS_DATA (f)->hdwp;
2175 /* unmap the image if it is a widget. This is used by redisplay via
2176 redisplay_unmap_subwindows */
2178 mswindows_unmap_subwindow (Lisp_Image_Instance *p)
2180 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2182 #ifdef DEFER_WINDOW_POS
2183 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2184 HDWP hdwp = begin_defer_window_pos (f);
2186 new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2189 SWP_HIDEWINDOW | SWP_NOACTIVATE |
2190 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
2191 /* Setting this flag causes the call to
2192 DeferWindowPos to fail with
2193 "Invalid parameter". I don't understand
2194 why we bother to try and set this
2196 /* | SWP_NOSENDCHANGING */
2199 mswindows_output_last_error ("unmapping");
2202 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2204 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2207 SWP_HIDEWINDOW | SWP_NOACTIVATE |
2208 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER );
2210 if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))
2211 SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
2215 /* map the subwindow. This is used by redisplay via
2216 redisplay_output_subwindow */
2218 mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
2219 struct display_glyph_area* dga)
2221 #ifdef DEFER_WINDOW_POS
2222 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2223 HDWP hdwp = begin_defer_window_pos (f);
2226 /* move the window before mapping it ... */
2227 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2229 x, y, dga->width, dga->height,
2231 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2232 /* ... adjust the child ... */
2233 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2235 -dga->xoffset, -dga->yoffset, 0, 0,
2236 SWP_NOZORDER | SWP_NOSIZE
2237 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2238 /* ... now map it - we are not allowed to move it at the same time. */
2239 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
2241 #ifdef DEFER_WINDOW_POS
2242 new_hdwp = DeferWindowPos
2244 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2246 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2248 /* | SWP_NOCOPYBITS */
2249 /* Setting this flag causes the call to
2250 DeferWindowPos to fail with
2251 "Invalid parameter". I don't understand
2252 why we bother to try and set this
2254 /* | SWP_NOSENDCHANGING */
2257 mswindows_output_last_error ("mapping");
2260 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2262 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2265 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2266 | SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE);
2271 /* resize the subwindow instance */
2273 mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
2275 /* Set the size of the control .... */
2276 if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2279 SWP_NOZORDER | SWP_NOMOVE
2280 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING))
2281 mswindows_output_last_error ("resizing");
2284 /* Simply resize the window here. */
2286 mswindows_redisplay_subwindow (Lisp_Image_Instance *p)
2288 mswindows_resize_subwindow (p,
2289 IMAGE_INSTANCE_WIDTH (p),
2290 IMAGE_INSTANCE_HEIGHT (p));
2293 /* when you click on a widget you may activate another widget this
2294 needs to be checked and all appropriate widgets updated */
2296 mswindows_redisplay_widget (Lisp_Image_Instance *p)
2298 /* Possibly update the face font and colors. */
2299 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))
2300 && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
2301 || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
2302 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)))
2304 /* set the widget font from the widget face */
2305 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2307 (WPARAM) mswindows_widget_hfont
2308 (p, IMAGE_INSTANCE_FRAME (p)),
2309 MAKELPARAM (TRUE, 0));
2311 /* Possibly update the dimensions. */
2312 if (IMAGE_INSTANCE_SIZE_CHANGED (p))
2314 mswindows_resize_subwindow (p,
2315 IMAGE_INSTANCE_WIDTH (p),
2316 IMAGE_INSTANCE_HEIGHT (p));
2318 /* Possibly update the text in the widget. */
2319 if (IMAGE_INSTANCE_TEXT_CHANGED (p)
2320 && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)))
2323 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p),
2324 C_STRING_ALLOCA, lparam,
2326 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2327 WM_SETTEXT, 0, (LPARAM)lparam);
2329 /* Set active state. */
2330 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
2332 Lisp_Object item = IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p);
2333 LONG style = GetWindowLong
2334 (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2340 if (gui_item_active_p (item))
2341 SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2342 GWL_STYLE, style & ~WS_DISABLED);
2344 SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2345 GWL_STYLE, style | WS_DISABLED);
2349 /* register widgets into our hashtable so that we can cope with the
2350 callbacks. The hashtable is weak so deregistration is handled
2353 mswindows_register_gui_item (Lisp_Object image_instance,
2354 Lisp_Object gui, Lisp_Object domain)
2356 Lisp_Object frame = DOMAIN_FRAME (domain);
2357 struct frame* f = XFRAME (frame);
2358 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f),
2361 Fputhash (make_int (id), image_instance,
2362 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
2363 Fputhash (make_int (id), XGUI_ITEM (gui)->callback,
2364 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
2365 Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex,
2366 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
2371 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2373 return mswindows_register_gui_item (instance,
2374 XIMAGE_INSTANCE_WIDGET_ITEM (instance),
2379 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2380 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2381 int dest_mask, Lisp_Object domain)
2383 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2384 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2385 Lisp_Object frame = DOMAIN_FRAME (domain);
2388 CHECK_MSWINDOWS_DEVICE (device);
2390 /* have to set the type this late in case there is no device
2391 instantiation for a widget */
2392 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2393 /* Allocate space for the clip window */
2394 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2396 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2399 XEMACS_CONTROL_CLASS,
2401 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2402 0, /* starting x position */
2403 0, /* starting y position */
2404 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2405 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2407 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2409 NULL, /* must be null for this class */
2411 signal_simple_error ("window creation failed with code",
2412 make_int (GetLastError()));
2414 wnd = CreateWindow( "STATIC",
2417 0, /* starting x position */
2418 0, /* starting y position */
2419 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2420 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2421 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2424 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2428 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2429 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2433 mswindows_image_instance_equal (Lisp_Image_Instance *p1,
2434 Lisp_Image_Instance *p2, int depth)
2436 switch (IMAGE_INSTANCE_TYPE (p1))
2438 case IMAGE_MONO_PIXMAP:
2439 case IMAGE_COLOR_PIXMAP:
2441 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2442 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2453 static unsigned long
2454 mswindows_image_instance_hash (Lisp_Image_Instance *p, int depth)
2456 switch (IMAGE_INSTANCE_TYPE (p))
2458 case IMAGE_MONO_PIXMAP:
2459 case IMAGE_COLOR_PIXMAP:
2461 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2468 /* Set all the slots in an image instance structure to reasonable
2469 default values. This is used somewhere within an instantiate
2470 method. It is assumed that the device slot within the image
2471 instance is already set -- this is the case when instantiate
2472 methods are called. */
2475 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
2477 enum image_instance_type type)
2479 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2480 IMAGE_INSTANCE_TYPE (ii) = type;
2481 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2482 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2483 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2484 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2485 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2486 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2487 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
2488 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) =
2489 xnew_array_and_zero (HBITMAP, slices);
2495 /************************************************************************/
2497 /************************************************************************/
2499 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2500 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2501 int dest_mask, Lisp_Object domain,
2502 const char* class, int flags, int exflags)
2504 /* this function can call lisp */
2505 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2506 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2507 Lisp_Object frame = DOMAIN_FRAME (domain);
2511 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2512 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2514 CHECK_MSWINDOWS_DEVICE (device);
2516 if (!gui_item_active_p (gui))
2517 flags |= WS_DISABLED;
2519 style = pgui->style;
2521 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex))
2523 id = mswindows_register_widget_instance (image_instance, domain);
2526 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2527 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii),
2528 C_STRING_ALLOCA, nm,
2531 /* allocate space for the clip window and then allocate the clip window */
2532 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2534 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2536 WS_EX_CONTROLPARENT, /* EX flags */
2537 XEMACS_CONTROL_CLASS,
2539 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2540 0, /* starting x position */
2541 0, /* starting y position */
2542 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2543 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2545 DOMAIN_MSWINDOWS_HANDLE (domain),
2546 (HMENU)id, /* No menu */
2547 NULL, /* must be null for this class */
2549 signal_simple_error ("window creation failed with code",
2550 make_int (GetLastError()));
2552 if ((wnd = CreateWindowEx(
2553 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2556 flags | WS_CHILD | WS_VISIBLE,
2557 0, /* starting x position */
2558 0, /* starting y position */
2559 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2560 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2562 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2563 (HMENU)id, /* No menu */
2566 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2569 signal_simple_error ("window creation failed with code",
2570 make_int (GetLastError()));
2572 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2573 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2574 /* set the widget font from the widget face */
2575 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2576 SendMessage (wnd, WM_SETFONT,
2577 (WPARAM) mswindows_widget_hfont (ii, domain),
2578 MAKELPARAM (TRUE, 0));
2580 /* #### doesn't work. need to investigate more closely. */
2581 if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (ii))
2586 /* Instantiate a native layout widget. */
2588 mswindows_native_layout_instantiate (Lisp_Object image_instance,
2589 Lisp_Object instantiator,
2590 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2591 int dest_mask, Lisp_Object domain)
2593 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2595 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2596 pointer_bg, dest_mask, domain, "STATIC",
2597 /* Approximation to styles available with
2598 an XEmacs layout. */
2599 (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2601 EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2603 GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
2604 ? SS_ETCHEDFRAME : SS_SUNKEN) | DS_CONTROL,
2608 /* Instantiate a button widget. Unfortunately instantiated widgets are
2609 particular to a frame since they need to have a parent. It's not
2610 like images where you just select the image into the context you
2611 want to display it in and BitBlt it. So image instances can have a
2612 many-to-one relationship with things you see, whereas widgets can
2613 only be one-to-one (i.e. per frame) */
2615 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2616 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2617 int dest_mask, Lisp_Object domain)
2619 /* This function can call lisp */
2620 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2622 int flags = WS_TABSTOP | BS_NOTIFY;
2623 /* BS_NOTIFY #### is needed to get exotic feedback only. Since we
2624 seem to want nothing beyond BN_CLICK, the style is perhaps not
2627 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2628 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2629 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2633 if (!IMAGE_INSTANCEP (glyph))
2634 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2636 if (IMAGE_INSTANCEP (glyph))
2637 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2638 BS_BITMAP : BS_ICON;
2641 style = pgui->style;
2643 /* #### consider using the default face for radio and toggle
2645 if (EQ (style, Qradio))
2647 flags |= BS_RADIOBUTTON;
2649 else if (EQ (style, Qtoggle))
2651 flags |= BS_AUTOCHECKBOX;
2655 flags |= BS_DEFPUSHBUTTON;
2658 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2659 pointer_bg, dest_mask, domain, "BUTTON",
2662 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2663 /* set the checked state */
2664 if (gui_item_selected_p (gui))
2665 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2667 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2668 /* add the image if one was given */
2669 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)
2671 IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph)))
2673 SendMessage (wnd, BM_SETIMAGE,
2674 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2675 IMAGE_BITMAP : IMAGE_ICON),
2676 (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2677 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2678 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2682 /* Update the state of a button. */
2684 mswindows_button_redisplay (Lisp_Object image_instance)
2686 /* This function can GC if IN_REDISPLAY is false. */
2687 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2689 /* buttons checked or otherwise */
2690 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
2691 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2692 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2694 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2695 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2698 /* instantiate an edit control */
2700 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2701 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2702 int dest_mask, Lisp_Object domain)
2704 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2705 pointer_bg, dest_mask, domain, "EDIT",
2706 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2707 | WS_BORDER, WS_EX_CLIENTEDGE);
2710 /* instantiate a progress gauge */
2712 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2713 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2714 int dest_mask, Lisp_Object domain)
2717 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2719 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2720 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2721 WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE);
2722 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2723 /* set the colors */
2724 #ifdef PBS_SETBKCOLOR
2725 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2726 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2729 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2730 XIMAGE_INSTANCE_FRAME (ii))))));
2732 #ifdef PBS_SETBARCOLOR
2733 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2734 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2737 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2738 XIMAGE_INSTANCE_FRAME (ii))))));
2740 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEMS (ii))->value;
2742 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2743 PBM_SETPOS, (WPARAM)XINT (val), 0);
2746 /* instantiate a tree view widget */
2747 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2748 HWND wnd, HTREEITEM parent, Lisp_Object item,
2749 int children, Lisp_Object domain)
2751 TV_INSERTSTRUCT tvitem;
2754 tvitem.hParent = parent;
2755 tvitem.hInsertAfter = TVI_LAST;
2756 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2757 tvitem.item.cChildren = children;
2759 if (GUI_ITEMP (item))
2761 tvitem.item.lParam = mswindows_register_gui_item (image_instance,
2763 tvitem.item.mask |= TVIF_PARAM;
2764 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2765 C_STRING_ALLOCA, tvitem.item.pszText,
2769 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2770 C_STRING_ALLOCA, tvitem.item.pszText,
2773 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2775 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2776 0, (LPARAM)&tvitem)) == 0)
2777 signal_simple_error ("error adding tree view entry", item);
2782 static void add_tree_item_list (Lisp_Object image_instance,
2783 HWND wnd, HTREEITEM parent, Lisp_Object list,
2788 /* get the first item */
2789 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2790 /* recursively add items to the tree view */
2791 LIST_LOOP (rest, XCDR (list))
2793 if (LISTP (XCAR (rest)))
2794 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2796 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2801 mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2802 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2803 int dest_mask, Lisp_Object domain)
2808 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2809 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2810 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2811 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2812 | TVS_HASLINES | TVS_HASBUTTONS,
2815 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2818 parent = add_tree_item (image_instance, wnd, NULL,
2819 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
2822 /* recursively add items to the tree view */
2823 /* add items to the tab */
2824 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2826 if (LISTP (XCAR (rest)))
2827 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2829 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2833 /* Set the properties of a tree view. */
2835 mswindows_tree_view_redisplay (Lisp_Object image_instance)
2837 /* This function can GC if IN_REDISPLAY is false. */
2838 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2840 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2842 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2845 /* Delete previous items. */
2846 SendMessage (wnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
2848 parent = add_tree_item (image_instance, wnd, NULL,
2849 XCAR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)),
2850 TRUE, IMAGE_INSTANCE_DOMAIN (ii));
2852 /* recursively add items to the tree view */
2853 /* add items to the tab */
2854 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
2856 if (LISTP (XCAR (rest)))
2857 add_tree_item_list (image_instance, wnd, parent, XCAR (rest),
2858 IMAGE_INSTANCE_DOMAIN (ii));
2860 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE,
2861 IMAGE_INSTANCE_DOMAIN (ii));
2866 /* instantiate a tab control */
2868 add_tab_item (Lisp_Object image_instance,
2869 HWND wnd, Lisp_Object item,
2870 Lisp_Object domain, int i)
2875 tvitem.mask = TCIF_TEXT;
2877 if (GUI_ITEMP (item))
2879 tvitem.lParam = mswindows_register_gui_item (image_instance,
2881 tvitem.mask |= TCIF_PARAM;
2882 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2883 C_STRING_ALLOCA, tvitem.pszText,
2888 CHECK_STRING (item);
2889 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2890 C_STRING_ALLOCA, tvitem.pszText,
2894 tvitem.cchTextMax = strlen (tvitem.pszText);
2896 if ((ret = SendMessage (wnd, TCM_INSERTITEM,
2897 i, (LPARAM)&tvitem)) < 0)
2898 signal_simple_error ("error adding tab entry", item);
2904 mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2905 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2906 int dest_mask, Lisp_Object domain)
2908 /* This function can call lisp */
2911 int i = 0, selected = 0;
2912 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2913 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
2914 unsigned int flags = WS_TABSTOP;
2916 if (EQ (orient, Qleft) || EQ (orient, Qright))
2918 flags |= TCS_VERTICAL | TCS_MULTILINE;
2920 if (EQ (orient, Qright) || EQ (orient, Qbottom))
2922 flags |= TCS_BOTTOM;
2925 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2926 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2927 /* borders don't suit tabs so well */
2929 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2930 /* add items to the tab */
2931 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2933 int idx = add_tab_item (image_instance, wnd, XCAR (rest), domain, i);
2935 if (gui_item_selected_p (XCAR (rest)))
2939 SendMessage (wnd, TCM_SETCURSEL, selected, 0);
2942 /* Set the properties of a tab control. */
2944 mswindows_tab_control_redisplay (Lisp_Object image_instance)
2946 /* This function can GC if IN_REDISPLAY is false. */
2947 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2948 #ifdef DEBUG_WIDGET_OUTPUT
2949 stderr_out ("tab control %p redisplayed\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
2951 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
2953 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
2955 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2956 int i = 0, selected_idx = 0;
2959 assert (!NILP (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2961 /* If only the order has changed then simply select the first
2962 one. This stops horrendous rebuilding of the tabs each time
2963 you click on one. */
2964 if (tab_control_order_only_changed (image_instance))
2966 Lisp_Object selected =
2967 gui_item_list_find_selected
2968 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
2969 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
2970 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
2972 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2974 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
2976 Lisp_Object old_selected = gui_item_list_find_selected
2977 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2979 /* Pick up the new selected item. */
2980 XGUI_ITEM (old_selected)->selected =
2981 XGUI_ITEM (XCAR (rest))->selected;
2982 XGUI_ITEM (XCAR (rest))->selected =
2983 XGUI_ITEM (selected)->selected;
2984 /* We're not actually changing the items. */
2985 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
2986 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
2988 SendMessage (wnd, TCM_SETCURSEL, i, 0);
2989 #ifdef DEBUG_WIDGET_OUTPUT
2990 stderr_out ("tab control %p selected item %d\n",
2991 IMAGE_INSTANCE_SUBWINDOW_ID (ii), i);
3000 /* delete the pre-existing items */
3001 SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
3003 /* add items to the tab */
3004 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
3006 add_tab_item (image_instance, wnd, XCAR (rest),
3007 IMAGE_INSTANCE_FRAME (ii), i);
3008 if (gui_item_selected_p (XCAR (rest)))
3012 SendMessage (wnd, TCM_SETCURSEL, selected_idx, 0);
3017 /* instantiate a static control possible for putting other things in */
3019 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3020 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3021 int dest_mask, Lisp_Object domain)
3023 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3024 pointer_bg, dest_mask, domain, "STATIC",
3025 0, WS_EX_STATICEDGE);
3028 /* instantiate a scrollbar control */
3030 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3031 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3032 int dest_mask, Lisp_Object domain)
3034 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3035 pointer_bg, dest_mask, domain, "SCROLLBAR",
3036 WS_TABSTOP, WS_EX_CLIENTEDGE);
3039 /* instantiate a combo control */
3041 mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3042 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3043 int dest_mask, Lisp_Object domain)
3045 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3048 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
3051 /* Maybe ought to generalise this more but it may be very windows
3052 specific. In windows the window height of a combo box is the
3053 height when the combo box is open. Thus we need to set the height
3054 before creating the window and then reset it to a single line
3055 after the window is created so that redisplay does the right
3057 widget_instantiate (image_instance, instantiator, pointer_fg,
3058 pointer_bg, dest_mask, domain);
3060 /* We now have everything right apart from the height. */
3061 default_face_font_info (domain, 0, 0, &height, 0, 0);
3062 GET_LIST_LENGTH (items, len);
3064 height = (height + WIDGET_BORDER_HEIGHT * 2 ) * len;
3065 IMAGE_INSTANCE_HEIGHT (ii) = height;
3067 /* Now create the widget. */
3068 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3069 pointer_bg, dest_mask, domain, "COMBOBOX",
3070 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
3072 | CBS_HASSTRINGS | WS_VSCROLL,
3074 /* Reset the height. layout will probably do this safely, but better make sure. */
3075 image_instance_layout (image_instance,
3076 IMAGE_UNSPECIFIED_GEOMETRY,
3077 IMAGE_UNSPECIFIED_GEOMETRY,
3078 IMAGE_UNCHANGED_GEOMETRY,
3079 IMAGE_UNCHANGED_GEOMETRY,
3082 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3083 /* add items to the combo box */
3084 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
3085 LIST_LOOP (rest, items)
3088 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (rest),
3089 C_STRING_ALLOCA, lparam,
3091 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
3092 signal_simple_error ("error adding combo entries", instantiator);
3096 /* get properties of a control */
3098 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
3100 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3101 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3102 /* get the text from a control */
3103 if (EQ (prop, Q_text))
3105 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
3106 Extbyte *buf = (Extbyte*) alloca (len+1);
3108 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
3109 return build_ext_string (buf, Qnative);
3114 /* get properties of a button */
3116 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
3118 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3119 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3120 /* check the state of a button */
3121 if (EQ (prop, Q_selected))
3123 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
3131 /* get properties of a combo box */
3133 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
3135 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3136 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3137 /* get the text from a control */
3138 if (EQ (prop, Q_text))
3140 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
3141 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
3142 Extbyte* buf = (Extbyte*) alloca (len+1);
3143 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
3144 return build_ext_string (buf, Qnative);
3149 /* set the properties of a progress gauge */
3151 mswindows_progress_gauge_redisplay (Lisp_Object image_instance)
3153 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3155 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
3158 #ifdef ERROR_CHECK_GLYPHS
3159 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
3161 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
3162 #ifdef DEBUG_WIDGET_OUTPUT
3163 stderr_out ("progress gauge displayed value on %p updated to %ld\n",
3164 WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3168 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3169 PBM_SETPOS, (WPARAM)XINT (val), 0);
3174 mswindows_control_wnd_proc (HWND hwnd, UINT msg,
3175 WPARAM wParam, LPARAM lParam)
3181 case WM_CTLCOLORBTN:
3182 case WM_CTLCOLORLISTBOX:
3183 case WM_CTLCOLOREDIT:
3184 case WM_CTLCOLORSTATIC:
3185 case WM_CTLCOLORSCROLLBAR:
3187 return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam);
3189 return DefWindowProc (hwnd, msg, wParam, lParam);
3193 #endif /* HAVE_WIDGETS */
3196 /************************************************************************/
3197 /* initialization */
3198 /************************************************************************/
3201 syms_of_glyphs_mswindows (void)
3203 defkeyword (&Q_resource_id, ":resource-id");
3204 defkeyword (&Q_resource_type, ":resource-type");
3208 console_type_create_glyphs_mswindows (void)
3210 /* image methods - display */
3211 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
3212 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
3213 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
3214 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
3215 CONSOLE_HAS_METHOD (mswindows, redisplay_subwindow);
3216 CONSOLE_HAS_METHOD (mswindows, resize_subwindow);
3217 CONSOLE_HAS_METHOD (mswindows, redisplay_widget);
3218 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
3219 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
3220 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
3221 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
3223 /* image methods - printer */
3224 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_image_instance);
3225 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_image_instance);
3226 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_equal);
3227 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_hash);
3228 CONSOLE_INHERITS_METHOD (msprinter, mswindows, init_image_instance_from_eimage);
3229 CONSOLE_INHERITS_METHOD (msprinter, mswindows, locate_pixmap_file);
3233 image_instantiator_format_create_glyphs_mswindows (void)
3235 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing);
3236 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string);
3237 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string);
3238 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit);
3239 /* image-instantiator types */
3240 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
3241 INITIALIZE_DEVICE_IIFORMAT (msprinter, xbm);
3242 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
3243 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xbm, instantiate);
3245 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
3246 INITIALIZE_DEVICE_IIFORMAT (msprinter, xpm);
3247 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
3248 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xpm, instantiate);
3251 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
3252 INITIALIZE_DEVICE_IIFORMAT (msprinter, xface);
3253 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
3254 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xface, instantiate);
3257 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, jpeg);
3260 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, tiff);
3263 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, png);
3266 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif);
3269 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
3270 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
3272 IIFORMAT_VALID_CONSOLE (mswindows, layout);
3273 INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout);
3274 IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate);
3276 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
3277 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
3278 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
3279 IIFORMAT_HAS_DEVMETHOD (mswindows, button, redisplay);
3280 /* edit-field widget */
3281 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
3282 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
3284 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
3285 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
3287 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
3288 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
3290 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
3291 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
3292 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
3294 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
3295 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
3296 /* progress gauge */
3297 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
3298 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, redisplay);
3299 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
3300 /* tree view widget */
3301 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
3302 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
3303 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, redisplay);
3304 /* tab control widget */
3305 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
3306 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
3307 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, redisplay);
3309 /* windows bitmap format */
3310 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
3311 IIFORMAT_HAS_METHOD (bmp, validate);
3312 IIFORMAT_HAS_METHOD (bmp, normalize);
3313 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
3314 IIFORMAT_HAS_METHOD (bmp, instantiate);
3316 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
3317 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
3318 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, bmp);
3320 /* mswindows resources */
3321 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
3322 "mswindows-resource");
3324 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
3325 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
3326 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
3327 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
3329 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
3330 check_valid_resource_symbol);
3331 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
3332 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
3333 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, mswindows_resource);
3337 vars_of_glyphs_mswindows (void)
3339 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
3340 A list of the directories in which mswindows bitmap files may be found.
3341 This is used by the `make-image-instance' function.
3343 Vmswindows_bitmap_file_path = Qnil;
3347 complex_vars_of_glyphs_mswindows (void)