comparison src/glyphs-msw.c @ 428:3ecd8885ac67 r21-2-22

Import from CVS: tag r21-2-22
author cvs
date Mon, 13 Aug 2007 11:28:15 +0200
parents
children a5df635868b2
comparison
equal deleted inserted replaced
427:0a0253eac470 428:3ecd8885ac67
1 /* mswindows-specific glyph objects.
2 Copyright (C) 1998, 1999 Andy Piper.
3
4 This file is part of XEmacs.
5
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
9 later version.
10
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
14 for more details.
15
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. */
20
21 /* Synched up with: Not in FSF. */
22
23 /* written by Andy Piper <andy@xemacs.org> plagerising bits from
24 glyphs-x.c */
25
26 #include <config.h>
27 #include "lisp.h"
28 #include "lstream.h"
29
30 #define OEMRESOURCE /* Define OCR_ and friend constants */
31 #include "console-msw.h"
32 #include "glyphs-msw.h"
33 #include "objects-msw.h"
34
35 #include "window.h"
36 #include "elhash.h"
37 #include "buffer.h"
38 #include "frame.h"
39 #include "insdel.h"
40 #include "opaque.h"
41 #include "sysfile.h"
42 #include "faces.h"
43 #include "imgproc.h"
44
45 #ifdef FILE_CODING
46 #include "file-coding.h"
47 #endif
48 #include <stdio.h>
49 #include <ctype.h>
50 #ifdef HAVE_XFACE
51 #include <setjmp.h>
52 #endif
53
54 #define WIDGET_GLYPH_SLOT 0
55
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);
60 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
61 #ifdef HAVE_JPEG
62 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
63 #endif
64 #ifdef HAVE_TIFF
65 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff);
66 #endif
67 #ifdef HAVE_PNG
68 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png);
69 #endif
70 #ifdef HAVE_GIF
71 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif);
72 #endif
73 #ifdef HAVE_XPM
74 DEFINE_DEVICE_IIFORMAT (mswindows, xpm);
75 #endif
76 DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
77 #ifdef HAVE_XFACE
78 DEFINE_DEVICE_IIFORMAT (mswindows, xface);
79 #endif
80 DEFINE_DEVICE_IIFORMAT (mswindows, button);
81 DEFINE_DEVICE_IIFORMAT (mswindows, edit_field);
82 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
83 DEFINE_DEVICE_IIFORMAT (mswindows, widget);
84 DEFINE_DEVICE_IIFORMAT (mswindows, label);
85 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
86 DEFINE_DEVICE_IIFORMAT (mswindows, combo_box);
87 DEFINE_DEVICE_IIFORMAT (mswindows, progress_gauge);
88 DEFINE_DEVICE_IIFORMAT (mswindows, tree_view);
89 DEFINE_DEVICE_IIFORMAT (mswindows, tab_control);
90
91 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
92 Lisp_Object Qbmp;
93 Lisp_Object Vmswindows_bitmap_file_path;
94 static COLORREF transparent_color = RGB (1,1,1);
95
96 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource);
97 Lisp_Object Q_resource_type, Q_resource_id;
98 Lisp_Object Qmswindows_resource;
99
100 static void
101 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
102 int slices,
103 enum image_instance_type type);
104 static void
105 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
106 struct frame* f);
107
108 COLORREF mswindows_string_to_color (CONST char *name);
109
110 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
111
112 /************************************************************************/
113 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
114 /* proper display */
115 /************************************************************************/
116 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
117 int width, int height,
118 unsigned char *pic,
119 int *bit_count,
120 unsigned char** bmp_data)
121 {
122 struct device *d = XDEVICE (device);
123 int i,j;
124 RGBQUAD* colortbl;
125 int ncolors;
126 BITMAPINFO* bmp_info;
127 unsigned char *ip, *dp;
128
129 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
130 {
131 int bpline = BPLINE(width * 3);
132 /* FIXME: we can do this because 24bpp implies no color table, once
133 * we start palettizing this is no longer true. The X versions of
134 * this function quantises to 256 colors or bit masks down to a
135 * long. Windows can actually handle rgb triples in the raw so I
136 * don't see much point trying to optimize down to the best
137 * structure - unless it has memory / color allocation implications
138 * .... */
139 bmp_info=xnew_and_zero (BITMAPINFO);
140
141 if (!bmp_info)
142 {
143 return NULL;
144 }
145
146 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
147 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
148 bmp_info->bmiHeader.biSizeImage=width*height*3;
149
150 /* bitmap data needs to be in blue, green, red triples - in that
151 order, eimage is in RGB format so we need to convert */
152 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
153 *bit_count = bpline * height;
154
155 if (!bmp_data)
156 {
157 xfree (bmp_info);
158 return NULL;
159 }
160
161 ip = pic;
162 for (i = height-1; i >= 0; i--) {
163 dp = (*bmp_data) + (i * bpline);
164 for (j = 0; j < width; j++) {
165 dp[2] =*ip++;
166 dp[1] =*ip++;
167 *dp =*ip++;
168 dp += 3;
169 }
170 }
171 }
172 else /* scale to 256 colors */
173 {
174 int rd,gr,bl;
175 quant_table *qtable;
176 int bpline = BPLINE (width * 3);
177 /* Quantize the image and get a histogram while we're at it.
178 Do this first to save memory */
179 qtable = build_EImage_quantable(pic, width, height, 256);
180 if (qtable == NULL) return NULL;
181
182 /* use our quantize table to allocate the colors */
183 ncolors = qtable->num_active_colors;
184 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
185 sizeof(RGBQUAD) * ncolors);
186 if (!bmp_info)
187 {
188 xfree (qtable);
189 return NULL;
190 }
191
192 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
193
194 bmp_info->bmiHeader.biBitCount=8;
195 bmp_info->bmiHeader.biCompression=BI_RGB;
196 bmp_info->bmiHeader.biSizeImage=bpline*height;
197 bmp_info->bmiHeader.biClrUsed=ncolors;
198 bmp_info->bmiHeader.biClrImportant=ncolors;
199
200 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
201 *bit_count = bpline * height;
202
203 if (!*bmp_data)
204 {
205 xfree (qtable);
206 xfree (bmp_info);
207 return NULL;
208 }
209
210 /* build up an RGBQUAD colortable */
211 for (i = 0; i < qtable->num_active_colors; i++) {
212 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
213 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
214 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
215 colortbl[i].rgbReserved = 0;
216 }
217
218 /* now build up the data. picture has to be upside-down and
219 back-to-front for msw bitmaps */
220 ip = pic;
221 for (i = height-1; i >= 0; i--) {
222 dp = (*bmp_data) + (i * bpline);
223 for (j = 0; j < width; j++) {
224 rd = *ip++;
225 gr = *ip++;
226 bl = *ip++;
227 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
228 }
229 }
230 xfree (qtable);
231 }
232 /* fix up the standard stuff */
233 bmp_info->bmiHeader.biWidth=width;
234 bmp_info->bmiHeader.biHeight=height;
235 bmp_info->bmiHeader.biPlanes=1;
236 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
237 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
238 bmp_info->bmiHeader.biYPelsPerMeter=0;
239
240 return bmp_info;
241 }
242
243 /* Given a pixmap filename, look through all of the "standard" places
244 where the file might be located. Return a full pathname if found;
245 otherwise, return Qnil. */
246
247 static Lisp_Object
248 mswindows_locate_pixmap_file (Lisp_Object name)
249 {
250 /* This function can GC if IN_REDISPLAY is false */
251 Lisp_Object found;
252
253 /* Check non-absolute pathnames with a directory component relative to
254 the search path; that's the way Xt does it. */
255 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
256 (XSTRING_BYTE (name, 0) == '.' &&
257 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
258 (XSTRING_BYTE (name, 1) == '.' &&
259 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
260 {
261 if (!NILP (Ffile_readable_p (name)))
262 return name;
263 else
264 return Qnil;
265 }
266
267 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0)
268 {
269 Lisp_Object temp = list1 (Vdata_directory);
270 struct gcpro gcpro1;
271
272 GCPRO1 (temp);
273 locate_file (temp, name, Qnil, &found, R_OK);
274 UNGCPRO;
275 }
276
277 return found;
278 }
279
280
281 /* Initialize an image instance from a bitmap
282
283 DEST_MASK specifies the mask of allowed image types.
284
285 If this fails, signal an error. INSTANTIATOR is only used
286 in the error message. */
287
288 static void
289 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
290 BITMAPINFO *bmp_info,
291 int dest_mask,
292 void *bmp_data,
293 int bmp_bits,
294 int slices,
295 Lisp_Object instantiator,
296 int x_hot, int y_hot,
297 int create_mask)
298 {
299 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
300 struct device *d = XDEVICE (device);
301 struct frame *f;
302 void* bmp_buf=0;
303 int type = 0;
304 HBITMAP bitmap;
305 HDC hdc;
306
307 if (!DEVICE_MSWINDOWS_P (d))
308 signal_simple_error ("Not an mswindows device", device);
309
310 if (NILP (DEVICE_SELECTED_FRAME (d)))
311 signal_simple_error ("No selected frame on mswindows device", device);
312
313 f = XFRAME (DEVICE_SELECTED_FRAME (d));
314
315 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
316 type = IMAGE_COLOR_PIXMAP;
317 else if (dest_mask & IMAGE_POINTER_MASK)
318 type = IMAGE_POINTER;
319 else
320 incompatible_image_types (instantiator, dest_mask,
321 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
322 hdc = FRAME_MSWINDOWS_CDC (f);
323
324 bitmap=CreateDIBSection (hdc,
325 bmp_info,
326 DIB_RGB_COLORS,
327 &bmp_buf,
328 0,0);
329
330 if (!bitmap || !bmp_buf)
331 signal_simple_error ("Unable to create bitmap", instantiator);
332
333 /* copy in the actual bitmap */
334 memcpy (bmp_buf, bmp_data, bmp_bits);
335
336 mswindows_initialize_dibitmap_image_instance (ii, slices, type);
337
338 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
339 find_keyword_in_vector (instantiator, Q_file);
340
341 /* Fixup a set of bitmaps. */
342 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
343
344 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
345 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
346 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
347 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
348 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
349 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
350
351 if (create_mask)
352 {
353 mswindows_initialize_image_instance_mask (ii, f);
354 }
355
356 if (type == IMAGE_POINTER)
357 {
358 mswindows_initialize_image_instance_icon(ii, TRUE);
359 }
360 }
361
362 static void
363 image_instance_add_dibitmap (struct Lisp_Image_Instance *ii,
364 BITMAPINFO *bmp_info,
365 void *bmp_data,
366 int bmp_bits,
367 int slice,
368 Lisp_Object instantiator)
369 {
370 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
371 struct device *d = XDEVICE (device);
372 struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d));
373 void* bmp_buf=0;
374 HDC hdc = FRAME_MSWINDOWS_CDC (f);
375 HBITMAP bitmap = CreateDIBSection (hdc,
376 bmp_info,
377 DIB_RGB_COLORS,
378 &bmp_buf,
379 0,0);
380
381 if (!bitmap || !bmp_buf)
382 signal_simple_error ("Unable to create bitmap", instantiator);
383
384 /* copy in the actual bitmap */
385 memcpy (bmp_buf, bmp_data, bmp_bits);
386 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (ii, slice) = bitmap;
387 }
388
389 static void
390 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
391 int width, int height,
392 int slices,
393 unsigned char *eimage,
394 int dest_mask,
395 Lisp_Object instantiator,
396 Lisp_Object domain)
397 {
398 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
399 BITMAPINFO* bmp_info;
400 unsigned char* bmp_data;
401 int bmp_bits;
402 COLORREF bkcolor;
403 int slice;
404
405 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
406 signal_simple_error ("Not an mswindows device", device);
407
408 /* this is a hack but MaskBlt and TransparentBlt are not supported
409 on most windows variants */
410 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
411 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
412
413 for (slice = 0; slice < slices; slice++)
414 {
415 /* build a bitmap from the eimage */
416 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height,
417 eimage + (width * height * 3 * slice),
418 &bmp_bits, &bmp_data)))
419 {
420 signal_simple_error ("EImage to DIBitmap conversion failed",
421 instantiator);
422 }
423
424 /* Now create the pixmap and set up the image instance */
425 if (slice == 0)
426 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
427 bmp_data, bmp_bits, slices, instantiator,
428 0, 0, 0);
429 else
430 image_instance_add_dibitmap (ii, bmp_info, bmp_data, bmp_bits, slice,
431 instantiator);
432
433 xfree (bmp_info);
434 xfree (bmp_data);
435 }
436 }
437
438 static void set_mono_pixel ( unsigned char* bits,
439 int bpline, int height,
440 int x, int y, int white )
441 {
442 int index;
443 unsigned char bitnum;
444 /* Find the byte on which this scanline begins */
445 index = (height - y - 1) * bpline;
446 /* Find the byte containing this pixel */
447 index += (x >> 3);
448 /* Which bit is it? */
449 bitnum = (unsigned char)( 7 - (x % 8) );
450 if( white ) /* Turn it on */
451 bits[index] |= (1<<bitnum);
452 else /* Turn it off */
453 bits[index] &= ~(1<<bitnum);
454 }
455
456 static void
457 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
458 struct frame* f)
459 {
460 HBITMAP mask;
461 HGDIOBJ old = NULL;
462 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
463 unsigned char* dibits;
464 BITMAPINFO* bmp_info =
465 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
466 int i, j;
467 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
468
469 void* and_bits;
470 int maskbpline = BPLINE (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8));
471 int bpline = BPLINE (IMAGE_INSTANCE_PIXMAP_WIDTH (image) * 3);
472
473 if (!bmp_info)
474 return;
475
476 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
477 bmp_info->bmiHeader.biHeight = height;
478 bmp_info->bmiHeader.biPlanes=1;
479 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
480 bmp_info->bmiHeader.biBitCount=1;
481 bmp_info->bmiHeader.biCompression=BI_RGB;
482 bmp_info->bmiHeader.biClrUsed = 2;
483 bmp_info->bmiHeader.biClrImportant = 2;
484 bmp_info->bmiHeader.biSizeImage = height * maskbpline;
485 bmp_info->bmiColors[0].rgbRed = 0;
486 bmp_info->bmiColors[0].rgbGreen = 0;
487 bmp_info->bmiColors[0].rgbBlue = 0;
488 bmp_info->bmiColors[0].rgbReserved = 0;
489 bmp_info->bmiColors[1].rgbRed = 255;
490 bmp_info->bmiColors[1].rgbGreen = 255;
491 bmp_info->bmiColors[1].rgbBlue = 255;
492 bmp_info->bmiColors[0].rgbReserved = 0;
493
494 if (!(mask = CreateDIBSection (hcdc,
495 bmp_info,
496 DIB_RGB_COLORS,
497 &and_bits,
498 0,0)))
499 {
500 xfree (bmp_info);
501 return;
502 }
503
504 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
505 /* build up an in-memory set of bits to mess with */
506 xzero (*bmp_info);
507
508 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
509 bmp_info->bmiHeader.biHeight = -height;
510 bmp_info->bmiHeader.biPlanes=1;
511 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
512 bmp_info->bmiHeader.biBitCount=24;
513 bmp_info->bmiHeader.biCompression=BI_RGB;
514 bmp_info->bmiHeader.biClrUsed = 0;
515 bmp_info->bmiHeader.biClrImportant = 0;
516 bmp_info->bmiHeader.biSizeImage = height * bpline;
517
518 dibits = xmalloc_and_zero (bpline * height);
519 if (GetDIBits (hcdc,
520 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
521 0,
522 height,
523 dibits,
524 bmp_info,
525 DIB_RGB_COLORS) <= 0)
526 {
527 xfree (bmp_info);
528 return;
529 }
530
531 /* now set the colored bits in the mask and transparent ones to
532 black in the original */
533 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
534 {
535 for(j=0; j<height; j++)
536 {
537 unsigned char* idx = &dibits[j * bpline + i * 3];
538
539 if( RGB (idx[2], idx[1], idx[0]) == transparent_color )
540 {
541 idx[0] = idx[1] = idx[2] = 0;
542 set_mono_pixel( and_bits, maskbpline, height, i, j, TRUE );
543 }
544 else
545 {
546 set_mono_pixel( and_bits, maskbpline, height, i, j, FALSE );
547 }
548 }
549 }
550
551 SetDIBits (hcdc,
552 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image),
553 0,
554 height,
555 dibits,
556 bmp_info,
557 DIB_RGB_COLORS);
558
559 xfree (bmp_info);
560 xfree (dibits);
561
562 SelectObject(hcdc, old);
563
564 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
565 }
566
567 void
568 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
569 int cursor)
570 {
571 ICONINFO x_icon;
572
573 /* we rely on windows to do any resizing necessary */
574 x_icon.fIcon=cursor ? FALSE : TRUE;
575 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
576 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
577 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
578 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
579
580 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
581 CreateIconIndirect (&x_icon);
582 }
583
584 HBITMAP
585 mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
586 struct frame* f,
587 int newx, int newy)
588 {
589 HBITMAP newbmp;
590 HGDIOBJ old1, old2;
591 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
592 HDC hdcDst = CreateCompatibleDC (hcdc);
593
594 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
595
596 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
597
598 old2 = SelectObject (hdcDst, newbmp);
599
600 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
601 hcdc, 0, 0,
602 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
603 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
604 SRCCOPY))
605 {
606 DeleteObject (newbmp);
607 DeleteDC (hdcDst);
608 return 0;
609 }
610
611 SelectObject (hdcDst, old2);
612 SelectObject (hcdc, old1);
613 DeleteDC (hdcDst);
614
615 return newbmp;
616 }
617
618 HBITMAP
619 mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
620 struct frame* f,
621 int newx, int newy)
622 {
623 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
624 {
625 HBITMAP newmask;
626 HGDIOBJ old1, old2;
627 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
628 HDC hdcDst = CreateCompatibleDC (hcdc);
629
630 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
631 newmask = CreateCompatibleBitmap(hcdc, newx, newy);
632 old2 = SelectObject (hdcDst, newmask);
633
634 if (!StretchBlt(hdcDst, 0, 0, newx, newy,
635 hcdc, 0, 0,
636 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
637 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
638 SRCCOPY))
639 {
640 DeleteObject (newmask);
641 DeleteDC (hdcDst);
642 return NULL;
643 }
644
645 SelectObject (hdcDst, old2);
646 SelectObject (hcdc, old1);
647
648 DeleteDC (hdcDst);
649
650 return newmask;
651 }
652
653 return NULL;
654 }
655
656 int
657 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
658 struct frame* f,
659 int newx, int newy)
660 {
661 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
662 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
663
664 if (!newbmp)
665 return FALSE;
666
667 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
668 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
669 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
670 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
671
672 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
673 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
674 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
675 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
676
677 return TRUE;
678 }
679
680 /**********************************************************************
681 * XPM *
682 **********************************************************************/
683
684 #ifdef HAVE_XPM
685
686 struct color_symbol
687 {
688 char* name;
689 COLORREF color;
690 };
691
692 static struct color_symbol*
693 extract_xpm_color_names (Lisp_Object device,
694 Lisp_Object domain,
695 Lisp_Object color_symbol_alist,
696 int* nsymbols)
697 {
698 /* This function can GC */
699 Lisp_Object rest;
700 Lisp_Object results = Qnil;
701 int i, j;
702 struct color_symbol *colortbl;
703 struct gcpro gcpro1, gcpro2;
704
705 GCPRO2 (results, device);
706
707 /* We built up results to be (("name" . #<color>) ...) so that if an
708 error happens we don't lose any malloc()ed data, or more importantly,
709 leave any pixels allocated in the server. */
710 i = 0;
711 LIST_LOOP (rest, color_symbol_alist)
712 {
713 Lisp_Object cons = XCAR (rest);
714 Lisp_Object name = XCAR (cons);
715 Lisp_Object value = XCDR (cons);
716 if (NILP (value))
717 continue;
718 if (STRINGP (value))
719 value =
720 Fmake_color_instance
721 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
722 else
723 {
724 assert (COLOR_SPECIFIERP (value));
725 value = Fspecifier_instance (value, domain, Qnil, Qnil);
726 }
727 if (NILP (value))
728 continue;
729 results = noseeum_cons (noseeum_cons (name, value), results);
730 i++;
731 }
732 UNGCPRO; /* no more evaluation */
733
734 *nsymbols=i;
735 if (i == 0) return 0;
736
737 colortbl = xnew_array_and_zero (struct color_symbol, i);
738
739 for (j=0; j<i; j++)
740 {
741 Lisp_Object cons = XCAR (results);
742 colortbl[j].color =
743 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
744
745 GET_C_STRING_OS_DATA_ALLOCA (XCAR (cons), colortbl[j].name);
746 colortbl[j].name = xstrdup (colortbl[j].name); /* mustn't lose this when we return */
747 free_cons (XCONS (cons));
748 cons = results;
749 results = XCDR (results);
750 free_cons (XCONS (cons));
751 }
752 return colortbl;
753 }
754
755 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
756 unsigned char** data,
757 int* width, int* height,
758 int* x_hot, int* y_hot,
759 int* transp,
760 struct color_symbol* color_symbols,
761 int nsymbols)
762 {
763 XpmImage xpmimage;
764 XpmInfo xpminfo;
765 int result, i, j, transp_idx, maskbpline;
766 unsigned char* dptr;
767 unsigned int* sptr;
768 COLORREF color; /* the american spelling virus hits again .. */
769 COLORREF* colortbl;
770
771 xzero (xpmimage);
772 xzero (xpminfo);
773 xpminfo.valuemask=XpmHotspot;
774 *transp=FALSE;
775
776 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
777 &xpmimage,
778 &xpminfo);
779 switch (result)
780 {
781 case XpmSuccess:
782 break;
783 case XpmFileInvalid:
784 {
785 signal_simple_error ("Invalid XPM data", image);
786 }
787 case XpmNoMemory:
788 {
789 signal_double_file_error ("Parsing pixmap data",
790 "out of memory", image);
791 }
792 default:
793 {
794 signal_double_file_error_2 ("Parsing pixmap data",
795 "unknown error code",
796 make_int (result), image);
797 }
798 }
799
800 *width = xpmimage.width;
801 *height = xpmimage.height;
802 maskbpline = BPLINE (((~7UL & (unsigned long)(*width + 7)) / 8));
803
804 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
805
806 if (!*data)
807 {
808 XpmFreeXpmImage (&xpmimage);
809 XpmFreeXpmInfo (&xpminfo);
810 return 0;
811 }
812
813 /* build a color table to speed things up */
814 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
815 if (!colortbl)
816 {
817 xfree (*data);
818 XpmFreeXpmImage (&xpmimage);
819 XpmFreeXpmInfo (&xpminfo);
820 return 0;
821 }
822
823 for (i=0; i<xpmimage.ncolors; i++)
824 {
825 /* goto alert!!!! */
826 /* pick up symbolic colors in preference */
827 if (xpmimage.colorTable[i].symbolic)
828 {
829 if (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
830 ||
831 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))
832 {
833 *transp=TRUE;
834 colortbl[i]=transparent_color;
835 transp_idx=i;
836 goto label_found_color;
837 }
838 else if (color_symbols)
839 {
840 for (j = 0; j<nsymbols; j++)
841 {
842 if (!strcmp (xpmimage.colorTable[i].symbolic,
843 color_symbols[j].name ))
844 {
845 colortbl[i]=color_symbols[j].color;
846 goto label_found_color;
847 }
848 }
849 }
850 else if (xpmimage.colorTable[i].c_color == 0)
851 {
852 goto label_no_color;
853 }
854 }
855 /* pick up transparencies */
856 if (!strcasecmp (xpmimage.colorTable[i].c_color,"None"))
857 {
858 *transp=TRUE;
859 colortbl[i]=transparent_color;
860 transp_idx=i;
861 goto label_found_color;
862 }
863 /* finally pick up a normal color spec */
864 if (xpmimage.colorTable[i].c_color)
865 {
866 colortbl[i]=
867 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
868 goto label_found_color;
869 }
870
871 label_no_color:
872 xfree (*data);
873 xfree (colortbl);
874 XpmFreeXpmImage (&xpmimage);
875 XpmFreeXpmInfo (&xpminfo);
876 return 0;
877
878 label_found_color:;
879 }
880
881 /* convert the image */
882 sptr=xpmimage.data;
883 dptr=*data;
884 for (i = 0; i< *width * *height; i++)
885 {
886 color = colortbl[*sptr++];
887
888 /* split out the 0x02bbggrr colorref into an rgb triple */
889 *dptr++=GetRValue (color); /* red */
890 *dptr++=GetGValue (color); /* green */
891 *dptr++=GetBValue (color); /* blue */
892 }
893
894 *x_hot=xpminfo.x_hotspot;
895 *y_hot=xpminfo.y_hotspot;
896
897 XpmFreeXpmImage (&xpmimage);
898 XpmFreeXpmInfo (&xpminfo);
899 xfree (colortbl);
900 return TRUE;
901 }
902
903 static void
904 mswindows_xpm_instantiate (Lisp_Object image_instance,
905 Lisp_Object instantiator,
906 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
907 int dest_mask, Lisp_Object domain)
908 {
909 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
910 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
911 CONST Extbyte *bytes;
912 Extcount len;
913 unsigned char *eimage;
914 int width, height, x_hot, y_hot;
915 BITMAPINFO* bmp_info;
916 unsigned char* bmp_data;
917 int bmp_bits;
918 int nsymbols=0, transp;
919 struct color_symbol* color_symbols=NULL;
920
921 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
922 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
923 Q_color_symbols);
924
925 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
926 signal_simple_error ("Not an mswindows device", device);
927
928 assert (!NILP (data));
929
930 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
931
932 /* in case we have color symbols */
933 color_symbols = extract_xpm_color_names (device, domain,
934 color_symbol_alist, &nsymbols);
935
936 /* convert to an eimage to make processing easier */
937 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
938 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
939 {
940 signal_simple_error ("XPM to EImage conversion failed",
941 image_instance);
942 }
943
944 if (color_symbols)
945 {
946 while (nsymbols--)
947 {
948 xfree (color_symbols[nsymbols].name);
949 }
950 xfree(color_symbols);
951 }
952
953 /* build a bitmap from the eimage */
954 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
955 &bmp_bits, &bmp_data)))
956 {
957 signal_simple_error ("XPM to EImage conversion failed",
958 image_instance);
959 }
960 xfree (eimage);
961
962 /* Now create the pixmap and set up the image instance */
963 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
964 bmp_data, bmp_bits, 1, instantiator,
965 x_hot, y_hot, transp);
966
967 xfree (bmp_info);
968 xfree (bmp_data);
969 }
970 #endif /* HAVE_XPM */
971
972 /**********************************************************************
973 * BMP *
974 **********************************************************************/
975
976 static void
977 bmp_validate (Lisp_Object instantiator)
978 {
979 file_or_data_must_be_present (instantiator);
980 }
981
982 static Lisp_Object
983 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
984 {
985 return simple_image_type_normalize (inst, console_type, Qbmp);
986 }
987
988 static int
989 bmp_possible_dest_types (void)
990 {
991 return IMAGE_COLOR_PIXMAP_MASK;
992 }
993
994 static void
995 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
996 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
997 int dest_mask, Lisp_Object domain)
998 {
999 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1000 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1001 CONST Extbyte *bytes;
1002 Extcount len;
1003 BITMAPFILEHEADER* bmp_file_header;
1004 BITMAPINFO* bmp_info;
1005 void* bmp_data;
1006 int bmp_bits;
1007 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1008
1009 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1010 signal_simple_error ("Not an mswindows device", device);
1011
1012 assert (!NILP (data));
1013
1014 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
1015
1016 /* Then slurp the image into memory, decoding along the way.
1017 The result is the image in a simple one-byte-per-pixel
1018 format. */
1019
1020 bmp_file_header=(BITMAPFILEHEADER*)bytes;
1021 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
1022 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
1023 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
1024
1025 /* Now create the pixmap and set up the image instance */
1026 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
1027 bmp_data, bmp_bits, 1, instantiator,
1028 0, 0, 0);
1029 }
1030
1031
1032 /**********************************************************************
1033 * RESOURCES *
1034 **********************************************************************/
1035
1036 static void
1037 mswindows_resource_validate (Lisp_Object instantiator)
1038 {
1039 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
1040 &&
1041 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
1042 ||
1043 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
1044 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
1045 instantiator);
1046 }
1047
1048 static Lisp_Object
1049 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type)
1050 {
1051 /* This function can call lisp */
1052 Lisp_Object file = Qnil;
1053 struct gcpro gcpro1, gcpro2;
1054 Lisp_Object alist = Qnil;
1055
1056 GCPRO2 (file, alist);
1057
1058 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1059 console_type);
1060
1061 if (CONSP (file)) /* failure locating filename */
1062 signal_double_file_error ("Opening pixmap file",
1063 "no such file or directory",
1064 Fcar (file));
1065
1066 if (NILP (file)) /* no conversion necessary */
1067 RETURN_UNGCPRO (inst);
1068
1069 alist = tagged_vector_to_alist (inst);
1070
1071 {
1072 alist = remassq_no_quit (Q_file, alist);
1073 alist = Fcons (Fcons (Q_file, file), alist);
1074 }
1075
1076 {
1077 Lisp_Object result = alist_to_tagged_vector (Qmswindows_resource, alist);
1078 free_alist (alist);
1079 RETURN_UNGCPRO (result);
1080 }
1081 }
1082
1083 static int
1084 mswindows_resource_possible_dest_types (void)
1085 {
1086 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
1087 }
1088
1089 typedef struct
1090 {
1091 char *name;
1092 int resource_id;
1093 } resource_t;
1094
1095 #ifndef OCR_ICOCUR
1096 #define OCR_ICOCUR 32647
1097 #define OIC_SAMPLE 32512
1098 #define OIC_HAND 32513
1099 #define OIC_QUES 32514
1100 #define OIC_BANG 32515
1101 #define OIC_NOTE 32516
1102 #define OIC_WINLOGO 32517
1103 #define LR_SHARED 0x8000
1104 #endif
1105
1106 static CONST resource_t bitmap_table[] =
1107 {
1108 /* bitmaps */
1109 { "close", OBM_CLOSE },
1110 { "uparrow", OBM_UPARROW },
1111 { "dnarrow", OBM_DNARROW },
1112 { "rgarrow", OBM_RGARROW },
1113 { "lfarrow", OBM_LFARROW },
1114 { "reduce", OBM_REDUCE },
1115 { "zoom", OBM_ZOOM },
1116 { "restore", OBM_RESTORE },
1117 { "reduced", OBM_REDUCED },
1118 { "zoomd", OBM_ZOOMD },
1119 { "restored", OBM_RESTORED },
1120 { "uparrowd", OBM_UPARROWD },
1121 { "dnarrowd", OBM_DNARROWD },
1122 { "rgarrowd", OBM_RGARROWD },
1123 { "lfarrowd", OBM_LFARROWD },
1124 { "mnarrow", OBM_MNARROW },
1125 { "combo", OBM_COMBO },
1126 { "uparrowi", OBM_UPARROWI },
1127 { "dnarrowi", OBM_DNARROWI },
1128 { "rgarrowi", OBM_RGARROWI },
1129 { "lfarrowi", OBM_LFARROWI },
1130 { "size", OBM_SIZE },
1131 { "btsize", OBM_BTSIZE },
1132 { "check", OBM_CHECK },
1133 { "checkboxes", OBM_CHECKBOXES },
1134 { "btncorners" , OBM_BTNCORNERS },
1135 {0}
1136 };
1137
1138 static CONST resource_t cursor_table[] =
1139 {
1140 /* cursors */
1141 { "normal", OCR_NORMAL },
1142 { "ibeam", OCR_IBEAM },
1143 { "wait", OCR_WAIT },
1144 { "cross", OCR_CROSS },
1145 { "up", OCR_UP },
1146 /* { "icon", OCR_ICON }, */
1147 { "sizenwse", OCR_SIZENWSE },
1148 { "sizenesw", OCR_SIZENESW },
1149 { "sizewe", OCR_SIZEWE },
1150 { "sizens", OCR_SIZENS },
1151 { "sizeall", OCR_SIZEALL },
1152 /* { "icour", OCR_ICOCUR }, */
1153 { "no", OCR_NO },
1154 { 0 }
1155 };
1156
1157 static CONST resource_t icon_table[] =
1158 {
1159 /* icons */
1160 { "sample", OIC_SAMPLE },
1161 { "hand", OIC_HAND },
1162 { "ques", OIC_QUES },
1163 { "bang", OIC_BANG },
1164 { "note", OIC_NOTE },
1165 { "winlogo", OIC_WINLOGO },
1166 {0}
1167 };
1168
1169 static int resource_name_to_resource (Lisp_Object name, int type)
1170 {
1171 CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
1172 : type == IMAGE_ICON ? icon_table
1173 : bitmap_table);
1174
1175 if (INTP (name))
1176 {
1177 return XINT (name);
1178 }
1179 else if (!STRINGP (name))
1180 {
1181 signal_simple_error ("invalid resource identifier", name);
1182 }
1183
1184 do {
1185 Extbyte* nm=0;
1186 GET_C_STRING_OS_DATA_ALLOCA (name, nm);
1187 if (!strcasecmp ((char*)res->name, nm))
1188 return res->resource_id;
1189 } while ((++res)->name);
1190 return 0;
1191 }
1192
1193 static int
1194 resource_symbol_to_type (Lisp_Object data)
1195 {
1196 if (EQ (data, Qcursor))
1197 return IMAGE_CURSOR;
1198 else if (EQ (data, Qicon))
1199 return IMAGE_ICON;
1200 else if (EQ (data, Qbitmap))
1201 return IMAGE_BITMAP;
1202 else
1203 return 0;
1204 }
1205
1206 static void
1207 mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1208 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1209 int dest_mask, Lisp_Object domain)
1210 {
1211 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1212 unsigned int type = 0;
1213 HANDLE himage = NULL;
1214 LPCTSTR resid=0;
1215 HINSTANCE hinst = NULL;
1216 ICONINFO iconinfo;
1217 int iitype=0;
1218 char* fname=0;
1219 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1220
1221 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
1222 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
1223 Q_resource_type);
1224 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
1225 Q_resource_id);
1226
1227 xzero (iconinfo);
1228
1229 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1230 signal_simple_error ("Not an mswindows device", device);
1231
1232 type = resource_symbol_to_type (resource_type);
1233
1234 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
1235 iitype = IMAGE_POINTER;
1236 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1237 iitype = IMAGE_COLOR_PIXMAP;
1238 else
1239 incompatible_image_types (instantiator, dest_mask,
1240 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
1241
1242 /* mess with the keyword info we were provided with */
1243 if (!NILP (file))
1244 {
1245 Extbyte* f=0;
1246 GET_C_STRING_FILENAME_DATA_ALLOCA (file, f);
1247 #ifdef __CYGWIN32__
1248 CYGWIN_WIN32_PATH (f, fname);
1249 #else
1250 fname = f;
1251 #endif
1252
1253 if (NILP (resource_id))
1254 resid = (LPCTSTR)fname;
1255 else
1256 {
1257 hinst = LoadLibraryEx (fname, NULL,
1258 LOAD_LIBRARY_AS_DATAFILE);
1259 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1260 type));
1261
1262 if (!resid)
1263 GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid);
1264 }
1265 }
1266 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
1267 type))))
1268 signal_simple_error ("Invalid resource identifier", resource_id);
1269
1270 /* load the image */
1271 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
1272 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
1273 LR_SHARED |
1274 (!NILP (file) ? LR_LOADFROMFILE : 0))))
1275 {
1276 signal_simple_error ("Cannot load image", instantiator);
1277 }
1278
1279 if (hinst)
1280 FreeLibrary (hinst);
1281
1282 mswindows_initialize_dibitmap_image_instance (ii, 1, iitype);
1283
1284 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
1285 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
1286 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
1287 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
1288 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
1289 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1290
1291 /* hey, we've got an icon type thing so we can reverse engineer the
1292 bitmap and mask */
1293 if (type != IMAGE_BITMAP)
1294 {
1295 GetIconInfo (himage, &iconinfo);
1296 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
1297 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
1298 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
1299 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
1300 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
1301 }
1302 else
1303 {
1304 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
1305 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
1306 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
1307 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1308 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1309 }
1310 }
1311
1312 static void
1313 check_valid_resource_symbol (Lisp_Object data)
1314 {
1315 CHECK_SYMBOL (data);
1316 if (!resource_symbol_to_type (data))
1317 signal_simple_error ("invalid resource type", data);
1318 }
1319
1320 static void
1321 check_valid_resource_id (Lisp_Object data)
1322 {
1323 if (!resource_name_to_resource (data, IMAGE_CURSOR)
1324 &&
1325 !resource_name_to_resource (data, IMAGE_ICON)
1326 &&
1327 !resource_name_to_resource (data, IMAGE_BITMAP))
1328 signal_simple_error ("invalid resource identifier", data);
1329 }
1330
1331 void
1332 check_valid_string_or_int (Lisp_Object data)
1333 {
1334 if (!INTP (data))
1335 CHECK_STRING (data);
1336 else
1337 CHECK_INT (data);
1338 }
1339
1340 /**********************************************************************
1341 * XBM *
1342 **********************************************************************/
1343 #ifndef HAVE_X_WINDOWS
1344 /* $XConsortium: RdBitF.c,v 1.10 94/04/17 20:16:13 kaleb Exp $ */
1345
1346 /*
1347
1348 Copyright (c) 1988 X Consortium
1349
1350 Permission is hereby granted, free of charge, to any person obtaining a copy
1351 of this software and associated documentation files (the "Software"), to deal
1352 in the Software without restriction, including without limitation the rights
1353 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1354 copies of the Software, and to permit persons to whom the Software is
1355 furnished to do so, subject to the following conditions:
1356
1357 The above copyright notice and this permission notice shall be included in
1358 all copies or substantial portions of the Software.
1359
1360 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1361 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1362 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1363 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1364 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1365 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1366
1367 Except as contained in this notice, the name of the X Consortium shall not be
1368 used in advertising or otherwise to promote the sale, use or other dealings
1369 in this Software without prior written authorization from the X Consortium.
1370
1371 */
1372
1373 /*
1374 * This file contains miscellaneous utility routines and is not part of the
1375 * Xlib standard.
1376 *
1377 * Public entry points:
1378 *
1379 * XmuReadBitmapData read data from FILE descriptor
1380 * XmuReadBitmapDataFromFile read X10 or X11 format bitmap files
1381 * and return data
1382 *
1383 * Note that this file and ../X/XRdBitF.c look very similar.... Keep them
1384 * that way (but don't use common source code so that people can have one
1385 * without the other).
1386 */
1387
1388
1389 /*
1390 * Based on an optimized version provided by Jim Becker, August 5, 1988.
1391 */
1392 #ifndef BitmapSuccess
1393 #define BitmapSuccess 0
1394 #define BitmapOpenFailed 1
1395 #define BitmapFileInvalid 2
1396 #define BitmapNoMemory 3
1397 #endif
1398 #define MAX_SIZE 255
1399
1400 /* shared data for the image read/parse logic */
1401 static short hexTable[256]; /* conversion value */
1402 static int initialized = FALSE; /* easier to fill in at run time */
1403
1404 /*
1405 * Table index for the hex values. Initialized once, first time.
1406 * Used for translation value or delimiter significance lookup.
1407 */
1408 static void initHexTable()
1409 {
1410 /*
1411 * We build the table at run time for several reasons:
1412 *
1413 * 1. portable to non-ASCII machines.
1414 * 2. still reentrant since we set the init flag after setting table.
1415 * 3. easier to extend.
1416 * 4. less prone to bugs.
1417 */
1418 hexTable['0'] = 0; hexTable['1'] = 1;
1419 hexTable['2'] = 2; hexTable['3'] = 3;
1420 hexTable['4'] = 4; hexTable['5'] = 5;
1421 hexTable['6'] = 6; hexTable['7'] = 7;
1422 hexTable['8'] = 8; hexTable['9'] = 9;
1423 hexTable['A'] = 10; hexTable['B'] = 11;
1424 hexTable['C'] = 12; hexTable['D'] = 13;
1425 hexTable['E'] = 14; hexTable['F'] = 15;
1426 hexTable['a'] = 10; hexTable['b'] = 11;
1427 hexTable['c'] = 12; hexTable['d'] = 13;
1428 hexTable['e'] = 14; hexTable['f'] = 15;
1429
1430 /* delimiters of significance are flagged w/ negative value */
1431 hexTable[' '] = -1; hexTable[','] = -1;
1432 hexTable['}'] = -1; hexTable['\n'] = -1;
1433 hexTable['\t'] = -1;
1434
1435 initialized = TRUE;
1436 }
1437
1438 /*
1439 * read next hex value in the input stream, return -1 if EOF
1440 */
1441 static int NextInt ( FILE *fstream )
1442 {
1443 int ch;
1444 int value = 0;
1445 int gotone = 0;
1446 int done = 0;
1447
1448 /* loop, accumulate hex value until find delimiter */
1449 /* skip any initial delimiters found in read stream */
1450
1451 while (!done) {
1452 ch = getc(fstream);
1453 if (ch == EOF) {
1454 value = -1;
1455 done++;
1456 } else {
1457 /* trim high bits, check type and accumulate */
1458 ch &= 0xff;
1459 if (isascii(ch) && isxdigit(ch)) {
1460 value = (value << 4) + hexTable[ch];
1461 gotone++;
1462 } else if ((hexTable[ch]) < 0 && gotone)
1463 done++;
1464 }
1465 }
1466 return value;
1467 }
1468
1469
1470 /*
1471 * The data returned by the following routine is always in left-most byte
1472 * first and left-most bit first. If it doesn't return BitmapSuccess then
1473 * its arguments won't have been touched. This routine should look as much
1474 * like the Xlib routine XReadBitmapfile as possible.
1475 */
1476 int read_bitmap_data (fstream, width, height, datap, x_hot, y_hot)
1477 FILE *fstream; /* handle on file */
1478 unsigned int *width, *height; /* RETURNED */
1479 unsigned char **datap; /* RETURNED */
1480 int *x_hot, *y_hot; /* RETURNED */
1481 {
1482 unsigned char *data = NULL; /* working variable */
1483 char line[MAX_SIZE]; /* input line from file */
1484 int size; /* number of bytes of data */
1485 char name_and_type[MAX_SIZE]; /* an input line */
1486 char *type; /* for parsing */
1487 int value; /* from an input line */
1488 int version10p; /* boolean, old format */
1489 int padding; /* to handle alignment */
1490 int bytes_per_line; /* per scanline of data */
1491 unsigned int ww = 0; /* width */
1492 unsigned int hh = 0; /* height */
1493 int hx = -1; /* x hotspot */
1494 int hy = -1; /* y hotspot */
1495
1496 #define Xmalloc(size) malloc(size)
1497
1498 /* first time initialization */
1499 if (initialized == FALSE) initHexTable();
1500
1501 /* error cleanup and return macro */
1502 #define RETURN(code) { if (data) free (data); return code; }
1503
1504 while (fgets(line, MAX_SIZE, fstream)) {
1505 if (strlen(line) == MAX_SIZE-1) {
1506 RETURN (BitmapFileInvalid);
1507 }
1508 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
1509 if (!(type = strrchr(name_and_type, '_')))
1510 type = name_and_type;
1511 else
1512 type++;
1513
1514 if (!strcmp("width", type))
1515 ww = (unsigned int) value;
1516 if (!strcmp("height", type))
1517 hh = (unsigned int) value;
1518 if (!strcmp("hot", type)) {
1519 if (type-- == name_and_type || type-- == name_and_type)
1520 continue;
1521 if (!strcmp("x_hot", type))
1522 hx = value;
1523 if (!strcmp("y_hot", type))
1524 hy = value;
1525 }
1526 continue;
1527 }
1528
1529 if (sscanf(line, "static short %s = {", name_and_type) == 1)
1530 version10p = 1;
1531 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
1532 version10p = 0;
1533 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
1534 version10p = 0;
1535 else
1536 continue;
1537
1538 if (!(type = strrchr(name_and_type, '_')))
1539 type = name_and_type;
1540 else
1541 type++;
1542
1543 if (strcmp("bits[]", type))
1544 continue;
1545
1546 if (!ww || !hh)
1547 RETURN (BitmapFileInvalid);
1548
1549 if ((ww % 16) && ((ww % 16) < 9) && version10p)
1550 padding = 1;
1551 else
1552 padding = 0;
1553
1554 bytes_per_line = (ww+7)/8 + padding;
1555
1556 size = bytes_per_line * hh;
1557 data = (unsigned char *) Xmalloc ((unsigned int) size);
1558 if (!data)
1559 RETURN (BitmapNoMemory);
1560
1561 if (version10p) {
1562 unsigned char *ptr;
1563 int bytes;
1564
1565 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
1566 if ((value = NextInt(fstream)) < 0)
1567 RETURN (BitmapFileInvalid);
1568 *(ptr++) = value;
1569 if (!padding || ((bytes+2) % bytes_per_line))
1570 *(ptr++) = value >> 8;
1571 }
1572 } else {
1573 unsigned char *ptr;
1574 int bytes;
1575
1576 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
1577 if ((value = NextInt(fstream)) < 0)
1578 RETURN (BitmapFileInvalid);
1579 *ptr=value;
1580 }
1581 }
1582 break;
1583 } /* end while */
1584
1585 if (data == NULL) {
1586 RETURN (BitmapFileInvalid);
1587 }
1588
1589 *datap = data;
1590 data = NULL;
1591 *width = ww;
1592 *height = hh;
1593 if (x_hot) *x_hot = hx;
1594 if (y_hot) *y_hot = hy;
1595
1596 RETURN (BitmapSuccess);
1597 }
1598
1599
1600 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
1601 unsigned int *height, unsigned char **datap,
1602 int *x_hot, int *y_hot)
1603 {
1604 FILE *fstream;
1605 int status;
1606
1607 if ((fstream = fopen (filename, "r")) == NULL) {
1608 return BitmapOpenFailed;
1609 }
1610 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
1611 fclose (fstream);
1612 return status;
1613 }
1614 #endif /* HAVE_X_WINDOWS */
1615
1616 /* this table flips four bits around. */
1617 static int flip_table[] =
1618 {
1619 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
1620 };
1621
1622 /* the bitmap data comes in the following format: Widths are padded to
1623 a multiple of 8. Scan lines are stored in increasing byte order
1624 from left to right, little-endian within a byte. 0 = white, 1 =
1625 black. It must be converted to the following format: Widths are
1626 padded to a multiple of 16. Scan lines are stored in increasing
1627 byte order from left to right, big-endian within a byte. 0 =
1628 black, 1 = white. */
1629 HBITMAP
1630 xbm_create_bitmap_from_data (HDC hdc, char *data,
1631 unsigned int width, unsigned int height,
1632 int mask, COLORREF fg, COLORREF bg)
1633 {
1634 int old_width = (width + 7)/8;
1635 int new_width = BPLINE (2*((width + 15)/16));
1636 unsigned char *offset;
1637 void *bmp_buf = 0;
1638 unsigned char *new_data, *new_offset;
1639 int i, j;
1640 BITMAPINFO* bmp_info =
1641 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
1642 HBITMAP bitmap;
1643
1644 if (!bmp_info)
1645 return NULL;
1646
1647 new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
1648
1649 if (!new_data)
1650 {
1651 xfree (bmp_info);
1652 return NULL;
1653 }
1654
1655 for (i=0; i<height; i++)
1656 {
1657 offset = data + i*old_width;
1658 new_offset = new_data + i*new_width;
1659
1660 for (j=0; j<old_width; j++)
1661 {
1662 int byte = offset[j];
1663 new_offset[j] = ~ (unsigned char)
1664 ((flip_table[byte & 0xf] << 4) + flip_table[byte >> 4]);
1665 }
1666 }
1667
1668 /* if we want a mask invert the bits */
1669 if (!mask)
1670 {
1671 new_offset = &new_data[height * new_width];
1672 while (new_offset-- != new_data)
1673 {
1674 *new_offset ^= 0xff;
1675 }
1676 }
1677
1678 bmp_info->bmiHeader.biWidth=width;
1679 bmp_info->bmiHeader.biHeight=-(LONG)height;
1680 bmp_info->bmiHeader.biPlanes=1;
1681 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
1682 bmp_info->bmiHeader.biBitCount=1;
1683 bmp_info->bmiHeader.biCompression=BI_RGB;
1684 bmp_info->bmiHeader.biClrUsed = 2;
1685 bmp_info->bmiHeader.biClrImportant = 2;
1686 bmp_info->bmiHeader.biSizeImage = height * new_width;
1687 bmp_info->bmiColors[0].rgbRed = GetRValue (fg);
1688 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg);
1689 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg);
1690 bmp_info->bmiColors[0].rgbReserved = 0;
1691 bmp_info->bmiColors[1].rgbRed = GetRValue (bg);
1692 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg);
1693 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg);
1694 bmp_info->bmiColors[1].rgbReserved = 0;
1695
1696 bitmap = CreateDIBSection (hdc,
1697 bmp_info,
1698 DIB_RGB_COLORS,
1699 &bmp_buf,
1700 0,0);
1701
1702 xfree (bmp_info);
1703
1704 if (!bitmap || !bmp_buf)
1705 {
1706 xfree (new_data);
1707 return NULL;
1708 }
1709
1710 /* copy in the actual bitmap */
1711 memcpy (bmp_buf, new_data, height * new_width);
1712 xfree (new_data);
1713
1714 return bitmap;
1715 }
1716
1717 /* Given inline data for a mono pixmap, initialize the given
1718 image instance accordingly. */
1719
1720 static void
1721 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii,
1722 int width, int height,
1723 /* Note that data is in ext-format! */
1724 CONST char *bits,
1725 Lisp_Object instantiator,
1726 Lisp_Object pointer_fg,
1727 Lisp_Object pointer_bg,
1728 int dest_mask,
1729 HBITMAP mask,
1730 Lisp_Object mask_filename)
1731 {
1732 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
1733 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device)));
1734 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground);
1735 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background);
1736 enum image_instance_type type;
1737 COLORREF black = PALETTERGB (0,0,0);
1738 COLORREF white = PALETTERGB (255,255,255);
1739
1740 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1741
1742 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
1743 signal_simple_error ("Not an MS-Windows device", device);
1744
1745 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) &&
1746 (dest_mask & IMAGE_COLOR_PIXMAP_MASK))
1747 {
1748 if (!NILP (foreground) || !NILP (background))
1749 type = IMAGE_COLOR_PIXMAP;
1750 else
1751 type = IMAGE_MONO_PIXMAP;
1752 }
1753 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK)
1754 type = IMAGE_MONO_PIXMAP;
1755 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
1756 type = IMAGE_COLOR_PIXMAP;
1757 else if (dest_mask & IMAGE_POINTER_MASK)
1758 type = IMAGE_POINTER;
1759 else
1760 incompatible_image_types (instantiator, dest_mask,
1761 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
1762 | IMAGE_POINTER_MASK);
1763
1764 mswindows_initialize_dibitmap_image_instance (ii, 1, type);
1765
1766 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
1767 find_keyword_in_vector (instantiator, Q_file);
1768 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
1769 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
1770 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
1771 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
1772 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
1773 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask :
1774 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1775 TRUE, black, white);
1776
1777 switch (type)
1778 {
1779 case IMAGE_MONO_PIXMAP:
1780 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1781 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1782 FALSE, black, black);
1783 break;
1784
1785 case IMAGE_COLOR_PIXMAP:
1786 {
1787 COLORREF fg = black;
1788 COLORREF bg = white;
1789
1790 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground))
1791 foreground =
1792 Fmake_color_instance (foreground, device,
1793 encode_error_behavior_flag (ERROR_ME));
1794
1795 if (COLOR_INSTANCEP (foreground))
1796 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1797
1798 if (!NILP (background) && !COLOR_INSTANCEP (background))
1799 background =
1800 Fmake_color_instance (background, device,
1801 encode_error_behavior_flag (ERROR_ME));
1802
1803 if (COLOR_INSTANCEP (background))
1804 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1805
1806 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1807 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1808
1809 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1810 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1811 FALSE, fg, black);
1812 }
1813 break;
1814
1815 case IMAGE_POINTER:
1816 {
1817 COLORREF fg = black;
1818 COLORREF bg = white;
1819
1820 if (NILP (foreground))
1821 foreground = pointer_fg;
1822 if (NILP (background))
1823 background = pointer_bg;
1824
1825 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) =
1826 find_keyword_in_vector (instantiator, Q_hotspot_x);
1827 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) =
1828 find_keyword_in_vector (instantiator, Q_hotspot_y);
1829 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground;
1830 IMAGE_INSTANCE_PIXMAP_BG (ii) = background;
1831 if (COLOR_INSTANCEP (foreground))
1832 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground));
1833 if (COLOR_INSTANCEP (background))
1834 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background));
1835
1836 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) =
1837 xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height,
1838 TRUE, fg, black);
1839 mswindows_initialize_image_instance_icon (ii, TRUE);
1840 }
1841 break;
1842
1843 default:
1844 abort ();
1845 }
1846 }
1847
1848 static void
1849 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1850 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1851 int dest_mask, int width, int height,
1852 /* Note that data is in ext-format! */
1853 CONST char *bits)
1854 {
1855 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1856 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1857 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1858 struct frame* f = XFRAME (DEVICE_SELECTED_FRAME
1859 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))));
1860 HDC hdc = FRAME_MSWINDOWS_CDC (f);
1861 HBITMAP mask = 0;
1862 CONST char *gcc_may_you_rot_in_hell;
1863
1864 if (!NILP (mask_data))
1865 {
1866 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))),
1867 gcc_may_you_rot_in_hell);
1868 mask =
1869 xbm_create_bitmap_from_data ( hdc,
1870 (unsigned char *)
1871 gcc_may_you_rot_in_hell,
1872 XINT (XCAR (mask_data)),
1873 XINT (XCAR (XCDR (mask_data))), FALSE,
1874 PALETTERGB (0,0,0),
1875 PALETTERGB (255,255,255));
1876 }
1877
1878 init_image_instance_from_xbm_inline (ii, width, height, bits,
1879 instantiator, pointer_fg, pointer_bg,
1880 dest_mask, mask, mask_file);
1881 }
1882
1883 /* Instantiate method for XBM's. */
1884
1885 static void
1886 mswindows_xbm_instantiate (Lisp_Object image_instance,
1887 Lisp_Object instantiator,
1888 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1889 int dest_mask, Lisp_Object domain)
1890 {
1891 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1892 CONST char *gcc_go_home;
1893
1894 assert (!NILP (data));
1895
1896 GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (data))),
1897 gcc_go_home);
1898
1899 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1900 pointer_bg, dest_mask, XINT (XCAR (data)),
1901 XINT (XCAR (XCDR (data))), gcc_go_home);
1902 }
1903
1904 #ifdef HAVE_XFACE
1905 /**********************************************************************
1906 * X-Face *
1907 **********************************************************************/
1908 #if defined(EXTERN)
1909 /* This is about to get redefined! */
1910 #undef EXTERN
1911 #endif
1912 /* We have to define SYSV32 so that compface.h includes string.h
1913 instead of strings.h. */
1914 #define SYSV32
1915 #ifdef __cplusplus
1916 extern "C" {
1917 #endif
1918 #include <compface.h>
1919 #ifdef __cplusplus
1920 }
1921 #endif
1922 /* JMP_BUF cannot be used here because if it doesn't get defined
1923 to jmp_buf we end up with a conflicting type error with the
1924 definition in compface.h */
1925 extern jmp_buf comp_env;
1926 #undef SYSV32
1927
1928 static void
1929 mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1930 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1931 int dest_mask, Lisp_Object domain)
1932 {
1933 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1934 int i, stattis;
1935 char *p, *bits, *bp;
1936 CONST char * volatile emsg = 0;
1937 CONST char * volatile dstring;
1938
1939 assert (!NILP (data));
1940
1941 GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring);
1942
1943 if ((p = strchr (dstring, ':')))
1944 {
1945 dstring = p + 1;
1946 }
1947
1948 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
1949 if (!(stattis = setjmp (comp_env)))
1950 {
1951 UnCompAll ((char *) dstring);
1952 UnGenFace ();
1953 }
1954
1955 switch (stattis)
1956 {
1957 case -2:
1958 emsg = "uncompface: internal error";
1959 break;
1960 case -1:
1961 emsg = "uncompface: insufficient or invalid data";
1962 break;
1963 case 1:
1964 emsg = "uncompface: excess data ignored";
1965 break;
1966 }
1967
1968 if (emsg)
1969 signal_simple_error_2 (emsg, data, Qimage);
1970
1971 bp = bits = (char *) alloca (PIXELS / 8);
1972
1973 /* the compface library exports char F[], which uses a single byte per
1974 pixel to represent a 48x48 bitmap. Yuck. */
1975 for (i = 0, p = F; i < (PIXELS / 8); ++i)
1976 {
1977 int n, b;
1978 /* reverse the bit order of each byte... */
1979 for (b = n = 0; b < 8; ++b)
1980 {
1981 n |= ((*p++) << b);
1982 }
1983 *bp++ = (char) n;
1984 }
1985
1986 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1987 pointer_bg, dest_mask, 48, 48, bits);
1988 }
1989 #endif /* HAVE_XFACE */
1990
1991
1992 /************************************************************************/
1993 /* image instance methods */
1994 /************************************************************************/
1995
1996 static void
1997 mswindows_print_image_instance (struct Lisp_Image_Instance *p,
1998 Lisp_Object printcharfun,
1999 int escapeflag)
2000 {
2001 char buf[100];
2002
2003 switch (IMAGE_INSTANCE_TYPE (p))
2004 {
2005 case IMAGE_MONO_PIXMAP:
2006 case IMAGE_COLOR_PIXMAP:
2007 case IMAGE_POINTER:
2008 sprintf (buf, " (0x%lx",
2009 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
2010 write_c_string (buf, printcharfun);
2011 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2012 {
2013 sprintf (buf, "/0x%lx",
2014 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2015 write_c_string (buf, printcharfun);
2016 }
2017 write_c_string (")", printcharfun);
2018 break;
2019
2020 default:
2021 break;
2022 }
2023 }
2024
2025 #ifdef DEBUG_WIDGETS
2026 extern int debug_widget_instances;
2027 #endif
2028
2029 static void
2030 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
2031 {
2032 if (DEVICE_LIVE_P (XDEVICE (p->device)))
2033 {
2034 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET
2035 ||
2036 IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
2037 {
2038 #ifdef DEBUG_WIDGETS
2039 debug_widget_instances--;
2040 stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
2041 #endif
2042 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2043 {
2044 DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
2045 DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p));
2046 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
2047 }
2048 }
2049 else if (p->data)
2050 {
2051 int i;
2052 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
2053 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
2054
2055 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p))
2056 {
2057 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
2058 {
2059 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i))
2060 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i));
2061 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0;
2062 }
2063 xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p));
2064 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0;
2065 }
2066 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
2067 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
2068 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
2069 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
2070 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
2071 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
2072 }
2073 }
2074
2075 if (p->data)
2076 {
2077 xfree (p->data);
2078 p->data = 0;
2079 }
2080 }
2081
2082 /************************************************************************/
2083 /* subwindow and widget support */
2084 /************************************************************************/
2085
2086 /* unmap the image if it is a widget. This is used by redisplay via
2087 redisplay_unmap_subwindows */
2088 static void
2089 mswindows_unmap_subwindow (struct Lisp_Image_Instance *p)
2090 {
2091 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
2092 {
2093 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2094 NULL,
2095 0, 0, 0, 0,
2096 SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
2097 | SWP_NOSENDCHANGING);
2098 }
2099 }
2100
2101 /* map the subwindow. This is used by redisplay via
2102 redisplay_output_subwindow */
2103 static void
2104 mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y,
2105 struct display_glyph_area* dga)
2106 {
2107 /* move the window before mapping it ... */
2108 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2109 NULL,
2110 x, y, dga->width, dga->height,
2111 SWP_NOZORDER
2112 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2113 /* ... adjust the child ... */
2114 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2115 NULL,
2116 -dga->xoffset, -dga->yoffset, 0, 0,
2117 SWP_NOZORDER | SWP_NOSIZE
2118 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2119 /* ... now map it - we are not allowed to move it at the same time. */
2120 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
2121 NULL,
2122 0, 0, 0, 0,
2123 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
2124 | SWP_SHOWWINDOW | SWP_NOCOPYBITS
2125 | SWP_NOSENDCHANGING);
2126 }
2127
2128 /* resize the subwindow instance */
2129 static void
2130 mswindows_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h)
2131 {
2132 /* Set the size of the control .... */
2133 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2134 NULL,
2135 0, 0, w, h,
2136 SWP_NOZORDER | SWP_NOMOVE
2137 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
2138 }
2139
2140 /* when you click on a widget you may activate another widget this
2141 needs to be checked and all appropriate widgets updated */
2142 static void
2143 mswindows_update_subwindow (struct Lisp_Image_Instance *p)
2144 {
2145 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
2146 {
2147 /* buttons checked or otherwise */
2148 if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton))
2149 {
2150 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (p)))
2151 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2152 BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2153 else
2154 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2155 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2156 }
2157
2158 /* set the widget font from the widget face */
2159 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
2160 WM_SETFONT,
2161 (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
2162 (XFONT_INSTANCE (widget_face_font_info
2163 (IMAGE_INSTANCE_SUBWINDOW_FRAME (p),
2164 IMAGE_INSTANCE_WIDGET_FACE (p),
2165 0, 0))),
2166 MAKELPARAM (TRUE, 0));
2167 }
2168 }
2169
2170 /* register widgets into our hastable so that we can cope with the
2171 callbacks. The hashtable is weak so deregistration is handled
2172 automatically */
2173 static int
2174 mswindows_register_gui_item (Lisp_Object gui, Lisp_Object domain)
2175 {
2176 Lisp_Object frame = FW_FRAME (domain);
2177 struct frame* f = XFRAME (frame);
2178 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f),
2179 gui,
2180 WIDGET_GLYPH_SLOT);
2181 Fputhash (make_int (id),
2182 XGUI_ITEM (gui)->callback,
2183 FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
2184 return id;
2185 }
2186
2187 static int
2188 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
2189 {
2190 return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_ITEM (instance),
2191 domain);
2192 }
2193
2194 static void
2195 mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2196 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2197 int dest_mask, Lisp_Object domain)
2198 {
2199 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2200 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2201 struct device* d = XDEVICE (device);
2202 Lisp_Object frame = FW_FRAME (domain);
2203 HWND wnd;
2204
2205 if (!DEVICE_MSWINDOWS_P (d))
2206 signal_simple_error ("Not an mswindows device", device);
2207
2208 /* have to set the type this late in case there is no device
2209 instantiation for a widget */
2210 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
2211 /* Allocate space for the clip window */
2212 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2213
2214 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2215 = CreateWindowEx(
2216 0, /* EX flags */
2217 XEMACS_CONTROL_CLASS,
2218 0, /* text */
2219 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2220 0, /* starting x position */
2221 0, /* starting y position */
2222 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2223 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2224 /* parent window */
2225 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2226 NULL, /* No menu */
2227 NULL, /* must be null for this class */
2228 NULL)) == NULL)
2229 signal_simple_error ("window creation failed with code",
2230 make_int (GetLastError()));
2231
2232 wnd = CreateWindow( "STATIC",
2233 "",
2234 WS_CHILD,
2235 0, /* starting x position */
2236 0, /* starting y position */
2237 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2238 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2239 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2240 0,
2241 (HINSTANCE)
2242 GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2243 GWL_HINSTANCE),
2244 NULL);
2245
2246 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2247 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2248 }
2249
2250 static int
2251 mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
2252 struct Lisp_Image_Instance *p2, int depth)
2253 {
2254 switch (IMAGE_INSTANCE_TYPE (p1))
2255 {
2256 case IMAGE_MONO_PIXMAP:
2257 case IMAGE_COLOR_PIXMAP:
2258 case IMAGE_POINTER:
2259 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
2260 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
2261 return 0;
2262 break;
2263
2264 default:
2265 break;
2266 }
2267
2268 return 1;
2269 }
2270
2271 static unsigned long
2272 mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
2273 {
2274 switch (IMAGE_INSTANCE_TYPE (p))
2275 {
2276 case IMAGE_MONO_PIXMAP:
2277 case IMAGE_COLOR_PIXMAP:
2278 case IMAGE_POINTER:
2279 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
2280
2281 default:
2282 return 0;
2283 }
2284 }
2285
2286 /* Set all the slots in an image instance structure to reasonable
2287 default values. This is used somewhere within an instantiate
2288 method. It is assumed that the device slot within the image
2289 instance is already set -- this is the case when instantiate
2290 methods are called. */
2291
2292 static void
2293 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
2294 int slices,
2295 enum image_instance_type type)
2296 {
2297 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
2298 IMAGE_INSTANCE_TYPE (ii) = type;
2299 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
2300 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
2301 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
2302 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
2303 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
2304 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
2305 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
2306 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) =
2307 xnew_array_and_zero (HBITMAP, slices);
2308 }
2309
2310
2311 #ifdef HAVE_WIDGETS
2312
2313 /************************************************************************/
2314 /* widgets */
2315 /************************************************************************/
2316 static void
2317 mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2318 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2319 int dest_mask, Lisp_Object domain,
2320 CONST char* class, int flags, int exflags)
2321 {
2322 /* this function can call lisp */
2323 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2324 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
2325 struct device* d = XDEVICE (device);
2326 Lisp_Object frame = FW_FRAME (domain);
2327 Extbyte* nm=0;
2328 HWND wnd;
2329 int id = 0xffff;
2330 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2331 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2332
2333 if (!DEVICE_MSWINDOWS_P (d))
2334 signal_simple_error ("Not an mswindows device", device);
2335
2336 if (!gui_item_active_p (gui))
2337 flags |= WS_DISABLED;
2338
2339 style = pgui->style;
2340
2341 if (!NILP (pgui->callback))
2342 {
2343 id = mswindows_register_widget_instance (image_instance, domain);
2344 }
2345 /* have to set the type this late in case there is no device
2346 instantiation for a widget */
2347 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
2348 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2349 GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
2350
2351 /* allocate space for the clip window and then allocate the clip window */
2352 ii->data = xnew_and_zero (struct mswindows_subwindow_data);
2353
2354 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
2355 = CreateWindowEx(
2356 0, /* EX flags */
2357 XEMACS_CONTROL_CLASS,
2358 0, /* text */
2359 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
2360 0, /* starting x position */
2361 0, /* starting y position */
2362 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2363 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2364 /* parent window */
2365 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2366 (HMENU)id, /* No menu */
2367 NULL, /* must be null for this class */
2368 NULL)) == NULL)
2369 signal_simple_error ("window creation failed with code",
2370 make_int (GetLastError()));
2371
2372 if ((wnd = CreateWindowEx(
2373 exflags /* | WS_EX_NOPARENTNOTIFY*/,
2374 class,
2375 nm,
2376 flags | WS_CHILD | WS_VISIBLE,
2377 0, /* starting x position */
2378 0, /* starting y position */
2379 IMAGE_INSTANCE_WIDGET_WIDTH (ii),
2380 IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
2381 /* parent window */
2382 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
2383 (HMENU)id, /* No menu */
2384 (HINSTANCE)
2385 GetWindowLong
2386 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
2387 GWL_HINSTANCE),
2388 NULL)) == NULL)
2389 signal_simple_error ("window creation failed with code",
2390 make_int (GetLastError()));
2391
2392 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
2393 SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
2394 /* set the widget font from the widget face */
2395 SendMessage (wnd, WM_SETFONT,
2396 (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
2397 (XFONT_INSTANCE (widget_face_font_info
2398 (domain,
2399 IMAGE_INSTANCE_WIDGET_FACE (ii),
2400 0, 0))),
2401 MAKELPARAM (TRUE, 0));
2402 }
2403
2404 /* Instantiate a button widget. Unfortunately instantiated widgets are
2405 particular to a frame since they need to have a parent. It's not
2406 like images where you just select the image into the context you
2407 want to display it in and BitBlt it. So images instances can have a
2408 many-to-one relationship with things you see, whereas widgets can
2409 only be one-to-one (i.e. per frame) */
2410 static void
2411 mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2412 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2413 int dest_mask, Lisp_Object domain)
2414 {
2415 /* this function can call lisp */
2416 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2417 HWND wnd;
2418 int flags = BS_NOTIFY;
2419 Lisp_Object style;
2420 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2421 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui);
2422 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2423
2424 if (!gui_item_active_p (gui))
2425 flags |= WS_DISABLED;
2426
2427 if (!NILP (glyph))
2428 {
2429 if (!IMAGE_INSTANCEP (glyph))
2430 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2431
2432 if (IMAGE_INSTANCEP (glyph))
2433 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2434 BS_BITMAP : BS_ICON;
2435 }
2436
2437 style = pgui->style;
2438
2439 if (EQ (style, Qradio))
2440 {
2441 flags |= BS_RADIOBUTTON;
2442 }
2443 else if (EQ (style, Qtoggle))
2444 {
2445 flags |= BS_AUTOCHECKBOX;
2446 }
2447 else
2448 flags |= BS_DEFPUSHBUTTON;
2449
2450 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2451 pointer_bg, dest_mask, domain, "BUTTON", flags,
2452 WS_EX_CONTROLPARENT);
2453
2454 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2455 /* set the checked state */
2456 if (gui_item_selected_p (gui))
2457 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
2458 else
2459 SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
2460 /* add the image if one was given */
2461 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph))
2462 {
2463 SendMessage (wnd, BM_SETIMAGE,
2464 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2465 IMAGE_BITMAP : IMAGE_ICON),
2466 (LPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
2467 XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
2468 XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
2469 }
2470 }
2471
2472 /* instantiate an edit control */
2473 static void
2474 mswindows_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2475 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2476 int dest_mask, Lisp_Object domain)
2477 {
2478 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2479 pointer_bg, dest_mask, domain, "EDIT",
2480 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
2481 | WS_BORDER,
2482 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2483 }
2484
2485 /* instantiate a progress gauge */
2486 static void
2487 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2488 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2489 int dest_mask, Lisp_Object domain)
2490 {
2491 HWND wnd;
2492 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2493 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2494 pointer_bg, dest_mask, domain, PROGRESS_CLASS,
2495 WS_TABSTOP | WS_BORDER | PBS_SMOOTH,
2496 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2497 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2498 /* set the colors */
2499 #ifdef PBS_SETBKCOLOR
2500 SendMessage (wnd, PBS_SETBKCOLOR, 0,
2501 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2502 (XCOLOR_INSTANCE
2503 (FACE_BACKGROUND
2504 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2505 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2506 #endif
2507 #ifdef PBS_SETBARCOLOR
2508 SendMessage (wnd, PBS_SETBARCOLOR, 0,
2509 (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR
2510 (XCOLOR_INSTANCE
2511 (FACE_FOREGROUND
2512 (XIMAGE_INSTANCE_WIDGET_FACE (ii),
2513 XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
2514 #endif
2515 }
2516
2517 /* instantiate a tree view widget */
2518 static HTREEITEM add_tree_item (Lisp_Object image_instance,
2519 HWND wnd, HTREEITEM parent, Lisp_Object item,
2520 int children, Lisp_Object domain)
2521 {
2522 TV_INSERTSTRUCT tvitem;
2523 HTREEITEM ret;
2524
2525 tvitem.hParent = parent;
2526 tvitem.hInsertAfter = TVI_LAST;
2527 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
2528 tvitem.item.cChildren = children;
2529
2530 if (GUI_ITEMP (item))
2531 {
2532 tvitem.item.lParam = mswindows_register_gui_item (item, domain);
2533 tvitem.item.mask |= TVIF_PARAM;
2534 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
2535 tvitem.item.pszText);
2536 }
2537 else
2538 GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.item.pszText);
2539
2540 tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
2541
2542 if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
2543 0, (LPARAM)&tvitem)) == 0)
2544 signal_simple_error ("error adding tree view entry", item);
2545
2546 return ret;
2547 }
2548
2549 static void add_tree_item_list (Lisp_Object image_instance,
2550 HWND wnd, HTREEITEM parent, Lisp_Object list,
2551 Lisp_Object domain)
2552 {
2553 Lisp_Object rest;
2554
2555 /* get the first item */
2556 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
2557 /* recursively add items to the tree view */
2558 LIST_LOOP (rest, XCDR (list))
2559 {
2560 if (LISTP (XCAR (rest)))
2561 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2562 else
2563 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2564 }
2565 }
2566
2567 static void
2568 mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2569 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2570 int dest_mask, Lisp_Object domain)
2571 {
2572 Lisp_Object rest;
2573 HWND wnd;
2574 HTREEITEM parent;
2575 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2576 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2577 pointer_bg, dest_mask, domain, WC_TREEVIEW,
2578 WS_TABSTOP | WS_BORDER | PBS_SMOOTH
2579 | TVS_HASLINES | TVS_HASBUTTONS,
2580 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2581
2582 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2583
2584 /* define a root */
2585 parent = add_tree_item (image_instance, wnd, NULL,
2586 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
2587 TRUE, domain);
2588
2589 /* recursively add items to the tree view */
2590 /* add items to the tab */
2591 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2592 {
2593 if (LISTP (XCAR (rest)))
2594 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
2595 else
2596 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
2597 }
2598 }
2599
2600 /* instantiate a tab control */
2601 static TC_ITEM* add_tab_item (Lisp_Object image_instance,
2602 HWND wnd, Lisp_Object item,
2603 Lisp_Object domain, int index)
2604 {
2605 TC_ITEM tvitem, *ret;
2606
2607 tvitem.mask = TCIF_TEXT;
2608
2609 if (GUI_ITEMP (item))
2610 {
2611 tvitem.lParam = mswindows_register_gui_item (item, domain);
2612 tvitem.mask |= TCIF_PARAM;
2613 GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
2614 tvitem.pszText);
2615 }
2616 else
2617 {
2618 CHECK_STRING (item);
2619 GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.pszText);
2620 }
2621
2622 tvitem.cchTextMax = strlen (tvitem.pszText);
2623
2624 if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
2625 index, (LPARAM)&tvitem)) < 0)
2626 signal_simple_error ("error adding tab entry", item);
2627
2628 return ret;
2629 }
2630
2631 static void
2632 mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2633 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2634 int dest_mask, Lisp_Object domain)
2635 {
2636 Lisp_Object rest;
2637 HWND wnd;
2638 int index = 0;
2639 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2640 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2641 pointer_bg, dest_mask, domain, WC_TABCONTROL,
2642 /* borders don't suit tabs so well */
2643 WS_TABSTOP,
2644 WS_EX_CONTROLPARENT);
2645
2646 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2647 /* add items to the tab */
2648 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2649 {
2650 add_tab_item (image_instance, wnd, XCAR (rest), domain, index);
2651 index++;
2652 }
2653 }
2654
2655 /* set the properties of a tab control */
2656 static Lisp_Object
2657 mswindows_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop,
2658 Lisp_Object val)
2659 {
2660 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2661
2662 if (EQ (prop, Q_items))
2663 {
2664 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2665 int index = 0;
2666 Lisp_Object rest;
2667 check_valid_item_list_1 (val);
2668
2669 /* delete the pre-existing items */
2670 SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
2671
2672 IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
2673 Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
2674 parse_gui_item_tree_children (val));
2675
2676 /* add items to the tab */
2677 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2678 {
2679 add_tab_item (image_instance, wnd, XCAR (rest),
2680 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), index);
2681 index++;
2682 }
2683
2684 return Qt;
2685 }
2686 return Qunbound;
2687 }
2688
2689 /* instantiate a static control possible for putting other things in */
2690 static void
2691 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2692 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2693 int dest_mask, Lisp_Object domain)
2694 {
2695 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2696 pointer_bg, dest_mask, domain, "STATIC",
2697 0, WS_EX_STATICEDGE);
2698 }
2699
2700 /* instantiate a scrollbar control */
2701 static void
2702 mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2703 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2704 int dest_mask, Lisp_Object domain)
2705 {
2706 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2707 pointer_bg, dest_mask, domain, "SCROLLBAR",
2708 0,
2709 WS_EX_CLIENTEDGE );
2710 }
2711
2712 /* instantiate a combo control */
2713 static void
2714 mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2715 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2716 int dest_mask, Lisp_Object domain)
2717 {
2718 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2719 HANDLE wnd;
2720 Lisp_Object rest;
2721 Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
2722 Q_items, Qnil);
2723 int len;
2724 GET_LIST_LENGTH (data, len);
2725
2726 /* Maybe ought to generalise this more but it may be very windows
2727 specific. In windows the window height of a combo box is the
2728 height when the combo box is open. Thus we need to set the height
2729 before creating the window and then reset it to a single line
2730 after the window is created so that redisplay does the right
2731 thing. */
2732 widget_instantiate_1 (image_instance, instantiator, pointer_fg,
2733 pointer_bg, dest_mask, domain, len + 1, 0, 0);
2734
2735 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
2736 pointer_bg, dest_mask, domain, "COMBOBOX",
2737 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
2738 | CBS_AUTOHSCROLL
2739 | CBS_HASSTRINGS | WS_VSCROLL,
2740 WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
2741 /* reset the height */
2742 widget_text_to_pixel_conversion (domain,
2743 IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0,
2744 &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0);
2745 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2746 /* add items to the combo box */
2747 SendMessage (wnd, CB_RESETCONTENT, 0, 0);
2748 LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
2749 {
2750 Extbyte* lparam;
2751 GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam);
2752 if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
2753 signal_simple_error ("error adding combo entries", instantiator);
2754 }
2755 }
2756
2757 /* get properties of a control */
2758 static Lisp_Object
2759 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
2760 {
2761 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2762 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2763 /* get the text from a control */
2764 if (EQ (prop, Q_text))
2765 {
2766 Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
2767 Extbyte* buf =alloca (len+1);
2768
2769 SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
2770 return build_ext_string (buf, FORMAT_OS);
2771 }
2772 return Qunbound;
2773 }
2774
2775 /* get properties of a button */
2776 static Lisp_Object
2777 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
2778 {
2779 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2780 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2781 /* check the state of a button */
2782 if (EQ (prop, Q_selected))
2783 {
2784 if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
2785 return Qt;
2786 else
2787 return Qnil;
2788 }
2789 return Qunbound;
2790 }
2791
2792 /* get properties of a combo box */
2793 static Lisp_Object
2794 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
2795 {
2796 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2797 HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
2798 /* get the text from a control */
2799 if (EQ (prop, Q_text))
2800 {
2801 long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
2802 Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
2803 Extbyte* buf = alloca (len+1);
2804 SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
2805 return build_ext_string (buf, FORMAT_OS);
2806 }
2807 return Qunbound;
2808 }
2809
2810 /* set the properties of a control */
2811 static Lisp_Object
2812 mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
2813 Lisp_Object val)
2814 {
2815 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2816
2817 if (EQ (prop, Q_text))
2818 {
2819 Extbyte* lparam=0;
2820 CHECK_STRING (val);
2821 GET_C_STRING_OS_DATA_ALLOCA (val, lparam);
2822 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2823 WM_SETTEXT, 0, (LPARAM)lparam);
2824 return Qt;
2825 }
2826 return Qunbound;
2827 }
2828
2829 /* set the properties of a progres guage */
2830 static Lisp_Object
2831 mswindows_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop,
2832 Lisp_Object val)
2833 {
2834 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2835
2836 if (EQ (prop, Q_percent))
2837 {
2838 CHECK_INT (val);
2839 SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
2840 PBM_SETPOS, (WPARAM)XINT (val), 0);
2841 return Qt;
2842 }
2843 return Qunbound;
2844 }
2845
2846 LRESULT WINAPI
2847 mswindows_control_wnd_proc (HWND hwnd, UINT message,
2848 WPARAM wParam, LPARAM lParam)
2849 {
2850 switch (message)
2851 {
2852 case WM_NOTIFY:
2853 case WM_COMMAND:
2854 case WM_CTLCOLORBTN:
2855 case WM_CTLCOLORLISTBOX:
2856 case WM_CTLCOLOREDIT:
2857 case WM_CTLCOLORSTATIC:
2858 case WM_CTLCOLORSCROLLBAR:
2859
2860 return mswindows_wnd_proc (GetParent (hwnd), message, wParam, lParam);
2861 default:
2862 return DefWindowProc (hwnd, message, wParam, lParam);
2863 }
2864 }
2865
2866 #endif /* HAVE_WIDGETS */
2867
2868
2869 /************************************************************************/
2870 /* initialization */
2871 /************************************************************************/
2872
2873 void
2874 syms_of_glyphs_mswindows (void)
2875 {
2876 defkeyword (&Q_resource_id, ":resource-id");
2877 defkeyword (&Q_resource_type, ":resource-type");
2878 }
2879
2880 void
2881 console_type_create_glyphs_mswindows (void)
2882 {
2883 /* image methods */
2884
2885 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
2886 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
2887 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
2888 CONSOLE_HAS_METHOD (mswindows, map_subwindow);
2889 CONSOLE_HAS_METHOD (mswindows, update_subwindow);
2890 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
2891 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
2892 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
2893 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
2894 CONSOLE_HAS_METHOD (mswindows, resize_subwindow);
2895 }
2896
2897 void
2898 image_instantiator_format_create_glyphs_mswindows (void)
2899 {
2900 IIFORMAT_VALID_CONSOLE (mswindows, nothing);
2901 IIFORMAT_VALID_CONSOLE (mswindows, string);
2902 IIFORMAT_VALID_CONSOLE (mswindows, layout);
2903 IIFORMAT_VALID_CONSOLE (mswindows, formatted_string);
2904 IIFORMAT_VALID_CONSOLE (mswindows, inherit);
2905 /* image-instantiator types */
2906 #ifdef HAVE_XPM
2907 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
2908 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
2909 #endif
2910 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
2911 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
2912 #ifdef HAVE_XFACE
2913 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
2914 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
2915 #endif
2916 #ifdef HAVE_JPEG
2917 IIFORMAT_VALID_CONSOLE (mswindows, jpeg);
2918 #endif
2919 #ifdef HAVE_TIFF
2920 IIFORMAT_VALID_CONSOLE (mswindows, tiff);
2921 #endif
2922 #ifdef HAVE_PNG
2923 IIFORMAT_VALID_CONSOLE (mswindows, png);
2924 #endif
2925 #ifdef HAVE_GIF
2926 IIFORMAT_VALID_CONSOLE (mswindows, gif);
2927 #endif
2928 #ifdef HAVE_WIDGETS
2929 /* button widget */
2930 INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
2931 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
2932 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
2933
2934 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field);
2935 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate);
2936
2937 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
2938 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
2939
2940 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
2941 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
2942 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property);
2943
2944 /* label */
2945 INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
2946 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
2947
2948 /* combo box */
2949 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box);
2950 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property);
2951 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate);
2952
2953 /* scrollbar */
2954 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
2955 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
2956
2957 /* progress gauge */
2958 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge);
2959 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, set_property);
2960 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate);
2961
2962 /* tree view widget */
2963 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view);
2964 /* IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);*/
2965 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate);
2966
2967 /* tab control widget */
2968 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
2969 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
2970 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, set_property);
2971 #endif
2972 /* windows bitmap format */
2973 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
2974 IIFORMAT_HAS_METHOD (bmp, validate);
2975 IIFORMAT_HAS_METHOD (bmp, normalize);
2976 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
2977 IIFORMAT_HAS_METHOD (bmp, instantiate);
2978
2979 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
2980 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
2981 IIFORMAT_VALID_CONSOLE (mswindows, bmp);
2982
2983 /* mswindows resources */
2984 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource,
2985 "mswindows-resource");
2986
2987 IIFORMAT_HAS_METHOD (mswindows_resource, validate);
2988 IIFORMAT_HAS_METHOD (mswindows_resource, normalize);
2989 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types);
2990 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate);
2991
2992 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type,
2993 check_valid_resource_symbol);
2994 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id);
2995 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string);
2996 IIFORMAT_VALID_CONSOLE (mswindows, mswindows_resource);
2997 }
2998
2999 void
3000 vars_of_glyphs_mswindows (void)
3001 {
3002 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
3003 A list of the directories in which mswindows bitmap files may be found.
3004 This is used by the `make-image-instance' function.
3005 */ );
3006 Vmswindows_bitmap_file_path = Qnil;
3007 }
3008
3009 void
3010 complex_vars_of_glyphs_mswindows (void)
3011 {
3012 }