Ejemplo n.º 1
0
/* UserUpdateMonitorSize
 *
 * Reset size of the monitor using atached device
 *
 * Arguments
 *
 *   PMONITOR
 *      pGdiDevice  Pointer to the PDEVOBJ, which size has changed
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS NTAPI
UserUpdateMonitorSize(IN HDEV hDev)
{
	PMONITOR pMonitor;
    SIZEL DeviceSize;

    /* Find monitor attached to given device */
    for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor = pMonitor->pMonitorNext)
    {
        if (pMonitor->hDev == hDev)
            break;
    }

    if (pMonitor == NULL)
    {
        /* No monitor has been found */
        return STATUS_INVALID_PARAMETER;
    }

    /* Get the size of the hdev */
    PDEVOBJ_sizl((PPDEVOBJ)hDev, &DeviceSize);

    /* Update monitor size */
    pMonitor->rcMonitor.left  = 0;
    pMonitor->rcMonitor.top   = 0;
    pMonitor->rcMonitor.right  = pMonitor->rcMonitor.left + DeviceSize.cx;
    pMonitor->rcMonitor.bottom = pMonitor->rcMonitor.top + DeviceSize.cy;
    pMonitor->rcWork = pMonitor->rcMonitor;

    /* Destroy monitor region... */
    if (pMonitor->hrgnMonitor)
    {
        GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
        GreDeleteObject(pMonitor->hrgnMonitor);
    }

    /* ...and create new one */
    pMonitor->hrgnMonitor = NtGdiCreateRectRgn(
        pMonitor->rcMonitor.left,
        pMonitor->rcMonitor.top,
        pMonitor->rcMonitor.right,
        pMonitor->rcMonitor.bottom);
    if (pMonitor->hrgnMonitor)
        IntGdiSetRegionOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);

    return STATUS_SUCCESS;
}
Ejemplo n.º 2
0
static
void
DC_vUpdateDC(PDC pdc)
{
    HRGN hVisRgn ;
    PPDEVOBJ ppdev = pdc->ppdev ;

    pdc->dhpdev = ppdev->dhpdev;

    SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
    pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);

    PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl);
    hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
    ASSERT(hVisRgn);
    GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
    GreDeleteObject(hVisRgn);

    pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
    pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;

    /* Mark EBRUSHOBJs as dirty */
    pdc->pdcattr->ulDirty_ |= DIRTY_DEFAULT ;
}
Ejemplo n.º 3
0
/*
 * @implemented
 */
