Ejemplo n.º 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;
}
Ejemplo n.º 2
0
INT
FASTCALL
GdiGetClipBox(
    _In_ HDC hdc,
    _Out_ LPRECT prc)
{
    PDC pdc;
    INT iComplexity;

    /* Lock the DC */
    pdc = DC_LockDc(hdc);
    if (!pdc)
    {
        return ERROR;
    }

    /* Update RAO region if necessary */
    if (pdc->fs & DC_FLAG_DIRTY_RAO)
        CLIPPING_UpdateGCRegion(pdc);

    /* Check if we have a RAO region (intersection of API and VIS region) */
    if (pdc->prgnRao)
    {
        /* We have a RAO region, use it */
        iComplexity = REGION_GetRgnBox(pdc->prgnRao, prc);
    }
    else
    {
        /* No RAO region means no API region, so use the VIS region */
        ASSERT(pdc->prgnVis);
        iComplexity = REGION_GetRgnBox(pdc->prgnVis, prc);
    }

    /* Unlock the DC */
    DC_UnlockDc(pdc);

    /* Convert the rect to logical coordinates */
    IntDPtoLP(pdc, (LPPOINT)prc, 2);

    /* Return the complexity */
    return iComplexity;
}
Ejemplo n.º 3
0
int FASTCALL GdiExtSelectClipRgn(PDC dc,
                                 HRGN hrgn,
                                 int fnMode)
{
  //  dc->fs &= ~DC_FLAG_DIRTY_RAO;

  if (!hrgn)
  {
    if (fnMode == RGN_COPY)
    {
      if (dc->rosdc.hClipRgn != NULL)
      {
        GreDeleteObject(dc->rosdc.hClipRgn);
        dc->rosdc.hClipRgn = NULL;
      }
    }
    else
    {
      EngSetLastError(ERROR_INVALID_PARAMETER);
      return ERROR;
    }
  }
  else
  {
    if (!dc->rosdc.hClipRgn)
    {
      RECTL rect;
      if(dc->prgnVis)
      {
		REGION_GetRgnBox(dc->prgnVis, &rect);
        dc->rosdc.hClipRgn = IntSysCreateRectRgnIndirect(&rect);
      }
      else
      {
        dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
      }
    }
    if(fnMode == RGN_COPY)
    {
      NtGdiCombineRgn(dc->rosdc.hClipRgn, hrgn, 0, fnMode);
    }
    else
      NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode);
  }

  return CLIPPING_UpdateGCRegion(dc);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
BOOL APIENTRY
NtGdiExtFloodFill(
    HDC  hDC,
    INT  XStart,
    INT  YStart,
    COLORREF  Color,
    UINT  FillType)
{
    PDC dc;
#if 0
    PDC_ATTR   pdcattr;
#endif
    SURFACE    *psurf;
    EXLATEOBJ  exlo;
    BOOL       Ret = FALSE;
    RECTL      DestRect;
    POINTL     Pt;
    ULONG      ConvColor;

    dc = DC_LockDc(hDC);
    if (!dc)
    {
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }
    if (dc->dctype == DC_TYPE_INFO)
    {
        DC_UnlockDc(dc);
        /* Yes, Windows really returns TRUE in this case */
        return TRUE;
    }

    if (!dc->dclevel.pSurface)
    {
        Ret = FALSE;
        goto cleanup;
    }

#if 0
    pdcattr = dc->pdcattr;
#endif

    Pt.x = XStart;
    Pt.y = YStart;
    IntLPtoDP(dc, (LPPOINT)&Pt, 1);

    DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);

    /// FIXME: what about prgnVIS? And what about REAL clipping?
    psurf = dc->dclevel.pSurface;
    if (dc->prgnRao)
    {
        Ret = REGION_PtInRegion(dc->prgnRao, Pt.x, Pt.y);
        if (Ret)
            REGION_GetRgnBox(dc->prgnRao, (LPRECT)&DestRect);
        else
        {
            DC_vFinishBlit(dc, NULL);
            goto cleanup;
        }
    }
    else
    {
        RECTL_vSetRect(&DestRect, 0, 0, psurf->SurfObj.sizlBitmap.cx, psurf->SurfObj.sizlBitmap.cy);
    }

    EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);

    /* Only solid fills supported for now
     * How to support pattern brushes and non standard surfaces (not offering dib functions):
     * Version a (most likely slow): call DrvPatBlt for every pixel
     * Version b: create a flood mask and let MaskBlt blit a masked brush */
    ConvColor = XLATEOBJ_iXlate(&exlo.xlo, Color);
    Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);

    DC_vFinishBlit(dc, NULL);

    EXLATEOBJ_vCleanup(&exlo);

