2 * PROJECT: ReactOS Framebuffer Display Driver
3 * LICENSE: Microsoft NT4 DDK Sample Code License
4 * FILE: boot/drivers/video/displays/framebuf/enable.c
5 * PURPOSE: Main Driver Initialization and PDEV Enabling
6 * PROGRAMMERS: Copyright (c) 1992-1995 Microsoft Corporation
7 * ReactOS Portable Systems Group
12 // The driver function table with all function index/address pairs
14 static DRVFN gadrvfn
[] =
16 { INDEX_DrvEnablePDEV
, (PFN
) DrvEnablePDEV
},
17 { INDEX_DrvCompletePDEV
, (PFN
) DrvCompletePDEV
},
18 { INDEX_DrvDisablePDEV
, (PFN
) DrvDisablePDEV
},
19 { INDEX_DrvEnableSurface
, (PFN
) DrvEnableSurface
},
20 { INDEX_DrvDisableSurface
, (PFN
) DrvDisableSurface
},
21 { INDEX_DrvAssertMode
, (PFN
) DrvAssertMode
},
22 // eVb: 1.2 [VGARISC Change] - Disable hardware palette support
23 { INDEX_DrvSetPalette
, (PFN
) DrvSetPalette
},
25 // eVb: 1.1 [VGARISC Change] - Disable hardware pointer support
27 { INDEX_DrvMovePointer
, (PFN
) DrvMovePointer
},
28 { INDEX_DrvSetPointerShape
, (PFN
) DrvSetPointerShape
},
31 { INDEX_DrvGetModes
, (PFN
) DrvGetModes
}
34 // Define the functions you want to hook for 8/16/24/32 pel formats
36 #define HOOKS_BMF8BPP 0
38 #define HOOKS_BMF16BPP 0
40 #define HOOKS_BMF24BPP 0
42 #define HOOKS_BMF32BPP 0
44 /******************************Public*Routine******************************\
47 * Enables the driver by retrieving the drivers function table and version.
49 \**************************************************************************/
56 // Engine Version is passed down so future drivers can support previous
57 // engine versions. A next generation driver can support both the old
58 // and new engine conventions if told what version of engine it is
59 // working with. For the first version the driver does nothing with it.
60 // eVb: 1.1 [DDK Change] - Remove bogus statement
63 // Fill in as much as we can.
65 if (cj
>= sizeof(DRVENABLEDATA
))
66 pded
->pdrvfn
= gadrvfn
;
68 if (cj
>= (sizeof(ULONG
) * 2))
69 pded
->c
= sizeof(gadrvfn
) / sizeof(DRVFN
);
71 // DDI version this driver was targeted for is passed back to engine.
72 // Future graphic's engine may break calls down to old driver format.
74 if (cj
>= sizeof(ULONG
))
75 // eVb: 1.2 [DDK Change] - Use DDI_DRIVER_VERSION_NT4 instead of DDI_DRIVER_VERSION
76 pded
->iDriverVersion
= DDI_DRIVER_VERSION_NT4
;
82 /******************************Public*Routine******************************\
85 * DDI function, Enables the Physical Device.
87 * Return Value: device handle to pdev.
89 \**************************************************************************/
92 DEVMODEW
*pDevmode
, // Pointer to DEVMODE
93 PWSTR pwszLogAddress
, // Logical address
94 ULONG cPatterns
, // number of patterns
95 HSURF
*ahsurfPatterns
, // return standard patterns
96 ULONG cjGdiInfo
, // Length of memory pointed to by pGdiInfo
97 ULONG
*pGdiInfo
, // Pointer to GdiInfo structure
98 ULONG cjDevInfo
, // Length of following PDEVINFO structure
99 DEVINFO
*pDevInfo
, // physical device information structure
100 HDEV hdev
, // HDEV, used for callbacks
101 PWSTR pwszDeviceName
, // DeviceName - not used
102 HANDLE hDriver
) // Handle to base driver
106 PPDEV ppdev
= (PPDEV
) NULL
;
108 UNREFERENCED_PARAMETER(pwszLogAddress
);
109 UNREFERENCED_PARAMETER(pwszDeviceName
);
111 // Allocate a physical device structure.
113 ppdev
= (PPDEV
) EngAllocMem(0, sizeof(PDEV
), ALLOC_TAG
);
115 if (ppdev
== (PPDEV
) NULL
)
117 RIP("DISP DrvEnablePDEV failed EngAllocMem\n");
121 memset(ppdev
, 0, sizeof(PDEV
));
123 // Save the screen handle in the PDEV.
125 ppdev
->hDriver
= hDriver
;
127 // Get the current screen mode information. Set up device caps and devinfo.
129 if (!bInitPDEV(ppdev
, pDevmode
, &GdiInfo
, &DevInfo
))
131 DISPDBG((0,"DISP DrvEnablePDEV failed\n"));
135 // eVb: 1.2 [VGARISC Change] - Disable hardware pointer support
137 // Initialize the cursor information.
139 if (!bInitPointer(ppdev
, &DevInfo
))
141 // Not a fatal error...
142 DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
147 // Initialize palette information.
149 if (!bInitPaletteInfo(ppdev
, &DevInfo
))
151 RIP("DrvEnablePDEV failed bInitPalette\n");
155 // Copy the devinfo into the engine buffer.
157 memcpy(pDevInfo
, &DevInfo
, min(sizeof(DEVINFO
), cjDevInfo
));
159 // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
162 memcpy(pGdiInfo
, &GdiInfo
, min(cjGdiInfo
, sizeof(GDIINFO
)));
164 return((DHPDEV
) ppdev
);
166 // Error case for failure.
172 /******************************Public*Routine******************************\
175 * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
177 \**************************************************************************/
179 VOID
DrvCompletePDEV(
183 ((PPDEV
) dhpdev
)->hdevEng
= hdev
;
186 /******************************Public*Routine******************************\
189 * Release the resources allocated in DrvEnablePDEV. If a surface has been
190 * enabled DrvDisableSurface will have already been called.
192 \**************************************************************************/
197 vDisablePalette((PPDEV
) dhpdev
);
201 /******************************Public*Routine******************************\
204 * Enable the surface for the device. Hook the calls this driver supports.
206 * Return: Handle to the surface if successful, 0 for failure.
208 \**************************************************************************/
210 HSURF
DrvEnableSurface(
219 // Create engine bitmap around frame buffer.
221 ppdev
= (PPDEV
) dhpdev
;
223 if (!bInitSURF(ppdev
, TRUE
))
225 RIP("DISP DrvEnableSurface failed bInitSURF\n");
229 sizl
.cx
= ppdev
->cxScreen
;
230 sizl
.cy
= ppdev
->cyScreen
;
232 // eVb: 1.3 [VGARISC Change] - Disable dynamic palette and > 4BPP support
234 if (ppdev
->ulBitCount
== 8)
236 if (!bInit256ColorPalette(ppdev
)) {
237 RIP("DISP DrvEnableSurface failed to init the 8bpp palette\n");
240 ulBitmapType
= BMF_8BPP
;
241 flHooks
= HOOKS_BMF8BPP
;
243 else if (ppdev
->ulBitCount
== 16)
245 ulBitmapType
= BMF_16BPP
;
246 flHooks
= HOOKS_BMF16BPP
;
248 else if (ppdev
->ulBitCount
== 24)
250 ulBitmapType
= BMF_24BPP
;
251 flHooks
= HOOKS_BMF24BPP
;
255 ulBitmapType
= BMF_32BPP
;
256 flHooks
= HOOKS_BMF32BPP
;
258 // eVb: 1.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
259 ppdev
->flHooks
= flHooks
;
262 ulBitmapType
= BMF_4BPP
;
265 // eVb: 1.4 [DDK Change] - Use EngCreateDeviceSurface instead of EngCreateBitmap
266 hsurf
= (HSURF
)EngCreateDeviceSurface((DHSURF
)ppdev
,
270 if (hsurf
== (HSURF
) 0)
272 RIP("DISP DrvEnableSurface failed EngCreateDeviceSurface\n");
277 // eVb: 1.5 [DDK Change] - Use EngModifySurface instead of EngAssociateSurface
278 if ( !EngModifySurface(hsurf
,
280 ppdev
->flHooks
| HOOK_SYNCHRONIZE
,
287 RIP("DISP DrvEnableSurface failed EngModifySurface\n");
291 ppdev
->hsurfEng
= hsurf
;
292 // eVb: 1.4 [VGARISC Change] - Allocate 4BPP DIB that will store GDI drawing
294 hSurfBitmap
= (HSURF
)EngCreateBitmap(sizl
, 0, ulBitmapType
, 0, NULL
);
295 if (hSurfBitmap
== (HSURF
) 0)
297 RIP("DISP DrvEnableSurface failed EngCreateBitmap\n");
301 if ( !EngModifySurface(hSurfBitmap
,
303 ppdev
->flHooks
| HOOK_SYNCHRONIZE
,
310 RIP("DISP DrvEnableSurface failed second EngModifySurface\n");
314 ppdev
->pso
= EngLockSurface(hSurfBitmap
);
315 if (ppdev
->pso
== NULL
)
317 RIP("DISP DrvEnableSurface failed EngLockSurface\n");
324 /******************************Public*Routine******************************\
327 * Free resources allocated by DrvEnableSurface. Release the surface.
329 \**************************************************************************/
331 VOID
DrvDisableSurface(
334 EngDeleteSurface(((PPDEV
) dhpdev
)->hsurfEng
);
335 vDisableSURF((PPDEV
) dhpdev
);
336 ((PPDEV
) dhpdev
)->hsurfEng
= (HSURF
) 0;
339 /******************************Public*Routine******************************\
342 * This asks the device to reset itself to the mode of the pdev passed in.
344 \**************************************************************************/
350 PPDEV ppdev
= (PPDEV
) dhpdev
;
357 // The screen must be reenabled, reinitialize the device to clean state.
359 // eVb: 1.6 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
360 pjScreen
= ppdev
->pjScreen
;
362 if (!bInitSURF(ppdev
, FALSE
))
364 DISPDBG((0, "DISP DrvAssertMode failed bInitSURF\n"));
368 if (pjScreen
!= ppdev
->pjScreen
) {
370 if ( !EngModifySurface(ppdev
->hsurfEng
,
372 ppdev
->flHooks
| HOOK_SYNCHRONIZE
,
379 DISPDBG((0, "DISP DrvAssertMode failed EngModifySurface\n"));
389 // We must give up the display.
390 // Call the kernel driver to reset the device to a known state.
393 if (EngDeviceIoControl(ppdev
->hDriver
,
394 IOCTL_VIDEO_RESET_DEVICE
,
401 RIP("DISP DrvAssertMode failed IOCTL");
411 /******************************Public*Routine******************************\
414 * Returns the list of available modes for the device.
416 \**************************************************************************/
427 PVIDEO_MODE_INFORMATION pVideoModeInformation
, pVideoTemp
;
428 DWORD cOutputModes
= cjSize
/ (sizeof(DEVMODEW
) + DRIVER_EXTRA_SIZE
);
431 DISPDBG((3, "DrvGetModes\n"));
433 cModes
= getAvailableModes(hDriver
,
434 (PVIDEO_MODE_INFORMATION
*) &pVideoModeInformation
,
439 DISPDBG((0, "DrvGetModes failed to get mode information"));
445 cbOutputSize
= cModes
* (sizeof(DEVMODEW
) + DRIVER_EXTRA_SIZE
);
450 // Now copy the information for the supported modes back into the output
456 pVideoTemp
= pVideoModeInformation
;
460 if (pVideoTemp
->Length
!= 0)
462 if (cOutputModes
== 0)
468 // Zero the entire structure to start off with.
471 memset(pdm
, 0, sizeof(DEVMODEW
));
474 // Set the name of the device to the name of the DLL.
477 memcpy(pdm
->dmDeviceName
, DLL_NAME
, sizeof(DLL_NAME
));
479 pdm
->dmSpecVersion
= DM_SPECVERSION
;
480 pdm
->dmDriverVersion
= DM_SPECVERSION
;
481 pdm
->dmSize
= sizeof(DEVMODEW
);
482 pdm
->dmDriverExtra
= DRIVER_EXTRA_SIZE
;
484 pdm
->dmBitsPerPel
= pVideoTemp
->NumberOfPlanes
*
485 pVideoTemp
->BitsPerPlane
;
486 pdm
->dmPelsWidth
= pVideoTemp
->VisScreenWidth
;
487 pdm
->dmPelsHeight
= pVideoTemp
->VisScreenHeight
;
488 pdm
->dmDisplayFrequency
= pVideoTemp
->Frequency
;
489 pdm
->dmDisplayFlags
= 0;
491 pdm
->dmFields
= DM_BITSPERPEL
|
494 DM_DISPLAYFREQUENCY
|
498 // Go to the next DEVMODE entry in the buffer.
503 pdm
= (LPDEVMODEW
) ( ((ULONG
)pdm
) + sizeof(DEVMODEW
) +
506 cbOutputSize
+= (sizeof(DEVMODEW
) + DRIVER_EXTRA_SIZE
);
510 pVideoTemp
= (PVIDEO_MODE_INFORMATION
)
511 (((PUCHAR
)pVideoTemp
) + cbModeSize
);
516 EngFreeMem(pVideoModeInformation
);