示例#1
0
VOID APIENTRY VBoxDispDrvDisableSurface(DHPDEV dhpdev)
{
    PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev;
    LOGF_ENTER();

    if (pDev->surface.hSurface)
    {
        EngDeleteSurface(pDev->surface.hSurface);
        pDev->surface.hSurface = NULL;
    }

    if (pDev->surface.psoBitmap)
    {
        Assert(pDev->surface.hBitmap);
        EngUnlockSurface(pDev->surface.psoBitmap);
        pDev->surface.psoBitmap = NULL;
    }

    if (pDev->surface.hBitmap)
    {
        EngDeleteSurface((HSURF) pDev->surface.hBitmap);
        pDev->surface.hBitmap = NULL;
    }

    int rc;
    rc = VBoxDispMPUnmapMemory(pDev);
    VBOX_WARNRC(rc);

    LOGF_LEAVE();
}
示例#2
0
文件: heap.c 项目: Gaikokujin/WinNT4
VOID DrvDeleteDeviceBitmap(
DHSURF  dhsurf)
{
    DSURF*   pdsurf;
    PDEV*    ppdev;
    SURFOBJ* psoDib;
    HSURF    hsurfDib;

    pdsurf = (DSURF*) dhsurf;
    ppdev  = pdsurf->ppdev;

    if (pdsurf->dt == DT_SCREEN)
    {
        pohFree(ppdev, pdsurf->poh);
    }
    else
    {
        ASSERTDD(pdsurf->dt == DT_DIB, "Expected DIB type");

        psoDib = pdsurf->pso;

        // Get the hsurf from the SURFOBJ before we unlock it (it's not
        // legal to dereference psoDib when it's unlocked):

        hsurfDib = psoDib->hsurf;
        EngUnlockSurface(psoDib);
        EngDeleteSurface(hsurfDib);
    }

    EngFreeMem(pdsurf);
}
示例#3
0
BOOL APIENTRY
IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
{
  POINTL SrcPoint;
  BOOL Result = TRUE;

  if (EnterLeave->OutputObj != EnterLeave->DestObj && NULL != EnterLeave->OutputObj)
    {
    if (! EnterLeave->ReadOnly)
      {
      SrcPoint.x = 0;
      SrcPoint.y = 0;
      if (EnterLeave->DestRect.left < 0)
        {
          SrcPoint.x = - EnterLeave->DestRect.left;
          EnterLeave->DestRect.left = 0;
        }
      if (EnterLeave->DestObj->sizlBitmap.cx < EnterLeave->DestRect.right)
        {
          EnterLeave->DestRect.right = EnterLeave->DestObj->sizlBitmap.cx;
        }
      if (EnterLeave->DestRect.top < 0)
        {
          SrcPoint.y = - EnterLeave->DestRect.top;
          EnterLeave->DestRect.top = 0;
        }
      if (EnterLeave->DestObj->sizlBitmap.cy < EnterLeave->DestRect.bottom)
        {
          EnterLeave->DestRect.bottom = EnterLeave->DestObj->sizlBitmap.cy;
        }
      if (SrcPoint.x < EnterLeave->OutputObj->sizlBitmap.cx &&
          EnterLeave->DestRect.left <= EnterLeave->DestRect.right &&
          EnterLeave->DestRect.left < EnterLeave->DestObj->sizlBitmap.cx &&
          SrcPoint.y < EnterLeave->OutputObj->sizlBitmap.cy &&
          EnterLeave->DestRect.top <= EnterLeave->DestRect.bottom &&
          EnterLeave->DestRect.top < EnterLeave->DestObj->sizlBitmap.cy)
        {
          Result = GDIDEVFUNCS(EnterLeave->DestObj).CopyBits(
                                                 EnterLeave->DestObj,
                                                 EnterLeave->OutputObj,
                                                 EnterLeave->TrivialClipObj, NULL,
                                                 &EnterLeave->DestRect, &SrcPoint);
        }
      else
        {
          Result = TRUE;
        }
      }
    EngUnlockSurface(EnterLeave->OutputObj);
    EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
    EngDeleteClip(EnterLeave->TrivialClipObj);
    }
  else
    {
    Result = TRUE;
    }

  return Result;
}
示例#4
0
文件: surface.c 项目: damouse/PCC
static VOID FreeDrawArea(DrawArea *drawarea)
{
    if (drawarea->surf_obj) {
        EngUnlockSurface(drawarea->surf_obj);
        EngDeleteSurface(drawarea->bitmap);
        drawarea->surf_obj = NULL;
    }
}
示例#5
0
文件: heap.c 项目: Gaikokujin/WinNT4
BOOL bMoveDibToOffscreenDfbIfRoom(
PDEV*   ppdev,
DSURF*  pdsurf)
{
    OH*         poh;
    SURFOBJ*    pso;
    RECTL       rclDst;
    POINTL      ptlSrc;
    HSURF       hsurf;

    ASSERTDD(pdsurf->dt == DT_DIB,
             "Can't move a bitmap off-screen when it's already off-screen");

    // If we're in full-screen mode, we can't move anything to off-screen
    // memory:

    if (!ppdev->bEnabled)
        return(FALSE);

    poh = pohAllocate(ppdev, pdsurf->sizl.cx, pdsurf->sizl.cy,
                      FLOH_ONLY_IF_ROOM);
    if (poh == NULL)
    {
        // There wasn't any free room.

        return(FALSE);
    }

    // 'pdsurf->sizl' is the actual bitmap dimension, not 'poh->cx' or
    // 'poh->cy'.

    rclDst.left   = poh->x;
    rclDst.top    = poh->y;
    rclDst.right  = rclDst.left + pdsurf->sizl.cx;
    rclDst.bottom = rclDst.top  + pdsurf->sizl.cy;

    ptlSrc.x      = 0;
    ptlSrc.y      = 0;

    vPutBits(ppdev, pdsurf->pso, &rclDst, &ptlSrc);

    // Update the data structures to reflect the new off-screen node:

    pso           = pdsurf->pso;
    pdsurf->dt    = DT_SCREEN;
    pdsurf->poh   = poh;
    poh->pdsurf   = pdsurf;

    // Now free the DIB.  Get the hsurf from the SURFOBJ before we unlock
    // it (it's not legal to dereference psoDib when it's unlocked):

    hsurf = pso->hsurf;
    EngUnlockSurface(pso);
    EngDeleteSurface(hsurf);

    return(TRUE);
}
示例#6
0
VOID DrvDisableSurface(
DHPDEV dhpdev)
{
    PDEV*   ppdev;
    HSURF   hsurf;

    ppdev = (PDEV*) dhpdev;

    // Note: In an error case, some of the following relies on the
    //       fact that the PDEV is zero-initialized, so fields like
    //       'hsurfScreen' will be zero unless the surface has been
    //       sucessfully initialized, and makes the assumption that
    //       EngDeleteSurface can take '0' as a parameter.

    vDisableHardware(ppdev);

    hsurf = ppdev->pso->hsurf;
    EngUnlockSurface(ppdev->pso);
    EngDeleteSurface(hsurf);
}
示例#7
0
BOOL bSetSimPointerShape (
    SURFOBJ  *pso,
    SURFOBJ  *psoMask,
    SURFOBJ  *psoColor,
    XLATEOBJ *pxlo,
    LONG      x,
    LONG      y,
    FLONG     fl )

