1 /* mswindows-specific glyph objects.
2 Copyright (C) 1998, 99 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> plagerising 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);
75 DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
77 DEFINE_DEVICE_IIFORMAT (mswindows, xface);
79 DEFINE_DEVICE_IIFORMAT (mswindows, button);
80 DEFINE_DEVICE_IIFORMAT (mswindows, edit_field);
82 DEFINE_DEVICE_IIFORMAT (mswindows, group);
84 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
85 DEFINE_DEVICE_IIFORMAT (mswindows, widget);
86 DEFINE_DEVICE_IIFORMAT (mswindows, label);
87 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
88 DEFINE_DEVICE_IIFORMAT (mswindows, combo_box);
89 DEFINE_DEVICE_IIFORMAT (mswindows, progress_gauge);
90 DEFINE_DEVICE_IIFORMAT (mswindows, tree_view);
91 DEFINE_DEVICE_IIFORMAT (mswindows, tab_control);
93 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
95 Lisp_Object Vmswindows_bitmap_file_path;
96 static COLORREF transparent_color = RGB (1,1,1);
98 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource);
99 Lisp_Object Q_resource_type, Q_resource_id;
100 Lisp_Object Qmswindows_resource;
103 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
104 enum image_instance_type type);
106 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
109 COLORREF mswindows_string_to_color (CONST char *name);
110 void check_valid_item_list_1 (Lisp_Object items);
112 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
114 /************************************************************************/
115 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
117 /************************************************************************/
118 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
119 int width, int height,
122 unsigned char** bmp_data)
124 struct device *d = XDEVICE (device);
128 BITMAPINFO* bmp_info;
129 unsigned char *ip, *dp;
131 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
133 int bpline = BPLINE(width * 3);
134 /* FIXME: we can do this because 24bpp implies no color table, once
135 * we start palettizing this is no longer true. The X versions of
136 * this function quantises to 256 colors or bit masks down to a
137 * long. Windows can actually handle rgb triples in the raw so I
138 * don't see much point trying to optimize down to the best
139 * structure - unless it has memory / color allocation implications
141 bmp_info=xnew_and_zero (BITMAPINFO);
148 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
149 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
150 bmp_info->bmiHeader.biSizeImage=width*height*3;
152 /* bitmap data needs to be in blue, green, red triples - in that
153 order, eimage is in RGB format so we need to convert */
154 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
155 *bit_count = bpline * height;
164 for (i = height-1; i >= 0; i--) {
165 dp = (*bmp_data) + (i * bpline);
166 for (j = 0; j < width; j++) {
174 else /* scale to 256 colors */
178 int bpline = BPLINE (width * 3);
179 /* Quantize the image and get a histogram while we're at it.
180 Do this first to save memory */
181 qtable = build_EImage_quantable(pic, width, height, 256);
182 if (qtable == NULL) return NULL;
184 /* use our quantize table to allocate the colors */
185 ncolors = qtable->num_active_colors;
186 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
187 sizeof(RGBQUAD) * ncolors);
194 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
196 bmp_info->bmiHeader.biBitCount=8;
197 bmp_info->bmiHeader.biCompression=BI_RGB;
198 bmp_info->bmiHeader.biSizeImage=bpline*height;
199 bmp_info->bmiHeader.biClrUsed=ncolors;
200 bmp_info->bmiHeader.biClrImportant=ncolors;
202 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
203 *bit_count = bpline * height;
212 /* build up an RGBQUAD colortable */
213 for (i = 0; i < qtable->num_active_colors; i++) {
214 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
215 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
216 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
217 colortbl[i].rgbReserved = 0;
220 /* now build up the data. picture has to be upside-down and
221 back-to-front for msw bitmaps */
223 for (i = height-1; i >= 0; i--) {
224 dp = (*bmp_data) + (i * bpline);
225 for (j = 0; j < width; j++) {
229 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
234 /* fix up the standard stuff */
235 bmp_info->bmiHeader.biWidth=width;
236 bmp_info->bmiHeader.biHeight=height;
237 bmp_info->bmiHeader.biPlanes=1;
238 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
239 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
240 bmp_info->bmiHeader.biYPelsPerMeter=0;
245 /* Given a pixmap filename, look through all of the "standard" places
246 where the file might be located. Return a full pathname if found;
247 otherwise, return Qnil. */
250 mswindows_locate_pixmap_file (Lisp_Object name)
252 /* This function can GC if IN_REDISPLAY is false */
255 /* Check non-absolute pathnames with a directory component relative to
256 the search path; that's the way Xt does it. */
257 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
258 (XSTRING_BYTE (name, 0) == '.' &&
259 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
260 (XSTRING_BYTE (name, 1) == '.' &&
261 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
263 if (!NILP (Ffile_readable_p (name)))
269 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
271 Lisp_Object temp = list1 (Vdata_directory);
275 locate_file (temp, name, Qnil, &found, R_OK);
283 /* Initialize an image instance from a bitmap
285 DEST_MASK specifies the mask of allowed image types.
287 If this fails, signal an error. INSTANTIATOR is only used
288 in the error message. */
291 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
292 BITMAPINFO *bmp_info,
296 Lisp_Object instantiator,
297 int x_hot, int y_hot,
300 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
301 struct device *d = XDEVICE (device);
308 if (!DEVICE_MSWINDOWS_P (d))
309 signal_simple_error ("Not an mswindows device", device);
311 if (NILP (DEVICE_SELECTED_FRAME (d)))
312 signal_simple_error ("No selected frame on mswindows device", device);
314 f = XFRAME (DEVICE_SELECTED_FRAME (d));
316 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
317 type = IMAGE_COLOR_PIXMAP;
318 else if (dest_mask & IMAGE_POINTER_MASK)
319 type = IMAGE_POINTER;
321 incompatible_image_types (instantiator, dest_mask,
322 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
323 hdc = FRAME_MSWINDOWS_CDC (f);
325 bitmap=CreateDIBSection (hdc,
331 if (!bitmap || !bmp_buf)
332 signal_simple_error ("Unable to create bitmap", instantiator);
334 /* copy in the actual bitmap */
335 memcpy (bmp_buf, bmp_data, bmp_bits);
337 mswindows_initialize_dibitmap_image_instance (ii, type);
339 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
340 find_keyword_in_vector (instantiator, Q_file);
342 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
343 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
344 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
345 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
346 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
347 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
348 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
352 mswindows_initialize_image_instance_mask (ii, f);
355 if (type == IMAGE_POINTER)
357 mswindows_initialize_image_instance_icon(ii, TRUE);
362 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
363 int width, int height,
364 unsigned char *eimage,
366 Lisp_Object instantiator,
369 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
370 BITMAPINFO* bmp_info;
371 unsigned char* bmp_data;
375 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
376 signal_simple_error ("Not an mswindows device", device);
378 /* this is a hack but MaskBlt and TransparentBlt are not supported
379 on most windows variants */
380 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
381 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
383 /* build a bitmap from the eimage */
384 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
385 &bmp_bits, &bmp_data)))
387 signal_simple_error ("EImage to DIBitmap conversion failed",
391 /* Now create the pixmap and set up the image instance */
392 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
393 bmp_data, bmp_bits, instantiator,
400 static void set_mono_pixel ( unsigned char* bits,
401 int bpline, int height,
402 int x, int y, int white )
405 unsigned char bitnum;
406 /* Find the byte on which this scanline begins */
407 index = (height - y - 1) * bpline;
408 /* Find the byte containing this pixel */
410 /* Which bit is it? */
411 bitnum = (unsigned char)( 7 - (x % 8) );
412 if( white ) /* Turn it on */
413 bits[index] |= (1<<bitnum);
414 else /* Turn it off */
415 bits[index] &= ~(1<<bitnum);
419 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
424 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
425 unsigned char* dibits;
426 BITMAPINFO* bmp_info =
427 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
429 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
432 int maskbpline = BPLINE (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8));
433 int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
438 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
439 bmp_info->bmiHeader.biHeight = height;
440 bmp_info->bmiHeader.biPlanes=1;
441 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
442 bmp_info->bmiHeader.biBitCount=1;
443 bmp_info->bmiHeader.biCompression=BI_RGB;
444 bmp_info->bmiHeader.biClrUsed = 2;
445 bmp_info->bmiHeader.biClrImportant = 2;
446 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
447 bmp_info->bmiColors[0].rgbRed = 0;
448 bmp_info->bmiColors[0].rgbGreen = 0;
449 bmp_info->bmiColors[0].rgbBlue = 0;
450 bmp_info->bmiColors[0].rgbReserved = 0;
451 bmp_info->bmiColors[1].rgbRed = 255;
452 bmp_info->bmiColors[1].rgbGreen = 255;
453 bmp_info->bmiColors[1].rgbBlue = 255;
454 bmp_info->bmiColors[0].rgbReserved = 0;
456 if (!(mask = CreateDIBSection (hcdc,
466 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
467 /* build up an in-memory set of bits to mess with */
470 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
471 bmp_info->bmiHeader.biHeight = -height;
472 bmp_info->bmiHeader.biPlanes=1;
473 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
474 bmp_info->bmiHeader.biBitCount=24;
475 bmp_info->bmiHeader.biCompression=BI_RGB;
476 bmp_info->bmiHeader.biClrUsed = 0;
477 bmp_info->bmiHeader.biClrImportant = 0;
478 bmp_info->bmiHeader.biSizeImage = height * bpline;
480 dibits = xmalloc_and_zero (bpline * height);
482 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
487 DIB_RGB_COLORS) <= 0)
493 /* now set the colored bits in the mask and transparent ones to
494 black in the original */
495 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
497 for(j=0; j<height; j++)
499 unsigned char* idx = &dibits[j * bpline + i * 3];
501 if( RGB (idx[2], idx[1], idx[0]) == transparent_color )
503 idx[0] = idx[1] = idx[2] = 0;
504 set_mono_pixel( and_bits, maskbpline, height, i, j, TRUE );
508 set_mono_pixel( and_bits, maskbpline, height, i, j, FALSE );
514 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
524 SelectObject(hcdc, old);
526 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
530 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
535 /* we rely on windows to do any resizing necessary */
536 x_icon.fIcon=cursor ? FALSE : TRUE;
537 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
538 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
539 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
540 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
542 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
543 CreateIconIndirect (&x_icon);
547 mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
553 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
554 HDC hdcDst = CreateCompatibleDC (hcdc);
556 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
558 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
560 old2 = SelectObject (hdcDst, newbmp);
562 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
564 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
565 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
568 DeleteObject (newbmp);
573 SelectObject (hdcDst, old2);
574 SelectObject (hcdc, old1);
581 mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
585 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
589 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
590 HDC hdcDst = CreateCompatibleDC (hcdc);
592 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
593 newmask = CreateCompatibleBitmap(hcdc, newx, newy);
594 old2 = SelectObject (hdcDst, newmask);
596 if (!StretchBlt(hdcDst, 0, 0, newx, newy,
598 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
599 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
602 DeleteObject (newmask);
607 SelectObject (hdcDst, old2);
608 SelectObject (hcdc, old1);
619 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
623 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
624 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
629 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
630 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
631 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
632 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
634 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
635 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
636 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
637 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
642 /**********************************************************************
644 **********************************************************************/
654 static struct color_symbol*
655 extract_xpm_color_names (Lisp_Object device,
657 Lisp_Object color_symbol_alist,
660 /* This function can GC */
662 Lisp_Object results = Qnil;
664 struct color_symbol *colortbl;
665 struct gcpro gcpro1, gcpro2;
667 GCPRO2 (results, device);
669 /* We built up results to be (("name" . #<color>) ...) so that if an
670 error happens we don't lose any malloc()ed data, or more importantly,
671 leave any pixels allocated in the server. */
673 LIST_LOOP (rest, color_symbol_alist)
675 Lisp_Object cons = XCAR (rest);
676 Lisp_Object name = XCAR (cons);
677 Lisp_Object value = XCDR (cons);
683 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
686 assert (COLOR_SPECIFIERP (value));
687 value = Fspecifier_instance (value, domain, Qnil, Qnil);
691 results = noseeum_cons (noseeum_cons (name, value), results);
694 UNGCPRO; /* no more evaluation */
697 if (i == 0) return 0;
699 colortbl = xnew_array_and_zero (struct color_symbol, i);
703 Lisp_Object cons = XCAR (results);
705 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
707 GET_C_STRING_OS_DATA_ALLOCA (XCAR (cons), colortbl[j].name);
708 colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
709 free_cons (XCONS (cons));
711 results = XCDR (results);
712 free_cons (XCONS (cons));
717 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
718 unsigned char** data,
719 int* width, int* height,
720 int* x_hot, int* y_hot,
722 struct color_symbol* color_symbols,
727 int result, i, j, transp_idx, maskbpline;
730 COLORREF color; /* the american spelling virus hits again .. */
735 xpminfo.valuemask=XpmHotspot;
738 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
747 signal_simple_error ("Invalid XPM data", image);
751 signal_double_file_error ("Parsing pixmap data",
752 "out of memory", image);
756 signal_double_file_error_2 ("Parsing pixmap data",
757 "unknown error code",
758 make_int (result), image);
762 *width = xpmimage.width;
763 *height = xpmimage.height;
764 maskbpline = BPLINE (((~7UL & (unsigned long)(*width + 7)) / 8));
766 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
770 XpmFreeXpmImage (&xpmimage);
771 XpmFreeXpmInfo (&xpminfo);
775 /* build a color table to speed things up */
776 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
780 XpmFreeXpmImage (&xpmimage);
781 XpmFreeXpmInfo (&xpminfo);
785 for (i=0; i<xpmimage.ncolors; i++)
788 /* pick up symbolic colors in preference */
789 if (xpmimage.colorTable[i].symbolic)
791 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
793 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
796 colortbl[i]=transparent_color;
798 goto label_found_color;
800 else if (color_symbols)
802 for (j = 0; j<nsymbols; j++)
804 if (!strcmp (xpmimage.colorTable[i].symbolic,
805 color_symbols[j].name ))
807 colortbl[i]=color_symbols[j].color;
808 goto label_found_color;
812 else if (xpmimage.colorTable[i].c_color == 0)
817 /* pick up transparencies */
818 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
821 colortbl[i]=transparent_color;
823 goto label_found_color;
825 /* finally pick up a normal color spec */
826 if (xpmimage.colorTable[i].c_color)
829 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
830 goto label_found_color;
836 XpmFreeXpmImage (&xpmimage);
837 XpmFreeXpmInfo (&xpminfo);
843 /* convert the image */
846 for (i = 0; i< *width * *height; i++)
848 color = colortbl[*sptr++];
850 /* split out the 0x02bbggrr colorref into an rgb triple */
851 *dptr++=GetRValue (color); /* red */
852 *dptr++=GetGValue (color); /* green */
853 *dptr++=GetBValue (color); /* blue */
856 *x_hot=xpminfo.x_hotspot;
857 *y_hot=xpminfo.y_hotspot;
859 XpmFreeXpmImage (&xpmimage);
860 XpmFreeXpmInfo (&xpminfo);
866 mswindows_xpm_instantiate (Lisp_Object image_instance,
867 Lisp_Object instantiator,
868 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
869 int dest_mask, Lisp_Object domain)
871 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
872 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
873 CONST Extbyte *bytes;
875 unsigned char *eimage;
876 int width, height, x_hot, y_hot;
877 BITMAPINFO* bmp_info;
878 unsigned char* bmp_data;
880 int nsymbols=0, transp;
881 struct color_symbol* color_symbols=NULL;
883 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
884 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
887 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
888 signal_simple_error ("Not an mswindows device", device);
890 assert (!NILP (data));
892 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
894 /* in case we have color symbols */
895 color_symbols = extract_xpm_color_names (device, domain,
896 color_symbol_alist, &nsymbols);
898 /* convert to an eimage to make processing easier */
899 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
900 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
902 signal_simple_error ("XPM to EImage conversion failed",
910 xfree (color_symbols[nsymbols].name);
912 xfree(color_symbols);
915 /* build a bitmap from the eimage */
916 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
917 &bmp_bits, &bmp_data)))
919 signal_simple_error ("XPM to EImage conversion failed",
924 /* Now create the pixmap and set up the image instance */
925 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
926 bmp_data, bmp_bits, instantiator,
927 x_hot, y_hot, transp);
932 #endif /* HAVE_XPM */
934 /**********************************************************************
936 **********************************************************************/
939 bmp_validate (Lisp_Object instantiator)
941 file_or_data_must_be_present (instantiator);
945 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
947 return simple_image_type_normalize (inst, console_type, Qbmp);
951 bmp_possible_dest_types (void)
953 return IMAGE_COLOR_PIXMAP_MASK;
957 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
958 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
959 int dest_mask, Lisp_Object domain)
961 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
962 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
963 CONST Extbyte *bytes;
965 BITMAPFILEHEADER* bmp_file_header;
966 BITMAPINFO* bmp_info;
969 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
971 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
972 signal_simple_error ("Not an mswindows device", device);
974 assert (!NILP (data));
976 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
978 /* Then slurp the image into memory, decoding along the way.
979 The result is the image in a simple one-byte-per-pixel
982 bmp_file_header=(BITMAPFILEHEADER*)bytes;
983 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
984 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
985 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
987 /* Now create the pixmap and set up the image instance */
988 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
989 bmp_data, bmp_bits, instantiator,
994 /**********************************************************************
996 **********************************************************************/
999 mswindows_resource_validate (Lisp_Object instantiator)
1001 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
1003 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
1005 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
1006 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
1011 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type)
1013 /* This function can call lisp */
1014 Lisp_Object file = Qnil;
1015 struct gcpro gcpro1, gcpro2;
1016 Lisp_Object alist = Qnil;
1018 GCPRO2 (file, alist);
1020 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1023 if (CONSP (file)) /* failure locating filename */
1024 signal_double_file_error ("Opening pixmap file",
1025 "no such file or directory",
1028 if (NILP (file)) /* no conversion necessary */
1029 RETURN_UNGCPRO (inst);
1031 alist = tagged_vector_to_alist (inst);
1034 alist = remassq_no_quit (Q_file, alist);
1035 alist = Fcons (Fcons (Q_file, file), alist);
1039 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
1041 RETURN_UNGCPRO (result);
1046 mswindows_resource_possible_dest_types (void)
1048 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1058 #define OCR_ICOCUR 32647
1059 #define OIC_SAMPLE 32512
1060 #define OIC_HAND 32513
1061 #define OIC_QUES 32514
1062 #define OIC_BANG 32515
1063 #define OIC_NOTE 32516
1064 #define OIC_WINLOGO 32517
1065 #define LR_SHARED 0x8000
1068 static CONST resource_t bitmap_table[] =
1071 { "close", OBM_CLOSE },
1072 { "uparrow", OBM_UPARROW },
1073 { "dnarrow", OBM_DNARROW },
1074 { "rgarrow", OBM_RGARROW },
1075 { "lfarrow", OBM_LFARROW },
1076 { "reduce", OBM_REDUCE },
1077 { "zoom", OBM_ZOOM },
1078 { "restore", OBM_RESTORE },
1079 { "reduced", OBM_REDUCED },
1080 { "zoomd", OBM_ZOOMD },
1081 { "restored", OBM_RESTORED },
1082 { "uparrowd", OBM_UPARROWD },
1083 { "dnarrowd", OBM_DNARROWD },
1084 { "rgarrowd", OBM_RGARROWD },
1085 { "lfarrowd", OBM_LFARROWD },
1086 { "mnarrow", OBM_MNARROW },
1087 { "combo", OBM_COMBO },
1088 { "uparrowi", OBM_UPARROWI },
1089 { "dnarrowi", OBM_DNARROWI },
1090 { "rgarrowi", OBM_RGARROWI },
1091 { "lfarrowi", OBM_LFARROWI },
1092 { "size", OBM_SIZE },
1093 { "btsize", OBM_BTSIZE },
1094 { "check", OBM_CHECK },
1095 { "checkboxes", OBM_CHECKBOXES },
1096 { "btncorners" , OBM_BTNCORNERS },
1100 static CONST resource_t cursor_table[] =
1103 { "normal", OCR_NORMAL },
1104 { "ibeam", OCR_IBEAM },
1105 { "wait", OCR_WAIT },
1106 { "cross", OCR_CROSS },
1108 /* { "icon", OCR_ICON }, */
1109 { "sizenwse", OCR_SIZENWSE },
1110 { "sizenesw", OCR_SIZENESW },
1111 { "sizewe", OCR_SIZEWE },
1112 { "sizens", OCR_SIZENS },
1113 { "sizeall", OCR_SIZEALL },
1114 /* { "icour", OCR_ICOCUR }, */
1119 static CONST resource_t icon_table[] =
1122 { "sample", OIC_SAMPLE },
1123 { "hand", OIC_HAND },
1124 { "ques", OIC_QUES },
1125 { "bang", OIC_BANG },
1126 { "note", OIC_NOTE },
1127 { "winlogo", OIC_WINLOGO },
1131 static int resource_name_to_resource (Lisp_Object name, int type)
1133 CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1134 : type == IMAGE_ICON ? icon_table
1141 else if (!STRINGP (name))
1143 signal_simple_error ("invalid resource identifier", name);
1148 GET_C_STRING_OS_DATA_ALLOCA (name, nm);
1149 if (!strcasecmp ((char*)res->name, nm))
1150 return res->resource_id;
1151 } while ((++res)->name);
1156 resource_symbol_to_type (Lisp_Object data)
1158 if (EQ (data, Qcursor))
1159 return IMAGE_CURSOR;
1160 else if (EQ (data, Qicon))
1162 else if (EQ (data, Qbitmap))
1163 return IMAGE_BITMAP;
1169 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1170 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1171 int dest_mask, Lisp_Object domain)
1173 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1174 unsigned int type = 0;
1175 HANDLE himage = NULL;
1177 HINSTANCE hinst = NULL;
1181 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1183 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1184 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1186 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1191 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1192 signal_simple_error ("Not an mswindows device", device);
1194 type = resource_symbol_to_type (resource_type);
1196 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1197 iitype = IMAGE_POINTER;
1198 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1199 iitype = IMAGE_COLOR_PIXMAP;
1201 incompatible_image_types (instantiator, dest_mask,
1202 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1204 /* mess with the keyword info we were provided with */
1208 GET_C_STRING_FILENAME_DATA_ALLOCA (file, f);
1210 CYGWIN_WIN32_PATH (f, fname);
1215 if (NILP (resource_id))
1216 resid = (LPCTSTR)fname;
1219 hinst = LoadLibraryEx (fname, NULL,
1220 LOAD_LIBRARY_AS_DATAFILE);
1221 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1225 GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid);
1228 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1230 signal_simple_error ("Invalid resource identifier", resource_id);
1232 /* load the image */
1233 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
1234 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1236 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1238 signal_simple_error ("Cannot load image", instantiator);
1242 FreeLibrary (hinst);
1244 mswindows_initialize_dibitmap_image_instance (ii, iitype);
1246 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1247 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
1248 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1249 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
1250 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1251 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1253 /* hey, we've got an icon type thing so we can reverse engineer the
1255 if (type != IMAGE_BITMAP)
1257 GetIconInfo (himage, &iconinfo);
1258 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1259 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1260 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1261 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1262 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
1266 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1267 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
1268 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1269 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1270 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1275 check_valid_resource_symbol (Lisp_Object data)
1277 CHECK_SYMBOL (data);
1278 if (!resource_symbol_to_type (data))
1279 signal_simple_error ("invalid resource type", data);
1283 check_valid_resource_id (Lisp_Object data)
1285 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1287 !resource_name_to_resource (data, IMAGE_ICON)
1289 !resource_name_to_resource (data, IMAGE_BITMAP))
1290 signal_simple_error ("invalid resource identifier", data);
1294 check_valid_string_or_int (Lisp_Object data)
1297 CHECK_STRING (data);
1302 /**********************************************************************
1304 **********************************************************************/
1305 #ifndef HAVE_X_WINDOWS
1306 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1310 Copyright (c) 1988 X Consortium
1312 Permission is hereby granted, free of charge, to any person obtaining a copy
1313 of this software and associated documentation files (the "Software"), to deal
1314 in the Software without restriction, including without limitation the rights
1315 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1316 copies of the Software, and to permit persons to whom the Software is
1317 furnished to do so, subject to the following conditions:
1319 The above copyright notice and this permission notice shall be included in
1320 all copies or substantial portions of the Software.
1322 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1323 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1324 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1325 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1326 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1327 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1329 Except as contained in this notice, the name of the X Consortium shall not be
1330 used in advertising or otherwise to promote the sale, use or other dealings
1331 in this Software without prior written authorization from the X Consortium.
1336 * This file contains miscellaneous utility routines and is not part of the
1339 * Public entry points:
1341 * XmuReadBitmapData read data from FILE descriptor
1342 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1345 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1346 * that way (but don't use common source code so that people can have one
1347 * without the other).
1352 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1354 #ifndef BitmapSuccess
1355 #define BitmapSuccess 0
1356 #define BitmapOpenFailed 1
1357 #define BitmapFileInvalid 2
1358 #define BitmapNoMemory 3
1360 #define MAX_SIZE 255
1362 /* shared data for the image read/parse logic */
1363 static short hexTable[256]; /* conversion value */
1364 static int initialized = FALSE; /* easier to fill in at run time */
1367 * Table index for the hex values. Initialized once, first time.
1368 * Used for translation value or delimiter significance lookup.
1370 static void initHexTable()
1373 * We build the table at run time for several reasons:
1375 * 1. portable to non-ASCII machines.
1376 * 2. still reentrant since we set the init flag after setting table.
1377 * 3. easier to extend.
1378 * 4. less prone to bugs.
1380 hexTable['0'] = 0; hexTable['1'] = 1;
1381 hexTable['2'] = 2; hexTable['3'] = 3;
1382 hexTable['4'] = 4; hexTable['5'] = 5;
1383 hexTable['6'] = 6; hexTable['7'] = 7;
1384 hexTable['8'] = 8; hexTable['9'] = 9;
1385 hexTable['A'] = 10; hexTable['B'] = 11;
1386 hexTable['C'] = 12; hexTable['D'] = 13;
1387 hexTable['E'] = 14; hexTable['F'] = 15;
1388 hexTable['a'] = 10; hexTable['b'] = 11;
1389 hexTable['c'] = 12; hexTable['d'] = 13;
1390 hexTable['e'] = 14; hexTable['f'] = 15;
1392 /* delimiters of significance are flagged w/ negative value */
1393 hexTable[' '] = -1; hexTable[','] = -1;
1394 hexTable['}'] = -1; hexTable['\n'] = -1;
1395 hexTable['\t'] = -1;
1401 * read next hex value in the input stream, return -1 if EOF
1403 static int NextInt ( FILE *fstream )
1410 /* loop, accumulate hex value until find delimiter */
1411 /* skip any initial delimiters found in read stream */
1419 /* trim high bits, check type and accumulate */
1421 if (isascii(ch) && isxdigit(ch)) {
1422 value = (value << 4) + hexTable[ch];
1424 } else if ((hexTable[ch]) < 0 && gotone)
1433 * The data returned by the following routine is always in left-most byte
1434 * first and left-most bit first. If it doesn't return BitmapSuccess then
1435 * its arguments won't have been touched. This routine should look as much
1436 * like the Xlib routine XReadBitmapfile as possible.
1438 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
1439 FILE *fstream; /* handle on file */
1440 unsigned int *width, *height; /* RETURNED */
1441 unsigned char **datap; /* RETURNED */
1442 int *x_hot, *y_hot; /* RETURNED */
1444 unsigned char *data = NULL; /* working variable */
1445 char line[MAX_SIZE]; /* input line from file */
1446 int size; /* number of bytes of data */
1447 char name_and_type[MAX_SIZE]; /* an input line */
1448 char *type; /* for parsing */
1449 int value; /* from an input line */
1450 int version10p; /* boolean, old format */
1451 int padding; /* to handle alignment */
1452 int bytes_per_line; /* per scanline of data */
1453 unsigned int ww = 0; /* width */
1454 unsigned int hh = 0; /* height */
1455 int hx = -1; /* x hotspot */
1456 int hy = -1; /* y hotspot */
1458 #define Xmalloc(size) malloc(size)
1460 /* first time initialization */
1461 if (initialized == FALSE) initHexTable();
1463 /* error cleanup and return macro */
1464 #define RETURN(code) { if (data) free (data); return code; }
1466 while (fgets(line, MAX_SIZE, fstream)) {
1467 if (strlen(line) == MAX_SIZE-1) {
1468 RETURN (BitmapFileInvalid);
1470 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1471 if (!(type = strrchr(name_and_type, '_')))
1472 type = name_and_type;
1476 if (!strcmp("width", type))
1477 ww = (unsigned int) value;
1478 if (!strcmp("height", type))
1479 hh = (unsigned int) value;
1480 if (!strcmp("hot", type)) {
1481 if (type-- == name_and_type || type-- == name_and_type)
1483 if (!strcmp("x_hot", type))
1485 if (!strcmp("y_hot", type))
1491 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1493 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1495 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1500 if (!(type = strrchr(name_and_type, '_')))
1501 type = name_and_type;
1505 if (strcmp("bits[]", type))
1509 RETURN (BitmapFileInvalid);
1511 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1516 bytes_per_line = (ww+7)/8 + padding;
1518 size = bytes_per_line * hh;
1519 data = (unsigned char *) Xmalloc ((unsigned int) size);
1521 RETURN (BitmapNoMemory);
1527 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1528 if ((value = NextInt(fstream)) < 0)
1529 RETURN (BitmapFileInvalid);
1531 if (!padding || ((bytes+2) % bytes_per_line))
1532 *(ptr++) = value >> 8;
1538 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1539 if ((value = NextInt(fstream)) < 0)
1540 RETURN (BitmapFileInvalid);
1548 RETURN (BitmapFileInvalid);
1555 if (x_hot) *x_hot = hx;
1556 if (y_hot) *y_hot = hy;
1558 RETURN (BitmapSuccess);
1562 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
1563 unsigned int *height, unsigned char **datap,
1564 int *x_hot, int *y_hot)
1569 if ((fstream = fopen (filename, "r")) == NULL) {
1570 return BitmapOpenFailed;
1572 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1576 #endif /* HAVE_X_WINDOWS */
1578 /* this table flips four bits around. */
1579 static int flip_table[] =
1581 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1584 /* the bitmap data comes in the following format: Widths are padded to
1585 a multiple of 8. Scan lines are stored in increasing byte order
1586 from left to right, little-endian within a byte. 0 = white, 1 =
1587 black. It must be converted to the following format: Widths are
1588 padded to a multiple of 16. Scan lines are stored in increasing
1589 byte order from left to right, big-endian within a byte. 0 =
1590 black, 1 = white. */
1592 xbm_create_bitmap_from_data (HDC hdc, char *data,
1593 unsigned int width, unsigned int height,
1594 int mask, COLORREF fg, COLORREF bg)
1596 int old_width = (width + 7)/8;
1597 int new_width = BPLINE (2*((width + 15)/16));
1598 unsigned char *offset;
1600 unsigned char *new_data, *new_offset;
1602 BITMAPINFO* bmp_info =
1603 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1609 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
1617 for (i=0; i<height; i++)
1619 offset = data + i*old_width;
1620 new_offset = new_data + i*new_width;
1622 for (j=0; j<old_width; j++)
1624 int byte = offset[j];
1625 new_offset[j] = ~ (unsigned char)
1626 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1630 /* if we want a mask invert the bits */
1633 new_offset = &new_data[height * new_width];
1634 while (new_offset-- != new_data)
1636 *new_offset ^= 0xff;
1640 bmp_info->bmiHeader.biWidth=width;
1641 bmp_info->bmiHeader.biHeight=-(LONG)height;
1642 bmp_info->bmiHeader.biPlanes=1;
1643 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1644 bmp_info->bmiHeader.biBitCount=1;
1645 bmp_info->bmiHeader.biCompression=BI_RGB;
1646 bmp_info->bmiHeader.biClrUsed = 2;
1647 bmp_info->bmiHeader.biClrImportant = 2;
1648 bmp_info->bmiHeader.biSizeImage = height * new_width;
1649 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1650 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1651 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1652 bmp_info->bmiColors[0].rgbReserved = 0;
1653 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1654 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1655 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1656 bmp_info->bmiColors[1].rgbReserved = 0;
1658 bitmap = CreateDIBSection (hdc,
1666 if (!bitmap || !bmp_buf)
1672 /* copy in the actual bitmap */
1673 memcpy (bmp_buf, new_data, height * new_width);
1679 /* Given inline data for a mono pixmap, initialize the given
1680 image instance accordingly. */
1683 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
1684 int width, int height,
1685 /* Note that data is in ext-format! */
1687 Lisp_Object instantiator,
1688 Lisp_Object pointer_fg,
1689 Lisp_Object pointer_bg,
1692 Lisp_Object mask_filename)
1694 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1695 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device)));
1696 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1697 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1698 enum image_instance_type type;
1699 COLORREF black = PALETTERGB (0,0,0);
1700 COLORREF white = PALETTERGB (255,255,255);
1702 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1704 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1705 signal_simple_error ("Not an MS-Windows device", device);
1707 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1708 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1710 if (!NILP (foreground) || !NILP (background))
1711 type = IMAGE_COLOR_PIXMAP;
1713 type = IMAGE_MONO_PIXMAP;
1715 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1716 type = IMAGE_MONO_PIXMAP;
1717 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1718 type = IMAGE_COLOR_PIXMAP;
1719 else if (dest_mask & IMAGE_POINTER_MASK)
1720 type = IMAGE_POINTER;
1722 incompatible_image_types (instantiator, dest_mask,
1723 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1724 | IMAGE_POINTER_MASK);
1726 mswindows_initialize_dibitmap_image_instance (ii, type);
1728 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1729 find_keyword_in_vector (instantiator, Q_file);
1730 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
1731 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
1732 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1733 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1734 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1735 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1736 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1737 TRUE, black, white);
1741 case IMAGE_MONO_PIXMAP:
1742 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1743 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1744 FALSE, black, black);
1747 case IMAGE_COLOR_PIXMAP:
1749 COLORREF fg = black;
1750 COLORREF bg = white;
1752 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1754 Fmake_color_instance (foreground, device,
1755 encode_error_behavior_flag (ERROR_ME));
1757 if (COLOR_INSTANCEP (foreground))
1758 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1760 if (!NILP (background) && !COLOR_INSTANCEP (background))
1762 Fmake_color_instance (background, device,
1763 encode_error_behavior_flag (ERROR_ME));
1765 if (COLOR_INSTANCEP (background))
1766 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1768 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1769 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1771 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1772 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1779 COLORREF fg = black;
1780 COLORREF bg = white;
1782 if (NILP (foreground))
1783 foreground = pointer_fg;
1784 if (NILP (background))
1785 background = pointer_bg;
1787 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1788 find_keyword_in_vector (instantiator, Q_hotspot_x);
1789 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1790 find_keyword_in_vector (instantiator, Q_hotspot_y);
1791 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1792 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1793 if (COLOR_INSTANCEP (foreground))
1794 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1795 if (COLOR_INSTANCEP (background))
1796 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1798 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1799 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1801 mswindows_initialize_image_instance_icon (ii, TRUE);
1811 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1812 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1813 int dest_mask, int width, int height,
1814 /* Note that data is in ext-format! */
1817 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1818 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1819 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1820 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME
1821 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))));
1822 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1824 CONST char *gcc_may_you_rot_in_hell;
1826 if (!NILP (mask_data))
1828 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
1829 gcc_may_you_rot_in_hell);
1831 xbm_create_bitmap_from_data ( hdc,
1833 gcc_may_you_rot_in_hell,
1834 XINT (XCAR (mask_data)),
1835 XINT (XCAR (XCDR (mask_data))), FALSE,
1837 PALETTERGB (255,255,255));
1840 init_image_instance_from_xbm_inline (ii, width, height, bits,
1841 instantiator, pointer_fg, pointer_bg,
1842 dest_mask, mask, mask_file);
1845 /* Instantiate method for XBM's. */
1848 mswindows_xbm_instantiate (Lisp_Object image_instance,
1849 Lisp_Object instantiator,
1850 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1851 int dest_mask, Lisp_Object domain)
1853 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1854 CONST char *gcc_go_home;
1856 assert (!NILP (data));
1858 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
1861 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1862 pointer_bg, dest_mask, XINT (XCAR (data)),
1863 XINT (XCAR (XCDR (data))), gcc_go_home);
1867 /**********************************************************************
1869 **********************************************************************/
1871 /* This is about to get redefined! */
1874 /* We have to define SYSV32 so that compface.h includes string.h
1875 instead of strings.h. */
1880 #include <compface.h>
1884 /* JMP_BUF cannot be used here because if it doesn't get defined
1885 to jmp_buf we end up with a conflicting type error with the
1886 definition in compface.h */
1887 extern jmp_buf comp_env;
1891 mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1892 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1893 int dest_mask, Lisp_Object domain)
1895 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1897 char *p, *bits, *bp;
1898 CONST char * volatile emsg = 0;
1899 CONST char * volatile dstring;
1901 assert (!NILP (data));
1903 GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring);
1905 if ((p = strchr (dstring, ':')))
1910 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
1911 if (!(stattis = setjmp (comp_env)))
1913 UnCompAll ((char *) dstring);
1920 emsg = "uncompface: internal error";
1923 emsg = "uncompface: insufficient or invalid data";
1926 emsg = "uncompface: excess data ignored";
1931 signal_simple_error_2 (emsg, data, Qimage);
1933 bp = bits = (char *) alloca (PIXELS / 8);
1935 /* the compface library exports char F[], which uses a single byte per
1936 pixel to represent a 48x48 bitmap. Yuck. */
1937 for (i = 0, p = F; i < (PIXELS / 8); ++i)
1940 /* reverse the bit order of each byte... */
1941 for (b = n = 0; b < 8; ++b)
1948 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1949 pointer_bg, dest_mask, 48, 48, bits);
1951 #endif /* HAVE_XFACE */
1954 /************************************************************************/
1955 /* image instance methods */
1956 /************************************************************************/
1959 mswindows_print_image_instance (struct Lisp_Image_Instance *p,
1960 Lisp_Object printcharfun,
1965 switch (IMAGE_INSTANCE_TYPE (p))
1967 case IMAGE_MONO_PIXMAP:
1968 case IMAGE_COLOR_PIXMAP:
1970 sprintf (buf, " (0x%lx",
1971 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1972 write_c_string (buf, printcharfun);
1973 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1975 sprintf (buf, "/0x%lx",
1976 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1977 write_c_string (buf, printcharfun);
1979 write_c_string (")", printcharfun);
1988 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
1990 if (DEVICE_LIVE_P (XDEVICE (p->device)))
1992 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET
1994 IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
1996 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
1997 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
1998 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
2002 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
2003 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
2004 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
2005 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2006 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2007 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
2008 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
2009 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
2010 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2021 /************************************************************************/
2022 /* subwindow and widget support */
2023 /************************************************************************/
2025 /* unmap the image if it is a widget. This is used by redisplay via
2026 redisplay_unmap_subwindows */
2028 mswindows_unmap_subwindow (struct Lisp_Image_Instance *p)
2030 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2032 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2035 SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
2036 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2040 /* map the subwindow. This is used by redisplay via
2041 redisplay_output_subwindow */
2043 mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y)
2045 /* ShowWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), SW_SHOW);*/
2046 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2049 SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSIZE
2050 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2053 /* resize the subwindow instance */
2055 mswindows_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h)
2057 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2060 SWP_NOZORDER | SWP_NOMOVE
2061 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2064 /* when you click on a widget you may activate another widget this
2065 needs to be checked and all appropriate widgets updated */
2067 mswindows_update_subwindow (struct Lisp_Image_Instance *p)
2069 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
2071 /* buttons checked or otherwise */
2072 if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton))
2074 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_SINGLE_ITEM (p)))
2075 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2076 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2078 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2079 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2084 /* register widgets into our hastable so that we can cope with the
2085 callbacks. The hashtable is weak so deregistration is handled
2088 mswindows_register_gui_item (Lisp_Object gui, Lisp_Object domain)
2090 Lisp_Object frame = FW_FRAME (domain);
2091 struct frame* f = XFRAME (frame);
2092 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f),
2095 Fputhash (make_int (id),
2096 XGUI_ITEM (gui)->callback,
2097 FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
2102 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2104 return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_SINGLE_ITEM (instance),
2109 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2110 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2111 int dest_mask, Lisp_Object domain)
2113 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2114 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2115 struct device* d = XDEVICE (device);
2116 Lisp_Object frame = FW_FRAME (domain);
2119 if (!DEVICE_MSWINDOWS_P (d))
2120 signal_simple_error ("Not an mswindows device", device);
2122 /* have to set the type this late in case there is no device
2123 instantiation for a widget */
2124 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2126 wnd = CreateWindow( "STATIC",
2129 0, /* starting x position */
2130 0, /* starting y position */
2131 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2132 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2133 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), /* parent window */
2136 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2140 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2141 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2145 mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
2146 struct Lisp_Image_Instance *p2, int depth)
2148 switch (IMAGE_INSTANCE_TYPE (p1))
2150 case IMAGE_MONO_PIXMAP:
2151 case IMAGE_COLOR_PIXMAP:
2153 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2154 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2165 static unsigned long
2166 mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
2168 switch (IMAGE_INSTANCE_TYPE (p))
2170 case IMAGE_MONO_PIXMAP:
2171 case IMAGE_COLOR_PIXMAP:
2173 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2180 /* Set all the slots in an image instance structure to reasonable
2181 default values. This is used somewhere within an instantiate
2182 method. It is assumed that the device slot within the image
2183 instance is already set -- this is the case when instantiate
2184 methods are called. */
2187 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
2188 enum image_instance_type type)
2190 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2191 IMAGE_INSTANCE_TYPE (ii) = type;
2192 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2193 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2194 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2195 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2196 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2197 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2201 /************************************************************************/
2203 /************************************************************************/
2205 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2206 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2207 int dest_mask, Lisp_Object domain,
2208 CONST char* class, int flags, int exflags)
2210 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2212 struct Lisp_Image_Instance *groupii = 0;
2213 Lisp_Object group = find_keyword_in_vector (instantiator, Q_group);
2215 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2216 struct device* d = XDEVICE (device);
2217 Lisp_Object frame = FW_FRAME (domain);
2221 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2222 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2224 if (!DEVICE_MSWINDOWS_P (d))
2225 signal_simple_error ("Not an mswindows device", device);
2227 /* if the user specified another glyph as a group pick up the
2228 instance in our domain. */
2231 if (SYMBOLP (group))
2232 group = XSYMBOL (group)->value;
2233 group = glyph_image_instance (group, domain, ERROR_ME, 1);
2234 groupii = XIMAGE_INSTANCE (group);
2237 if (!gui_item_active_p (gui))
2238 flags |= WS_DISABLED;
2240 style = pgui->style;
2242 if (!NILP (pgui->callback))
2244 id = mswindows_register_widget_instance (image_instance, domain);
2246 /* have to set the type this late in case there is no device
2247 instantiation for a widget */
2248 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
2249 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2250 GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
2252 wnd = CreateWindowEx(
2253 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2257 0, /* starting x position */
2258 0, /* starting y position */
2259 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2260 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2262 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2263 (HMENU)id, /* No menu */
2265 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2269 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2270 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2271 /* set the widget font from the widget face */
2272 SendMessage (wnd, WM_SETFONT,
2273 (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
2274 (XFONT_INSTANCE (widget_face_font_info
2276 IMAGE_INSTANCE_WIDGET_FACE (ii),
2278 MAKELPARAM (TRUE, 0));
2281 /* Instantiate a button widget. Unfortunately instantiated widgets are
2282 particular to a frame since they need to have a parent. It's not
2283 like images where you just select the image into the context you
2284 want to display it in and BitBlt it. So images instances can have a
2285 many-to-one relationship with things you see, whereas widgets can
2286 only be one-to-one (i.e. per frame) */
2288 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2289 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2290 int dest_mask, Lisp_Object domain)
2292 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2294 int flags = BS_NOTIFY;
2296 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2297 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2298 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2300 if (!gui_item_active_p (gui))
2301 flags |= WS_DISABLED;
2305 if (!IMAGE_INSTANCEP (glyph))
2306 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2308 if (IMAGE_INSTANCEP (glyph))
2309 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2310 BS_BITMAP : BS_ICON;
2313 style = pgui->style;
2315 if (EQ (style, Qradio))
2317 flags |= BS_RADIOBUTTON;
2319 else if (EQ (style, Qtoggle))
2321 flags |= BS_AUTOCHECKBOX;
2324 flags |= BS_DEFPUSHBUTTON;
2326 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2327 pointer_bg, dest_mask, domain, "BUTTON", flags,
2328 WS_EX_CONTROLPARENT);
2330 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2331 /* set the checked state */
2332 if (gui_item_selected_p (gui))
2333 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2335 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2336 /* add the image if one was given */
2337 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph))
2339 SendMessage (wnd, BM_SETIMAGE,
2340 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2341 IMAGE_BITMAP : IMAGE_ICON),
2342 (LPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2343 XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2344 XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2348 /* instantiate an edit control */
2350 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2351 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2352 int dest_mask, Lisp_Object domain)
2354 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2355 pointer_bg, dest_mask, domain, "EDIT",
2356 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2358 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2361 /* instantiate a progress gauge */
2363 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2364 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2365 int dest_mask, Lisp_Object domain)
2368 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2369 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2370 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2371 WS_TABSTOP | WS_BORDER | PBS_SMOOTH,
2372 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2373 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2374 /* set the colors */
2375 #ifdef PBS_SETBKCOLOR
2376 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2377 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2380 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2381 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2383 #ifdef PBS_SETBARCOLOR
2384 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2385 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2388 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2389 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2393 /* instantiate a tree view widget */
2394 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2395 HWND wnd, HTREEITEM parent, Lisp_Object entry,
2396 int children, Lisp_Object domain)
2398 TV_INSERTSTRUCT tvitem;
2401 tvitem.hParent = parent;
2402 tvitem.hInsertAfter = TVI_LAST;
2403 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2404 tvitem.item.cChildren = children;
2406 if (VECTORP (entry))
2408 /* we always maintain the real gui item at the head of the
2409 list. We have to put them in the list in the first place
2410 because the whole model assumes that the glyph instances have
2411 references to all the associated data. If we didn't do this
2412 GC would bite us badly. */
2413 Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
2414 if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
2417 Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
2418 Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
2422 XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
2423 Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
2426 tvitem.item.lParam = mswindows_register_gui_item (gui, domain);
2427 tvitem.item.mask |= TVIF_PARAM;
2428 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
2429 tvitem.item.pszText);
2432 GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.item.pszText);
2434 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2436 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2437 0, (LPARAM)&tvitem)) == 0)
2438 signal_simple_error ("error adding tree view entry", entry);
2443 static void add_tree_item_list (Lisp_Object image_instance,
2444 HWND wnd, HTREEITEM parent, Lisp_Object list,
2449 /* get the first item */
2450 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2451 /* recursively add items to the tree view */
2452 LIST_LOOP (rest, XCDR (list))
2454 if (LISTP (XCAR (rest)))
2455 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2457 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2462 mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2463 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2464 int dest_mask, Lisp_Object domain)
2469 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2470 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2471 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2472 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2473 | TVS_HASLINES | TVS_HASBUTTONS,
2474 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2476 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2479 parent = add_tree_item (image_instance,
2480 wnd, NULL, IMAGE_INSTANCE_WIDGET_TEXT (ii), TRUE,
2483 /* recursively add items to the tree view */
2484 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2486 if (LISTP (XCAR (rest)))
2487 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2489 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2493 /* instantiate a tab control */
2494 static TC_ITEM* add_tab_item (Lisp_Object image_instance,
2495 HWND wnd, Lisp_Object entry,
2496 Lisp_Object domain, int index)
2498 TC_ITEM tvitem, *ret;
2500 tvitem.mask = TCIF_TEXT;
2502 if (VECTORP (entry))
2504 /* we always maintain the real gui item at the head of the
2505 list. We have to put them in the list in the first place
2506 because the whole model assumes that the glyph instances have
2507 references to all the associated data. If we didn't do this
2508 GC would bite us badly. */
2509 Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
2510 if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
2513 Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
2514 Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
2518 XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
2519 Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
2522 tvitem.lParam = mswindows_register_gui_item (gui, domain);
2523 tvitem.mask |= TCIF_PARAM;
2524 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
2528 GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.pszText);
2530 tvitem.cchTextMax = strlen (tvitem.pszText);
2532 if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
2533 index, (LPARAM)&tvitem)) < 0)
2534 signal_simple_error ("error adding tab entry", entry);
2540 mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2541 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2542 int dest_mask, Lisp_Object domain)
2547 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2548 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2549 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2550 /* borders don't suit tabs so well */
2552 WS_EX_CONTROLPARENT);
2554 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2555 /* add items to the tab */
2556 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2558 add_tab_item (image_instance, wnd, XCAR (rest), domain, index);
2563 /* set the properties of a tab control */
2565 mswindows_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop,
2568 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2570 if (EQ (prop, Q_items))
2572 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2575 check_valid_item_list_1 (val);
2577 /* delete the pre-existing items */
2578 SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
2580 /* add items to the tab */
2581 LIST_LOOP (rest, val)
2583 add_tab_item (image_instance, wnd, XCAR (rest),
2584 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), index);
2593 /* instantiate a static control possible for putting other things in */
2595 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2596 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2597 int dest_mask, Lisp_Object domain)
2599 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2600 pointer_bg, dest_mask, domain, "STATIC",
2601 0, WS_EX_STATICEDGE);
2605 /* instantiate a static control possible for putting other things in */
2607 mswindows_group_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2608 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2609 int dest_mask, Lisp_Object domain)
2611 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2612 pointer_bg, dest_mask, domain, "BUTTON",
2613 WS_GROUP | BS_GROUPBOX | WS_BORDER,
2618 /* instantiate a scrollbar control */
2620 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2621 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2622 int dest_mask, Lisp_Object domain)
2624 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2625 pointer_bg, dest_mask, domain, "SCROLLBAR",
2630 /* instantiate a combo control */
2632 mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2633 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2634 int dest_mask, Lisp_Object domain)
2636 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2640 /* Maybe ought to generalise this more but it may be very windows
2641 specific. In windows the window height of a combo box is the
2642 height when the combo box is open. Thus we need to set the height
2643 before creating the window and then reset it to a single line
2644 after the window is created so that redisplay does the right
2646 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2647 pointer_bg, dest_mask, domain, "COMBOBOX",
2648 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
2650 | CBS_HASSTRINGS | WS_VSCROLL,
2651 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2652 /* reset the height */
2653 widget_text_to_pixel_conversion (domain,
2654 IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0,
2655 &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0);
2656 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2657 /* add items to the combo box */
2658 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
2659 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2662 GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam);
2663 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
2664 signal_simple_error ("error adding combo entries", instantiator);
2668 /* get properties of a control */
2670 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
2672 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2673 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2674 /* get the text from a control */
2675 if (EQ (prop, Q_text))
2677 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
2678 Extbyte* buf =alloca (len+1);
2680 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
2681 return build_ext_string (buf, FORMAT_OS);
2686 /* get properties of a button */
2688 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
2690 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2691 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2692 /* check the state of a button */
2693 if (EQ (prop, Q_selected))
2695 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
2703 /* get properties of a combo box */
2705 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
2707 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2708 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2709 /* get the text from a control */
2710 if (EQ (prop, Q_text))
2712 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
2713 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
2714 Extbyte* buf = alloca (len+1);
2715 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
2716 return build_ext_string (buf, FORMAT_OS);
2721 /* set the properties of a control */
2723 mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
2726 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2728 if (EQ (prop, Q_text))
2732 GET_C_STRING_OS_DATA_ALLOCA (val, lparam);
2733 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2734 WM_SETTEXT, 0, (LPARAM)lparam);
2740 /* set the properties of a progres guage */
2742 mswindows_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop,
2745 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2747 if (EQ (prop, Q_percent))
2750 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2751 PBM_SETPOS, (WPARAM)XINT (val), 0);
2758 /************************************************************************/
2759 /* initialization */
2760 /************************************************************************/
2763 syms_of_glyphs_mswindows (void)
2765 defkeyword (&Q_resource_id, ":resource-id");
2766 defkeyword (&Q_resource_type, ":resource-type");
2770 console_type_create_glyphs_mswindows (void)
2774 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
2775 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
2776 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
2777 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
2778 CONSOLE_HAS_METHOD (mswindows, update_subwindow);
2779 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
2780 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
2781 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
2782 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
2783 CONSOLE_HAS_METHOD (mswindows, resize_subwindow);
2787 image_instantiator_format_create_glyphs_mswindows (void)
2789 IIFORMAT_VALID_CONSOLE (mswindows, nothing);
2790 IIFORMAT_VALID_CONSOLE (mswindows, string);
2791 IIFORMAT_VALID_CONSOLE (mswindows, formatted_string);
2792 IIFORMAT_VALID_CONSOLE (mswindows, inherit);
2793 /* image-instantiator types */
2795 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
2796 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
2798 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
2799 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
2801 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
2802 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
2805 IIFORMAT_VALID_CONSOLE (mswindows, jpeg);
2808 IIFORMAT_VALID_CONSOLE (mswindows, tiff);
2811 IIFORMAT_VALID_CONSOLE (mswindows, png);
2814 IIFORMAT_VALID_CONSOLE (mswindows, gif);
2817 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
2818 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
2819 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
2821 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
2822 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
2824 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
2825 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
2827 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
2828 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
2829 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property);
2831 INITIALIZE_DEVICE_IIFORMAT (mswindows, group);
2832 IIFORMAT_HAS_DEVMETHOD (mswindows, group, instantiate);
2835 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
2836 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
2839 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
2840 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
2841 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
2844 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
2845 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
2847 /* progress gauge */
2848 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
2849 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, set_property);
2850 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
2852 /* tree view widget */
2853 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
2854 /* IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/
2855 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
2857 /* tab control widget */
2858 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
2859 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
2860 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, set_property);
2862 /* windows bitmap format */
2863 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
2864 IIFORMAT_HAS_METHOD (bmp, validate);
2865 IIFORMAT_HAS_METHOD (bmp, normalize);
2866 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
2867 IIFORMAT_HAS_METHOD (bmp, instantiate);
2869 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
2870 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
2871 IIFORMAT_VALID_CONSOLE (mswindows, bmp);
2873 /* mswindows resources */
2874 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
2875 "mswindows-resource");
2877 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
2878 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
2879 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
2880 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
2882 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
2883 check_valid_resource_symbol);
2884 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
2885 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
2886 IIFORMAT_VALID_CONSOLE (mswindows, mswindows_resource);
2890 vars_of_glyphs_mswindows (void)
2892 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
2893 A list of the directories in which mswindows bitmap files may be found.
2894 This is used by the `make-image-instance' function.
2896 Vmswindows_bitmap_file_path = Qnil;
2900 complex_vars_of_glyphs_mswindows (void)