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

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: enable.c
        !             3: *
        !             4: * This module contains the functions that enable and disable the
        !             5: * driver, the pdev, and the surface.
        !             6: *
        !             7: * Copyright (c) 1992 Microsoft Corporation
        !             8: \**************************************************************************/
        !             9: 
        !            10: #include "driver.h"
        !            11: 
        !            12: #define GDI_MODE            1
        !            13: #define FULL_SCREEN_MODE    2
        !            14: 
        !            15: ULONG   gLastState = GDI_MODE;
        !            16: 
        !            17: #if DBG
        !            18: 
        !            19: ULONG   gCount = 1;
        !            20: 
        !            21: DHPDEV WDrvEnablePDEV(
        !            22:     DEVMODEW   *pDevmode,       // Pointer to DEVMODE
        !            23:     PWSTR       pwszLogAddress, // Logical address
        !            24:     ULONG       cPatterns,      // number of patterns
        !            25:     HSURF      *ahsurfPatterns, // return standard patterns
        !            26:     ULONG       cjGdiInfo,      // Length of memory pointed to by pGdiInfo
        !            27:     ULONG      *pGdiInfo,       // Pointer to GdiInfo structure
        !            28:     ULONG       cjDevInfo,      // Length of following PDEVINFO structure
        !            29:     DEVINFO    *pDevInfo,       // physical device information structure
        !            30:     PWSTR       pwszDataFile,   // DataFile - not used
        !            31:     PWSTR       pwszDeviceName, // DeviceName - not used
        !            32:     HANDLE      hDriver)        // Handle to base driver
        !            33: {
        !            34:     DHPDEV bRet;
        !            35: 
        !            36:     LOGDBG((1, "DrvEnablePDEV\n"));
        !            37: 
        !            38:     if (InterlockedDecrement(&gCount) != 0)
        !            39:         RIP("Somebody else is in here\n");
        !            40: 
        !            41:     bRet = DrvEnablePDEV(
        !            42:                 pDevmode,
        !            43:                 pwszLogAddress,
        !            44:                 cPatterns,
        !            45:                 ahsurfPatterns,
        !            46:                 cjGdiInfo,
        !            47:                 pGdiInfo,
        !            48:                 cjDevInfo,
        !            49:                 pDevInfo,
        !            50:                 pwszDataFile,
        !            51:                 pwszDeviceName,
        !            52:                 hDriver);
        !            53: 
        !            54:     if (InterlockedIncrement(&gCount) <= 0)
        !            55:         RIP("Can't leave\n");
        !            56: 
        !            57:     LOGDBG((5, "DrvEnablePDEV done\n"));
        !            58: 
        !            59:     return(bRet);
        !            60: }
        !            61: 
        !            62: VOID WDrvCompletePDEV(
        !            63:     DHPDEV dhpdev,
        !            64:     HDEV  hdev)
        !            65: {
        !            66:     LOGDBG((1, "DrvCompletePDEV\n"));
        !            67: 
        !            68:     if (InterlockedDecrement(&gCount) != 0)
        !            69:         RIP("Somebody else is in here\n");
        !            70: 
        !            71:     DrvCompletePDEV(
        !            72:                 dhpdev,
        !            73:                 hdev);
        !            74: 
        !            75:     if (InterlockedIncrement(&gCount) <= 0)
        !            76:         RIP("Can't leave\n");
        !            77: 
        !            78:     LOGDBG((5, "DrvCompletePDEV done\n"));
        !            79: }
        !            80: 
        !            81: VOID WDrvDisablePDEV(DHPDEV dhpdev)
        !            82: {
        !            83:     LOGDBG((1, "DrvDisable\n"));
        !            84: 
        !            85:     DrvDisablePDEV(dhpdev);
        !            86: 
        !            87:     LOGDBG((5, "DrvDisable done\n"));
        !            88: }
        !            89: 
        !            90: HSURF WDrvEnableSurface(DHPDEV dhpdev)
        !            91: {
        !            92:     HSURF h;
        !            93: 
        !            94:     LOGDBG((1, "DrvEnableSurface\n"));
        !            95: 
        !            96:     if (InterlockedDecrement(&gCount) != 0)
        !            97:         RIP("Somebody else is in here\n");
        !            98: 
        !            99:     h = DrvEnableSurface(dhpdev);
        !           100: 
        !           101:     if (InterlockedIncrement(&gCount) <= 0)
        !           102:         RIP("Can't leave\n");
        !           103: 
        !           104:     LOGDBG((5, "DrvEnableSurface done\n"));
        !           105: 
        !           106:     return(h);
        !           107: }
        !           108: 
        !           109: VOID WDrvDisableSurface(DHPDEV dhpdev)
        !           110: {
        !           111:     LOGDBG((1, "DrvDisableSurface\n"));
        !           112: 
        !           113:     DrvDisableSurface(dhpdev);
        !           114: 
        !           115:     LOGDBG((5, "DrvDisableSurface done\n"));
        !           116: }
        !           117: 
        !           118: 
        !           119: VOID  WDrvAssertMode(
        !           120: DHPDEV dhpdev,
        !           121: BOOL   bEnable)
        !           122: {
        !           123:     LOGDBG((1, "DrvAssertMode\n"));
        !           124: 
        !           125:     if (bEnable)
        !           126:     {
        !           127:         // When the driver is active we'll always expect gCount to be
        !           128:         // one at the beginning of any driver call:
        !           129: 
        !           130:         if (InterlockedIncrement(&gCount) <= 0)
        !           131:             RIP("Somebody else is in here\n");
        !           132:     }
        !           133:     else
        !           134:     {
        !           135:         if (InterlockedDecrement(&gCount) != 0)
        !           136:             RIP("Somebody else is in here\n");
        !           137:     }
        !           138: 
        !           139:     DrvAssertMode(dhpdev,bEnable);
        !           140: 
        !           141:     LOGDBG((5, "DrvAssertMode done\n"));
        !           142: }
        !           143: 
        !           144: 
        !           145: VOID WDrvMovePointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl)
        !           146: {
        !           147:     LOGDBG((1, "DrvMovePointer\n"));
        !           148: 
        !           149:     if (InterlockedDecrement(&gCount) != 0)
        !           150:         RIP("Somebody else is in here\n");
        !           151: 
        !           152:     DrvMovePointer(pso,x,y,prcl);
        !           153: 
        !           154:     if (InterlockedIncrement(&gCount) <= 0)
        !           155:         RIP("Can't leave\n");
        !           156: 
        !           157:     LOGDBG((5, "DrvMovePointer done\n"));
        !           158: }
        !           159: 
        !           160: ULONG WDrvSetPointerShape(
        !           161: SURFOBJ  *pso,
        !           162: SURFOBJ  *psoMask,
        !           163: SURFOBJ  *psoColor,
        !           164: XLATEOBJ *pxlo,
        !           165: LONG      xHot,
        !           166: LONG      yHot,
        !           167: LONG      x,
        !           168: LONG      y,
        !           169: RECTL    *prcl,
        !           170: FLONG     fl)
        !           171: {
        !           172:     ULONG u;
        !           173: 
        !           174:     LOGDBG((1, "DrvSetPointerShape\n"));
        !           175: 
        !           176:     if (InterlockedDecrement(&gCount) != 0)
        !           177:         RIP("Somebody else is in here\n");
        !           178: 
        !           179:     u = DrvSetPointerShape(
        !           180:                 pso,
        !           181:                 psoMask,
        !           182:                 psoColor,
        !           183:                 pxlo,
        !           184:                 xHot,
        !           185:                 yHot,
        !           186:                 x,
        !           187:                 y,
        !           188:                 prcl,
        !           189:                 fl);
        !           190: 
        !           191:     if (InterlockedIncrement(&gCount) <= 0)
        !           192:         RIP("Can't leave\n");
        !           193: 
        !           194:     LOGDBG((5, "DrvSetPointerShape done\n"));
        !           195: 
        !           196:     return(u);
        !           197: }
        !           198: 
        !           199: ULONG WDrvDitherColor(
        !           200: DHPDEV dhpdev,
        !           201: ULONG  iMode,
        !           202: ULONG  rgb,
        !           203: ULONG *pul)
        !           204: {
        !           205:     ULONG u;
        !           206: 
        !           207:     LOGDBG((1, "DrvDitherColor\n"));
        !           208: 
        !           209:     u = DrvDitherColor(
        !           210:                 dhpdev,
        !           211:                 iMode,
        !           212:                 rgb,
        !           213:                 pul);
        !           214: 
        !           215:     LOGDBG((5, "DrvDitherColor done\n"));
        !           216: 
        !           217:     return(u);
        !           218: }
        !           219: 
        !           220: 
        !           221: BOOL WDrvSetPalette(
        !           222: DHPDEV  dhpdev,
        !           223: PALOBJ *ppalo,
        !           224: FLONG   fl,
        !           225: ULONG   iStart,
        !           226: ULONG   cColors)
        !           227: {
        !           228:     BOOL u;
        !           229: 
        !           230:     LOGDBG((1, "DrvSetPalette\n"));
        !           231: 
        !           232:     if (InterlockedDecrement(&gCount) != 0)
        !           233:         RIP("Somebody else is in here\n");
        !           234: 
        !           235:     u = DrvSetPalette(
        !           236:                 dhpdev,
        !           237:                 ppalo,
        !           238:                 fl,
        !           239:                 iStart,
        !           240:                 cColors);
        !           241: 
        !           242: 
        !           243:     if (InterlockedIncrement(&gCount) <= 0)
        !           244:         RIP("Can't leave\n");
        !           245: 
        !           246:     LOGDBG((5, "DrvSetPalette done\n"));
        !           247: 
        !           248:     return(u);
        !           249: }
        !           250: 
        !           251: BOOL WDrvCopyBits(
        !           252: SURFOBJ  *psoDest,
        !           253: SURFOBJ  *psoSrc,
        !           254: CLIPOBJ  *pco,
        !           255: XLATEOBJ *pxlo,
        !           256: RECTL    *prclDest,
        !           257: POINTL   *pptlSrc)
        !           258: {
        !           259:     BOOL u;
        !           260: 
        !           261:     LOGDBG((1, "DrvCopyBits\n"));
        !           262: 
        !           263:     if (InterlockedDecrement(&gCount) != 0)
        !           264:         RIP("Somebody else is in here\n");
        !           265: 
        !           266:     u = DrvCopyBits(
        !           267:                 psoDest,
        !           268:                 psoSrc,
        !           269:                 pco,
        !           270:                 pxlo,
        !           271:                 prclDest,
        !           272:                 pptlSrc);
        !           273: 
        !           274:     if (InterlockedIncrement(&gCount) <= 0)
        !           275:         RIP("Can't leave\n");
        !           276: 
        !           277:     LOGDBG((5, "DrvCopyBits done\n"));
        !           278: 
        !           279:     return(u);
        !           280: }
        !           281: 
        !           282: 
        !           283: BOOL WDrvBitBlt(
        !           284: SURFOBJ  *psoTrg,
        !           285: SURFOBJ  *psoSrc,
        !           286: SURFOBJ  *psoMask,
        !           287: CLIPOBJ  *pco,
        !           288: XLATEOBJ *pxlo,
        !           289: RECTL    *prclTrg,
        !           290: POINTL   *pptlSrc,
        !           291: POINTL   *pptlMask,
        !           292: BRUSHOBJ *pbo,
        !           293: POINTL   *pptlBrush,
        !           294: ROP4      rop4)
        !           295: {
        !           296:     BOOL u;
        !           297: 
        !           298:     LOGDBG((1, "DrvBitBlt\n"));
        !           299: 
        !           300:     if (InterlockedDecrement(&gCount) != 0)
        !           301:         RIP("Somebody else is in here\n");
        !           302: 
        !           303:     u = DrvBitBlt(
        !           304:                 psoTrg,
        !           305:                 psoSrc,
        !           306:                 psoMask,
        !           307:                 pco,
        !           308:                 pxlo,
        !           309:                 prclTrg,
        !           310:                 pptlSrc,
        !           311:                 pptlMask,
        !           312:                 pbo,
        !           313:                 pptlBrush,
        !           314:                 rop4);
        !           315: 
        !           316:     if (InterlockedIncrement(&gCount) <= 0)
        !           317:         RIP("Can't leave\n");
        !           318: 
        !           319:     LOGDBG((5, "DrvBitBlt done\n"));
        !           320: 
        !           321:     return(u);
        !           322: }
        !           323: 
        !           324: BOOL WDrvTextOut(
        !           325: SURFOBJ  *pso,
        !           326: STROBJ   *pstro,
        !           327: FONTOBJ  *pfo,
        !           328: CLIPOBJ  *pco,
        !           329: RECTL    *prclExtra,
        !           330: RECTL    *prclOpaque,
        !           331: BRUSHOBJ *pboFore,
        !           332: BRUSHOBJ *pboOpaque,
        !           333: POINTL   *pptlOrg,
        !           334: MIX       mix)
        !           335: {
        !           336:     BOOL u;
        !           337: 
        !           338:     LOGDBG((1, "DrvTextOut\n"));
        !           339: 
        !           340:     if (InterlockedDecrement(&gCount) != 0)
        !           341:         RIP("Somebody else is in here\n");
        !           342: 
        !           343:     u = DrvTextOut(
        !           344:                 pso,
        !           345:                 pstro,
        !           346:                 pfo,
        !           347:                 pco,
        !           348:                 prclExtra,
        !           349:                 prclOpaque,
        !           350:                 pboFore,
        !           351:                 pboOpaque,
        !           352:                 pptlOrg,
        !           353:                 mix);
        !           354: 
        !           355:     if (InterlockedIncrement(&gCount) <= 0)
        !           356:         RIP("Can't leave\n");
        !           357: 
        !           358:     LOGDBG((5, "DrvTextOut done\n"));
        !           359: 
        !           360:     return(u);
        !           361: }
        !           362: 
        !           363: ULONG WDrvGetModes(
        !           364: HANDLE    hDriver,
        !           365: ULONG     cjSize,
        !           366: DEVMODEW *pdm)
        !           367: {
        !           368:     ULONG u;
        !           369: 
        !           370:     LOGDBG((1, "DrvGetModes\n"));
        !           371: 
        !           372:     if (InterlockedDecrement(&gCount) != 0)
        !           373:         RIP("Somebody else is in here\n");
        !           374: 
        !           375:     u = DrvGetModes(
        !           376:                 hDriver,
        !           377:                 cjSize,
        !           378:                 pdm);
        !           379: 
        !           380:     if (InterlockedIncrement(&gCount) <= 0)
        !           381:         RIP("Can't leave\n");
        !           382: 
        !           383:     LOGDBG((5, "DrvGetModes done\n"));
        !           384: 
        !           385:     return(u);
        !           386: }
        !           387: 
        !           388: BOOL WDrvStrokePath(
        !           389: SURFOBJ   *pso,
        !           390: PATHOBJ   *ppo,
        !           391: CLIPOBJ   *pco,
        !           392: XFORMOBJ  *pxo,
        !           393: BRUSHOBJ  *pbo,
        !           394: POINTL    *pptlBrushOrg,
        !           395: LINEATTRS *plineattrs,
        !           396: MIX        mix)
        !           397: {
        !           398:     BOOL u;
        !           399: 
        !           400:     LOGDBG((1, "DrvStrokePath\n"));
        !           401: 
        !           402:     if (InterlockedDecrement(&gCount) != 0)
        !           403:         RIP("Somebody else is in here\n");
        !           404: 
        !           405:     u = DrvStrokePath(
        !           406:                 pso,
        !           407:                 ppo,
        !           408:                 pco,
        !           409:                 pxo,
        !           410:                 pbo,
        !           411:                 pptlBrushOrg,
        !           412:                 plineattrs,
        !           413:                 mix);
        !           414: 
        !           415:     if (InterlockedIncrement(&gCount) <= 0)
        !           416:         RIP("Can't leave\n");
        !           417: 
        !           418:     LOGDBG((5, "DrvStrokePath done\n"));
        !           419: 
        !           420:     return(u);
        !           421: }
        !           422: 
        !           423: 
        !           424: BOOL WDrvFillPath(
        !           425: SURFOBJ  *pso,
        !           426: PATHOBJ  *ppo,
        !           427: CLIPOBJ  *pco,
        !           428: BRUSHOBJ *pbo,
        !           429: POINTL   *pptlBrushOrg,
        !           430: MIX       mix,
        !           431: FLONG     flOptions)
        !           432: {
        !           433:     BOOL u;
        !           434: 
        !           435:     LOGDBG((1, "DrvFillPath\n"));
        !           436: 
        !           437:     if (InterlockedDecrement(&gCount) != 0)
        !           438:         RIP("Somebody else is in here\n");
        !           439: 
        !           440:     u = DrvFillPath(pso,
        !           441:                 ppo,
        !           442:                 pco,
        !           443:                 pbo,
        !           444:                 pptlBrushOrg,
        !           445:                 mix,
        !           446:                 flOptions);
        !           447: 
        !           448:     if (InterlockedIncrement(&gCount) <= 0)
        !           449:         RIP("Can't leave\n");
        !           450: 
        !           451:     LOGDBG((5, "DrvFillPath done\n"));
        !           452: 
        !           453:     return(u);
        !           454: }
        !           455: 
        !           456: BOOL WDrvPaint(
        !           457: SURFOBJ  *pso,
        !           458: CLIPOBJ  *pco,
        !           459: BRUSHOBJ *pbo,
        !           460: POINTL   *pptlBrushOrg,
        !           461: MIX       mix)
        !           462: {
        !           463:     BOOL u;
        !           464: 
        !           465:     LOGDBG((1, "DrvPaint\n"));
        !           466: 
        !           467:     if (InterlockedDecrement(&gCount) != 0)
        !           468:         RIP("Somebody else is in here\n");
        !           469: 
        !           470:     u = DrvPaint(
        !           471:                 pso,
        !           472:                 pco,
        !           473:                 pbo,
        !           474:                 pptlBrushOrg,
        !           475:                 mix);
        !           476: 
        !           477:     if (InterlockedIncrement(&gCount) <= 0)
        !           478:         RIP("Can't leave\n");
        !           479: 
        !           480:     LOGDBG((5, "DrvPaint done\n"));
        !           481: 
        !           482:     return(u);
        !           483: }
        !           484: 
        !           485: BOOL WDrvRealizeBrush(
        !           486: BRUSHOBJ *pbo,
        !           487: SURFOBJ  *psoTarget,
        !           488: SURFOBJ  *psoPattern,
        !           489: SURFOBJ  *psoMask,
        !           490: XLATEOBJ *pxlo,
        !           491: ULONG    iHatch)
        !           492: {
        !           493:     BOOL u;
        !           494: 
        !           495:     LOGDBG((1, "DrvRealizeBrush\n"));
        !           496: 
        !           497:     if (gCount != 0)
        !           498:         RIP("DrvRealizeBrush Somebody else is in here\n");
        !           499: 
        !           500:     u = DrvRealizeBrush(
        !           501:                 pbo,
        !           502:                 psoTarget,
        !           503:                 psoPattern,
        !           504:                 psoMask,
        !           505:                 pxlo,
        !           506:                 iHatch);
        !           507: 
        !           508:     LOGDBG((5, "DrvRealizeBrush done\n"));
        !           509: 
        !           510:     return(u);
        !           511: }
        !           512: 
        !           513: ULONG WDrvSaveScreenBits(SURFOBJ *pso,ULONG iMode,ULONG ident,RECTL *prcl)
        !           514: {
        !           515:     ULONG u;
        !           516: 
        !           517:     LOGDBG((1, "DrvSaveScreenBits\n"));
        !           518: 
        !           519:     if (InterlockedDecrement(&gCount) != 0)
        !           520:         RIP("Somebody else is in here\n");
        !           521: 
        !           522:     u = DrvSaveScreenBits(pso,iMode,ident,prcl);
        !           523: 
        !           524:     if (InterlockedIncrement(&gCount) <= 0)
        !           525:         RIP("Can't leave\n");
        !           526: 
        !           527:     LOGDBG((5, "DrvSaveScreenBits done\n"));
        !           528: 
        !           529:     return(u);
        !           530: }
        !           531: 
        !           532: VOID WDrvDestroyFont(FONTOBJ *pfo)
        !           533: {
        !           534:     LOGDBG((1, "DrvDestroyFont\n"));
        !           535: 
        !           536: // !!!    if (InterlockedDecrement(&gCount) != 0)
        !           537: // !!!        RIP("Somebody else is in here\n");
        !           538: 
        !           539:     DrvDestroyFont(pfo);
        !           540: 
        !           541: // !!!    if (InterlockedIncrement(&gCount) <= 0)
        !           542: // !!!        RIP("Can't leave\n");
        !           543: 
        !           544:     LOGDBG((5, "DrvDestroyFont done\n"));
        !           545: }
        !           546: 
        !           547: //
        !           548: // On a checked build, we thunk all driver calls for debugging purposes:
        !           549: //
        !           550: 
        !           551: DRVFN gadrvfn[] = {
        !           552:     {   INDEX_DrvEnablePDEV,            (PFN) WDrvEnablePDEV         },
        !           553:     {   INDEX_DrvCompletePDEV,          (PFN) WDrvCompletePDEV       },
        !           554:     {   INDEX_DrvDisablePDEV,           (PFN) WDrvDisablePDEV        },
        !           555:     {   INDEX_DrvEnableSurface,         (PFN) WDrvEnableSurface      },
        !           556:     {   INDEX_DrvDisableSurface,        (PFN) WDrvDisableSurface     },
        !           557:     {   INDEX_DrvAssertMode,            (PFN) WDrvAssertMode         },
        !           558:     {   INDEX_DrvMovePointer,           (PFN) WDrvMovePointer        },
        !           559:     {   INDEX_DrvSetPointerShape,       (PFN) WDrvSetPointerShape    },
        !           560:     {   INDEX_DrvDitherColor,           (PFN) WDrvDitherColor        },
        !           561:     {   INDEX_DrvSetPalette,            (PFN) WDrvSetPalette         },
        !           562:     {   INDEX_DrvCopyBits,              (PFN) WDrvCopyBits           },
        !           563:     {   INDEX_DrvBitBlt,                (PFN) WDrvBitBlt             },
        !           564:     {   INDEX_DrvTextOut,               (PFN) WDrvTextOut            },
        !           565:     {   INDEX_DrvGetModes,              (PFN) WDrvGetModes           },
        !           566:     {   INDEX_DrvStrokePath,            (PFN) WDrvStrokePath         },
        !           567:     {   INDEX_DrvFillPath,              (PFN) WDrvFillPath           },
        !           568:     {   INDEX_DrvPaint,                 (PFN) WDrvPaint              },
        !           569:     {   INDEX_DrvRealizeBrush,          (PFN) WDrvRealizeBrush       },
        !           570:     {   INDEX_DrvSaveScreenBits,        (PFN) WDrvSaveScreenBits     },
        !           571:     {   INDEX_DrvDestroyFont,           (PFN) WDrvDestroyFont        }
        !           572: };
        !           573: 
        !           574: #else
        !           575: 
        !           576: //
        !           577: // Build the driver function table gadrvfn with function index/address pairs
        !           578: //
        !           579: 
        !           580: DRVFN gadrvfn[] = {
        !           581:     {   INDEX_DrvEnablePDEV,            (PFN) DrvEnablePDEV         },
        !           582:     {   INDEX_DrvCompletePDEV,          (PFN) DrvCompletePDEV       },
        !           583:     {   INDEX_DrvDisablePDEV,           (PFN) DrvDisablePDEV        },
        !           584:     {   INDEX_DrvEnableSurface,         (PFN) DrvEnableSurface      },
        !           585:     {   INDEX_DrvDisableSurface,        (PFN) DrvDisableSurface     },
        !           586:     {   INDEX_DrvAssertMode,            (PFN) DrvAssertMode         },
        !           587:     {   INDEX_DrvMovePointer,           (PFN) DrvMovePointer        },
        !           588:     {   INDEX_DrvSetPointerShape,       (PFN) DrvSetPointerShape    },
        !           589:     {   INDEX_DrvDitherColor,           (PFN) DrvDitherColor        },
        !           590:     {   INDEX_DrvSetPalette,            (PFN) DrvSetPalette         },
        !           591:     {   INDEX_DrvCopyBits,              (PFN) DrvCopyBits           },
        !           592:     {   INDEX_DrvBitBlt,                (PFN) DrvBitBlt             },
        !           593:     {   INDEX_DrvTextOut,               (PFN) DrvTextOut            },
        !           594:     {   INDEX_DrvGetModes,              (PFN) DrvGetModes           },
        !           595:     {   INDEX_DrvStrokePath,            (PFN) DrvStrokePath         },
        !           596:     {   INDEX_DrvFillPath,              (PFN) DrvFillPath           },
        !           597:     {   INDEX_DrvPaint,                 (PFN) DrvPaint              },
        !           598:     {   INDEX_DrvRealizeBrush,          (PFN) DrvRealizeBrush       },
        !           599:     {   INDEX_DrvSaveScreenBits,        (PFN) DrvSaveScreenBits     },
        !           600:     {   INDEX_DrvDestroyFont,           (PFN) DrvDestroyFont        }
        !           601: };
        !           602: #endif
        !           603: 
        !           604: /******************************Public*Routine******************************\
        !           605: * DrvEnableDriver
        !           606: *
        !           607: * Enables the driver by retrieving the drivers function table and version.
        !           608: *
        !           609: \**************************************************************************/
        !           610: 
        !           611: BOOL DrvEnableDriver(
        !           612: ULONG iEngineVersion,
        !           613: ULONG cj,
        !           614: PDRVENABLEDATA pded)
        !           615: {
        !           616:     UNREFERENCED_PARAMETER(iEngineVersion);
        !           617: 
        !           618:     DISPDBG((2, "*** S3.DLL!DrvEnableDriver - Entry ***\n"));
        !           619: 
        !           620: // Engine Version is passed down so future drivers can support previous
        !           621: // engine versions.  A next generation driver can support both the old
        !           622: // and new engine conventions if told what version of engine it is
        !           623: // working with.  For the first version the driver does nothing with it.
        !           624: 
        !           625:     DISPDBG((2, "S3.DLL!DrvEnableDriver - iEngineVersion: %ld\n", iEngineVersion));
        !           626: 
        !           627: // Fill in as much as we can.
        !           628: 
        !           629:     if (cj >= sizeof(DRVENABLEDATA))
        !           630:         pded->pdrvfn = gadrvfn;
        !           631: 
        !           632:     if (cj >= (sizeof(ULONG) * 2))
        !           633:         pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
        !           634: 
        !           635: // DDI version this driver was targeted for is passed back to engine.
        !           636: // Future graphic's engine may break calls down to old driver format.
        !           637: 
        !           638:     if (cj >= sizeof(ULONG))
        !           639:         pded->iDriverVersion = DDI_DRIVER_VERSION;
        !           640: 
        !           641:     return(TRUE);
        !           642: }
        !           643: 
        !           644: /******************************Public*Routine******************************\
        !           645: * DrvDisableDriver
        !           646: *
        !           647: * Tells the driver it is being disabled. Release any resources allocated in
        !           648: * DrvEnableDriver.
        !           649: *
        !           650: \**************************************************************************/
        !           651: 
        !           652: VOID DrvDisableDriver(VOID)
        !           653: {
        !           654:     return;
        !           655: }
        !           656: 
        !           657: /******************************Public*Routine******************************\
        !           658: * DrvEnablePDEV
        !           659: *
        !           660: * DDI function, Enables the Physical Device.
        !           661: *
        !           662: * Return Value: device handle to pdev.
        !           663: *
        !           664: \**************************************************************************/
        !           665: 
        !           666: DHPDEV DrvEnablePDEV(
        !           667:     DEVMODEW   *pDevmode,       // Pointer to DEVMODE
        !           668:     PWSTR       pwszLogAddress, // Logical address
        !           669:     ULONG       cPatterns,      // number of patterns
        !           670:     HSURF      *ahsurfPatterns, // return standard patterns
        !           671:     ULONG       cjGdiInfo,      // Length of memory pointed to by pGdiInfo
        !           672:     ULONG      *pGdiInfo,       // Pointer to GdiInfo structure
        !           673:     ULONG       cjDevInfo,      // Length of following PDEVINFO structure
        !           674:     DEVINFO    *pDevInfo,       // physical device information structure
        !           675:     PWSTR       pwszDataFile,   // DataFile - not used
        !           676:     PWSTR       pwszDeviceName, // DeviceName - not used
        !           677:     HANDLE      hDriver)        // Handle to base driver
        !           678: {
        !           679:     GDIINFO GdiInfo;
        !           680:     DEVINFO DevInfo;
        !           681:     PPDEV   ppdev = (PPDEV) NULL;
        !           682: 
        !           683:     UNREFERENCED_PARAMETER(pwszLogAddress);
        !           684:     UNREFERENCED_PARAMETER(pwszDataFile);
        !           685:     UNREFERENCED_PARAMETER(pwszDeviceName);
        !           686: 
        !           687:     // Allocate a physical device structure.
        !           688: 
        !           689:     ppdev = (PPDEV) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(PDEV));
        !           690: 
        !           691:     if (ppdev == (PPDEV) NULL)
        !           692:     {
        !           693:         DISPDBG((0, "DISP DrvEnablePDEV failed LocalAlloc\n"));
        !           694:         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        !           695:         goto error0;
        !           696:     }
        !           697: 
        !           698:     // Set up pointers in PDEV to temporary structures we build up to return.
        !           699: 
        !           700:     ppdev->pGdiInfo = &GdiInfo;
        !           701:     ppdev->pDevInfo = &DevInfo;
        !           702: 
        !           703:     // Save the screen handle in the PDEV.
        !           704: 
        !           705:     ppdev->hDriver = hDriver;
        !           706: 
        !           707:     // Get the current screen mode information.  Set up device caps and devinfo.
        !           708: 
        !           709:     if (!bInitPDEV(ppdev, pDevmode))
        !           710:     {
        !           711:         DISPDBG((0, "S3 DrvEnablePDEV failed bGetScreenInfo\n"));
        !           712:         goto error1;
        !           713:     }
        !           714: 
        !           715:     // Initialize palette information.
        !           716: 
        !           717:     if (!bInitPaletteInfo(ppdev))
        !           718:     {
        !           719:         DISPDBG((0, "DISP DrvEnableSurface failed bInitPalette\n"));
        !           720:         goto error1;
        !           721:     }
        !           722: 
        !           723:     // Initialize device standard patterns.
        !           724: 
        !           725:     if (!bInitPatterns(ppdev, min(cPatterns, HS_DDI_MAX)))
        !           726:     {
        !           727:         DISPDBG((0, "DISP DrvEnablePDEV failed bInitPatterns\n"));
        !           728:         goto error2;
        !           729:     }
        !           730: 
        !           731:     // Copy the devinfo into the engine buffer.
        !           732: 
        !           733:     memcpy(pDevInfo, ppdev->pDevInfo, min(sizeof(DEVINFO), cjDevInfo));
        !           734: 
        !           735:     // Set the ahsurfPatterns array to handles each of the standard
        !           736:     // patterns that were just created.
        !           737: 
        !           738:     memcpy((PVOID) ahsurfPatterns, ppdev->ahbmPat, ppdev->cPatterns*sizeof(HBITMAP));
        !           739: 
        !           740:     // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
        !           741:     // pdev.
        !           742: 
        !           743:     memcpy(pGdiInfo, ppdev->pGdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
        !           744: 
        !           745:     // Set NULL into pointers for stack allocated memory.
        !           746: 
        !           747:     ppdev->pGdiInfo = (GDIINFO *) NULL;
        !           748:     ppdev->pDevInfo = (DEVINFO *) NULL;
        !           749: 
        !           750:     return((DHPDEV) ppdev);
        !           751: 
        !           752:     // Error case for failure.
        !           753: 
        !           754: error2:
        !           755:     vDisablePatterns(ppdev);
        !           756:     vDisablePalette(ppdev);
        !           757: 
        !           758: error1:
        !           759:     LocalFree(ppdev);
        !           760: 
        !           761: error0:
        !           762: 
        !           763:     return((DHPDEV) 0);
        !           764: }
        !           765: 
        !           766: /******************************Public*Routine******************************\
        !           767: * DrvCompletePDEV
        !           768: *
        !           769: * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
        !           770: *
        !           771: \**************************************************************************/
        !           772: 
        !           773: VOID DrvCompletePDEV(
        !           774:     DHPDEV dhpdev,
        !           775:     HDEV  hdev)
        !           776: {
        !           777:     ((PPDEV) dhpdev)->hdevEng = hdev;
        !           778: }
        !           779: 
        !           780: /******************************Public*Routine******************************\
        !           781: * DrvDisablePDEV
        !           782: *
        !           783: * Release the resources allocated in DrvEnablePDEV.  If a surface has been
        !           784: * enabled DrvDisableSurface will have already been called.
        !           785: *
        !           786: \**************************************************************************/
        !           787: 
        !           788: VOID DrvDisablePDEV(
        !           789:     DHPDEV dhpdev)
        !           790: {
        !           791:     vDisablePalette((PPDEV) dhpdev);
        !           792:     vDisablePatterns((PPDEV) dhpdev);
        !           793:     LocalFree(dhpdev);
        !           794: }
        !           795: 
        !           796: /******************************Public*Routine******************************\
        !           797: * DrvEnableSurface
        !           798: *
        !           799: * Enable the surface for the device.  Hook the calls this driver supports.
        !           800: *
        !           801: * Return: Handle to the surface if successful, 0 for failure.
        !           802: *
        !           803: \**************************************************************************/
        !           804: 
        !           805: HSURF DrvEnableSurface(
        !           806:     DHPDEV dhpdev)
        !           807: {
        !           808:     PPDEV ppdev;
        !           809:     HSURF hsurf,
        !           810:           hsurfBm;
        !           811:     SIZEL sizl;
        !           812:     ULONG ulBitmapType;
        !           813:     FLONG flHooks;
        !           814:     BOOL  bRet;
        !           815: 
        !           816:     // Create engine bitmap around frame buffer.
        !           817: 
        !           818:     ppdev = (PPDEV) dhpdev;
        !           819: 
        !           820:     if (!bInitSURF(ppdev, TRUE))
        !           821:     {
        !           822:         DISPDBG((0, "DISP DrvEnableSurface failed bInitSURF\n"));
        !           823:         return(FALSE);
        !           824:     }
        !           825: 
        !           826:     if (ppdev->ulBitCount == 8)  {
        !           827:         if (!bInit256ColorPalette(ppdev)) {
        !           828:             DISPDBG((0, "DISP DrvEnableSurface failed to init the 8bpp palette\n"));
        !           829:             return(FALSE);
        !           830:         }
        !           831:     }
        !           832: 
        !           833:     sizl.cx = ppdev->cxScreen;
        !           834:     sizl.cy = ppdev->cyScreen;
        !           835: 
        !           836:     // Init the bank manager for the punt system.
        !           837: 
        !           838:     bRet = bBankInit(ppdev, TRUE);
        !           839:     if (bRet == FALSE)
        !           840:     {
        !           841:         return (NULL);
        !           842:     }
        !           843: 
        !           844:     // Set all the hooks and create our bitmaps
        !           845: 
        !           846:     if (ppdev->ulBitCount == 8)
        !           847:     {
        !           848:         ulBitmapType = BMF_8BPP;
        !           849:         flHooks = HOOKS_BMF8BPP;
        !           850:     }
        !           851:     else if (ppdev->ulBitCount == 16)
        !           852:     {
        !           853:         ulBitmapType = BMF_16BPP;
        !           854:         flHooks = HOOKS_BMF16BPP;
        !           855:     }
        !           856:     else
        !           857:     {
        !           858:         DISPDBG((0,"S3.DLL: ppdev->ulBitCount is invalid\n"));
        !           859:     }
        !           860: 
        !           861:     hsurfBm = (HSURF) EngCreateBitmap(sizl,
        !           862:                                       (ULONG) (ppdev->lDeltaScreen),
        !           863:                                       (ULONG) (ulBitmapType),
        !           864:                                       (FLONG) (((ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0)),
        !           865:                                       (PVOID) (ppdev->pjScreen));
        !           866: 
        !           867:     if ((hsurfBm == 0) || (!EngAssociateSurface(hsurfBm, ppdev->hdevEng, 0)))
        !           868:     {
        !           869:         DISPDBG((0, "S3.DLL!DrvEnableSurface - failed EngAssociateSurface bitmap\n"));
        !           870:         EngDeleteSurface(hsurfBm);
        !           871:         return(NULL);
        !           872:     }
        !           873: 
        !           874:     ppdev->hsurfBm = hsurfBm;
        !           875: 
        !           876:     // Note: the engine lock cannot fail, so no error code is checked.
        !           877: 
        !           878:     ppdev->pSurfObj = EngLockSurface(hsurfBm);
        !           879: 
        !           880:     // BUGBUG Check return code.
        !           881: 
        !           882:     sizl.cy = S3BM_HEIGHT;
        !           883: 
        !           884:     hsurf = EngCreateSurface((DHSURF) ppdev, sizl);
        !           885:     if (hsurf == NULL)
        !           886:     {
        !           887:         DISPDBG((0, "S3.DLL!DrvEnableSurface - failed EngCreateSurface bitmap\n"));
        !           888:         EngDeleteSurface(hsurfBm);
        !           889:         return (NULL);
        !           890:     }
        !           891: 
        !           892:     if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
        !           893:     {
        !           894:         DISPDBG((0, "S3.DLL!DrvEnableSurface - failed EngAssociateSurface\n"));
        !           895:         EngDeleteSurface(hsurfBm);
        !           896:         EngDeleteSurface(hsurf);
        !           897:         return(NULL);
        !           898:     }
        !           899: 
        !           900:     ppdev->hsurfEng = hsurf;
        !           901: 
        !           902:     // Create a temporary bitmap for the screen to screen punt blits.
        !           903:     // First, create a surface.
        !           904: 
        !           905:     sizl.cx = ppdev->cxMaxRam;
        !           906: 
        !           907: #if defined(_X86_) || defined(i386)
        !           908: 
        !           909:     ppdev->psoTemp = NULL;
        !           910: 
        !           911: #else
        !           912: 
        !           913:     sizl.cy = ppdev->cyScreen;
        !           914: 
        !           915:     hsurfBm = (HSURF) EngCreateBitmap(sizl,
        !           916:                                       (ULONG) (ppdev->lDeltaScreen),
        !           917:                                       BMF_8BPP,
        !           918:                                       BMF_TOPDOWN,
        !           919:                                       NULL);
        !           920:     if (hsurfBm == NULL)
        !           921:     {
        !           922:         DISPDBG((0, "S3.DLL!DrvEnableSurface - failed EngCreateBitmap\n"));
        !           923:         EngDeleteSurface(hsurfBm);
        !           924:         EngDeleteSurface(hsurf);
        !           925:         return(NULL);
        !           926:     }
        !           927: 
        !           928:     // Get a pointer to the surface object.
        !           929: 
        !           930:     ppdev->psoTemp = EngLockSurface(hsurfBm);
        !           931: 
        !           932: #endif
        !           933: 
        !           934:     // These values are here for the strip drawer, they should be removed.
        !           935: 
        !           936:     ppdev->iFormat   = BMF_PHYSDEVICE;
        !           937:     ppdev->lNextScan = S3BM_WIDTH;
        !           938: 
        !           939:     // Set the shadow clip values.
        !           940: 
        !           941:     ppdev->ClipRight  = 0;
        !           942:     ppdev->ClipLeft   = 0;
        !           943:     ppdev->ClipTop    = 0;
        !           944:     ppdev->ClipBottom = 0;
        !           945: 
        !           946:     vResetS3Clipping(ppdev);
        !           947: 
        !           948:     return(hsurf);
        !           949: }
        !           950: 
        !           951: /******************************Public*Routine******************************\
        !           952: * DrvDisableSurface
        !           953: *
        !           954: * Free resources allocated by DrvEnableSurface.  Release the surface.
        !           955: *
        !           956: \**************************************************************************/
        !           957: 
        !           958: VOID DrvDisableSurface(
        !           959:     DHPDEV dhpdev)
        !           960: {
        !           961:     //!!! check and return error.  unlock and delete hsurfBM see XGA
        !           962:     EngDeleteSurface(((PPDEV) dhpdev)->hsurfEng);
        !           963:     vDisableSURF((PPDEV) dhpdev);
        !           964:     ((PPDEV) dhpdev)->hsurfEng = (HSURF) 0;
        !           965: }
        !           966: 
        !           967: /******************************Public*Routine******************************\
        !           968: * DrvAssertMode
        !           969: *
        !           970: * This asks the device to reset itself to the mode of the pdev passed in.
        !           971: *
        !           972: \**************************************************************************/
        !           973: 
        !           974: VOID DrvAssertMode(
        !           975:     DHPDEV dhpdev,
        !           976:     BOOL bEnable)
        !           977: {
        !           978:     PPDEV   ppdev = (PPDEV) dhpdev;
        !           979:     ULONG   ulReturn;
        !           980: 
        !           981: #if CATCHIT
        !           982: 
        !           983:     if (gLastState == GDI_MODE)
        !           984:     {
        !           985:         if (bEnable == TRUE)
        !           986:         {
        !           987:             RIP("S3.DLL!DrvAssertMode - Told to go into GDI mode while in GDI mode\n");
        !           988:             return;
        !           989:         }
        !           990:     }
        !           991:     else if (gLastState == FULL_SCREEN_MODE)
        !           992:     {
        !           993:         if (bEnable == FALSE)
        !           994:         {
        !           995:             RIP("S3.DLL!DrvAssertMode - Told to go into Full Screen mode while in Full Screen mode\n");
        !           996:             return;
        !           997:         }
        !           998:     }
        !           999:     else
        !          1000:     {
        !          1001:         RIP("S3.DLL!DrvAssertMode - Undefine mode\n");
        !          1002:         return;
        !          1003:     }
        !          1004: 
        !          1005: #endif
        !          1006: 
        !          1007:     if (bEnable)
        !          1008:     {
        !          1009:         gLastState = GDI_MODE;
        !          1010: 
        !          1011:         // The screen must be reenabled, reinitialize the device to
        !          1012:         // a clean state.
        !          1013: 
        !          1014:         bInitSURF(ppdev, FALSE);
        !          1015:         bBankInit(ppdev, FALSE);
        !          1016: 
        !          1017:         // Restore the off screen data.  This protects the Desktop
        !          1018:         // from an DOS application that might trash the off screen
        !          1019:         // memory.
        !          1020: 
        !          1021:         ppdev->ClipRight = -1;
        !          1022:         ppdev->ClipLeft  = -1;
        !          1023:         ppdev->ClipTop   = -1;
        !          1024:         ppdev->ClipBottom = -1;
        !          1025:         vResetS3Clipping(ppdev);
        !          1026: 
        !          1027:         vRestoreOffScreenMemory(ppdev);
        !          1028:     }
        !          1029:     else
        !          1030:     {
        !          1031:         gLastState = FULL_SCREEN_MODE;
        !          1032: 
        !          1033:         // We must give up the display.
        !          1034: 
        !          1035:         ppdev->ClipRight = -1;
        !          1036:         ppdev->ClipLeft  = -1;
        !          1037:         ppdev->ClipTop   = -1;
        !          1038:         ppdev->ClipBottom = -1;
        !          1039:         vResetS3Clipping(ppdev);
        !          1040:         vSaveOffScreenMemory(ppdev);
        !          1041: 
        !          1042:         // Call the kernel driver to reset the device to a known state.
        !          1043: 
        !          1044:         if (!DeviceIoControl(ppdev->hDriver,
        !          1045:                              IOCTL_VIDEO_RESET_DEVICE,
        !          1046:                              NULL,
        !          1047:                              0,
        !          1048:                              NULL,
        !          1049:                              0,
        !          1050:                              &ulReturn,
        !          1051:                              NULL))
        !          1052:         {
        !          1053:             DISPDBG((0, "S3.DLL!DrvAssertMode - DrvAssertMode failed IOCTL"));
        !          1054:         }
        !          1055: 
        !          1056:     }
        !          1057: 
        !          1058:     return;
        !          1059: }
        !          1060: 
        !          1061: 
        !          1062: /******************************Public*Routine******************************\
        !          1063: * DrvGetModes
        !          1064: *
        !          1065: * Returns the list of available modes for the device.
        !          1066: *
        !          1067: \**************************************************************************/
        !          1068: 
        !          1069: ULONG DrvGetModes(
        !          1070: HANDLE hDriver,
        !          1071: ULONG cjSize,
        !          1072: DEVMODEW *pdm)
        !          1073: 
        !          1074: {
        !          1075: 
        !          1076:     DWORD cModes;
        !          1077:     DWORD cbOutputSize;
        !          1078:     PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
        !          1079:     DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
        !          1080:     DWORD cbModeSize;
        !          1081: 
        !          1082:     DISPDBG((3, "S3.dll:DrvGetModes\n"));
        !          1083: 
        !          1084:     cModes = getAvailableModes(hDriver,
        !          1085:                                (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
        !          1086:                                 &cbModeSize);
        !          1087: 
        !          1088: 
        !          1089:     if (cModes == 0)
        !          1090:     {
        !          1091:         DISPDBG((0, "S3 DISP DrvGetModes failed to get mode information"));
        !          1092:         return 0;
        !          1093:     }
        !          1094: 
        !          1095:     if (pdm == NULL)
        !          1096:     {
        !          1097:         cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
        !          1098:     }
        !          1099:     else
        !          1100:     {
        !          1101:         //
        !          1102:         // Now copy the information for the supported modes back into the output
        !          1103:         // buffer
        !          1104:         //
        !          1105: 
        !          1106:         cbOutputSize = 0;
        !          1107: 
        !          1108:         pVideoTemp = pVideoModeInformation;
        !          1109: 
        !          1110:         do
        !          1111:         {
        !          1112:             if (pVideoTemp->Length != 0)
        !          1113:             {
        !          1114:                 if (cOutputModes == 0)
        !          1115:                 {
        !          1116:                     break;
        !          1117:                 }
        !          1118: 
        !          1119:                 //
        !          1120:                 // Zero the entire structure to start off with.
        !          1121:                 //
        !          1122: 
        !          1123:                 memset(pdm, 0, sizeof(DEVMODEW));
        !          1124: 
        !          1125:                 //
        !          1126:                 // Set the name of the device to the name of the DLL.
        !          1127:                 //
        !          1128: 
        !          1129:                 memcpy(&(pdm->dmDeviceName), L"s3", sizeof(L"s3"));
        !          1130: 
        !          1131:                 pdm->dmSpecVersion = DM_SPECVERSION;
        !          1132:                 pdm->dmDriverVersion = DM_SPECVERSION;
        !          1133: 
        !          1134:                 //
        !          1135:                 // We currently do not support Extra information in the driver
        !          1136:                 //
        !          1137: 
        !          1138:                 pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
        !          1139: 
        !          1140:                 pdm->dmSize = sizeof(DEVMODEW);
        !          1141:                 pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
        !          1142:                                     pVideoTemp->BitsPerPlane;
        !          1143:                 pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
        !          1144:                 pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
        !          1145:                 pdm->dmDisplayFrequency = pVideoTemp->Frequency;
        !          1146: 
        !          1147:                 if (pVideoTemp->AttributeFlags & VIDEO_MODE_INTERLACED)
        !          1148:                 {
        !          1149:                     pdm->dmDisplayFlags |= DM_INTERLACED;
        !          1150:                 }
        !          1151: 
        !          1152:                 //
        !          1153:                 // Go to the next DEVMODE entry in the buffer.
        !          1154:                 //
        !          1155: 
        !          1156:                 cOutputModes--;
        !          1157: 
        !          1158:                 pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) +
        !          1159:                                                    DRIVER_EXTRA_SIZE);
        !          1160: 
        !          1161:                 cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
        !          1162: 
        !          1163:             }
        !          1164: 
        !          1165:             pVideoTemp = (PVIDEO_MODE_INFORMATION)
        !          1166:                 (((PUCHAR)pVideoTemp) + cbModeSize);
        !          1167: 
        !          1168: 
        !          1169:         } while (--cModes);
        !          1170:     }
        !          1171: 
        !          1172:     LocalFree(pVideoModeInformation);
        !          1173: 
        !          1174:     return cbOutputSize;
        !          1175: }

unix.superglobalmegacorp.com

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