Leaked source code of windows server 2003
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.

2133 lines
58 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: metasup.c
  3. *
  4. * OpenGL metafile support
  5. *
  6. * History:
  7. * Thu Feb 23 15:27:47 1995 -by- Drew Bliss [drewb]
  8. * Created
  9. *
  10. * Copyright (c) 1995 Microsoft Corporation
  11. \**************************************************************************/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include <ntpsapi.h>
  15. #include <wingdip.h>
  16. #include "global.h"
  17. #include <glgenwin.h>
  18. #include "metasup.h"
  19. #if defined(GL_METAFILE)
  20. #include <glmf.h>
  21. #include <encoding.h>
  22. GLCLTPROCTABLE gcptGlsProcTable;
  23. GLEXTPROCTABLE geptGlsExtProcTable;
  24. // Functions in GL which we will do device coordinate translation for
  25. typedef struct _GLDEVICEPROCS
  26. {
  27. void (APIENTRY *glBitmap)(GLsizei width, GLsizei height,
  28. GLfloat xorig, GLfloat yorig,
  29. GLfloat xmove, GLfloat ymove,
  30. const GLubyte *bitmap);
  31. void (APIENTRY *glCopyPixels)(GLint x, GLint y,
  32. GLsizei width, GLsizei height,
  33. GLenum type);
  34. void (APIENTRY *glCopyTexImage1D)(GLenum target, GLint level,
  35. GLenum internalformat,
  36. GLint x, GLint y,
  37. GLsizei width, GLint border);
  38. void (APIENTRY *glCopyTexImage2D)(GLenum target, GLint level,
  39. GLenum internalformat,
  40. GLint x, GLint y,
  41. GLsizei width, GLsizei height,
  42. GLint border);
  43. void (APIENTRY *glCopyTexSubImage1D)(GLenum target, GLint level,
  44. GLint xoffset, GLint x, GLint y,
  45. GLsizei width);
  46. void (APIENTRY *glCopyTexSubImage2D)(GLenum target, GLint level,
  47. GLint xoffset, GLint yoffset,
  48. GLint x, GLint y,
  49. GLsizei width, GLsizei height);
  50. void (APIENTRY *glDrawPixels)(GLsizei width, GLsizei height,
  51. GLenum format, GLenum type,
  52. const GLvoid *pixels);
  53. void (APIENTRY *glLineWidth)(GLfloat width);
  54. void (APIENTRY *glPointSize)(GLfloat size);
  55. void (APIENTRY *glScissor)(GLint x, GLint y,
  56. GLsizei width, GLsizei height);
  57. void (APIENTRY *glViewport)(GLint x, GLint y,
  58. GLsizei w, GLsizei h);
  59. } GLDEVICEPROCS;
  60. #define GL_DEVICE_PROCS (sizeof(GLDEVICEPROCS)/sizeof(PROC))
  61. // Opcode for device procs
  62. static GLSopcode glsopDeviceProcs[GL_DEVICE_PROCS] =
  63. {
  64. GLS_OP_glBitmap,
  65. GLS_OP_glCopyPixels,
  66. GLS_OP_glCopyTexImage1D,
  67. GLS_OP_glCopyTexImage2D,
  68. GLS_OP_glCopyTexSubImage1D,
  69. GLS_OP_glCopyTexSubImage2D,
  70. GLS_OP_glDrawPixels,
  71. GLS_OP_glLineWidth,
  72. GLS_OP_glPointSize,
  73. GLS_OP_glScissor,
  74. GLS_OP_glViewport
  75. };
  76. static GLDEVICEPROCS gdpGlsActual;
  77. /*****************************Private*Routine******************************\
  78. *
  79. * GLS recording callbacks
  80. *
  81. * Perfoms any necessary work when capturing a call
  82. *
  83. * History:
  84. * Mon Mar 27 14:21:09 1995 -by- Drew Bliss [drewb]
  85. * Created
  86. *
  87. \**************************************************************************/
  88. void GlsBitmapIn(GLsizei width, GLsizei height,
  89. GLfloat xorig, GLfloat yorig,
  90. GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
  91. {
  92. PLRC plrc;
  93. RECTL rcl;
  94. plrc = GLTEB_CLTCURRENTRC();
  95. ASSERTOPENGL(plrc != NULL, "GlsBitmapIn: No current RC!\n");
  96. // Record bounds for the bitmap
  97. rcl.left = 0;
  98. rcl.top = 0;
  99. rcl.right = width;
  100. rcl.bottom = height;
  101. plrc->prclGlsBounds = &rcl;
  102. gdpGlsActual.glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap);
  103. plrc->prclGlsBounds = NULL;
  104. }
  105. void GlsDrawPixelsIn(GLsizei width, GLsizei height,
  106. GLenum format, GLenum type,
  107. const GLvoid *pixels)
  108. {
  109. PLRC plrc;
  110. RECTL rcl;
  111. plrc = GLTEB_CLTCURRENTRC();
  112. ASSERTOPENGL(plrc != NULL, "GlsBitmapIn: No current RC!\n");
  113. // Record bounds for the bitmap
  114. rcl.left = 0;
  115. rcl.top = 0;
  116. rcl.right = width;
  117. rcl.bottom = height;
  118. plrc->prclGlsBounds = &rcl;
  119. gdpGlsActual.glDrawPixels(width, height, format, type, pixels);
  120. plrc->prclGlsBounds = NULL;
  121. }
  122. void GlsViewportIn(GLint x, GLint y, GLsizei width, GLsizei height)
  123. {
  124. RECTL rcl;
  125. PLRC plrc;
  126. plrc = GLTEB_CLTCURRENTRC();
  127. ASSERTOPENGL(plrc != NULL, "GlsViewportIn: No current RC!\n");
  128. // Send the bounds on
  129. // The rect is inclusive-exclusive while the incoming parameters
  130. // are inclusive-inclusive
  131. rcl.left = x;
  132. rcl.right = x+width+1;
  133. rcl.top = y;
  134. rcl.bottom = y+height+1;
  135. if (!GlGdiAddGlsBounds(plrc->gwidCreate.hdc, &rcl))
  136. {
  137. ASSERTOPENGL(FALSE, "GdiAddGlsBounds failed");
  138. }
  139. gdpGlsActual.glViewport(x, y, width, height);
  140. }
  141. // glViewport is the only device-dependent function that we need to
  142. // do work for on input
  143. static GLDEVICEPROCS gdpInput =
  144. {
  145. GlsBitmapIn,
  146. NULL,
  147. NULL,
  148. NULL,
  149. NULL,
  150. NULL,
  151. GlsDrawPixelsIn,
  152. NULL,
  153. NULL,
  154. NULL,
  155. GlsViewportIn
  156. };
  157. /*****************************Private*Routine******************************\
  158. *
  159. * MetaLoadGls
  160. *
  161. * Loads glmf32.dll for metafile use
  162. *
  163. * History:
  164. * Thu Feb 23 17:40:59 1995 -by- Drew Bliss [drewb]
  165. * Created
  166. *
  167. \**************************************************************************/
  168. static char *pszGlsEntryPoints[] =
  169. {
  170. "glsBeginCapture",
  171. "glsBinary",
  172. "glsCallArrayInContext",
  173. "glsCaptureFlags",
  174. "glsCaptureFunc",
  175. "glsCommandFunc",
  176. "glsContext",
  177. "glsDeleteContext",
  178. "glsEndCapture",
  179. "glsFlush",
  180. "glsGenContext",
  181. "glsGetCaptureDispatchTable",
  182. "glsGetCaptureExecTable",
  183. "glsGetCommandAlignment",
  184. "glsGetCurrentContext",
  185. "glsUpdateCaptureExecTable",
  186. "glsWriteFunc",
  187. "glsBeginGLS",
  188. "glsBlock",
  189. "glsCallStream",
  190. "glsEndGLS",
  191. "glsError",
  192. "glsGLRC",
  193. "glsGLRCLayer",
  194. "glsHeaderGLRCi",
  195. "glsHeaderLayerf",
  196. "glsHeaderLayeri",
  197. "glsHeaderf",
  198. "glsHeaderfv",
  199. "glsHeaderi",
  200. "glsHeaderiv",
  201. "glsHeaderubz",
  202. "glsRequireExtension",
  203. "glsUnsupportedCommand",
  204. "glsAppRef",
  205. "glsBeginObj",
  206. "glsCharubz",
  207. "glsComment",
  208. "glsDisplayMapfv",
  209. "glsEndObj",
  210. "glsNumb",
  211. "glsNumbv",
  212. "glsNumd",
  213. "glsNumdv",
  214. "glsNumf",
  215. "glsNumfv",
  216. "glsNumi",
  217. "glsNumiv",
  218. "glsNuml",
  219. "glsNumlv",
  220. "glsNums",
  221. "glsNumsv",
  222. "glsNumub",
  223. "glsNumubv",
  224. "glsNumui",
  225. "glsNumuiv",
  226. "glsNumul",
  227. "glsNumulv",
  228. "glsNumus",
  229. "glsNumusv",
  230. "glsPad",
  231. "glsSwapBuffers"
  232. };
  233. #define GLS_ENTRY_POINT_STRINGS (sizeof(pszGlsEntryPoints)/sizeof(char *))
  234. typedef struct _GLSENTRYPOINTS
  235. {
  236. GLboolean (APIENTRY *glsBeginCapture)(const GLubyte *, GLSenum,
  237. GLbitfield);
  238. GLSenum (APIENTRY *glsBinary)(GLboolean);
  239. void (APIENTRY *glsCallArrayInContext)(GLuint, GLSenum, size_t,
  240. const GLubyte *);
  241. void (APIENTRY *glsCaptureFlags)(GLSopcode, GLbitfield);
  242. void (APIENTRY *glsCaptureFunc)(GLSenum, GLScaptureFunc);
  243. void (APIENTRY *glsCommandFunc)(GLSopcode, GLSfunc);
  244. void (APIENTRY *glsContext)(GLuint);
  245. void (APIENTRY *glsDeleteContext)(GLuint);
  246. void (APIENTRY *glsEndCapture)(void);
  247. void (APIENTRY *glsFlush)(GLSenum);
  248. GLuint (APIENTRY *glsGenContext)(void);
  249. void (APIENTRY *glsGetCaptureDispatchTable)(GLCLTPROCTABLE *,
  250. GLEXTPROCTABLE *);
  251. void (APIENTRY *glsGetCaptureExecTable)(GLCLTPROCTABLE *,
  252. GLEXTPROCTABLE *);
  253. GLScommandAlignment *
  254. (APIENTRY *glsGetCommandAlignment)(GLSopcode, GLSenum,
  255. GLScommandAlignment *);
  256. GLuint (APIENTRY *glsGetCurrentContext)(void);
  257. void (APIENTRY *glsUpdateCaptureExecTable)(GLCLTPROCTABLE *,
  258. GLEXTPROCTABLE *);
  259. void (APIENTRY *glsWriteFunc)(GLSwriteFunc);
  260. // The following are only used in glsCommandFunc and so don't
  261. // require real prototypes
  262. GLSfunc glsBeginGLS;
  263. GLSfunc glsBlock;
  264. GLSfunc glsCallStream;
  265. GLSfunc glsEndGLS;
  266. GLSfunc glsError;
  267. GLSfunc glsGLRC;
  268. GLSfunc glsGLRCLayer;
  269. GLSfunc glsHeaderGLRCi;
  270. GLSfunc glsHeaderLayerf;
  271. GLSfunc glsHeaderLayeri;
  272. GLSfunc glsHeaderf;
  273. GLSfunc glsHeaderfv;
  274. GLSfunc glsHeaderi;
  275. GLSfunc glsHeaderiv;
  276. GLSfunc glsHeaderubz;
  277. GLSfunc glsRequireExtension;
  278. GLSfunc glsUnsupportedCommand;
  279. GLSfunc glsAppRef;
  280. GLSfunc glsBeginObj;
  281. GLSfunc glsCharubz;
  282. GLSfunc glsComment;
  283. GLSfunc glsDisplayMapfv;
  284. GLSfunc glsEndObj;
  285. GLSfunc glsNumb;
  286. GLSfunc glsNumbv;
  287. GLSfunc glsNumd;
  288. GLSfunc glsNumdv;
  289. GLSfunc glsNumf;
  290. GLSfunc glsNumfv;
  291. GLSfunc glsNumi;
  292. GLSfunc glsNumiv;
  293. GLSfunc glsNuml;
  294. GLSfunc glsNumlv;
  295. GLSfunc glsNums;
  296. GLSfunc glsNumsv;
  297. GLSfunc glsNumub;
  298. GLSfunc glsNumubv;
  299. GLSfunc glsNumui;
  300. GLSfunc glsNumuiv;
  301. GLSfunc glsNumul;
  302. GLSfunc glsNumulv;
  303. GLSfunc glsNumus;
  304. GLSfunc glsNumusv;
  305. GLSfunc glsPad;
  306. GLSfunc glsSwapBuffers;
  307. } GLSENTRYPOINTS;
  308. #define GLS_ENTRY_POINTS (sizeof(GLSENTRYPOINTS)/sizeof(void *))
  309. static GLSENTRYPOINTS gepGlsFuncs = {NULL};
  310. static HMODULE hGlsDll = NULL;
  311. BOOL MetaLoadGls(void)
  312. {
  313. HMODULE hdll;
  314. BOOL bRet = FALSE;
  315. GLSENTRYPOINTS gep;
  316. PROC *ppfn, *ppfnActual, *ppfnInput;
  317. GLSfunc *pgfnNormal, *pgfnExt;
  318. int i;
  319. ASSERTOPENGL(GLS_ENTRY_POINT_STRINGS == GLS_ENTRY_POINTS,
  320. "GLS entry point strings/pointers mismatch\n");
  321. ENTERCRITICALSECTION(&semLocal);
  322. if (hGlsDll != NULL)
  323. {
  324. bRet = TRUE;
  325. goto Exit;
  326. }
  327. hdll = LoadLibrary(__TEXT("glmf32.dll"));
  328. if (hdll == NULL)
  329. {
  330. WARNING1("Unable to load glmf32.dll, %d\n", GetLastError());
  331. goto Exit;
  332. }
  333. ppfn = (PROC *)&gep;
  334. for (i = 0; i < GLS_ENTRY_POINTS; i++)
  335. {
  336. if (!(*ppfn = GetProcAddress(hdll, pszGlsEntryPoints[i])))
  337. {
  338. WARNING1("glmf32.dll is missing '%s'\n", pszGlsEntryPoints[i]);
  339. FreeLibrary(hdll);
  340. goto Exit;
  341. }
  342. ppfn++;
  343. }
  344. // The table copied out is constant as long as the DLL is loaded
  345. gep.glsGetCaptureDispatchTable(&gcptGlsProcTable, &geptGlsExtProcTable);
  346. // Patch the table for certain functions to allow us to
  347. // do some coordinate conversion and bounds accumlation
  348. ppfnActual = (PROC *)&gdpGlsActual;
  349. ppfnInput = (PROC *)&gdpInput;
  350. for (i = 0; i < GL_DEVICE_PROCS; i++)
  351. {
  352. if (*ppfnInput != NULL)
  353. {
  354. ppfn = ((PROC *)&gcptGlsProcTable.glDispatchTable)+
  355. glsopDeviceProcs[i]-GLS_OP_glNewList;
  356. *ppfnActual = *ppfn;
  357. *ppfn = *ppfnInput;
  358. }
  359. ppfnActual++;
  360. ppfnInput++;
  361. }
  362. gepGlsFuncs = gep;
  363. hGlsDll = hdll;
  364. bRet = TRUE;
  365. Exit:
  366. LEAVECRITICALSECTION(&semLocal);
  367. return bRet;
  368. }
  369. /*****************************Private*Routine******************************\
  370. *
  371. * MetaGlProcTables
  372. *
  373. * Returns the GL dispatch tables to use for metafile RC's
  374. *
  375. * History:
  376. * Thu Feb 23 17:40:25 1995 -by- Drew Bliss [drewb]
  377. * Created
  378. *
  379. \**************************************************************************/
  380. void MetaGlProcTables(PGLCLTPROCTABLE *ppgcpt, PGLEXTPROCTABLE *ppgept)
  381. {
  382. ASSERTOPENGL(hGlsDll != NULL, "MetaGlProcTables: GLS not loaded\n");
  383. *ppgcpt = &gcptGlsProcTable;
  384. *ppgept = &geptGlsExtProcTable;
  385. }
  386. /******************************Public*Routine******************************\
  387. *
  388. * MetaSetCltProcTable
  389. *
  390. * Update GLS's generic dispatch tables
  391. *
  392. * History:
  393. * Fri Jan 05 16:40:31 1996 -by- Drew Bliss [drewb]
  394. * Created
  395. *
  396. \**************************************************************************/
  397. void MetaSetCltProcTable(GLCLTPROCTABLE *pgcpt, GLEXTPROCTABLE *pgept)
  398. {
  399. gepGlsFuncs.glsUpdateCaptureExecTable(pgcpt, pgept);
  400. }
  401. /******************************Public*Routine******************************\
  402. *
  403. * MetaGetCltProcTable
  404. *
  405. * Retrieves GLS's generic dispatch tables
  406. *
  407. * History:
  408. * Fri Jan 05 19:14:18 1996 -by- Drew Bliss [drewb]
  409. * Created
  410. *
  411. \**************************************************************************/
  412. void MetaGetCltProcTable(GLCLTPROCTABLE *pgcpt, GLEXTPROCTABLE *pgept)
  413. {
  414. gepGlsFuncs.glsGetCaptureExecTable(pgcpt, pgept);
  415. }
  416. /*****************************Private*Routine******************************\
  417. *
  418. * GlsWriter
  419. *
  420. * GLS write function for metafile support
  421. *
  422. * History:
  423. * Thu Feb 23 15:49:03 1995 -by- Drew Bliss [drewb]
  424. * Created
  425. *
  426. \**************************************************************************/
  427. size_t GlsWriter(size_t cb, CONST BYTE *pb)
  428. {
  429. PLRC plrc;
  430. #if 0
  431. DbgPrint("GlsWriter(%d)\n", cb);
  432. #endif
  433. plrc = GLTEB_CLTCURRENTRC();
  434. if( plrc == NULL )
  435. {
  436. DBGERROR( "GlsWriter: No current RC!\n");
  437. return 0;
  438. }
  439. ASSERTOPENGL(plrc->gwidCreate.hdc != NULL,
  440. "GlsWriter: hdcCreate is NULL\n");
  441. ASSERTOPENGL(gepGlsFuncs.glsGetCurrentContext() ==
  442. plrc->uiGlsCaptureContext,
  443. "GlsWriter: Wrong GLS context\n");
  444. ASSERTOPENGL(plrc->fCapturing == TRUE,
  445. "GlsWriter: Not capturing\n");
  446. if (GlGdiAddGlsRecord(plrc->gwidCreate.hdc,
  447. cb, (BYTE *)pb, plrc->prclGlsBounds))
  448. {
  449. return cb;
  450. }
  451. else
  452. {
  453. return 0;
  454. }
  455. }
  456. /*****************************Private*Routine******************************\
  457. *
  458. * GlsFlush
  459. *
  460. * Post-command GLS callback to flush the GLS stream
  461. *
  462. * History:
  463. * Fri Feb 24 10:12:49 1995 -by- Drew Bliss [drewb]
  464. * Created
  465. *
  466. \**************************************************************************/
  467. void GlsFlush(GLSopcode op)
  468. {
  469. gepGlsFuncs.glsFlush(GLS_LAST);
  470. }
  471. /*****************************Private*Routine******************************\
  472. *
  473. * MetaRcBegin
  474. *
  475. * Start capturing on a metafile
  476. *
  477. * History:
  478. * Thu Feb 23 18:35:32 1995 -by- Drew Bliss [drewb]
  479. * Created
  480. *
  481. \**************************************************************************/
  482. BOOL MetaRcBegin(PLRC plrc, HDC hdc)
  483. {
  484. PLRC plrcOld;
  485. // The GLS commands here will cause data to be written, which
  486. // requires a current RC. The RC is only used for data storage
  487. // so we don't need to set the proc table
  488. plrcOld = GLTEB_CLTCURRENTRC();
  489. GLTEB_SET_CLTCURRENTRC(plrc);
  490. // Set capturing first because the block commands will cause
  491. // GlsWriter calls
  492. plrc->fCapturing = TRUE;
  493. // Start recording
  494. if (!gepGlsFuncs.glsBeginCapture("", gepGlsFuncs.glsBinary(GL_FALSE),
  495. GLS_NONE))
  496. {
  497. plrc->fCapturing = FALSE;
  498. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  499. GLTEB_SET_CLTCURRENTRC(plrcOld);
  500. return FALSE;
  501. }
  502. GLTEB_SET_CLTCURRENTRC(plrcOld);
  503. return TRUE;
  504. }
  505. /*****************************Private*Routine******************************\
  506. *
  507. * MetaRcEnd
  508. *
  509. * Stop capturing on a metafile RC
  510. *
  511. * History:
  512. * Thu Feb 23 17:13:48 1995 -by- Drew Bliss [drewb]
  513. * Created
  514. *
  515. \**************************************************************************/
  516. void MetaRcEnd(PLRC plrc)
  517. {
  518. PLRC plrcOld;
  519. // The GLS commands here will cause data to be written, which
  520. // requires a current RC. The RC is only used for data storage
  521. // so we don't need to set the proc table
  522. plrcOld = GLTEB_CLTCURRENTRC();
  523. GLTEB_SET_CLTCURRENTRC(plrc);
  524. gepGlsFuncs.glsEndCapture();
  525. plrc->fCapturing = FALSE;
  526. GLTEB_SET_CLTCURRENTRC(plrcOld);
  527. }
  528. // Table of operations which GLS should execute when capturing
  529. // in order to return information
  530. // Currently all of them are in the list
  531. // Should we attempt to do only the critical calls?
  532. static GLSopcode opExecuteBits[] =
  533. {
  534. GLS_OP_glAccum,
  535. GLS_OP_glAlphaFunc,
  536. GLS_OP_glAreTexturesResidentEXT,
  537. GLS_OP_glArrayElementEXT,
  538. GLS_OP_glBegin,
  539. GLS_OP_glBindTextureEXT,
  540. GLS_OP_glBitmap,
  541. GLS_OP_glBlendColorEXT,
  542. GLS_OP_glBlendEquationEXT,
  543. GLS_OP_glBlendFunc,
  544. GLS_OP_glCallList,
  545. GLS_OP_glCallLists,
  546. GLS_OP_glClear,
  547. GLS_OP_glClearAccum,
  548. GLS_OP_glClearColor,
  549. GLS_OP_glClearDepth,
  550. GLS_OP_glClearIndex,
  551. GLS_OP_glClearStencil,
  552. GLS_OP_glClipPlane,
  553. GLS_OP_glColor3b,
  554. GLS_OP_glColor3bv,
  555. GLS_OP_glColor3d,
  556. GLS_OP_glColor3dv,
  557. GLS_OP_glColor3f,
  558. GLS_OP_glColor3fv,
  559. GLS_OP_glColor3i,
  560. GLS_OP_glColor3iv,
  561. GLS_OP_glColor3s,
  562. GLS_OP_glColor3sv,
  563. GLS_OP_glColor3ub,
  564. GLS_OP_glColor3ubv,
  565. GLS_OP_glColor3ui,
  566. GLS_OP_glColor3uiv,
  567. GLS_OP_glColor3us,
  568. GLS_OP_glColor3usv,
  569. GLS_OP_glColor4b,
  570. GLS_OP_glColor4bv,
  571. GLS_OP_glColor4d,
  572. GLS_OP_glColor4dv,
  573. GLS_OP_glColor4f,
  574. GLS_OP_glColor4fv,
  575. GLS_OP_glColor4i,
  576. GLS_OP_glColor4iv,
  577. GLS_OP_glColor4s,
  578. GLS_OP_glColor4sv,
  579. GLS_OP_glColor4ub,
  580. GLS_OP_glColor4ubv,
  581. GLS_OP_glColor4ui,
  582. GLS_OP_glColor4uiv,
  583. GLS_OP_glColor4us,
  584. GLS_OP_glColor4usv,
  585. GLS_OP_glColorMask,
  586. GLS_OP_glColorMaterial,
  587. GLS_OP_glColorPointerEXT,
  588. GLS_OP_glColorSubTableEXT,
  589. GLS_OP_glDrawRangeElementsWIN,
  590. GLS_OP_glColorTableParameterfvSGI,
  591. GLS_OP_glColorTableParameterivSGI,
  592. GLS_OP_glColorTableEXT,
  593. GLS_OP_glConvolutionFilter1DEXT,
  594. GLS_OP_glConvolutionFilter2DEXT,
  595. GLS_OP_glConvolutionParameterfEXT,
  596. GLS_OP_glConvolutionParameterfvEXT,
  597. GLS_OP_glConvolutionParameteriEXT,
  598. GLS_OP_glConvolutionParameterivEXT,
  599. GLS_OP_glCopyColorTableSGI,
  600. GLS_OP_glCopyConvolutionFilter1DEXT,
  601. GLS_OP_glCopyConvolutionFilter2DEXT,
  602. GLS_OP_glCopyPixels,
  603. GLS_OP_glCopyTexImage1DEXT,
  604. GLS_OP_glCopyTexImage2DEXT,
  605. GLS_OP_glCopyTexSubImage1DEXT,
  606. GLS_OP_glCopyTexSubImage2DEXT,
  607. GLS_OP_glCopyTexSubImage3DEXT,
  608. GLS_OP_glCullFace,
  609. GLS_OP_glDeleteLists,
  610. GLS_OP_glDeleteTexturesEXT,
  611. GLS_OP_glDepthFunc,
  612. GLS_OP_glDepthMask,
  613. GLS_OP_glDepthRange,
  614. GLS_OP_glDetailTexFuncSGIS,
  615. GLS_OP_glDisable,
  616. GLS_OP_glDrawArraysEXT,
  617. GLS_OP_glDrawBuffer,
  618. GLS_OP_glDrawPixels,
  619. GLS_OP_glEdgeFlag,
  620. GLS_OP_glEdgeFlagPointerEXT,
  621. GLS_OP_glEdgeFlagv,
  622. GLS_OP_glEnable,
  623. GLS_OP_glEnd,
  624. GLS_OP_glEndList,
  625. GLS_OP_glEvalCoord1d,
  626. GLS_OP_glEvalCoord1dv,
  627. GLS_OP_glEvalCoord1f,
  628. GLS_OP_glEvalCoord1fv,
  629. GLS_OP_glEvalCoord2d,
  630. GLS_OP_glEvalCoord2dv,
  631. GLS_OP_glEvalCoord2f,
  632. GLS_OP_glEvalCoord2fv,
  633. GLS_OP_glEvalMesh1,
  634. GLS_OP_glEvalMesh2,
  635. GLS_OP_glEvalPoint1,
  636. GLS_OP_glEvalPoint2,
  637. GLS_OP_glFeedbackBuffer,
  638. GLS_OP_glFinish,
  639. GLS_OP_glFlush,
  640. GLS_OP_glFogf,
  641. GLS_OP_glFogfv,
  642. GLS_OP_glFogi,
  643. GLS_OP_glFogiv,
  644. GLS_OP_glFrontFace,
  645. GLS_OP_glFrustum,
  646. GLS_OP_glGenLists,
  647. GLS_OP_glGenTexturesEXT,
  648. GLS_OP_glGetBooleanv,
  649. GLS_OP_glGetClipPlane,
  650. GLS_OP_glGetColorTableParameterfvEXT,
  651. GLS_OP_glGetColorTableParameterivEXT,
  652. GLS_OP_glGetColorTableEXT,
  653. GLS_OP_glGetConvolutionFilterEXT,
  654. GLS_OP_glGetConvolutionParameterfvEXT,
  655. GLS_OP_glGetConvolutionParameterivEXT,
  656. GLS_OP_glGetDetailTexFuncSGIS,
  657. GLS_OP_glGetDoublev,
  658. GLS_OP_glGetError,
  659. GLS_OP_glGetFloatv,
  660. GLS_OP_glGetHistogramEXT,
  661. GLS_OP_glGetHistogramParameterfvEXT,
  662. GLS_OP_glGetHistogramParameterivEXT,
  663. GLS_OP_glGetIntegerv,
  664. GLS_OP_glGetLightfv,
  665. GLS_OP_glGetLightiv,
  666. GLS_OP_glGetMapdv,
  667. GLS_OP_glGetMapfv,
  668. GLS_OP_glGetMapiv,
  669. GLS_OP_glGetMaterialfv,
  670. GLS_OP_glGetMaterialiv,
  671. GLS_OP_glGetMinmaxEXT,
  672. GLS_OP_glGetMinmaxParameterfvEXT,
  673. GLS_OP_glGetMinmaxParameterivEXT,
  674. GLS_OP_glGetPixelMapfv,
  675. GLS_OP_glGetPixelMapuiv,
  676. GLS_OP_glGetPixelMapusv,
  677. GLS_OP_glGetPointervEXT,
  678. GLS_OP_glGetPolygonStipple,
  679. GLS_OP_glGetSeparableFilterEXT,
  680. GLS_OP_glGetSharpenTexFuncSGIS,
  681. GLS_OP_glGetString,
  682. GLS_OP_glGetTexColorTableParameterfvSGI,
  683. GLS_OP_glGetTexColorTableParameterivSGI,
  684. GLS_OP_glGetTexEnvfv,
  685. GLS_OP_glGetTexEnviv,
  686. GLS_OP_glGetTexGendv,
  687. GLS_OP_glGetTexGenfv,
  688. GLS_OP_glGetTexGeniv,
  689. GLS_OP_glGetTexImage,
  690. GLS_OP_glGetTexLevelParameterfv,
  691. GLS_OP_glGetTexLevelParameteriv,
  692. GLS_OP_glGetTexParameterfv,
  693. GLS_OP_glGetTexParameteriv,
  694. GLS_OP_glHint,
  695. GLS_OP_glHistogramEXT,
  696. GLS_OP_glIndexMask,
  697. GLS_OP_glIndexPointerEXT,
  698. GLS_OP_glIndexd,
  699. GLS_OP_glIndexdv,
  700. GLS_OP_glIndexf,
  701. GLS_OP_glIndexfv,
  702. GLS_OP_glIndexi,
  703. GLS_OP_glIndexiv,
  704. GLS_OP_glIndexs,
  705. GLS_OP_glIndexsv,
  706. GLS_OP_glInitNames,
  707. GLS_OP_glIsEnabled,
  708. GLS_OP_glIsList,
  709. GLS_OP_glIsTextureEXT,
  710. GLS_OP_glLightModelf,
  711. GLS_OP_glLightModelfv,
  712. GLS_OP_glLightModeli,
  713. GLS_OP_glLightModeliv,
  714. GLS_OP_glLightf,
  715. GLS_OP_glLightfv,
  716. GLS_OP_glLighti,
  717. GLS_OP_glLightiv,
  718. GLS_OP_glLineStipple,
  719. GLS_OP_glLineWidth,
  720. GLS_OP_glListBase,
  721. GLS_OP_glLoadIdentity,
  722. GLS_OP_glLoadMatrixd,
  723. GLS_OP_glLoadMatrixf,
  724. GLS_OP_glLoadName,
  725. GLS_OP_glLogicOp,
  726. GLS_OP_glMap1d,
  727. GLS_OP_glMap1f,
  728. GLS_OP_glMap2d,
  729. GLS_OP_glMap2f,
  730. GLS_OP_glMapGrid1d,
  731. GLS_OP_glMapGrid1f,
  732. GLS_OP_glMapGrid2d,
  733. GLS_OP_glMapGrid2f,
  734. GLS_OP_glMaterialf,
  735. GLS_OP_glMaterialfv,
  736. GLS_OP_glMateriali,
  737. GLS_OP_glMaterialiv,
  738. GLS_OP_glMatrixMode,
  739. GLS_OP_glMinmaxEXT,
  740. GLS_OP_glMultMatrixd,
  741. GLS_OP_glMultMatrixf,
  742. GLS_OP_glNewList,
  743. GLS_OP_glNormal3b,
  744. GLS_OP_glNormal3bv,
  745. GLS_OP_glNormal3d,
  746. GLS_OP_glNormal3dv,
  747. GLS_OP_glNormal3f,
  748. GLS_OP_glNormal3fv,
  749. GLS_OP_glNormal3i,
  750. GLS_OP_glNormal3iv,
  751. GLS_OP_glNormal3s,
  752. GLS_OP_glNormal3sv,
  753. GLS_OP_glNormalPointerEXT,
  754. GLS_OP_glOrtho,
  755. GLS_OP_glPassThrough,
  756. GLS_OP_glPixelMapfv,
  757. GLS_OP_glPixelMapuiv,
  758. GLS_OP_glPixelMapusv,
  759. GLS_OP_glPixelStoref,
  760. GLS_OP_glPixelStorei,
  761. GLS_OP_glPixelTexGenSGIX,
  762. GLS_OP_glPixelTransferf,
  763. GLS_OP_glPixelTransferi,
  764. GLS_OP_glPixelZoom,
  765. GLS_OP_glPointSize,
  766. GLS_OP_glPolygonMode,
  767. GLS_OP_glPolygonOffsetEXT,
  768. GLS_OP_glPolygonStipple,
  769. GLS_OP_glPopAttrib,
  770. GLS_OP_glPopMatrix,
  771. GLS_OP_glPopName,
  772. GLS_OP_glPrioritizeTexturesEXT,
  773. GLS_OP_glPushAttrib,
  774. GLS_OP_glPushMatrix,
  775. GLS_OP_glPushName,
  776. GLS_OP_glRasterPos2d,
  777. GLS_OP_glRasterPos2dv,
  778. GLS_OP_glRasterPos2f,
  779. GLS_OP_glRasterPos2fv,
  780. GLS_OP_glRasterPos2i,
  781. GLS_OP_glRasterPos2iv,
  782. GLS_OP_glRasterPos2s,
  783. GLS_OP_glRasterPos2sv,
  784. GLS_OP_glRasterPos3d,
  785. GLS_OP_glRasterPos3dv,
  786. GLS_OP_glRasterPos3f,
  787. GLS_OP_glRasterPos3fv,
  788. GLS_OP_glRasterPos3i,
  789. GLS_OP_glRasterPos3iv,
  790. GLS_OP_glRasterPos3s,
  791. GLS_OP_glRasterPos3sv,
  792. GLS_OP_glRasterPos4d,
  793. GLS_OP_glRasterPos4dv,
  794. GLS_OP_glRasterPos4f,
  795. GLS_OP_glRasterPos4fv,
  796. GLS_OP_glRasterPos4i,
  797. GLS_OP_glRasterPos4iv,
  798. GLS_OP_glRasterPos4s,
  799. GLS_OP_glRasterPos4sv,
  800. GLS_OP_glReadBuffer,
  801. GLS_OP_glReadPixels,
  802. GLS_OP_glRectd,
  803. GLS_OP_glRectdv,
  804. GLS_OP_glRectf,
  805. GLS_OP_glRectfv,
  806. GLS_OP_glRecti,
  807. GLS_OP_glRectiv,
  808. GLS_OP_glRects,
  809. GLS_OP_glRectsv,
  810. GLS_OP_glRenderMode,
  811. GLS_OP_glResetHistogramEXT,
  812. GLS_OP_glResetMinmaxEXT,
  813. GLS_OP_glRotated,
  814. GLS_OP_glRotatef,
  815. GLS_OP_glSampleMaskSGIS,
  816. GLS_OP_glSamplePatternSGIS,
  817. GLS_OP_glScaled,
  818. GLS_OP_glScalef,
  819. GLS_OP_glScissor,
  820. GLS_OP_glSelectBuffer,
  821. GLS_OP_glSeparableFilter2DEXT,
  822. GLS_OP_glShadeModel,
  823. GLS_OP_glSharpenTexFuncSGIS,
  824. GLS_OP_glStencilFunc,
  825. GLS_OP_glStencilMask,
  826. GLS_OP_glStencilOp,
  827. GLS_OP_glTagSampleBufferSGIX,
  828. GLS_OP_glTexColorTableParameterfvSGI,
  829. GLS_OP_glTexColorTableParameterivSGI,
  830. GLS_OP_glTexCoord1d,
  831. GLS_OP_glTexCoord1dv,
  832. GLS_OP_glTexCoord1f,
  833. GLS_OP_glTexCoord1fv,
  834. GLS_OP_glTexCoord1i,
  835. GLS_OP_glTexCoord1iv,
  836. GLS_OP_glTexCoord1s,
  837. GLS_OP_glTexCoord1sv,
  838. GLS_OP_glTexCoord2d,
  839. GLS_OP_glTexCoord2dv,
  840. GLS_OP_glTexCoord2f,
  841. GLS_OP_glTexCoord2fv,
  842. GLS_OP_glTexCoord2i,
  843. GLS_OP_glTexCoord2iv,
  844. GLS_OP_glTexCoord2s,
  845. GLS_OP_glTexCoord2sv,
  846. GLS_OP_glTexCoord3d,
  847. GLS_OP_glTexCoord3dv,
  848. GLS_OP_glTexCoord3f,
  849. GLS_OP_glTexCoord3fv,
  850. GLS_OP_glTexCoord3i,
  851. GLS_OP_glTexCoord3iv,
  852. GLS_OP_glTexCoord3s,
  853. GLS_OP_glTexCoord3sv,
  854. GLS_OP_glTexCoord4d,
  855. GLS_OP_glTexCoord4dv,
  856. GLS_OP_glTexCoord4f,
  857. GLS_OP_glTexCoord4fv,
  858. GLS_OP_glTexCoord4i,
  859. GLS_OP_glTexCoord4iv,
  860. GLS_OP_glTexCoord4s,
  861. GLS_OP_glTexCoord4sv,
  862. GLS_OP_glTexCoordPointerEXT,
  863. GLS_OP_glTexEnvf,
  864. GLS_OP_glTexEnvfv,
  865. GLS_OP_glTexEnvi,
  866. GLS_OP_glTexEnviv,
  867. GLS_OP_glTexGend,
  868. GLS_OP_glTexGendv,
  869. GLS_OP_glTexGenf,
  870. GLS_OP_glTexGenfv,
  871. GLS_OP_glTexGeni,
  872. GLS_OP_glTexGeniv,
  873. GLS_OP_glTexImage1D,
  874. GLS_OP_glTexImage2D,
  875. GLS_OP_glTexImage3DEXT,
  876. GLS_OP_glTexImage4DSGIS,
  877. GLS_OP_glTexParameterf,
  878. GLS_OP_glTexParameterfv,
  879. GLS_OP_glTexParameteri,
  880. GLS_OP_glTexParameteriv,
  881. GLS_OP_glTexSubImage1DEXT,
  882. GLS_OP_glTexSubImage2DEXT,
  883. GLS_OP_glTexSubImage3DEXT,
  884. GLS_OP_glTexSubImage4DSGIS,
  885. GLS_OP_glTranslated,
  886. GLS_OP_glTranslatef,
  887. GLS_OP_glVertex2d,
  888. GLS_OP_glVertex2dv,
  889. GLS_OP_glVertex2f,
  890. GLS_OP_glVertex2fv,
  891. GLS_OP_glVertex2i,
  892. GLS_OP_glVertex2iv,
  893. GLS_OP_glVertex2s,
  894. GLS_OP_glVertex2sv,
  895. GLS_OP_glVertex3d,
  896. GLS_OP_glVertex3dv,
  897. GLS_OP_glVertex3f,
  898. GLS_OP_glVertex3fv,
  899. GLS_OP_glVertex3i,
  900. GLS_OP_glVertex3iv,
  901. GLS_OP_glVertex3s,
  902. GLS_OP_glVertex3sv,
  903. GLS_OP_glVertex4d,
  904. GLS_OP_glVertex4dv,
  905. GLS_OP_glVertex4f,
  906. GLS_OP_glVertex4fv,
  907. GLS_OP_glVertex4i,
  908. GLS_OP_glVertex4iv,
  909. GLS_OP_glVertex4s,
  910. GLS_OP_glVertex4sv,
  911. GLS_OP_glVertexPointerEXT,
  912. GLS_OP_glViewport,
  913. GLS_OP_glArrayElement,
  914. GLS_OP_glBindTexture,
  915. GLS_OP_glColorPointer,
  916. GLS_OP_glDisableClientState,
  917. GLS_OP_glDrawArrays,
  918. GLS_OP_glDrawElements,
  919. GLS_OP_glEdgeFlagPointer,
  920. GLS_OP_glEnableClientState,
  921. GLS_OP_glIndexPointer,
  922. GLS_OP_glIndexub,
  923. GLS_OP_glIndexubv,
  924. GLS_OP_glInterleavedArrays,
  925. GLS_OP_glNormalPointer,
  926. GLS_OP_glPolygonOffset,
  927. GLS_OP_glTexCoordPointer,
  928. GLS_OP_glVertexPointer,
  929. GLS_OP_glAreTexturesResident,
  930. GLS_OP_glCopyTexImage1D,
  931. GLS_OP_glCopyTexImage2D,
  932. GLS_OP_glCopyTexSubImage1D,
  933. GLS_OP_glCopyTexSubImage2D,
  934. GLS_OP_glDeleteTextures,
  935. GLS_OP_glGenTextures,
  936. GLS_OP_glGetPointerv,
  937. GLS_OP_glIsTexture,
  938. GLS_OP_glPrioritizeTextures,
  939. GLS_OP_glTexSubImage1D,
  940. GLS_OP_glTexSubImage2D,
  941. GLS_OP_glPushClientAttrib,
  942. GLS_OP_glPopClientAttrib,
  943. };
  944. #define EXECUTE_BITS (sizeof(opExecuteBits)/sizeof(opExecuteBits[0]))
  945. /*****************************Private*Routine******************************\
  946. *
  947. * CreateMetaRc
  948. *
  949. * Creates a rendering context for a metafile DC
  950. *
  951. * History:
  952. * Thu Feb 23 15:27:47 1995 -by- Drew Bliss [drewb]
  953. * Created
  954. *
  955. \**************************************************************************/
  956. BOOL CreateMetaRc(HDC hdc, PLRC plrc)
  957. {
  958. int i;
  959. BOOL fSuccess;
  960. if (!MetaLoadGls())
  961. {
  962. return FALSE;
  963. }
  964. // If there's currently a GLS context active we can't record
  965. // because we require our own context to be current for recording
  966. if (gepGlsFuncs.glsGetCurrentContext() != 0)
  967. {
  968. SetLastError(ERROR_BUSY);
  969. return FALSE;
  970. }
  971. // Create a GLS context to record into
  972. plrc->uiGlsCaptureContext = gepGlsFuncs.glsGenContext();
  973. if (plrc->uiGlsCaptureContext == 0)
  974. {
  975. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  976. goto EH_NoContext;
  977. }
  978. // No bounds by default
  979. plrc->prclGlsBounds = NULL;
  980. // Set current GLS context
  981. gepGlsFuncs.glsContext(plrc->uiGlsCaptureContext);
  982. // Point to our writer function
  983. gepGlsFuncs.glsWriteFunc(GlsWriter);
  984. // Set up a callback to flush after every command
  985. // This lets every GL command form its own separate record in the
  986. // metafile
  987. gepGlsFuncs.glsCaptureFunc(GLS_CAPTURE_EXIT_FUNC, GlsFlush);
  988. // Set execute bits on commands which retrieve state
  989. // This allows accurate results to come back for retrieval functions
  990. for (i = 0; i < EXECUTE_BITS; i++)
  991. {
  992. gepGlsFuncs.glsCaptureFlags(opExecuteBits[i],
  993. GLS_CAPTURE_EXECUTE_BIT |
  994. GLS_CAPTURE_WRITE_BIT);
  995. }
  996. fSuccess = MetaRcBegin(plrc, hdc);
  997. // Remove context to avoid inadvertent GLS calls
  998. // Also needed in failure case
  999. gepGlsFuncs.glsContext(0);
  1000. if (fSuccess)
  1001. {
  1002. return TRUE;
  1003. }
  1004. gepGlsFuncs.glsDeleteContext(plrc->uiGlsCaptureContext);
  1005. plrc->uiGlsCaptureContext = 0;
  1006. EH_NoContext:
  1007. DBGERROR("CreateMetaRc failed\n");
  1008. return FALSE;
  1009. }
  1010. /*****************************Private*Routine******************************\
  1011. *
  1012. * DeleteMetaRc
  1013. *
  1014. * Cleans up a metafile RC
  1015. *
  1016. * History:
  1017. * Thu Feb 23 16:35:19 1995 -by- Drew Bliss [drewb]
  1018. * Created
  1019. *
  1020. \**************************************************************************/
  1021. void DeleteMetaRc(PLRC plrc)
  1022. {
  1023. GLuint uiGlsCurrent;
  1024. if (plrc->uiGlsCaptureContext != 0)
  1025. {
  1026. // Make the GLS context current just in case
  1027. // A different GLS context can be active at this time, though,
  1028. // because a different metafile RC could be current to this
  1029. // thread at the time of the delete, so we have to preserve
  1030. // any current context
  1031. uiGlsCurrent = gepGlsFuncs.glsGetCurrentContext();
  1032. gepGlsFuncs.glsContext(plrc->uiGlsCaptureContext);
  1033. // If we're still capturing, stop
  1034. if (plrc->fCapturing)
  1035. {
  1036. MetaRcEnd(plrc);
  1037. }
  1038. // Restore old context
  1039. gepGlsFuncs.glsContext(uiGlsCurrent);
  1040. // Clean up dying context
  1041. gepGlsFuncs.glsDeleteContext(plrc->uiGlsCaptureContext);
  1042. plrc->uiGlsCaptureContext = 0;
  1043. }
  1044. // Clean up playback context if necessary
  1045. // This can happen when metafile playback crashes or an
  1046. // application crashes while enumerating
  1047. if (plrc->uiGlsPlaybackContext != 0)
  1048. {
  1049. gepGlsFuncs.glsDeleteContext(plrc->uiGlsPlaybackContext);
  1050. plrc->uiGlsPlaybackContext = 0;
  1051. }
  1052. // LRC and handle will be cleaned up elsewhere
  1053. }
  1054. /*****************************Private*Routine******************************\
  1055. *
  1056. * ActivateMetaRc
  1057. *
  1058. * Make a metafile RC current
  1059. *
  1060. * History:
  1061. * Thu Feb 23 16:50:31 1995 -by- Drew Bliss [drewb]
  1062. * Created
  1063. *
  1064. \**************************************************************************/
  1065. void ActivateMetaRc(PLRC plrc, HDC hdc)
  1066. {
  1067. ASSERTOPENGL(plrc->uiGlsCaptureContext != 0,
  1068. "ActivateMetaRc: No GLS context\n");
  1069. ASSERTOPENGL(gepGlsFuncs.glsGetCurrentContext() == 0,
  1070. "ActivateMetaRc: Already a current GLS context\n");
  1071. gepGlsFuncs.glsContext(plrc->uiGlsCaptureContext);
  1072. }
  1073. /*****************************Private*Routine******************************\
  1074. *
  1075. * DeactivateMetaRc
  1076. *
  1077. * Make a metafile RC non-current
  1078. *
  1079. * History:
  1080. * Thu Feb 23 16:49:51 1995 -by- Drew Bliss [drewb]
  1081. * Created
  1082. *
  1083. \**************************************************************************/
  1084. void DeactivateMetaRc(PLRC plrc)
  1085. {
  1086. // The current GLS context may not be this RC's capturing context
  1087. // in the case where the RC has been made current after a
  1088. // CloseEnhMetaFile has stopped capturing
  1089. if (gepGlsFuncs.glsGetCurrentContext() == plrc->uiGlsCaptureContext)
  1090. {
  1091. gepGlsFuncs.glsContext(0);
  1092. }
  1093. }
  1094. /*****************************Private*Routine******************************\
  1095. *
  1096. * GlmfSave
  1097. *
  1098. * Save all current GL state
  1099. *
  1100. * History:
  1101. * Fri Feb 24 15:15:50 1995 -by- Drew Bliss [drewb]
  1102. * Created
  1103. *
  1104. \**************************************************************************/
  1105. void GlmfSave(void)
  1106. {
  1107. // What is the exact list of state to be saved?
  1108. // What about overflowing the projection and textures stacks?
  1109. // They're small
  1110. glPushAttrib(GL_ALL_ATTRIB_BITS);
  1111. glMatrixMode(GL_MODELVIEW);
  1112. glPushMatrix();
  1113. glMatrixMode(GL_PROJECTION);
  1114. glPushMatrix();
  1115. glMatrixMode(GL_TEXTURE);
  1116. glPushMatrix();
  1117. }
  1118. /*****************************Private*Routine******************************\
  1119. *
  1120. * GlmfRestore
  1121. *
  1122. * Restores saved state
  1123. *
  1124. * History:
  1125. * Fri Feb 24 15:16:14 1995 -by- Drew Bliss [drewb]
  1126. * Created
  1127. *
  1128. \**************************************************************************/
  1129. void GlmfRestore(void)
  1130. {
  1131. glMatrixMode(GL_TEXTURE);
  1132. glPopMatrix();
  1133. glMatrixMode(GL_PROJECTION);
  1134. glPopMatrix();
  1135. glMatrixMode(GL_MODELVIEW);
  1136. glPopMatrix();
  1137. glPopAttrib();
  1138. }
  1139. #define ScaleLongX(plrc, l) \
  1140. MulDiv(l, plrc->iGlsNumeratorX, plrc->iGlsDenominatorX)
  1141. #define ScaleLongY(plrc, l) \
  1142. MulDiv(l, plrc->iGlsNumeratorY, plrc->iGlsDenominatorY)
  1143. #define ScaleFloatX(plrc, f) ((f)*(plrc)->fGlsScaleX)
  1144. #define ScaleFloatY(plrc, f) ((f)*(plrc)->fGlsScaleY)
  1145. /*****************************Private*Routine******************************\
  1146. *
  1147. * TransformLongPt
  1148. *
  1149. * Transform an integer point
  1150. *
  1151. * History:
  1152. * Fri Feb 24 15:27:37 1995 -by- Drew Bliss [drewb]
  1153. * Created
  1154. *
  1155. \**************************************************************************/
  1156. void TransformLongPt(PLRC plrc, POINT *ppt)
  1157. {
  1158. ppt->x = MulDiv(ppt->x-plrc->iGlsSubtractX, plrc->iGlsNumeratorX,
  1159. plrc->iGlsDenominatorX)+plrc->iGlsAddX;
  1160. ppt->y = MulDiv(ppt->y-plrc->iGlsSubtractY, plrc->iGlsNumeratorY,
  1161. plrc->iGlsDenominatorY)+plrc->iGlsAddY;
  1162. }
  1163. /*****************************Private*Routine******************************\
  1164. *
  1165. * ScaleLongPt
  1166. *
  1167. * Scale an integer point, no translation, for values rather than coordinates
  1168. *
  1169. * History:
  1170. * Fri Feb 24 15:27:52 1995 -by- Drew Bliss [drewb]
  1171. * Created
  1172. *
  1173. \**************************************************************************/
  1174. void ScaleLongPt(PLRC plrc, POINT *ppt)
  1175. {
  1176. ppt->x = MulDiv(ppt->x, plrc->iGlsNumeratorX, plrc->iGlsDenominatorX);
  1177. ppt->y = MulDiv(ppt->y, plrc->iGlsNumeratorY, plrc->iGlsDenominatorY);
  1178. }
  1179. /*****************************Private*Routine******************************\
  1180. *
  1181. * TransformFloatPt
  1182. *
  1183. * Transform a float point
  1184. *
  1185. * History:
  1186. * Fri Feb 24 15:27:37 1995 -by- Drew Bliss [drewb]
  1187. * Created
  1188. *
  1189. \**************************************************************************/
  1190. void TransformFloatPt(PLRC plrc, POINTFLOAT *pptf)
  1191. {
  1192. pptf->x = (pptf->x-plrc->iGlsSubtractX)*plrc->iGlsNumeratorX/
  1193. plrc->iGlsDenominatorX+plrc->iGlsAddX;
  1194. pptf->y = (pptf->y-plrc->iGlsSubtractY)*plrc->iGlsNumeratorY/
  1195. plrc->iGlsDenominatorY+plrc->iGlsAddY;
  1196. }
  1197. /*****************************Private*Routine******************************\
  1198. *
  1199. * ScaleFloatPt
  1200. *
  1201. * Scale a float point
  1202. *
  1203. * History:
  1204. * Fri Feb 24 15:27:37 1995 -by- Drew Bliss [drewb]
  1205. * Created
  1206. *
  1207. \**************************************************************************/
  1208. void ScaleFloatPt(PLRC plrc, POINTFLOAT *pptf)
  1209. {
  1210. pptf->x = pptf->x*plrc->iGlsNumeratorX/plrc->iGlsDenominatorX;
  1211. pptf->y = pptf->y*plrc->iGlsNumeratorY/plrc->iGlsDenominatorY;
  1212. }
  1213. /*****************************Private*Routine******************************\
  1214. *
  1215. * GLS output scaling callbacks
  1216. *
  1217. * The following functions are used as GLS command functions for
  1218. * intercepting device coordinates and scaling them appropriately
  1219. *
  1220. * Bitmap contents are not scaled, but the current raster position is
  1221. * correctly maintained so that they are positioned appropriately
  1222. *
  1223. * Stipples are not scaled
  1224. *
  1225. * History:
  1226. * Fri Feb 24 15:28:23 1995 -by- Drew Bliss [drewb]
  1227. * Created
  1228. *
  1229. \**************************************************************************/
  1230. void GlsBitmapOut(GLsizei width, GLsizei height,
  1231. GLfloat xorig, GLfloat yorig,
  1232. GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
  1233. {
  1234. PLRC plrc;
  1235. POINTFLOAT ptf;
  1236. plrc = GLTEB_CLTCURRENTRC();
  1237. ptf.x = xmove;
  1238. ptf.y = ymove;
  1239. ScaleFloatPt(plrc, &ptf);
  1240. glBitmap(width, height, xorig, yorig, ptf.x, ptf.y, bitmap);
  1241. }
  1242. void GlsCopyPixelsOut(GLint x, GLint y, GLsizei width, GLsizei height,
  1243. GLenum type)
  1244. {
  1245. POINT ptXY, ptWH;
  1246. PLRC plrc;
  1247. plrc = GLTEB_CLTCURRENTRC();
  1248. ptXY.x = x;
  1249. ptXY.y = y;
  1250. TransformLongPt(plrc, &ptXY);
  1251. ptWH.x = (LONG)width;
  1252. ptWH.y = (LONG)height;
  1253. ScaleLongPt(plrc, &ptWH);
  1254. glCopyPixels(ptXY.x, ptXY.y, ptWH.x, ptWH.y, type);
  1255. }
  1256. void GlsCopyTexImage1DOut(GLenum target, GLint level,
  1257. GLenum internalformat,
  1258. GLint x, GLint y,
  1259. GLsizei width, GLint border)
  1260. {
  1261. POINT ptXY;
  1262. PLRC plrc;
  1263. plrc = GLTEB_CLTCURRENTRC();
  1264. ptXY.x = x;
  1265. ptXY.y = y;
  1266. TransformLongPt(plrc, &ptXY);
  1267. glCopyTexImage1D(target, level, internalformat,
  1268. ptXY.x, ptXY.y, ScaleLongX(plrc, width), border);
  1269. }
  1270. void GlsCopyTexImage2DOut(GLenum target, GLint level,
  1271. GLenum internalformat,
  1272. GLint x, GLint y,
  1273. GLsizei width, GLsizei height,
  1274. GLint border)
  1275. {
  1276. POINT ptXY, ptWH;
  1277. PLRC plrc;
  1278. plrc = GLTEB_CLTCURRENTRC();
  1279. ptXY.x = x;
  1280. ptXY.y = y;
  1281. TransformLongPt(plrc, &ptXY);
  1282. ptWH.x = (LONG)width;
  1283. ptWH.y = (LONG)height;
  1284. ScaleLongPt(plrc, &ptWH);
  1285. glCopyTexImage2D(target, level, internalformat,
  1286. ptXY.x, ptXY.y, ptWH.x, ptWH.y, border);
  1287. }
  1288. void GlsCopyTexSubImage1DOut(GLenum target, GLint level,
  1289. GLint xoffset, GLint x, GLint y,
  1290. GLsizei width)
  1291. {
  1292. POINT ptXY;
  1293. PLRC plrc;
  1294. plrc = GLTEB_CLTCURRENTRC();
  1295. ptXY.x = x;
  1296. ptXY.y = y;
  1297. TransformLongPt(plrc, &ptXY);
  1298. glCopyTexSubImage1D(target, level, xoffset,
  1299. ptXY.x, ptXY.y, ScaleLongX(plrc, width));
  1300. }
  1301. void GlsCopyTexSubImage2DOut(GLenum target, GLint level,
  1302. GLint xoffset, GLint yoffset,
  1303. GLint x, GLint y,
  1304. GLsizei width, GLsizei height)
  1305. {
  1306. POINT ptXY, ptWH;
  1307. PLRC plrc;
  1308. plrc = GLTEB_CLTCURRENTRC();
  1309. ptXY.x = x;
  1310. ptXY.y = y;
  1311. TransformLongPt(plrc, &ptXY);
  1312. ptWH.x = (LONG)width;
  1313. ptWH.y = (LONG)height;
  1314. ScaleLongPt(plrc, &ptWH);
  1315. glCopyTexSubImage2D(target, level, xoffset, yoffset,
  1316. ptXY.x, ptXY.y, ptWH.x, ptWH.y);
  1317. }
  1318. void GlsLineWidthOut(GLfloat width)
  1319. {
  1320. PLRC plrc;
  1321. plrc = GLTEB_CLTCURRENTRC();
  1322. // Use X scaling here
  1323. glLineWidth(ScaleFloatX(plrc, width));
  1324. }
  1325. void GlsPointSizeOut(GLfloat size)
  1326. {
  1327. PLRC plrc;
  1328. plrc = GLTEB_CLTCURRENTRC();
  1329. // Use X scaling here
  1330. glPointSize(ScaleFloatX(plrc, size));
  1331. }
  1332. void GlsScissorOut(GLint x, GLint y, GLsizei width, GLsizei height)
  1333. {
  1334. POINT ptXY, ptWH;
  1335. PLRC plrc;
  1336. plrc = GLTEB_CLTCURRENTRC();
  1337. ptXY.x = x;
  1338. ptXY.y = y;
  1339. TransformLongPt(plrc, &ptXY);
  1340. ptWH.x = (LONG)width;
  1341. ptWH.y = (LONG)height;
  1342. ScaleLongPt(plrc, &ptWH);
  1343. glScissor(ptXY.x, ptXY.y, ptWH.x, ptWH.y);
  1344. }
  1345. void GlsViewportOut(GLint x, GLint y, GLsizei width, GLsizei height)
  1346. {
  1347. POINT ptXY, ptWH;
  1348. PLRC plrc;
  1349. plrc = GLTEB_CLTCURRENTRC();
  1350. ptXY.x = x;
  1351. ptXY.y = y;
  1352. TransformLongPt(plrc, &ptXY);
  1353. ptWH.x = (LONG)width;
  1354. ptWH.y = (LONG)height;
  1355. ScaleLongPt(plrc, &ptWH);
  1356. #if 0
  1357. DbgPrint("glViewport(%d, %d, %d, %d)\n", ptXY.x, ptXY.y,
  1358. ptWH.x, ptWH.y);
  1359. #endif
  1360. glViewport(ptXY.x, ptXY.y, ptWH.x, ptWH.y);
  1361. }
  1362. static GLDEVICEPROCS gdpOutput =
  1363. {
  1364. GlsBitmapOut,
  1365. GlsCopyPixelsOut,
  1366. GlsCopyTexImage1DOut,
  1367. GlsCopyTexImage2DOut,
  1368. GlsCopyTexSubImage1DOut,
  1369. GlsCopyTexSubImage2DOut,
  1370. NULL, // glDrawPixels
  1371. GlsLineWidthOut,
  1372. GlsPointSizeOut,
  1373. GlsScissorOut,
  1374. GlsViewportOut
  1375. };
  1376. /*****************************Private*Routine******************************\
  1377. *
  1378. * GlmfHookDeviceFns
  1379. *
  1380. * Hook all functions that deal with device units
  1381. *
  1382. * History:
  1383. * Fri Feb 24 15:30:45 1995 -by- Drew Bliss [drewb]
  1384. * Created
  1385. *
  1386. \**************************************************************************/
  1387. void GlmfHookDeviceFns(void)
  1388. {
  1389. int i;
  1390. PROC *ppfn;
  1391. ppfn = (PROC *)&gdpOutput;
  1392. for (i = 0; i < GL_DEVICE_PROCS; i++)
  1393. {
  1394. if (*ppfn != NULL)
  1395. {
  1396. gepGlsFuncs.glsCommandFunc(glsopDeviceProcs[i], *ppfn);
  1397. }
  1398. ppfn++;
  1399. }
  1400. }
  1401. /*****************************Private*Routine******************************\
  1402. *
  1403. * GlmfInitTransform
  1404. *
  1405. * Compute 2D playback transform from source and destination rectangles
  1406. * Hook GLS with scaling functions
  1407. *
  1408. * History:
  1409. * Fri Feb 24 15:31:24 1995 -by- Drew Bliss [drewb]
  1410. * Created
  1411. *
  1412. \**************************************************************************/
  1413. void GlmfInitTransform(LPRECTL prclFrom, LPRECTL prclTo)
  1414. {
  1415. PLRC plrc;
  1416. plrc = GLTEB_CLTCURRENTRC();
  1417. // Rectangles are inclusive-inclusive
  1418. plrc->iGlsSubtractX = prclFrom->left;
  1419. plrc->iGlsSubtractY = prclFrom->top;
  1420. plrc->iGlsNumeratorX = prclTo->right-prclTo->left+1;
  1421. plrc->iGlsNumeratorY = prclTo->bottom-prclTo->top+1;
  1422. plrc->iGlsDenominatorX = prclFrom->right-prclFrom->left+1;
  1423. plrc->iGlsDenominatorY = prclFrom->bottom-prclFrom->top+1;
  1424. plrc->iGlsAddX = prclTo->left;
  1425. plrc->iGlsAddY = prclTo->top;
  1426. #if 0
  1427. DbgPrint("- %d,%d * %d,%d / %d,%d + %d,%d\n",
  1428. plrc->iGlsSubtractX, plrc->iGlsSubtractY,
  1429. plrc->iGlsNumeratorX, plrc->iGlsNumeratorY,
  1430. plrc->iGlsDenominatorX, plrc->iGlsDenominatorY,
  1431. plrc->iGlsAddX, plrc->iGlsAddY);
  1432. #endif
  1433. // Only install hooks if the transform is not identity
  1434. if (plrc->iGlsSubtractX != plrc->iGlsAddX ||
  1435. plrc->iGlsSubtractY != plrc->iGlsAddY ||
  1436. plrc->iGlsNumeratorX != plrc->iGlsDenominatorX ||
  1437. plrc->iGlsNumeratorY != plrc->iGlsDenominatorY)
  1438. {
  1439. plrc->fGlsScaleX = (GLfloat)plrc->iGlsNumeratorX/
  1440. plrc->iGlsDenominatorX;
  1441. plrc->fGlsScaleY = (GLfloat)plrc->iGlsNumeratorY/
  1442. plrc->iGlsDenominatorY;
  1443. GlmfHookDeviceFns();
  1444. }
  1445. }
  1446. // Table of functions which need to have their command funcs
  1447. // reset for playback virtualization
  1448. static GLSopcode opRecirculate[] =
  1449. {
  1450. GLS_OP_glsBeginGLS,
  1451. GLS_OP_glsBlock,
  1452. GLS_OP_glsCallStream,
  1453. GLS_OP_glsEndGLS,
  1454. GLS_OP_glsError,
  1455. GLS_OP_glsGLRC,
  1456. GLS_OP_glsGLRCLayer,
  1457. GLS_OP_glsHeaderGLRCi,
  1458. GLS_OP_glsHeaderLayerf,
  1459. GLS_OP_glsHeaderLayeri,
  1460. GLS_OP_glsHeaderf,
  1461. GLS_OP_glsHeaderfv,
  1462. GLS_OP_glsHeaderi,
  1463. GLS_OP_glsHeaderiv,
  1464. GLS_OP_glsHeaderubz,
  1465. GLS_OP_glsRequireExtension,
  1466. GLS_OP_glsUnsupportedCommand,
  1467. GLS_OP_glsAppRef,
  1468. GLS_OP_glsBeginObj,
  1469. GLS_OP_glsCharubz,
  1470. GLS_OP_glsComment,
  1471. GLS_OP_glsDisplayMapfv,
  1472. GLS_OP_glsEndObj,
  1473. GLS_OP_glsNumb,
  1474. GLS_OP_glsNumbv,
  1475. GLS_OP_glsNumd,
  1476. GLS_OP_glsNumdv,
  1477. GLS_OP_glsNumf,
  1478. GLS_OP_glsNumfv,
  1479. GLS_OP_glsNumi,
  1480. GLS_OP_glsNumiv,
  1481. GLS_OP_glsNuml,
  1482. GLS_OP_glsNumlv,
  1483. GLS_OP_glsNums,
  1484. GLS_OP_glsNumsv,
  1485. GLS_OP_glsNumub,
  1486. GLS_OP_glsNumubv,
  1487. GLS_OP_glsNumui,
  1488. GLS_OP_glsNumuiv,
  1489. GLS_OP_glsNumul,
  1490. GLS_OP_glsNumulv,
  1491. GLS_OP_glsNumus,
  1492. GLS_OP_glsNumusv,
  1493. GLS_OP_glsPad,
  1494. GLS_OP_glsSwapBuffers
  1495. };
  1496. #define RECIRCULATE_OPS (sizeof(opRecirculate)/sizeof(opRecirculate[0]))
  1497. /******************************Public*Routine******************************\
  1498. *
  1499. * GlmfInitPlayback
  1500. *
  1501. * Initialize GL metafile playback, called from PlayEnhMetaFile for
  1502. * metafiles with GL information in them
  1503. *
  1504. * History:
  1505. * Fri Feb 24 10:32:29 1995 -by- Drew Bliss [drewb]
  1506. * Created
  1507. *
  1508. \**************************************************************************/
  1509. BOOL APIENTRY GlmfInitPlayback(HDC hdc, ENHMETAHEADER *pemh, LPRECTL prclDest)
  1510. {
  1511. GLuint uiCurrentCtx;
  1512. PLRC plrc;
  1513. RECTL rclSourceDevice;
  1514. int i;
  1515. // If we don't have the appropriate GL context set up,
  1516. // do nothing. This allows applications to play metafiles containing
  1517. // GL information even if they don't know anything about GL
  1518. plrc = GLTEB_CLTCURRENTRC();
  1519. if (plrc == NULL)
  1520. {
  1521. return TRUE;
  1522. }
  1523. if (!MetaLoadGls())
  1524. {
  1525. return FALSE;
  1526. }
  1527. plrc->uiGlsPlaybackContext = gepGlsFuncs.glsGenContext();
  1528. if (plrc->uiGlsPlaybackContext == 0)
  1529. {
  1530. return FALSE;
  1531. }
  1532. GlmfSave();
  1533. // Set an initial viewport just as a default
  1534. glViewport(prclDest->left, prclDest->top,
  1535. prclDest->right-prclDest->left,
  1536. prclDest->bottom-prclDest->top);
  1537. // The frame is in .01mm units. Convert it to reference
  1538. // device units using the information in the metafile header
  1539. rclSourceDevice.left = MulDiv(pemh->rclFrame.left, pemh->szlDevice.cx,
  1540. pemh->szlMillimeters.cx*100);
  1541. rclSourceDevice.right = MulDiv(pemh->rclFrame.right, pemh->szlDevice.cx,
  1542. pemh->szlMillimeters.cx*100);
  1543. rclSourceDevice.top = MulDiv(pemh->rclFrame.top, pemh->szlDevice.cy,
  1544. pemh->szlMillimeters.cy*100);
  1545. rclSourceDevice.bottom = MulDiv(pemh->rclFrame.bottom, pemh->szlDevice.cy,
  1546. pemh->szlMillimeters.cy*100);
  1547. // We are resetting command funcs so we need our playback context
  1548. // to be current. Another context could be current now, though,
  1549. // so preserve it
  1550. uiCurrentCtx = gepGlsFuncs.glsGetCurrentContext();
  1551. gepGlsFuncs.glsContext(plrc->uiGlsPlaybackContext);
  1552. GlmfInitTransform(&rclSourceDevice, prclDest);
  1553. // Reset all GLS command funcs to point to the actual exported
  1554. // routines. This means that playback on this context will
  1555. // be exactly the same as if all the routines were being called
  1556. // directly, so embedding a metafile into another one works
  1557. // as expected
  1558. //
  1559. // NOTE: This context should not be made current because any
  1560. // GLS commands executed on it when it is current will now
  1561. // cause infinite loops
  1562. for (i = 0; i < RECIRCULATE_OPS; i++)
  1563. {
  1564. gepGlsFuncs.glsCommandFunc(opRecirculate[i],
  1565. (&gepGlsFuncs.glsBeginGLS)[i]);
  1566. }
  1567. // Restore preserved context
  1568. gepGlsFuncs.glsContext(uiCurrentCtx);
  1569. return TRUE;
  1570. }
  1571. /******************************Public*Routine******************************\
  1572. *
  1573. * GlmfBeginGlsBlock
  1574. *
  1575. * Sets up things for GLS record playback which can only be active during
  1576. * GLS records
  1577. * Currently this only sets the world transform to identity to avoid
  1578. * it interacting with GL drawing
  1579. *
  1580. * History:
  1581. * Mon Apr 10 11:20:19 1995 -by- Drew Bliss [drewb]
  1582. * Created
  1583. *
  1584. \**************************************************************************/
  1585. BOOL APIENTRY GlmfBeginGlsBlock(HDC hdc)
  1586. {
  1587. PLRC plrc;
  1588. BOOL bRet;
  1589. // If we don't have the appropriate GL context set up,
  1590. // do nothing. This allows applications to play metafiles containing
  1591. // GL information even if they don't know anything about GL
  1592. plrc = GLTEB_CLTCURRENTRC();
  1593. if (plrc == NULL)
  1594. {
  1595. return TRUE;
  1596. }
  1597. bRet = GetWorldTransform(hdc, &plrc->xformMeta);
  1598. if (bRet)
  1599. {
  1600. bRet = ModifyWorldTransform(hdc, NULL, MWT_IDENTITY);
  1601. }
  1602. return bRet;
  1603. }
  1604. /******************************Public*Routine******************************\
  1605. *
  1606. * GlmfPlayGlsRecord
  1607. *
  1608. * Play a GL metafile record
  1609. *
  1610. * History:
  1611. * Fri Feb 24 10:33:38 1995 -by- Drew Bliss [drewb]
  1612. * Created
  1613. *
  1614. \**************************************************************************/
  1615. #define PLAY_STACK_BUFFER 256
  1616. BOOL APIENTRY GlmfPlayGlsRecord(HDC hdc, DWORD cb, BYTE *pb,
  1617. LPRECTL prclBounds)
  1618. {
  1619. PLRC plrc;
  1620. LARGE_INTEGER liBuffer[(PLAY_STACK_BUFFER+sizeof(LARGE_INTEGER)-1)/
  1621. sizeof(LARGE_INTEGER)+1];
  1622. BYTE *pbPlay, *pbAlloc = NULL;
  1623. __GLSbinCommandHead_large *gbch;
  1624. GLSopcode op;
  1625. GLScommandAlignment gca;
  1626. #if 0
  1627. DbgPrint("GlmfPlayGlsRecord(%d)\n", cb);
  1628. #endif
  1629. // If we don't have the appropriate GL and GLS contexts set up,
  1630. // do nothing. This allows applications to play metafiles containing
  1631. // GL information even if they don't know anything about GL
  1632. plrc = GLTEB_CLTCURRENTRC();
  1633. if (plrc == NULL || plrc->uiGlsPlaybackContext == 0)
  1634. {
  1635. return TRUE;
  1636. }
  1637. ASSERTOPENGL(hGlsDll != NULL, "GlmfPlayGlsRecord: GLS not loaded\n");
  1638. ASSERTOPENGL(plrc->tidCurrent == GetCurrentThreadId(),
  1639. "GlmfPlayGlsRecord: "
  1640. "Current RC does not belong to this thread!\n");
  1641. ASSERTOPENGL(plrc->gwidCurrent.hdc != 0,
  1642. "GlmfPlayGlsRecord: Current HDC is NULL!\n");
  1643. // pb points to some arbitrary block of memory
  1644. // GLS requires that this block be appropriately aligned for
  1645. // any commands that are executed out of it, so we need to
  1646. // determine which command is in the buffer and then query
  1647. // GLS for its alignment.
  1648. // This is trickier than you would think since GLS doesn't
  1649. // always add padding to commands relative to their beginning; it
  1650. // sometimes adds padding to the end of the previous command.
  1651. // We need to detect the case where padding is added.
  1652. //
  1653. // NOTE: This definitely works when there is only one command
  1654. // in the buffer. It should work when there are multiple commands
  1655. // because the following commands are padded according to the
  1656. // alignment of the initial command. However, this assumption
  1657. // should probably be validated if blocks start containing
  1658. // multiple commands.
  1659. // Check for an initial pad and skip it if necessary
  1660. gbch = (__GLSbinCommandHead_large *)pb;
  1661. if (gbch->opSmall == GLS_OP_glsPad &&
  1662. gbch->countSmall == 1)
  1663. {
  1664. pb += sizeof(__GLSbinCommandHead_small);
  1665. cb -= sizeof(__GLSbinCommandHead_small);
  1666. gbch = (__GLSbinCommandHead_large *)pb;
  1667. }
  1668. ASSERTOPENGL(gbch->countSmall == 0 ||
  1669. gbch->opSmall != GLS_OP_glsPad,
  1670. "Unexpected glsPad in command buffer\n");
  1671. op = gbch->countSmall == 0 ? gbch->opLarge : gbch->opSmall;
  1672. gepGlsFuncs.glsGetCommandAlignment(op, gepGlsFuncs.glsBinary(GL_FALSE),
  1673. &gca);
  1674. ASSERTOPENGL(gca.mask <= 7, "Unhandled GLS playback alignment\n");
  1675. if (((ULONG_PTR)pb & gca.mask) != gca.value)
  1676. {
  1677. if (cb <= PLAY_STACK_BUFFER)
  1678. {
  1679. pbPlay = (BYTE *)liBuffer+gca.value;
  1680. }
  1681. else
  1682. {
  1683. pbAlloc = (BYTE *)ALLOC(cb+gca.value);
  1684. if (pbAlloc == NULL)
  1685. {
  1686. return FALSE;
  1687. }
  1688. pbPlay = pbAlloc+gca.value;
  1689. }
  1690. RtlCopyMemory(pbPlay, pb, cb);
  1691. }
  1692. else
  1693. {
  1694. pbPlay = pb;
  1695. }
  1696. gepGlsFuncs.glsCallArrayInContext(plrc->uiGlsPlaybackContext,
  1697. gepGlsFuncs.glsBinary(GL_FALSE),
  1698. cb, pbPlay);
  1699. if (pbAlloc != NULL)
  1700. {
  1701. FREE(pbAlloc);
  1702. }
  1703. return TRUE;
  1704. }
  1705. /******************************Public*Routine******************************\
  1706. *
  1707. * GlmfEndGlsBlock
  1708. *
  1709. * Resets state changed for GLS record playback
  1710. * Currently restores the world transform
  1711. *
  1712. * History:
  1713. * Mon Apr 10 11:23:06 1995 -by- Drew Bliss [drewb]
  1714. * Created
  1715. *
  1716. \**************************************************************************/
  1717. BOOL APIENTRY GlmfEndGlsBlock(HDC hdc)
  1718. {
  1719. PLRC plrc;
  1720. // If we don't have the appropriate GL context set up,
  1721. // do nothing. This allows applications to play metafiles containing
  1722. // GL information even if they don't know anything about GL
  1723. plrc = GLTEB_CLTCURRENTRC();
  1724. if (plrc == NULL)
  1725. {
  1726. return TRUE;
  1727. }
  1728. // Doesn't matter which side we multiply by since the transform
  1729. // should be identity
  1730. return ModifyWorldTransform(hdc, &plrc->xformMeta, MWT_LEFTMULTIPLY);
  1731. }
  1732. /******************************Public*Routine******************************\
  1733. *
  1734. * GlmfEndPlayback
  1735. *
  1736. * End GL metafile playback, called at the end of metafile playback
  1737. * Only called if GlmfInitPlayback was successful
  1738. *
  1739. * History:
  1740. * Fri Feb 24 10:36:36 1995 -by- Drew Bliss [drewb]
  1741. * Created
  1742. *
  1743. \**************************************************************************/
  1744. BOOL APIENTRY GlmfEndPlayback(HDC hdc)
  1745. {
  1746. PLRC plrc;
  1747. // If we don't have the appropriate GL and GLS contexts set up,
  1748. // do nothing. This allows applications to play metafiles containing
  1749. // GL information even if they don't know anything about GL
  1750. plrc = GLTEB_CLTCURRENTRC();
  1751. if (plrc == NULL || plrc->uiGlsPlaybackContext == 0)
  1752. {
  1753. return TRUE;
  1754. }
  1755. ASSERTOPENGL(hGlsDll != NULL, "GlmfEndPlayback: GLS not loaded\n");
  1756. // Since GlmfInitPlayback completed, we must have saved state
  1757. GlmfRestore();
  1758. ASSERTOPENGL(plrc->uiGlsPlaybackContext != 0,
  1759. "GlmfEndPlayback: No playback context\n");
  1760. gepGlsFuncs.glsDeleteContext(plrc->uiGlsPlaybackContext);
  1761. plrc->uiGlsPlaybackContext = 0;
  1762. // Request cleanup of windows on the theory that most orphaned
  1763. // windows are produced by DCs created for metafiles and memory
  1764. // DCs used by printing. Cleaning up during playback will mean
  1765. // that orphaned windows are only around for one extra playback
  1766. wglValidateWindows();
  1767. return TRUE;
  1768. }
  1769. /******************************Public*Routine******************************\
  1770. *
  1771. * GlmfCloseMetaFile
  1772. *
  1773. * Called in CloseEnhMetaFile if GL records are present in the metafile
  1774. *
  1775. * History:
  1776. * Fri Mar 03 18:05:50 1995 -by- Drew Bliss [drewb]
  1777. * Created
  1778. *
  1779. \**************************************************************************/
  1780. BOOL APIENTRY GlmfCloseMetaFile(HDC hdc)
  1781. {
  1782. PLRC plrc;
  1783. GLGENwindow *pwnd;
  1784. GLWINDOWID gwid;
  1785. // This DC has just gone away so clean up its WNDOBJ if necessary
  1786. WindowIdFromHdc(hdc, &gwid);
  1787. pwnd = pwndGetFromID(&gwid);
  1788. if (pwnd != NULL)
  1789. {
  1790. pwndCleanup(pwnd);
  1791. }
  1792. // The app could have called wglDeleteContext before CloseEnhMetaFile,
  1793. // so we're not guaranteed to have a context
  1794. plrc = GLTEB_CLTCURRENTRC();
  1795. if (plrc == NULL ||
  1796. !plrc->fCapturing)
  1797. {
  1798. return TRUE;
  1799. }
  1800. ASSERTOPENGL(hGlsDll != NULL, "GlmfCloseMetaFile: GLS not loaded\n");
  1801. ASSERTOPENGL(plrc->uiGlsCaptureContext != 0,
  1802. "GlmfCloseMetaFile: GLS context is invalid");
  1803. MetaRcEnd(plrc);
  1804. // Set the proc table to the generic routines because capturing
  1805. // is over. Metafiling always uses the generic routines because
  1806. // the underlying surface is always faked on top of an info DC.
  1807. {
  1808. // Use RGBA or CI proc table depending on the color mode.
  1809. GLCLTPROCTABLE *pglProcTable;
  1810. __GL_SETUP();
  1811. if (gc->modes.colorIndexMode)
  1812. pglProcTable = &glCltCIProcTable;
  1813. else
  1814. pglProcTable = &glCltRGBAProcTable;
  1815. SetCltProcTable(pglProcTable, &glExtProcTable, TRUE);
  1816. }
  1817. return TRUE;
  1818. }
  1819. /******************************Public*Routine******************************\
  1820. *
  1821. * GlGdi routines
  1822. *
  1823. * Thunks to allow the same binary to run on both NT with metafile support
  1824. * and Win95 without it
  1825. *
  1826. * History:
  1827. * Thu Aug 31 15:46:37 1995 -by- Drew Bliss [drewb]
  1828. * Created
  1829. *
  1830. \**************************************************************************/
  1831. #if DBG
  1832. BOOL APIENTRY GlGdiAddGlsRecord(HDC hdc, DWORD cb, BYTE *pb,
  1833. LPRECTL prclBounds)
  1834. {
  1835. ASSERTOPENGL(pfnGdiAddGlsRecord != NULL,
  1836. "GdiAddGlsRecord called without support\n");
  1837. return pfnGdiAddGlsRecord(hdc, cb, pb, prclBounds);
  1838. }
  1839. BOOL APIENTRY GlGdiAddGlsBounds(HDC hdc, LPRECTL prclBounds)
  1840. {
  1841. ASSERTOPENGL(pfnGdiAddGlsBounds != NULL,
  1842. "GdiAddGlsBounds called without support\n");
  1843. return pfnGdiAddGlsBounds(hdc, prclBounds);
  1844. }
  1845. BOOL APIENTRY GlGdiIsMetaPrintDC(HDC hdc)
  1846. {
  1847. ASSERTOPENGL(pfnGdiIsMetaPrintDC != NULL,
  1848. "GdiIsMetaPrintDC called without support\n");
  1849. return pfnGdiIsMetaPrintDC(hdc);
  1850. }
  1851. #endif
  1852. #else
  1853. PROC * APIENTRY wglGetDefaultDispatchTable(void)
  1854. {
  1855. return NULL;
  1856. }
  1857. BOOL APIENTRY GlmfInitPlayback(HDC hdc, ENHMETAHEADER *pemh, LPRECTL prclDest)
  1858. {
  1859. return FALSE;
  1860. }
  1861. BOOL APIENTRY GlmfBeginGlsBlock(HDC hdc)
  1862. {
  1863. return FALSE;
  1864. }
  1865. BOOL APIENTRY GlmfPlayGlsRecord(HDC hdc, DWORD cb, BYTE *pb,
  1866. LPRECTL prclBounds)
  1867. {
  1868. return FALSE;
  1869. }
  1870. BOOL APIENTRY GlmfEndGlsBlock(HDC hdc)
  1871. {
  1872. return FALSE;
  1873. }
  1874. BOOL APIENTRY GlmfEndPlayback(HDC hdc)
  1875. {
  1876. return FALSE;
  1877. }
  1878. BOOL APIENTRY GlmfCloseMetaFile(HDC hdc)
  1879. {
  1880. return FALSE;
  1881. }
  1882. #endif