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);
111 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
113 /************************************************************************/
114 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
116 /************************************************************************/
117 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
118 int width, int height,
121 unsigned char** bmp_data)
123 struct device *d = XDEVICE (device);
127 BITMAPINFO* bmp_info;
128 unsigned char *ip, *dp;
130 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
132 int bpline = BPLINE(width * 3);
133 /* FIXME: we can do this because 24bpp implies no color table, once
134 * we start palettizing this is no longer true. The X versions of
135 * this function quantises to 256 colors or bit masks down to a
136 * long. Windows can actually handle rgb triples in the raw so I
137 * don't see much point trying to optimize down to the best
138 * structure - unless it has memory / color allocation implications
140 bmp_info=xnew_and_zero (BITMAPINFO);
147 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
148 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
149 bmp_info->bmiHeader.biSizeImage=width*height*3;
151 /* bitmap data needs to be in blue, green, red triples - in that
152 order, eimage is in RGB format so we need to convert */
153 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
154 *bit_count = bpline * height;
163 for (i = height-1; i >= 0; i--) {
164 dp = (*bmp_data) + (i * bpline);
165 for (j = 0; j < width; j++) {
173 else /* scale to 256 colors */
177 int bpline = BPLINE (width * 3);
178 /* Quantize the image and get a histogram while we're at it.
179 Do this first to save memory */
180 qtable = build_EImage_quantable(pic, width, height, 256);
181 if (qtable == NULL) return NULL;
183 /* use our quantize table to allocate the colors */
184 ncolors = qtable->num_active_colors;
185 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
186 sizeof(RGBQUAD) * ncolors);
193 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
195 bmp_info->bmiHeader.biBitCount=8;
196 bmp_info->bmiHeader.biCompression=BI_RGB;
197 bmp_info->bmiHeader.biSizeImage=bpline*height;
198 bmp_info->bmiHeader.biClrUsed=ncolors;
199 bmp_info->bmiHeader.biClrImportant=ncolors;
201 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
202 *bit_count = bpline * height;
211 /* build up an RGBQUAD colortable */
212 for (i = 0; i < qtable->num_active_colors; i++) {
213 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
214 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
215 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
216 colortbl[i].rgbReserved = 0;
219 /* now build up the data. picture has to be upside-down and
220 back-to-front for msw bitmaps */
222 for (i = height-1; i >= 0; i--) {
223 dp = (*bmp_data) + (i * bpline);
224 for (j = 0; j < width; j++) {
228 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
233 /* fix up the standard stuff */
234 bmp_info->bmiHeader.biWidth=width;
235 bmp_info->bmiHeader.biHeight=height;
236 bmp_info->bmiHeader.biPlanes=1;
237 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
238 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
239 bmp_info->bmiHeader.biYPelsPerMeter=0;
244 /* Given a pixmap filename, look through all of the "standard" places
245 where the file might be located. Return a full pathname if found;
246 otherwise, return Qnil. */
249 mswindows_locate_pixmap_file (Lisp_Object name)
251 /* This function can GC if IN_REDISPLAY is false */
254 /* Check non-absolute pathnames with a directory component relative to
255 the search path; that's the way Xt does it. */
256 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
257 (XSTRING_BYTE (name, 0) == '.' &&
258 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
259 (XSTRING_BYTE (name, 1) == '.' &&
260 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
262 if (!NILP (Ffile_readable_p (name)))
268 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
270 Lisp_Object temp = list1 (Vdata_directory);
274 locate_file (temp, name, Qnil, &found, R_OK);
282 /* Initialize an image instance from a bitmap
284 DEST_MASK specifies the mask of allowed image types.
286 If this fails, signal an error. INSTANTIATOR is only used
287 in the error message. */
290 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
291 BITMAPINFO *bmp_info,
295 Lisp_Object instantiator,
296 int x_hot, int y_hot,
299 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
300 struct device *d = XDEVICE (device);
307 if (!DEVICE_MSWINDOWS_P (d))
308 signal_simple_error ("Not an mswindows device", device);
310 if (NILP (DEVICE_SELECTED_FRAME (d)))
311 signal_simple_error ("No selected frame on mswindows device", device);
313 f = XFRAME (DEVICE_SELECTED_FRAME (d));
315 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
316 type = IMAGE_COLOR_PIXMAP;
317 else if (dest_mask & IMAGE_POINTER_MASK)
318 type = IMAGE_POINTER;
320 incompatible_image_types (instantiator, dest_mask,
321 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
322 hdc = FRAME_MSWINDOWS_CDC (f);
324 bitmap=CreateDIBSection (hdc,
330 if (!bitmap || !bmp_buf)
331 signal_simple_error ("Unable to create bitmap", instantiator);
333 /* copy in the actual bitmap */
334 memcpy (bmp_buf, bmp_data, bmp_bits);
336 mswindows_initialize_dibitmap_image_instance (ii, type);
338 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
339 find_keyword_in_vector (instantiator, Q_file);
341 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
342 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
343 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
344 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
345 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
346 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
347 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
351 mswindows_initialize_image_instance_mask (ii, f);
354 if (type == IMAGE_POINTER)
356 mswindows_initialize_image_instance_icon(ii, TRUE);
361 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
362 int width, int height,
363 unsigned char *eimage,
365 Lisp_Object instantiator,
368 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
369 BITMAPINFO* bmp_info;
370 unsigned char* bmp_data;
374 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
375 signal_simple_error ("Not an mswindows device", device);
377 /* this is a hack but MaskBlt and TransparentBlt are not supported
378 on most windows variants */
379 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
380 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
382 /* build a bitmap from the eimage */
383 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
384 &bmp_bits, &bmp_data)))
386 signal_simple_error ("EImage to DIBitmap conversion failed",
390 /* Now create the pixmap and set up the image instance */
391 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
392 bmp_data, bmp_bits, instantiator,
399 static void set_mono_pixel ( unsigned char* bits,
400 int bpline, int height,
401 int x, int y, int white )
404 unsigned char bitnum;
405 /* Find the byte on which this scanline begins */
406 index = (height - y - 1) * bpline;
407 /* Find the byte containing this pixel */
409 /* Which bit is it? */
410 bitnum = (unsigned char)( 7 - (x % 8) );
411 if( white ) /* Turn it on */
412 bits[index] |= (1<<bitnum);
413 else /* Turn it off */
414 bits[index] &= ~(1<<bitnum);
418 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
423 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
424 unsigned char* dibits;
425 BITMAPINFO* bmp_info =
426 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
428 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
431 int maskbpline = BPLINE (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8));
432 int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
437 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
438 bmp_info->bmiHeader.biHeight = height;
439 bmp_info->bmiHeader.biPlanes=1;
440 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
441 bmp_info->bmiHeader.biBitCount=1;
442 bmp_info->bmiHeader.biCompression=BI_RGB;
443 bmp_info->bmiHeader.biClrUsed = 2;
444 bmp_info->bmiHeader.biClrImportant = 2;
445 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
446 bmp_info->bmiColors[0].rgbRed = 0;
447 bmp_info->bmiColors[0].rgbGreen = 0;
448 bmp_info->bmiColors[0].rgbBlue = 0;
449 bmp_info->bmiColors[0].rgbReserved = 0;
450 bmp_info->bmiColors[1].rgbRed = 255;
451 bmp_info->bmiColors[1].rgbGreen = 255;
452 bmp_info->bmiColors[1].rgbBlue = 255;
453 bmp_info->bmiColors[0].rgbReserved = 0;
455 if (!(mask = CreateDIBSection (hcdc,
465 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
466 /* build up an in-memory set of bits to mess with */
469 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
470 bmp_info->bmiHeader.biHeight = -height;
471 bmp_info->bmiHeader.biPlanes=1;
472 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
473 bmp_info->bmiHeader.biBitCount=24;
474 bmp_info->bmiHeader.biCompression=BI_RGB;
475 bmp_info->bmiHeader.biClrUsed = 0;
476 bmp_info->bmiHeader.biClrImportant = 0;
477 bmp_info->bmiHeader.biSizeImage = height * bpline;
479 dibits = xmalloc_and_zero (bpline * height);
481 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
486 DIB_RGB_COLORS) <= 0)
492 /* now set the colored bits in the mask and transparent ones to
493 black in the original */
494 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
496 for(j=0; j<height; j++)
498 unsigned char* idx = &dibits[j * bpline + i * 3];
500 if( RGB (idx[2], idx[1], idx[0]) == transparent_color )
502 idx[0] = idx[1] = idx[2] = 0;
503 set_mono_pixel( and_bits, maskbpline, height, i, j, TRUE );
507 set_mono_pixel( and_bits, maskbpline, height, i, j, FALSE );
513 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
523 SelectObject(hcdc, old);
525 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
529 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
534 /* we rely on windows to do any resizing necessary */
535 x_icon.fIcon=cursor ? FALSE : TRUE;
536 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
537 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
538 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
539 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
541 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
542 CreateIconIndirect (&x_icon);
546 mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
552 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
553 HDC hdcDst = CreateCompatibleDC (hcdc);
555 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
557 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
559 old2 = SelectObject (hdcDst, newbmp);
561 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
563 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
564 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
567 DeleteObject (newbmp);
572 SelectObject (hdcDst, old2);
573 SelectObject (hcdc, old1);
580 mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
584 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
588 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
589 HDC hdcDst = CreateCompatibleDC (hcdc);
591 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
592 newmask = CreateCompatibleBitmap(hcdc, newx, newy);
593 old2 = SelectObject (hdcDst, newmask);
595 if (!StretchBlt(hdcDst, 0, 0, newx, newy,
597 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
598 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
601 DeleteObject (newmask);
606 SelectObject (hdcDst, old2);
607 SelectObject (hcdc, old1);
618 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
622 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
623 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
628 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
629 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
630 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
631 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
633 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
634 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
635 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
636 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
641 /**********************************************************************
643 **********************************************************************/
653 static struct color_symbol*
654 extract_xpm_color_names (Lisp_Object device,
656 Lisp_Object color_symbol_alist,
659 /* This function can GC */
661 Lisp_Object results = Qnil;
663 struct color_symbol *colortbl;
664 struct gcpro gcpro1, gcpro2;
666 GCPRO2 (results, device);
668 /* We built up results to be (("name" . #<color>) ...) so that if an
669 error happens we don't lose any malloc()ed data, or more importantly,
670 leave any pixels allocated in the server. */
672 LIST_LOOP (rest, color_symbol_alist)
674 Lisp_Object cons = XCAR (rest);
675 Lisp_Object name = XCAR (cons);
676 Lisp_Object value = XCDR (cons);
682 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
685 assert (COLOR_SPECIFIERP (value));
686 value = Fspecifier_instance (value, domain, Qnil, Qnil);
690 results = noseeum_cons (noseeum_cons (name, value), results);
693 UNGCPRO; /* no more evaluation */
696 if (i == 0) return 0;
698 colortbl = xnew_array_and_zero (struct color_symbol, i);
702 Lisp_Object cons = XCAR (results);
704 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
706 GET_C_STRING_OS_DATA_ALLOCA (XCAR (cons), colortbl[j].name);
707 colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
708 free_cons (XCONS (cons));
710 results = XCDR (results);
711 free_cons (XCONS (cons));
716 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
717 unsigned char** data,
718 int* width, int* height,
719 int* x_hot, int* y_hot,
721 struct color_symbol* color_symbols,
726 int result, i, j, transp_idx, maskbpline;
729 COLORREF color; /* the american spelling virus hits again .. */
734 xpminfo.valuemask=XpmHotspot;
737 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
746 signal_simple_error ("Invalid XPM data", image);
750 signal_double_file_error ("Parsing pixmap data",
751 "out of memory", image);
755 signal_double_file_error_2 ("Parsing pixmap data",
756 "unknown error code",
757 make_int (result), image);
761 *width = xpmimage.width;
762 *height = xpmimage.height;
763 maskbpline = BPLINE (((~7UL & (unsigned long)(*width + 7)) / 8));
765 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
769 XpmFreeXpmImage (&xpmimage);
770 XpmFreeXpmInfo (&xpminfo);
774 /* build a color table to speed things up */
775 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
779 XpmFreeXpmImage (&xpmimage);
780 XpmFreeXpmInfo (&xpminfo);
784 for (i=0; i<xpmimage.ncolors; i++)
787 /* pick up symbolic colors in preference */
788 if (xpmimage.colorTable[i].symbolic)
790 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
792 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
795 colortbl[i]=transparent_color;
797 goto label_found_color;
799 else if (color_symbols)
801 for (j = 0; j<nsymbols; j++)
803 if (!strcmp (xpmimage.colorTable[i].symbolic,
804 color_symbols[j].name ))
806 colortbl[i]=color_symbols[j].color;
807 goto label_found_color;
811 else if (xpmimage.colorTable[i].c_color == 0)
816 /* pick up transparencies */
817 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
820 colortbl[i]=transparent_color;
822 goto label_found_color;
824 /* finally pick up a normal color spec */
825 if (xpmimage.colorTable[i].c_color)
828 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
829 goto label_found_color;
835 XpmFreeXpmImage (&xpmimage);
836 XpmFreeXpmInfo (&xpminfo);
842 /* convert the image */
845 for (i = 0; i< *width * *height; i++)
847 color = colortbl[*sptr++];
849 /* split out the 0x02bbggrr colorref into an rgb triple */
850 *dptr++=GetRValue (color); /* red */
851 *dptr++=GetGValue (color); /* green */
852 *dptr++=GetBValue (color); /* blue */
855 *x_hot=xpminfo.x_hotspot;
856 *y_hot=xpminfo.y_hotspot;
858 XpmFreeXpmImage (&xpmimage);
859 XpmFreeXpmInfo (&xpminfo);
865 mswindows_xpm_instantiate (Lisp_Object image_instance,
866 Lisp_Object instantiator,
867 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
868 int dest_mask, Lisp_Object domain)
870 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
871 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
872 CONST Extbyte *bytes;
874 unsigned char *eimage;
875 int width, height, x_hot, y_hot;
876 BITMAPINFO* bmp_info;
877 unsigned char* bmp_data;
879 int nsymbols=0, transp;
880 struct color_symbol* color_symbols=NULL;
882 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
883 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
886 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
887 signal_simple_error ("Not an mswindows device", device);
889 assert (!NILP (data));
891 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
893 /* in case we have color symbols */
894 color_symbols = extract_xpm_color_names (device, domain,
895 color_symbol_alist, &nsymbols);
897 /* convert to an eimage to make processing easier */
898 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
899 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
901 signal_simple_error ("XPM to EImage conversion failed",
909 xfree (color_symbols[nsymbols].name);
911 xfree(color_symbols);
914 /* build a bitmap from the eimage */
915 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
916 &bmp_bits, &bmp_data)))
918 signal_simple_error ("XPM to EImage conversion failed",
923 /* Now create the pixmap and set up the image instance */
924 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
925 bmp_data, bmp_bits, instantiator,
926 x_hot, y_hot, transp);
931 #endif /* HAVE_XPM */
933 /**********************************************************************
935 **********************************************************************/
938 bmp_validate (Lisp_Object instantiator)
940 file_or_data_must_be_present (instantiator);
944 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
946 return simple_image_type_normalize (inst, console_type, Qbmp);
950 bmp_possible_dest_types (void)
952 return IMAGE_COLOR_PIXMAP_MASK;
956 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
957 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
958 int dest_mask, Lisp_Object domain)
960 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
961 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
962 CONST Extbyte *bytes;
964 BITMAPFILEHEADER* bmp_file_header;
965 BITMAPINFO* bmp_info;
968 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
970 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
971 signal_simple_error ("Not an mswindows device", device);
973 assert (!NILP (data));
975 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
977 /* Then slurp the image into memory, decoding along the way.
978 The result is the image in a simple one-byte-per-pixel
981 bmp_file_header=(BITMAPFILEHEADER*)bytes;
982 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
983 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
984 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
986 /* Now create the pixmap and set up the image instance */
987 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
988 bmp_data, bmp_bits, instantiator,
993 /**********************************************************************
995 **********************************************************************/
998 mswindows_resource_validate (Lisp_Object instantiator)
1000 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
1002 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
1004 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
1005 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
1010 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type)
1012 /* This function can call lisp */
1013 Lisp_Object file = Qnil;
1014 struct gcpro gcpro1, gcpro2;
1015 Lisp_Object alist = Qnil;
1017 GCPRO2 (file, alist);
1019 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1022 if (CONSP (file)) /* failure locating filename */
1023 signal_double_file_error ("Opening pixmap file",
1024 "no such file or directory",
1027 if (NILP (file)) /* no conversion necessary */
1028 RETURN_UNGCPRO (inst);
1030 alist = tagged_vector_to_alist (inst);
1033 alist = remassq_no_quit (Q_file, alist);
1034 alist = Fcons (Fcons (Q_file, file), alist);
1038 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
1040 RETURN_UNGCPRO (result);
1045 mswindows_resource_possible_dest_types (void)
1047 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1057 #define OCR_ICOCUR 32647
1058 #define OIC_SAMPLE 32512
1059 #define OIC_HAND 32513
1060 #define OIC_QUES 32514
1061 #define OIC_BANG 32515
1062 #define OIC_NOTE 32516
1063 #define OIC_WINLOGO 32517
1064 #define LR_SHARED 0x8000
1067 static CONST resource_t bitmap_table[] =
1070 { "close", OBM_CLOSE },
1071 { "uparrow", OBM_UPARROW },
1072 { "dnarrow", OBM_DNARROW },
1073 { "rgarrow", OBM_RGARROW },
1074 { "lfarrow", OBM_LFARROW },
1075 { "reduce", OBM_REDUCE },
1076 { "zoom", OBM_ZOOM },
1077 { "restore", OBM_RESTORE },
1078 { "reduced", OBM_REDUCED },
1079 { "zoomd", OBM_ZOOMD },
1080 { "restored", OBM_RESTORED },
1081 { "uparrowd", OBM_UPARROWD },
1082 { "dnarrowd", OBM_DNARROWD },
1083 { "rgarrowd", OBM_RGARROWD },
1084 { "lfarrowd", OBM_LFARROWD },
1085 { "mnarrow", OBM_MNARROW },
1086 { "combo", OBM_COMBO },
1087 { "uparrowi", OBM_UPARROWI },
1088 { "dnarrowi", OBM_DNARROWI },
1089 { "rgarrowi", OBM_RGARROWI },
1090 { "lfarrowi", OBM_LFARROWI },
1091 { "size", OBM_SIZE },
1092 { "btsize", OBM_BTSIZE },
1093 { "check", OBM_CHECK },
1094 { "checkboxes", OBM_CHECKBOXES },
1095 { "btncorners" , OBM_BTNCORNERS },
1099 static CONST resource_t cursor_table[] =
1102 { "normal", OCR_NORMAL },
1103 { "ibeam", OCR_IBEAM },
1104 { "wait", OCR_WAIT },
1105 { "cross", OCR_CROSS },
1107 /* { "icon", OCR_ICON }, */
1108 { "sizenwse", OCR_SIZENWSE },
1109 { "sizenesw", OCR_SIZENESW },
1110 { "sizewe", OCR_SIZEWE },
1111 { "sizens", OCR_SIZENS },
1112 { "sizeall", OCR_SIZEALL },
1113 /* { "icour", OCR_ICOCUR }, */
1118 static CONST resource_t icon_table[] =
1121 { "sample", OIC_SAMPLE },
1122 { "hand", OIC_HAND },
1123 { "ques", OIC_QUES },
1124 { "bang", OIC_BANG },
1125 { "note", OIC_NOTE },
1126 { "winlogo", OIC_WINLOGO },
1130 static int resource_name_to_resource (Lisp_Object name, int type)
1132 CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1133 : type == IMAGE_ICON ? icon_table
1140 else if (!STRINGP (name))
1142 signal_simple_error ("invalid resource identifier", name);
1147 GET_C_STRING_OS_DATA_ALLOCA (name, nm);
1148 if (!strcasecmp ((char*)res->name, nm))
1149 return res->resource_id;
1150 } while ((++res)->name);
1155 resource_symbol_to_type (Lisp_Object data)
1157 if (EQ (data, Qcursor))
1158 return IMAGE_CURSOR;
1159 else if (EQ (data, Qicon))
1161 else if (EQ (data, Qbitmap))
1162 return IMAGE_BITMAP;
1168 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1169 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1170 int dest_mask, Lisp_Object domain)
1172 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1173 unsigned int type = 0;
1174 HANDLE himage = NULL;
1176 HINSTANCE hinst = NULL;
1180 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1182 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1183 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1185 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1190 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1191 signal_simple_error ("Not an mswindows device", device);
1193 type = resource_symbol_to_type (resource_type);
1195 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1196 iitype = IMAGE_POINTER;
1197 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1198 iitype = IMAGE_COLOR_PIXMAP;
1200 incompatible_image_types (instantiator, dest_mask,
1201 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1203 /* mess with the keyword info we were provided with */
1207 GET_C_STRING_FILENAME_DATA_ALLOCA (file, f);
1209 CYGWIN_WIN32_PATH (f, fname);
1214 if (NILP (resource_id))
1215 resid = (LPCTSTR)fname;
1218 hinst = LoadLibraryEx (fname, NULL,
1219 LOAD_LIBRARY_AS_DATAFILE);
1220 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1224 GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid);
1227 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1229 signal_simple_error ("Invalid resource identifier", resource_id);
1231 /* load the image */
1232 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
1233 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1235 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1237 signal_simple_error ("Cannot load image", instantiator);
1241 FreeLibrary (hinst);
1243 mswindows_initialize_dibitmap_image_instance (ii, iitype);
1245 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1246 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
1247 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1248 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
1249 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1250 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1252 /* hey, we've got an icon type thing so we can reverse engineer the
1254 if (type != IMAGE_BITMAP)
1256 GetIconInfo (himage, &iconinfo);
1257 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1258 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1259 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1260 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1261 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
1265 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1266 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
1267 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1268 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1269 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1274 check_valid_resource_symbol (Lisp_Object data)
1276 CHECK_SYMBOL (data);
1277 if (!resource_symbol_to_type (data))
1278 signal_simple_error ("invalid resource type", data);
1282 check_valid_resource_id (Lisp_Object data)
1284 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1286 !resource_name_to_resource (data, IMAGE_ICON)
1288 !resource_name_to_resource (data, IMAGE_BITMAP))
1289 signal_simple_error ("invalid resource identifier", data);
1293 check_valid_string_or_int (Lisp_Object data)
1296 CHECK_STRING (data);
1301 /**********************************************************************
1303 **********************************************************************/
1304 #ifndef HAVE_X_WINDOWS
1305 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1309 Copyright (c) 1988 X Consortium
1311 Permission is hereby granted, free of charge, to any person obtaining a copy
1312 of this software and associated documentation files (the "Software"), to deal
1313 in the Software without restriction, including without limitation the rights
1314 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1315 copies of the Software, and to permit persons to whom the Software is
1316 furnished to do so, subject to the following conditions:
1318 The above copyright notice and this permission notice shall be included in
1319 all copies or substantial portions of the Software.
1321 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1322 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1323 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1324 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1325 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1326 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1328 Except as contained in this notice, the name of the X Consortium shall not be
1329 used in advertising or otherwise to promote the sale, use or other dealings
1330 in this Software without prior written authorization from the X Consortium.
1335 * This file contains miscellaneous utility routines and is not part of the
1338 * Public entry points:
1340 * XmuReadBitmapData read data from FILE descriptor
1341 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1344 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1345 * that way (but don't use common source code so that people can have one
1346 * without the other).
1351 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1353 #ifndef BitmapSuccess
1354 #define BitmapSuccess 0
1355 #define BitmapOpenFailed 1
1356 #define BitmapFileInvalid 2
1357 #define BitmapNoMemory 3
1359 #define MAX_SIZE 255
1361 /* shared data for the image read/parse logic */
1362 static short hexTable[256]; /* conversion value */
1363 static int initialized = FALSE; /* easier to fill in at run time */
1366 * Table index for the hex values. Initialized once, first time.
1367 * Used for translation value or delimiter significance lookup.
1369 static void initHexTable()
1372 * We build the table at run time for several reasons:
1374 * 1. portable to non-ASCII machines.
1375 * 2. still reentrant since we set the init flag after setting table.
1376 * 3. easier to extend.
1377 * 4. less prone to bugs.
1379 hexTable['0'] = 0; hexTable['1'] = 1;
1380 hexTable['2'] = 2; hexTable['3'] = 3;
1381 hexTable['4'] = 4; hexTable['5'] = 5;
1382 hexTable['6'] = 6; hexTable['7'] = 7;
1383 hexTable['8'] = 8; hexTable['9'] = 9;
1384 hexTable['A'] = 10; hexTable['B'] = 11;
1385 hexTable['C'] = 12; hexTable['D'] = 13;
1386 hexTable['E'] = 14; hexTable['F'] = 15;
1387 hexTable['a'] = 10; hexTable['b'] = 11;
1388 hexTable['c'] = 12; hexTable['d'] = 13;
1389 hexTable['e'] = 14; hexTable['f'] = 15;
1391 /* delimiters of significance are flagged w/ negative value */
1392 hexTable[' '] = -1; hexTable[','] = -1;
1393 hexTable['}'] = -1; hexTable['\n'] = -1;
1394 hexTable['\t'] = -1;
1400 * read next hex value in the input stream, return -1 if EOF
1402 static int NextInt ( FILE *fstream )
1409 /* loop, accumulate hex value until find delimiter */
1410 /* skip any initial delimiters found in read stream */
1418 /* trim high bits, check type and accumulate */
1420 if (isascii(ch) && isxdigit(ch)) {
1421 value = (value << 4) + hexTable[ch];
1423 } else if ((hexTable[ch]) < 0 && gotone)
1432 * The data returned by the following routine is always in left-most byte
1433 * first and left-most bit first. If it doesn't return BitmapSuccess then
1434 * its arguments won't have been touched. This routine should look as much
1435 * like the Xlib routine XReadBitmapfile as possible.
1437 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
1438 FILE *fstream; /* handle on file */
1439 unsigned int *width, *height; /* RETURNED */
1440 unsigned char **datap; /* RETURNED */
1441 int *x_hot, *y_hot; /* RETURNED */
1443 unsigned char *data = NULL; /* working variable */
1444 char line[MAX_SIZE]; /* input line from file */
1445 int size; /* number of bytes of data */
1446 char name_and_type[MAX_SIZE]; /* an input line */
1447 char *type; /* for parsing */
1448 int value; /* from an input line */
1449 int version10p; /* boolean, old format */
1450 int padding; /* to handle alignment */
1451 int bytes_per_line; /* per scanline of data */
1452 unsigned int ww = 0; /* width */
1453 unsigned int hh = 0; /* height */
1454 int hx = -1; /* x hotspot */
1455 int hy = -1; /* y hotspot */
1457 #define Xmalloc(size) malloc(size)
1459 /* first time initialization */
1460 if (initialized == FALSE) initHexTable();
1462 /* error cleanup and return macro */
1463 #define RETURN(code) { if (data) free (data); return code; }
1465 while (fgets(line, MAX_SIZE, fstream)) {
1466 if (strlen(line) == MAX_SIZE-1) {
1467 RETURN (BitmapFileInvalid);
1469 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1470 if (!(type = strrchr(name_and_type, '_')))
1471 type = name_and_type;
1475 if (!strcmp("width", type))
1476 ww = (unsigned int) value;
1477 if (!strcmp("height", type))
1478 hh = (unsigned int) value;
1479 if (!strcmp("hot", type)) {
1480 if (type-- == name_and_type || type-- == name_and_type)
1482 if (!strcmp("x_hot", type))
1484 if (!strcmp("y_hot", type))
1490 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1492 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1494 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1499 if (!(type = strrchr(name_and_type, '_')))
1500 type = name_and_type;
1504 if (strcmp("bits[]", type))
1508 RETURN (BitmapFileInvalid);
1510 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1515 bytes_per_line = (ww+7)/8 + padding;
1517 size = bytes_per_line * hh;
1518 data = (unsigned char *) Xmalloc ((unsigned int) size);
1520 RETURN (BitmapNoMemory);
1526 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1527 if ((value = NextInt(fstream)) < 0)
1528 RETURN (BitmapFileInvalid);
1530 if (!padding || ((bytes+2) % bytes_per_line))
1531 *(ptr++) = value >> 8;
1537 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1538 if ((value = NextInt(fstream)) < 0)
1539 RETURN (BitmapFileInvalid);
1547 RETURN (BitmapFileInvalid);
1554 if (x_hot) *x_hot = hx;
1555 if (y_hot) *y_hot = hy;
1557 RETURN (BitmapSuccess);
1561 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
1562 unsigned int *height, unsigned char **datap,
1563 int *x_hot, int *y_hot)
1568 if ((fstream = fopen (filename, "r")) == NULL) {
1569 return BitmapOpenFailed;
1571 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1575 #endif /* HAVE_X_WINDOWS */
1577 /* this table flips four bits around. */
1578 static int flip_table[] =
1580 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1583 /* the bitmap data comes in the following format: Widths are padded to
1584 a multiple of 8. Scan lines are stored in increasing byte order
1585 from left to right, little-endian within a byte. 0 = white, 1 =
1586 black. It must be converted to the following format: Widths are
1587 padded to a multiple of 16. Scan lines are stored in increasing
1588 byte order from left to right, big-endian within a byte. 0 =
1589 black, 1 = white. */
1591 xbm_create_bitmap_from_data (HDC hdc, char *data,
1592 unsigned int width, unsigned int height,
1593 int mask, COLORREF fg, COLORREF bg)
1595 int old_width = (width + 7)/8;
1596 int new_width = BPLINE (2*((width + 15)/16));
1597 unsigned char *offset;
1599 unsigned char *new_data, *new_offset;
1601 BITMAPINFO* bmp_info =
1602 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1608 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
1616 for (i=0; i<height; i++)
1618 offset = data + i*old_width;
1619 new_offset = new_data + i*new_width;
1621 for (j=0; j<old_width; j++)
1623 int byte = offset[j];
1624 new_offset[j] = ~ (unsigned char)
1625 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1629 /* if we want a mask invert the bits */
1632 new_offset = &new_data[height * new_width];
1633 while (new_offset-- != new_data)
1635 *new_offset ^= 0xff;
1639 bmp_info->bmiHeader.biWidth=width;
1640 bmp_info->bmiHeader.biHeight=-(LONG)height;
1641 bmp_info->bmiHeader.biPlanes=1;
1642 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1643 bmp_info->bmiHeader.biBitCount=1;
1644 bmp_info->bmiHeader.biCompression=BI_RGB;
1645 bmp_info->bmiHeader.biClrUsed = 2;
1646 bmp_info->bmiHeader.biClrImportant = 2;
1647 bmp_info->bmiHeader.biSizeImage = height * new_width;
1648 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1649 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1650 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1651 bmp_info->bmiColors[0].rgbReserved = 0;
1652 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1653 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1654 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1655 bmp_info->bmiColors[1].rgbReserved = 0;
1657 bitmap = CreateDIBSection (hdc,
1665 if (!bitmap || !bmp_buf)
1671 /* copy in the actual bitmap */
1672 memcpy (bmp_buf, new_data, height * new_width);
1678 /* Given inline data for a mono pixmap, initialize the given
1679 image instance accordingly. */
1682 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
1683 int width, int height,
1684 /* Note that data is in ext-format! */
1686 Lisp_Object instantiator,
1687 Lisp_Object pointer_fg,
1688 Lisp_Object pointer_bg,
1691 Lisp_Object mask_filename)
1693 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1694 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device)));
1695 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1696 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1697 enum image_instance_type type;
1698 COLORREF black = PALETTERGB (0,0,0);
1699 COLORREF white = PALETTERGB (255,255,255);
1701 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1703 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1704 signal_simple_error ("Not an MS-Windows device", device);
1706 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1707 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1709 if (!NILP (foreground) || !NILP (background))
1710 type = IMAGE_COLOR_PIXMAP;
1712 type = IMAGE_MONO_PIXMAP;
1714 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1715 type = IMAGE_MONO_PIXMAP;
1716 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1717 type = IMAGE_COLOR_PIXMAP;
1718 else if (dest_mask & IMAGE_POINTER_MASK)
1719 type = IMAGE_POINTER;
1721 incompatible_image_types (instantiator, dest_mask,
1722 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1723 | IMAGE_POINTER_MASK);
1725 mswindows_initialize_dibitmap_image_instance (ii, type);
1727 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1728 find_keyword_in_vector (instantiator, Q_file);
1729 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
1730 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
1731 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1732 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1733 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1734 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1735 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1736 TRUE, black, white);
1740 case IMAGE_MONO_PIXMAP:
1741 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1742 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1743 FALSE, black, black);
1746 case IMAGE_COLOR_PIXMAP:
1748 COLORREF fg = black;
1749 COLORREF bg = white;
1751 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1753 Fmake_color_instance (foreground, device,
1754 encode_error_behavior_flag (ERROR_ME));
1756 if (COLOR_INSTANCEP (foreground))
1757 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1759 if (!NILP (background) && !COLOR_INSTANCEP (background))
1761 Fmake_color_instance (background, device,
1762 encode_error_behavior_flag (ERROR_ME));
1764 if (COLOR_INSTANCEP (background))
1765 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1767 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1768 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1770 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1771 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1778 COLORREF fg = black;
1779 COLORREF bg = white;
1781 if (NILP (foreground))
1782 foreground = pointer_fg;
1783 if (NILP (background))
1784 background = pointer_bg;
1786 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1787 find_keyword_in_vector (instantiator, Q_hotspot_x);
1788 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1789 find_keyword_in_vector (instantiator, Q_hotspot_y);
1790 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1791 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1792 if (COLOR_INSTANCEP (foreground))
1793 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1794 if (COLOR_INSTANCEP (background))
1795 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1797 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1798 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1800 mswindows_initialize_image_instance_icon (ii, TRUE);
1810 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1811 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1812 int dest_mask, int width, int height,
1813 /* Note that data is in ext-format! */
1816 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1817 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1818 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1819 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME
1820 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))));
1821 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1823 CONST char *gcc_may_you_rot_in_hell;
1825 if (!NILP (mask_data))
1827 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
1828 gcc_may_you_rot_in_hell);
1830 xbm_create_bitmap_from_data ( hdc,
1832 gcc_may_you_rot_in_hell,
1833 XINT (XCAR (mask_data)),
1834 XINT (XCAR (XCDR (mask_data))), FALSE,
1836 PALETTERGB (255,255,255));
1839 init_image_instance_from_xbm_inline (ii, width, height, bits,
1840 instantiator, pointer_fg, pointer_bg,
1841 dest_mask, mask, mask_file);
1844 /* Instantiate method for XBM's. */
1847 mswindows_xbm_instantiate (Lisp_Object image_instance,
1848 Lisp_Object instantiator,
1849 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1850 int dest_mask, Lisp_Object domain)
1852 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1853 CONST char *gcc_go_home;
1855 assert (!NILP (data));
1857 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
1860 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1861 pointer_bg, dest_mask, XINT (XCAR (data)),
1862 XINT (XCAR (XCDR (data))), gcc_go_home);
1866 /**********************************************************************
1868 **********************************************************************/
1870 /* This is about to get redefined! */
1873 /* We have to define SYSV32 so that compface.h includes string.h
1874 instead of strings.h. */
1879 #include <compface.h>
1883 /* JMP_BUF cannot be used here because if it doesn't get defined
1884 to jmp_buf we end up with a conflicting type error with the
1885 definition in compface.h */
1886 extern jmp_buf comp_env;
1890 mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1891 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1892 int dest_mask, Lisp_Object domain)
1894 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1896 char *p, *bits, *bp;
1897 CONST char * volatile emsg = 0;
1898 CONST char * volatile dstring;
1900 assert (!NILP (data));
1902 GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring);
1904 if ((p = strchr (dstring, ':')))
1909 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
1910 if (!(stattis = setjmp (comp_env)))
1912 UnCompAll ((char *) dstring);
1919 emsg = "uncompface: internal error";
1922 emsg = "uncompface: insufficient or invalid data";
1925 emsg = "uncompface: excess data ignored";
1930 signal_simple_error_2 (emsg, data, Qimage);
1932 bp = bits = (char *) alloca (PIXELS / 8);
1934 /* the compface library exports char F[], which uses a single byte per
1935 pixel to represent a 48x48 bitmap. Yuck. */
1936 for (i = 0, p = F; i < (PIXELS / 8); ++i)
1939 /* reverse the bit order of each byte... */
1940 for (b = n = 0; b < 8; ++b)
1947 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1948 pointer_bg, dest_mask, 48, 48, bits);
1950 #endif /* HAVE_XFACE */
1953 /************************************************************************/
1954 /* image instance methods */
1955 /************************************************************************/
1958 mswindows_print_image_instance (struct Lisp_Image_Instance *p,
1959 Lisp_Object printcharfun,
1964 switch (IMAGE_INSTANCE_TYPE (p))
1966 case IMAGE_MONO_PIXMAP:
1967 case IMAGE_COLOR_PIXMAP:
1969 sprintf (buf, " (0x%lx",
1970 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1971 write_c_string (buf, printcharfun);
1972 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1974 sprintf (buf, "/0x%lx",
1975 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1976 write_c_string (buf, printcharfun);
1978 write_c_string (")", printcharfun);
1987 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
1989 if (DEVICE_LIVE_P (XDEVICE (p->device)))
1991 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET
1993 IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
1995 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
1996 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
1997 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
2001 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
2002 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
2003 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
2004 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2005 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2006 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
2007 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
2008 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
2009 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2020 /************************************************************************/
2021 /* subwindow and widget support */
2022 /************************************************************************/
2024 /* unmap the image if it is a widget. This is used by redisplay via
2025 redisplay_unmap_subwindows */
2027 mswindows_unmap_subwindow (struct Lisp_Image_Instance *p)
2029 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2031 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2034 SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
2035 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2039 /* map the subwindow. This is used by redisplay via
2040 redisplay_output_subwindow */
2042 mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y)
2044 /* ShowWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), SW_SHOW);*/
2045 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2048 SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSIZE
2049 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2052 /* when you click on a widget you may activate another widget this
2053 needs to be checked and all appropriate widgets updated */
2055 mswindows_update_subwindow (struct Lisp_Image_Instance *p)
2057 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
2059 /* buttons checked or otherwise */
2060 if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton))
2062 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_SINGLE_ITEM (p)))
2063 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2064 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2066 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2067 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2072 /* register widgets into our hastable so that we can cope with the
2073 callbacks. The hashtable is weak so deregistration is handled
2076 mswindows_register_gui_item (Lisp_Object gui, Lisp_Object domain)
2078 Lisp_Object frame = FW_FRAME (domain);
2079 struct frame* f = XFRAME (frame);
2080 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f),
2083 Fputhash (make_int (id),
2084 XGUI_ITEM (gui)->callback,
2085 FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
2090 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2092 return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_SINGLE_ITEM (instance),
2097 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2098 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2099 int dest_mask, Lisp_Object domain)
2101 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2102 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2103 struct device* d = XDEVICE (device);
2104 Lisp_Object frame = FW_FRAME (domain);
2107 if (!DEVICE_MSWINDOWS_P (d))
2108 signal_simple_error ("Not an mswindows device", device);
2110 /* have to set the type this late in case there is no device
2111 instantiation for a widget */
2112 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2114 wnd = CreateWindow( "STATIC",
2117 0, /* starting x position */
2118 0, /* starting y position */
2119 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2120 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2121 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), /* parent window */
2124 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2128 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2129 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2133 mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
2134 struct Lisp_Image_Instance *p2, int depth)
2136 switch (IMAGE_INSTANCE_TYPE (p1))
2138 case IMAGE_MONO_PIXMAP:
2139 case IMAGE_COLOR_PIXMAP:
2141 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2142 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2153 static unsigned long
2154 mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
2156 switch (IMAGE_INSTANCE_TYPE (p))
2158 case IMAGE_MONO_PIXMAP:
2159 case IMAGE_COLOR_PIXMAP:
2161 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2168 /* Set all the slots in an image instance structure to reasonable
2169 default values. This is used somewhere within an instantiate
2170 method. It is assumed that the device slot within the image
2171 instance is already set -- this is the case when instantiate
2172 methods are called. */
2175 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
2176 enum image_instance_type type)
2178 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2179 IMAGE_INSTANCE_TYPE (ii) = type;
2180 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2181 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2182 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2183 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2184 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2185 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2189 /************************************************************************/
2191 /************************************************************************/
2193 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2194 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2195 int dest_mask, Lisp_Object domain,
2196 CONST char* class, int flags, int exflags)
2198 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2200 struct Lisp_Image_Instance *groupii = 0;
2201 Lisp_Object group = find_keyword_in_vector (instantiator, Q_group);
2203 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2204 struct device* d = XDEVICE (device);
2205 Lisp_Object frame = FW_FRAME (domain);
2209 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2210 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2212 if (!DEVICE_MSWINDOWS_P (d))
2213 signal_simple_error ("Not an mswindows device", device);
2215 /* if the user specified another glyph as a group pick up the
2216 instance in our domain. */
2219 if (SYMBOLP (group))
2220 group = XSYMBOL (group)->value;
2221 group = glyph_image_instance (group, domain, ERROR_ME, 1);
2222 groupii = XIMAGE_INSTANCE (group);
2225 if (!gui_item_active_p (gui))
2226 flags |= WS_DISABLED;
2228 style = pgui->style;
2230 if (!NILP (pgui->callback))
2232 id = mswindows_register_widget_instance (image_instance, domain);
2234 /* have to set the type this late in case there is no device
2235 instantiation for a widget */
2236 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
2237 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2238 GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
2240 wnd = CreateWindowEx(
2241 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2245 0, /* starting x position */
2246 0, /* starting y position */
2247 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2248 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2250 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2251 (HMENU)id, /* No menu */
2253 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2257 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2258 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2259 /* set the widget font from the widget face */
2260 SendMessage (wnd, WM_SETFONT,
2261 (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
2262 (XFONT_INSTANCE (widget_face_font_info
2264 IMAGE_INSTANCE_WIDGET_FACE (ii),
2266 MAKELPARAM (TRUE, 0));
2269 /* Instantiate a button widget. Unfortunately instantiated widgets are
2270 particular to a frame since they need to have a parent. It's not
2271 like images where you just select the image into the context you
2272 want to display it in and BitBlt it. So images instances can have a
2273 many-to-one relationship with things you see, whereas widgets can
2274 only be one-to-one (i.e. per frame) */
2276 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2277 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2278 int dest_mask, Lisp_Object domain)
2280 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2282 int flags = BS_NOTIFY;
2284 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2285 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2286 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2288 if (!gui_item_active_p (gui))
2289 flags |= WS_DISABLED;
2293 if (!IMAGE_INSTANCEP (glyph))
2294 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2296 if (IMAGE_INSTANCEP (glyph))
2297 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2298 BS_BITMAP : BS_ICON;
2301 style = pgui->style;
2303 if (EQ (style, Qradio))
2305 flags |= BS_RADIOBUTTON;
2307 else if (EQ (style, Qtoggle))
2309 flags |= BS_AUTOCHECKBOX;
2312 flags |= BS_DEFPUSHBUTTON;
2314 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2315 pointer_bg, dest_mask, domain, "BUTTON", flags,
2316 WS_EX_CONTROLPARENT);
2318 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2319 /* set the checked state */
2320 if (gui_item_selected_p (gui))
2321 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2323 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2324 /* add the image if one was given */
2325 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph))
2327 SendMessage (wnd, BM_SETIMAGE,
2328 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2329 IMAGE_BITMAP : IMAGE_ICON),
2330 (LPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2331 XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2332 XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2336 /* instantiate an edit control */
2338 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2339 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2340 int dest_mask, Lisp_Object domain)
2342 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2343 pointer_bg, dest_mask, domain, "EDIT",
2344 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2346 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2349 /* instantiate a progress gauge */
2351 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2352 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2353 int dest_mask, Lisp_Object domain)
2356 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2357 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2358 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2359 WS_TABSTOP | WS_BORDER | PBS_SMOOTH,
2360 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2361 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2362 /* set the colors */
2363 #ifdef PBS_SETBKCOLOR
2364 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2365 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2368 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2369 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2371 #ifdef PBS_SETBARCOLOR
2372 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2373 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2376 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2377 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2381 /* instantiate a tree view widget */
2382 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2383 HWND wnd, HTREEITEM parent, Lisp_Object entry,
2384 int children, Lisp_Object domain)
2386 TV_INSERTSTRUCT tvitem;
2389 tvitem.hParent = parent;
2390 tvitem.hInsertAfter = TVI_LAST;
2391 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2392 tvitem.item.cChildren = children;
2394 if (VECTORP (entry))
2396 /* we always maintain the real gui item at the head of the
2397 list. We have to put them in the list in the first place
2398 because the whole model assumes that the glyph instances have
2399 references to all the associated data. If we didn't do this
2400 GC would bite us badly. */
2401 Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
2402 if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
2405 Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
2406 Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
2410 XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
2411 Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
2414 tvitem.item.lParam = mswindows_register_gui_item (gui, domain);
2415 tvitem.item.mask |= TVIF_PARAM;
2416 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
2417 tvitem.item.pszText);
2420 GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.item.pszText);
2422 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2424 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2425 0, (LPARAM)&tvitem)) == 0)
2426 signal_simple_error ("error adding tree view entry", entry);
2431 static void add_tree_item_list (Lisp_Object image_instance,
2432 HWND wnd, HTREEITEM parent, Lisp_Object list,
2437 /* get the first item */
2438 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2439 /* recursively add items to the tree view */
2440 LIST_LOOP (rest, XCDR (list))
2442 if (LISTP (XCAR (rest)))
2443 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2445 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2450 mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2451 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2452 int dest_mask, Lisp_Object domain)
2457 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2458 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2459 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2460 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2461 | TVS_HASLINES | TVS_HASBUTTONS,
2462 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2464 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2467 parent = add_tree_item (image_instance,
2468 wnd, NULL, IMAGE_INSTANCE_WIDGET_TEXT (ii), TRUE,
2471 /* recursively add items to the tree view */
2472 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2474 if (LISTP (XCAR (rest)))
2475 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2477 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2481 /* instantiate a tab control */
2482 static TC_ITEM* add_tab_item (Lisp_Object image_instance,
2483 HWND wnd, Lisp_Object entry,
2484 Lisp_Object domain, int index)
2486 TC_ITEM tvitem, *ret;
2488 tvitem.mask = TCIF_TEXT;
2490 if (VECTORP (entry))
2492 /* we always maintain the real gui item at the head of the
2493 list. We have to put them in the list in the first place
2494 because the whole model assumes that the glyph instances have
2495 references to all the associated data. If we didn't do this
2496 GC would bite us badly. */
2497 Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
2498 if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
2501 Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
2502 Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
2506 XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
2507 Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
2510 tvitem.lParam = mswindows_register_gui_item (gui, domain);
2511 tvitem.mask |= TCIF_PARAM;
2512 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
2516 GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.pszText);
2518 tvitem.cchTextMax = strlen (tvitem.pszText);
2520 if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
2521 index, (LPARAM)&tvitem)) < 0)
2522 signal_simple_error ("error adding tab entry", entry);
2528 mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2529 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2530 int dest_mask, Lisp_Object domain)
2535 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2536 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2537 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2538 /* borders don't suit tabs so well */
2540 WS_EX_CONTROLPARENT);
2542 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2544 /* add items to the tab */
2545 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2547 add_tab_item (image_instance, wnd, XCAR (rest), domain, index);
2552 /* instantiate a static control possible for putting other things in */
2554 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2555 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2556 int dest_mask, Lisp_Object domain)
2558 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2559 pointer_bg, dest_mask, domain, "STATIC",
2560 0, WS_EX_STATICEDGE);
2564 /* instantiate a static control possible for putting other things in */
2566 mswindows_group_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2567 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2568 int dest_mask, Lisp_Object domain)
2570 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2571 pointer_bg, dest_mask, domain, "BUTTON",
2572 WS_GROUP | BS_GROUPBOX | WS_BORDER,
2577 /* instantiate a scrollbar control */
2579 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2580 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2581 int dest_mask, Lisp_Object domain)
2583 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2584 pointer_bg, dest_mask, domain, "SCROLLBAR",
2589 /* instantiate a combo control */
2591 mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2592 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2593 int dest_mask, Lisp_Object domain)
2595 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2599 /* Maybe ought to generalise this more but it may be very windows
2600 specific. In windows the window height of a combo box is the
2601 height when the combo box is open. Thus we need to set the height
2602 before creating the window and then reset it to a single line
2603 after the window is created so that redisplay does the right
2605 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2606 pointer_bg, dest_mask, domain, "COMBOBOX",
2607 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
2609 | CBS_HASSTRINGS | WS_VSCROLL,
2610 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2611 /* reset the height */
2612 widget_text_to_pixel_conversion (domain,
2613 IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0,
2614 &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0);
2615 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2616 /* add items to the combo box */
2617 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
2618 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2621 GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam);
2622 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
2623 signal_simple_error ("error adding combo entries", instantiator);
2627 /* get properties of a control */
2629 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
2631 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2632 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2633 /* get the text from a control */
2634 if (EQ (prop, Q_text))
2636 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
2637 Extbyte* buf =alloca (len+1);
2639 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
2640 return build_ext_string (buf, FORMAT_OS);
2645 /* get properties of a button */
2647 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
2649 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2650 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2651 /* check the state of a button */
2652 if (EQ (prop, Q_selected))
2654 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
2662 /* get properties of a combo box */
2664 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
2666 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2667 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2668 /* get the text from a control */
2669 if (EQ (prop, Q_text))
2671 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
2672 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
2673 Extbyte* buf = alloca (len+1);
2674 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
2675 return build_ext_string (buf, FORMAT_OS);
2680 /* set the properties of a control */
2682 mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
2685 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2687 if (EQ (prop, Q_text))
2691 GET_C_STRING_OS_DATA_ALLOCA (val, lparam);
2692 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2693 WM_SETTEXT, 0, (LPARAM)lparam);
2699 /* set the properties of a progres guage */
2701 mswindows_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop,
2704 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2706 if (EQ (prop, Q_percent))
2709 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2710 PBM_SETPOS, (WPARAM)XINT (val), 0);
2717 /************************************************************************/
2718 /* initialization */
2719 /************************************************************************/
2722 syms_of_glyphs_mswindows (void)
2724 defkeyword (&Q_resource_id, ":resource-id");
2725 defkeyword (&Q_resource_type, ":resource-type");
2729 console_type_create_glyphs_mswindows (void)
2733 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
2734 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
2735 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
2736 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
2737 CONSOLE_HAS_METHOD (mswindows, update_subwindow);
2738 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
2739 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
2740 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
2741 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
2745 image_instantiator_format_create_glyphs_mswindows (void)
2747 IIFORMAT_VALID_CONSOLE (mswindows, nothing);
2748 IIFORMAT_VALID_CONSOLE (mswindows, string);
2749 IIFORMAT_VALID_CONSOLE (mswindows, formatted_string);
2750 IIFORMAT_VALID_CONSOLE (mswindows, inherit);
2751 /* image-instantiator types */
2753 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
2754 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
2756 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
2757 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
2759 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
2760 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
2763 IIFORMAT_VALID_CONSOLE (mswindows, jpeg);
2766 IIFORMAT_VALID_CONSOLE (mswindows, tiff);
2769 IIFORMAT_VALID_CONSOLE (mswindows, png);
2772 IIFORMAT_VALID_CONSOLE (mswindows, gif);
2775 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
2776 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
2777 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
2779 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
2780 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
2782 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
2783 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
2785 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
2786 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
2787 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property);
2789 INITIALIZE_DEVICE_IIFORMAT (mswindows, group);
2790 IIFORMAT_HAS_DEVMETHOD (mswindows, group, instantiate);
2793 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
2794 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
2797 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
2798 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
2799 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
2802 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
2803 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
2805 /* progress gauge */
2806 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
2807 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, set_property);
2808 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
2810 /* tree view widget */
2811 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
2812 /* IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/
2813 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
2815 /* tab control widget */
2816 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
2817 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
2819 /* windows bitmap format */
2820 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
2821 IIFORMAT_HAS_METHOD (bmp, validate);
2822 IIFORMAT_HAS_METHOD (bmp, normalize);
2823 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
2824 IIFORMAT_HAS_METHOD (bmp, instantiate);
2826 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
2827 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
2828 IIFORMAT_VALID_CONSOLE (mswindows, bmp);
2830 /* mswindows resources */
2831 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
2832 "mswindows-resource");
2834 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
2835 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
2836 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
2837 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
2839 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
2840 check_valid_resource_symbol);
2841 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
2842 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
2843 IIFORMAT_VALID_CONSOLE (mswindows, mswindows_resource);
2847 vars_of_glyphs_mswindows (void)
2849 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
2850 A list of the directories in which mswindows bitmap files may be found.
2851 This is used by the `make-image-instance' function.
2853 Vmswindows_bitmap_file_path = Qnil;
2857 complex_vars_of_glyphs_mswindows (void)