Annotation of ntddk/src/video/displays/vga/savescr.c, revision 1.1

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: savescr.c                                                   *
        !             3: *                                                                          *
        !             4: * DrvSaveScreenBits                                                        *
        !             5: *                                                                          *
        !             6: * Copyright (c) 1992 Microsoft Corporation                                 *
        !             7: \**************************************************************************/
        !             8: 
        !             9: 
        !            10: #include <driver.h>
        !            11: 
        !            12: 
        !            13: //**************************************************************************//
        !            14: // Note: if this is turned on, you *MUST* make sure to invalidate and reset //
        !            15: // this when going to/returning from fullscreen mode (in DrvAssertMode).    //
        !            16: //**************************************************************************//
        !            17: #define OFFSCREEN_SUPPORTED 0   // 1 to support saves to offscreen memory
        !            18:                                 //  (code currently not written)
        !            19: 
        !            20: VOID
        !            21: vRestoreScreenBitsFromOffscreen(
        !            22:    PDEVSURF pdsurf,
        !            23:    PRECTL prcl,
        !            24:    PBYTE pjSrcBuffer
        !            25:    );
        !            26: 
        !            27: VOID
        !            28: vRestoreScreenBitsFromMemory(
        !            29:    PDEVSURF pdsurf,
        !            30:    PRECTL prcl,
        !            31:    PBYTE pjSrcBuffer,
        !            32:    ULONG ulRestoreWidthInBytes,
        !            33:    ULONG ulSrcDelta
        !            34:    );
        !            35: 
        !            36: VOID
        !            37: vSaveScreenBitsToMemory(
        !            38:    PDEVSURF pdsurf,
        !            39:    PRECTL prcl,
        !            40:    PVOID pjDestBuffer,
        !            41:    ULONG ulSaveWidthInBytes,
        !            42:    ULONG ulSaveHeight,
        !            43:    ULONG ulDestScanWidth
        !            44:    );
        !            45: 
        !            46: /******************************Public*Routine******************************\
        !            47: * DrvSaveScreenBits(pso,iMode,iIdent,prcl)                                 *
        !            48: *                                                                          *
        !            49: * Saves and restores the specified area of the screen                      *
        !            50: *                                                                          *
        !            51: \**************************************************************************/
        !            52: 
        !            53: ULONG DrvSaveScreenBits(SURFOBJ *pso, ULONG iMode, ULONG iIdent, RECTL *prcl)
        !            54: {
        !            55:     PDEVSURF pdsurf;
        !            56:     PPDEV ppdev;
        !            57:     PSAVED_SCREEN_BITS pSSB, *pLastSSBPtr, pSSBTemp;
        !            58:     BOOL bIdentFound;
        !            59:     ULONG ulSaveSize, ulSaveHeight;
        !            60:     ULONG ulSaveWidthInBytes, ulSaveWidthInAlignedBytes;
        !            61: 
        !            62: //    ASSERT(pso != (SURFOBJ *) NULL,"DrvSaveScreenBits invalid pso");
        !            63: 
        !            64:     pdsurf = (PDEVSURF) pso->dhsurf;
        !            65: 
        !            66: //    ASSERT(pdsurf != (PDEVSURF) NULL,"DrvSaveScreenBits invalid dhsurf");
        !            67: //    ASSERT(pdsurf->iFormat == BMF_PHYSDEVICE,
        !            68: //            "DrvSaveScreenBits DFBs not supported");
        !            69: 
        !            70:     ppdev = pdsurf->ppdev;  // find the PDEV that goes with this surface
        !            71: 
        !            72:     //
        !            73:     // Save, restore, or free a block of screen bits.
        !            74:     //
        !            75: 
        !            76:     switch(iMode)
        !            77:     {
        !            78:         //
        !            79:         // Save a block of screen bits.
        !            80:         //
        !            81: 
        !            82:         case SS_SAVE:
        !            83: 
        !            84: //            ASSERT(prcl != (RECTL *) NULL,"DrvSaveScreenBits invalid prcl");
        !            85:             // Figure out how big the save area will be
        !            86:             ulSaveHeight = prcl->bottom - prcl->top;
        !            87:             ulSaveWidthInBytes =
        !            88:                     ((ULONG)((prcl->right + 7) - (prcl->left & ~0x07))) >> 3;
        !            89: 
        !            90: #if OFFSCREEN_SUPPORTED
        !            91:             // This is the size of the the save area for one plane, or the
        !            92:             // number of addresses required to save this in offscreen memory.
        !            93:             // A system memory save area would require four times as many bytes
        !            94:             ulSaveSize = ulSaveHeight * pSSB->ulSaveWidthInBytes;
        !            95: 
        !            96:             // See if there's enough memory left in the display memory heap to
        !            97:             // save this rectangle
        !            98:             if (ulSaveSize >
        !            99:                     (pdsurf->pjAdapterHeapTop - pdsurf->pjAdapterHeapStart))
        !           100:             {
        !           101: #endif
        !           102:                 // Not enough offscreen memory; store in system memory.
        !           103:                 // Calculate new buffer width, allowing for padding so we can
        !           104:                 // dword align
        !           105:                 ulSaveWidthInAlignedBytes =
        !           106:                     (((ULONG)((prcl->right + 31) - (prcl->left & ~0x1F)))
        !           107:                                   >> 5) << 2;
        !           108: 
        !           109:                 // # of bytes to hold all 4 planes of save rect in memory
        !           110:                 ulSaveSize = ((ulSaveHeight * ulSaveWidthInAlignedBytes) << 2)
        !           111:                         + sizeof(SAVED_SCREEN_BITS);
        !           112: 
        !           113:                 // If the preallocated saved screen bits buffer is free and big
        !           114:                 // enough to handle this save, we'll use that
        !           115:                 if ((ppdev->flPreallocSSBBufferInUse == FALSE) &&
        !           116:                     (ulSaveSize <= ppdev->ulPreallocSSBSize))
        !           117:                 {
        !           118:                     // Save in preallocated buffer
        !           119: 
        !           120:                     pSSB = (PSAVED_SCREEN_BITS) ppdev->pjPreallocSSBBuffer;
        !           121: 
        !           122:                     // Mark that we're saving in the preallocated buffer
        !           123:                     pSSB->bFlags = SSB_IN_PREALLOC_BUFFER;
        !           124: 
        !           125:                     // Make sure no other screen bits save tries to use the
        !           126:                     //  buffer
        !           127:                     ppdev->flPreallocSSBBufferInUse = TRUE;
        !           128:                 }
        !           129:                 else
        !           130:                 {
        !           131:                     // Save in system memory buffer
        !           132: 
        !           133:                     // Allocate a structure to contain the save info and the
        !           134:                     // save buffer (four planes' worth)
        !           135:                     pSSB = (PSAVED_SCREEN_BITS)
        !           136:                            (LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
        !           137:                            ulSaveSize));
        !           138:                     if (pSSB == NULL)
        !           139:                     {
        !           140:                         // Couldn't get memory, so fail this call
        !           141:                         return((ULONG)0);
        !           142:                     }
        !           143: 
        !           144:                     // Mark that we're not saving in display memory
        !           145:                     pSSB->bFlags = 0;
        !           146:                 }
        !           147: 
        !           148:                 // Start address at which to save, accounting for
        !           149:                 // the number of bytes by which to pad on the left to dword
        !           150:                 // align (assumes each scan line starts dword aligned, which is
        !           151:                 // true in 640, 800, and 1024 wide cases)
        !           152:                 pSSB->pjBuffer = ((PBYTE) pSSB) + sizeof(SAVED_SCREEN_BITS) +
        !           153:                                  ((prcl->left >> 3) & 0x03);
        !           154: 
        !           155:                 pSSB->ulSaveWidthInBytes = ulSaveWidthInBytes;
        !           156: 
        !           157:                 // Distance from end of one scan to start of next (number of
        !           158:                 // padding bytes for dword alignment purposes)
        !           159:                 pSSB->ulDelta =
        !           160:                         ulSaveWidthInAlignedBytes - pSSB->ulSaveWidthInBytes;
        !           161: 
        !           162:                 // Save the rectangle to system memory
        !           163:                 vSaveScreenBitsToMemory(pdsurf,
        !           164:                                         prcl,
        !           165:                                         pSSB->pjBuffer,
        !           166:                                         pSSB->ulSaveWidthInBytes,
        !           167:                                         ulSaveHeight,
        !           168:                                         ulSaveWidthInAlignedBytes);
        !           169: #if OFFSCREEN_SUPPORTED
        !           170:             }
        !           171:             else
        !           172:             {
        !           173:                 // Store in offscreen memory
        !           174:                 // Allocate a structure to contain the save info
        !           175:                 pSSB = (PSAVED_SCREEN_BITS)
        !           176:                        (LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
        !           177:                        sizeof(SAVED_SCREEN_BITS));
        !           178:                 if (pSSB == NULL)
        !           179:                 {
        !           180:                     // Couldn't get memory, so fail this call
        !           181:                     return(0);
        !           182:                 }
        !           183:                 pSSB->bFlags = SSB_IN_ADAPTER_MEMORY;
        !           184: 
        !           185:                 pSSB->ulSaveWidthInBytes = ulSaveWidthInBytes;
        !           186: 
        !           187:                 /***/
        !           188: 
        !           189:             }
        !           190: #endif
        !           191: 
        !           192:             // Link the new saved screen bits block into the list
        !           193:             pSSB->pvNextSSB = pdsurf->ssbList;
        !           194:             pdsurf->ssbList = pSSB;
        !           195: 
        !           196:             return((ULONG) pSSB);
        !           197: 
        !           198:         //
        !           199:         // Restore a saved screen bits block to the screen, then free it.
        !           200:         //
        !           201: 
        !           202:         case SS_RESTORE:
        !           203: //            ASSERT(prcl != (RECTL *) NULL,"DrvSaveScreenBits invalid prcl");
        !           204: 
        !           205:             // Point to the first block in the saved screen bits list
        !           206:             pSSB = pdsurf->ssbList;
        !           207: 
        !           208:             // Try to find the specified saved screen bits block
        !           209:             bIdentFound = FALSE;
        !           210:             while ((pSSB != (PSAVED_SCREEN_BITS) NULL) && !bIdentFound)
        !           211:             {
        !           212:                 if (pSSB == (PSAVED_SCREEN_BITS) iIdent)
        !           213:                 {
        !           214:                     // It's a match; restore this block
        !           215: 
        !           216:                     // Handle copies from offscreen memory and system memory
        !           217:                     // separately
        !           218: #if OFFSCREEN_SUPPORTED
        !           219:                     if (pSSB->bFlags & SSB_IN_ADAPTER_MEMORY)
        !           220:                     {
        !           221:                         vRestoreScreenBitsFromOffscreen(pdsurf,
        !           222:                                                         prcl,
        !           223:                                                         pSSB->pjBuffer);
        !           224:                     }
        !           225:                     else
        !           226:                     {
        !           227: #endif
        !           228:                         vRestoreScreenBitsFromMemory(pdsurf,
        !           229:                                                      prcl,
        !           230:                                                      pSSB->pjBuffer,
        !           231:                                                      pSSB->ulSaveWidthInBytes,
        !           232:                                                      pSSB->ulDelta);
        !           233: #if OFFSCREEN_SUPPORTED
        !           234:                     }
        !           235: #endif
        !           236: 
        !           237:                     bIdentFound = TRUE;
        !           238:                 }
        !           239:                 else
        !           240:                 {
        !           241:                     // Not a match, so check another block, if there is one.
        !           242:                     // Point to the next saved screen bits block
        !           243:                     pSSB = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
        !           244:                 }
        !           245:             }
        !           246: 
        !           247:             // See if we succeeded in finding a block to restore
        !           248:             if (!bIdentFound)
        !           249:             {
        !           250:                 // It was a bad identifier, so we'll return failure
        !           251: 
        !           252:                 DISPDBG((0, "DrvSaveScreenBits SS_RESTORE invalid iIdent"));
        !           253:                 return(FALSE);
        !           254:             }
        !           255: 
        !           256:             // Always free the saved screen bits block after restoring it
        !           257: 
        !           258:         //
        !           259:         // Free up the saved screen bits block.
        !           260:         //
        !           261: 
        !           262:         case SS_FREE:
        !           263: 
        !           264:             // Point to the first block in the saved screen bits list
        !           265:             pSSB = pdsurf->ssbList;
        !           266: 
        !           267:             // Point to the pointer to the first block, so we can unlink the
        !           268:             // first block if it's the one we're freeing
        !           269:             pLastSSBPtr = &pdsurf->ssbList;
        !           270: 
        !           271:             // Try to find the specified saved screen bits block
        !           272:             while (pSSB != (PSAVED_SCREEN_BITS) NULL)
        !           273:             {
        !           274:                 if (pSSB == (PSAVED_SCREEN_BITS) iIdent)
        !           275:                 {
        !           276:                     // It's a match; free up this block
        !           277: 
        !           278:                     // Unlink the block from the list
        !           279:                     *pLastSSBPtr = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
        !           280: 
        !           281:                     // If the block is in offscreen memory, adjust the display
        !           282:                     // memory heap to free up the offscreen memory allocated to
        !           283:                     // the block
        !           284:                     if (pSSB->bFlags & SSB_IN_ADAPTER_MEMORY)
        !           285:                     {
        !           286:                         if (pSSB->pjBuffer != pdsurf->pjAdapterHeapTop)
        !           287:                         {
        !           288:                             // The block is not on top of the heap, so compact
        !           289:                             // the heap to move the newly freed space to the
        !           290:                             // top of the display memory heap
        !           291: 
        !           292:                             // First, adjust the pointers to all the blocks
        !           293:                             // that are above the freed one in the display
        !           294:                             // memory heap
        !           295:                             pSSBTemp = pdsurf->ssbList;
        !           296:                             while (pSSBTemp != NULL)
        !           297:                             {
        !           298:                                 if (pSSBTemp->pjBuffer < pSSB->pjBuffer)
        !           299:                                 {
        !           300:                                     // This block is above the one we're
        !           301:                                     // freeing in the display memory heap, so
        !           302:                                     // shift its pointer down (the actual
        !           303:                                     // movement of the bytes happens below)
        !           304:                                     pSSBTemp->pjBuffer += pSSB->ulSize;
        !           305:                                 }
        !           306:                                 pSSBTemp = (PSAVED_SCREEN_BITS)
        !           307:                                            pSSBTemp->pvNextSSB;
        !           308:                             }
        !           309:                             // Now actually shift all the higher blocks to
        !           310:                             // squeeze out the block we just freed
        !           311: 
        !           312:                             memcpy(pdsurf->pjAdapterHeapTop + pSSB->ulSize,
        !           313:                                    pdsurf->pjAdapterHeapTop,
        !           314:                                    pSSB->pjBuffer - pdsurf->pjAdapterHeapTop);
        !           315:                         }
        !           316: 
        !           317:                         // Adjust the top of the used display memory heap to
        !           318:                         // account for the block we just freed
        !           319:                         pdsurf->pjAdapterHeapTop += pSSB->ulSize;
        !           320:                     }
        !           321:                     else if (pSSB->bFlags & SSB_IN_PREALLOC_BUFFER)
        !           322:                     {
        !           323:                         // If the block's save area is in the preallocated
        !           324:                         // buffer, mark that the buffer is no longer in use
        !           325:                         // and is free for reuse
        !           326:                         ppdev->flPreallocSSBBufferInUse = FALSE;
        !           327: 
        !           328:                         // We're done; there's nothing to free up
        !           329:                         return(TRUE);
        !           330:                     }
        !           331: 
        !           332:                     // Deallocate the block's memory
        !           333:                     LocalFree(pSSB);
        !           334: 
        !           335:                     // We've successfully freed the block
        !           336:                     return(TRUE);
        !           337:                 }
        !           338: 
        !           339:                 // Not a match, so check another block, if there is one
        !           340:                 // Remember the block that points to the block we're advancing
        !           341:                 // to, for unlinking later
        !           342:                 pLastSSBPtr = (PSAVED_SCREEN_BITS *) &pSSB->pvNextSSB;
        !           343: 
        !           344:                 // Point to the next saved screen bits block
        !           345:                 pSSB = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
        !           346:             }
        !           347: 
        !           348:             // It was a bad identifier, so we'll do nothing. We won't return
        !           349:             // FALSE because SS_FREE always returns TRUE
        !           350: 
        !           351:             DISPDBG((0, "DrvSaveScreenBits SS_FREE invalid iIdent"));
        !           352: 
        !           353:             return(TRUE);
        !           354: 
        !           355:         //
        !           356:         // An unknown mode was passed in.
        !           357:         //
        !           358: 
        !           359:         default:
        !           360: 
        !           361:             DISPDBG((0, "DrvSaveScreenBits invalid iMode"));
        !           362: 
        !           363:             return(FALSE);
        !           364:             break;
        !           365:     }
        !           366: }
        !           367: 

unix.superglobalmegacorp.com

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