/*++
 *
 *  WOW v1.0
 *
 *  Copyright (c) 1991, Microsoft Corporation
 *
 *  WGDI31.C
 *  WOW32 16-bit Win 3.1 GDI API support
 *
 *  History:
 *  Created 16-Mar-1992 by Chandan S. Chauhan (ChandanC)
 *
--*/

#include "precomp.h"
#pragma hdrstop
#include <drivinit.h>

MODNAME(wgdi31.c);


// This must be removed POSTBETA 2 for sure. We should be using common defines between
// GDI and WOW. ChandanC 5/27/94.

#define NOFIRSTSAVE     0x7FFFFFFE
#define ADD_MSTT        0x7FFFFFFD


ULONG FASTCALL WG32AbortDoc(PVDMFRAME pFrame)
{
    ULONG    ul;
    register PABORTDOC16 parg16;

    GETARGPTR(pFrame, sizeof(ABORTDOC16), parg16);

    ul = GETINT16(AbortDoc(HDC32(parg16->f1)));

    if ((INT)ul < 0) {
        WOW32ASSERT ("WOW::WG32AbortDoc: Failed\n");
    }

    FREEARGPTR(parg16);

    RETURN(ul);
}


ULONG FASTCALL WG32CreateScalableFontResource(PVDMFRAME pFrame)
{
    ULONG    ul;
    PSZ      t2;
    PSZ      t3;
    PSZ      t4;
    DWORD    fHidden;
    register PCREATESCALABLEFONTRESOURCE16 parg16;

    GETARGPTR(pFrame, sizeof(CREATESCALABLEFONTRESOURCE16), parg16);
    GETPSZPTR(parg16->f2, t2);
    GETPSZPTR(parg16->f3, t3);
    GETPSZPTR(parg16->f4, t4);

    // We need to convert this param to 2 if the app gives 1. This tells GDI
    // to embed client TID in the private (hidden) font.
    //

    fHidden = (parg16->f1 == 1) ? 2 : (parg16->f1);

    ul = GETBOOL16(CreateScalableFontResource(fHidden,
                                              t2,
                                              t3,
                                              t4));
    FREEARGPTR(parg16);

    RETURN(ul);
}


ULONG FASTCALL WG32EndDoc(PVDMFRAME pFrame)
{
    ULONG    ul;
    register PENDDOC16 parg16;

    GETARGPTR(pFrame, sizeof(ENDDOC16), parg16);

    ul = GETINT16(EndDoc(HDC32(parg16->f1)));

    FREEARGPTR(parg16);

    RETURN(ul);
}


ULONG FASTCALL WG32EndPage(PVDMFRAME pFrame)
{
    ULONG    ul;
    register PENDPAGE16 parg16;

    GETARGPTR(pFrame, sizeof(ENDPAGE16), parg16);

    ul = GETINT16(EndPage(HDC32(parg16->f1)));

    FREEARGPTR(parg16);

    RETURN(ul);
}


ULONG FASTCALL WG32EnumFontFamilies(PVDMFRAME pFrame)
{
    return( W32EnumFontHandler(pFrame, TRUE) );
}


ULONG FASTCALL WG32GetAspectRatioFilterEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     AspectRatio;
    register PGETASPECTRATIOFILTEREX16 parg16;

    GETARGPTR(pFrame, sizeof(GETASPECTRATIOFILTEREX16), parg16);

    ul = GETBOOL16(GetAspectRatioFilterEx(HDC32(parg16->f1), &AspectRatio));

    PUTSIZE16(parg16->f2, &AspectRatio);

    FREEARGPTR(parg16);

    RETURN(ul);
}


