1 /*
2  * PROJECT:         ReactOS Framebuffer Display Driver
3  * LICENSE:         Microsoft NT4 DDK Sample Code License
4  * FILE:            win32ss/drivers/displays/vga_new/screen.c
5  * PURPOSE:         Surface, Screen and PDEV support/initialization
6  * PROGRAMMERS:     Copyright (c) 1992-1995 Microsoft Corporation
7  *                  ReactOS Portable Systems Group
8  */
9 #include "driver.h"
10 
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"}
14 
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.
17 
18 const DEVINFO gDevInfoFrameBuffer = {
19 // eVb: 2.1 [VGARISC CHANGE] - No capabilities
20     ( 0
21 // eVb: 2.1 [END]
22 // eVb: 2.8 [DDK CHANGE] - No dithering support
23 // eVb: 2.8 [END]
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          */
31 // eVb: 2.2 [END]
32 // eVb: 2.9 [DDK CHANGE] - No dithering support
33     0,                /* Width of color dither          */
34     0,                /* Height of color dither   */
35 // eVb: 2.9 [END]
36     0                 /* Default palette to use for this device */
37 };
38 
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.
43 *
44 \**************************************************************************/
45 
46 GDIINFO gaulCap = {
47 
48      GDI_DRIVER_VERSION,
49      DT_RASDISPLAY,         // ulTechnology
50      0,                     // ulHorzSize
51      0,                     // ulVertSize
52      0,                     // ulHorzRes (filled in at initialization)
53      0,                     // ulVertRes (filled in at initialization)
54      4,                     // cBitsPixel
55      1,                     // cPlanes
56      16,                    // ulNumColors
57      0,                     // flRaster (DDI reserved field)
58 
59      0,                     // ulLogPixelsX (filled in at initialization)
60      0,                     // ulLogPixelsY (filled in at initialization)
61 
62      TC_RA_ABLE | TC_SCROLLBLT,  // flTextCaps
63 
64      6,                     // ulDACRed
65      6,                     // ulDACGree
66      6,                     // ulDACBlue
67 
68      0x0024,                // ulAspectX  (one-to-one aspect ratio)
69      0x0024,                // ulAspectY
70      0x0033,                // ulAspectXY
71 
72      1,                     // xStyleStep
73      1,                     // yStyleSte;
74      3,                     // denStyleStep
75 
76      { 0, 0 },              // ptlPhysOffset
77      { 0, 0 },              // szlPhysSize
78 
79      0,                     // ulNumPalReg (win3.1 16 color drivers say 0 too)
80 
81 // These fields are for halftone initialization.
82 
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
91         20000,                                  // RedGamma
92         20000,                                  // GreenGamma
93         20000,                                  // BlueGamma
94         0, 0, 0, 0, 0, 0
95      },
96 
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
102 
103      0,                                         // ulVRefresh
104 // eVb: 2.4 [VGARISC DDK CHANGE] - Use 1 bit alignment, not 8
105      1,                      // ulBltAlignment (preferred window alignment
106 // eVb: 2.4 [END]
107                              //   for fast-text routines)
108      0,                                         // ulPanningHorzRes
109      0,                                         // ulPanningVertRes
110 };
111 
112 /******************************Module*Header*******************************\
113 * Color tables
114 \**************************************************************************/
115 
116 // Values for the internal, EGA-compatible palette.
117 #if 0
118 static WORD PaletteBuffer[] = {
119 
120         16, // 16 entries
121         0,  // start with first palette register
122 
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).
127 
128         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
129 };
130 
131 
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.
135 
136 static BYTE ColorBuffer[] = {
137 
138       16, // 16 entries
139       0,
140       0,
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
158 };
159 #endif
160 // eVb: 2.3 [END]
161 /******************************Public*Routine******************************\
162 * bInitSURF
163 *
164 * Enables the surface.        Maps the frame buffer into memory.
165 *
166 \**************************************************************************/
167 
168 BOOL bInitSURF(PPDEV ppdev, BOOL bFirst)
169 {
170     DWORD returnedDataLength;
171     DWORD MaxWidth, MaxHeight;
172     VIDEO_MEMORY videoMemory;
173     VIDEO_MEMORY_INFORMATION videoMemoryInformation;
174 // eVb: 2.1 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
175     ULONG RemappingNeeded = 0;
176 // eVb: 2.1 [END]
177     //
178     // Set the current mode into the hardware.
179     //
180 
181     if (EngDeviceIoControl(ppdev->hDriver,
182                            IOCTL_VIDEO_SET_CURRENT_MODE,
183                            &(ppdev->ulMode),
184                            sizeof(ULONG),
185 // eVb: 2.2 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
186                            &RemappingNeeded,
187                            sizeof(ULONG),
188 // eVb: 2.2 [END]
189                            &returnedDataLength))
190     {
191         RIP("DISP bInitSURF failed IOCTL_SET_MODE\n");
192         return(FALSE);
193     }
194 
195     //
196     // If this is the first time we enable the surface we need to map in the
197     // memory also.
198     //
199 // eVb: 2.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping
200     if (bFirst || RemappingNeeded)
201     {
202 // eVb: 2.3 [END]
203         videoMemory.RequestedVirtualAddress = NULL;
204 
205         if (EngDeviceIoControl(ppdev->hDriver,
206                                IOCTL_VIDEO_MAP_VIDEO_MEMORY,
207                                &videoMemory,
208                                sizeof(VIDEO_MEMORY),
209                                &videoMemoryInformation,
210                                sizeof(VIDEO_MEMORY_INFORMATION),
211                                &returnedDataLength))
212         {
213             RIP("DISP bInitSURF failed IOCTL_VIDEO_MAP\n");
214             return(FALSE);
215         }
216 
217         ppdev->pjScreen = (PBYTE)(videoMemoryInformation.FrameBufferBase);
218 
219         if (videoMemoryInformation.FrameBufferBase !=
220             videoMemoryInformation.VideoRamBase)
221         {
222             RIP("VideoRamBase does not correspond to FrameBufferBase\n");
223         }
224 // eVb: 2.4 [DDK Change] - Make sure frame buffer mapping worked
225         //
226         // Make sure we can access this video memory
227         //
228 
229         *(PULONG)(ppdev->pjScreen) = 0xaa55aa55;
230 
231         if (*(PULONG)(ppdev->pjScreen) != 0xaa55aa55) {
232 
233             DISPDBG((1, "Frame buffer memory is not accessible.\n"));
234             return(FALSE);
235         }
236 // eVb: 2.4 [END]
237         ppdev->cScreenSize = videoMemoryInformation.VideoRamLength;
238 
239         //
240         // Initialize the head of the offscreen list to NULL.
241         //
242 
243         ppdev->pOffscreenList = NULL;
244 
245         // It's a hardware pointer; set up pointer attributes.
246 
247         MaxHeight = ppdev->PointerCapabilities.MaxHeight;
248 
249         // Allocate space for two DIBs (data/mask) for the pointer. If this
250         // device supports a color Pointer, we will allocate a larger bitmap.
251         // If this is a color bitmap we allocate for the largest possible
252         // bitmap because we have no idea of what the pixel depth might be.
253 
254         // Width rounded up to nearest byte multiple
255 
256         if (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))
257         {
258             MaxWidth = (ppdev->PointerCapabilities.MaxWidth + 7) / 8;
259         }
260         else
261         {
262             MaxWidth = ppdev->PointerCapabilities.MaxWidth * sizeof(DWORD);
263         }
264 
265         ppdev->cjPointerAttributes =
266                 sizeof(VIDEO_POINTER_ATTRIBUTES) +
267                 ((sizeof(UCHAR) * MaxWidth * MaxHeight) * 2);
268 
269         ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)
270                 EngAllocMem(0, ppdev->cjPointerAttributes, ALLOC_TAG);
271 
272         if (ppdev->pPointerAttributes == NULL) {
273 
274             DISPDBG((0, "bInitPointer EngAllocMem failed\n"));
275             return(FALSE);
276         }
277 
278         ppdev->pPointerAttributes->Flags = ppdev->PointerCapabilities.Flags;
279         ppdev->pPointerAttributes->WidthInBytes = MaxWidth;
280         ppdev->pPointerAttributes->Width = ppdev->PointerCapabilities.MaxWidth;
281         ppdev->pPointerAttributes->Height = MaxHeight;
282         ppdev->pPointerAttributes->Column = 0;
283         ppdev->pPointerAttributes->Row = 0;
284         ppdev->pPointerAttributes->Enable = 0;
285     }
286 
287     return(TRUE);
288 }
289 
290 /******************************Public*Routine******************************\
291 * vDisableSURF
292 *
293 * Disable the surface. Un-Maps the frame in memory.
294 *
295 \**************************************************************************/
296 
297 VOID vDisableSURF(PPDEV ppdev)
298 {
299     DWORD returnedDataLength;
300     VIDEO_MEMORY videoMemory;
301 
302     videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen;
303 
304     if (EngDeviceIoControl(ppdev->hDriver,
305                            IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
306                            &videoMemory,
307                            sizeof(VIDEO_MEMORY),
308                            NULL,
309                            0,
310                            &returnedDataLength))
311     {
312         RIP("DISP vDisableSURF failed IOCTL_VIDEO_UNMAP\n");
313     }
314 }
315 
316 
317 /******************************Public*Routine******************************\
318 * bInitPDEV
319 *
320 * Determine the mode we should be in based on the DEVMODE passed in.
321 * Query mini-port to get information needed to fill in the DevInfo and the
322 * GdiInfo .
323 *
324 \**************************************************************************/
325 
326 BOOL bInitPDEV(
327 PPDEV ppdev,
328 DEVMODEW *pDevMode,
329 GDIINFO *pGdiInfo,
330 DEVINFO *pDevInfo)
331 {
332     ULONG cModes;
333     PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
334 #if 0
335     VIDEO_COLOR_CAPABILITIES colorCapabilities;
336     ULONG ulTemp;
337 #endif
338     BOOL bSelectDefault;
339     ULONG cbModeSize;
340 
341     //
342     // calls the miniport to get mode information.
343     //
344 
345     cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
346 
347     if (cModes == 0)
348     {
349         return(FALSE);
350     }
351 
352     //
353     // Now see if the requested mode has a match in that table.
354     //
355 
356     pVideoModeSelected = NULL;
357     pVideoTemp = pVideoBuffer;
358 
359     if ((pDevMode->dmPelsWidth        == 0) &&
360         (pDevMode->dmPelsHeight       == 0) &&
361         (pDevMode->dmBitsPerPel       == 0) &&
362         (pDevMode->dmDisplayFrequency == 0))
363     {
364         DISPDBG((2, "Default mode requested"));
365         bSelectDefault = TRUE;
366     }
367     else
368     {
369 // eVb: 2.5 [DDK Change] - Add missing newlines to debug output
370         DISPDBG((2, "Requested mode...\n"));
371         DISPDBG((2, "   Screen width  -- %li\n", pDevMode->dmPelsWidth));
372         DISPDBG((2, "   Screen height -- %li\n", pDevMode->dmPelsHeight));
373         DISPDBG((2, "   Bits per pel  -- %li\n", pDevMode->dmBitsPerPel));
374         DISPDBG((2, "   Frequency     -- %li\n", pDevMode->dmDisplayFrequency));
375 // eVb: 2.5 [END]
376         bSelectDefault = FALSE;
377     }
378 
379     while (cModes--)
380     {
381         if (pVideoTemp->Length != 0)
382         {
383             if (bSelectDefault ||
384                 ((pVideoTemp->VisScreenWidth  == pDevMode->dmPelsWidth) &&
385                  (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
386                  (pVideoTemp->BitsPerPlane *
387                   pVideoTemp->NumberOfPlanes  == pDevMode->dmBitsPerPel) &&
388                  (pVideoTemp->Frequency  == pDevMode->dmDisplayFrequency)))
389             {
390                 pVideoModeSelected = pVideoTemp;
391                 DISPDBG((3, "Found a match\n")) ;
392                 break;
393             }
394         }
395 
396         pVideoTemp = (PVIDEO_MODE_INFORMATION)
397             (((PUCHAR)pVideoTemp) + cbModeSize);
398     }
399 
400     //
401     // If no mode has been found, return an error
402     //
403 
404     if (pVideoModeSelected == NULL)
405     {
406         EngFreeMem(pVideoBuffer);
407         DISPDBG((0,"DISP bInitPDEV failed - no valid modes\n"));
408         return(FALSE);
409     }
410 
411     //
412     // Fill in the GDIINFO data structure with the information returned from
413     // the kernel driver.
414     //
415 
416     ppdev->ulMode = pVideoModeSelected->ModeIndex;
417     ppdev->cxScreen = pVideoModeSelected->VisScreenWidth;
418     ppdev->cyScreen = pVideoModeSelected->VisScreenHeight;
419     ppdev->lDeltaScreen = pVideoModeSelected->ScreenStride;
420 // eVb: 2.8 [VGARISC CHANGE] - Extra fields not required on VGA, start with defaults
421 #if 0
422     ppdev->ulBitCount = pVideoModeSelected->BitsPerPlane *
423                         pVideoModeSelected->NumberOfPlanes;
424     ppdev->flRed = pVideoModeSelected->RedMask;
425     ppdev->flGreen = pVideoModeSelected->GreenMask;
426     ppdev->flBlue = pVideoModeSelected->BlueMask;
427 #else
428     *pGdiInfo = gaulCap;
429 #endif
430 // eVb: 2.8 [END]
431 
432 
433     pGdiInfo->ulVersion    = GDI_DRIVER_VERSION;
434     pGdiInfo->ulTechnology = DT_RASDISPLAY;
435     pGdiInfo->ulHorzSize   = pVideoModeSelected->XMillimeter;
436     pGdiInfo->ulVertSize   = pVideoModeSelected->YMillimeter;
437 
438     pGdiInfo->ulHorzRes        = ppdev->cxScreen;
439     pGdiInfo->ulVertRes        = ppdev->cyScreen;
440     pGdiInfo->ulPanningHorzRes = ppdev->cxScreen;
441     pGdiInfo->ulPanningVertRes = ppdev->cyScreen;
442     pGdiInfo->cBitsPixel       = pVideoModeSelected->BitsPerPlane;
443     pGdiInfo->cPlanes          = pVideoModeSelected->NumberOfPlanes;
444     pGdiInfo->ulVRefresh       = pVideoModeSelected->Frequency;
445     pGdiInfo->ulBltAlignment   = 1;     // We don't have accelerated screen-
446                                         //   to-screen blts, and any
447                                         //   window alignment is okay
448 
449     pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
450     pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
451 
452 // eVb: 2.9 [VGARISC CHANGE] - Extra fields not required on VGA
453 #if 0
454 #ifdef MIPS
455     if (ppdev->ulBitCount == 8)
456         pGdiInfo->flTextCaps = (TC_RA_ABLE | TC_SCROLLBLT);
457     else
458 #endif
459     pGdiInfo->flTextCaps = TC_RA_ABLE;
460 
461     pGdiInfo->flRaster = 0;           // flRaster is reserved by DDI
462 #endif
463 // eVb: 2.9 [END]
464 
465     pGdiInfo->ulDACRed   = pVideoModeSelected->NumberRedBits;
466     pGdiInfo->ulDACGreen = pVideoModeSelected->NumberGreenBits;
467     pGdiInfo->ulDACBlue  = pVideoModeSelected->NumberBlueBits;
468 
469 // eVb: 2.7 [VGARISC CHANGE] - Extra fields not required on VGA
470 #if 0
471     pGdiInfo->ulAspectX    = 0x24;    // One-to-one aspect ratio
472     pGdiInfo->ulAspectY    = 0x24;
473     pGdiInfo->ulAspectXY   = 0x33;
474 
475     pGdiInfo->xStyleStep   = 1;       // A style unit is 3 pels
476     pGdiInfo->yStyleStep   = 1;
477     pGdiInfo->denStyleStep = 3;
478 
479     pGdiInfo->ptlPhysOffset.x = 0;
480     pGdiInfo->ptlPhysOffset.y = 0;
481     pGdiInfo->szlPhysSize.cx  = 0;
482     pGdiInfo->szlPhysSize.cy  = 0;
483 
484     // RGB and CMY color info.
485 
486     //
487     // try to get it from the miniport.
488     // if the miniport doesn ot support this feature, use defaults.
489     //
490 
491     if (EngDeviceIoControl(ppdev->hDriver,
492                            IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
493                            NULL,
494                            0,
495                            &colorCapabilities,
496                            sizeof(VIDEO_COLOR_CAPABILITIES),
497                            &ulTemp))
498     {
499 
500         DISPDBG((2, "getcolorCapabilities failed \n"));
501 
502         pGdiInfo->ciDevice.Red.x = 6700;
503         pGdiInfo->ciDevice.Red.y = 3300;
504         pGdiInfo->ciDevice.Red.Y = 0;
505         pGdiInfo->ciDevice.Green.x = 2100;
506         pGdiInfo->ciDevice.Green.y = 7100;
507         pGdiInfo->ciDevice.Green.Y = 0;
508         pGdiInfo->ciDevice.Blue.x = 1400;
509         pGdiInfo->ciDevice.Blue.y = 800;
510         pGdiInfo->ciDevice.Blue.Y = 0;
511         pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
512         pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
513         pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
514 
515         pGdiInfo->ciDevice.RedGamma = 20000;
516         pGdiInfo->ciDevice.GreenGamma = 20000;
517         pGdiInfo->ciDevice.BlueGamma = 20000;
518 
519     }
520     else
521     {
522         pGdiInfo->ciDevice.Red.x = colorCapabilities.RedChromaticity_x;
523         pGdiInfo->ciDevice.Red.y = colorCapabilities.RedChromaticity_y;
524         pGdiInfo->ciDevice.Red.Y = 0;
525         pGdiInfo->ciDevice.Green.x = colorCapabilities.GreenChromaticity_x;
526         pGdiInfo->ciDevice.Green.y = colorCapabilities.GreenChromaticity_y;
527         pGdiInfo->ciDevice.Green.Y = 0;
528         pGdiInfo->ciDevice.Blue.x = colorCapabilities.BlueChromaticity_x;
529         pGdiInfo->ciDevice.Blue.y = colorCapabilities.BlueChromaticity_y;
530         pGdiInfo->ciDevice.Blue.Y = 0;
531         pGdiInfo->ciDevice.AlignmentWhite.x = colorCapabilities.WhiteChromaticity_x;
532         pGdiInfo->ciDevice.AlignmentWhite.y = colorCapabilities.WhiteChromaticity_y;
533         pGdiInfo->ciDevice.AlignmentWhite.Y = colorCapabilities.WhiteChromaticity_Y;
534 
535         // if we have a color device store the three color gamma values,
536         // otherwise store the unique gamma value in all three.
537 
538         if (colorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
539         {
540             pGdiInfo->ciDevice.RedGamma = colorCapabilities.RedGamma;
541             pGdiInfo->ciDevice.GreenGamma = colorCapabilities.GreenGamma;
542             pGdiInfo->ciDevice.BlueGamma = colorCapabilities.BlueGamma;
543         }
544         else
545         {
546             pGdiInfo->ciDevice.RedGamma = colorCapabilities.WhiteGamma;
547             pGdiInfo->ciDevice.GreenGamma = colorCapabilities.WhiteGamma;
548             pGdiInfo->ciDevice.BlueGamma = colorCapabilities.WhiteGamma;
549         }
550 
551     };
552 
553     pGdiInfo->ciDevice.Cyan.x = 0;
554     pGdiInfo->ciDevice.Cyan.y = 0;
555     pGdiInfo->ciDevice.Cyan.Y = 0;
556     pGdiInfo->ciDevice.Magenta.x = 0;
557     pGdiInfo->ciDevice.Magenta.y = 0;
558     pGdiInfo->ciDevice.Magenta.Y = 0;
559     pGdiInfo->ciDevice.Yellow.x = 0;
560     pGdiInfo->ciDevice.Yellow.y = 0;
561     pGdiInfo->ciDevice.Yellow.Y = 0;
562 
563     // No dye correction for raster displays.
564 
565     pGdiInfo->ciDevice.MagentaInCyanDye = 0;
566     pGdiInfo->ciDevice.YellowInCyanDye = 0;
567     pGdiInfo->ciDevice.CyanInMagentaDye = 0;
568     pGdiInfo->ciDevice.YellowInMagentaDye = 0;
569     pGdiInfo->ciDevice.CyanInYellowDye = 0;
570     pGdiInfo->ciDevice.MagentaInYellowDye = 0;
571 
572     pGdiInfo->ulDevicePelsDPI = 0;   // For printers only
573     pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
574 
575     // BUGBUG this should be modified to take into account the size
576     // of the display and the resolution.
577 
578     pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
579 
580     pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
581 // eVb: 2.7 [END]
582 #endif
583 
584     // Fill in the basic devinfo structure
585 
586     *pDevInfo = gDevInfoFrameBuffer;
587 
588 // eVb: 2.6 [VGARISC CHANGE] - Use defaults in gaulCap for GDI Info
589 #if 0
590     // Fill in the rest of the devinfo and GdiInfo structures.
591 
592     if (ppdev->ulBitCount == 8)
593     {
594         // It is Palette Managed.
595 
596         pGdiInfo->ulNumColors = 20;
597         pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;
598 // eVb: 2.7 [DDK CHANGE] - No dithering support
599         pDevInfo->flGraphicsCaps |= GCAPS_PALMANAGED;
600 // eVb: 2.7 [END]
601         pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
602         pDevInfo->iDitherFormat = BMF_8BPP;
603 
604         // Assuming palette is orthogonal - all colors are same size.
605 
606         ppdev->cPaletteShift   = 8 - pGdiInfo->ulDACRed;
607     }
608     else
609     {
610         pGdiInfo->ulNumColors = (ULONG) (-1);
611         pGdiInfo->ulNumPalReg = 0;
612 
613         if (ppdev->ulBitCount == 16)
614         {
615             pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
616             pDevInfo->iDitherFormat = BMF_16BPP;
617         }
618         else if (ppdev->ulBitCount == 24)
619         {
620             pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP;
621             pDevInfo->iDitherFormat = BMF_24BPP;
622         }
623         else
624         {
625             pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
626             pDevInfo->iDitherFormat = BMF_32BPP;
627         }
628     }
629 #endif
630 // eVb: 2.6 [END]
631 
632     EngFreeMem(pVideoBuffer);
633 
634     return(TRUE);
635 }
636 
637 
638 /******************************Public*Routine******************************\
639 * getAvailableModes
640 *
641 * Calls the miniport to get the list of modes supported by the kernel driver,
642 * and returns the list of modes supported by the diplay driver among those
643 *
644 * returns the number of entries in the videomode buffer.
645 * 0 means no modes are supported by the miniport or that an error occured.
646 *
647 * NOTE: the buffer must be freed up by the caller.
648 *
649 \**************************************************************************/
650 
651 DWORD getAvailableModes(
652 HANDLE hDriver,
653 PVIDEO_MODE_INFORMATION *modeInformation,
654 DWORD *cbModeSize)
655 {
656     ULONG ulTemp;
657     VIDEO_NUM_MODES modes;
658     PVIDEO_MODE_INFORMATION pVideoTemp;
659 
660     //
661     // Get the number of modes supported by the mini-port
662     //
663 
664     if (EngDeviceIoControl(hDriver,
665                            IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
666                            NULL,
667                            0,
668                            &modes,
669                            sizeof(VIDEO_NUM_MODES),
670                            &ulTemp))
671     {
672         DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
673         return 0;
674     }
675 
676     *cbModeSize = modes.ModeInformationLength;
677 
678     //
679     // Allocate the buffer for the mini-port to write the modes in.
680     //
681 
682     *modeInformation = (PVIDEO_MODE_INFORMATION)
683                         EngAllocMem(0, modes.NumModes *
684                                     modes.ModeInformationLength, ALLOC_TAG);
685 
686     if (*modeInformation == NULL)
687     {
688         DISPDBG((0, "getAvailableModes failed EngAllocMem\n"));
689 
690         return 0;
691     }
692 
693     //
694     // Ask the mini-port to fill in the available modes.
695     //
696 
697     if (EngDeviceIoControl(hDriver,
698                            IOCTL_VIDEO_QUERY_AVAIL_MODES,
699                            NULL,
700                            0,
701                            *modeInformation,
702                            modes.NumModes * modes.ModeInformationLength,
703                            &ulTemp))
704     {
705 
706         DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
707 
708         EngFreeMem(*modeInformation);
709         *modeInformation = NULL;
710 
711         return 0;
712     }
713 
714     //
715     // Now see which of these modes are supported by the display driver.
716     // As an internal mechanism, set the length to 0 for the modes we
717     // DO NOT support.
718     //
719 
720     ulTemp = modes.NumModes;
721     pVideoTemp = *modeInformation;
722 
723 // eVb: 2.5 [VGARISC CHANGE] - Add correct mode checks for VGA
724     //
725     // Mode is rejected if it is not 4 planes, or not graphics, or is not
726     // one of 1 bits per pel.
727     //
728 
729     while (ulTemp--)
730     {
731         if ((pVideoTemp->NumberOfPlanes != 4 ) ||
732             !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
733             ((pVideoTemp->BitsPerPlane != 1) ||
734              (pVideoTemp->VisScreenWidth > 800)))
735 // eVb: 2.5 [END]
736         {
737             pVideoTemp->Length = 0;
738         }
739 
740         pVideoTemp = (PVIDEO_MODE_INFORMATION)
741             (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
742     }
743 
744     return modes.NumModes;
745 
746 }
747