1 /* mswindows-specific glyph objects.
2 Copyright (C) 1998, 1999, 2000 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> plagiarising bits from
30 #define OEMRESOURCE /* Define OCR_ and friend constants */
31 #include "console-msw.h"
32 #include "glyphs-msw.h"
33 #include "objects-msw.h"
46 #include "file-coding.h"
54 #define WIDGET_GLYPH_SLOT 0
56 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
57 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
58 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
59 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
61 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
64 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff);
67 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png);
70 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif);
73 DEFINE_DEVICE_IIFORMAT (mswindows, xpm);
74 DEFINE_DEVICE_IIFORMAT (msprinter, xpm);
76 DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
77 DEFINE_DEVICE_IIFORMAT (msprinter, xbm);
79 DEFINE_DEVICE_IIFORMAT (mswindows, xface);
80 DEFINE_DEVICE_IIFORMAT (msprinter, xface);
82 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
83 DEFINE_DEVICE_IIFORMAT (mswindows, native_layout);
84 DEFINE_DEVICE_IIFORMAT (mswindows, button);
85 DEFINE_DEVICE_IIFORMAT (mswindows, edit_field);
86 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
87 DEFINE_DEVICE_IIFORMAT (mswindows, widget);
88 DEFINE_DEVICE_IIFORMAT (mswindows, label);
89 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
90 DEFINE_DEVICE_IIFORMAT (mswindows, combo_box);
91 DEFINE_DEVICE_IIFORMAT (mswindows, progress_gauge);
92 DEFINE_DEVICE_IIFORMAT (mswindows, tree_view);
93 DEFINE_DEVICE_IIFORMAT (mswindows, tab_control);
95 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
97 Lisp_Object Vmswindows_bitmap_file_path;
98 static COLORREF transparent_color = RGB (1,1,1);
100 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource);
101 Lisp_Object Q_resource_type, Q_resource_id;
102 Lisp_Object Qmswindows_resource;
105 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
107 enum image_instance_type type);
109 mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
113 * Given device D, retrieve compatible device context. D can be either
114 * mswindows or an msprinter device.
117 get_device_compdc (struct device *d)
119 if (DEVICE_MSWINDOWS_P (d))
120 return DEVICE_MSWINDOWS_HCDC (d);
122 return DEVICE_MSPRINTER_HCDC (d);
126 * Initialize image instance pixel sizes in II. For a display bitmap,
127 * these will be same as real bitmap sizes. For a printer bitmap,
128 * these will be scaled up so that the bitmap is proportionally enlarged
129 * when output to printer. Redisplay code takes care of scaling, to
130 * conserve memory we do not really scale bitmaps. Set the watermark
132 * #### Add support for unscalable bitmaps.
134 static void init_image_instance_geometry (Lisp_Image_Instance *ii)
136 struct device *d = DOMAIN_XDEVICE (ii->domain);
138 if (/* #### Scaleable && */ DEVICE_MSPRINTER_P (d))
140 HDC printer_dc = DEVICE_MSPRINTER_HCDC (d);
141 HDC display_dc = CreateCompatibleDC (NULL);
142 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
143 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
144 GetDeviceCaps (printer_dc, LOGPIXELSX),
145 GetDeviceCaps (display_dc, LOGPIXELSX));
146 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
147 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
148 GetDeviceCaps (printer_dc, LOGPIXELSY),
149 GetDeviceCaps (display_dc, LOGPIXELSY));
153 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
154 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii);
155 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
156 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii);
160 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
162 /************************************************************************/
163 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
165 /************************************************************************/
166 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
167 int width, int height,
170 unsigned char** bmp_data)
172 struct device *d = XDEVICE (device);
176 BITMAPINFO* bmp_info;
177 unsigned char *ip, *dp;
179 if (GetDeviceCaps (get_device_compdc (d), BITSPIXEL) > 0)
181 int bpline = BPLINE(width * 3);
182 /* FIXME: we can do this because 24bpp implies no color table, once
183 * we start palettizing this is no longer true. The X versions of
184 * this function quantises to 256 colors or bit masks down to a
185 * long. Windows can actually handle rgb triples in the raw so I
186 * don't see much point trying to optimize down to the best
187 * structure - unless it has memory / color allocation implications
189 bmp_info=xnew_and_zero (BITMAPINFO);
196 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
197 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
198 bmp_info->bmiHeader.biSizeImage=width*height*3;
200 /* bitmap data needs to be in blue, green, red triples - in that
201 order, eimage is in RGB format so we need to convert */
202 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
203 *bit_count = bpline * height;
212 for (i = height-1; i >= 0; i--) {
213 dp = (*bmp_data) + (i * bpline);
214 for (j = 0; j < width; j++) {
222 else /* scale to 256 colors */
226 int bpline = BPLINE (width * 3);
227 /* Quantize the image and get a histogram while we're at it.
228 Do this first to save memory */
229 qtable = build_EImage_quantable(pic, width, height, 256);
230 if (qtable == NULL) return NULL;
232 /* use our quantize table to allocate the colors */
233 ncolors = qtable->num_active_colors;
234 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
235 sizeof(RGBQUAD) * ncolors);
242 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
244 bmp_info->bmiHeader.biBitCount=8;
245 bmp_info->bmiHeader.biCompression=BI_RGB;
246 bmp_info->bmiHeader.biSizeImage=bpline*height;
247 bmp_info->bmiHeader.biClrUsed=ncolors;
248 bmp_info->bmiHeader.biClrImportant=ncolors;
250 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
251 *bit_count = bpline * height;
260 /* build up an RGBQUAD colortable */
261 for (i = 0; i < qtable->num_active_colors; i++)
263 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
264 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
265 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
266 colortbl[i].rgbReserved = 0;
269 /* now build up the data. picture has to be upside-down and
270 back-to-front for msw bitmaps */
272 for (i = height-1; i >= 0; i--)
274 dp = (*bmp_data) + (i * bpline);
275 for (j = 0; j < width; j++)
280 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
285 /* fix up the standard stuff */
286 bmp_info->bmiHeader.biWidth=width;
287 bmp_info->bmiHeader.biHeight=height;
288 bmp_info->bmiHeader.biPlanes=1;
289 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
290 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
291 bmp_info->bmiHeader.biYPelsPerMeter=0;
296 /* Given a pixmap filename, look through all of the "standard" places
297 where the file might be located. Return a full pathname if found;
298 otherwise, return Qnil. */
301 mswindows_locate_pixmap_file (Lisp_Object name)
303 /* This function can GC if IN_REDISPLAY is false */
306 /* Check non-absolute pathnames with a directory component relative to
307 the search path; that's the way Xt does it. */
308 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
309 (XSTRING_BYTE (name, 0) == '.' &&
310 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
311 (XSTRING_BYTE (name, 1) == '.' &&
312 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
314 if (!NILP (Ffile_readable_p (name)))
315 return Fexpand_file_name (name, Qnil);
320 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
322 Lisp_Object temp = list1 (Vdata_directory);
326 locate_file (temp, name, Qnil, &found, R_OK);
334 /* Initialize an image instance from a bitmap
336 DEST_MASK specifies the mask of allowed image types.
338 If this fails, signal an error. INSTANTIATOR is only used
339 in the error message. */
342 init_image_instance_from_dibitmap (Lisp_Image_Instance *ii,
343 BITMAPINFO *bmp_info,
348 Lisp_Object instantiator,
349 int x_hot, int y_hot,
352 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii));
354 enum image_instance_type type;
358 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
359 type = IMAGE_COLOR_PIXMAP;
360 else if (dest_mask & IMAGE_POINTER_MASK)
361 type = IMAGE_POINTER;
363 incompatible_image_types (instantiator, dest_mask,
364 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
366 hdc = get_device_compdc (d);
367 bitmap = CreateDIBSection (hdc,
373 if (!bitmap || !bmp_buf)
374 signal_simple_error ("Unable to create bitmap", instantiator);
376 /* copy in the actual bitmap */
377 memcpy (bmp_buf, bmp_data, bmp_bits);
379 mswindows_initialize_dibitmap_image_instance (ii, slices, type);
381 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
382 find_keyword_in_vector (instantiator, Q_file);
384 /* Fixup a set of bitmaps. */
385 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
387 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
388 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
389 bmp_info->bmiHeader.biWidth;
390 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
391 bmp_info->bmiHeader.biHeight;
392 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
393 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
394 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
395 init_image_instance_geometry (ii);
399 mswindows_initialize_image_instance_mask (ii, hdc);
402 if (type == IMAGE_POINTER)
404 mswindows_initialize_image_instance_icon(ii, TRUE);
409 image_instance_add_dibitmap (Lisp_Image_Instance *ii,
410 BITMAPINFO *bmp_info,
414 Lisp_Object instantiator)
416 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii));
419 HBITMAP bitmap = CreateDIBSection (get_device_compdc (d),
425 if (!bitmap || !bmp_buf)
426 signal_simple_error ("Unable to create bitmap", instantiator);
428 /* copy in the actual bitmap */
429 memcpy (bmp_buf, bmp_data, bmp_bits);
430 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (ii, slice) = bitmap;
434 mswindows_init_image_instance_from_eimage (Lisp_Image_Instance *ii,
435 int width, int height,
437 unsigned char *eimage,
439 Lisp_Object instantiator,
442 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
443 BITMAPINFO* bmp_info;
444 unsigned char* bmp_data;
449 CHECK_MSGDI_DEVICE (device);
451 /* this is a hack but MaskBlt and TransparentBlt are not supported
452 on most windows variants */
453 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
454 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
456 for (slice = 0; slice < slices; slice++)
458 /* build a bitmap from the eimage */
459 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height,
460 eimage + (width * height * 3 * slice),
461 &bmp_bits, &bmp_data)))
463 signal_simple_error ("EImage to DIBitmap conversion failed",
467 /* Now create the pixmap and set up the image instance */
469 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
470 bmp_data, bmp_bits, slices, instantiator,
473 image_instance_add_dibitmap (ii, bmp_info, bmp_data, bmp_bits, slice,
482 set_mono_pixel (unsigned char* bits,
483 int bpline, int height,
484 int x, int y, int white)
487 unsigned char bitnum;
488 /* Find the byte on which this scanline begins */
489 i = (height - y - 1) * bpline;
490 /* Find the byte containing this pixel */
492 /* Which bit is it? */
493 bitnum = (unsigned char) (7 - (x & 7));
494 if (white) /* Turn it on */
495 bits[i] |= (1 << bitnum);
496 else /* Turn it off */
497 bits[i] &= ~(1 << bitnum);
501 mswindows_initialize_image_instance_mask (Lisp_Image_Instance* image,
506 unsigned char *dibits, *and_bits;
507 BITMAPINFO *bmp_info =
508 (BITMAPINFO*) xmalloc_and_zero (sizeof (BITMAPINFO) + sizeof (RGBQUAD));
510 int height = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (image);
512 int maskbpline = BPLINE ((IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) + 7) / 8);
513 int bpline = BPLINE (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) * 3);
518 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
519 bmp_info->bmiHeader.biHeight = height;
520 bmp_info->bmiHeader.biPlanes = 1;
521 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
522 bmp_info->bmiHeader.biBitCount = 1;
523 bmp_info->bmiHeader.biCompression = BI_RGB;
524 bmp_info->bmiHeader.biClrUsed = 2;
525 bmp_info->bmiHeader.biClrImportant = 2;
526 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
527 bmp_info->bmiColors[0].rgbRed = 0;
528 bmp_info->bmiColors[0].rgbGreen = 0;
529 bmp_info->bmiColors[0].rgbBlue = 0;
530 bmp_info->bmiColors[0].rgbReserved = 0;
531 bmp_info->bmiColors[1].rgbRed = 255;
532 bmp_info->bmiColors[1].rgbGreen = 255;
533 bmp_info->bmiColors[1].rgbBlue = 255;
534 bmp_info->bmiColors[0].rgbReserved = 0;
536 if (!(mask = CreateDIBSection (hcdc,
546 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
547 /* build up an in-memory set of bits to mess with */
550 bmp_info->bmiHeader.biWidth = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image);
551 bmp_info->bmiHeader.biHeight = -height;
552 bmp_info->bmiHeader.biPlanes = 1;
553 bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
554 bmp_info->bmiHeader.biBitCount = 24;
555 bmp_info->bmiHeader.biCompression = BI_RGB;
556 bmp_info->bmiHeader.biClrUsed = 0;
557 bmp_info->bmiHeader.biClrImportant = 0;
558 bmp_info->bmiHeader.biSizeImage = height * bpline;
560 dibits = (unsigned char*) xmalloc_and_zero (bpline * height);
562 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
567 DIB_RGB_COLORS) <= 0)
573 /* now set the colored bits in the mask and transparent ones to
574 black in the original */
575 for (i = 0; i < IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); i++)
577 for (j=0; j<height; j++)
579 unsigned char* idx = &dibits[j * bpline + i * 3];
581 if (RGB (idx[2], idx[1], idx[0]) == transparent_color)
583 idx[0] = idx[1] = idx[2] = 0;
584 set_mono_pixel (and_bits, maskbpline, height, i, j, TRUE);
588 set_mono_pixel (and_bits, maskbpline, height, i, j, FALSE);
594 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
604 SelectObject(hcdc, old);
606 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
610 mswindows_initialize_image_instance_icon (Lisp_Image_Instance* image,
615 /* we rely on windows to do any resizing necessary */
616 x_icon.fIcon=cursor ? FALSE : TRUE;
617 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
618 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
619 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
620 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
622 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
623 CreateIconIndirect (&x_icon);
627 create_resized_bitmap (HBITMAP curbmp, struct frame *f,
634 HDC hcdc = get_device_compdc (XDEVICE (FRAME_DEVICE (f)));
635 HDC hdcDst = CreateCompatibleDC (hcdc);
637 old1 = SelectObject (hcdc, curbmp);
639 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
641 old2 = SelectObject (hdcDst, newbmp);
643 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
649 DeleteObject (newbmp);
654 SelectObject (hdcDst, old2);
655 SelectObject (hcdc, old1);
662 mswindows_create_resized_bitmap (Lisp_Image_Instance* ii,
666 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii),
668 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
669 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
674 mswindows_create_resized_mask (Lisp_Image_Instance* ii,
678 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii) == NULL)
681 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_MASK (ii),
683 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii),
684 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii),
688 #if 0 /* Currently unused */
689 /* #### Warining: This function is not correct anymore with
690 resizable printer bitmaps. If you uncomment it, clean it. --kkm */
692 mswindows_resize_dibitmap_instance (Lisp_Image_Instance* ii,
696 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
697 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
702 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
703 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
704 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
705 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
707 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
708 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
709 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
710 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
716 /**********************************************************************
718 **********************************************************************/
728 static struct color_symbol*
729 extract_xpm_color_names (Lisp_Object device,
731 Lisp_Object color_symbol_alist,
734 /* This function can GC */
736 Lisp_Object results = Qnil;
738 struct color_symbol *colortbl;
739 struct gcpro gcpro1, gcpro2;
741 GCPRO2 (results, device);
743 /* We built up results to be (("name" . #<color>) ...) so that if an
744 error happens we don't lose any malloc()ed data, or more importantly,
745 leave any pixels allocated in the server. */
747 LIST_LOOP (rest, color_symbol_alist)
749 Lisp_Object cons = XCAR (rest);
750 Lisp_Object name = XCAR (cons);
751 Lisp_Object value = XCDR (cons);
757 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
760 assert (COLOR_SPECIFIERP (value));
761 value = Fspecifier_instance (value, domain, Qnil, Qnil);
765 results = noseeum_cons (noseeum_cons (name, value), results);
768 UNGCPRO; /* no more evaluation */
771 if (i == 0) return 0;
773 colortbl = xnew_array_and_zero (struct color_symbol, i);
777 Lisp_Object cons = XCAR (results);
779 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
781 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (cons),
782 C_STRING_ALLOCA, colortbl[j].name,
784 colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
785 free_cons (XCONS (cons));
787 results = XCDR (results);
788 free_cons (XCONS (cons));
793 static int xpm_to_eimage (Lisp_Object image, const Extbyte *buffer,
794 unsigned char** data,
795 int* width, int* height,
796 int* x_hot, int* y_hot,
798 struct color_symbol* color_symbols,
803 int result, i, j, transp_idx, maskbpline;
806 COLORREF color; /* the american spelling virus hits again .. */
811 xpminfo.valuemask=XpmHotspot;
814 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
823 signal_simple_error ("Invalid XPM data", image);
827 signal_double_file_error ("Parsing pixmap data",
828 "out of memory", image);
832 signal_double_file_error_2 ("Parsing pixmap data",
834 make_int (result), image);
838 *width = xpmimage.width;
839 *height = xpmimage.height;
840 maskbpline = BPLINE ((~7UL & (unsigned long)(*width + 7)) / 8);
842 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
846 XpmFreeXpmImage (&xpmimage);
847 XpmFreeXpmInfo (&xpminfo);
851 /* build a color table to speed things up */
852 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
856 XpmFreeXpmImage (&xpmimage);
857 XpmFreeXpmInfo (&xpminfo);
861 for (i=0; i<xpmimage.ncolors; i++)
864 /* pick up symbolic colors in preference */
865 if (xpmimage.colorTable[i].symbolic)
867 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
869 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
872 colortbl[i]=transparent_color;
874 goto label_found_color;
876 else if (color_symbols)
878 for (j = 0; j<nsymbols; j++)
880 if (!strcmp (xpmimage.colorTable[i].symbolic,
881 color_symbols[j].name ))
883 colortbl[i]=color_symbols[j].color;
884 goto label_found_color;
888 else if (xpmimage.colorTable[i].c_color == 0)
893 /* pick up transparencies */
894 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
897 colortbl[i]=transparent_color;
899 goto label_found_color;
901 /* finally pick up a normal color spec */
902 if (xpmimage.colorTable[i].c_color)
905 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
906 goto label_found_color;
912 XpmFreeXpmImage (&xpmimage);
913 XpmFreeXpmInfo (&xpminfo);
919 /* convert the image */
922 for (i = 0; i< *width * *height; i++)
924 color = colortbl[*sptr++];
926 /* split out the 0x02bbggrr colorref into an rgb triple */
927 *dptr++=GetRValue (color); /* red */
928 *dptr++=GetGValue (color); /* green */
929 *dptr++=GetBValue (color); /* blue */
932 *x_hot=xpminfo.x_hotspot;
933 *y_hot=xpminfo.y_hotspot;
935 XpmFreeXpmImage (&xpmimage);
936 XpmFreeXpmInfo (&xpminfo);
942 mswindows_xpm_instantiate (Lisp_Object image_instance,
943 Lisp_Object instantiator,
944 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
945 int dest_mask, Lisp_Object domain)
947 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
948 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
949 const Extbyte *bytes;
951 unsigned char *eimage;
952 int width, height, x_hot, y_hot;
953 BITMAPINFO* bmp_info;
954 unsigned char* bmp_data;
956 int nsymbols=0, transp;
957 struct color_symbol* color_symbols=NULL;
959 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
960 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
963 CHECK_MSGDI_DEVICE (device);
965 assert (!NILP (data));
967 TO_EXTERNAL_FORMAT (LISP_STRING, data,
968 ALLOCA, (bytes, len),
971 /* in case we have color symbols */
972 color_symbols = extract_xpm_color_names (device, domain,
973 color_symbol_alist, &nsymbols);
975 /* convert to an eimage to make processing easier */
976 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
977 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
979 signal_simple_error ("XPM to EImage conversion failed",
987 xfree (color_symbols[nsymbols].name);
989 xfree(color_symbols);
992 /* build a bitmap from the eimage */
993 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
994 &bmp_bits, &bmp_data)))
996 signal_simple_error ("XPM to EImage conversion failed",
1001 /* Now create the pixmap and set up the image instance */
1002 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
1003 bmp_data, bmp_bits, 1, instantiator,
1004 x_hot, y_hot, transp);
1009 #endif /* HAVE_XPM */
1011 /**********************************************************************
1013 **********************************************************************/
1016 bmp_validate (Lisp_Object instantiator)
1018 file_or_data_must_be_present (instantiator);
1022 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
1024 return simple_image_type_normalize (inst, console_type, Qbmp);
1028 bmp_possible_dest_types (void)
1030 return IMAGE_COLOR_PIXMAP_MASK;
1034 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1035 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1036 int dest_mask, Lisp_Object domain)
1038 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1039 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1040 const Extbyte *bytes;
1042 BITMAPFILEHEADER* bmp_file_header;
1043 BITMAPINFO* bmp_info;
1046 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1048 CHECK_MSGDI_DEVICE (device);
1050 assert (!NILP (data));
1052 TO_EXTERNAL_FORMAT (LISP_STRING, data,
1053 ALLOCA, (bytes, len),
1056 /* Then slurp the image into memory, decoding along the way.
1057 The result is the image in a simple one-byte-per-pixel
1060 bmp_file_header=(BITMAPFILEHEADER*)bytes;
1061 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
1062 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
1063 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
1065 /* Now create the pixmap and set up the image instance */
1066 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
1067 bmp_data, bmp_bits, 1, instantiator,
1072 /**********************************************************************
1074 **********************************************************************/
1077 mswindows_resource_validate (Lisp_Object instantiator)
1079 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
1081 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
1083 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
1084 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
1089 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type)
1091 /* This function can call lisp */
1092 Lisp_Object file = Qnil;
1093 struct gcpro gcpro1, gcpro2;
1094 Lisp_Object alist = Qnil;
1096 GCPRO2 (file, alist);
1098 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1101 if (CONSP (file)) /* failure locating filename */
1102 signal_double_file_error ("Opening pixmap file",
1103 "no such file or directory",
1106 if (NILP (file)) /* no conversion necessary */
1107 RETURN_UNGCPRO (inst);
1109 alist = tagged_vector_to_alist (inst);
1112 alist = remassq_no_quit (Q_file, alist);
1113 alist = Fcons (Fcons (Q_file, file), alist);
1117 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
1119 RETURN_UNGCPRO (result);
1124 mswindows_resource_possible_dest_types (void)
1126 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1136 #define OCR_ICOCUR 32647
1137 #define OIC_SAMPLE 32512
1138 #define OIC_HAND 32513
1139 #define OIC_QUES 32514
1140 #define OIC_BANG 32515
1141 #define OIC_NOTE 32516
1142 #define OIC_WINLOGO 32517
1143 #if defined (CYGWIN) && CYGWIN_VERSION_DLL_MAJOR < 21
1144 #define LR_SHARED 0x8000
1148 static const resource_t bitmap_table[] =
1151 { "close", OBM_CLOSE },
1152 { "uparrow", OBM_UPARROW },
1153 { "dnarrow", OBM_DNARROW },
1154 { "rgarrow", OBM_RGARROW },
1155 { "lfarrow", OBM_LFARROW },
1156 { "reduce", OBM_REDUCE },
1157 { "zoom", OBM_ZOOM },
1158 { "restore", OBM_RESTORE },
1159 { "reduced", OBM_REDUCED },
1160 { "zoomd", OBM_ZOOMD },
1161 { "restored", OBM_RESTORED },
1162 { "uparrowd", OBM_UPARROWD },
1163 { "dnarrowd", OBM_DNARROWD },
1164 { "rgarrowd", OBM_RGARROWD },
1165 { "lfarrowd", OBM_LFARROWD },
1166 { "mnarrow", OBM_MNARROW },
1167 { "combo", OBM_COMBO },
1168 { "uparrowi", OBM_UPARROWI },
1169 { "dnarrowi", OBM_DNARROWI },
1170 { "rgarrowi", OBM_RGARROWI },
1171 { "lfarrowi", OBM_LFARROWI },
1172 { "size", OBM_SIZE },
1173 { "btsize", OBM_BTSIZE },
1174 { "check", OBM_CHECK },
1175 { "checkboxes", OBM_CHECKBOXES },
1176 { "btncorners" , OBM_BTNCORNERS },
1180 static const resource_t cursor_table[] =
1183 { "normal", OCR_NORMAL },
1184 { "ibeam", OCR_IBEAM },
1185 { "wait", OCR_WAIT },
1186 { "cross", OCR_CROSS },
1188 /* { "icon", OCR_ICON }, */
1189 { "sizenwse", OCR_SIZENWSE },
1190 { "sizenesw", OCR_SIZENESW },
1191 { "sizewe", OCR_SIZEWE },
1192 { "sizens", OCR_SIZENS },
1193 { "sizeall", OCR_SIZEALL },
1194 /* { "icour", OCR_ICOCUR }, */
1199 static const resource_t icon_table[] =
1202 { "sample", OIC_SAMPLE },
1203 { "hand", OIC_HAND },
1204 { "ques", OIC_QUES },
1205 { "bang", OIC_BANG },
1206 { "note", OIC_NOTE },
1207 { "winlogo", OIC_WINLOGO },
1211 static int resource_name_to_resource (Lisp_Object name, int type)
1213 const resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1214 : type == IMAGE_ICON ? icon_table
1221 else if (!STRINGP (name))
1223 signal_simple_error ("invalid resource identifier", name);
1228 TO_EXTERNAL_FORMAT (LISP_STRING, name,
1229 C_STRING_ALLOCA, nm,
1231 if (!strcasecmp ((char*)res->name, nm))
1232 return res->resource_id;
1233 } while ((++res)->name);
1238 resource_symbol_to_type (Lisp_Object data)
1240 if (EQ (data, Qcursor))
1241 return IMAGE_CURSOR;
1242 else if (EQ (data, Qicon))
1244 else if (EQ (data, Qbitmap))
1245 return IMAGE_BITMAP;
1251 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1252 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1253 int dest_mask, Lisp_Object domain)
1255 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1256 unsigned int type = 0;
1257 HANDLE himage = NULL;
1259 HINSTANCE hinst = NULL;
1261 enum image_instance_type iitype;
1263 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1265 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1266 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1268 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1273 CHECK_MSGDI_DEVICE (device);
1275 type = resource_symbol_to_type (resource_type);
1277 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1278 iitype = IMAGE_POINTER;
1279 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1280 iitype = IMAGE_COLOR_PIXMAP;
1282 incompatible_image_types (instantiator, dest_mask,
1283 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1285 /* mess with the keyword info we were provided with */
1289 TO_EXTERNAL_FORMAT (LISP_STRING, file,
1293 CYGWIN_WIN32_PATH (f, fname);
1298 if (NILP (resource_id))
1299 resid = (LPCTSTR)fname;
1302 hinst = LoadLibraryEx (fname, NULL,
1303 LOAD_LIBRARY_AS_DATAFILE);
1304 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1308 TO_EXTERNAL_FORMAT (LISP_STRING, resource_id,
1309 C_STRING_ALLOCA, resid,
1313 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1315 signal_simple_error ("Invalid resource identifier", resource_id);
1317 /* load the image */
1318 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
1319 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1321 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1323 signal_simple_error ("Cannot load image", instantiator);
1327 FreeLibrary (hinst);
1329 mswindows_initialize_dibitmap_image_instance (ii, 1, iitype);
1331 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1332 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
1333 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1334 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
1335 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1336 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1337 init_image_instance_geometry (ii);
1339 /* hey, we've got an icon type thing so we can reverse engineer the
1341 if (type != IMAGE_BITMAP)
1343 GetIconInfo ((HICON)himage, &iconinfo);
1344 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1345 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1346 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1347 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1348 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (HICON) himage;
1352 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1353 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (HBITMAP) himage;
1354 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1355 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1356 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1361 check_valid_resource_symbol (Lisp_Object data)
1363 CHECK_SYMBOL (data);
1364 if (!resource_symbol_to_type (data))
1365 signal_simple_error ("invalid resource type", data);
1369 check_valid_resource_id (Lisp_Object data)
1371 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1373 !resource_name_to_resource (data, IMAGE_ICON)
1375 !resource_name_to_resource (data, IMAGE_BITMAP))
1376 signal_simple_error ("invalid resource identifier", data);
1379 /**********************************************************************
1381 **********************************************************************/
1382 #ifndef HAVE_X_WINDOWS
1383 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1387 Copyright (c) 1988 X Consortium
1389 Permission is hereby granted, free of charge, to any person obtaining a copy
1390 of this software and associated documentation files (the "Software"), to deal
1391 in the Software without restriction, including without limitation the rights
1392 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1393 copies of the Software, and to permit persons to whom the Software is
1394 furnished to do so, subject to the following conditions:
1396 The above copyright notice and this permission notice shall be included in
1397 all copies or substantial portions of the Software.
1399 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1400 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1401 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1402 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1403 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1404 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1406 Except as contained in this notice, the name of the X Consortium shall not be
1407 used in advertising or otherwise to promote the sale, use or other dealings
1408 in this Software without prior written authorization from the X Consortium.
1413 * This file contains miscellaneous utility routines and is not part of the
1416 * Public entry points:
1418 * XmuReadBitmapData read data from FILE descriptor
1419 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1422 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1423 * that way (but don't use common source code so that people can have one
1424 * without the other).
1429 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1431 #ifndef BitmapSuccess
1432 #define BitmapSuccess 0
1433 #define BitmapOpenFailed 1
1434 #define BitmapFileInvalid 2
1435 #define BitmapNoMemory 3
1437 #define MAX_SIZE 255
1439 /* shared data for the image read/parse logic */
1440 static short hexTable[256]; /* conversion value */
1441 static int initialized = FALSE; /* easier to fill in at run time */
1444 * Table index for the hex values. Initialized once, first time.
1445 * Used for translation value or delimiter significance lookup.
1451 * We build the table at run time for several reasons:
1453 * 1. portable to non-ASCII machines.
1454 * 2. still reentrant since we set the init flag after setting table.
1455 * 3. easier to extend.
1456 * 4. less prone to bugs.
1458 hexTable['0'] = 0; hexTable['1'] = 1;
1459 hexTable['2'] = 2; hexTable['3'] = 3;
1460 hexTable['4'] = 4; hexTable['5'] = 5;
1461 hexTable['6'] = 6; hexTable['7'] = 7;
1462 hexTable['8'] = 8; hexTable['9'] = 9;
1463 hexTable['A'] = 10; hexTable['B'] = 11;
1464 hexTable['C'] = 12; hexTable['D'] = 13;
1465 hexTable['E'] = 14; hexTable['F'] = 15;
1466 hexTable['a'] = 10; hexTable['b'] = 11;
1467 hexTable['c'] = 12; hexTable['d'] = 13;
1468 hexTable['e'] = 14; hexTable['f'] = 15;
1470 /* delimiters of significance are flagged w/ negative value */
1471 hexTable[' '] = -1; hexTable[','] = -1;
1472 hexTable['}'] = -1; hexTable['\n'] = -1;
1473 hexTable['\t'] = -1;
1479 * read next hex value in the input stream, return -1 if EOF
1482 NextInt (FILE *fstream)
1489 /* loop, accumulate hex value until find delimiter */
1490 /* skip any initial delimiters found in read stream */
1498 /* trim high bits, check type and accumulate */
1500 if (isascii(ch) && isxdigit(ch)) {
1501 value = (value << 4) + hexTable[ch];
1503 } else if ((hexTable[ch]) < 0 && gotone)
1512 * The data returned by the following routine is always in left-most byte
1513 * first and left-most bit first. If it doesn't return BitmapSuccess then
1514 * its arguments won't have been touched. This routine should look as much
1515 * like the Xlib routine XReadBitmapfile as possible.
1517 int read_bitmap_data (FILE* fstream, unsigned int *width,
1518 unsigned int *height, unsigned char **datap,
1519 int *x_hot, int *y_hot)
1521 unsigned char *data = NULL; /* working variable */
1522 char line[MAX_SIZE]; /* input line from file */
1523 int size; /* number of bytes of data */
1524 char name_and_type[MAX_SIZE]; /* an input line */
1525 char *type; /* for parsing */
1526 int value; /* from an input line */
1527 int version10p; /* boolean, old format */
1528 int padding; /* to handle alignment */
1529 int bytes_per_line; /* per scanline of data */
1530 unsigned int ww = 0; /* width */
1531 unsigned int hh = 0; /* height */
1532 int hx = -1; /* x hotspot */
1533 int hy = -1; /* y hotspot */
1535 #define Xmalloc(size) malloc(size)
1537 /* first time initialization */
1538 if (initialized == FALSE) initHexTable();
1540 /* error cleanup and return macro */
1541 #define RETURN(code) { if (data) free (data); return code; }
1543 while (fgets(line, MAX_SIZE, fstream)) {
1544 if (strlen(line) == MAX_SIZE-1) {
1545 RETURN (BitmapFileInvalid);
1547 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1548 if (!(type = strrchr(name_and_type, '_')))
1549 type = name_and_type;
1553 if (!strcmp("width", type))
1554 ww = (unsigned int) value;
1555 if (!strcmp("height", type))
1556 hh = (unsigned int) value;
1557 if (!strcmp("hot", type)) {
1558 if (type-- == name_and_type || type-- == name_and_type)
1560 if (!strcmp("x_hot", type))
1562 if (!strcmp("y_hot", type))
1568 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1570 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1572 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1577 if (!(type = strrchr(name_and_type, '_')))
1578 type = name_and_type;
1582 if (strcmp("bits[]", type))
1586 RETURN (BitmapFileInvalid);
1588 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1593 bytes_per_line = (ww+7)/8 + padding;
1595 size = bytes_per_line * hh;
1596 data = (unsigned char *) Xmalloc ((unsigned int) size);
1598 RETURN (BitmapNoMemory);
1604 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1605 if ((value = NextInt(fstream)) < 0)
1606 RETURN (BitmapFileInvalid);
1608 if (!padding || ((bytes+2) % bytes_per_line))
1609 *(ptr++) = value >> 8;
1615 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1616 if ((value = NextInt(fstream)) < 0)
1617 RETURN (BitmapFileInvalid);
1625 RETURN (BitmapFileInvalid);
1632 if (x_hot) *x_hot = hx;
1633 if (y_hot) *y_hot = hy;
1635 RETURN (BitmapSuccess);
1639 int read_bitmap_data_from_file (const char *filename, unsigned int *width,
1640 unsigned int *height, unsigned char **datap,
1641 int *x_hot, int *y_hot)
1646 if ((fstream = fopen (filename, "r")) == NULL) {
1647 return BitmapOpenFailed;
1649 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1653 #endif /* HAVE_X_WINDOWS */
1655 /* this table flips four bits around. */
1656 static int flip_table[] =
1658 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1661 /* the bitmap data comes in the following format: Widths are padded to
1662 a multiple of 8. Scan lines are stored in increasing byte order
1663 from left to right, little-endian within a byte. 0 = white, 1 =
1664 black. It must be converted to the following format: Widths are
1665 padded to a multiple of 16. Scan lines are stored in increasing
1666 byte order from left to right, big-endian within a byte. 0 =
1667 black, 1 = white. */
1669 xbm_create_bitmap_from_data (HDC hdc, char *data,
1670 unsigned int width, unsigned int height,
1671 int mask, COLORREF fg, COLORREF bg)
1673 int old_width = (width + 7)/8;
1674 int new_width = BPLINE (2*((width + 15)/16));
1675 unsigned char *offset;
1677 unsigned char *new_data, *new_offset;
1679 BITMAPINFO *bmp_info =
1680 (BITMAPINFO*) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1686 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
1694 for (i=0; i<height; i++)
1696 offset = data + i*old_width;
1697 new_offset = new_data + i*new_width;
1699 for (j=0; j<old_width; j++)
1701 int byte = offset[j];
1702 new_offset[j] = ~ (unsigned char)
1703 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1707 /* if we want a mask invert the bits */
1710 new_offset = &new_data[height * new_width];
1711 while (new_offset-- != new_data)
1713 *new_offset ^= 0xff;
1717 bmp_info->bmiHeader.biWidth=width;
1718 bmp_info->bmiHeader.biHeight=-(LONG)height;
1719 bmp_info->bmiHeader.biPlanes=1;
1720 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1721 bmp_info->bmiHeader.biBitCount=1;
1722 bmp_info->bmiHeader.biCompression=BI_RGB;
1723 bmp_info->bmiHeader.biClrUsed = 2;
1724 bmp_info->bmiHeader.biClrImportant = 2;
1725 bmp_info->bmiHeader.biSizeImage = height * new_width;
1726 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1727 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1728 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1729 bmp_info->bmiColors[0].rgbReserved = 0;
1730 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1731 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1732 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1733 bmp_info->bmiColors[1].rgbReserved = 0;
1735 bitmap = CreateDIBSection (hdc,
1743 if (!bitmap || !bmp_buf)
1749 /* copy in the actual bitmap */
1750 memcpy (bmp_buf, new_data, height * new_width);
1756 /* Given inline data for a mono pixmap, initialize the given
1757 image instance accordingly. */
1760 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
1761 int width, int height,
1762 /* Note that data is in ext-format! */
1764 Lisp_Object instantiator,
1765 Lisp_Object pointer_fg,
1766 Lisp_Object pointer_bg,
1769 Lisp_Object mask_filename)
1771 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1772 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1773 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1774 enum image_instance_type type;
1775 COLORREF black = PALETTERGB (0,0,0);
1776 COLORREF white = PALETTERGB (255,255,255);
1779 CHECK_MSGDI_DEVICE (device);
1781 hdc = get_device_compdc (XDEVICE (device));
1783 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1784 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1786 if (!NILP (foreground) || !NILP (background))
1787 type = IMAGE_COLOR_PIXMAP;
1789 type = IMAGE_MONO_PIXMAP;
1791 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1792 type = IMAGE_MONO_PIXMAP;
1793 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1794 type = IMAGE_COLOR_PIXMAP;
1795 else if (dest_mask & IMAGE_POINTER_MASK)
1796 type = IMAGE_POINTER;
1798 incompatible_image_types (instantiator, dest_mask,
1799 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1800 | IMAGE_POINTER_MASK);
1802 mswindows_initialize_dibitmap_image_instance (ii, 1, type);
1804 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1805 find_keyword_in_vector (instantiator, Q_file);
1806 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = width;
1807 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = height;
1808 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1809 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1810 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1811 init_image_instance_geometry (ii);
1813 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1814 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1815 TRUE, black, white);
1819 case IMAGE_MONO_PIXMAP:
1820 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1821 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1822 FALSE, black, black);
1825 case IMAGE_COLOR_PIXMAP:
1827 COLORREF fg = black;
1828 COLORREF bg = white;
1830 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1832 Fmake_color_instance (foreground, device,
1833 encode_error_behavior_flag (ERROR_ME));
1835 if (COLOR_INSTANCEP (foreground))
1836 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1838 if (!NILP (background) && !COLOR_INSTANCEP (background))
1840 Fmake_color_instance (background, device,
1841 encode_error_behavior_flag (ERROR_ME));
1843 if (COLOR_INSTANCEP (background))
1844 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1846 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1847 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1849 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1850 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1857 COLORREF fg = black;
1858 COLORREF bg = white;
1860 if (NILP (foreground))
1861 foreground = pointer_fg;
1862 if (NILP (background))
1863 background = pointer_bg;
1865 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1866 find_keyword_in_vector (instantiator, Q_hotspot_x);
1867 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1868 find_keyword_in_vector (instantiator, Q_hotspot_y);
1869 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1870 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1871 if (COLOR_INSTANCEP (foreground))
1872 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1873 if (COLOR_INSTANCEP (background))
1874 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1876 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1877 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1879 mswindows_initialize_image_instance_icon (ii, TRUE);
1889 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1890 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1891 int dest_mask, int width, int height,
1892 /* Note that data is in ext-format! */
1895 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1896 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1897 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1898 HDC hdc = get_device_compdc (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
1901 if (!NILP (mask_data))
1903 const char *ext_data;
1905 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))),
1906 C_STRING_ALLOCA, ext_data,
1908 mask = xbm_create_bitmap_from_data (hdc,
1909 (unsigned char *) ext_data,
1910 XINT (XCAR (mask_data)),
1911 XINT (XCAR (XCDR (mask_data))),
1914 PALETTERGB (255,255,255));
1917 init_image_instance_from_xbm_inline (ii, width, height, bits,
1918 instantiator, pointer_fg, pointer_bg,
1919 dest_mask, mask, mask_file);
1922 /* Instantiate method for XBM's. */
1925 mswindows_xbm_instantiate (Lisp_Object image_instance,
1926 Lisp_Object instantiator,
1927 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1928 int dest_mask, Lisp_Object domain)
1930 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1931 const char *ext_data;
1933 assert (!NILP (data));
1935 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))),
1936 C_STRING_ALLOCA, ext_data,
1939 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1940 pointer_bg, dest_mask, XINT (XCAR (data)),
1941 XINT (XCAR (XCDR (data))), ext_data);
1945 /**********************************************************************
1947 **********************************************************************/
1949 /* This is about to get redefined! */
1952 /* We have to define SYSV32 so that compface.h includes string.h
1953 instead of strings.h. */
1958 #include <compface.h>
1962 /* JMP_BUF cannot be used here because if it doesn't get defined
1963 to jmp_buf we end up with a conflicting type error with the
1964 definition in compface.h */
1965 extern jmp_buf comp_env;
1969 mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1970 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1971 int dest_mask, Lisp_Object domain)
1973 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1975 char *p, *bits, *bp;
1976 const char * volatile emsg = 0;
1977 const char * volatile dstring;
1979 assert (!NILP (data));
1981 TO_EXTERNAL_FORMAT (LISP_STRING, data,
1982 C_STRING_ALLOCA, dstring,
1985 if ((p = strchr (dstring, ':')))
1990 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
1991 if (!(stattis = setjmp (comp_env)))
1993 UnCompAll ((char *) dstring);
2000 emsg = "uncompface: internal error";
2003 emsg = "uncompface: insufficient or invalid data";
2006 emsg = "uncompface: excess data ignored";
2011 signal_simple_error_2 (emsg, data, Qimage);
2013 bp = bits = (char *) alloca (PIXELS / 8);
2015 /* the compface library exports char F[], which uses a single byte per
2016 pixel to represent a 48x48 bitmap. Yuck. */
2017 for (i = 0, p = F; i < (PIXELS / 8); ++i)
2020 /* reverse the bit order of each byte... */
2021 for (b = n = 0; b < 8; ++b)
2028 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
2029 pointer_bg, dest_mask, 48, 48, bits);
2031 #endif /* HAVE_XFACE */
2034 /************************************************************************/
2035 /* image instance methods */
2036 /************************************************************************/
2039 mswindows_print_image_instance (Lisp_Image_Instance *p,
2040 Lisp_Object printcharfun,
2045 switch (IMAGE_INSTANCE_TYPE (p))
2047 case IMAGE_MONO_PIXMAP:
2048 case IMAGE_COLOR_PIXMAP:
2050 sprintf (buf, " (0x%lx",
2051 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
2052 write_c_string (buf, printcharfun);
2053 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2055 sprintf (buf, "/0x%lx",
2056 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2057 write_c_string (buf, printcharfun);
2059 write_c_string (")", printcharfun);
2067 #ifdef DEBUG_WIDGETS
2068 extern int debug_widget_instances;
2072 mswindows_finalize_image_instance (Lisp_Image_Instance *p)
2077 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
2079 if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p))
2080 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
2082 #ifdef DEBUG_WIDGETS
2083 debug_widget_instances--;
2084 stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
2086 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2088 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
2089 DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p));
2090 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
2096 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
2097 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
2099 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p))
2101 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
2103 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i))
2104 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i));
2105 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0;
2107 xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p));
2108 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0;
2110 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2111 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2112 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
2113 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
2114 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
2115 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2126 /************************************************************************/
2127 /* subwindow and widget support */
2128 /************************************************************************/
2131 mswindows_widget_hfont (Lisp_Image_Instance *p,
2134 Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (p);
2135 int under = FACE_UNDERLINE_P (face, domain);
2136 int strike = FACE_STRIKETHRU_P (face, domain);
2137 Lisp_Object font = query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (p),
2140 return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike);
2144 begin_defer_window_pos (struct frame *f)
2146 if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0)
2147 FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10);
2148 return FRAME_MSWINDOWS_DATA (f)->hdwp;
2151 /* unmap the image if it is a widget. This is used by redisplay via
2152 redisplay_unmap_subwindows */
2154 mswindows_unmap_subwindow (Lisp_Image_Instance *p)
2156 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2158 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2159 HDWP hdwp = begin_defer_window_pos (f);
2161 new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2164 SWP_HIDEWINDOW | SWP_NOACTIVATE |
2165 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
2166 /* Setting this flag causes the call to
2167 DeferWindowPos to fail with
2168 "Invalid parameter". I don't understand
2169 why we bother to try and set this
2171 /* | SWP_NOSENDCHANGING */
2174 mswindows_output_last_error ("unmapping");
2177 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2178 if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))
2179 SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
2183 /* map the subwindow. This is used by redisplay via
2184 redisplay_output_subwindow */
2186 mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
2187 struct display_glyph_area* dga)
2189 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2190 HDWP hdwp = begin_defer_window_pos (f);
2192 /* move the window before mapping it ... */
2193 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2195 x, y, dga->width, dga->height,
2197 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2198 /* ... adjust the child ... */
2199 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2201 -dga->xoffset, -dga->yoffset, 0, 0,
2202 SWP_NOZORDER | SWP_NOSIZE
2203 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2204 /* ... now map it - we are not allowed to move it at the same time. */
2205 new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2208 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2210 /* | SWP_NOCOPYBITS */
2211 /* Setting this flag causes the call to
2212 DeferWindowPos to fail with
2213 "Invalid parameter". I don't understand
2214 why we bother to try and set this
2216 /* | SWP_NOSENDCHANGING */
2219 mswindows_output_last_error ("mapping");
2222 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2225 /* resize the subwindow instance */
2227 mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
2229 /* Set the size of the control .... */
2230 if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2233 SWP_NOZORDER | SWP_NOMOVE
2234 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING))
2235 mswindows_output_last_error ("resizing");
2238 /* Simply resize the window here. */
2240 mswindows_update_subwindow (Lisp_Image_Instance *p)
2242 mswindows_resize_subwindow (p,
2243 IMAGE_INSTANCE_WIDTH (p),
2244 IMAGE_INSTANCE_HEIGHT (p));
2247 /* when you click on a widget you may activate another widget this
2248 needs to be checked and all appropriate widgets updated */
2250 mswindows_update_widget (Lisp_Image_Instance *p)
2252 /* Possibly update the face font and colors. */
2253 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))
2254 && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
2255 || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
2256 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)))
2258 /* set the widget font from the widget face */
2259 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2261 (WPARAM) mswindows_widget_hfont
2262 (p, IMAGE_INSTANCE_FRAME (p)),
2263 MAKELPARAM (TRUE, 0));
2265 /* Possibly update the dimensions. */
2266 if (IMAGE_INSTANCE_SIZE_CHANGED (p))
2268 mswindows_resize_subwindow (p,
2269 IMAGE_INSTANCE_WIDTH (p),
2270 IMAGE_INSTANCE_HEIGHT (p));
2272 /* Possibly update the text in the widget. */
2273 if (IMAGE_INSTANCE_TEXT_CHANGED (p)
2274 && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)))
2277 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p),
2278 C_STRING_ALLOCA, lparam,
2280 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2281 WM_SETTEXT, 0, (LPARAM)lparam);
2285 /* register widgets into our hastable so that we can cope with the
2286 callbacks. The hashtable is weak so deregistration is handled
2289 mswindows_register_gui_item (Lisp_Object image_instance,
2290 Lisp_Object gui, Lisp_Object domain)
2292 Lisp_Object frame = DOMAIN_FRAME (domain);
2293 struct frame* f = XFRAME (frame);
2294 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f),
2297 Fputhash (make_int (id), image_instance,
2298 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
2299 Fputhash (make_int (id), XGUI_ITEM (gui)->callback,
2300 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
2301 Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex,
2302 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
2307 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2309 return mswindows_register_gui_item (instance,
2310 XIMAGE_INSTANCE_WIDGET_ITEM (instance),
2315 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2316 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2317 int dest_mask, Lisp_Object domain)
2319 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2320 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2321 Lisp_Object frame = DOMAIN_FRAME (domain);
2324 CHECK_MSWINDOWS_DEVICE (device);
2326 /* have to set the type this late in case there is no device
2327 instantiation for a widget */
2328 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2329 /* Allocate space for the clip window */
2330 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2332 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2335 XEMACS_CONTROL_CLASS,
2337 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2338 0, /* starting x position */
2339 0, /* starting y position */
2340 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2341 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2343 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2345 NULL, /* must be null for this class */
2347 signal_simple_error ("window creation failed with code",
2348 make_int (GetLastError()));
2350 wnd = CreateWindow( "STATIC",
2353 0, /* starting x position */
2354 0, /* starting y position */
2355 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2356 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2357 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2360 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2364 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2365 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2369 mswindows_image_instance_equal (Lisp_Image_Instance *p1,
2370 Lisp_Image_Instance *p2, int depth)
2372 switch (IMAGE_INSTANCE_TYPE (p1))
2374 case IMAGE_MONO_PIXMAP:
2375 case IMAGE_COLOR_PIXMAP:
2377 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2378 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2389 static unsigned long
2390 mswindows_image_instance_hash (Lisp_Image_Instance *p, int depth)
2392 switch (IMAGE_INSTANCE_TYPE (p))
2394 case IMAGE_MONO_PIXMAP:
2395 case IMAGE_COLOR_PIXMAP:
2397 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2404 /* Set all the slots in an image instance structure to reasonable
2405 default values. This is used somewhere within an instantiate
2406 method. It is assumed that the device slot within the image
2407 instance is already set -- this is the case when instantiate
2408 methods are called. */
2411 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
2413 enum image_instance_type type)
2415 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2416 IMAGE_INSTANCE_TYPE (ii) = type;
2417 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2418 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2419 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2420 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2421 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2422 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2423 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
2424 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) =
2425 xnew_array_and_zero (HBITMAP, slices);
2431 /************************************************************************/
2433 /************************************************************************/
2435 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2436 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2437 int dest_mask, Lisp_Object domain,
2438 const char* class, int flags, int exflags)
2440 /* this function can call lisp */
2441 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2442 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2443 Lisp_Object frame = DOMAIN_FRAME (domain);
2447 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2448 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2450 CHECK_MSWINDOWS_DEVICE (device);
2452 if (!gui_item_active_p (gui))
2453 flags |= WS_DISABLED;
2455 style = pgui->style;
2457 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex))
2459 id = mswindows_register_widget_instance (image_instance, domain);
2462 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2463 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii),
2464 C_STRING_ALLOCA, nm,
2467 /* allocate space for the clip window and then allocate the clip window */
2468 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2470 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2472 WS_EX_CONTROLPARENT, /* EX flags */
2473 XEMACS_CONTROL_CLASS,
2475 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2476 0, /* starting x position */
2477 0, /* starting y position */
2478 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2479 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2481 DOMAIN_MSWINDOWS_HANDLE (domain),
2482 (HMENU)id, /* No menu */
2483 NULL, /* must be null for this class */
2485 signal_simple_error ("window creation failed with code",
2486 make_int (GetLastError()));
2488 if ((wnd = CreateWindowEx(
2489 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2492 flags | WS_CHILD | WS_VISIBLE,
2493 0, /* starting x position */
2494 0, /* starting y position */
2495 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2496 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2498 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2499 (HMENU)id, /* No menu */
2502 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2505 signal_simple_error ("window creation failed with code",
2506 make_int (GetLastError()));
2508 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2509 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2510 /* set the widget font from the widget face */
2511 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2512 SendMessage (wnd, WM_SETFONT,
2513 (WPARAM) mswindows_widget_hfont (ii, domain),
2514 MAKELPARAM (TRUE, 0));
2517 /* Instantiate a native layout widget. */
2519 mswindows_native_layout_instantiate (Lisp_Object image_instance,
2520 Lisp_Object instantiator,
2521 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2522 int dest_mask, Lisp_Object domain)
2524 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2526 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2527 pointer_bg, dest_mask, domain, "STATIC",
2528 /* Approximation to styles available with
2529 an XEmacs layout. */
2530 EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2532 EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2534 GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
2535 ? SS_ETCHEDFRAME : SS_SUNKEN,
2539 /* Instantiate a button widget. Unfortunately instantiated widgets are
2540 particular to a frame since they need to have a parent. It's not
2541 like images where you just select the image into the context you
2542 want to display it in and BitBlt it. So image instances can have a
2543 many-to-one relationship with things you see, whereas widgets can
2544 only be one-to-one (i.e. per frame) */
2546 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2547 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2548 int dest_mask, Lisp_Object domain)
2550 /* This function can call lisp */
2551 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2553 int flags = WS_TABSTOP;/* BS_NOTIFY #### is needed to get exotic feedback
2554 only. Since we seem to want nothing beyond BN_CLICK,
2555 the style is perhaps not necessary -- kkm */
2557 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2558 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2559 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2563 if (!IMAGE_INSTANCEP (glyph))
2564 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2566 if (IMAGE_INSTANCEP (glyph))
2567 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2568 BS_BITMAP : BS_ICON;
2571 style = pgui->style;
2573 /* #### consider using the default face for radio and toggle
2575 if (EQ (style, Qradio))
2577 flags |= BS_RADIOBUTTON;
2579 else if (EQ (style, Qtoggle))
2581 flags |= BS_AUTOCHECKBOX;
2585 flags |= BS_DEFPUSHBUTTON;
2588 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2589 pointer_bg, dest_mask, domain, "BUTTON",
2592 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2593 /* set the checked state */
2594 if (gui_item_selected_p (gui))
2595 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2597 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2598 /* add the image if one was given */
2599 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)
2601 IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph)))
2603 SendMessage (wnd, BM_SETIMAGE,
2604 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2605 IMAGE_BITMAP : IMAGE_ICON),
2606 (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2607 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2608 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2612 /* Update the state of a button. */
2614 mswindows_button_update (Lisp_Object image_instance)
2616 /* This function can GC if IN_REDISPLAY is false. */
2617 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2619 /* buttons checked or otherwise */
2620 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
2621 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2622 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2624 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2625 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2628 /* instantiate an edit control */
2630 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2631 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2632 int dest_mask, Lisp_Object domain)
2634 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2635 pointer_bg, dest_mask, domain, "EDIT",
2636 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2637 | WS_BORDER, WS_EX_CLIENTEDGE);
2640 /* instantiate a progress gauge */
2642 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2643 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2644 int dest_mask, Lisp_Object domain)
2647 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2648 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2649 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2650 WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE);
2651 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2652 /* set the colors */
2653 #ifdef PBS_SETBKCOLOR
2654 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2655 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2658 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2659 XIMAGE_INSTANCE_FRAME (ii))))));
2661 #ifdef PBS_SETBARCOLOR
2662 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2663 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2666 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2667 XIMAGE_INSTANCE_FRAME (ii))))));
2671 /* instantiate a tree view widget */
2672 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2673 HWND wnd, HTREEITEM parent, Lisp_Object item,
2674 int children, Lisp_Object domain)
2676 TV_INSERTSTRUCT tvitem;
2679 tvitem.hParent = parent;
2680 tvitem.hInsertAfter = TVI_LAST;
2681 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2682 tvitem.item.cChildren = children;
2684 if (GUI_ITEMP (item))
2686 tvitem.item.lParam = mswindows_register_gui_item (image_instance,
2688 tvitem.item.mask |= TVIF_PARAM;
2689 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2690 C_STRING_ALLOCA, tvitem.item.pszText,
2694 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2695 C_STRING_ALLOCA, tvitem.item.pszText,
2698 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2700 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2701 0, (LPARAM)&tvitem)) == 0)
2702 signal_simple_error ("error adding tree view entry", item);
2707 static void add_tree_item_list (Lisp_Object image_instance,
2708 HWND wnd, HTREEITEM parent, Lisp_Object list,
2713 /* get the first item */
2714 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2715 /* recursively add items to the tree view */
2716 LIST_LOOP (rest, XCDR (list))
2718 if (LISTP (XCAR (rest)))
2719 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2721 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2726 mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2727 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2728 int dest_mask, Lisp_Object domain)
2733 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2734 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2735 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2736 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2737 | TVS_HASLINES | TVS_HASBUTTONS,
2740 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2743 parent = add_tree_item (image_instance, wnd, NULL,
2744 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
2747 /* recursively add items to the tree view */
2748 /* add items to the tab */
2749 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2751 if (LISTP (XCAR (rest)))
2752 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2754 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2758 /* instantiate a tab control */
2759 static TC_ITEM* add_tab_item (Lisp_Object image_instance,
2760 HWND wnd, Lisp_Object item,
2761 Lisp_Object domain, int i)
2763 TC_ITEM tvitem, *ret;
2765 tvitem.mask = TCIF_TEXT;
2767 if (GUI_ITEMP (item))
2769 tvitem.lParam = mswindows_register_gui_item (image_instance,
2771 tvitem.mask |= TCIF_PARAM;
2772 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2773 C_STRING_ALLOCA, tvitem.pszText,
2778 CHECK_STRING (item);
2779 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2780 C_STRING_ALLOCA, tvitem.pszText,
2784 tvitem.cchTextMax = strlen (tvitem.pszText);
2786 if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
2787 i, (LPARAM)&tvitem)) < 0)
2788 signal_simple_error ("error adding tab entry", item);
2794 mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2795 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2796 int dest_mask, Lisp_Object domain)
2798 /* This function can call lisp */
2801 int i = 0, selected = 0;
2802 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2803 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
2804 unsigned int flags = WS_TABSTOP;
2806 if (EQ (orient, Qleft) || EQ (orient, Qright))
2808 flags |= TCS_VERTICAL | TCS_MULTILINE;
2810 if (EQ (orient, Qright) || EQ (orient, Qbottom))
2812 flags |= TCS_BOTTOM;
2815 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2816 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2817 /* borders don't suit tabs so well */
2819 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2820 /* add items to the tab */
2821 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2823 add_tab_item (image_instance, wnd, XCAR (rest), domain, i);
2824 if (gui_item_selected_p (XCAR (rest)))
2828 SendMessage (wnd, TCM_SETCURSEL, selected, 0);
2831 /* set the properties of a tab control */
2833 mswindows_tab_control_update (Lisp_Object image_instance)
2835 /* This function can GC if IN_REDISPLAY is false. */
2836 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2838 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2840 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2841 int i = 0, selected = 0;
2844 /* delete the pre-existing items */
2845 SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
2847 /* add items to the tab */
2848 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
2850 add_tab_item (image_instance, wnd, XCAR (rest),
2851 IMAGE_INSTANCE_FRAME (ii), i);
2852 if (gui_item_selected_p (XCAR (rest)))
2856 SendMessage (wnd, TCM_SETCURSEL, selected, 0);
2860 /* instantiate a static control possible for putting other things in */
2862 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2863 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2864 int dest_mask, Lisp_Object domain)
2866 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2867 pointer_bg, dest_mask, domain, "STATIC",
2868 0, WS_EX_STATICEDGE);
2871 /* instantiate a scrollbar control */
2873 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2874 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2875 int dest_mask, Lisp_Object domain)
2877 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2878 pointer_bg, dest_mask, domain, "SCROLLBAR",
2879 WS_TABSTOP, WS_EX_CLIENTEDGE);
2882 /* instantiate a combo control */
2884 mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2885 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2886 int dest_mask, Lisp_Object domain)
2888 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2891 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
2895 /* Maybe ought to generalise this more but it may be very windows
2896 specific. In windows the window height of a combo box is the
2897 height when the combo box is open. Thus we need to set the height
2898 before creating the window and then reset it to a single line
2899 after the window is created so that redisplay does the right
2901 widget_instantiate (image_instance, instantiator, pointer_fg,
2902 pointer_bg, dest_mask, domain);
2904 /* We now have everything right apart from the height. */
2905 default_face_font_info (domain, 0, 0, &height, 0, 0);
2906 GET_LIST_LENGTH (data, len);
2908 height = (height + WIDGET_BORDER_HEIGHT * 2 ) * len;
2909 IMAGE_INSTANCE_HEIGHT (ii) = height;
2911 /* Now create the widget. */
2912 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2913 pointer_bg, dest_mask, domain, "COMBOBOX",
2914 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
2916 | CBS_HASSTRINGS | WS_VSCROLL,
2918 /* Reset the height. layout will probably do this safely, but better make sure. */
2919 image_instance_layout (image_instance,
2920 IMAGE_UNSPECIFIED_GEOMETRY,
2921 IMAGE_UNSPECIFIED_GEOMETRY,
2924 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2925 /* add items to the combo box */
2926 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
2927 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2930 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (rest),
2931 C_STRING_ALLOCA, lparam,
2933 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
2934 signal_simple_error ("error adding combo entries", instantiator);
2938 /* get properties of a control */
2940 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
2942 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2943 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2944 /* get the text from a control */
2945 if (EQ (prop, Q_text))
2947 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
2948 Extbyte *buf = (Extbyte*) alloca (len+1);
2950 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
2951 return build_ext_string (buf, Qnative);
2956 /* get properties of a button */
2958 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
2960 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2961 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2962 /* check the state of a button */
2963 if (EQ (prop, Q_selected))
2965 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
2973 /* get properties of a combo box */
2975 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
2977 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2978 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2979 /* get the text from a control */
2980 if (EQ (prop, Q_text))
2982 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
2983 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
2984 Extbyte* buf = (Extbyte*) alloca (len+1);
2985 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
2986 return build_ext_string (buf, Qnative);
2991 /* set the properties of a progres guage */
2993 mswindows_progress_gauge_update (Lisp_Object image_instance)
2995 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2997 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
3000 #ifdef ERROR_CHECK_GLYPHS
3001 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
3003 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
3004 #ifdef DEBUG_WIDGET_OUTPUT
3005 printf ("progress gauge displayed value on %p updated to %ld\n",
3006 WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3010 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3011 PBM_SETPOS, (WPARAM)XINT (val), 0);
3016 mswindows_control_wnd_proc (HWND hwnd, UINT msg,
3017 WPARAM wParam, LPARAM lParam)
3023 case WM_CTLCOLORBTN:
3024 case WM_CTLCOLORLISTBOX:
3025 case WM_CTLCOLOREDIT:
3026 case WM_CTLCOLORSTATIC:
3027 case WM_CTLCOLORSCROLLBAR:
3029 return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam);
3031 return DefWindowProc (hwnd, msg, wParam, lParam);
3035 #endif /* HAVE_WIDGETS */
3038 /************************************************************************/
3039 /* initialization */
3040 /************************************************************************/
3043 syms_of_glyphs_mswindows (void)
3045 defkeyword (&Q_resource_id, ":resource-id");
3046 defkeyword (&Q_resource_type, ":resource-type");
3050 console_type_create_glyphs_mswindows (void)
3052 /* image methods - display */
3053 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
3054 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
3055 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
3056 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
3057 CONSOLE_HAS_METHOD (mswindows, update_subwindow);
3058 CONSOLE_HAS_METHOD (mswindows, resize_subwindow);
3059 CONSOLE_HAS_METHOD (mswindows, update_widget);
3060 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
3061 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
3062 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
3063 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
3065 /* image methods - printer */
3066 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_image_instance);
3067 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_image_instance);
3068 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_equal);
3069 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_hash);
3070 CONSOLE_INHERITS_METHOD (msprinter, mswindows, init_image_instance_from_eimage);
3071 CONSOLE_INHERITS_METHOD (msprinter, mswindows, locate_pixmap_file);
3075 image_instantiator_format_create_glyphs_mswindows (void)
3077 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing);
3078 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string);
3079 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string);
3080 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit);
3081 /* image-instantiator types */
3082 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
3083 INITIALIZE_DEVICE_IIFORMAT (msprinter, xbm);
3084 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
3085 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xbm, instantiate);
3087 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
3088 INITIALIZE_DEVICE_IIFORMAT (msprinter, xpm);
3089 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
3090 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xpm, instantiate);
3093 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
3094 INITIALIZE_DEVICE_IIFORMAT (msprinter, xface);
3095 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
3096 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xface, instantiate);
3099 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, jpeg);
3102 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, tiff);
3105 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, png);
3108 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif);
3111 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
3112 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
3114 IIFORMAT_VALID_CONSOLE (mswindows, layout);
3115 INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout);
3116 IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate);
3118 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
3119 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
3120 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
3121 IIFORMAT_HAS_DEVMETHOD (mswindows, button, update);
3122 /* edit-field widget */
3123 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
3124 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
3126 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
3127 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
3129 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
3130 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
3132 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
3133 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
3134 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
3136 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
3137 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
3138 /* progress gauge */
3139 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
3140 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, update);
3141 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
3142 /* tree view widget */
3143 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
3144 /* IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/
3145 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
3146 /* tab control widget */
3147 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
3148 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
3149 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, update);
3151 /* windows bitmap format */
3152 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
3153 IIFORMAT_HAS_METHOD (bmp, validate);
3154 IIFORMAT_HAS_METHOD (bmp, normalize);
3155 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
3156 IIFORMAT_HAS_METHOD (bmp, instantiate);
3158 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
3159 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
3160 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, bmp);
3162 /* mswindows resources */
3163 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
3164 "mswindows-resource");
3166 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
3167 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
3168 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
3169 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
3171 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
3172 check_valid_resource_symbol);
3173 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
3174 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
3175 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, mswindows_resource);
3179 vars_of_glyphs_mswindows (void)
3181 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
3182 A list of the directories in which mswindows bitmap files may be found.
3183 This is used by the `make-image-instance' function.
3185 Vmswindows_bitmap_file_path = Qnil;
3189 complex_vars_of_glyphs_mswindows (void)