/*
 * Escape() function.
 *
 * Copyright 1994  Bob Amstadt
 */

#include <string.h>
#include "windef.h"
#include "wingdi.h"
#include "gdi.h"
#include "heap.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(driver);

/***********************************************************************
 *            Escape16  [GDI.38]
 */
INT16 WINAPI Escape16( HDC16 hdc, INT16 nEscape, INT16 cbInput,
                       SEGPTR lpszInData, SEGPTR lpvOutData )
{
    INT16 ret = 0;
    DC * dc = DC_GetDCPtr( hdc );
    if (dc)
    {
        if (dc->funcs->pEscape)
        {
            if(nEscape == SETABORTPROC) SetAbortProc16(hdc, lpszInData);
            ret = dc->funcs->pEscape( dc, nEscape, cbInput, lpszInData, lpvOutData );
        }
        GDI_ReleaseObj( hdc );
    }
    return ret;
}

/************************************************************************
 *             Escape  [GDI32.200]
 */
INT WINAPI Escape( HDC hdc, INT nEscape, INT cbInput,
		   LPCSTR lpszInData, LPVOID lpvOutData )
{
    SEGPTR	segin,segout;
    INT	ret = 0;
    DC * dc = DC_GetDCPtr( hdc );
    if (!dc) return 0;
    if (!dc->funcs->pEscape) goto done;

    segin	= (SEGPTR)lpszInData;
    segout	= (SEGPTR)lpvOutData;
    switch (nEscape) {
    	/* Escape(hdc,QUERYESCSUPPORT,LPINT,NULL) */
        /* Escape(hdc,CLIP_TO_PATH,LPINT,NULL) */
    case QUERYESCSUPPORT:
    case CLIP_TO_PATH:
      {
    	LPINT16 x = (LPINT16)SEGPTR_NEW(INT16);
	*x = *(INT*)lpszInData;
	segin = SEGPTR_GET(x);
 	cbInput = sizeof(INT16);
	break;
      }

    	/* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT32) */
    	/* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT32) */
    	/* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT32) */

    case GETSCALINGFACTOR:
    case GETPHYSPAGESIZE:
    case GETPRINTINGOFFSET:
	segout = SEGPTR_GET(SEGPTR_NEW(POINT16));
	cbInput = sizeof(POINT16);
	break;

        /* Escape(hdc,EXT_DEVICE_CAPS,LPINT,LPDWORD) */
    case EXT_DEVICE_CAPS:
      {
    	LPINT16 lpIndex = (LPINT16)SEGPTR_NEW(INT16);
	LPDWORD lpCaps = (LPDWORD)SEGPTR_NEW(DWORD);
	*lpIndex = *(INT*)lpszInData;
	
	segin = SEGPTR_GET(lpIndex);
	segout = SEGPTR_GET(lpCaps);
 	cbInput = sizeof(INT16);
	break;
      }

        /* Escape(hdc,SETLINECAP,LPINT,LPINT) */
    case SETLINECAP:
    case SETLINEJOIN:
    case SETMITERLIMIT:
      {
    	LPINT16 new = (LPINT16)SEGPTR_NEW(INT16);
    	LPINT16 old = (LPINT16)SEGPTR_NEW(INT16);
	*new = *(INT*)lpszInData;
	segin = SEGPTR_GET(new);
	segout = SEGPTR_GET(old);
 	cbInput = sizeof(INT16);
	break;
      }
      /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
    case GETTECHNOLOGY: {
        segout = SEGPTR_GET(SEGPTR_ALLOC(200)); /* enough I hope */
        break;

    }

      /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */

    case ENABLEPAIRKERNING: {
        LPINT16 enab = SEGPTR_NEW(INT16);
        segout = SEGPTR_GET(SEGPTR_NEW(INT16));
        segin = SEGPTR_GET(enab);
        *enab = *(INT*)lpszInData;
	cbInput = sizeof(INT16);
        break;
    }

      /* Escape(hdc,GETFACENAME,NULL,LPSTR); */

    case GETFACENAME: {
        segout = SEGPTR_GET(SEGPTR_ALLOC(200));
        break;
    }

      /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFOA);
       * lpvOutData is actually a pointer to the DocInfo structure and used as
       * a second input parameter
       */

    case STARTDOC: /* string may not be \0 terminated */
        if(lpszInData) {
	    char *cp = SEGPTR_ALLOC(cbInput);
	    memcpy(cp, lpszInData, cbInput);
	    segin = SEGPTR_GET(cp);
	} else
	    segin = 0;

	if(lpvOutData) {
	    DOCINFO16 *lpsegdoc = SEGPTR_NEW(DOCINFO16);
	    DOCINFOA *lpdoc = lpvOutData;
	    memset(lpsegdoc, 0, sizeof(*lpsegdoc));
	    lpsegdoc->cbSize = sizeof(*lpsegdoc);
	    lpsegdoc->lpszDocName = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDocName));
	    lpsegdoc->lpszOutput = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszOutput));
	    lpsegdoc->lpszDatatype = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDatatype));
	    lpsegdoc->fwType = lpdoc->fwType;
	    segout = SEGPTR_GET(lpsegdoc);
	}
	break;

    case SETABORTPROC:
        SetAbortProc(hdc, (ABORTPROC)lpszInData);
	break;

      /* Escape(hdc,END_PATH,PATHINFO,NULL); */
    case END_PATH:
      {
        BYTE *p = SEGPTR_ALLOC(cbInput);
	memcpy(p, lpszInData, cbInput);
	segin = SEGPTR_GET(p);
	break;
      }

    default:
        break;

    }

    ret = dc->funcs->pEscape( dc, nEscape, cbInput, segin, segout );

    switch(nEscape) {
    case QUERYESCSUPPORT:
    	if (ret)
		TRACE("target DC implements Escape %d\n",nEscape);
    	SEGPTR_FREE(MapSL(segin));
	break;

    case SETLINECAP:
    case SETLINEJOIN:
    case SETMITERLIMIT:
        *(LPINT)lpvOutData = *(LPINT16)MapSL(segout);
        SEGPTR_FREE(MapSL(segin));
	SEGPTR_FREE(MapSL(segout));
	break;
    case GETSCALINGFACTOR:
    case GETPRINTINGOFFSET:
    case GETPHYSPAGESIZE: {
    	LPPOINT16 x = MapSL(segout);
	CONV_POINT16TO32(x,(LPPOINT)lpvOutData);
	SEGPTR_FREE(x);
	break;
    }
    case EXT_DEVICE_CAPS:
        *(LPDWORD)lpvOutData = *(LPDWORD)MapSL(segout);
        SEGPTR_FREE(MapSL(segin));
        SEGPTR_FREE(MapSL(segout));
	break;

    case GETTECHNOLOGY: {
        LPSTR x=MapSL(segout);
        strcpy(lpvOutData,x);
        SEGPTR_FREE(x);
	break;
    }
    case ENABLEPAIRKERNING: {
        LPINT16 enab = MapSL(segout);

        *(LPINT)lpvOutData = *enab;
        SEGPTR_FREE(enab);
        SEGPTR_FREE(MapSL(segin));
	break;
    }
    case GETFACENAME: {
        LPSTR x = (LPSTR)MapSL(segout);
        strcpy(lpvOutData,x);
        SEGPTR_FREE(x);
        break;
    }
    case STARTDOC: {
        DOCINFO16 *doc = MapSL(segout);
	SEGPTR_FREE(MapSL(doc->lpszDocName));
	SEGPTR_FREE(MapSL(doc->lpszOutput));
	SEGPTR_FREE(MapSL(doc->lpszDatatype));
	SEGPTR_FREE(doc);
	SEGPTR_FREE(MapSL(segin));
	break;
    }

    case CLIP_TO_PATH:
    case END_PATH:
        SEGPTR_FREE(MapSL(segin));
	break;

    default:
    	break;
    }
 done:
    GDI_ReleaseObj( hdc );
    return ret;
}

