1 /* mswindows-specific glyph 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 <andy@xemacs.org> plagerising bits from
30 #define OEMRESOURCE /* Define OCR_ and friend constants */
31 #include "console-msw.h"
32 #include "glyphs-msw.h"
33 #include "objects-msw.h"
46 #include "file-coding.h"
54 #define WIDGET_GLYPH_SLOT 0
57 DEFINE_DEVICE_IIFORMAT (mswindows, xpm);
59 DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
61 DEFINE_DEVICE_IIFORMAT (mswindows, xface);
63 DEFINE_DEVICE_IIFORMAT (mswindows, button);
64 DEFINE_DEVICE_IIFORMAT (mswindows, edit);
66 DEFINE_DEVICE_IIFORMAT (mswindows, group);
68 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
69 DEFINE_DEVICE_IIFORMAT (mswindows, widget);
70 DEFINE_DEVICE_IIFORMAT (mswindows, label);
71 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
72 DEFINE_DEVICE_IIFORMAT (mswindows, combo);
73 DEFINE_DEVICE_IIFORMAT (mswindows, progress);
74 DEFINE_DEVICE_IIFORMAT (mswindows, tree);
75 DEFINE_DEVICE_IIFORMAT (mswindows, tab);
77 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
79 Lisp_Object Vmswindows_bitmap_file_path;
80 static COLORREF transparent_color = RGB (1,1,1);
82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource);
83 Lisp_Object Q_resource_type, Q_resource_id;
84 Lisp_Object Qmswindows_resource;
87 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
88 enum image_instance_type type);
90 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
93 COLORREF mswindows_string_to_color (CONST char *name);
95 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
97 /************************************************************************/
98 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
100 /************************************************************************/
101 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
102 int width, int height,
105 unsigned char** bmp_data)
107 struct device *d = XDEVICE (device);
111 BITMAPINFO* bmp_info;
112 unsigned char *ip, *dp;
114 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
116 int bpline = BPLINE(width * 3);
117 /* FIXME: we can do this because 24bpp implies no color table, once
118 * we start palettizing this is no longer true. The X versions of
119 * this function quantises to 256 colors or bit masks down to a
120 * long. Windows can actually handle rgb triples in the raw so I
121 * don't see much point trying to optimize down to the best
122 * structure - unless it has memory / color allocation implications
124 bmp_info=xnew_and_zero (BITMAPINFO);
131 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
132 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
133 bmp_info->bmiHeader.biSizeImage=width*height*3;
135 /* bitmap data needs to be in blue, green, red triples - in that
136 order, eimage is in RGB format so we need to convert */
137 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
138 *bit_count = bpline * height;
147 for (i = height-1; i >= 0; i--) {
148 dp = (*bmp_data) + (i * bpline);
149 for (j = 0; j < width; j++) {
157 else /* scale to 256 colors */
161 int bpline = BPLINE (width * 3);
162 /* Quantize the image and get a histogram while we're at it.
163 Do this first to save memory */
164 qtable = build_EImage_quantable(pic, width, height, 256);
165 if (qtable == NULL) return NULL;
167 /* use our quantize table to allocate the colors */
168 ncolors = qtable->num_active_colors;
169 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
170 sizeof(RGBQUAD) * ncolors);
177 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
179 bmp_info->bmiHeader.biBitCount=8;
180 bmp_info->bmiHeader.biCompression=BI_RGB;
181 bmp_info->bmiHeader.biSizeImage=bpline*height;
182 bmp_info->bmiHeader.biClrUsed=ncolors;
183 bmp_info->bmiHeader.biClrImportant=ncolors;
185 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
186 *bit_count = bpline * height;
195 /* build up an RGBQUAD colortable */
196 for (i = 0; i < qtable->num_active_colors; i++) {
197 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
198 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
199 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
200 colortbl[i].rgbReserved = 0;
203 /* now build up the data. picture has to be upside-down and
204 back-to-front for msw bitmaps */
206 for (i = height-1; i >= 0; i--) {
207 dp = (*bmp_data) + (i * bpline);
208 for (j = 0; j < width; j++) {
212 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
217 /* fix up the standard stuff */
218 bmp_info->bmiHeader.biWidth=width;
219 bmp_info->bmiHeader.biHeight=height;
220 bmp_info->bmiHeader.biPlanes=1;
221 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
222 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
223 bmp_info->bmiHeader.biYPelsPerMeter=0;
228 /* Given a pixmap filename, look through all of the "standard" places
229 where the file might be located. Return a full pathname if found;
230 otherwise, return Qnil. */
233 mswindows_locate_pixmap_file (Lisp_Object name)
235 /* This function can GC if IN_REDISPLAY is false */
238 /* Check non-absolute pathnames with a directory component relative to
239 the search path; that's the way Xt does it. */
240 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
241 (XSTRING_BYTE (name, 0) == '.' &&
242 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
243 (XSTRING_BYTE (name, 1) == '.' &&
244 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
246 if (!NILP (Ffile_readable_p (name)))
252 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
254 Lisp_Object temp = list1 (Vdata_directory);
258 locate_file (temp, name, Qnil, &found, R_OK);
266 /* Initialize an image instance from a bitmap
268 DEST_MASK specifies the mask of allowed image types.
270 If this fails, signal an error. INSTANTIATOR is only used
271 in the error message. */
274 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
275 BITMAPINFO *bmp_info,
279 Lisp_Object instantiator,
280 int x_hot, int y_hot,
283 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
284 struct device *d = XDEVICE (device);
291 if (!DEVICE_MSWINDOWS_P (d))
292 signal_simple_error ("Not an mswindows device", device);
294 if (NILP (DEVICE_SELECTED_FRAME (d)))
295 signal_simple_error ("No selected frame on mswindows device", device);
297 f = XFRAME (DEVICE_SELECTED_FRAME (d));
299 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
300 type = IMAGE_COLOR_PIXMAP;
301 else if (dest_mask & IMAGE_POINTER_MASK)
302 type = IMAGE_POINTER;
304 incompatible_image_types (instantiator, dest_mask,
305 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
306 hdc = FRAME_MSWINDOWS_CDC (f);
308 bitmap=CreateDIBSection (hdc,
314 if (!bitmap || !bmp_buf)
315 signal_simple_error ("Unable to create bitmap", instantiator);
317 /* copy in the actual bitmap */
318 memcpy (bmp_buf, bmp_data, bmp_bits);
320 mswindows_initialize_dibitmap_image_instance (ii, type);
322 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
323 find_keyword_in_vector (instantiator, Q_file);
325 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
326 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
327 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
328 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
329 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
330 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
331 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
335 mswindows_initialize_image_instance_mask (ii, f);
338 if (type == IMAGE_POINTER)
340 mswindows_initialize_image_instance_icon(ii, TRUE);
345 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
346 int width, int height,
347 unsigned char *eimage,
349 Lisp_Object instantiator,
352 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
353 BITMAPINFO* bmp_info;
354 unsigned char* bmp_data;
358 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
359 signal_simple_error ("Not an mswindows device", device);
361 /* this is a hack but MaskBlt and TransparentBlt are not supported
362 on most windows variants */
363 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
364 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
366 /* build a bitmap from the eimage */
367 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
368 &bmp_bits, &bmp_data)))
370 signal_simple_error ("EImage to DIBitmap conversion failed",
374 /* Now create the pixmap and set up the image instance */
375 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
376 bmp_data, bmp_bits, instantiator,
383 static void set_mono_pixel ( unsigned char* bits,
384 int bpline, int height,
385 int x, int y, int white )
388 unsigned char bitnum;
389 /* Find the byte on which this scanline begins */
390 index = (height - y - 1) * bpline;
391 /* Find the byte containing this pixel */
393 /* Which bit is it? */
394 bitnum = (unsigned char)( 7 - (x % 8) );
395 if( white ) /* Turn it on */
396 bits[index] |= (1<<bitnum);
397 else /* Turn it off */
398 bits[index] &= ~(1<<bitnum);
402 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
407 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
408 unsigned char* dibits;
409 BITMAPINFO* bmp_info =
410 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
412 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
415 int maskbpline = BPLINE (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8));
416 int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
421 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
422 bmp_info->bmiHeader.biHeight = height;
423 bmp_info->bmiHeader.biPlanes=1;
424 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
425 bmp_info->bmiHeader.biBitCount=1;
426 bmp_info->bmiHeader.biCompression=BI_RGB;
427 bmp_info->bmiHeader.biClrUsed = 2;
428 bmp_info->bmiHeader.biClrImportant = 2;
429 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
430 bmp_info->bmiColors[0].rgbRed = 0;
431 bmp_info->bmiColors[0].rgbGreen = 0;
432 bmp_info->bmiColors[0].rgbBlue = 0;
433 bmp_info->bmiColors[0].rgbReserved = 0;
434 bmp_info->bmiColors[1].rgbRed = 255;
435 bmp_info->bmiColors[1].rgbGreen = 255;
436 bmp_info->bmiColors[1].rgbBlue = 255;
437 bmp_info->bmiColors[0].rgbReserved = 0;
439 if (!(mask = CreateDIBSection (hcdc,
449 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
450 /* build up an in-memory set of bits to mess with */
453 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
454 bmp_info->bmiHeader.biHeight = -height;
455 bmp_info->bmiHeader.biPlanes=1;
456 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
457 bmp_info->bmiHeader.biBitCount=24;
458 bmp_info->bmiHeader.biCompression=BI_RGB;
459 bmp_info->bmiHeader.biClrUsed = 0;
460 bmp_info->bmiHeader.biClrImportant = 0;
461 bmp_info->bmiHeader.biSizeImage = height * bpline;
463 dibits = xmalloc_and_zero (bpline * height);
465 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
470 DIB_RGB_COLORS) <= 0)
476 /* now set the colored bits in the mask and transparent ones to
477 black in the original */
478 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
480 for(j=0; j<height; j++)
482 unsigned char* idx = &dibits[j * bpline + i * 3];
484 if( RGB (idx[2], idx[1], idx[0]) == transparent_color )
486 idx[0] = idx[1] = idx[2] = 0;
487 set_mono_pixel( and_bits, maskbpline, height, i, j, TRUE );
491 set_mono_pixel( and_bits, maskbpline, height, i, j, FALSE );
497 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
507 SelectObject(hcdc, old);
509 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
513 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
518 /* we rely on windows to do any resizing necessary */
519 x_icon.fIcon=cursor ? FALSE : TRUE;
520 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
521 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
522 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
523 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
525 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
526 CreateIconIndirect (&x_icon);
530 mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
536 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
537 HDC hdcDst = CreateCompatibleDC (hcdc);
539 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
541 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
543 old2 = SelectObject (hdcDst, newbmp);
545 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
547 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
548 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
551 DeleteObject (newbmp);
556 SelectObject (hdcDst, old2);
557 SelectObject (hcdc, old1);
564 mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
568 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
572 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
573 HDC hdcDst = CreateCompatibleDC (hcdc);
575 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
576 newmask = CreateCompatibleBitmap(hcdc, newx, newy);
577 old2 = SelectObject (hdcDst, newmask);
579 if (!StretchBlt(hdcDst, 0, 0, newx, newy,
581 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
582 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
585 DeleteObject (newmask);
590 SelectObject (hdcDst, old2);
591 SelectObject (hcdc, old1);
602 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
606 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
607 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
612 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
613 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
614 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
615 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
617 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
618 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
619 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
620 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
625 /**********************************************************************
627 **********************************************************************/
637 static struct color_symbol*
638 extract_xpm_color_names (Lisp_Object device,
640 Lisp_Object color_symbol_alist,
643 /* This function can GC */
645 Lisp_Object results = Qnil;
647 struct color_symbol *colortbl;
648 struct gcpro gcpro1, gcpro2;
650 GCPRO2 (results, device);
652 /* We built up results to be (("name" . #<color>) ...) so that if an
653 error happens we don't lose any malloc()ed data, or more importantly,
654 leave any pixels allocated in the server. */
656 LIST_LOOP (rest, color_symbol_alist)
658 Lisp_Object cons = XCAR (rest);
659 Lisp_Object name = XCAR (cons);
660 Lisp_Object value = XCDR (cons);
666 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
669 assert (COLOR_SPECIFIERP (value));
670 value = Fspecifier_instance (value, domain, Qnil, Qnil);
674 results = noseeum_cons (noseeum_cons (name, value), results);
677 UNGCPRO; /* no more evaluation */
680 if (i == 0) return 0;
682 colortbl = xnew_array_and_zero (struct color_symbol, i);
686 Lisp_Object cons = XCAR (results);
688 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
690 GET_C_STRING_OS_DATA_ALLOCA (XCAR (cons), colortbl[j].name);
691 colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
692 free_cons (XCONS (cons));
694 results = XCDR (results);
695 free_cons (XCONS (cons));
700 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
701 unsigned char** data,
702 int* width, int* height,
703 int* x_hot, int* y_hot,
705 struct color_symbol* color_symbols,
710 int result, i, j, transp_idx, maskbpline;
713 COLORREF color; /* the american spelling virus hits again .. */
718 xpminfo.valuemask=XpmHotspot;
721 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
730 signal_simple_error ("Invalid XPM data", image);
734 signal_double_file_error ("Parsing pixmap data",
735 "out of memory", image);
739 signal_double_file_error_2 ("Parsing pixmap data",
740 "unknown error code",
741 make_int (result), image);
745 *width = xpmimage.width;
746 *height = xpmimage.height;
747 maskbpline = BPLINE (((~7UL & (unsigned long)(*width + 7)) / 8));
749 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
753 XpmFreeXpmImage (&xpmimage);
754 XpmFreeXpmInfo (&xpminfo);
758 /* build a color table to speed things up */
759 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
763 XpmFreeXpmImage (&xpmimage);
764 XpmFreeXpmInfo (&xpminfo);
768 for (i=0; i<xpmimage.ncolors; i++)
771 /* pick up symbolic colors in preference */
772 if (xpmimage.colorTable[i].symbolic)
774 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
776 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
779 colortbl[i]=transparent_color;
781 goto label_found_color;
783 else if (color_symbols)
785 for (j = 0; j<nsymbols; j++)
787 if (!strcmp (xpmimage.colorTable[i].symbolic,
788 color_symbols[j].name ))
790 colortbl[i]=color_symbols[j].color;
791 goto label_found_color;
795 else if (xpmimage.colorTable[i].c_color == 0)
800 /* pick up transparencies */
801 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
804 colortbl[i]=transparent_color;
806 goto label_found_color;
808 /* finally pick up a normal color spec */
809 if (xpmimage.colorTable[i].c_color)
812 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
813 goto label_found_color;
819 XpmFreeXpmImage (&xpmimage);
820 XpmFreeXpmInfo (&xpminfo);
826 /* convert the image */
829 for (i = 0; i< *width * *height; i++)
831 color = colortbl[*sptr++];
833 /* split out the 0x02bbggrr colorref into an rgb triple */
834 *dptr++=GetRValue (color); /* red */
835 *dptr++=GetGValue (color); /* green */
836 *dptr++=GetBValue (color); /* blue */
839 *x_hot=xpminfo.x_hotspot;
840 *y_hot=xpminfo.y_hotspot;
842 XpmFreeXpmImage (&xpmimage);
843 XpmFreeXpmInfo (&xpminfo);
849 mswindows_xpm_instantiate (Lisp_Object image_instance,
850 Lisp_Object instantiator,
851 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
852 int dest_mask, Lisp_Object domain)
854 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
855 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
856 CONST Extbyte *bytes;
858 unsigned char *eimage;
859 int width, height, x_hot, y_hot;
860 BITMAPINFO* bmp_info;
861 unsigned char* bmp_data;
863 int nsymbols=0, transp;
864 struct color_symbol* color_symbols=NULL;
866 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
867 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
870 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
871 signal_simple_error ("Not an mswindows device", device);
873 assert (!NILP (data));
875 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
877 /* in case we have color symbols */
878 color_symbols = extract_xpm_color_names (device, domain,
879 color_symbol_alist, &nsymbols);
881 /* convert to an eimage to make processing easier */
882 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
883 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
885 signal_simple_error ("XPM to EImage conversion failed",
893 xfree (color_symbols[nsymbols].name);
895 xfree(color_symbols);
898 /* build a bitmap from the eimage */
899 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
900 &bmp_bits, &bmp_data)))
902 signal_simple_error ("XPM to EImage conversion failed",
907 /* Now create the pixmap and set up the image instance */
908 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
909 bmp_data, bmp_bits, instantiator,
910 x_hot, y_hot, transp);
915 #endif /* HAVE_XPM */
917 /**********************************************************************
919 **********************************************************************/
922 bmp_validate (Lisp_Object instantiator)
924 file_or_data_must_be_present (instantiator);
928 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
930 return simple_image_type_normalize (inst, console_type, Qbmp);
934 bmp_possible_dest_types (void)
936 return IMAGE_COLOR_PIXMAP_MASK;
940 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
941 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
942 int dest_mask, Lisp_Object domain)
944 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
945 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
946 CONST Extbyte *bytes;
948 BITMAPFILEHEADER* bmp_file_header;
949 BITMAPINFO* bmp_info;
952 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
954 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
955 signal_simple_error ("Not an mswindows device", device);
957 assert (!NILP (data));
959 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
961 /* Then slurp the image into memory, decoding along the way.
962 The result is the image in a simple one-byte-per-pixel
965 bmp_file_header=(BITMAPFILEHEADER*)bytes;
966 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
967 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
968 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
970 /* Now create the pixmap and set up the image instance */
971 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
972 bmp_data, bmp_bits, instantiator,
977 /**********************************************************************
979 **********************************************************************/
982 mswindows_resource_validate (Lisp_Object instantiator)
984 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
986 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
988 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
989 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
994 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type)
996 /* This function can call lisp */
997 Lisp_Object file = Qnil;
998 struct gcpro gcpro1, gcpro2;
999 Lisp_Object alist = Qnil;
1001 GCPRO2 (file, alist);
1003 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1006 if (CONSP (file)) /* failure locating filename */
1007 signal_double_file_error ("Opening pixmap file",
1008 "no such file or directory",
1011 if (NILP (file)) /* no conversion necessary */
1012 RETURN_UNGCPRO (inst);
1014 alist = tagged_vector_to_alist (inst);
1017 alist = remassq_no_quit (Q_file, alist);
1018 alist = Fcons (Fcons (Q_file, file), alist);
1022 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
1024 RETURN_UNGCPRO (result);
1029 mswindows_resource_possible_dest_types (void)
1031 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1041 #define OCR_ICOCUR 32647
1042 #define OIC_SAMPLE 32512
1043 #define OIC_HAND 32513
1044 #define OIC_QUES 32514
1045 #define OIC_BANG 32515
1046 #define OIC_NOTE 32516
1047 #define OIC_WINLOGO 32517
1048 #define LR_SHARED 0x8000
1051 static CONST resource_t bitmap_table[] =
1054 { "close", OBM_CLOSE },
1055 { "uparrow", OBM_UPARROW },
1056 { "dnarrow", OBM_DNARROW },
1057 { "rgarrow", OBM_RGARROW },
1058 { "lfarrow", OBM_LFARROW },
1059 { "reduce", OBM_REDUCE },
1060 { "zoom", OBM_ZOOM },
1061 { "restore", OBM_RESTORE },
1062 { "reduced", OBM_REDUCED },
1063 { "zoomd", OBM_ZOOMD },
1064 { "restored", OBM_RESTORED },
1065 { "uparrowd", OBM_UPARROWD },
1066 { "dnarrowd", OBM_DNARROWD },
1067 { "rgarrowd", OBM_RGARROWD },
1068 { "lfarrowd", OBM_LFARROWD },
1069 { "mnarrow", OBM_MNARROW },
1070 { "combo", OBM_COMBO },
1071 { "uparrowi", OBM_UPARROWI },
1072 { "dnarrowi", OBM_DNARROWI },
1073 { "rgarrowi", OBM_RGARROWI },
1074 { "lfarrowi", OBM_LFARROWI },
1075 { "size", OBM_SIZE },
1076 { "btsize", OBM_BTSIZE },
1077 { "check", OBM_CHECK },
1078 { "checkboxes", OBM_CHECKBOXES },
1079 { "btncorners" , OBM_BTNCORNERS },
1083 static CONST resource_t cursor_table[] =
1086 { "normal", OCR_NORMAL },
1087 { "ibeam", OCR_IBEAM },
1088 { "wait", OCR_WAIT },
1089 { "cross", OCR_CROSS },
1091 /* { "icon", OCR_ICON }, */
1092 { "sizenwse", OCR_SIZENWSE },
1093 { "sizenesw", OCR_SIZENESW },
1094 { "sizewe", OCR_SIZEWE },
1095 { "sizens", OCR_SIZENS },
1096 { "sizeall", OCR_SIZEALL },
1097 /* { "icour", OCR_ICOCUR }, */
1102 static CONST resource_t icon_table[] =
1105 { "sample", OIC_SAMPLE },
1106 { "hand", OIC_HAND },
1107 { "ques", OIC_QUES },
1108 { "bang", OIC_BANG },
1109 { "note", OIC_NOTE },
1110 { "winlogo", OIC_WINLOGO },
1114 static int resource_name_to_resource (Lisp_Object name, int type)
1116 CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1117 : type == IMAGE_ICON ? icon_table
1124 else if (!STRINGP (name))
1126 signal_simple_error ("invalid resource identifier", name);
1131 GET_C_STRING_OS_DATA_ALLOCA (name, nm);
1132 if (!strcasecmp ((char*)res->name, nm))
1133 return res->resource_id;
1134 } while ((++res)->name);
1139 resource_symbol_to_type (Lisp_Object data)
1141 if (EQ (data, Qcursor))
1142 return IMAGE_CURSOR;
1143 else if (EQ (data, Qicon))
1145 else if (EQ (data, Qbitmap))
1146 return IMAGE_BITMAP;
1152 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1153 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1154 int dest_mask, Lisp_Object domain)
1156 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1157 unsigned int type = 0;
1158 HANDLE himage = NULL;
1160 HINSTANCE hinst = NULL;
1164 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1166 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1167 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1169 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1174 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1175 signal_simple_error ("Not an mswindows device", device);
1177 type = resource_symbol_to_type (resource_type);
1179 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1180 iitype = IMAGE_POINTER;
1181 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1182 iitype = IMAGE_COLOR_PIXMAP;
1184 incompatible_image_types (instantiator, dest_mask,
1185 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1187 /* mess with the keyword info we were provided with */
1191 GET_C_STRING_FILENAME_DATA_ALLOCA (file, f);
1193 CYGWIN_WIN32_PATH (f, fname);
1198 if (NILP (resource_id))
1199 resid = (LPCTSTR)fname;
1202 hinst = LoadLibraryEx (fname, NULL,
1203 LOAD_LIBRARY_AS_DATAFILE);
1204 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1208 GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid);
1211 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1213 signal_simple_error ("Invalid resource identifier", resource_id);
1215 /* load the image */
1216 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
1217 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1219 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1221 signal_simple_error ("Cannot load image", instantiator);
1225 FreeLibrary (hinst);
1227 mswindows_initialize_dibitmap_image_instance (ii, iitype);
1229 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1230 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
1231 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1232 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
1233 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1234 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1236 /* hey, we've got an icon type thing so we can reverse engineer the
1238 if (type != IMAGE_BITMAP)
1240 GetIconInfo (himage, &iconinfo);
1241 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1242 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1243 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1244 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1245 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
1249 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1250 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
1251 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1252 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1253 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1258 check_valid_resource_symbol (Lisp_Object data)
1260 CHECK_SYMBOL (data);
1261 if (!resource_symbol_to_type (data))
1262 signal_simple_error ("invalid resource type", data);
1266 check_valid_resource_id (Lisp_Object data)
1268 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1270 !resource_name_to_resource (data, IMAGE_ICON)
1272 !resource_name_to_resource (data, IMAGE_BITMAP))
1273 signal_simple_error ("invalid resource identifier", data);
1277 check_valid_string_or_int (Lisp_Object data)
1280 CHECK_STRING (data);
1285 /**********************************************************************
1287 **********************************************************************/
1288 #ifndef HAVE_X_WINDOWS
1289 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1293 Copyright (c) 1988 X Consortium
1295 Permission is hereby granted, free of charge, to any person obtaining a copy
1296 of this software and associated documentation files (the "Software"), to deal
1297 in the Software without restriction, including without limitation the rights
1298 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1299 copies of the Software, and to permit persons to whom the Software is
1300 furnished to do so, subject to the following conditions:
1302 The above copyright notice and this permission notice shall be included in
1303 all copies or substantial portions of the Software.
1305 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1306 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1307 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1308 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1309 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1310 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1312 Except as contained in this notice, the name of the X Consortium shall not be
1313 used in advertising or otherwise to promote the sale, use or other dealings
1314 in this Software without prior written authorization from the X Consortium.
1319 * This file contains miscellaneous utility routines and is not part of the
1322 * Public entry points:
1324 * XmuReadBitmapData read data from FILE descriptor
1325 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1328 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1329 * that way (but don't use common source code so that people can have one
1330 * without the other).
1335 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1337 #ifndef BitmapSuccess
1338 #define BitmapSuccess 0
1339 #define BitmapOpenFailed 1
1340 #define BitmapFileInvalid 2
1341 #define BitmapNoMemory 3
1343 #define MAX_SIZE 255
1345 /* shared data for the image read/parse logic */
1346 static short hexTable[256]; /* conversion value */
1347 static int initialized = FALSE; /* easier to fill in at run time */
1350 * Table index for the hex values. Initialized once, first time.
1351 * Used for translation value or delimiter significance lookup.
1353 static void initHexTable()
1356 * We build the table at run time for several reasons:
1358 * 1. portable to non-ASCII machines.
1359 * 2. still reentrant since we set the init flag after setting table.
1360 * 3. easier to extend.
1361 * 4. less prone to bugs.
1363 hexTable['0'] = 0; hexTable['1'] = 1;
1364 hexTable['2'] = 2; hexTable['3'] = 3;
1365 hexTable['4'] = 4; hexTable['5'] = 5;
1366 hexTable['6'] = 6; hexTable['7'] = 7;
1367 hexTable['8'] = 8; hexTable['9'] = 9;
1368 hexTable['A'] = 10; hexTable['B'] = 11;
1369 hexTable['C'] = 12; hexTable['D'] = 13;
1370 hexTable['E'] = 14; hexTable['F'] = 15;
1371 hexTable['a'] = 10; hexTable['b'] = 11;
1372 hexTable['c'] = 12; hexTable['d'] = 13;
1373 hexTable['e'] = 14; hexTable['f'] = 15;
1375 /* delimiters of significance are flagged w/ negative value */
1376 hexTable[' '] = -1; hexTable[','] = -1;
1377 hexTable['}'] = -1; hexTable['\n'] = -1;
1378 hexTable['\t'] = -1;
1384 * read next hex value in the input stream, return -1 if EOF
1386 static int NextInt ( FILE *fstream )
1393 /* loop, accumulate hex value until find delimiter */
1394 /* skip any initial delimiters found in read stream */
1402 /* trim high bits, check type and accumulate */
1404 if (isascii(ch) && isxdigit(ch)) {
1405 value = (value << 4) + hexTable[ch];
1407 } else if ((hexTable[ch]) < 0 && gotone)
1416 * The data returned by the following routine is always in left-most byte
1417 * first and left-most bit first. If it doesn't return BitmapSuccess then
1418 * its arguments won't have been touched. This routine should look as much
1419 * like the Xlib routine XReadBitmapfile as possible.
1421 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
1422 FILE *fstream; /* handle on file */
1423 unsigned int *width, *height; /* RETURNED */
1424 unsigned char **datap; /* RETURNED */
1425 int *x_hot, *y_hot; /* RETURNED */
1427 unsigned char *data = NULL; /* working variable */
1428 char line[MAX_SIZE]; /* input line from file */
1429 int size; /* number of bytes of data */
1430 char name_and_type[MAX_SIZE]; /* an input line */
1431 char *type; /* for parsing */
1432 int value; /* from an input line */
1433 int version10p; /* boolean, old format */
1434 int padding; /* to handle alignment */
1435 int bytes_per_line; /* per scanline of data */
1436 unsigned int ww = 0; /* width */
1437 unsigned int hh = 0; /* height */
1438 int hx = -1; /* x hotspot */
1439 int hy = -1; /* y hotspot */
1441 #define Xmalloc(size) malloc(size)
1443 /* first time initialization */
1444 if (initialized == FALSE) initHexTable();
1446 /* error cleanup and return macro */
1447 #define RETURN(code) { if (data) free (data); return code; }
1449 while (fgets(line, MAX_SIZE, fstream)) {
1450 if (strlen(line) == MAX_SIZE-1) {
1451 RETURN (BitmapFileInvalid);
1453 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1454 if (!(type = strrchr(name_and_type, '_')))
1455 type = name_and_type;
1459 if (!strcmp("width", type))
1460 ww = (unsigned int) value;
1461 if (!strcmp("height", type))
1462 hh = (unsigned int) value;
1463 if (!strcmp("hot", type)) {
1464 if (type-- == name_and_type || type-- == name_and_type)
1466 if (!strcmp("x_hot", type))
1468 if (!strcmp("y_hot", type))
1474 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1476 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1478 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1483 if (!(type = strrchr(name_and_type, '_')))
1484 type = name_and_type;
1488 if (strcmp("bits[]", type))
1492 RETURN (BitmapFileInvalid);
1494 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1499 bytes_per_line = (ww+7)/8 + padding;
1501 size = bytes_per_line * hh;
1502 data = (unsigned char *) Xmalloc ((unsigned int) size);
1504 RETURN (BitmapNoMemory);
1510 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1511 if ((value = NextInt(fstream)) < 0)
1512 RETURN (BitmapFileInvalid);
1514 if (!padding || ((bytes+2) % bytes_per_line))
1515 *(ptr++) = value >> 8;
1521 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1522 if ((value = NextInt(fstream)) < 0)
1523 RETURN (BitmapFileInvalid);
1531 RETURN (BitmapFileInvalid);
1538 if (x_hot) *x_hot = hx;
1539 if (y_hot) *y_hot = hy;
1541 RETURN (BitmapSuccess);
1545 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
1546 unsigned int *height, unsigned char **datap,
1547 int *x_hot, int *y_hot)
1552 if ((fstream = fopen (filename, "r")) == NULL) {
1553 return BitmapOpenFailed;
1555 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1559 #endif /* HAVE_X_WINDOWS */
1561 /* this table flips four bits around. */
1562 static int flip_table[] =
1564 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1567 /* the bitmap data comes in the following format: Widths are padded to
1568 a multiple of 8. Scan lines are stored in increasing byte order
1569 from left to right, little-endian within a byte. 0 = white, 1 =
1570 black. It must be converted to the following format: Widths are
1571 padded to a multiple of 16. Scan lines are stored in increasing
1572 byte order from left to right, big-endian within a byte. 0 =
1573 black, 1 = white. */
1575 xbm_create_bitmap_from_data (HDC hdc, char *data,
1576 unsigned int width, unsigned int height,
1577 int mask, COLORREF fg, COLORREF bg)
1579 int old_width = (width + 7)/8;
1580 int new_width = BPLINE (2*((width + 15)/16));
1581 unsigned char *offset;
1583 unsigned char *new_data, *new_offset;
1585 BITMAPINFO* bmp_info =
1586 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1592 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
1600 for (i=0; i<height; i++)
1602 offset = data + i*old_width;
1603 new_offset = new_data + i*new_width;
1605 for (j=0; j<old_width; j++)
1607 int byte = offset[j];
1608 new_offset[j] = ~ (unsigned char)
1609 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1613 /* if we want a mask invert the bits */
1616 new_offset = &new_data[height * new_width];
1617 while (new_offset-- != new_data)
1619 *new_offset ^= 0xff;
1623 bmp_info->bmiHeader.biWidth=width;
1624 bmp_info->bmiHeader.biHeight=-(LONG)height;
1625 bmp_info->bmiHeader.biPlanes=1;
1626 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1627 bmp_info->bmiHeader.biBitCount=1;
1628 bmp_info->bmiHeader.biCompression=BI_RGB;
1629 bmp_info->bmiHeader.biClrUsed = 2;
1630 bmp_info->bmiHeader.biClrImportant = 2;
1631 bmp_info->bmiHeader.biSizeImage = height * new_width;
1632 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1633 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1634 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1635 bmp_info->bmiColors[0].rgbReserved = 0;
1636 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1637 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1638 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1639 bmp_info->bmiColors[1].rgbReserved = 0;
1641 bitmap = CreateDIBSection (hdc,
1649 if (!bitmap || !bmp_buf)
1655 /* copy in the actual bitmap */
1656 memcpy (bmp_buf, new_data, height * new_width);
1662 /* Given inline data for a mono pixmap, initialize the given
1663 image instance accordingly. */
1666 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
1667 int width, int height,
1668 /* Note that data is in ext-format! */
1670 Lisp_Object instantiator,
1671 Lisp_Object pointer_fg,
1672 Lisp_Object pointer_bg,
1675 Lisp_Object mask_filename)
1677 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1678 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device)));
1679 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1680 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1681 enum image_instance_type type;
1682 COLORREF black = PALETTERGB (0,0,0);
1683 COLORREF white = PALETTERGB (255,255,255);
1685 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1687 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1688 signal_simple_error ("Not an MS-Windows device", device);
1690 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1691 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1693 if (!NILP (foreground) || !NILP (background))
1694 type = IMAGE_COLOR_PIXMAP;
1696 type = IMAGE_MONO_PIXMAP;
1698 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1699 type = IMAGE_MONO_PIXMAP;
1700 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1701 type = IMAGE_COLOR_PIXMAP;
1702 else if (dest_mask & IMAGE_POINTER_MASK)
1703 type = IMAGE_POINTER;
1705 incompatible_image_types (instantiator, dest_mask,
1706 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1707 | IMAGE_POINTER_MASK);
1709 mswindows_initialize_dibitmap_image_instance (ii, type);
1711 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1712 find_keyword_in_vector (instantiator, Q_file);
1713 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
1714 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
1715 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1716 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1717 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1718 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1719 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1720 TRUE, black, white);
1724 case IMAGE_MONO_PIXMAP:
1725 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1726 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1727 FALSE, black, black);
1730 case IMAGE_COLOR_PIXMAP:
1732 COLORREF fg = black;
1733 COLORREF bg = white;
1735 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1737 Fmake_color_instance (foreground, device,
1738 encode_error_behavior_flag (ERROR_ME));
1740 if (COLOR_INSTANCEP (foreground))
1741 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1743 if (!NILP (background) && !COLOR_INSTANCEP (background))
1745 Fmake_color_instance (background, device,
1746 encode_error_behavior_flag (ERROR_ME));
1748 if (COLOR_INSTANCEP (background))
1749 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1751 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1752 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1754 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1755 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1762 COLORREF fg = black;
1763 COLORREF bg = white;
1765 if (NILP (foreground))
1766 foreground = pointer_fg;
1767 if (NILP (background))
1768 background = pointer_bg;
1770 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1771 find_keyword_in_vector (instantiator, Q_hotspot_x);
1772 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1773 find_keyword_in_vector (instantiator, Q_hotspot_y);
1774 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1775 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1776 if (COLOR_INSTANCEP (foreground))
1777 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1778 if (COLOR_INSTANCEP (background))
1779 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1781 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1782 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1784 mswindows_initialize_image_instance_icon (ii, TRUE);
1794 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1795 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1796 int dest_mask, int width, int height,
1797 /* Note that data is in ext-format! */
1800 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1801 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1802 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1803 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME
1804 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))));
1805 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1807 CONST char *gcc_may_you_rot_in_hell;
1809 if (!NILP (mask_data))
1811 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
1812 gcc_may_you_rot_in_hell);
1814 xbm_create_bitmap_from_data ( hdc,
1816 gcc_may_you_rot_in_hell,
1817 XINT (XCAR (mask_data)),
1818 XINT (XCAR (XCDR (mask_data))), FALSE,
1820 PALETTERGB (255,255,255));
1823 init_image_instance_from_xbm_inline (ii, width, height, bits,
1824 instantiator, pointer_fg, pointer_bg,
1825 dest_mask, mask, mask_file);
1828 /* Instantiate method for XBM's. */
1831 mswindows_xbm_instantiate (Lisp_Object image_instance,
1832 Lisp_Object instantiator,
1833 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1834 int dest_mask, Lisp_Object domain)
1836 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1837 CONST char *gcc_go_home;
1839 assert (!NILP (data));
1841 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
1844 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1845 pointer_bg, dest_mask, XINT (XCAR (data)),
1846 XINT (XCAR (XCDR (data))), gcc_go_home);
1850 /**********************************************************************
1852 **********************************************************************/
1854 /* This is about to get redefined! */
1857 /* We have to define SYSV32 so that compface.h includes string.h
1858 instead of strings.h. */
1863 #include <compface.h>
1867 /* JMP_BUF cannot be used here because if it doesn't get defined
1868 to jmp_buf we end up with a conflicting type error with the
1869 definition in compface.h */
1870 extern jmp_buf comp_env;
1874 mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1875 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1876 int dest_mask, Lisp_Object domain)
1878 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1880 char *p, *bits, *bp;
1881 CONST char * volatile emsg = 0;
1882 CONST char * volatile dstring;
1884 assert (!NILP (data));
1886 GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring);
1888 if ((p = strchr (dstring, ':')))
1893 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
1894 if (!(stattis = setjmp (comp_env)))
1896 UnCompAll ((char *) dstring);
1903 emsg = "uncompface: internal error";
1906 emsg = "uncompface: insufficient or invalid data";
1909 emsg = "uncompface: excess data ignored";
1914 signal_simple_error_2 (emsg, data, Qimage);
1916 bp = bits = (char *) alloca (PIXELS / 8);
1918 /* the compface library exports char F[], which uses a single byte per
1919 pixel to represent a 48x48 bitmap. Yuck. */
1920 for (i = 0, p = F; i < (PIXELS / 8); ++i)
1923 /* reverse the bit order of each byte... */
1924 for (b = n = 0; b < 8; ++b)
1931 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1932 pointer_bg, dest_mask, 48, 48, bits);
1934 #endif /* HAVE_XFACE */
1937 /************************************************************************/
1938 /* image instance methods */
1939 /************************************************************************/
1942 mswindows_print_image_instance (struct Lisp_Image_Instance *p,
1943 Lisp_Object printcharfun,
1948 switch (IMAGE_INSTANCE_TYPE (p))
1950 case IMAGE_MONO_PIXMAP:
1951 case IMAGE_COLOR_PIXMAP:
1953 sprintf (buf, " (0x%lx",
1954 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1955 write_c_string (buf, printcharfun);
1956 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1958 sprintf (buf, "/0x%lx",
1959 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1960 write_c_string (buf, printcharfun);
1962 write_c_string (")", printcharfun);
1971 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
1973 if (DEVICE_LIVE_P (XDEVICE (p->device)))
1975 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET
1977 IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
1979 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
1980 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
1981 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
1985 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
1986 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
1987 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
1988 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
1989 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
1990 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
1991 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
1992 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
1993 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2004 /************************************************************************/
2005 /* subwindow and widget support */
2006 /************************************************************************/
2008 /* unmap the image if it is a widget. This is used by redisplay via
2009 redisplay_unmap_subwindows */
2011 mswindows_unmap_subwindow (struct Lisp_Image_Instance *p)
2013 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2015 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2018 SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
2019 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2023 /* map the subwindow. This is used by redisplay via
2024 redisplay_output_subwindow */
2026 mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y)
2028 /* ShowWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), SW_SHOW);*/
2029 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2032 SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSIZE
2033 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2036 /* when you click on a widget you may activate another widget this
2037 needs to be checked and all appropriate widgets updated */
2039 mswindows_update_subwindow (struct Lisp_Image_Instance *p)
2041 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
2043 /* buttons checked or otherwise */
2044 if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton))
2046 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_SINGLE_ITEM (p)))
2047 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2048 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2050 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2051 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2056 /* register widgets into our hastable so that we can cope with the
2057 callbacks. The hashtable is weak so deregistration is handled
2060 mswindows_register_gui_item (Lisp_Object gui, Lisp_Object domain)
2062 Lisp_Object frame = FW_FRAME (domain);
2063 struct frame* f = XFRAME (frame);
2064 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f),
2067 Fputhash (make_int (id),
2068 XGUI_ITEM (gui)->callback,
2069 FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
2074 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2076 return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_SINGLE_ITEM (instance),
2081 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2082 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2083 int dest_mask, Lisp_Object domain)
2085 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2086 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2087 struct device* d = XDEVICE (device);
2088 Lisp_Object frame = FW_FRAME (domain);
2091 if (!DEVICE_MSWINDOWS_P (d))
2092 signal_simple_error ("Not an mswindows device", device);
2094 /* have to set the type this late in case there is no device
2095 instantiation for a widget */
2096 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2098 wnd = CreateWindow( "STATIC",
2101 0, /* starting x position */
2102 0, /* starting y position */
2103 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2104 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2105 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), /* parent window */
2108 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2112 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2113 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2117 mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
2118 struct Lisp_Image_Instance *p2, int depth)
2120 switch (IMAGE_INSTANCE_TYPE (p1))
2122 case IMAGE_MONO_PIXMAP:
2123 case IMAGE_COLOR_PIXMAP:
2125 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2126 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2137 static unsigned long
2138 mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
2140 switch (IMAGE_INSTANCE_TYPE (p))
2142 case IMAGE_MONO_PIXMAP:
2143 case IMAGE_COLOR_PIXMAP:
2145 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2152 /* Set all the slots in an image instance structure to reasonable
2153 default values. This is used somewhere within an instantiate
2154 method. It is assumed that the device slot within the image
2155 instance is already set -- this is the case when instantiate
2156 methods are called. */
2159 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
2160 enum image_instance_type type)
2162 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2163 IMAGE_INSTANCE_TYPE (ii) = type;
2164 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2165 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2166 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2167 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2168 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2169 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2173 /************************************************************************/
2175 /************************************************************************/
2177 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2178 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2179 int dest_mask, Lisp_Object domain,
2180 CONST char* class, int flags, int exflags)
2182 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2184 struct Lisp_Image_Instance *groupii = 0;
2185 Lisp_Object group = find_keyword_in_vector (instantiator, Q_group);
2187 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2188 struct device* d = XDEVICE (device);
2189 Lisp_Object frame = FW_FRAME (domain);
2193 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2194 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2196 if (!DEVICE_MSWINDOWS_P (d))
2197 signal_simple_error ("Not an mswindows device", device);
2199 /* if the user specified another glyph as a group pick up the
2200 instance in our domain. */
2203 if (SYMBOLP (group))
2204 group = XSYMBOL (group)->value;
2205 group = glyph_image_instance (group, domain, ERROR_ME, 1);
2206 groupii = XIMAGE_INSTANCE (group);
2209 if (!gui_item_active_p (gui))
2210 flags |= WS_DISABLED;
2212 style = pgui->style;
2214 if (!NILP (pgui->callback))
2216 id = mswindows_register_widget_instance (image_instance, domain);
2218 /* have to set the type this late in case there is no device
2219 instantiation for a widget */
2220 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
2221 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2222 GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
2224 wnd = CreateWindowEx(
2225 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2229 0, /* starting x position */
2230 0, /* starting y position */
2231 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2232 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2234 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2235 (HMENU)id, /* No menu */
2237 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2241 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2242 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2243 /* set the widget font from the widget face */
2244 SendMessage (wnd, WM_SETFONT,
2245 (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
2246 (XFONT_INSTANCE (widget_face_font_info
2248 IMAGE_INSTANCE_WIDGET_FACE (ii),
2250 MAKELPARAM (TRUE, 0));
2253 /* Instantiate a button widget. Unfortunately instantiated widgets are
2254 particular to a frame since they need to have a parent. It's not
2255 like images where you just select the image into the context you
2256 want to display it in and BitBlt it. So images instances can have a
2257 many-to-one relationship with things you see, whereas widgets can
2258 only be one-to-one (i.e. per frame) */
2260 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2261 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2262 int dest_mask, Lisp_Object domain)
2264 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2266 int flags = BS_NOTIFY;
2268 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2269 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2270 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2272 if (!gui_item_active_p (gui))
2273 flags |= WS_DISABLED;
2277 if (!IMAGE_INSTANCEP (glyph))
2278 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2280 if (IMAGE_INSTANCEP (glyph))
2281 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2282 BS_BITMAP : BS_ICON;
2285 style = pgui->style;
2287 if (EQ (style, Qradio))
2289 flags |= BS_RADIOBUTTON;
2291 else if (EQ (style, Qtoggle))
2293 flags |= BS_AUTOCHECKBOX;
2296 flags |= BS_DEFPUSHBUTTON;
2298 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2299 pointer_bg, dest_mask, domain, "BUTTON", flags,
2300 WS_EX_CONTROLPARENT);
2302 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2303 /* set the checked state */
2304 if (gui_item_selected_p (gui))
2305 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2307 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2308 /* add the image if one was given */
2309 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph))
2311 SendMessage (wnd, BM_SETIMAGE,
2312 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2313 IMAGE_BITMAP : IMAGE_ICON),
2314 (LPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2315 XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2316 XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2320 /* instantiate an edit control */
2322 mswindows_edit_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2323 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2324 int dest_mask, Lisp_Object domain)
2326 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2327 pointer_bg, dest_mask, domain, "EDIT",
2328 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2330 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2333 /* instantiate a progress gauge */
2335 mswindows_progress_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2336 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2337 int dest_mask, Lisp_Object domain)
2340 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2341 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2342 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2343 WS_TABSTOP | WS_BORDER | PBS_SMOOTH,
2344 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2345 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2346 /* set the colors */
2347 #ifdef PBS_SETBKCOLOR
2348 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2349 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2352 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2353 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2355 #ifdef PBS_SETBARCOLOR
2356 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2357 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2360 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2361 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2365 /* instantiate a tree view widget */
2366 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2367 HWND wnd, HTREEITEM parent, Lisp_Object entry,
2368 int children, Lisp_Object domain)
2370 TV_INSERTSTRUCT tvitem;
2373 tvitem.hParent = parent;
2374 tvitem.hInsertAfter = TVI_LAST;
2375 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2376 tvitem.item.cChildren = children;
2378 if (VECTORP (entry))
2380 /* we always maintain the real gui item at the head of the
2381 list. We have to put them in the list in the first place
2382 because the whole model assumes that the glyph instances have
2383 references to all the associated data. If we didn't do this
2384 GC would bite us badly. */
2385 Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
2386 if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
2389 Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
2390 Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
2394 XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
2395 Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
2398 tvitem.item.lParam = mswindows_register_gui_item (gui, domain);
2399 tvitem.item.mask |= TVIF_PARAM;
2400 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
2401 tvitem.item.pszText);
2404 GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.item.pszText);
2406 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2408 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2409 0, (LPARAM)&tvitem)) == 0)
2410 signal_simple_error ("error adding tree view entry", entry);
2415 static void add_tree_item_list (Lisp_Object image_instance,
2416 HWND wnd, HTREEITEM parent, Lisp_Object list,
2421 /* get the first item */
2422 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2423 /* recursively add items to the tree view */
2424 LIST_LOOP (rest, XCDR (list))
2426 if (LISTP (XCAR (rest)))
2427 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2429 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2434 mswindows_tree_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2435 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2436 int dest_mask, Lisp_Object domain)
2441 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2442 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2443 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2444 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2445 | TVS_HASLINES | TVS_HASBUTTONS,
2446 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2448 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2451 parent = add_tree_item (image_instance,
2452 wnd, NULL, IMAGE_INSTANCE_WIDGET_TEXT (ii), TRUE,
2455 /* recursively add items to the tree view */
2456 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2458 if (LISTP (XCAR (rest)))
2459 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2461 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2465 /* instantiate a tab control */
2466 static TC_ITEM* add_tab_item (Lisp_Object image_instance,
2467 HWND wnd, Lisp_Object entry,
2468 Lisp_Object domain, int index)
2470 TC_ITEM tvitem, *ret;
2472 tvitem.mask = TCIF_TEXT;
2474 if (VECTORP (entry))
2476 /* we always maintain the real gui item at the head of the
2477 list. We have to put them in the list in the first place
2478 because the whole model assumes that the glyph instances have
2479 references to all the associated data. If we didn't do this
2480 GC would bite us badly. */
2481 Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
2482 if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
2485 Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
2486 Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
2490 XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
2491 Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
2494 tvitem.lParam = mswindows_register_gui_item (gui, domain);
2495 tvitem.mask |= TCIF_PARAM;
2496 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
2500 GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.pszText);
2502 tvitem.cchTextMax = strlen (tvitem.pszText);
2504 if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
2505 index, (LPARAM)&tvitem)) < 0)
2506 signal_simple_error ("error adding tab entry", entry);
2512 mswindows_tab_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2513 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2514 int dest_mask, Lisp_Object domain)
2520 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2521 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2522 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2523 /* borders don't suit tabs so well */
2525 WS_EX_CONTROLPARENT);
2527 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2529 /* add items to the tab */
2530 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2532 add_tab_item (image_instance, wnd, XCAR (rest), domain, index);
2537 /* instantiate a static control possible for putting other things in */
2539 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2540 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2541 int dest_mask, Lisp_Object domain)
2543 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2544 pointer_bg, dest_mask, domain, "STATIC",
2545 0, WS_EX_STATICEDGE);
2549 /* instantiate a static control possible for putting other things in */
2551 mswindows_group_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2552 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2553 int dest_mask, Lisp_Object domain)
2555 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2556 pointer_bg, dest_mask, domain, "BUTTON",
2557 WS_GROUP | BS_GROUPBOX | WS_BORDER,
2562 /* instantiate a scrollbar control */
2564 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2565 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2566 int dest_mask, Lisp_Object domain)
2568 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2569 pointer_bg, dest_mask, domain, "SCROLLBAR",
2574 /* instantiate a combo control */
2576 mswindows_combo_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2577 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2578 int dest_mask, Lisp_Object domain)
2580 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2584 /* Maybe ought to generalise this more but it may be very windows
2585 specific. In windows the window height of a combo box is the
2586 height when the combo box is open. Thus we need to set the height
2587 before creating the window and then reset it to a single line
2588 after the window is created so that redisplay does the right
2590 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2591 pointer_bg, dest_mask, domain, "COMBOBOX",
2592 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
2594 | CBS_HASSTRINGS | WS_VSCROLL,
2595 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2596 /* reset the height */
2597 widget_text_to_pixel_conversion (domain,
2598 IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0,
2599 &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0);
2600 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2601 /* add items to the combo box */
2602 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
2603 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2606 GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam);
2607 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
2608 signal_simple_error ("error adding combo entries", instantiator);
2612 /* get properties of a control */
2614 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
2616 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2617 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2618 /* get the text from a control */
2619 if (EQ (prop, Q_text))
2621 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
2622 Extbyte* buf =alloca (len+1);
2624 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
2625 return build_ext_string (buf, FORMAT_OS);
2630 /* get properties of a button */
2632 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
2634 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2635 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2636 /* check the state of a button */
2637 if (EQ (prop, Q_selected))
2639 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
2647 /* get properties of a combo box */
2649 mswindows_combo_property (Lisp_Object image_instance, Lisp_Object prop)
2651 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2652 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2653 /* get the text from a control */
2654 if (EQ (prop, Q_text))
2656 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
2657 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
2658 Extbyte* buf = alloca (len+1);
2659 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
2660 return build_ext_string (buf, FORMAT_OS);
2665 /* set the properties of a control */
2667 mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
2670 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2672 if (EQ (prop, Q_text))
2676 GET_C_STRING_OS_DATA_ALLOCA (val, lparam);
2677 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2678 WM_SETTEXT, 0, (LPARAM)lparam);
2684 /* set the properties of a progres guage */
2686 mswindows_progress_set_property (Lisp_Object image_instance, Lisp_Object prop,
2689 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2691 if (EQ (prop, Q_percent))
2694 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2695 PBM_SETPOS, (WPARAM)XINT (val), 0);
2702 /************************************************************************/
2703 /* initialization */
2704 /************************************************************************/
2707 syms_of_glyphs_mswindows (void)
2709 defkeyword (&Q_resource_id, ":resource-id");
2710 defkeyword (&Q_resource_type, ":resource-type");
2714 console_type_create_glyphs_mswindows (void)
2718 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
2719 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
2720 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
2721 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
2722 CONSOLE_HAS_METHOD (mswindows, update_subwindow);
2723 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
2724 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
2725 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
2726 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
2730 image_instantiator_format_create_glyphs_mswindows (void)
2732 /* image-instantiator types */
2734 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
2735 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
2737 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
2738 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
2740 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
2741 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
2744 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
2745 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
2746 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
2748 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit);
2749 IIFORMAT_HAS_DEVMETHOD (mswindows, edit, instantiate);
2751 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
2752 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
2754 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
2755 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
2756 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property);
2758 INITIALIZE_DEVICE_IIFORMAT (mswindows, group);
2759 IIFORMAT_HAS_DEVMETHOD (mswindows, group, instantiate);
2762 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
2763 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
2766 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo);
2767 IIFORMAT_HAS_DEVMETHOD (mswindows, combo, property);
2768 IIFORMAT_HAS_DEVMETHOD (mswindows, combo, instantiate);
2771 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
2772 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
2774 /* progress gauge */
2775 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress);
2776 IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);
2777 IIFORMAT_HAS_DEVMETHOD (mswindows, progress, instantiate);
2779 /* tree view widget */
2780 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree);
2781 /* IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/
2782 IIFORMAT_HAS_DEVMETHOD (mswindows, tree, instantiate);
2784 /* tab control widget */
2785 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab);
2786 IIFORMAT_HAS_DEVMETHOD (mswindows, tab, instantiate);
2788 /* windows bitmap format */
2789 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
2790 IIFORMAT_HAS_METHOD (bmp, validate);
2791 IIFORMAT_HAS_METHOD (bmp, normalize);
2792 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
2793 IIFORMAT_HAS_METHOD (bmp, instantiate);
2795 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
2796 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
2798 /* mswindows resources */
2799 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
2800 "mswindows-resource");
2802 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
2803 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
2804 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
2805 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
2807 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
2808 check_valid_resource_symbol);
2809 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
2810 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
2814 vars_of_glyphs_mswindows (void)
2817 Fprovide (Qmswindows_resource);
2818 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
2819 A list of the directories in which mswindows bitmap files may be found.
2820 This is used by the `make-image-instance' function.
2822 Vmswindows_bitmap_file_path = Qnil;
2827 Fprovide (Qscrollbar);
2829 Fprovide (Qprogress);
2835 complex_vars_of_glyphs_mswindows (void)