723 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			723 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /******************************Module*Header*******************************\
 | |
| * Module Name: enable.c
 | |
| *
 | |
| * Functions to enable and disable the driver
 | |
| *
 | |
| * Copyright (c) 1992-1995 Microsoft Corporation
 | |
| \**************************************************************************/
 | |
| 
 | |
| #include "driver.h"
 | |
| 
 | |
| extern GDIINFO gaulCap;             // in gdiinfo.c
 | |
| extern LOGPALETTE logPalVGA;        // in gdiinfo.c
 | |
| extern DEVINFO devinfoVGA;          // in gdiinfo.c
 | |
| 
 | |
| extern LPBYTE pPtrSave;
 | |
| extern LPBYTE pPtrWork;
 | |
| 
 | |
| BOOL SetUpBanking(PDEVSURF, PPDEV);
 | |
| BOOL bInitPointer(PPDEV);
 | |
| 
 | |
| extern ajConvertBuffer[1];            // Arbitrary sized array!
 | |
| 
 | |
| static  DRVFN   gadrvfn[] = {
 | |
|     {   INDEX_DrvEnablePDEV,            (PFN) DrvEnablePDEV             },
 | |
|     {   INDEX_DrvCompletePDEV,          (PFN) DrvCompletePDEV           },
 | |
|     {   INDEX_DrvDisablePDEV,           (PFN) DrvDisablePDEV            },
 | |
|     {   INDEX_DrvEnableSurface,         (PFN) DrvEnableSurface          },
 | |
|     {   INDEX_DrvDisableSurface,        (PFN) DrvDisableSurface         },
 | |
|     {   INDEX_DrvRealizeBrush,          (PFN) DrvRealizeBrush           },
 | |
|     {   INDEX_DrvCreateDeviceBitmap,    (PFN) DrvCreateDeviceBitmap     },
 | |
|     {   INDEX_DrvDeleteDeviceBitmap,    (PFN) DrvDeleteDeviceBitmap     },
 | |
|     {   INDEX_DrvBitBlt,                (PFN) DrvBitBlt                 },
 | |
|     {   INDEX_DrvTextOut,               (PFN) DrvTextOut                },
 | |
|     {   INDEX_DrvSetPointerShape,       (PFN) DrvSetPointerShape        },
 | |
|     {   INDEX_DrvMovePointer,           (PFN) DrvMovePointer            },
 | |
|     {   INDEX_DrvStrokePath,            (PFN) DrvStrokePath             },
 | |
|     {   INDEX_DrvCopyBits,              (PFN) DrvCopyBits               },
 | |
|     {   INDEX_DrvDitherColor,           (PFN) DrvDitherColor            },
 | |
|     {   INDEX_DrvAssertMode,            (PFN) DrvAssertMode             },
 | |
|     {   INDEX_DrvSaveScreenBits,        (PFN) DrvSaveScreenBits         },
 | |
|     {   INDEX_DrvGetModes,              (PFN) DrvGetModes               },
 | |
|     {   INDEX_DrvFillPath,              (PFN) DrvFillPath               },
 | |
|     {   INDEX_DrvPaint,                 (PFN) DrvPaint                  }
 | |
| };
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * BOOL bEnableDriver(iEngineVersion, cb, pded)
 | |
| *
 | |
| * Enables the driver by filling the function table.  This call is made by
 | |
| * the Engine to fill its driver function table in the LDEV (Logical DEVice).
 | |
| * This call should only be made once per driver but we can handle being
 | |
| * called multiple times.
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| BOOL DrvEnableDriver
 | |
| (
 | |
|     ULONG           iEngineVersion,
 | |
|     ULONG           cb,
 | |
|     PDRVENABLEDATA  pded
 | |
| )
 | |
| {
 | |
|     DISPDBG((2, "enabling Driver\n"));
 | |
| 
 | |
|     cb /= sizeof(ULONG);
 | |
| 
 | |
|     switch(cb)
 | |
|     {
 | |
|     case 3:
 | |
|         pded->pdrvfn = gadrvfn;
 | |
|     case 2:
 | |
|         pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
 | |
|     case 1:
 | |
|         pded->iDriverVersion = DDI_DRIVER_VERSION_NT4;
 | |
|     }
 | |
| 
 | |
|     return(TRUE);
 | |
| }
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * DHPDEV DrvEnablePDEV
 | |
