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 /* #### Warning: 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,
1023 Lisp_Object dest_mask)
1025 return simple_image_type_normalize (inst, console_type, Qbmp);
1029 bmp_possible_dest_types (void)
1031 return IMAGE_COLOR_PIXMAP_MASK;
1035 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1036 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1037 int dest_mask, Lisp_Object domain)
1039 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1040 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1041 const Extbyte *bytes;
1043 BITMAPFILEHEADER* bmp_file_header;
1044 BITMAPINFO* bmp_info;
1047 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1049 CHECK_MSGDI_DEVICE (device);
1051 assert (!NILP (data));
1053 TO_EXTERNAL_FORMAT (LISP_STRING, data,
1054 ALLOCA, (bytes, len),
1057 /* Then slurp the image into memory, decoding along the way.
1058 The result is the image in a simple one-byte-per-pixel
1061 bmp_file_header=(BITMAPFILEHEADER*)bytes;
1062 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
1063 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
1064 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
1066 /* Now create the pixmap and set up the image instance */
1067 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
1068 bmp_data, bmp_bits, 1, instantiator,
1073 /**********************************************************************
1075 **********************************************************************/
1078 mswindows_resource_validate (Lisp_Object instantiator)
1080 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
1082 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
1084 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
1085 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
1090 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type,
1091 Lisp_Object dest_mask)
1093 /* This function can call lisp */
1094 Lisp_Object file = Qnil;
1095 struct gcpro gcpro1, gcpro2;
1096 Lisp_Object alist = Qnil;
1098 GCPRO2 (file, alist);
1100 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1103 if (CONSP (file)) /* failure locating filename */
1104 signal_double_file_error ("Opening pixmap file",
1105 "no such file or directory",
1108 if (NILP (file)) /* no conversion necessary */
1109 RETURN_UNGCPRO (inst);
1111 alist = tagged_vector_to_alist (inst);
1114 alist = remassq_no_quit (Q_file, alist);
1115 alist = Fcons (Fcons (Q_file, file), alist);
1119 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
1121 RETURN_UNGCPRO (result);
1126 mswindows_resource_possible_dest_types (void)
1128 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1138 #define OCR_ICOCUR 32647
1139 #define OIC_SAMPLE 32512
1140 #define OIC_HAND 32513
1141 #define OIC_QUES 32514
1142 #define OIC_BANG 32515
1143 #define OIC_NOTE 32516
1144 #define OIC_WINLOGO 32517
1145 #if defined (CYGWIN) && CYGWIN_VERSION_DLL_MAJOR < 21
1146 #define LR_SHARED 0x8000
1150 static const resource_t bitmap_table[] =
1153 { "close", OBM_CLOSE },
1154 { "uparrow", OBM_UPARROW },
1155 { "dnarrow", OBM_DNARROW },
1156 { "rgarrow", OBM_RGARROW },
1157 { "lfarrow", OBM_LFARROW },
1158 { "reduce", OBM_REDUCE },
1159 { "zoom", OBM_ZOOM },
1160 { "restore", OBM_RESTORE },
1161 { "reduced", OBM_REDUCED },
1162 { "zoomd", OBM_ZOOMD },
1163 { "restored", OBM_RESTORED },
1164 { "uparrowd", OBM_UPARROWD },
1165 { "dnarrowd", OBM_DNARROWD },
1166 { "rgarrowd", OBM_RGARROWD },
1167 { "lfarrowd", OBM_LFARROWD },
1168 { "mnarrow", OBM_MNARROW },
1169 { "combo", OBM_COMBO },
1170 { "uparrowi", OBM_UPARROWI },
1171 { "dnarrowi", OBM_DNARROWI },
1172 { "rgarrowi", OBM_RGARROWI },
1173 { "lfarrowi", OBM_LFARROWI },
1174 { "size", OBM_SIZE },
1175 { "btsize", OBM_BTSIZE },
1176 { "check", OBM_CHECK },
1177 { "checkboxes", OBM_CHECKBOXES },
1178 { "btncorners" , OBM_BTNCORNERS },
1182 static const resource_t cursor_table[] =
1185 { "normal", OCR_NORMAL },
1186 { "ibeam", OCR_IBEAM },
1187 { "wait", OCR_WAIT },
1188 { "cross", OCR_CROSS },
1190 /* { "icon", OCR_ICON }, */
1191 { "sizenwse", OCR_SIZENWSE },
1192 { "sizenesw", OCR_SIZENESW },
1193 { "sizewe", OCR_SIZEWE },
1194 { "sizens", OCR_SIZENS },
1195 { "sizeall", OCR_SIZEALL },
1196 /* { "icour", OCR_ICOCUR }, */
1201 static const resource_t icon_table[] =
1204 { "sample", OIC_SAMPLE },
1205 { "hand", OIC_HAND },
1206 { "ques", OIC_QUES },
1207 { "bang", OIC_BANG },
1208 { "note", OIC_NOTE },
1209 { "winlogo", OIC_WINLOGO },
1213 static int resource_name_to_resource (Lisp_Object name, int type)
1215 const resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1216 : type == IMAGE_ICON ? icon_table
1223 else if (!STRINGP (name))
1225 signal_simple_error ("invalid resource identifier", name);
1230 TO_EXTERNAL_FORMAT (LISP_STRING, name,
1231 C_STRING_ALLOCA, nm,
1233 if (!strcasecmp ((char*)res->name, nm))
1234 return res->resource_id;
1235 } while ((++res)->name);
1240 resource_symbol_to_type (Lisp_Object data)
1242 if (EQ (data, Qcursor))
1243 return IMAGE_CURSOR;
1244 else if (EQ (data, Qicon))
1246 else if (EQ (data, Qbitmap))
1247 return IMAGE_BITMAP;
1253 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1254 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1255 int dest_mask, Lisp_Object domain)
1257 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1258 unsigned int type = 0;
1259 HANDLE himage = NULL;
1261 HINSTANCE hinst = NULL;
1263 enum image_instance_type iitype;
1265 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1267 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1268 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1270 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1275 CHECK_MSGDI_DEVICE (device);
1277 type = resource_symbol_to_type (resource_type);
1279 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1280 iitype = IMAGE_POINTER;
1281 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1282 iitype = IMAGE_COLOR_PIXMAP;
1284 incompatible_image_types (instantiator, dest_mask,
1285 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1287 /* mess with the keyword info we were provided with */
1291 TO_EXTERNAL_FORMAT (LISP_STRING, file,
1295 CYGWIN_WIN32_PATH (f, fname);
1300 if (NILP (resource_id))
1301 resid = (LPCTSTR)fname;
1304 hinst = LoadLibraryEx (fname, NULL,
1305 LOAD_LIBRARY_AS_DATAFILE);
1306 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1310 TO_EXTERNAL_FORMAT (LISP_STRING, resource_id,
1311 C_STRING_ALLOCA, resid,
1315 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1317 signal_simple_error ("Invalid resource identifier", resource_id);
1319 /* load the image */
1320 if (xLoadImageA) /* not in NT 3.5 */
1322 if (!(himage = xLoadImageA (hinst, resid, type, 0, 0,
1323 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1325 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1326 signal_simple_error ("Cannot load image", instantiator);
1330 /* Is this correct? I don't really care. */
1334 himage = LoadBitmap (hinst, resid);
1337 himage = LoadCursor (hinst, resid);
1340 himage = LoadIcon (hinst, resid);
1345 signal_simple_error ("Cannot load image", instantiator);
1349 FreeLibrary (hinst);
1351 mswindows_initialize_dibitmap_image_instance (ii, 1, iitype);
1353 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1354 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) =
1355 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1356 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) =
1357 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1358 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1359 init_image_instance_geometry (ii);
1361 /* hey, we've got an icon type thing so we can reverse engineer the
1363 if (type != IMAGE_BITMAP)
1365 GetIconInfo ((HICON)himage, &iconinfo);
1366 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1367 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1368 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1369 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1370 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (HICON) himage;
1374 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1375 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (HBITMAP) himage;
1376 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1377 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1378 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1383 check_valid_resource_symbol (Lisp_Object data)
1385 CHECK_SYMBOL (data);
1386 if (!resource_symbol_to_type (data))
1387 signal_simple_error ("invalid resource type", data);
1391 check_valid_resource_id (Lisp_Object data)
1393 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1395 !resource_name_to_resource (data, IMAGE_ICON)
1397 !resource_name_to_resource (data, IMAGE_BITMAP))
1398 signal_simple_error ("invalid resource identifier", data);
1401 /**********************************************************************
1403 **********************************************************************/
1404 #ifndef HAVE_X_WINDOWS
1405 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1409 Copyright (c) 1988 X Consortium
1411 Permission is hereby granted, free of charge, to any person obtaining a copy
1412 of this software and associated documentation files (the "Software"), to deal
1413 in the Software without restriction, including without limitation the rights
1414 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1415 copies of the Software, and to permit persons to whom the Software is
1416 furnished to do so, subject to the following conditions:
1418 The above copyright notice and this permission notice shall be included in
1419 all copies or substantial portions of the Software.
1421 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1422 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1423 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1424 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1425 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1426 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1428 Except as contained in this notice, the name of the X Consortium shall not be
1429 used in advertising or otherwise to promote the sale, use or other dealings
1430 in this Software without prior written authorization from the X Consortium.
1435 * This file contains miscellaneous utility routines and is not part of the
1438 * Public entry points:
1440 * XmuReadBitmapData read data from FILE descriptor
1441 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1444 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1445 * that way (but don't use common source code so that people can have one
1446 * without the other).
1451 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1453 #ifndef BitmapSuccess
1454 #define BitmapSuccess 0
1455 #define BitmapOpenFailed 1
1456 #define BitmapFileInvalid 2
1457 #define BitmapNoMemory 3
1459 #define MAX_SIZE 255
1461 /* shared data for the image read/parse logic */
1462 static short hexTable[256]; /* conversion value */
1463 static int initialized = FALSE; /* easier to fill in at run time */
1466 * Table index for the hex values. Initialized once, first time.
1467 * Used for translation value or delimiter significance lookup.
1473 * We build the table at run time for several reasons:
1475 * 1. portable to non-ASCII machines.
1476 * 2. still reentrant since we set the init flag after setting table.
1477 * 3. easier to extend.
1478 * 4. less prone to bugs.
1480 hexTable['0'] = 0; hexTable['1'] = 1;
1481 hexTable['2'] = 2; hexTable['3'] = 3;
1482 hexTable['4'] = 4; hexTable['5'] = 5;
1483 hexTable['6'] = 6; hexTable['7'] = 7;
1484 hexTable['8'] = 8; hexTable['9'] = 9;
1485 hexTable['A'] = 10; hexTable['B'] = 11;
1486 hexTable['C'] = 12; hexTable['D'] = 13;
1487 hexTable['E'] = 14; hexTable['F'] = 15;
1488 hexTable['a'] = 10; hexTable['b'] = 11;
1489 hexTable['c'] = 12; hexTable['d'] = 13;
1490 hexTable['e'] = 14; hexTable['f'] = 15;
1492 /* delimiters of significance are flagged w/ negative value */
1493 hexTable[' '] = -1; hexTable[','] = -1;
1494 hexTable['}'] = -1; hexTable['\n'] = -1;
1495 hexTable['\t'] = -1;
1501 * read next hex value in the input stream, return -1 if EOF
1504 NextInt (FILE *fstream)
1511 /* loop, accumulate hex value until find delimiter */
1512 /* skip any initial delimiters found in read stream */
1520 /* trim high bits, check type and accumulate */
1522 if (isascii(ch) && isxdigit(ch)) {
1523 value = (value << 4) + hexTable[ch];
1525 } else if ((hexTable[ch]) < 0 && gotone)
1534 * The data returned by the following routine is always in left-most byte
1535 * first and left-most bit first. If it doesn't return BitmapSuccess then
1536 * its arguments won't have been touched. This routine should look as much
1537 * like the Xlib routine XReadBitmapfile as possible.
1539 int read_bitmap_data (FILE* fstream, unsigned int *width,
1540 unsigned int *height, unsigned char **datap,
1541 int *x_hot, int *y_hot)
1543 unsigned char *data = NULL; /* working variable */
1544 char line[MAX_SIZE]; /* input line from file */
1545 int size; /* number of bytes of data */
1546 char name_and_type[MAX_SIZE]; /* an input line */
1547 char *type; /* for parsing */
1548 int value; /* from an input line */
1549 int version10p; /* boolean, old format */
1550 int padding; /* to handle alignment */
1551 int bytes_per_line; /* per scanline of data */
1552 unsigned int ww = 0; /* width */
1553 unsigned int hh = 0; /* height */
1554 int hx = -1; /* x hotspot */
1555 int hy = -1; /* y hotspot */
1557 #define Xmalloc(size) malloc(size)
1559 /* first time initialization */
1560 if (initialized == FALSE) initHexTable();
1562 /* error cleanup and return macro */
1563 #define RETURN(code) { if (data) free (data); return code; }
1565 while (fgets(line, MAX_SIZE, fstream)) {
1566 if (strlen(line) == MAX_SIZE-1) {
1567 RETURN (BitmapFileInvalid);
1569 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1570 if (!(type = strrchr(name_and_type, '_')))
1571 type = name_and_type;
1575 if (!strcmp("width", type))
1576 ww = (unsigned int) value;
1577 if (!strcmp("height", type))
1578 hh = (unsigned int) value;
1579 if (!strcmp("hot", type)) {
1580 if (type-- == name_and_type || type-- == name_and_type)
1582 if (!strcmp("x_hot", type))
1584 if (!strcmp("y_hot", type))
1590 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1592 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1594 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1599 if (!(type = strrchr(name_and_type, '_')))
1600 type = name_and_type;
1604 if (strcmp("bits[]", type))
1608 RETURN (BitmapFileInvalid);
1610 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1615 bytes_per_line = (ww+7)/8 + padding;
1617 size = bytes_per_line * hh;
1618 data = (unsigned char *) Xmalloc ((unsigned int) size);
1620 RETURN (BitmapNoMemory);
1626 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1627 if ((value = NextInt(fstream)) < 0)
1628 RETURN (BitmapFileInvalid);
1630 if (!padding || ((bytes+2) % bytes_per_line))
1631 *(ptr++) = value >> 8;
1637 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1638 if ((value = NextInt(fstream)) < 0)
1639 RETURN (BitmapFileInvalid);
1647 RETURN (BitmapFileInvalid);
1654 if (x_hot) *x_hot = hx;
1655 if (y_hot) *y_hot = hy;
1657 RETURN (BitmapSuccess);
1661 int read_bitmap_data_from_file (const char *filename, unsigned int *width,
1662 unsigned int *height, unsigned char **datap,
1663 int *x_hot, int *y_hot)
1668 if ((fstream = fopen (filename, "r")) == NULL) {
1669 return BitmapOpenFailed;
1671 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1675 #endif /* HAVE_X_WINDOWS */
1677 /* this table flips four bits around. */
1678 static int flip_table[] =
1680 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1683 /* the bitmap data comes in the following format: Widths are padded to
1684 a multiple of 8. Scan lines are stored in increasing byte order
1685 from left to right, little-endian within a byte. 0 = white, 1 =
1686 black. It must be converted to the following format: Widths are
1687 padded to a multiple of 16. Scan lines are stored in increasing
1688 byte order from left to right, big-endian within a byte. 0 =
1689 black, 1 = white. */
1691 xbm_create_bitmap_from_data (HDC hdc, char *data,
1692 unsigned int width, unsigned int height,
1693 int mask, COLORREF fg, COLORREF bg)
1695 int old_width = (width + 7)/8;
1696 int new_width = BPLINE (2*((width + 15)/16));
1697 unsigned char *offset;
1699 unsigned char *new_data, *new_offset;
1701 BITMAPINFO *bmp_info =
1702 (BITMAPINFO*) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1708 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
1716 for (i=0; i<height; i++)
1718 offset = data + i*old_width;
1719 new_offset = new_data + i*new_width;
1721 for (j=0; j<old_width; j++)
1723 int byte = offset[j];
1724 new_offset[j] = ~ (unsigned char)
1725 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1729 /* if we want a mask invert the bits */
1732 new_offset = &new_data[height * new_width];
1733 while (new_offset-- != new_data)
1735 *new_offset ^= 0xff;
1739 bmp_info->bmiHeader.biWidth=width;
1740 bmp_info->bmiHeader.biHeight=-(LONG)height;
1741 bmp_info->bmiHeader.biPlanes=1;
1742 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1743 bmp_info->bmiHeader.biBitCount=1;
1744 bmp_info->bmiHeader.biCompression=BI_RGB;
1745 bmp_info->bmiHeader.biClrUsed = 2;
1746 bmp_info->bmiHeader.biClrImportant = 2;
1747 bmp_info->bmiHeader.biSizeImage = height * new_width;
1748 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1749 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1750 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1751 bmp_info->bmiColors[0].rgbReserved = 0;
1752 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1753 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1754 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1755 bmp_info->bmiColors[1].rgbReserved = 0;
1757 bitmap = CreateDIBSection (hdc,
1765 if (!bitmap || !bmp_buf)
1771 /* copy in the actual bitmap */
1772 memcpy (bmp_buf, new_data, height * new_width);
1778 /* Given inline data for a mono pixmap, initialize the given
1779 image instance accordingly. */
1782 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
1783 int width, int height,
1784 /* Note that data is in ext-format! */
1786 Lisp_Object instantiator,
1787 Lisp_Object pointer_fg,
1788 Lisp_Object pointer_bg,
1791 Lisp_Object mask_filename)
1793 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1794 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1795 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1796 enum image_instance_type type;
1797 COLORREF black = PALETTERGB (0,0,0);
1798 COLORREF white = PALETTERGB (255,255,255);
1801 CHECK_MSGDI_DEVICE (device);
1803 hdc = get_device_compdc (XDEVICE (device));
1805 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1806 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1808 if (!NILP (foreground) || !NILP (background))
1809 type = IMAGE_COLOR_PIXMAP;
1811 type = IMAGE_MONO_PIXMAP;
1813 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1814 type = IMAGE_MONO_PIXMAP;
1815 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1816 type = IMAGE_COLOR_PIXMAP;
1817 else if (dest_mask & IMAGE_POINTER_MASK)
1818 type = IMAGE_POINTER;
1820 incompatible_image_types (instantiator, dest_mask,
1821 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1822 | IMAGE_POINTER_MASK);
1824 mswindows_initialize_dibitmap_image_instance (ii, 1, type);
1826 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1827 find_keyword_in_vector (instantiator, Q_file);
1828 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = width;
1829 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = height;
1830 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1831 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1832 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1833 init_image_instance_geometry (ii);
1835 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1836 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1837 TRUE, black, white);
1841 case IMAGE_MONO_PIXMAP:
1842 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1843 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1844 FALSE, black, black);
1847 case IMAGE_COLOR_PIXMAP:
1849 COLORREF fg = black;
1850 COLORREF bg = white;
1852 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1854 Fmake_color_instance (foreground, device,
1855 encode_error_behavior_flag (ERROR_ME));
1857 if (COLOR_INSTANCEP (foreground))
1858 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1860 if (!NILP (background) && !COLOR_INSTANCEP (background))
1862 Fmake_color_instance (background, device,
1863 encode_error_behavior_flag (ERROR_ME));
1865 if (COLOR_INSTANCEP (background))
1866 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1868 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1869 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1871 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1872 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1879 COLORREF fg = black;
1880 COLORREF bg = white;
1882 if (NILP (foreground))
1883 foreground = pointer_fg;
1884 if (NILP (background))
1885 background = pointer_bg;
1887 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1888 find_keyword_in_vector (instantiator, Q_hotspot_x);
1889 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1890 find_keyword_in_vector (instantiator, Q_hotspot_y);
1891 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1892 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1893 if (COLOR_INSTANCEP (foreground))
1894 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1895 if (COLOR_INSTANCEP (background))
1896 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1898 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1899 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1901 mswindows_initialize_image_instance_icon (ii, TRUE);
1911 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1912 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1913 int dest_mask, int width, int height,
1914 /* Note that data is in ext-format! */
1917 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1918 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1919 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1920 HDC hdc = get_device_compdc (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
1923 if (!NILP (mask_data))
1925 const char *ext_data;
1927 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))),
1928 C_STRING_ALLOCA, ext_data,
1930 mask = xbm_create_bitmap_from_data (hdc,
1931 (unsigned char *) ext_data,
1932 XINT (XCAR (mask_data)),
1933 XINT (XCAR (XCDR (mask_data))),
1936 PALETTERGB (255,255,255));
1939 init_image_instance_from_xbm_inline (ii, width, height, bits,
1940 instantiator, pointer_fg, pointer_bg,
1941 dest_mask, mask, mask_file);
1944 /* Instantiate method for XBM's. */
1947 mswindows_xbm_instantiate (Lisp_Object image_instance,
1948 Lisp_Object instantiator,
1949 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1950 int dest_mask, Lisp_Object domain)
1952 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1953 const char *ext_data;
1955 assert (!NILP (data));
1957 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))),
1958 C_STRING_ALLOCA, ext_data,
1961 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1962 pointer_bg, dest_mask, XINT (XCAR (data)),
1963 XINT (XCAR (XCDR (data))), ext_data);
1967 /**********************************************************************
1969 **********************************************************************/
1971 /* This is about to get redefined! */
1974 /* We have to define SYSV32 so that compface.h includes string.h
1975 instead of strings.h. */
1980 #include <compface.h>
1984 /* JMP_BUF cannot be used here because if it doesn't get defined
1985 to jmp_buf we end up with a conflicting type error with the
1986 definition in compface.h */
1987 extern jmp_buf comp_env;
1991 mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1992 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1993 int dest_mask, Lisp_Object domain)
1995 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1997 char *p, *bits, *bp;
1998 const char * volatile emsg = 0;
1999 const char * volatile dstring;
2001 assert (!NILP (data));
2003 TO_EXTERNAL_FORMAT (LISP_STRING, data,
2004 C_STRING_ALLOCA, dstring,
2007 if ((p = strchr (dstring, ':')))
2012 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
2013 if (!(stattis = setjmp (comp_env)))
2015 UnCompAll ((char *) dstring);
2022 emsg = "uncompface: internal error";
2025 emsg = "uncompface: insufficient or invalid data";
2028 emsg = "uncompface: excess data ignored";
2033 signal_simple_error_2 (emsg, data, Qimage);
2035 bp = bits = (char *) alloca (PIXELS / 8);
2037 /* the compface library exports char F[], which uses a single byte per
2038 pixel to represent a 48x48 bitmap. Yuck. */
2039 for (i = 0, p = F; i < (PIXELS / 8); ++i)
2042 /* reverse the bit order of each byte... */
2043 for (b = n = 0; b < 8; ++b)
2050 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
2051 pointer_bg, dest_mask, 48, 48, bits);
2053 #endif /* HAVE_XFACE */
2056 /************************************************************************/
2057 /* image instance methods */
2058 /************************************************************************/
2061 mswindows_print_image_instance (Lisp_Image_Instance *p,
2062 Lisp_Object printcharfun,
2067 switch (IMAGE_INSTANCE_TYPE (p))
2069 case IMAGE_MONO_PIXMAP:
2070 case IMAGE_COLOR_PIXMAP:
2072 sprintf (buf, " (0x%lx",
2073 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
2074 write_c_string (buf, printcharfun);
2075 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2077 sprintf (buf, "/0x%lx",
2078 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2079 write_c_string (buf, printcharfun);
2081 write_c_string (")", printcharfun);
2089 #ifdef DEBUG_WIDGETS
2090 extern int debug_widget_instances;
2094 mswindows_finalize_image_instance (Lisp_Image_Instance *p)
2099 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
2101 if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p))
2102 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
2104 #ifdef DEBUG_WIDGETS
2105 debug_widget_instances--;
2106 stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
2108 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2110 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
2111 DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p));
2112 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
2118 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
2119 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
2121 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p))
2123 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
2125 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i))
2126 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i));
2127 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0;
2129 xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p));
2130 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0;
2132 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2133 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2134 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
2135 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
2136 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
2137 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2148 /************************************************************************/
2149 /* subwindow and widget support */
2150 /************************************************************************/
2153 mswindows_widget_hfont (Lisp_Image_Instance *p,
2156 Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (p);
2157 int under = FACE_UNDERLINE_P (face, domain);
2158 int strike = FACE_STRIKETHRU_P (face, domain);
2159 Lisp_Object font = query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (p),
2162 return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike);
2166 begin_defer_window_pos (struct frame *f)
2168 #ifdef DEFER_WINDOW_POS
2169 if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0)
2170 FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10);
2172 return FRAME_MSWINDOWS_DATA (f)->hdwp;
2175 /* unmap the image if it is a widget. This is used by redisplay via
2176 redisplay_unmap_subwindows */
2178 mswindows_unmap_subwindow (Lisp_Image_Instance *p)
2180 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2182 #ifdef DEFER_WINDOW_POS
2183 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2184 HDWP hdwp = begin_defer_window_pos (f);
2186 new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2189 SWP_HIDEWINDOW | SWP_NOACTIVATE |
2190 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
2191 /* Setting this flag causes the call to
2192 DeferWindowPos to fail with
2193 "Invalid parameter". I don't understand
2194 why we bother to try and set this
2196 /* | SWP_NOSENDCHANGING */
2199 mswindows_output_last_error ("unmapping");
2202 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2204 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2207 SWP_HIDEWINDOW | SWP_NOACTIVATE |
2208 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER );
2210 if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))
2211 SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p)));
2215 /* map the subwindow. This is used by redisplay via
2216 redisplay_output_subwindow */
2218 mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y,
2219 struct display_glyph_area* dga)
2221 #ifdef DEFER_WINDOW_POS
2222 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
2223 HDWP hdwp = begin_defer_window_pos (f);
2226 /* move the window before mapping it ... */
2227 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2229 x, y, dga->width, dga->height,
2231 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2232 /* ... adjust the child ... */
2233 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2235 -dga->xoffset, -dga->yoffset, 0, 0,
2236 SWP_NOZORDER | SWP_NOSIZE
2237 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2238 /* ... now map it - we are not allowed to move it at the same time. */
2239 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
2241 #ifdef DEFER_WINDOW_POS
2242 new_hdwp = DeferWindowPos
2244 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2246 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2248 /* | SWP_NOCOPYBITS */
2249 /* Setting this flag causes the call to
2250 DeferWindowPos to fail with
2251 "Invalid parameter". I don't understand
2252 why we bother to try and set this
2254 /* | SWP_NOSENDCHANGING */
2257 mswindows_output_last_error ("mapping");
2260 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp;
2262 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2265 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2266 | SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE);
2271 /* resize the subwindow instance */
2273 mswindows_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
2275 /* Set the size of the control .... */
2276 if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2279 SWP_NOZORDER | SWP_NOMOVE
2280 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING))
2281 mswindows_output_last_error ("resizing");
2284 /* Simply resize the window here. */
2286 mswindows_redisplay_subwindow (Lisp_Image_Instance *p)
2288 mswindows_resize_subwindow (p,
2289 IMAGE_INSTANCE_WIDTH (p),
2290 IMAGE_INSTANCE_HEIGHT (p));
2293 /* when you click on a widget you may activate another widget this
2294 needs to be checked and all appropriate widgets updated */
2296 mswindows_redisplay_widget (Lisp_Image_Instance *p)
2298 /* Possibly update the face font and colors. */
2299 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))
2300 && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
2301 || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
2302 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)))
2304 /* set the widget font from the widget face */
2305 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2307 (WPARAM) mswindows_widget_hfont
2308 (p, IMAGE_INSTANCE_FRAME (p)),
2309 MAKELPARAM (TRUE, 0));
2311 /* Possibly update the dimensions. */
2312 if (IMAGE_INSTANCE_SIZE_CHANGED (p))
2314 mswindows_resize_subwindow (p,
2315 IMAGE_INSTANCE_WIDTH (p),
2316 IMAGE_INSTANCE_HEIGHT (p));
2318 /* Possibly update the text in the widget. */
2319 if (IMAGE_INSTANCE_TEXT_CHANGED (p)
2320 && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)))
2323 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (p),
2324 C_STRING_ALLOCA, lparam,
2326 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2327 WM_SETTEXT, 0, (LPARAM)lparam);
2331 /* register widgets into our hashtable so that we can cope with the
2332 callbacks. The hashtable is weak so deregistration is handled
2335 mswindows_register_gui_item (Lisp_Object image_instance,
2336 Lisp_Object gui, Lisp_Object domain)
2338 Lisp_Object frame = DOMAIN_FRAME (domain);
2339 struct frame* f = XFRAME (frame);
2340 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f),
2343 Fputhash (make_int (id), image_instance,
2344 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
2345 Fputhash (make_int (id), XGUI_ITEM (gui)->callback,
2346 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
2347 Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex,
2348 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
2353 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2355 return mswindows_register_gui_item (instance,
2356 XIMAGE_INSTANCE_WIDGET_ITEM (instance),
2361 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2362 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2363 int dest_mask, Lisp_Object domain)
2365 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2366 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2367 Lisp_Object frame = DOMAIN_FRAME (domain);
2370 CHECK_MSWINDOWS_DEVICE (device);
2372 /* have to set the type this late in case there is no device
2373 instantiation for a widget */
2374 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2375 /* Allocate space for the clip window */
2376 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2378 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2381 XEMACS_CONTROL_CLASS,
2383 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2384 0, /* starting x position */
2385 0, /* starting y position */
2386 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2387 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2389 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2391 NULL, /* must be null for this class */
2393 signal_simple_error ("window creation failed with code",
2394 make_int (GetLastError()));
2396 wnd = CreateWindow( "STATIC",
2399 0, /* starting x position */
2400 0, /* starting y position */
2401 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2402 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2403 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2406 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2410 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2411 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2415 mswindows_image_instance_equal (Lisp_Image_Instance *p1,
2416 Lisp_Image_Instance *p2, int depth)
2418 switch (IMAGE_INSTANCE_TYPE (p1))
2420 case IMAGE_MONO_PIXMAP:
2421 case IMAGE_COLOR_PIXMAP:
2423 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2424 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2435 static unsigned long
2436 mswindows_image_instance_hash (Lisp_Image_Instance *p, int depth)
2438 switch (IMAGE_INSTANCE_TYPE (p))
2440 case IMAGE_MONO_PIXMAP:
2441 case IMAGE_COLOR_PIXMAP:
2443 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2450 /* Set all the slots in an image instance structure to reasonable
2451 default values. This is used somewhere within an instantiate
2452 method. It is assumed that the device slot within the image
2453 instance is already set -- this is the case when instantiate
2454 methods are called. */
2457 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii,
2459 enum image_instance_type type)
2461 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2462 IMAGE_INSTANCE_TYPE (ii) = type;
2463 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2464 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2465 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2466 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2467 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2468 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2469 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
2470 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) =
2471 xnew_array_and_zero (HBITMAP, slices);
2477 /************************************************************************/
2479 /************************************************************************/
2481 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2482 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2483 int dest_mask, Lisp_Object domain,
2484 const char* class, int flags, int exflags)
2486 /* this function can call lisp */
2487 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2488 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2489 Lisp_Object frame = DOMAIN_FRAME (domain);
2493 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2494 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2496 CHECK_MSWINDOWS_DEVICE (device);
2498 if (!gui_item_active_p (gui))
2499 flags |= WS_DISABLED;
2501 style = pgui->style;
2503 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex))
2505 id = mswindows_register_widget_instance (image_instance, domain);
2508 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2509 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii),
2510 C_STRING_ALLOCA, nm,
2513 /* allocate space for the clip window and then allocate the clip window */
2514 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2516 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2518 WS_EX_CONTROLPARENT, /* EX flags */
2519 XEMACS_CONTROL_CLASS,
2521 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2522 0, /* starting x position */
2523 0, /* starting y position */
2524 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2525 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2527 DOMAIN_MSWINDOWS_HANDLE (domain),
2528 (HMENU)id, /* No menu */
2529 NULL, /* must be null for this class */
2531 signal_simple_error ("window creation failed with code",
2532 make_int (GetLastError()));
2534 if ((wnd = CreateWindowEx(
2535 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2538 flags | WS_CHILD | WS_VISIBLE,
2539 0, /* starting x position */
2540 0, /* starting y position */
2541 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2542 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2544 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2545 (HMENU)id, /* No menu */
2548 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2551 signal_simple_error ("window creation failed with code",
2552 make_int (GetLastError()));
2554 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2555 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2556 /* set the widget font from the widget face */
2557 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2558 SendMessage (wnd, WM_SETFONT,
2559 (WPARAM) mswindows_widget_hfont (ii, domain),
2560 MAKELPARAM (TRUE, 0));
2562 /* #### doesn't work. need to investigate more closely. */
2563 if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (ii))
2568 /* Instantiate a native layout widget. */
2570 mswindows_native_layout_instantiate (Lisp_Object image_instance,
2571 Lisp_Object instantiator,
2572 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2573 int dest_mask, Lisp_Object domain)
2575 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2577 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2578 pointer_bg, dest_mask, domain, "STATIC",
2579 /* Approximation to styles available with
2580 an XEmacs layout. */
2581 (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2583 EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii),
2585 GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
2586 ? SS_ETCHEDFRAME : SS_SUNKEN) | DS_CONTROL,
2590 /* Instantiate a button widget. Unfortunately instantiated widgets are
2591 particular to a frame since they need to have a parent. It's not
2592 like images where you just select the image into the context you
2593 want to display it in and BitBlt it. So image instances can have a
2594 many-to-one relationship with things you see, whereas widgets can
2595 only be one-to-one (i.e. per frame) */
2597 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2598 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2599 int dest_mask, Lisp_Object domain)
2601 /* This function can call lisp */
2602 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2604 int flags = WS_TABSTOP | BS_NOTIFY;
2605 /* BS_NOTIFY #### is needed to get exotic feedback only. Since we
2606 seem to want nothing beyond BN_CLICK, the style is perhaps not
2609 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2610 Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2611 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2615 if (!IMAGE_INSTANCEP (glyph))
2616 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2618 if (IMAGE_INSTANCEP (glyph))
2619 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2620 BS_BITMAP : BS_ICON;
2623 style = pgui->style;
2625 /* #### consider using the default face for radio and toggle
2627 if (EQ (style, Qradio))
2629 flags |= BS_RADIOBUTTON;
2631 else if (EQ (style, Qtoggle))
2633 flags |= BS_AUTOCHECKBOX;
2637 flags |= BS_DEFPUSHBUTTON;
2640 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2641 pointer_bg, dest_mask, domain, "BUTTON",
2644 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2645 /* set the checked state */
2646 if (gui_item_selected_p (gui))
2647 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2649 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2650 /* add the image if one was given */
2651 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph)
2653 IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph)))
2655 SendMessage (wnd, BM_SETIMAGE,
2656 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2657 IMAGE_BITMAP : IMAGE_ICON),
2658 (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2659 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2660 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2664 /* Update the state of a button. */
2666 mswindows_button_redisplay (Lisp_Object image_instance)
2668 /* This function can GC if IN_REDISPLAY is false. */
2669 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2671 /* buttons checked or otherwise */
2672 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii)))
2673 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2674 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2676 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2677 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2680 /* instantiate an edit control */
2682 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2683 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2684 int dest_mask, Lisp_Object domain)
2686 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2687 pointer_bg, dest_mask, domain, "EDIT",
2688 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2689 | WS_BORDER, WS_EX_CLIENTEDGE);
2692 /* instantiate a progress gauge */
2694 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2695 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2696 int dest_mask, Lisp_Object domain)
2699 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2701 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2702 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2703 WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE);
2704 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2705 /* set the colors */
2706 #ifdef PBS_SETBKCOLOR
2707 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2708 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2711 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2712 XIMAGE_INSTANCE_FRAME (ii))))));
2714 #ifdef PBS_SETBARCOLOR
2715 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2716 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2719 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2720 XIMAGE_INSTANCE_FRAME (ii))))));
2722 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEMS (ii))->value;
2724 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2725 PBM_SETPOS, (WPARAM)XINT (val), 0);
2728 /* instantiate a tree view widget */
2729 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2730 HWND wnd, HTREEITEM parent, Lisp_Object item,
2731 int children, Lisp_Object domain)
2733 TV_INSERTSTRUCT tvitem;
2736 tvitem.hParent = parent;
2737 tvitem.hInsertAfter = TVI_LAST;
2738 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2739 tvitem.item.cChildren = children;
2741 if (GUI_ITEMP (item))
2743 tvitem.item.lParam = mswindows_register_gui_item (image_instance,
2745 tvitem.item.mask |= TVIF_PARAM;
2746 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2747 C_STRING_ALLOCA, tvitem.item.pszText,
2751 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2752 C_STRING_ALLOCA, tvitem.item.pszText,
2755 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2757 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2758 0, (LPARAM)&tvitem)) == 0)
2759 signal_simple_error ("error adding tree view entry", item);
2764 static void add_tree_item_list (Lisp_Object image_instance,
2765 HWND wnd, HTREEITEM parent, Lisp_Object list,
2770 /* get the first item */
2771 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2772 /* recursively add items to the tree view */
2773 LIST_LOOP (rest, XCDR (list))
2775 if (LISTP (XCAR (rest)))
2776 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2778 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2783 mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2784 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2785 int dest_mask, Lisp_Object domain)
2790 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2791 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2792 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2793 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2794 | TVS_HASLINES | TVS_HASBUTTONS,
2797 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2800 parent = add_tree_item (image_instance, wnd, NULL,
2801 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
2804 /* recursively add items to the tree view */
2805 /* add items to the tab */
2806 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2808 if (LISTP (XCAR (rest)))
2809 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2811 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2815 /* Set the properties of a tree view. */
2817 mswindows_tree_view_redisplay (Lisp_Object image_instance)
2819 /* This function can GC if IN_REDISPLAY is false. */
2820 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2822 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2824 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2827 /* Delete previous items. */
2828 SendMessage (wnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
2830 parent = add_tree_item (image_instance, wnd, NULL,
2831 XCAR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)),
2832 TRUE, IMAGE_INSTANCE_DOMAIN (ii));
2834 /* recursively add items to the tree view */
2835 /* add items to the tab */
2836 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
2838 if (LISTP (XCAR (rest)))
2839 add_tree_item_list (image_instance, wnd, parent, XCAR (rest),
2840 IMAGE_INSTANCE_DOMAIN (ii));
2842 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE,
2843 IMAGE_INSTANCE_DOMAIN (ii));
2848 /* instantiate a tab control */
2850 add_tab_item (Lisp_Object image_instance,
2851 HWND wnd, Lisp_Object item,
2852 Lisp_Object domain, int i)
2857 tvitem.mask = TCIF_TEXT;
2859 if (GUI_ITEMP (item))
2861 tvitem.lParam = mswindows_register_gui_item (image_instance,
2863 tvitem.mask |= TCIF_PARAM;
2864 TO_EXTERNAL_FORMAT (LISP_STRING, XGUI_ITEM (item)->name,
2865 C_STRING_ALLOCA, tvitem.pszText,
2870 CHECK_STRING (item);
2871 TO_EXTERNAL_FORMAT (LISP_STRING, item,
2872 C_STRING_ALLOCA, tvitem.pszText,
2876 tvitem.cchTextMax = strlen (tvitem.pszText);
2878 if ((ret = SendMessage (wnd, TCM_INSERTITEM,
2879 i, (LPARAM)&tvitem)) < 0)
2880 signal_simple_error ("error adding tab entry", item);
2886 mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2887 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2888 int dest_mask, Lisp_Object domain)
2890 /* This function can call lisp */
2893 int i = 0, selected = 0;
2894 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2895 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
2896 unsigned int flags = WS_TABSTOP;
2898 if (EQ (orient, Qleft) || EQ (orient, Qright))
2900 flags |= TCS_VERTICAL | TCS_MULTILINE;
2902 if (EQ (orient, Qright) || EQ (orient, Qbottom))
2904 flags |= TCS_BOTTOM;
2907 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2908 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2909 /* borders don't suit tabs so well */
2911 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2912 /* add items to the tab */
2913 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2915 int idx = add_tab_item (image_instance, wnd, XCAR (rest), domain, i);
2917 if (gui_item_selected_p (XCAR (rest)))
2921 SendMessage (wnd, TCM_SETCURSEL, selected, 0);
2924 /* Set the properties of a tab control. */
2926 mswindows_tab_control_redisplay (Lisp_Object image_instance)
2928 /* This function can GC if IN_REDISPLAY is false. */
2929 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2930 #ifdef DEBUG_WIDGET_OUTPUT
2931 stderr_out ("tab control %p redisplayed\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
2933 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
2935 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
2937 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2938 int i = 0, selected = 0;
2941 assert (!NILP (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2943 /* If only the order has changed then simply select the first
2944 one. This stops horrendous rebuilding of the tabs each time
2945 you click on one. */
2946 if (tab_control_order_only_changed (image_instance))
2948 Lisp_Object selected =
2949 gui_item_list_find_selected
2950 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
2951 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
2952 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
2954 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2956 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
2958 Lisp_Object old_selected = gui_item_list_find_selected
2959 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2961 /* Pick up the new selected item. */
2962 XGUI_ITEM (old_selected)->selected =
2963 XGUI_ITEM (XCAR (rest))->selected;
2964 XGUI_ITEM (XCAR (rest))->selected =
2965 XGUI_ITEM (selected)->selected;
2966 /* We're not actually changing the items. */
2967 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
2968 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
2970 SendMessage (wnd, TCM_SETCURSEL, i, 0);
2971 #ifdef DEBUG_WIDGET_OUTPUT
2972 stderr_out ("tab control %p selected item %d\n",
2973 IMAGE_INSTANCE_SUBWINDOW_ID (ii), i);
2982 /* delete the pre-existing items */
2983 SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
2985 /* add items to the tab */
2986 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
2988 add_tab_item (image_instance, wnd, XCAR (rest),
2989 IMAGE_INSTANCE_FRAME (ii), i);
2990 if (gui_item_selected_p (XCAR (rest)))
2994 SendMessage (wnd, TCM_SETCURSEL, selected, 0);
2999 /* instantiate a static control possible for putting other things in */
3001 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3002 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3003 int dest_mask, Lisp_Object domain)
3005 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3006 pointer_bg, dest_mask, domain, "STATIC",
3007 0, WS_EX_STATICEDGE);
3010 /* instantiate a scrollbar control */
3012 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3013 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3014 int dest_mask, Lisp_Object domain)
3016 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3017 pointer_bg, dest_mask, domain, "SCROLLBAR",
3018 WS_TABSTOP, WS_EX_CLIENTEDGE);
3021 /* instantiate a combo control */
3023 mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
3024 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
3025 int dest_mask, Lisp_Object domain)
3027 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3030 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
3033 /* Maybe ought to generalise this more but it may be very windows
3034 specific. In windows the window height of a combo box is the
3035 height when the combo box is open. Thus we need to set the height
3036 before creating the window and then reset it to a single line
3037 after the window is created so that redisplay does the right
3039 widget_instantiate (image_instance, instantiator, pointer_fg,
3040 pointer_bg, dest_mask, domain);
3042 /* We now have everything right apart from the height. */
3043 default_face_font_info (domain, 0, 0, &height, 0, 0);
3044 GET_LIST_LENGTH (items, len);
3046 height = (height + WIDGET_BORDER_HEIGHT * 2 ) * len;
3047 IMAGE_INSTANCE_HEIGHT (ii) = height;
3049 /* Now create the widget. */
3050 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
3051 pointer_bg, dest_mask, domain, "COMBOBOX",
3052 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
3054 | CBS_HASSTRINGS | WS_VSCROLL,
3056 /* Reset the height. layout will probably do this safely, but better make sure. */
3057 image_instance_layout (image_instance,
3058 IMAGE_UNSPECIFIED_GEOMETRY,
3059 IMAGE_UNSPECIFIED_GEOMETRY,
3060 IMAGE_UNCHANGED_GEOMETRY,
3061 IMAGE_UNCHANGED_GEOMETRY,
3064 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3065 /* add items to the combo box */
3066 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
3067 LIST_LOOP (rest, items)
3070 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (rest),
3071 C_STRING_ALLOCA, lparam,
3073 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
3074 signal_simple_error ("error adding combo entries", instantiator);
3078 /* get properties of a control */
3080 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
3082 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3083 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3084 /* get the text from a control */
3085 if (EQ (prop, Q_text))
3087 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
3088 Extbyte *buf = (Extbyte*) alloca (len+1);
3090 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
3091 return build_ext_string (buf, Qnative);
3096 /* get properties of a button */
3098 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
3100 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3101 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3102 /* check the state of a button */
3103 if (EQ (prop, Q_selected))
3105 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
3113 /* get properties of a combo box */
3115 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
3117 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3118 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
3119 /* get the text from a control */
3120 if (EQ (prop, Q_text))
3122 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
3123 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
3124 Extbyte* buf = (Extbyte*) alloca (len+1);
3125 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
3126 return build_ext_string (buf, Qnative);
3131 /* set the properties of a progress gauge */
3133 mswindows_progress_gauge_redisplay (Lisp_Object image_instance)
3135 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
3137 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
3140 #ifdef ERROR_CHECK_GLYPHS
3141 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
3143 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
3144 #ifdef DEBUG_WIDGET_OUTPUT
3145 stderr_out ("progress gauge displayed value on %p updated to %ld\n",
3146 WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3150 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
3151 PBM_SETPOS, (WPARAM)XINT (val), 0);
3156 mswindows_control_wnd_proc (HWND hwnd, UINT msg,
3157 WPARAM wParam, LPARAM lParam)
3163 case WM_CTLCOLORBTN:
3164 case WM_CTLCOLORLISTBOX:
3165 case WM_CTLCOLOREDIT:
3166 case WM_CTLCOLORSTATIC:
3167 case WM_CTLCOLORSCROLLBAR:
3169 return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam);
3171 return DefWindowProc (hwnd, msg, wParam, lParam);
3175 #endif /* HAVE_WIDGETS */
3178 /************************************************************************/
3179 /* initialization */
3180 /************************************************************************/
3183 syms_of_glyphs_mswindows (void)
3185 defkeyword (&Q_resource_id, ":resource-id");
3186 defkeyword (&Q_resource_type, ":resource-type");
3190 console_type_create_glyphs_mswindows (void)
3192 /* image methods - display */
3193 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
3194 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
3195 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
3196 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
3197 CONSOLE_HAS_METHOD (mswindows, redisplay_subwindow);
3198 CONSOLE_HAS_METHOD (mswindows, resize_subwindow);
3199 CONSOLE_HAS_METHOD (mswindows, redisplay_widget);
3200 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
3201 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
3202 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
3203 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
3205 /* image methods - printer */
3206 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_image_instance);
3207 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_image_instance);
3208 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_equal);
3209 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_hash);
3210 CONSOLE_INHERITS_METHOD (msprinter, mswindows, init_image_instance_from_eimage);
3211 CONSOLE_INHERITS_METHOD (msprinter, mswindows, locate_pixmap_file);
3215 image_instantiator_format_create_glyphs_mswindows (void)
3217 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing);
3218 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string);
3219 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string);
3220 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit);
3221 /* image-instantiator types */
3222 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
3223 INITIALIZE_DEVICE_IIFORMAT (msprinter, xbm);
3224 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
3225 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xbm, instantiate);
3227 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
3228 INITIALIZE_DEVICE_IIFORMAT (msprinter, xpm);
3229 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
3230 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xpm, instantiate);
3233 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
3234 INITIALIZE_DEVICE_IIFORMAT (msprinter, xface);
3235 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
3236 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xface, instantiate);
3239 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, jpeg);
3242 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, tiff);
3245 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, png);
3248 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif);
3251 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
3252 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
3254 IIFORMAT_VALID_CONSOLE (mswindows, layout);
3255 INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout);
3256 IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate);
3258 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
3259 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
3260 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
3261 IIFORMAT_HAS_DEVMETHOD (mswindows, button, redisplay);
3262 /* edit-field widget */
3263 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
3264 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
3266 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
3267 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
3269 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
3270 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
3272 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
3273 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
3274 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
3276 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
3277 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
3278 /* progress gauge */
3279 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
3280 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, redisplay);
3281 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
3282 /* tree view widget */
3283 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
3284 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
3285 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, redisplay);
3286 /* tab control widget */
3287 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
3288 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
3289 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, redisplay);
3291 /* windows bitmap format */
3292 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
3293 IIFORMAT_HAS_METHOD (bmp, validate);
3294 IIFORMAT_HAS_METHOD (bmp, normalize);
3295 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
3296 IIFORMAT_HAS_METHOD (bmp, instantiate);
3298 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
3299 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
3300 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, bmp);
3302 /* mswindows resources */
3303 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
3304 "mswindows-resource");
3306 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
3307 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
3308 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
3309 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
3311 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
3312 check_valid_resource_symbol);
3313 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
3314 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
3315 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, mswindows_resource);
3319 vars_of_glyphs_mswindows (void)
3321 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
3322 A list of the directories in which mswindows bitmap files may be found.
3323 This is used by the `make-image-instance' function.
3325 Vmswindows_bitmap_file_path = Qnil;
3329 complex_vars_of_glyphs_mswindows (void)