|
|
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.