| *
 | |
| * Enable the Physical DEVice
 | |
| *
 | |
| * Warnings:
 | |
| *   The PDEV isn't complete until bCompletePDEV is called.
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| DHPDEV DrvEnablePDEV
 | |
| (
 | |
|     DEVMODEW *pdrivw,
 | |
|     PWSTR     pwszLogAddress,
 | |
|     ULONG     cPatterns,
 | |
|     HSURF    *ahsurfPatterns,
 | |
|     ULONG     cjGdiInfo,
 | |
|     ULONG    *pdevcaps,
 | |
|     ULONG     cb,
 | |
|     PDEVINFO  pdevinfo,
 | |
|     HDEV      hdev,           // HDEV, used for callbacks
 | |
|     PWSTR     pwszDeviceName,
 | |
|     HANDLE    hDriver          // Handle to base driver
 | |
| )
 | |
| {
 | |
|     PPDEV   ppdev;
 | |
| 
 | |
|     DISPDBG((2, "enabling PDEV\n"));
 | |
| 
 | |
|     //
 | |
|     // Define flag to keep track of allocation
 | |
|     //
 | |
| 
 | |
|     ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG);
 | |
| 
 | |
|     if (ppdev == NULL)
 | |
|     {
 | |
|         goto errorAllocPDEV;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     memset(ppdev, 0, sizeof(PDEV));
 | |
| 
 | |
|     //
 | |
|     // Identifier, for debugging purposes
 | |
|     //
 | |
| 
 | |
|     ppdev->ident = PDEV_IDENT;
 | |
| 
 | |
|     //
 | |
|     // Cache the device driver handle away for later use.
 | |
|     //
 | |
| 
 | |
|     ppdev->hDriver = hDriver;
 | |
| 
 | |
|     //
 | |
|     // Initialize the cursor stuff.  We can violate the atomic rule here
 | |
|     // since nobody can talk to the driver yet.
 | |
|     //
 | |
| 
 | |
|     ppdev->xyCursor.x = 320;            // Non-atomic
 | |
|     ppdev->xyCursor.y = 240;            // Non-atomic
 | |
| 
 | |
|     ppdev->ptlExtent.x = 0;
 | |
|     ppdev->ptlExtent.y = 0;
 | |
|     ppdev->cExtent = 0;
 | |
| 
 | |
|     ppdev->flCursor = CURSOR_DOWN;
 | |
| 
 | |
|     //
 | |
|     // Get the current screen mode information.  Set up device caps and devinfo.
 | |
|     //
 | |
| 
 | |
|     if (!bInitPDEV(ppdev, pdrivw, &gaulCap, NULL))
 | |
|     {
 | |
|         DISPDBG((1, "DrvEnablePDEV failed bInitPDEV\n"));
 | |
|         goto errorbInitPDEV;
 | |
|     }
 | |
| 
 | |
|     cjGdiInfo=min(cjGdiInfo, sizeof(GDIINFO));
 | |
| 
 | |
|     memcpy(pdevcaps, &gaulCap, cjGdiInfo);
 | |
| 
 | |
|      // Now let's pass back the devinfo
 | |
| 
 | |
|     ppdev->hpalDefault = EngCreatePalette(PAL_INDEXED, 16,
 | |
|                                               (PULONG) (logPalVGA.palPalEntry),
 | |
|                                               0, 0, 0);
 | |
| 
 | |
|     if (ppdev->hpalDefault == (HPALETTE) 0)
 | |
|     {
 | |
|         goto errorEngCreatePalette;
 | |
|     }
 | |
| 
 | |
|     *pdevinfo = devinfoVGA;
 | |
| 
 | |
|     pdevinfo->hpalDefault = ppdev->hpalDefault;
 | |
| 
 | |
|     // Try to preallocate a saved screen bits buffer. If we fail, set the flag
 | |
|     // to indicate the buffer is in use, so that we'll never attempt to use it.
 | |
|     // If we succeed, mark the buffer as free.
 | |
| 
 | |
|     if ((ppdev->pjPreallocSSBBuffer = (PUCHAR)
 | |
|               EngAllocMem(0, PREALLOC_SSB_SIZE, ALLOC_TAG)) != NULL)
 | |
|     {
 | |
|         ppdev->flPreallocSSBBufferInUse = FALSE;
 | |
|         ppdev->ulPreallocSSBSize = PREALLOC_SSB_SIZE;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         ppdev->flPreallocSSBBufferInUse = TRUE;
 | |
|     }
 | |
| 
 | |
|     // Fill in the DIB4->VGA conversion tables. Allow 256 extra bytes so that
 | |
|     // we can always safely align the tables to a 256-byte boundary, for
 | |
|     // look-up reasons. There are four tables, each 256 bytes long
 | |
| 
 | |
|     ppdev->pucDIB4ToVGAConvBuffer =
 | |
|             (UCHAR *) EngAllocMem(0, (256*4+256)*sizeof(UCHAR), ALLOC_TAG);
 | |
| 
 | |
|     if (ppdev->pucDIB4ToVGAConvBuffer == NULL)
 | |
|     {
 | |
|         goto errorAllocpucDIB4ToVGAConvBuffer;
 | |
|     }
 | |
| 
 | |
|     // Round the table start up to the nearest 256 byte boundary, because the
 | |
|     // tables must start on 256-byte boundaries for look-up reasons
 | |
| 
 | |
|     ppdev->pucDIB4ToVGAConvTables =
 | |
|             (UCHAR *) ((ULONG) (ppdev->pucDIB4ToVGAConvBuffer + 0xFF) & ~0xFF);
 | |
| 
 | |
|     vSetDIB4ToVGATables(ppdev->pucDIB4ToVGAConvTables);
 | |
| 
 | |
|     return((DHPDEV) ppdev);
 | |
| 
 | |
| errorAllocpucDIB4ToVGAConvBuffer:
 | |
| 
 | |
|     //
 | |
|     // Free the preallocated saved screen bits buffer, if there is one.
 | |
|     //
 | |
| 
 | |
|     if (ppdev->pjPreallocSSBBuffer != NULL)
 | |
|     {
 | |
|         EngFreeMem(ppdev->pjPreallocSSBBuffer);
 | |
|     }
 | |
| 
 | |
|     EngDeletePalette(ppdev->hpalDefault);
 | |
| 
 | |
| errorEngCreatePalette:
 | |
| errorbInitPDEV:
 | |
| 
 | |
|     EngFreeMem(ppdev);
 | |
| 
 | |
| errorAllocPDEV:
 | |
| 
 | |
|     return((DHPDEV) 0);
 | |
| 
 | |
|     UNREFERENCED_PARAMETER(cb);
 | |
|     UNREFERENCED_PARAMETER(pwszLogAddress);
 | |
|     UNREFERENCED_PARAMETER(pwszDeviceName);
 | |
| }
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * BOOL bCompletePDEV(dhpdev, hpdev)
 | |