HRGN
WINAPI
CreateRectRgn(int x1, int y1, int x2, int y2)
{
    PRGN_ATTR pRgn_Attr;
    HRGN hrgn;
    int tmp;

/// <-
//// Remove when Brush/Pen/Rgn Attr is ready!
    return NtGdiCreateRectRgn(x1,y1,x2,y2);
////

    /* Normalize points */
    tmp = x1;
    if ( x1 > x2 )
    {
        x1 = x2;
        x2 = tmp;
    }

    tmp = y1;
    if ( y1 > y2 )
    {
        y1 = y2;
        y2 = tmp;
    }
    /* Check outside 24 bit limit for universal set. Chp 9 Areas, pg 560.*/
    if ( x1 < -(1<<27)  ||
            y1 < -(1<<27)  ||
            x2 > (1<<27)-1 ||
            y2 > (1<<27)-1 )
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    hrgn = hGetPEBHandle(hctRegionHandle, 0);

    if (!hrgn)
        hrgn = NtGdiCreateRectRgn(0, 0, 1, 1);

    if (!hrgn)
        return hrgn;

    if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
    {
        DPRINT1("No Attr for Region handle!!!\n");
        DeleteRegion(hrgn);
        return NULL;
    }

    if (( x1 == x2) || (y1 == y2))
    {
        pRgn_Attr->iComplexity = NULLREGION;
        pRgn_Attr->Rect.left = pRgn_Attr->Rect.top =
                                   pRgn_Attr->Rect.right = pRgn_Attr->Rect.bottom = 0;
    }
    else
    {
        pRgn_Attr->iComplexity = SIMPLEREGION;
        pRgn_Attr->Rect.left   = x1;
        pRgn_Attr->Rect.top    = y1;
        pRgn_Attr->Rect.right  = x2;
        pRgn_Attr->Rect.bottom = y2;
    }

    pRgn_Attr->AttrFlags = (ATTR_RGN_DIRTY|ATTR_RGN_VALID);

    return hrgn;
}
Ejemplo n.º 4
0
HDC FASTCALL
UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
{
   PWND Parent;
   ULONG DcxFlags;
   DCE* Dce = NULL;
   BOOL UpdateClipOrigin = FALSE;
   BOOL bUpdateVisRgn = TRUE;
   HDC hDC = NULL;
   PPROCESSINFO ppi;
   PLIST_ENTRY ListEntry;

   if (NULL == Wnd)
   {
      Flags &= ~DCX_USESTYLE;
      Flags |= DCX_CACHE;
   }

   if (Flags & DCX_PARENTCLIP) Flags |= DCX_CACHE;

   // When GetDC is called with hWnd nz, DCX_CACHE & _WINDOW are clear w _USESTYLE set.
   if (Flags & DCX_USESTYLE)
   {
      Flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);
      if (!(Flags & DCX_WINDOW)) // Not window rectangle
      {
         if (Wnd->pcls->style & CS_PARENTDC)
         {
            Flags |= DCX_PARENTCLIP;
         }

         if (!(Flags & DCX_CACHE) && // Not on the cheap wine list.
             !(Wnd->pcls->style & CS_OWNDC) )
         {
            if (!(Wnd->pcls->style & CS_CLASSDC))
            // The window is not POWNED or has any CLASS, so we are looking for cheap wine.
               Flags |= DCX_CACHE;
            else
            {
               if (Wnd->pcls->pdce) hDC = ((PDCE)Wnd->pcls->pdce)->hDC;
               TRACE("We have CLASS!!\n");
            }
         }

         if (Wnd->style & WS_CLIPSIBLINGS)
         {
            Flags |= DCX_CLIPSIBLINGS;
         }

         if (Wnd->style & WS_CLIPCHILDREN &&
             !(Wnd->style & WS_MINIMIZE))
         {
            Flags |= DCX_CLIPCHILDREN;
         }
         /* If minized with icon in the set, we are forced to be cheap! */
         if (Wnd->style & WS_MINIMIZE && Wnd->pcls->spicn)
         {
            Flags |= DCX_CACHE;
         }
      }
      else
      {
         if (Wnd->style & WS_CLIPSIBLINGS) Flags |= DCX_CLIPSIBLINGS;
         Flags |= DCX_CACHE;
      }
   }

   if (Flags & DCX_WINDOW) Flags &= ~DCX_CLIPCHILDREN;

   if (Flags & DCX_NOCLIPCHILDREN)
   {
      Flags |= DCX_CACHE;
      Flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
   }

   Parent = (Wnd ? Wnd->spwndParent : NULL);

   if (NULL == Wnd || !(Wnd->style & WS_CHILD) || NULL == Parent)
   {
      Flags &= ~DCX_PARENTCLIP;
      Flags |= DCX_CLIPSIBLINGS;
   }

   /* It seems parent clip is ignored when clipping siblings or children */
   if (Flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) Flags &= ~DCX_PARENTCLIP;

   if (Flags & DCX_PARENTCLIP)
   {
      if ((Wnd->style & WS_VISIBLE) &&
          (Parent->style & WS_VISIBLE))
      {
         Flags &= ~DCX_CLIPCHILDREN;
         if (Parent->style & WS_CLIPSIBLINGS)
         {
            Flags |= DCX_CLIPSIBLINGS;
         }
      }
   }

   // Window nz, check to see if we still own this or it is just cheap wine tonight.
   if (!(Flags & DCX_CACHE))
   {
      if ( Wnd->head.pti != GetW32ThreadInfo())
         Flags |= DCX_CACHE; // Ah~ Not Powned! Forced to be cheap~
   }

   DcxFlags = Flags & DCX_CACHECOMPAREMASK;

   if (Flags & DCX_CACHE)
   { // Scan the cheap wine list for our match.
      DCE* DceEmpty = NULL;
      DCE* DceUnused = NULL;
      KeEnterCriticalRegion();
      ListEntry = LEDce.Flink;
      while (ListEntry != &LEDce)
      {
         Dce = CONTAINING_RECORD(ListEntry, DCE, List);
         ListEntry = ListEntry->Flink;
//
// The way I understand this, you can have more than one DC per window.
// Only one Owned if one was requested and saved and one Cached.
//
         if ((Dce->DCXFlags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE)
         {
            DceUnused = Dce;
            if (Dce->DCXFlags & DCX_DCEEMPTY)
            {
               DceEmpty = Dce;
            }
            else if (Dce->hwndCurrent == (Wnd ? Wnd->head.h : NULL) &&
                     ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags))
            {
               UpdateClipOrigin = TRUE;
               break;
            }
         }
         Dce = NULL; // Loop issue?
      }
      KeLeaveCriticalRegion();

      Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;

      if (Dce == NULL)
      {
         Dce = DceAllocDCE(NULL, DCE_CACHE_DC);
      }
      if (Dce == NULL) return NULL;

      Dce->hwndCurrent = (Wnd ? Wnd->head.h : NULL);
      Dce->pwndOrg = Dce->pwndClip = Wnd;
   }
   else // If we are here, we are POWNED or having CLASS.
   {
      KeEnterCriticalRegion();
      ListEntry = LEDce.Flink;
      while (ListEntry != &LEDce)
      {
          Dce = CONTAINING_RECORD(ListEntry, DCE, List);
          ListEntry = ListEntry->Flink;

          // Skip Cache DCE entries.
          if (!(Dce->DCXFlags & DCX_CACHE))
          {
             // Check for Window handle than HDC match for CLASS.
             if (Dce->hwndCurrent == Wnd->head.h)
             {
                bUpdateVisRgn = FALSE;
                break;
             }
             else if (Dce->hDC == hDC) break;
          }
          Dce = NULL; // Loop issue?
      }
      KeLeaveCriticalRegion();

      if (Dce == NULL)
      {
         return(NULL);
      }

      if ( (Flags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) &&
           (Dce->DCXFlags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) )
      {
         DceDeleteClipRgn(Dce);
      }
   }