{
    PPDEV     ppdev = (PPDEV) pso->dhpdev;
    PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
    ULONG     cxSrc, cySrc, cxSrcBytes;
    ULONG     ulOffset;
    HSURF     hsurf;
    SIZEL     sizl;
    ULONG     ulBitmapType;
    FLONG     flBitmap;
    SURFOBJ  *psoSrc;
    SURFOBJ  *psoDst;
    RECTL     prclDst;
    POINTL    pptlSrc;
    XLATEOBJ  xlo;
    ULONG     ulXlate[2];

    if (!(ppdev->flCaps & CAPS_NEED_SW_POINTER)) {
        return FALSE;
    } /* endif */

    //
    // Check if we have enough off-screen memory to hold the screen image underneath
    // the new pointer
    //
    cxSrc = psoMask->sizlBitmap.cx;
    cySrc = psoMask->sizlBitmap.cy >> 1;
    cxSrcBytes = (cxSrc + 7) / 8;

    ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen;
    ulOffset += 64;              // skip over solid color pattern used in bitblt.c
    ulOffset += 1024;            // skip over hardware pointer bitmap

    if ((ppdev->cScreenSize < ulOffset + cxSrc * cySrc * (ppdev->ulBitCount/8)) ||
        (psoMask->iType & STYPE_BITMAP) ||
        (!(psoMask->fjBitmap & BMF_TOPDOWN))) {
        return FALSE;
    } /* endif */

    //
    // Update the attributes of pointer
    //
    pPointerAttributes->Width  = cxSrc;
    pPointerAttributes->Height = cySrc;
    pPointerAttributes->WidthInBytes = cxSrcBytes;

    //
    // Discard the old pointer
    //
    if (ppdev->hsurfMask != NULL) {
        EngDeleteSurface(ppdev->hsurfMask);
        EngDeleteSurface(ppdev->hsurfColor);
    } /* endif */

    //
    // Create a copy of mask bitmap
    //
    sizl.cx = cxSrc;
    sizl.cy = cySrc;
    flBitmap = BMF_TOPDOWN;
    prclDst.top = 0;
    prclDst.bottom = cySrc;
    prclDst.left = 0;
    prclDst.right = cxSrc;

    psoSrc = psoMask;
    ulBitmapType = BMF_1BPP;
    pptlSrc.x = 0;
    pptlSrc.y = 0;

    if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl,
                                                 0,            // Let GDI choose ulWidth
                                                 ulBitmapType,
                                                 flBitmap,
                                                 NULL))) {     // Let GDI allocate
        return FALSE;
    } else {
        ppdev->hsurfMask = hsurf;
    } /* endif */

    psoDst  = EngLockSurface(ppdev->hsurfMask);
    if (!EngCopyBits(psoDst,                 // Target surface
                     psoSrc,                 // Source surface
                     (CLIPOBJ *) NULL,       // Clip through this
                     (XLATEOBJ *) NULL,      // Color translation
                     &prclDst,               // Target offset and extent
                     &pptlSrc)) {            // Source offset
        EngDeleteSurface(ppdev->hsurfMask);
        return FALSE;
    } /* endif */
    EngUnlockSurface(psoDst);

    //
    // Create a copy of pointer bitmap
    //
    ulBitmapType = pso->iBitmapFormat;

    if (psoColor == (SURFOBJ *) NULL) {

        //
        // Use second half of mask bitmap if it is monochrome
        //
        pPointerAttributes->Flags |=  VIDEO_MODE_MONO_POINTER;
        pPointerAttributes->Flags &= ~VIDEO_MODE_COLOR_POINTER;
        psoSrc = psoMask;
        pptlSrc.x = 0;
        pptlSrc.y = cySrc;

        //
        // Create the translation table for monochrome-to-color conversion
        //
        pxlo = &xlo;
        xlo.iUniq    = 0;
        xlo.flXlate  = XO_TABLE;
        xlo.iSrcType = PAL_INDEXED;
        xlo.iDstType = (ppdev->ulBitCount == 8) ? PAL_INDEXED : PAL_RGB;
        xlo.cEntries = 2;
        xlo.pulXlate = (ULONG *)ulXlate;
        ulXlate[0]   = 0x00000000;                                         // Black
        ulXlate[1]   = (ppdev->ulBitCount == 8) ? 0x000000FF : 0x00FFFFFF; // White

    } else {

        pPointerAttributes->Flags &= ~VIDEO_MODE_MONO_POINTER;
        pPointerAttributes->Flags |=  VIDEO_MODE_COLOR_POINTER;
        psoSrc = psoColor;
        pptlSrc.x = 0;
        pptlSrc.y = 0;

    } /* endif */

    if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl,
                                                 0,            // Let GDI choose ulWidth
                                                 ulBitmapType,
                                                 flBitmap,
                                                 NULL))) {     // Let GDI allocate
        EngDeleteSurface(ppdev->hsurfMask);
        return FALSE;
    } else {
        ppdev->hsurfColor = hsurf;
    } /* endif */

    psoDst  = EngLockSurface(ppdev->hsurfColor);
    if (!EngCopyBits(psoDst,                 // Target surface
                     psoSrc,                 // Source surface
                     (CLIPOBJ *) NULL,       // Clip through this
                     pxlo,                   // Color translation
                     &prclDst,               // Target offset and extent
                     &pptlSrc)) {            // Source offset
        EngDeleteSurface(ppdev->hsurfMask);
        EngDeleteSurface(ppdev->hsurfColor);
        return FALSE;
    } /* endif */
    EngUnlockSurface(psoDst);

    return TRUE;
}
示例#8
0
VOID vShowSimPointer (
    PPDEV     ppdev,
    SURFOBJ  *pso,
    RECTL    *prcl,
    BOOL      bShow )

