|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: screen.c
3: *
4: * Initializes the GDIINFO and DEVINFO structures for DrvEnablePDEV.
5: *
6: * Copyright (c) 1992 Microsoft Corporation
7: \**************************************************************************/
8:
9: #include "driver.h"
10:
11: #define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
12: CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | \
13: FF_DONTCARE,L"System"}
14: #define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
15: CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | \
16: FF_DONTCARE,L"MS Sans Serif"}
17: #define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
18: CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | \
19: FF_DONTCARE, L"Courier"}
20:
21: // This is the basic devinfo for a default driver. This is used as a base and customized based
22: // on information passed back from the miniport driver.
23:
24: const DEVINFO gDevInfoFrameBuffer = {
25: (GCAPS_OPAQUERECT | // Graphics capabilities
26: GCAPS_PALMANAGED |
27: GCAPS_ALTERNATEFILL |
28: GCAPS_WINDINGFILL |
29: GCAPS_MONO_DITHER |
30: GCAPS_COLOR_DITHER |
31: GCAPS_TRAPPAINT),
32:
33: // Should also implement GCAPS_HORIZSTRIKE so that the underlines
34: // aren't drawn using DrvBitBlt
35:
36: SYSTM_LOGFONT, // Default font description
37: HELVE_LOGFONT, // ANSI variable font description
38: COURI_LOGFONT, // ANSI fixed font description
39: 0, // Count of device fonts
40: BMF_8BPP, // Preferred DIB format
41: 8, // Width of color dither
42: 8, // Height of color dither
43: 0 // Default palette to use for this device
44: };
45:
46: /******************************Public*Routine******************************\
47: * bInitSURF
48: *
49: * Enables the surface. Maps the frame buffer into memory.
50: *
51: \**************************************************************************/
52:
53: BOOL bInitSURF(PPDEV ppdev, BOOL bFirst)
54: {
55: VIDEO_MEMORY VideoMemory;
56: VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
57: DWORD ReturnedDataLength;
58:
59: // Set the mode.
60:
61: if (!DeviceIoControl(ppdev->hDriver,
62: IOCTL_VIDEO_SET_CURRENT_MODE,
63: (LPVOID) &ppdev->ulMode, // input buffer
64: sizeof(DWORD),
65: NULL,
66: 0,
67: &ReturnedDataLength,
68: NULL))
69: {
70: RIP("Failed SET_CURRENT_MODE");
71: return(FALSE);
72: }
73:
74: if (bFirst)
75: {
76: // Get the linear memory address range.
77:
78: VideoMemory.RequestedVirtualAddress = NULL;
79:
80: if (!DeviceIoControl(ppdev->hDriver,
81: IOCTL_VIDEO_MAP_VIDEO_MEMORY,
82: (PVOID) &VideoMemory, // input buffer
83: sizeof (VIDEO_MEMORY),
84: (PVOID) &VideoMemoryInfo, // output buffer
85: sizeof (VideoMemoryInfo),
86: &ReturnedDataLength,
87: NULL))
88: {
89: RIP("Failed MAP_VIDEO_MEMORY");
90: return(FALSE);
91: }
92: }
93:
94: // Record the Frame Buffer Linear Address.
95:
96: if (bFirst)
97: {
98: ppdev->pjScreen = (PBYTE) VideoMemoryInfo.FrameBufferBase;
99: }
100:
101: // Set the various write mode values, so we don't have to read before write
102: // later on
103:
104: vSetWriteModes(&ppdev->ulrm0_wmX);
105:
106: // Initialize the VGA registers to their default states, so that we
107: // can be sure of drawing properly even when the miniport didn't
108: // happen to set them the way we like them:
109:
110: vInitRegs(ppdev);
111:
112: // Since we just did a mode-set, we'll be in non-planar mode. And make
113: // sure we reset the bank manager (otherwise, after a switch from full-
114: // screen, we may think we've got one bank mapped in, when in fact there's
115: // a different one mapped in, and bad things would happen...).
116:
117: ppdev->flBank &= ~BANK_PLANAR;
118:
119: ppdev->rcl1WindowClip.bottom = -1;
120: ppdev->rcl2WindowClip[0].bottom = -1;
121: ppdev->rcl2WindowClip[1].bottom = -1;
122:
123: ppdev->rcl1PlanarClip.bottom = -1;
124: ppdev->rcl2PlanarClip[0].bottom = -1;
125: ppdev->rcl2PlanarClip[1].bottom = -1;
126:
127: return(TRUE);
128: }
129:
130: /******************************Public*Routine******************************\
131: * vDisableSURF
132: *
133: * Disable the surface. Un-Maps the frame in memory.
134: *
135: \**************************************************************************/
136:
137: VOID vDisableSURF(PPDEV ppdev)
138: {
139: DWORD returnedDataLength;
140: VIDEO_MEMORY videoMemory;
141:
142: videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen;
143:
144: if (!DeviceIoControl(ppdev->hDriver,
145: IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
146: (LPVOID) &videoMemory,
147: sizeof(VIDEO_MEMORY),
148: NULL,
149: 0,
150: &returnedDataLength,
151: NULL))
152: {
153: RIP("Failed UNMAP_VIDEO_MEMORY");
154: }
155: }
156:
157: /******************************Public*Routine******************************\
158: * bInitPDEV
159: *
160: * Determine the mode we should be in based on the DEVMODE passed in.
161: * Query mini-port to get information needed to fill in the DevInfo and the
162: * GdiInfo .
163: *
164: \**************************************************************************/
165:
166: BOOL bInitPDEV(
167: PPDEV ppdev,
168: DEVMODEW *pDevMode)
169: {
170: GDIINFO *pGdiInfo;
171: ULONG cModes;
172: PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
173: VIDEO_COLOR_CAPABILITIES colorCapabilities;
174: ULONG ulTemp;
175: BOOL bSelectDefault;
176: ULONG cbModeSize;
177:
178: pGdiInfo = ppdev->pGdiInfo;
179:
180: //
181: // calls the miniport to get mode information.
182: //
183:
184: cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
185:
186: if (cModes == 0)
187: {
188: DISPDBG((0, "vga256.dll: no available modes\n"));
189: return(FALSE);
190: }
191:
192: //
193: // Determine if we are looking for a default mode.
194: //
195:
196: if ( ((pDevMode->dmPelsWidth) ||
197: (pDevMode->dmPelsHeight) ||
198: (pDevMode->dmBitsPerPel) ||
199: (pDevMode->dmDisplayFlags) ||
200: (pDevMode->dmDisplayFrequency)) == 0)
201: {
202: bSelectDefault = TRUE;
203: }
204: else
205: {
206: bSelectDefault = FALSE;
207: }
208:
209: //
210: // Now see if the requested mode has a match in that table.
211: //
212:
213: pVideoModeSelected = NULL;
214: pVideoTemp = pVideoBuffer;
215:
216: while (cModes--)
217: {
218: if (pVideoTemp->Length != 0)
219: {
220: if (bSelectDefault ||
221: ((pVideoTemp->VisScreenWidth == pDevMode->dmPelsWidth) &&
222: (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
223: (pVideoTemp->BitsPerPlane *
224: pVideoTemp->NumberOfPlanes == pDevMode->dmBitsPerPel) &&
225: ((pVideoTemp->Frequency == pDevMode->dmDisplayFrequency) ||
226: (pDevMode->dmDisplayFrequency == 0)) &&
227: (((pVideoTemp->AttributeFlags &
228: VIDEO_MODE_INTERLACED) ? 1:0) ==
229: ((pDevMode->dmDisplayFlags & DM_INTERLACED) ? 1:0)) ) )
230:
231: {
232: pVideoModeSelected = pVideoTemp;
233: DISPDBG((2, "vga256: Found a match\n")) ;
234: break;
235: }
236: }
237:
238: pVideoTemp = (PVIDEO_MODE_INFORMATION)
239: (((PUCHAR)pVideoTemp) + cbModeSize);
240: }
241:
242: //
243: // If no mode has been found, return an error
244: //
245:
246: if (pVideoModeSelected == NULL)
247: {
248: DISPDBG((0, "vga256.dll: no valid modes\n"));
249: LocalFree(pVideoBuffer);
250: return(FALSE);
251: }
252:
253: //
254: // Fill in the GDIINFO data structure with the information returned from
255: // the kernel driver.
256: //
257:
258: ppdev->ulMode = pVideoModeSelected->ModeIndex;
259: ppdev->cxScreen = pVideoModeSelected->VisScreenWidth;
260: ppdev->cyScreen = pVideoModeSelected->VisScreenHeight;
261: ppdev->ulBitCount = pVideoModeSelected->BitsPerPlane *
262: pVideoModeSelected->NumberOfPlanes;
263: ppdev->lDeltaScreen = pVideoModeSelected->ScreenStride;
264:
265: ppdev->flRed = pVideoModeSelected->RedMask;
266: ppdev->flGreen = pVideoModeSelected->GreenMask;
267: ppdev->flBlue = pVideoModeSelected->BlueMask;
268:
269: if (!(pVideoModeSelected->AttributeFlags & VIDEO_MODE_NO_OFF_SCREEN))
270: {
271: ppdev->fl |= DRIVER_USE_OFFSCREEN;
272: }
273:
274: pGdiInfo->ulVersion = 0x1000; // Our driver is version 1.000
275: pGdiInfo->ulTechnology = DT_RASDISPLAY;
276: pGdiInfo->ulHorzSize = pVideoModeSelected->XMillimeter;
277: pGdiInfo->ulVertSize = pVideoModeSelected->YMillimeter;
278:
279: pGdiInfo->ulHorzRes = ppdev->cxScreen;
280: pGdiInfo->ulVertRes = ppdev->cyScreen;
281: pGdiInfo->cBitsPixel = pVideoModeSelected->BitsPerPlane;
282: pGdiInfo->cPlanes = pVideoModeSelected->NumberOfPlanes;
283:
284: pGdiInfo->ulLogPixelsX = 96;
285: pGdiInfo->ulLogPixelsY = 96;
286:
287: pGdiInfo->flTextCaps = TC_RA_ABLE | TC_SCROLLBLT;
288: pGdiInfo->flRaster = 0; // DDI reservers flRaster
289:
290: pGdiInfo->ulDACRed = pVideoModeSelected->NumberRedBits;
291: pGdiInfo->ulDACGreen = pVideoModeSelected->NumberGreenBits;
292: pGdiInfo->ulDACBlue = pVideoModeSelected->NumberBlueBits;
293:
294: pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio
295: pGdiInfo->ulAspectY = 0x24;
296: pGdiInfo->ulAspectXY = 0x33;
297:
298: pGdiInfo->xStyleStep = 1; // A style unit is 3 pels
299: pGdiInfo->yStyleStep = 1;
300: pGdiInfo->denStyleStep = 3;
301:
302: pGdiInfo->ptlPhysOffset.x = 0;
303: pGdiInfo->ptlPhysOffset.y = 0;
304: pGdiInfo->szlPhysSize.cx = 0;
305: pGdiInfo->szlPhysSize.cy = 0;
306:
307: // RGB and CMY color info.
308:
309: // try to get it from the miniport.
310: // if the miniport doesn ot support this feature, use defaults.
311:
312: if (!DeviceIoControl(ppdev->hDriver,
313: IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
314: NULL,
315: 0,
316: &colorCapabilities,
317: sizeof(VIDEO_COLOR_CAPABILITIES),
318: &ulTemp,
319: NULL))
320: {
321: DISPDBG((1, "vga256 DISP getcolorCapabilities failed \n"));
322:
323: pGdiInfo->ciDevice.Red.x = 6700;
324: pGdiInfo->ciDevice.Red.y = 3300;
325: pGdiInfo->ciDevice.Red.Y = 0;
326: pGdiInfo->ciDevice.Green.x = 2100;
327: pGdiInfo->ciDevice.Green.y = 7100;
328: pGdiInfo->ciDevice.Green.Y = 0;
329: pGdiInfo->ciDevice.Blue.x = 1400;
330: pGdiInfo->ciDevice.Blue.y = 800;
331: pGdiInfo->ciDevice.Blue.Y = 0;
332: pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
333: pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
334: pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
335:
336: pGdiInfo->ciDevice.RedGamma = 20000;
337: pGdiInfo->ciDevice.GreenGamma = 20000;
338: pGdiInfo->ciDevice.BlueGamma = 20000;
339:
340: }
341: else
342: {
343:
344: pGdiInfo->ciDevice.Red.x = colorCapabilities.RedChromaticity_x;
345: pGdiInfo->ciDevice.Red.y = colorCapabilities.RedChromaticity_y;
346: pGdiInfo->ciDevice.Red.Y = 0;
347: pGdiInfo->ciDevice.Green.x = colorCapabilities.GreenChromaticity_x;
348: pGdiInfo->ciDevice.Green.y = colorCapabilities.GreenChromaticity_y;
349: pGdiInfo->ciDevice.Green.Y = 0;
350: pGdiInfo->ciDevice.Blue.x = colorCapabilities.BlueChromaticity_x;
351: pGdiInfo->ciDevice.Blue.y = colorCapabilities.BlueChromaticity_y;
352: pGdiInfo->ciDevice.Blue.Y = 0;
353: pGdiInfo->ciDevice.AlignmentWhite.x = colorCapabilities.WhiteChromaticity_x;
354: pGdiInfo->ciDevice.AlignmentWhite.y = colorCapabilities.WhiteChromaticity_y;
355: pGdiInfo->ciDevice.AlignmentWhite.Y = colorCapabilities.WhiteChromaticity_Y;
356:
357: // if we have a color device store the three color gamma values,
358: // otherwise store the unique gamma value in all three.
359:
360: if (colorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
361: {
362: pGdiInfo->ciDevice.RedGamma = colorCapabilities.RedGamma;
363: pGdiInfo->ciDevice.GreenGamma = colorCapabilities.GreenGamma;
364: pGdiInfo->ciDevice.BlueGamma = colorCapabilities.BlueGamma;
365: }
366: else
367: {
368: pGdiInfo->ciDevice.RedGamma = colorCapabilities.WhiteGamma;
369: pGdiInfo->ciDevice.GreenGamma = colorCapabilities.WhiteGamma;
370: pGdiInfo->ciDevice.BlueGamma = colorCapabilities.WhiteGamma;
371: }
372:
373: };
374:
375: pGdiInfo->ciDevice.Cyan.x = 0;
376: pGdiInfo->ciDevice.Cyan.y = 0;
377: pGdiInfo->ciDevice.Cyan.Y = 0;
378: pGdiInfo->ciDevice.Magenta.x = 0;
379: pGdiInfo->ciDevice.Magenta.y = 0;
380: pGdiInfo->ciDevice.Magenta.Y = 0;
381: pGdiInfo->ciDevice.Yellow.x = 0;
382: pGdiInfo->ciDevice.Yellow.y = 0;
383: pGdiInfo->ciDevice.Yellow.Y = 0;
384:
385: // No dye correction for raster displays.
386:
387: pGdiInfo->ciDevice.MagentaInCyanDye = 0;
388: pGdiInfo->ciDevice.YellowInCyanDye = 0;
389: pGdiInfo->ciDevice.CyanInMagentaDye = 0;
390: pGdiInfo->ciDevice.YellowInMagentaDye = 0;
391: pGdiInfo->ciDevice.CyanInYellowDye = 0;
392: pGdiInfo->ciDevice.MagentaInYellowDye = 0;
393:
394: // Fill in the rest of the devinfo and GdiInfo structures.
395:
396: pGdiInfo->ulNumColors = 20;
397: pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;
398:
399: pGdiInfo->ulDevicePelsDPI = 0; // For printers only
400: pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
401: pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
402: pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
403: pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
404:
405: // Fill in the basic devinfo structure
406:
407: *(ppdev->pDevInfo) = gDevInfoFrameBuffer;
408:
409: LocalFree(pVideoBuffer);
410:
411: return(TRUE);
412: }
413:
414: /******************************Public*Routine******************************\
415: * VOID vInitBrushCache(ppdev)
416: *
417: * Initializes various brush cache structures. Must be done after bank
418: * initialization.
419: *
420: \**************************************************************************/
421:
422: VOID vInitBrushCache(PPDEV ppdev)
423: {
424: LONG cCacheBrushesPerScan = ppdev->lNextScan / BRUSH_SIZE;
425: LONG cCacheScans = ppdev->cTotalScans - ppdev->cyScreen;
426: LONG cCacheEntries;
427: LONG i;
428: LONG j;
429: BRUSHCACHEENTRY* pbce;
430: BRUSHCACHEENTRY* pbceEnd;
431:
432: cCacheEntries = min(cCacheScans*cCacheBrushesPerScan, BRUSH_MAX_CACHE_SIZE);
433:
434: if (cCacheEntries <= 0)
435: {
436: goto InitFailed;
437: }
438:
439: ppdev->pbceCache = (BRUSHCACHEENTRY*) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
440: cCacheEntries * sizeof(BRUSHCACHEENTRY));
441: if (ppdev->pbceCache == NULL)
442: {
443: goto InitFailed;
444: }
445:
446: // We successfully managed to allocate all our data structures for looking
447: // after off-screen memory, so set the flag saying that we can use it
448: // (note that if ppdev->fl's DRIVER_USE_OFFSCREEN hasn't been set, the
449: // memory cannot be used for long-term storage):
450:
451: ppdev->fl |= DRIVER_HAS_OFFSCREEN;
452:
453: ppdev->iCache = 0; // 0 is a reserved index
454: ppdev->iCacheLast = cCacheEntries - 1;
455:
456: // Initialize our cache entry array:
457:
458: pbce = &ppdev->pbceCache[0];
459: pbceEnd = &ppdev->pbceCache[cCacheEntries];
460:
461: for (i = ppdev->cyScreen; i < ppdev->cTotalScans; i++)
462: {
463: for (j = 0; j < cCacheBrushesPerScan; j++)
464: {
465: // Bitmap offset is in planar format, where every byte is one
466: // quadpixel:
467:
468: pbce->yCache = i;
469: pbce->ulCache = (i * ppdev->lNextScan + j * BRUSH_SIZE) / 4;
470:
471: // This verification pointer doesn't actually have to be
472: // initialized, but we do so for debugging purposes:
473:
474: pbce->prbVerifyRealization = NULL;
475:
476: pbce++;
477: if (pbce >= pbceEnd)
478: return;
479: }
480: }
481:
482: RIP("Shouldn't get here");
483:
484: InitFailed:
485: ppdev->fl &= ~(DRIVER_USE_OFFSCREEN | DRIVER_HAS_OFFSCREEN);
486: return;
487: }
488:
489: /******************************Public*Routine******************************\
490: * VOID vResetBrushCache(ppdev)
491: *
492: * Blows away the brush cache entries -- this is useful when switching
493: * out of full-screen mode, where anyone could have written over the video
494: * memory where we cache our brushes.
495: *
496: \**************************************************************************/
497:
498: VOID vResetBrushCache(PPDEV ppdev)
499: {
500: BRUSHCACHEENTRY* pbce;
501: LONG i;
502:
503: // Make sure we actually have a brush cache before we try to reset it:
504:
505: if (ppdev->fl & DRIVER_HAS_OFFSCREEN)
506: {
507: pbce = &ppdev->pbceCache[0];
508: for (i = ppdev->iCacheLast; i >= 0; i--)
509: {
510: pbce->prbVerifyRealization = NULL;
511: pbce++;
512: }
513: }
514: }
515:
516: /******************************Public*Routine******************************\
517: * VOID vDisableBrushCache(ppdev)
518: *
519: * Frees various brush cache structures.
520: *
521: \**************************************************************************/
522:
523: VOID vDisableBrushCache(PPDEV ppdev)
524: {
525: if (ppdev->pbceCache != NULL)
526: {
527: LocalFree(ppdev->pbceCache);
528: }
529: }
530:
531: /******************************Public*Routine******************************\
532: * getAvailableModes
533: *
534: * Calls the miniport to get the list of modes supported by the kernel driver,
535: * and returns the list of modes supported by the diplay driver among those
536: *
537: * returns the number of entries in the videomode buffer.
538: * 0 means no modes are supported by the miniport or that an error occured.
539: *
540: * NOTE: the buffer must be freed up by the caller.
541: *
542: \**************************************************************************/
543:
544: DWORD getAvailableModes(
545: HANDLE hDriver,
546: PVIDEO_MODE_INFORMATION *modeInformation,
547: DWORD *cbModeSize)
548: {
549: ULONG ulTemp;
550: VIDEO_NUM_MODES modes;
551: PVIDEO_MODE_INFORMATION pVideoTemp;
552:
553: //
554: // Get the number of modes supported by the mini-port
555: //
556:
557: if (!DeviceIoControl(hDriver,
558: IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
559: NULL,
560: 0,
561: &modes,
562: sizeof(VIDEO_NUM_MODES),
563: &ulTemp,
564: NULL))
565: {
566: DISPDBG((0, "vga256 getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
567: return(0);
568: }
569:
570: *cbModeSize = modes.ModeInformationLength;
571:
572: //
573: // Allocate the buffer for the mini-port to write the modes in.
574: //
575:
576: *modeInformation = (PVIDEO_MODE_INFORMATION)
577: LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
578: modes.NumModes *
579: modes.ModeInformationLength);
580:
581: if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
582: {
583: DISPDBG((0, "vga256 getAvailableModes failed LocalAlloc\n"));
584:
585: return 0;
586: }
587:
588: //
589: // Ask the mini-port to fill in the available modes.
590: //
591:
592: if (!DeviceIoControl(hDriver,
593: IOCTL_VIDEO_QUERY_AVAIL_MODES,
594: NULL,
595: 0,
596: *modeInformation,
597: modes.NumModes * modes.ModeInformationLength,
598: &ulTemp,
599: NULL))
600: {
601:
602: DISPDBG((0, "vga256 getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
603:
604: LocalFree(*modeInformation);
605: *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
606:
607: return(0);
608: }
609:
610: //
611: // Now see which of these modes are supported by the display driver.
612: // As an internal mechanism, set the length to 0 for the modes we
613: // DO NOT support.
614: //
615:
616: ulTemp = modes.NumModes;
617: pVideoTemp = *modeInformation;
618:
619: //
620: // Mode is rejected if it is not one plane, or not graphics, or is not
621: // one of 8 bits per pel (that is all the vga 256 currently supports)
622: //
623:
624: while (ulTemp--)
625: {
626: if ((pVideoTemp->NumberOfPlanes != 1 ) ||
627: !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
628: (pVideoTemp->BitsPerPlane != 8))
629: {
630: pVideoTemp->Length = 0;
631: }
632:
633: pVideoTemp = (PVIDEO_MODE_INFORMATION)
634: (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
635: }
636:
637: return modes.NumModes;
638:
639: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.