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 color table, once
91 * we start palettizing this is no longer true. The X versions of
92 * this function quantises to 256 colors 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),
524 DeleteObject (newbmp);
529 SelectObject (hdcDst, old2);
530 SelectObject (hcdc, old1);
537 mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
541 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
545 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
546 HDC hdcDst = CreateCompatibleDC (hcdc);
548 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
549 newmask = CreateCompatibleBitmap(hcdc, newx, newy);
550 old2 = SelectObject (hdcDst, newmask);
552 if (!StretchBlt(hdcDst, 0, 0, newx, newy,
554 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
555 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
558 DeleteObject (newmask);
563 SelectObject (hdcDst, old2);
564 SelectObject (hcdc, old1);
575 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
579 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
580 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
585 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
586 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
587 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
588 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
590 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
591 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
592 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
593 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
598 /**********************************************************************
600 **********************************************************************/
610 static struct color_symbol*
611 extract_xpm_color_names (Lisp_Object device,
613 Lisp_Object color_symbol_alist,
616 /* This function can GC */
618 Lisp_Object results = Qnil;
620 struct color_symbol *colortbl;
621 struct gcpro gcpro1, gcpro2;
623 GCPRO2 (results, device);
625 /* We built up results to be (("name" . #<color>) ...) so that if an
626 error happens we don't lose any malloc()ed data, or more importantly,
627 leave any pixels allocated in the server. */
629 LIST_LOOP (rest, color_symbol_alist)
631 Lisp_Object cons = XCAR (rest);
632 Lisp_Object name = XCAR (cons);
633 Lisp_Object value = XCDR (cons);
639 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
642 assert (COLOR_SPECIFIERP (value));
643 value = Fspecifier_instance (value, domain, Qnil, Qnil);
647 results = noseeum_cons (noseeum_cons (name, value), results);
650 UNGCPRO; /* no more evaluation */
653 if (i == 0) return 0;
655 colortbl = xnew_array_and_zero (struct color_symbol, i);
659 Lisp_Object cons = XCAR (results);
661 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
663 colortbl[j].name = (char *) XSTRING_DATA (XCAR (cons));
664 free_cons (XCONS (cons));
666 results = XCDR (results);
667 free_cons (XCONS (cons));
672 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
673 unsigned char** data,
674 int* width, int* height,
675 int* x_hot, int* y_hot,
677 struct color_symbol* color_symbols,
682 int result, i, j, transp_idx, maskbpline;
685 COLORREF color; /* the american spelling virus hits again .. */
690 xpminfo.valuemask=XpmHotspot;
693 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
702 signal_simple_error ("Invalid XPM data", image);
706 signal_double_file_error ("Parsing pixmap data",
707 "out of memory", image);
711 signal_double_file_error_2 ("Parsing pixmap data",
712 "unknown error code",
713 make_int (result), image);
717 *width = xpmimage.width;
718 *height = xpmimage.height;
719 maskbpline = BPLINE (((~7UL & (unsigned long)(*width + 7)) / 8));
721 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
725 XpmFreeXpmImage (&xpmimage);
726 XpmFreeXpmInfo (&xpminfo);
730 /* build a color table to speed things up */
731 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
735 XpmFreeXpmImage (&xpmimage);
736 XpmFreeXpmInfo (&xpminfo);
740 for (i=0; i<xpmimage.ncolors; i++)
743 /* pick up symbolic colors in preference */
744 if (xpmimage.colorTable[i].symbolic)
746 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
748 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
751 colortbl[i]=transparent_color;
753 goto label_found_color;
755 else if (color_symbols)
757 for (j = 0; j<nsymbols; j++)
759 if (!strcmp (xpmimage.colorTable[i].symbolic,
760 color_symbols[j].name ))
762 colortbl[i]=color_symbols[j].color;
763 goto label_found_color;
767 else if (xpmimage.colorTable[i].c_color == 0)
772 /* pick up transparencies */
773 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
776 colortbl[i]=transparent_color;
778 goto label_found_color;
780 /* finally pick up a normal color spec */
781 if (xpmimage.colorTable[i].c_color)
784 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
785 goto label_found_color;
791 XpmFreeXpmImage (&xpmimage);
792 XpmFreeXpmInfo (&xpminfo);
798 /* convert the image */
801 for (i = 0; i< *width * *height; i++)
803 color = colortbl[*sptr++];
805 /* split out the 0x02bbggrr colorref into an rgb triple */
806 *dptr++=GetRValue (color); /* red */
807 *dptr++=GetGValue (color); /* green */
808 *dptr++=GetBValue (color); /* blue */
811 *x_hot=xpminfo.x_hotspot;
812 *y_hot=xpminfo.y_hotspot;
814 XpmFreeXpmImage (&xpmimage);
815 XpmFreeXpmInfo (&xpminfo);
821 mswindows_xpm_instantiate (Lisp_Object image_instance,
822 Lisp_Object instantiator,
823 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
824 int dest_mask, Lisp_Object domain)
826 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
827 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
828 CONST Extbyte *bytes;
830 unsigned char *eimage;
831 int width, height, x_hot, y_hot;
832 BITMAPINFO* bmp_info;
833 unsigned char* bmp_data;
835 int nsymbols=0, transp;
836 struct color_symbol* color_symbols=NULL;
838 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
839 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
842 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
843 signal_simple_error ("Not an mswindows device", device);
845 assert (!NILP (data));
847 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
849 /* in case we have color symbols */
850 color_symbols = extract_xpm_color_names (device, domain,
851 color_symbol_alist, &nsymbols);
853 /* convert to an eimage to make processing easier */
854 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
855 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
857 signal_simple_error ("XPM to EImage conversion failed",
862 xfree(color_symbols);
864 /* build a bitmap from the eimage */
865 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
866 &bmp_bits, &bmp_data)))
868 signal_simple_error ("XPM to EImage conversion failed",
873 /* Now create the pixmap and set up the image instance */
874 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
875 bmp_data, bmp_bits, instantiator,
876 x_hot, y_hot, transp);
881 #endif /* HAVE_XPM */
883 /**********************************************************************
885 **********************************************************************/
888 bmp_validate (Lisp_Object instantiator)
890 file_or_data_must_be_present (instantiator);
894 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
896 return simple_image_type_normalize (inst, console_type, Qbmp);
900 bmp_possible_dest_types (void)
902 return IMAGE_COLOR_PIXMAP_MASK;
906 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
907 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
908 int dest_mask, Lisp_Object domain)
910 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
911 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
912 CONST Extbyte *bytes;
914 BITMAPFILEHEADER* bmp_file_header;
915 BITMAPINFO* bmp_info;
918 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
920 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
921 signal_simple_error ("Not an mswindows device", device);
923 assert (!NILP (data));
925 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
927 /* Then slurp the image into memory, decoding along the way.
928 The result is the image in a simple one-byte-per-pixel
931 bmp_file_header=(BITMAPFILEHEADER*)bytes;
932 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
933 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
934 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
936 /* Now create the pixmap and set up the image instance */
937 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
938 bmp_data, bmp_bits, instantiator,
943 /**********************************************************************
945 **********************************************************************/
948 mswindows_resource_validate (Lisp_Object instantiator)
950 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
952 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
954 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
955 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
960 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type)
962 /* This function can call lisp */
963 Lisp_Object file = Qnil;
964 struct gcpro gcpro1, gcpro2;
965 Lisp_Object alist = Qnil;
967 GCPRO2 (file, alist);
969 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
972 if (CONSP (file)) /* failure locating filename */
973 signal_double_file_error ("Opening pixmap file",
974 "no such file or directory",
977 if (NILP (file)) /* no conversion necessary */
978 RETURN_UNGCPRO (inst);
980 alist = tagged_vector_to_alist (inst);
983 alist = remassq_no_quit (Q_file, alist);
984 alist = Fcons (Fcons (Q_file, file), alist);
988 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
990 RETURN_UNGCPRO (result);
995 mswindows_resource_possible_dest_types (void)
997 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1007 #define OCR_ICOCUR 32647
1008 #define OIC_SAMPLE 32512
1009 #define OIC_HAND 32513
1010 #define OIC_QUES 32514
1011 #define OIC_BANG 32515
1012 #define OIC_NOTE 32516
1013 #define OIC_WINLOGO 32517
1014 #define LR_SHARED 0x8000
1017 static CONST resource_t bitmap_table[] =
1020 { "close", OBM_CLOSE },
1021 { "uparrow", OBM_UPARROW },
1022 { "dnarrow", OBM_DNARROW },
1023 { "rgarrow", OBM_RGARROW },
1024 { "lfarrow", OBM_LFARROW },
1025 { "reduce", OBM_REDUCE },
1026 { "zoom", OBM_ZOOM },
1027 { "restore", OBM_RESTORE },
1028 { "reduced", OBM_REDUCED },
1029 { "zoomd", OBM_ZOOMD },
1030 { "restored", OBM_RESTORED },
1031 { "uparrowd", OBM_UPARROWD },
1032 { "dnarrowd", OBM_DNARROWD },
1033 { "rgarrowd", OBM_RGARROWD },
1034 { "lfarrowd", OBM_LFARROWD },
1035 { "mnarrow", OBM_MNARROW },
1036 { "combo", OBM_COMBO },
1037 { "uparrowi", OBM_UPARROWI },
1038 { "dnarrowi", OBM_DNARROWI },
1039 { "rgarrowi", OBM_RGARROWI },
1040 { "lfarrowi", OBM_LFARROWI },
1041 { "size", OBM_SIZE },
1042 { "btsize", OBM_BTSIZE },
1043 { "check", OBM_CHECK },
1044 { "checkboxes", OBM_CHECKBOXES },
1045 { "btncorners" , OBM_BTNCORNERS },
1049 static CONST resource_t cursor_table[] =
1052 { "normal", OCR_NORMAL },
1053 { "ibeam", OCR_IBEAM },
1054 { "wait", OCR_WAIT },
1055 { "cross", OCR_CROSS },
1057 /* { "icon", OCR_ICON }, */
1058 { "sizenwse", OCR_SIZENWSE },
1059 { "sizenesw", OCR_SIZENESW },
1060 { "sizewe", OCR_SIZEWE },
1061 { "sizens", OCR_SIZENS },
1062 { "sizeall", OCR_SIZEALL },
1063 /* { "icour", OCR_ICOCUR }, */
1068 static CONST resource_t icon_table[] =
1071 { "sample", OIC_SAMPLE },
1072 { "hand", OIC_HAND },
1073 { "ques", OIC_QUES },
1074 { "bang", OIC_BANG },
1075 { "note", OIC_NOTE },
1076 { "winlogo", OIC_WINLOGO },
1080 static int resource_name_to_resource (Lisp_Object name, int type)
1082 CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1083 : type == IMAGE_ICON ? icon_table
1090 else if (!STRINGP (name))
1092 signal_simple_error ("invalid resource identifier", name);
1096 if (!strcasecmp ((char*)res->name, XSTRING_DATA (name)))
1097 return res->resource_id;
1098 } while ((++res)->name);
1103 resource_symbol_to_type (Lisp_Object data)
1105 if (EQ (data, Qcursor))
1106 return IMAGE_CURSOR;
1107 else if (EQ (data, Qicon))
1109 else if (EQ (data, Qbitmap))
1110 return IMAGE_BITMAP;
1116 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1117 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1118 int dest_mask, Lisp_Object domain)
1120 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1121 unsigned int type = 0;
1122 HANDLE himage = NULL;
1124 HINSTANCE hinst = NULL;
1128 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1130 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1131 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1133 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1138 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1139 signal_simple_error ("Not an mswindows device", device);
1141 type = resource_symbol_to_type (resource_type);
1143 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1144 iitype = IMAGE_POINTER;
1145 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1146 iitype = IMAGE_COLOR_PIXMAP;
1148 incompatible_image_types (instantiator, dest_mask,
1149 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1151 /* mess with the keyword info we were provided with */
1155 CYGWIN_WIN32_PATH (XSTRING_DATA (file), fname);
1157 /* #### FIXME someone who knows ... */
1158 fname = XSTRING_DATA (file);
1161 if (NILP (resource_id))
1162 resid = (LPCTSTR)fname;
1165 hinst = LoadLibraryEx (fname, NULL,
1166 LOAD_LIBRARY_AS_DATAFILE);
1167 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1171 resid = XSTRING_DATA (resource_id);
1174 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1176 signal_simple_error ("Invalid resource identifier", resource_id);
1178 /* load the image */
1179 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
1180 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1182 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1184 signal_simple_error ("Cannot load image", instantiator);
1188 FreeLibrary (hinst);
1190 mswindows_initialize_dibitmap_image_instance (ii, iitype);
1192 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1193 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
1194 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1195 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
1196 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1197 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1199 /* hey, we've got an icon type thing so we can reverse engineer the
1201 if (type != IMAGE_BITMAP)
1203 GetIconInfo (himage, &iconinfo);
1204 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1205 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1206 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1207 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1208 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
1212 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1213 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
1214 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1215 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1216 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1221 check_valid_resource_symbol (Lisp_Object data)
1223 CHECK_SYMBOL (data);
1224 if (!resource_symbol_to_type (data))
1225 signal_simple_error ("invalid resource type", data);
1229 check_valid_resource_id (Lisp_Object data)
1231 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1233 !resource_name_to_resource (data, IMAGE_ICON)
1235 !resource_name_to_resource (data, IMAGE_BITMAP))
1236 signal_simple_error ("invalid resource identifier", data);
1240 check_valid_string_or_int (Lisp_Object data)
1243 CHECK_STRING (data);
1248 /**********************************************************************
1250 **********************************************************************/
1251 #ifndef HAVE_X_WINDOWS
1252 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1256 Copyright (c) 1988 X Consortium
1258 Permission is hereby granted, free of charge, to any person obtaining a copy
1259 of this software and associated documentation files (the "Software"), to deal
1260 in the Software without restriction, including without limitation the rights
1261 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1262 copies of the Software, and to permit persons to whom the Software is
1263 furnished to do so, subject to the following conditions:
1265 The above copyright notice and this permission notice shall be included in
1266 all copies or substantial portions of the Software.
1268 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1269 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1270 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1271 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1272 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1273 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1275 Except as contained in this notice, the name of the X Consortium shall not be
1276 used in advertising or otherwise to promote the sale, use or other dealings
1277 in this Software without prior written authorization from the X Consortium.
1282 * This file contains miscellaneous utility routines and is not part of the
1285 * Public entry points:
1287 * XmuReadBitmapData read data from FILE descriptor
1288 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1291 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1292 * that way (but don't use common source code so that people can have one
1293 * without the other).
1298 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1300 #ifndef BitmapSuccess
1301 #define BitmapSuccess 0
1302 #define BitmapOpenFailed 1
1303 #define BitmapFileInvalid 2
1304 #define BitmapNoMemory 3
1306 #define MAX_SIZE 255
1308 /* shared data for the image read/parse logic */
1309 static short hexTable[256]; /* conversion value */
1310 static int initialized = FALSE; /* easier to fill in at run time */
1313 * Table index for the hex values. Initialized once, first time.
1314 * Used for translation value or delimiter significance lookup.
1316 static void initHexTable()
1319 * We build the table at run time for several reasons:
1321 * 1. portable to non-ASCII machines.
1322 * 2. still reentrant since we set the init flag after setting table.
1323 * 3. easier to extend.
1324 * 4. less prone to bugs.
1326 hexTable['0'] = 0; hexTable['1'] = 1;
1327 hexTable['2'] = 2; hexTable['3'] = 3;
1328 hexTable['4'] = 4; hexTable['5'] = 5;
1329 hexTable['6'] = 6; hexTable['7'] = 7;
1330 hexTable['8'] = 8; hexTable['9'] = 9;
1331 hexTable['A'] = 10; hexTable['B'] = 11;
1332 hexTable['C'] = 12; hexTable['D'] = 13;
1333 hexTable['E'] = 14; hexTable['F'] = 15;
1334 hexTable['a'] = 10; hexTable['b'] = 11;
1335 hexTable['c'] = 12; hexTable['d'] = 13;
1336 hexTable['e'] = 14; hexTable['f'] = 15;
1338 /* delimiters of significance are flagged w/ negative value */
1339 hexTable[' '] = -1; hexTable[','] = -1;
1340 hexTable['}'] = -1; hexTable['\n'] = -1;
1341 hexTable['\t'] = -1;
1347 * read next hex value in the input stream, return -1 if EOF
1349 static int NextInt ( FILE *fstream )
1356 /* loop, accumulate hex value until find delimiter */
1357 /* skip any initial delimiters found in read stream */
1365 /* trim high bits, check type and accumulate */
1367 if (isascii(ch) && isxdigit(ch)) {
1368 value = (value << 4) + hexTable[ch];
1370 } else if ((hexTable[ch]) < 0 && gotone)
1379 * The data returned by the following routine is always in left-most byte
1380 * first and left-most bit first. If it doesn't return BitmapSuccess then
1381 * its arguments won't have been touched. This routine should look as much
1382 * like the Xlib routine XReadBitmapfile as possible.
1384 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
1385 FILE *fstream; /* handle on file */
1386 unsigned int *width, *height; /* RETURNED */
1387 unsigned char **datap; /* RETURNED */
1388 int *x_hot, *y_hot; /* RETURNED */
1390 unsigned char *data = NULL; /* working variable */
1391 char line[MAX_SIZE]; /* input line from file */
1392 int size; /* number of bytes of data */
1393 char name_and_type[MAX_SIZE]; /* an input line */
1394 char *type; /* for parsing */
1395 int value; /* from an input line */
1396 int version10p; /* boolean, old format */
1397 int padding; /* to handle alignment */
1398 int bytes_per_line; /* per scanline of data */
1399 unsigned int ww = 0; /* width */
1400 unsigned int hh = 0; /* height */
1401 int hx = -1; /* x hotspot */
1402 int hy = -1; /* y hotspot */
1404 #define Xmalloc(size) malloc(size)
1406 /* first time initialization */
1407 if (initialized == FALSE) initHexTable();
1409 /* error cleanup and return macro */
1410 #define RETURN(code) { if (data) free (data); return code; }
1412 while (fgets(line, MAX_SIZE, fstream)) {
1413 if (strlen(line) == MAX_SIZE-1) {
1414 RETURN (BitmapFileInvalid);
1416 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1417 if (!(type = strrchr(name_and_type, '_')))
1418 type = name_and_type;
1422 if (!strcmp("width", type))
1423 ww = (unsigned int) value;
1424 if (!strcmp("height", type))
1425 hh = (unsigned int) value;
1426 if (!strcmp("hot", type)) {
1427 if (type-- == name_and_type || type-- == name_and_type)
1429 if (!strcmp("x_hot", type))
1431 if (!strcmp("y_hot", type))
1437 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1439 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1441 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1446 if (!(type = strrchr(name_and_type, '_')))
1447 type = name_and_type;
1451 if (strcmp("bits[]", type))
1455 RETURN (BitmapFileInvalid);
1457 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1462 bytes_per_line = (ww+7)/8 + padding;
1464 size = bytes_per_line * hh;
1465 data = (unsigned char *) Xmalloc ((unsigned int) size);
1467 RETURN (BitmapNoMemory);
1473 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1474 if ((value = NextInt(fstream)) < 0)
1475 RETURN (BitmapFileInvalid);
1477 if (!padding || ((bytes+2) % bytes_per_line))
1478 *(ptr++) = value >> 8;
1484 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1485 if ((value = NextInt(fstream)) < 0)
1486 RETURN (BitmapFileInvalid);
1494 RETURN (BitmapFileInvalid);
1501 if (x_hot) *x_hot = hx;
1502 if (y_hot) *y_hot = hy;
1504 RETURN (BitmapSuccess);
1508 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
1509 unsigned int *height, unsigned char **datap,
1510 int *x_hot, int *y_hot)
1515 if ((fstream = fopen (filename, "r")) == NULL) {
1516 return BitmapOpenFailed;
1518 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1522 #endif /* HAVE_X_WINDOWS */
1524 /* this table flips four bits around. */
1525 static int flip_table[] =
1527 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1530 /* the bitmap data comes in the following format: Widths are padded to
1531 a multiple of 8. Scan lines are stored in increasing byte order
1532 from left to right, little-endian within a byte. 0 = white, 1 =
1533 black. It must be converted to the following format: Widths are
1534 padded to a multiple of 16. Scan lines are stored in increasing
1535 byte order from left to right, big-endian within a byte. 0 =
1536 black, 1 = white. */
1538 xbm_create_bitmap_from_data (HDC hdc, char *data,
1539 unsigned int width, unsigned int height,
1540 int mask, COLORREF fg, COLORREF bg)
1542 int old_width = (width + 7)/8;
1543 int new_width = 2*((width + 15)/16);
1544 unsigned char *offset;
1546 unsigned char *new_data, *new_offset;
1548 BITMAPINFO* bmp_info =
1549 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1555 new_data = (unsigned char *) xmalloc (height * new_width);
1563 for (i=0; i<height; i++)
1565 offset = data + i*old_width;
1566 new_offset = new_data + i*new_width;
1568 new_offset[new_width - 1] = 0; /* there may be an extra byte
1569 that needs to be padded */
1570 for (j=0; j<old_width; j++)
1572 int byte = offset[j];
1573 new_offset[j] = ~ (unsigned char)
1574 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1578 /* if we want a mask invert the bits */
1581 new_offset = &new_data[height * new_width];
1582 while (new_offset-- != new_data)
1584 *new_offset ^= 0xff;
1588 bmp_info->bmiHeader.biWidth=width;
1589 bmp_info->bmiHeader.biHeight=-height;
1590 bmp_info->bmiHeader.biPlanes=1;
1591 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1592 bmp_info->bmiHeader.biBitCount=1;
1593 bmp_info->bmiHeader.biCompression=BI_RGB;
1594 bmp_info->bmiHeader.biClrUsed = 2;
1595 bmp_info->bmiHeader.biClrImportant = 2;
1596 bmp_info->bmiHeader.biSizeImage = height * new_width;
1597 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1598 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1599 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1600 bmp_info->bmiColors[0].rgbReserved = 0;
1601 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1602 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1603 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1604 bmp_info->bmiColors[1].rgbReserved = 0;
1606 bitmap = CreateDIBSection (hdc,
1614 if (!bitmap || !bmp_buf)
1620 /* copy in the actual bitmap */
1621 memcpy (bmp_buf, new_data, height * new_width);
1627 /* Given inline data for a mono pixmap, initialize the given
1628 image instance accordingly. */
1631 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
1632 int width, int height,
1633 /* Note that data is in ext-format! */
1635 Lisp_Object instantiator,
1636 Lisp_Object pointer_fg,
1637 Lisp_Object pointer_bg,
1640 Lisp_Object mask_filename)
1642 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1643 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device)));
1644 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1645 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1646 enum image_instance_type type;
1647 COLORREF black = PALETTERGB (0,0,0);
1648 COLORREF white = PALETTERGB (255,255,255);
1650 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1652 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1653 signal_simple_error ("Not an MS-Windows device", device);
1655 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1656 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1658 if (!NILP (foreground) || !NILP (background))
1659 type = IMAGE_COLOR_PIXMAP;
1661 type = IMAGE_MONO_PIXMAP;
1663 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1664 type = IMAGE_MONO_PIXMAP;
1665 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1666 type = IMAGE_COLOR_PIXMAP;
1667 else if (dest_mask & IMAGE_POINTER_MASK)
1668 type = IMAGE_POINTER;
1670 incompatible_image_types (instantiator, dest_mask,
1671 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1672 | IMAGE_POINTER_MASK);
1674 mswindows_initialize_dibitmap_image_instance (ii, type);
1676 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1677 find_keyword_in_vector (instantiator, Q_file);
1678 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
1679 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
1680 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1681 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1682 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1683 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1684 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1685 TRUE, black, white);
1689 case IMAGE_MONO_PIXMAP:
1690 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1691 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1692 FALSE, black, black);
1695 case IMAGE_COLOR_PIXMAP:
1697 COLORREF fg = black;
1698 COLORREF bg = white;
1700 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1702 Fmake_color_instance (foreground, device,
1703 encode_error_behavior_flag (ERROR_ME));
1705 if (COLOR_INSTANCEP (foreground))
1706 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1708 if (!NILP (background) && !COLOR_INSTANCEP (background))
1710 Fmake_color_instance (background, device,
1711 encode_error_behavior_flag (ERROR_ME));
1713 if (COLOR_INSTANCEP (background))
1714 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1716 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1717 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1719 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1720 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1727 COLORREF fg = black;
1728 COLORREF bg = white;
1730 if (NILP (foreground))
1731 foreground = pointer_fg;
1732 if (NILP (background))
1733 background = pointer_bg;
1735 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1736 find_keyword_in_vector (instantiator, Q_hotspot_x);
1737 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1738 find_keyword_in_vector (instantiator, Q_hotspot_y);
1739 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1740 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1741 if (COLOR_INSTANCEP (foreground))
1742 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1743 if (COLOR_INSTANCEP (background))
1744 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1746 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1747 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1749 mswindows_initialize_image_instance_icon (ii, TRUE);
1759 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1760 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1761 int dest_mask, int width, int height,
1762 /* Note that data is in ext-format! */
1765 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1766 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1767 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1768 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME
1769 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))));
1770 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1772 CONST char *gcc_may_you_rot_in_hell;
1774 if (!NILP (mask_data))
1776 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
1777 gcc_may_you_rot_in_hell);
1779 xbm_create_bitmap_from_data ( hdc,
1781 gcc_may_you_rot_in_hell,
1782 XINT (XCAR (mask_data)),
1783 XINT (XCAR (XCDR (mask_data))), FALSE,
1785 PALETTERGB (255,255,255));
1788 init_image_instance_from_xbm_inline (ii, width, height, bits,
1789 instantiator, pointer_fg, pointer_bg,
1790 dest_mask, mask, mask_file);
1793 /* Instantiate method for XBM's. */
1796 mswindows_xbm_instantiate (Lisp_Object image_instance,
1797 Lisp_Object instantiator,
1798 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1799 int dest_mask, Lisp_Object domain)
1801 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1802 CONST char *gcc_go_home;
1804 assert (!NILP (data));
1806 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
1809 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1810 pointer_bg, dest_mask, XINT (XCAR (data)),
1811 XINT (XCAR (XCDR (data))), gcc_go_home);
1815 /************************************************************************/
1816 /* image instance methods */
1817 /************************************************************************/
1820 mswindows_print_image_instance (struct Lisp_Image_Instance *p,
1821 Lisp_Object printcharfun,
1826 switch (IMAGE_INSTANCE_TYPE (p))
1828 case IMAGE_MONO_PIXMAP:
1829 case IMAGE_COLOR_PIXMAP:
1831 sprintf (buf, " (0x%lx",
1832 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1833 write_c_string (buf, printcharfun);
1834 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1836 sprintf (buf, "/0x%lx",
1837 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1838 write_c_string (buf, printcharfun);
1840 write_c_string (")", printcharfun);
1848 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
1853 if (DEVICE_LIVE_P (XDEVICE (p->device)))
1855 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
1856 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1857 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
1858 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1859 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1860 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
1861 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
1862 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
1863 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
1871 mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
1872 struct Lisp_Image_Instance *p2, int depth)
1874 switch (IMAGE_INSTANCE_TYPE (p1))
1876 case IMAGE_MONO_PIXMAP:
1877 case IMAGE_COLOR_PIXMAP:
1879 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
1880 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
1890 static unsigned long
1891 mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
1893 switch (IMAGE_INSTANCE_TYPE (p))
1895 case IMAGE_MONO_PIXMAP:
1896 case IMAGE_COLOR_PIXMAP:
1898 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
1904 /* Set all the slots in an image instance structure to reasonable
1905 default values. This is used somewhere within an instantiate
1906 method. It is assumed that the device slot within the image
1907 instance is already set -- this is the case when instantiate
1908 methods are called. */
1911 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
1912 enum image_instance_type type)
1914 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
1915 IMAGE_INSTANCE_TYPE (ii) = type;
1916 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
1917 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
1918 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
1919 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
1920 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
1921 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
1925 /************************************************************************/
1926 /* initialization */
1927 /************************************************************************/
1930 syms_of_glyphs_mswindows (void)
1932 defkeyword (&Q_resource_id, ":resource-id");
1933 defkeyword (&Q_resource_type, ":resource-type");
1937 console_type_create_glyphs_mswindows (void)
1941 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
1942 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
1943 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
1944 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
1945 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
1946 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
1948 CONSOLE_HAS_METHOD (mswindows, xpm_instantiate);
1950 CONSOLE_HAS_METHOD (mswindows, xbm_instantiate);
1954 image_instantiator_format_create_glyphs_mswindows (void)
1956 /* image-instantiator types */
1958 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
1960 IIFORMAT_HAS_METHOD (bmp, validate);
1961 IIFORMAT_HAS_METHOD (bmp, normalize);
1962 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
1963 IIFORMAT_HAS_METHOD (bmp, instantiate);
1965 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
1966 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
1968 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
1969 "mswindows-resource");
1971 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
1972 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
1973 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
1974 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
1976 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
1977 check_valid_resource_symbol);
1978 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
1979 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
1983 vars_of_glyphs_mswindows (void)
1986 Fprovide (Qmswindows_resource);
1987 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
1988 A list of the directories in which mswindows bitmap files may be found.
1989 This is used by the `make-image-instance' function.
1991 Vmswindows_bitmap_file_path = Qnil;
1995 complex_vars_of_glyphs_mswindows (void)