| *
 | |
| * Complete the initialization of the PDEV
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| VOID DrvCompletePDEV(
 | |
|     DHPDEV dhpdev,
 | |
|     HDEV  hdev)
 | |
| {
 | |
|     PPDEV   ppdev;
 | |
| 
 | |
|     ppdev = (PPDEV) dhpdev;
 | |
| 
 | |
|     ppdev->hdevEng = hdev;
 | |
| }
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * VOID DrvDisablePDEV(dhpdev)
 | |
| *
 | |
| * Shutdown this physical device.
 | |
| *
 | |
| * Warnings:
 | |
| *   If a surface is still active for this PDEV it will be freed.
 | |
| *
 | |
| 
 | |
| \**************************************************************************/
 | |
| 
 | |
| VOID DrvDisablePDEV(DHPDEV dhpdev)
 | |
| {
 | |
|     PPDEV   ppdev;
 | |
| 
 | |
|     ppdev = (PPDEV) dhpdev;
 | |
| 
 | |
|     DISPDBG((2, "disabling PDEV\n"));
 | |
| 
 | |
|     EngDeletePalette(ppdev->hpalDefault);
 | |
| 
 | |
| // Free the preallocated saved screen bits buffer, if there is one.
 | |
| 
 | |
|     if (ppdev->pjPreallocSSBBuffer != NULL)
 | |
|     {
 | |
|         EngFreeMem(ppdev->pjPreallocSSBBuffer);
 | |
|     }
 | |
| 
 | |
| // Free the conversion table buffer
 | |
| 
 | |
|     if (ppdev->pucDIB4ToVGAConvBuffer != NULL)
 | |
|     {
 | |
|         EngFreeMem(ppdev->pucDIB4ToVGAConvBuffer);
 | |
|     }
 | |
| 
 | |
| // Delete the PDEV
 | |
| 
 | |
|     EngFreeMem(dhpdev);
 | |
| 
 | |
|     DISPDBG((2, "disabled PDEV\n"));
 | |
| 
 | |
| }
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * HSURF DrvEnableSurface(dhpdev)
 | |
