2 * PROJECT: ReactOS Framebuffer Display Driver
3 * LICENSE: Microsoft NT4 DDK Sample Code License
4 * FILE: boot/drivers/video/displays/framebuf/screen.c
5 * PURPOSE: Surface, Screen and PDEV support/initialization
6 * PROGRAMMERS: Copyright (c) 1992-1995 Microsoft Corporation
7 * ReactOS Portable Systems Group
11 #define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | FF_DONTCARE,L"System"}
12 #define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | FF_DONTCARE,L"MS Sans Serif"}
13 #define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_DONTCARE, L"Courier"}
15 // This is the basic devinfo for a default driver. This is used as a base and customized based
16 // on information passed back from the miniport driver.
18 const DEVINFO gDevInfoFrameBuffer
= {
19 // eVb: 2.1 [VGARISC CHANGE] - No capabilities
22 // eVb: 2.8 [DDK CHANGE] - No dithering support
24 ), /* Graphics capabilities */
25 SYSTM_LOGFONT
, /* Default font description */
26 HELVE_LOGFONT
, /* ANSI variable font description */
27 COURI_LOGFONT
, /* ANSI fixed font description */
28 0, /* Count of device fonts */
29 // eVb: 2.2 [VGARISC CHANGE] - DIB format is 4BPP
30 BMF_4BPP
, /* Preferred DIB format */
32 // eVb: 2.9 [DDK CHANGE] - No dithering support
33 0, /* Width of color dither */
34 0, /* Height of color dither */
36 0 /* Default palette to use for this device */
39 // eVb: 2.3 [VGARISC CHANGE] - Add VGA structures from NT4 DDK Sample VGA driver
40 /******************************Public*Data*Struct*************************\
41 * This contains the GDIINFO structure that contains the device capabilities
42 * which are passed to the NT GDI engine during dhpdevEnablePDEV.
44 \**************************************************************************/
49 DT_RASDISPLAY
, // ulTechnology
52 0, // ulHorzRes (filled in at initialization)
53 0, // ulVertRes (filled in at initialization)
57 0, // flRaster (DDI reserved field)
59 0, // ulLogPixelsX (filled in at initialization)
60 0, // ulLogPixelsY (filled in at initialization)
62 TC_RA_ABLE
| TC_SCROLLBLT
, // flTextCaps
68 0x0024, // ulAspectX (one-to-one aspect ratio)
76 { 0, 0 }, // ptlPhysOffset
77 { 0, 0 }, // szlPhysSize
79 0, // ulNumPalReg (win3.1 16 color drivers say 0 too)
81 // These fields are for halftone initialization.
83 { // ciDevice, ColorInfo
84 { 6700, 3300, 0 }, // Red
85 { 2100, 7100, 0 }, // Green
86 { 1400, 800, 0 }, // Blue
87 { 1750, 3950, 0 }, // Cyan
88 { 4050, 2050, 0 }, // Magenta
89 { 4400, 5200, 0 }, // Yellow
90 { 3127, 3290, 0 }, // AlignmentWhite
97 0, // ulDevicePelsDPI (filled in at initialization)
98 PRIMARY_ORDER_CBA
, // ulPrimaryOrder
99 HT_PATSIZE_4x4_M
, // ulHTPatternSize
100 HT_FORMAT_4BPP_IRGB
, // ulHTOutputFormat
101 HT_FLAG_ADDITIVE_PRIMS
, // flHTFlags
104 // eVb: 2.4 [VGARISC DDK CHANGE] - Use 1 bit alignment, not 8
105 1, // ulBltAlignment (preferred window alignment
107 // for fast-text routines)
108 0, // ulPanningHorzRes
109 0, // ulPanningVertRes
112 /******************************Module*Header*******************************\
114 \**************************************************************************/
116 // Values for the internal, EGA-compatible palette.
118 static WORD PaletteBuffer
[] = {
121 0, // start with first palette register
123 // On the VGA, the palette contains indices into the array of color DACs.
124 // Since we can program the DACs as we please, we'll just put all the indices
125 // down at the beginning of the DAC array (that is, pass pixel values through
126 // the internal palette unchanged).
128 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
132 // These are the values for the first 16 DAC registers, the only ones we'll
133 // work with. These correspond to the RGB colors (6 bits for each primary, with
134 // the fourth entry unused) for pixel values 0-15.
136 static BYTE ColorBuffer
[] = {
141 0, // start with first palette register
142 0x00, 0x00, 0x00, 0x00, // black
143 0x2A, 0x00, 0x15, 0x00, // red
144 0x00, 0x2A, 0x15, 0x00, // green
145 0x2A, 0x2A, 0x15, 0x00, // mustard/brown
146 0x00, 0x00, 0x2A, 0x00, // blue
147 0x2A, 0x15, 0x2A, 0x00, // magenta
148 0x15, 0x2A, 0x2A, 0x00, // ScanLinesan
149 0x21, 0x22, 0x23, 0x00, // dark gray 2A
150 0x30, 0x31, 0x32, 0x00, // light gray 39
151 0x3F, 0x00, 0x00, 0x00, // bright red
152 0x00, 0x3F, 0x00, 0x00, // bright green
153 0x3F, 0x3F, 0x00, 0x00, // bright yellow
154 0x00, 0x00, 0x3F, 0x00, // bright blue
155 0x3F, 0x00, 0x3F, 0x00, // bright magenta
156 0x00, 0x3F, 0x3F, 0x00, // bright ScanLinesan
157 0x3F, 0x3F, 0x3F, 0x00 // bright white
160 /******************************Public*Routine******************************\
163 * Enables the surface. Maps the frame buffer into memory.
165 \**************************************************************************/
167 BOOL
bInitSURF(PPDEV ppdev
, BOOL bFirst
)
169 DWORD returnedDataLength
;
170 DWORD MaxWidth
, MaxHeight
;
171 VIDEO_MEMORY videoMemory
;
172 VIDEO_MEMORY_INFORMATION videoMemoryInformation
;
173 // eVb: 2.1 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
174 ULONG RemappingNeeded
= 0;
177 // Set the current mode into the hardware.
180 if (EngDeviceIoControl(ppdev
->hDriver
,
181 IOCTL_VIDEO_SET_CURRENT_MODE
,
184 // eVb: 2.2 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
188 &returnedDataLength
))
190 RIP("DISP bInitSURF failed IOCTL_SET_MODE\n");
195 // If this is the first time we enable the surface we need to map in the
198 // eVb: 2.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
199 if (bFirst
|| RemappingNeeded
)
202 videoMemory
.RequestedVirtualAddress
= NULL
;
204 if (EngDeviceIoControl(ppdev
->hDriver
,
205 IOCTL_VIDEO_MAP_VIDEO_MEMORY
,
207 sizeof(VIDEO_MEMORY
),
208 &videoMemoryInformation
,
209 sizeof(VIDEO_MEMORY_INFORMATION
),
210 &returnedDataLength
))
212 RIP("DISP bInitSURF failed IOCTL_VIDEO_MAP\n");
216 ppdev
->pjScreen
= (PBYTE
)(videoMemoryInformation
.FrameBufferBase
);
218 if (videoMemoryInformation
.FrameBufferBase
!=
219 videoMemoryInformation
.VideoRamBase
)
221 RIP("VideoRamBase does not correspond to FrameBufferBase\n");
223 // eVb: 2.4 [DDK Change] - Make sure frame buffer mapping worked
225 // Make sure we can access this video memory
228 *(PULONG
)(ppdev
->pjScreen
) = 0xaa55aa55;
230 if (*(PULONG
)(ppdev
->pjScreen
) != 0xaa55aa55) {
232 DISPDBG((1, "Frame buffer memory is not accessible.\n"));
236 ppdev
->cScreenSize
= videoMemoryInformation
.VideoRamLength
;
239 // Initialize the head of the offscreen list to NULL.
242 ppdev
->pOffscreenList
= NULL
;
244 // It's a hardware pointer; set up pointer attributes.
246 MaxHeight
= ppdev
->PointerCapabilities
.MaxHeight
;
248 // Allocate space for two DIBs (data/mask) for the pointer. If this
249 // device supports a color Pointer, we will allocate a larger bitmap.
250 // If this is a color bitmap we allocate for the largest possible
251 // bitmap because we have no idea of what the pixel depth might be.
253 // Width rounded up to nearest byte multiple
255 if (!(ppdev
->PointerCapabilities
.Flags
& VIDEO_MODE_COLOR_POINTER
))
257 MaxWidth
= (ppdev
->PointerCapabilities
.MaxWidth
+ 7) / 8;
261 MaxWidth
= ppdev
->PointerCapabilities
.MaxWidth
* sizeof(DWORD
);
264 ppdev
->cjPointerAttributes
=
265 sizeof(VIDEO_POINTER_ATTRIBUTES
) +
266 ((sizeof(UCHAR
) * MaxWidth
* MaxHeight
) * 2);
268 ppdev
->pPointerAttributes
= (PVIDEO_POINTER_ATTRIBUTES
)
269 EngAllocMem(0, ppdev
->cjPointerAttributes
, ALLOC_TAG
);
271 if (ppdev
->pPointerAttributes
== NULL
) {
273 DISPDBG((0, "bInitPointer EngAllocMem failed\n"));
277 ppdev
->pPointerAttributes
->Flags
= ppdev
->PointerCapabilities
.Flags
;
278 ppdev
->pPointerAttributes
->WidthInBytes
= MaxWidth
;
279 ppdev
->pPointerAttributes
->Width
= ppdev
->PointerCapabilities
.MaxWidth
;
280 ppdev
->pPointerAttributes
->Height
= MaxHeight
;
281 ppdev
->pPointerAttributes
->Column
= 0;
282 ppdev
->pPointerAttributes
->Row
= 0;
283 ppdev
->pPointerAttributes
->Enable
= 0;
289 /******************************Public*Routine******************************\
292 * Disable the surface. Un-Maps the frame in memory.
294 \**************************************************************************/
296 VOID
vDisableSURF(PPDEV ppdev
)
298 DWORD returnedDataLength
;
299 VIDEO_MEMORY videoMemory
;
301 videoMemory
.RequestedVirtualAddress
= (PVOID
) ppdev
->pjScreen
;
303 if (EngDeviceIoControl(ppdev
->hDriver
,
304 IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
,
306 sizeof(VIDEO_MEMORY
),
309 &returnedDataLength
))
311 RIP("DISP vDisableSURF failed IOCTL_VIDEO_UNMAP\n");
316 /******************************Public*Routine******************************\
319 * Determine the mode we should be in based on the DEVMODE passed in.
320 * Query mini-port to get information needed to fill in the DevInfo and the
323 \**************************************************************************/
332 PVIDEO_MODE_INFORMATION pVideoBuffer
, pVideoModeSelected
, pVideoTemp
;
333 VIDEO_COLOR_CAPABILITIES colorCapabilities
;
339 // calls the miniport to get mode information.
342 cModes
= getAvailableModes(ppdev
->hDriver
, &pVideoBuffer
, &cbModeSize
);
350 // Now see if the requested mode has a match in that table.
353 pVideoModeSelected
= NULL
;
354 pVideoTemp
= pVideoBuffer
;
356 if ((pDevMode
->dmPelsWidth
== 0) &&
357 (pDevMode
->dmPelsHeight
== 0) &&
358 (pDevMode
->dmBitsPerPel
== 0) &&
359 (pDevMode
->dmDisplayFrequency
== 0))
361 DISPDBG((2, "Default mode requested"));
362 bSelectDefault
= TRUE
;
366 // eVb: 2.5 [DDK Change] - Add missing newlines to debug output
367 DISPDBG((2, "Requested mode...\n"));
368 DISPDBG((2, " Screen width -- %li\n", pDevMode
->dmPelsWidth
));
369 DISPDBG((2, " Screen height -- %li\n", pDevMode
->dmPelsHeight
));
370 DISPDBG((2, " Bits per pel -- %li\n", pDevMode
->dmBitsPerPel
));
371 DISPDBG((2, " Frequency -- %li\n", pDevMode
->dmDisplayFrequency
));
373 bSelectDefault
= FALSE
;
378 if (pVideoTemp
->Length
!= 0)
380 if (bSelectDefault
||
381 ((pVideoTemp
->VisScreenWidth
== pDevMode
->dmPelsWidth
) &&
382 (pVideoTemp
->VisScreenHeight
== pDevMode
->dmPelsHeight
) &&
383 (pVideoTemp
->BitsPerPlane
*
384 pVideoTemp
->NumberOfPlanes
== pDevMode
->dmBitsPerPel
) &&
385 (pVideoTemp
->Frequency
== pDevMode
->dmDisplayFrequency
)))
387 pVideoModeSelected
= pVideoTemp
;
388 DISPDBG((3, "Found a match\n")) ;
393 pVideoTemp
= (PVIDEO_MODE_INFORMATION
)
394 (((PUCHAR
)pVideoTemp
) + cbModeSize
);
398 // If no mode has been found, return an error
401 if (pVideoModeSelected
== NULL
)
403 EngFreeMem(pVideoBuffer
);
404 DISPDBG((0,"DISP bInitPDEV failed - no valid modes\n"));
409 // Fill in the GDIINFO data structure with the information returned from
410 // the kernel driver.
413 ppdev
->ulMode
= pVideoModeSelected
->ModeIndex
;
414 ppdev
->cxScreen
= pVideoModeSelected
->VisScreenWidth
;
415 ppdev
->cyScreen
= pVideoModeSelected
->VisScreenHeight
;
416 ppdev
->lDeltaScreen
= pVideoModeSelected
->ScreenStride
;
417 // eVb: 2.8 [VGARISC CHANGE] - Extra fields not required on VGA, start with defaults
419 ppdev
->ulBitCount
= pVideoModeSelected
->BitsPerPlane
*
420 pVideoModeSelected
->NumberOfPlanes
;
421 ppdev
->flRed
= pVideoModeSelected
->RedMask
;
422 ppdev
->flGreen
= pVideoModeSelected
->GreenMask
;
423 ppdev
->flBlue
= pVideoModeSelected
->BlueMask
;
430 pGdiInfo
->ulVersion
= GDI_DRIVER_VERSION
;
431 pGdiInfo
->ulTechnology
= DT_RASDISPLAY
;
432 pGdiInfo
->ulHorzSize
= pVideoModeSelected
->XMillimeter
;
433 pGdiInfo
->ulVertSize
= pVideoModeSelected
->YMillimeter
;
435 pGdiInfo
->ulHorzRes
= ppdev
->cxScreen
;
436 pGdiInfo
->ulVertRes
= ppdev
->cyScreen
;
437 pGdiInfo
->ulPanningHorzRes
= ppdev
->cxScreen
;
438 pGdiInfo
->ulPanningVertRes
= ppdev
->cyScreen
;
439 pGdiInfo
->cBitsPixel
= pVideoModeSelected
->BitsPerPlane
;
440 pGdiInfo
->cPlanes
= pVideoModeSelected
->NumberOfPlanes
;
441 pGdiInfo
->ulVRefresh
= pVideoModeSelected
->Frequency
;
442 pGdiInfo
->ulBltAlignment
= 1; // We don't have accelerated screen-
443 // to-screen blts, and any
444 // window alignment is okay
446 pGdiInfo
->ulLogPixelsX
= pDevMode
->dmLogPixels
;
447 pGdiInfo
->ulLogPixelsY
= pDevMode
->dmLogPixels
;
449 // eVb: 2.9 [VGARISC CHANGE] - Extra fields not required on VGA
452 if (ppdev
->ulBitCount
== 8)
453 pGdiInfo
->flTextCaps
= (TC_RA_ABLE
| TC_SCROLLBLT
);
456 pGdiInfo
->flTextCaps
= TC_RA_ABLE
;
458 pGdiInfo
->flRaster
= 0; // flRaster is reserved by DDI
462 pGdiInfo
->ulDACRed
= pVideoModeSelected
->NumberRedBits
;
463 pGdiInfo
->ulDACGreen
= pVideoModeSelected
->NumberGreenBits
;
464 pGdiInfo
->ulDACBlue
= pVideoModeSelected
->NumberBlueBits
;
466 // eVb: 2.7 [VGARISC CHANGE] - Extra fields not required on VGA
468 pGdiInfo
->ulAspectX
= 0x24; // One-to-one aspect ratio
469 pGdiInfo
->ulAspectY
= 0x24;
470 pGdiInfo
->ulAspectXY
= 0x33;
472 pGdiInfo
->xStyleStep
= 1; // A style unit is 3 pels
473 pGdiInfo
->yStyleStep
= 1;
474 pGdiInfo
->denStyleStep
= 3;
476 pGdiInfo
->ptlPhysOffset
.x
= 0;
477 pGdiInfo
->ptlPhysOffset
.y
= 0;
478 pGdiInfo
->szlPhysSize
.cx
= 0;
479 pGdiInfo
->szlPhysSize
.cy
= 0;
481 // RGB and CMY color info.
484 // try to get it from the miniport.
485 // if the miniport doesn ot support this feature, use defaults.
488 if (EngDeviceIoControl(ppdev
->hDriver
,
489 IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
,
493 sizeof(VIDEO_COLOR_CAPABILITIES
),
497 DISPDBG((2, "getcolorCapabilities failed \n"));
499 pGdiInfo
->ciDevice
.Red
.x
= 6700;
500 pGdiInfo
->ciDevice
.Red
.y
= 3300;
501 pGdiInfo
->ciDevice
.Red
.Y
= 0;
502 pGdiInfo
->ciDevice
.Green
.x
= 2100;
503 pGdiInfo
->ciDevice
.Green
.y
= 7100;
504 pGdiInfo
->ciDevice
.Green
.Y
= 0;
505 pGdiInfo
->ciDevice
.Blue
.x
= 1400;
506 pGdiInfo
->ciDevice
.Blue
.y
= 800;
507 pGdiInfo
->ciDevice
.Blue
.Y
= 0;
508 pGdiInfo
->ciDevice
.AlignmentWhite
.x
= 3127;
509 pGdiInfo
->ciDevice
.AlignmentWhite
.y
= 3290;
510 pGdiInfo
->ciDevice
.AlignmentWhite
.Y
= 0;
512 pGdiInfo
->ciDevice
.RedGamma
= 20000;
513 pGdiInfo
->ciDevice
.GreenGamma
= 20000;
514 pGdiInfo
->ciDevice
.BlueGamma
= 20000;
519 pGdiInfo
->ciDevice
.Red
.x
= colorCapabilities
.RedChromaticity_x
;
520 pGdiInfo
->ciDevice
.Red
.y
= colorCapabilities
.RedChromaticity_y
;
521 pGdiInfo
->ciDevice
.Red
.Y
= 0;
522 pGdiInfo
->ciDevice
.Green
.x
= colorCapabilities
.GreenChromaticity_x
;
523 pGdiInfo
->ciDevice
.Green
.y
= colorCapabilities
.GreenChromaticity_y
;
524 pGdiInfo
->ciDevice
.Green
.Y
= 0;
525 pGdiInfo
->ciDevice
.Blue
.x
= colorCapabilities
.BlueChromaticity_x
;
526 pGdiInfo
->ciDevice
.Blue
.y
= colorCapabilities
.BlueChromaticity_y
;
527 pGdiInfo
->ciDevice
.Blue
.Y
= 0;
528 pGdiInfo
->ciDevice
.AlignmentWhite
.x
= colorCapabilities
.WhiteChromaticity_x
;
529 pGdiInfo
->ciDevice
.AlignmentWhite
.y
= colorCapabilities
.WhiteChromaticity_y
;
530 pGdiInfo
->ciDevice
.AlignmentWhite
.Y
= colorCapabilities
.WhiteChromaticity_Y
;
532 // if we have a color device store the three color gamma values,
533 // otherwise store the unique gamma value in all three.
535 if (colorCapabilities
.AttributeFlags
& VIDEO_DEVICE_COLOR
)
537 pGdiInfo
->ciDevice
.RedGamma
= colorCapabilities
.RedGamma
;
538 pGdiInfo
->ciDevice
.GreenGamma
= colorCapabilities
.GreenGamma
;
539 pGdiInfo
->ciDevice
.BlueGamma
= colorCapabilities
.BlueGamma
;
543 pGdiInfo
->ciDevice
.RedGamma
= colorCapabilities
.WhiteGamma
;
544 pGdiInfo
->ciDevice
.GreenGamma
= colorCapabilities
.WhiteGamma
;
545 pGdiInfo
->ciDevice
.BlueGamma
= colorCapabilities
.WhiteGamma
;
550 pGdiInfo
->ciDevice
.Cyan
.x
= 0;
551 pGdiInfo
->ciDevice
.Cyan
.y
= 0;
552 pGdiInfo
->ciDevice
.Cyan
.Y
= 0;
553 pGdiInfo
->ciDevice
.Magenta
.x
= 0;
554 pGdiInfo
->ciDevice
.Magenta
.y
= 0;
555 pGdiInfo
->ciDevice
.Magenta
.Y
= 0;
556 pGdiInfo
->ciDevice
.Yellow
.x
= 0;
557 pGdiInfo
->ciDevice
.Yellow
.y
= 0;
558 pGdiInfo
->ciDevice
.Yellow
.Y
= 0;
560 // No dye correction for raster displays.
562 pGdiInfo
->ciDevice
.MagentaInCyanDye
= 0;
563 pGdiInfo
->ciDevice
.YellowInCyanDye
= 0;
564 pGdiInfo
->ciDevice
.CyanInMagentaDye
= 0;
565 pGdiInfo
->ciDevice
.YellowInMagentaDye
= 0;
566 pGdiInfo
->ciDevice
.CyanInYellowDye
= 0;
567 pGdiInfo
->ciDevice
.MagentaInYellowDye
= 0;
569 pGdiInfo
->ulDevicePelsDPI
= 0; // For printers only
570 pGdiInfo
->ulPrimaryOrder
= PRIMARY_ORDER_CBA
;
572 // BUGBUG this should be modified to take into account the size
573 // of the display and the resolution.
575 pGdiInfo
->ulHTPatternSize
= HT_PATSIZE_4x4_M
;
577 pGdiInfo
->flHTFlags
= HT_FLAG_ADDITIVE_PRIMS
;
581 // Fill in the basic devinfo structure
583 *pDevInfo
= gDevInfoFrameBuffer
;
585 // eVb: 2.6 [VGARISC CHANGE] - Use defaults in gaulCap for GDI Info
587 // Fill in the rest of the devinfo and GdiInfo structures.
589 if (ppdev
->ulBitCount
== 8)
591 // It is Palette Managed.
593 pGdiInfo
->ulNumColors
= 20;
594 pGdiInfo
->ulNumPalReg
= 1 << ppdev
->ulBitCount
;
595 // eVb: 2.7 [DDK CHANGE] - No dithering support
596 pDevInfo
->flGraphicsCaps
|= GCAPS_PALMANAGED
;
598 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_8BPP
;
599 pDevInfo
->iDitherFormat
= BMF_8BPP
;
601 // Assuming palette is orthogonal - all colors are same size.
603 ppdev
->cPaletteShift
= 8 - pGdiInfo
->ulDACRed
;
607 pGdiInfo
->ulNumColors
= (ULONG
) (-1);
608 pGdiInfo
->ulNumPalReg
= 0;
610 if (ppdev
->ulBitCount
== 16)
612 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_16BPP
;
613 pDevInfo
->iDitherFormat
= BMF_16BPP
;
615 else if (ppdev
->ulBitCount
== 24)
617 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_24BPP
;
618 pDevInfo
->iDitherFormat
= BMF_24BPP
;
622 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_32BPP
;
623 pDevInfo
->iDitherFormat
= BMF_32BPP
;
629 EngFreeMem(pVideoBuffer
);
635 /******************************Public*Routine******************************\
638 * Calls the miniport to get the list of modes supported by the kernel driver,
639 * and returns the list of modes supported by the diplay driver among those
641 * returns the number of entries in the videomode buffer.
642 * 0 means no modes are supported by the miniport or that an error occured.
644 * NOTE: the buffer must be freed up by the caller.
646 \**************************************************************************/
648 DWORD
getAvailableModes(
650 PVIDEO_MODE_INFORMATION
*modeInformation
,
654 VIDEO_NUM_MODES modes
;
655 PVIDEO_MODE_INFORMATION pVideoTemp
;
658 // Get the number of modes supported by the mini-port
661 if (EngDeviceIoControl(hDriver
,
662 IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
,
666 sizeof(VIDEO_NUM_MODES
),
669 DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
673 *cbModeSize
= modes
.ModeInformationLength
;
676 // Allocate the buffer for the mini-port to write the modes in.
679 *modeInformation
= (PVIDEO_MODE_INFORMATION
)
680 EngAllocMem(0, modes
.NumModes
*
681 modes
.ModeInformationLength
, ALLOC_TAG
);
683 if (*modeInformation
== (PVIDEO_MODE_INFORMATION
) NULL
)
685 DISPDBG((0, "getAvailableModes failed EngAllocMem\n"));
691 // Ask the mini-port to fill in the available modes.
694 if (EngDeviceIoControl(hDriver
,
695 IOCTL_VIDEO_QUERY_AVAIL_MODES
,
699 modes
.NumModes
* modes
.ModeInformationLength
,
703 DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
705 EngFreeMem(*modeInformation
);
706 *modeInformation
= (PVIDEO_MODE_INFORMATION
) NULL
;
712 // Now see which of these modes are supported by the display driver.
713 // As an internal mechanism, set the length to 0 for the modes we
717 ulTemp
= modes
.NumModes
;
718 pVideoTemp
= *modeInformation
;
720 // eVb: 2.5 [VGARISC CHANGE] - Add correct mode checks for VGA
722 // Mode is rejected if it is not 4 planes, or not graphics, or is not
723 // one of 1 bits per pel.
728 if ((pVideoTemp
->NumberOfPlanes
!= 4 ) ||
729 !(pVideoTemp
->AttributeFlags
& VIDEO_MODE_GRAPHICS
) ||
730 ((pVideoTemp
->BitsPerPlane
!= 1) ||
731 (pVideoTemp
->VisScreenWidth
> 800)))
734 pVideoTemp
->Length
= 0;
737 pVideoTemp
= (PVIDEO_MODE_INFORMATION
)
738 (((PUCHAR
)pVideoTemp
) + modes
.ModeInformationLength
);
741 return modes
.NumModes
;