Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

523 lines
13 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: MetaSup.c
  3. *
  4. * This file contains the routines for playing the GDI metafile. Most of these
  5. * routines are adopted from windows gdi code. Most of the code is from
  6. * win3.0 except for the GetEvent code which is taken from win2.1
  7. *
  8. *
  9. * Public Functions:
  10. * EnumMetaFile
  11. * Private Functions:
  12. *
  13. *
  14. * Created: 02-Jul-1991
  15. *
  16. * Copyright (c) 1985, 1991 Microsoft Corporation
  17. *
  18. * History:
  19. * 02-Jul-1991 -by- John Colleran [johnc]
  20. * Combined From Win 3.1 and WLO 1.0 sources
  21. \***************************************************************************/
  22. #include <windows.h>
  23. #include "gdi16.h"
  24. extern HANDLE hFirstMetaFile;
  25. extern HDC hScreenDC;
  26. #define MYSTOCKBITMAP (SYSTEM_FIXED_FONT+1)
  27. #define MYSTOCKRGN (SYSTEM_FIXED_FONT+2)
  28. #define CNT_GDI_STOCK_OBJ (MYSTOCKRGN+1)
  29. HANDLE ahStockObject[CNT_GDI_STOCK_OBJ] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  30. HBITMAP hStaticBitmap;
  31. // Provide a Mapping from Object type to a stock object; See GetCurObject
  32. int mpObjectToStock[] =
  33. { -1, // UNUSED 0
  34. WHITE_PEN, // OBJ_PEN 1
  35. BLACK_BRUSH, // OBJ_BRUSH 2
  36. -1, // OBJ_DC 3
  37. -1, // OBJ_METADC 4
  38. DEFAULT_PALETTE, // OBJ_PALETTE 5
  39. SYSTEM_FONT, // OBJ_FONT 6
  40. MYSTOCKBITMAP, // OBJ_BITMAP 7
  41. MYSTOCKRGN, // OBJ_RGN 8 //!!!!! init
  42. -1, // OBJ_METAFILE 9
  43. -1 }; // OBJ_MEMDC 10
  44. HANDLE INTERNAL GetCurObject(HDC hdc, WORD wObjType)
  45. {
  46. HANDLE cur;
  47. //!!!!! fix to work with meta DCs as well
  48. GdiLogFunc3( " GetCurObject" );
  49. ASSERTGDI( wObjType <= MAX_OBJ, "GetCurObject invalid Obj" );
  50. //!!!!! fix regions when new API is done
  51. if( wObjType == OBJ_RGN )
  52. {
  53. return(0);
  54. }
  55. if( wObjType == OBJ_PALETTE)
  56. {
  57. cur = SelectPalette( hdc, ahStockObject[DEFAULT_PALETTE], FALSE );
  58. SelectPalette( hdc, cur, FALSE );
  59. }
  60. else
  61. {
  62. cur = SelectObject(hdc,ahStockObject[mpObjectToStock[wObjType]]);
  63. SelectObject( hdc, cur );
  64. }
  65. ASSERTGDIW( cur, "GetCurObect Failed. Type %d", wObjType );
  66. return(cur);
  67. }
  68. #if 0 // this is going to gdi.dll
  69. /******************************** Public Function **************************\
  70. * BOOL GDIENTRY EnumMetaFile(hmf)
  71. *
  72. * The EnumMetaFile function enumerates the GDI calls within the metafile
  73. * identified by the hMF parameter. The EnumMetaFile function retrieves each
  74. * GDI call within the metafile and passes it to the function pointed to by the
  75. * lpCallbackFunc parameter. This callback function, an application-supplied
  76. * function, can process each GDI call as desired. Enumeration continues until
  77. * there are no more GDI calls or the callback function returns zero.
  78. *
  79. *
  80. * Effects:
  81. *
  82. \***************************************************************************/
  83. BOOL GDIENTRY EnumMetaFile(hdc, hMF, lpCallbackFunction, lpClientData)
  84. HDC hdc;
  85. LOCALHANDLE hMF;
  86. FARPROC lpCallbackFunction;
  87. LPBYTE lpClientData;
  88. {
  89. WORD i;
  90. WORD noObjs;
  91. BOOL bPrint=TRUE;
  92. HANDLE hObject;
  93. HANDLE hLBrush;
  94. HANDLE hLPen;
  95. HANDLE hLFont;
  96. HANDLE hRegion;
  97. HANDLE hPalette;
  98. LPMETAFILE lpMF;
  99. LPMETARECORD lpMR = NULL;
  100. LPHANDLETABLE lpHandleTable = NULL;
  101. GLOBALHANDLE hHandleTable = NULL;
  102. GdiLogFunc( "EnumMetaFile");
  103. if (!ISDCVALID(hdc))
  104. {
  105. ASSERTGDI( FALSE, "EnumMetaFile: DC is invalid");
  106. return (FALSE);
  107. }
  108. /* use GlobalFix() instead of GlobalLock() to insure that the
  109. ** memory never moves, keeping our aliased selector pointing to the
  110. ** right place
  111. */
  112. // !!!!! replaced GlobalFix with GlobalLock
  113. if (hMF && (lpMF = (LPMETAFILE)(DWORD)(0xFFFF0000 & (DWORD)GlobalLock(hMF))))
  114. {
  115. if ((noObjs = lpMF->MetaFileHeader.mtNoObjects) > 0)
  116. {
  117. if (!(hHandleTable =
  118. GlobalAlloc((WORD)(GMEM_ZEROINIT | GMEM_MOVEABLE), (LONG)
  119. ((sizeof(HANDLE) * lpMF->MetaFileHeader.mtNoObjects) +
  120. sizeof(WORD)))))
  121. {
  122. goto ABRRT2;
  123. }
  124. lpHandleTable = (LPHANDLETABLE)GlobalLock(hHandleTable);
  125. }
  126. /* only do object save/reselect for real DC's */
  127. if (hdc && !ISMETADC(hdc))
  128. {
  129. hLPen = GetCurObject( hdc, OBJ_PEN ); /* save the old objects so */
  130. hLBrush = GetCurObject( hdc, OBJ_BRUSH); /* we can put them back */
  131. hLFont = GetCurObject( hdc, OBJ_FONT);
  132. hRegion = GetCurObject( hdc, OBJ_RGN);
  133. hPalette = GetCurObject( hdc, OBJ_PALETTE);
  134. }
  135. while(lpMR = GetEvent(lpMF, lpMR, FALSE))
  136. {
  137. typedef int (FAR PASCAL *ENUMPROC)(HDC, LPHANDLETABLE, LPMETARECORD, int, LPBYTE);
  138. if ((bPrint = (*((ENUMPROC)lpCallbackFunction))(hdc, lpHandleTable, lpMR, noObjs, lpClientData))
  139. == 0)
  140. {
  141. GetEvent(lpMF,lpMR,TRUE);
  142. break;
  143. }
  144. }
  145. if (hdc && !ISMETADC(hdc))
  146. {
  147. SelectObject(hdc, hLPen);
  148. SelectObject(hdc, hLBrush);
  149. SelectObject(hdc, hLFont);
  150. if (hRegion)
  151. SelectObject(hdc, hRegion);
  152. SelectPalette(hdc, hPalette, 0);
  153. }
  154. for(i = 0; i < lpMF->MetaFileHeader.mtNoObjects; ++i)
  155. if (hObject = lpHandleTable->objectHandle[i])
  156. DeleteObject(hObject);
  157. if (hHandleTable)
  158. {
  159. GlobalUnlock(hHandleTable);
  160. GlobalFree(hHandleTable);
  161. }
  162. ABRRT2:;
  163. GlobalUnfix(hMF);
  164. }
  165. return(bPrint);
  166. }
  167. #endif // this is going to gdi.dll
  168. /***************************** Internal Function **************************\
  169. * BOOL FAR PASCAL PlayIntoAMetafile
  170. *
  171. * if this record is being played into another metafile, simply record
  172. * it into that metafile, without hassling with a real playing.
  173. *
  174. * Returns: TRUE if record was played (copied) into another metafile
  175. * FALESE if destination DC was a real (non-meta) DC
  176. *
  177. * Effects: ?
  178. *
  179. * Warnings: ?
  180. *
  181. \***************************************************************************/
  182. BOOL INTERNAL PlayIntoAMetafile(LPMETARECORD lpMR, HDC hdcDest)
  183. {
  184. GdiLogFunc3( " PlayIntoAMetafile");
  185. if (!ISMETADC(hdcDest))
  186. return(FALSE);
  187. else
  188. {
  189. /* the size is the same minus 3 words for the record header */
  190. RecordParms(hdcDest, lpMR->rdFunction, (DWORD)lpMR->rdSize - 3,
  191. (LPWORD)&(lpMR->rdParm[0]));
  192. return(TRUE);
  193. }
  194. }
  195. BOOL INTERNAL IsDCValid(HDC hdc)
  196. {
  197. NPMETARECORDER npdc;
  198. hdc = (HDC)HANDLEFROMMETADC(hdc);
  199. // Is the DC a valid Real DC
  200. switch (GetObjectType(hdc))
  201. {
  202. case OBJ_DC:
  203. case OBJ_METADC:
  204. case OBJ_MEMDC:
  205. return(TRUE);
  206. break;
  207. }
  208. // Is the DC a GDI16 metafile DC
  209. if (npdc = (NPMETARECORDER)LocalLock(hdc))
  210. {
  211. if( npdc->metaDCHeader.ident == ID_METADC )
  212. return(TRUE);
  213. }
  214. ASSERTGDI(FALSE, "Invalid DC");
  215. return(FALSE);
  216. }
  217. /***************************** Internal Function **************************\
  218. * IsMetaDC(hdc)
  219. *
  220. *
  221. * Returns TRUE iff hdc is a valid GDI16 Metafile
  222. *
  223. *
  224. \***************************************************************************/
  225. BOOL INTERNAL IsMetaDC(HDC hdc)
  226. {
  227. NPMETARECORDER npdc;
  228. BOOL fMeta = FALSE;
  229. GdiLogFunc3(" IsMetaDC");
  230. if( ((UINT)hdc) & METADCBIT )
  231. if( npdc = (NPMETARECORDER)LocalLock( (HANDLE)HANDLEFROMMETADC(hdc)))
  232. {
  233. if( npdc->metaDCHeader.ident == ID_METADC )
  234. fMeta = TRUE;
  235. LocalUnlock( (HANDLE)HANDLEFROMMETADC(hdc) );
  236. }
  237. return( fMeta );
  238. }
  239. /***************************** Public Function ****************************\
  240. * HANDLE INTERNAL GetPMetaFile( HDC hdc )
  241. *
  242. * if hdc is a DC it is validated as a metafile
  243. * if hdc is a PALETTE the metafile the palette is selected into is returned
  244. *
  245. * Returns:
  246. * -1 iff Error
  247. * HANDLE to metafile if valid meta DC
  248. * 0 if valid object
  249. *
  250. * Effects:
  251. *
  252. * History:
  253. * 08-Jul-1991 -by- John Colleran [johnc]
  254. * Wrote it.
  255. \***************************************************************************/
  256. HANDLE INTERNAL GetPMetaFile( HDC hdc )
  257. {
  258. NPMETARECORDER npMR;
  259. GdiLogFunc3( " GetPMetaFile");
  260. if( hdc & METADCBIT )
  261. {
  262. if( npMR = (NPMETARECORDER)LocalLock(HANDLEFROMMETADC(hdc)) )
  263. {
  264. if(npMR->metaDCHeader.ident == ID_METADC )
  265. {
  266. LocalUnlock(HANDLEFROMMETADC(hdc));
  267. return( HANDLEFROMMETADC(hdc) );
  268. }
  269. LocalUnlock(HANDLEFROMMETADC(hdc));
  270. }
  271. }
  272. // is hdc really a palette or object for the strange no-DC APIs
  273. // Validate the object is real
  274. if( (hdc != (HDC)NULL) && (GetObjectType( hdc ) == 0))
  275. {
  276. extern int iLogLevel; // Gdi.asm
  277. // WinWord has a bug where it deletes valid objects so
  278. // only log this error if the loglevel is high.
  279. ASSERTGDI( (iLogLevel < 5), "GetPMetaFile: Invalid metafile or object")
  280. return( -1 ); // Not a valid object
  281. }
  282. else
  283. return( 0 ); // Valid Object
  284. }
  285. BOOL INTERNAL IsObjectStock(HANDLE hObj)
  286. {
  287. int ii;
  288. // handle Bitmaps and regions !!!!!
  289. // Get all the Stock Objects
  290. for( ii=WHITE_BRUSH; ii<=NULL_PEN; ii++ )
  291. if( ahStockObject[ii] == hObj )
  292. return( TRUE );
  293. for( ii=OEM_FIXED_FONT; ii<=SYSTEM_FIXED_FONT; ii++ )
  294. if( ahStockObject[ii] == hObj )
  295. return( TRUE );
  296. return( FALSE );
  297. }
  298. /***************************** Internal Function **************************\
  299. * GetObjectAndType
  300. *
  301. *
  302. * Returns the object type, eg OBJ_FONT, as well as a the LogObject
  303. *
  304. *
  305. \***************************************************************************/
  306. int INTERNAL GetObjectAndType(HANDLE hObj, LPSTR lpObjectBuf)
  307. {
  308. int iObj = -1;
  309. GdiLogFunc3( " GetObjectAndType" );
  310. GetObject(hObj, MAXOBJECTSIZE, lpObjectBuf);
  311. switch( iObj = (int)GetObjectType(hObj) )
  312. {
  313. case OBJ_PEN:
  314. case OBJ_BITMAP:
  315. case OBJ_BRUSH:
  316. case OBJ_FONT:
  317. break;
  318. // Watch out for Palettes; returns the number of entries.
  319. case OBJ_PALETTE:
  320. GetPaletteEntries( hObj, 0, 1, (LPPALETTEENTRY)lpObjectBuf );
  321. iObj = OBJ_PALETTE;
  322. break;
  323. case OBJ_RGN:
  324. break;
  325. default:
  326. ASSERTGDIW( 0, "GetObject unknown object type: %d", iObj);
  327. break;
  328. }
  329. return( iObj );
  330. }
  331. /***************************** Internal Function **************************\
  332. * BOOL GDIENTRY InitializeGdi
  333. *
  334. * Initializes the GDI16.exe
  335. *
  336. *
  337. * Effects:
  338. *
  339. * Returns: TRUE iff GDI was initilized successfully
  340. *
  341. \***************************************************************************/
  342. BOOL INTERNAL InitializeGdi(void)
  343. {
  344. BOOL status;
  345. int ii;
  346. GdiLogFunc2 ( " InitializeGDI");
  347. if( !(hScreenDC = CreateCompatibleDC(NULL)))
  348. goto ExitInit;
  349. // Get all the Stock Objects
  350. for( ii=WHITE_BRUSH; ii<=NULL_PEN; ii++ )
  351. ahStockObject[ii] = GetStockObject( ii );
  352. for( ii=OEM_FIXED_FONT; ii<=SYSTEM_FIXED_FONT; ii++ )
  353. ahStockObject[ii] = GetStockObject( ii );
  354. // Create a fake Stock Region and Bitmap
  355. ahStockObject[MYSTOCKRGN] = CreateRectRgn(1,1,3,3);
  356. hStaticBitmap = ahStockObject[MYSTOCKBITMAP] = CreateBitmap(1,1,1,1,NULL);
  357. status = TRUE;
  358. ExitInit:
  359. ASSERTGDI( status, "GDI16 Failed to initialized correctly");
  360. return( status );
  361. }
  362. /***************************************************************************
  363. debugging support
  364. ***************************************************************************/
  365. #ifdef DEBUG
  366. void dDbgOut(int iLevel, LPSTR lpszFormat, ...)
  367. {
  368. char buf[256];
  369. char far *lpcLogLevel;
  370. extern int iLogLevel; // Gdi.asm
  371. extern int iBreakLevel; // Gdi.asm
  372. // Get the external logging level from the emulated ROM
  373. (LONG)lpcLogLevel = 0x00400042;
  374. if (*lpcLogLevel >= '0' && *lpcLogLevel <= '9')
  375. iLogLevel = (*lpcLogLevel-'0')*10+(*(lpcLogLevel+1)-'0');
  376. if (iLevel<=iLogLevel)
  377. {
  378. OutputDebugString(" W16GDI:");
  379. wvsprintf(buf, lpszFormat, (LPSTR)(&lpszFormat + 1));
  380. OutputDebugString(buf);
  381. OutputDebugString("\r\n");
  382. if( iLevel<=iBreakLevel )
  383. _asm int 3;
  384. }
  385. }
  386. void dDbgAssert(LPSTR str, LPSTR file, int line)
  387. {
  388. static char buf3[256];
  389. wsprintf(buf3, "Assertion FAILED: %s %d : %s", file, line, str );
  390. OutputDebugString(buf3);
  391. OutputDebugString("\r\n");
  392. _asm int 3;
  393. }
  394. #undef LocalLock
  395. #undef LocalUnlock
  396. #undef LocalAlloc
  397. #undef GlobalLock
  398. #undef GlobalUnlock
  399. #undef GlobalAlloc
  400. PSTR INTERNAL _LocalLock(HANDLE h )
  401. {
  402. PSTR p;
  403. dDbgOut(7, "LocalLock 0x%X", h );
  404. p = LocalLock(h);
  405. if( p == NULL )
  406. _asm int 3
  407. return( p );
  408. }
  409. BOOL INTERNAL _LocalUnlock(HANDLE h )
  410. {
  411. dDbgOut(7, "LocalUnlock 0x%X", h );
  412. return( LocalUnlock(h) );
  413. }
  414. HANDLE INTERNAL _LocalAlloc(WORD w, WORD w2)
  415. {
  416. dDbgOut(7, "LocalAlloc");
  417. return( LocalAlloc(w,w2) );
  418. }
  419. LPSTR INTERNAL _GlobalLock(HANDLE h )
  420. {
  421. dDbgOut(7, "GlobalLock 0x%X", h );
  422. return( GlobalLock(h) );
  423. }
  424. BOOL INTERNAL _GlobalUnlock(HANDLE h )
  425. {
  426. dDbgOut(7, "GlobalUnlock 0x%X", h );
  427. return( GlobalUnlock(h) );
  428. }
  429. HANDLE INTERNAL _GlobalAlloc(WORD w, DWORD dw )
  430. {
  431. dDbgOut(7, "GlobalAlloc");
  432. return( GlobalAlloc(w,dw) );
  433. }
  434. #endif