windows-nt/Source/XPSP1/NT/base/mvdm/wow16/gdi/metasup.c
2020-09-26 16:20:57 +08:00

524 lines
13 KiB
C

/****************************** Module Header ******************************\
* Module Name: MetaSup.c
*
* This file contains the routines for playing the GDI metafile. Most of these
* routines are adopted from windows gdi code. Most of the code is from
* win3.0 except for the GetEvent code which is taken from win2.1
*
*
* Public Functions:
* EnumMetaFile
* Private Functions:
*
*
* Created: 02-Jul-1991
*
* Copyright (c) 1985, 1991 Microsoft Corporation
*
* History:
* 02-Jul-1991 -by- John Colleran [johnc]
* Combined From Win 3.1 and WLO 1.0 sources
\***************************************************************************/
#include <windows.h>
#include "gdi16.h"
extern HANDLE hFirstMetaFile;
extern HDC hScreenDC;
#define MYSTOCKBITMAP (SYSTEM_FIXED_FONT+1)
#define MYSTOCKRGN (SYSTEM_FIXED_FONT+2)
#define CNT_GDI_STOCK_OBJ (MYSTOCKRGN+1)
HANDLE ahStockObject[CNT_GDI_STOCK_OBJ] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
HBITMAP hStaticBitmap;
// Provide a Mapping from Object type to a stock object; See GetCurObject
int mpObjectToStock[] =
{ -1, // UNUSED 0
WHITE_PEN, // OBJ_PEN 1
BLACK_BRUSH, // OBJ_BRUSH 2
-1, // OBJ_DC 3
-1, // OBJ_METADC 4
DEFAULT_PALETTE, // OBJ_PALETTE 5
SYSTEM_FONT, // OBJ_FONT 6
MYSTOCKBITMAP, // OBJ_BITMAP 7
MYSTOCKRGN, // OBJ_RGN 8 //!!!!! init
-1, // OBJ_METAFILE 9
-1 }; // OBJ_MEMDC 10
HANDLE INTERNAL GetCurObject(HDC hdc, WORD wObjType)
{
HANDLE cur;
//!!!!! fix to work with meta DCs as well
GdiLogFunc3( " GetCurObject" );
ASSERTGDI( wObjType <= MAX_OBJ, "GetCurObject invalid Obj" );
//!!!!! fix regions when new API is done
if( wObjType == OBJ_RGN )
{
return(0);
}
if( wObjType == OBJ_PALETTE)
{
cur = SelectPalette( hdc, ahStockObject[DEFAULT_PALETTE], FALSE );
SelectPalette( hdc, cur, FALSE );
}
else
{
cur = SelectObject(hdc,ahStockObject[mpObjectToStock[wObjType]]);
SelectObject( hdc, cur );
}
ASSERTGDIW( cur, "GetCurObect Failed. Type %d", wObjType );
return(cur);
}
#if 0 // this is going to gdi.dll
/******************************** Public Function **************************\
* BOOL GDIENTRY EnumMetaFile(hmf)
*
* The EnumMetaFile function enumerates the GDI calls within the metafile
* identified by the hMF parameter. The EnumMetaFile function retrieves each
* GDI call within the metafile and passes it to the function pointed to by the
* lpCallbackFunc parameter. This callback function, an application-supplied
* function, can process each GDI call as desired. Enumeration continues until
* there are no more GDI calls or the callback function returns zero.
*
*
* Effects:
*
\***************************************************************************/
BOOL GDIENTRY EnumMetaFile(hdc, hMF, lpCallbackFunction, lpClientData)
HDC hdc;
LOCALHANDLE hMF;
FARPROC lpCallbackFunction;
LPBYTE lpClientData;
{
WORD i;
WORD noObjs;
BOOL bPrint=TRUE;
HANDLE hObject;
HANDLE hLBrush;
HANDLE hLPen;
HANDLE hLFont;
HANDLE hRegion;
HANDLE hPalette;
LPMETAFILE lpMF;
LPMETARECORD lpMR = NULL;
LPHANDLETABLE lpHandleTable = NULL;
GLOBALHANDLE hHandleTable = NULL;
GdiLogFunc( "EnumMetaFile");
if (!ISDCVALID(hdc))
{
ASSERTGDI( FALSE, "EnumMetaFile: DC is invalid");
return (FALSE);
}
/* use GlobalFix() instead of GlobalLock() to insure that the
** memory never moves, keeping our aliased selector pointing to the
** right place
*/
// !!!!! replaced GlobalFix with GlobalLock
if (hMF && (lpMF = (LPMETAFILE)(DWORD)(0xFFFF0000 & (DWORD)GlobalLock(hMF))))
{
if ((noObjs = lpMF->MetaFileHeader.mtNoObjects) > 0)
{
if (!(hHandleTable =
GlobalAlloc((WORD)(GMEM_ZEROINIT | GMEM_MOVEABLE), (LONG)
((sizeof(HANDLE) * lpMF->MetaFileHeader.mtNoObjects) +
sizeof(WORD)))))
{
goto ABRRT2;
}
lpHandleTable = (LPHANDLETABLE)GlobalLock(hHandleTable);
}
/* only do object save/reselect for real DC's */
if (hdc && !ISMETADC(hdc))
{
hLPen = GetCurObject( hdc, OBJ_PEN ); /* save the old objects so */
hLBrush = GetCurObject( hdc, OBJ_BRUSH); /* we can put them back */
hLFont = GetCurObject( hdc, OBJ_FONT);
hRegion = GetCurObject( hdc, OBJ_RGN);
hPalette = GetCurObject( hdc, OBJ_PALETTE);
}
while(lpMR = GetEvent(lpMF, lpMR, FALSE))
{
typedef int (FAR PASCAL *ENUMPROC)(HDC, LPHANDLETABLE, LPMETARECORD, int, LPBYTE);
if ((bPrint = (*((ENUMPROC)lpCallbackFunction))(hdc, lpHandleTable, lpMR, noObjs, lpClientData))
== 0)
{
GetEvent(lpMF,lpMR,TRUE);
break;
}
}
if (hdc && !ISMETADC(hdc))
{
SelectObject(hdc, hLPen);
SelectObject(hdc, hLBrush);
SelectObject(hdc, hLFont);
if (hRegion)
SelectObject(hdc, hRegion);
SelectPalette(hdc, hPalette, 0);
}
for(i = 0; i < lpMF->MetaFileHeader.mtNoObjects; ++i)
if (hObject = lpHandleTable->objectHandle[i])
DeleteObject(hObject);
if (hHandleTable)
{
GlobalUnlock(hHandleTable);
GlobalFree(hHandleTable);
}
ABRRT2:;
GlobalUnfix(hMF);
}
return(bPrint);
}
#endif // this is going to gdi.dll
/***************************** Internal Function **************************\
* BOOL FAR PASCAL PlayIntoAMetafile
*
* if this record is being played into another metafile, simply record
* it into that metafile, without hassling with a real playing.
*
* Returns: TRUE if record was played (copied) into another metafile
* FALESE if destination DC was a real (non-meta) DC
*
* Effects: ?
*
* Warnings: ?
*
\***************************************************************************/
BOOL INTERNAL PlayIntoAMetafile(LPMETARECORD lpMR, HDC hdcDest)
{
GdiLogFunc3( " PlayIntoAMetafile");
if (!ISMETADC(hdcDest))
return(FALSE);
else
{
/* the size is the same minus 3 words for the record header */
RecordParms(hdcDest, lpMR->rdFunction, (DWORD)lpMR->rdSize - 3,
(LPWORD)&(lpMR->rdParm[0]));
return(TRUE);
}
}
BOOL INTERNAL IsDCValid(HDC hdc)
{
NPMETARECORDER npdc;
hdc = (HDC)HANDLEFROMMETADC(hdc);
// Is the DC a valid Real DC
switch (GetObjectType(hdc))
{
case OBJ_DC:
case OBJ_METADC:
case OBJ_MEMDC:
return(TRUE);
break;
}
// Is the DC a GDI16 metafile DC
if (npdc = (NPMETARECORDER)LocalLock(hdc))
{
if( npdc->metaDCHeader.ident == ID_METADC )
return(TRUE);
}
ASSERTGDI(FALSE, "Invalid DC");
return(FALSE);
}
/***************************** Internal Function **************************\
* IsMetaDC(hdc)
*
*
* Returns TRUE iff hdc is a valid GDI16 Metafile
*
*
\***************************************************************************/
BOOL INTERNAL IsMetaDC(HDC hdc)
{
NPMETARECORDER npdc;
BOOL fMeta = FALSE;
GdiLogFunc3(" IsMetaDC");
if( ((UINT)hdc) & METADCBIT )
if( npdc = (NPMETARECORDER)LocalLock( (HANDLE)HANDLEFROMMETADC(hdc)))
{
if( npdc->metaDCHeader.ident == ID_METADC )
fMeta = TRUE;
LocalUnlock( (HANDLE)HANDLEFROMMETADC(hdc) );
}
return( fMeta );
}
/***************************** Public Function ****************************\
* HANDLE INTERNAL GetPMetaFile( HDC hdc )
*
* if hdc is a DC it is validated as a metafile
* if hdc is a PALETTE the metafile the palette is selected into is returned
*
* Returns:
* -1 iff Error
* HANDLE to metafile if valid meta DC
* 0 if valid object
*
* Effects:
*
* History:
* 08-Jul-1991 -by- John Colleran [johnc]
* Wrote it.
\***************************************************************************/
HANDLE INTERNAL GetPMetaFile( HDC hdc )
{
NPMETARECORDER npMR;
GdiLogFunc3( " GetPMetaFile");
if( hdc & METADCBIT )
{
if( npMR = (NPMETARECORDER)LocalLock(HANDLEFROMMETADC(hdc)) )
{
if(npMR->metaDCHeader.ident == ID_METADC )
{
LocalUnlock(HANDLEFROMMETADC(hdc));
return( HANDLEFROMMETADC(hdc) );
}
LocalUnlock(HANDLEFROMMETADC(hdc));
}
}
// is hdc really a palette or object for the strange no-DC APIs
// Validate the object is real
if( (hdc != (HDC)NULL) && (GetObjectType( hdc ) == 0))
{
extern int iLogLevel; // Gdi.asm
// WinWord has a bug where it deletes valid objects so
// only log this error if the loglevel is high.
ASSERTGDI( (iLogLevel < 5), "GetPMetaFile: Invalid metafile or object")
return( -1 ); // Not a valid object
}
else
return( 0 ); // Valid Object
}
BOOL INTERNAL IsObjectStock(HANDLE hObj)
{
int ii;
// handle Bitmaps and regions !!!!!
// Get all the Stock Objects
for( ii=WHITE_BRUSH; ii<=NULL_PEN; ii++ )
if( ahStockObject[ii] == hObj )
return( TRUE );
for( ii=OEM_FIXED_FONT; ii<=SYSTEM_FIXED_FONT; ii++ )
if( ahStockObject[ii] == hObj )
return( TRUE );
return( FALSE );
}
/***************************** Internal Function **************************\
* GetObjectAndType
*
*
* Returns the object type, eg OBJ_FONT, as well as a the LogObject
*
*
\***************************************************************************/
int INTERNAL GetObjectAndType(HANDLE hObj, LPSTR lpObjectBuf)
{
int iObj = -1;
GdiLogFunc3( " GetObjectAndType" );
GetObject(hObj, MAXOBJECTSIZE, lpObjectBuf);
switch( iObj = (int)GetObjectType(hObj) )
{
case OBJ_PEN:
case OBJ_BITMAP:
case OBJ_BRUSH:
case OBJ_FONT:
break;
// Watch out for Palettes; returns the number of entries.
case OBJ_PALETTE:
GetPaletteEntries( hObj, 0, 1, (LPPALETTEENTRY)lpObjectBuf );
iObj = OBJ_PALETTE;
break;
case OBJ_RGN:
break;
default:
ASSERTGDIW( 0, "GetObject unknown object type: %d", iObj);
break;
}
return( iObj );
}
/***************************** Internal Function **************************\
* BOOL GDIENTRY InitializeGdi
*
* Initializes the GDI16.exe
*
*
* Effects:
*
* Returns: TRUE iff GDI was initilized successfully
*
\***************************************************************************/
BOOL INTERNAL InitializeGdi(void)
{
BOOL status;
int ii;
GdiLogFunc2 ( " InitializeGDI");
if( !(hScreenDC = CreateCompatibleDC(NULL)))
goto ExitInit;
// Get all the Stock Objects
for( ii=WHITE_BRUSH; ii<=NULL_PEN; ii++ )
ahStockObject[ii] = GetStockObject( ii );
for( ii=OEM_FIXED_FONT; ii<=SYSTEM_FIXED_FONT; ii++ )
ahStockObject[ii] = GetStockObject( ii );
// Create a fake Stock Region and Bitmap
ahStockObject[MYSTOCKRGN] = CreateRectRgn(1,1,3,3);
hStaticBitmap = ahStockObject[MYSTOCKBITMAP] = CreateBitmap(1,1,1,1,NULL);
status = TRUE;
ExitInit:
ASSERTGDI( status, "GDI16 Failed to initialized correctly");
return( status );
}
/***************************************************************************
debugging support
***************************************************************************/
#ifdef DEBUG
void dDbgOut(int iLevel, LPSTR lpszFormat, ...)
{
char buf[256];
char far *lpcLogLevel;
extern int iLogLevel; // Gdi.asm
extern int iBreakLevel; // Gdi.asm
// Get the external logging level from the emulated ROM
(LONG)lpcLogLevel = 0x00400042;
if (*lpcLogLevel >= '0' && *lpcLogLevel <= '9')
iLogLevel = (*lpcLogLevel-'0')*10+(*(lpcLogLevel+1)-'0');
if (iLevel<=iLogLevel)
{
OutputDebugString(" W16GDI:");
wvsprintf(buf, lpszFormat, (LPSTR)(&lpszFormat + 1));
OutputDebugString(buf);
OutputDebugString("\r\n");
if( iLevel<=iBreakLevel )
_asm int 3;
}
}
void dDbgAssert(LPSTR str, LPSTR file, int line)
{
static char buf3[256];
wsprintf(buf3, "Assertion FAILED: %s %d : %s", file, line, str );
OutputDebugString(buf3);
OutputDebugString("\r\n");
_asm int 3;
}
#undef LocalLock
#undef LocalUnlock
#undef LocalAlloc
#undef GlobalLock
#undef GlobalUnlock
#undef GlobalAlloc
PSTR INTERNAL _LocalLock(HANDLE h )
{
PSTR p;
dDbgOut(7, "LocalLock 0x%X", h );
p = LocalLock(h);
if( p == NULL )
_asm int 3
return( p );
}
BOOL INTERNAL _LocalUnlock(HANDLE h )
{
dDbgOut(7, "LocalUnlock 0x%X", h );
return( LocalUnlock(h) );
}
HANDLE INTERNAL _LocalAlloc(WORD w, WORD w2)
{
dDbgOut(7, "LocalAlloc");
return( LocalAlloc(w,w2) );
}
LPSTR INTERNAL _GlobalLock(HANDLE h )
{
dDbgOut(7, "GlobalLock 0x%X", h );
return( GlobalLock(h) );
}
BOOL INTERNAL _GlobalUnlock(HANDLE h )
{
dDbgOut(7, "GlobalUnlock 0x%X", h );
return( GlobalUnlock(h) );
}
HANDLE INTERNAL _GlobalAlloc(WORD w, DWORD dw )
{
dDbgOut(7, "GlobalAlloc");
return( GlobalAlloc(w,dw) );
}
#endif