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

#include <string.h>
#include "windef.h"
#include "wingdi.h"
#include "gdi.h"
#include "heap.h"
#include "ldt.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(PTR_SEG_TO_LIN(segin));
	break;

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

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

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

    case CLIP_TO_PATH:
    case END_PATH:
        SEGPTR_FREE(PTR_SEG_TO_LIN(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;
}
