Release 970305
[wine] / objects / oembitmap.c
1 /*
2  * GDI OEM bitmap objects
3  *
4  * Copyright 1994, 1995 Alexandre Julliard
5  *
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <X11/Xlib.h>
11 #include <X11/Xutil.h>
12 #include <X11/xpm.h>
13 #include "gdi.h"
14 #include "bitmap.h"
15 #include "callback.h"
16 #include "color.h"
17 #include "cursoricon.h"
18 #include "stddebug.h"
19 #include "debug.h"
20 #include "xmalloc.h"
21
22   /* Include OEM pixmaps */
23 #include "bitmaps/obm_cdrom"
24 #include "bitmaps/obm_harddisk"
25 #include "bitmaps/obm_drive"
26 #include "bitmaps/obm_folder2"
27 #include "bitmaps/obm_folder"
28 #include "bitmaps/obm_lfarrowi"
29 #include "bitmaps/obm_rgarrowi"
30 #include "bitmaps/obm_dnarrowi"
31 #include "bitmaps/obm_uparrowi"
32 #include "bitmaps/obm_combo"
33 #include "bitmaps/obm_mnarrow"
34 #include "bitmaps/obm_lfarrowd"
35 #include "bitmaps/obm_rgarrowd"
36 #include "bitmaps/obm_dnarrowd"
37 #include "bitmaps/obm_uparrowd"
38 #include "bitmaps/obm_restored"
39 #include "bitmaps/obm_restore"
40 #include "bitmaps/obm_lfarrow"
41 #include "bitmaps/obm_rgarrow"
42 #include "bitmaps/obm_dnarrow"
43 #include "bitmaps/obm_uparrow"
44 #include "bitmaps/obm_old_restore"
45 #include "bitmaps/obm_old_zoom"
46 #include "bitmaps/obm_old_reduce"
47 #include "bitmaps/obm_btncorners"
48 #include "bitmaps/obm_checkboxes"
49 #include "bitmaps/obm_check"
50 #include "bitmaps/obm_btsize"
51 #include "bitmaps/obm_old_lfarrow"
52 #include "bitmaps/obm_old_rgarrow"
53 #include "bitmaps/obm_old_dnarrow"
54 #include "bitmaps/obm_old_uparrow"
55 #include "bitmaps/obm_size"
56 #include "bitmaps/obm_old_close"
57 #include "bitmaps/obm_trtype"
58
59 #ifndef WIN_95_LOOK
60 #include "bitmaps/obm_zoomd"
61 #include "bitmaps/obm_reduced"
62 #include "bitmaps/obm_zoom"
63 #include "bitmaps/obm_reduce"
64 #include "bitmaps/obm_close"
65 #else
66 #include "bitmaps/obm_zoomd_95"
67 #include "bitmaps/obm_reduced_95"
68 #include "bitmaps/obm_zoom_95"
69 #include "bitmaps/obm_reduce_95"
70 #include "bitmaps/obm_close_95"
71 #include "bitmaps/obm_closed_95"
72 #endif  /* WIN_95_LOOK */
73
74 #define OBM_FIRST  OBM_TRTYPE      /* First OEM bitmap */
75 #define OBM_LAST   OBM_OLD_CLOSE   /* Last OEM bitmap */
76
77 static const struct
78 {
79     char** data;   /* Pointer to bitmap data */
80     BOOL32 color;  /* Is it a color bitmap?  */
81 } OBM_Pixmaps_Data[OBM_LAST-OBM_FIRST+1] = {
82     { obm_trtype, TRUE },       /* OBM_TRTYPE */    
83     { obm_cdrom, TRUE },        /* OBM_CDROM    */
84     { obm_harddisk, TRUE },     /* OBM_HARDDISK */
85     { obm_drive, TRUE },        /* OBM_DRIVE    */
86     { obm_folder2, TRUE },      /* OBM_FOLDER2  */
87     { obm_folder, TRUE },       /* OBM_FOLDER   */
88     { obm_lfarrowi, TRUE },     /* OBM_LFARROWI */
89     { obm_rgarrowi, TRUE },     /* OBM_RGARROWI */
90     { obm_dnarrowi, TRUE },     /* OBM_DNARROWI */
91     { obm_uparrowi, TRUE },     /* OBM_UPARROWI */
92     { obm_combo, FALSE },       /* OBM_COMBO */
93     { obm_mnarrow, FALSE },     /* OBM_MNARROW */
94     { obm_lfarrowd, TRUE },     /* OBM_LFARROWD */
95     { obm_rgarrowd, TRUE },     /* OBM_RGARROWD */
96     { obm_dnarrowd, TRUE },     /* OBM_DNARROWD */
97     { obm_uparrowd, TRUE },     /* OBM_UPARROWD */
98     { obm_restored, TRUE },     /* OBM_RESTORED */
99 #ifdef WIN_95_LOOK
100     { obm_zoomd_95, TRUE },     /* OBM_ZOOMD */
101     { obm_reduced_95, TRUE },   /* OBM_REDUCED */
102 #else
103     { obm_zoomd, TRUE },        /* OBM_ZOOMD */
104     { obm_reduced, TRUE },      /* OBM_REDUCED */
105 #endif
106     { obm_restore, TRUE },      /* OBM_RESTORE */
107 #ifdef WIN_95_LOOK
108     { obm_zoom_95, TRUE },      /* OBM_ZOOM */
109     { obm_reduce_95, TRUE },    /* OBM_REDUCE */
110 #else
111     { obm_zoom, TRUE },         /* OBM_ZOOM */
112     { obm_reduce, TRUE },       /* OBM_REDUCE */
113 #endif
114     { obm_lfarrow, TRUE },      /* OBM_LFARROW */
115     { obm_rgarrow, TRUE },      /* OBM_RGARROW */
116     { obm_dnarrow, TRUE },      /* OBM_DNARROW */
117     { obm_uparrow, TRUE },      /* OBM_UPARROW */
118 #ifdef WIN_95_LOOK
119     { obm_close_95, TRUE },     /* OBM_CLOSE */
120 #else
121     { obm_close, TRUE },        /* OBM_CLOSE */
122 #endif
123     { obm_old_restore, FALSE }, /* OBM_OLD_RESTORE */
124     { obm_old_zoom, FALSE },    /* OBM_OLD_ZOOM */
125     { obm_old_reduce, FALSE },  /* OBM_OLD_REDUCE */
126     { obm_btncorners, FALSE },  /* OBM_BTNCORNERS */
127     { obm_checkboxes, FALSE },  /* OBM_CHECKBOXES */
128     { obm_check, FALSE },       /* OBM_CHECK */
129     { obm_btsize, FALSE },      /* OBM_BTSIZE */
130     { obm_old_lfarrow, FALSE }, /* OBM_OLD_LFARROW */
131     { obm_old_rgarrow, FALSE }, /* OBM_OLD_RGARROW */
132     { obm_old_dnarrow, FALSE }, /* OBM_OLD_DNARROW */
133     { obm_old_uparrow, FALSE }, /* OBM_OLD_UPARROW */
134     { obm_size, FALSE },        /* OBM_SIZE */
135     { obm_old_close, FALSE },   /* OBM_OLD_CLOSE */
136 };
137
138
139   /* Include OEM icons */
140 #include "bitmaps/oic_sample"
141 #include "bitmaps/oic_hand"
142 #include "bitmaps/oic_ques"
143 #include "bitmaps/oic_bang"
144 #include "bitmaps/oic_note"
145 #include "bitmaps/oic_portrait"
146 #include "bitmaps/oic_landscape"
147 #include "bitmaps/oic_wineicon"
148
149 #define OIC_FIRST  OIC_SAMPLE      /* First OEM icon */
150 #define OIC_LAST   OIC_WINEICON   /* Last OEM icon */
151
152 static char ** const OBM_Icons_Data[OIC_LAST-OIC_FIRST+1] =
153 {
154     oic_sample,    /* OIC_SAMPLE */
155     oic_hand,      /* OIC_HAND */
156     oic_ques,      /* OIC_QUES */
157     oic_bang,      /* OIC_BANG */
158     oic_note,      /* OIC_NOTE */
159     oic_portrait,  /* OIC_PORTRAIT */
160     oic_landscape, /* OIC_LANDSCAPE */
161     oic_wineicon   /* OIC_WINEICON */
162 };
163
164
165   /* Include OEM cursors */
166 #include "bitmaps/ocr_normal"
167 #include "bitmaps/ocr_ibeam"
168 #include "bitmaps/ocr_wait"
169 #include "bitmaps/ocr_cross"
170 #include "bitmaps/ocr_up"
171 #include "bitmaps/ocr_size"
172 #include "bitmaps/ocr_icon"
173 #include "bitmaps/ocr_sizenwse"
174 #include "bitmaps/ocr_sizenesw"
175 #include "bitmaps/ocr_sizewe"
176 #include "bitmaps/ocr_sizens"
177 #include "bitmaps/ocr_bummer"
178 #include "bitmaps/ocr_dragobject"
179 /*#include "bitmaps/ocr_sizeall"*/
180 /*#include "bitmaps/ocr_icocur"*/
181
182 /* Cursor are not all contiguous (go figure...) */
183 #define OCR_FIRST0 OCR_BUMMER
184 #define OCR_LAST0  OCR_DRAGOBJECT
185 #define OCR_BASE0       0
186
187 #define OCR_FIRST1 OCR_NORMAL
188 #define OCR_LAST1  OCR_UP
189 #define OCR_BASE1       (OCR_BASE0 + OCR_LAST0 - OCR_FIRST0 + 1)
190
191 #define OCR_FIRST2 OCR_SIZE
192 #define OCR_LAST2  OCR_SIZENS 
193 #define OCR_BASE2       (OCR_BASE1 + OCR_LAST1 - OCR_FIRST1 + 1)
194
195 #define NB_CURSORS (OCR_BASE2 + OCR_LAST2 - OCR_FIRST2 + 1)
196 static char **OBM_Cursors_Data[NB_CURSORS] = 
197 {
198     ocr_bummer,    /* OCR_BUMMER */
199     ocr_dragobject,/* OCR_DRAGOBJECT */ 
200     ocr_normal,    /* OCR_NORMAL */
201     ocr_ibeam,     /* OCR_IBEAM */
202     ocr_wait,      /* OCR_WAIT */
203     ocr_cross,     /* OCR_CROSS */
204     ocr_up,        /* OCR_UP */
205     ocr_size,      /* OCR_SIZE */
206     ocr_icon,      /* OCR_ICON */
207     ocr_sizenwse,  /* OCR_SIZENWSE */
208     ocr_sizenesw,  /* OCR_SIZENESW */
209     ocr_sizewe,    /* OCR_SIZEWE */
210     ocr_sizens     /* OCR_SIZENS */
211 #if 0
212     ocr_sizeall,   /* OCR_SIZEALL */
213     ocr_icocur     /* OCR_ICOCUR */
214 #endif
215 };
216
217 static HGLOBAL16 OBM_Cursors[NB_CURSORS];
218
219
220   /* All the colors used in the xpm files must be included in this   */
221   /* list, to make sure that the loaded bitmaps only use colors from */
222   /* the Windows colormap. Note: the PALETTEINDEX() are not really   */
223   /* palette indexes, but system colors that will be converted to    */
224   /* indexes later on.                                               */
225
226 static const struct
227 {
228     char *   name;
229     COLORREF color;
230 } OBM_SymbolicColors[] =
231 {
232     { "black",            RGB(0,0,0) },
233     { "white",            RGB(255,255,255) },
234     { "red",              RGB(255,0,0) },
235     { "green",            RGB(0,255,0) },
236     { "blue",             RGB(0,0,255) },
237     { "yellow",           RGB(255,255,0) },
238     { "cyan",             RGB(0,255,255) },    
239     { "dkyellow",         RGB(128,128,0) },
240     { "purple",           RGB(128,0,128) },
241     { "ltgray",           RGB(192,192,192) },
242     { "dkgray",           RGB(128,128,128) },
243     { "foldercol",        RGB(0,191,191) },
244     { "button_face",      PALETTEINDEX(COLOR_BTNFACE) },
245     { "button_shadow",    PALETTEINDEX(COLOR_BTNSHADOW) },
246     { "button_highlight", PALETTEINDEX(COLOR_BTNHIGHLIGHT) },
247     { "button_edge",      PALETTEINDEX(COLOR_BTNHIGHLIGHT) },
248     { "button_text",      PALETTEINDEX(COLOR_BTNTEXT) },
249     { "window_frame",     PALETTEINDEX(COLOR_WINDOWFRAME) }
250 };
251
252 #define NB_COLOR_SYMBOLS \
253             (sizeof(OBM_SymbolicColors)/sizeof(OBM_SymbolicColors[0]))
254
255   /* These are the symbolic colors for monochrome bitmaps   */
256   /* This is needed to make sure that black is always 0 and */
257   /* white always 1, as required by Windows.                */
258
259 static XpmColorSymbol OBM_BlackAndWhite[2] =
260 {
261     { "black", NULL, 0 },
262     { "white", NULL, 0xffffffff }
263 };
264
265 static XpmColorSymbol *OBM_Colors = NULL;
266
267
268 /***********************************************************************
269  *           OBM_InitColorSymbols
270  */
271 static BOOL32 OBM_InitColorSymbols()
272 {
273     int i;
274
275     if (OBM_Colors) return TRUE;  /* Already initialised */
276
277     OBM_Colors = (XpmColorSymbol *) malloc( sizeof(XpmColorSymbol) *
278                                             NB_COLOR_SYMBOLS );
279     if (!OBM_Colors) return FALSE;
280     for (i = 0; i < NB_COLOR_SYMBOLS; i++)
281     {
282         OBM_Colors[i].name  = OBM_SymbolicColors[i].name;
283         OBM_Colors[i].value = NULL;
284         if (OBM_SymbolicColors[i].color & 0xff000000)  /* PALETTEINDEX */
285             OBM_Colors[i].pixel = COLOR_ToPhysical( NULL,
286                             GetSysColor32(OBM_SymbolicColors[i].color & 0xff));
287         else  /* RGB*/
288             OBM_Colors[i].pixel = COLOR_ToPhysical( NULL,
289                                                  OBM_SymbolicColors[i].color );
290     }
291     return TRUE;
292 }
293
294
295 /***********************************************************************
296  *           OBM_MakeBitmap
297  *
298  * Allocate a GDI bitmap.
299  */
300 static HBITMAP16 OBM_MakeBitmap( WORD width, WORD height,
301                                  WORD bpp, Pixmap pixmap )
302 {
303     HBITMAP16 hbitmap;
304     BITMAPOBJ * bmpObjPtr;
305
306     if (!pixmap) return 0;
307
308     hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
309     if (!hbitmap) return 0;
310
311     bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
312     bmpObjPtr->size.cx = 0;
313     bmpObjPtr->size.cy = 0;
314     bmpObjPtr->pixmap  = pixmap;
315     bmpObjPtr->bitmap.bmType       = 0;
316     bmpObjPtr->bitmap.bmWidth      = width;
317     bmpObjPtr->bitmap.bmHeight     = height;
318     bmpObjPtr->bitmap.bmWidthBytes = BITMAP_WIDTH_BYTES( width, bpp );
319     bmpObjPtr->bitmap.bmPlanes     = 1;
320     bmpObjPtr->bitmap.bmBitsPixel  = bpp;
321     bmpObjPtr->bitmap.bmBits       = NULL;
322     return hbitmap;
323 }
324
325
326 /***********************************************************************
327  *           OBM_CreateBitmaps
328  *
329  * Create the 2 bitmaps from XPM data.
330  */
331 static BOOL32 OBM_CreateBitmaps( char **data, BOOL32 color, HBITMAP16 *hBitmap,
332                                  HBITMAP16 *hBitmapMask, POINT32 *hotspot )
333 {
334     Pixmap pixmap, pixmask;
335     XpmAttributes *attrs;
336     int err;
337
338     attrs = (XpmAttributes *)xmalloc( XpmAttributesSize() );
339     attrs->valuemask    = XpmColormap | XpmDepth | XpmColorSymbols |XpmHotspot;
340     attrs->colormap     = COLOR_GetColormap();
341     attrs->depth        = color ? screenDepth : 1;
342     attrs->colorsymbols = (attrs->depth > 1) ? OBM_Colors : OBM_BlackAndWhite;
343     attrs->numsymbols   = (attrs->depth > 1) ? NB_COLOR_SYMBOLS : 2;
344         
345     err = XpmCreatePixmapFromData( display, rootWindow, data,
346                                    &pixmap, &pixmask, attrs );
347
348     if (err != XpmSuccess)
349     {
350         free( attrs );
351         return FALSE;
352     }
353     if (hotspot)
354     {
355         hotspot->x = attrs->x_hotspot;
356         hotspot->y = attrs->y_hotspot;
357     }
358     *hBitmap = OBM_MakeBitmap( attrs->width, attrs->height,
359                                attrs->depth, pixmap );
360     if (hBitmapMask) *hBitmapMask = OBM_MakeBitmap(attrs->width, attrs->height,
361                                                    1, pixmask );
362     free( attrs );
363     if (!*hBitmap)
364     {
365         if (pixmap) XFreePixmap( display, pixmap );
366         if (pixmask) XFreePixmap( display, pixmask );
367         if (*hBitmap) GDI_FreeObject( *hBitmap );
368         if (hBitmapMask && *hBitmapMask) GDI_FreeObject( *hBitmapMask );
369         return FALSE;
370     }
371     else return TRUE;
372 }
373
374
375 /***********************************************************************
376  *           OBM_LoadBitmap
377  */
378 HBITMAP16 OBM_LoadBitmap( WORD id )
379 {
380     HBITMAP16 hbitmap;
381
382     if ((id < OBM_FIRST) || (id > OBM_LAST)) return 0;
383     id -= OBM_FIRST;
384
385     if (!OBM_InitColorSymbols()) return 0;
386     
387     if (!CallTo32_LargeStack( (int(*)())OBM_CreateBitmaps, 5,
388                               OBM_Pixmaps_Data[id].data,
389                               OBM_Pixmaps_Data[id].color,
390                               &hbitmap, NULL, NULL ))
391     {
392         fprintf( stderr, "Error creating OEM bitmap %d\n", OBM_FIRST+id );
393         return 0;
394     }
395     return hbitmap;
396 }
397
398
399 /***********************************************************************
400  *           OBM_LoadCursorIcon
401  */
402 HGLOBAL16 OBM_LoadCursorIcon( WORD id, BOOL32 fCursor )
403 {
404     HGLOBAL16 handle;
405     CURSORICONINFO *pInfo;
406     BITMAPOBJ *bmpXor, *bmpAnd;
407     HBITMAP16 hXorBits, hAndBits;
408     POINT32 hotspot;
409     int sizeXor, sizeAnd;
410
411     if (fCursor)
412     {
413         if ((id >= OCR_FIRST1) && (id <= OCR_LAST1))
414              id = OCR_BASE1 + id - OCR_FIRST1;
415         else if ((id >= OCR_FIRST2) && (id <= OCR_LAST2))
416                   id = OCR_BASE2 + id - OCR_FIRST2;
417              else if ((id >= OCR_FIRST0) && (id <= OCR_LAST0))
418                        id = OCR_BASE0 + id - OCR_FIRST0;
419         else return 0;
420         if (OBM_Cursors[id]) return OBM_Cursors[id];
421     }
422     else
423     {
424         if ((id < OIC_FIRST) || (id > OIC_LAST)) return 0;
425         id -= OIC_FIRST;
426     }
427
428     if (!OBM_InitColorSymbols()) return 0;
429     
430     if (!CallTo32_LargeStack( (int(*)())OBM_CreateBitmaps, 5,
431                            fCursor ? OBM_Cursors_Data[id] : OBM_Icons_Data[id],
432                            !fCursor, &hXorBits, &hAndBits, &hotspot ))
433     {
434         fprintf( stderr, "Error creating OEM cursor/icon %d\n", id );
435         return 0;
436     }
437
438     bmpXor = (BITMAPOBJ *) GDI_GetObjPtr( hXorBits, BITMAP_MAGIC );
439     bmpAnd = (BITMAPOBJ *) GDI_GetObjPtr( hAndBits, BITMAP_MAGIC );
440     sizeXor = bmpXor->bitmap.bmHeight * bmpXor->bitmap.bmWidthBytes;
441     sizeAnd = bmpXor->bitmap.bmHeight * BITMAP_WIDTH_BYTES( bmpXor->bitmap.bmWidth, 1 );
442
443     if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
444                                   sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
445     {
446         DeleteObject32( hXorBits );
447         DeleteObject32( hAndBits );
448         return 0;
449     }
450
451     pInfo = (CURSORICONINFO *)GlobalLock16( handle );
452     pInfo->ptHotSpot.x   = hotspot.x;
453     pInfo->ptHotSpot.y   = hotspot.y;
454     pInfo->nWidth        = bmpXor->bitmap.bmWidth;
455     pInfo->nHeight       = bmpXor->bitmap.bmHeight;
456     pInfo->nWidthBytes   = bmpXor->bitmap.bmWidthBytes;
457     pInfo->bPlanes       = bmpXor->bitmap.bmPlanes;
458     pInfo->bBitsPerPixel = bmpXor->bitmap.bmBitsPixel;
459
460     if (hAndBits)
461     {
462           /* Invert the mask */
463
464         XSetFunction( display, BITMAP_monoGC, GXinvert );
465         XFillRectangle( display, bmpAnd->pixmap, BITMAP_monoGC, 0, 0,
466                         bmpAnd->bitmap.bmWidth, bmpAnd->bitmap.bmHeight );
467         XSetFunction( display, BITMAP_monoGC, GXcopy );
468
469           /* Set the masked pixels to black */
470
471         if (bmpXor->bitmap.bmBitsPixel != 1)
472         {
473             XSetForeground( display, BITMAP_colorGC,
474                             COLOR_ToPhysical( NULL, RGB(0,0,0) ));
475             XSetBackground( display, BITMAP_colorGC, 0 );
476             XSetFunction( display, BITMAP_colorGC, GXor );
477             XCopyPlane(display, bmpAnd->pixmap, bmpXor->pixmap, BITMAP_colorGC,
478                        0, 0, bmpXor->bitmap.bmWidth, bmpXor->bitmap.bmHeight,
479                        0, 0, 1 );
480             XSetFunction( display, BITMAP_colorGC, GXcopy );
481         }
482     }
483
484     if (hAndBits) GetBitmapBits32( hAndBits, sizeAnd, (char *)(pInfo + 1) );
485     else memset( (char *)(pInfo + 1), 0xff, sizeAnd );
486     GetBitmapBits32( hXorBits, sizeXor, (char *)(pInfo + 1) + sizeAnd );
487
488     DeleteObject32( hXorBits );
489     DeleteObject32( hAndBits );
490
491     if (fCursor) OBM_Cursors[id] = handle;
492     return handle;
493 }