|
|
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,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: (GCAPS_OPAQUERECT | /* Graphics capabilities */ ! 20: GCAPS_ALTERNATEFILL | GCAPS_WINDINGFILL | ! 21: GCAPS_TRAPPAINT | GCAPS_MONO_DITHER), ! 22: SYSTM_LOGFONT, /* Default font description */ ! 23: HELVE_LOGFONT, /* ANSI variable font description */ ! 24: COURI_LOGFONT, /* ANSI fixed font description */ ! 25: 0, /* Count of device fonts */ ! 26: 0, /* Preferred DIB format */ ! 27: 8, /* Width of color dither */ ! 28: 8, /* Height of color dither */ ! 29: 0 /* Default palette to use for this device */ ! 30: }; ! 31: ! 32: PUCHAR gpucCsrBase = NULL; ! 33: ! 34: // Under a heavy loaded system it seems that IOCTL_VIDEO_SET_CURRENT_MODE failed, ! 35: // which caused the system to hang. This is where we record the last value ! 36: // from the miniport. ! 37: ! 38: BOOL gbLastReturnSetCurrentMode; ! 39: ! 40: /******************************Public*Routine******************************\ ! 41: * bInitSURF ! 42: * ! 43: * Enables the surface. Maps the frame buffer into memory. ! 44: * ! 45: \**************************************************************************/ ! 46: ! 47: BOOL bInitSURF( ! 48: PPDEV ppdev, ! 49: BOOL bFirst) ! 50: { ! 51: VIDEO_MEMORY VideoMemory; ! 52: VIDEO_MEMORY_INFORMATION VideoMemoryInfo; ! 53: DWORD ReturnedDataLength; ! 54: INT i; ! 55: BYTE byte; ! 56: ! 57: #if !defined(_X86_) && !defined(i386) ! 58: VIDEO_PUBLIC_ACCESS_RANGES VideoAccessRange; ! 59: #endif ! 60: ! 61: ! 62: DISPDBG((2, "S3.DLL! bInitSURF entry\n")); ! 63: ! 64: // Set the mode. ! 65: ! 66: gbLastReturnSetCurrentMode = DeviceIoControl(ppdev->hDriver, ! 67: IOCTL_VIDEO_SET_CURRENT_MODE, ! 68: &ppdev->ulMode, // input buffer ! 69: sizeof(DWORD), ! 70: NULL, ! 71: 0, ! 72: &ReturnedDataLength, ! 73: NULL); ! 74: if (gbLastReturnSetCurrentMode == FALSE) ! 75: { ! 76: DISPDBG((0, "S3.DLL!bInitSURF - Initialization error-Set mode")); ! 77: return (FALSE); ! 78: } ! 79: ! 80: if (bFirst) ! 81: { ! 82: #if !defined(_X86_) && !defined(i386) ! 83: ! 84: // ! 85: // Map io ports into virtual memory. ! 86: // ! 87: ! 88: VideoMemory.RequestedVirtualAddress = NULL; ! 89: ! 90: if (!DeviceIoControl(ppdev->hDriver, ! 91: IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES, ! 92: NULL, // input buffer ! 93: 0, ! 94: (PVOID) &VideoAccessRange, // output buffer ! 95: sizeof (VideoAccessRange), ! 96: &ReturnedDataLength, ! 97: NULL)) { ! 98: ! 99: RIP("S3.DLL: Initialization error-Map IO port base"); ! 100: return (FALSE); ! 101: ! 102: } ! 103: ! 104: gpucCsrBase = (PUCHAR)VideoAccessRange.VirtualAddress; ! 105: ! 106: #endif ! 107: ! 108: // Set all the register addresses. ! 109: ! 110: ppdev->cur_x = 0x86E8; ! 111: ppdev->cur_y = 0x82E8; ! 112: ! 113: ppdev->dest_x = 0x8EE8; ! 114: ppdev->dest_y = 0x8AE8; ! 115: ! 116: ppdev->axstp = 0x8AE8; ! 117: ppdev->diastp = 0x8EE8; ! 118: ! 119: ppdev->rect_width = 0x96E8; ! 120: ppdev->line_max = 0x96E8; ! 121: ! 122: ppdev->err_term = 0x92E8; ! 123: ! 124: ppdev->gp_stat = 0x9AE8; ! 125: ppdev->cmd = 0x9AE8; ! 126: ppdev->short_stroke_reg = 0x9EE8; ! 127: ! 128: ppdev->multifunc_cntl = 0xBEE8; ! 129: ! 130: ppdev->bkgd_color = 0xA2E8; ! 131: ppdev->frgd_color = 0xA6E8; ! 132: ! 133: ppdev->bkgd_mix = 0xB6E8; ! 134: ppdev->frgd_mix = 0xBAE8; ! 135: ! 136: ppdev->wrt_mask = 0xAAE8; ! 137: ppdev->rd_mask = 0xAEE8; ! 138: ! 139: ppdev->pixel_transfer = 0xE2E8; ! 140: ! 141: // Check if the I/O register need to be remapped. ! 142: ! 143: OUTPW (CRTC_INDEX, ((SYSCTL_UNLOCK << 8) | CR39)); ! 144: ! 145: OUTP (CRTC_INDEX, 0x43); ! 146: if (INP(CRTC_DATA) & 0x10) ! 147: { ! 148: ppdev->cur_x ^= 0x3A0; ! 149: ppdev->cur_y ^= 0x3A0; ! 150: ppdev->dest_x ^= 0x3A0; ! 151: ppdev->dest_y ^= 0x3A0; ! 152: ppdev->axstp ^= 0x3A0; ! 153: ppdev->diastp ^= 0x3A0; ! 154: ppdev->rect_width ^= 0x3A0; ! 155: ppdev->line_max ^= 0x3A0; ! 156: ppdev->err_term ^= 0x3A0; ! 157: ppdev->gp_stat ^= 0x3A0; ! 158: ppdev->cmd ^= 0x3A0; ! 159: ppdev->short_stroke_reg ^= 0x3A0; ! 160: ppdev->multifunc_cntl ^= 0x3A0; ! 161: ppdev->bkgd_color ^= 0x3A0; ! 162: ppdev->frgd_color ^= 0x3A0; ! 163: ppdev->bkgd_mix ^= 0x3A0; ! 164: ppdev->frgd_mix ^= 0x3A0; ! 165: ppdev->wrt_mask ^= 0x3A0; ! 166: ppdev->rd_mask ^= 0x3A0; ! 167: ppdev->pixel_transfer ^= 0x3A0; ! 168: } ! 169: ! 170: // Get the linear memory address range. ! 171: ! 172: VideoMemory.RequestedVirtualAddress = NULL; ! 173: ! 174: if (!DeviceIoControl(ppdev->hDriver, ! 175: IOCTL_VIDEO_MAP_VIDEO_MEMORY, ! 176: (PVOID) &VideoMemory, // input buffer ! 177: sizeof (VIDEO_MEMORY), ! 178: (PVOID) &VideoMemoryInfo, // output buffer ! 179: sizeof (VideoMemoryInfo), ! 180: &ReturnedDataLength, ! 181: NULL)) ! 182: { ! 183: DISPDBG((0, "S3.DLL!bInitSURF - Initialization error-Map buffer address")); ! 184: return (FALSE); ! 185: } ! 186: ! 187: // Record the Frame Buffer Linear Address. ! 188: ! 189: ppdev->pjScreen = (PBYTE) VideoMemoryInfo.FrameBufferBase; ! 190: ! 191: // Create a default Clip Object. This will be used when a NULL ! 192: // clip object is passed to us. ! 193: ! 194: ppdev->pcoDefault = EngCreateClip(); ! 195: ! 196: ppdev->pcoDefault->iDComplexity = DC_RECT; ! 197: ppdev->pcoDefault->iMode = TC_RECTANGLES; ! 198: ! 199: ppdev->pcoDefault->rclBounds.left = 0; ! 200: ppdev->pcoDefault->rclBounds.top = 0; ! 201: ppdev->pcoDefault->rclBounds.right = ppdev->cxScreen; ! 202: ppdev->pcoDefault->rclBounds.bottom = ppdev->cyScreen; ! 203: ! 204: ppdev->pcoFullRam = EngCreateClip(); ! 205: ! 206: ppdev->pcoFullRam->iDComplexity = DC_TRIVIAL; ! 207: ppdev->pcoFullRam->iMode = TC_RECTANGLES; ! 208: ! 209: ppdev->pcoFullRam->rclBounds.left = 0; ! 210: ppdev->pcoFullRam->rclBounds.top = 0; ! 211: ppdev->pcoFullRam->rclBounds.right = ppdev->cxMaxRam; ! 212: ppdev->pcoFullRam->rclBounds.bottom = ppdev->cyMaxRam; ! 213: ! 214: // Create a DDA object (now only used by trap enumeration) ! 215: ! 216: ppdev->pdda = EngCreateDDA(); ! 217: ! 218: // Initialize the Unique Brush Counter, ! 219: // Allocate and Initialize the Brush cache manager arrays. ! 220: // Init the Expansion Cache Tags. ! 221: ! 222: ppdev->gBrushUnique = 1; ! 223: ! 224: ppdev->iMaxCachedColorBrushes = MAX_COLOR_PATTERNS; ! 225: ppdev->iNextColorBrushCacheSlot = 0; ! 226: ! 227: ppdev->pulColorBrushCacheEntries = (PULONG) LocalAlloc(LPTR, MAX_COLOR_PATTERNS * sizeof (ULONG)); ! 228: ! 229: if (ppdev->pulColorBrushCacheEntries == NULL) ! 230: { ! 231: DISPDBG((0, "S3.DLL!bInitSURF - LocalAlloc for pulColorBrushCacheEntries failed\n")); ! 232: return (FALSE); ! 233: } ! 234: ! 235: ppdev->ulColorExpansionCacheTag = 0; ! 236: ! 237: ppdev->iMaxCachedMonoBrushes = MAX_MONO_PATTERNS; ! 238: ppdev->iNextMonoBrushCacheSlot = 0; ! 239: ! 240: ppdev->pulMonoBrushCacheEntries = (PULONG) LocalAlloc(LPTR, MAX_MONO_PATTERNS * sizeof (ULONG)); ! 241: ! 242: if (ppdev->pulMonoBrushCacheEntries == NULL) ! 243: { ! 244: DISPDBG((0, "S3.DLL!bInitSURF - LocalAlloc for pulMonoBrushCacheEntries failed\n")); ! 245: return (FALSE); ! 246: } ! 247: ! 248: for (i = 0; i < 8; i++) ! 249: { ! 250: ppdev->aulMonoExpansionCacheTag[i] = 0; ! 251: } ! 252: ! 253: ppdev->iNextMonoBrushExpansionSlot = 0; ! 254: ! 255: // Init the cache tags for the Source bitmap cache. ! 256: ! 257: ppdev->hsurfCachedBitmap = NULL; ! 258: ppdev->iUniqCachedBitmap = (ULONG) -1; ! 259: ! 260: // Init the Save Screen Bits structures. ! 261: ! 262: ppdev->iUniqeSaveScreenBits = 1; ! 263: ppdev->SavedScreenBitsHeader.pssbLink = NULL; ! 264: ppdev->SavedScreenBitsHeader.iUniq = (ULONG) -1; ! 265: ! 266: // Get the chip ID and set the New Bank Control bool. ! 267: ! 268: OUTPW(0x3d4, 0x4838); // unlocke S3 regs ! 269: OUTP(0x3d4, 0x30); // crtc index for S# ID reg ! 270: byte = INP(0x3d5); // Get the ID ! 271: OUTPW(0x3d4, 0x0038); // Lock the S3 regs ! 272: ! 273: ppdev->s3ChipID = byte; ! 274: ! 275: if (ppdev->cxScreen == 1280) ! 276: ppdev->bBt485Dac = TRUE; ! 277: else ! 278: ppdev->bBt485Dac = FALSE; ! 279: ! 280: // Pickup the initial value for the Pointer Control Register. ! 281: // This is requried for the 928,801/805 and benign on the 911/924. ! 282: ! 283: OUTP(CRTC_INDEX, HGC_MODE); ! 284: ppdev->HgcMode = ((INP(CRTC_DATA) & ~0x11) << 8) | HGC_MODE; ! 285: ! 286: switch(byte) ! 287: { ! 288: case 0x90: // 801/805 rev 0 ! 289: case 0x91: // 801/805 rev 1 ! 290: case 0x92: // 801/805 rev 2 ! 291: case 0x93: // 801/805 rev 3 ! 292: ! 293: case 0xA0: // 928 rev 0 ! 294: case 0xA1: // 928 rev 1 ! 295: case 0xA2: // 928 rev 2 ! 296: case 0xA3: // 928 rev 3 ! 297: ppdev->bNewBankControl = TRUE; ! 298: ! 299: // Pick up the initial values for the System Control and Linear Address ! 300: // Windows Control register. ! 301: ! 302: OUTPW (CRTC_INDEX, ((SYSCTL_UNLOCK << 8) | CR39)); ! 303: ! 304: OUTP(CRTC_INDEX, SYS_CNFG); ! 305: ppdev->SysCnfg = ((INP(CRTC_DATA) << 8) | SYS_CNFG) & ~0x0900; ! 306: ! 307: OUTP(CRTC_INDEX, LAW_CTL); ! 308: ppdev->LawCtl = ((INP(CRTC_DATA) << 8) | LAW_CTL) & ~0x1000; ! 309: ! 310: OUTP(CRTC_INDEX, EX_SCTL_2); ! 311: ppdev->ExtSysCtl2 = (INP(CRTC_DATA) & ~0x0C); ! 312: ! 313: if (ppdev->bBt485Dac == TRUE) ! 314: { ! 315: // Make a copy of the Extened DAC control register ! 316: ! 317: OUTP(CRTC_INDEX, EX_DAC_CT); ! 318: ppdev->ExtDacCtl = (((INP(CRTC_DATA) << 8) | EX_DAC_CT) & ~0x0300) ; ! 319: ! 320: // Get a copy of the Bt486 command register 0 ! 321: ! 322: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0100)); ! 323: ppdev->Bt485CmdReg0 = INP (BT485_ADDR_CMD_REG0); ! 324: ! 325: // Get a copy of the Bt486 command register 1 ! 326: ! 327: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 328: ppdev->Bt485CmdReg1 = INP (BT485_ADDR_CMD_REG1); ! 329: ! 330: // Get a copy of the Bt486 command register 2 ! 331: // And mask off the Cursor control bits. ! 332: ! 333: ppdev->Bt485CmdReg2 = INP (BT485_ADDR_CMD_REG2) & BT485_CURSOR_DISABLE; ! 334: ! 335: // Disable the cursor ! 336: ! 337: OUTP (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2); ! 338: ! 339: // To get the Bt485 command register 3 we have to go through ! 340: // following indirection "dance". ! 341: ! 342: // First set the Command Reg3 access bit in Command Reg0 ! 343: ! 344: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0100)); ! 345: OUTP (BT485_ADDR_CMD_REG0, ppdev->Bt485CmdReg0 | BT485_CMD_REG_3_ACCESS); ! 346: ! 347: // Now set the index to 1 ! 348: ! 349: OUTPW (CRTC_INDEX, ppdev->ExtDacCtl); ! 350: OUTP (0x3c8, 0x01); ! 351: ! 352: // Now access command register 3 ! 353: // and save the value away ! 354: ! 355: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200)); ! 356: ppdev->Bt485CmdReg3 = INP(BT485_ADDR_CMD_REG3); ! 357: ! 358: // Set Command register 3 for a 64 X 64 cursor. ! 359: ! 360: ppdev->Bt485CmdReg3 |= BT485_64X64_CURSOR; ! 361: OUTP (BT485_ADDR_CMD_REG3, ppdev->Bt485CmdReg3); ! 362: ! 363: // Disable access to command reg 3 ! 364: ! 365: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0100)); ! 366: OUTP (BT485_ADDR_CMD_REG0, ppdev->Bt485CmdReg0); ! 367: ! 368: // Set the color 1 and color 2 for the cursor. ! 369: // Select Address register; cursor/overscan color write on the Bt485. ! 370: ! 371: OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0100)); ! 372: OUTP (BT485_ADDR_CUR_COLOR_WRITE, BT485_CURSOR_COLOR_1); ! 373: ! 374: // Output the RGB for Cursor color 1 ! 375: ! 376: OUTP (BT485_CUR_COLOR_DATA, 0x00); ! 377: OUTP (BT485_CUR_COLOR_DATA, 0x00); ! 378: OUTP (BT485_CUR_COLOR_DATA, 0x00); ! 379: ! 380: // Output the RGB for Cursor color 2 ! 381: ! 382: OUTP (BT485_CUR_COLOR_DATA, 0xff); ! 383: OUTP (BT485_CUR_COLOR_DATA, 0xff); ! 384: OUTP (BT485_CUR_COLOR_DATA, 0xff); ! 385: ! 386: // reset the DAC addr ! 387: ! 388: OUTPW (CRTC_INDEX, ppdev->ExtDacCtl); ! 389: } ! 390: ! 391: break; ! 392: ! 393: case 0x81: // 911 ! 394: case 0x82: // 924 ! 395: default: ! 396: ppdev->bNewBankControl = FALSE; ! 397: break; ! 398: } ! 399: } ! 400: ! 401: // Initialize the shadow copies of the S3 registers to an ! 402: // invalid state. This also needs to be done when we return from a ! 403: // screen session. ! 404: ! 405: ppdev->ForegroundMix = ! 406: ppdev->BackgroundMix = ! 407: ppdev->ForegroundColor = ! 408: ppdev->BackgroundColor = ! 409: ppdev->WriteMask = ! 410: ppdev->ReadMask = (WORD) -1; ! 411: ! 412: // Reset the clipping registers. ! 413: ! 414: vResetS3Clipping(ppdev); ! 415: ! 416: // Unlock the registers used by the cursor ! 417: ! 418: OUTPW (CRTC_INDEX, ((SYSCTL_UNLOCK << 8) | CR39)); ! 419: ! 420: return(TRUE); ! 421: } ! 422: ! 423: /******************************Public*Routine******************************\ ! 424: * vDisableSURF ! 425: * ! 426: * Disable the surface. Un-Maps the frame in memory. ! 427: * ! 428: \**************************************************************************/ ! 429: ! 430: VOID vDisableSURF(PPDEV ppdev) ! 431: { ! 432: DWORD returnedDataLength; ! 433: VIDEO_MEMORY videoMemory; ! 434: ! 435: videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen; ! 436: ! 437: if (!DeviceIoControl(ppdev->hDriver, ! 438: IOCTL_VIDEO_UNMAP_VIDEO_MEMORY, ! 439: &videoMemory, ! 440: sizeof(VIDEO_MEMORY), ! 441: NULL, ! 442: 0, ! 443: &returnedDataLength, ! 444: NULL)) ! 445: { ! 446: DISPDBG((0, "DISP vDisableSURF failed IOCTL_VIDEO_UNMAP\n")); ! 447: } ! 448: ! 449: #if !defined(_X86_) && !defined(i386) ! 450: ! 451: ! 452: // NOTE NOTE NOTE ! 453: // ! 454: // WE NEED TO UNMAP THE CSRS HERE! ! 455: ! 456: #endif ! 457: ! 458: } ! 459: ! 460: /******************************Public*Routine******************************\ ! 461: * bInitPDEV ! 462: * ! 463: * Determine the mode we should be in based on the DEVMODE passed in. ! 464: * Query mini-port to get information needed to fill in the DevInfo and the ! 465: * GdiInfo . ! 466: * ! 467: \**************************************************************************/ ! 468: ! 469: BOOL bInitPDEV( ! 470: PPDEV ppdev, ! 471: DEVMODEW *pDevMode) ! 472: { ! 473: ! 474: ! 475: ULONG cModes; ! 476: PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp; ! 477: BOOL bSelectDefault; ! 478: GDIINFO *pGdiInfo; ! 479: VIDEO_MODE_INFORMATION VideoModeInformation; ! 480: ULONG cbModeSize; ! 481: ! 482: ! 483: DISPDBG((2,"S3.DLL:!bInitPDEV - Entry\n")); ! 484: ! 485: pGdiInfo = ppdev->pGdiInfo; ! 486: ! 487: // ! 488: // calls the miniport to get mode information. ! 489: // ! 490: ! 491: cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize); ! 492: ! 493: if (cModes == 0) ! 494: { ! 495: return(FALSE); ! 496: } ! 497: ! 498: // ! 499: // Determine if we are looking for a default mode. ! 500: // ! 501: ! 502: if ( ((pDevMode->dmPelsWidth) || ! 503: (pDevMode->dmPelsHeight) || ! 504: (pDevMode->dmBitsPerPel) || ! 505: (pDevMode->dmDisplayFlags) || ! 506: (pDevMode->dmDisplayFrequency)) == 0) ! 507: { ! 508: bSelectDefault = TRUE; ! 509: } ! 510: else ! 511: { ! 512: bSelectDefault = FALSE; ! 513: } ! 514: ! 515: // ! 516: // Now see if the requested mode has a match in that table. ! 517: // ! 518: ! 519: pVideoModeSelected = NULL; ! 520: pVideoTemp = pVideoBuffer; ! 521: ! 522: while (cModes--) ! 523: { ! 524: if (pVideoTemp->Length != 0) ! 525: { ! 526: if (bSelectDefault || ! 527: ((pVideoTemp->VisScreenWidth == pDevMode->dmPelsWidth) && ! 528: (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) && ! 529: (pVideoTemp->BitsPerPlane * ! 530: pVideoTemp->NumberOfPlanes == pDevMode->dmBitsPerPel)) && ! 531: (pVideoTemp->Frequency == pDevMode->dmDisplayFrequency)) ! 532: { ! 533: pVideoModeSelected = pVideoTemp; ! 534: DISPDBG((3, "S3: Found a match\n")); ! 535: break; ! 536: } ! 537: } ! 538: ! 539: pVideoTemp = (PVIDEO_MODE_INFORMATION) ! 540: (((PUCHAR)pVideoTemp) + cbModeSize); ! 541: ! 542: } ! 543: ! 544: // ! 545: // If no mode has been found, return an error ! 546: // ! 547: ! 548: if (pVideoModeSelected == NULL) ! 549: { ! 550: return(FALSE); ! 551: } ! 552: ! 553: ! 554: // We have chosen the one we want. Save it in a stack buffer and ! 555: // get rid of allocated memory before we forget to free it. ! 556: ! 557: VideoModeInformation = *pVideoModeSelected; ! 558: LocalFree(pVideoBuffer); ! 559: ! 560: // Set up screen information from the mini-port ! 561: ! 562: ppdev->ulMode = VideoModeInformation.ModeIndex; ! 563: ppdev->cxScreen = VideoModeInformation.VisScreenWidth; ! 564: ppdev->cyScreen = VideoModeInformation.VisScreenHeight; ! 565: ! 566: ppdev->cxMaxRam = VideoModeInformation.VideoMemoryBitmapWidth; ! 567: ppdev->cyMaxRam = VideoModeInformation.VideoMemoryBitmapHeight; ! 568: ! 569: ppdev->ulBitCount = VideoModeInformation.BitsPerPlane * ! 570: VideoModeInformation.NumberOfPlanes; ! 571: ppdev->lDeltaScreen = VideoModeInformation.ScreenStride; ! 572: ! 573: ppdev->flRed = VideoModeInformation.RedMask; ! 574: ppdev->flGreen = VideoModeInformation.GreenMask; ! 575: ppdev->flBlue = VideoModeInformation.BlueMask; ! 576: ! 577: // Fill in the GDIINFO data structure with the information ! 578: // returned from the kernel driver. ! 579: ! 580: pGdiInfo->ulVersion = 0x1000; // Our driver is version 1.000 ! 581: pGdiInfo->ulTechnology = DT_RASDISPLAY; ! 582: pGdiInfo->ulHorzSize = VideoModeInformation.XMillimeter; ! 583: pGdiInfo->ulVertSize = VideoModeInformation.YMillimeter; ! 584: ! 585: pGdiInfo->ulHorzRes = ppdev->cxScreen; ! 586: pGdiInfo->ulVertRes = ppdev->cyScreen; ! 587: pGdiInfo->cBitsPixel = VideoModeInformation.BitsPerPlane; ! 588: pGdiInfo->cPlanes = VideoModeInformation.NumberOfPlanes; ! 589: ! 590: // The following block of code is left in place to make it easy ! 591: // when we go to a 16/24/32 bit per pixel bitmap. ! 592: ! 593: if (ppdev->ulBitCount == 8) ! 594: { ! 595: // It is Palette Managed. ! 596: ! 597: pGdiInfo->ulNumColors = 20; ! 598: pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount; ! 599: ! 600: pGdiInfo->flRaster = 0; // DDI reserved field ! 601: } ! 602: else ! 603: { ! 604: pGdiInfo->ulNumColors = 1 << ppdev->ulBitCount; ! 605: pGdiInfo->ulNumPalReg = 0; ! 606: ! 607: pGdiInfo->flRaster = 0; // DDI reserved field ! 608: } ! 609: ! 610: pGdiInfo->ulLogPixelsX = 96; ! 611: pGdiInfo->ulLogPixelsY = 96; ! 612: ! 613: pGdiInfo->flTextCaps = TC_RA_ABLE; ! 614: ! 615: pGdiInfo->ulDACRed = VideoModeInformation.NumberRedBits; ! 616: pGdiInfo->ulDACGreen = VideoModeInformation.NumberGreenBits; ! 617: pGdiInfo->ulDACBlue = VideoModeInformation.NumberBlueBits; ! 618: ! 619: pGdiInfo->xStyleStep = 1; // A style unit is 3 pels ! 620: pGdiInfo->yStyleStep = 1; ! 621: pGdiInfo->denStyleStep = 3; ! 622: ! 623: pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio ! 624: pGdiInfo->ulAspectY = 0x24; ! 625: pGdiInfo->ulAspectXY = 0x33; ! 626: ! 627: pGdiInfo->ptlPhysOffset.x = 0; ! 628: pGdiInfo->ptlPhysOffset.y = 0; ! 629: pGdiInfo->szlPhysSize.cx = 0; ! 630: pGdiInfo->szlPhysSize.cy = 0; ! 631: ! 632: // RGB and CMY color info. ! 633: ! 634: pGdiInfo->ciDevice.Red.x = 6700; ! 635: pGdiInfo->ciDevice.Red.y = 3300; ! 636: pGdiInfo->ciDevice.Red.Y = 0; ! 637: ! 638: pGdiInfo->ciDevice.Green.x = 2100; ! 639: pGdiInfo->ciDevice.Green.y = 7100; ! 640: pGdiInfo->ciDevice.Green.Y = 0; ! 641: ! 642: pGdiInfo->ciDevice.Blue.x = 1400; ! 643: pGdiInfo->ciDevice.Blue.y = 800; ! 644: pGdiInfo->ciDevice.Blue.Y = 0; ! 645: ! 646: pGdiInfo->ciDevice.Cyan.x = 1750; ! 647: pGdiInfo->ciDevice.Cyan.y = 3950; ! 648: pGdiInfo->ciDevice.Cyan.Y = 0; ! 649: ! 650: pGdiInfo->ciDevice.Magenta.x = 4050; ! 651: pGdiInfo->ciDevice.Magenta.y = 2050; ! 652: pGdiInfo->ciDevice.Magenta.Y = 0; ! 653: ! 654: pGdiInfo->ciDevice.Yellow.x = 4400; ! 655: pGdiInfo->ciDevice.Yellow.y = 5200; ! 656: pGdiInfo->ciDevice.Yellow.Y = 0; ! 657: ! 658: pGdiInfo->ciDevice.AlignmentWhite.x = 3127; ! 659: pGdiInfo->ciDevice.AlignmentWhite.y = 3290; ! 660: pGdiInfo->ciDevice.AlignmentWhite.Y = 0; ! 661: ! 662: // Color Gamma adjustment values. ! 663: ! 664: pGdiInfo->ciDevice.RedGamma = 20000; ! 665: pGdiInfo->ciDevice.GreenGamma = 20000; ! 666: pGdiInfo->ciDevice.BlueGamma = 20000; ! 667: ! 668: // No dye correction for raster displays. ! 669: ! 670: pGdiInfo->ciDevice.MagentaInCyanDye = 0; ! 671: pGdiInfo->ciDevice.YellowInCyanDye = 0; ! 672: pGdiInfo->ciDevice.CyanInMagentaDye = 0; ! 673: pGdiInfo->ciDevice.YellowInMagentaDye = 0; ! 674: pGdiInfo->ciDevice.CyanInYellowDye = 0; ! 675: pGdiInfo->ciDevice.MagentaInYellowDye = 0; ! 676: ! 677: pGdiInfo->ulDevicePelsDPI = 0; // For printers only ! 678: pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA; ! 679: pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M; ! 680: pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP; ! 681: pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS; ! 682: ! 683: // Fill in the devinfo structure ! 684: ! 685: *(ppdev->pDevInfo) = gDevInfoFrameBuffer; ! 686: ! 687: if (ppdev->ulBitCount == 8) ! 688: { ! 689: ppdev->pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED | ! 690: GCAPS_COLOR_DITHER); ! 691: ppdev->pDevInfo->iDitherFormat = BMF_8BPP; ! 692: } ! 693: else if (ppdev->ulBitCount == 16) ! 694: { ! 695: ppdev->pDevInfo->iDitherFormat = BMF_16BPP; ! 696: } ! 697: else ! 698: { ! 699: ppdev->pDevInfo->iDitherFormat = BMF_32BPP; ! 700: } ! 701: ! 702: return(TRUE); ! 703: } ! 704: ! 705: ! 706: /******************************Public*Routine******************************\ ! 707: * getAvailableModes ! 708: * ! 709: * Calls the miniport to get the list of modes supported by the kernel driver, ! 710: * and returns the list of modes supported by the diplay driver among those ! 711: * ! 712: * returns the number of entries in the videomode buffer. ! 713: * 0 means no modes are supported by the miniport or that an error occured. ! 714: * ! 715: * NOTE: the buffer must be freed up by the caller. ! 716: * ! 717: \**************************************************************************/ ! 718: DWORD getAvailableModes( ! 719: HANDLE hDriver, ! 720: PVIDEO_MODE_INFORMATION *modeInformation, ! 721: DWORD *cbModeSize) ! 722: { ! 723: ! 724: ULONG ulTemp; ! 725: VIDEO_NUM_MODES modes; ! 726: PVIDEO_MODE_INFORMATION pVideoTemp; ! 727: ! 728: // ! 729: // Get the number of modes supported by the mini-port ! 730: // ! 731: ! 732: if (!DeviceIoControl(hDriver, ! 733: IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES, ! 734: NULL, ! 735: 0, ! 736: &modes, ! 737: sizeof(VIDEO_NUM_MODES), ! 738: &ulTemp, ! 739: NULL)) ! 740: { ! 741: DISPDBG((0, "s3.dll getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n")); ! 742: return(0); ! 743: } ! 744: ! 745: *cbModeSize = modes.ModeInformationLength; ! 746: ! 747: // ! 748: // Allocate the buffer for the mini-port to write the modes in. ! 749: // ! 750: ! 751: *modeInformation = (PVIDEO_MODE_INFORMATION) ! 752: LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, ! 753: modes.NumModes * ! 754: modes.ModeInformationLength); ! 755: ! 756: if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL) ! 757: { ! 758: DISPDBG((0, "S3.dll: getAvailableModes failed LocalAlloc\n")); ! 759: return 0; ! 760: } ! 761: ! 762: // ! 763: // Ask the mini-port to fill in the available modes. ! 764: // ! 765: ! 766: if (!DeviceIoControl(hDriver, ! 767: IOCTL_VIDEO_QUERY_AVAIL_MODES, ! 768: NULL, ! 769: 0, ! 770: *modeInformation, ! 771: modes.NumModes * modes.ModeInformationLength, ! 772: &ulTemp, ! 773: NULL)) ! 774: { ! 775: ! 776: DISPDBG((0, "S3.dll: getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n")); ! 777: ! 778: LocalFree(*modeInformation); ! 779: *modeInformation = (PVIDEO_MODE_INFORMATION) NULL; ! 780: ! 781: return(0); ! 782: } ! 783: ! 784: // ! 785: // Now see which of these modes are supported by the display driver. ! 786: // As an internal mechanism, set the length to 0 for the modes we ! 787: // DO NOT support. ! 788: // ! 789: ! 790: ulTemp = modes.NumModes; ! 791: pVideoTemp = *modeInformation; ! 792: ! 793: // ! 794: // Mode is rejected if it is not one plane, or not graphics, or is not ! 795: // one of 8, 16 or 32 bits per pel. ! 796: // ! 797: ! 798: while (ulTemp--) ! 799: { ! 800: if ((pVideoTemp->NumberOfPlanes != 1 ) || ! 801: !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) || ! 802: ((pVideoTemp->BitsPerPlane != 8) && ! 803: (pVideoTemp->BitsPerPlane != 16) && ! 804: (pVideoTemp->BitsPerPlane != 32))) ! 805: { ! 806: pVideoTemp->Length = 0; ! 807: } ! 808: ! 809: pVideoTemp = (PVIDEO_MODE_INFORMATION) ! 810: (((PUCHAR)pVideoTemp) + modes.ModeInformationLength); ! 811: } ! 812: ! 813: return modes.NumModes; ! 814: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.