cleanup:
    DC_UnlockDc(dc);
    return Ret;
}
Ejemplo n.º 6
0
/* NtUserEnumDisplayMonitors
 *
 * Enumerates display monitors which intersect the given HDC/cliprect
 *
 * Arguments
 *
 *   hDC
 *      Handle to a DC for which to enum intersecting monitors. If this is NULL
 *      it returns all monitors which are part of the current virtual screen.
 *
 *   pRect
 *      Clipping rectangle with coordinate system origin at the DCs origin if the
 *      given HDC is not NULL or in virtual screen coordinated if it is NULL.
 *      Can be NULL
 *
 *   hMonitorList
 *      Pointer to an array of HMONITOR which is filled with monitor handles.
 *      Can be NULL
 *
 *   monitorRectList
 *      Pointer to an array of RECT which is filled with intersection rectangles.
 *      Can be NULL
 *
 *   listSize
 *      Size of the hMonitorList and monitorRectList arguments. If this is zero
 *      hMonitorList and monitorRectList are ignored.
 *
 * Returns
 *   The number of monitors which intersect the specified region or -1 on failure.
 */
INT
APIENTRY
NtUserEnumDisplayMonitors(
    OPTIONAL IN HDC hDC,
    OPTIONAL IN LPCRECTL pRect,
    OPTIONAL OUT HMONITOR *hMonitorList,
    OPTIONAL OUT PRECTL monitorRectList,
    OPTIONAL IN DWORD listSize)
{
    INT numMonitors, i;
    HMONITOR *safeHMonitorList = NULL;
    PRECTL safeRectList = NULL;
    RECTL rect, *myRect;
    RECTL dcRect;
    NTSTATUS status;

    /* get rect */
    if (pRect != NULL)
    {
        status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
        if (!NT_SUCCESS(status))
        {
            TRACE("MmCopyFromCaller() failed!\n");
            SetLastNtError(status);
            return -1;
        }
    }

    if (hDC != NULL)
    {
        PDC dc;
        INT regionType;

        /* get visible region bounding rect */
        dc = DC_LockDc(hDC);
        if (dc == NULL)
        {
            TRACE("DC_LockDc() failed!\n");
            /* FIXME: setlasterror? */
            return -1;
        }
        regionType = REGION_GetRgnBox(dc->prgnVis, &dcRect);
        DC_UnlockDc(dc);

        if (regionType == 0)
        {
            TRACE("NtGdiGetRgnBox() failed!\n");
            return -1;
        }
        if (regionType == NULLREGION)
            return 0;
        if (regionType == COMPLEXREGION)
        {
            /* TODO: warning */
        }

        /* if hDC and pRect are given the area of interest is pRect with
           coordinate origin at the DC position */
        if (pRect != NULL)
        {
            rect.left += dcRect.left;
            rect.right += dcRect.left;
            rect.top += dcRect.top;
            rect.bottom += dcRect.top;
        }
        /* if hDC is given and pRect is not the area of interest is the
           bounding rect of hDC */
        else
        {
            rect = dcRect;
        }
    }

    if (hDC == NULL && pRect == NULL)
        myRect = NULL;
    else
        myRect = ▭

    /* find intersecting monitors */
    numMonitors = IntGetMonitorsFromRect(myRect, NULL, NULL, 0, 0);
    if (numMonitors == 0 || listSize == 0 ||
            (hMonitorList == NULL && monitorRectList == NULL))
    {
        TRACE("numMonitors = %d\n", numMonitors);
        return numMonitors;
    }

    if (hMonitorList != NULL && listSize != 0)
    {
        safeHMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * listSize, USERTAG_MONITORRECTS);
        if (safeHMonitorList == NULL)
        {
            /* FIXME: EngSetLastError? */
            return -1;
        }
    }
    if (monitorRectList != NULL && listSize != 0)
    {
        safeRectList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * listSize, USERTAG_MONITORRECTS);
        if (safeRectList == NULL)
        {
            ExFreePoolWithTag(safeHMonitorList, USERTAG_MONITORRECTS);
            /* FIXME: EngSetLastError? */
            return -1;
        }
    }

    /* get intersecting monitors */
    numMonitors = IntGetMonitorsFromRect(myRect, safeHMonitorList, safeRectList,
                                         listSize, 0 );

    if (hDC != NULL && pRect != NULL && safeRectList != NULL)
        for (i = 0; i < numMonitors; i++)
        {
            safeRectList[i].left -= dcRect.left;
            safeRectList[i].right -= dcRect.left;
            safeRectList[i].top -= dcRect.top;
            safeRectList[i].bottom -= dcRect.top;
        }

    /* output result */
    if (hMonitorList != NULL && listSize != 0)
    {
        status = MmCopyToCaller(hMonitorList, safeHMonitorList, sizeof (HMONITOR) * listSize);
        ExFreePool(safeHMonitorList);
        if (!NT_SUCCESS(status))
        {
            ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
            SetLastNtError(status);
            return -1;
        }
    }
    if (monitorRectList != NULL && listSize != 0)
    {
        status = MmCopyToCaller(monitorRectList, safeRectList, sizeof (RECT) * listSize);
        ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
        if (!NT_SUCCESS(status))
        {
            SetLastNtError(status);
            return -1;
        }
    }

    return numMonitors;
}
Ejemplo n.º 7
0
/* NtUserEnumDisplayMonitors
 *
 * Enumerates display monitors which intersect the given HDC/cliprect
 *
 * Arguments
 *
 *   hdc
 *      Handle to a DC for which to enum intersecting monitors. If this is NULL
 *      it returns all monitors which are part of the current virtual screen.
 *
 *   pUnsafeRect
 *      Clipping rectangle with coordinate system origin at the DCs origin if the
 *      given HDC is not NULL or in virtual screen coordinated if it is NULL.
 *      Can be NULL
 *
 *   phUnsafeMonitorList
 *      Pointer to an array of HMONITOR which is filled with monitor handles.
 *      Can be NULL
 *
 *   prcUnsafeMonitorList
 *      Pointer to an array of RECT which is filled with intersection rectangles.
 *      Can be NULL
 *
 *   dwListSize
 *      Size of the hMonitorList and monitorRectList arguments. If this is zero
 *      hMonitorList and monitorRectList are ignored.
 *
 * Returns
 *   The number of monitors which intersect the specified region or -1 on failure.
 */
