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 { INDEX_DrvSetPalette
, (PFN
) DrvSetPalette
},
23 { INDEX_DrvMovePointer
, (PFN
) DrvMovePointer
},
24 { INDEX_DrvSetPointerShape
, (PFN
) DrvSetPointerShape
},
25 { INDEX_DrvGetModes
, (PFN
) DrvGetModes
}
28 // Define the functions you want to hook for 8/16/24/32 pel formats
30 #define HOOKS_BMF8BPP 0
32 #define HOOKS_BMF16BPP 0
34 #define HOOKS_BMF24BPP 0
36 #define HOOKS_BMF32BPP 0
38 /******************************Public*Routine******************************\
41 * Enables the driver by retrieving the drivers function table and version.
43 \**************************************************************************/
50 // Engine Version is passed down so future drivers can support previous
51 // engine versions. A next generation driver can support both the old
52 // and new engine conventions if told what version of engine it is
53 // working with. For the first version the driver does nothing with it.
54 // eVb: 1.1 [DDK Change] - Remove bogus statement
57 // Fill in as much as we can.
59 if (cj
>= sizeof(DRVENABLEDATA
))
60 pded
->pdrvfn
= gadrvfn
;
62 if (cj
>= (sizeof(ULONG
) * 2))
63 pded
->c
= sizeof(gadrvfn
) / sizeof(DRVFN
);
65 // DDI version this driver was targeted for is passed back to engine.
66 // Future graphic's engine may break calls down to old driver format.
68 if (cj
>= sizeof(ULONG
))
69 // eVb: 1.2 [DDK Change] - Use DDI_DRIVER_VERSION_NT4 instead of DDI_DRIVER_VERSION
70 pded
->iDriverVersion
= DDI_DRIVER_VERSION_NT4
;
76 /******************************Public*Routine******************************\
79 * DDI function, Enables the Physical Device.
81 * Return Value: device handle to pdev.
83 \**************************************************************************/
86 DEVMODEW
*pDevmode
, // Pointer to DEVMODE
87 PWSTR pwszLogAddress
, // Logical address
88 ULONG cPatterns
, // number of patterns
89 HSURF
*ahsurfPatterns
, // return standard patterns
90 ULONG cjGdiInfo
, // Length of memory pointed to by pGdiInfo
91 ULONG
*pGdiInfo
, // Pointer to GdiInfo structure
92 ULONG cjDevInfo
, // Length of following PDEVINFO structure
93 DEVINFO
*pDevInfo
, // physical device information structure
94 HDEV hdev
, // HDEV, used for callbacks
95 PWSTR pwszDeviceName
, // DeviceName - not used
96 HANDLE hDriver
) // Handle to base driver
100 PPDEV ppdev
= (PPDEV
) NULL
;
102 UNREFERENCED_PARAMETER(pwszLogAddress
);
103 UNREFERENCED_PARAMETER(pwszDeviceName
);
105 // Allocate a physical device structure.
107 ppdev
= (PPDEV
) EngAllocMem(0, sizeof(PDEV
), ALLOC_TAG
);
109 if (ppdev
== (PPDEV
) NULL
)
111 RIP("DISP DrvEnablePDEV failed EngAllocMem\n");
115 memset(ppdev
, 0, sizeof(PDEV
));
117 // Save the screen handle in the PDEV.
119 ppdev
->hDriver
= hDriver
;
121 // Get the current screen mode information. Set up device caps and devinfo.
123 if (!bInitPDEV(ppdev
, pDevmode
, &GdiInfo
, &DevInfo
))
125 DISPDBG((0,"DISP DrvEnablePDEV failed\n"));
129 // Initialize the cursor information.
131 if (!bInitPointer(ppdev
, &DevInfo
))
133 // Not a fatal error...
134 DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
137 // Initialize palette information.
139 if (!bInitPaletteInfo(ppdev
, &DevInfo
))
141 RIP("DrvEnablePDEV failed bInitPalette\n");
145 // Copy the devinfo into the engine buffer.
147 memcpy(pDevInfo
, &DevInfo
, min(sizeof(DEVINFO
), cjDevInfo
));
149 // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
152 memcpy(pGdiInfo
, &GdiInfo
, min(cjGdiInfo
, sizeof(GDIINFO
)));
154 return((DHPDEV
) ppdev
);
156 // Error case for failure.
162 /******************************Public*Routine******************************\
165 * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
167 \**************************************************************************/
169 VOID
DrvCompletePDEV(
173 ((PPDEV
) dhpdev
)->hdevEng
= hdev
;
176 /******************************Public*Routine******************************\
179 * Release the resources allocated in DrvEnablePDEV. If a surface has been
180 * enabled DrvDisableSurface will have already been called.
182 \**************************************************************************/
187 vDisablePalette((PPDEV
) dhpdev
);
191 /******************************Public*Routine******************************\
194 * Enable the surface for the device. Hook the calls this driver supports.
196 * Return: Handle to the surface if successful, 0 for failure.
198 \**************************************************************************/
200 HSURF
DrvEnableSurface(
209 // Create engine bitmap around frame buffer.
211 ppdev
= (PPDEV
) dhpdev
;
213 if (!bInitSURF(ppdev
, TRUE
))
215 RIP("DISP DrvEnableSurface failed bInitSURF\n");
219 sizl
.cx
= ppdev
->cxScreen
;
220 sizl
.cy
= ppdev
->cyScreen
;
222 if (ppdev
->ulBitCount
== 8)
224 if (!bInit256ColorPalette(ppdev
)) {
225 RIP("DISP DrvEnableSurface failed to init the 8bpp palette\n");
228 ulBitmapType
= BMF_8BPP
;
229 flHooks
= HOOKS_BMF8BPP
;
231 else if (ppdev
->ulBitCount
== 16)
233 ulBitmapType
= BMF_16BPP
;
234 flHooks
= HOOKS_BMF16BPP
;
236 else if (ppdev
->ulBitCount
== 24)
238 ulBitmapType
= BMF_24BPP
;
239 flHooks
= HOOKS_BMF24BPP
;
243 ulBitmapType
= BMF_32BPP
;
244 flHooks
= HOOKS_BMF32BPP
;
246 // eVb: 1.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
247 ppdev
->flHooks
= flHooks
;
249 // eVb: 1.4 [DDK Change] - Use EngCreateDeviceSurface instead of EngCreateBitmap
250 hsurf
= (HSURF
)EngCreateDeviceSurface((DHSURF
)ppdev
,
254 if (hsurf
== (HSURF
) 0)
256 RIP("DISP DrvEnableSurface failed EngCreateDeviceSurface\n");
261 // eVb: 1.5 [DDK Change] - Use EngModifySurface instead of EngAssociateSurface
262 if ( !EngModifySurface(hsurf
,
264 ppdev
->flHooks
| HOOK_SYNCHRONIZE
,
271 RIP("DISP DrvEnableSurface failed EngModifySurface\n");
275 ppdev
->hsurfEng
= hsurf
;
280 /******************************Public*Routine******************************\
283 * Free resources allocated by DrvEnableSurface. Release the surface.
285 \**************************************************************************/
287 VOID
DrvDisableSurface(
290 EngDeleteSurface(((PPDEV
) dhpdev
)->hsurfEng
);
291 vDisableSURF((PPDEV
) dhpdev
);
292 ((PPDEV
) dhpdev
)->hsurfEng
= (HSURF
) 0;
295 /******************************Public*Routine******************************\
298 * This asks the device to reset itself to the mode of the pdev passed in.
300 \**************************************************************************/
306 PPDEV ppdev
= (PPDEV
) dhpdev
;
313 // The screen must be reenabled, reinitialize the device to clean state.
315 // eVb: 1.6 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
316 pjScreen
= ppdev
->pjScreen
;
318 if (!bInitSURF(ppdev
, FALSE
))
320 DISPDBG((0, "DISP DrvAssertMode failed bInitSURF\n"));
324 if (pjScreen
!= ppdev
->pjScreen
) {
326 if ( !EngModifySurface(ppdev
->hsurfEng
,
328 ppdev
->flHooks
| HOOK_SYNCHRONIZE
,
335 DISPDBG((0, "DISP DrvAssertMode failed EngModifySurface\n"));
345 // We must give up the display.
346 // Call the kernel driver to reset the device to a known state.
349 if (EngDeviceIoControl(ppdev
->hDriver
,
350 IOCTL_VIDEO_RESET_DEVICE
,
357 RIP("DISP DrvAssertMode failed IOCTL");
367 /******************************Public*Routine******************************\
370 * Returns the list of available modes for the device.
372 \**************************************************************************/
383 PVIDEO_MODE_INFORMATION pVideoModeInformation
, pVideoTemp
;
384 DWORD cOutputModes
= cjSize
/ (sizeof(DEVMODEW
) + DRIVER_EXTRA_SIZE
);
387 DISPDBG((3, "DrvGetModes\n"));
389 cModes
= getAvailableModes(hDriver
,
390 (PVIDEO_MODE_INFORMATION
*) &pVideoModeInformation
,
395 DISPDBG((0, "DrvGetModes failed to get mode information"));
401 cbOutputSize
= cModes
* (sizeof(DEVMODEW
) + DRIVER_EXTRA_SIZE
);
406 // Now copy the information for the supported modes back into the output
412 pVideoTemp
= pVideoModeInformation
;
416 if (pVideoTemp
->Length
!= 0)
418 if (cOutputModes
== 0)
424 // Zero the entire structure to start off with.
427 memset(pdm
, 0, sizeof(DEVMODEW
));
430 // Set the name of the device to the name of the DLL.
433 memcpy(pdm
->dmDeviceName
, DLL_NAME
, sizeof(DLL_NAME
));
435 pdm
->dmSpecVersion
= DM_SPECVERSION
;
436 pdm
->dmDriverVersion
= DM_SPECVERSION
;
437 pdm
->dmSize
= sizeof(DEVMODEW
);
438 pdm
->dmDriverExtra
= DRIVER_EXTRA_SIZE
;
440 pdm
->dmBitsPerPel
= pVideoTemp
->NumberOfPlanes
*
441 pVideoTemp
->BitsPerPlane
;
442 pdm
->dmPelsWidth
= pVideoTemp
->VisScreenWidth
;
443 pdm
->dmPelsHeight
= pVideoTemp
->VisScreenHeight
;
444 pdm
->dmDisplayFrequency
= pVideoTemp
->Frequency
;
445 pdm
->dmDisplayFlags
= 0;
447 pdm
->dmFields
= DM_BITSPERPEL
|
450 DM_DISPLAYFREQUENCY
|
454 // Go to the next DEVMODE entry in the buffer.
459 pdm
= (LPDEVMODEW
) ( ((ULONG
)pdm
) + sizeof(DEVMODEW
) +
462 cbOutputSize
+= (sizeof(DEVMODEW
) + DRIVER_EXTRA_SIZE
);
466 pVideoTemp
= (PVIDEO_MODE_INFORMATION
)
467 (((PUCHAR
)pVideoTemp
) + cbModeSize
);
472 EngFreeMem(pVideoModeInformation
);