1 /* mswindows-specific Lisp objects.
2 Copyright (C) 1998 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 <andyp@parallax.co.uk> plagerising buts from
30 #define OEMRESOURCE /* Define OCR_ and friend constants */
31 #include "console-msw.h"
32 #include "glyphs-msw.h"
33 #include "objects-msw.h"
44 #include "file-coding.h"
50 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
52 Lisp_Object Vmswindows_bitmap_file_path;
53 static COLORREF transparent_color = RGB (1,1,1);
55 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource);
56 Lisp_Object Q_resource_type, Q_resource_id;
57 Lisp_Object Qmswindows_resource;
60 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
61 enum image_instance_type type);
63 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
66 COLORREF mswindows_string_to_color (CONST char *name);
68 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
70 /************************************************************************/
71 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
73 /************************************************************************/
74 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
75 int width, int height,
78 unsigned char** bmp_data)
80 struct device *d = XDEVICE (device);
85 unsigned char *ip, *dp;
87 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
89 int bpline = BPLINE(width * 3);
90 /* FIXME: we can do this because 24bpp implies no colour table, once
91 * we start paletizing this is no longer true. The X versions of
92 * this function quantises to 256 colours or bit masks down to a
93 * long. Windows can actually handle rgb triples in the raw so I
94 * don't see much point trying to optimize down to the best
95 * structure - unless it has memory / color allocation implications
97 bmp_info=xnew_and_zero (BITMAPINFO);
104 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
105 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
106 bmp_info->bmiHeader.biSizeImage=width*height*3;
108 /* bitmap data needs to be in blue, green, red triples - in that
109 order, eimage is in RGB format so we need to convert */
110 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
111 *bit_count = bpline * height;
120 for (i = height-1; i >= 0; i--) {
121 dp = (*bmp_data) + (i * bpline);
122 for (j = 0; j < width; j++) {
130 else /* scale to 256 colors */
134 int bpline = BPLINE (width * 3);
135 /* Quantize the image and get a histogram while we're at it.
136 Do this first to save memory */
137 qtable = build_EImage_quantable(pic, width, height, 256);
138 if (qtable == NULL) return NULL;
140 /* use our quantize table to allocate the colors */
141 ncolors = qtable->num_active_colors;
142 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
143 sizeof(RGBQUAD) * ncolors);
150 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
152 bmp_info->bmiHeader.biBitCount=8;
153 bmp_info->bmiHeader.biCompression=BI_RGB;
154 bmp_info->bmiHeader.biSizeImage=bpline*height;
155 bmp_info->bmiHeader.biClrUsed=ncolors;
156 bmp_info->bmiHeader.biClrImportant=ncolors;
158 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
159 *bit_count = bpline * height;
168 /* build up an RGBQUAD colortable */
169 for (i = 0; i < qtable->num_active_colors; i++) {
170 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
171 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
172 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
173 colortbl[i].rgbReserved = 0;
176 /* now build up the data. picture has to be upside-down and
177 back-to-front for msw bitmaps */
179 for (i = height-1; i >= 0; i--) {
180 dp = (*bmp_data) + (i * bpline);
181 for (j = 0; j < width; j++) {
185 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
190 /* fix up the standard stuff */
191 bmp_info->bmiHeader.biWidth=width;
192 bmp_info->bmiHeader.biHeight=height;
193 bmp_info->bmiHeader.biPlanes=1;
194 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
195 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
196 bmp_info->bmiHeader.biYPelsPerMeter=0;
201 /* Given a pixmap filename, look through all of the "standard" places
202 where the file might be located. Return a full pathname if found;
203 otherwise, return Qnil. */
206 mswindows_locate_pixmap_file (Lisp_Object name)
208 /* This function can GC if IN_REDISPLAY is false */
211 /* Check non-absolute pathnames with a directory component relative to
212 the search path; that's the way Xt does it. */
213 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
214 (XSTRING_BYTE (name, 0) == '.' &&
215 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
216 (XSTRING_BYTE (name, 1) == '.' &&
217 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
219 if (!NILP (Ffile_readable_p (name)))
225 if (locate_file (Vmswindows_bitmap_file_path, name, "", &found, R_OK) < 0)
227 Lisp_Object temp = list1 (Vdata_directory);
231 locate_file (temp, name, "", &found, R_OK);
239 /* Initialize an image instance from a bitmap
241 DEST_MASK specifies the mask of allowed image types.
243 If this fails, signal an error. INSTANTIATOR is only used
244 in the error message. */
247 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
248 BITMAPINFO *bmp_info,
252 Lisp_Object instantiator,
253 int x_hot, int y_hot,
256 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
257 struct device *d = XDEVICE (device);
264 if (!DEVICE_MSWINDOWS_P (d))
265 signal_simple_error ("Not an mswindows device", device);
267 if (NILP (DEVICE_SELECTED_FRAME (d)))
268 signal_simple_error ("No selected frame on mswindows device", device);
270 f = XFRAME (DEVICE_SELECTED_FRAME (d));
272 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
273 type = IMAGE_COLOR_PIXMAP;
274 else if (dest_mask & IMAGE_POINTER_MASK)
275 type = IMAGE_POINTER;
277 incompatible_image_types (instantiator, dest_mask,
278 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
279 hdc = FRAME_MSWINDOWS_CDC (f);
281 bitmap=CreateDIBSection (hdc,
287 if (!bitmap || !bmp_buf)
288 signal_simple_error ("Unable to create bitmap", instantiator);
290 /* copy in the actual bitmap */
291 memcpy (bmp_buf, bmp_data, bmp_bits);
293 mswindows_initialize_dibitmap_image_instance (ii, type);
295 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
296 find_keyword_in_vector (instantiator, Q_file);
298 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
299 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
300 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
301 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
302 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
303 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
304 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
308 mswindows_initialize_image_instance_mask (ii, f);
311 if (type == IMAGE_POINTER)
313 mswindows_initialize_image_instance_icon(ii, TRUE);
318 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
319 int width, int height,
320 unsigned char *eimage,
322 Lisp_Object instantiator,
325 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
326 BITMAPINFO* bmp_info;
327 unsigned char* bmp_data;
331 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
332 signal_simple_error ("Not an mswindows device", device);
334 /* this is a hack but MaskBlt and TransparentBlt are not supported
335 on most windows variants */
336 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
337 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
339 /* build a bitmap from the eimage */
340 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
341 &bmp_bits, &bmp_data)))
343 signal_simple_error ("EImage to DIBitmap conversion failed",
347 /* Now create the pixmap and set up the image instance */
348 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
349 bmp_data, bmp_bits, instantiator,
356 static void set_mono_pixel ( unsigned char* bits,
357 int bpline, int height,
358 int x, int y, int white )
361 unsigned char bitnum;
362 /* Find the byte on which this scanline begins */
363 index = (height - y - 1) * bpline;
364 /* Find the byte containing this pixel */
366 /* Which bit is it? */
367 bitnum = (unsigned char)( 7 - (x % 8) );
368 if( white ) /* Turn it on */
369 bits[index] |= (1<<bitnum);
370 else /* Turn it off */
371 bits[index] &= ~(1<<bitnum);
375 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
380 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
381 unsigned char* dibits;
382 BITMAPINFO* bmp_info =
383 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
385 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
388 int maskbpline = BPLINE (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8));
389 int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
394 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
395 bmp_info->bmiHeader.biHeight = height;
396 bmp_info->bmiHeader.biPlanes=1;
397 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
398 bmp_info->bmiHeader.biBitCount=1;
399 bmp_info->bmiHeader.biCompression=BI_RGB;
400 bmp_info->bmiHeader.biClrUsed = 2;
401 bmp_info->bmiHeader.biClrImportant = 2;
402 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
403 bmp_info->bmiColors[0].rgbRed = 0;
404 bmp_info->bmiColors[0].rgbGreen = 0;
405 bmp_info->bmiColors[0].rgbBlue = 0;
406 bmp_info->bmiColors[0].rgbReserved = 0;
407 bmp_info->bmiColors[1].rgbRed = 255;
408 bmp_info->bmiColors[1].rgbGreen = 255;
409 bmp_info->bmiColors[1].rgbBlue = 255;
410 bmp_info->bmiColors[0].rgbReserved = 0;
412 if (!(mask = CreateDIBSection (hcdc,
422 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
423 /* build up an in-memory set of bits to mess with */
426 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
427 bmp_info->bmiHeader.biHeight = -height;
428 bmp_info->bmiHeader.biPlanes=1;
429 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
430 bmp_info->bmiHeader.biBitCount=24;
431 bmp_info->bmiHeader.biCompression=BI_RGB;
432 bmp_info->bmiHeader.biClrUsed = 0;
433 bmp_info->bmiHeader.biClrImportant = 0;
434 bmp_info->bmiHeader.biSizeImage = height * bpline;
436 dibits = xmalloc_and_zero (bpline * height);
438 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
443 DIB_RGB_COLORS) <= 0)
449 /* now set the colored bits in the mask and transparent ones to
450 black in the original */
451 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
453 for(j=0; j<height; j++)
455 unsigned char* idx = &dibits[j * bpline + i * 3];
457 if( RGB (idx[2], idx[1], idx[0]) == transparent_color )
459 idx[0] = idx[1] = idx[2] = 0;
460 set_mono_pixel( and_bits, maskbpline, height, i, j, TRUE );
464 set_mono_pixel( and_bits, maskbpline, height, i, j, FALSE );
470 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
480 SelectObject(hcdc, old);
482 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
486 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
491 /* we rely on windows to do any resizing necessary */
492 x_icon.fIcon=cursor ? FALSE : TRUE;
493 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
494 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
495 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
496 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
498 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
499 CreateIconIndirect (&x_icon);
503 mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
509 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
510 HDC hdcDst = CreateCompatibleDC (hcdc);
512 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
514 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
516 old2 = SelectObject (hdcDst, newbmp);
518 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
520 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
521 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
527 SelectObject (hdcDst, old2);
528 SelectObject (hcdc, old1);
535 mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
539 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
543 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
544 HDC hdcDst = CreateCompatibleDC (hcdc);
546 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
547 newmask = CreateCompatibleBitmap(hcdc, newx, newy);
548 old2 = SelectObject (hdcDst, newmask);
550 if (!StretchBlt(hdcDst, 0, 0, newx, newy,
552 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
553 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
559 SelectObject (hdcDst, old2);
560 SelectObject (hcdc, old1);
571 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
575 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
576 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
581 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
582 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
583 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
584 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
586 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
587 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
588 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
589 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
594 /**********************************************************************
596 **********************************************************************/
606 static struct color_symbol*
607 extract_xpm_color_names (Lisp_Object device,
609 Lisp_Object color_symbol_alist,
612 /* This function can GC */
614 Lisp_Object results = Qnil;
616 struct color_symbol *colortbl;
617 struct gcpro gcpro1, gcpro2;
619 GCPRO2 (results, device);
621 /* We built up results to be (("name" . #<color>) ...) so that if an
622 error happens we don't lose any malloc()ed data, or more importantly,
623 leave any pixels allocated in the server. */
625 LIST_LOOP (rest, color_symbol_alist)
627 Lisp_Object cons = XCAR (rest);
628 Lisp_Object name = XCAR (cons);
629 Lisp_Object value = XCDR (cons);
635 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
638 assert (COLOR_SPECIFIERP (value));
639 value = Fspecifier_instance (value, domain, Qnil, Qnil);
643 results = noseeum_cons (noseeum_cons (name, value), results);
646 UNGCPRO; /* no more evaluation */
649 if (i == 0) return 0;
651 colortbl = xnew_array_and_zero (struct color_symbol, i);
655 Lisp_Object cons = XCAR (results);
657 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
659 colortbl[j].name = (char *) XSTRING_DATA (XCAR (cons));
660 free_cons (XCONS (cons));
662 results = XCDR (results);
663 free_cons (XCONS (cons));
668 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
669 unsigned char** data,
670 int* width, int* height,
671 int* x_hot, int* y_hot,
673 struct color_symbol* color_symbols,
678 int result, i, j, transp_idx, maskbpline;
681 COLORREF color; /* the american spelling virus hits again .. */
686 xpminfo.valuemask=XpmHotspot;
689 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
698 signal_simple_error ("invalid XPM data", image);
702 signal_double_file_error ("Parsing pixmap data",
703 "out of memory", image);
707 signal_double_file_error_2 ("Parsing pixmap data",
708 "unknown error code",
709 make_int (result), image);
713 *width = xpmimage.width;
714 *height = xpmimage.height;
715 maskbpline = BPLINE (((~7UL & (unsigned long)(*width + 7)) / 8));
717 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
721 XpmFreeXpmImage (&xpmimage);
722 XpmFreeXpmInfo (&xpminfo);
726 /* build a color table to speed things up */
727 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
731 XpmFreeXpmImage (&xpmimage);
732 XpmFreeXpmInfo (&xpminfo);
736 for (i=0; i<xpmimage.ncolors; i++)
739 /* pick up symbolic colors in preference */
740 if (xpmimage.colorTable[i].symbolic)
742 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
744 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
747 colortbl[i]=transparent_color;
749 goto label_found_color;
751 else if (color_symbols)
753 for (j = 0; j<nsymbols; j++)
755 if (!strcmp (xpmimage.colorTable[i].symbolic,
756 color_symbols[j].name ))
758 colortbl[i]=color_symbols[j].color;
759 goto label_found_color;
763 else if (xpmimage.colorTable[i].c_color == 0)
768 /* pick up transparencies */
769 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
772 colortbl[i]=transparent_color;
774 goto label_found_color;
776 /* finally pick up a normal color spec */
777 if (xpmimage.colorTable[i].c_color)
780 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
781 goto label_found_color;
787 XpmFreeXpmImage (&xpmimage);
788 XpmFreeXpmInfo (&xpminfo);
794 /* convert the image */
797 for (i = 0; i< *width * *height; i++)
799 color = colortbl[*sptr++];
801 /* split out the 0x02bbggrr colorref into an rgb triple */
802 *dptr++=GetRValue (color); /* red */
803 *dptr++=GetGValue (color); /* green */
804 *dptr++=GetBValue (color); /* blue */
807 *x_hot=xpminfo.x_hotspot;
808 *y_hot=xpminfo.y_hotspot;
810 XpmFreeXpmImage (&xpmimage);
811 XpmFreeXpmInfo (&xpminfo);
817 mswindows_xpm_instantiate (Lisp_Object image_instance,
818 Lisp_Object instantiator,
819 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
820 int dest_mask, Lisp_Object domain)
822 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
823 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
824 CONST Extbyte *bytes;
826 unsigned char *eimage;
827 int width, height, x_hot, y_hot;
828 BITMAPINFO* bmp_info;
829 unsigned char* bmp_data;
831 int nsymbols=0, transp;
832 struct color_symbol* color_symbols=NULL;
834 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
835 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
838 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
839 signal_simple_error ("Not an mswindows device", device);
841 assert (!NILP (data));
843 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
845 /* in case we have color symbols */
846 color_symbols = extract_xpm_color_names (device, domain,
847 color_symbol_alist, &nsymbols);
849 /* convert to an eimage to make processing easier */
850 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
851 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
853 signal_simple_error ("XPM to EImage conversion failed",
858 xfree(color_symbols);
860 /* build a bitmap from the eimage */
861 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
862 &bmp_bits, &bmp_data)))
864 signal_simple_error ("XPM to EImage conversion failed",
869 /* Now create the pixmap and set up the image instance */
870 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
871 bmp_data, bmp_bits, instantiator,
872 x_hot, y_hot, transp);
877 #endif /* HAVE_XPM */
879 /**********************************************************************
881 **********************************************************************/
884 bmp_validate (Lisp_Object instantiator)
886 file_or_data_must_be_present (instantiator);
890 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
892 return simple_image_type_normalize (inst, console_type, Qbmp);
896 bmp_possible_dest_types (void)
898 return IMAGE_COLOR_PIXMAP_MASK;
902 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
903 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
904 int dest_mask, Lisp_Object domain)
906 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
907 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
908 CONST Extbyte *bytes;
910 BITMAPFILEHEADER* bmp_file_header;
911 BITMAPINFO* bmp_info;
914 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
916 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
917 signal_simple_error ("Not an mswindows device", device);
919 assert (!NILP (data));
921 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
923 /* Then slurp the image into memory, decoding along the way.
924 The result is the image in a simple one-byte-per-pixel
927 bmp_file_header=(BITMAPFILEHEADER*)bytes;
928 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
929 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
930 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
932 /* Now create the pixmap and set up the image instance */
933 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
934 bmp_data, bmp_bits, instantiator,
939 /**********************************************************************
941 **********************************************************************/
944 mswindows_resource_validate (Lisp_Object instantiator)
946 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
948 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
950 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
951 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
956 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type)
958 /* This function can call lisp */
959 Lisp_Object file = Qnil;
960 struct gcpro gcpro1, gcpro2;
961 Lisp_Object alist = Qnil;
963 GCPRO2 (file, alist);
965 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
968 if (CONSP (file)) /* failure locating filename */
969 signal_double_file_error ("Opening pixmap file",
970 "no such file or directory",
973 if (NILP (file)) /* no conversion necessary */
974 RETURN_UNGCPRO (inst);
976 alist = tagged_vector_to_alist (inst);
979 alist = remassq_no_quit (Q_file, alist);
980 alist = Fcons (Fcons (Q_file, file), alist);
984 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
986 RETURN_UNGCPRO (result);
991 mswindows_resource_possible_dest_types (void)
993 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1003 #define OCR_ICOCUR 32647
1004 #define OIC_SAMPLE 32512
1005 #define OIC_HAND 32513
1006 #define OIC_QUES 32514
1007 #define OIC_BANG 32515
1008 #define OIC_NOTE 32516
1009 #define OIC_WINLOGO 32517
1010 #define LR_SHARED 0x8000
1013 static CONST resource_t bitmap_table[] =
1016 { "close", OBM_CLOSE },
1017 { "uparrow", OBM_UPARROW },
1018 { "dnarrow", OBM_DNARROW },
1019 { "rgarrow", OBM_RGARROW },
1020 { "lfarrow", OBM_LFARROW },
1021 { "reduce", OBM_REDUCE },
1022 { "zoom", OBM_ZOOM },
1023 { "restore", OBM_RESTORE },
1024 { "reduced", OBM_REDUCED },
1025 { "zoomd", OBM_ZOOMD },
1026 { "restored", OBM_RESTORED },
1027 { "uparrowd", OBM_UPARROWD },
1028 { "dnarrowd", OBM_DNARROWD },
1029 { "rgarrowd", OBM_RGARROWD },
1030 { "lfarrowd", OBM_LFARROWD },
1031 { "mnarrow", OBM_MNARROW },
1032 { "combo", OBM_COMBO },
1033 { "uparrowi", OBM_UPARROWI },
1034 { "dnarrowi", OBM_DNARROWI },
1035 { "rgarrowi", OBM_RGARROWI },
1036 { "lfarrowi", OBM_LFARROWI },
1037 { "size", OBM_SIZE },
1038 { "btsize", OBM_BTSIZE },
1039 { "check", OBM_CHECK },
1040 { "cehckboxes", OBM_CHECKBOXES },
1041 { "btncorners" , OBM_BTNCORNERS },
1045 static CONST resource_t cursor_table[] =
1048 { "normal", OCR_NORMAL },
1049 { "ibeam", OCR_IBEAM },
1050 { "wait", OCR_WAIT },
1051 { "cross", OCR_CROSS },
1053 /* { "icon", OCR_ICON }, */
1054 { "sizenwse", OCR_SIZENWSE },
1055 { "sizenesw", OCR_SIZENESW },
1056 { "sizewe", OCR_SIZEWE },
1057 { "sizens", OCR_SIZENS },
1058 { "sizeall", OCR_SIZEALL },
1059 /* { "icour", OCR_ICOCUR }, */
1064 static CONST resource_t icon_table[] =
1067 { "sample", OIC_SAMPLE },
1068 { "hand", OIC_HAND },
1069 { "ques", OIC_QUES },
1070 { "bang", OIC_BANG },
1071 { "note", OIC_NOTE },
1072 { "winlogo", OIC_WINLOGO },
1076 static int resource_name_to_resource (Lisp_Object name, int type)
1078 CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1079 : type == IMAGE_ICON ? icon_table
1086 else if (!STRINGP (name))
1088 signal_simple_error ("invalid resource identifier", name);
1092 if (!strcasecmp ((char*)res->name, XSTRING_DATA (name)))
1093 return res->resource_id;
1094 } while ((++res)->name);
1099 resource_symbol_to_type (Lisp_Object data)
1101 if (EQ (data, Qcursor))
1102 return IMAGE_CURSOR;
1103 else if (EQ (data, Qicon))
1105 else if (EQ (data, Qbitmap))
1106 return IMAGE_BITMAP;
1112 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1113 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1114 int dest_mask, Lisp_Object domain)
1116 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1117 unsigned int type = 0;
1118 HANDLE himage = NULL;
1120 HINSTANCE hinst = NULL;
1124 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1126 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1127 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1129 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1134 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1135 signal_simple_error ("Not an mswindows device", device);
1137 type = resource_symbol_to_type (resource_type);
1139 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1140 iitype = IMAGE_POINTER;
1141 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1142 iitype = IMAGE_COLOR_PIXMAP;
1144 incompatible_image_types (instantiator, dest_mask,
1145 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1147 /* mess with the keyword info we were provided with */
1151 CYGWIN_WIN32_PATH (XSTRING_DATA (file), fname);
1153 /* #### FIXME someone who knows ... */
1154 fname = XSTRING_DATA (file);
1157 if (NILP (resource_id))
1158 resid = (LPCTSTR)fname;
1161 hinst = LoadLibraryEx (fname, NULL,
1162 LOAD_LIBRARY_AS_DATAFILE);
1163 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1167 resid = XSTRING_DATA (resource_id);
1170 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1172 signal_simple_error ("invalid resource identifier", resource_id);
1174 /* load the image */
1175 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
1176 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1178 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1180 signal_simple_error ("cannot load image", instantiator);
1184 FreeLibrary (hinst);
1186 mswindows_initialize_dibitmap_image_instance (ii, iitype);
1188 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1189 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
1190 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1191 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
1192 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1193 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1195 /* hey, we've got an icon type thing so we can reverse engineer the
1197 if (type != IMAGE_BITMAP)
1199 GetIconInfo (himage, &iconinfo);
1200 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1201 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1202 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1203 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1204 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
1208 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1209 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
1210 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1211 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1212 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1217 check_valid_resource_symbol (Lisp_Object data)
1219 CHECK_SYMBOL (data);
1220 if (!resource_symbol_to_type (data))
1221 signal_simple_error ("invalid resource type", data);
1225 check_valid_resource_id (Lisp_Object data)
1227 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1229 !resource_name_to_resource (data, IMAGE_ICON)
1231 !resource_name_to_resource (data, IMAGE_BITMAP))
1232 signal_simple_error ("invalid resource identifier", data);
1236 check_valid_string_or_int (Lisp_Object data)
1239 CHECK_STRING (data);
1244 /**********************************************************************
1246 **********************************************************************/
1247 #ifndef HAVE_X_WINDOWS
1248 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1252 Copyright (c) 1988 X Consortium
1254 Permission is hereby granted, free of charge, to any person obtaining a copy
1255 of this software and associated documentation files (the "Software"), to deal
1256 in the Software without restriction, including without limitation the rights
1257 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1258 copies of the Software, and to permit persons to whom the Software is
1259 furnished to do so, subject to the following conditions:
1261 The above copyright notice and this permission notice shall be included in
1262 all copies or substantial portions of the Software.
1264 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1265 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1266 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1267 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1268 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1269 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1271 Except as contained in this notice, the name of the X Consortium shall not be
1272 used in advertising or otherwise to promote the sale, use or other dealings
1273 in this Software without prior written authorization from the X Consortium.
1278 * This file contains miscellaneous utility routines and is not part of the
1281 * Public entry points:
1283 * XmuReadBitmapData read data from FILE descriptor
1284 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1287 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1288 * that way (but don't use common source code so that people can have one
1289 * without the other).
1294 * Based on an optimized version provided by Jim Becker, Auguest 5, 1988.
1296 #ifndef BitmapSuccess
1297 #define BitmapSuccess 0
1298 #define BitmapOpenFailed 1
1299 #define BitmapFileInvalid 2
1300 #define BitmapNoMemory 3
1302 #define MAX_SIZE 255
1304 /* shared data for the image read/parse logic */
1305 static short hexTable[256]; /* conversion value */
1306 static int initialized = FALSE; /* easier to fill in at run time */
1309 * Table index for the hex values. Initialized once, first time.
1310 * Used for translation value or delimiter significance lookup.
1312 static void initHexTable()
1315 * We build the table at run time for several reasons:
1317 * 1. portable to non-ASCII machines.
1318 * 2. still reentrant since we set the init flag after setting table.
1319 * 3. easier to extend.
1320 * 4. less prone to bugs.
1322 hexTable['0'] = 0; hexTable['1'] = 1;
1323 hexTable['2'] = 2; hexTable['3'] = 3;
1324 hexTable['4'] = 4; hexTable['5'] = 5;
1325 hexTable['6'] = 6; hexTable['7'] = 7;
1326 hexTable['8'] = 8; hexTable['9'] = 9;
1327 hexTable['A'] = 10; hexTable['B'] = 11;
1328 hexTable['C'] = 12; hexTable['D'] = 13;
1329 hexTable['E'] = 14; hexTable['F'] = 15;
1330 hexTable['a'] = 10; hexTable['b'] = 11;
1331 hexTable['c'] = 12; hexTable['d'] = 13;
1332 hexTable['e'] = 14; hexTable['f'] = 15;
1334 /* delimiters of significance are flagged w/ negative value */
1335 hexTable[' '] = -1; hexTable[','] = -1;
1336 hexTable['}'] = -1; hexTable['\n'] = -1;
1337 hexTable['\t'] = -1;
1343 * read next hex value in the input stream, return -1 if EOF
1345 static int NextInt ( FILE *fstream )
1352 /* loop, accumulate hex value until find delimiter */
1353 /* skip any initial delimiters found in read stream */
1361 /* trim high bits, check type and accumulate */
1363 if (isascii(ch) && isxdigit(ch)) {
1364 value = (value << 4) + hexTable[ch];
1366 } else if ((hexTable[ch]) < 0 && gotone)
1375 * The data returned by the following routine is always in left-most byte
1376 * first and left-most bit first. If it doesn't return BitmapSuccess then
1377 * its arguments won't have been touched. This routine should look as much
1378 * like the Xlib routine XReadBitmapfile as possible.
1380 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
1381 FILE *fstream; /* handle on file */
1382 unsigned int *width, *height; /* RETURNED */
1383 unsigned char **datap; /* RETURNED */
1384 int *x_hot, *y_hot; /* RETURNED */
1386 unsigned char *data = NULL; /* working variable */
1387 char line[MAX_SIZE]; /* input line from file */
1388 int size; /* number of bytes of data */
1389 char name_and_type[MAX_SIZE]; /* an input line */
1390 char *type; /* for parsing */
1391 int value; /* from an input line */
1392 int version10p; /* boolean, old format */
1393 int padding; /* to handle alignment */
1394 int bytes_per_line; /* per scanline of data */
1395 unsigned int ww = 0; /* width */
1396 unsigned int hh = 0; /* height */
1397 int hx = -1; /* x hotspot */
1398 int hy = -1; /* y hotspot */
1400 #define Xmalloc(size) malloc(size)
1402 /* first time initialization */
1403 if (initialized == FALSE) initHexTable();
1405 /* error cleanup and return macro */
1406 #define RETURN(code) { if (data) free (data); return code; }
1408 while (fgets(line, MAX_SIZE, fstream)) {
1409 if (strlen(line) == MAX_SIZE-1) {
1410 RETURN (BitmapFileInvalid);
1412 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1413 if (!(type = strrchr(name_and_type, '_')))
1414 type = name_and_type;
1418 if (!strcmp("width", type))
1419 ww = (unsigned int) value;
1420 if (!strcmp("height", type))
1421 hh = (unsigned int) value;
1422 if (!strcmp("hot", type)) {
1423 if (type-- == name_and_type || type-- == name_and_type)
1425 if (!strcmp("x_hot", type))
1427 if (!strcmp("y_hot", type))
1433 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1435 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1437 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1442 if (!(type = strrchr(name_and_type, '_')))
1443 type = name_and_type;
1447 if (strcmp("bits[]", type))
1451 RETURN (BitmapFileInvalid);
1453 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1458 bytes_per_line = (ww+7)/8 + padding;
1460 size = bytes_per_line * hh;
1461 data = (unsigned char *) Xmalloc ((unsigned int) size);
1463 RETURN (BitmapNoMemory);
1469 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1470 if ((value = NextInt(fstream)) < 0)
1471 RETURN (BitmapFileInvalid);
1473 if (!padding || ((bytes+2) % bytes_per_line))
1474 *(ptr++) = value >> 8;
1480 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1481 if ((value = NextInt(fstream)) < 0)
1482 RETURN (BitmapFileInvalid);
1490 RETURN (BitmapFileInvalid);
1497 if (x_hot) *x_hot = hx;
1498 if (y_hot) *y_hot = hy;
1500 RETURN (BitmapSuccess);
1504 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
1505 unsigned int *height, unsigned char **datap,
1506 int *x_hot, int *y_hot)
1511 if ((fstream = fopen (filename, "r")) == NULL) {
1512 return BitmapOpenFailed;
1514 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1518 #endif /* HAVE_X_WINDOWS */
1520 /* this table flips four bits around. */
1521 static int flip_table[] =
1523 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1526 /* the bitmap data comes in the following format: Widths are padded to
1527 a multiple of 8. Scan lines are stored in increasing byte order
1528 from left to right, little-endian within a byte. 0 = white, 1 =
1529 black. It must be converted to the following format: Widths are
1530 padded to a multiple of 16. Scan lines are stored in increasing
1531 byte order from left to right, big-endian within a byte. 0 =
1532 black, 1 = white. */
1534 xbm_create_bitmap_from_data (HDC hdc, char *data,
1535 unsigned int width, unsigned int height,
1536 int mask, COLORREF fg, COLORREF bg)
1538 int old_width = (width + 7)/8;
1539 int new_width = 2*((width + 15)/16);
1540 unsigned char *offset;
1542 unsigned char *new_data, *new_offset;
1544 BITMAPINFO* bmp_info =
1545 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1551 new_data = (unsigned char *) xmalloc (height * new_width);
1559 for (i=0; i<height; i++)
1561 offset = data + i*old_width;
1562 new_offset = new_data + i*new_width;
1564 new_offset[new_width - 1] = 0; /* there may be an extra byte
1565 that needs to be padded */
1566 for (j=0; j<old_width; j++)
1568 int byte = offset[j];
1569 new_offset[j] = ~ (unsigned char)
1570 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1574 /* if we want a mask invert the bits */
1577 new_offset = &new_data[height * new_width];
1578 while (new_offset-- != new_data)
1580 *new_offset ^= 0xff;
1584 bmp_info->bmiHeader.biWidth=width;
1585 bmp_info->bmiHeader.biHeight=-height;
1586 bmp_info->bmiHeader.biPlanes=1;
1587 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1588 bmp_info->bmiHeader.biBitCount=1;
1589 bmp_info->bmiHeader.biCompression=BI_RGB;
1590 bmp_info->bmiHeader.biClrUsed = 2;
1591 bmp_info->bmiHeader.biClrImportant = 2;
1592 bmp_info->bmiHeader.biSizeImage = height * new_width;
1593 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1594 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1595 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1596 bmp_info->bmiColors[0].rgbReserved = 0;
1597 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1598 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1599 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1600 bmp_info->bmiColors[1].rgbReserved = 0;
1602 bitmap = CreateDIBSection (hdc,
1610 if (!bitmap || !bmp_buf)
1616 /* copy in the actual bitmap */
1617 memcpy (bmp_buf, new_data, height * new_width);
1623 /* Given inline data for a mono pixmap, initialize the given
1624 image instance accordingly. */
1627 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
1628 int width, int height,
1629 /* Note that data is in ext-format! */
1631 Lisp_Object instantiator,
1632 Lisp_Object pointer_fg,
1633 Lisp_Object pointer_bg,
1636 Lisp_Object mask_filename)
1638 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1639 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device)));
1640 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1641 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1642 enum image_instance_type type;
1643 COLORREF black = PALETTERGB (0,0,0);
1644 COLORREF white = PALETTERGB (255,255,255);
1646 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1648 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1649 signal_simple_error ("Not an MS-Windows device", device);
1651 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1652 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1654 if (!NILP (foreground) || !NILP (background))
1655 type = IMAGE_COLOR_PIXMAP;
1657 type = IMAGE_MONO_PIXMAP;
1659 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1660 type = IMAGE_MONO_PIXMAP;
1661 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1662 type = IMAGE_COLOR_PIXMAP;
1663 else if (dest_mask & IMAGE_POINTER_MASK)
1664 type = IMAGE_POINTER;
1666 incompatible_image_types (instantiator, dest_mask,
1667 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1668 | IMAGE_POINTER_MASK);
1670 mswindows_initialize_dibitmap_image_instance (ii, type);
1672 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1673 find_keyword_in_vector (instantiator, Q_file);
1674 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
1675 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
1676 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1677 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1678 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1679 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1680 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1681 TRUE, black, white);
1685 case IMAGE_MONO_PIXMAP:
1686 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1687 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1688 FALSE, black, black);
1691 case IMAGE_COLOR_PIXMAP:
1693 COLORREF fg = black;
1694 COLORREF bg = white;
1696 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1698 Fmake_color_instance (foreground, device,
1699 encode_error_behavior_flag (ERROR_ME));
1701 if (COLOR_INSTANCEP (foreground))
1702 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1704 if (!NILP (background) && !COLOR_INSTANCEP (background))
1706 Fmake_color_instance (background, device,
1707 encode_error_behavior_flag (ERROR_ME));
1709 if (COLOR_INSTANCEP (background))
1710 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1712 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1713 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1715 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1716 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1723 COLORREF fg = black;
1724 COLORREF bg = white;
1726 if (NILP (foreground))
1727 foreground = pointer_fg;
1728 if (NILP (background))
1729 background = pointer_bg;
1731 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii),
1732 find_keyword_in_vector (instantiator, Q_hotspot_x));
1733 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii),
1734 find_keyword_in_vector (instantiator, Q_hotspot_y));
1735 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1736 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1737 if (COLOR_INSTANCEP (foreground))
1738 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1739 if (COLOR_INSTANCEP (background))
1740 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1742 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1743 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1745 mswindows_initialize_image_instance_icon (ii, TRUE);
1755 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1756 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1757 int dest_mask, int width, int height,
1758 /* Note that data is in ext-format! */
1761 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1762 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1763 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1764 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME
1765 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))));
1766 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1768 CONST char *gcc_may_you_rot_in_hell;
1770 if (!NILP (mask_data))
1772 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
1773 gcc_may_you_rot_in_hell);
1775 xbm_create_bitmap_from_data ( hdc,
1777 gcc_may_you_rot_in_hell,
1778 XINT (XCAR (mask_data)),
1779 XINT (XCAR (XCDR (mask_data))), FALSE,
1781 PALETTERGB (255,255,255));
1784 init_image_instance_from_xbm_inline (ii, width, height, bits,
1785 instantiator, pointer_fg, pointer_bg,
1786 dest_mask, mask, mask_file);
1789 /* Instantiate method for XBM's. */
1792 mswindows_xbm_instantiate (Lisp_Object image_instance,
1793 Lisp_Object instantiator,
1794 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1795 int dest_mask, Lisp_Object domain)
1797 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1798 CONST char *gcc_go_home;
1800 assert (!NILP (data));
1802 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
1805 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1806 pointer_bg, dest_mask, XINT (XCAR (data)),
1807 XINT (XCAR (XCDR (data))), gcc_go_home);
1811 /************************************************************************/
1812 /* image instance methods */
1813 /************************************************************************/
1816 mswindows_print_image_instance (struct Lisp_Image_Instance *p,
1817 Lisp_Object printcharfun,
1822 switch (IMAGE_INSTANCE_TYPE (p))
1824 case IMAGE_MONO_PIXMAP:
1825 case IMAGE_COLOR_PIXMAP:
1827 sprintf (buf, " (0x%lx",
1828 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1829 write_c_string (buf, printcharfun);
1830 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1832 sprintf (buf, "/0x%lx",
1833 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1834 write_c_string (buf, printcharfun);
1836 write_c_string (")", printcharfun);
1844 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
1849 if (DEVICE_LIVE_P (XDEVICE (p->device)))
1851 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
1852 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1853 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
1854 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1855 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1856 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
1857 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
1858 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
1859 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
1867 mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
1868 struct Lisp_Image_Instance *p2, int depth)
1870 switch (IMAGE_INSTANCE_TYPE (p1))
1872 case IMAGE_MONO_PIXMAP:
1873 case IMAGE_COLOR_PIXMAP:
1875 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
1876 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
1886 static unsigned long
1887 mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
1889 switch (IMAGE_INSTANCE_TYPE (p))
1891 case IMAGE_MONO_PIXMAP:
1892 case IMAGE_COLOR_PIXMAP:
1894 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
1900 /* Set all the slots in an image instance structure to reasonable
1901 default values. This is used somewhere within an instantiate
1902 method. It is assumed that the device slot within the image
1903 instance is already set -- this is the case when instantiate
1904 methods are called. */
1907 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
1908 enum image_instance_type type)
1910 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
1911 IMAGE_INSTANCE_TYPE (ii) = type;
1912 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
1913 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
1914 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
1915 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
1916 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
1917 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
1921 /************************************************************************/
1922 /* initialization */
1923 /************************************************************************/
1926 syms_of_glyphs_mswindows (void)
1928 defkeyword (&Q_resource_id, ":resource-id");
1929 defkeyword (&Q_resource_type, ":resource-type");
1933 console_type_create_glyphs_mswindows (void)
1937 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
1938 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
1939 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
1940 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
1941 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
1942 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
1944 CONSOLE_HAS_METHOD (mswindows, xpm_instantiate);
1946 CONSOLE_HAS_METHOD (mswindows, xbm_instantiate);
1950 image_instantiator_format_create_glyphs_mswindows (void)
1952 /* image-instantiator types */
1954 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
1956 IIFORMAT_HAS_METHOD (bmp, validate);
1957 IIFORMAT_HAS_METHOD (bmp, normalize);
1958 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
1959 IIFORMAT_HAS_METHOD (bmp, instantiate);
1961 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
1962 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
1964 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
1965 "mswindows-resource");
1967 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
1968 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
1969 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
1970 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
1972 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
1973 check_valid_resource_symbol);
1974 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
1975 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
1979 vars_of_glyphs_mswindows (void)
1982 Fprovide (Qmswindows_resource);
1983 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
1984 A list of the directories in which mswindows bitmap files may be found.
1985 This is used by the `make-image-instance' function.
1987 Vmswindows_bitmap_file_path = Qnil;
1991 complex_vars_of_glyphs_mswindows (void)