| *
 | |
| * Enable the surface for the device.  This will actually intialize the
 | |
| * screen on the VGA.
 | |
| *
 | |
| * Warnings:
 | |
| *   This routine should only be called ONCE per PDEV.
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| HSURF DrvEnableSurface(DHPDEV dhpdev)
 | |
| {
 | |
|     PPDEV    ppdev;
 | |
|     PDEVSURF pdsurf;
 | |
|     DHSURF   dhsurf;
 | |
|     HSURF    hsurf;
 | |
| 
 | |
|     DISPDBG((2, "enabling Surface\n"));
 | |
| 
 | |
|     ppdev = (PPDEV) dhpdev;
 | |
| 
 | |
|     //
 | |
|     // Initialize the VGA device into the selected mode which will also map
 | |
|     // the video frame buffer
 | |
|     //
 | |
| 
 | |
|     if (!bInitVGA(ppdev, TRUE))
 | |
|     {
 | |
|         goto error_done;
 | |
|     }
 | |
| 
 | |
|     dhsurf = (DHSURF) EngAllocMem(0, sizeof(DEVSURF), ALLOC_TAG);
 | |
| 
 | |
|     if (dhsurf == (DHSURF) 0)
 | |
|     {
 | |
|         goto error_done;
 | |
|     }
 | |
| 
 | |
|     pdsurf = (PDEVSURF) dhsurf;
 | |
| 
 | |
|     pdsurf->ident           = DEVSURF_IDENT;
 | |
|     pdsurf->flSurf          = 0;
 | |
|     pdsurf->iFormat         = BMF_PHYSDEVICE;
 | |
|     pdsurf->jReserved1      = 0;
 | |
|     pdsurf->jReserved2      = 0;
 | |
|     pdsurf->ppdev           = ppdev;
 | |
|     pdsurf->sizlSurf.cx     = ppdev->sizlSurf.cx;
 | |
|     pdsurf->sizlSurf.cy     = ppdev->sizlSurf.cy;
 | |
|     pdsurf->lNextPlane      = 0;
 | |
|     pdsurf->pvScan0         = ppdev->pjScreen;
 | |
|     pdsurf->pvBitmapStart   = ppdev->pjScreen;
 | |
|     pdsurf->pvStart         = ppdev->pjScreen;
 | |
|     pdsurf->pvConv          = &ajConvertBuffer[0];
 | |
| 
 | |
|     // Initialize pointer information.
 | |
| 
 | |
|     //
 | |
|     // bInitPointer must be called before bInitSavedBits.
 | |
|     //
 | |
| 
 | |
|     if (!bInitPointer(ppdev)) {
 | |
|         DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
 | |
|         goto error_clean;
 | |
|     }
 | |
| 
 | |
|     if (!SetUpBanking(pdsurf, ppdev)) {
 | |
|         DISPDBG((0, "DrvEnablePDEV failed SetUpBanking\n"));
 | |
|         goto error_clean;
 | |
|     }
 | |
| 
 | |
|     if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizlSurf, BMF_4BPP)) ==
 | |
|         (HSURF) 0)
 | |