INT
APIENTRY
NtUserEnumDisplayMonitors(
    OPTIONAL IN HDC hdc,
    OPTIONAL IN LPCRECTL pUnsafeRect,
    OPTIONAL OUT HMONITOR *phUnsafeMonitorList,
    OPTIONAL OUT PRECTL prcUnsafeMonitorList,
    OPTIONAL IN DWORD dwListSize)
{
    INT cMonitors, iRet = -1, i;
    HMONITOR *phMonitorList = NULL;
    PRECTL prcMonitorList = NULL;
    RECTL rc, *pRect;
    RECTL DcRect = {0};
    NTSTATUS Status;

    /* Get rectangle */
    if (pUnsafeRect != NULL)
    {
        Status = MmCopyFromCaller(&rc, pUnsafeRect, sizeof(RECT));
        if (!NT_SUCCESS(Status))
        {
            TRACE("MmCopyFromCaller() failed!\n");
            SetLastNtError(Status);
            return -1;
        }
    }

    if (hdc != NULL)
    {
        PDC pDc;
        INT iRgnType;

        /* Get visible region bounding rect */
        pDc = DC_LockDc(hdc);
        if (pDc == NULL)
        {
            TRACE("DC_LockDc() failed!\n");
            /* FIXME: setlasterror? */
            return -1;
        }
        iRgnType = REGION_GetRgnBox(pDc->prgnVis, &DcRect);
        DC_UnlockDc(pDc);

        if (iRgnType == 0)
        {
            TRACE("NtGdiGetRgnBox() failed!\n");
            return -1;
        }
        if (iRgnType == NULLREGION)
            return 0;
        if (iRgnType == COMPLEXREGION)
        {
            /* TODO: Warning */
        }

        /* If hdc and pRect are given the area of interest is pRect with
           coordinate origin at the DC position */
        if (pUnsafeRect != NULL)
        {
            rc.left += DcRect.left;
            rc.right += DcRect.left;
            rc.top += DcRect.top;
            rc.bottom += DcRect.top;
        }
        /* If hdc is given and pRect is not the area of interest is the
           bounding rect of hdc */
        else
        {
            rc = DcRect;
        }
    }

    if (hdc == NULL && pUnsafeRect == NULL)
        pRect = NULL;
    else
        pRect = &rc;

    UserEnterShared();

    /* Find intersecting monitors */
    cMonitors = IntGetMonitorsFromRect(pRect, NULL, NULL, 0, MONITOR_DEFAULTTONULL);
    if (cMonitors == 0 || dwListSize == 0 ||
        (phUnsafeMonitorList == NULL && prcUnsafeMonitorList == NULL))
    {
        /* Simple case - just return monitors count */
        TRACE("cMonitors = %d\n", cMonitors);
        iRet = cMonitors;
        goto cleanup;
    }

    /* Allocate safe buffers */
    if (phUnsafeMonitorList != NULL && dwListSize != 0)
    {
        phMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * dwListSize, USERTAG_MONITORRECTS);
        if (phMonitorList == NULL)
        {
            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto cleanup;
        }
    }
    if (prcUnsafeMonitorList != NULL && dwListSize != 0)
    {
        prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * dwListSize, USERTAG_MONITORRECTS);
        if (prcMonitorList == NULL)
        {
            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto cleanup;
        }
    }

    /* Get intersecting monitors */
    cMonitors = IntGetMonitorsFromRect(pRect, phMonitorList, prcMonitorList,
                                       dwListSize, MONITOR_DEFAULTTONULL);

    if (hdc != NULL && pRect != NULL && prcMonitorList != NULL)
        for (i = 0; i < cMonitors; i++)
        {
            prcMonitorList[i].left -= DcRect.left;
            prcMonitorList[i].right -= DcRect.left;
            prcMonitorList[i].top -= DcRect.top;
            prcMonitorList[i].bottom -= DcRect.top;
        }

    /* Output result */
    if (phUnsafeMonitorList != NULL && dwListSize != 0)
    {
        Status = MmCopyToCaller(phUnsafeMonitorList, phMonitorList, sizeof(HMONITOR) * dwListSize);
        if (!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            goto cleanup;
        }
    }
    if (prcUnsafeMonitorList != NULL && dwListSize != 0)
    {
        Status = MmCopyToCaller(prcUnsafeMonitorList, prcMonitorList, sizeof(RECT) * dwListSize);
        if (!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            goto cleanup;
        }
    }

    /* Return monitors count on success */
    iRet = cMonitors;

