Windows NT 4.0 source code leak
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.

1657 lines
52 KiB

4 years ago
  1. //******************************Module*Header*******************************
  2. // Module Name: mcd.c
  3. //
  4. // Main module for Mini Client Driver wrapper library.
  5. //
  6. // Copyright (c) 1995 Microsoft Corporation
  7. //**************************************************************************
  8. #include <stddef.h>
  9. #include <stdarg.h>
  10. #include <windows.h>
  11. #include <wtypes.h>
  12. #include <rx.h>
  13. #include <windef.h>
  14. #include <wingdi.h>
  15. #include <winddi.h>
  16. #include "mcdrv.h"
  17. #include "mcd.h"
  18. #include "mcdint.h"
  19. #include "debug.h"
  20. extern ULONG McdFlags;
  21. extern ULONG McdPrivateFlags;
  22. #if DBG
  23. extern ULONG McdDebugFlags;
  24. #endif
  25. //******************************Public*Routine******************************
  26. //
  27. // BOOL APIENTRY MCDGetDriverInfo(HDC hdc)
  28. //
  29. // Checks to determine if the device driver reports MCD capabilities.
  30. //
  31. //**************************************************************************
  32. BOOL APIENTRY MCDGetDriverInfo(HDC hdc, MCDDRIVERINFO *pMCDDriverInfo)
  33. {
  34. int rxId = RXFUNCS;
  35. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDDRIVERINFOCMDI)];
  36. RXHDR *prxHdr;
  37. MCDDRIVERINFOCMDI *pInfoCmd;
  38. if ( !(McdPrivateFlags & MCDPRIVATE_MCD_ENABLED) )
  39. {
  40. return FALSE;
  41. }
  42. prxHdr = (RXHDR *)(cmdBuffer);
  43. prxHdr->hrxRC = NULL;
  44. prxHdr->hrxSharedMem = NULL;
  45. prxHdr->pSharedMem = (VOID *)NULL;
  46. prxHdr->flags = RX_FL_MCD_REQUEST;
  47. pInfoCmd = (MCDDRIVERINFOCMDI *)(prxHdr + 1);
  48. pInfoCmd->command = MCD_DRIVERINFO;
  49. // Force the version to 0
  50. pMCDDriverInfo->verMajor = 0;
  51. if (!(BOOL)ExtEscape(hdc, RXFUNCS,
  52. sizeof(cmdBuffer),
  53. (char *)prxHdr, sizeof(MCDDRIVERINFO),
  54. (char *)pMCDDriverInfo))
  55. return FALSE;
  56. // See if the driver filled in a non-null version:
  57. return (pMCDDriverInfo->verMajor != 0);
  58. }
  59. //******************************Public*Routine******************************
  60. //
  61. // LONG APIENTRY MCDDescribeMcdPixelFormat(HDC hdc,
  62. // LONG iPixelFormat,
  63. // MCDPIXELFORMAT *ppfd)
  64. //
  65. // Returns information about the specified hardware-dependent pixel format.
  66. //
  67. //**************************************************************************
  68. LONG APIENTRY MCDDescribeMcdPixelFormat(HDC hdc, LONG iPixelFormat,
  69. MCDPIXELFORMAT *pMcdPixelFmt)
  70. {
  71. LONG lRet = 0;
  72. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDPIXELFORMATCMDI)];
  73. RXHDR *prxHdr;
  74. MCDPIXELFORMATCMDI *pPixelFmtCmd;
  75. if ( !(McdPrivateFlags & MCDPRIVATE_PALETTEFORMATS) &&
  76. ((GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES)) == 8) &&
  77. (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) )
  78. {
  79. return lRet;
  80. }
  81. prxHdr = (RXHDR *)(cmdBuffer);
  82. prxHdr->hrxRC = NULL;
  83. prxHdr->hrxSharedMem = NULL;
  84. prxHdr->pSharedMem = (VOID *)NULL;
  85. prxHdr->flags = RX_FL_MCD_REQUEST;
  86. pPixelFmtCmd = (MCDPIXELFORMATCMDI *)(prxHdr + 1);
  87. pPixelFmtCmd->command = MCD_DESCRIBEPIXELFORMAT;
  88. pPixelFmtCmd->iPixelFormat = iPixelFormat;
  89. lRet = (LONG)ExtEscape(hdc, RXFUNCS,
  90. sizeof(cmdBuffer),
  91. (char *)prxHdr, sizeof(MCDPIXELFORMAT),
  92. (char *)pMcdPixelFmt);
  93. // Limit overlay/underlay planes to 15 each (as per spec).
  94. if (pMcdPixelFmt)
  95. {
  96. if (pMcdPixelFmt->cOverlayPlanes > 15)
  97. pMcdPixelFmt->cOverlayPlanes = 15;
  98. if (pMcdPixelFmt->cUnderlayPlanes > 15)
  99. pMcdPixelFmt->cUnderlayPlanes = 15;
  100. }
  101. return lRet;
  102. }
  103. //******************************Public*Routine******************************
  104. //
  105. // LONG APIENTRY MCDDescribePixelFormat(HDC hdc,
  106. // LONG iPixelFormat,
  107. // LPPIXELFORMATDESCRIPTOR ppfd)
  108. //
  109. // Returns a PIXELFORMATDESCRIPTOR describing the specified hardware-dependent
  110. // pixel format.
  111. //
  112. //**************************************************************************
  113. #define STANDARD_MCD_FLAGS\
  114. (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)
  115. LONG APIENTRY MCDDescribePixelFormat(HDC hdc, LONG iPixelFormat,
  116. LPPIXELFORMATDESCRIPTOR ppfd)
  117. {
  118. LONG lRet = 0;
  119. MCDPIXELFORMAT mcdPixelFmt;
  120. lRet = MCDDescribeMcdPixelFormat(hdc, iPixelFormat,
  121. (MCDPIXELFORMAT *) ppfd ? &mcdPixelFmt : NULL);
  122. if (ppfd && lRet)
  123. {
  124. ppfd->nSize = sizeof(*ppfd);
  125. ppfd->nVersion = 1;
  126. ppfd->dwFlags = mcdPixelFmt.dwFlags | STANDARD_MCD_FLAGS |
  127. ((mcdPixelFmt.dwFlags & PFD_DOUBLEBUFFER) ?
  128. 0 : PFD_SUPPORT_GDI);
  129. memcpy(&ppfd->iPixelType, &mcdPixelFmt.iPixelType,
  130. offsetof(MCDPIXELFORMAT, cDepthBits) - offsetof(MCDPIXELFORMAT, iPixelType));
  131. ppfd->cDepthBits = mcdPixelFmt.cDepthBits;
  132. //!!!mcd -- This is copied from generic\pixelfmt.c. Perhaps we
  133. //!!!mcd should call DescribePixelFormat to fill it in with
  134. //!!!mcd the data of the first generic pixelformat. Or fill
  135. //!!!mcd this in later when we return.
  136. if (ppfd->iPixelType == PFD_TYPE_RGBA)
  137. {
  138. if (ppfd->cColorBits < 8)
  139. {
  140. ppfd->cAccumBits = 16;
  141. ppfd->cAccumRedBits = 5;
  142. ppfd->cAccumGreenBits = 6;
  143. ppfd->cAccumBlueBits = 5;
  144. ppfd->cAccumAlphaBits = 0;
  145. }
  146. else
  147. {
  148. if (ppfd->cColorBits <= 16)
  149. {
  150. ppfd->cAccumBits = 32;
  151. ppfd->cAccumRedBits = 11;
  152. ppfd->cAccumGreenBits = 11;
  153. ppfd->cAccumBlueBits = 10;
  154. ppfd->cAccumAlphaBits = 0;
  155. }
  156. else
  157. {
  158. ppfd->cAccumBits = 64;
  159. ppfd->cAccumRedBits = 16;
  160. ppfd->cAccumGreenBits = 16;
  161. ppfd->cAccumBlueBits = 16;
  162. ppfd->cAccumAlphaBits = 0;
  163. }
  164. }
  165. }
  166. else
  167. {
  168. ppfd->cAccumBits = 0;
  169. ppfd->cAccumRedBits = 0;
  170. ppfd->cAccumGreenBits = 0;
  171. ppfd->cAccumBlueBits = 0;
  172. ppfd->cAccumAlphaBits = 0;
  173. }
  174. if (mcdPixelFmt.cStencilBits)
  175. {
  176. ppfd->cStencilBits = mcdPixelFmt.cStencilBits;
  177. }
  178. else
  179. {
  180. if (McdPrivateFlags & MCDPRIVATE_USEGENERICSTENCIL)
  181. ppfd->cStencilBits = 8;
  182. else
  183. ppfd->cStencilBits = 0;
  184. }
  185. ppfd->cAuxBuffers = 0;
  186. ppfd->iLayerType = PFD_MAIN_PLANE;
  187. ppfd->bReserved = (BYTE) (mcdPixelFmt.cOverlayPlanes |
  188. (mcdPixelFmt.cUnderlayPlanes << 4));
  189. ppfd->dwLayerMask = 0;
  190. ppfd->dwVisibleMask = mcdPixelFmt.dwTransparentColor;
  191. ppfd->dwDamageMask = 0;
  192. }
  193. return lRet;
  194. }
  195. //******************************Public*Routine******************************
  196. //
  197. // BOOL APIENTRY MCDCreateContext(MCDCONTEXT *pMCDContext,
  198. // MCDRCINFO *pRcInfo,
  199. // HWND hwnd,
  200. // HDC hdc,
  201. // LONG iPixelFormat,
  202. // LONG iLayerPlane,
  203. // ULONG flags)
  204. //
  205. // Creates an MCD rendering context for the specified hdc/hwnd according
  206. // to the specified flags.
  207. //
  208. //**************************************************************************
  209. BOOL APIENTRY MCDCreateContext(MCDCONTEXT *pMCDContext,
  210. MCDRCINFO *pRcInfo,
  211. HWND hwnd, HDC hdc, LONG iPixelFormat,
  212. LONG iLayerPlane, ULONG flags)
  213. {
  214. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(RXCREATECONTEXT)];
  215. RXHDR *prxHdr;
  216. RXCREATECONTEXT *prxCreateContext;
  217. prxHdr = (RXHDR *)cmdBuffer;
  218. prxHdr->hrxRC = NULL;
  219. prxHdr->hrxSharedMem = NULL;
  220. prxHdr->pSharedMem = (VOID *)NULL;
  221. prxHdr->sharedMemSize = 0;
  222. prxHdr->flags = RX_FL_CREATE_CONTEXT | RX_FL_MCD_REQUEST;
  223. // Pack iPixelFormat in lower word, iLayerPlane in upper word
  224. prxHdr->reserved1 = iPixelFormat | (iLayerPlane << 16);
  225. prxHdr->reserved2 = McdFlags;
  226. prxHdr->reserved3 = (ULONG)pRcInfo;
  227. prxCreateContext = (RXCREATECONTEXT *)(prxHdr + 1);
  228. prxCreateContext->command = RXCMD_CREATE_CONTEXT;
  229. prxCreateContext->hwnd = (ULONG)hwnd;
  230. prxCreateContext->flags = flags;
  231. pMCDContext->hMCDContext = (MCDHANDLE)ExtEscape(hdc, RXFUNCS,
  232. sizeof(RXHDR) + sizeof(RXCREATECONTEXT),
  233. (char *)cmdBuffer, sizeof(MCDRCINFO),
  234. (char *)pRcInfo);
  235. pMCDContext->hdc = hdc;
  236. return (pMCDContext->hMCDContext != (HANDLE)NULL);
  237. }
  238. #define MCD_MEM_ALIGN 32
  239. //******************************Public*Routine******************************
  240. //
  241. // UCHAR * APIENTRY MCDAlloc(MCDCONTEXT *pMCDContext,
  242. // ULONG numBytes,
  243. // MCDHANDLE *pMCDHandle,
  244. // ULONG flags);
  245. //
  246. // Allocate a chunk of shared memory to use for vertex and pixel data.
  247. //
  248. // The return value is a pointer to a shared memory region which can be
  249. // subsequently used by the caller. For vertex processing, caller should
  250. // use MCDLockMemory()/MCDUnlockMemory to serialize hardware access to the
  251. // memory.
  252. //
  253. //**************************************************************************
  254. UCHAR * APIENTRY MCDAlloc(MCDCONTEXT *pMCDContext, ULONG numBytes,
  255. HANDLE *pMCDHandle, ULONG flags)
  256. {
  257. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDALLOCCMDI)];
  258. ULONG outBuffer;
  259. ULONG totalSize = numBytes + MCD_MEM_ALIGN + sizeof(MCDMEMHDRI);
  260. MCDALLOCCMDI *pCmdAlloc;
  261. RXHDR *prxHdr;
  262. VOID *pResult;
  263. MCDMEMHDRI *pMCDMemHdr;
  264. UCHAR *pBase;
  265. UCHAR *pAlign;
  266. prxHdr = (RXHDR *)(cmdBuffer);
  267. prxHdr->hrxRC = pMCDContext->hMCDContext;
  268. prxHdr->hrxSharedMem = NULL;
  269. prxHdr->pSharedMem = (VOID *)NULL;
  270. prxHdr->flags = RX_FL_MCD_REQUEST;
  271. pCmdAlloc = (MCDALLOCCMDI *)(prxHdr + 1);
  272. pCmdAlloc->command = MCD_ALLOC;
  273. pCmdAlloc->sourceProcessID = GetCurrentProcessId();
  274. pCmdAlloc->numBytes = totalSize;
  275. pCmdAlloc->flags = flags;
  276. pBase = (UCHAR *)ExtEscape(pMCDContext->hdc, RXFUNCS,
  277. sizeof(cmdBuffer),
  278. (char *)prxHdr, 4, (char *)pMCDHandle);
  279. if (!pBase)
  280. return (VOID *)NULL;
  281. pAlign = (UCHAR *)(((ULONG)(pBase + sizeof(MCDMEMHDRI)) + (MCD_MEM_ALIGN - 1)) &
  282. ~(MCD_MEM_ALIGN - 1));
  283. pMCDMemHdr = (MCDMEMHDRI *)(pAlign - sizeof(MCDMEMHDRI));
  284. pMCDMemHdr->flags = 0;
  285. pMCDMemHdr->numBytes = numBytes;
  286. pMCDMemHdr->pMaxMem = (VOID *)((char *)pMCDMemHdr + totalSize);
  287. pMCDMemHdr->hMCDMem = *pMCDHandle;
  288. pMCDMemHdr->pBase = pBase;
  289. return (VOID *)(pAlign);
  290. }
  291. //******************************Public*Routine******************************
  292. //
  293. // BOOL APIENTRY MCDFree(MCDCONTEXT *pMCDContext,
  294. // VOID *pMem);
  295. //
  296. // Frees a chunk of driver-allocated shared memory.
  297. //
  298. // Returns TRUE for success, FALSE for failure.
  299. //
  300. //**************************************************************************
  301. BOOL APIENTRY MCDFree(MCDCONTEXT *pMCDContext, VOID *pMCDMem)
  302. {
  303. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDFREECMDI)];
  304. MCDFREECMDI *pCmdFree;
  305. RXHDR *prxHdr;
  306. MCDMEMHDRI *pMCDMemHdr;
  307. pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  308. prxHdr = (RXHDR *)(cmdBuffer);
  309. prxHdr->hrxRC = NULL;
  310. prxHdr->hrxSharedMem = NULL;
  311. prxHdr->pSharedMem = (VOID *)NULL;
  312. prxHdr->flags = RX_FL_MCD_REQUEST;
  313. pCmdFree = (MCDFREECMDI *)(prxHdr + 1);
  314. pCmdFree->command = MCD_FREE;
  315. pCmdFree->hMCDMem = pMCDMemHdr->hMCDMem;
  316. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  317. sizeof(cmdBuffer),
  318. (char *)prxHdr, 0, (char *)NULL);
  319. }
  320. //******************************Public*Routine******************************
  321. //
  322. // VOID APIENTRY MCDBeginState(MCDCONTEXT *pMCDContext, VOID *pMCDMem);
  323. //
  324. // Begins a batch of state commands to issue to the driver.
  325. //
  326. //**************************************************************************
  327. VOID APIENTRY MCDBeginState(MCDCONTEXT *pMCDContext, VOID *pMCDMem)
  328. {
  329. MCDMEMHDRI *pMCDMemHdr;
  330. MCDSTATECMDI *pMCDStateCmd;
  331. pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  332. pMCDStateCmd = (MCDSTATECMDI *)pMCDMem;
  333. pMCDStateCmd->command = MCD_STATE;
  334. pMCDStateCmd->numStates = 0;
  335. pMCDStateCmd->pNextState = (MCDSTATE *)(pMCDStateCmd + 1);
  336. pMCDStateCmd->pMaxState = (MCDSTATE *)(pMCDMemHdr->pMaxMem);
  337. pMCDMemHdr->pMCDContext = pMCDContext;
  338. }
  339. //******************************Public*Routine******************************
  340. //
  341. // BOOL APIENTRY MCDFlushState(VOID pMCDMem);
  342. //
  343. // Flushes a batch of state commands to the driver.
  344. //
  345. // Returns TRUE for success, FALSE for failure.
  346. //
  347. //**************************************************************************
  348. BOOL APIENTRY MCDFlushState(VOID *pMCDMem)
  349. {
  350. RXHDR rxHdr;
  351. MCDMEMHDRI *pMCDMemHdr;
  352. MCDSTATECMDI *pMCDStateCmd;
  353. pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  354. pMCDStateCmd = (MCDSTATECMDI *)pMCDMem;
  355. rxHdr.hrxRC = pMCDMemHdr->pMCDContext->hMCDContext;
  356. rxHdr.hrxSharedMem = pMCDMemHdr->hMCDMem;
  357. rxHdr.pSharedMem = (char *)pMCDMem;
  358. rxHdr.sharedMemSize = (char *)pMCDStateCmd->pNextState -
  359. (char *)pMCDStateCmd;
  360. rxHdr.flags = RX_FL_MCD_REQUEST;
  361. if (!rxHdr.sharedMemSize)
  362. return TRUE;
  363. return (BOOL)ExtEscape(pMCDMemHdr->pMCDContext->hdc, RXFUNCS,
  364. sizeof(RXHDR), (char *)&rxHdr, 0, (char *)NULL);
  365. }
  366. //******************************Public*Routine******************************
  367. //
  368. // BOOL APIENTRY MCDAddState(VOID *pMCDMem, ULONG stateToChange,
  369. // ULONG stateValue);
  370. //
  371. // Adds a state to a state buffer (started with MCDBeginState). If there
  372. // is no room in the state stream (i.e., the memory buffer), the current
  373. // batch of state commands is automatically flushed.
  374. //
  375. //
  376. // Returns TRUE for success, FALSE for failure. A FALSE return will occur
  377. // if an automatic flush is performed which fails.
  378. //
  379. //**************************************************************************
  380. BOOL APIENTRY MCDAddState(VOID *pMCDMem, ULONG stateToChange,
  381. ULONG stateValue)
  382. {
  383. MCDSTATECMDI *pMCDStateCmd;
  384. MCDSTATE *pState;
  385. BOOL retVal = TRUE;
  386. pMCDStateCmd = (MCDSTATECMDI *)pMCDMem;
  387. if (((char *)pMCDStateCmd->pNextState + sizeof(MCDSTATE)) >=
  388. (char *)pMCDStateCmd->pMaxState) {
  389. MCDMEMHDRI *pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  390. retVal = MCDFlushState(pMCDMem);
  391. pMCDStateCmd = (MCDSTATECMDI *)pMCDMem;
  392. pMCDStateCmd->command = MCD_STATE;
  393. pMCDStateCmd->numStates = 0;
  394. pMCDStateCmd->pNextState = (MCDSTATE *)(pMCDStateCmd + 1);
  395. pMCDStateCmd->pMaxState = (MCDSTATE *)(pMCDMemHdr->pMaxMem);
  396. }
  397. pMCDStateCmd->numStates++;
  398. pState = pMCDStateCmd->pNextState;
  399. pState->size = sizeof(MCDSTATE);
  400. pState->state = stateToChange;
  401. pState->stateValue = stateValue;
  402. pMCDStateCmd->pNextState++;
  403. return retVal;
  404. }
  405. //******************************Public*Routine******************************
  406. //
  407. // BOOL APIENTRY MCDAddStateStruct(VOID *pMCDMem, ULONG stateToChange,
  408. // VOID *pStateValue, ULONG stateValueSize)
  409. //
  410. //
  411. // Adds a state structure to a state buffer (started with MCDBeginState). If
  412. // there is no room in the state stream (i.e., the memory buffer), the current
  413. // batch of state commands is automatically flushed.
  414. //
  415. //
  416. // Returns TRUE for success, FALSE for failure. A FALSE return will occur
  417. // if an automatic flush is performed which fails.
  418. //
  419. //**************************************************************************
  420. BOOL APIENTRY MCDAddStateStruct(VOID *pMCDMem, ULONG stateToChange,
  421. VOID *pStateValue, ULONG stateValueSize)
  422. {
  423. MCDSTATECMDI *pMCDStateCmd;
  424. MCDSTATE *pState;
  425. BOOL retVal;
  426. pMCDStateCmd = (MCDSTATECMDI *)pMCDMem;
  427. if (((char *)pMCDStateCmd->pNextState + stateValueSize) >=
  428. (char *)pMCDStateCmd->pMaxState) {
  429. MCDMEMHDRI *pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  430. retVal = MCDFlushState(pMCDMem);
  431. pMCDStateCmd = (MCDSTATECMDI *)pMCDMem;
  432. pMCDStateCmd->command = MCD_STATE;
  433. pMCDStateCmd->numStates = 0;
  434. pMCDStateCmd->pNextState = (MCDSTATE *)(pMCDStateCmd + 1);
  435. pMCDStateCmd->pMaxState = (MCDSTATE *)(pMCDMemHdr->pMaxMem);
  436. }
  437. pMCDStateCmd->numStates++;
  438. pState = pMCDStateCmd->pNextState;
  439. pState->state = stateToChange;
  440. pState->size = offsetof(MCDSTATE, stateValue) + stateValueSize;
  441. memcpy((char *)&pState->stateValue, (char *)pStateValue, stateValueSize);
  442. pMCDStateCmd->pNextState = (MCDSTATE *)(((char *)pMCDStateCmd->pNextState) +
  443. pState->size);
  444. return retVal;
  445. }
  446. //******************************Public*Routine******************************
  447. //
  448. // BOOL APIENTRY MCDSetViewport(MCDCONTEXT *pMCDContext, VOID pMCDMem,
  449. // MCDVIEWPORT pMCDViewport)
  450. //
  451. // Establishes the viewport scaling to convert transformed coordinates to
  452. // screen coordinates.
  453. //
  454. //**************************************************************************
  455. BOOL APIENTRY MCDSetViewport(MCDCONTEXT *pMCDContext, VOID *pMCDMem,
  456. MCDVIEWPORT *pMCDViewport)
  457. {
  458. RXHDR rxHdr;
  459. MCDMEMHDRI *pMCDMemHdr;
  460. MCDVIEWPORTCMDI *pMCDViewportCmd;
  461. pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  462. pMCDViewportCmd = (MCDVIEWPORTCMDI *)pMCDMem;
  463. pMCDViewportCmd->MCDViewport = *pMCDViewport;
  464. pMCDViewportCmd->command = MCD_VIEWPORT;
  465. rxHdr.hrxRC = pMCDContext->hMCDContext;
  466. rxHdr.hrxSharedMem = pMCDMemHdr->hMCDMem;
  467. rxHdr.pSharedMem = (char *)pMCDMem;
  468. rxHdr.sharedMemSize = sizeof(MCDVIEWPORTCMDI);
  469. rxHdr.flags = RX_FL_MCD_REQUEST;
  470. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  471. sizeof(RXHDR), (char *)&rxHdr, 0, (char *)NULL);
  472. }
  473. //******************************Public*Routine******************************
  474. //
  475. // ULONG APIENTRY MCDQueryMemStatus((VOID *pMCDMem);
  476. //
  477. // Returns the status of the specified memory block. Return values are:
  478. //
  479. // MCD_MEM_READY - memory is available for client access
  480. // MCD_MEM_BUSY - memory is busy due to driver access
  481. // MCD_MEM_INVALID - queried memory is invalid
  482. //
  483. //**************************************************************************
  484. ULONG APIENTRY MCDQueryMemStatus(VOID *pMCDMem)
  485. {
  486. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDMEMSTATUSCMDI)];
  487. MCDMEMHDRI *pMCDMemHdr =
  488. (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  489. MCDMEMSTATUSCMDI *pCmdMemStatus;
  490. RXHDR *prxHdr;
  491. prxHdr = (RXHDR *)(cmdBuffer);
  492. prxHdr->hrxRC = NULL;
  493. prxHdr->hrxSharedMem = NULL;
  494. prxHdr->pSharedMem = (VOID *)NULL;
  495. prxHdr->flags = RX_FL_MCD_REQUEST;
  496. pCmdMemStatus = (MCDMEMSTATUSCMDI *)(prxHdr + 1);
  497. pCmdMemStatus->command = MCD_QUERYMEMSTATUS;
  498. pCmdMemStatus->hMCDMem = pMCDMemHdr->hMCDMem;
  499. return (ULONG)ExtEscape(pMCDMemHdr->pMCDContext->hdc, RXFUNCS,
  500. sizeof(cmdBuffer),
  501. (char *)prxHdr, 0, (char *)NULL);
  502. }
  503. //******************************Public*Routine******************************
  504. //
  505. // BOOL APIENTRY MCDProcessBatch(MCDCONTEXT *pMCDContext, VOID pMCDMem,
  506. // ULONG batchSize, VOID *pMCDFirstCmd)
  507. //
  508. // Processes a batch of primitives pointed to by pMCDMem.
  509. //
  510. // Returns TRUE if the batch was processed without error, FALSE otherwise.
  511. //
  512. //**************************************************************************
  513. PVOID APIENTRY MCDProcessBatch(MCDCONTEXT *pMCDContext, VOID *pMCDMem,
  514. ULONG batchSize, VOID *pMCDFirstCmd)
  515. {
  516. RXHDR rxHdr;
  517. MCDMEMHDRI *pMCDMemHdr;
  518. #if DBG
  519. if (McdDebugFlags & MCDDEBUG_DISABLE_PROCBATCH)
  520. {
  521. MCDSync(pMCDContext);
  522. return pMCDFirstCmd;
  523. }
  524. #endif
  525. pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  526. rxHdr.hrxRC = pMCDContext->hMCDContext;
  527. rxHdr.hrxSharedMem = pMCDMemHdr->hMCDMem;
  528. rxHdr.pSharedMem = (char *)pMCDFirstCmd;
  529. rxHdr.sharedMemSize = batchSize;
  530. rxHdr.flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK | RX_FL_MCD_BATCH;
  531. return (PVOID)ExtEscape(pMCDContext->hdc, RXFUNCS,
  532. sizeof(RXHDR), (char *)&rxHdr, 0, (char *)NULL);
  533. }
  534. //******************************Public*Routine******************************
  535. //
  536. // BOOL APIENTRY MCDReadSpan(MCDCONTEXT *pMCDContext, VOID pMCDMem,
  537. // ULONG x, ULONG y, ULONG numPixels, ULONG type)
  538. //
  539. // Reads a span of pixel data from the buffer requested by "type".
  540. // The pixel values are returned in pMCDMem.
  541. //
  542. // Returns TRUE for success, FALSE for failure.
  543. //
  544. //**************************************************************************
  545. BOOL APIENTRY MCDReadSpan(MCDCONTEXT *pMCDContext, VOID *pMCDMem,
  546. ULONG x, ULONG y, ULONG numPixels, ULONG type)
  547. {
  548. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDSPANCMDI)];
  549. RXHDR *prxHdr;
  550. MCDMEMHDRI *pMCDMemHdr;
  551. MCDSPANCMDI *pMCDSpanCmd;
  552. pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  553. prxHdr = (RXHDR *)cmdBuffer;
  554. prxHdr->hrxRC = pMCDContext->hMCDContext;
  555. prxHdr->hrxSharedMem = NULL;
  556. prxHdr->pSharedMem = (VOID *)NULL;
  557. prxHdr->sharedMemSize = 0;
  558. prxHdr->flags = RX_FL_MCD_REQUEST;
  559. pMCDSpanCmd = (MCDSPANCMDI *)(prxHdr + 1);
  560. pMCDSpanCmd->command = MCD_READSPAN;
  561. pMCDSpanCmd->hMem = pMCDMemHdr->hMCDMem;
  562. pMCDSpanCmd->MCDSpan.x = x;
  563. pMCDSpanCmd->MCDSpan.y = y;
  564. pMCDSpanCmd->MCDSpan.numPixels = numPixels;
  565. pMCDSpanCmd->MCDSpan.type = type;
  566. pMCDSpanCmd->MCDSpan.pPixels = (VOID *)((char *)pMCDMem);
  567. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  568. sizeof(cmdBuffer), (char *)prxHdr, 0, (char *)NULL);
  569. }
  570. //******************************Public*Routine******************************
  571. //
  572. // BOOL APIENTRY MCDWriteSpan(MCDCONTEXT *pMCDContext, VOID pMCDMem,
  573. // ULONG x, ULONG y, ULONG numPixels, ULONG type)
  574. //
  575. // Writes a span of pixel data to the buffer requested by "type".
  576. // The pixel values are given in pMCDMem.
  577. //
  578. // Returns TRUE for success, FALSE for failure.
  579. //
  580. //**************************************************************************
  581. BOOL APIENTRY MCDWriteSpan(MCDCONTEXT *pMCDContext, VOID *pMCDMem,
  582. ULONG x, ULONG y, ULONG numPixels, ULONG type)
  583. {
  584. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDSPANCMDI)];
  585. RXHDR *prxHdr;
  586. MCDMEMHDRI *pMCDMemHdr;
  587. MCDSPANCMDI *pMCDSpanCmd;
  588. pMCDMemHdr = (MCDMEMHDRI *)((char *)pMCDMem - sizeof(MCDMEMHDRI));
  589. prxHdr = (RXHDR *)cmdBuffer;
  590. prxHdr->hrxRC = pMCDContext->hMCDContext;
  591. prxHdr->hrxSharedMem = NULL;
  592. prxHdr->pSharedMem = (VOID *)NULL;
  593. prxHdr->sharedMemSize = 0;
  594. prxHdr->flags = RX_FL_MCD_REQUEST;
  595. pMCDSpanCmd = (MCDSPANCMDI *)(prxHdr + 1);
  596. pMCDSpanCmd->command = MCD_WRITESPAN;
  597. pMCDSpanCmd->hMem = pMCDMemHdr->hMCDMem;
  598. pMCDSpanCmd->MCDSpan.x = x;
  599. pMCDSpanCmd->MCDSpan.y = y;
  600. pMCDSpanCmd->MCDSpan.numPixels = numPixels;
  601. pMCDSpanCmd->MCDSpan.type = type;
  602. pMCDSpanCmd->MCDSpan.pPixels = (VOID *)((char *)pMCDMem);
  603. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  604. sizeof(cmdBuffer), (char *)prxHdr, 0, (char *)NULL);
  605. }
  606. //******************************Public*Routine******************************
  607. //
  608. // BOOL APIENTRY MCDClear(MCDCONTEXT *pMCDContext, RECTL rect, ULONG buffers);
  609. //
  610. // Clears buffers specified for the given rectangle. The current fill values
  611. // will be used.
  612. //
  613. //**************************************************************************
  614. BOOL APIENTRY MCDClear(MCDCONTEXT *pMCDContext, RECTL rect, ULONG buffers)
  615. {
  616. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDCLEARCMDI)];
  617. MCDCLEARCMDI *pClearCmd;
  618. RXHDR *prxHdr;
  619. #if DBG
  620. if (McdDebugFlags & MCDDEBUG_DISABLE_CLEAR)
  621. {
  622. MCDSync(pMCDContext);
  623. return FALSE;
  624. }
  625. #endif
  626. prxHdr = (RXHDR *)(cmdBuffer);
  627. prxHdr->hrxRC = pMCDContext->hMCDContext;
  628. prxHdr->hrxSharedMem = NULL;
  629. prxHdr->pSharedMem = (VOID *)NULL;
  630. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  631. pClearCmd = (MCDCLEARCMDI *)(prxHdr + 1);
  632. pClearCmd->command = MCD_CLEAR;
  633. pClearCmd->buffers = buffers;
  634. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  635. sizeof(cmdBuffer),
  636. (char *)prxHdr, 0, (char *)NULL);
  637. }
  638. //******************************Public*Routine******************************
  639. //
  640. // BOOL APIENTRY MCDSetScissorRect(MCDCONTEXT *pMCDContext, RECTL *pRect,
  641. // BOOL bEnabled);
  642. //
  643. // Sets the scissor rectangle.
  644. //
  645. //**************************************************************************
  646. //!! Need semaphore to remove display lock !!
  647. BOOL APIENTRY MCDSetScissorRect(MCDCONTEXT *pMCDContext, RECTL *pRect,
  648. BOOL bEnabled)
  649. {
  650. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDSCISSORCMDI)];
  651. MCDSCISSORCMDI *pScissorCmd;
  652. RXHDR *prxHdr;
  653. prxHdr = (RXHDR *)(cmdBuffer);
  654. prxHdr->hrxRC = pMCDContext->hMCDContext;
  655. prxHdr->hrxSharedMem = NULL;
  656. prxHdr->pSharedMem = (VOID *)NULL;
  657. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  658. pScissorCmd = (MCDSCISSORCMDI *)(prxHdr + 1);
  659. pScissorCmd->command = MCD_SCISSOR;
  660. pScissorCmd->rect = *pRect;
  661. pScissorCmd->bEnabled = bEnabled;
  662. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  663. sizeof(cmdBuffer),
  664. (char *)prxHdr, 0, (char *)NULL);
  665. }
  666. //******************************Public*Routine******************************
  667. //
  668. // BOOL APIENTRY MCDSwap(MCDCONTEXT *pMCDContext, ULONG flags);
  669. //
  670. // Swaps the front and back buffers.
  671. //
  672. //**************************************************************************
  673. BOOL APIENTRY MCDSwap(MCDCONTEXT *pMCDContext, ULONG flags)
  674. {
  675. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDSWAPCMDI)];
  676. MCDSWAPCMDI *pSwapCmd;
  677. RXHDR *prxHdr;
  678. prxHdr = (RXHDR *)(cmdBuffer);
  679. prxHdr->hrxRC = 0;
  680. prxHdr->hrxSharedMem = NULL;
  681. prxHdr->pSharedMem = (VOID *)NULL;
  682. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  683. pSwapCmd = (MCDSWAPCMDI *)(prxHdr + 1);
  684. pSwapCmd->command = MCD_SWAP;
  685. pSwapCmd->flags = flags;
  686. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  687. sizeof(cmdBuffer),
  688. (char *)prxHdr, 0, (char *)NULL);
  689. }
  690. //******************************Public*Routine******************************
  691. //
  692. // BOOL APIENTRY MCDDeleteContext(MCDCONTEXT *pMCDContext);
  693. //
  694. // Deletes the specified context. This will free the buffers associated with
  695. // the context, but will *not* free memory or textures created with the
  696. // context.
  697. //
  698. //**************************************************************************
  699. BOOL APIENTRY MCDDeleteContext(MCDCONTEXT *pMCDContext)
  700. {
  701. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDDELETERCCMDI)];
  702. MCDDELETERCCMDI *pDeleteRcCmd;
  703. RXHDR *prxHdr;
  704. prxHdr = (RXHDR *)(cmdBuffer);
  705. prxHdr->hrxRC = pMCDContext->hMCDContext;
  706. prxHdr->hrxSharedMem = NULL;
  707. prxHdr->pSharedMem = (VOID *)NULL;
  708. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  709. pDeleteRcCmd = (MCDDELETERCCMDI *)(prxHdr + 1);
  710. pDeleteRcCmd->command = MCD_DELETERC;
  711. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  712. sizeof(cmdBuffer),
  713. (char *)prxHdr, 0, (char *)NULL);
  714. }
  715. //******************************Public*Routine******************************
  716. //
  717. // BOOL APIENTRY MCDAllocBuffers(MCDCONTEXT *pMCDContext)
  718. //
  719. // Allocates the buffers required for the specified context.
  720. //
  721. //**************************************************************************
  722. BOOL APIENTRY MCDAllocBuffers(MCDCONTEXT *pMCDContext, RECTL *pWndRect)
  723. {
  724. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDALLOCBUFFERSCMDI)];
  725. RXHDR *prxHdr;
  726. MCDALLOCBUFFERSCMDI *pAllocBuffersCmd;
  727. #if DBG
  728. if (McdDebugFlags & MCDDEBUG_DISABLE_ALLOCBUF)
  729. {
  730. return FALSE;
  731. }
  732. #endif
  733. prxHdr = (RXHDR *)(cmdBuffer);
  734. prxHdr->hrxRC = pMCDContext->hMCDContext;
  735. prxHdr->hrxSharedMem = NULL;
  736. prxHdr->pSharedMem = (VOID *)NULL;
  737. prxHdr->flags = RX_FL_MCD_REQUEST;
  738. pAllocBuffersCmd = (MCDALLOCBUFFERSCMDI *)(prxHdr + 1);
  739. pAllocBuffersCmd->command = MCD_ALLOCBUFFERS;
  740. pAllocBuffersCmd->WndRect = *pWndRect;
  741. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  742. sizeof(cmdBuffer),
  743. (char *)prxHdr, 0, (char *)NULL);
  744. }
  745. //******************************Public*Routine******************************
  746. //
  747. // BOOL APIENTRY MCDGetBuffers(MCDCONTEXT *pMCDContext,
  748. // MCDBUFFERS *pMCDBuffers);
  749. //
  750. // Returns information about the buffers (front, back, and depth) associated
  751. // with the specified context.
  752. //
  753. //**************************************************************************
  754. BOOL APIENTRY MCDGetBuffers(MCDCONTEXT *pMCDContext, MCDBUFFERS *pMCDBuffers)
  755. {
  756. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDGETBUFFERSCMDI)];
  757. RXHDR *prxHdr;
  758. MCDGETBUFFERSCMDI *pGetBuffersCmd;
  759. #if DBG
  760. if (McdDebugFlags & MCDDEBUG_DISABLE_GETBUF)
  761. {
  762. if (pMCDBuffers)
  763. {
  764. pMCDBuffers->mcdFrontBuf.bufFlags &= ~MCDBUF_ENABLED;
  765. pMCDBuffers->mcdBackBuf.bufFlags &= ~MCDBUF_ENABLED;
  766. pMCDBuffers->mcdDepthBuf.bufFlags &= ~MCDBUF_ENABLED;
  767. }
  768. return TRUE;
  769. }
  770. #endif
  771. prxHdr = (RXHDR *)(cmdBuffer);
  772. prxHdr->hrxRC = pMCDContext->hMCDContext;
  773. prxHdr->hrxSharedMem = NULL;
  774. prxHdr->pSharedMem = (VOID *)NULL;
  775. prxHdr->flags = RX_FL_MCD_REQUEST;
  776. pGetBuffersCmd = (MCDGETBUFFERSCMDI *)(prxHdr + 1);
  777. pGetBuffersCmd->command = MCD_GETBUFFERS;
  778. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  779. sizeof(cmdBuffer),
  780. (char *)prxHdr, sizeof(MCDBUFFERS),
  781. (char *)pMCDBuffers);
  782. }
  783. //******************************Public*Routine******************************
  784. //
  785. // BOOL MCDLock();
  786. //
  787. // Grab the MCD synchronization lock.
  788. //
  789. //**************************************************************************
  790. static BOOL __MCDLockRequest(MCDCONTEXT *pMCDContext, ULONG tid)
  791. {
  792. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDLOCKCMDI)];
  793. MCDLOCKCMDI *pCmd;
  794. RXHDR *prxHdr;
  795. prxHdr = (RXHDR *)(cmdBuffer);
  796. prxHdr->hrxRC = pMCDContext->hMCDContext;
  797. prxHdr->hrxSharedMem = NULL;
  798. prxHdr->pSharedMem = (VOID *)NULL;
  799. prxHdr->flags = RX_FL_MCD_REQUEST;
  800. pCmd = (MCDLOCKCMDI *)(prxHdr + 1);
  801. pCmd->command = MCD_LOCK;
  802. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  803. sizeof(cmdBuffer),
  804. (char *)prxHdr, 0, (char *)NULL);
  805. }
  806. BOOL APIENTRY MCDLock(MCDCONTEXT *pMCDContext)
  807. {
  808. BOOL bRet;
  809. ULONG tid;
  810. tid = GetCurrentThreadId();
  811. do
  812. {
  813. bRet = __MCDLockRequest(pMCDContext, tid);
  814. if (!bRet)
  815. Sleep(0);
  816. }
  817. while (bRet == FALSE);
  818. return bRet;
  819. }
  820. //******************************Public*Routine******************************
  821. //
  822. // VOID MCDUnlock();
  823. //
  824. // Release the MCD synchronization lock.
  825. //
  826. //**************************************************************************
  827. VOID APIENTRY MCDUnlock(MCDCONTEXT *pMCDContext)
  828. {
  829. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDLOCKCMDI)];
  830. MCDLOCKCMDI *pCmd;
  831. RXHDR *prxHdr;
  832. prxHdr = (RXHDR *)(cmdBuffer);
  833. prxHdr->hrxRC = pMCDContext->hMCDContext;
  834. prxHdr->hrxSharedMem = NULL;
  835. prxHdr->pSharedMem = (VOID *)NULL;
  836. prxHdr->flags = RX_FL_MCD_REQUEST;
  837. pCmd = (MCDLOCKCMDI *)(prxHdr + 1);
  838. pCmd->command = MCD_UNLOCK;
  839. ExtEscape(pMCDContext->hdc, RXFUNCS,
  840. sizeof(cmdBuffer),
  841. (char *)prxHdr, 0, (char *)NULL);
  842. }
  843. //******************************Public*Routine******************************
  844. //
  845. // VOID MCDBindContext();
  846. //
  847. // Bind a new window to the specified context.
  848. //
  849. //**************************************************************************
  850. BOOL APIENTRY MCDBindContext(MCDCONTEXT *pMCDContext, HWND hWnd, HDC hdc)
  851. {
  852. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDBINDCONTEXTCMDI)];
  853. MCDBINDCONTEXTCMDI *pCmd;
  854. RXHDR *prxHdr;
  855. prxHdr = (RXHDR *)(cmdBuffer);
  856. prxHdr->hrxRC = pMCDContext->hMCDContext;
  857. prxHdr->hrxSharedMem = NULL;
  858. prxHdr->pSharedMem = (VOID *)NULL;
  859. prxHdr->flags = RX_FL_MCD_REQUEST;
  860. pCmd = (MCDBINDCONTEXTCMDI *)(prxHdr + 1);
  861. pCmd->command = MCD_BINDCONTEXT;
  862. pCmd->hWnd = hWnd;
  863. pMCDContext->hdc = hdc;
  864. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  865. sizeof(cmdBuffer),
  866. (char *)prxHdr, 0, (char *)NULL);
  867. }
  868. //******************************Public*Routine******************************
  869. //
  870. // BOOL MCDSync();
  871. //
  872. // Synchronizes the 3D hardware.
  873. //
  874. //**************************************************************************
  875. BOOL APIENTRY MCDSync(MCDCONTEXT *pMCDContext)
  876. {
  877. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDSYNCCMDI)];
  878. MCDSYNCCMDI *pCmd;
  879. RXHDR *prxHdr;
  880. prxHdr = (RXHDR *)(cmdBuffer);
  881. prxHdr->hrxRC = pMCDContext->hMCDContext;
  882. prxHdr->hrxSharedMem = NULL;
  883. prxHdr->pSharedMem = (VOID *)NULL;
  884. prxHdr->flags = RX_FL_MCD_REQUEST;
  885. pCmd = (MCDSYNCCMDI *)(prxHdr + 1);
  886. pCmd->command = MCD_SYNC;
  887. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  888. sizeof(cmdBuffer),
  889. (char *)prxHdr, 0, (char *)NULL);
  890. }
  891. //******************************Public*Routine******************************
  892. //
  893. // MCDHANDLE MCDCreateTexture();
  894. //
  895. // Creates and loads a texture on the MCD device.
  896. //
  897. //**************************************************************************
  898. MCDHANDLE APIENTRY MCDCreateTexture(MCDCONTEXT *pMCDContext,
  899. MCDTEXTUREDATA *pTexData,
  900. ULONG flags,
  901. VOID *pSurface)
  902. {
  903. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDCREATETEXCMDI)];
  904. MCDCREATETEXCMDI *pCmd;
  905. RXHDR *prxHdr;
  906. prxHdr = (RXHDR *)(cmdBuffer);
  907. prxHdr->hrxRC = pMCDContext->hMCDContext;
  908. prxHdr->hrxSharedMem = NULL;
  909. prxHdr->pSharedMem = (VOID *)NULL;
  910. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  911. pCmd = (MCDCREATETEXCMDI *)(prxHdr + 1);
  912. pCmd->command = MCD_CREATE_TEXTURE;
  913. pCmd->pTexData = pTexData;
  914. pCmd->flags = flags;
  915. pCmd->pSurface = pSurface;
  916. return (MCDHANDLE)ExtEscape(pMCDContext->hdc, RXFUNCS,
  917. sizeof(cmdBuffer),
  918. (char *)prxHdr, 0, (char *)NULL);
  919. }
  920. //******************************Public*Routine******************************
  921. //
  922. // BOOL APIENTRY MCDDeleteTexture(MCDCONTEXT *pMCDContext,
  923. // MCDHANDLE hMCDTexture);
  924. //
  925. // Deletes the specified texture. This will free the device memory associated
  926. // with the texture.
  927. //
  928. //**************************************************************************
  929. BOOL APIENTRY MCDDeleteTexture(MCDCONTEXT *pMCDContext, MCDHANDLE hTex)
  930. {
  931. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDDELETETEXCMDI)];
  932. MCDDELETETEXCMDI *pDeleteTexCmd;
  933. RXHDR *prxHdr;
  934. prxHdr = (RXHDR *)(cmdBuffer);
  935. prxHdr->hrxRC = pMCDContext->hMCDContext;
  936. prxHdr->hrxSharedMem = NULL;
  937. prxHdr->pSharedMem = (VOID *)NULL;
  938. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  939. pDeleteTexCmd = (MCDDELETETEXCMDI *)(prxHdr + 1);
  940. pDeleteTexCmd->command = MCD_DELETE_TEXTURE;
  941. pDeleteTexCmd->hTex = hTex;
  942. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  943. sizeof(cmdBuffer),
  944. (char *)prxHdr, 0, (char *)NULL);
  945. }
  946. //******************************Public*Routine******************************
  947. //
  948. // BOOL MCDUpdateSubTexture();
  949. //
  950. // Updates a texture (or region of a texture).
  951. //
  952. //**************************************************************************
  953. BOOL APIENTRY MCDUpdateSubTexture(MCDCONTEXT *pMCDContext,
  954. MCDTEXTUREDATA *pTexData, MCDHANDLE hTex,
  955. ULONG lod, RECTL *pRect)
  956. {
  957. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDUPDATESUBTEXCMDI)];
  958. MCDUPDATESUBTEXCMDI *pCmd;
  959. RXHDR *prxHdr;
  960. prxHdr = (RXHDR *)(cmdBuffer);
  961. prxHdr->hrxRC = pMCDContext->hMCDContext;
  962. prxHdr->hrxSharedMem = NULL;
  963. prxHdr->pSharedMem = (VOID *)NULL;
  964. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  965. pCmd = (MCDUPDATESUBTEXCMDI *)(prxHdr + 1);
  966. pCmd->command = MCD_UPDATE_SUB_TEXTURE;
  967. pCmd->hTex = hTex;
  968. pCmd->pTexData = pTexData;
  969. pCmd->lod = lod;
  970. pCmd->rect = *pRect;
  971. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  972. sizeof(cmdBuffer),
  973. (char *)prxHdr, 0, (char *)NULL);
  974. }
  975. //******************************Public*Routine******************************
  976. //
  977. // BOOL MCDUpdateTexturePalette();
  978. //
  979. // Updates the palette for the specified texture.
  980. //
  981. //**************************************************************************
  982. BOOL APIENTRY MCDUpdateTexturePalette(MCDCONTEXT *pMCDContext,
  983. MCDTEXTUREDATA *pTexData, MCDHANDLE hTex,
  984. ULONG start, ULONG numEntries)
  985. {
  986. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDUPDATETEXPALETTECMDI)];
  987. MCDUPDATETEXPALETTECMDI *pCmd;
  988. RXHDR *prxHdr;
  989. prxHdr = (RXHDR *)(cmdBuffer);
  990. prxHdr->hrxRC = pMCDContext->hMCDContext;
  991. prxHdr->hrxSharedMem = NULL;
  992. prxHdr->pSharedMem = (VOID *)NULL;
  993. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  994. pCmd = (MCDUPDATETEXPALETTECMDI *)(prxHdr + 1);
  995. pCmd->command = MCD_UPDATE_TEXTURE_PALETTE;
  996. pCmd->hTex = hTex;
  997. pCmd->pTexData = pTexData;
  998. pCmd->start = start;
  999. pCmd->numEntries = numEntries;
  1000. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1001. sizeof(cmdBuffer),
  1002. (char *)prxHdr, 0, (char *)NULL);
  1003. }
  1004. //******************************Public*Routine******************************
  1005. //
  1006. // BOOL MCDUpdateTexturePriority();
  1007. //
  1008. // Updates the priority for the specified texture.
  1009. //
  1010. //**************************************************************************
  1011. BOOL APIENTRY MCDUpdateTexturePriority(MCDCONTEXT *pMCDContext,
  1012. MCDTEXTUREDATA *pTexData,
  1013. MCDHANDLE hTex)
  1014. {
  1015. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDUPDATETEXPRIORITYCMDI)];
  1016. MCDUPDATETEXPRIORITYCMDI *pCmd;
  1017. RXHDR *prxHdr;
  1018. prxHdr = (RXHDR *)(cmdBuffer);
  1019. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1020. prxHdr->hrxSharedMem = NULL;
  1021. prxHdr->pSharedMem = (VOID *)NULL;
  1022. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  1023. pCmd = (MCDUPDATETEXPRIORITYCMDI *)(prxHdr + 1);
  1024. pCmd->command = MCD_UPDATE_TEXTURE_PRIORITY;
  1025. pCmd->hTex = hTex;
  1026. pCmd->pTexData = pTexData;
  1027. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1028. sizeof(cmdBuffer),
  1029. (char *)prxHdr, 0, (char *)NULL);
  1030. }
  1031. //******************************Public*Routine******************************
  1032. //
  1033. // BOOL MCDUpdateTextureStata();
  1034. //
  1035. // Updates the state for the specified texture.
  1036. //
  1037. //**************************************************************************
  1038. BOOL APIENTRY MCDUpdateTextureState(MCDCONTEXT *pMCDContext,
  1039. MCDTEXTUREDATA *pTexData,
  1040. MCDHANDLE hTex)
  1041. {
  1042. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDUPDATETEXSTATECMDI)];
  1043. MCDUPDATETEXSTATECMDI *pCmd;
  1044. RXHDR *prxHdr;
  1045. prxHdr = (RXHDR *)(cmdBuffer);
  1046. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1047. prxHdr->hrxSharedMem = NULL;
  1048. prxHdr->pSharedMem = (VOID *)NULL;
  1049. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  1050. pCmd = (MCDUPDATETEXSTATECMDI *)(prxHdr + 1);
  1051. pCmd->command = MCD_UPDATE_TEXTURE_STATE;
  1052. pCmd->hTex = hTex;
  1053. pCmd->pTexData = pTexData;
  1054. return (BOOL)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1055. sizeof(cmdBuffer),
  1056. (char *)prxHdr, 0, (char *)NULL);
  1057. }
  1058. //******************************Public*Routine******************************
  1059. //
  1060. // ULONG MCDTextureStatus();
  1061. //
  1062. // Returns the status for the specified texture.
  1063. //
  1064. //**************************************************************************
  1065. ULONG APIENTRY MCDTextureStatus(MCDCONTEXT *pMCDContext, MCDHANDLE hTex)
  1066. {
  1067. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDTEXSTATUSCMDI)];
  1068. MCDTEXSTATUSCMDI *pCmd;
  1069. RXHDR *prxHdr;
  1070. prxHdr = (RXHDR *)(cmdBuffer);
  1071. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1072. prxHdr->hrxSharedMem = NULL;
  1073. prxHdr->pSharedMem = (VOID *)NULL;
  1074. prxHdr->flags = RX_FL_MCD_REQUEST;
  1075. pCmd = (MCDTEXSTATUSCMDI *)(prxHdr + 1);
  1076. pCmd->command = MCD_TEXTURE_STATUS;
  1077. pCmd->hTex = hTex;
  1078. return (ULONG)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1079. sizeof(cmdBuffer),
  1080. (char *)prxHdr, 0, (char *)NULL);
  1081. }
  1082. //******************************Public*Routine******************************
  1083. //
  1084. // ULONG MCDTextureKey();
  1085. //
  1086. // Returns the driver-managed "key" for the specified texture.
  1087. //
  1088. //**************************************************************************
  1089. ULONG APIENTRY MCDTextureKey(MCDCONTEXT *pMCDContext, MCDHANDLE hTex)
  1090. {
  1091. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDTEXKEYCMDI)];
  1092. MCDTEXKEYCMDI *pCmd;
  1093. RXHDR *prxHdr;
  1094. prxHdr = (RXHDR *)(cmdBuffer);
  1095. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1096. prxHdr->hrxSharedMem = NULL;
  1097. prxHdr->pSharedMem = (VOID *)NULL;
  1098. prxHdr->flags = RX_FL_MCD_REQUEST;
  1099. pCmd = (MCDTEXKEYCMDI *)(prxHdr + 1);
  1100. pCmd->command = MCD_GET_TEXTURE_KEY;
  1101. pCmd->hTex = hTex;
  1102. return (ULONG)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1103. sizeof(cmdBuffer),
  1104. (char *)prxHdr, 0, (char *)NULL);
  1105. }
  1106. //******************************Public*Routine******************************
  1107. //
  1108. // BOOL APIENTRY MCDDescribeMcdLayerPlane(HDC hdc, LONG iPixelFormat,
  1109. // LONG iLayerPlane,
  1110. // MCDLAYERPLANE *pMcdPixelFmt)
  1111. //
  1112. // Returns hardware specific information about the specified layer plane.
  1113. //
  1114. //**************************************************************************
  1115. BOOL APIENTRY MCDDescribeMcdLayerPlane(HDC hdc, LONG iPixelFormat,
  1116. LONG iLayerPlane,
  1117. MCDLAYERPLANE *pMcdLayer)
  1118. {
  1119. BOOL bRet = FALSE;
  1120. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDLAYERPLANECMDI)];
  1121. RXHDR *prxHdr;
  1122. MCDLAYERPLANECMDI *pLayerPlaneCmd;
  1123. prxHdr = (RXHDR *)(cmdBuffer);
  1124. prxHdr->hrxRC = NULL;
  1125. prxHdr->hrxSharedMem = NULL;
  1126. prxHdr->pSharedMem = (VOID *)NULL;
  1127. prxHdr->flags = RX_FL_MCD_REQUEST;
  1128. pLayerPlaneCmd = (MCDLAYERPLANECMDI *)(prxHdr + 1);
  1129. pLayerPlaneCmd->command = MCD_DESCRIBELAYERPLANE;
  1130. pLayerPlaneCmd->iPixelFormat = iPixelFormat;
  1131. pLayerPlaneCmd->iLayerPlane = iLayerPlane;
  1132. bRet = (BOOL)ExtEscape(hdc, RXFUNCS,
  1133. sizeof(cmdBuffer),
  1134. (char *)prxHdr, sizeof(MCDLAYERPLANE),
  1135. (char *)pMcdLayer);
  1136. return bRet;
  1137. }
  1138. //******************************Public*Routine******************************
  1139. //
  1140. // BOOL APIENTRY MCDDescribeLayerPlane(HDC hdc, LONG iPixelFormat,
  1141. // LONG iLayerPlane,
  1142. // LPLAYERPLANEDESCRIPTOR ppfd)
  1143. //
  1144. // Returns LAYERPLANEDESCRIPTOR describing the specified layer plane.
  1145. //
  1146. //**************************************************************************
  1147. BOOL APIENTRY MCDDescribeLayerPlane(HDC hdc, LONG iPixelFormat,
  1148. LONG iLayerPlane,
  1149. LPLAYERPLANEDESCRIPTOR plpd)
  1150. {
  1151. BOOL bRet = FALSE;
  1152. MCDLAYERPLANE McdLayer;
  1153. if (!MCDDescribeMcdLayerPlane(hdc, iPixelFormat, iLayerPlane, &McdLayer))
  1154. return bRet;
  1155. if (plpd)
  1156. {
  1157. plpd->nSize = sizeof(*plpd);
  1158. memcpy(&plpd->nVersion, &McdLayer.nVersion,
  1159. offsetof(LAYERPLANEDESCRIPTOR, cAccumBits) - offsetof(LAYERPLANEDESCRIPTOR, nVersion));
  1160. plpd->cAccumBits = 0;
  1161. plpd->cAccumRedBits = 0;
  1162. plpd->cAccumGreenBits = 0;
  1163. plpd->cAccumBlueBits = 0;
  1164. plpd->cAccumAlphaBits = 0;
  1165. plpd->cDepthBits = 0;
  1166. plpd->cStencilBits = 0;
  1167. plpd->cAuxBuffers = McdLayer.cAuxBuffers;
  1168. plpd->iLayerPlane = McdLayer.iLayerPlane;
  1169. plpd->bReserved = 0;
  1170. plpd->crTransparent = McdLayer.crTransparent;
  1171. bRet = TRUE;
  1172. }
  1173. return bRet;
  1174. }
  1175. //******************************Public*Routine******************************
  1176. //
  1177. // LONG APIENTRY MCDSetLayerPalette(HDC hdc, BOOL bRealize,
  1178. // LONG cEntries, COLORREF *pcr)
  1179. //
  1180. // Sets the palette of the specified layer plane.
  1181. //
  1182. //**************************************************************************
  1183. LONG APIENTRY MCDSetLayerPalette(HDC hdc, LONG iLayerPlane, BOOL bRealize,
  1184. LONG cEntries, COLORREF *pcr)
  1185. {
  1186. LONG lRet = 0;
  1187. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDSETLAYERPALCMDI) + (255 * sizeof(COLORREF))];
  1188. BYTE *pjBuffer = (BYTE *) NULL;
  1189. RXHDR *prxHdr;
  1190. MCDSETLAYERPALCMDI *pSetLayerPalCmd;
  1191. // Use stack allocation if possible; otherwise, allocate heap memory for
  1192. // the command buffer.
  1193. if (cEntries <= 256)
  1194. prxHdr = (RXHDR *)(cmdBuffer);
  1195. else
  1196. {
  1197. LONG lBytes;
  1198. lBytes = sizeof(RXHDR) + sizeof(MCDSETLAYERPALCMDI) +
  1199. ((cEntries - 1) * sizeof(COLORREF));
  1200. pjBuffer = (BYTE *) LocalAlloc(LMEM_FIXED, lBytes);
  1201. prxHdr = (RXHDR *)pjBuffer;
  1202. }
  1203. if (prxHdr != (RXHDR *) NULL)
  1204. {
  1205. prxHdr->hrxRC = NULL;
  1206. prxHdr->hrxSharedMem = NULL;
  1207. prxHdr->pSharedMem = (VOID *)NULL;
  1208. prxHdr->flags = RX_FL_MCD_REQUEST | RX_FL_MCD_DISPLAY_LOCK;
  1209. pSetLayerPalCmd = (MCDSETLAYERPALCMDI *)(prxHdr + 1);
  1210. pSetLayerPalCmd->command = MCD_SETLAYERPALETTE;
  1211. pSetLayerPalCmd->iLayerPlane = iLayerPlane;
  1212. pSetLayerPalCmd->bRealize = bRealize;
  1213. pSetLayerPalCmd->cEntries = cEntries;
  1214. memcpy(&pSetLayerPalCmd->acr[0], pcr, cEntries * sizeof(COLORREF));
  1215. lRet = (BOOL)ExtEscape(hdc, RXFUNCS,
  1216. sizeof(cmdBuffer),
  1217. (char *)prxHdr, 0, (char *)NULL);
  1218. }
  1219. // Delete the heap memory if it was allocated for the command buffer.
  1220. if (pjBuffer)
  1221. {
  1222. LocalFree(pjBuffer);
  1223. }
  1224. return lRet;
  1225. }
  1226. //******************************Public*Routine******************************
  1227. //
  1228. // ULONG APIENTRY MCDDrawPixels(MCDCONTEXT *pMCDContext, ULONG width,
  1229. // ULONG height, ULONG format, ULONG type,
  1230. // VOID *pPixels, BOOL packed)
  1231. //
  1232. // MCD version of glDrawPixels
  1233. //
  1234. //**************************************************************************
  1235. ULONG APIENTRY MCDDrawPixels(MCDCONTEXT *pMCDContext, ULONG width,
  1236. ULONG height, ULONG format, ULONG type,
  1237. VOID *pPixels, BOOL packed)
  1238. {
  1239. ULONG ulRet = (ULONG) FALSE;
  1240. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDDRAWPIXELSCMDI)];
  1241. RXHDR *prxHdr;
  1242. MCDDRAWPIXELSCMDI *pPixelsCmd;
  1243. prxHdr = (RXHDR *)(cmdBuffer);
  1244. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1245. prxHdr->hrxSharedMem = NULL;
  1246. prxHdr->pSharedMem = (VOID *)NULL;
  1247. prxHdr->flags = RX_FL_MCD_REQUEST;
  1248. pPixelsCmd = (MCDDRAWPIXELSCMDI *)(prxHdr + 1);
  1249. pPixelsCmd->command = MCD_DRAW_PIXELS;
  1250. pPixelsCmd->width = width;
  1251. pPixelsCmd->height = height;
  1252. pPixelsCmd->format = format;
  1253. pPixelsCmd->type = type;
  1254. pPixelsCmd->packed = packed;
  1255. pPixelsCmd->pPixels = pPixels;
  1256. ulRet = (ULONG)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1257. sizeof(cmdBuffer), (char *)prxHdr,
  1258. 0, (char *)NULL);
  1259. return ulRet;
  1260. }
  1261. //******************************Public*Routine******************************
  1262. //
  1263. // ULONG APIENTRY MCDReadPixels(MCDCONTEXT *pMCDContext, LONG x, LONG y,
  1264. // ULONG width, ULONG height, ULONG format,
  1265. // ULONG type, VOID *pPixels)
  1266. //
  1267. // MCD version of glReadPixels
  1268. //
  1269. //**************************************************************************
  1270. ULONG APIENTRY MCDReadPixels(MCDCONTEXT *pMCDContext, LONG x, LONG y,
  1271. ULONG width, ULONG height, ULONG format,
  1272. ULONG type, VOID *pPixels)
  1273. {
  1274. ULONG ulRet = (ULONG) FALSE;
  1275. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDREADPIXELSCMDI)];
  1276. RXHDR *prxHdr;
  1277. MCDREADPIXELSCMDI *pPixelsCmd;
  1278. prxHdr = (RXHDR *)(cmdBuffer);
  1279. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1280. prxHdr->hrxSharedMem = NULL;
  1281. prxHdr->pSharedMem = (VOID *)NULL;
  1282. prxHdr->flags = RX_FL_MCD_REQUEST;
  1283. pPixelsCmd = (MCDREADPIXELSCMDI *)(prxHdr + 1);
  1284. pPixelsCmd->command = MCD_READ_PIXELS;
  1285. pPixelsCmd->x = x;
  1286. pPixelsCmd->y = y;
  1287. pPixelsCmd->width = width;
  1288. pPixelsCmd->height = height;
  1289. pPixelsCmd->format = format;
  1290. pPixelsCmd->type = type;
  1291. pPixelsCmd->pPixels = pPixels;
  1292. ulRet = (ULONG)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1293. sizeof(cmdBuffer), (char *)prxHdr,
  1294. 0, (char *)NULL);
  1295. return ulRet;
  1296. }
  1297. //******************************Public*Routine******************************
  1298. //
  1299. // ULONG APIENTRY MCDCopyPixels(MCDCONTEXT *pMCDContext, LONG x, LONG y,
  1300. // ULONG width, ULONG height, ULONG type)
  1301. //
  1302. // MCD version of glCopyPixels
  1303. //
  1304. //**************************************************************************
  1305. ULONG APIENTRY MCDCopyPixels(MCDCONTEXT *pMCDContext, LONG x, LONG y,
  1306. ULONG width, ULONG height, ULONG type)
  1307. {
  1308. ULONG ulRet = (ULONG) FALSE;
  1309. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDCOPYPIXELSCMDI)];
  1310. RXHDR *prxHdr;
  1311. MCDCOPYPIXELSCMDI *pPixelsCmd;
  1312. prxHdr = (RXHDR *)(cmdBuffer);
  1313. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1314. prxHdr->hrxSharedMem = NULL;
  1315. prxHdr->pSharedMem = (VOID *)NULL;
  1316. prxHdr->flags = RX_FL_MCD_REQUEST;
  1317. pPixelsCmd = (MCDCOPYPIXELSCMDI *)(prxHdr + 1);
  1318. pPixelsCmd->command = MCD_COPY_PIXELS;
  1319. pPixelsCmd->x = x;
  1320. pPixelsCmd->y = y;
  1321. pPixelsCmd->width = width;
  1322. pPixelsCmd->height = height;
  1323. pPixelsCmd->type = type;
  1324. ulRet = (ULONG)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1325. sizeof(cmdBuffer), (char *)prxHdr,
  1326. 0, (char *)NULL);
  1327. return ulRet;
  1328. }
  1329. //******************************Public*Routine******************************
  1330. //
  1331. // ULONG APIENTRY MCDPixelMap(MCDCONTEXT *pMCDContext, ULONG mapType,
  1332. // ULONG mapSize, VOID *pMap)
  1333. //
  1334. // MCD version of glPixelMap
  1335. //
  1336. //**************************************************************************
  1337. ULONG APIENTRY MCDPixelMap(MCDCONTEXT *pMCDContext, ULONG mapType,
  1338. ULONG mapSize, VOID *pMap)
  1339. {
  1340. ULONG ulRet = (ULONG) FALSE;
  1341. BYTE cmdBuffer[sizeof(RXHDR) + sizeof(MCDPIXELMAPCMDI)];
  1342. RXHDR *prxHdr;
  1343. MCDPIXELMAPCMDI *pPixelsCmd;
  1344. prxHdr = (RXHDR *)(cmdBuffer);
  1345. prxHdr->hrxRC = pMCDContext->hMCDContext;
  1346. prxHdr->hrxSharedMem = NULL;
  1347. prxHdr->pSharedMem = (VOID *)NULL;
  1348. prxHdr->flags = RX_FL_MCD_REQUEST;
  1349. pPixelsCmd = (MCDPIXELMAPCMDI *)(prxHdr + 1);
  1350. pPixelsCmd->command = MCD_PIXEL_MAP;
  1351. pPixelsCmd->mapType = mapType;
  1352. pPixelsCmd->mapSize = mapSize;
  1353. pPixelsCmd->pMap = pMap;
  1354. ulRet = (ULONG)ExtEscape(pMCDContext->hdc, RXFUNCS,
  1355. sizeof(cmdBuffer), (char *)prxHdr,
  1356. 0, (char *)NULL);
  1357. return ulRet;
  1358. }