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 bite = offset[j];
1724 new_offset[j] = ~ (unsigned char)
1725 ((flip_table[bite & 0xf] << 4) + flip_table[bite >> 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 finalize_destroy_window (void *win)
2096 DestroyWindow ((HWND) win);
2100 mswindows_finalize_image_instance (Lisp_Image_Instance *p)
2105 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
2107 if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p))
2108 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
2110 #ifdef DEBUG_WIDGETS
2111 debug_widget_instances--;
2112 stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
2114 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2116 /* DestroyWindow is not safe here, as it will send messages
2117 to our window proc. */
2118 register_post_gc_action
2119 (finalize_destroy_window,
2120 (void *) (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p)));
2121 register_post_gc_action
2122 (finalize_destroy_window,
2123 (void *) (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
2124 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
2130 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
2131 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
2133 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p))
2135 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
2137 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i))
2138 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i));
2139 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0;
2141 xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p));
2142 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0;
2144 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2145 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2146 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
2147 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
2148 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
2149 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2160 /************************************************************************/
2161 /* subwindow and widget support */
2162 /************************************************************************/
2165 mswindows_widget_hfont (Lisp_Image_Instance *p,
2168 Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (p);
2169 int under = FACE_UNDERLINE_P (face, domain);
2170 int strike = FACE_STRIKETHRU_P (face, domain);
2171 Lisp_Object font = query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (p),
2174 return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike);
2178 begin_defer_window_pos (struct frame *f)
2180 #ifdef DEFER_WINDOW_POS
2181 if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0)
2182 FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10);
2184 return FRAME_MSWINDOWS_DATA (f)->hdwp;
2187 /* unmap the image if it is a widget. This is used by redisplay via
2188 redisplay_unmap_subwindows */
2190 mswindows_unmap_subwindow (Lisp_Image_Instance *p)
2192 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2194 #ifdef DEFER_WINDOW_POS
2195 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2196 HDWP hdwp = begin_defer_window_pos (f);
2198 new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2201 SWP_HIDEWINDOW | SWP_NOACTIVATE |
2202 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
2203 /* Setting this flag causes the call to
2204 DeferWindowPos to fail with
2205 "Invalid parameter". I don't understand
2206 why we bother to try and set this
2208 /* | SWP_NOSENDCHANGING */
2211 mswindows_output_last_error ("unmapping");
2214 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2216 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2219 SWP_HIDEWINDOW | SWP_NOACTIVATE |
2220 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER );
2222 if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))
2223 SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
2227 /* map the subwindow. This is used by redisplay via
2228 redisplay_output_subwindow */
2230 mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
2231 struct display_glyph_area* dga)
2233 #ifdef DEFER_WINDOW_POS
2234 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2235 HDWP hdwp = begin_defer_window_pos (f);
2238 /* move the window before mapping it ... */
2239 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2241 x, y, dga->width, dga->height,
2243 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2244 /* ... adjust the child ... */
2245 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2247 -dga->xoffset, -dga->yoffset, 0, 0,
2248 SWP_NOZORDER | SWP_NOSIZE
2249 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2250 /* ... now map it - we are not allowed to move it at the same time. */
2251 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
2253 #ifdef DEFER_WINDOW_POS
2254 new_hdwp = DeferWindowPos
2256 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2258 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2260 /* | SWP_NOCOPYBITS */
2261 /* Setting this flag causes the call to
2262 DeferWindowPos to fail with
2263 "Invalid parameter". I don't understand
2264 why we bother to try and set this
2266 /* | SWP_NOSENDCHANGING */
2269 mswindows_output_last_error ("mapping");
2272 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2274 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2277 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2278 | SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE);
2280 /* Doing this once does not seem to be enough, for instance when
2281 mapping the search dialog this gets called four times. If we
2282 only set on the first time through then the subwindow never
2283 gets focus as intended. However, doing this everytime doesn't
2284 seem so bad, after all we only need to redo this after the
2285 focus changes - and if that happens resetting the initial
2286 focus doesn't seem so bad. */
2287 if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (p))
2288 SetFocus (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
2293 /* resize the subwindow instance */
2295 mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
2297 /* Set the size of the control .... */
2298 if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2301 SWP_NOZORDER | SWP_NOMOVE
2302 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING))
2303 mswindows_output_last_error ("resizing");
2306 /* Simply resize the window here. */
2308 mswindows_redisplay_subwindow (Lisp_Image_Instance *p)
2310 mswindows_resize_subwindow (p,
2311 IMAGE_INSTANCE_WIDTH (p),
2312 IMAGE_INSTANCE_HEIGHT (p));
2315 /* when you click on a widget you may activate another widget this
2316 needs to be checked and all appropriate widgets updated */
2318 mswindows_redisplay_widget (Lisp_Image_Instance *p)
2320 /* Possibly update the face font and colors. */
2321 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))
2322 && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
2323 || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
2324 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)))
2326 /* set the widget font from the widget face */
2327 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2329 (WPARAM) mswindows_widget_hfont
2330 (p, IMAGE_INSTANCE_FRAME (p)),
2331 MAKELPARAM (TRUE, 0));
2333 /* Possibly update the dimensions. */
2334 if (IMAGE_INSTANCE_SIZE_CHANGED (p))
2336 mswindows_resize_subwindow (p,
2337 IMAGE_INSTANCE_WIDTH (p),
2338 IMAGE_INSTANCE_HEIGHT (p));
2340 /* Possibly update the text in the widget. */
2341 if (IMAGE_INSTANCE_TEXT_CHANGED (p)
2342 && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)))
2345 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p),
2346 C_STRING_ALLOCA, lparam,
2348 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2349 WM_SETTEXT, 0, (LPARAM)lparam);
2351 /* Set active state. */
2352 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
2354 Lisp_Object item = IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p);
2355 LONG style = GetWindowLong
2356 (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2362 if (gui_item_active_p (item))
2363 SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2364 GWL_STYLE, style & ~WS_DISABLED);
2366 SetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2367 GWL_STYLE, style | WS_DISABLED);
2371 /* Account for some of the limitations with widget images. */
2373 mswindows_widget_border_width (void)
2375 return DEFAULT_WIDGET_BORDER_WIDTH;
2378 /* register widgets into our hashtable so that we can cope with the
2379 callbacks. The hashtable is weak so deregistration is handled
2382 mswindows_register_gui_item (Lisp_Object image_instance,
2383 Lisp_Object gui, Lisp_Object domain)
2385 Lisp_Object frame = DOMAIN_FRAME (domain);
2386 struct frame* f = XFRAME (frame);
2387 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f),
2390 Fputhash (make_int (id), image_instance,
2391 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
2392 Fputhash (make_int (id), XGUI_ITEM (gui)->callback,
2393 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
2394 Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex,
2395 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
2400 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2402 return mswindows_register_gui_item (instance,
2403 XIMAGE_INSTANCE_WIDGET_ITEM (instance),
2408 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2409 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2410 int dest_mask, Lisp_Object domain)
2412 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2413 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2414 Lisp_Object frame = DOMAIN_FRAME (domain);
2417 CHECK_MSWINDOWS_DEVICE (device);
2419 /* have to set the type this late in case there is no device
2420 instantiation for a widget */
2421 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2422 /* Allocate space for the clip window */
2423 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2425 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2428 XEMACS_CONTROL_CLASS,
2430 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2431 0, /* starting x position */
2432 0, /* starting y position */
2433 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2434 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2436 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2438 NULL, /* must be null for this class */
2440 signal_simple_error ("window creation failed with code",
2441 make_int (GetLastError()));
2443 wnd = CreateWindow( "STATIC",
2446 0, /* starting x position */
2447 0, /* starting y position */
2448 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2449 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2450 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2453 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2457 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2458 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2462 mswindows_image_instance_equal (Lisp_Image_Instance *p1,
2463 Lisp_Image_Instance *p2, int depth)
2465 switch (IMAGE_INSTANCE_TYPE (p1))
2467 case IMAGE_MONO_PIXMAP:
2468 case IMAGE_COLOR_PIXMAP:
2470 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2471 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2482 static unsigned long
2483 mswindows_image_instance_hash (Lisp_Image_Instance *p, int depth)
2485 switch (IMAGE_INSTANCE_TYPE (p))
2487 case IMAGE_MONO_PIXMAP:
2488 case IMAGE_COLOR_PIXMAP:
2490 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2497 /* Set all the slots in an image instance structure to reasonable
2498 default values. This is used somewhere within an instantiate
2499 method. It is assumed that the device slot within the image
2500 instance is already set -- this is the case when instantiate
2501 methods are called. */
2504 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
2506 enum image_instance_type type)
2508 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2509 IMAGE_INSTANCE_TYPE (ii) = type;
2510 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2511 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2512 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2513 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2514 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2515 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2516 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
2517 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) =
2518 xnew_array_and_zero (HBITMAP, slices);
2524 /************************************************************************/
2526 /************************************************************************/
2528 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2529 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2530 int dest_mask, Lisp_Object domain,
2531 const char* class, int flags, int exflags)
2533 /* this function can call lisp */
2534 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2535 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2536 Lisp_Object frame = DOMAIN_FRAME (domain);
2540 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2541 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2543 CHECK_MSWINDOWS_DEVICE (device);
2545 if (!gui_item_active_p (gui))
2546 flags |= WS_DISABLED;
2548 style = pgui->style;
2550 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex))
2552 id = mswindows_register_widget_instance (image_instance, domain);
2555 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2556 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii),
2557 C_STRING_ALLOCA, nm,
2560 /* allocate space for the clip window and then allocate the clip window */
2561 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2563 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2565 WS_EX_CONTROLPARENT, /* EX flags */
2566 XEMACS_CONTROL_CLASS,
2568 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2569 0, /* starting x position */
2570 0, /* starting y position */
2571 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2572 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2574 DOMAIN_MSWINDOWS_HANDLE (domain),
2575 (HMENU)id, /* No menu */
2576 NULL, /* must be null for this class */
2578 signal_simple_error ("window creation failed with code",
2579 make_int (GetLastError()));
2581 if ((wnd = CreateWindowEx(
2582 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2585 flags | WS_CHILD | WS_VISIBLE,
2586 0, /* starting x position */
2587 0, /* starting y position */
2588 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2589 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2591 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2592 (HMENU)id, /* No menu */
2595 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2598 signal_simple_error ("window creation failed with code",
2599 make_int (GetLastError()));
2601 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2602 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2603 /* set the widget font from the widget face */
2604 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2605 SendMessage (wnd, WM_SETFONT,
2606 (WPARAM) mswindows_widget_hfont (ii, domain),
2607 MAKELPARAM (TRUE, 0));
2610 /* Instantiate a native layout widget. */
2612 mswindows_native_layout_instantiate (Lisp_Object image_instance,
2613 Lisp_Object instantiator,
2614 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2615 int dest_mask, Lisp_Object domain)
2617 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2619 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2620 pointer_bg, dest_mask, domain, "STATIC",
2621 /* Approximation to styles available with
2622 an XEmacs layout. */
2623 (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2625 EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2627 GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
2628 ? SS_ETCHEDFRAME : SS_SUNKEN) | DS_CONTROL,
2632 /* Instantiate a button widget. Unfortunately instantiated widgets are
2633 particular to a frame since they need to have a parent. It's not
2634 like images where you just select the image into the context you
2635 want to display it in and BitBlt it. So image instances can have a
2636 many-to-one relationship with things you see, whereas widgets can
2637 only be one-to-one (i.e. per frame) */
2639 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2640 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2641 int dest_mask, Lisp_Object domain)
2643 /* This function can call lisp */
2644 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2646 int flags = WS_TABSTOP | BS_NOTIFY;
2647 /* BS_NOTIFY #### is needed to get exotic feedback only. Since we
2648 seem to want nothing beyond BN_CLICK, the style is perhaps not
2651 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2652 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2653 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2657 if (!IMAGE_INSTANCEP (glyph))
2658 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2660 if (IMAGE_INSTANCEP (glyph))
2661 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2662 BS_BITMAP : BS_ICON;
2665 style = pgui->style;
2667 /* #### consider using the default face for radio and toggle
2669 if (EQ (style, Qradio))
2671 flags |= BS_RADIOBUTTON;
2673 else if (EQ (style, Qtoggle))
2675 flags |= BS_AUTOCHECKBOX;
2679 flags |= BS_DEFPUSHBUTTON;
2682 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2683 pointer_bg, dest_mask, domain, "BUTTON",
2686 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2687 /* set the checked state */
2688 if (gui_item_selected_p (gui))
2689 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2691 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2692 /* add the image if one was given */
2693 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)
2695 IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph)))
2697 SendMessage (wnd, BM_SETIMAGE,
2698 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2699 IMAGE_BITMAP : IMAGE_ICON),
2700 (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2701 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2702 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2706 /* Update the state of a button. */
2708 mswindows_button_redisplay (Lisp_Object image_instance)
2710 /* This function can GC if IN_REDISPLAY is false. */
2711 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2713 /* buttons checked or otherwise */
2714 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
2715 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2716 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2718 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2719 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2722 /* instantiate an edit control */
2724 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2725 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2726 int dest_mask, Lisp_Object domain)
2728 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2729 pointer_bg, dest_mask, domain, "EDIT",
2730 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2731 | WS_BORDER, WS_EX_CLIENTEDGE);
2734 /* instantiate a progress gauge */
2736 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2737 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2738 int dest_mask, Lisp_Object domain)
2741 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2743 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2744 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2745 WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE);
2746 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2747 /* set the colors */
2748 #ifdef PBS_SETBKCOLOR
2749 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2750 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2753 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2754 XIMAGE_INSTANCE_FRAME (ii))))));
2756 #ifdef PBS_SETBARCOLOR
2757 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2758 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2761 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2762 XIMAGE_INSTANCE_FRAME (ii))))));
2764 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEMS (ii))->value;
2766 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2767 PBM_SETPOS, (WPARAM)XINT (val), 0);
2770 /* instantiate a tree view widget */
2771 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2772 HWND wnd, HTREEITEM parent, Lisp_Object item,
2773 int children, Lisp_Object domain)
2775 TV_INSERTSTRUCT tvitem;
2778 tvitem.hParent = parent;
2779 tvitem.hInsertAfter = TVI_LAST;
2780 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2781 tvitem.item.cChildren = children;
2783 if (GUI_ITEMP (item))
2785 tvitem.item.lParam = mswindows_register_gui_item (image_instance,
2787 tvitem.item.mask |= TVIF_PARAM;
2788 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2789 C_STRING_ALLOCA, tvitem.item.pszText,
2793 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2794 C_STRING_ALLOCA, tvitem.item.pszText,
2797 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2799 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2800 0, (LPARAM)&tvitem)) == 0)
2801 signal_simple_error ("error adding tree view entry", item);
2806 static void add_tree_item_list (Lisp_Object image_instance,
2807 HWND wnd, HTREEITEM parent, Lisp_Object list,
2812 /* get the first item */
2813 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2814 /* recursively add items to the tree view */
2815 LIST_LOOP (rest, XCDR (list))
2817 if (LISTP (XCAR (rest)))
2818 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2820 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2825 mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2826 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2827 int dest_mask, Lisp_Object domain)
2832 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2833 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2834 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2835 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2836 | TVS_HASLINES | TVS_HASBUTTONS,
2839 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2842 parent = add_tree_item (image_instance, wnd, NULL,
2843 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
2846 /* recursively add items to the tree view */
2847 /* add items to the tab */
2848 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2850 if (LISTP (XCAR (rest)))
2851 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2853 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2857 /* Set the properties of a tree view. */
2859 mswindows_tree_view_redisplay (Lisp_Object image_instance)
2861 /* This function can GC if IN_REDISPLAY is false. */
2862 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2864 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2866 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2869 /* Delete previous items. */
2870 SendMessage (wnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
2872 parent = add_tree_item (image_instance, wnd, NULL,
2873 XCAR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)),
2874 TRUE, IMAGE_INSTANCE_DOMAIN (ii));
2876 /* recursively add items to the tree view */
2877 /* add items to the tab */
2878 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
2880 if (LISTP (XCAR (rest)))
2881 add_tree_item_list (image_instance, wnd, parent, XCAR (rest),
2882 IMAGE_INSTANCE_DOMAIN (ii));
2884 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE,
2885 IMAGE_INSTANCE_DOMAIN (ii));
2890 /* instantiate a tab control */
2892 add_tab_item (Lisp_Object image_instance,
2893 HWND wnd, Lisp_Object item,
2894 Lisp_Object domain, int i)
2899 tvitem.mask = TCIF_TEXT;
2901 if (GUI_ITEMP (item))
2903 tvitem.lParam = mswindows_register_gui_item (image_instance,
2905 tvitem.mask |= TCIF_PARAM;
2906 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2907 C_STRING_ALLOCA, tvitem.pszText,
2912 CHECK_STRING (item);
2913 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2914 C_STRING_ALLOCA, tvitem.pszText,
2918 tvitem.cchTextMax = strlen (tvitem.pszText);
2920 if ((ret = SendMessage (wnd, TCM_INSERTITEM,
2921 i, (LPARAM)&tvitem)) < 0)
2922 signal_simple_error ("error adding tab entry", item);
2928 mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2929 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2930 int dest_mask, Lisp_Object domain)
2932 /* This function can call lisp */
2935 int i = 0, selected = 0;
2936 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2937 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
2938 unsigned int flags = WS_TABSTOP;
2940 if (EQ (orient, Qleft) || EQ (orient, Qright))
2942 flags |= TCS_VERTICAL | TCS_MULTILINE;
2944 if (EQ (orient, Qright) || EQ (orient, Qbottom))
2946 flags |= TCS_BOTTOM;
2949 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2950 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2951 /* borders don't suit tabs so well */
2953 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2954 /* add items to the tab */
2955 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2957 int idx = add_tab_item (image_instance, wnd, XCAR (rest), domain, i);
2959 if (gui_item_selected_p (XCAR (rest)))
2963 SendMessage (wnd, TCM_SETCURSEL, selected, 0);
2966 /* Set the properties of a tab control. */
2968 mswindows_tab_control_redisplay (Lisp_Object image_instance)
2970 /* This function can GC if IN_REDISPLAY is false. */
2971 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2972 #ifdef DEBUG_WIDGET_OUTPUT
2973 stderr_out ("tab control %p redisplayed\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
2975 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
2977 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
2979 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2980 int i = 0, selected_idx = 0;
2983 assert (!NILP (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2985 /* If only the order has changed then simply select the first
2986 one. This stops horrendous rebuilding of the tabs each time
2987 you click on one. */
2988 if (tab_control_order_only_changed (image_instance))
2990 Lisp_Object selected =
2991 gui_item_list_find_selected
2992 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
2993 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
2994 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
2996 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2998 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
3000 Lisp_Object old_selected = gui_item_list_find_selected
3001 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
3003 /* Pick up the new selected item. */
3004 XGUI_ITEM (old_selected)->selected =
3005 XGUI_ITEM (XCAR (rest))->selected;
3006 XGUI_ITEM (XCAR (rest))->selected =
3007 XGUI_ITEM (selected)->selected;
3008 /* We're not actually changing the items. */
3009 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
3010 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
3012 SendMessage (wnd, TCM_SETCURSEL, i, 0);
3013 #ifdef DEBUG_WIDGET_OUTPUT
3014 stderr_out ("tab control %p selected item %d\n",
3015 IMAGE_INSTANCE_SUBWINDOW_ID (ii), i);
3024 /* delete the pre-existing items */
3025 SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
3027 /* add items to the tab */
3028 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
3030 add_tab_item (image_instance, wnd, XCAR (rest),
3031 IMAGE_INSTANCE_FRAME (ii), i);
3032 if (gui_item_selected_p (XCAR (rest)))
3036 SendMessage (wnd, TCM_SETCURSEL, selected_idx, 0);
3041 /* instantiate a static control possible for putting other things in */
3043 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3044 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3045 int dest_mask, Lisp_Object domain)
3047 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3048 pointer_bg, dest_mask, domain, "STATIC",
3049 0, WS_EX_STATICEDGE);
3052 /* instantiate a scrollbar control */
3054 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3055 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3056 int dest_mask, Lisp_Object domain)
3058 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3059 pointer_bg, dest_mask, domain, "SCROLLBAR",
3060 WS_TABSTOP, WS_EX_CLIENTEDGE);
3063 /* instantiate a combo control */
3065 mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3066 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3067 int dest_mask, Lisp_Object domain)
3069 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3072 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
3075 /* Maybe ought to generalise this more but it may be very windows
3076 specific. In windows the window height of a combo box is the
3077 height when the combo box is open. Thus we need to set the height
3078 before creating the window and then reset it to a single line
3079 after the window is created so that redisplay does the right
3081 widget_instantiate (image_instance, instantiator, pointer_fg,
3082 pointer_bg, dest_mask, domain);
3084 /* We now have everything right apart from the height. */
3085 default_face_font_info (domain, 0, 0, &height, 0, 0);
3086 GET_LIST_LENGTH (items, len);
3088 height = (height + DEFAULT_WIDGET_BORDER_WIDTH * 2 ) * len;
3089 IMAGE_INSTANCE_HEIGHT (ii) = height;
3091 /* Now create the widget. */
3092 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3093 pointer_bg, dest_mask, domain, "COMBOBOX",
3094 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
3096 | CBS_HASSTRINGS | WS_VSCROLL,
3098 /* Reset the height. layout will probably do this safely, but better make sure. */
3099 image_instance_layout (image_instance,
3100 IMAGE_UNSPECIFIED_GEOMETRY,
3101 IMAGE_UNSPECIFIED_GEOMETRY,
3102 IMAGE_UNCHANGED_GEOMETRY,
3103 IMAGE_UNCHANGED_GEOMETRY,
3106 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3107 /* add items to the combo box */
3108 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
3109 LIST_LOOP (rest, items)
3112 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (rest),
3113 C_STRING_ALLOCA, lparam,
3115 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
3116 signal_simple_error ("error adding combo entries", instantiator);
3120 /* get properties of a control */
3122 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
3124 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3125 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3126 /* get the text from a control */
3127 if (EQ (prop, Q_text))
3129 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
3130 Extbyte *buf = (Extbyte*) alloca (len+1);
3132 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
3133 return build_ext_string (buf, Qnative);
3138 /* get properties of a button */
3140 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
3142 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3143 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3144 /* check the state of a button */
3145 if (EQ (prop, Q_selected))
3147 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
3155 /* get properties of a combo box */
3157 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
3159 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3160 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3161 /* get the text from a control */
3162 if (EQ (prop, Q_text))
3164 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
3165 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
3166 Extbyte* buf = (Extbyte*) alloca (len+1);
3167 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
3168 return build_ext_string (buf, Qnative);
3173 /* set the properties of a progress gauge */
3175 mswindows_progress_gauge_redisplay (Lisp_Object image_instance)
3177 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3179 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
3182 #ifdef ERROR_CHECK_GLYPHS
3183 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
3185 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
3186 #ifdef DEBUG_WIDGET_OUTPUT
3187 stderr_out ("progress gauge displayed value on %p updated to %ld\n",
3188 WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3192 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3193 PBM_SETPOS, (WPARAM)XINT (val), 0);
3198 mswindows_control_wnd_proc (HWND hwnd, UINT msg,
3199 WPARAM wParam, LPARAM lParam)
3205 case WM_CTLCOLORBTN:
3206 case WM_CTLCOLORLISTBOX:
3207 case WM_CTLCOLOREDIT:
3208 case WM_CTLCOLORSTATIC:
3209 case WM_CTLCOLORSCROLLBAR:
3211 return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam);
3213 return DefWindowProc (hwnd, msg, wParam, lParam);
3217 #endif /* HAVE_WIDGETS */
3220 /************************************************************************/
3221 /* initialization */
3222 /************************************************************************/
3225 syms_of_glyphs_mswindows (void)
3227 defkeyword (&Q_resource_id, ":resource-id");
3228 defkeyword (&Q_resource_type, ":resource-type");
3232 console_type_create_glyphs_mswindows (void)
3234 /* image methods - display */
3235 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
3236 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
3237 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
3238 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
3239 CONSOLE_HAS_METHOD (mswindows, redisplay_subwindow);
3240 CONSOLE_HAS_METHOD (mswindows, resize_subwindow);
3241 CONSOLE_HAS_METHOD (mswindows, redisplay_widget);
3242 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
3243 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
3244 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
3245 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
3246 CONSOLE_HAS_METHOD (mswindows, widget_border_width);
3248 /* image methods - printer */
3249 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_image_instance);
3250 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_image_instance);
3251 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_equal);
3252 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_hash);
3253 CONSOLE_INHERITS_METHOD (msprinter, mswindows, init_image_instance_from_eimage);
3254 CONSOLE_INHERITS_METHOD (msprinter, mswindows, locate_pixmap_file);
3258 image_instantiator_format_create_glyphs_mswindows (void)
3260 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing);
3261 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string);
3262 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string);
3263 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit);
3264 /* image-instantiator types */
3265 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
3266 INITIALIZE_DEVICE_IIFORMAT (msprinter, xbm);
3267 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
3268 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xbm, instantiate);
3270 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
3271 INITIALIZE_DEVICE_IIFORMAT (msprinter, xpm);
3272 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
3273 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xpm, instantiate);
3276 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
3277 INITIALIZE_DEVICE_IIFORMAT (msprinter, xface);
3278 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
3279 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xface, instantiate);
3282 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, jpeg);
3285 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, tiff);
3288 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, png);
3291 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif);
3294 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
3295 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
3297 IIFORMAT_VALID_CONSOLE (mswindows, layout);
3298 INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout);
3299 IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate);
3301 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
3302 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
3303 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
3304 IIFORMAT_HAS_DEVMETHOD (mswindows, button, redisplay);
3305 /* edit-field widget */
3306 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
3307 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
3309 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
3310 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
3312 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
3313 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
3315 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
3316 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
3317 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
3319 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
3320 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
3321 /* progress gauge */
3322 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
3323 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, redisplay);
3324 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
3325 /* tree view widget */
3326 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
3327 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
3328 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, redisplay);
3329 /* tab control widget */
3330 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
3331 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
3332 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, redisplay);
3334 /* windows bitmap format */
3335 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
3336 IIFORMAT_HAS_METHOD (bmp, validate);
3337 IIFORMAT_HAS_METHOD (bmp, normalize);
3338 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
3339 IIFORMAT_HAS_METHOD (bmp, instantiate);
3341 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
3342 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
3343 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, bmp);
3345 /* mswindows resources */
3346 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
3347 "mswindows-resource");
3349 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
3350 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
3351 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
3352 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
3354 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
3355 check_valid_resource_symbol);
3356 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
3357 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
3358 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, mswindows_resource);
3362 vars_of_glyphs_mswindows (void)
3364 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
3365 A list of the directories in which mswindows bitmap files may be found.
3366 This is used by the `make-image-instance' function.
3368 Vmswindows_bitmap_file_path = Qnil;
3372 complex_vars_of_glyphs_mswindows (void)