Removed W->A from DEFWND_ImmIsUIMessageW.
[wine] / dlls / gdi / mfdrv / objects.c
1 /*
2  * GDI objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "wownt32.h"
30 #include "mfdrv/metafiledrv.h"
31 #include "gdi.h"
32 #include "gdi_private.h"
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
36
37 /******************************************************************
38  *         MFDRV_AddHandle
39  */
40 UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
41 {
42     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
43     UINT16 index;
44
45     for(index = 0; index < physDev->handles_size; index++)
46         if(physDev->handles[index] == 0) break; 
47     if(index == physDev->handles_size) {
48         physDev->handles_size += HANDLE_LIST_INC;
49         physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
50                                        physDev->handles,
51                                        physDev->handles_size * sizeof(physDev->handles[0]));
52     }
53     physDev->handles[index] = obj;
54
55     physDev->cur_handles++; 
56     if(physDev->cur_handles > physDev->mh->mtNoObjects)
57         physDev->mh->mtNoObjects++;
58
59     return index ; /* index 0 is not reserved for metafiles */
60 }
61
62 /******************************************************************
63  *         MFDRV_FindObject
64  */
65 static INT16 MFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
66 {
67     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
68     INT16 index;
69
70     for(index = 0; index < physDev->handles_size; index++)
71         if(physDev->handles[index] == obj) break;
72
73     if(index == physDev->handles_size) return -1;
74
75     return index ;
76 }
77
78
79 /******************************************************************
80  *         MFDRV_DeleteObject
81  */
82 BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
83 {   
84     METARECORD mr;
85     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
86     INT16 index;
87     BOOL ret = TRUE;
88
89     index = MFDRV_FindObject(dev, obj);
90     if( index < 0 )
91         return 0;
92
93     mr.rdSize = sizeof mr / 2;
94     mr.rdFunction = META_DELETEOBJECT;
95     mr.rdParm[0] = index;
96
97     if(!MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 ))
98         ret = FALSE;
99
100     physDev->handles[index] = 0;
101     physDev->cur_handles--;
102     return ret;
103 }
104
105
106 /***********************************************************************
107  *           MFDRV_SelectObject
108  */
109 static BOOL MFDRV_SelectObject( PHYSDEV dev, INT16 index)
110 {
111     METARECORD mr;
112
113     mr.rdSize = sizeof mr / 2;
114     mr.rdFunction = META_SELECTOBJECT;
115     mr.rdParm[0] = index;
116
117     return MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 );
118 }
119
120
121 /***********************************************************************
122  *           MFDRV_SelectBitmap
123  */
124 HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
125 {
126     return 0;
127 }
128
129
130 /******************************************************************
131  *         MFDRV_CreateBrushIndirect
132  */
133
134 INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
135 {
136     DWORD size;
137     METARECORD *mr;
138     LOGBRUSH logbrush;
139     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
140     BOOL r;
141
142     if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
143
144     switch(logbrush.lbStyle)
145     {
146     case BS_SOLID:
147     case BS_NULL:
148     case BS_HATCHED:
149         {
150             LOGBRUSH16 lb16;
151
152             lb16.lbStyle = logbrush.lbStyle;
153             lb16.lbColor = logbrush.lbColor;
154             lb16.lbHatch = logbrush.lbHatch;
155             size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
156             mr = HeapAlloc( GetProcessHeap(), 0, size );
157             mr->rdSize = size / 2;
158             mr->rdFunction = META_CREATEBRUSHINDIRECT;
159             memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
160             break;
161         }
162     case BS_PATTERN:
163         {
164             BITMAP bm;
165             BYTE *bits;
166             BITMAPINFO *info;
167             DWORD bmSize;
168
169             GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
170             if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
171                 FIXME("Trying to store a colour pattern brush\n");
172                 goto done;
173             }
174
175             bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, 1);
176
177             size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) +
178               sizeof(RGBQUAD) + bmSize;
179
180             mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
181             if(!mr) goto done;
182             mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
183             mr->rdSize = size / 2;
184             mr->rdParm[0] = BS_PATTERN;
185             mr->rdParm[1] = DIB_RGB_COLORS;
186             info = (BITMAPINFO *)(mr->rdParm + 2);
187
188             info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
189             info->bmiHeader.biWidth = bm.bmWidth;
190             info->bmiHeader.biHeight = bm.bmHeight;
191             info->bmiHeader.biPlanes = 1;
192             info->bmiHeader.biBitCount = 1;
193             bits = ((BYTE *)info) + sizeof(BITMAPINFO) + sizeof(RGBQUAD);
194
195             GetDIBits(physDev->hdc, (HANDLE)logbrush.lbHatch, 0, bm.bmHeight,
196                       bits, info, DIB_RGB_COLORS);
197             *(DWORD *)info->bmiColors = 0;
198             *(DWORD *)(info->bmiColors + 1) = 0xffffff;
199             break;
200         }
201
202     case BS_DIBPATTERN:
203         {
204               BITMAPINFO *info;
205               DWORD bmSize, biSize;
206
207               info = GlobalLock16((HGLOBAL16)logbrush.lbHatch);
208               if (info->bmiHeader.biCompression)
209                   bmSize = info->bmiHeader.biSizeImage;
210               else
211                   bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
212                                                 info->bmiHeader.biHeight,
213                                                 info->bmiHeader.biBitCount);
214               biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush.lbColor));
215               size = sizeof(METARECORD) + biSize + bmSize + 2;
216               mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
217               if(!mr) goto done;
218               mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
219               mr->rdSize = size / 2;
220               *(mr->rdParm) = logbrush.lbStyle;
221               *(mr->rdParm + 1) = LOWORD(logbrush.lbColor);
222               memcpy(mr->rdParm + 2, info, biSize + bmSize);
223               break;
224         }
225         default:
226             FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
227             return 0;
228     }
229     r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
230     HeapFree(GetProcessHeap(), 0, mr);
231     if( !r )
232         return -1;
233 done:
234     return MFDRV_AddHandle( dev, hBrush );
235 }
236
237
238 /***********************************************************************
239  *           MFDRV_SelectBrush
240  */
241 HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
242 {
243     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
244     INT16 index;
245
246     index = MFDRV_FindObject(dev, hbrush);
247     if( index < 0 )
248     {
249         index = MFDRV_CreateBrushIndirect( dev, hbrush );
250         if( index < 0 )
251             return 0;
252         GDI_hdc_using_object(hbrush, physDev->hdc);
253     }
254     return MFDRV_SelectObject( dev, index ) ? hbrush : HGDI_ERROR;
255 }
256
257 /******************************************************************
258  *         MFDRV_CreateFontIndirect
259  */
260
261 static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont)
262 {
263     char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
264     METARECORD *mr = (METARECORD *)&buffer;
265
266     mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
267     mr->rdFunction = META_CREATEFONTINDIRECT;
268     memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16));
269     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
270         return 0;
271     return MFDRV_AddHandle( dev, hFont );
272 }
273
274
275 /***********************************************************************
276  *           MFDRV_SelectFont
277  */
278 HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
279 {
280     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
281     LOGFONT16 lf16;
282     INT16 index;
283
284     index = MFDRV_FindObject(dev, hfont);
285     if( index < 0 )
286     {
287         if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 ))
288             return HGDI_ERROR;
289         index = MFDRV_CreateFontIndirect(dev, hfont, &lf16);
290         if( index < 0 )
291             return HGDI_ERROR;
292         GDI_hdc_using_object(hfont, physDev->hdc);
293     }
294     return MFDRV_SelectObject( dev, index ) ? hfont : HGDI_ERROR;
295 }
296
297 /******************************************************************
298  *         MFDRV_CreatePenIndirect
299  */
300 static UINT16 MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
301 {
302     char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
303     METARECORD *mr = (METARECORD *)&buffer;
304
305     mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
306     mr->rdFunction = META_CREATEPENINDIRECT;
307     memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
308     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
309         return 0;
310     return MFDRV_AddHandle( dev, hPen );
311 }
312
313
314 /***********************************************************************
315  *           MFDRV_SelectPen
316  */
317 HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen )
318 {
319     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
320     LOGPEN16 logpen;
321     INT16 index;
322
323     index = MFDRV_FindObject(dev, hpen);
324     if( index < 0 )
325     {
326         if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen ))
327             return 0;
328         index = MFDRV_CreatePenIndirect( dev, hpen, &logpen );
329         if( index < 0 )
330             return 0;
331         GDI_hdc_using_object(hpen, physDev->hdc);
332     }
333     return MFDRV_SelectObject( dev, index ) ? hpen : HGDI_ERROR;
334 }
335
336
337 /******************************************************************
338  *         MFDRV_CreatePalette
339  */
340 static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette)
341 {
342     int index;
343     BOOL ret;
344     METARECORD *mr;
345
346     mr = HeapAlloc( GetProcessHeap(), 0, sizeof(METARECORD) + sizeofPalette - sizeof(WORD) );
347     mr->rdSize = (sizeof(METARECORD) + sizeofPalette - sizeof(WORD)) / sizeof(WORD);
348     mr->rdFunction = META_CREATEPALETTE;
349     memcpy(&(mr->rdParm), logPalette, sizeofPalette);
350     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD))))
351     {
352         HeapFree(GetProcessHeap(), 0, mr);
353         return FALSE;
354     }
355
356     mr->rdSize = sizeof(METARECORD) / sizeof(WORD);
357     mr->rdFunction = META_SELECTPALETTE;
358
359     if ((index = MFDRV_AddHandle( dev, hPalette )) == -1) ret = FALSE;
360     else
361     {
362         *(mr->rdParm) = index;
363         ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD));
364     }
365     HeapFree(GetProcessHeap(), 0, mr);
366     return ret;
367 }
368
369
370 /***********************************************************************
371  *           MFDRV_SelectPalette
372  */
373 HPALETTE MFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPalette, BOOL bForceBackground )
374 {
375 #define PALVERSION 0x0300
376
377     PLOGPALETTE logPalette;
378     WORD        wNumEntries = 0;
379     BOOL        creationSucceed;
380     int         sizeofPalette;
381
382     GetObjectA(hPalette, sizeof(WORD), (LPSTR) &wNumEntries);
383
384     if (wNumEntries == 0) return 0;
385
386     sizeofPalette = sizeof(LOGPALETTE) + ((wNumEntries-1) * sizeof(PALETTEENTRY));
387     logPalette = HeapAlloc( GetProcessHeap(), 0, sizeofPalette );
388
389     if (logPalette == NULL) return 0;
390
391     logPalette->palVersion = PALVERSION;
392     logPalette->palNumEntries = wNumEntries;
393
394     GetPaletteEntries(hPalette, 0, wNumEntries, logPalette->palPalEntry);
395
396     creationSucceed = MFDRV_CreatePalette( dev, hPalette, logPalette, sizeofPalette );
397
398     HeapFree( GetProcessHeap(), 0, logPalette );
399
400     if (creationSucceed)
401         return hPalette;
402
403     return 0;
404 }
405
406 /***********************************************************************
407  *           MFDRV_RealizePalette
408  */
409 UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy)
410 {
411     char buffer[sizeof(METARECORD) - sizeof(WORD)];
412     METARECORD *mr = (METARECORD *)&buffer;
413
414     mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD);
415     mr->rdFunction = META_REALIZEPALETTE;
416
417     if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0;
418
419     /* The return value is suppose to be the number of entries
420        in the logical palette mapped to the system palette or 0
421        if the function failed. Since it's not trivial here to
422        get that kind of information and since it's of little
423        use in the case of metafiles, we'll always return 1. */
424     return 1;
425 }