// First time use hax, need to use DceAllocDCE during window display init.
   if (NULL == Dce)
   {
      return(NULL);
   }

   if (!GreIsHandleValid(Dce->hDC))
   {
      ERR("FIXME: Got DCE with invalid hDC! %p\n", Dce->hDC);
      Dce->hDC = DceCreateDisplayDC();
      /* FIXME: Handle error */
   }

   Dce->DCXFlags = Flags | DCX_DCEBUSY;

   /*
    * Bump it up! This prevents the random errors in wine dce tests and with
    * proper bits set in DCX_CACHECOMPAREMASK.
    * Reference:
    *   http://www.reactos.org/archives/public/ros-dev/2008-July/010498.html
    *   http://www.reactos.org/archives/public/ros-dev/2008-July/010499.html
    */
   RemoveEntryList(&Dce->List);
   InsertHeadList(&LEDce, &Dce->List);

   /* Introduced in rev 6691 and modified later. */
   if ( (Flags & DCX_INTERSECTUPDATE) && !ClipRegion )
   {
      Flags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN;
      Dce->DCXFlags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN;
      ClipRegion = Wnd->hrgnUpdate;
      bUpdateVisRgn = TRUE;
   }

   if (ClipRegion == HRGN_WINDOW)
   {
      if (!(Flags & DCX_WINDOW))
      {
         Dce->hrgnClip = NtGdiCreateRectRgn(
             Wnd->rcClient.left,
             Wnd->rcClient.top,
             Wnd->rcClient.right,
             Wnd->rcClient.bottom);
      }
      else
      {
          Dce->hrgnClip = NtGdiCreateRectRgn(
              Wnd->rcWindow.left,
              Wnd->rcWindow.top,
              Wnd->rcWindow.right,
              Wnd->rcWindow.bottom);
      }
      Dce->DCXFlags &= ~DCX_KEEPCLIPRGN;
      bUpdateVisRgn = TRUE;
   }
   else if (ClipRegion != NULL)
   {
      if (Dce->hrgnClip != NULL)
      {
         ERR("Should not be called!!\n");
         GreDeleteObject(Dce->hrgnClip);
         Dce->hrgnClip = NULL;
      }
      Dce->hrgnClip = ClipRegion;
      bUpdateVisRgn = TRUE;
   }

   if (IntGdiSetHookFlags(Dce->hDC, DCHF_VALIDATEVISRGN)) bUpdateVisRgn = TRUE;

   DceSetDrawable(Wnd, Dce->hDC, Flags, UpdateClipOrigin);

   if (bUpdateVisRgn) DceUpdateVisRgn(Dce, Wnd, Flags);

   if (Dce->DCXFlags & DCX_CACHE)
   {
      TRACE("ENTER!!!!!! DCX_CACHE!!!!!!   hDC-> %p\n", Dce->hDC);
      // Need to set ownership so Sync dcattr will work.
      GreSetDCOwner(Dce->hDC, GDI_OBJ_HMGR_POWNED);
      Dce->ptiOwner = GetW32ThreadInfo(); // Set the temp owning
   }

   if ( Wnd &&
        Wnd->ExStyle & WS_EX_LAYOUTRTL &&
       !(Flags & DCX_KEEPLAYOUT) )
   {
      NtGdiSetLayout(Dce->hDC, -1, LAYOUT_RTL);
   }

   if (Dce->DCXFlags & DCX_PROCESSOWNED)
   {
      ppi = PsGetCurrentProcessWin32Process();
      ppi->W32PF_flags |= W32PF_OWNDCCLEANUP;
      Dce->ptiOwner = NULL;
      Dce->ppiOwner = ppi;
   }

   return(Dce->hDC);
}