diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/wow16/gdi/metasup.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/mvdm/wow16/gdi/metasup.c')
-rw-r--r-- | private/mvdm/wow16/gdi/metasup.c | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/private/mvdm/wow16/gdi/metasup.c b/private/mvdm/wow16/gdi/metasup.c new file mode 100644 index 000000000..1989bf44f --- /dev/null +++ b/private/mvdm/wow16/gdi/metasup.c @@ -0,0 +1,523 @@ +/****************************** 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 |