Пример #1
0
int FASTCALL
CLIPPING_UpdateGCRegion(DC* Dc)
{
   PROSRGNDATA CombinedRegion;
   HRGN hRgnVis;
   PREGION prgnClip, prgnGCClip;

    // would prefer this, but the rest of the code sucks
//    ASSERT(Dc->rosdc.hGCClipRgn);
//    ASSERT(Dc->rosdc.hClipRgn);
   ASSERT(Dc->prgnVis);
   hRgnVis = Dc->prgnVis->BaseObject.hHmgr;

   if (Dc->rosdc.hGCClipRgn == NULL)
      Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);

   prgnGCClip = REGION_LockRgn(Dc->rosdc.hGCClipRgn);
   ASSERT(prgnGCClip);

   if (Dc->rosdc.hClipRgn == NULL)
      IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, NULL, RGN_COPY);
   else
   {
      prgnClip = REGION_LockRgn(Dc->rosdc.hClipRgn); // FIXME: locking order, ugh
      IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, prgnClip, RGN_AND);
      REGION_UnlockRgn(prgnClip);
   }
   REGION_UnlockRgn(prgnGCClip);

   NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);

   if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
   {
     CLIPOBJ *CombinedClip;

     CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
        CombinedRegion->Buffer,
        &CombinedRegion->rdh.rcBound);

     RGNOBJAPI_Unlock(CombinedRegion);

     if ( !CombinedClip )
     {
       DPRINT1("IntEngCreateClipRegion() failed\n");
       return ERROR;
     }

     if(Dc->rosdc.CombinedClip != NULL)
       IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);

      Dc->rosdc.CombinedClip = CombinedClip ;
   }

   return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y);
}
Пример #2
0
int APIENTRY NtGdiExcludeClipRect(HDC  hDC,
                         int  LeftRect,
                         int  TopRect,
                         int  RightRect,
                         int  BottomRect)
{
   INT Result;
   RECTL Rect;
   PREGION prgnNew, prgnClip;
   PDC dc = DC_LockDc(hDC);

   if (!dc)
   {
      EngSetLastError(ERROR_INVALID_HANDLE);
      return ERROR;
   }

   Rect.left = LeftRect;
   Rect.top = TopRect;
   Rect.right = RightRect;
   Rect.bottom = BottomRect;

   IntLPtoDP(dc, (LPPOINT)&Rect, 2);

   prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
   if (!prgnNew)
   {
      Result = ERROR;
   }
   else
   {
      if (!dc->rosdc.hClipRgn)
      {
         dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
         prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
         IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
         REGION_UnlockRgn(prgnClip);
         Result = SIMPLEREGION;
      }
      else
      {
         prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
         Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF);
         REGION_UnlockRgn(prgnClip);
      }
      REGION_Delete(prgnNew);
   }
   if (Result != ERROR)
      CLIPPING_UpdateGCRegion(dc);

   DC_UnlockDc(dc);

   return Result;
}
Пример #3
0
INT FASTCALL
GdiSelectVisRgn(HDC hdc, HRGN hrgn)
{
  int retval;
  DC *dc;
  PREGION prgn;

  if (!hrgn)
  {
  	EngSetLastError(ERROR_INVALID_PARAMETER);
  	return ERROR;
  }
  if (!(dc = DC_LockDc(hdc)))
  {
  	EngSetLastError(ERROR_INVALID_HANDLE);
  	return ERROR;
  }

  dc->fs &= ~DC_FLAG_DIRTY_RAO;

  ASSERT (dc->prgnVis != NULL);

  prgn = RGNOBJAPI_Lock(hrgn, NULL);
  retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR;
  RGNOBJAPI_Unlock(prgn);
  if ( retval != ERROR )
  {
    IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
    CLIPPING_UpdateGCRegion(dc);
  }
  DC_UnlockDc(dc);

  return retval;
}
Пример #4
0
VOID FASTCALL
co_VIS_WindowLayoutChanged(
   PWND Wnd,
   PREGION NewlyExposed)
{
   PWND Parent;
   USER_REFERENCE_ENTRY Ref;

   ASSERT_REFS_CO(Wnd);

   Parent = Wnd->spwndParent;
   if(Parent)
   {
       PREGION TempRgn = IntSysCreateRectpRgn(0, 0, 0, 0);

       if (!TempRgn)
           return;

       IntGdiCombineRgn(TempRgn, NewlyExposed, NULL, RGN_COPY);
       REGION_bOffsetRgn(TempRgn,
                         Wnd->rcWindow.left - Parent->rcClient.left,
                         Wnd->rcWindow.top - Parent->rcClient.top);

       UserRefObjectCo(Parent, &Ref);
       co_UserRedrawWindow(Parent, NULL, TempRgn,
                           RDW_FRAME | RDW_ERASE | RDW_INVALIDATE |
                           RDW_ALLCHILDREN);
       UserDerefObjectCo(Parent);

       REGION_Delete(TempRgn);
   }
}
Пример #5
0
INT FASTCALL
GdiGetClipBox(HDC hDC, PRECTL rc)
{
   INT retval;
   PDC dc;
   PROSRGNDATA pRgnNew, pRgn = NULL;
   BOOL Unlock = FALSE; //Small hack

   if (!(dc = DC_LockDc(hDC)))
   {
      return ERROR;
   }

   /* FIXME! Rao and Vis only! */
   if (dc->prgnAPI) // APIRGN
   {
      pRgn = dc->prgnAPI;
   }
   else if (dc->dclevel.prgnMeta) // METARGN
   {
      pRgn = dc->dclevel.prgnMeta;
   }
   else if (dc->rosdc.hClipRgn)
   {
	   Unlock = TRUE ;
       pRgn = REGION_LockRgn(dc->rosdc.hClipRgn); // CLIPRGN
   }

   if (pRgn)
   {
      pRgnNew = IntSysCreateRectpRgn( 0, 0, 0, 0 );

	  if (!pRgnNew)
      {
         DC_UnlockDc(dc);
		 if(Unlock) REGION_UnlockRgn(pRgn);
         return ERROR;
      }

      IntGdiCombineRgn(pRgnNew, dc->prgnVis, pRgn, RGN_AND);

      retval = REGION_GetRgnBox(pRgnNew, rc);

	  REGION_Delete(pRgnNew);

      DC_UnlockDc(dc);
	  if(Unlock) REGION_UnlockRgn(pRgn);
      return retval;
   }

   retval = REGION_GetRgnBox(dc->prgnVis, rc);
   IntDPtoLP(dc, (LPPOINT)rc, 2);
   DC_UnlockDc(dc);

   return retval;
}
Пример #6
0
int
FASTCALL
IntGdiExtSelectClipRgn(
    PDC dc,
    PREGION prgn,
    int fnMode)
{
    if (fnMode == RGN_COPY)
    {
        if (!prgn)
        {
            if (dc->dclevel.prgnClip != NULL)
            {
                REGION_Delete(dc->dclevel.prgnClip);
                dc->dclevel.prgnClip = NULL;
                dc->fs |= DC_FLAG_DIRTY_RAO;
            }
            return SIMPLEREGION;
        }

        if (!dc->dclevel.prgnClip)
            dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);

        dc->fs |= DC_FLAG_DIRTY_RAO;

        return IntGdiCombineRgn(dc->dclevel.prgnClip, prgn, NULL, RGN_COPY);
    }

    ASSERT(prgn != NULL);

    if (!dc->dclevel.prgnClip)
    {
        RECTL rect;

        REGION_GetRgnBox(dc->prgnVis, &rect);
        dc->dclevel.prgnClip = IntSysCreateRectpRgnIndirect(&rect);
    }

    dc->fs |= DC_FLAG_DIRTY_RAO;

    return IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgn, fnMode);
}
Пример #7
0
int
FASTCALL
IntGdiSetMetaRgn(PDC pDC)
{
  INT Ret = ERROR;
  PROSRGNDATA TempRgn;

  if ( pDC->dclevel.prgnMeta )
  {
     if ( pDC->dclevel.prgnClip )
     {
        TempRgn = IntSysCreateRectpRgn(0,0,0,0);
        if (TempRgn)
        {
           Ret = IntGdiCombineRgn( TempRgn,
                     pDC->dclevel.prgnMeta,
                     pDC->dclevel.prgnClip,
                                   RGN_AND);
           if ( Ret )
           {
              GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnMeta->BaseObject);
              if (!((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.ulShareCount)
                 REGION_Delete(pDC->dclevel.prgnMeta);

              pDC->dclevel.prgnMeta = TempRgn;

              GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnClip->BaseObject);
              if (!((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.ulShareCount)
                 REGION_Delete(pDC->dclevel.prgnClip);

              pDC->dclevel.prgnClip = NULL;

              IntGdiReleaseRaoRgn(pDC);
           }
           else
              REGION_Delete(TempRgn);
        }
     }
     else
        Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
  }
  else
  {
     if ( pDC->dclevel.prgnClip )
     {
        Ret = REGION_Complexity(pDC->dclevel.prgnClip);
        pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
        pDC->dclevel.prgnClip = NULL;
     }
     else
       Ret = SIMPLEREGION;
  }
  return Ret;
}
Пример #8
0
VOID
FASTCALL
DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
{
    DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr);

    /* Copy full DC attribute */
    *pdcDst->pdcattr = *pdcSrc->pdcattr;

    /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
    /* The VisRectRegion field needs to be set to a valid state */

    /* Mark some fields as dirty */
    pdcDst->pdcattr->ulDirty_ |= (DIRTY_FILL|DIRTY_LINE|DIRTY_TEXT|DIRTY_BACKGROUND|DIRTY_CHARSET|DC_ICM_NOT_CALIBRATED|DC_ICM_NOT_SET); // Note: Use if, To is FALSE....

    /* Copy DC level */
    pdcDst->dclevel.pColorSpace     = pdcSrc->dclevel.pColorSpace;
    pdcDst->dclevel.laPath          = pdcSrc->dclevel.laPath;
    pdcDst->dclevel.ca              = pdcSrc->dclevel.ca;
    pdcDst->dclevel.mxWorldToDevice = pdcSrc->dclevel.mxWorldToDevice;
    pdcDst->dclevel.mxDeviceToWorld = pdcSrc->dclevel.mxDeviceToWorld;
    pdcDst->dclevel.mxWorldToPage   = pdcSrc->dclevel.mxWorldToPage;
    pdcDst->dclevel.efM11PtoD       = pdcSrc->dclevel.efM11PtoD;
    pdcDst->dclevel.efM22PtoD       = pdcSrc->dclevel.efM22PtoD;
    pdcDst->dclevel.sizl            = pdcSrc->dclevel.sizl;
    pdcDst->dclevel.hpal            = pdcSrc->dclevel.hpal;

    /* Handle references here correctly */
    DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill);
    DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
    DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal);

    /* Dereference the old font, reference the new one */
    if (pdcDst->dclevel.plfnt) LFONT_ShareUnlockFont(pdcDst->dclevel.plfnt); /// @todo should aways be != NULL
    GDIOBJ_vReferenceObjectByPointer(&pdcSrc->dclevel.plfnt->BaseObject);
    pdcDst->dclevel.plfnt           = pdcSrc->dclevel.plfnt;

    /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
    if (!To)
    {
        IntGdiExtSelectClipRgn(pdcDst, pdcSrc->dclevel.prgnClip, RGN_COPY);
        if (pdcDst->dclevel.prgnMeta)
        {
            REGION_Delete(pdcDst->dclevel.prgnMeta);
            pdcDst->dclevel.prgnMeta = NULL;
        }
        if (pdcSrc->dclevel.prgnMeta)
        {
            pdcDst->dclevel.prgnMeta = IntSysCreateRectpRgn(0, 0, 0, 0);
            IntGdiCombineRgn(pdcDst->dclevel.prgnMeta, pdcSrc->dclevel.prgnMeta, NULL, RGN_COPY);
        }
        pdcDst->fs |= DC_FLAG_DIRTY_RAO;
    }
}
Пример #9
0
VOID
FASTCALL
GdiSelectVisRgn(
    HDC hdc,
    PREGION prgn)
{
    DC *dc;

    if (!(dc = DC_LockDc(hdc)))
    {
        EngSetLastError(ERROR_INVALID_HANDLE);
        return;
    }

    dc->fs |= DC_FLAG_DIRTY_RAO;

    ASSERT(dc->prgnVis != NULL);
    ASSERT(prgn != NULL);

    IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY);
    REGION_bOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);

    DC_UnlockDc(dc);
}
Пример #10
0
INT FASTCALL
NEW_CLIPPING_UpdateGCRegion(PDC pDC)
{
  CLIPOBJ * co;

  /* Must have VisRgn set to a valid state! */
  ASSERT (pDC->prgnVis);

  if (pDC->prgnAPI)
  {
     REGION_Delete(pDC->prgnAPI);
     pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
  }

  if (pDC->prgnRao)
  {
     REGION_Delete(pDC->prgnRao);
     pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
  }

  if (pDC->dclevel.prgnMeta && pDC->dclevel.prgnClip)
  {
     IntGdiCombineRgn( pDC->prgnAPI,
                       pDC->dclevel.prgnClip,
                       pDC->dclevel.prgnMeta,
                       RGN_AND);
  }
  else
  {
     if (pDC->dclevel.prgnClip)
     {
        IntGdiCombineRgn( pDC->prgnAPI,
                          pDC->dclevel.prgnClip,
                          NULL,
                          RGN_COPY);
     }
     else if (pDC->dclevel.prgnMeta)
     {
        IntGdiCombineRgn( pDC->prgnAPI,
                          pDC->dclevel.prgnMeta,
                          NULL,
                          RGN_COPY);
     }
  }

  IntGdiCombineRgn( pDC->prgnRao,
                    pDC->prgnVis,
                    pDC->prgnAPI,
                    RGN_AND);

  RtlCopyMemory(&pDC->erclClip,
                &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound,
                sizeof(RECTL));

  pDC->fs &= ~DC_FLAG_DIRTY_RAO;

  IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);

  // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
  // the rects from region objects rects in pClipRgn->Buffer.
  // With pDC->co.pClipRgn->Buffer,
  // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;

  co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount,
                               ((PROSRGNDATA)pDC->prgnRao)->Buffer,
                                 &pDC->erclClip);
  if (co)
  {
    if (pDC->rosdc.CombinedClip != NULL)
      IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);

    pDC->rosdc.CombinedClip = co;
  }

  return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
}
Пример #11
0
/* See wine, msdn, osr and  Feng Yuan - Windows Graphics Programming Win32 Gdi And Directdraw

   1st: http://www.codeproject.com/gdi/cliprgnguide.asp is wrong!

   The intersection of the clip with the meta region is not Rao it's API!
   Go back and read 7.2 Clipping pages 418-19:
   Rao = API & Vis:
   1) The Rao region is the intersection of the API region and the system region,
      named after the Microsoft engineer who initially proposed it.
   2) The Rao region can be calculated from the API region and the system region.

   API:
      API region is the intersection of the meta region and the clipping region,
      clearly named after the fact that it is controlled by GDI API calls.
*/
INT
APIENTRY
NtGdiGetRandomRgn(
    HDC hdc,
    HRGN hrgnDest,
    INT iCode)
{
    INT ret = 0;
    PDC pdc;
    HRGN hrgnSrc = NULL;
    POINTL ptlOrg;

    pdc = DC_LockDc(hdc);
    if (!pdc)
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return -1;
    }

    switch (iCode)
    {
        case CLIPRGN:
            hrgnSrc = pdc->rosdc.hClipRgn;
//            if (pdc->dclevel.prgnClip) hrgnSrc = pdc->dclevel.prgnClip->BaseObject.hHmgr;
            break;
        case METARGN:
            if (pdc->dclevel.prgnMeta)
                hrgnSrc = pdc->dclevel.prgnMeta->BaseObject.hHmgr;
            break;
        case APIRGN:
            if (pdc->prgnAPI) hrgnSrc = pdc->prgnAPI->BaseObject.hHmgr;
//            else if (pdc->dclevel.prgnClip) hrgnSrc = pdc->dclevel.prgnClip->BaseObject.hHmgr;
            else if (pdc->rosdc.hClipRgn) hrgnSrc = pdc->rosdc.hClipRgn;
            else if (pdc->dclevel.prgnMeta) hrgnSrc = pdc->dclevel.prgnMeta->BaseObject.hHmgr;
            break;
        case SYSRGN:
            if (pdc->prgnVis)
            {
                PREGION prgnDest = REGION_LockRgn(hrgnDest);
                ret = IntGdiCombineRgn(prgnDest, pdc->prgnVis, 0, RGN_COPY) == ERROR ? -1 : 1;
                REGION_UnlockRgn(prgnDest);
            }
            break;
        default:
            hrgnSrc = NULL;
    }

    if (hrgnSrc)
    {
        ret = NtGdiCombineRgn(hrgnDest, hrgnSrc, 0, RGN_COPY) == ERROR ? -1 : 1;
    }

    if (iCode == SYSRGN)
    {
        ptlOrg = pdc->ptlDCOrig;
        NtGdiOffsetRgn(hrgnDest, ptlOrg.x, ptlOrg.y );
    }

    DC_UnlockDc(pdc);

    return ret;
}
Пример #12
0
PREGION FASTCALL
VIS_ComputeVisibleRegion(
   PWND Wnd,
   BOOLEAN ClientArea,
   BOOLEAN ClipChildren,
   BOOLEAN ClipSiblings)
{
   PREGION VisRgn, ClipRgn;
   PWND PreviousWindow, CurrentWindow, CurrentSibling;

   if (!Wnd || !(Wnd->style & WS_VISIBLE))
   {
      return NULL;
   }

   VisRgn = NULL;

   if (ClientArea)
   {
      VisRgn = IntSysCreateRectpRgnIndirect(&Wnd->rcClient);
   }
   else
   {
      VisRgn = IntSysCreateRectpRgnIndirect(&Wnd->rcWindow);
   }

   /*
    * Walk through all parent windows and for each clip the visble region
    * to the parent's client area and exclude all siblings that are over
    * our window.
    */

   PreviousWindow = Wnd;
   CurrentWindow = Wnd->spwndParent;
   while (CurrentWindow)
   {
      if (!VerifyWnd(CurrentWindow))
      {
         ERR("ATM the Current Window or Parent is dead! %p\n",CurrentWindow);
         if (VisRgn)
             REGION_Delete(VisRgn);
         return NULL;
      }

      if (!(CurrentWindow->style & WS_VISIBLE))
      {
         if (VisRgn)
             REGION_Delete(VisRgn);
         return NULL;
      }

      ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentWindow->rcClient);
      IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
      REGION_Delete(ClipRgn);

      if ((PreviousWindow->style & WS_CLIPSIBLINGS) ||
          (PreviousWindow == Wnd && ClipSiblings))
      {
         CurrentSibling = CurrentWindow->spwndChild;
         while ( CurrentSibling != NULL &&
                 CurrentSibling != PreviousWindow )
         {
            if ((CurrentSibling->style & WS_VISIBLE) &&
                !(CurrentSibling->ExStyle & WS_EX_TRANSPARENT))
            {
               ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentSibling->rcWindow);
               /* Combine it with the window region if available */
               if (CurrentSibling->hrgnClip && !(CurrentSibling->style & WS_MINIMIZE))
               {
                  PREGION SiblingClipRgn = REGION_LockRgn(CurrentSibling->hrgnClip);
                  if (SiblingClipRgn)
                  {
                      REGION_bOffsetRgn(ClipRgn, -CurrentSibling->rcWindow.left, -CurrentSibling->rcWindow.top);
                      IntGdiCombineRgn(ClipRgn, ClipRgn, SiblingClipRgn, RGN_AND);
                      REGION_bOffsetRgn(ClipRgn, CurrentSibling->rcWindow.left, CurrentSibling->rcWindow.top);
                      REGION_UnlockRgn(SiblingClipRgn);
                  }
               }
               IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
               REGION_Delete(ClipRgn);
            }
            CurrentSibling = CurrentSibling->spwndNext;
         }
      }

      PreviousWindow = CurrentWindow;
      CurrentWindow = CurrentWindow->spwndParent;
   }

   if (ClipChildren)
   {
      CurrentWindow = Wnd->spwndChild;
      while (CurrentWindow)
      {
         if ((CurrentWindow->style & WS_VISIBLE) &&
             !(CurrentWindow->ExStyle & WS_EX_TRANSPARENT))
         {
            ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentWindow->rcWindow);
            /* Combine it with the window region if available */
            if (CurrentWindow->hrgnClip && !(CurrentWindow->style & WS_MINIMIZE))
            {
               PREGION CurrentRgnClip = REGION_LockRgn(CurrentWindow->hrgnClip);
               if (CurrentRgnClip)
               {
                   REGION_bOffsetRgn(ClipRgn, -CurrentWindow->rcWindow.left, -CurrentWindow->rcWindow.top);
                   IntGdiCombineRgn(ClipRgn, ClipRgn, CurrentRgnClip, RGN_AND);
                   REGION_bOffsetRgn(ClipRgn, CurrentWindow->rcWindow.left, CurrentWindow->rcWindow.top);
                   REGION_UnlockRgn(CurrentRgnClip);
               }
            }
            IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
            REGION_Delete(ClipRgn);
         }
         CurrentWindow = CurrentWindow->spwndNext;
      }
   }

   if (Wnd->hrgnClip && !(Wnd->style & WS_MINIMIZE))
   {
      PREGION WndRgnClip = REGION_LockRgn(Wnd->hrgnClip);
      if (WndRgnClip)
      {
          REGION_bOffsetRgn(VisRgn, -Wnd->rcWindow.left, -Wnd->rcWindow.top);
          IntGdiCombineRgn(VisRgn, VisRgn, WndRgnClip, RGN_AND);
          REGION_bOffsetRgn(VisRgn, Wnd->rcWindow.left, Wnd->rcWindow.top);
          REGION_UnlockRgn(WndRgnClip);
      }
   }

   return VisRgn;
}
Пример #13
0
VOID
FASTCALL
DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags)
{
   PREGION RgnVisible = NULL;
   ULONG DcxFlags;
   PWND DesktopWindow;

   if (Flags & DCX_PARENTCLIP)
   {
      PWND Parent;

      Parent = Window->spwndParent;
      if (!Parent)
      {
         RgnVisible = NULL;
         goto noparent;
      }

      if (Parent->style & WS_CLIPSIBLINGS)
      {
         DcxFlags = DCX_CLIPSIBLINGS |
                    (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
      }
      else
      {
         DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
      }
      RgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags);
   }
   else if (Window == NULL)
   {
      DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
      if (NULL != DesktopWindow)
      {
         RgnVisible = IntSysCreateRectpRgnIndirect(&DesktopWindow->rcWindow);
      }
      else
      {
         RgnVisible = NULL;
      }
   }
   else
   {
      RgnVisible = DceGetVisRgn(Window, Flags, 0, 0);
   }

noparent:
   if (Flags & DCX_INTERSECTRGN)
   {
      PREGION RgnClip = NULL;

      if (Dce->hrgnClip != NULL)
          RgnClip = REGION_LockRgn(Dce->hrgnClip);

      if (RgnClip)
      {
         IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_AND);
         REGION_UnlockRgn(RgnClip);
      }
      else
      {
         if (RgnVisible != NULL)
         {
            REGION_Delete(RgnVisible);
         }
         RgnVisible = IntSysCreateRectpRgn(0, 0, 0, 0);
      }
   }
   else if ((Flags & DCX_EXCLUDERGN) && Dce->hrgnClip != NULL)
   {
       PREGION RgnClip = REGION_LockRgn(Dce->hrgnClip);
       IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_DIFF);
       REGION_UnlockRgn(RgnClip);
   }

   Dce->DCXFlags &= ~DCX_DCEDIRTY;
   GdiSelectVisRgn(Dce->hDC, RgnVisible);
   /* Tell GDI driver */
   if (Window)
       IntEngWindowChanged(Window, WOC_RGN_CLIENT);

   if (RgnVisible != NULL)
   {
      REGION_Delete(RgnVisible);
   }
}