|     {
 | |
|         DISPDBG((0, "DrvEnablePDEV failed EngCreateDeviceSurface\n"));
 | |
|         goto error_clean;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // vInitSavedBits must be called after bInitPointer.
 | |
|     //
 | |
| 
 | |
|     vInitSavedBits(ppdev);
 | |
| 
 | |
|     if (EngAssociateSurface(hsurf, ppdev->hdevEng,
 | |
|                         HOOK_BITBLT | HOOK_TEXTOUT | HOOK_STROKEPATH |
 | |
|                         HOOK_COPYBITS | HOOK_PAINT | HOOK_FILLPATH
 | |
|                         ))
 | |
|     {
 | |
|         ppdev->hsurfEng = hsurf;
 | |
|         ppdev->pdsurf = pdsurf;
 | |
| 
 | |
|         // Set up an empty saved screen block list
 | |
|         pdsurf->ssbList = NULL;
 | |
| 
 | |
|         DISPDBG((2, "enabled surface\n"));
 | |
| 
 | |
|         return(hsurf);
 | |
|     }
 | |
| 
 | |
|     DISPDBG((0, "DrvEnablePDEV failed EngDeleteSurface\n"));
 | |
|     EngDeleteSurface(hsurf);
 | |
| 
 | |
| error_clean:
 | |
|     // We created the surface, so delete it
 | |
|     EngFreeMem(dhsurf);
 | |
| 
 | |
| error_done:
 | |
|     return((HSURF) 0);
 | |
| }
 | |
| 
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * DrvDisableSurface
 | |
| *
 | |
| * Free resources associated with this surface.
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| VOID DrvDisableSurface(DHPDEV dhpdev)
 | |
| {
 | |
|     PPDEV   ppdev = (PPDEV) dhpdev;
 | |
|     PDEVSURF pdsurf = ppdev->pdsurf;
 | |
|     PSAVED_SCREEN_BITS pSSB, pSSBNext;
 | |
| 
 | |
|     DISPDBG((2, "disabling surface\n"));
 | |
| 
 | |
|     // Free up banking-related stuff.
 | |
|     EngFreeMem(pdsurf->pBankSelectInfo);
 | |
| 
 | |
|     if (pdsurf->pbiBankInfo != NULL) {
 | |
|         EngFreeMem(pdsurf->pbiBankInfo);
 | |
|     }
 | |
| 
 | |
|     if (pdsurf->pbiBankInfo2RW != NULL) {
 | |
|         EngFreeMem(pdsurf->pbiBankInfo2RW);
 | |
|     }
 | |
| 
 | |
|     if (pdsurf->pvBankBufferPlane0 != NULL) {
 | |
|         EngFreeMem(pdsurf->pvBankBufferPlane0);
 | |
|     }
 | |
| 
 | |
|     if (ppdev->pPointerAttributes != NULL) {
 | |
|         EngFreeMem(ppdev->pPointerAttributes);
 | |
|     }
 | |
| 
 | |
|     // Free any pending saved screen bit blocks.
 | |
|     pSSB = pdsurf->ssbList;
 | |
|     while (pSSB != (PSAVED_SCREEN_BITS) NULL) {
 | |
| 
 | |
|         //
 | |
|         // Point to the next saved screen bits block
 | |
|         //
 | |
| 
 | |
|         pSSBNext = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
 | |
| 
 | |
|         //
 | |
|         // Free the current block
 | |
|         //
 | |
| 
 | |
|         EngFreeMem(pSSB);
 | |
|         pSSB = pSSBNext;
 | |
|     }
 | |
| 
 | |
|     EngDeleteSurface((HSURF) ppdev->hsurfEng);
 | |
| 
 | |
|     EngFreeMem(pdsurf);  // free the surface
 | |
| 
 | |
|     DISPDBG((2, "disabled surface\n"));
 | |
| 
 | |
| }
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * DrvAssertMode
 | |
| *
 | |
| * Ping the device back into its last known mode
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| BOOL DrvAssertMode(DHPDEV dhpdev, BOOL Enable)
 | |
