Пример #1
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;
}
Пример #2
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);
}
Пример #3
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;
}
Пример #4
0
int
APIENTRY
NtGdiExtSelectClipRgn(
    HDC  hDC,
    HRGN  hrgn,
    int  fnMode)
{
    int retval;
    DC *dc;
    PREGION prgn;

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

    prgn = REGION_LockRgn(hrgn);

    if ((prgn == NULL) && (fnMode != RGN_COPY))
    {
        EngSetLastError(ERROR_INVALID_HANDLE);
        retval = ERROR;
    }
    else
    {
        retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
    }

    if (prgn)
        REGION_UnlockRgn(prgn);

    DC_UnlockDc(dc);
    return retval;
}
Пример #5
0
DWORD
APIENTRY
NtUserCallHwndParamLock(
   HWND hWnd,
   DWORD Param,
   DWORD Routine)
{
   DWORD Ret = 0;
   PWND Window;
   USER_REFERENCE_ENTRY Ref;
   DECLARE_RETURN(DWORD);

   TRACE("Enter NtUserCallHwndParamLock\n");
   UserEnterExclusive();

   if (!(Window = UserGetWindowObject(hWnd)))
   {
      RETURN( FALSE);
   }
   UserRefObjectCo(Window, &Ref);

   switch (Routine)
   {
      case TWOPARAM_ROUTINE_VALIDATERGN:
      {
          PREGION Rgn = REGION_LockRgn((HRGN)Param);
          if (Rgn)
          {
              Ret = (DWORD)co_UserRedrawWindow( Window, NULL, Rgn, RDW_VALIDATE);
              REGION_UnlockRgn(Rgn);
          }
          break;
      }
   }

   UserDerefObjectCo(Window);

   RETURN( Ret);

CLEANUP:
   TRACE("Leave NtUserCallHwndParamLock, ret=%lu\n",_ret_);
   UserLeave();
   END_CLEANUP;

}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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);
   }
}