267
|
1 /* mswindows-specific Lisp objects.
|
280
|
2 Copyright (C) 1998 Andy Piper.
|
267
|
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 <andyp@parallax.co.uk> plagerising buts from
|
|
24 glyphs-x.c */
|
|
25
|
|
26 #include <config.h>
|
|
27 #include "lisp.h"
|
|
28 #include "lstream.h"
|
286
|
29
|
|
30 #define OEMRESOURCE /* Define OCR_ and friend constants */
|
267
|
31 #include "console-msw.h"
|
|
32 #include "glyphs-msw.h"
|
|
33 #include "objects-msw.h"
|
|
34
|
|
35 #include "buffer.h"
|
|
36 #include "frame.h"
|
|
37 #include "insdel.h"
|
|
38 #include "opaque.h"
|
|
39 #include "sysfile.h"
|
|
40 #include "faces.h"
|
|
41 #include "imgproc.h"
|
|
42
|
|
43 #ifdef FILE_CODING
|
|
44 #include "file-coding.h"
|
|
45 #endif
|
|
46
|
|
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
|
|
48 Lisp_Object Qbmp;
|
|
49 Lisp_Object Vmswindows_bitmap_file_path;
|
282
|
50 static COLORREF transparent_color = RGB (1,1,1);
|
267
|
51
|
286
|
52 DEFINE_IMAGE_INSTANTIATOR_FORMAT (resource);
|
|
53 Lisp_Object Qresource;
|
284
|
54 Lisp_Object Q_resource_type, Q_resource_id;
|
|
55
|
267
|
56 static void
|
|
57 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
|
|
58 enum image_instance_type type);
|
282
|
59 static void
|
|
60 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
|
|
61 struct frame* f);
|
267
|
62
|
269
|
63 COLORREF mswindows_string_to_color (CONST char *name);
|
267
|
64
|
|
65 /************************************************************************/
|
|
66 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/
|
|
67 /* proper display */
|
|
68 /************************************************************************/
|
278
|
69 static BITMAPINFO* convert_EImage_to_DIBitmap (Lisp_Object device,
|
|
70 int width, int height,
|
|
71 unsigned char *pic,
|
|
72 int *bit_count,
|
|
73 unsigned char** bmp_data)
|
267
|
74 {
|
|
75 struct device *d = XDEVICE (device);
|
269
|
76 int i,j;
|
267
|
77 RGBQUAD* colortbl;
|
|
78 int ncolors;
|
|
79 BITMAPINFO* bmp_info;
|
269
|
80 unsigned char *ip, *dp;
|
267
|
81
|
269
|
82 if (DEVICE_MSWINDOWS_BITSPIXEL (d) > 0)
|
267
|
83 {
|
269
|
84 int bpline=(int)(~3UL & (unsigned long)((width*3) +3));
|
267
|
85 /* FIXME: we can do this because 24bpp implies no colour table, once
|
|
86 * we start paletizing this is no longer true. The X versions of
|
|
87 * this function quantises to 256 colours or bit masks down to a
|
|
88 * long. Windows can actually handle rgb triples in the raw so I
|
272
|
89 * don't see much point trying to optimize down to the best
|
267
|
90 * structure - unless it has memory / color allocation implications
|
|
91 * .... */
|
269
|
92 bmp_info=xnew_and_zero (BITMAPINFO);
|
267
|
93
|
|
94 if (!bmp_info)
|
|
95 {
|
|
96 return NULL;
|
|
97 }
|
|
98
|
|
99 bmp_info->bmiHeader.biBitCount=24; /* just RGB triples for now */
|
|
100 bmp_info->bmiHeader.biCompression=BI_RGB; /* just RGB triples for now */
|
|
101 bmp_info->bmiHeader.biSizeImage=width*height*3;
|
|
102
|
|
103 /* bitmap data needs to be in blue, green, red triples - in that
|
|
104 order, eimage is in RGB format so we need to convert */
|
272
|
105 *bmp_data = xnew_array_and_zero (unsigned char, bpline * height);
|
278
|
106 *bit_count = bpline * height;
|
267
|
107
|
|
108 if (!bmp_data)
|
|
109 {
|
272
|
110 xfree (bmp_info);
|
267
|
111 return NULL;
|
|
112 }
|
272
|
113
|
|
114 ip = pic;
|
|
115 for (i = height-1; i >= 0; i--) {
|
|
116 dp = (*bmp_data) + (i * bpline);
|
|
117 for (j = 0; j < width; j++) {
|
|
118 dp[2] =*ip++;
|
|
119 dp[1] =*ip++;
|
|
120 *dp =*ip++;
|
|
121 dp += 3;
|
267
|
122 }
|
272
|
123 }
|
267
|
124 }
|
|
125 else /* scale to 256 colors */
|
|
126 {
|
272
|
127 int rd,gr,bl;
|
267
|
128 quant_table *qtable;
|
|
129 int bpline= (int)(~3UL & (unsigned long)(width +3));
|
|
130 /* Quantize the image and get a histogram while we're at it.
|
|
131 Do this first to save memory */
|
269
|
132 qtable = build_EImage_quantable(pic, width, height, 256);
|
267
|
133 if (qtable == NULL) return NULL;
|
|
134
|
|
135 /* use our quantize table to allocate the colors */
|
|
136 ncolors = qtable->num_active_colors;
|
272
|
137 bmp_info=(BITMAPINFO*)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) +
|
267
|
138 sizeof(RGBQUAD) * ncolors);
|
|
139 if (!bmp_info)
|
|
140 {
|
272
|
141 xfree (qtable);
|
267
|
142 return NULL;
|
|
143 }
|
|
144
|
|
145 colortbl=(RGBQUAD*)(((unsigned char*)bmp_info)+sizeof(BITMAPINFOHEADER));
|
|
146
|
|
147 bmp_info->bmiHeader.biBitCount=8;
|
|
148 bmp_info->bmiHeader.biCompression=BI_RGB;
|
|
149 bmp_info->bmiHeader.biSizeImage=bpline*height;
|
|
150 bmp_info->bmiHeader.biClrUsed=ncolors;
|
|
151 bmp_info->bmiHeader.biClrImportant=ncolors;
|
|
152
|
|
153 *bmp_data = (unsigned char *) xmalloc_and_zero (bpline * height);
|
|
154 *bit_count = bpline * height;
|
|
155
|
|
156 if (!*bmp_data)
|
|
157 {
|
269
|
158 xfree (qtable);
|
|
159 xfree (bmp_info);
|
267
|
160 return NULL;
|
|
161 }
|
|
162
|
|
163 /* build up an RGBQUAD colortable */
|
|
164 for (i = 0; i < qtable->num_active_colors; i++) {
|
286
|
165 colortbl[i].rgbRed = (BYTE) qtable->rm[i];
|
|
166 colortbl[i].rgbGreen = (BYTE) qtable->gm[i];
|
|
167 colortbl[i].rgbBlue = (BYTE) qtable->bm[i];
|
267
|
168 colortbl[i].rgbReserved = 0;
|
|
169 }
|
|
170
|
|
171 /* now build up the data. picture has to be upside-down and
|
|
172 back-to-front for msw bitmaps */
|
|
173 ip = pic;
|
|
174 for (i = height-1; i >= 0; i--) {
|
|
175 dp = (*bmp_data) + (i * bpline);
|
|
176 for (j = 0; j < width; j++) {
|
|
177 rd = *ip++;
|
|
178 gr = *ip++;
|
|
179 bl = *ip++;
|
269
|
180 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl);
|
267
|
181 }
|
|
182 }
|
269
|
183 xfree (qtable);
|
267
|
184 }
|
|
185 /* fix up the standard stuff */
|
|
186 bmp_info->bmiHeader.biWidth=width;
|
|
187 bmp_info->bmiHeader.biHeight=height;
|
|
188 bmp_info->bmiHeader.biPlanes=1;
|
|
189 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
269
|
190 bmp_info->bmiHeader.biXPelsPerMeter=0; /* unless you know better */
|
|
191 bmp_info->bmiHeader.biYPelsPerMeter=0;
|
267
|
192
|
|
193 return bmp_info;
|
|
194 }
|
|
195
|
|
196 /* Given a pixmap filename, look through all of the "standard" places
|
|
197 where the file might be located. Return a full pathname if found;
|
|
198 otherwise, return Qnil. */
|
|
199
|
280
|
200 static Lisp_Object
|
278
|
201 mswindows_locate_pixmap_file (Lisp_Object name)
|
267
|
202 {
|
|
203 /* This function can GC if IN_REDISPLAY is false */
|
276
|
204 Lisp_Object found;
|
267
|
205
|
|
206 /* Check non-absolute pathnames with a directory component relative to
|
|
207 the search path; that's the way Xt does it. */
|
269
|
208 if (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 0)) ||
|
267
|
209 (XSTRING_BYTE (name, 0) == '.' &&
|
269
|
210 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 1)) ||
|
267
|
211 (XSTRING_BYTE (name, 1) == '.' &&
|
269
|
212 (IS_DIRECTORY_SEP(XSTRING_BYTE (name, 2)))))))
|
267
|
213 {
|
|
214 if (!NILP (Ffile_readable_p (name)))
|
|
215 return name;
|
|
216 else
|
|
217 return Qnil;
|
|
218 }
|
|
219
|
276
|
220 if (locate_file (Vmswindows_bitmap_file_path, name, "", &found, R_OK) < 0)
|
|
221 {
|
|
222 Lisp_Object temp = list1 (Vdata_directory);
|
|
223 struct gcpro gcpro1;
|
267
|
224
|
276
|
225 GCPRO1 (temp);
|
|
226 locate_file (temp, name, "", &found, R_OK);
|
|
227 UNGCPRO;
|
|
228 }
|
267
|
229
|
276
|
230 return found;
|
267
|
231 }
|
|
232
|
|
233
|
|
234 /* Initialize an image instance from a bitmap
|
|
235
|
|
236 DEST_MASK specifies the mask of allowed image types.
|
|
237
|
|
238 If this fails, signal an error. INSTANTIATOR is only used
|
|
239 in the error message. */
|
|
240
|
|
241 static void
|
|
242 init_image_instance_from_dibitmap (struct Lisp_Image_Instance *ii,
|
|
243 BITMAPINFO *bmp_info,
|
|
244 int dest_mask,
|
|
245 void *bmp_data,
|
|
246 int bmp_bits,
|
282
|
247 Lisp_Object instantiator,
|
|
248 int x_hot, int y_hot,
|
|
249 int create_mask)
|
267
|
250 {
|
|
251 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
|
|
252 struct device *d = XDEVICE (device);
|
269
|
253 struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d));
|
267
|
254 void* bmp_buf=0;
|
282
|
255 int type;
|
267
|
256 HBITMAP bitmap;
|
269
|
257 HDC hdc;
|
267
|
258
|
|
259 if (!DEVICE_MSWINDOWS_P (d))
|
|
260 signal_simple_error ("Not an mswindows device", device);
|
|
261
|
|
262 if (NILP (DEVICE_SELECTED_FRAME (d)))
|
|
263 signal_simple_error ("No selected frame on mswindows device", device);
|
|
264
|
282
|
265 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
|
|
266 type = IMAGE_COLOR_PIXMAP;
|
|
267 else if (dest_mask & IMAGE_POINTER_MASK)
|
|
268 type = IMAGE_POINTER;
|
|
269 else
|
267
|
270 incompatible_image_types (instantiator, dest_mask,
|
282
|
271 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
|
267
|
272 hdc = FRAME_MSWINDOWS_DC (f);
|
|
273
|
269
|
274 bitmap=CreateDIBSection (hdc,
|
267
|
275 bmp_info,
|
|
276 DIB_RGB_COLORS,
|
|
277 &bmp_buf,
|
|
278 0,0);
|
|
279
|
|
280 if (!bitmap || !bmp_buf)
|
|
281 signal_simple_error ("Unable to create bitmap", instantiator);
|
|
282
|
|
283 /* copy in the actual bitmap */
|
269
|
284 memcpy (bmp_buf, bmp_data, bmp_bits);
|
267
|
285
|
282
|
286 mswindows_initialize_dibitmap_image_instance (ii, type);
|
267
|
287
|
|
288 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
|
|
289 find_keyword_in_vector (instantiator, Q_file);
|
|
290
|
|
291 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
|
282
|
292 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
|
267
|
293 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
|
|
294 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
|
|
295 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount;
|
282
|
296 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), x_hot);
|
|
297 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), y_hot);
|
|
298
|
|
299 if (create_mask)
|
|
300 {
|
|
301 mswindows_initialize_image_instance_mask (ii, f);
|
|
302 }
|
|
303
|
|
304 if (type == IMAGE_POINTER)
|
|
305 {
|
|
306 mswindows_initialize_image_instance_icon(ii, TRUE);
|
|
307 }
|
267
|
308 }
|
|
309
|
278
|
310 static void
|
|
311 mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
|
|
312 int width, int height,
|
|
313 unsigned char *eimage,
|
|
314 int dest_mask,
|
|
315 Lisp_Object instantiator,
|
|
316 Lisp_Object domain)
|
|
317 {
|
|
318 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
|
|
319 BITMAPINFO* bmp_info;
|
|
320 unsigned char* bmp_data;
|
|
321 int bmp_bits;
|
|
322 COLORREF bkcolor;
|
|
323
|
|
324 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
|
|
325 signal_simple_error ("Not an mswindows device", device);
|
|
326
|
|
327 /* this is a hack but MaskBlt and TransparentBlt are not supported
|
|
328 on most windows variants */
|
|
329 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
|
|
330 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
|
|
331
|
|
332 /* build a bitmap from the eimage */
|
|
333 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
|
|
334 &bmp_bits, &bmp_data)))
|
|
335 {
|
|
336 signal_simple_error ("EImage to DIBitmap conversion failed",
|
|
337 instantiator);
|
|
338 }
|
|
339
|
|
340 /* Now create the pixmap and set up the image instance */
|
|
341 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
|
282
|
342 bmp_data, bmp_bits, instantiator,
|
|
343 0, 0, 0);
|
278
|
344
|
|
345 xfree (bmp_info);
|
|
346 xfree (bmp_data);
|
|
347 }
|
|
348
|
282
|
349 static void set_mono_pixel ( unsigned char* bits,
|
|
350 int bpline, int height,
|
|
351 int x, int y, int white )
|
|
352 {
|
|
353 int index;
|
|
354 unsigned char bitnum;
|
|
355 /* Find the byte on which this scanline begins */
|
|
356 index = (height - y - 1) * bpline;
|
|
357 /* Find the byte containing this pixel */
|
|
358 index += (x >> 3);
|
|
359 /* Which bit is it? */
|
|
360 bitnum = (unsigned char)( 7 - (x % 8) );
|
|
361 if( white ) /* Turn it on */
|
|
362 bits[index] |= (1<<bitnum);
|
|
363 else /* Turn it off */
|
|
364 bits[index] &= ~(1<<bitnum);
|
|
365 }
|
|
366
|
|
367 static void
|
|
368 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
|
|
369 struct frame* f)
|
276
|
370 {
|
284
|
371 HBITMAP mask;
|
|
372 HGDIOBJ old = NULL;
|
276
|
373 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
|
282
|
374 BITMAPINFO* bmp_info =
|
284
|
375 xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD));
|
282
|
376 int i, j;
|
|
377 int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image);
|
276
|
378
|
282
|
379 void* and_bits;
|
|
380 int bpline= (int)(~3UL & (unsigned long)
|
|
381 (((IMAGE_INSTANCE_PIXMAP_WIDTH (image)+7)/8) +3));
|
|
382
|
|
383 bmp_info->bmiHeader.biWidth=IMAGE_INSTANCE_PIXMAP_WIDTH (image);
|
|
384 bmp_info->bmiHeader.biHeight = height;
|
|
385 bmp_info->bmiHeader.biPlanes=1;
|
|
386 bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
|
387 bmp_info->bmiHeader.biBitCount=1;
|
|
388 bmp_info->bmiHeader.biCompression=BI_RGB;
|
|
389 bmp_info->bmiHeader.biClrUsed = 2;
|
|
390 bmp_info->bmiHeader.biClrImportant = 2;
|
|
391 bmp_info->bmiHeader.biSizeImage = height * bpline;
|
|
392 bmp_info->bmiColors[0].rgbRed = 0;
|
|
393 bmp_info->bmiColors[0].rgbGreen = 0;
|
|
394 bmp_info->bmiColors[0].rgbBlue = 0;
|
|
395 bmp_info->bmiColors[0].rgbReserved = 0;
|
|
396 bmp_info->bmiColors[1].rgbRed = 255;
|
|
397 bmp_info->bmiColors[1].rgbGreen = 255;
|
|
398 bmp_info->bmiColors[1].rgbBlue = 255;
|
|
399 bmp_info->bmiColors[0].rgbReserved = 0;
|
|
400
|
|
401 if (!(mask = CreateDIBSection (hcdc,
|
|
402 bmp_info,
|
|
403 DIB_RGB_COLORS,
|
|
404 &and_bits,
|
|
405 0,0)))
|
276
|
406 {
|
282
|
407 xfree (bmp_info);
|
|
408 return;
|
276
|
409 }
|
|
410
|
282
|
411 xfree (bmp_info);
|
284
|
412 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image));
|
276
|
413
|
282
|
414 for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++)
|
|
415 {
|
|
416 for(j=0; j<height; j++)
|
|
417 {
|
|
418 if( GetPixel( hcdc, i, j ) == transparent_color )
|
|
419 {
|
|
420 SetPixel( hcdc, i, j, RGB (0,0,0));
|
|
421 set_mono_pixel( and_bits, bpline, height, i, j, TRUE );
|
|
422 }
|
|
423 else
|
|
424 {
|
|
425 set_mono_pixel( and_bits, bpline, height, i, j, FALSE );
|
|
426 }
|
|
427 }
|
276
|
428 }
|
|
429
|
282
|
430 GdiFlush();
|
284
|
431 SelectObject(hcdc, old);
|
282
|
432
|
|
433 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask;
|
|
434 }
|
|
435
|
|
436 void
|
|
437 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
|
|
438 int cursor)
|
|
439 {
|
|
440 ICONINFO x_icon;
|
|
441
|
|
442 /* we rely on windows to do any resizing necessary */
|
|
443 x_icon.fIcon=cursor ? FALSE : TRUE;
|
|
444 x_icon.xHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image));
|
|
445 x_icon.yHotspot=XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image));
|
|
446 x_icon.hbmMask=IMAGE_INSTANCE_MSWINDOWS_MASK (image);
|
|
447 x_icon.hbmColor=IMAGE_INSTANCE_MSWINDOWS_BITMAP (image);
|
276
|
448
|
282
|
449 IMAGE_INSTANCE_MSWINDOWS_ICON (image)=
|
276
|
450 CreateIconIndirect (&x_icon);
|
|
451 }
|
|
452
|
286
|
453 HBITMAP
|
|
454 mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
|
|
455 struct frame* f,
|
|
456 int newx, int newy)
|
276
|
457 {
|
286
|
458 HBITMAP newbmp;
|
|
459 HGDIOBJ old1, old2;
|
276
|
460 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
|
|
461 HDC hdcDst = CreateCompatibleDC (hcdc);
|
|
462
|
286
|
463 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
|
276
|
464
|
284
|
465 newbmp = CreateCompatibleBitmap (hcdc, newx, newy);
|
276
|
466
|
286
|
467 old2 = SelectObject (hdcDst, newbmp);
|
276
|
468
|
284
|
469 if (!StretchBlt (hdcDst, 0, 0, newx, newy,
|
|
470 hcdc, 0, 0,
|
|
471 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
|
|
472 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
|
|
473 SRCCOPY))
|
276
|
474 {
|
286
|
475 return 0;
|
276
|
476 }
|
284
|
477
|
286
|
478 SelectObject (hdcDst, old2);
|
|
479 SelectObject (hcdc, old1);
|
|
480 DeleteDC (hdcDst);
|
|
481
|
|
482 return newbmp;
|
|
483 }
|
|
484
|
|
485 HBITMAP
|
|
486 mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
|
|
487 struct frame* f,
|
|
488 int newx, int newy)
|
|
489 {
|
284
|
490 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
|
|
491 {
|
286
|
492 HBITMAP newmask;
|
|
493 HGDIOBJ old1, old2;
|
|
494 HDC hcdc = FRAME_MSWINDOWS_CDC (f);
|
|
495 HDC hdcDst = CreateCompatibleDC (hcdc);
|
|
496
|
|
497 old1 = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
|
284
|
498 newmask = CreateCompatibleBitmap(hcdc, newx, newy);
|
286
|
499 old2 = SelectObject (hdcDst, newmask);
|
284
|
500
|
|
501 if (!StretchBlt(hdcDst, 0, 0, newx, newy,
|
|
502 hcdc, 0, 0,
|
|
503 IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
|
|
504 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
|
|
505 SRCCOPY))
|
|
506 {
|
286
|
507 return NULL;
|
284
|
508 }
|
286
|
509
|
|
510 SelectObject (hdcDst, old2);
|
|
511 SelectObject (hcdc, old1);
|
|
512
|
|
513 DeleteDC (hdcDst);
|
|
514
|
|
515 return newmask;
|
284
|
516 }
|
|
517
|
286
|
518 return NULL;
|
|
519 }
|
|
520
|
|
521 int
|
|
522 mswindows_resize_dibitmap_instance (struct Lisp_Image_Instance* ii,
|
|
523 struct frame* f,
|
|
524 int newx, int newy)
|
|
525 {
|
|
526 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy);
|
|
527 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy);
|
|
528
|
|
529 if (!newbmp)
|
|
530 return FALSE;
|
276
|
531
|
|
532 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii))
|
|
533 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii));
|
|
534 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii))
|
|
535 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii));
|
|
536
|
|
537 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp;
|
284
|
538 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask;
|
276
|
539 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx;
|
|
540 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy;
|
|
541
|
|
542 return TRUE;
|
|
543 }
|
|
544
|
267
|
545 /**********************************************************************
|
|
546 * XPM *
|
|
547 **********************************************************************/
|
|
548
|
|
549 #ifdef HAVE_XPM
|
280
|
550
|
|
551 struct color_symbol
|
|
552 {
|
|
553 char* name;
|
|
554 COLORREF color;
|
|
555 };
|
|
556
|
|
557 static struct color_symbol*
|
|
558 extract_xpm_color_names (Lisp_Object device,
|
|
559 Lisp_Object domain,
|
|
560 Lisp_Object color_symbol_alist,
|
|
561 int* nsymbols)
|
|
562 {
|
|
563 /* This function can GC */
|
|
564 Lisp_Object rest;
|
|
565 Lisp_Object results = Qnil;
|
|
566 int i, j;
|
|
567 struct color_symbol *colortbl;
|
|
568 struct gcpro gcpro1, gcpro2;
|
|
569
|
|
570 GCPRO2 (results, device);
|
|
571
|
|
572 /* We built up results to be (("name" . #<color>) ...) so that if an
|
|
573 error happens we don't lose any malloc()ed data, or more importantly,
|
|
574 leave any pixels allocated in the server. */
|
|
575 i = 0;
|
|
576 LIST_LOOP (rest, color_symbol_alist)
|
|
577 {
|
|
578 Lisp_Object cons = XCAR (rest);
|
|
579 Lisp_Object name = XCAR (cons);
|
|
580 Lisp_Object value = XCDR (cons);
|
|
581 if (NILP (value))
|
|
582 continue;
|
|
583 if (STRINGP (value))
|
|
584 value =
|
|
585 Fmake_color_instance
|
|
586 (value, device, encode_error_behavior_flag (ERROR_ME_NOT));
|
|
587 else
|
|
588 {
|
|
589 assert (COLOR_SPECIFIERP (value));
|
|
590 value = Fspecifier_instance (value, domain, Qnil, Qnil);
|
|
591 }
|
|
592 if (NILP (value))
|
|
593 continue;
|
|
594 results = noseeum_cons (noseeum_cons (name, value), results);
|
|
595 i++;
|
|
596 }
|
|
597 UNGCPRO; /* no more evaluation */
|
|
598
|
|
599 *nsymbols=i;
|
|
600 if (i == 0) return 0;
|
|
601
|
|
602 colortbl = xnew_array_and_zero (struct color_symbol, i);
|
|
603
|
|
604 for (j=0; j<i; j++)
|
|
605 {
|
|
606 Lisp_Object cons = XCAR (results);
|
|
607 colortbl[j].color =
|
|
608 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
|
|
609
|
|
610 colortbl[j].name = (char *) XSTRING_DATA (XCAR (cons));
|
|
611 free_cons (XCONS (cons));
|
|
612 cons = results;
|
|
613 results = XCDR (results);
|
|
614 free_cons (XCONS (cons));
|
|
615 }
|
|
616 return colortbl;
|
|
617 }
|
|
618
|
269
|
619 static int xpm_to_eimage (Lisp_Object image, CONST Extbyte *buffer,
|
276
|
620 unsigned char** data,
|
|
621 int* width, int* height,
|
|
622 int* x_hot, int* y_hot,
|
282
|
623 int* transp,
|
|
624 struct color_symbol* color_symbols,
|
280
|
625 int nsymbols)
|
267
|
626 {
|
|
627 XpmImage xpmimage;
|
|
628 XpmInfo xpminfo;
|
280
|
629 int result, i, j, transp_idx, maskbpline;
|
267
|
630 unsigned char* dptr;
|
|
631 unsigned int* sptr;
|
|
632 COLORREF color; /* the american spelling virus hits again .. */
|
|
633 COLORREF* colortbl;
|
|
634
|
272
|
635 xzero (xpmimage);
|
|
636 xzero (xpminfo);
|
276
|
637 xpminfo.valuemask=XpmHotspot;
|
282
|
638 *transp=FALSE;
|
276
|
639
|
269
|
640 result = XpmCreateXpmImageFromBuffer ((char*)buffer,
|
267
|
641 &xpmimage,
|
|
642 &xpminfo);
|
269
|
643 switch (result)
|
267
|
644 {
|
|
645 case XpmSuccess:
|
|
646 break;
|
|
647 case XpmFileInvalid:
|
|
648 {
|
|
649 signal_simple_error ("invalid XPM data", image);
|
|
650 }
|
|
651 case XpmNoMemory:
|
|
652 {
|
|
653 signal_double_file_error ("Parsing pixmap data",
|
|
654 "out of memory", image);
|
|
655 }
|
|
656 default:
|
|
657 {
|
|
658 signal_double_file_error_2 ("Parsing pixmap data",
|
|
659 "unknown error code",
|
|
660 make_int (result), image);
|
|
661 }
|
|
662 }
|
|
663
|
|
664 *width = xpmimage.width;
|
|
665 *height = xpmimage.height;
|
276
|
666 maskbpline = (int)(~3UL & (unsigned long)
|
|
667 (((~7UL & (unsigned long)(*width + 7)) / 8) + 3));
|
|
668
|
|
669 *data = xnew_array_and_zero (unsigned char, *width * *height * 3);
|
267
|
670
|
|
671 if (!*data)
|
|
672 {
|
269
|
673 XpmFreeXpmImage (&xpmimage);
|
|
674 XpmFreeXpmInfo (&xpminfo);
|
267
|
675 return 0;
|
|
676 }
|
|
677
|
|
678 /* build a color table to speed things up */
|
|
679 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors);
|
|
680 if (!colortbl)
|
|
681 {
|
269
|
682 xfree (*data);
|
|
683 XpmFreeXpmImage (&xpmimage);
|
|
684 XpmFreeXpmInfo (&xpminfo);
|
267
|
685 return 0;
|
|
686 }
|
|
687
|
|
688 for (i=0; i<xpmimage.ncolors; i++)
|
|
689 {
|
280
|
690 /* pick up symbolic colors */
|
|
691 if (xpmimage.colorTable[i].c_color == 0
|
|
692 &&
|
|
693 xpmimage.colorTable[i].symbolic != 0)
|
|
694 {
|
|
695 if (!color_symbols)
|
|
696 {
|
|
697 xfree (*data);
|
|
698 xfree (colortbl);
|
|
699 XpmFreeXpmImage (&xpmimage);
|
|
700 XpmFreeXpmInfo (&xpminfo);
|
|
701 return 0;
|
|
702 }
|
|
703 for (j = 0; j<nsymbols; j++)
|
|
704 {
|
|
705 if (!strcmp (xpmimage.colorTable[i].symbolic,
|
|
706 color_symbols[j].name ))
|
|
707 {
|
|
708 colortbl[i]=color_symbols[j].color;
|
|
709 }
|
|
710 }
|
|
711 }
|
267
|
712 /* pick up transparencies */
|
282
|
713 else if (!strcasecmp (xpmimage.colorTable[i].c_color,"None")
|
|
714 ||
|
284
|
715 (xpmimage.colorTable[i].symbolic
|
|
716 &&
|
|
717 (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor")
|
|
718 ||
|
|
719 !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))))
|
267
|
720 {
|
282
|
721 *transp=TRUE;
|
|
722 colortbl[i]=transparent_color;
|
276
|
723 transp_idx=i;
|
267
|
724 }
|
|
725 else
|
|
726 {
|
|
727 colortbl[i]=
|
269
|
728 mswindows_string_to_color (xpmimage.colorTable[i].c_color);
|
267
|
729 }
|
|
730 }
|
|
731
|
|
732 /* convert the image */
|
|
733 sptr=xpmimage.data;
|
|
734 dptr=*data;
|
|
735 for (i = 0; i< *width * *height; i++)
|
|
736 {
|
|
737 color = colortbl[*sptr++];
|
|
738
|
|
739 /* split out the 0x02bbggrr colorref into an rgb triple */
|
269
|
740 *dptr++=GetRValue (color); /* red */
|
|
741 *dptr++=GetGValue (color); /* green */
|
|
742 *dptr++=GetBValue (color); /* blue */
|
267
|
743 }
|
|
744
|
276
|
745 *x_hot=xpminfo.x_hotspot;
|
|
746 *y_hot=xpminfo.y_hotspot;
|
|
747
|
269
|
748 XpmFreeXpmImage (&xpmimage);
|
|
749 XpmFreeXpmInfo (&xpminfo);
|
|
750 xfree (colortbl);
|
267
|
751 return TRUE;
|
|
752 }
|
|
753
|
280
|
754 static void
|
267
|
755 mswindows_xpm_instantiate (Lisp_Object image_instance,
|
|
756 Lisp_Object instantiator,
|
|
757 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
758 int dest_mask, Lisp_Object domain)
|
|
759 {
|
|
760 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
|
|
761 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
|
|
762 CONST Extbyte *bytes;
|
|
763 Extcount len;
|
|
764 unsigned char *eimage;
|
276
|
765 int width, height, x_hot, y_hot;
|
267
|
766 BITMAPINFO* bmp_info;
|
|
767 unsigned char* bmp_data;
|
|
768 int bmp_bits;
|
282
|
769 int nsymbols=0, transp;
|
280
|
770 struct color_symbol* color_symbols=NULL;
|
267
|
771
|
|
772 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
|
280
|
773 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator,
|
|
774 Q_color_symbols);
|
267
|
775
|
|
776 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
|
|
777 signal_simple_error ("Not an mswindows device", device);
|
|
778
|
|
779 assert (!NILP (data));
|
|
780
|
|
781 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
|
|
782
|
280
|
783 /* in case we have color symbols */
|
|
784 color_symbols = extract_xpm_color_names (device, domain,
|
|
785 color_symbol_alist, &nsymbols);
|
|
786
|
267
|
787 /* convert to an eimage to make processing easier */
|
269
|
788 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height,
|
282
|
789 &x_hot, &y_hot, &transp, color_symbols, nsymbols))
|
267
|
790 {
|
|
791 signal_simple_error ("XPM to EImage conversion failed",
|
|
792 image_instance);
|
|
793 }
|
|
794
|
280
|
795 if (color_symbols)
|
|
796 xfree(color_symbols);
|
|
797
|
267
|
798 /* build a bitmap from the eimage */
|
278
|
799 if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
|
|
800 &bmp_bits, &bmp_data)))
|
267
|
801 {
|
|
802 signal_simple_error ("XPM to EImage conversion failed",
|
|
803 image_instance);
|
|
804 }
|
269
|
805 xfree (eimage);
|
267
|
806
|
|
807 /* Now create the pixmap and set up the image instance */
|
|
808 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
|
282
|
809 bmp_data, bmp_bits, instantiator,
|
|
810 x_hot, y_hot, transp);
|
267
|
811
|
269
|
812 xfree (bmp_info);
|
|
813 xfree (bmp_data);
|
267
|
814 }
|
|
815 #endif /* HAVE_XPM */
|
|
816
|
|
817 /**********************************************************************
|
|
818 * BMP *
|
|
819 **********************************************************************/
|
|
820
|
|
821 static void
|
|
822 bmp_validate (Lisp_Object instantiator)
|
|
823 {
|
|
824 file_or_data_must_be_present (instantiator);
|
|
825 }
|
|
826
|
|
827 static Lisp_Object
|
|
828 bmp_normalize (Lisp_Object inst, Lisp_Object console_type)
|
|
829 {
|
|
830 return simple_image_type_normalize (inst, console_type, Qbmp);
|
|
831 }
|
|
832
|
|
833 static int
|
|
834 bmp_possible_dest_types (void)
|
|
835 {
|
|
836 return IMAGE_COLOR_PIXMAP_MASK;
|
|
837 }
|
|
838
|
|
839 static void
|
|
840 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
|
|
841 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
842 int dest_mask, Lisp_Object domain)
|
|
843 {
|
|
844 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
|
|
845 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
|
|
846 CONST Extbyte *bytes;
|
|
847 Extcount len;
|
|
848 BITMAPFILEHEADER* bmp_file_header;
|
|
849 BITMAPINFO* bmp_info;
|
|
850 void* bmp_data;
|
|
851 int bmp_bits;
|
|
852 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
|
|
853
|
|
854 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
|
|
855 signal_simple_error ("Not an mswindows device", device);
|
|
856
|
|
857 assert (!NILP (data));
|
|
858
|
|
859 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
|
|
860
|
|
861 /* Then slurp the image into memory, decoding along the way.
|
|
862 The result is the image in a simple one-byte-per-pixel
|
|
863 format. */
|
|
864
|
|
865 bmp_file_header=(BITMAPFILEHEADER*)bytes;
|
|
866 bmp_info = (BITMAPINFO*)(bytes + sizeof(BITMAPFILEHEADER));
|
|
867 bmp_data = (Extbyte*)bytes + bmp_file_header->bfOffBits;
|
|
868 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits;
|
|
869
|
|
870 /* Now create the pixmap and set up the image instance */
|
|
871 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
|
282
|
872 bmp_data, bmp_bits, instantiator,
|
|
873 0, 0, 0);
|
267
|
874 }
|
|
875
|
|
876
|
284
|
877 /**********************************************************************
|
286
|
878 * RESOURCES *
|
284
|
879 **********************************************************************/
|
|
880
|
|
881 static void
|
286
|
882 resource_validate (Lisp_Object instantiator)
|
284
|
883 {
|
|
884 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
|
|
885 &&
|
|
886 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
|
|
887 ||
|
|
888 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
|
|
889 signal_simple_error ("Must supply :file, :resource-id and :resource-type",
|
|
890 instantiator);
|
|
891 }
|
|
892
|
|
893 static Lisp_Object
|
286
|
894 resource_normalize (Lisp_Object inst, Lisp_Object console_type)
|
284
|
895 {
|
|
896 /* This function can call lisp */
|
|
897 Lisp_Object file = Qnil;
|
|
898 struct gcpro gcpro1, gcpro2;
|
|
899 Lisp_Object alist = Qnil;
|
|
900
|
|
901 GCPRO2 (file, alist);
|
|
902
|
|
903 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
|
|
904 console_type);
|
|
905
|
|
906 if (CONSP (file)) /* failure locating filename */
|
|
907 signal_double_file_error ("Opening pixmap file",
|
|
908 "no such file or directory",
|
|
909 Fcar (file));
|
|
910
|
|
911 if (NILP (file)) /* no conversion necessary */
|
|
912 RETURN_UNGCPRO (inst);
|
|
913
|
|
914 alist = tagged_vector_to_alist (inst);
|
|
915
|
|
916 {
|
|
917 alist = remassq_no_quit (Q_file, alist);
|
|
918 alist = Fcons (Fcons (Q_file, file), alist);
|
|
919 }
|
|
920
|
|
921 {
|
286
|
922 Lisp_Object result = alist_to_tagged_vector (Qresource, alist);
|
284
|
923 free_alist (alist);
|
|
924 RETURN_UNGCPRO (result);
|
|
925 }
|
|
926 }
|
|
927
|
|
928 static int
|
286
|
929 resource_possible_dest_types (void)
|
284
|
930 {
|
|
931 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK;
|
|
932 }
|
|
933
|
|
934 typedef struct
|
|
935 {
|
|
936 char *name;
|
|
937 int resource_id;
|
|
938 } resource_t;
|
|
939
|
|
940 #ifndef OCR_ICOCUR
|
|
941 #define OCR_ICOCUR 32647
|
|
942 #define OIC_SAMPLE 32512
|
|
943 #define OIC_HAND 32513
|
|
944 #define OIC_QUES 32514
|
|
945 #define OIC_BANG 32515
|
|
946 #define OIC_NOTE 32516
|
|
947 #define OIC_WINLOGO 32517
|
|
948 #define LR_SHARED 0x8000
|
|
949 #endif
|
|
950
|
286
|
951 static CONST resource_t bitmap_table[] =
|
284
|
952 {
|
|
953 /* bitmaps */
|
|
954 { "close", OBM_CLOSE },
|
|
955 { "uparrow", OBM_UPARROW },
|
|
956 { "dnarrow", OBM_DNARROW },
|
|
957 { "rgarrow", OBM_RGARROW },
|
|
958 { "lfarrow", OBM_LFARROW },
|
|
959 { "reduce", OBM_REDUCE },
|
|
960 { "zoom", OBM_ZOOM },
|
|
961 { "restore", OBM_RESTORE },
|
|
962 { "reduced", OBM_REDUCED },
|
|
963 { "zoomd", OBM_ZOOMD },
|
|
964 { "restored", OBM_RESTORED },
|
|
965 { "uparrowd", OBM_UPARROWD },
|
|
966 { "dnarrowd", OBM_DNARROWD },
|
|
967 { "rgarrowd", OBM_RGARROWD },
|
|
968 { "lfarrowd", OBM_LFARROWD },
|
|
969 { "mnarrow", OBM_MNARROW },
|
|
970 { "combo", OBM_COMBO },
|
|
971 { "uparrowi", OBM_UPARROWI },
|
|
972 { "dnarrowi", OBM_DNARROWI },
|
|
973 { "rgarrowi", OBM_RGARROWI },
|
|
974 { "lfarrowi", OBM_LFARROWI },
|
|
975 { "size", OBM_SIZE },
|
|
976 { "btsize", OBM_BTSIZE },
|
|
977 { "check", OBM_CHECK },
|
|
978 { "cehckboxes", OBM_CHECKBOXES },
|
|
979 { "btncorners" , OBM_BTNCORNERS },
|
286
|
980 {0}
|
|
981 };
|
|
982
|
|
983 static CONST resource_t cursor_table[] =
|
|
984 {
|
284
|
985 /* cursors */
|
|
986 { "normal", OCR_NORMAL },
|
|
987 { "ibeam", OCR_IBEAM },
|
|
988 { "wait", OCR_WAIT },
|
|
989 { "cross", OCR_CROSS },
|
|
990 { "up", OCR_UP },
|
|
991 /* { "icon", OCR_ICON }, */
|
|
992 { "sizenwse", OCR_SIZENWSE },
|
|
993 { "sizenesw", OCR_SIZENESW },
|
|
994 { "sizewe", OCR_SIZEWE },
|
|
995 { "sizens", OCR_SIZENS },
|
|
996 { "sizeall", OCR_SIZEALL },
|
|
997 /* { "icour", OCR_ICOCUR }, */
|
|
998 { "no", OCR_NO },
|
286
|
999 { 0 }
|
|
1000 };
|
|
1001
|
|
1002 static CONST resource_t icon_table[] =
|
|
1003 {
|
284
|
1004 /* icons */
|
|
1005 { "sample", OIC_SAMPLE },
|
|
1006 { "hand", OIC_HAND },
|
|
1007 { "ques", OIC_QUES },
|
|
1008 { "bang", OIC_BANG },
|
|
1009 { "note", OIC_NOTE },
|
|
1010 { "winlogo", OIC_WINLOGO },
|
|
1011 {0}
|
|
1012 };
|
|
1013
|
286
|
1014 static int resource_name_to_resource (Lisp_Object name, int type)
|
284
|
1015 {
|
286
|
1016 CONST resource_t* res = (type == IMAGE_CURSOR ? cursor_table
|
|
1017 : type == IMAGE_ICON ? icon_table
|
|
1018 : bitmap_table);
|
284
|
1019
|
|
1020 if (INTP (name))
|
|
1021 {
|
|
1022 return XINT (name);
|
|
1023 }
|
|
1024 else if (!STRINGP (name))
|
|
1025 {
|
|
1026 signal_simple_error ("invalid resource identifier", name);
|
|
1027 }
|
|
1028
|
|
1029 do {
|
|
1030 if (!strcasecmp ((char*)res->name, XSTRING_DATA (name)))
|
|
1031 return res->resource_id;
|
|
1032 } while ((++res)->name);
|
|
1033 return 0;
|
|
1034 }
|
|
1035
|
286
|
1036 static int
|
|
1037 resource_symbol_to_type (Lisp_Object data)
|
|
1038 {
|
|
1039 if (EQ (data, Qcursor))
|
|
1040 return IMAGE_CURSOR;
|
|
1041 else if (EQ (data, Qicon))
|
|
1042 return IMAGE_ICON;
|
|
1043 else if (EQ (data, Qbitmap))
|
|
1044 return IMAGE_BITMAP;
|
|
1045 else
|
|
1046 return 0;
|
|
1047 }
|
|
1048
|
284
|
1049 static void
|
286
|
1050 resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
|
284
|
1051 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
|
|
1052 int dest_mask, Lisp_Object domain)
|
|
1053 {
|
|
1054 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
|
|
1055 unsigned int type = 0;
|
|
1056 HANDLE himage = NULL;
|
|
1057 LPCTSTR resid=0;
|
286
|
1058 HINSTANCE hinst = NULL;
|
|
1059 ICONINFO iconinfo;
|
284
|
1060 int iitype=0;
|
286
|
1061 char* fname=0;
|
284
|
1062 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
|
|
1063
|
|
1064 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file);
|
|
1065 Lisp_Object resource_type = find_keyword_in_vector (instantiator,
|
|
1066 Q_resource_type);
|
|
1067 Lisp_Object resource_id = find_keyword_in_vector (instantiator,
|
|
1068 Q_resource_id);
|
|
1069
|
286
|
1070 xzero (iconinfo);
|
|
1071
|
284
|
1072 if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
|
|
1073 signal_simple_error ("Not an mswindows device", device);
|
|
1074
|
286
|
1075 type = resource_symbol_to_type (resource_type);
|
284
|
1076
|
|
1077 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR)
|
|
1078 iitype = IMAGE_POINTER;
|
|
1079 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK)
|
|
1080 iitype = IMAGE_COLOR_PIXMAP;
|
|
1081 else
|
|
1082 incompatible_image_types (instantiator, dest_mask,
|
|
1083 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK);
|
|
1084
|
286
|
1085 /* mess with the keyword info we were provided with */
|
284
|
1086 if (!NILP (file))
|
286
|
1087 {
|
|
1088 #ifdef __CYGWIN32__
|
|
1089 CYGWIN_WIN32_PATH (XSTRING_DATA (file), fname);
|
|
1090 #else
|
|
1091 /* #### FIXME someone who knows ... */
|
|
1092 fname = XSTRING_DATA (file);
|
|
1093 #endif
|
|
1094
|
|
1095 if (NILP (resource_id))
|
|
1096 resid = (LPCTSTR)fname;
|
|
1097 else
|
|
1098 {
|
|
1099 hinst = LoadLibraryEx (fname, NULL,
|
|
1100 LOAD_LIBRARY_AS_DATAFILE);
|
|
1101 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
|
|
1102 type));
|
|
1103
|
|
1104 if (!resid)
|
|
1105 resid = XSTRING_DATA (resource_id);
|
|
1106 }
|
|
1107 }
|
|
1108 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
|
|
1109 type))))
|
|
1110 signal_simple_error ("invalid resource identifier", resource_id);
|
284
|
1111
|
|
1112 /* load the image */
|
286
|
1113 if (!(himage = LoadImage (hinst, resid, type, 0, 0,
|
284
|
1114 LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
|
|
1115 LR_SHARED |
|
|
1116 (!NILP (file) ? LR_LOADFROMFILE : 0))))
|
|
1117 {
|
|
1118 signal_simple_error ("cannot load image", instantiator);
|
|
1119 }
|
|
1120
|
286
|
1121 if (hinst)
|
|
1122 FreeLibrary (hinst);
|
|
1123
|
284
|
1124 mswindows_initialize_dibitmap_image_instance (ii, iitype);
|
|
1125
|
|
1126 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
|
|
1127 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
|
286
|
1128 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON);
|
284
|
1129 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) =
|
286
|
1130 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON);
|
|
1131 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1;
|
|
1132
|
|
1133 /* hey, we've got an icon type thing so we can reverse engineer the
|
|
1134 bitmap and mask */
|
|
1135 if (type != IMAGE_BITMAP)
|
|
1136 {
|
|
1137 GetIconInfo (himage, &iconinfo);
|
|
1138 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor;
|
|
1139 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask;
|
|
1140 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), iconinfo.xHotspot);
|
|
1141 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), iconinfo.yHotspot);
|
|
1142 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = himage;
|
|
1143 }
|
|
1144 else
|
|
1145 {
|
|
1146 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL;
|
|
1147 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = himage;
|
|
1148 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
|
|
1149 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0);
|
|
1150 XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0);
|
|
1151 }
|
284
|
1152 }
|
|
1153
|
286
|
1154 static void
|
|
1155 check_valid_resource_symbol (Lisp_Object data)
|
284
|
1156 {
|
|
1157 CHECK_SYMBOL (data);
|
286
|
1158 if (!resource_symbol_to_type (data))
|
|
1159 signal_simple_error ("invalid resource type", data);
|
|
1160 }
|
|
1161
|
|
1162 static void
|
|
1163 check_valid_resource_id (Lisp_Object data)
|
|
1164 {
|
|
1165 if (!resource_name_to_resource (data, IMAGE_CURSOR)
|
|
1166 &&
|
|
1167 !resource_name_to_resource (data, IMAGE_ICON)
|
|
1168 &&
|
|
1169 !resource_name_to_resource (data, IMAGE_BITMAP))
|
|
1170 signal_simple_error ("invalid resource identifier", data);
|
284
|
1171 }
|
|
1172
|
|
1173 void
|
|
1174 check_valid_string_or_int (Lisp_Object data)
|
|
1175 {
|
|
1176 if (!INTP (data))
|
|
1177 CHECK_STRING (data);
|
|
1178 else
|
|
1179 CHECK_INT (data);
|
|
1180 }
|
|
1181
|
|
1182
|
267
|
1183 /************************************************************************/
|
|
1184 /* image instance methods */
|
|
1185 /************************************************************************/
|
|
1186
|
|
1187 static void
|
|
1188 mswindows_print_image_instance (struct Lisp_Image_Instance *p,
|
|
1189 Lisp_Object printcharfun,
|
|
1190 int escapeflag)
|
|
1191 {
|
|
1192 char buf[100];
|
|
1193
|
|
1194 switch (IMAGE_INSTANCE_TYPE (p))
|
|
1195 {
|
|
1196 case IMAGE_MONO_PIXMAP:
|
|
1197 case IMAGE_COLOR_PIXMAP:
|
|
1198 case IMAGE_POINTER:
|
|
1199 sprintf (buf, " (0x%lx",
|
|
1200 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
|
|
1201 write_c_string (buf, printcharfun);
|
|
1202 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
|
|
1203 {
|
|
1204 sprintf (buf, "/0x%lx",
|
|
1205 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p));
|
|
1206 write_c_string (buf, printcharfun);
|
|
1207 }
|
|
1208 write_c_string (")", printcharfun);
|
|
1209 break;
|
|
1210 default:
|
|
1211 break;
|
|
1212 }
|
|
1213 }
|
|
1214
|
|
1215 static void
|
|
1216 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
|
|
1217 {
|
|
1218 if (!p->data)
|
|
1219 return;
|
|
1220
|
|
1221 if (DEVICE_LIVE_P (XDEVICE (p->device)))
|
|
1222 {
|
|
1223 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
|
269
|
1224 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
|
267
|
1225 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
|
272
|
1226 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
|
|
1227 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
|
|
1228 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
|
|
1229 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
|
|
1230 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
|
|
1231 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
|
267
|
1232 }
|
|
1233
|
|
1234 xfree (p->data);
|
|
1235 p->data = 0;
|
|
1236 }
|
|
1237
|
|
1238 static int
|
|
1239 mswindows_image_instance_equal (struct Lisp_Image_Instance *p1,
|
|
1240 struct Lisp_Image_Instance *p2, int depth)
|
|
1241 {
|
|
1242 switch (IMAGE_INSTANCE_TYPE (p1))
|
|
1243 {
|
|
1244 case IMAGE_MONO_PIXMAP:
|
|
1245 case IMAGE_COLOR_PIXMAP:
|
|
1246 case IMAGE_POINTER:
|
|
1247 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1)
|
|
1248 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
|
|
1249 return 0;
|
|
1250 break;
|
|
1251 default:
|
|
1252 break;
|
|
1253 }
|
|
1254
|
|
1255 return 1;
|
|
1256 }
|
|
1257
|
|
1258 static unsigned long
|
|
1259 mswindows_image_instance_hash (struct Lisp_Image_Instance *p, int depth)
|
|
1260 {
|
|
1261 switch (IMAGE_INSTANCE_TYPE (p))
|
|
1262 {
|
|
1263 case IMAGE_MONO_PIXMAP:
|
|
1264 case IMAGE_COLOR_PIXMAP:
|
|
1265 case IMAGE_POINTER:
|
|
1266 return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
|
|
1267 default:
|
|
1268 return 0;
|
|
1269 }
|
|
1270 }
|
|
1271
|
|
1272 /* Set all the slots in an image instance structure to reasonable
|
|
1273 default values. This is used somewhere within an instantiate
|
|
1274 method. It is assumed that the device slot within the image
|
|
1275 instance is already set -- this is the case when instantiate
|
|
1276 methods are called. */
|
|
1277
|
|
1278 static void
|
|
1279 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
|
|
1280 enum image_instance_type type)
|
|
1281 {
|
|
1282 ii->data = xnew_and_zero (struct mswindows_image_instance_data);
|
|
1283 IMAGE_INSTANCE_TYPE (ii) = type;
|
|
1284 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
|
|
1285 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
|
|
1286 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil;
|
|
1287 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
|
|
1288 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
|
|
1289 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
|
|
1290 }
|
|
1291
|
|
1292
|
|
1293 /************************************************************************/
|
|
1294 /* initialization */
|
|
1295 /************************************************************************/
|
|
1296
|
|
1297 void
|
|
1298 syms_of_glyphs_mswindows (void)
|
|
1299 {
|
284
|
1300 defkeyword (&Q_resource_id, ":resource-id");
|
|
1301 defkeyword (&Q_resource_type, ":resource-type");
|
267
|
1302 }
|
|
1303
|
|
1304 void
|
|
1305 console_type_create_glyphs_mswindows (void)
|
|
1306 {
|
|
1307 /* image methods */
|
|
1308
|
|
1309 CONSOLE_HAS_METHOD (mswindows, print_image_instance);
|
|
1310 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
|
|
1311 CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
|
|
1312 CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
|
278
|
1313 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
|
|
1314 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
|
280
|
1315 #ifdef HAVE_XPM
|
|
1316 CONSOLE_HAS_METHOD (mswindows, xpm_instantiate);
|
|
1317 #endif
|
267
|
1318 }
|
|
1319
|
|
1320 void
|
|
1321 image_instantiator_format_create_glyphs_mswindows (void)
|
|
1322 {
|
|
1323 /* image-instantiator types */
|
|
1324
|
|
1325 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
|
|
1326
|
|
1327 IIFORMAT_HAS_METHOD (bmp, validate);
|
|
1328 IIFORMAT_HAS_METHOD (bmp, normalize);
|
|
1329 IIFORMAT_HAS_METHOD (bmp, possible_dest_types);
|
|
1330 IIFORMAT_HAS_METHOD (bmp, instantiate);
|
|
1331
|
|
1332 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string);
|
|
1333 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string);
|
284
|
1334
|
286
|
1335 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (resource, "resource");
|
284
|
1336
|
286
|
1337 IIFORMAT_HAS_METHOD (resource, validate);
|
|
1338 IIFORMAT_HAS_METHOD (resource, normalize);
|
|
1339 IIFORMAT_HAS_METHOD (resource, possible_dest_types);
|
|
1340 IIFORMAT_HAS_METHOD (resource, instantiate);
|
284
|
1341
|
286
|
1342 IIFORMAT_VALID_KEYWORD (resource, Q_resource_type,
|
|
1343 check_valid_resource_symbol);
|
|
1344 IIFORMAT_VALID_KEYWORD (resource, Q_resource_id, check_valid_resource_id);
|
|
1345 IIFORMAT_VALID_KEYWORD (resource, Q_file, check_valid_string);
|
267
|
1346 }
|
|
1347
|
|
1348 void
|
|
1349 vars_of_glyphs_mswindows (void)
|
|
1350 {
|
|
1351 Fprovide (Qbmp);
|
286
|
1352 Fprovide (Qresource);
|
267
|
1353 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /*
|
|
1354 A list of the directories in which mswindows bitmap files may be found.
|
|
1355 This is used by the `make-image-instance' function.
|
|
1356 */ );
|
|
1357 Vmswindows_bitmap_file_path = Qnil;
|
|
1358 }
|
|
1359
|
|
1360 void
|
|
1361 complex_vars_of_glyphs_mswindows (void)
|
|
1362 {
|
|
1363 }
|