21 #include "../../SDL_internal.h"
22 #include "../SDL_sysvideo.h"
24 #define INCL_DOSERRORS
25 #define INCL_DOSPROCESS
26 #define INCL_DOSMODULEMGR
29 #define INCL_GPIBITMAPS
36 typedef struct _VODATA {
58 HRGN hrgnShape, BOOL fVisible);
60 ULONG ulBPP, ULONG fccColorEncoding,
61 PULONG pulScanLineSize);
88 DosExitList(EXLST_EXIT, (PFNEXITLIST)
NULL);
95 INITPROCOUT stInitProcOut;
101 ulRC = DosLoadModule(acBuf,
sizeof(acBuf),
"VMAN", &
hmodVMan);
102 if (ulRC != NO_ERROR) {
103 debug_os2(
"Could not load VMAN.DLL, rc = %u : %s", ulRC, acBuf);
110 if (ulRC != NO_ERROR) {
111 debug_os2(
"Could not query address of pfnVMIEntry func. of VMAN.DLL, "
119 stInitProcOut.ulLength =
sizeof(stInitProcOut);
121 if (ulRC != RC_SUCCESS) {
122 debug_os2(
"Could not initialize VMAN for this process");
132 if (DosExitList(EXLST_ADD | 0x00001000, (PFNEXITLIST)
ExitVMan) != NO_ERROR) {
143 if (pVOData->cRectl >= cRects)
144 return pVOData->pRectl;
146 pRectl =
SDL_realloc(pVOData->pRectl, cRects *
sizeof(RECTL));
150 pVOData->pRectl = pRectl;
151 pVOData->cRectl = cRects;
159 if (pVOData->cBltRect >= cRects)
160 return pVOData->pBltRect;
162 pBltRect =
SDL_realloc(pVOData->pBltRect, cRects *
sizeof(BLTRECT));
163 if (pBltRect ==
NULL)
166 pVOData->pBltRect = pBltRect;
167 pVOData->cBltRect = cRects;
175 GDDMODEINFO sCurModeInfo;
182 if (ulRC != RC_SUCCESS) {
183 debug_os2(
"Could not query desktop video mode.");
187 pInfo->
ulBPP = sCurModeInfo.ulBpp;
204 if (pVOData ==
NULL) {
214 if (pVOData->pRectl !=
NULL)
217 if (pVOData->pBltRect !=
NULL)
225 HRGN hrgnShape, BOOL fVisible)
228 BOOL fSuccess =
FALSE;
230 hps = WinGetPS(hwnd);
232 if (pVOData->hrgnVisible != NULLHANDLE) {
233 GpiDestroyRegion(hps, pVOData->hrgnVisible);
234 pVOData->hrgnVisible = NULLHANDLE;
239 pVOData->hrgnVisible = GpiCreateRegion(hps, 0,
NULL);
240 if (pVOData->hrgnVisible == NULLHANDLE) {
243 if (WinQueryVisibleRegion(hwnd, pVOData->hrgnVisible) == RGN_ERROR) {
244 GpiDestroyRegion(hps, pVOData->hrgnVisible);
245 pVOData->hrgnVisible = NULLHANDLE;
247 if (hrgnShape != NULLHANDLE)
248 GpiCombineRegion(hps, pVOData->hrgnVisible, pVOData->hrgnVisible,
249 hrgnShape, CRGN_AND);
254 WinQueryWindowRect(hwnd, &pVOData->rectlWin);
255 WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2);
257 if (pSDLDisplayMode !=
NULL) {
258 pVOData->ulScreenHeight = pSDLDisplayMode->
h;
259 pVOData->ulScreenBytesPerLine =
270 ULONG ulBPP, ULONG fccColorEncoding,
271 PULONG pulScanLineSize)
274 ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
279 if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0)
283 ulScanLineSize = (ulScanLineSize + 3) & ~3;
284 *pulScanLineSize = ulScanLineSize;
286 ulRC = DosAllocMem(&pVOData->pBuffer,
287 (ulHeight * ulScanLineSize) +
sizeof(ULONG),
288 PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE);
289 if (ulRC != NO_ERROR) {
290 debug_os2(
"DosAllocMem(), rc = %u", ulRC);
294 pVOData->ulBPP = ulBPP;
295 pVOData->ulScanLineSize = ulScanLineSize;
296 pVOData->ulWidth = ulWidth;
297 pVOData->ulHeight = ulHeight;
299 return pVOData->pBuffer;
306 if (pVOData->pBuffer ==
NULL)
309 ulRC = DosFreeMem(pVOData->pBuffer);
310 if (ulRC != NO_ERROR) {
311 debug_os2(
"DosFreeMem(), rc = %u", ulRC);
313 pVOData->pBuffer =
NULL;
320 PRECTL prectlDst, prectlScan;
330 BITBLTINFO sBitbltInfo = { 0 };
334 if (pVOData->pBuffer ==
NULL)
337 if (pVOData->hrgnVisible == NULLHANDLE)
340 bmiSrc.ulLength =
sizeof(BMAPINFO);
341 bmiSrc.ulType = BMAP_MEMORY;
342 bmiSrc.ulWidth = pVOData->ulWidth;
343 bmiSrc.ulHeight = pVOData->ulHeight;
344 bmiSrc.ulBpp = pVOData->ulBPP;
345 bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize;
346 bmiSrc.pBits = (PBYTE)pVOData->pBuffer;
348 bmiDst.ulLength =
sizeof(BMAPINFO);
349 bmiDst.ulType = BMAP_VRAM;
351 bmiDst.ulWidth = bmiSrc.ulWidth;
352 bmiDst.ulHeight = bmiSrc.ulHeight;
353 bmiDst.ulBpp = bmiSrc.ulBpp;
354 bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine;
358 if (cSDLRects == 0) {
362 stSDLRectDef.
w = bmiSrc.ulWidth;
363 stSDLRectDef.
h = bmiSrc.ulHeight;
364 pSDLRects = &stSDLRectDef;
371 if (prectlDst ==
NULL) {
375 prectlScan = prectlDst;
376 for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, pSDLRects++, prectlScan++) {
377 prectlScan->xLeft = pSDLRects->
x;
378 prectlScan->yTop = pVOData->ulHeight - pSDLRects->
y;
379 prectlScan->xRight = prectlScan->xLeft + pSDLRects->
w;
380 prectlScan->yBottom = prectlScan->yTop - pSDLRects->
h;
383 hps = WinGetPS(hwnd);
384 if (hps == NULLHANDLE)
388 hrgnUpdate = GpiCreateRegion(hps, cSDLRects, prectlDst);
390 GpiCombineRegion(hps, hrgnUpdate, hrgnUpdate, pVOData->hrgnVisible, CRGN_AND);
395 rgnCtl.ulDirection = 1;
396 rgnCtl.crcReturned = 0;
397 GpiQueryRegionRects(hps, hrgnUpdate,
NULL, &rgnCtl,
NULL);
398 if (rgnCtl.crcReturned == 0) {
399 GpiDestroyRegion(hps, hrgnUpdate);
405 if (prectlDst ==
NULL) {
407 GpiDestroyRegion(hps, hrgnUpdate);
412 rgnCtl.crc = rgnCtl.crcReturned;
413 rgnCtl.ulDirection = 1;
414 GpiQueryRegionRects(hps, hrgnUpdate,
NULL, &rgnCtl, prectlDst);
415 GpiDestroyRegion(hps, hrgnUpdate);
417 cSDLRects = rgnCtl.crcReturned;
423 if (pbrDst ==
NULL) {
428 prectlScan = prectlDst;
429 pptlSrcOrg = (PPOINTL)prectlDst;
430 for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, prectlScan++, pptlSrcOrg++) {
431 pbrDst[ulIdx].ulXOrg = pVOData->rectlWin.xLeft + prectlScan->xLeft;
432 pbrDst[ulIdx].ulYOrg = pVOData->ulScreenHeight -
433 (pVOData->rectlWin.yBottom + prectlScan->yTop);
434 pbrDst[ulIdx].ulXExt = prectlScan->xRight - prectlScan->xLeft;
435 pbrDst[ulIdx].ulYExt = prectlScan->yTop - prectlScan->yBottom;
436 pptlSrcOrg->x = prectlScan->xLeft;
437 pptlSrcOrg->y = bmiSrc.ulHeight - prectlScan->yTop;
439 pptlSrcOrg = (PPOINTL)prectlDst;
442 sHWReqIn.ulLength =
sizeof(HWREQIN);
443 sHWReqIn.ulFlags = REQUEST_HW;
444 sHWReqIn.cScrChangeRects = 1;
445 sHWReqIn.arectlScreen = &pVOData->rectlWin;
446 if (
pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn,
NULL) != RC_SUCCESS) {
447 debug_os2(
"pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed");
448 sHWReqIn.cScrChangeRects = 0;
452 rclSrcBounds.xLeft = 0;
453 rclSrcBounds.yBottom = 0;
454 rclSrcBounds.xRight = bmiSrc.ulWidth;
455 rclSrcBounds.yTop = bmiSrc.ulHeight;
457 sBitbltInfo.ulLength =
sizeof(BITBLTINFO);
458 sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW;
459 sBitbltInfo.cBlits = cSDLRects;
460 sBitbltInfo.ulROP = ROP_SRCCOPY;
461 sBitbltInfo.pSrcBmapInfo = &bmiSrc;
462 sBitbltInfo.pDstBmapInfo = &bmiDst;
463 sBitbltInfo.prclSrcBounds = &rclSrcBounds;
464 sBitbltInfo.prclDstBounds = &pVOData->rectlWin;
465 sBitbltInfo.aptlSrcOrg = pptlSrcOrg;
466 sBitbltInfo.abrDst = pbrDst;
469 if (
pfnVMIEntry(0, VMI_CMD_BITBLT, &sBitbltInfo,
NULL) != RC_SUCCESS) {
470 debug_os2(
"pfnVMIEntry(,VMI_CMD_BITBLT,,) failed");
471 sHWReqIn.cScrChangeRects = 0;
475 sHWReqIn.ulFlags = 0;
476 if (
pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn,
NULL) != RC_SUCCESS) {
477 debug_os2(
"pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed");
481 return sHWReqIn.cScrChangeRects != 0;
#define SDL_OutOfMemory()
VOID APIENTRY ExitVMan(VOID)
static ULONG ulVRAMAddress
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape, BOOL fVisible)
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo)
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, ULONG cSDLRects)
static VOID voClose(PVODATA pVOData)
static FNVMIENTRY * pfnVMIEntry
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, ULONG ulBPP, ULONG fccColorEncoding, PULONG pulScanLineSize)
static VOID voVideoBufFree(PVODATA pVOData)
static BOOL _vmanInit(void)
static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects)
static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects)
The structure that defines a display mode.
A rectangle, with the origin at the upper left (integer).
ULONG ulScreenBytesPerLine