| /* | |
| * 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.@] | |
| */ | |
| 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) */ | |
| /* Escape(hdc,EPSPRINTING,LPINT,NULL) */ | |
| case QUERYESCSUPPORT: | |
| case CLIP_TO_PATH: | |
| case EPSPRINTING: | |
| { | |
| 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.@] | |
| * | |
| * 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.@] | |
| * | |
| * | |
| */ | |
| INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData) | |
| { | |
| FIXME("DrawEscape, stub\n"); | |
| return 0; | |
| } |