Ignore:
Timestamp:
Jan 11, 2004, 12:42:14 PM (22 years ago)
Author:
sandervl
Message:

Update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gdi32/dibsect.cpp

    r10167 r10373  
    1 /* $Id: dibsect.cpp,v 1.67 2003-07-16 10:46:17 sandervl Exp $ */
     1/* $Id: dibsect.cpp,v 1.68 2004-01-11 11:42:10 sandervl Exp $ */
    22
    33/*
     
    66 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
    77 * Copyright 1998 Patrick Haller
     8 * Copyright 2002-2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
    89 *
    910 * Project Odin Software License can be found in LICENSE.TXT
    1011 *
    11  * NOTE:
    12  * This is not a complete solution for CreateDIBSection, but enough for Quake 2!
     12 * Basic GPI object and bitmap data synchronization:
     13 *
     14 * - CreateDIBSection:
     15 *      register a memory range for exception notification
     16 *      set to read/commit during creation
     17 *
     18 * - if(exception)
     19 *      if(invalid)
     20 *         sync and set to commit/read, clear invalid flag
     21 *      if(write violation)
     22 *         make as dirty and set range to read/write
     23 *
     24 * - before GDI operation
     25 *       if(dirty)
     26 *           flush (set bitmap bits), clear dirty flag, set range to readonly
     27 *
     28 * - after GDI operation
     29 *       set invalid flag, set range to invalid
     30 *
     31 * - GdiFlush:
     32 *       NOP
     33 *
     34 * Should probably detect partial changes to avoid having to sync the entire
     35 * DIB section each time something minor changes.
     36 *
     37 * Might get a little bit more complicated when the application gives us a memory
     38 * mapped file handle. (although we can change the protection flags of aliased pages)
    1339 *
    1440 */
     
    2753#include "oslibgpi.h"
    2854#include "rgbcvt.h"
     55#include <memmap.h>
    2956
    3057#define DBG_LOCALLOG  DBG_dibsect
    3158#include "dbglocal.h"
    3259
    33 
    34 //******************************************************************************
    35 //******************************************************************************
    36 DIBSection::DIBSection(BITMAPINFOHEADER_W *pbmi, char *pColors, DWORD iUsage, DWORD hSection, DWORD dwOffset, DWORD handle, int fFlip)
     60static BOOL WIN32API DIBExceptionNotify(LPVOID lpBase, ULONG offset, BOOL fWriteAccess,
     61                                        DWORD dwSize, DWORD dwUserData);
     62
     63
     64//******************************************************************************
     65//******************************************************************************
     66DIBSection::DIBSection(BITMAPINFOHEADER_W *pbmi, char *pColors, DWORD iUsage, DWORD hSection, DWORD dwOffset, HBITMAP hBitmap, int fFlip)
    3767                : bmpBits(NULL), pOS2bmp(NULL), next(NULL), bmpBitsDblBuffer(NULL),
    38                   hdc(0), hwndParent(0)
     68                  hdc(0), hwndParent(0), fDirty(FALSE), fInvalid(FALSE), dwSize(0)
    3969{
    4070 int  palsize=0;
     
    90120   }
    91121   if(!bmpBits) {
    92         DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT);
    93    }
    94    memset(bmpBits, 0, bmpsize*pbmi->biHeight);
     122        APIRET rc = DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_COMMIT);
     123        if(rc) {
     124            dprintf(("DosAllocMem failed with %d", rc));
     125            DebugInt3();
     126        }
     127        if(MMAP_RegisterMemoryRange(DIBExceptionNotify, bmpBits, bmpsize*pbmi->biHeight, hBitmap) == FALSE)
     128        {
     129            dprintf(("MMAP_RegisterMemoryRange failed!!"));
     130            DebugInt3();
     131        }
     132        dwSize = bmpsize*pbmi->biHeight;
     133   }
     134   else memset(bmpBits, 0, bmpsize*pbmi->biHeight);
    95135
    96136   pOS2bmp = (BITMAPINFO2 *)malloc(os2bmphdrsize);
     
    111151   }
    112152   pOS2bmp->cbImage       = pbmi->biSizeImage;
    113    dprintf(("handle                 %x", handle));
     153   dprintf(("hBitmap                %x", hBitmap));
    114154   dprintf(("pOS2bmp->cx            %d\n", pOS2bmp->cx));
    115155   dprintf(("pOS2bmp->cy            %d\n", pOS2bmp->cy));
     
    169209   }
    170210
    171    this->handle = handle;
     211   this->hBitmap = hBitmap;
    172212   this->iUsage = iUsage;
    173213
     
    197237DIBSection::~DIBSection()
    198238{
    199    dprintf(("Delete DIBSection %x", handle));
     239   dprintf(("Delete DIBSection %x", hBitmap));
    200240
    201241   if(hSection) {
    202         UnmapViewOfFile(bmpBits);
    203    }
    204    else
    205    if(bmpBits)
    206         DosFreeMem(bmpBits);
     242       UnmapViewOfFile(bmpBits);
     243   }
     244   else
     245   {
     246       if(MMAP_UnregisterMemoryRange(bmpBits) == FALSE)
     247       {
     248           dprintf(("MMAP_UnregisterMemoryRange failed!!"));
     249           DebugInt3();
     250       }
     251       if(bmpBits)
     252           DosFreeMem(bmpBits);
     253   }
    207254
    208255   if(bmpBitsDblBuffer)
    209         DosFreeMem(bmpBitsDblBuffer);
     256       DosFreeMem(bmpBitsDblBuffer);
    210257
    211258   if(pOS2bmp)
    212         free(pOS2bmp);
     259       free(pOS2bmp);
    213260
    214261   lock();
    215262   if(section == this)
    216263   {
    217      section = this->next;
     264       section = this->next;
    218265   }
    219266   else
    220267   {
    221      DIBSection *dsect = section;
    222 
    223      while(dsect->next != this)
    224      {
    225        dsect = dsect->next;
    226      }
    227      dsect->next = this->next;
     268       DIBSection *dsect = section;
     269
     270       while(dsect->next != this)
     271       {
     272           dsect = dsect->next;
     273       }
     274       dsect->next = this->next;
    228275   }
    229276   unlock();
    230 }
    231 //******************************************************************************
    232 //******************************************************************************
    233 int DIBSection::SetDIBits(HDC hdc, HBITMAP hbitmap, UINT startscan, UINT
    234                           lines, const VOID *bits, BITMAPINFOHEADER_W *pbmi,
    235                           UINT coloruse)
    236 {
    237   lines = (int)lines >= 0 ? (int)lines : (int)-lines;
    238   int  palsize=0;
    239 
    240   bmpsize = pbmi->biWidth;
    241   os2bmphdrsize = sizeof(BITMAPINFO2);
    242 
    243   switch(pbmi->biBitCount)
    244   {
    245     case 1:
    246       bmpsize = ((bmpsize + 31) & ~31) / 8;
    247       palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2);
    248       os2bmphdrsize += palsize;
    249       break;
    250     case 4:
    251       bmpsize = ((bmpsize + 7) & ~7) / 2;
    252       palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2);
    253       os2bmphdrsize += palsize;
    254       break;
    255     case 8:
    256       palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2);
    257       os2bmphdrsize += palsize;
    258       bmpsize = (bmpsize + 3) & ~3;
    259       break;
    260     case 16:
    261       bmpsize *= 2;
    262       bmpsize = (bmpsize + 3) & ~3;
    263       break;
    264     case 24:
    265       bmpsize *= 3;
    266       bmpsize = (bmpsize + 3) & ~3;
    267       break;
    268     case 32:
    269       bmpsize *= 4;
    270       break;
    271    }
    272 
    273    //SvL: TODO: Correct??
    274    if(!hSection && pOS2bmp->cx != pbmi->biWidth && pOS2bmp->cy != pbmi->biHeight &&
    275       pOS2bmp->cBitCount != pbmi->biBitCount)
    276    {
    277         char *oldbits = bmpBits;
    278         int oldsize = dibinfo.dsBm.bmWidthBytes * dibinfo.dsBm.bmHeight;
    279 
    280         DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT);
    281         memcpy(bmpBits, oldbits, min(oldsize, bmpsize*pbmi->biHeight));
    282         DosFreeMem(oldbits);
    283    }
    284    pOS2bmp    = (BITMAPINFO2 *)realloc(pOS2bmp, os2bmphdrsize);
    285    pOS2bmp->cbFix         = sizeof(BITMAPINFO2) - sizeof(RGB2);
    286    pOS2bmp->cx            = pbmi->biWidth;
    287    pOS2bmp->cy            = pbmi->biHeight;
    288    pOS2bmp->cPlanes       = pbmi->biPlanes;
    289    pOS2bmp->cBitCount     = pbmi->biBitCount;
    290    pOS2bmp->ulCompression = pbmi->biCompression; //same as OS/2 (uncompressed, rle8, rle4)
    291    //SvL: Ignore BI_BITFIELDS_W type (GpiDrawBits fails otherwise)
    292    if(pOS2bmp->ulCompression == BI_BITFIELDS_W) {
    293         pOS2bmp->ulCompression = 0;
    294    }
    295    pOS2bmp->cbImage       = pbmi->biSizeImage;
    296 
    297    // clear DIBSECTION structure
    298    memset(&dibinfo, 0, sizeof(dibinfo));
    299 
    300    // copy BITMAPINFOHEADER data into DIBSECTION structure
    301    memcpy(&dibinfo.dsBmih, pbmi, sizeof(*pbmi));
    302    dibinfo.dsBm.bmType      = 0;
    303    dibinfo.dsBm.bmWidth     = pbmi->biWidth;
    304    dibinfo.dsBm.bmHeight    = pbmi->biHeight;
    305    dibinfo.dsBm.bmWidthBytes= bmpsize;
    306    dibinfo.dsBm.bmPlanes    = pbmi->biPlanes;
    307    dibinfo.dsBm.bmBitsPixel = pbmi->biBitCount;
    308    dibinfo.dsBm.bmBits      = bmpBits;
    309 
    310    dibinfo.dshSection       = hSection;
    311    dibinfo.dsOffset         = dwOffset;
    312 
    313    if(coloruse == DIB_PAL_COLORS || pbmi->biBitCount <= 8)
    314    {
    315         dibinfo.dsBitfields[0] = dibinfo.dsBitfields[1] = dibinfo.dsBitfields[2] = 0;
    316    }
    317    else {
    318         char *pColors = (char *)pbmi + 1;
    319 
    320         switch(pbmi->biBitCount)
    321         {
    322            case 16:
    323                 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors : 0x7c00;
    324                 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0x03e0;
    325                 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0x001f;
    326                 break;
    327 
    328            case 24:
    329            case 32:
    330                 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors       : 0xff0000;
    331                 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0x00ff00;
    332                 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0x0000ff;
    333                 if(dibinfo.dsBitfields[0] != 0xff0000 && dibinfo.dsBitfields[1] != 0xff00 && dibinfo.dsBitfields[2] != 0xff) {
    334                     dprintf(("DIBSection: unsupported bitfields for 32 bits bitmap!!"));
    335                 }
    336                 break;
    337         }
    338         dprintf(("BI_BITFIELDS_W %x %x %x", dibinfo.dsBitfields[0], dibinfo.dsBitfields[1], dibinfo.dsBitfields[2]));
    339    }
    340 
    341    //double buffer for rgb 555 dib sections (for conversion) or flipped sections
    342    if(dibinfo.dsBitfields[1] == 0x03e0 || (fFlip & FLIP_VERT)) {
    343         if(bmpBitsDblBuffer) {
    344             DosFreeMem(bmpBitsDblBuffer);
    345         }
    346         DosAllocMem((PPVOID)&bmpBitsDblBuffer, dibinfo.dsBm.bmWidthBytes*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT);
    347    }
    348 
    349    dprintf(("DIBSection::SetDIBits (%d,%d), %d %d", pbmi->biWidth, pbmi->biHeight, pbmi->biBitCount, pbmi->biCompression));
    350    if(palsize) {
    351         SetDIBColorTable(0, (pbmi->biClrUsed) ? pbmi->biClrUsed : (1 << pbmi->biBitCount), (RGBQUAD *)(pbmi+1));
    352    }
    353 
    354    if(bits)
    355    {
    356       if(pOS2bmp->ulCompression == BCA_UNCOMP) {
    357           int size = bmpsize*lines;
    358           memcpy(bmpBits+bmpsize*startscan, bits, size);
    359       }
    360       else {
    361           dprintf(("Compressed image!!"));
    362           if(startscan != 0) {
    363                dprintf(("WARNING: Compressed image & startscan != 0!!!!"));
    364           }
    365           memcpy(bmpBits, bits, pbmi->biSizeImage);
    366       }
    367    }
    368    return(lines);
    369277}
    370278//******************************************************************************
     
    472380
    473381  dprintf(("DIBSection::BitBlt %x %X (hps %x) %x to(%d,%d)(%d,%d) from (%d,%d)(%d,%d) rop %x flip %x",
    474           handle, hdcDest, hps, hwndDest, nXdest, nYdest, nDestWidth, nDestHeight,
     382          hBitmap, hdcDest, hps, hwndDest, nXdest, nYdest, nDestWidth, nDestHeight,
    475383          nXsrc, nYsrc, nSrcWidth, nSrcHeight, Rop, fFlip));
     384
     385  //shortcut; better to sync it here instead of in the exception handler
     386  //(pages touched inside PMGPI)
     387  if(isInvalid()) {
     388      sync();
     389  }
    476390
    477391  if(hwndDest) {
     
    637551  }
    638552  if(rc == GPI_OK) {
    639         DIBSection *destdib = DIBSection::findHDC(hdcDest);
    640         if(destdib) {
    641             destdib->sync(hps, nYdest, nDestHeight, FALSE);
    642         }
    643553#ifdef INVERT
    644554        //restore old y inversion height
     
    664574 char  *destBuf;
    665575
    666   dprintf(("Sync destination dibsection %x (%x) (%d,%d) flip %d", handle, hdc, nYdest, nDestHeight, fFlip));
     576  dprintf(("Sync destination dibsection %x (%x) (%d,%d) flip %d", hBitmap, hdc, nYdest, nDestHeight, fFlip));
    667577
    668578  BITMAPINFO2 *tmphdr = (BITMAPINFO2 *)malloc(os2bmphdrsize);
     
    692602  if(fFlip & FLIP_VERT) {
    693603#endif
     604        //origin is top left, so no y conversion is necessary
    694605        destBuf = bmpBitsDblBuffer + nYdest*dibinfo.dsBm.bmWidthBytes;
    695606
     
    729640        tmphdr->cbImage = dibinfo.dsBm.bmHeight*dibinfo.dsBm.bmWidthBytes;
    730641
    731         destBuf = GetDIBObject() + nYdest*dibinfo.dsBm.bmWidthBytes;
    732 
     642        //origin is bottom left, nYdest is based on top left coordinate system
    733643#ifdef INVERT
    734644        int dest = dibinfo.dsBm.bmHeight - nYdest - nDestHeight;
     
    736646        int dest = nYdest;
    737647#endif
    738         rc = GpiQueryBitmapBits(hdc, nYdest, nDestHeight, destBuf,
     648
     649        destBuf = GetDIBObject() + dest*dibinfo.dsBm.bmWidthBytes;
     650
     651        rc = GpiQueryBitmapBits(hdc, dest, nDestHeight, destBuf,
    739652                                tmphdr);
    740653        if(rc == GPI_ALTERROR) {
     
    769682#endif
    770683
     684}
     685//******************************************************************************
     686//******************************************************************************
     687void DIBSection::flush(HDC hdc, DWORD nYdest, DWORD nDestHeight, BOOL orgYInversion)
     688{
     689 APIRET rc;
     690 char  *destBuf;
     691
     692  dprintf(("flush destination dibsection %x (%x) (%d,%d) flip %d", hBitmap, hdc, nYdest, nDestHeight, fFlip));
     693
     694#ifdef INVERT
     695  int oldyinversion = 0;
     696  if(orgYInversion == TRUE) {
     697      oldyinversion = GpiQueryYInversion(hdc);
     698      dprintf(("Flush destination dibsection: hdc y inversion = %d", oldyinversion));
     699      if(oldyinversion != 0) {
     700#ifdef DEBUG
     701          POINT point;
     702          GetViewportOrgEx(hdc, &point);
     703          dprintf(("Viewport origin (%d,%d)", point.x, point.y));
     704#endif
     705          GpiEnableYInversion(hdc, 0);
     706      }
     707  }
     708#else
     709  dprintf(("flush destination dibsection: hdc y inversion = %d", GpiQueryYInversion(hdc)));
     710#endif
     711
     712#ifndef INVERT
     713  if(!(fFlip & FLIP_VERT)) {
     714#else
     715  if(fFlip & FLIP_VERT) {
     716#endif
     717        //origin is top left, so no y conversion is necessary
     718        destBuf = bmpBitsDblBuffer + nYdest*dibinfo.dsBm.bmWidthBytes;
     719
     720        //SvL: cbImage can be too small for compressed images; GpiQueryBitmapBits
     721        //     will fail in that case (CoolEdit 2000). Perhaps because the returned
     722        //     compressed image is larger than the original.
     723        //     Use uncompressed size instead
     724        //     NOTE: The correct size will be returned by GpiQueryBitmapBits
     725        pOS2bmp->cbImage = dibinfo.dsBm.bmHeight*dibinfo.dsBm.bmWidthBytes;
     726
     727        //manually reverse bitmap data
     728        char *src = GetDIBObject() + (nYdest+nDestHeight-1)*dibinfo.dsBm.bmWidthBytes;
     729        char *dst = destBuf;
     730        for(int i=0;i<nDestHeight;i++) {
     731            memcpy(dst, src, dibinfo.dsBm.bmWidthBytes);
     732            dst += dibinfo.dsBm.bmWidthBytes;
     733            src -= dibinfo.dsBm.bmWidthBytes;
     734        }
     735
     736        if(dibinfo.dsBitfields[1] == 0x3E0) {//RGB 555?
     737            dprintf(("DIBSection::flush: convert RGB 565 to RGB 555"));
     738
     739            pRGB565to555((WORD *)destBuf, (WORD *)destBuf, (nDestHeight*dibinfo.dsBm.bmWidthBytes)/sizeof(WORD));
     740        }
     741
     742#ifdef INVERT
     743        int dest = dibinfo.dsBm.bmHeight - nYdest - nDestHeight;
     744#else
     745        int dest = nYdest;
     746#endif
     747        rc = GpiSetBitmapBits(hdc, dest, nDestHeight, destBuf,
     748                              pOS2bmp);
     749        if(rc == GPI_ALTERROR) {
     750            dprintf(("ERROR: GpiQueryBitmapBits failed with %x", WinGetLastError(0)));
     751        }
     752
     753  }
     754  else {
     755        //SvL: cbImage can be too small for compressed images; GpiQueryBitmapBits
     756        //     will fail in that case (CoolEdit 2000). Perhaps because the returned
     757        //     compressed image is larger than the original.
     758        //     Use uncompressed size instead
     759        //     NOTE: The correct size will be returned by GpiQueryBitmapBits
     760        pOS2bmp->cbImage = dibinfo.dsBm.bmHeight*dibinfo.dsBm.bmWidthBytes;
     761
     762        //origin is bottom left, nYdest is based on top left coordinate system
     763#ifdef INVERT
     764        int dest = dibinfo.dsBm.bmHeight - nYdest - nDestHeight;
     765#else
     766        int dest = nYdest;
     767#endif
     768
     769        destBuf = GetDIBObject() + dest*dibinfo.dsBm.bmWidthBytes;
     770
     771        if(dibinfo.dsBitfields[1] == 0x3E0) {//RGB 555?
     772            dprintf(("DIBSection::flush: convert RGB 565 to RGB 555"));
     773
     774            pRGB565to555((WORD *)bmpBitsDblBuffer, (WORD *)destBuf, (nDestHeight*dibinfo.dsBm.bmWidthBytes)/sizeof(WORD));
     775            destBuf = bmpBitsDblBuffer;
     776        }
     777
     778        rc = GpiSetBitmapBits(hdc, dest, nDestHeight, destBuf,
     779                              pOS2bmp);
     780        if(rc == GPI_ALTERROR) {
     781            dprintf(("ERROR: GpiQueryBitmapBits failed with %x", WinGetLastError(0)));
     782        }
     783#ifdef DEBUG_PALETTE
     784        if(rc != GPI_ALTERROR && pOS2bmp->cBitCount <= 8) {
     785            for(int i=0;i<(1<<pOS2bmp->cBitCount);i++)
     786            {
     787                dprintf2(("Index %d : 0x%08X\n",i, *((ULONG*)(&pOS2bmp->argbColor[i])) ));
     788            }
     789        }
     790#endif
     791  }
     792  if(rc != nDestHeight) {
     793      dprintf(("!WARNING!: GpiQueryBitmapBits returned %d instead of %d scanlines", rc, nDestHeight));
     794  }
     795
     796#ifdef INVERT
     797  if(oldyinversion) GpiEnableYInversion(hdc, oldyinversion);
     798#endif
     799
     800}
     801//******************************************************************************
     802//Mark the DIB section as invalid; a subsequent read or write access must
     803//cause a pagefault
     804//******************************************************************************
     805void DIBSection::setInvalid()
     806{
     807    if(!fInvalid) {
     808        dprintf(("DIBSection::setInvalid %x (%x)", GetBitmapHandle(), GetDIBObject()));
     809        APIRET rc = DosSetMem(bmpBits, dwSize, PAG_DECOMMIT);
     810        if(rc) {
     811            dprintf(("DIBSection::setInvalid: DosSetMem failed with %d!!", rc));
     812            DebugInt3();
     813        }
     814        fInvalid = TRUE;
     815    }
     816}
     817//******************************************************************************
     818//******************************************************************************
     819void DIBSection::flush()
     820{
     821    if(pOS2bmp == NULL) {
     822        DebugInt3();
     823        return;
     824    }
     825    if(hdc == 0) {
     826         HBITMAP hOldBmp;
     827         HDC hdcFlush = CreateCompatibleDC(0);
     828
     829         hOldBmp = SelectObject(hdcFlush, hBitmap);
     830         flush(hdcFlush, 0, pOS2bmp->cy);
     831
     832         SelectObject(hdcFlush, hOldBmp);
     833         DeleteDC(hdcFlush);
     834    }
     835    else flush(hdc, 0, pOS2bmp->cy);
     836
     837    APIRET rc = DosSetMem(bmpBits, dwSize, PAG_READ);
     838    if(rc) {
     839        dprintf(("DIBSection::flush: DosSetMem failed with %d!!", rc));
     840        DebugInt3();
     841    }
     842    fDirty = FALSE;
     843}
     844//******************************************************************************
     845//******************************************************************************
     846void DIBSection::sync()
     847{
     848    if(pOS2bmp == NULL) {
     849        DebugInt3();
     850        return;
     851    }
     852    APIRET rc = DosSetMem(bmpBits, dwSize, PAG_COMMIT|PAG_READ|PAG_WRITE);
     853    if(rc) {
     854        //might already be committed
     855        rc = DosSetMem(bmpBits, dwSize, PAG_READ|PAG_WRITE);
     856        if(rc) {
     857            dprintf(("DIBSection::sync: DosSetMem failed with %d!!", rc));
     858            DebugInt3();
     859        }
     860    }
     861    if(hdc == 0) {
     862         HBITMAP hOldBmp;
     863         HDC hdcFlush = CreateCompatibleDC(0);
     864
     865         hOldBmp = SelectObject(hdcFlush, hBitmap);
     866         sync(hdcFlush, 0, pOS2bmp->cy);
     867
     868         SelectObject(hdcFlush, hOldBmp);
     869         DeleteDC(hdcFlush);
     870    }
     871    else sync(hdc, 0, pOS2bmp->cy);
     872   
     873    fInvalid = FALSE;
     874
     875    //Set bitmap memory to readonly again to detect updates
     876    rc = DosSetMem(bmpBits, dwSize, PAG_READ);
     877    if(rc) {
     878        dprintf(("DosSetMem failed with %d!!", rc));
     879        DebugInt3();
     880    }
     881}
     882//******************************************************************************
     883//******************************************************************************
     884void DIBSection::syncAll()
     885{
     886  if (!section)
     887      return;
     888
     889  lock();
     890  DIBSection *dsect = section;
     891
     892  do
     893  {
     894      if(dsect->isDirty() && dsect->isInvalid()) {
     895          DebugInt3();
     896      }
     897      if(dsect->isInvalid())
     898      {
     899          dsect->sync();
     900      }
     901      dsect = dsect->next;
     902  }
     903  while(dsect);
     904
     905  unlock();
     906
     907  return;
    771908}
    772909//******************************************************************************
     
    796933  this->hdc  = hdc;
    797934  hwndParent = WindowFromDC(hdc);
    798   dprintf(("SelectDIBObject %x into %x hwndParent = %x", handle, hdc, hwndParent));
    799 }
    800 //******************************************************************************
    801 //******************************************************************************
    802 DIBSection *DIBSection::findObj(HANDLE handle)
     935  dprintf(("SelectDIBObject %x into %x hwndParent = %x", hBitmap, hdc, hwndParent));
     936}
     937//******************************************************************************
     938//******************************************************************************
     939DIBSection *DIBSection::findObj(HBITMAP hBitmap)
    803940{
    804941  // PH 2001-08-18 shortcut for performance optimization
     
    806943      return NULL;
    807944
     945  lock();
    808946  DIBSection *dsect = section;
    809   lock();
    810947
    811948  do
    812949  {
    813     if(dsect->handle == handle)
     950    if(dsect->hBitmap == hBitmap)
    814951    {
    815952        unlock();
     
    832969      return NULL;
    833970 
     971  lock();
    834972  DIBSection *dsect = section;
    835973 
    836   lock();
    837974  do
    838975  {
     
    851988//******************************************************************************
    852989//******************************************************************************
    853 void DIBSection::deleteSection(HANDLE handle)
    854 {
    855  DIBSection *dsect = findObj(handle);
     990void DIBSection::deleteSection(HBITMAP hBitmap)
     991{
     992 DIBSection *dsect = findObj(hBitmap);
    856993
    857994  if(dsect)
     
    8651002 LPBITMAP_W  dsBm        = (LPBITMAP_W)lpBuffer;
    8661003
    867   dprintf2(("GetDIBSection %x %d %x", handle, iSize, lpBuffer));
     1004  dprintf2(("GetDIBSection %x %d %x", hBitmap, iSize, lpBuffer));
    8681005  if(iSize == sizeof(DIBSECTION))
    8691006  {
     
    9171054DIBSection      *DIBSection::section = NULL;
    9181055CRITICAL_SECTION DIBSection::dibcritsect;
     1056
     1057
     1058//******************************************************************************
     1059//******************************************************************************
     1060static BOOL WIN32API DIBExceptionNotify(LPVOID lpBase, ULONG offset, BOOL fWriteAccess,
     1061                                        DWORD dwSize, DWORD dwUserData)
     1062{
     1063    DIBSection *dsect;
     1064    HBITMAP hBitmap = (HBITMAP)dwUserData;
     1065
     1066    dprintf(("DIBExceptionNotify %x %x %d %d %x", lpBase, offset, fWriteAccess, dwSize, dwUserData));
     1067
     1068    dsect = DIBSection::findObj(hBitmap);
     1069    if(dsect == NULL) {
     1070        dprintf(("dib section not found!!"));
     1071        DebugInt3();
     1072        return FALSE;
     1073    }
     1074    if(dsect->isInvalid())
     1075    {//implies read or write to reserved pages
     1076        //synchronize bitmap memory and bitmap object
     1077        dsect->sync();
     1078    }
     1079    else
     1080    if(!fWriteAccess) {
     1081        APIRET rc = DosSetMem(lpBase, dwSize, PAG_READ|PAG_COMMIT);
     1082        if(rc) {
     1083            dprintf(("DosSetMem failed with %d!!", rc));
     1084            DebugInt3();
     1085            return FALSE;
     1086        }
     1087    }
     1088
     1089    if(fWriteAccess) {
     1090        APIRET rc = DosSetMem(lpBase, dwSize, PAG_READ|PAG_WRITE);
     1091        if(rc) {
     1092            dprintf(("DosSetMem failed with %d!!", rc));
     1093            DebugInt3();
     1094            return FALSE;
     1095        }
     1096        dsect->setDirty();
     1097    }
     1098
     1099
     1100    return TRUE;
     1101}
     1102//******************************************************************************
     1103//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.