/******************************************************************************
 *		ExtEscape	[GDI32.95]
 *
 * PARAMS
 *    hdc         [I] Handle to device context
 *    nEscape     [I] Escape function
 *    cbInput     [I] Number of bytes in input structure
 *    lpszInData  [I] Pointer to input structure
 *    cbOutput    [I] Number of bytes in output structure
 *    lpszOutData [O] Pointer to output structure
 *
 * RETURNS
 *    Success: >0
 *    Not implemented: 0
 *    Failure: <0
 */
INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput, 
		      LPCSTR lpszInData, INT cbOutput, LPSTR lpszOutData )
{
    char *inBuf, *outBuf;
    INT ret;

    inBuf = SEGPTR_ALLOC(cbInput);
    memcpy(inBuf, lpszInData, cbInput);
    outBuf = cbOutput ? SEGPTR_ALLOC(cbOutput) : NULL;
    ret = Escape16( hdc, nEscape, cbInput, SEGPTR_GET(inBuf),
		    SEGPTR_GET(outBuf) );
    SEGPTR_FREE(inBuf);
    if(outBuf) {
	memcpy(lpszOutData, outBuf, cbOutput);
	SEGPTR_FREE(outBuf);
    }
    return ret;
}

/*******************************************************************
 *      DrawEscape [GDI32.74]
 *
 *
 */
INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
{
    FIXME("DrawEscape, stub\n");
    return 0;
}
