update for HEAD-2003091401
[reactos.git] / drivers / dd / vga / display / main / enable.c
1 /*
2  * entry.c
3  *
4  * $Revision$
5  * $Author$
6  * $Date$
7  *
8  */
9
10 #include "../vgaddi.h"
11 #include "../vgavideo/vgavideo.h"
12 #define NDEBUG
13 #include <debug.h>
14
15 #define  DBG_PREFIX  "VGADDI: "
16
17 static BOOL VGAInitialized = FALSE;
18
19 DRVFN FuncList[] =
20 {
21   /*  Required Display driver fuctions  */
22   {INDEX_DrvAssertMode, (PFN) DrvAssertMode},
23   {INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV},
24   {INDEX_DrvCopyBits, (PFN) DrvCopyBits},
25   {INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV},
26   {INDEX_DrvDisableSurface, (PFN) DrvDisableSurface},
27   {INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV},
28   {INDEX_DrvEnableSurface, (PFN) DrvEnableSurface},
29   {INDEX_DrvGetModes, (PFN) DrvGetModes},
30   {INDEX_DrvLineTo, (PFN) DrvLineTo},
31   {INDEX_DrvPaint, (PFN) DrvPaint},
32   {INDEX_DrvBitBlt, (PFN) DrvBitBlt},
33   {INDEX_DrvTransparentBlt, (PFN) DrvTransparentBlt},
34   {INDEX_DrvMovePointer, (PFN) DrvMovePointer},
35   {INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape},
36
37 #if 0
38   /*  Optional Display driver functions  */
39   {INDEX_, (PFN) },
40   {INDEX_DescribePixelFormat, (PFN) VGADDIDescribePixelFormat},
41   {INDEX_DrvDitherColor, (PFN) VGADDIDitherColor},
42   {INDEX_DrvFillPath, (PFN) VGADDIFillPath},
43   {INDEX_DrvGetTrueTypeFile, (PFN) VGADDIGetTrueTypeFile},
44   {INDEX_DrvLoadFontFile, (PFN) VGADDILoadFontFile},
45   {INDEX_DrvQueryFont, (PFN) VGADDIQueryFont},
46   {INDEX_DrvQueryFontCaps, (PFN) VGADDIQueryFontCaps},
47   {INDEX_DrvQueryFontData, (PFN) VGADDIQueryFontData},
48   {INDEX_DrvQueryFontFile, (PFN) VGADDIQueryFontFile},
49   {INDEX_DrvQueryFontTree, (PFN) VGADDIQueryFontTree},
50   {INDEX_DrvQueryTrueTypeOutline, (PFN) VGADDIQueryTrueTypeOutline},
51   {INDEX_DrvQueryTrueTypeTable, (PFN) VGADDIQueryTrueTypeTable},
52   {INDEX_DrvRealizeBrush, (PFN) VGADDIRealizeBrush},
53   {INDEX_DrvResetPDEV, (PFN) VGADDIResetPDEV},
54   {INDEX_DrvSetPalette, (PFN) VGADDISetPalette},
55   {INDEX_DrvSetPixelFormat, (PFN) VGADDISetPixelFormat},
56   {INDEX_DrvStretchBlt, (PFN) VGADDIStretchBlt},
57   {INDEX_DrvStrokePath, (PFN) VGADDIStrokePath},
58   {INDEX_DrvSwapBuffers, (PFN) VGADDISwapBuffers},
59   {INDEX_DrvTextOut, (PFN) VGADDITextOut},
60   {INDEX_DrvUnloadFontFile, (PFN) VGADDIUnloadFontFile},
61 #endif
62 };
63
64 GDIINFO gaulCap = {
65   GDI_DRIVER_VERSION,
66   DT_RASDISPLAY,         // ulTechnology
67   0,                     // ulHorzSize
68   0,                     // ulVertSize
69   0,                     // ulHorzRes (filled in at initialization)
70   0,                     // ulVertRes (filled in at initialization)
71   4,                     // cBitsPixel
72   1,                     // cPlanes
73   16,                    // ulNumColors
74   0,                     // flRaster (DDI reserved field)
75
76   96,                    // ulLogPixelsX (must be set to 96 according to MSDN)
77   96,                    // ulLogPixelsY (must be set to 96 according to MSDN)
78
79   TC_RA_ABLE | TC_SCROLLBLT,  // flTextCaps
80
81   6,                     // ulDACRed
82   6,                     // ulDACGree
83   6,                     // ulDACBlue
84
85   0x0024,                // ulAspectX  (one-to-one aspect ratio)
86   0x0024,                // ulAspectY
87   0x0033,                // ulAspectXY
88
89   1,                     // xStyleStep
90   1,                     // yStyleSte;
91   3,                     // denStyleStep
92
93   { 0, 0 },              // ptlPhysOffset
94   { 0, 0 },              // szlPhysSize
95
96   0,                     // ulNumPalReg (win3.1 16 color drivers say 0 too)
97
98 // These fields are for halftone initialization.
99
100   {                                         // ciDevice, ColorInfo
101     { 6700, 3300, 0 },                      // Red
102     { 2100, 7100, 0 },                      // Green
103     { 1400,  800, 0 },                      // Blue
104     { 1750, 3950, 0 },                      // Cyan
105     { 4050, 2050, 0 },                      // Magenta
106     { 4400, 5200, 0 },                      // Yellow
107     { 3127, 3290, 0 },                      // AlignmentWhite
108     20000,                                  // RedGamma
109     20000,                                  // GreenGamma
110     20000,                                  // BlueGamma
111     0, 0, 0, 0, 0, 0
112   },
113
114   0,                                         // ulDevicePelsDPI
115   PRIMARY_ORDER_CBA,                         // ulPrimaryOrder
116   HT_PATSIZE_4x4_M,                          // ulHTPatternSize
117   HT_FORMAT_4BPP_IRGB,                       // ulHTOutputFormat
118   HT_FLAG_ADDITIVE_PRIMS,                    // flHTFlags
119
120   0,                                         // ulVRefresh
121   8,                                         // ulBltAlignment
122   0,                                         // ulPanningHorzRes
123   0,                                         // ulPanningVertRes
124 };
125
126 // Palette for VGA
127
128 typedef struct _VGALOGPALETTE
129 {
130    USHORT ident;
131    USHORT NumEntries;
132    PALETTEENTRY PaletteEntry[16];
133 } VGALOGPALETTE;
134
135 const VGALOGPALETTE VGApalette =
136 {
137
138 0x400,  // driver version
139 16,     // num entries
140 {
141   { 0x00, 0x00, 0x00, 0x00 }, // 0
142   { 0x80, 0x00, 0x00, 0x00 }, // 1
143   { 0x00, 0x80, 0x00, 0x00 }, // 2
144   { 0x80, 0x80, 0x00, 0x00 }, // 3
145   { 0x00, 0x00, 0x80, 0x00 }, // 4
146   { 0x80, 0x00, 0x80, 0x00 }, // 5
147   { 0x00, 0x80, 0x80, 0x00 }, // 6
148   { 0x80, 0x80, 0x80, 0x00 }, // 7
149   { 0xc0, 0xc0, 0xc0, 0x00 }, // 8
150   { 0xff, 0x00, 0x00, 0x00 }, // 9
151   { 0x00, 0xff, 0x00, 0x00 }, // 10
152   { 0xff, 0xff, 0x00, 0x00 }, // 11
153   { 0x00, 0x00, 0xff, 0x00 }, // 12
154   { 0xff, 0x00, 0xff, 0x00 }, // 13
155   { 0x00, 0xff, 0xff, 0x00 }, // 14
156   { 0xff, 0xff, 0xff, 0x00 } // 15
157 }
158 };
159
160 // Devinfo structure passed back to the engine in DrvEnablePDEV
161
162 #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"}
163 #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"}
164 #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"}
165
166 DEVINFO devinfoVGA =
167 {
168   (GCAPS_OPAQUERECT | GCAPS_HORIZSTRIKE | GCAPS_ALTERNATEFILL | GCAPS_MONO_DITHER | GCAPS_COLOR_DITHER |
169    GCAPS_WINDINGFILL | GCAPS_DITHERONREALIZE
170    ),       // Graphics capabilities
171
172   SYSTM_LOGFONT,  // Default font description
173   HELVE_LOGFONT,  // ANSI variable font description
174   COURI_LOGFONT,  // ANSI fixed font description
175   0,              // Count of device fonts
176   BMF_4BPP,       // preferred DIB format
177   8,              // Width of color dither
178   8,              // Height of color dither
179   0               // Default palette to use for this device
180 };
181
182
183 BOOL STDCALL
184 DrvEnableDriver(IN ULONG EngineVersion,
185                 IN ULONG SizeOfDED,
186                 OUT PDRVENABLEDATA DriveEnableData)
187 {
188 /*  EngDebugPrint("VGADDI", "DrvEnableDriver called...\n", 0); */
189
190   vgaPreCalc();
191
192   // FIXME: Use Vidport to map the memory properly
193   vidmem = (char *)(0xd0000000 + 0xa0000);
194
195   VGADDI_InitializeOffScreenMem((640 * 480) >> 3, 65536 - ((640 * 480) >> 3));
196
197   DriveEnableData->pdrvfn = FuncList;
198   DriveEnableData->c = sizeof(FuncList) / sizeof(DRVFN);
199   DriveEnableData->iDriverVersion = DDI_DRIVER_VERSION;
200
201   return  TRUE;
202 }
203
204 //    DrvDisableDriver
205 //  DESCRIPTION:
206 //    This function is called by the KMGDI at exit.  It should cleanup.
207 //  ARGUMENTS:
208 //    NONE
209 //  RETURNS:
210 //    NONE
211
212 VOID STDCALL
213 DrvDisableDriver(VOID)
214 {
215   return;
216 }
217
218 //  -----------------------------------------------  Driver Implementation 
219
220
221 //    DrvEnablePDEV
222 //  DESCRIPTION:
223 //    This function is called after DrvEnableDriver to get information
224 //    about the mode that is to be used.  This function just returns
225 //    information, and should not yet initialize the mode.
226 //  ARGUMENTS:
227 //    IN DEVMODEW *  DM            Describes the mode requested
228 //    IN LPWSTR      LogAddress    
229 //    IN ULONG       PatternCount  number of patterns expected
230 //    OUT HSURF *    SurfPatterns  array to contain pattern handles
231 //    IN ULONG       GDIInfoSize   the size of the GDIInfo object passed in
232 //    OUT GDIINFO *  GDIInfo       GDI Info object
233 //    IN ULONG       DevInfoSize   the size of the DevInfo object passed in
234 //    OUT DEVINFO *  DevInfo       Device Info object
235 //    IN LPWSTR      DevDataFile   ignore
236 //    IN LPWSTR      DeviceName    Device name
237 //    IN HANDLE      Driver        handle to KM driver
238 //  RETURNS:
239 //    DHPDEV  a handle to a DPev object
240
241 DHPDEV STDCALL
242 DrvEnablePDEV(IN DEVMODEW *DM,
243               IN LPWSTR LogAddress,
244               IN ULONG PatternCount,
245               OUT HSURF *SurfPatterns,
246               IN ULONG GDIInfoSize,
247               OUT GDIINFO *GDIInfo,
248               IN ULONG DevInfoSize,
249               OUT DEVINFO *DevInfo,
250               IN LPWSTR DevDataFile,
251               IN LPWSTR DeviceName,
252               IN HANDLE Driver)
253 {
254   PPDEV  PDev;
255
256   PDev = EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG);
257   if (PDev == NULL)
258     {
259       EngDebugPrint(DBG_PREFIX, "EngAllocMem failed for PDEV\n", 0);
260       return(NULL);
261     }
262   PDev->KMDriver = Driver;
263   DPRINT( "PDev: %x, Driver: %x\n", PDev, PDev->KMDriver );
264   PDev->xyCursor.x = 320;
265   PDev->xyCursor.y = 240;
266   PDev->ptlExtent.x = 0;
267   PDev->ptlExtent.y = 0;
268   PDev->cExtent = 0;
269   PDev->flCursor = CURSOR_DOWN;
270
271   gaulCap.ulHorzRes = 640;
272   gaulCap.ulVertRes = 480;
273   if (sizeof(GDIINFO) < GDIInfoSize)
274     {
275     GDIInfoSize = sizeof(GDIINFO);
276     }
277   memcpy(GDIInfo, &gaulCap, GDIInfoSize);
278
279   devinfoVGA.hpalDefault = EngCreatePalette(PAL_INDEXED, 16, (ULONG *) VGApalette.PaletteEntry, 0, 0, 0);
280   if (sizeof(DEVINFO) < DevInfoSize)
281     {
282     DevInfoSize = sizeof(DEVINFO);
283     }
284   memcpy(DevInfo, &devinfoVGA, DevInfoSize);
285
286   return(PDev);
287 }
288
289
290 //    DrvCompletePDEV
291 //  DESCRIPTION
292 //    Called after initialization of PDEV is complete.  Supplies
293 //    a reference to the GDI handle for the PDEV.
294
295 VOID STDCALL
296 DrvCompletePDEV(IN DHPDEV PDev,
297                 IN HDEV Dev)
298 {
299   ((PPDEV) PDev)->GDIDevHandle = Dev; // Handle to the DC
300 }
301
302
303 BOOL STDCALL
304 DrvAssertMode(IN DHPDEV DPev,
305               IN BOOL Enable)
306 {
307   PPDEV ppdev = (PPDEV)DPev;
308   ULONG returnedDataLength;
309
310   if(Enable==TRUE)
311   {
312     // Reenable our graphics mode
313
314     if (!InitPointer(ppdev))
315     {
316       // Failed to set pointer
317       return FALSE;
318     }
319
320     if (!VGAInitialized)
321       {
322         if (!InitVGA(ppdev, FALSE))
323           {
324             // Failed to initialize the VGA
325             return FALSE;
326           }
327         VGAInitialized = TRUE;
328       }
329   } else {
330     // Go back to last known mode
331     DPRINT( "ppdev: %x, KMDriver: %x", ppdev, ppdev->KMDriver );
332     if (EngDeviceIoControl(ppdev->KMDriver, IOCTL_VIDEO_RESET_DEVICE, NULL, 0, NULL, 0, &returnedDataLength))
333     {
334       // Failed to go back to mode
335       return FALSE;
336     }
337     VGAInitialized = FALSE;
338   }
339   return TRUE;
340 }
341
342
343 VOID STDCALL
344 DrvDisablePDEV(IN DHPDEV PDev)
345 {
346   PPDEV ppdev = (PPDEV)PDev;\r
347
348   // EngDeletePalette(devinfoVGA.hpalDefault);
349   if (ppdev->pjPreallocSSBBuffer != NULL)
350   {
351     EngFreeMem(ppdev->pjPreallocSSBBuffer);
352   }
353
354   if (ppdev->pucDIB4ToVGAConvBuffer != NULL)
355   {
356     EngFreeMem(ppdev->pucDIB4ToVGAConvBuffer);
357   }
358   DPRINT( "Freeing PDEV\n" );
359   EngFreeMem(PDev);
360 }
361
362
363 VOID STDCALL
364 DrvDisableSurface(IN DHPDEV PDev)
365 {
366   PPDEV ppdev = (PPDEV)PDev;
367   PDEVSURF pdsurf = ppdev->AssociatedSurf;
368   PSAVED_SCREEN_BITS pSSB, pSSBNext;
369   CHECKPOINT;
370   DPRINT( "KMDriver: %x\n", ppdev->KMDriver );
371   //  EngFreeMem(pdsurf->BankSelectInfo);
372   CHECKPOINT;
373   if (pdsurf->BankInfo != NULL) {
374     EngFreeMem(pdsurf->BankInfo);
375   }
376   CHECKPOINT;
377   if (pdsurf->BankInfo2RW != NULL) {
378     EngFreeMem(pdsurf->BankInfo2RW);
379   }
380   CHECKPOINT;
381   if (pdsurf->BankBufferPlane0 != NULL) {
382     EngFreeMem(pdsurf->BankBufferPlane0);
383   }
384   CHECKPOINT;
385   if (ppdev->pPointerAttributes != NULL) {
386     EngFreeMem(ppdev->pPointerAttributes);
387   }
388   CHECKPOINT;
389   // free any pending saved screen bit blocks
390 #if 0
391   pSSB = pdsurf->ssbList;
392   while (pSSB != (PSAVED_SCREEN_BITS) NULL) {
393
394     // Point to the next saved screen bits block
395     pSSBNext = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
396
397     // Free the current block
398     EngFreeMem(pSSB);
399     pSSB = pSSBNext;
400     }
401 #endif
402   EngDeleteSurface((HSURF) ppdev->SurfHandle);
403   //  EngFreeMem(pdsurf); // free the surface
404 }
405
406
407 static VOID
408 InitSavedBits(PPDEV ppdev)
409 {
410   if (!(ppdev->fl & DRIVER_OFFSCREEN_REFRESHED))
411   {
412     return;
413   }
414
415   // set up rect to right of visible screen
416   ppdev->SavedBitsRight.left   = ppdev->sizeSurf.cx;
417   ppdev->SavedBitsRight.top    = 0;
418   ppdev->SavedBitsRight.right  = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
419   ppdev->SavedBitsRight.bottom = ppdev->sizeSurf.cy;
420
421   if ((ppdev->SavedBitsRight.right <= ppdev->SavedBitsRight.left) ||
422       (ppdev->SavedBitsRight.bottom <= ppdev->SavedBitsRight.top))
423   {
424     ppdev->SavedBitsRight.left   = 0;
425     ppdev->SavedBitsRight.top    = 0;
426     ppdev->SavedBitsRight.right  = 0;
427     ppdev->SavedBitsRight.bottom = 0;
428   }
429
430   // set up rect below visible screen
431   ppdev->SavedBitsBottom.left   = 0;
432   ppdev->SavedBitsBottom.top    = ppdev->sizeSurf.cy;
433   ppdev->SavedBitsBottom.right  = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
434   ppdev->SavedBitsBottom.bottom = ppdev->sizeMem.cy - ppdev->NumScansUsedByPointer;
435
436   if ((ppdev->SavedBitsBottom.right <= ppdev->SavedBitsBottom.left) ||
437       (ppdev->SavedBitsBottom.bottom <= ppdev->SavedBitsBottom.top))
438   {
439     ppdev->SavedBitsBottom.left   = 0;
440     ppdev->SavedBitsBottom.top    = 0;
441     ppdev->SavedBitsBottom.right  = 0;
442     ppdev->SavedBitsBottom.bottom = 0;
443   }
444
445   ppdev->BitsSaved = FALSE;
446
447   return;
448 }
449
450
451 HSURF STDCALL
452 DrvEnableSurface(IN DHPDEV PDev)
453 {
454   PPDEV ppdev = (PPDEV)PDev;
455   PDEVSURF pdsurf;
456   DHSURF dhsurf;
457   HSURF hsurf;
458
459   DPRINT("DrvEnableSurface() called\n");
460
461   // Initialize the VGA
462   if (!VGAInitialized)
463     {
464       if (!InitVGA(ppdev, TRUE))
465         {
466           goto error_done;
467         }
468       VGAInitialized = TRUE;
469     }
470
471   // dhsurf is of type DEVSURF, which is the drivers specialized surface type
472   dhsurf = (DHSURF)EngAllocMem(0, sizeof(DEVSURF), ALLOC_TAG);
473   if (dhsurf == (DHSURF) 0)
474   {
475     goto error_done;
476   }
477
478   pdsurf = (PDEVSURF) dhsurf;
479   pdsurf->ident         = DEVSURF_IDENT;
480   pdsurf->flSurf        = 0;
481   pdsurf->Format       = BMF_PHYSDEVICE;
482   pdsurf->jReserved1    = 0;
483   pdsurf->jReserved2    = 0;
484   pdsurf->ppdev         = ppdev;
485   pdsurf->sizeSurf.cx   = ppdev->sizeSurf.cx;
486   pdsurf->sizeSurf.cy   = ppdev->sizeSurf.cy;
487   pdsurf->NextPlane    = 0;
488   pdsurf->Scan0       = ppdev->fbScreen;
489   pdsurf->BitmapStart = ppdev->fbScreen;
490   pdsurf->StartBmp      = ppdev->fbScreen;
491
492 /*  pdsurf->Conv          = &ConvertBuffer[0]; */
493
494   if (!InitPointer(ppdev)) {
495       DbgPrint("DrvEnablePDEV failed bInitPointer\n");
496       goto error_clean;
497    }
498
499 /* if (!SetUpBanking(pdsurf, ppdev)) {
500       DISPDBG((0, "DrvEnablePDEV failed SetUpBanking\n"));
501       goto error_clean;
502    } BANKING CODE UNIMPLEMENTED */
503
504   if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizeSurf, BMF_4BPP)) ==
505       (HSURF)0)
506   {
507     // Call to EngCreateDeviceSurface failed
508     EngDebugPrint("VGADDI:", "EngCreateDeviceSurface call failed\n", 0);
509     goto error_clean;
510   }
511
512   InitSavedBits(ppdev);
513
514   if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO | HOOK_COPYBITS |
515     HOOK_TRANSPARENTBLT))
516   {
517 /*    EngDebugPrint("VGADDI:", "Successfully associated surface\n", 0); */
518     ppdev->SurfHandle = hsurf;
519     ppdev->AssociatedSurf = pdsurf;
520
521     // Set up an empty saved screen block list
522     pdsurf->ssbList = NULL;
523
524     return(hsurf);
525   }
526   DPRINT( "EngAssociateSurface() failed\n" );
527   EngDeleteSurface(hsurf);
528
529 error_clean:
530    EngFreeMem(dhsurf);
531
532 error_done:
533    return((HSURF)0);
534 }
535
536
537 ULONG STDCALL
538 DrvGetModes(IN HANDLE Driver,
539             IN ULONG DataSize,
540             OUT PDEVMODEW DM)
541 {
542   DWORD NumModes;
543   DWORD ModeSize;
544   DWORD OutputSize;
545   DWORD OutputModes = DataSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
546   PVIDEO_MODE_INFORMATION VideoModeInformation, VideoTemp;
547
548   NumModes = getAvailableModes(Driver,
549                                (PVIDEO_MODE_INFORMATION *) &VideoModeInformation,
550                                &ModeSize);
551
552   if (NumModes == 0)
553   {
554     return 0;
555   }
556
557   if (DM == NULL)
558   {
559     OutputSize = NumModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
560   } else {
561
562     OutputSize=0;
563     VideoTemp = VideoModeInformation;
564
565     do
566     {
567       if (VideoTemp->Length != 0)
568       {
569         if (OutputModes == 0)
570         {
571           break;
572         }
573
574         memset(DM, 0, sizeof(DEVMODEW));
575         memcpy(DM->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
576
577         DM->dmSpecVersion      = DM_SPECVERSION;
578         DM->dmDriverVersion    = DM_SPECVERSION;
579         DM->dmSize             = sizeof(DEVMODEW);
580         DM->dmDriverExtra      = DRIVER_EXTRA_SIZE;
581         DM->dmBitsPerPel       = VideoTemp->NumberOfPlanes *
582                                  VideoTemp->BitsPerPlane;
583         DM->dmPelsWidth        = VideoTemp->VisScreenWidth;
584         DM->dmPelsHeight       = VideoTemp->VisScreenHeight;
585         DM->dmDisplayFrequency = VideoTemp->Frequency;
586         DM->dmDisplayFlags     = 0;
587
588         DM->dmFields           = DM_BITSPERPEL       |
589                                  DM_PELSWIDTH        |
590                                  DM_PELSHEIGHT       |
591                                  DM_DISPLAYFREQUENCY |
592                                  DM_DISPLAYFLAGS     ;
593
594         // next DEVMODE entry
595         OutputModes--;
596
597         DM = (PDEVMODEW) ( ((ULONG)DM) + sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
598
599         OutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
600       }
601
602       VideoTemp = (PVIDEO_MODE_INFORMATION)(((PUCHAR)VideoTemp) + ModeSize);
603
604     } while (--NumModes);
605   }
606 }
607
608 /* EOF */