{
    PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes;
    RECTL     rclScreen, rclPointer;
    POINTL    ptlPointerOffset;
    ULONG     ulOffset;
    BOOL      b;
    SURFOBJ  *psoMask;
    SURFOBJ  *psoColor;

    ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen;
    ulOffset += 64;              // skip over solid color pattern used in bitblt.c
    ulOffset += 1024;            // skip over hardware pointer bitmap

    if (bShow) {
        rclScreen.top    = 0;
        rclScreen.bottom = ppdev->cyScreen;
        rclScreen.left   = 0;
        rclScreen.right  = ppdev->cxScreen;

        rclPointer.top    = pPointerAttributes->Row - ppdev->ptlHotSpot.y;
        rclPointer.bottom = rclPointer.top + pPointerAttributes->Height;
        rclPointer.left   = pPointerAttributes->Column - ppdev->ptlHotSpot.x;
        rclPointer.right  = rclPointer.left + pPointerAttributes->Width;

        //
        // Trim down the simulation cursor beyond the screen
        //
        if (bIntersect(&rclScreen, &rclPointer, &ppdev->rclPrevPointer)) {

            prcl->top    = ppdev->rclPrevPointer.top;
            prcl->bottom = ppdev->rclPrevPointer.bottom;
            prcl->left   = ppdev->rclPrevPointer.left;
            prcl->right  = ppdev->rclPrevPointer.right;

            ptlPointerOffset.x = (rclPointer.left >= 0) ? 0 : (rclPointer.left * (-1));
            ptlPointerOffset.y = (rclPointer.top >= 0) ? 0 : (rclPointer.top * (-1));

            //
            // Save the screen image where the pointer affects
            //
            vHwSaveScreen(ppdev, &ppdev->rclPrevPointer, ulOffset);

            //
            // Draw the pointer
            //
            // Note: Clipping the transparent portion of pointer is required for
            //       better performance.
            //
            if ((pso != NULL) && (pso->iType == STYPE_DEVICE))
                pso = (SURFOBJ *)(((PPDEV)(pso->dhpdev))->pSurfObj);

            psoMask  = EngLockSurface(ppdev->hsurfMask);
            psoColor = EngLockSurface(ppdev->hsurfColor);

            b = EngBitBlt(pso,                        // Target surface
                          psoColor,                   // Source surface
                          psoMask,                    // Mask
                          (CLIPOBJ *) NULL,           // Clip through this
                          (XLATEOBJ *) NULL,          // Color translation
                          prcl,                       // Target offset and extent
                          &ptlPointerOffset,          // Source offset
                          &ptlPointerOffset,          // Mask offset
                          (BRUSHOBJ *) NULL,          // Brush data (from cbRealizeBrush)
                          (POINTL *) NULL,            // Brush offset (origin)
                          0x0000CC66);                // Raster operation

            EngUnlockSurface(psoMask);
            EngUnlockSurface(psoColor);

        } else {

            //
            // The entire pointer is outside of screen
            //
            pPointerAttributes->Enable = 0;

        } /* endif */
    } else {

        //
        // Restore the screen image corrupted by the simulation pointer
        //
        vHwRestoreScreen(ppdev, &ppdev->rclPrevPointer, ulOffset);

    } /* endif */
}
HBITMAP APIENTRY VBoxDispDrvDeriveSurface(DD_DIRECTDRAW_GLOBAL *pDirectDraw, DD_SURFACE_LOCAL *pSurface)
{
    PVBOXDISPDEV pDev = (PVBOXDISPDEV)pDirectDraw->dhpdev;
    LOGF_ENTER();

    if (pSurface->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
    {
        WARN(("Can't derive surface DDSCAPS_NONLOCALVIDMEM"));
        return NULL;
    }

    if (pSurface->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
    {
        WARN(("Can't derive surface DDSCAPS2_TEXTUREMANAGE"));
        return NULL;
    }

    if (pSurface->lpGbl->ddpfSurface.dwRGBBitCount != pDev->mode.ulBitsPerPel)
    {
        WARN(("Can't derive surface with different bpp"));
        return NULL;
    }

    Assert(pDev->surface.hSurface);

    /* Create GDI managed bitmap, which resides in our DDraw heap memory */
    HBITMAP hBitmap;
    SIZEL size;

    size.cx = pDev->mode.ulWidth;
    size.cy = pDev->mode.ulHeight;

    hBitmap = EngCreateBitmap(size, pSurface->lpGbl->lPitch, pDev->surface.ulFormat,
                              pDev->mode.lScanlineStride>0 ? BMF_TOPDOWN:0,
                              (PBYTE)pDev->memInfo.VideoRamBase + pSurface->lpGbl->fpVidMem);

    if (!hBitmap)
    {
        WARN(("EngCreateBitmap failed"));
        return 0;
    }

    if (pSurface->lpGbl->fpVidMem == 0)
    {
        /* Screen surface, mark it so it will be recognized by the driver.
         * so the driver will be called on any operations on the surface
         * (required for VBVA and VRDP).
         */
        SURFOBJ *pso;

        if (!EngAssociateSurface((HSURF)hBitmap, pDev->hDevGDI, pDev->flDrawingHooks))
        {
            WARN(("EngAssociateSurface failed"));
            EngDeleteSurface((HSURF)hBitmap);
            return NULL;
        }

        pso = EngLockSurface((HSURF)hBitmap);
        if (!pso)
        {
            WARN(("EngLockSurface failed"));
            EngDeleteSurface((HSURF)hBitmap);
            return NULL;
        }

        pso->dhpdev = (DHPDEV)pDev;
        EngUnlockSurface(pso);
    }

    LOGF_LEAVE();
    return hBitmap;
}
示例#10
0
BOOL APIENTRY
IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
            SURFOBJ *psoDest,
            RECTL *DestRect,
            BOOL ReadOnly,
            POINTL *Translate,
            SURFOBJ **ppsoOutput)
{
  LONG Exchange;
  SIZEL BitmapSize;
  POINTL SrcPoint;
  LONG Width;
  RECTL ClippedDestRect;

  /* Normalize */
  if (DestRect->right < DestRect->left)
    {
    Exchange = DestRect->left;
    DestRect->left = DestRect->right;
    DestRect->right = Exchange;
    }
  if (DestRect->bottom < DestRect->top)
    {
    Exchange = DestRect->top;
    DestRect->top = DestRect->bottom;
    DestRect->bottom = Exchange;
    }

  if (NULL != psoDest && STYPE_BITMAP != psoDest->iType &&
      (NULL == psoDest->pvScan0 || 0 == psoDest->lDelta))
    {
    /* Driver needs to support DrvCopyBits, else we can't do anything */
    SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
    if (!(psurfDest->flags & HOOK_COPYBITS))
    {
      return FALSE;
    }

    /* Allocate a temporary bitmap */
    BitmapSize.cx = DestRect->right - DestRect->left;
    BitmapSize.cy = DestRect->bottom - DestRect->top;
    Width = WIDTH_BYTES_ALIGN32(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat));
    EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width,
                                               psoDest->iBitmapFormat,
                                               BMF_TOPDOWN | BMF_NOZEROINIT, NULL);

    if (!EnterLeave->OutputBitmap)
      {
      DPRINT1("EngCreateBitmap() failed\n");
      return FALSE;
      }

    *ppsoOutput = EngLockSurface((HSURF)EnterLeave->OutputBitmap);
    if (*ppsoOutput == NULL)
    {
      EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
      return FALSE;
    }

    EnterLeave->DestRect.left = 0;
    EnterLeave->DestRect.top = 0;
    EnterLeave->DestRect.right = BitmapSize.cx;
    EnterLeave->DestRect.bottom = BitmapSize.cy;
    SrcPoint.x = DestRect->left;
    SrcPoint.y = DestRect->top;
    ClippedDestRect = EnterLeave->DestRect;
    if (SrcPoint.x < 0)
      {
        ClippedDestRect.left -= SrcPoint.x;
        SrcPoint.x = 0;
      }
    if (psoDest->sizlBitmap.cx < SrcPoint.x + ClippedDestRect.right - ClippedDestRect.left)
      {
        ClippedDestRect.right = ClippedDestRect.left + psoDest->sizlBitmap.cx - SrcPoint.x;
      }
    if (SrcPoint.y < 0)
      {
        ClippedDestRect.top -= SrcPoint.y;
        SrcPoint.y = 0;
      }
    if (psoDest->sizlBitmap.cy < SrcPoint.y + ClippedDestRect.bottom - ClippedDestRect.top)
      {
        ClippedDestRect.bottom = ClippedDestRect.top + psoDest->sizlBitmap.cy - SrcPoint.y;
      }
    EnterLeave->TrivialClipObj = EngCreateClip();
    if (EnterLeave->TrivialClipObj == NULL)
    {
      EngUnlockSurface(*ppsoOutput);
      EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
      return FALSE;
    }
    EnterLeave->TrivialClipObj->iDComplexity = DC_TRIVIAL;
    if (ClippedDestRect.left < (*ppsoOutput)->sizlBitmap.cx &&
        0 <= ClippedDestRect.right &&
        SrcPoint.x < psoDest->sizlBitmap.cx &&
        ClippedDestRect.top <= (*ppsoOutput)->sizlBitmap.cy &&
        0 <= ClippedDestRect.bottom &&
        SrcPoint.y < psoDest->sizlBitmap.cy &&
        ! GDIDEVFUNCS(psoDest).CopyBits(
                                        *ppsoOutput, psoDest,
                                        EnterLeave->TrivialClipObj, NULL,
                                        &ClippedDestRect, &SrcPoint))
      {
          EngDeleteClip(EnterLeave->TrivialClipObj);
          EngUnlockSurface(*ppsoOutput);
          EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
          return FALSE;
      }
    EnterLeave->DestRect.left = DestRect->left;
    EnterLeave->DestRect.top = DestRect->top;
    EnterLeave->DestRect.right = DestRect->right;
    EnterLeave->DestRect.bottom = DestRect->bottom;
    Translate->x = - DestRect->left;
    Translate->y = - DestRect->top;
    }
  else
    {
    Translate->x = 0;
    Translate->y = 0;
    *ppsoOutput = psoDest;
    }

  if (NULL != *ppsoOutput)
  {
    SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj);
    if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE))
    {
      if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface)
        {
          GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface(*ppsoOutput, DestRect, 0);
        }
      else if (STYPE_BITMAP == (*ppsoOutput)->iType
               && NULL != GDIDEVFUNCS(*ppsoOutput).Synchronize)
        {
          GDIDEVFUNCS(*ppsoOutput).Synchronize((*ppsoOutput)->dhpdev, DestRect);
        }
    }
  }
  else return FALSE;

  EnterLeave->DestObj = psoDest;
  EnterLeave->OutputObj = *ppsoOutput;
  EnterLeave->ReadOnly = ReadOnly;

  return TRUE;
}