Annotation of ntddk/src/video/displays/s3/screen.c, revision 1.1.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.