1 /*
2 * PROJECT: ReactOS Framebuffer Display Driver
3 * LICENSE: Microsoft NT4 DDK Sample Code License
4 * FILE: win32ss/drivers/displays/vga_new/enable.c
5 * PURPOSE: Main Driver Initialization and PDEV Enabling
6 * PROGRAMMERS: Copyright (c) 1992-1995 Microsoft Corporation
7 * ReactOS Portable Systems Group
8 */
9
10 #include "driver.h"
11
12 // The driver function table with all function index/address pairs
13
14 static DRVFN gadrvfn[] =
15 {
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 },
24 // eVb: 1.2 [END]
25 // eVb: 1.1 [VGARISC Change] - Disable hardware pointer support
26 #if 0
27 { INDEX_DrvMovePointer, (PFN) DrvMovePointer },
28 { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape },
29 #endif
30 // eVb: 1.1 [END]
31 { INDEX_DrvGetModes, (PFN) DrvGetModes }
32 };
33
34 // Define the functions you want to hook for 8/16/24/32 pel formats
35
36 #define HOOKS_BMF8BPP 0
37
38 #define HOOKS_BMF16BPP 0
39
40 #define HOOKS_BMF24BPP 0
41
42 #define HOOKS_BMF32BPP 0
43
44 /******************************Public*Routine******************************\
45 * DrvEnableDriver
46 *
47 * Enables the driver by retrieving the drivers function table and version.
48 *
49 \**************************************************************************/
50
DrvEnableDriver(ULONG iEngineVersion,ULONG cj,PDRVENABLEDATA pded)51 BOOL APIENTRY DrvEnableDriver(
52 ULONG iEngineVersion,
53 ULONG cj,
54 PDRVENABLEDATA pded)
55 {
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
61 //iEngineVersion;
62 // eVb: 1.1 [END]
63 // Fill in as much as we can.
64
65 if (cj >= sizeof(DRVENABLEDATA))
66 pded->pdrvfn = gadrvfn;
67
68 if (cj >= (sizeof(ULONG) * 2))
69 pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
70
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.
73
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;
77 // eVb: 1.2 [END]
78
79 return TRUE;
80 }
81
82 /******************************Public*Routine******************************\
83 * DrvEnablePDEV
84 *
85 * DDI function, Enables the Physical Device.
86 *
87 * Return Value: device handle to pdev.
88 *
89 \**************************************************************************/
90
DrvEnablePDEV(DEVMODEW * pDevmode,PWSTR pwszLogAddress,ULONG cPatterns,HSURF * ahsurfPatterns,ULONG cjGdiInfo,ULONG * pGdiInfo,ULONG cjDevInfo,DEVINFO * pDevInfo,HDEV hdev,PWSTR pwszDeviceName,HANDLE hDriver)91 DHPDEV APIENTRY DrvEnablePDEV(
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
103 {
104 GDIINFO GdiInfo;
105 DEVINFO DevInfo;
106 PPDEV ppdev = NULL;
107
108 UNREFERENCED_PARAMETER(pwszLogAddress);
109 UNREFERENCED_PARAMETER(pwszDeviceName);
110
111 // Allocate a physical device structure.
112
113 ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG);
114
115 if (ppdev == NULL)
116 {
117 RIP("DISP DrvEnablePDEV failed EngAllocMem\n");
118 return NULL;
119 }
120
121 memset(ppdev, 0, sizeof(PDEV));
122
123 // Save the screen handle in the PDEV.
124
125 ppdev->hDriver = hDriver;
126
127 // Get the current screen mode information. Set up device caps and devinfo.
128
129 if (!bInitPDEV(ppdev, pDevmode, &GdiInfo, &DevInfo))
130 {
131 DISPDBG((0,"DISP DrvEnablePDEV failed\n"));
132 goto error_free;
133 }
134
135 // eVb: 1.2 [VGARISC Change] - Disable hardware pointer support
136 #if 0
137 // Initialize the cursor information.
138
139 if (!bInitPointer(ppdev, &DevInfo))
140 {
141 // Not a fatal error...
142 DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
143 }
144
145 #endif
146 // eVb: 1.2 [END]
147 // Initialize palette information.
148
149 if (!bInitPaletteInfo(ppdev, &DevInfo))
150 {
151 RIP("DrvEnablePDEV failed bInitPalette\n");
152 goto error_free;
153 }
154
155 // Copy the devinfo into the engine buffer.
156
157 memcpy(pDevInfo, &DevInfo, min(sizeof(DEVINFO), cjDevInfo));
158
159 // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
160 // pdev.
161
162 memcpy(pGdiInfo, &GdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
163
164 return (DHPDEV)ppdev;
165
166 // Error case for failure.
167 error_free:
168 EngFreeMem(ppdev);
169 return NULL;
170 }
171
172 /******************************Public*Routine******************************\
173 * DrvCompletePDEV
174 *
175 * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
176 *
177 \**************************************************************************/
178
DrvCompletePDEV(DHPDEV dhpdev,HDEV hdev)179 VOID APIENTRY DrvCompletePDEV(
180 DHPDEV dhpdev,
181 HDEV hdev)
182 {
183 ((PPDEV) dhpdev)->hdevEng = hdev;
184 }
185
186 /******************************Public*Routine******************************\
187 * DrvDisablePDEV
188 *
189 * Release the resources allocated in DrvEnablePDEV. If a surface has been
190 * enabled DrvDisableSurface will have already been called.
191 *
192 \**************************************************************************/
193
DrvDisablePDEV(DHPDEV dhpdev)194 VOID APIENTRY DrvDisablePDEV(
195 DHPDEV dhpdev)
196 {
197 vDisablePalette((PPDEV) dhpdev);
198 EngFreeMem(dhpdev);
199 }
200
201 /******************************Public*Routine******************************\
202 * DrvEnableSurface
203 *
204 * Enable the surface for the device. Hook the calls this driver supports.
205 *
206 * Return: Handle to the surface if successful, 0 for failure.
207 *
208 \**************************************************************************/
209
DrvEnableSurface(DHPDEV dhpdev)210 HSURF APIENTRY DrvEnableSurface(
211 DHPDEV dhpdev)
212 {
213 PPDEV ppdev;
214 HSURF hsurf;
215 SIZEL sizl;
216 ULONG ulBitmapType;
217 #if 0
218 FLONG flHooks;
219 #endif
220 HSURF hSurfBitmap;
221
222 // Create engine bitmap around frame buffer.
223
224 ppdev = (PPDEV) dhpdev;
225
226 if (!bInitSURF(ppdev, TRUE))
227 {
228 RIP("DISP DrvEnableSurface failed bInitSURF\n");
229 return NULL;
230 }
231
232 sizl.cx = ppdev->cxScreen;
233 sizl.cy = ppdev->cyScreen;
234
235 // eVb: 1.3 [VGARISC Change] - Disable dynamic palette and > 4BPP support
236 #if 0
237 if (ppdev->ulBitCount == 8)
238 {
239 if (!bInit256ColorPalette(ppdev)) {
240 RIP("DISP DrvEnableSurface failed to init the 8bpp palette\n");
241 return NULL;
242 }
243 ulBitmapType = BMF_8BPP;
244 flHooks = HOOKS_BMF8BPP;
245 }
246 else if (ppdev->ulBitCount == 16)
247 {
248 ulBitmapType = BMF_16BPP;
249 flHooks = HOOKS_BMF16BPP;
250 }
251 else if (ppdev->ulBitCount == 24)
252 {
253 ulBitmapType = BMF_24BPP;
254 flHooks = HOOKS_BMF24BPP;
255 }
256 else
257 {
258 ulBitmapType = BMF_32BPP;
259 flHooks = HOOKS_BMF32BPP;
260 }
261 // eVb: 1.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
262 ppdev->flHooks = flHooks;
263 // eVb: 1.3 [END]
264 #else
265 ulBitmapType = BMF_4BPP;
266 #endif
267 // eVb: 1.3 [END]
268 // eVb: 1.4 [DDK Change] - Use EngCreateDeviceSurface instead of EngCreateBitmap
269 hsurf = (HSURF)EngCreateDeviceSurface((DHSURF)ppdev,
270 sizl,
271 ulBitmapType);
272
273 if (hsurf == NULL)
274 {
275 RIP("DISP DrvEnableSurface failed EngCreateDeviceSurface\n");
276 return NULL;
277 }
278 // eVb: 1.4 [END]
279
280 // eVb: 1.5 [DDK Change] - Use EngModifySurface instead of EngAssociateSurface
281 if ( !EngModifySurface(hsurf,
282 ppdev->hdevEng,
283 ppdev->flHooks | HOOK_SYNCHRONIZE,
284 MS_NOTSYSTEMMEMORY,
285 (DHSURF)ppdev,
286 ppdev->pjScreen,
287 ppdev->lDeltaScreen,
288 NULL))
289 {
290 RIP("DISP DrvEnableSurface failed EngModifySurface\n");
291 return NULL;
292 }
293 // eVb: 1.5 [END]
294 ppdev->hsurfEng = hsurf;
295 // eVb: 1.4 [VGARISC Change] - Allocate 4BPP DIB that will store GDI drawing
296 hSurfBitmap = (HSURF)EngCreateBitmap(sizl, 0, ulBitmapType, 0, NULL);
297 if (hSurfBitmap == NULL)
298 {
299 RIP("DISP DrvEnableSurface failed EngCreateBitmap\n");
300 return NULL;
301 }
302
303 if ( !EngModifySurface(hSurfBitmap,
304 ppdev->hdevEng,
305 ppdev->flHooks | HOOK_SYNCHRONIZE,
306 MS_NOTSYSTEMMEMORY,
307 (DHSURF)ppdev,
308 ppdev->pjScreen,
309 ppdev->lDeltaScreen,
310 NULL))
311 {
312 RIP("DISP DrvEnableSurface failed second EngModifySurface\n");
313 return NULL;
314 }
315
316 ppdev->pso = EngLockSurface(hSurfBitmap);
317 if (ppdev->pso == NULL)
318 {
319 RIP("DISP DrvEnableSurface failed EngLockSurface\n");
320 return NULL;
321 }
322 // eVb: 1.4 [END]
323 return hsurf;
324 }
325
326 /******************************Public*Routine******************************\
327 * DrvDisableSurface
328 *
329 * Free resources allocated by DrvEnableSurface. Release the surface.
330 *
331 \**************************************************************************/
332
DrvDisableSurface(DHPDEV dhpdev)333 VOID APIENTRY DrvDisableSurface(
334 DHPDEV dhpdev)
335 {
336 EngDeleteSurface(((PPDEV) dhpdev)->hsurfEng);
337 vDisableSURF((PPDEV) dhpdev);
338 ((PPDEV) dhpdev)->hsurfEng = NULL;
339 }
340
341 /******************************Public*Routine******************************\
342 * DrvAssertMode
343 *
344 * This asks the device to reset itself to the mode of the pdev passed in.
345 *
346 \**************************************************************************/
347
DrvAssertMode(DHPDEV dhpdev,BOOL bEnable)348 BOOL APIENTRY DrvAssertMode(
349 DHPDEV dhpdev,
350 BOOL bEnable)
351 {
352 PPDEV ppdev = (PPDEV) dhpdev;
353 ULONG ulReturn;
354 PBYTE pjScreen;
355
356 if (bEnable)
357 {
358 //
359 // The screen must be reenabled, reinitialize the device to clean state.
360 //
361 // eVb: 1.6 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
362 pjScreen = ppdev->pjScreen;
363
364 if (!bInitSURF(ppdev, FALSE))
365 {
366 DISPDBG((0, "DISP DrvAssertMode failed bInitSURF\n"));
367 return (FALSE);
368 }
369
370 if (pjScreen != ppdev->pjScreen) {
371
372 if ( !EngModifySurface(ppdev->hsurfEng,
373 ppdev->hdevEng,
374 ppdev->flHooks | HOOK_SYNCHRONIZE,
375 MS_NOTSYSTEMMEMORY,
376 (DHSURF)ppdev,
377 ppdev->pjScreen,
378 ppdev->lDeltaScreen,
379 NULL))
380 {
381 DISPDBG((0, "DISP DrvAssertMode failed EngModifySurface\n"));
382 return (FALSE);
383 }
384 }
385 // eVb: 1.6 [END]
386 return (TRUE);
387 }
388 else
389 {
390 //
391 // We must give up the display.
392 // Call the kernel driver to reset the device to a known state.
393 //
394
395 if (EngDeviceIoControl(ppdev->hDriver,
396 IOCTL_VIDEO_RESET_DEVICE,
397 NULL,
398 0,
399 NULL,
400 0,
401 &ulReturn))
402 {
403 RIP("DISP DrvAssertMode failed IOCTL");
404 return FALSE;
405 }
406 else
407 {
408 return TRUE;
409 }
410 }
411 }
412
413 /******************************Public*Routine******************************\
414 * DrvGetModes
415 *
416 * Returns the list of available modes for the device.
417 *
418 \**************************************************************************/
419
DrvGetModes(HANDLE hDriver,ULONG cjSize,DEVMODEW * pdm)420 ULONG APIENTRY DrvGetModes(
421 HANDLE hDriver,
422 ULONG cjSize,
423 DEVMODEW *pdm)
424
425 {
426
427 DWORD cModes;
428 DWORD cbOutputSize;
429 PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
430 DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
431 DWORD cbModeSize;
432
433 DISPDBG((3, "DrvGetModes\n"));
434
435 cModes = getAvailableModes(hDriver,
436 (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
437 &cbModeSize);
438
439 if (cModes == 0)
440 {
441 DISPDBG((0, "DrvGetModes failed to get mode information"));
442 return 0;
443 }
444
445 if (pdm == NULL)
446 {
447 cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
448 }
449 else
450 {
451 //
452 // Now copy the information for the supported modes back into the output
453 // buffer
454 //
455
456 cbOutputSize = 0;
457
458 pVideoTemp = pVideoModeInformation;
459
460 do
461 {
462 if (pVideoTemp->Length != 0)
463 {
464 if (cOutputModes == 0)
465 {
466 break;
467 }
468
469 //
470 // Zero the entire structure to start off with.
471 //
472
473 memset(pdm, 0, sizeof(DEVMODEW));
474
475 //
476 // Set the name of the device to the name of the DLL.
477 //
478
479 memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
480
481 pdm->dmSpecVersion = DM_SPECVERSION;
482 pdm->dmDriverVersion = DM_SPECVERSION;
483 pdm->dmSize = sizeof(DEVMODEW);
484 pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
485
486 pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
487 pVideoTemp->BitsPerPlane;
488 pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
489 pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
490 pdm->dmDisplayFrequency = pVideoTemp->Frequency;
491 pdm->dmDisplayFlags = 0;
492
493 pdm->dmFields = DM_BITSPERPEL |
494 DM_PELSWIDTH |
495 DM_PELSHEIGHT |
496 DM_DISPLAYFREQUENCY |
497 DM_DISPLAYFLAGS ;
498
499 //
500 // Go to the next DEVMODE entry in the buffer.
501 //
502
503 cOutputModes--;
504
505 pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) +
506 DRIVER_EXTRA_SIZE);
507
508 cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
509
510 }
511
512 pVideoTemp = (PVIDEO_MODE_INFORMATION)
513 (((PUCHAR)pVideoTemp) + cbModeSize);
514
515 } while (--cModes);
516 }
517
518 EngFreeMem(pVideoModeInformation);
519
520 return cbOutputSize;
521
522 }
523