mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 22:50:43 +00:00
2a2321bbca
Added syslevel locking for GDI operations. Propagate the changes through the graphics code.
289 lines
7.2 KiB
C
289 lines
7.2 KiB
C
/*
|
|
* 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 "dc.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;
|
|
}
|