cleanup:
    if (phMonitorList)
        ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS);
    if (prcMonitorList)
        ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS);

    UserLeave();
    return iRet;
}
Ejemplo n.º 8
0
DWORD
APIENTRY
NtGdiGetBoundsRect(
    IN HDC hdc,
    OUT LPRECT prc,
    IN DWORD flags)
{
    DWORD ret;
    PDC pdc;
    RECT rc;

    /* Lock the DC */
    if (!(pdc = DC_LockDc(hdc))) return 0;

    if (!(flags & DCB_WINDOWMGR))
    {
       rc = pdc->erclBoundsApp;

       if (RECTL_bIsEmptyRect(&rc))
       {
          rc.left = rc.top = rc.right = rc.bottom = 0;
          ret = DCB_RESET;
       }
       else
       {
          RECTL rcRgn;
          if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc);
          if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn))
          {
             REGION_GetRgnBox(pdc->prgnVis, &rcRgn);
          }
          rc.left   = max( rc.left, 0 );
          rc.top    = max( rc.top, 0 );
          rc.right  = min( rc.right,  rcRgn.right - rcRgn.left );
          rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top );
          DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top);
          DPRINT("rc  l %d t %d\n",rc.left,rc.top);
          DPRINT("    r %d b %d\n",rc.right,rc.bottom);
          ret = DCB_SET;
       }
       IntDPtoLP( pdc, &rc, 2 );
       DPRINT("rc1 l %d t %d\n",rc.left,rc.top);
       DPRINT("    r %d b %d\n",rc.right,rc.bottom);
    }
    else
    {
       rc = pdc->erclBounds;
       ret = DCB_SET;
    }

    /* Copy the rect to the caller */
    _SEH2_TRY
    {
        ProbeForWrite(prc, sizeof(RECT), 1);
        *prc = rc;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        ret = 0;
    }
    _SEH2_END;

    if (flags & DCB_RESET)
    {
        if (!(flags & DCB_WINDOWMGR))
        {
           pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
           pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
        }
        else
        {
           pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
           pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
        }
    }

    DC_UnlockDc(pdc);
    return ret;
}