ULONG FASTCALL WG32GetBitmapDimensionEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Dimension;
    register PGETBITMAPDIMENSIONEX16 parg16;

    GETARGPTR(pFrame, sizeof(GETBITMAPDIMENSIONEX16), parg16);

    ul = GETBOOL16(GetBitmapDimensionEx(HBITMAP32(parg16->f1), &Dimension));

    PUTSIZE16(parg16->f2, &Dimension);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetBoundsRect(PVDMFRAME pFrame)
{
    ULONG    ul = 0;
    RECT     Bounds;
    register PGETBOUNDSRECT16 parg16;

    GETARGPTR(pFrame, sizeof(GETBOUNDSRECT16), parg16);

    ul = GETUINT16(GetBoundsRect(HDC32(parg16->f1),
                                 &Bounds,
                                 UINT32(parg16->f3)));

    //
    // Win16 GetBoundsRect always returns DCB_SET or DCB_RESET.
    //
    ul = (ul & DCB_SET) ? DCB_SET : DCB_RESET;

    PUTRECT16(parg16->f2, &Bounds);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetBrushOrgEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    register PGETBRUSHORGEX16 parg16;

    GETARGPTR(pFrame, sizeof(GETBRUSHORGEX16), parg16);

    ul = GETBOOL16(GetBrushOrgEx(HDC32(parg16->f1), &Point));

    PUTPOINT16(parg16->f2, &Point);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetCharABCWidths(PVDMFRAME pFrame)
{
    ULONG    ul=0;
    LPABC    lpAbc;
    WORD     cb;
    register PGETCHARABCWIDTHS16 parg16;

    GETARGPTR(pFrame, sizeof(GETCHARABCWIDTHS16), parg16);

    cb = WORD32(parg16->f3) - WORD32(parg16->f2) + 1;
    if (lpAbc = (LPABC) malloc_w (sizeof(ABC) * cb)) {
        ul = GETBOOL16(GetCharABCWidths(HDC32(parg16->f1),
                                        WORD32(parg16->f2),
                                        WORD32(parg16->f3),
                                        lpAbc));
        if (ul) {
            putabcpairs16(parg16->f4, cb, lpAbc);
        }

        free_w (lpAbc);
    }

    FREEARGPTR(parg16);
    RETURN (ul);
}



ULONG FASTCALL WG32GetCurrentPositionEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    register PGETCURRENTPOSITIONEX16 parg16;

    GETARGPTR(pFrame, sizeof(GETCURRENTPOSITIONEX16), parg16);

    ul = GETBOOL16(GetCurrentPositionEx(HDC32(parg16->f1), &Point));

    PUTPOINT16(parg16->f2, &Point);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetFontData(PVDMFRAME pFrame)
{
    ULONG    ul;
    LPSTR    lpBuffer = NULL;
    register PGETFONTDATA16 parg16;

    GETARGPTR(pFrame, sizeof(GETFONTDATA16), parg16);

    if( parg16->f4 && parg16->f5 ) {
        if (!(lpBuffer = (LPSTR) malloc_w (DWORD32(parg16->f5)))) {
            FREEARGPTR(parg16);
            RETURN ((ULONG)-1);
        }
    }

    ul = GETDWORD16(GetFontData(HDC32(parg16->f1),
                                DWORD32(parg16->f2),
                                DWORD32(parg16->f3),
                                lpBuffer,
                                DWORD32(parg16->f5)));

    if( lpBuffer ) {
        PUTBUFFER16(parg16->f4, DWORD32(parg16->f5), lpBuffer);
        free_w(lpBuffer);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}

ULONG FASTCALL WG32GetGlyphOutline(PVDMFRAME pFrame)
{
    ULONG        ul;
    LPSTR        lpBuffer = NULL;
    MAT2         Matrix;
    GLYPHMETRICS Metrics;
    register     PGETGLYPHOUTLINE16 parg16;

    GETARGPTR(pFrame, sizeof(GETGLYPHOUTLINE16), parg16);
    GETMAT2(parg16->f7, &Matrix);

    if (parg16->f5 && parg16->f6) {
        if((lpBuffer = (LPSTR) malloc_w(DWORD32(parg16->f5))) == NULL) {
            FREEARGPTR(parg16);
            return((ULONG)-1);
        }
    }

    ul = GETDWORD16(GetGlyphOutline(HDC32(parg16->f1),
                                    WORD32(parg16->f2),
                                    WORD32(parg16->f3),
                                    parg16->f4 ? &Metrics : (GLYPHMETRICS*)NULL,
                                    DWORD32(parg16->f5),
                                    lpBuffer,
                                    &Matrix));

    if ( FETCHDWORD(parg16->f4) != 0 ) {
        PUTGLYPHMETRICS16(FETCHDWORD(parg16->f4), &Metrics);
    }

    if ( lpBuffer ) {
        PUTBUFFER16(parg16->f6, DWORD32(parg16->f5), lpBuffer);
        free_w(lpBuffer);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetKerningPairs(PVDMFRAME pFrame)
{
    ULONG        ul;
    LPKERNINGPAIR lpkrnpair = NULL;
    register     PGETKERNINGPAIRS16 parg16;

    GETARGPTR(pFrame, sizeof(GETKERNINGPAIRS16), parg16);

    if (FETCHDWORD(parg16->f3)) {
        lpkrnpair = (LPKERNINGPAIR) malloc_w (sizeof(KERNINGPAIR) * (parg16->f2));
        if (!lpkrnpair) {
            LOGDEBUG (0, ("WOW::WG32GetKeriningPairs: *** MALLOC failed ***\n"));
            FREEARGPTR(parg16);
            RETURN (0);
        }

    }

    ul = GetKerningPairs(HDC32(parg16->f1), parg16->f2, lpkrnpair);

    if (FETCHDWORD(parg16->f3)) {
        putkerningpairs16 (FETCHDWORD(parg16->f3), parg16->f2, lpkrnpair);
        free_w (lpkrnpair);
    }

    FREEARGPTR(parg16);
    RETURN (ul);
}


ULONG FASTCALL WG32GetOutlineTextMetrics(PVDMFRAME pFrame)
{
    ULONG ul;
    register PGETOUTLINETEXTMETRICS16 parg16;
    UINT    cb;
    UINT    new_cb;
    VPOUTLINETEXTMETRIC16   vpotm;
    LPOUTLINETEXTMETRIC lpBuffer;

    GETARGPTR(pFrame, sizeof(GETOUTLINETEXTMETRICS16), parg16);

    vpotm = (VPOUTLINETEXTMETRIC16)FETCHDWORD(parg16->f3);

    new_cb = cb = FETCHWORD(parg16->f2);

    if ( vpotm ) {
        new_cb += sizeof(OUTLINETEXTMETRIC) - sizeof(OUTLINETEXTMETRIC16);
        if (!(lpBuffer = (LPOUTLINETEXTMETRIC)malloc_w(new_cb))) {
            FREEARGPTR(parg16);
            RETURN (0);
        }
    } else {
        lpBuffer = NULL;
    }


    ul = GETDWORD16(GetOutlineTextMetrics(HDC32(parg16->f1), new_cb, lpBuffer));

    if ( vpotm ) {
        PUTOUTLINETEXTMETRIC16(vpotm, cb, lpBuffer);
        free_w( lpBuffer );
    } else {
        if ( ul != 0 ) {
            ul -= sizeof(OUTLINETEXTMETRIC) - sizeof(OUTLINETEXTMETRIC16);
        }
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetRasterizerCaps(PVDMFRAME pFrame)
{
    ULONG ul;
    RASTERIZER_STATUS RStatus;
    register PGETRASTERIZERCAPS16 parg16;

    GETARGPTR(pFrame, sizeof(GETRASTERIZERCAPS16), parg16);

    ul = GETBOOL16(GetRasterizerCaps(&RStatus, INT32(parg16->f2)));

    PUTRASTERIZERSTATUS16(parg16->f1, &RStatus);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetTextExtentPoint(PVDMFRAME pFrame)
{
    ULONG    ul;
    PSZ      lpString;
    SIZE     Size;
    register PGETTEXTEXTENTPOINT16 parg16;

    GETARGPTR(pFrame, sizeof(GETTEXTEXTENTPOINT16), parg16);
    GETPSZPTR(parg16->f2, lpString);

    ul = GETBOOL16(GetTextExtentPoint(HDC32(parg16->f1),
                                      lpString,
                                      INT32(parg16->f3),
                                      &Size));
    PUTSIZE16(parg16->f4, &Size);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetViewportExtEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Size;
    register PGETVIEWPORTEXTEX16 parg16;

    GETARGPTR(pFrame, sizeof(GETVIEWPORTEXTEX16), parg16);

    ul = GETBOOL16(GetViewportExtEx(HDC32(parg16->f1), &Size));

    PUTSIZE16(parg16->f2, &Size);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetViewportOrgEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    register PGETVIEWPORTORGEX16 parg16;

    GETARGPTR(pFrame, sizeof(GETVIEWPORTORGEX16), parg16);

    ul = GETBOOL16(GetViewportOrgEx(HDC32(parg16->f1), &Point));

    PUTPOINT16(parg16->f2, &Point);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetWindowExtEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Size;
    register PGETWINDOWEXTEX16 parg16;

    GETARGPTR(pFrame, sizeof(GETWINDOWEXTEX16), parg16);

    ul = GETBOOL16(GetWindowExtEx( HDC32(parg16->f1),&Size));

    PUTSIZE16(parg16->f2, &Size);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32GetWindowOrgEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    register PGETWINDOWORGEX16 parg16;

    GETARGPTR(pFrame, sizeof(GETWINDOWORGEX16), parg16);

    ul = GETBOOL16(GetWindowOrgEx(HDC32(parg16->f1), &Point));

    PUTPOINT16(parg16->f2, &Point);

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32IsGDIObject(PVDMFRAME pFrame)
{
    ULONG ul;
    register PISGDIOBJECT16 parg16;

    GETARGPTR(pFrame, sizeof(ISGDIOBJECT16), parg16);

    // The Win31 isgdiobject returns the objecttype if handle is valid
    // eventhough the return value is BOOL.  So do the same
    //                                                       - Nanduri

    ul = (ULONG)GetObjectType(HOBJ32(parg16->f1));

    FREEARGPTR(parg16);
    RETURN (ul);
}


ULONG FASTCALL WG32MoveToEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    LPPOINT  lpPoint = NULL;
    register PMOVETOEX16 parg16;

    GETARGPTR(pFrame, sizeof(MOVETOEX16), parg16);

    if (parg16->f4) {
        lpPoint = &Point;
    }

    ul = GETBOOL16(MoveToEx(HDC32(parg16->f1),
                            INT32(parg16->f2),
                            INT32(parg16->f3),
                            lpPoint));
    if (parg16->f4) {
        PUTPOINT16(parg16->f4, lpPoint);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32OffsetViewportOrgEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    LPPOINT  lpPoint = NULL;
    register POFFSETVIEWPORTORGEX16 parg16;

    GETARGPTR(pFrame, sizeof(OFFSETVIEWPORTEX16), parg16);

    if (parg16->f4) {
        lpPoint = &Point;
    }

    ul = GETBOOL16(OffsetViewportOrgEx(HDC32(parg16->f1),
                                       INT32(parg16->f2),
                                       INT32(parg16->f3),
                                       lpPoint));

    if (parg16->f4) {
        PUTPOINT16(parg16->f4, lpPoint);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32OffsetWindowOrgEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    LPPOINT  lpPoint = NULL;
    register POFFSETWINDOWORGEX16 parg16;

    GETARGPTR(pFrame, sizeof(OFFSETWINDOWORGEX16), parg16);

    if (parg16->f4) {
        lpPoint = &Point;
    }

    ul = GETBOOL16(OffsetWindowOrgEx(HDC32(parg16->f1),
                                     INT32(parg16->f2),
                                     INT32(parg16->f3),
                                     lpPoint));

    if (parg16->f4) {
        PUTPOINT16(parg16->f4, lpPoint);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32ResetDC(PVDMFRAME pFrame)
{
    ULONG     ul = 0;
    LPDEVMODE lpInitData;
    register  PRESETDC16 parg16;

    GETARGPTR(pFrame, sizeof(RESETDC16), parg16);

    if( lpInitData = GetDevMode32(parg16->f2) ) {

        ul = GETHDC16(ResetDC(HDC32(parg16->f1), lpInitData));

        FREEDEVMODE32(lpInitData);

    }

    RETURN (ul);
}


ULONG FASTCALL WG32ScaleViewportExtEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Size;
    LPSIZE   lpSize = NULL;
    register PSCALEVIEWPORTEXTEX16 parg16;

    GETARGPTR(pFrame, sizeof(SCALEVIEWPORTEXTEX16), parg16);

    if (parg16->f6) {
        lpSize = &Size;
    }

    ul = GETBOOL16(ScaleViewportExtEx(HDC32(parg16->f1),
                                      INT32(parg16->f2),
                                      INT32(parg16->f3),
                                      INT32(parg16->f4),
                                      INT32(parg16->f5),
                                      lpSize));
    if (parg16->f6) {
        PUTSIZE16(parg16->f6, lpSize);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32ScaleWindowExtEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Size;
    LPSIZE   lpSize = NULL;
    register PSCALEWINDOWEXTEX16 parg16;

    GETARGPTR(pFrame, sizeof(SCALEWINDOWEXTEX16), parg16);

    if (parg16->f6) {
        lpSize = &Size;
    }

    ul = GETBOOL16(ScaleWindowExtEx(HDC32(parg16->f1),
                                    INT32(parg16->f2),
                                    INT32(parg16->f3),
                                    INT32(parg16->f4),
                                    INT32(parg16->f5),
                                    lpSize));
    if (parg16->f6) {
        PUTSIZE16(parg16->f6, lpSize);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32SetAbortProc(PVDMFRAME pFrame)
{
    ULONG    ul;
    register PSETABORTPROC16 parg16;

    GETARGPTR(pFrame, sizeof(SETABORTPROC16), parg16);

    ((PTDB)SEGPTR(pFrame->wTDB, 0))->TDB_vpfnAbortProc = FETCHDWORD(parg16->f2);

    ul = GETINT16(SetAbortProc(HDC32(parg16->f1), (ABORTPROC) W32AbortProc));

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32SetBitmapDimensionEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Size;
    LPSIZE   lpSize = NULL;
    register PSETBITMAPDIMENSIONEX16 parg16;

    GETARGPTR(pFrame, sizeof(SETBITMAPDIMENSIONEX16), parg16);

    if (parg16->f4) {
        lpSize = &Size;
    }

    ul = GETBOOL16(SetBitmapDimensionEx(HBITMAP32(parg16->f1),
                                        INT32(parg16->f2),
                                        INT32(parg16->f3),
                                        lpSize));
    if (parg16->f4) {
        PUTSIZE16(parg16->f4, lpSize);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32SetBoundsRect(PVDMFRAME pFrame)
{
    ULONG    ul = 0;
    RECT     rcBounds;
    register PSETBOUNDSRECT16 parg16;

    GETARGPTR(pFrame, sizeof(SETBOUNDSRECT16), parg16);
    GETRECT16(parg16->f2, &rcBounds);

    ul = GETWORD16(SetBoundsRect(HDC32(parg16->f1),
                                 &rcBounds,
                                 WORD32(parg16->f3)));

    FREEARGPTR(parg16);

    RETURN (ul);
}


#if 0  // implemented in gdi.exe

ULONG FASTCALL WG32SetMetaFileBitsBetter(PVDMFRAME pFrame)
{
    return(WG32SetMetaFileBits(pFrame));
}

#endif

ULONG FASTCALL WG32SetViewportExtEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Size;
    LPSIZE   lpSize = NULL;
    register PSETVIEWPORTEXTEX16 parg16;

    GETARGPTR(pFrame, sizeof(SETVIEWPORTEXTEX16), parg16);

    if (parg16->f4) {
        lpSize = &Size;
    }

    ul = GETBOOL16(SetViewportExtEx(HDC32(parg16->f1),
                                    INT32(parg16->f2),
                                    INT32(parg16->f3),
                                    lpSize));

    if (parg16->f4) {
        PUTSIZE16(parg16->f4, lpSize);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32SetViewportOrgEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    LPPOINT  lpPoint = NULL;
    register PSETVIEWPORTORGEX16 parg16;

    GETARGPTR(pFrame, sizeof(SETVIEWPORTORGEX16), parg16);

    if (parg16->f4) {
        lpPoint = &Point;
    }

    ul = GETBOOL16(SetViewportOrgEx(HDC32(parg16->f1),
                                    INT32(parg16->f2),
                                    INT32(parg16->f3),
                                    lpPoint));
    if (parg16->f4) {
        PUTPOINT16(parg16->f4, lpPoint);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32SetWindowExtEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    SIZE     Size;
    LPSIZE   lpSize = NULL;
    register PSETWINDOWEXTEX16 parg16;

    GETARGPTR(pFrame, sizeof(SETWINDOWEXTEX16), parg16);

    if (parg16->f4) {
        lpSize = &Size;
    }

    ul = GETBOOL16(SetWindowExtEx(HDC32(parg16->f1),
                                  INT32(parg16->f2),
                                  INT32(parg16->f3),
                                  lpSize));
    if (parg16->f4) {
        PUTSIZE16(parg16->f4, lpSize);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32SetWindowOrgEx(PVDMFRAME pFrame)
{
    ULONG    ul;
    POINT    Point;
    LPPOINT  lpPoint = NULL;
    register PSETWINDOWORGEX16 parg16;

    GETARGPTR(pFrame, sizeof(SETWINDOWORGEX16), parg16);

    if (parg16->f4) {
        lpPoint = &Point;
    }

    ul = GETBOOL16(SetWindowOrgEx(HDC32(parg16->f1),
                                  INT32(parg16->f2),
                                  INT32(parg16->f3),
                                  lpPoint));

    if (parg16->f4) {
        PUTPOINT16(parg16->f4, lpPoint);
    }

    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32StartDoc(PVDMFRAME pFrame)
{
    ULONG       ul;
    VPVOID      vpDocName;
    VPVOID      vpOutput;
    DOCINFO     DocInfo;
    LPDOCINFO16 pdi16;
    register    PSTARTDOC16 parg16;

    GETARGPTR(pFrame, sizeof(STARTDOC16), parg16);
    GETVDMPTR(parg16->f2, sizeof(DOCINFO16), pdi16);

    //
    // Win32 StartDoc depends on having the correct current directory
    // when printing to FILE: (which pops up for a filename).
    //

    UpdateDosCurrentDirectory(DIR_DOS_TO_NT);

    DocInfo.cbSize = sizeof(DOCINFO);

    vpDocName = FETCHDWORD(pdi16->lpszDocName);
    vpOutput  = FETCHDWORD(pdi16->lpszOutput);

    GETPSZPTR(vpDocName, DocInfo.lpszDocName);
    GETPSZPTR(vpOutput, DocInfo.lpszOutput);

    FREEVDMPTR(pdi16);

    ul = GETINT16(StartDoc(HDC32(parg16->f1), &DocInfo));

    if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_NOFIRSTSAVE) {
        int l;
        char szBuf[80];

        if ((l = ExtEscape(HDC32(parg16->f1),
                                    GETTECHNOLOGY,
                                    NULL,
                                    NULL,
                                    sizeof(szBuf),
                                    szBuf)) > 0) {

            if (!lstrcmpi(szBuf, "POSTSCRIPT")) {
                l = ExtEscape(HDC32(parg16->f1),
                        NOFIRSTSAVE,
                        NULL,
                        NULL,
                        NULL,
                        NULL);

                // This HACK is for FH4.0 only. If you have any questions
                // talk to PingW or ChandanC.
                // July 21st 1994.
                //
                if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_ADD_MSTT) {
                    l = ExtEscape(HDC32(parg16->f1),
                        ADD_MSTT,
                        NULL,
                        NULL,
                        NULL,
                        NULL);
                }
            }
        }
    }

    FREEPSZPTR(DocInfo.lpszDocName);
    FREEPSZPTR(DocInfo.lpszOutput);
    FREEARGPTR(parg16);

    RETURN (ul);
}


ULONG FASTCALL WG32StartPage(PVDMFRAME pFrame)
{
    ULONG    ul;
    register PSTARTPAGE16 parg16;
    char szBuf[80];

    GETARGPTR(pFrame, sizeof(STARTPAGE16), parg16);

    ul = GETINT16(StartPage(HDC32(parg16->f1)));

    FREEARGPTR(parg16);

    RETURN (ul);
}


// InquireVisRgn is an undocumented Win 3.1 API. This code has been
// suggested by ChuckWh. If this does not fix the FileMaker Pro 2.0
// problem, then ChuckWh would be providing us with an private entry
// point.
// ChandanC 7th Feb 93
//

HRGN ghrgnVis = NULL;


ULONG FASTCALL WG32InquireVisRgn(PVDMFRAME pFrame)
{
    register PINQUIREVISRGN16 parg16;
    extern int GetRandomRgn(HDC hdc, HRGN hrgn, int cmd);

    GETARGPTR(pFrame, sizeof(INQUIREVISRGN16), parg16);

    // call special gdi entry point to get copy of vis rgn

    GetRandomRgn(HDC32(parg16->f1), ghrgnVis, 4);

    FREEARGPTR(parg16);

    RETURN (GETHRGN16(ghrgnVis));
}


BOOL InitVisRgn()
{
    ghrgnVis = CreateRectRgn(0,0,0,0);

    return(ghrgnVis != NULL);
}


VOID putabcpairs16(VPABC16 vpAbc, UINT cb, LPABC lpAbc)
{
    UINT i;
    register PABC16 pAbc16;

    GETVDMPTR(vpAbc, sizeof(ABC16), pAbc16);

    for (i=0; i < cb; i++) {
        pAbc16[i].abcA = (INT16) lpAbc[i].abcA;
        pAbc16[i].abcB = (WORD)  lpAbc[i].abcB;
        pAbc16[i].abcC = (INT16) lpAbc[i].abcC;
    }

    FLUSHVDMPTR(vpAbc, sizeof(ABC16), pAbc16);
    FREEVDMPTR(pAbc16);
}


ULONG FASTCALL WG32GetClipRgn(PVDMFRAME pFrame)
{
    register PGETCLIPRGN16 parg16;

    // this is a private win3.1 entry pointed defined as HRGN GetClipRgn(HDC);
    // NT exports the entry point defined as DWORD GetClipRgn(HDC,HRGN);
    // NT will not give out the handle to its internal cliprgn so instead
    // makes a copy.  Any app uses this private win3.1 entry point will
    // have a global region created for it that will go away when the
    // app goes away.

    GETARGPTR(pFrame, sizeof(GETCLIPRGN16), parg16);

    if (CURRENTPTD()->hrgnClip == NULL)
        CURRENTPTD()->hrgnClip = CreateRectRgn(0,0,0,0);

    GetClipRgn(HDC32(parg16->f1), CURRENTPTD()->hrgnClip);

    FREEARGPTR(parg16);

    RETURN (GETHRGN16(CURRENTPTD()->hrgnClip));
}
