Annotation of ntddk/src/video/displays/s3/screen.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.