advapi32/tests: Test SystemFunction036.
[wine] / dlls / gdi.exe16 / gdi.c
1 /*
2  * GDI 16-bit functions
3  *
4  * Copyright 2002 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "wownt32.h"
27 #include "wine/wingdi16.h"
28 #include "wine/list.h"
29 #include "wine/debug.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
32
33 #define HGDIOBJ_32(handle16)    ((HGDIOBJ)(ULONG_PTR)(handle16))
34 #define HGDIOBJ_16(handle32)    ((HGDIOBJ16)(ULONG_PTR)(handle32))
35
36 struct saved_visrgn
37 {
38     struct list entry;
39     HDC         hdc;
40     HRGN        hrgn;
41 };
42
43 static struct list saved_regions = LIST_INIT( saved_regions );
44
45 static HPALETTE16 hPrimaryPalette;
46
47 /*
48  * ############################################################################
49  */
50
51 #include <pshpack1.h>
52 #define GDI_MAX_THUNKS      32
53
54 static struct gdi_thunk
55 {
56     BYTE                        popl_eax;       /* popl  %eax (return address) */
57     BYTE                        pushl_pfn16;    /* pushl pfn16 */
58     DWORD                       pfn16;          /* pfn16 */
59     BYTE                        pushl_eax;      /* pushl %eax */
60     BYTE                        jmp;            /* ljmp GDI_Callback3216 */
61     DWORD                       callback;
62     HDC16                       hdc;
63 } *GDI_Thunks;
64
65 #include <poppack.h>
66
67 /**********************************************************************
68  *           GDI_Callback3216
69  */
70 static BOOL CALLBACK GDI_Callback3216( DWORD pfn16, HDC hdc, INT code )
71 {
72     if (pfn16)
73     {
74         WORD args[2];
75         DWORD ret;
76
77         args[1] = HDC_16(hdc);
78         args[0] = code;
79         WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret );
80         return LOWORD(ret);
81     }
82     return TRUE;
83 }
84
85
86 /******************************************************************
87  *              GDI_AddThunk
88  *
89  */
90 static struct gdi_thunk* GDI_AddThunk(HDC16 dc16, ABORTPROC16 pfn16)
91 {
92     struct gdi_thunk* thunk;
93
94     if (!GDI_Thunks)
95     {
96         GDI_Thunks = VirtualAlloc(NULL, GDI_MAX_THUNKS * sizeof(*GDI_Thunks),
97                                         MEM_COMMIT, PAGE_EXECUTE_READWRITE);
98         if (!GDI_Thunks)
99         {
100             return NULL;
101         }
102         for (thunk = GDI_Thunks; thunk < &GDI_Thunks[GDI_MAX_THUNKS]; thunk++)
103         {
104             thunk->popl_eax     = 0x58;   /* popl  %eax */
105             thunk->pushl_pfn16  = 0x68;   /* pushl pfn16 */
106             thunk->pfn16        = 0;
107             thunk->pushl_eax    = 0x50;   /* pushl %eax */
108             thunk->jmp          = 0xe9;   /* jmp GDI_Callback3216 */
109             thunk->callback     = (char *)GDI_Callback3216 - (char *)(&thunk->callback + 1);
110         }
111     }
112     for (thunk = GDI_Thunks; thunk < &GDI_Thunks[GDI_MAX_THUNKS]; thunk++)
113     {
114         if (thunk->pfn16 == 0)
115         {
116             thunk->pfn16 = (DWORD)pfn16;
117             thunk->hdc   = dc16;
118             return thunk;
119         }
120     }
121     FIXME("Out of mmdrv-thunks. Bump GDI_MAX_THUNKS\n");
122     return NULL;
123 }
124
125 /******************************************************************
126  *              GDI_DeleteThunk
127  */
128 static void    GDI_DeleteThunk(struct gdi_thunk* thunk)
129 {
130     thunk->pfn16 = 0;
131 }
132
133 /******************************************************************
134  *              GDI_FindThunk
135  */
136 static struct gdi_thunk*        GDI_FindThunk(HDC16 hdc)
137 {
138     struct gdi_thunk* thunk;
139
140     if (!GDI_Thunks) return NULL;
141     for (thunk = GDI_Thunks; thunk < &GDI_Thunks[GDI_MAX_THUNKS]; thunk++)
142     {
143         if (thunk->hdc == hdc)  return thunk;
144     }
145     return NULL;
146 }
147
148 /**********************************************************************
149  *           QueryAbort   (GDI.155)
150  *
151  *  Calls the app's AbortProc function if avail.
152  *
153  * RETURNS
154  * TRUE if no AbortProc avail or AbortProc wants to continue printing.
155  * FALSE if AbortProc wants to abort printing.
156  */
157 BOOL16 WINAPI QueryAbort16(HDC16 hdc16, INT16 reserved)
158 {
159     struct gdi_thunk* thunk = GDI_FindThunk(hdc16);
160
161     if (!thunk) {
162         ERR("Invalid hdc 0x%x\n", hdc16);
163         return FALSE;
164     }
165     return GDI_Callback3216( thunk->pfn16, HDC_32(hdc16), 0 );
166 }
167
168
169 /**********************************************************************
170  *           SetAbortProc   (GDI.381)
171  */
172 INT16 WINAPI SetAbortProc16(HDC16 hdc16, ABORTPROC16 abrtprc)
173 {
174     struct gdi_thunk*   thunk;
175
176     thunk = GDI_AddThunk(hdc16, abrtprc);
177     if (!thunk) return FALSE;
178     if (!SetAbortProc(HDC_32( hdc16 ), (ABORTPROC)thunk))
179     {
180         GDI_DeleteThunk(thunk);
181         return FALSE;
182     }
183     return TRUE;
184 }
185
186 /*
187  * ############################################################################
188  */
189
190 struct callback16_info
191 {
192     FARPROC16 proc;
193     LPARAM    param;
194 };
195
196 /* callback for LineDDA16 */
197 static void CALLBACK linedda_callback( INT x, INT y, LPARAM param )
198 {
199     const struct callback16_info *info = (struct callback16_info *)param;
200     WORD args[4];
201
202     args[3] = x;
203     args[2] = y;
204     args[1] = HIWORD(info->param);
205     args[0] = LOWORD(info->param);
206     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, NULL );
207 }
208
209 /* callback for EnumObjects16 */
210 static INT CALLBACK enum_pens_callback( void *ptr, LPARAM param )
211 {
212     const struct callback16_info *info = (struct callback16_info *)param;
213     LOGPEN *pen = ptr;
214     LOGPEN16 pen16;
215     SEGPTR segptr;
216     DWORD ret;
217     WORD args[4];
218
219     pen16.lopnStyle   = pen->lopnStyle;
220     pen16.lopnWidth.x = pen->lopnWidth.x;
221     pen16.lopnWidth.y = pen->lopnWidth.y;
222     pen16.lopnColor   = pen->lopnColor;
223     segptr = MapLS( &pen16 );
224     args[3] = SELECTOROF(segptr);
225     args[2] = OFFSETOF(segptr);
226     args[1] = HIWORD(info->param);
227     args[0] = LOWORD(info->param);
228     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
229     UnMapLS( segptr );
230     return LOWORD(ret);
231 }
232
233 /* callback for EnumObjects16 */
234 static INT CALLBACK enum_brushes_callback( void *ptr, LPARAM param )
235 {
236     const struct callback16_info *info = (struct callback16_info *)param;
237     LOGBRUSH *brush = ptr;
238     LOGBRUSH16 brush16;
239     SEGPTR segptr;
240     DWORD ret;
241     WORD args[4];
242
243     brush16.lbStyle = brush->lbStyle;
244     brush16.lbColor = brush->lbColor;
245     brush16.lbHatch = brush->lbHatch;
246     segptr = MapLS( &brush16 );
247     args[3] = SELECTOROF(segptr);
248     args[2] = OFFSETOF(segptr);
249     args[1] = HIWORD(info->param);
250     args[0] = LOWORD(info->param);
251     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
252     UnMapLS( segptr );
253     return ret;
254 }
255
256 /* convert a LOGFONT16 to a LOGFONTW */
257 static void logfont_16_to_W( const LOGFONT16 *font16, LPLOGFONTW font32 )
258 {
259     font32->lfHeight = font16->lfHeight;
260     font32->lfWidth = font16->lfWidth;
261     font32->lfEscapement = font16->lfEscapement;
262     font32->lfOrientation = font16->lfOrientation;
263     font32->lfWeight = font16->lfWeight;
264     font32->lfItalic = font16->lfItalic;
265     font32->lfUnderline = font16->lfUnderline;
266     font32->lfStrikeOut = font16->lfStrikeOut;
267     font32->lfCharSet = font16->lfCharSet;
268     font32->lfOutPrecision = font16->lfOutPrecision;
269     font32->lfClipPrecision = font16->lfClipPrecision;
270     font32->lfQuality = font16->lfQuality;
271     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
272     MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
273     font32->lfFaceName[LF_FACESIZE-1] = 0;
274 }
275
276 /* convert a LOGFONTW to a LOGFONT16 */
277 static void logfont_W_to_16( const LOGFONTW* font32, LPLOGFONT16 font16 )
278 {
279     font16->lfHeight = font32->lfHeight;
280     font16->lfWidth = font32->lfWidth;
281     font16->lfEscapement = font32->lfEscapement;
282     font16->lfOrientation = font32->lfOrientation;
283     font16->lfWeight = font32->lfWeight;
284     font16->lfItalic = font32->lfItalic;
285     font16->lfUnderline = font32->lfUnderline;
286     font16->lfStrikeOut = font32->lfStrikeOut;
287     font16->lfCharSet = font32->lfCharSet;
288     font16->lfOutPrecision = font32->lfOutPrecision;
289     font16->lfClipPrecision = font32->lfClipPrecision;
290     font16->lfQuality = font32->lfQuality;
291     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
292     WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1, font16->lfFaceName, LF_FACESIZE, NULL, NULL );
293     font16->lfFaceName[LF_FACESIZE-1] = 0;
294 }
295
296 /* convert a ENUMLOGFONTEXW to a ENUMLOGFONTEX16 */
297 static void enumlogfontex_W_to_16( const ENUMLOGFONTEXW *fontW,
298                                    LPENUMLOGFONTEX16 font16 )
299 {
300     logfont_W_to_16( (const LOGFONTW *)fontW, (LPLOGFONT16)font16);
301
302     WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
303                          (LPSTR) font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
304     font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
305     WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
306                          (LPSTR) font16->elfStyle, LF_FACESIZE, NULL, NULL );
307     font16->elfStyle[LF_FACESIZE-1] = '\0';
308     WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
309                          (LPSTR) font16->elfScript, LF_FACESIZE, NULL, NULL );
310     font16->elfScript[LF_FACESIZE-1] = '\0';
311 }
312
313 /* convert a NEWTEXTMETRICEXW to a NEWTEXTMETRICEX16 */
314 static void newtextmetricex_W_to_16( const NEWTEXTMETRICEXW *ptmW,
315                                      LPNEWTEXTMETRICEX16 ptm16 )
316 {
317     ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
318     ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
319     ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
320     ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
321     ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
322     ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
323     ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
324     ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
325     ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
326     ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
327     ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
328     ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
329     ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
330     ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
331     ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : ptmW->ntmTm.tmBreakChar;
332     ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
333     ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
334     ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
335     ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
336     ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
337     ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
338     ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
339     ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
340     ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
341     ptm16->ntmFontSig = ptmW->ntmFontSig;
342 }
343
344 /*
345  * callback for EnumFontFamiliesEx16
346  * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
347  *       We have to use other types because of the FONTENUMPROCW definition.
348  */
349 static INT CALLBACK enum_font_callback( const LOGFONTW *plf,
350                                         const TEXTMETRICW *ptm, DWORD fType,
351                                         LPARAM param )
352 {
353     const struct callback16_info *info = (struct callback16_info *)param;
354     ENUMLOGFONTEX16 elfe16;
355     NEWTEXTMETRICEX16 ntm16;
356     SEGPTR segelfe16;
357     SEGPTR segntm16;
358     WORD args[7];
359     DWORD ret;
360
361     enumlogfontex_W_to_16((const ENUMLOGFONTEXW *)plf, &elfe16);
362     newtextmetricex_W_to_16((const NEWTEXTMETRICEXW *)ptm, &ntm16);
363     segelfe16 = MapLS( &elfe16 );
364     segntm16 = MapLS( &ntm16 );
365     args[6] = SELECTOROF(segelfe16);
366     args[5] = OFFSETOF(segelfe16);
367     args[4] = SELECTOROF(segntm16);
368     args[3] = OFFSETOF(segntm16);
369     args[2] = fType;
370     args[1] = HIWORD(info->param);
371     args[0] = LOWORD(info->param);
372
373     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
374     UnMapLS( segelfe16 );
375     UnMapLS( segntm16 );
376     return LOWORD(ret);
377 }
378
379 struct dib_segptr_bits
380 {
381     struct list entry;
382     HBITMAP16 bmp;
383     WORD      sel;
384     WORD      count;
385 };
386
387 static struct list dib_segptr_list = LIST_INIT( dib_segptr_list );
388
389 static SEGPTR alloc_segptr_bits( HBITMAP bmp, void *bits32 )
390 {
391     DIBSECTION dib;
392     unsigned int i, size;
393     struct dib_segptr_bits *bits;
394
395     if (!(bits = HeapAlloc( GetProcessHeap(), 0, sizeof(*bits) ))) return 0;
396
397     GetObjectW( bmp, sizeof(dib), &dib );
398     size = dib.dsBm.bmHeight * dib.dsBm.bmWidthBytes;
399
400     /* calculate number of sel's needed for size with 64K steps */
401     bits->bmp   = HBITMAP_16( bmp );
402     bits->count = (size + 0xffff) / 0x10000;
403     bits->sel   = AllocSelectorArray16( bits->count );
404
405     for (i = 0; i < bits->count; i++)
406     {
407         SetSelectorBase(bits->sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
408         SetSelectorLimit16(bits->sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
409         size -= 0x10000;
410     }
411     list_add_head( &dib_segptr_list, &bits->entry );
412     return MAKESEGPTR( bits->sel, 0 );
413 }
414
415 static void free_segptr_bits( HBITMAP16 bmp )
416 {
417     unsigned int i;
418     struct dib_segptr_bits *bits;
419
420     LIST_FOR_EACH_ENTRY( bits, &dib_segptr_list, struct dib_segptr_bits, entry )
421     {
422         if (bits->bmp != bmp) continue;
423         for (i = 0; i < bits->count; i++) FreeSelector16( bits->sel + (i << __AHSHIFT) );
424
425         list_remove( &bits->entry );
426         HeapFree( GetProcessHeap(), 0, bits );
427         return;
428     }
429 }
430
431
432 /**********************************************************************
433  *              DllMain
434  */
435 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
436 {
437     if (reason == DLL_PROCESS_ATTACH) LoadLibrary16( "gdi.exe" );
438     return TRUE;
439 }
440
441
442 /***********************************************************************
443  *           SetBkColor    (GDI.1)
444  */
445 COLORREF WINAPI SetBkColor16( HDC16 hdc, COLORREF color )
446 {
447     return SetBkColor( HDC_32(hdc), color );
448 }
449
450
451 /***********************************************************************
452  *              SetBkMode (GDI.2)
453  */
454 INT16 WINAPI SetBkMode16( HDC16 hdc, INT16 mode )
455 {
456     return SetBkMode( HDC_32(hdc), mode );
457 }
458
459
460 /***********************************************************************
461  *           SetMapMode    (GDI.3)
462  */
463 INT16 WINAPI SetMapMode16( HDC16 hdc, INT16 mode )
464 {
465     return SetMapMode( HDC_32(hdc), mode );
466 }
467
468
469 /***********************************************************************
470  *              SetROP2 (GDI.4)
471  */
472 INT16 WINAPI SetROP216( HDC16 hdc, INT16 mode )
473 {
474     return SetROP2( HDC_32(hdc), mode );
475 }
476
477
478 /***********************************************************************
479  *              SetRelAbs (GDI.5)
480  */
481 INT16 WINAPI SetRelAbs16( HDC16 hdc, INT16 mode )
482 {
483     return SetRelAbs( HDC_32(hdc), mode );
484 }
485
486
487 /***********************************************************************
488  *              SetPolyFillMode (GDI.6)
489  */
490 INT16 WINAPI SetPolyFillMode16( HDC16 hdc, INT16 mode )
491 {
492     return SetPolyFillMode( HDC_32(hdc), mode );
493 }
494
495
496 /***********************************************************************
497  *              SetStretchBltMode (GDI.7)
498  */
499 INT16 WINAPI SetStretchBltMode16( HDC16 hdc, INT16 mode )
500 {
501     return SetStretchBltMode( HDC_32(hdc), mode );
502 }
503
504
505 /***********************************************************************
506  *           SetTextCharacterExtra    (GDI.8)
507  */
508 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
509 {
510     return SetTextCharacterExtra( HDC_32(hdc), extra );
511 }
512
513
514 /***********************************************************************
515  *           SetTextColor    (GDI.9)
516  */
517 COLORREF WINAPI SetTextColor16( HDC16 hdc, COLORREF color )
518 {
519     return SetTextColor( HDC_32(hdc), color );
520 }
521
522
523 /***********************************************************************
524  *           SetTextJustification    (GDI.10)
525  */
526 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
527 {
528     return SetTextJustification( HDC_32(hdc), extra, breaks );
529 }
530
531
532 /***********************************************************************
533  *           SetWindowOrg    (GDI.11)
534  */
535 DWORD WINAPI SetWindowOrg16( HDC16 hdc, INT16 x, INT16 y )
536 {
537     POINT pt;
538     if (!SetWindowOrgEx( HDC_32(hdc), x, y, &pt )) return 0;
539     return MAKELONG( pt.x, pt.y );
540 }
541
542
543 /***********************************************************************
544  *           SetWindowExt    (GDI.12)
545  */
546 DWORD WINAPI SetWindowExt16( HDC16 hdc, INT16 x, INT16 y )
547 {
548     SIZE size;
549     if (!SetWindowExtEx( HDC_32(hdc), x, y, &size )) return 0;
550     return MAKELONG( size.cx, size.cy );
551 }
552
553
554 /***********************************************************************
555  *           SetViewportOrg    (GDI.13)
556  */
557 DWORD WINAPI SetViewportOrg16( HDC16 hdc, INT16 x, INT16 y )
558 {
559     POINT pt;
560     if (!SetViewportOrgEx( HDC_32(hdc), x, y, &pt )) return 0;
561     return MAKELONG( pt.x, pt.y );
562 }
563
564
565 /***********************************************************************
566  *           SetViewportExt    (GDI.14)
567  */
568 DWORD WINAPI SetViewportExt16( HDC16 hdc, INT16 x, INT16 y )
569 {
570     SIZE size;
571     if (!SetViewportExtEx( HDC_32(hdc), x, y, &size )) return 0;
572     return MAKELONG( size.cx, size.cy );
573 }
574
575
576 /***********************************************************************
577  *           OffsetWindowOrg    (GDI.15)
578  */
579 DWORD WINAPI OffsetWindowOrg16( HDC16 hdc, INT16 x, INT16 y )
580 {
581     POINT pt;
582     if (!OffsetWindowOrgEx( HDC_32(hdc), x, y, &pt )) return 0;
583     return MAKELONG( pt.x, pt.y );
584 }
585
586
587 /***********************************************************************
588  *           ScaleWindowExt    (GDI.16)
589  */
590 DWORD WINAPI ScaleWindowExt16( HDC16 hdc, INT16 xNum, INT16 xDenom,
591                              INT16 yNum, INT16 yDenom )
592 {
593     SIZE size;
594     if (!ScaleWindowExtEx( HDC_32(hdc), xNum, xDenom, yNum, yDenom, &size ))
595         return FALSE;
596     return MAKELONG( size.cx,  size.cy );
597 }
598
599
600 /***********************************************************************
601  *           OffsetViewportOrg    (GDI.17)
602  */
603 DWORD WINAPI OffsetViewportOrg16( HDC16 hdc, INT16 x, INT16 y )
604 {
605     POINT pt;
606     if (!OffsetViewportOrgEx( HDC_32(hdc), x, y, &pt )) return 0;
607     return MAKELONG( pt.x, pt.y );
608 }
609
610
611 /***********************************************************************
612  *           ScaleViewportExt    (GDI.18)
613  */
614 DWORD WINAPI ScaleViewportExt16( HDC16 hdc, INT16 xNum, INT16 xDenom,
615                                INT16 yNum, INT16 yDenom )
616 {
617     SIZE size;
618     if (!ScaleViewportExtEx( HDC_32(hdc), xNum, xDenom, yNum, yDenom, &size ))
619         return FALSE;
620     return MAKELONG( size.cx,  size.cy );
621 }
622
623
624 /***********************************************************************
625  *           LineTo    (GDI.19)
626  */
627 BOOL16 WINAPI LineTo16( HDC16 hdc, INT16 x, INT16 y )
628 {
629     return LineTo( HDC_32(hdc), x, y );
630 }
631
632
633 /***********************************************************************
634  *           MoveTo    (GDI.20)
635  */
636 DWORD WINAPI MoveTo16( HDC16 hdc, INT16 x, INT16 y )
637 {
638     POINT pt;
639
640     if (!MoveToEx( HDC_32(hdc), x, y, &pt )) return 0;
641     return MAKELONG(pt.x,pt.y);
642 }
643
644
645 /***********************************************************************
646  *           ExcludeClipRect    (GDI.21)
647  */
648 INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top,
649                                 INT16 right, INT16 bottom )
650 {
651     return ExcludeClipRect( HDC_32(hdc), left, top, right, bottom );
652 }
653
654
655 /***********************************************************************
656  *           IntersectClipRect    (GDI.22)
657  */
658 INT16 WINAPI IntersectClipRect16( HDC16 hdc, INT16 left, INT16 top,
659                                   INT16 right, INT16 bottom )
660 {
661     return IntersectClipRect( HDC_32(hdc), left, top, right, bottom );
662 }
663
664
665 /***********************************************************************
666  *           Arc    (GDI.23)
667  */
668 BOOL16 WINAPI Arc16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
669                      INT16 bottom, INT16 xstart, INT16 ystart,
670                      INT16 xend, INT16 yend )
671 {
672     return Arc( HDC_32(hdc), left, top, right, bottom, xstart, ystart, xend, yend );
673 }
674
675
676 /***********************************************************************
677  *           Ellipse    (GDI.24)
678  */
679 BOOL16 WINAPI Ellipse16( HDC16 hdc, INT16 left, INT16 top,
680                          INT16 right, INT16 bottom )
681 {
682     return Ellipse( HDC_32(hdc), left, top, right, bottom );
683 }
684
685
686 /**********************************************************************
687  *          FloodFill   (GDI.25)
688  */
689 BOOL16 WINAPI FloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
690 {
691     return ExtFloodFill( HDC_32(hdc), x, y, color, FLOODFILLBORDER );
692 }
693
694
695 /***********************************************************************
696  *           Pie    (GDI.26)
697  */
698 BOOL16 WINAPI Pie16( HDC16 hdc, INT16 left, INT16 top,
699                      INT16 right, INT16 bottom, INT16 xstart, INT16 ystart,
700                      INT16 xend, INT16 yend )
701 {
702     return Pie( HDC_32(hdc), left, top, right, bottom, xstart, ystart, xend, yend );
703 }
704
705
706 /***********************************************************************
707  *           Rectangle    (GDI.27)
708  */
709 BOOL16 WINAPI Rectangle16( HDC16 hdc, INT16 left, INT16 top,
710                            INT16 right, INT16 bottom )
711 {
712     return Rectangle( HDC_32(hdc), left, top, right, bottom );
713 }
714
715
716 /***********************************************************************
717  *           RoundRect    (GDI.28)
718  */
719 BOOL16 WINAPI RoundRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
720                            INT16 bottom, INT16 ell_width, INT16 ell_height )
721 {
722     return RoundRect( HDC_32(hdc), left, top, right, bottom, ell_width, ell_height );
723 }
724
725
726 /***********************************************************************
727  *           PatBlt    (GDI.29)
728  */
729 BOOL16 WINAPI PatBlt16( HDC16 hdc, INT16 left, INT16 top,
730                         INT16 width, INT16 height, DWORD rop)
731 {
732     return PatBlt( HDC_32(hdc), left, top, width, height, rop );
733 }
734
735
736 /***********************************************************************
737  *           SaveDC    (GDI.30)
738  */
739 INT16 WINAPI SaveDC16( HDC16 hdc )
740 {
741     return SaveDC( HDC_32(hdc) );
742 }
743
744
745 /***********************************************************************
746  *           SetPixel    (GDI.31)
747  */
748 COLORREF WINAPI SetPixel16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
749 {
750     return SetPixel( HDC_32(hdc), x, y, color );
751 }
752
753
754 /***********************************************************************
755  *           OffsetClipRgn    (GDI.32)
756  */
757 INT16 WINAPI OffsetClipRgn16( HDC16 hdc, INT16 x, INT16 y )
758 {
759     return OffsetClipRgn( HDC_32(hdc), x, y );
760 }
761
762
763 /***********************************************************************
764  *           TextOut    (GDI.33)
765  */
766 BOOL16 WINAPI TextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR str, INT16 count )
767 {
768     return TextOutA( HDC_32(hdc), x, y, str, count );
769 }
770
771
772 /***********************************************************************
773  *           BitBlt    (GDI.34)
774  */
775 BOOL16 WINAPI BitBlt16( HDC16 hdcDst, INT16 xDst, INT16 yDst, INT16 width,
776                         INT16 height, HDC16 hdcSrc, INT16 xSrc, INT16 ySrc,
777                         DWORD rop )
778 {
779     return BitBlt( HDC_32(hdcDst), xDst, yDst, width, height, HDC_32(hdcSrc), xSrc, ySrc, rop );
780 }
781
782
783 /***********************************************************************
784  *           StretchBlt    (GDI.35)
785  */
786 BOOL16 WINAPI StretchBlt16( HDC16 hdcDst, INT16 xDst, INT16 yDst,
787                             INT16 widthDst, INT16 heightDst,
788                             HDC16 hdcSrc, INT16 xSrc, INT16 ySrc,
789                             INT16 widthSrc, INT16 heightSrc, DWORD rop )
790 {
791     return StretchBlt( HDC_32(hdcDst), xDst, yDst, widthDst, heightDst,
792                        HDC_32(hdcSrc), xSrc, ySrc, widthSrc, heightSrc, rop );
793 }
794
795
796 /**********************************************************************
797  *          Polygon  (GDI.36)
798  */
799 BOOL16 WINAPI Polygon16( HDC16 hdc, const POINT16* pt, INT16 count )
800 {
801     register int i;
802     BOOL ret;
803     LPPOINT pt32 = HeapAlloc( GetProcessHeap(), 0, count*sizeof(POINT) );
804
805     if (!pt32) return FALSE;
806     for (i=count;i--;)
807     {
808         pt32[i].x = pt[i].x;
809         pt32[i].y = pt[i].y;
810     }
811     ret = Polygon(HDC_32(hdc),pt32,count);
812     HeapFree( GetProcessHeap(), 0, pt32 );
813     return ret;
814 }
815
816
817 /**********************************************************************
818  *          Polyline  (GDI.37)
819  */
820 BOOL16 WINAPI Polyline16( HDC16 hdc, const POINT16* pt, INT16 count )
821 {
822     register int i;
823     BOOL16 ret;
824     LPPOINT pt32 = HeapAlloc( GetProcessHeap(), 0, count*sizeof(POINT) );
825
826     if (!pt32) return FALSE;
827     for (i=count;i--;)
828     {
829         pt32[i].x = pt[i].x;
830         pt32[i].y = pt[i].y;
831     }
832     ret = Polyline(HDC_32(hdc),pt32,count);
833     HeapFree( GetProcessHeap(), 0, pt32 );
834     return ret;
835 }
836
837
838 /***********************************************************************
839  *            Escape   (GDI.38)
840  */
841 INT16 WINAPI Escape16( HDC16 hdc, INT16 escape, INT16 in_count, SEGPTR in_data, LPVOID out_data )
842 {
843     INT ret;
844
845     switch(escape)
846     {
847     /* Escape(hdc,CLIP_TO_PATH,LPINT16,NULL) */
848     /* Escape(hdc,DRAFTMODE,LPINT16,NULL) */
849     /* Escape(hdc,ENUMPAPERBINS,LPINT16,LPSTR); */
850     /* Escape(hdc,EPSPRINTING,LPINT16,NULL) */
851     /* Escape(hdc,EXT_DEVICE_CAPS,LPINT16,LPDWORD) */
852     /* Escape(hdc,GETCOLORTABLE,LPINT16,LPDWORD) */
853     /* Escape(hdc,MOUSETRAILS,LPINT16,NULL) */
854     /* Escape(hdc,POSTSCRIPT_IGNORE,LPINT16,NULL) */
855     /* Escape(hdc,QUERYESCSUPPORT,LPINT16,NULL) */
856     /* Escape(hdc,SET_ARC_DIRECTION,LPINT16,NULL) */
857     /* Escape(hdc,SET_POLY_MODE,LPINT16,NULL) */
858     /* Escape(hdc,SET_SCREEN_ANGLE,LPINT16,NULL) */
859     /* Escape(hdc,SET_SPREAD,LPINT16,NULL) */
860     case CLIP_TO_PATH:
861     case DRAFTMODE:
862     case ENUMPAPERBINS:
863     case EPSPRINTING:
864     case EXT_DEVICE_CAPS:
865     case GETCOLORTABLE:
866     case MOUSETRAILS:
867     case POSTSCRIPT_IGNORE:
868     case QUERYESCSUPPORT:
869     case SET_ARC_DIRECTION:
870     case SET_POLY_MODE:
871     case SET_SCREEN_ANGLE:
872     case SET_SPREAD:
873     {
874         INT16 *ptr = MapSL(in_data);
875         INT data = *ptr;
876         return Escape( HDC_32(hdc), escape, sizeof(data), (LPCSTR)&data, out_data );
877     }
878
879     /* Escape(hdc,ENABLEDUPLEX,LPUINT16,NULL) */
880     case ENABLEDUPLEX:
881     {
882         UINT16 *ptr = MapSL(in_data);
883         UINT data = *ptr;
884         return Escape( HDC_32(hdc), escape, sizeof(data), (LPCSTR)&data, NULL );
885     }
886
887     /* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT16) */
888     /* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT16) */
889     /* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT16) */
890     case GETPHYSPAGESIZE:
891     case GETPRINTINGOFFSET:
892     case GETSCALINGFACTOR:
893     {
894         POINT16 *ptr = out_data;
895         POINT pt32;
896         ret = Escape( HDC_32(hdc), escape, 0, NULL, &pt32 );
897         ptr->x = pt32.x;
898         ptr->y = pt32.y;
899         return ret;
900     }
901
902     /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */
903     /* Escape(hdc,ENABLERELATIVEWIDTHS,LPINT16,LPINT16); */
904     /* Escape(hdc,SETCOPYCOUNT,LPINT16,LPINT16) */
905     /* Escape(hdc,SETKERNTRACK,LPINT16,LPINT16) */
906     /* Escape(hdc,SETLINECAP,LPINT16,LPINT16) */
907     /* Escape(hdc,SETLINEJOIN,LPINT16,LPINT16) */
908     /* Escape(hdc,SETMITERLIMIT,LPINT16,LPINT16) */
909     case ENABLEPAIRKERNING:
910     case ENABLERELATIVEWIDTHS:
911     case SETCOPYCOUNT:
912     case SETKERNTRACK:
913     case SETLINECAP:
914     case SETLINEJOIN:
915     case SETMITERLIMIT:
916     {
917         INT16 *new = MapSL(in_data);
918         INT16 *old = out_data;
919         INT out, in = *new;
920         ret = Escape( HDC_32(hdc), escape, sizeof(in), (LPCSTR)&in, &out );
921         *old = out;
922         return ret;
923     }
924
925     /* Escape(hdc,SETABORTPROC,ABORTPROC,NULL); */
926     case SETABORTPROC:
927         return SetAbortProc16( hdc, (ABORTPROC16)in_data );
928
929     /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFO16);
930      * lpvOutData is actually a pointer to the DocInfo structure and used as
931      * a second input parameter */
932     case STARTDOC:
933         if (out_data)
934         {
935             ret = StartDoc16( hdc, out_data );
936             if (ret > 0) ret = StartPage( HDC_32(hdc) );
937             return ret;
938         }
939         return Escape( HDC_32(hdc), escape, in_count, MapSL(in_data), NULL );
940
941     /* Escape(hdc,SET_BOUNDS,LPRECT16,NULL); */
942     /* Escape(hdc,SET_CLIP_BOX,LPRECT16,NULL); */
943     case SET_BOUNDS:
944     case SET_CLIP_BOX:
945     {
946         RECT16 *rc16 = MapSL(in_data);
947         RECT rc;
948         rc.left   = rc16->left;
949         rc.top    = rc16->top;
950         rc.right  = rc16->right;
951         rc.bottom = rc16->bottom;
952         return Escape( HDC_32(hdc), escape, sizeof(rc), (LPCSTR)&rc, NULL );
953     }
954
955     /* Escape(hdc,NEXTBAND,NULL,LPRECT16); */
956     case NEXTBAND:
957     {
958         RECT rc;
959         RECT16 *rc16 = out_data;
960         ret = Escape( HDC_32(hdc), escape, 0, NULL, &rc );
961         rc16->left   = rc.left;
962         rc16->top    = rc.top;
963         rc16->right  = rc.right;
964         rc16->bottom = rc.bottom;
965         return ret;
966     }
967     /* Escape(hdc,DRAWPATTERNRECT,PRECT_STRUCT*,NULL); */
968     case DRAWPATTERNRECT:
969     {
970         DRAWPATRECT pr;
971         DRAWPATRECT16 *pr16 = MapSL(in_data);
972
973         pr.ptPosition.x = pr16->ptPosition.x;
974         pr.ptPosition.y = pr16->ptPosition.y;
975         pr.ptSize.x     = pr16->ptSize.x;
976         pr.ptSize.y     = pr16->ptSize.y;
977         pr.wStyle       = pr16->wStyle;
978         pr.wPattern     = pr16->wPattern;
979         return Escape( HDC_32(hdc), escape, sizeof(pr), (LPCSTR)&pr, NULL );
980     }
981
982     /* Escape(hdc,ABORTDOC,NULL,NULL); */
983     /* Escape(hdc,BANDINFO,BANDINFOSTRUCT*,BANDINFOSTRUCT*); */
984     /* Escape(hdc,BEGIN_PATH,NULL,NULL); */
985     /* Escape(hdc,ENDDOC,NULL,NULL); */
986     /* Escape(hdc,END_PATH,PATHINFO,NULL); */
987     /* Escape(hdc,EXTTEXTOUT,EXTTEXT_STRUCT*,NULL); */
988     /* Escape(hdc,FLUSHOUTPUT,NULL,NULL); */
989     /* Escape(hdc,GETFACENAME,NULL,LPSTR); */
990     /* Escape(hdc,GETPAIRKERNTABLE,NULL,KERNPAIR*); */
991     /* Escape(hdc,GETSETPAPERBINS,BinInfo*,BinInfo*); */
992     /* Escape(hdc,GETSETPRINTORIENT,ORIENT*,NULL); */
993     /* Escape(hdc,GETSETSCREENPARAMS,SCREENPARAMS*,SCREENPARAMS*); */
994     /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
995     /* Escape(hdc,GETTRACKKERNTABLE,NULL,KERNTRACK*); */
996     /* Escape(hdc,MFCOMMENT,LPSTR,NULL); */
997     /* Escape(hdc,NEWFRAME,NULL,NULL); */
998     /* Escape(hdc,PASSTHROUGH,LPSTR,NULL); */
999     /* Escape(hdc,RESTORE_CTM,NULL,NULL); */
1000     /* Escape(hdc,SAVE_CTM,NULL,NULL); */
1001     /* Escape(hdc,SETALLJUSTVALUES,EXTTEXTDATA*,NULL); */
1002     /* Escape(hdc,SETCOLORTABLE,COLORTABLE_STRUCT*,LPDWORD); */
1003     /* Escape(hdc,SET_BACKGROUND_COLOR,LPDWORD,LPDWORD); */
1004     /* Escape(hdc,TRANSFORM_CTM,LPSTR,NULL); */
1005     case ABORTDOC:
1006     case BANDINFO:
1007     case BEGIN_PATH:
1008     case ENDDOC:
1009     case END_PATH:
1010     case EXTTEXTOUT:
1011     case FLUSHOUTPUT:
1012     case GETFACENAME:
1013     case GETPAIRKERNTABLE:
1014     case GETSETPAPERBINS:
1015     case GETSETPRINTORIENT:
1016     case GETSETSCREENPARAMS:
1017     case GETTECHNOLOGY:
1018     case GETTRACKKERNTABLE:
1019     case MFCOMMENT:
1020     case NEWFRAME:
1021     case PASSTHROUGH:
1022     case RESTORE_CTM:
1023     case SAVE_CTM:
1024     case SETALLJUSTVALUES:
1025     case SETCOLORTABLE:
1026     case SET_BACKGROUND_COLOR:
1027     case TRANSFORM_CTM:
1028         /* pass it unmodified to the 32-bit function */
1029         return Escape( HDC_32(hdc), escape, in_count, MapSL(in_data), out_data );
1030
1031     /* Escape(hdc,ENUMPAPERMETRICS,LPINT16,LPRECT16); */
1032     /* Escape(hdc,GETEXTENDEDTEXTMETRICS,LPUINT16,EXTTEXTMETRIC*); */
1033     /* Escape(hdc,GETEXTENTTABLE,LPSTR,LPINT16); */
1034     /* Escape(hdc,GETSETPAPERMETRICS,LPRECT16,LPRECT16); */
1035     /* Escape(hdc,GETVECTORBRUSHSIZE,LPLOGBRUSH16,LPPOINT16); */
1036     /* Escape(hdc,GETVECTORPENSIZE,LPLOGPEN16,LPPOINT16); */
1037     case ENUMPAPERMETRICS:
1038     case GETEXTENDEDTEXTMETRICS:
1039     case GETEXTENTTABLE:
1040     case GETSETPAPERMETRICS:
1041     case GETVECTORBRUSHSIZE:
1042     case GETVECTORPENSIZE:
1043     default:
1044         FIXME("unknown/unsupported 16-bit escape %x (%d,%p,%p\n",
1045               escape, in_count, MapSL(in_data), out_data );
1046         return Escape( HDC_32(hdc), escape, in_count, MapSL(in_data), out_data );
1047     }
1048 }
1049
1050
1051 /***********************************************************************
1052  *           RestoreDC    (GDI.39)
1053  */
1054 BOOL16 WINAPI RestoreDC16( HDC16 hdc, INT16 level )
1055 {
1056     return RestoreDC( HDC_32(hdc), level );
1057 }
1058
1059
1060 /***********************************************************************
1061  *           FillRgn    (GDI.40)
1062  */
1063 BOOL16 WINAPI FillRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush )
1064 {
1065     return FillRgn( HDC_32(hdc), HRGN_32(hrgn), HBRUSH_32(hbrush) );
1066 }
1067
1068
1069 /***********************************************************************
1070  *           FrameRgn     (GDI.41)
1071  */
1072 BOOL16 WINAPI FrameRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush,
1073                           INT16 nWidth, INT16 nHeight )
1074 {
1075     return FrameRgn( HDC_32(hdc), HRGN_32(hrgn), HBRUSH_32(hbrush), nWidth, nHeight );
1076 }
1077
1078
1079 /***********************************************************************
1080  *           InvertRgn    (GDI.42)
1081  */
1082 BOOL16 WINAPI InvertRgn16( HDC16 hdc, HRGN16 hrgn )
1083 {
1084     return InvertRgn( HDC_32(hdc), HRGN_32(hrgn) );
1085 }
1086
1087
1088 /***********************************************************************
1089  *           PaintRgn    (GDI.43)
1090  */
1091 BOOL16 WINAPI PaintRgn16( HDC16 hdc, HRGN16 hrgn )
1092 {
1093     return PaintRgn( HDC_32(hdc), HRGN_32(hrgn) );
1094 }
1095
1096
1097 /***********************************************************************
1098  *           SelectClipRgn    (GDI.44)
1099  */
1100 INT16 WINAPI SelectClipRgn16( HDC16 hdc, HRGN16 hrgn )
1101 {
1102     return SelectClipRgn( HDC_32(hdc), HRGN_32(hrgn) );
1103 }
1104
1105
1106 /***********************************************************************
1107  *           SelectObject    (GDI.45)
1108  */
1109 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
1110 {
1111     return HGDIOBJ_16( SelectObject( HDC_32(hdc), HGDIOBJ_32(handle) ) );
1112 }
1113
1114
1115 /***********************************************************************
1116  *           CombineRgn    (GDI.47)
1117  */
1118 INT16 WINAPI CombineRgn16(HRGN16 hDest, HRGN16 hSrc1, HRGN16 hSrc2, INT16 mode)
1119 {
1120     return CombineRgn( HRGN_32(hDest), HRGN_32(hSrc1), HRGN_32(hSrc2), mode );
1121 }
1122
1123
1124 /***********************************************************************
1125  *           CreateBitmap    (GDI.48)
1126  */
1127 HBITMAP16 WINAPI CreateBitmap16( INT16 width, INT16 height, UINT16 planes,
1128                                  UINT16 bpp, LPCVOID bits )
1129 {
1130     return HBITMAP_16( CreateBitmap( width, height, planes & 0xff, bpp & 0xff, bits ) );
1131 }
1132
1133
1134 /***********************************************************************
1135  *           CreateBitmapIndirect    (GDI.49)
1136  */
1137 HBITMAP16 WINAPI CreateBitmapIndirect16( const BITMAP16 * bmp )
1138 {
1139     return CreateBitmap16( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
1140                            bmp->bmBitsPixel, MapSL( bmp->bmBits ) );
1141 }
1142
1143
1144 /***********************************************************************
1145  *           CreateBrushIndirect    (GDI.50)
1146  */
1147 HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
1148 {
1149     LOGBRUSH brush32;
1150
1151     if (brush->lbStyle == BS_DIBPATTERN || brush->lbStyle == BS_DIBPATTERN8X8)
1152         return CreateDIBPatternBrush16( brush->lbHatch, brush->lbColor );
1153
1154     brush32.lbStyle = brush->lbStyle;
1155     brush32.lbColor = brush->lbColor;
1156     brush32.lbHatch = brush->lbHatch;
1157     return HBRUSH_16( CreateBrushIndirect(&brush32) );
1158 }
1159
1160
1161 /***********************************************************************
1162  *           CreateCompatibleBitmap    (GDI.51)
1163  */
1164 HBITMAP16 WINAPI CreateCompatibleBitmap16( HDC16 hdc, INT16 width, INT16 height )
1165 {
1166     return HBITMAP_16( CreateCompatibleBitmap( HDC_32(hdc), width, height ) );
1167 }
1168
1169
1170 /***********************************************************************
1171  *           CreateCompatibleDC    (GDI.52)
1172  */
1173 HDC16 WINAPI CreateCompatibleDC16( HDC16 hdc )
1174 {
1175     return HDC_16( CreateCompatibleDC( HDC_32(hdc) ) );
1176 }
1177
1178
1179 /***********************************************************************
1180  *           CreateDC    (GDI.53)
1181  */
1182 HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
1183                          const DEVMODEA *initData )
1184 {
1185     return HDC_16( CreateDCA( driver, device, output, initData ) );
1186 }
1187
1188
1189 /***********************************************************************
1190  *           CreateEllipticRgn    (GDI.54)
1191  */
1192 HRGN16 WINAPI CreateEllipticRgn16( INT16 left, INT16 top, INT16 right, INT16 bottom )
1193 {
1194     return HRGN_16( CreateEllipticRgn( left, top, right, bottom ) );
1195 }
1196
1197
1198 /***********************************************************************
1199  *           CreateEllipticRgnIndirect    (GDI.55)
1200  */
1201 HRGN16 WINAPI CreateEllipticRgnIndirect16( const RECT16 *rect )
1202 {
1203     return HRGN_16( CreateEllipticRgn( rect->left, rect->top, rect->right, rect->bottom ) );
1204 }
1205
1206
1207 /***********************************************************************
1208  *           CreateFont    (GDI.56)
1209  */
1210 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
1211                             INT16 weight, BYTE italic, BYTE underline,
1212                             BYTE strikeout, BYTE charset, BYTE outpres,
1213                             BYTE clippres, BYTE quality, BYTE pitch,
1214                             LPCSTR name )
1215 {
1216     return HFONT_16( CreateFontA( height, width, esc, orient, weight, italic, underline,
1217                                   strikeout, charset, outpres, clippres, quality, pitch, name ));
1218 }
1219
1220 /***********************************************************************
1221  *           CreateFontIndirect   (GDI.57)
1222  */
1223 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
1224 {
1225     HFONT ret;
1226
1227     if (plf16)
1228     {
1229         LOGFONTW lfW;
1230         logfont_16_to_W( plf16, &lfW );
1231         ret = CreateFontIndirectW( &lfW );
1232     }
1233     else ret = CreateFontIndirectW( NULL );
1234     return HFONT_16(ret);
1235 }
1236
1237
1238 /***********************************************************************
1239  *           CreateHatchBrush    (GDI.58)
1240  */
1241 HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
1242 {
1243     return HBRUSH_16( CreateHatchBrush( style, color ) );
1244 }
1245
1246
1247 /***********************************************************************
1248  *           CreatePatternBrush    (GDI.60)
1249  */
1250 HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
1251 {
1252     return HBRUSH_16( CreatePatternBrush( HBITMAP_32(hbitmap) ));
1253 }
1254
1255
1256 /***********************************************************************
1257  *           CreatePen    (GDI.61)
1258  */
1259 HPEN16 WINAPI CreatePen16( INT16 style, INT16 width, COLORREF color )
1260 {
1261     LOGPEN logpen;
1262
1263     logpen.lopnStyle = style;
1264     logpen.lopnWidth.x = width;
1265     logpen.lopnWidth.y = 0;
1266     logpen.lopnColor = color;
1267     return HPEN_16( CreatePenIndirect( &logpen ) );
1268 }
1269
1270
1271 /***********************************************************************
1272  *           CreatePenIndirect    (GDI.62)
1273  */
1274 HPEN16 WINAPI CreatePenIndirect16( const LOGPEN16 * pen )
1275 {
1276     LOGPEN logpen;
1277
1278     if (pen->lopnStyle > PS_INSIDEFRAME) return 0;
1279     logpen.lopnStyle   = pen->lopnStyle;
1280     logpen.lopnWidth.x = pen->lopnWidth.x;
1281     logpen.lopnWidth.y = pen->lopnWidth.y;
1282     logpen.lopnColor   = pen->lopnColor;
1283     return HPEN_16( CreatePenIndirect( &logpen ) );
1284 }
1285
1286
1287 /***********************************************************************
1288  *           CreatePolygonRgn    (GDI.63)
1289  */
1290 HRGN16 WINAPI CreatePolygonRgn16( const POINT16 * points, INT16 count, INT16 mode )
1291 {
1292     return CreatePolyPolygonRgn16( points, &count, 1, mode );
1293 }
1294
1295
1296 /***********************************************************************
1297  *           CreateRectRgn    (GDI.64)
1298  *
1299  * NOTE: cf. SetRectRgn16
1300  */
1301 HRGN16 WINAPI CreateRectRgn16( INT16 left, INT16 top, INT16 right, INT16 bottom )
1302 {
1303     HRGN hrgn;
1304
1305     if (left < right) hrgn = CreateRectRgn( left, top, right, bottom );
1306     else hrgn = CreateRectRgn( 0, 0, 0, 0 );
1307     return HRGN_16(hrgn);
1308 }
1309
1310
1311 /***********************************************************************
1312  *           CreateRectRgnIndirect    (GDI.65)
1313  */
1314 HRGN16 WINAPI CreateRectRgnIndirect16( const RECT16* rect )
1315 {
1316     return CreateRectRgn16( rect->left, rect->top, rect->right, rect->bottom );
1317 }
1318
1319
1320 /***********************************************************************
1321  *           CreateSolidBrush    (GDI.66)
1322  */
1323 HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
1324 {
1325     return HBRUSH_16( CreateSolidBrush( color ) );
1326 }
1327
1328
1329 /***********************************************************************
1330  *           DeleteDC    (GDI.68)
1331  */
1332 BOOL16 WINAPI DeleteDC16( HDC16 hdc )
1333 {
1334     if (DeleteDC( HDC_32(hdc) ))
1335     {
1336         struct saved_visrgn *saved, *next;
1337         struct gdi_thunk* thunk;
1338
1339         if ((thunk = GDI_FindThunk(hdc))) GDI_DeleteThunk(thunk);
1340
1341         LIST_FOR_EACH_ENTRY_SAFE( saved, next, &saved_regions, struct saved_visrgn, entry )
1342         {
1343             if (saved->hdc != HDC_32(hdc)) continue;
1344             list_remove( &saved->entry );
1345             DeleteObject( saved->hrgn );
1346             HeapFree( GetProcessHeap(), 0, saved );
1347         }
1348         return TRUE;
1349     }
1350     return FALSE;
1351 }
1352
1353
1354 /***********************************************************************
1355  *           DeleteObject    (GDI.69)
1356  *           SysDeleteObject (GDI.605)
1357  */
1358 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
1359 {
1360     if (GetObjectType( HGDIOBJ_32(obj) ) == OBJ_BITMAP) free_segptr_bits( obj );
1361     return DeleteObject( HGDIOBJ_32(obj) );
1362 }
1363
1364
1365 /***********************************************************************
1366  *           EnumFonts      (GDI.70)
1367  */
1368 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
1369                           LPARAM lpData )
1370 {
1371     return EnumFontFamilies16( hDC, lpName, efproc, lpData );
1372 }
1373
1374
1375 /***********************************************************************
1376  *           EnumObjects    (GDI.71)
1377  */
1378 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 obj, GOBJENUMPROC16 proc, LPARAM lParam )
1379 {
1380     struct callback16_info info;
1381
1382     info.proc  = (FARPROC16)proc;
1383     info.param = lParam;
1384     switch(obj)
1385     {
1386     case OBJ_PEN:
1387         return EnumObjects( HDC_32(hdc), OBJ_PEN, enum_pens_callback, (LPARAM)&info );
1388     case OBJ_BRUSH:
1389         return EnumObjects( HDC_32(hdc), OBJ_BRUSH, enum_brushes_callback, (LPARAM)&info );
1390     }
1391     return 0;
1392 }
1393
1394
1395 /***********************************************************************
1396  *           EqualRgn    (GDI.72)
1397  */
1398 BOOL16 WINAPI EqualRgn16( HRGN16 rgn1, HRGN16 rgn2 )
1399 {
1400     return EqualRgn( HRGN_32(rgn1), HRGN_32(rgn2) );
1401 }
1402
1403
1404 /***********************************************************************
1405  *           GetBitmapBits    (GDI.74)
1406  */
1407 LONG WINAPI GetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPVOID buffer )
1408 {
1409     return GetBitmapBits( HBITMAP_32(hbitmap), count, buffer );
1410 }
1411
1412
1413 /***********************************************************************
1414  *              GetBkColor (GDI.75)
1415  */
1416 COLORREF WINAPI GetBkColor16( HDC16 hdc )
1417 {
1418     return GetBkColor( HDC_32(hdc) );
1419 }
1420
1421
1422 /***********************************************************************
1423  *              GetBkMode (GDI.76)
1424  */
1425 INT16 WINAPI GetBkMode16( HDC16 hdc )
1426 {
1427     return GetBkMode( HDC_32(hdc) );
1428 }
1429
1430
1431 /***********************************************************************
1432  *           GetClipBox    (GDI.77)
1433  */
1434 INT16 WINAPI GetClipBox16( HDC16 hdc, LPRECT16 rect )
1435 {
1436     RECT rect32;
1437     INT ret = GetClipBox( HDC_32(hdc), &rect32 );
1438
1439     if (ret != ERROR)
1440     {
1441         rect->left   = rect32.left;
1442         rect->top    = rect32.top;
1443         rect->right  = rect32.right;
1444         rect->bottom = rect32.bottom;
1445     }
1446     return ret;
1447 }
1448
1449
1450 /***********************************************************************
1451  *              GetCurrentPosition (GDI.78)
1452  */
1453 DWORD WINAPI GetCurrentPosition16( HDC16 hdc )
1454 {
1455     POINT pt32;
1456     if (!GetCurrentPositionEx( HDC_32(hdc), &pt32 )) return 0;
1457     return MAKELONG( pt32.x, pt32.y );
1458 }
1459
1460
1461 /***********************************************************************
1462  *           GetDCOrg    (GDI.79)
1463  */
1464 DWORD WINAPI GetDCOrg16( HDC16 hdc )
1465 {
1466     POINT pt;
1467     if (GetDCOrgEx( HDC_32(hdc), &pt )) return MAKELONG( pt.x, pt.y );
1468     return 0;
1469 }
1470
1471
1472 /***********************************************************************
1473  *           GetDeviceCaps    (GDI.80)
1474  */
1475 INT16 WINAPI GetDeviceCaps16( HDC16 hdc, INT16 cap )
1476 {
1477     INT16 ret = GetDeviceCaps( HDC_32(hdc), cap );
1478     /* some apps don't expect -1 and think it's a B&W screen */
1479     if ((cap == NUMCOLORS) && (ret == -1)) ret = 2048;
1480     return ret;
1481 }
1482
1483
1484 /***********************************************************************
1485  *              GetMapMode (GDI.81)
1486  */
1487 INT16 WINAPI GetMapMode16( HDC16 hdc )
1488 {
1489     return GetMapMode( HDC_32(hdc) );
1490 }
1491
1492
1493 /***********************************************************************
1494  *           GetObject    (GDI.82)
1495  */
1496 INT16 WINAPI GetObject16( HGDIOBJ16 handle16, INT16 count, LPVOID buffer )
1497 {
1498     HGDIOBJ handle = HGDIOBJ_32( handle16 );
1499     switch( GetObjectType( handle ))
1500     {
1501     case OBJ_PEN:
1502         if (buffer)
1503         {
1504             LOGPEN16 *pen16 = buffer;
1505             LOGPEN pen;
1506
1507             if (count < sizeof(LOGPEN16)) return 0;
1508             if (!GetObjectW( handle, sizeof(pen), &pen )) return 0;
1509
1510             pen16->lopnStyle   = pen.lopnStyle;
1511             pen16->lopnColor   = pen.lopnColor;
1512             pen16->lopnWidth.x = pen.lopnWidth.x;
1513             pen16->lopnWidth.y = pen.lopnWidth.y;
1514         }
1515         return sizeof(LOGPEN16);
1516
1517     case OBJ_BRUSH:
1518         if (buffer)
1519         {
1520             LOGBRUSH brush;
1521             LOGBRUSH16 brush16;
1522
1523             if (!GetObjectW( handle, sizeof(brush), &brush )) return 0;
1524             brush16.lbStyle = brush.lbStyle;
1525             brush16.lbColor = brush.lbColor;
1526             brush16.lbHatch = brush.lbHatch;
1527             if (count > sizeof(brush16)) count = sizeof(brush16);
1528             memcpy( buffer, &brush16, count );
1529             return count;
1530         }
1531         return sizeof(LOGBRUSH16);
1532
1533     case OBJ_PAL:
1534         return GetObjectW( handle, count, buffer );
1535
1536     case OBJ_FONT:
1537         if (buffer)
1538         {
1539             LOGFONTW font;
1540             LOGFONT16 font16;
1541
1542             if (!GetObjectW( handle, sizeof(font), &font )) return 0;
1543             logfont_W_to_16( &font, &font16 );
1544             if (count > sizeof(font16)) count = sizeof(font16);
1545             memcpy( buffer, &font16, count );
1546             return count;
1547         }
1548         return sizeof(LOGFONT16);
1549
1550     case OBJ_BITMAP:
1551         {
1552             DIBSECTION dib;
1553             INT size;
1554             BITMAP16 *bmp16 = buffer;
1555
1556             if (!(size = GetObjectW( handle, sizeof(dib), &dib ))) return 0;
1557             if (size == sizeof(DIBSECTION) && count > sizeof(BITMAP16))
1558             {
1559                 FIXME("not implemented for DIBs: count %d\n", count);
1560                 return 0;
1561             }
1562             else
1563             {
1564                 if (count < sizeof(BITMAP16)) return 0;
1565                 bmp16->bmType       = dib.dsBm.bmType;
1566                 bmp16->bmWidth      = dib.dsBm.bmWidth;
1567                 bmp16->bmHeight     = dib.dsBm.bmHeight;
1568                 bmp16->bmWidthBytes = dib.dsBm.bmWidthBytes;
1569                 bmp16->bmPlanes     = dib.dsBm.bmPlanes;
1570                 bmp16->bmBitsPixel  = dib.dsBm.bmBitsPixel;
1571                 bmp16->bmBits       = 0;
1572                 return sizeof(BITMAP16);
1573             }
1574         }
1575
1576     default:
1577         return 0;
1578     }
1579 }
1580
1581
1582 /***********************************************************************
1583  *           GetPixel    (GDI.83)
1584  */
1585 COLORREF WINAPI GetPixel16( HDC16 hdc, INT16 x, INT16 y )
1586 {
1587     return GetPixel( HDC_32(hdc), x, y );
1588 }
1589
1590
1591 /***********************************************************************
1592  *              GetPolyFillMode (GDI.84)
1593  */
1594 INT16 WINAPI GetPolyFillMode16( HDC16 hdc )
1595 {
1596     return GetPolyFillMode( HDC_32(hdc) );
1597 }
1598
1599
1600 /***********************************************************************
1601  *              GetROP2 (GDI.85)
1602  */
1603 INT16 WINAPI GetROP216( HDC16 hdc )
1604 {
1605     return GetROP2( HDC_32(hdc) );
1606 }
1607
1608
1609 /***********************************************************************
1610  *              GetRelAbs (GDI.86)
1611  */
1612 INT16 WINAPI GetRelAbs16( HDC16 hdc )
1613 {
1614     return GetRelAbs( HDC_32(hdc), 0 );
1615 }
1616
1617
1618 /***********************************************************************
1619  *           GetStockObject    (GDI.87)
1620  */
1621 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
1622 {
1623     return HGDIOBJ_16( GetStockObject( obj ) );
1624 }
1625
1626
1627 /***********************************************************************
1628  *              GetStretchBltMode (GDI.88)
1629  */
1630 INT16 WINAPI GetStretchBltMode16( HDC16 hdc )
1631 {
1632     return GetStretchBltMode( HDC_32(hdc) );
1633 }
1634
1635
1636 /***********************************************************************
1637  *           GetTextCharacterExtra    (GDI.89)
1638  */
1639 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
1640 {
1641     return GetTextCharacterExtra( HDC_32(hdc) );
1642 }
1643
1644
1645 /***********************************************************************
1646  *              GetTextColor (GDI.90)
1647  */
1648 COLORREF WINAPI GetTextColor16( HDC16 hdc )
1649 {
1650     return GetTextColor( HDC_32(hdc) );
1651 }
1652
1653
1654 /***********************************************************************
1655  *           GetTextExtent    (GDI.91)
1656  */
1657 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1658 {
1659     SIZE size;
1660     if (!GetTextExtentPoint32A( HDC_32(hdc), str, count, &size )) return 0;
1661     return MAKELONG( size.cx, size.cy );
1662 }
1663
1664
1665 /***********************************************************************
1666  *           GetTextFace    (GDI.92)
1667  */
1668 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
1669 {
1670     return GetTextFaceA( HDC_32(hdc), count, name );
1671 }
1672
1673
1674 /***********************************************************************
1675  *           GetTextMetrics    (GDI.93)
1676  */
1677 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *tm )
1678 {
1679     TEXTMETRICW tm32;
1680
1681     if (!GetTextMetricsW( HDC_32(hdc), &tm32 )) return FALSE;
1682
1683     tm->tmHeight           = tm32.tmHeight;
1684     tm->tmAscent           = tm32.tmAscent;
1685     tm->tmDescent          = tm32.tmDescent;
1686     tm->tmInternalLeading  = tm32.tmInternalLeading;
1687     tm->tmExternalLeading  = tm32.tmExternalLeading;
1688     tm->tmAveCharWidth     = tm32.tmAveCharWidth;
1689     tm->tmMaxCharWidth     = tm32.tmMaxCharWidth;
1690     tm->tmWeight           = tm32.tmWeight;
1691     tm->tmOverhang         = tm32.tmOverhang;
1692     tm->tmDigitizedAspectX = tm32.tmDigitizedAspectX;
1693     tm->tmDigitizedAspectY = tm32.tmDigitizedAspectY;
1694     tm->tmFirstChar        = tm32.tmFirstChar;
1695     tm->tmLastChar         = tm32.tmLastChar;
1696     tm->tmDefaultChar      = tm32.tmDefaultChar;
1697     tm->tmBreakChar        = tm32.tmBreakChar;
1698     tm->tmItalic           = tm32.tmItalic;
1699     tm->tmUnderlined       = tm32.tmUnderlined;
1700     tm->tmStruckOut        = tm32.tmStruckOut;
1701     tm->tmPitchAndFamily   = tm32.tmPitchAndFamily;
1702     tm->tmCharSet          = tm32.tmCharSet;
1703     return TRUE;
1704 }
1705
1706
1707 /***********************************************************************
1708  *              GetViewportExt (GDI.94)
1709  */
1710 DWORD WINAPI GetViewportExt16( HDC16 hdc )
1711 {
1712     SIZE size;
1713     if (!GetViewportExtEx( HDC_32(hdc), &size )) return 0;
1714     return MAKELONG( size.cx, size.cy );
1715 }
1716
1717
1718 /***********************************************************************
1719  *              GetViewportOrg (GDI.95)
1720  */
1721 DWORD WINAPI GetViewportOrg16( HDC16 hdc )
1722 {
1723     POINT pt;
1724     if (!GetViewportOrgEx( HDC_32(hdc), &pt )) return 0;
1725     return MAKELONG( pt.x, pt.y );
1726 }
1727
1728
1729 /***********************************************************************
1730  *              GetWindowExt (GDI.96)
1731  */
1732 DWORD WINAPI GetWindowExt16( HDC16 hdc )
1733 {
1734     SIZE size;
1735     if (!GetWindowExtEx( HDC_32(hdc), &size )) return 0;
1736     return MAKELONG( size.cx, size.cy );
1737 }
1738
1739
1740 /***********************************************************************
1741  *              GetWindowOrg (GDI.97)
1742  */
1743 DWORD WINAPI GetWindowOrg16( HDC16 hdc )
1744 {
1745     POINT pt;
1746     if (!GetWindowOrgEx( HDC_32(hdc), &pt )) return 0;
1747     return MAKELONG( pt.x, pt.y );
1748 }
1749
1750
1751
1752
1753 /**********************************************************************
1754  *           LineDDA   (GDI.100)
1755  */
1756 void WINAPI LineDDA16( INT16 nXStart, INT16 nYStart, INT16 nXEnd,
1757                        INT16 nYEnd, LINEDDAPROC16 proc, LPARAM lParam )
1758 {
1759     struct callback16_info info;
1760     info.proc  = (FARPROC16)proc;
1761     info.param = lParam;
1762     LineDDA( nXStart, nYStart, nXEnd, nYEnd, linedda_callback, (LPARAM)&info );
1763 }
1764
1765
1766 /***********************************************************************
1767  *           OffsetRgn    (GDI.101)
1768  */
1769 INT16 WINAPI OffsetRgn16( HRGN16 hrgn, INT16 x, INT16 y )
1770 {
1771     return OffsetRgn( HRGN_32(hrgn), x, y );
1772 }
1773
1774
1775 /***********************************************************************
1776  *           PtVisible    (GDI.103)
1777  */
1778 BOOL16 WINAPI PtVisible16( HDC16 hdc, INT16 x, INT16 y )
1779 {
1780     return PtVisible( HDC_32(hdc), x, y );
1781 }
1782
1783
1784 /***********************************************************************
1785  *           SelectVisRgn   (GDI.105)
1786  */
1787 INT16 WINAPI SelectVisRgn16( HDC16 hdc, HRGN16 hrgn )
1788 {
1789     return SelectVisRgn( HDC_32(hdc), HRGN_32(hrgn) );
1790 }
1791
1792
1793 /***********************************************************************
1794  *           SetBitmapBits    (GDI.106)
1795  */
1796 LONG WINAPI SetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPCVOID buffer )
1797 {
1798     return SetBitmapBits( HBITMAP_32(hbitmap), count, buffer );
1799 }
1800
1801
1802 /***********************************************************************
1803  *           AddFontResource    (GDI.119)
1804  */
1805 INT16 WINAPI AddFontResource16( LPCSTR filename )
1806 {
1807     return AddFontResourceA( filename );
1808 }
1809
1810
1811 /***********************************************************************
1812  *           Death    (GDI.121)
1813  *
1814  * Disables GDI, switches back to text mode.
1815  * We don't have to do anything here,
1816  * just let console support handle everything
1817  */
1818 void WINAPI Death16(HDC16 hdc)
1819 {
1820     MESSAGE("Death(%04x) called. Application enters text mode...\n", hdc);
1821 }
1822
1823
1824 /***********************************************************************
1825  *           Resurrection    (GDI.122)
1826  *
1827  * Restores GDI functionality
1828  */
1829 void WINAPI Resurrection16(HDC16 hdc,
1830                            WORD w1, WORD w2, WORD w3, WORD w4, WORD w5, WORD w6)
1831 {
1832     MESSAGE("Resurrection(%04x, %04x, %04x, %04x, %04x, %04x, %04x) called. Application left text mode.\n",
1833             hdc, w1, w2, w3, w4, w5, w6);
1834 }
1835
1836
1837 /***********************************************************************
1838  *           MulDiv   (GDI.128)
1839  */
1840 INT16 WINAPI MulDiv16( INT16 nMultiplicand, INT16 nMultiplier, INT16 nDivisor)
1841 {
1842     INT ret;
1843     if (!nDivisor) return -32768;
1844     /* We want to deal with a positive divisor to simplify the logic. */
1845     if (nDivisor < 0)
1846     {
1847       nMultiplicand = - nMultiplicand;
1848       nDivisor = -nDivisor;
1849     }
1850     /* If the result is positive, we "add" to round. else,
1851      * we subtract to round. */
1852     if ( ( (nMultiplicand <  0) && (nMultiplier <  0) ) ||
1853          ( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
1854         ret = (((int)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
1855     else
1856         ret = (((int)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
1857     if ((ret > 32767) || (ret < -32767)) return -32768;
1858     return (INT16) ret;
1859 }
1860
1861
1862 /***********************************************************************
1863  *           GetRgnBox    (GDI.134)
1864  */
1865 INT16 WINAPI GetRgnBox16( HRGN16 hrgn, LPRECT16 rect )
1866 {
1867     RECT r;
1868     INT16 ret = GetRgnBox( HRGN_32(hrgn), &r );
1869     rect->left   = r.left;
1870     rect->top    = r.top;
1871     rect->right  = r.right;
1872     rect->bottom = r.bottom;
1873     return ret;
1874 }
1875
1876
1877 /***********************************************************************
1878  *           RemoveFontResource    (GDI.136)
1879  */
1880 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
1881 {
1882     return RemoveFontResourceA(str);
1883 }
1884
1885
1886 /***********************************************************************
1887  *           SetBrushOrg    (GDI.148)
1888  */
1889 DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
1890 {
1891     POINT pt;
1892
1893     if (!SetBrushOrgEx( HDC_32(hdc), x, y, &pt )) return 0;
1894     return MAKELONG( pt.x, pt.y );
1895 }
1896
1897
1898 /***********************************************************************
1899  *              GetBrushOrg (GDI.149)
1900  */
1901 DWORD WINAPI GetBrushOrg16( HDC16 hdc )
1902 {
1903     POINT pt;
1904     if (!GetBrushOrgEx( HDC_32(hdc), &pt )) return 0;
1905     return MAKELONG( pt.x, pt.y );
1906 }
1907
1908
1909 /***********************************************************************
1910  *           UnrealizeObject    (GDI.150)
1911  */
1912 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
1913 {
1914     return UnrealizeObject( HGDIOBJ_32(obj) );
1915 }
1916
1917
1918 /***********************************************************************
1919  *           CreateIC    (GDI.153)
1920  */
1921 HDC16 WINAPI CreateIC16( LPCSTR driver, LPCSTR device, LPCSTR output,
1922                          const DEVMODEA* initData )
1923 {
1924     return HDC_16( CreateICA( driver, device, output, initData ) );
1925 }
1926
1927
1928 /***********************************************************************
1929  *           GetNearestColor   (GDI.154)
1930  */
1931 COLORREF WINAPI GetNearestColor16( HDC16 hdc, COLORREF color )
1932 {
1933     return GetNearestColor( HDC_32(hdc), color );
1934 }
1935
1936
1937 /***********************************************************************
1938  *           CreateDiscardableBitmap    (GDI.156)
1939  */
1940 HBITMAP16 WINAPI CreateDiscardableBitmap16( HDC16 hdc, INT16 width, INT16 height )
1941 {
1942     return HBITMAP_16( CreateDiscardableBitmap( HDC_32(hdc), width, height ) );
1943 }
1944
1945
1946 /***********************************************************************
1947  *           PtInRegion    (GDI.161)
1948  */
1949 BOOL16 WINAPI PtInRegion16( HRGN16 hrgn, INT16 x, INT16 y )
1950 {
1951     return PtInRegion( HRGN_32(hrgn), x, y );
1952 }
1953
1954
1955 /***********************************************************************
1956  *           GetBitmapDimension    (GDI.162)
1957  */
1958 DWORD WINAPI GetBitmapDimension16( HBITMAP16 hbitmap )
1959 {
1960     SIZE16 size;
1961     if (!GetBitmapDimensionEx16( hbitmap, &size )) return 0;
1962     return MAKELONG( size.cx, size.cy );
1963 }
1964
1965
1966 /***********************************************************************
1967  *           SetBitmapDimension    (GDI.163)
1968  */
1969 DWORD WINAPI SetBitmapDimension16( HBITMAP16 hbitmap, INT16 x, INT16 y )
1970 {
1971     SIZE16 size;
1972     if (!SetBitmapDimensionEx16( hbitmap, x, y, &size )) return 0;
1973     return MAKELONG( size.cx, size.cy );
1974 }
1975
1976
1977 /***********************************************************************
1978  *           SetRectRgn    (GDI.172)
1979  *
1980  * NOTE: Win 3.1 sets region to empty if left > right
1981  */
1982 void WINAPI SetRectRgn16( HRGN16 hrgn, INT16 left, INT16 top, INT16 right, INT16 bottom )
1983 {
1984     if (left < right) SetRectRgn( HRGN_32(hrgn), left, top, right, bottom );
1985     else SetRectRgn( HRGN_32(hrgn), 0, 0, 0, 0 );
1986 }
1987
1988
1989 /******************************************************************
1990  *             PlayMetaFileRecord   (GDI.176)
1991  */
1992 void WINAPI PlayMetaFileRecord16( HDC16 hdc, HANDLETABLE16 *ht, METARECORD *mr, UINT16 handles )
1993 {
1994     HANDLETABLE *ht32 = HeapAlloc( GetProcessHeap(), 0, handles * sizeof(*ht32) );
1995     unsigned int i;
1996
1997     for (i = 0; i < handles; i++) ht32->objectHandle[i] = HGDIOBJ_32(ht->objectHandle[i]);
1998     PlayMetaFileRecord( HDC_32(hdc), ht32, mr, handles );
1999     for (i = 0; i < handles; i++) ht->objectHandle[i] = HGDIOBJ_16(ht32->objectHandle[i]);
2000     HeapFree( GetProcessHeap(), 0, ht32 );
2001 }
2002
2003
2004 /***********************************************************************
2005  *           SetDCHook   (GDI.190)
2006  */
2007 BOOL16 WINAPI SetDCHook16( HDC16 hdc16, FARPROC16 hookProc, DWORD dwHookData )
2008 {
2009     FIXME( "%04x %p %x: not supported\n", hdc16, hookProc, dwHookData );
2010     return FALSE;
2011 }
2012
2013
2014 /***********************************************************************
2015  *           GetDCHook   (GDI.191)
2016  */
2017 DWORD WINAPI GetDCHook16( HDC16 hdc16, FARPROC16 *phookProc )
2018 {
2019     FIXME( "%04x: not supported\n", hdc16 );
2020     return 0;
2021 }
2022
2023
2024 /***********************************************************************
2025  *           SetHookFlags   (GDI.192)
2026  */
2027 WORD WINAPI SetHookFlags16( HDC16 hdc, WORD flags )
2028 {
2029     return SetHookFlags( HDC_32(hdc), flags );
2030 }
2031
2032
2033 /***********************************************************************
2034  *           SetBoundsRect    (GDI.193)
2035  */
2036 UINT16 WINAPI SetBoundsRect16( HDC16 hdc, const RECT16* rect, UINT16 flags )
2037 {
2038     if (rect)
2039     {
2040         RECT rect32;
2041         rect32.left   = rect->left;
2042         rect32.top    = rect->top;
2043         rect32.right  = rect->right;
2044         rect32.bottom = rect->bottom;
2045         return SetBoundsRect( HDC_32( hdc ), &rect32, flags );
2046     }
2047     else return SetBoundsRect( HDC_32( hdc ), NULL, flags );
2048 }
2049
2050
2051 /***********************************************************************
2052  *           GetBoundsRect    (GDI.194)
2053  */
2054 UINT16 WINAPI GetBoundsRect16( HDC16 hdc, LPRECT16 rect, UINT16 flags)
2055 {
2056     RECT rect32;
2057     UINT ret = GetBoundsRect( HDC_32( hdc ), &rect32, flags );
2058     if (rect)
2059     {
2060         rect->left   = rect32.left;
2061         rect->top    = rect32.top;
2062         rect->right  = rect32.right;
2063         rect->bottom = rect32.bottom;
2064     }
2065     return ret;
2066 }
2067
2068
2069 /***********************************************************************
2070  *              EngineEnumerateFont (GDI.300)
2071  */
2072 WORD WINAPI EngineEnumerateFont16(LPSTR fontname, FARPROC16 proc, DWORD data )
2073 {
2074     FIXME("(%s,%p,%x),stub\n",fontname,proc,data);
2075     return 0;
2076 }
2077
2078
2079 /***********************************************************************
2080  *              EngineDeleteFont (GDI.301)
2081  */
2082 WORD WINAPI EngineDeleteFont16(LPFONTINFO16 lpFontInfo)
2083 {
2084     WORD handle;
2085
2086     /*  untested, don't know if it works.
2087         We seem to access some structure that is located after the
2088         FONTINFO. The FONTINFO documentation says that there may
2089         follow some char-width table or font bitmap or vector info.
2090         I think it is some kind of font bitmap that begins at offset 0x52,
2091         as FONTINFO goes up to 0x51.
2092         If this is correct, everything should be implemented correctly.
2093     */
2094     if ( ((lpFontInfo->dfType & (RASTER_FONTTYPE|DEVICE_FONTTYPE)) == (RASTER_FONTTYPE|DEVICE_FONTTYPE))
2095          && (LOWORD(lpFontInfo->dfFace) == LOWORD(lpFontInfo)+0x6e)
2096          && (handle = *(WORD *)(lpFontInfo+0x54)) )
2097     {
2098         *(WORD *)(lpFontInfo+0x54) = 0;
2099         GlobalFree16(handle);
2100     }
2101     return 1;
2102 }
2103
2104
2105 /***********************************************************************
2106  *              EngineRealizeFont (GDI.302)
2107  */
2108 WORD WINAPI EngineRealizeFont16(LPLOGFONT16 lplogFont, LPTEXTXFORM16 lptextxform, LPFONTINFO16 lpfontInfo)
2109 {
2110     FIXME("(%p,%p,%p),stub\n",lplogFont,lptextxform,lpfontInfo);
2111
2112     return 0;
2113 }
2114
2115
2116 /***********************************************************************
2117  *              EngineRealizeFontExt (GDI.315)
2118  */
2119 WORD WINAPI EngineRealizeFontExt16(LONG l1, LONG l2, LONG l3, LONG l4)
2120 {
2121     FIXME("(%08x,%08x,%08x,%08x),stub\n",l1,l2,l3,l4);
2122
2123     return 0;
2124 }
2125
2126
2127 /***********************************************************************
2128  *              EngineGetCharWidth (GDI.303)
2129  */
2130 WORD WINAPI EngineGetCharWidth16(LPFONTINFO16 lpFontInfo, BYTE firstChar, BYTE lastChar, LPINT16 buffer)
2131 {
2132     int i;
2133
2134     for (i = firstChar; i <= lastChar; i++)
2135        FIXME(" returns font's average width for range %d to %d\n", firstChar, lastChar);
2136     *buffer++ = lpFontInfo->dfAvgWidth; /* insert some charwidth functionality here; use average width for now */
2137     return 1;
2138 }
2139
2140
2141 /***********************************************************************
2142  *              EngineSetFontContext (GDI.304)
2143  */
2144 WORD WINAPI EngineSetFontContext16(LPFONTINFO16 lpFontInfo, WORD data)
2145 {
2146    FIXME("stub?\n");
2147    return 0;
2148 }
2149
2150 /***********************************************************************
2151  *              EngineGetGlyphBMP (GDI.305)
2152  */
2153 WORD WINAPI EngineGetGlyphBMP16(WORD word, LPFONTINFO16 lpFontInfo, WORD w1, WORD w2,
2154                               LPSTR string, DWORD dword, /*LPBITMAPMETRICS16*/ LPVOID metrics)
2155 {
2156     FIXME("stub?\n");
2157     return 0;
2158 }
2159
2160
2161 /***********************************************************************
2162  *              EngineMakeFontDir (GDI.306)
2163  */
2164 DWORD WINAPI EngineMakeFontDir16(HDC16 hdc, LPFONTDIR16 fontdir, LPCSTR string)
2165 {
2166     FIXME(" stub! (always fails)\n");
2167     return ~0UL; /* error */
2168 }
2169
2170
2171 /***********************************************************************
2172  *           GetCharABCWidths   (GDI.307)
2173  */
2174 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar, LPABC16 abc )
2175 {
2176     BOOL ret;
2177     UINT i;
2178     LPABC abc32 = HeapAlloc( GetProcessHeap(), 0, sizeof(ABC) * (lastChar - firstChar + 1) );
2179
2180     if ((ret = GetCharABCWidthsA( HDC_32(hdc), firstChar, lastChar, abc32 )))
2181     {
2182         for (i = firstChar; i <= lastChar; i++)
2183         {
2184             abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
2185             abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
2186             abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
2187         }
2188     }
2189     HeapFree( GetProcessHeap(), 0, abc32 );
2190     return ret;
2191 }
2192
2193
2194 /***********************************************************************
2195  *           GetOutlineTextMetrics (GDI.308)
2196  *
2197  * Gets metrics for TrueType fonts.
2198  *
2199  * PARAMS
2200  *    hdc    [In]  Handle of device context
2201  *    cbData [In]  Size of metric data array
2202  *    lpOTM  [Out] Address of metric data array
2203  *
2204  * RETURNS
2205  *    Success: Non-zero or size of required buffer
2206  *    Failure: 0
2207  *
2208  * NOTES
2209  *    lpOTM should be LPOUTLINETEXTMETRIC
2210  */
2211 UINT16 WINAPI GetOutlineTextMetrics16( HDC16 hdc, UINT16 cbData,
2212                                        LPOUTLINETEXTMETRIC16 lpOTM )
2213 {
2214     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
2215     return 0;
2216 }
2217
2218
2219 /***********************************************************************
2220  *           GetGlyphOutline    (GDI.309)
2221  */
2222 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
2223                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
2224                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
2225 {
2226     DWORD ret;
2227     GLYPHMETRICS gm32;
2228
2229     ret = GetGlyphOutlineA( HDC_32(hdc), uChar, fuFormat, &gm32, cbBuffer, lpBuffer, lpmat2);
2230     if (ret && ret != GDI_ERROR)
2231     {
2232         lpgm->gmBlackBoxX = gm32.gmBlackBoxX;
2233         lpgm->gmBlackBoxY = gm32.gmBlackBoxY;
2234         lpgm->gmptGlyphOrigin.x = gm32.gmptGlyphOrigin.x;
2235         lpgm->gmptGlyphOrigin.y = gm32.gmptGlyphOrigin.y;
2236         lpgm->gmCellIncX = gm32.gmCellIncX;
2237         lpgm->gmCellIncY = gm32.gmCellIncY;
2238     }
2239     return ret;
2240 }
2241
2242
2243 /***********************************************************************
2244  *           CreateScalableFontResource   (GDI.310)
2245  */
2246 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden, LPCSTR lpszResourceFile,
2247                                             LPCSTR fontFile, LPCSTR path )
2248 {
2249     return CreateScalableFontResourceA( fHidden, lpszResourceFile, fontFile, path );
2250 }
2251
2252
2253 /*************************************************************************
2254  *             GetFontData    (GDI.311)
2255  *
2256  */
2257 DWORD WINAPI GetFontData16( HDC16 hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD count )
2258 {
2259     return GetFontData( HDC_32(hdc), table, offset, buffer, count );
2260 }
2261
2262
2263 /*************************************************************************
2264  *             GetRasterizerCaps   (GDI.313)
2265  */
2266 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes )
2267 {
2268     return GetRasterizerCaps( lprs, cbNumBytes );
2269 }
2270
2271
2272 /***********************************************************************
2273  *             EnumFontFamilies    (GDI.330)
2274  */
2275 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
2276                                  FONTENUMPROC16 efproc, LPARAM lpData )
2277 {
2278     LOGFONT16 lf, *plf;
2279
2280     if (lpFamily)
2281     {
2282         if (!*lpFamily) return 1;
2283         lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
2284         lf.lfCharSet = DEFAULT_CHARSET;
2285         lf.lfPitchAndFamily = 0;
2286         plf = &lf;
2287     }
2288     else plf = NULL;
2289
2290     return EnumFontFamiliesEx16( hDC, plf, efproc, lpData, 0 );
2291 }
2292
2293
2294 /*************************************************************************
2295  *             GetKerningPairs   (GDI.332)
2296  *
2297  */
2298 INT16 WINAPI GetKerningPairs16( HDC16 hdc, INT16 count, LPKERNINGPAIR16 pairs )
2299 {
2300     KERNINGPAIR *pairs32;
2301     INT i, ret;
2302
2303     if (!count) return 0;
2304
2305     if (!(pairs32 = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pairs32) ))) return 0;
2306     if ((ret = GetKerningPairsA( HDC_32(hdc), count, pairs32 )))
2307     {
2308         for (i = 0; i < ret; i++)
2309         {
2310             pairs->wFirst      = pairs32->wFirst;
2311             pairs->wSecond     = pairs32->wSecond;
2312             pairs->iKernAmount = pairs32->iKernAmount;
2313         }
2314     }
2315     HeapFree( GetProcessHeap(), 0, pairs32 );
2316     return ret;
2317 }
2318
2319
2320
2321 /***********************************************************************
2322  *              GetTextAlign (GDI.345)
2323  */
2324 UINT16 WINAPI GetTextAlign16( HDC16 hdc )
2325 {
2326     return GetTextAlign( HDC_32(hdc) );
2327 }
2328
2329
2330 /***********************************************************************
2331  *           SetTextAlign    (GDI.346)
2332  */
2333 UINT16 WINAPI SetTextAlign16( HDC16 hdc, UINT16 align )
2334 {
2335     return SetTextAlign( HDC_32(hdc), align );
2336 }
2337
2338
2339 /***********************************************************************
2340  *           Chord    (GDI.348)
2341  */
2342 BOOL16 WINAPI Chord16( HDC16 hdc, INT16 left, INT16 top,
2343                        INT16 right, INT16 bottom, INT16 xstart, INT16 ystart,
2344                        INT16 xend, INT16 yend )
2345 {
2346     return Chord( HDC_32(hdc), left, top, right, bottom, xstart, ystart, xend, yend );
2347 }
2348
2349
2350 /***********************************************************************
2351  *           SetMapperFlags    (GDI.349)
2352  */
2353 DWORD WINAPI SetMapperFlags16( HDC16 hdc, DWORD flags )
2354 {
2355     return SetMapperFlags( HDC_32(hdc), flags );
2356 }
2357
2358
2359 /***********************************************************************
2360  *           GetCharWidth    (GDI.350)
2361  */
2362 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar, LPINT16 buffer )
2363 {
2364     BOOL retVal = FALSE;
2365
2366     if( firstChar != lastChar )
2367     {
2368         LPINT buf32 = HeapAlloc(GetProcessHeap(), 0, sizeof(INT)*(1 + (lastChar - firstChar)));
2369         if( buf32 )
2370         {
2371             LPINT obuf32 = buf32;
2372             int i;
2373
2374             retVal = GetCharWidth32A( HDC_32(hdc), firstChar, lastChar, buf32);
2375             if (retVal)
2376             {
2377                 for (i = firstChar; i <= lastChar; i++) *buffer++ = *buf32++;
2378             }
2379             HeapFree(GetProcessHeap(), 0, obuf32);
2380         }
2381     }
2382     else /* happens quite often to warrant a special treatment */
2383     {
2384         INT chWidth;
2385         retVal = GetCharWidth32A( HDC_32(hdc), firstChar, lastChar, &chWidth );
2386         *buffer = chWidth;
2387     }
2388     return retVal;
2389 }
2390
2391
2392 /***********************************************************************
2393  *           ExtTextOut   (GDI.351)
2394  */
2395 BOOL16 WINAPI ExtTextOut16( HDC16 hdc, INT16 x, INT16 y, UINT16 flags,
2396                             const RECT16 *lprect, LPCSTR str, UINT16 count,
2397                             const INT16 *lpDx )
2398 {
2399     BOOL        ret;
2400     int         i;
2401     RECT        rect32;
2402     LPINT       lpdx32 = NULL;
2403
2404     if (lpDx) {
2405         lpdx32 = HeapAlloc( GetProcessHeap(),0, sizeof(INT)*count );
2406         if(lpdx32 == NULL) return FALSE;
2407         for (i=count;i--;) lpdx32[i]=lpDx[i];
2408     }
2409     if (lprect)
2410     {
2411         rect32.left   = lprect->left;
2412         rect32.top    = lprect->top;
2413         rect32.right  = lprect->right;
2414         rect32.bottom = lprect->bottom;
2415     }
2416     ret = ExtTextOutA(HDC_32(hdc),x,y,flags,lprect?&rect32:NULL,str,count,lpdx32);
2417     HeapFree( GetProcessHeap(), 0, lpdx32 );
2418     return ret;
2419 }
2420
2421
2422 /***********************************************************************
2423  *           CreatePalette    (GDI.360)
2424  */
2425 HPALETTE16 WINAPI CreatePalette16( const LOGPALETTE* palette )
2426 {
2427     return HPALETTE_16( CreatePalette( palette ) );
2428 }
2429
2430
2431 /***********************************************************************
2432  *           GDISelectPalette   (GDI.361)
2433  */
2434 HPALETTE16 WINAPI GDISelectPalette16( HDC16 hdc, HPALETTE16 hpalette, WORD wBkg )
2435 {
2436     HPALETTE16 ret = HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpalette), wBkg ));
2437     if (ret && !wBkg) hPrimaryPalette = hpalette;
2438     return ret;
2439 }
2440
2441
2442 /***********************************************************************
2443  *           GDIRealizePalette   (GDI.362)
2444  */
2445 UINT16 WINAPI GDIRealizePalette16( HDC16 hdc )
2446 {
2447     return RealizePalette( HDC_32(hdc) );
2448 }
2449
2450
2451 /***********************************************************************
2452  *           GetPaletteEntries    (GDI.363)
2453  */
2454 UINT16 WINAPI GetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
2455                                    UINT16 count, LPPALETTEENTRY entries )
2456 {
2457     return GetPaletteEntries( HPALETTE_32(hpalette), start, count, entries );
2458 }
2459
2460
2461 /***********************************************************************
2462  *           SetPaletteEntries    (GDI.364)
2463  */
2464 UINT16 WINAPI SetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
2465                                    UINT16 count, const PALETTEENTRY *entries )
2466 {
2467     return SetPaletteEntries( HPALETTE_32(hpalette), start, count, entries );
2468 }
2469
2470
2471 /**********************************************************************
2472  *            UpdateColors   (GDI.366)
2473  */
2474 INT16 WINAPI UpdateColors16( HDC16 hdc )
2475 {
2476     UpdateColors( HDC_32(hdc) );
2477     return TRUE;
2478 }
2479
2480
2481 /***********************************************************************
2482  *           AnimatePalette   (GDI.367)
2483  */
2484 void WINAPI AnimatePalette16( HPALETTE16 hpalette, UINT16 StartIndex,
2485                               UINT16 NumEntries, const PALETTEENTRY* PaletteColors)
2486 {
2487     AnimatePalette( HPALETTE_32(hpalette), StartIndex, NumEntries, PaletteColors );
2488 }
2489
2490
2491 /***********************************************************************
2492  *           ResizePalette   (GDI.368)
2493  */
2494 BOOL16 WINAPI ResizePalette16( HPALETTE16 hpalette, UINT16 cEntries )
2495 {
2496     return ResizePalette( HPALETTE_32(hpalette), cEntries );
2497 }
2498
2499
2500 /***********************************************************************
2501  *           GetNearestPaletteIndex   (GDI.370)
2502  */
2503 UINT16 WINAPI GetNearestPaletteIndex16( HPALETTE16 hpalette, COLORREF color )
2504 {
2505     return GetNearestPaletteIndex( HPALETTE_32(hpalette), color );
2506 }
2507
2508
2509 /**********************************************************************
2510  *          ExtFloodFill   (GDI.372)
2511  */
2512 BOOL16 WINAPI ExtFloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color,
2513                               UINT16 fillType )
2514 {
2515     return ExtFloodFill( HDC_32(hdc), x, y, color, fillType );
2516 }
2517
2518
2519 /***********************************************************************
2520  *           SetSystemPaletteUse   (GDI.373)
2521  */
2522 UINT16 WINAPI SetSystemPaletteUse16( HDC16 hdc, UINT16 use )
2523 {
2524     return SetSystemPaletteUse( HDC_32(hdc), use );
2525 }
2526
2527
2528 /***********************************************************************
2529  *           GetSystemPaletteUse   (GDI.374)
2530  */
2531 UINT16 WINAPI GetSystemPaletteUse16( HDC16 hdc )
2532 {
2533     return GetSystemPaletteUse( HDC_32(hdc) );
2534 }
2535
2536
2537 /***********************************************************************
2538  *           GetSystemPaletteEntries   (GDI.375)
2539  */
2540 UINT16 WINAPI GetSystemPaletteEntries16( HDC16 hdc, UINT16 start, UINT16 count,
2541                                          LPPALETTEENTRY entries )
2542 {
2543     return GetSystemPaletteEntries( HDC_32(hdc), start, count, entries );
2544 }
2545
2546
2547 /***********************************************************************
2548  *           ResetDC    (GDI.376)
2549  */
2550 HDC16 WINAPI ResetDC16( HDC16 hdc, const DEVMODEA *devmode )
2551 {
2552     return HDC_16( ResetDCA(HDC_32(hdc), devmode) );
2553 }
2554
2555
2556 /******************************************************************
2557  *           StartDoc   (GDI.377)
2558  */
2559 INT16 WINAPI StartDoc16( HDC16 hdc, const DOCINFO16 *lpdoc )
2560 {
2561     DOCINFOA docA;
2562
2563     docA.cbSize = lpdoc->cbSize;
2564     docA.lpszDocName = MapSL(lpdoc->lpszDocName);
2565     docA.lpszOutput = MapSL(lpdoc->lpszOutput);
2566     if(lpdoc->cbSize > offsetof(DOCINFO16,lpszDatatype))
2567         docA.lpszDatatype = MapSL(lpdoc->lpszDatatype);
2568     else
2569         docA.lpszDatatype = NULL;
2570     if(lpdoc->cbSize > offsetof(DOCINFO16,fwType))
2571         docA.fwType = lpdoc->fwType;
2572     else
2573         docA.fwType = 0;
2574     return StartDocA( HDC_32(hdc), &docA );
2575 }
2576
2577
2578 /******************************************************************
2579  *           EndDoc   (GDI.378)
2580  */
2581 INT16 WINAPI EndDoc16( HDC16 hdc )
2582 {
2583     return EndDoc( HDC_32(hdc) );
2584 }
2585
2586
2587 /******************************************************************
2588  *           StartPage   (GDI.379)
2589  */
2590 INT16 WINAPI StartPage16( HDC16 hdc )
2591 {
2592     return StartPage( HDC_32(hdc) );
2593 }
2594
2595
2596 /******************************************************************
2597  *           EndPage   (GDI.380)
2598  */
2599 INT16 WINAPI EndPage16( HDC16 hdc )
2600 {
2601     return EndPage( HDC_32(hdc) );
2602 }
2603
2604
2605 /******************************************************************************
2606  *           AbortDoc   (GDI.382)
2607  */
2608 INT16 WINAPI AbortDoc16( HDC16 hdc )
2609 {
2610     return AbortDoc( HDC_32(hdc) );
2611 }
2612
2613
2614 /***********************************************************************
2615  *           FastWindowFrame    (GDI.400)
2616  */
2617 BOOL16 WINAPI FastWindowFrame16( HDC16 hdc, const RECT16 *rect,
2618                                INT16 width, INT16 height, DWORD rop )
2619 {
2620     HDC hdc32 = HDC_32(hdc);
2621     HBRUSH hbrush = SelectObject( hdc32, GetStockObject( GRAY_BRUSH ) );
2622     PatBlt( hdc32, rect->left, rect->top,
2623             rect->right - rect->left - width, height, rop );
2624     PatBlt( hdc32, rect->left, rect->top + height, width,
2625             rect->bottom - rect->top - height, rop );
2626     PatBlt( hdc32, rect->left + width, rect->bottom - 1,
2627             rect->right - rect->left - width, -height, rop );
2628     PatBlt( hdc32, rect->right - 1, rect->top, -width,
2629             rect->bottom - rect->top - height, rop );
2630     SelectObject( hdc32, hbrush );
2631     return TRUE;
2632 }
2633
2634
2635 /***********************************************************************
2636  *           GdiInit2     (GDI.403)
2637  *
2638  * See "Undocumented Windows"
2639  *
2640  * PARAMS
2641  *   h1 [I] GDI object
2642  *   h2 [I] global data
2643  */
2644 HANDLE16 WINAPI GdiInit216( HANDLE16 h1, HANDLE16 h2 )
2645 {
2646     FIXME("(%04x, %04x), stub.\n", h1, h2);
2647     if (h2 == 0xffff) return 0xffff; /* undefined return value */
2648     return h1; /* FIXME: should be the memory handle of h1 */
2649 }
2650
2651
2652 /***********************************************************************
2653  *           FinalGdiInit     (GDI.405)
2654  */
2655 void WINAPI FinalGdiInit16( HBRUSH16 hPattern /* [in] fill pattern of desktop */ )
2656 {
2657 }
2658
2659
2660 /***********************************************************************
2661  *           CreateUserBitmap    (GDI.407)
2662  */
2663 HBITMAP16 WINAPI CreateUserBitmap16( INT16 width, INT16 height, UINT16 planes,
2664                                      UINT16 bpp, LPCVOID bits )
2665 {
2666     return CreateBitmap16( width, height, planes, bpp, bits );
2667 }
2668
2669
2670 /***********************************************************************
2671  *           CreateUserDiscardableBitmap    (GDI.409)
2672  */
2673 HBITMAP16 WINAPI CreateUserDiscardableBitmap16( WORD dummy, INT16 width, INT16 height )
2674 {
2675     HDC hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
2676     HBITMAP ret = CreateCompatibleBitmap( hdc, width, height );
2677     DeleteDC( hdc );
2678     return HBITMAP_16(ret);
2679 }
2680
2681
2682 /***********************************************************************
2683  *              GetCurLogFont (GDI.411)
2684  */
2685 HFONT16 WINAPI GetCurLogFont16( HDC16 hdc )
2686 {
2687     return HFONT_16( GetCurrentObject( HDC_32(hdc), OBJ_FONT ) );
2688 }
2689
2690
2691 /***********************************************************************
2692  *           StretchDIBits   (GDI.439)
2693  */
2694 INT16 WINAPI StretchDIBits16( HDC16 hdc, INT16 xDst, INT16 yDst, INT16 widthDst,
2695                               INT16 heightDst, INT16 xSrc, INT16 ySrc, INT16 widthSrc,
2696                               INT16 heightSrc, const VOID *bits,
2697                               const BITMAPINFO *info, UINT16 wUsage, DWORD dwRop )
2698 {
2699     return StretchDIBits( HDC_32(hdc), xDst, yDst, widthDst, heightDst,
2700                           xSrc, ySrc, widthSrc, heightSrc, bits,
2701                           info, wUsage, dwRop );
2702 }
2703
2704
2705 /***********************************************************************
2706  *           SetDIBits    (GDI.440)
2707  */
2708 INT16 WINAPI SetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
2709                           UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
2710                           UINT16 coloruse )
2711 {
2712     return SetDIBits( HDC_32(hdc), HBITMAP_32(hbitmap), startscan, lines, bits, info, coloruse );
2713 }
2714
2715
2716 /***********************************************************************
2717  *           GetDIBits    (GDI.441)
2718  */
2719 INT16 WINAPI GetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
2720                           UINT16 lines, LPVOID bits, BITMAPINFO * info,
2721                           UINT16 coloruse )
2722 {
2723     return GetDIBits( HDC_32(hdc), HBITMAP_32(hbitmap), startscan, lines, bits, info, coloruse );
2724 }
2725
2726
2727 /***********************************************************************
2728  *           CreateDIBitmap    (GDI.442)
2729  */
2730 HBITMAP16 WINAPI CreateDIBitmap16( HDC16 hdc, const BITMAPINFOHEADER * header,
2731                                    DWORD init, LPCVOID bits, const BITMAPINFO * data,
2732                                    UINT16 coloruse )
2733 {
2734     return HBITMAP_16( CreateDIBitmap( HDC_32(hdc), header, init, bits, data, coloruse ) );
2735 }
2736
2737
2738 /***********************************************************************
2739  *           SetDIBitsToDevice    (GDI.443)
2740  */
2741 INT16 WINAPI SetDIBitsToDevice16( HDC16 hdc, INT16 xDest, INT16 yDest, INT16 cx,
2742                                   INT16 cy, INT16 xSrc, INT16 ySrc, UINT16 startscan,
2743                                   UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
2744                                   UINT16 coloruse )
2745 {
2746     return SetDIBitsToDevice( HDC_32(hdc), xDest, yDest, cx, cy, xSrc, ySrc,
2747                               startscan, lines, bits, info, coloruse );
2748 }
2749
2750
2751 /***********************************************************************
2752  *           CreateRoundRectRgn    (GDI.444)
2753  *
2754  * If either ellipse dimension is zero we call CreateRectRgn16 for its
2755  * `special' behaviour. -ve ellipse dimensions can result in GPFs under win3.1
2756  * we just let CreateRoundRectRgn convert them to +ve values.
2757  */
2758
2759 HRGN16 WINAPI CreateRoundRectRgn16( INT16 left, INT16 top, INT16 right, INT16 bottom,
2760                                     INT16 ellipse_width, INT16 ellipse_height )
2761 {
2762     if( ellipse_width == 0 || ellipse_height == 0 )
2763         return CreateRectRgn16( left, top, right, bottom );
2764     else
2765         return HRGN_16( CreateRoundRectRgn( left, top, right, bottom,
2766                                             ellipse_width, ellipse_height ));
2767 }
2768
2769
2770 /***********************************************************************
2771  *           CreateDIBPatternBrush    (GDI.445)
2772  */
2773 HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
2774 {
2775     BITMAPINFO *bmi;
2776     HBRUSH16 ret;
2777
2778     if (!(bmi = GlobalLock16( hbitmap ))) return 0;
2779     ret = HBRUSH_16( CreateDIBPatternBrushPt( bmi, coloruse ));
2780     GlobalUnlock16( hbitmap );
2781     return ret;
2782 }
2783
2784
2785 /**********************************************************************
2786  *          PolyPolygon (GDI.450)
2787  */
2788 BOOL16 WINAPI PolyPolygon16( HDC16 hdc, const POINT16* pt, const INT16* counts,
2789                              UINT16 polygons )
2790 {
2791     int         i,nrpts;
2792     LPPOINT     pt32;
2793     LPINT       counts32;
2794     BOOL16      ret;
2795
2796     nrpts=0;
2797     for (i=polygons;i--;)
2798         nrpts+=counts[i];
2799     pt32 = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT)*nrpts);
2800     if(pt32 == NULL) return FALSE;
2801     for (i=nrpts;i--;)
2802     {
2803         pt32[i].x = pt[i].x;
2804         pt32[i].y = pt[i].y;
2805     }
2806     counts32 = HeapAlloc( GetProcessHeap(), 0, polygons*sizeof(INT) );
2807     if(counts32 == NULL) {
2808         HeapFree( GetProcessHeap(), 0, pt32 );
2809         return FALSE;
2810     }
2811     for (i=polygons;i--;) counts32[i]=counts[i];
2812
2813     ret = PolyPolygon(HDC_32(hdc),pt32,counts32,polygons);
2814     HeapFree( GetProcessHeap(), 0, counts32 );
2815     HeapFree( GetProcessHeap(), 0, pt32 );
2816     return ret;
2817 }
2818
2819
2820 /***********************************************************************
2821  *           CreatePolyPolygonRgn    (GDI.451)
2822  */
2823 HRGN16 WINAPI CreatePolyPolygonRgn16( const POINT16 *points,
2824                                       const INT16 *count, INT16 nbpolygons, INT16 mode )
2825 {
2826     HRGN hrgn;
2827     int i, npts = 0;
2828     INT *count32;
2829     POINT *points32;
2830
2831     for (i = 0; i < nbpolygons; i++) npts += count[i];
2832     points32 = HeapAlloc( GetProcessHeap(), 0, npts * sizeof(POINT) );
2833     for (i = 0; i < npts; i++)
2834     {
2835         points32[i].x = points[i].x;
2836         points32[i].y = points[i].y;
2837     }
2838
2839     count32 = HeapAlloc( GetProcessHeap(), 0, nbpolygons * sizeof(INT) );
2840     for (i = 0; i < nbpolygons; i++) count32[i] = count[i];
2841     hrgn = CreatePolyPolygonRgn( points32, count32, nbpolygons, mode );
2842     HeapFree( GetProcessHeap(), 0, count32 );
2843     HeapFree( GetProcessHeap(), 0, points32 );
2844     return HRGN_16(hrgn);
2845 }
2846
2847
2848 /***********************************************************************
2849  *           GdiSeeGdiDo   (GDI.452)
2850  */
2851 DWORD WINAPI GdiSeeGdiDo16( WORD wReqType, WORD wParam1, WORD wParam2,
2852                           WORD wParam3 )
2853 {
2854     DWORD ret = ~0U;
2855
2856     switch (wReqType)
2857     {
2858     case 0x0001:  /* LocalAlloc */
2859         WARN("LocalAlloc16(%x, %x): ignoring\n", wParam1, wParam3);
2860         ret = 0;
2861         break;
2862     case 0x0002:  /* LocalFree */
2863         WARN("LocalFree16(%x): ignoring\n", wParam1);
2864         ret = 0;
2865         break;
2866     case 0x0003:  /* LocalCompact */
2867         WARN("LocalCompact16(%x): ignoring\n", wParam3);
2868         ret = 65000; /* lie about the amount of free space */
2869         break;
2870     case 0x0103:  /* LocalHeap */
2871         WARN("LocalHeap16(): ignoring\n");
2872         break;
2873     default:
2874         WARN("(wReqType=%04x): Unknown\n", wReqType);
2875         break;
2876     }
2877     return ret;
2878 }
2879
2880
2881 /***********************************************************************
2882  *           SetObjectOwner    (GDI.461)
2883  */
2884 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
2885 {
2886     /* Nothing to do */
2887 }
2888
2889
2890 /***********************************************************************
2891  *           IsGDIObject    (GDI.462)
2892  *
2893  * returns type of object if valid (W95 system programming secrets p. 264-5)
2894  */
2895 BOOL16 WINAPI IsGDIObject16( HGDIOBJ16 handle16 )
2896 {
2897     static const BYTE type_map[] =
2898     {
2899         0,  /* bad */
2900         1,  /* OBJ_PEN */
2901         2,  /* OBJ_BRUSH */
2902         7,  /* OBJ_DC */
2903         9,  /* OBJ_METADC */
2904         4,  /* OBJ_PAL */
2905         3,  /* OBJ_FONT */
2906         5,  /* OBJ_BITMAP */
2907         6,  /* OBJ_REGION */
2908         10, /* OBJ_METAFILE */
2909         7,  /* OBJ_MEMDC */
2910         0,  /* OBJ_EXTPEN */
2911         9,  /* OBJ_ENHMETADC */
2912         12, /* OBJ_ENHMETAFILE */
2913         0   /* OBJ_COLORSPACE */
2914     };
2915
2916     UINT type = GetObjectType( HGDIOBJ_32( handle16 ));
2917
2918     if (type >= sizeof(type_map)/sizeof(type_map[0])) return 0;
2919     return type_map[type];
2920 }
2921
2922
2923 /***********************************************************************
2924  *           RectVisible    (GDI.465)
2925  *           RectVisibleOld (GDI.104)
2926  */
2927 BOOL16 WINAPI RectVisible16( HDC16 hdc, const RECT16* rect16 )
2928 {
2929     RECT rect;
2930
2931     rect.left   = rect16->left;
2932     rect.top    = rect16->top;
2933     rect.right  = rect16->right;
2934     rect.bottom = rect16->bottom;
2935     return RectVisible( HDC_32(hdc), &rect );
2936 }
2937
2938
2939 /***********************************************************************
2940  *           RectInRegion    (GDI.466)
2941  *           RectInRegionOld (GDI.181)
2942  */
2943 BOOL16 WINAPI RectInRegion16( HRGN16 hrgn, const RECT16 *rect )
2944 {
2945     RECT r32;
2946
2947     r32.left   = rect->left;
2948     r32.top    = rect->top;
2949     r32.right  = rect->right;
2950     r32.bottom = rect->bottom;
2951     return RectInRegion( HRGN_32(hrgn), &r32 );
2952 }
2953
2954
2955 /***********************************************************************
2956  *           GetBitmapDimensionEx    (GDI.468)
2957  */
2958 BOOL16 WINAPI GetBitmapDimensionEx16( HBITMAP16 hbitmap, LPSIZE16 size )
2959 {
2960     SIZE size32;
2961     BOOL ret = GetBitmapDimensionEx( HBITMAP_32(hbitmap), &size32 );
2962
2963     if (ret)
2964     {
2965         size->cx = size32.cx;
2966         size->cy = size32.cy;
2967     }
2968     return ret;
2969 }
2970
2971
2972 /***********************************************************************
2973  *              GetBrushOrgEx (GDI.469)
2974  */
2975 BOOL16 WINAPI GetBrushOrgEx16( HDC16 hdc, LPPOINT16 pt )
2976 {
2977     POINT pt32;
2978     if (!GetBrushOrgEx( HDC_32(hdc), &pt32 )) return FALSE;
2979     pt->x = pt32.x;
2980     pt->y = pt32.y;
2981     return TRUE;
2982 }
2983
2984
2985 /***********************************************************************
2986  *              GetCurrentPositionEx (GDI.470)
2987  */
2988 BOOL16 WINAPI GetCurrentPositionEx16( HDC16 hdc, LPPOINT16 pt )
2989 {
2990     POINT pt32;
2991     if (!GetCurrentPositionEx( HDC_32(hdc), &pt32 )) return FALSE;
2992     pt->x = pt32.x;
2993     pt->y = pt32.y;
2994     return TRUE;
2995 }
2996
2997
2998 /***********************************************************************
2999  *           GetTextExtentPoint    (GDI.471)
3000  *
3001  * FIXME: Should this have a bug for compatibility?
3002  * Original Windows versions of GetTextExtentPoint{A,W} have documented
3003  * bugs (-> MSDN KB q147647.txt).
3004  */
3005 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count, LPSIZE16 size )
3006 {
3007     SIZE size32;
3008     BOOL ret = GetTextExtentPoint32A( HDC_32(hdc), str, count, &size32 );
3009
3010     if (ret)
3011     {
3012         size->cx = size32.cx;
3013         size->cy = size32.cy;
3014     }
3015     return ret;
3016 }
3017
3018
3019 /***********************************************************************
3020  *              GetViewportExtEx (GDI.472)
3021  */
3022 BOOL16 WINAPI GetViewportExtEx16( HDC16 hdc, LPSIZE16 size )
3023 {
3024     SIZE size32;
3025     if (!GetViewportExtEx( HDC_32(hdc), &size32 )) return FALSE;
3026     size->cx = size32.cx;
3027     size->cy = size32.cy;
3028     return TRUE;
3029 }
3030
3031
3032 /***********************************************************************
3033  *              GetViewportOrgEx (GDI.473)
3034  */
3035 BOOL16 WINAPI GetViewportOrgEx16( HDC16 hdc, LPPOINT16 pt )
3036 {
3037     POINT pt32;
3038     if (!GetViewportOrgEx( HDC_32(hdc), &pt32 )) return FALSE;
3039     pt->x = pt32.x;
3040     pt->y = pt32.y;
3041     return TRUE;
3042 }
3043
3044
3045 /***********************************************************************
3046  *              GetWindowExtEx (GDI.474)
3047  */
3048 BOOL16 WINAPI GetWindowExtEx16( HDC16 hdc, LPSIZE16 size )
3049 {
3050     SIZE size32;
3051     if (!GetWindowExtEx( HDC_32(hdc), &size32 )) return FALSE;
3052     size->cx = size32.cx;
3053     size->cy = size32.cy;
3054     return TRUE;
3055 }
3056
3057
3058 /***********************************************************************
3059  *              GetWindowOrgEx (GDI.475)
3060  */
3061 BOOL16 WINAPI GetWindowOrgEx16( HDC16 hdc, LPPOINT16 pt )
3062 {
3063     POINT pt32;
3064     if (!GetWindowOrgEx( HDC_32(hdc), &pt32 )) return FALSE;
3065     pt->x = pt32.x;
3066     pt->y = pt32.y;
3067     return TRUE;
3068 }
3069
3070
3071 /***********************************************************************
3072  *           OffsetViewportOrgEx    (GDI.476)
3073  */
3074 BOOL16 WINAPI OffsetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt)
3075 {
3076     POINT pt32;
3077     BOOL16 ret = OffsetViewportOrgEx( HDC_32(hdc), x, y, &pt32 );
3078     if (pt)
3079     {
3080         pt->x = pt32.x;
3081         pt->y = pt32.y;
3082     }
3083     return ret;
3084 }
3085
3086
3087 /***********************************************************************
3088  *           OffsetWindowOrgEx    (GDI.477)
3089  */
3090 BOOL16 WINAPI OffsetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
3091 {
3092     POINT pt32;
3093     BOOL16 ret = OffsetWindowOrgEx( HDC_32(hdc), x, y, &pt32 );
3094     if (pt)
3095     {
3096         pt->x = pt32.x;
3097         pt->y = pt32.y;
3098     }
3099     return ret;
3100 }
3101
3102
3103 /***********************************************************************
3104  *           SetBitmapDimensionEx    (GDI.478)
3105  */
3106 BOOL16 WINAPI SetBitmapDimensionEx16( HBITMAP16 hbitmap, INT16 x, INT16 y, LPSIZE16 prevSize )
3107 {
3108     SIZE size32;
3109     BOOL ret = SetBitmapDimensionEx( HBITMAP_32(hbitmap), x, y, &size32 );
3110
3111     if (ret && prevSize)
3112     {
3113         prevSize->cx = size32.cx;
3114         prevSize->cy = size32.cy;
3115     }
3116     return ret;
3117 }
3118
3119
3120 /***********************************************************************
3121  *           SetViewportExtEx    (GDI.479)
3122  */
3123 BOOL16 WINAPI SetViewportExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
3124 {
3125     SIZE size32;
3126     BOOL16 ret = SetViewportExtEx( HDC_32(hdc), x, y, &size32 );
3127     if (size) { size->cx = size32.cx; size->cy = size32.cy; }
3128     return ret;
3129 }
3130
3131
3132 /***********************************************************************
3133  *           SetViewportOrgEx    (GDI.480)
3134  */
3135 BOOL16 WINAPI SetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
3136 {
3137     POINT pt32;
3138     BOOL16 ret = SetViewportOrgEx( HDC_32(hdc), x, y, &pt32 );
3139     if (pt)
3140     {
3141         pt->x = pt32.x;
3142         pt->y = pt32.y;
3143     }
3144     return ret;
3145 }
3146
3147
3148 /***********************************************************************
3149  *           SetWindowExtEx    (GDI.481)
3150  */
3151 BOOL16 WINAPI SetWindowExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
3152 {
3153     SIZE size32;
3154     BOOL16 ret = SetWindowExtEx( HDC_32(hdc), x, y, &size32 );
3155     if (size) { size->cx = size32.cx; size->cy = size32.cy; }
3156     return ret;
3157 }
3158
3159
3160 /***********************************************************************
3161  *           SetWindowOrgEx    (GDI.482)
3162  */
3163 BOOL16 WINAPI SetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
3164 {
3165     POINT pt32;
3166     BOOL16 ret = SetWindowOrgEx( HDC_32(hdc), x, y, &pt32 );
3167     if (pt)
3168     {
3169         pt->x = pt32.x;
3170         pt->y = pt32.y;
3171     }
3172     return ret;
3173 }
3174
3175
3176 /***********************************************************************
3177  *           MoveToEx    (GDI.483)
3178  */
3179 BOOL16 WINAPI MoveToEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
3180 {
3181     POINT pt32;
3182
3183     if (!MoveToEx( HDC_32(hdc), x, y, &pt32 )) return FALSE;
3184     if (pt)
3185     {
3186         pt->x = pt32.x;
3187         pt->y = pt32.y;
3188     }
3189     return TRUE;
3190 }
3191
3192
3193 /***********************************************************************
3194  *           ScaleViewportExtEx    (GDI.484)
3195  */
3196 BOOL16 WINAPI ScaleViewportExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
3197                                     INT16 yNum, INT16 yDenom, LPSIZE16 size )
3198 {
3199     SIZE size32;
3200     BOOL16 ret = ScaleViewportExtEx( HDC_32(hdc), xNum, xDenom, yNum, yDenom,
3201                                        &size32 );
3202     if (size) { size->cx = size32.cx; size->cy = size32.cy; }
3203     return ret;
3204 }
3205
3206
3207 /***********************************************************************
3208  *           ScaleWindowExtEx    (GDI.485)
3209  */
3210 BOOL16 WINAPI ScaleWindowExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
3211                                   INT16 yNum, INT16 yDenom, LPSIZE16 size )
3212 {
3213     SIZE size32;
3214     BOOL16 ret = ScaleWindowExtEx( HDC_32(hdc), xNum, xDenom, yNum, yDenom,
3215                                      &size32 );
3216     if (size) { size->cx = size32.cx; size->cy = size32.cy; }
3217     return ret;
3218 }
3219
3220
3221 /***********************************************************************
3222  *           GetAspectRatioFilterEx  (GDI.486)
3223  */
3224 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
3225 {
3226     FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
3227     return FALSE;
3228 }
3229
3230
3231 /******************************************************************************
3232  *           PolyBezier  (GDI.502)
3233  */
3234 BOOL16 WINAPI PolyBezier16( HDC16 hdc, const POINT16* lppt, INT16 cPoints )
3235 {
3236     int i;
3237     BOOL16 ret;
3238     LPPOINT pt32 = HeapAlloc( GetProcessHeap(), 0, cPoints*sizeof(POINT) );
3239     if(!pt32) return FALSE;
3240     for (i=cPoints;i--;)
3241     {
3242         pt32[i].x = lppt[i].x;
3243         pt32[i].y = lppt[i].y;
3244     }
3245     ret= PolyBezier(HDC_32(hdc), pt32, cPoints);
3246     HeapFree( GetProcessHeap(), 0, pt32 );
3247     return ret;
3248 }
3249
3250
3251 /******************************************************************************
3252  *           PolyBezierTo  (GDI.503)
3253  */
3254 BOOL16 WINAPI PolyBezierTo16( HDC16 hdc, const POINT16* lppt, INT16 cPoints )
3255 {
3256     int i;
3257     BOOL16 ret;
3258     LPPOINT pt32 = HeapAlloc( GetProcessHeap(), 0,
3259                                            cPoints*sizeof(POINT) );
3260     if(!pt32) return FALSE;
3261     for (i=cPoints;i--;)
3262     {
3263         pt32[i].x = lppt[i].x;
3264         pt32[i].y = lppt[i].y;
3265     }
3266     ret= PolyBezierTo(HDC_32(hdc), pt32, cPoints);
3267     HeapFree( GetProcessHeap(), 0, pt32 );
3268     return ret;
3269 }
3270
3271
3272 /******************************************************************************
3273  *           ExtSelectClipRgn   (GDI.508)
3274  */
3275 INT16 WINAPI ExtSelectClipRgn16( HDC16 hdc, HRGN16 hrgn, INT16 fnMode )
3276 {
3277   return ExtSelectClipRgn( HDC_32(hdc), HRGN_32(hrgn), fnMode);
3278 }
3279
3280
3281 /***********************************************************************
3282  *           AbortPath    (GDI.511)
3283  */
3284 BOOL16 WINAPI AbortPath16(HDC16 hdc)
3285 {
3286     return AbortPath( HDC_32(hdc) );
3287 }
3288
3289
3290 /***********************************************************************
3291  *           BeginPath    (GDI.512)
3292  */
3293 BOOL16 WINAPI BeginPath16(HDC16 hdc)
3294 {
3295     return BeginPath( HDC_32(hdc) );
3296 }
3297
3298
3299 /***********************************************************************
3300  *           CloseFigure    (GDI.513)
3301  */
3302 BOOL16 WINAPI CloseFigure16(HDC16 hdc)
3303 {
3304     return CloseFigure( HDC_32(hdc) );
3305 }
3306
3307
3308 /***********************************************************************
3309  *           EndPath    (GDI.514)
3310  */
3311 BOOL16 WINAPI EndPath16(HDC16 hdc)
3312 {
3313     return EndPath( HDC_32(hdc) );
3314 }
3315
3316
3317 /***********************************************************************
3318  *           FillPath    (GDI.515)
3319  */
3320 BOOL16 WINAPI FillPath16(HDC16 hdc)
3321 {
3322     return FillPath( HDC_32(hdc) );
3323 }
3324
3325
3326 /*******************************************************************
3327  *           FlattenPath    (GDI.516)
3328  */
3329 BOOL16 WINAPI FlattenPath16(HDC16 hdc)
3330 {
3331     return FlattenPath( HDC_32(hdc) );
3332 }
3333
3334
3335 /***********************************************************************
3336  *           GetPath    (GDI.517)
3337  */
3338 INT16 WINAPI GetPath16(HDC16 hdc, LPPOINT16 pPoints, LPBYTE pTypes, INT16 nSize)
3339 {
3340     FIXME("(%d,%p,%p): stub\n",hdc,pPoints,pTypes);
3341     return 0;
3342 }
3343
3344
3345 /***********************************************************************
3346  *           PathToRegion    (GDI.518)
3347  */
3348 HRGN16 WINAPI PathToRegion16(HDC16 hdc)
3349 {
3350     return HRGN_16( PathToRegion( HDC_32(hdc) ));
3351 }
3352
3353
3354 /***********************************************************************
3355  *           SelectClipPath    (GDI.519)
3356  */
3357 BOOL16 WINAPI SelectClipPath16(HDC16 hdc, INT16 iMode)
3358 {
3359     return SelectClipPath( HDC_32(hdc), iMode );
3360 }
3361
3362
3363 /*******************************************************************
3364  *           StrokeAndFillPath    (GDI.520)
3365  */
3366 BOOL16 WINAPI StrokeAndFillPath16(HDC16 hdc)
3367 {
3368     return StrokeAndFillPath( HDC_32(hdc) );
3369 }
3370
3371
3372 /*******************************************************************
3373  *           StrokePath    (GDI.521)
3374  */
3375 BOOL16 WINAPI StrokePath16(HDC16 hdc)
3376 {
3377     return StrokePath( HDC_32(hdc) );
3378 }
3379
3380
3381 /*******************************************************************
3382  *           WidenPath    (GDI.522)
3383  */
3384 BOOL16 WINAPI WidenPath16(HDC16 hdc)
3385 {
3386     return WidenPath( HDC_32(hdc) );
3387 }
3388
3389
3390 /***********************************************************************
3391  *              GetArcDirection (GDI.524)
3392  */
3393 INT16 WINAPI GetArcDirection16( HDC16 hdc )
3394 {
3395     return GetArcDirection( HDC_32(hdc) );
3396 }
3397
3398
3399 /***********************************************************************
3400  *           SetArcDirection    (GDI.525)
3401  */
3402 INT16 WINAPI SetArcDirection16( HDC16 hdc, INT16 nDirection )
3403 {
3404     return SetArcDirection( HDC_32(hdc), (INT)nDirection );
3405 }
3406
3407
3408 /***********************************************************************
3409  *           CreateHalftonePalette (GDI.529)
3410  */
3411 HPALETTE16 WINAPI CreateHalftonePalette16( HDC16 hdc )
3412 {
3413     return HPALETTE_16( CreateHalftonePalette( HDC_32(hdc) ));
3414 }
3415
3416
3417 /***********************************************************************
3418  *           SetDIBColorTable    (GDI.602)
3419  */
3420 UINT16 WINAPI SetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries, RGBQUAD *colors )
3421 {
3422     return SetDIBColorTable( HDC_32(hdc), startpos, entries, colors );
3423 }
3424
3425
3426 /***********************************************************************
3427  *           GetDIBColorTable    (GDI.603)
3428  */
3429 UINT16 WINAPI GetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries, RGBQUAD *colors )
3430 {
3431     return GetDIBColorTable( HDC_32(hdc), startpos, entries, colors );
3432 }
3433
3434
3435 /***********************************************************************
3436  *           GetRegionData   (GDI.607)
3437  *
3438  * FIXME: is LPRGNDATA the same in Win16 and Win32 ?
3439  */
3440 DWORD WINAPI GetRegionData16( HRGN16 hrgn, DWORD count, LPRGNDATA rgndata )
3441 {
3442     return GetRegionData( HRGN_32(hrgn), count, rgndata );
3443 }
3444
3445
3446 /***********************************************************************
3447  *           GdiFreeResources   (GDI.609)
3448  */
3449 WORD WINAPI GdiFreeResources16( DWORD reserve )
3450 {
3451     return 90; /* lie about it, it shouldn't matter */
3452 }
3453
3454
3455 /***********************************************************************
3456  *           GdiSignalProc32     (GDI.610)
3457  */
3458 WORD WINAPI GdiSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
3459                            DWORD dwFlags, HMODULE16 hModule )
3460 {
3461     return 0;
3462 }
3463
3464
3465 /***********************************************************************
3466  *           GetTextCharset   (GDI.612)
3467  */
3468 UINT16 WINAPI GetTextCharset16( HDC16 hdc )
3469 {
3470     return GetTextCharset( HDC_32(hdc) );
3471 }
3472
3473
3474 /***********************************************************************
3475  *           EnumFontFamiliesEx (GDI.613)
3476  */
3477 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hdc, LPLOGFONT16 plf,
3478                                    FONTENUMPROC16 proc, LPARAM lParam,
3479                                    DWORD dwFlags)
3480 {
3481     struct callback16_info info;
3482     LOGFONTW lfW, *plfW;
3483
3484     info.proc  = (FARPROC16)proc;
3485     info.param = lParam;
3486
3487     if (plf)
3488     {
3489         logfont_16_to_W(plf, &lfW);
3490         plfW = &lfW;
3491     }
3492     else plfW = NULL;
3493
3494     return EnumFontFamiliesExW( HDC_32(hdc), plfW, enum_font_callback,
3495                                 (LPARAM)&info, dwFlags );
3496 }
3497
3498
3499 /*************************************************************************
3500  *             GetFontLanguageInfo   (GDI.616)
3501  */
3502 DWORD WINAPI GetFontLanguageInfo16( HDC16 hdc )
3503 {
3504     return GetFontLanguageInfo( HDC_32(hdc) );
3505 }
3506
3507
3508 /***********************************************************************
3509  *           SetLayout   (GDI.1000)
3510  *
3511  * Sets left->right or right->left text layout flags of a dc.
3512  */
3513 BOOL16 WINAPI SetLayout16( HDC16 hdc, DWORD layout )
3514 {
3515     return SetLayout( HDC_32(hdc), layout );
3516 }
3517
3518
3519 /***********************************************************************
3520  *           SetSolidBrush   (GDI.604)
3521  *
3522  * Change the color of a solid brush.
3523  *
3524  * PARAMS
3525  *  hBrush   [I] Brush to change the color of
3526  *  newColor [I] New color for hBrush
3527  *
3528  * RETURNS
3529  *  Success: TRUE. The color of hBrush is set to newColor.
3530  *  Failure: FALSE.
3531  *
3532  * FIXME
3533  *  This function is undocumented and untested. The implementation may
3534  *  not be correct.
3535  */
3536 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
3537 {
3538     FIXME( "%04x %08x no longer supported\n", hBrush, newColor );
3539     return FALSE;
3540 }
3541
3542
3543 /***********************************************************************
3544  *           Copy   (GDI.250)
3545  */
3546 void WINAPI Copy16( LPVOID src, LPVOID dst, WORD size )
3547 {
3548     memcpy( dst, src, size );
3549 }
3550
3551 /***********************************************************************
3552  *           RealizeDefaultPalette    (GDI.365)
3553  */
3554 UINT16 WINAPI RealizeDefaultPalette16( HDC16 hdc )
3555 {
3556     FIXME( "%04x semi-stub\n", hdc );
3557     return GDIRealizePalette16( hdc );
3558 }
3559
3560 /***********************************************************************
3561  *           IsDCCurrentPalette   (GDI.412)
3562  */
3563 BOOL16 WINAPI IsDCCurrentPalette16(HDC16 hDC)
3564 {
3565     return HPALETTE_16( GetCurrentObject( HDC_32(hDC), OBJ_PAL )) == hPrimaryPalette;
3566 }
3567
3568 /*********************************************************************
3569  *           SetMagicColors   (GDI.606)
3570  */
3571 VOID WINAPI SetMagicColors16(HDC16 hDC, COLORREF color, UINT16 index)
3572 {
3573     FIXME("(hDC %04x, color %04x, index %04x): stub\n", hDC, (int)color, index);
3574
3575 }
3576
3577
3578 /***********************************************************************
3579  *           DPtoLP    (GDI.67)
3580  */
3581 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
3582 {
3583     POINT points32[8], *pt32 = points32;
3584     int i;
3585     BOOL ret;
3586
3587     if (count > 8)
3588     {
3589         if (!(pt32 = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pt32) ))) return FALSE;
3590     }
3591     for (i = 0; i < count; i++)
3592     {
3593         pt32[i].x = points[i].x;
3594         pt32[i].y = points[i].y;
3595     }
3596     if ((ret = DPtoLP( HDC_32(hdc), pt32, count )))
3597     {
3598         for (i = 0; i < count; i++)
3599         {
3600             points[i].x = pt32[i].x;
3601             points[i].y = pt32[i].y;
3602         }
3603     }
3604     if (pt32 != points32) HeapFree( GetProcessHeap(), 0, pt32 );
3605     return ret;
3606 }
3607
3608
3609 /***********************************************************************
3610  *           LPtoDP    (GDI.99)
3611  */
3612 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
3613 {
3614     POINT points32[8], *pt32 = points32;
3615     int i;
3616     BOOL ret;
3617
3618     if (count > 8)
3619     {
3620         if (!(pt32 = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pt32) ))) return FALSE;
3621     }
3622     for (i = 0; i < count; i++)
3623     {
3624         pt32[i].x = points[i].x;
3625         pt32[i].y = points[i].y;
3626     }
3627     if ((ret = LPtoDP( HDC_32(hdc), pt32, count )))
3628     {
3629         for (i = 0; i < count; i++)
3630         {
3631             points[i].x = pt32[i].x;
3632             points[i].y = pt32[i].y;
3633         }
3634     }
3635     if (pt32 != points32) HeapFree( GetProcessHeap(), 0, pt32 );
3636     return ret;
3637 }
3638
3639
3640 /***********************************************************************
3641  *           GetDCState   (GDI.179)
3642  */
3643 HDC16 WINAPI GetDCState16( HDC16 hdc )
3644 {
3645     ERR( "no longer supported\n" );
3646     return 0;
3647 }
3648
3649
3650 /***********************************************************************
3651  *           SetDCState   (GDI.180)
3652  */
3653 void WINAPI SetDCState16( HDC16 hdc, HDC16 hdcs )
3654 {
3655     ERR( "no longer supported\n" );
3656 }
3657
3658 /***********************************************************************
3659  *           SetDCOrg   (GDI.117)
3660  */
3661 DWORD WINAPI SetDCOrg16( HDC16 hdc16, INT16 x, INT16 y )
3662 {
3663     FIXME( "%04x %d,%d no longer supported\n", hdc16, x, y );
3664     return 0;
3665 }
3666
3667
3668 /***********************************************************************
3669  *              InquireVisRgn   (GDI.131)
3670  */
3671 HRGN16 WINAPI InquireVisRgn16( HDC16 hdc )
3672 {
3673     static HRGN hrgn;
3674
3675     if (!hrgn) hrgn = CreateRectRgn( 0, 0, 0, 0 );
3676     GetRandomRgn( HDC_32(hdc), hrgn, SYSRGN );
3677     return HRGN_16(hrgn);
3678 }
3679
3680
3681 /***********************************************************************
3682  *           OffsetVisRgn    (GDI.102)
3683  */
3684 INT16 WINAPI OffsetVisRgn16( HDC16 hdc16, INT16 x, INT16 y )
3685 {
3686     FIXME( "%04x %d,%d no longer supported\n", hdc16, x, y );
3687     return ERROR;
3688 }
3689
3690
3691 /***********************************************************************
3692  *           ExcludeVisRect   (GDI.73)
3693  */
3694 INT16 WINAPI ExcludeVisRect16( HDC16 hdc16, INT16 left, INT16 top, INT16 right, INT16 bottom )
3695 {
3696     FIXME( "%04x %d,%d-%d,%d no longer supported\n", hdc16, left, top, right, bottom );
3697     return ERROR;
3698 }
3699
3700
3701 /***********************************************************************
3702  *           IntersectVisRect   (GDI.98)
3703  */
3704 INT16 WINAPI IntersectVisRect16( HDC16 hdc16, INT16 left, INT16 top, INT16 right, INT16 bottom )
3705 {
3706     FIXME( "%04x %d,%d-%d,%d no longer supported\n", hdc16, left, top, right, bottom );
3707     return ERROR;
3708 }
3709
3710
3711 /***********************************************************************
3712  *           SaveVisRgn   (GDI.129)
3713  */
3714 HRGN16 WINAPI SaveVisRgn16( HDC16 hdc16 )
3715 {
3716     struct saved_visrgn *saved;
3717     HDC hdc = HDC_32( hdc16 );
3718
3719     TRACE("%p\n", hdc );
3720
3721     if (!(saved = HeapAlloc( GetProcessHeap(), 0, sizeof(*saved) ))) return 0;
3722     if (!(saved->hrgn = CreateRectRgn( 0, 0, 0, 0 )))
3723     {
3724         HeapFree( GetProcessHeap(), 0, saved );
3725         return 0;
3726     }
3727     saved->hdc = hdc;
3728     GetRandomRgn( hdc, saved->hrgn, SYSRGN );
3729     list_add_head( &saved_regions, &saved->entry );
3730     return HRGN_16(saved->hrgn);
3731 }
3732
3733
3734 /***********************************************************************
3735  *           RestoreVisRgn   (GDI.130)
3736  */
3737 INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 )
3738 {
3739     struct saved_visrgn *saved;
3740     HDC hdc = HDC_32( hdc16 );
3741     INT16 ret = ERROR;
3742
3743     TRACE("%p\n", hdc );
3744
3745     LIST_FOR_EACH_ENTRY( saved, &saved_regions, struct saved_visrgn, entry )
3746     {
3747         if (saved->hdc != hdc) continue;
3748         ret = SelectVisRgn( hdc, saved->hrgn );
3749         list_remove( &saved->entry );
3750         DeleteObject( saved->hrgn );
3751         HeapFree( GetProcessHeap(), 0, saved );
3752         break;
3753     }
3754     return ret;
3755 }
3756
3757
3758 /***********************************************************************
3759  *              GetClipRgn (GDI.173)
3760  */
3761 HRGN16 WINAPI GetClipRgn16( HDC16 hdc )
3762 {
3763     static HRGN hrgn;
3764
3765     if (!hrgn) hrgn = CreateRectRgn( 0, 0, 0, 0 );
3766     GetClipRgn( HDC_32(hdc), hrgn );
3767     return HRGN_16(hrgn);
3768 }
3769
3770
3771 /***********************************************************************
3772  *           MakeObjectPrivate    (GDI.463)
3773  *
3774  * What does that mean ?
3775  * Some little docu can be found in "Undocumented Windows",
3776  * but this is basically useless.
3777  */
3778 void WINAPI MakeObjectPrivate16( HGDIOBJ16 handle16, BOOL16 private )
3779 {
3780     FIXME( "stub: %x %u\n", handle16, private );
3781 }
3782
3783 /***********************************************************************
3784  *           CreateDIBSection    (GDI.489)
3785  */
3786 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
3787                                      SEGPTR *bits16, HANDLE section, DWORD offset)
3788 {
3789     LPVOID bits32;
3790     HBITMAP hbitmap;
3791
3792     hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
3793     if (hbitmap && bits32 && bits16) *bits16 = alloc_segptr_bits( hbitmap, bits32 );
3794     return HBITMAP_16(hbitmap);
3795 }