Ignore:
Timestamp:
Nov 12, 2003, 3:13:26 PM (22 years ago)
Author:
sandervl
Message:

Visible & Clip region changes

File:
1 edited

Legend:

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

    r10140 r10316  
    1 /* $Id: region.cpp,v 1.32 2003-06-03 13:48:13 sandervl Exp $ */
     1/* $Id: region.cpp,v 1.33 2003-11-12 14:10:55 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 * TODO: Metafile recording
    1011 * TODO: Do we need to translate & set the last error for Gpi operations?
     12 *
     13 *
     14 * NOTE: In windows there is a clip and a visible region (just like in PM)
     15 *       We do not map the Win32 visible region to the PM visible region
     16 *       as that's rather annoying.
     17 *       Instead we use the intersection of the win32 visible and win32 clip
     18 *       region for the PM clip region.
     19 *       The original Win32 clip region is saved in pHps->hrgnWin32Clip.
     20 *       The Win32 visible region is saved in pHps->hrgnWinVis.
     21 *
     22 *
    1123 *
    1224 * Project Odin Software License can be found in LICENSE.TXT
     
    3143#include <stats.h>
    3244#include "dibsect.h"
     45#include <wingdi32.h>
    3346
    3447#define DBG_LOCALLOG    DBG_region
    3548#include "dbglocal.h"
     49
     50//GPI and Windows use the same values
     51#define GPI_TO_WIN_COMPLEXITY(a)        a
    3652
    3753typedef enum
     
    4258
    4359#define MEM_HPS_MAX 768
     60
     61int WIN32API OffsetRgn( HRGN  hrgn, int  xOffset, int  yOffset);
    4462
    4563static void convertDeviceRect(HWND hwnd, pDCData pHps, PRECTL pRectl, ULONG count);
     
    107125        LONG y = 0;
    108126
    109         if(pHps == 0 || pHps->isClient) //client area
     127        if(pHps && pHps->isClient) //client area
    110128        {
    111129            if(GetClientRect(OS2ToWin32Handle(hwnd), &rect) == TRUE) {
     
    132150   if(pHps->isPrinter)
    133151   {
    134       return pHps->printPageHeight;
     152      return GetDeviceCaps(pHps->hps, VERTRES_W);
    135153   }
    136154   else
     
    152170        LONG x = 0;
    153171
    154         if(pHps == 0 || pHps->isClient) //client area
     172        if(pHps && pHps->isClient) //client area
    155173        {
    156174            if(GetClientRect(OS2ToWin32Handle(hwnd), &rect) == TRUE) {
     
    164182        return x;
    165183   }
     184   else
     185   if(pHps->bitmapHandle)
     186   {
     187      return pHps->bitmapWidth;
     188   }
     189   else
     190   if(pHps->isMetaPS)
     191   {
     192      return 0;
     193   }
     194   else
     195   if(pHps->isPrinter)
     196   {
     197      return GetDeviceCaps(pHps->hps, HORZRES_W);
     198   }
    166199//   else
    167200//     DebugInt3();
     
    211244    if(pHps)
    212245    {
    213          wHeight += pHps->HPStoHDCInversionHeight;
     246        wHeight += pHps->HPStoHDCInversionHeight;
    214247    }
    215248
     
    388421}
    389422//******************************************************************************
    390 //******************************************************************************
    391 int WIN32API SelectClipRgn(HDC hdc, HRGN hrgn)
    392 {
    393  LONG lComplexity = RGN_NULL;
    394  HRGN hrgnNewClip;
    395  HRGN hrgnOldClip;
     423// GdiSetVisRgn
     424//
     425// Change the Win32 visible region to the specified region
     426//
     427// Parameters:
     428//
     429// pDCData pHps         - presentation space structure
     430// HRGN hrgn            - region handle (GPI)
     431//
     432//
     433// Returns:     - ERROR_W         -> failure
     434//              - NULLREGION_W    -> empty region
     435//              - SIMPLEREGION_W  -> rectangular region
     436//              - COMPLEXREGION_W -> complex region
     437//
     438// NOTE: In windows there is a clip and a visible region (just like in PM)
     439//       We do not map the Win32 visible region to the PM visible region
     440//       as that's rather annoying.
     441//       Instead we use the intersection of the win32 visible and win32 clip
     442//       region for the PM clip region.
     443//       The Win32 clip region is saved in pHps->hrgnWin32Clip.
     444//       The Win32 visible region is saved in pHps->hrgnWinVis.
     445//
     446//******************************************************************************
     447INT WIN32API GdiSetVisRgn(pDCData pHps, HRGN hrgn)
     448{
     449    HRGN hrgnNewClip = NULLHANDLE, hrgnOldClip = NULLHANDLE;
     450    LONG lComplexity = RGN_NULL;
     451    RECTL rectl = {0, 0, 1, 1};
     452
     453    if(pHps == NULL) {
     454        DebugInt3();
     455        return ERROR_W;
     456    }
     457
     458    if(hrgn != NULLHANDLE)
     459    {
     460        hrgnNewClip = GpiCreateRegion(pHps->hps, 1, &rectl);
     461        if(hrgnNewClip == NULLHANDLE) {
     462            dprintf(("ERROR: GdiCombineVisRgn: GpiCreateRegion failed!!"));
     463            DebugInt3();
     464            goto failure;
     465        }
     466        //make a copy of the new visible region
     467        lComplexity = GpiCombineRegion(pHps->hps, hrgnNewClip, hrgn, NULLHANDLE, CRGN_COPY);
     468    }
     469    else {
     470        hrgnNewClip = NULLHANDLE;
     471    }
     472
     473    //and set that as the GPI clip region
     474    lComplexity = GpiSetClipRegion(pHps->hps, hrgnNewClip, &hrgnOldClip);
     475    if (lComplexity != RGN_ERROR)
     476    {
     477        //SvL: Must check if origin changed here. Sometimes happens when
     478        //     window looses focus. (don't know why....)
     479        checkOrigin(pHps);
     480
     481        if(hrgnOldClip) GpiDestroyRegion(pHps->hps, hrgnOldClip);
     482
     483        dprintf(("New visible region %x", hrgn));
     484        pHps->hrgnWinVis = hrgn;
     485        return GPI_TO_WIN_COMPLEXITY(lComplexity);
     486    }
     487failure:
     488    if(hrgnNewClip) GpiDestroyRegion(pHps->hps, hrgnNewClip);
     489
     490    return ERROR_W;
     491}
     492//******************************************************************************
     493// GdiCombineVisRgn
     494//
     495// Combine the specified region with the visible region according to the operation
     496//
     497// Parameters:
     498//
     499// pDCData pHps         - presentation space structure
     500// HRGN hrgn            - region handle (Win32)
     501// INT operation        - combine operation (RGN_*)
     502//
     503//
     504// Returns:     - ERROR_W         -> failure
     505//              - NULLREGION_W    -> empty region
     506//              - SIMPLEREGION_W  -> rectangular region
     507//              - COMPLEXREGION_W -> complex region
     508//
     509// NOTE: In windows there is a clip and a visible region (just like in PM)
     510//       We do not map the Win32 visible region to the PM visible region
     511//       as that's rather annoying.
     512//       Instead we use the intersection of the win32 visible and win32 clip
     513//       region for the PM clip region.
     514//       The Win32 clip region is saved in pHps->hrgnWin32Clip.
     515//       The Win32 visible region is saved in pHps->hrgnWinVis.
     516//
     517//******************************************************************************
     518INT WIN32API GdiCombineVisRgn(pDCData pHps, HRGN hrgn, INT operation)
     519{
    396520#ifdef DEBUG
    397  HRGN hrgn1 = hrgn;
     521    HRGN hrgn1 = hrgn;
    398522#endif
    399 
    400     pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
    401     if(!pHps)
    402     {
    403         dprintf(("WARNING: SelectClipRgn: invalid hdc!", hdc, hrgn));
    404         SetLastError(ERROR_INVALID_HANDLE_W);
     523    LONG lComplexity = RGN_NULL;
     524
     525    if(pHps == NULL) {
     526        DebugInt3();
    405527        return ERROR_W;
    406528    }
    407529
    408     if(hrgn)
    409     {
    410         hrgn = ObjQueryHandleData(hrgn, HNDL_REGION);
    411         if(hrgn == HANDLE_OBJ_ERROR) {
    412             dprintf(("WARNING: SelectClipRgn: invalid region!", hdc, hrgn1));
    413             SetLastError(ERROR_INVALID_HANDLE_W);
    414             return ERROR_W;
    415         }
    416     }
    417 
    418     if(hrgn)
    419     {
    420         RECTL rectl = {0,0,1,1};
    421         hrgnNewClip = GpiCreateRegion(pHps->hps, 1, &rectl);
    422         if(interpretRegionAs(pHps, hrgnNewClip, hrgn, AS_DEVICE) == 0)
     530    hrgn = ObjQueryHandleData(hrgn, HNDL_REGION);
     531    if(hrgn == HANDLE_OBJ_ERROR || !pHps) {
     532        dprintf(("ERROR: GdiCombineVisRgn %x invalid handle", hrgn1));
     533        return ERROR_W;
     534    }
     535    //interpretRegionAs converts the region and saves it in pHps->hrgnHDC
     536    if(!interpretRegionAs(pHps, 0, hrgn, AS_DEVICE) )
     537    {
     538        dprintf(("ERROR: interpretRegionAs failed!!"));
     539        return ERROR_W;
     540    }
     541
     542    //If there is no visible region, then create one that covers the whole DC
     543    if(pHps->hrgnWinVis == NULLHANDLE)
     544    {
     545         RECTL rectl = {0, 0, hdcWidth(0, pHps), hdcHeight(0, pHps)};
     546         dprintf(("No visible region: create one (0,0)(%d,%d)", rectl.xRight, rectl.yTop));
     547         pHps->hrgnWinVis = GpiCreateRegion(pHps->hps, 1, &rectl);
     548         if(pHps->hrgnWinVis == NULLHANDLE) {
     549             dprintf(("ERROR: GdiCombineVisRgn: GpiCreateRegion failed!!"));
     550             DebugInt3();
     551             goto failure;
     552         }
     553    }
     554
     555    LONG lMode;
     556    switch (operation)
     557    {
     558    case  RGN_AND_W  : lMode = CRGN_AND ; break;
     559    case  RGN_DIFF_W : lMode = CRGN_DIFF; break;
     560    default:
     561        dprintf(("ERROR: GdiCombineVisRgn %d invalid parameter", operation));
     562        DebugInt3();
     563        goto failure;
     564    }
     565    lComplexity = GpiCombineRegion(pHps->hps, pHps->hrgnWinVis, pHps->hrgnWinVis, pHps->hrgnHDC, lMode);
     566    if (lComplexity != RGN_ERROR)
     567    {
     568        return GdiSetVisRgn(pHps, pHps->hrgnWinVis);
     569    }
     570    dprintf(("ERROR: GdiCombineVisRgn: GpiCombineRegion failed"));
     571    DebugInt3();
     572
     573failure:
     574    return ERROR_W;
     575}
     576//******************************************************************************
     577// GdiCombineVisRgnClipRgn
     578//
     579// Combine the specified clip region with the visible region according to the operation
     580//
     581// Parameters:
     582//
     583// pDCData pHps         - presentation space structure
     584// HRGN hrgn            - region handle (GPI)
     585// INT operation        - combine operation (RGN_*)
     586//
     587//
     588// Returns:     - ERROR_W         -> failure
     589//              - NULLREGION_W    -> empty region
     590//              - SIMPLEREGION_W  -> rectangular region
     591//              - COMPLEXREGION_W -> complex region
     592//
     593// NOTE: In windows there is a clip and a visible region (just like in PM)
     594//       We do not map the Win32 visible region to the PM visible region
     595//       as that's rather annoying.
     596//       Instead we use the intersection of the win32 visible and win32 clip
     597//       region for the PM clip region.
     598//       The Win32 clip region is saved in pHps->hrgnWin32Clip.
     599//       The Win32 visible region is saved in pHps->hrgnWinVis.
     600//
     601//******************************************************************************
     602INT WIN32API GdiCombineVisRgnClipRgn(pDCData pHps, HRGN hrgn, INT operation)
     603{
     604    HRGN hrgnClip = NULL, hrgnOldClip, hrgnNewClip;
     605    LONG lComplexity = RGN_NULL;
     606
     607    //Create a region that will be used for the new GPI clip region
     608    RECTL rectl = {0, 0, 1, 1};
     609    hrgnNewClip = GpiCreateRegion(pHps->hps, 1, &rectl);
     610    if(hrgnNewClip == NULLHANDLE) {
     611        dprintf(("ERROR: GdiCombineVisRgnClipRgn: GpiCreateRegion failed!!"));
     612        DebugInt3();
     613        return ERROR_W;
     614    }
     615
     616    if(hrgn == NULLHANDLE)
     617    {
     618        if(pHps->hrgnWin32Clip != NULL)
    423619        {
    424             lComplexity = RGN_ERROR;
    425         }
    426     }
    427     else
    428         hrgnNewClip = 0;
    429 
    430     if(lComplexity != RGN_ERROR)
    431     {
    432         if(hrgnNewClip == 0) {
    433             GpiSetClipPath(pHps->hps, 0, SCP_RESET);
    434         }
    435         lComplexity = GpiSetClipRegion(pHps->hps, hrgnNewClip, &hrgnOldClip);
    436         if (lComplexity != RGN_ERROR )
    437         {
    438             if(hrgnOldClip)
    439                 GpiDestroyRegion(pHps->hps, hrgnOldClip);
    440 
    441             //todo: metafile recording
    442             SetLastError(ERROR_SUCCESS_W);
     620            //Only reset the path if both the visible and clip regions are zero
     621            if(!pHps->hrgnWinVis) {
     622                GpiSetClipPath(pHps->hps, 0, SCP_RESET);
     623
     624                GpiDestroyRegion(pHps->hps, hrgnNewClip);
     625                hrgnNewClip = NULLHANDLE;
     626            }
     627            else
     628            {//set PM clip region to Win32 visible region
     629                lComplexity = GpiCombineRegion(pHps->hps, hrgnNewClip, pHps->hrgnWinVis, NULLHANDLE, CRGN_COPY);
     630                if(lComplexity == RGN_ERROR) {
     631                    dprintf(("ERROR: GdiCombineVisRgnClipRgn: GpiSetClipRegion failed!!"));
     632                    DebugInt3();
     633                    goto failure;
     634                }
     635            }
     636            dprintfRegion(pHps->hps, hrgnNewClip);
     637            lComplexity = GpiSetClipRegion(pHps->hps, hrgnNewClip, &hrgnOldClip);
     638            if(lComplexity == RGN_ERROR) {
     639                dprintf(("ERROR: GdiCombineVisRgnClipRgn: GpiSetClipRegion failed!!"));
     640                DebugInt3();
     641            }
    443642
    444643            //SvL: Must check if origin changed here. Sometimes happens when
    445644            //     window looses focus. (don't know why....)
    446645            checkOrigin(pHps);
    447             return lComplexity;
    448         }
    449     }
    450 
    451     dprintf(("WARNING: SelectClipRgn: RGN_ERROR!", hdc, hrgn1));
    452     if(hrgnNewClip)
    453         GpiDestroyRegion(pHps->hps, hrgnNewClip);
    454 
    455     SetLastError(ERROR_SUCCESS_W);
    456     return lComplexity;
     646            if(hrgnOldClip) GpiDestroyRegion(pHps->hps, hrgnOldClip);
     647        }
     648        //else already NULL, so nothing to do.
     649
     650        pHps->hrgnWin32Clip = hrgn;
     651        return NULLREGION_W;
     652    }
     653
     654    LONG lMode;
     655    switch (operation)
     656    {
     657    case  RGN_AND_W  : lMode = CRGN_AND ; break;  //intersect clip & visible region
     658    default:
     659        dprintf(("ERROR: GdiCombineVisRgnClipRgn %d invalid parameter", operation));
     660        DebugInt3();
     661        goto failure;
     662    }
     663    // If there's no visible region (meaning entire DC is visible), then just set
     664    // the GPI clip region to the win32 clip region
     665    if (pHps->hrgnWinVis == NULLHANDLE)
     666    {
     667         lComplexity = GpiCombineRegion(pHps->hps, hrgnNewClip, hrgn, NULLHANDLE, CRGN_COPY);
     668    }
     669    else lComplexity = GpiCombineRegion(pHps->hps, hrgnNewClip, pHps->hrgnWinVis, hrgn, lMode);
     670
     671    if (lComplexity != RGN_ERROR)
     672    {
     673        dprintfRegion(pHps->hps, hrgnNewClip);
     674        //And activate the new clip region
     675        lComplexity = GpiSetClipRegion(pHps->hps, hrgnNewClip, &hrgnOldClip);
     676        if (lComplexity == RGN_ERROR )
     677        {
     678            dprintf(("ERROR: GdiCombineVisRgnClipRgn: GpiSetClipRegion failed"));
     679            DebugInt3();
     680            goto failure;
     681        }
     682        //SvL: Must check if origin changed here. Sometimes happens when
     683        //     window looses focus. (don't know why....)
     684        checkOrigin(pHps);
     685
     686        if(hrgnOldClip) GpiDestroyRegion(pHps->hps, hrgnOldClip);
     687
     688        pHps->hrgnWin32Clip = hrgn;
     689
     690        return GPI_TO_WIN_COMPLEXITY(lComplexity);
     691    }
     692    dprintf(("ERROR: GdiCombineVisRgnClipRgn: GpiCombineRegion failed"));
     693    DebugInt3();
     694
     695failure:
     696    if(hrgnNewClip) GpiDestroyRegion(pHps->hps, hrgnNewClip);
     697
     698    return ERROR_W;
    457699}
    458700//******************************************************************************
     
    464706#endif
    465707
    466    pDCData    pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
     708   pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
    467709   if (!pHps)
    468710   {
     
    473715
    474716   LONG lComplexity;
    475    HRGN hrgnCurrent = NULLHANDLE;
     717   HRGN hrgnCurrent = NULLHANDLE, hrgnOld = NULLHANDLE;
    476718
    477719   if(!hrgn && mode != RGN_COPY_W)
     
    506748            return 0;
    507749        }
     750        dprintfRegion(hdc, hrgn);
    508751   }
    509752
     
    511754   if(hrgn)
    512755   {
     756        //interpretRegionAs converts the region and saves it in pHps->hrgnHDC
    513757        if(!interpretRegionAs(pHps, 0, hrgn, AS_DEVICE) )
    514758        {
     
    518762   else
    519763   {
    520         //remove clip region
    521         GpiSetClipPath(pHps->hps, 0, SCP_RESET);
    522         GpiSetClipRegion(pHps->hps, NULLHANDLE, &hrgnCurrent);
    523 
    524         if(hrgnCurrent)
    525             GpiDestroyRegion(pHps->hps, hrgnCurrent);
     764        //Intersect the Windows clip region with the current visible region
     765        lComplexity = GdiCombineVisRgnClipRgn(pHps, NULLHANDLE, RGN_AND_W);
    526766
    527767        return NULLREGION_W;
    528768   }
    529769
    530    GpiSetClipRegion(pHps->hps, NULLHANDLE, &hrgnCurrent);
     770   // get current clipping region
     771   hrgnOld     = pHps->hrgnWin32Clip;
     772   hrgnCurrent = hrgnOld;
    531773
    532774   if(hrgnCurrent == NULLHANDLE)
    533    {
     775   {//if none, then create one
    534776        lMode = CRGN_COPY;
    535777        RECTL rectl = {0, 0, 1, 1};
     
    554796   {
    555797        HRGN hrgnOld;
    556         lComplexity = GpiSetClipRegion(pHps->hps, hrgnCurrent, &hrgnOld);
     798
     799        //Intersect the Windows clip region with the current visible region
     800        lComplexity = GdiCombineVisRgnClipRgn(pHps, hrgnCurrent, RGN_AND_W);
     801
    557802        SetLastError(ERROR_SUCCESS_W);
    558803
    559         //SvL: Must check if origin changed here. Sometimes happens when
    560         //     window looses focus. (don't know why....)
    561         checkOrigin(pHps);
    562 
    563         if (lComplexity != RGN_ERROR)
     804        if (lComplexity != RGN_ERROR) {
    564805            return lComplexity;
    565    }
    566    SetLastError(ERROR_SUCCESS_W);
     806        }
     807   }
     808   GpiDestroyRegion(pHps->hps, hrgnCurrent); //delete newly created region
     809
     810   SetLastError(ERROR_INVALID_PARAMETER_W); //TODO
    567811   return ERROR_W;
    568812}
    569813//******************************************************************************
     814//******************************************************************************
     815int WIN32API SelectClipRgn(HDC hdc, HRGN hrgn)
     816{
     817    return ExtSelectClipRgn(hdc, hrgn, RGN_COPY_W);
     818}
     819//******************************************************************************
     820// The GetClipBox function retrieves the dimensions of the tightest bounding
     821// rectangle that can be drawn around the current visible area on the device.
     822// The visible area is defined by the current clipping region or clip path, as well
     823// as any overlapping windows.
     824//
     825// NOTE: We simply call GpiQueryClipBox as it behaves just like GetClipBox
     826//
    570827//******************************************************************************
    571828int WIN32API GetClipBox(HDC hdc, PRECT lpRect)
     
    583840    if(pHps->isPrinter)
    584841    {
     842        //Some printers return the wrong clip box. Return the full page instead.
     843        //(TODO: which is incorrect!)
    585844        lpRect->left   = 0;
    586845        lpRect->top    = 0;
     
    608867            //Convert coordinates from PM to win32
    609868            if (pHps->yInvert > 0) {
    610              LONG temp     = pHps->yInvert - rectl.yBottom;
    611                  rectl.yBottom = pHps->yInvert - rectl.yTop;
    612              rectl.yTop    = temp;
     869                LONG temp     = pHps->yInvert - rectl.yBottom;
     870                rectl.yBottom = pHps->yInvert - rectl.yTop;
     871                rectl.yTop    = temp;
    613872            }
    614873#endif
     
    628887            }
    629888
    630             rc = (lComplexity == RGN_RECT) ? SIMPLEREGION_W : COMPLEXREGION_W;
     889            rc = GPI_TO_WIN_COMPLEXITY(lComplexity);
    631890        }
    632891    }
     
    655914    }
    656915
    657     if(GpiSetClipRegion(pHps->hps, NULL, &hrgnClip) == RGN_ERROR) {
    658         dprintf(("WARNING: GetClipRgn GpiSetClipRegion failed! (%x)", WinGetLastError(0)));
    659         SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
    660         return 0;
    661     }
    662     if(hrgnClip) {
    663         if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgnClip, pHps, NULL)) {
    664                 dprintf(("WARNING: GetClipRgn setWinDeviceRegionFromPMDeviceRegion failed!"));
    665                 GpiSetClipRegion(pHps->hps, hrgnClip, &hrgnTemp);
    666                 SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
    667                 return 0;
    668         }
    669         if(GpiSetClipRegion(pHps->hps, hrgnClip, &hrgnTemp) == RGN_ERROR )
    670         {
    671             dprintf(("WARNING: GetClipRgn GpiSetClipRegion failed %x!", WinGetLastError(0)));
     916    if(pHps->hrgnWin32Clip) {
     917        dprintfRegion(hdc, pHps->hrgnWin32Clip);
     918        if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, pHps->hrgnWin32Clip, pHps, NULL)) {
     919            dprintf(("WARNING: GetClipRgn setWinDeviceRegionFromPMDeviceRegion failed!"));
     920            GpiSetClipRegion(pHps->hps, hrgnClip, &hrgnTemp);
    672921            SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
    673922            return 0;
    674923        }
    675924    }
    676     else lComplexity = RGN_NULL;
     925    else {
     926       //no clip region; return NULL
     927       lComplexity = RGN_NULL;
     928    }
    677929
    678930    SetLastError(ERROR_SUCCESS_W);
     
    682934}
    683935//******************************************************************************
     936// The GetRandomRgn function copies the system clipping region of a specified
     937// device context to a specific region.
     938// It returns the visible region of the specified device context in screen
     939// coordinates (if it belongs to a window).
     940//
     941// VALUE = 1: This undocumented value will return the current Clip Region contained in the DC.
     942// VALUE = 2: This undocumented value will return the current Meta Region contained in the DC.
     943// VALUE = 3: This undocumented value will return the intersection of the Clip Region and Meta Region.
     944// VALUE = 4, SYSRGN: The only value that is documented and defined for this function.
     945//                    This value returns the System Region
     946//******************************************************************************
     947INT WIN32API GetRandomRgn(HDC hdc, HRGN hrgn, INT iNum)
     948{
     949    HWND hwnd;
     950    INT  ret;
     951
     952    if(iNum != SYSRGN_W) {
     953        dprintf(("WARNING: GetRandomRgn: invalid parameter %x", iNum));
     954        SetLastError(ERROR_INVALID_PARAMETER_W);
     955        return ERROR_W;
     956    }
     957    ret = GetClipRgn(hdc, hrgn);
     958
     959    hwnd = WindowFromDC(hdc);
     960    if(hwnd) {
     961        POINT pt = {0,0};
     962        //map from client to desktop coordinates
     963        MapWindowPoints(hwnd, 0, &pt, 1);
     964
     965        OffsetRgn(hrgn, pt.x, pt.y);
     966    }
     967    return ret;
     968}
     969//******************************************************************************
    684970//******************************************************************************
    685971int WIN32API ExcludeClipRect(HDC  hdc, int  left, int  top, int  right, int bottom)
     
    688974    if(!pHps)
    689975    {
    690         dprintf(("WARNING: ExcludeClipRgn %x (%d,%d)(%d,%d) invalid hdc", hdc, left, top, right, bottom));
     976        dprintf(("ERROR: ExcludeClipRgn %x (%d,%d)(%d,%d) invalid hdc", hdc, left, top, right, bottom));
    691977        SetLastError(ERROR_INVALID_HANDLE_W);
    692978        return ERROR_W;
     
    712998
    713999    dprintf(("ExcludeClipRgn %x (%d,%d)(%d,%d)", hdc, left, top, right, bottom));
     1000
    7141001    lComplexity = GpiExcludeClipRectangle(pHps->hps, &rectl);
    7151002    if (lComplexity == RGN_ERROR) {
     1003        dprintf(("ERROR: ExcludeClipRgn: GpiExcludeClipRectangle failed!!"));
    7161004        SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
    7171005        return ERROR_W;
     1006    }
     1007
     1008    //Ok, success. Now update the cached win32 clip region
     1009    if(pHps->hrgnWin32Clip != NULLHANDLE)
     1010    {
     1011        HRGN hrgnClipRect = GpiCreateRegion(pHps->hps, 1, &rectl);
     1012        if(hrgnClipRect == NULLHANDLE) {
     1013            dprintf(("ERROR: ExcludeClipRgn GpiCreateRegion failed!!"));
     1014            DebugInt3();
     1015            SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
     1016            return ERROR_W;
     1017        }
     1018        //subtract rect region from clip region
     1019        lComplexity = GpiCombineRegion(pHps->hps, pHps->hrgnWin32Clip, pHps->hrgnWin32Clip, hrgnClipRect, CRGN_DIFF);
     1020        GpiDestroyRegion(pHps->hps, hrgnClipRect);
     1021
     1022        if (lComplexity == RGN_ERROR) {
     1023            dprintf(("ERROR: ExcludeClipRgn GpiCombineRegion failed!!"));
     1024            DebugInt3();
     1025            SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
     1026            return ERROR_W;
     1027        }
    7181028    }
    7191029
     
    7561066    dprintf(("IntersectClipRect %x (%d,%d)(%d,%d)", hdc, left, top, right, bottom));
    7571067    lComplexity = GpiIntersectClipRectangle(pHps->hps, &rectl);
     1068    if (lComplexity == RGN_ERROR) {
     1069        dprintf(("ERROR: IntersectClipRect: GpiIntersectClipRectangle failed!!"));
     1070        SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
     1071        return ERROR_W;
     1072    }
     1073
     1074    //Ok, success. Now update the cached win32 clip region
     1075    if(pHps->hrgnWin32Clip != NULLHANDLE)
     1076    {
     1077        HRGN hrgnClipRect = GpiCreateRegion(pHps->hps, 1, &rectl);
     1078        if(hrgnClipRect == NULLHANDLE) {
     1079            dprintf(("ERROR: IntersectClipRect GpiCreateRegion failed!!"));
     1080            DebugInt3();
     1081            SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
     1082            return ERROR_W;
     1083        }
     1084        //intersect rect region with clip region
     1085        lComplexity = GpiCombineRegion(pHps->hps, pHps->hrgnWin32Clip, pHps->hrgnWin32Clip, hrgnClipRect, CRGN_AND);
     1086        GpiDestroyRegion(pHps->hps, hrgnClipRect);
     1087
     1088        if (lComplexity == RGN_ERROR) {
     1089            dprintf(("ERROR: IntersectClipRect GpiCombineRegion failed!!"));
     1090            DebugInt3();
     1091            SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
     1092            return ERROR_W;
     1093        }
     1094    }
    7581095
    7591096    //todo metafile recording
     
    7841121#endif
    7851122
    786    lComplexity = GpiOffsetClipRegion(pHps->hps, &pointl);
     1123   if(pHps->hrgnWin32Clip == NULLHANDLE) {
     1124       lComplexity = NULLREGION_W;
     1125   }
     1126   else {
     1127       lComplexity = GpiOffsetRegion(pHps->hps, pHps->hrgnWin32Clip, &pointl);
     1128       if (lComplexity == RGN_ERROR) {
     1129           dprintf(("ERROR: OffsetClipRgn: GpiOffsetRegion failed!!"));
     1130           SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
     1131           return ERROR_W;
     1132       }
     1133
     1134       //Intersect the Windows clip region with the current visible region
     1135       lComplexity = GdiCombineVisRgnClipRgn(pHps, pHps->hrgnWin32Clip, RGN_AND_W);
     1136
     1137       lComplexity = GPI_TO_WIN_COMPLEXITY(lComplexity);
     1138   }
    7871139
    7881140   //todo metafile recording
     
    10381390    dprintf(("CreateEllipticRgn (%d,%d)(%d,%d)", left, top, right, bottom));
    10391391    hrgn = GpiCreateEllipticRegion(hpsRegion, &rectl);
     1392    if(hrgn == RGN_ERROR) {
     1393        SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
     1394        dprintf(("WARNING: CreateEllipticRgn: GpiCreateEllipticRegion failed! %x", WinGetLastError(0)));
     1395        return 0;
     1396    }
    10401397
    10411398    if(ObjAllocateHandle(&hrgn, hrgn, HNDL_REGION) == FALSE) {
     
    10861443    polygon.aPointl  = (PPOINTL)(lppt + 1);
    10871444
     1445#ifdef DEBUG
     1446    for(int i=0;i<cPoints;i++) {
     1447        dprintf(("Point %d: (%d,%d)", i, lppt[i].x, lppt[i].y));
     1448    }
     1449#endif
    10881450    GpiMove(hpsRegion, (PPOINTL)lppt);
    10891451    hrgn = GpiCreatePolygonRegion(hpsRegion, 1, &polygon, POLYGON_BOUNDARY | flMode);
     1452    if(hrgn == RGN_ERROR) {
     1453        SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
     1454        dprintf(("WARNING: CreatePolygonRgn: GpiCreatePolygonRegion failed! %x", WinGetLastError(0)));
     1455        return 0;
     1456    }
    10901457
    10911458    if(ObjAllocateHandle(&hrgn, hrgn, HNDL_REGION) == FALSE) {
     
    12841651        dprintf(("WARNING: GetRgnBox %x %x invalid region!", hrgn1, pRect));
    12851652        SetLastError(ERROR_INVALID_HANDLE_W);
    1286         return FALSE;
     1653        return ERROR_W;
    12871654    }
    12881655
     
    13561723    }
    13571724
     1725    DIBSECTION_MARK_INVALID(hdc);
    13581726    return TRUE;
    13591727}
     
    14481816        SelectObject(hdc, hbrushRestore);
    14491817
     1818    if(lHits != GPI_ERROR)
     1819        DIBSECTION_MARK_INVALID(hdc);
     1820
    14501821    //todo metafile recording
    14511822    return (lHits != GPI_ERROR);
     
    14581829 HBRUSH hbrushRestore = 0;
    14591830#ifdef DEBUG
    1460  HRGN   hrgn1 = hrgn;
     1831    HRGN   hrgn1 = hrgn;
    14611832#endif
    1462 
    14631833
    14641834    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
     
    14831853    dprintf(("FillRgn %x %x %x", hdc, hrgn1, hBrush));
    14841854
     1855    DIBSECTION_CHECK_IF_DIRTY(hdc);
    14851856    interpretRegionAs(pHps, NULL, hrgn, AS_WORLD);
    14861857
     
    14951866        SelectObject(hdc, hbrushRestore);
    14961867
    1497     /* PF Sync DIBSection as well */
    1498     if(DIBSection::getSection() != NULL)
    1499     {
    1500         DIBSection *dsect = DIBSection::findHDC(hdc);
    1501         if(dsect)
    1502         {
    1503             dsect->sync(hdc, 0, dsect->GetHeight());
    1504         }
    1505     }
    1506 
     1868    if(success)
     1869        DIBSECTION_MARK_INVALID(hdc);
    15071870
    15081871    return(success);
     
    15121875BOOL WIN32API PaintRgn( HDC  hdc, HRGN  hrgn)
    15131876{
    1514    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
    1515    if(!pHps)
    1516    {
    1517       SetLastError(ERROR_INVALID_HANDLE_W);
    1518       return FALSE;
    1519    }
    1520 
    1521    return FillRgn(hdc, hrgn, (HBRUSH) pHps->lastBrushKey);
     1877   return FillRgn(hdc, hrgn, (HBRUSH) GetCurrentObject(hdc, OBJ_BRUSH_W));
    15221878}
    15231879//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.