Esempio n. 1
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;
}
Esempio n. 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);
}
Esempio n. 3
0
BOOL APIENTRY NtGdiRectVisible(HDC  hDC,
                      LPRECT UnsafeRect)
{
   NTSTATUS Status = STATUS_SUCCESS;
   PROSRGNDATA Rgn;
   PDC dc = DC_LockDc(hDC);
   BOOL Result = FALSE;
   RECTL Rect;

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

   _SEH2_TRY
   {
      ProbeForRead(UnsafeRect,
                   sizeof(RECT),
                   1);
      Rect = *UnsafeRect;
   }
   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
   {
      Status = _SEH2_GetExceptionCode();
   }
   _SEH2_END;

   if(!NT_SUCCESS(Status))
   {
      DC_UnlockDc(dc);
      SetLastNtError(Status);
      return FALSE;
   }

   if (dc->rosdc.hGCClipRgn)
   {
      if((Rgn = (PROSRGNDATA)RGNOBJAPI_Lock(dc->rosdc.hGCClipRgn, NULL)))
      {
         IntLPtoDP(dc, (LPPOINT)&Rect, 2);
         Result = REGION_RectInRegion(Rgn, &Rect);
         RGNOBJAPI_Unlock(Rgn);
      }
   }
   DC_UnlockDc(dc);

   return Result;
}
Esempio n. 4
0
/*
 * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND
 */
BOOLEAN
FASTCALL
IntEngWndUpdateClipObj(
  WNDGDI *WndObjInt,
  PWND Window)
{
  HRGN hVisRgn;
  PROSRGNDATA visRgn;
  CLIPOBJ *ClipObj = NULL;
  CLIPOBJ *OldClipObj;

  DPRINT("IntEngWndUpdateClipObj\n");

  hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
  if (hVisRgn != NULL)
  {
    NtGdiOffsetRgn(hVisRgn, Window->rcClient.left, Window->rcClient.top);
    visRgn = RGNOBJAPI_Lock(hVisRgn, NULL);
    if (visRgn != NULL)
    {
      if (visRgn->rdh.nCount > 0)
      {
        ClipObj = IntEngCreateClipRegion(visRgn->rdh.nCount, visRgn->Buffer,
                                         &visRgn->rdh.rcBound);
        DPRINT("Created visible region with %lu rects\n", visRgn->rdh.nCount);
        DPRINT("  BoundingRect: %d, %d  %d, %d\n",
               visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,
               visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);
        {
          ULONG i;
          for (i = 0; i < visRgn->rdh.nCount; i++)
          {
            DPRINT("  Rect #%lu: %ld,%ld  %ld,%ld\n", i+1,
                   visRgn->Buffer[i].left, visRgn->Buffer[i].top,
                   visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);
          }
        }
      }
      RGNOBJAPI_Unlock(visRgn);
    }
    else
    {
      DPRINT1("Warning: Couldn't lock visible region of window DC\n");
    }
    GreDeleteObject(hVisRgn);
  }
  else
  {
    DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n");
  }

  if (ClipObj == NULL)
  {
    /* Fall back to client rect */
    ClipObj = IntEngCreateClipRegion(1, &Window->rcClient,
                                     &Window->rcClient);
  }

  if (ClipObj == NULL)
  {
    DPRINT1("Warning: IntEngCreateClipRegion() failed!\n");
    return FALSE;
  }

  RtlCopyMemory(&WndObjInt->WndObj.coClient, ClipObj, sizeof (CLIPOBJ));
  RtlCopyMemory(&WndObjInt->WndObj.rclClient, &Window->rcClient, sizeof (RECT));
  OldClipObj = InterlockedExchangePointer((PVOID*)&WndObjInt->ClientClipObj, ClipObj);
  if (OldClipObj != NULL)
    IntEngDeleteClipRegion(OldClipObj);

  return TRUE;
}