| {
 | |
|     PPDEV   ppdev = (PPDEV) dhpdev;
 | |
|     ULONG   returnedDataLength;
 | |
| 
 | |
|     DISPDBG((2, "DrvAssertMode\n"));
 | |
| 
 | |
|     if (Enable) {
 | |
| 
 | |
|         //
 | |
|         // The screen must be reenabled since we had gone to full screen,
 | |
|         // or another pdev.
 | |
|         // Re-initialize the device.
 | |
|         //
 | |
| 
 | |
|         pPtrSave = ppdev->pPtrSave;
 | |
|         pPtrWork = ppdev->pPtrWork;
 | |
| 
 | |
|         if (!bInitVGA(ppdev, FALSE))
 | |
|         {
 | |
|             RIP("DrvAssertMode failed bInitVGA\n");
 | |
|             return FALSE;
 | |
|         }
 | |
| 
 | |
|         vForceBank0(ppdev);
 | |
| 
 | |
|         // Restore the off screen data.  This protects the Desktop
 | |
|         // from a DOS application that might trash the off screen
 | |
|         // memory.
 | |
| 
 | |
|         ppdev->bBitsSaved = FALSE;  // clear the DrvSaveScreenBits info flag
 | |
|                                     // ie. blow away cached screen region
 | |
| 
 | |
|     } else {
 | |
| 
 | |
|         //
 | |
|         // We must give up the display.
 | |
|         // Call the kernel driver to reset the device to a known state.
 | |
|         //
 | |
| 
 | |
|         if (EngDeviceIoControl(ppdev->hDriver,
 | |
|                                IOCTL_VIDEO_RESET_DEVICE,
 | |
|                                NULL,
 | |
|                                0,
 | |
|                                NULL,
 | |
|                                0,
 | |
|                                &returnedDataLength))
 | |
|         {
 | |
|             RIP("Reset Device Failed");
 | |
|             return FALSE;
 | |
| 
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * DrvGetModes
 | |
| *
 | |
| * Returns the list of available modes for the device.
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| ULONG DrvGetModes(
 | |
| HANDLE hDriver,
 | |
| ULONG cjSize,
 | |
| DEVMODEW *pdm)
 | |
| 
 | |
| {
 | |
| 
 | |
|     DWORD cModes;
 | |
|     DWORD cbOutputSize;
 | |
|     PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
 | |
|     DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
 | |
|     DWORD cbModeSize;
 | |
| 
 | |
|     DISPDBG((2, "DrvGetModes\n"));
 | |
| 
 | |
|     cModes = getAvailableModes(hDriver,
 | |
|                                (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
 | |
|                                &cbModeSize);
 | |
| 
 | |
|     if (cModes == 0)
 | |
|     {
 | |
|         DISPDBG((0, "DrvGetModes failed to get mode information"));
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     if (pdm == NULL)
 | |
|     {
 | |
|         cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         //
 | |
|         // Now copy the information for the supported modes back into the output
 | |
|         // buffer
 | |
|         //
 | |
| 
 | |
|         cbOutputSize = 0;
 | |
| 
 | |
|         pVideoTemp = pVideoModeInformation;
 | |
| 
 | |
|         do
 | |
|         {
 | |
|             if (pVideoTemp->Length != 0)
 | |
|             {
 | |
|                 if (cOutputModes == 0)
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 //
 | |
|                 // Zero the entire structure to start off with.
 | |
|                 //
 | |
| 
 | |
|                 memset(pdm, 0, sizeof(DEVMODEW));
 | |
| 
 | |
|                 //
 | |
|                 // Set the name of the device to the name of the DLL.
 | |
|                 //
 | |
| 
 | |
|                 memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
 | |
| 
 | |
|                 pdm->dmSpecVersion      = DM_SPECVERSION;
 | |
|                 pdm->dmDriverVersion    = DM_SPECVERSION;
 | |
|                 pdm->dmSize             = sizeof(DEVMODEW);
 | |
|                 pdm->dmDriverExtra      = DRIVER_EXTRA_SIZE;
 | |
| 
 | |
|                 pdm->dmBitsPerPel       = pVideoTemp->NumberOfPlanes *
 | |
|                                           pVideoTemp->BitsPerPlane;
 | |
|                 pdm->dmPelsWidth        = pVideoTemp->VisScreenWidth;
 | |
|                 pdm->dmPelsHeight       = pVideoTemp->VisScreenHeight;
 | |
|                 pdm->dmDisplayFrequency = pVideoTemp->Frequency;
 | |
|                 pdm->dmDisplayFlags     = 0;
 | |
| 
 | |
|                 pdm->dmFields           = DM_BITSPERPEL       |
 | |
|                                           DM_PELSWIDTH        |
 | |
|                                           DM_PELSHEIGHT       |
 | |
|                                           DM_DISPLAYFREQUENCY |
 | |
|                                           DM_DISPLAYFLAGS     ;
 | |
| 
 | |
|                 //
 | |
|                 // Go to the next DEVMODE entry in the buffer.
 | |
|                 //
 | |
| 
 | |
|                 cOutputModes--;
 | |
| 
 | |
|                 pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) +
 | |
|                                                    DRIVER_EXTRA_SIZE);
 | |
| 
 | |
|                 cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
 | |
| 
 | |
|             }
 | |
| 
 | |
|             pVideoTemp = (PVIDEO_MODE_INFORMATION)
 | |
|                 (((PUCHAR)pVideoTemp) + cbModeSize);
 | |
| 
 | |
|         } while (--cModes);
 | |
|     }
 | |
| 
 | |
|     EngFreeMem(pVideoModeInformation);
 | |
| 
 | |
|     return cbOutputSize;
 | |
| 
 | |
| }
 | |
| 
 | |
| /******************************Public*Routine******************************\
 | |
| * VOID vInitSavedBits(ppdev)
 | |
| *
 | |
| * Initializes saved bits structures.  Must be done after bank
 | |
| * initialization and vInitBrushCache.
 | |
| *
 | |
| \**************************************************************************/
 | |
| 
 | |
| VOID vInitSavedBits(PPDEV ppdev)
 | |
| {
 | |
|     if (!(ppdev->fl & DRIVER_OFFSCREEN_REFRESHED))
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // set up rect to right of visible screen
 | |
|     //
 | |
|     ppdev->rclSavedBitsRight.left   = ppdev->sizlSurf.cx;
 | |
|     ppdev->rclSavedBitsRight.top    = 0;
 | |
|     ppdev->rclSavedBitsRight.right  = ppdev->sizlMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
 | |
|     ppdev->rclSavedBitsRight.bottom = ppdev->sizlSurf.cy;
 | |
| 
 | |
|     if ((ppdev->rclSavedBitsRight.right <= ppdev->rclSavedBitsRight.left) ||
 | |
|         (ppdev->rclSavedBitsRight.bottom <= ppdev->rclSavedBitsRight.top))
 | |
|     {
 | |
|         ppdev->rclSavedBitsRight.left   = 0;
 | |
|         ppdev->rclSavedBitsRight.top    = 0;
 | |
|         ppdev->rclSavedBitsRight.right  = 0;
 | |
|         ppdev->rclSavedBitsRight.bottom = 0;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // set up rect below visible screen
 | |
|     //
 | |
|     ppdev->rclSavedBitsBottom.left   = 0;
 | |
|     ppdev->rclSavedBitsBottom.top    = ppdev->sizlSurf.cy;
 | |
|     ppdev->rclSavedBitsBottom.right  = ppdev->sizlMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
 | |
|     ppdev->rclSavedBitsBottom.bottom = ppdev->sizlMem.cy - ppdev->cNumScansUsedByPointer;
 | |
| 
 | |
|     if ((ppdev->rclSavedBitsBottom.right <= ppdev->rclSavedBitsBottom.left) ||
 | |
|         (ppdev->rclSavedBitsBottom.bottom <= ppdev->rclSavedBitsBottom.top))
 | |
|     {
 | |
|         ppdev->rclSavedBitsBottom.left   = 0;
 | |
|         ppdev->rclSavedBitsBottom.top    = 0;
 | |
|         ppdev->rclSavedBitsBottom.right  = 0;
 | |
|         ppdev->rclSavedBitsBottom.bottom = 0;
 | |
|     }
 | |
| 
 | |
|     DISPDBG((1,"rclSavedBitsRight: (%4x,%4x,%4x,%4x)\n",
 | |
|                ppdev->rclSavedBitsRight.left,
 | |
|                ppdev->rclSavedBitsRight.top,
 | |
|                ppdev->rclSavedBitsRight.right,
 | |
|                ppdev->rclSavedBitsRight.bottom
 | |
|             ));
 | |
| 
 | |
|     DISPDBG((1,"rclSavedBitsBottom: (%4x,%4x,%4x,%4x)\n",
 | |
|                ppdev->rclSavedBitsBottom.left,
 | |
|                ppdev->rclSavedBitsBottom.top,
 | |
|                ppdev->rclSavedBitsBottom.right,
 | |
|                ppdev->rclSavedBitsBottom.bottom
 | |
|             ));
 | |
| 
 | |
|     //
 | |
|     // NOTE: we have subtracted one DWORD from the right edge.  This is because
 | |
|     //       later it is assumed that we can align by right shifting by up to
 | |
|     //       one DWORD (unless of course, the width of the buffer is 0).
 | |
|     //
 | |
| 
 | |
|     ppdev->bBitsSaved = FALSE;
 | |
| 
 | |
|     return;
 | |
| }
 |