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