Пример #1
0
BOOL FASTCALL
co_IntRegisterLogonProcess(HANDLE ProcessId, BOOL Register)
{
   NTSTATUS Status;
   PEPROCESS Process;

   Status = PsLookupProcessByProcessId(ProcessId, &Process);
   if (!NT_SUCCESS(Status))
   {
      EngSetLastError(RtlNtStatusToDosError(Status));
      return FALSE;
   }

   ProcessId = Process->UniqueProcessId;

   ObDereferenceObject(Process);

   if (Register)
   {
      /* Register the logon process */
      if (gpidLogon != 0)
         return FALSE;

      gpidLogon = ProcessId;
   }
   else
   {
      /* Deregister the logon process */
      if (gpidLogon != ProcessId)
         return FALSE;

      gpidLogon = 0;
   }

   return TRUE;
}
Пример #2
0
HWND APIENTRY
NtUserSetClipboardViewer(HWND hWndNewViewer)
{
    HWND hWndNext = NULL;
    PWINSTATION_OBJECT pWinStaObj = NULL;
    PWND pWindow;

    UserEnterExclusive();

    pWinStaObj = IntGetWinStaForCbAccess();
    if (!pWinStaObj)
        goto cleanup;

    pWindow = UserGetWindowObject(hWndNewViewer);
    if (!pWindow)
    {
        EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
        goto cleanup;
    }

    /* Return previous viewer. New viever window should
       send messages to rest of the chain */
    if (pWinStaObj->spwndClipViewer)
        hWndNext = pWinStaObj->spwndClipViewer->head.h;

    /* Set new viewer window */
    pWinStaObj->spwndClipViewer = pWindow;

cleanup:
    if(pWinStaObj)
        ObDereferenceObject(pWinStaObj);

    UserLeave();

    return hWndNext;
}
Пример #3
0
BOOL APIENTRY
NtUserUnlockWindowStation(HWINSTA hWindowStation)
{
    PWINSTATION_OBJECT Object;
    NTSTATUS Status;
    BOOL Ret;

    TRACE("About to set process window station with handle (%p)\n",
          hWindowStation);

    if (gpidLogon != PsGetCurrentProcessId())
    {
        ERR("Unauthorized process attempted to unlock the window station!\n");
        EngSetLastError(ERROR_ACCESS_DENIED);
        return FALSE;
    }

    Status = IntValidateWindowStationHandle(hWindowStation,
                                            UserMode,
                                            0,
                                            &Object,
                                            0);
    if (!NT_SUCCESS(Status))
    {
        TRACE("Validation of window station handle (%p) failed\n",
              hWindowStation);
        SetLastNtError(Status);
        return FALSE;
    }

    Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
    Object->Flags &= ~WSS_LOCKED;

    ObDereferenceObject(Object);
    return Ret;
}
Пример #4
0
COLORREF FASTCALL
IntSetDCBrushColor(HDC hdc, COLORREF crColor)
{
   COLORREF OldColor = CLR_INVALID;
   PDC dc;
   if (!(dc = DC_LockDc(hdc)))
   {
      EngSetLastError(ERROR_INVALID_HANDLE);
      return CLR_INVALID;
   }
   else
   {
      OldColor = (COLORREF) dc->pdcattr->ulBrushClr;
      dc->pdcattr->ulBrushClr = (ULONG) crColor;

      if ( dc->pdcattr->crBrushClr != crColor )
      {
         dc->pdcattr->ulDirty_ |= DIRTY_FILL;
         dc->pdcattr->crBrushClr = crColor;
      }
   }
   DC_UnlockDc(dc);
   return OldColor;
}
Пример #5
0
HANDLE
IntCreateCurIconHandle(BOOLEAN Animated)
{
    PCURICON_OBJECT CurIcon;
    HANDLE hCurIcon;

    CurIcon = UserCreateObject(
        gHandleTable,
        NULL,
        NULL,
        &hCurIcon,
        TYPE_CURSOR,
        Animated ? sizeof(ACON) : sizeof(CURICON_OBJECT));

    if (!CurIcon)
    {
        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    UserDereferenceObject(CurIcon);

    return hCurIcon;
}
Пример #6
0
BOOL
APIENTRY
NtUserGetGUIThreadInfo(
   DWORD idThread, /* If NULL use foreground thread */
   LPGUITHREADINFO lpgui)
{
   NTSTATUS Status;
   PTHRDCARETINFO CaretInfo;
   GUITHREADINFO SafeGui;
   PDESKTOP Desktop;
   PUSER_MESSAGE_QUEUE MsgQueue;
   PTHREADINFO W32Thread;
   PETHREAD Thread = NULL;

   DECLARE_RETURN(BOOLEAN);

   TRACE("Enter NtUserGetGUIThreadInfo\n");
   UserEnterShared();

   Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   if(SafeGui.cbSize != sizeof(GUITHREADINFO))
   {
      EngSetLastError(ERROR_INVALID_PARAMETER);
      RETURN( FALSE);
   }

   if (idThread)
   {
      Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread);
      if(!NT_SUCCESS(Status))
      {
         EngSetLastError(ERROR_ACCESS_DENIED);
         RETURN( FALSE);
      }
      W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread;
      Desktop = W32Thread->rpdesk;

      if (!Thread || !Desktop )
      {
        if(Thread)
           ObDereferenceObject(Thread);
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
      
      if ( W32Thread->MessageQueue )
        MsgQueue = W32Thread->MessageQueue;
      else
      {
        if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue;
      }
   }
   else
   {  /* Get the foreground thread */
      /* FIXME: Handle NULL queue properly? */
      MsgQueue = IntGetFocusMessageQueue();
      if(!MsgQueue)
      {
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
   }

   CaretInfo = &MsgQueue->CaretInfo;

   SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
/*
   if (W32Thread->pMenuState->pGlobalPopupMenu)
   {
       SafeGui.flags |= GUI_INMENUMODE;

       if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify)
          SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify);

       if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar)
       {
          if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu)
          {
             SafeGui.flags |= GUI_SYSTEMMENUMODE;
          }
       }
       else
       {
          SafeGui.flags |= GUI_POPUPMENUMODE;
       }
   }
 */
   SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;

   if (MsgQueue->MenuOwner)
      SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;

   if (MsgQueue->MoveSize)
      SafeGui.flags |= GUI_INMOVESIZE;

   /* FIXME: Add flag GUI_16BITTASK */

   SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0;
   SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0;
   SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0;
   SafeGui.hwndMoveSize = MsgQueue->MoveSize;
   SafeGui.hwndCaret = CaretInfo->hWnd;

   SafeGui.rcCaret.left = CaretInfo->Pos.x;
   SafeGui.rcCaret.top = CaretInfo->Pos.y;
   SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
   SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;

   if (idThread)
      ObDereferenceObject(Thread);

   Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   RETURN( TRUE);

CLEANUP:
   TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Пример #7
0
BOOL
NTAPI
GreGradientFill(
    HDC hdc,
    PTRIVERTEX pVertex,
    ULONG nVertex,
    PVOID pMesh,
    ULONG nMesh,
    ULONG ulMode)
{
    PDC pdc;
    SURFACE *psurf;
    EXLATEOBJ exlo;
    RECTL rclExtent;
    POINTL ptlDitherOrg;
    ULONG i;
    BOOL bRet;

    /* Check parameters */
    if (ulMode & GRADIENT_FILL_TRIANGLE)
    {
        PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh;

        for (i = 0; i < nMesh; i++, pTriangle++)
        {
            if (pTriangle->Vertex1 >= nVertex ||
                pTriangle->Vertex2 >= nVertex ||
                pTriangle->Vertex3 >= nVertex)
            {
                EngSetLastError(ERROR_INVALID_PARAMETER);
                return FALSE;
            }
        }
    }
    else
    {
        PGRADIENT_RECT pRect = (PGRADIENT_RECT)pMesh;
        for (i = 0; i < nMesh; i++, pRect++)
        {
            if (pRect->UpperLeft >= nVertex || pRect->LowerRight >= nVertex)
            {
                EngSetLastError(ERROR_INVALID_PARAMETER);
                return FALSE;
            }
        }
    }

    /* Lock the output DC */
    pdc = DC_LockDc(hdc);
    if(!pdc)
    {
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if(pdc->dctype == DC_TYPE_INFO)
    {
        DC_UnlockDc(pdc);
        /* Yes, Windows really returns TRUE in this case */
        return TRUE;
    }

    psurf = pdc->dclevel.pSurface;
    if(!psurf)
    {
        /* Memory DC with no surface selected */
        DC_UnlockDc(pdc);
        return TRUE; // CHECKME
    }

    /* Calculate extent */
    rclExtent.left = rclExtent.right = pVertex->x;
    rclExtent.top = rclExtent.bottom = pVertex->y;
    for (i = 0; i < nVertex; i++)
    {
        rclExtent.left = min(rclExtent.left, (pVertex + i)->x);
        rclExtent.right = max(rclExtent.right, (pVertex + i)->x);
        rclExtent.top = min(rclExtent.top, (pVertex + i)->y);
        rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y);
    }
    IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2);

    rclExtent.left   += pdc->ptlDCOrig.x;
    rclExtent.right  += pdc->ptlDCOrig.x;
    rclExtent.top    += pdc->ptlDCOrig.y;
    rclExtent.bottom += pdc->ptlDCOrig.y;

    ptlDitherOrg.x = ptlDitherOrg.y = 0;
    IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);

    ptlDitherOrg.x += pdc->ptlDCOrig.x;
    ptlDitherOrg.y += pdc->ptlDCOrig.y;

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

    ASSERT(pdc->rosdc.CombinedClip);

    DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);

    bRet = IntEngGradientFill(&psurf->SurfObj,
                             pdc->rosdc.CombinedClip,
                             &exlo.xlo,
                             pVertex,
                             nVertex,
                             pMesh,
                             nMesh,
                             &rclExtent,
                             &ptlDitherOrg,
                             ulMode);

    EXLATEOBJ_vCleanup(&exlo);
    DC_vFinishBlit(pdc, NULL);
    DC_UnlockDc(pdc);

    return bRet;
}
Пример #8
0
ULONG_PTR
APIENTRY
NtGdiPolyPolyDraw( IN HDC hDC,
                   IN PPOINT UnsafePoints,
                   IN PULONG UnsafeCounts,
                   IN ULONG Count,
                   IN INT iFunc )
{
    DC *dc;
    PVOID pTemp;
    LPPOINT SafePoints;
    PULONG SafeCounts;
    NTSTATUS Status = STATUS_SUCCESS;
    BOOL Ret = TRUE;
    ULONG nPoints = 0, nMaxPoints = 0, nInvalid = 0, i;

    if (!UnsafePoints || !UnsafeCounts ||
        Count == 0 || iFunc == 0 || iFunc > GdiPolyPolyRgn)
    {
        /* Windows doesn't set last error */
        return FALSE;
    }

    _SEH2_TRY
    {
        ProbeForRead(UnsafePoints, Count * sizeof(POINT), 1);
        ProbeForRead(UnsafeCounts, Count * sizeof(ULONG), 1);

        /* Count points and validate poligons */
        for (i = 0; i < Count; i++)
        {
            if (UnsafeCounts[i] < 2)
            {
                nInvalid++;
            }
            nPoints += UnsafeCounts[i];
            nMaxPoints = max(nMaxPoints, UnsafeCounts[i]);
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    if (!NT_SUCCESS(Status))
    {
        /* Windows doesn't set last error */
        return FALSE;
    }

    if (nPoints == 0 || nPoints < nMaxPoints)
    {
        /* If all polygon counts are zero, or we have overflow,
           return without setting a last error code. */
        return FALSE;
    }

    if (nInvalid != 0)
    {
        /* If at least one poly count is 0 or 1, fail */
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Allocate one buffer for both counts and points */
    pTemp = ExAllocatePoolWithTag(PagedPool,
                                  Count * sizeof(ULONG) + nPoints * sizeof(POINT),
                                  TAG_SHAPE);
    if (!pTemp)
    {
        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    SafeCounts = pTemp;
    SafePoints = (PVOID)(SafeCounts + Count);

    _SEH2_TRY
    {
        /* Pointers already probed! */
        RtlCopyMemory(SafeCounts, UnsafeCounts, Count * sizeof(ULONG));
        RtlCopyMemory(SafePoints, UnsafePoints, nPoints * sizeof(POINT));
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    if (!NT_SUCCESS(Status))
    {
        ExFreePoolWithTag(pTemp, TAG_SHAPE);
        return FALSE;
    }

    /* Special handling for GdiPolyPolyRgn */
    if (iFunc == GdiPolyPolyRgn)
    {
        HRGN hRgn;
        hRgn = IntCreatePolyPolygonRgn(SafePoints, SafeCounts, Count, (INT_PTR)hDC);
        ExFreePoolWithTag(pTemp, TAG_SHAPE);
        return (ULONG_PTR)hRgn;
    }

    dc = DC_LockDc(hDC);
    if (!dc)
    {
        EngSetLastError(ERROR_INVALID_HANDLE);
        ExFreePoolWithTag(pTemp, TAG_SHAPE);
        return FALSE;
    }

    if (dc->dctype == DC_TYPE_INFO)
    {
        DC_UnlockDc(dc);
        ExFreePoolWithTag(pTemp, TAG_SHAPE);
        /* Yes, Windows really returns TRUE in this case */
        return TRUE;
    }

    DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
                            NULL, dc->rosdc.CombinedClip->rclBounds);

    if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(dc);

    if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
        DC_vUpdateLineBrush(dc);

    /* Perform the actual work */
    switch (iFunc)
    {
        case GdiPolyPolygon:
            Ret = IntGdiPolyPolygon(dc, SafePoints, SafeCounts, Count);
            break;
        case GdiPolyPolyLine:
            Ret = IntGdiPolyPolyline(dc, SafePoints, SafeCounts, Count);
            break;
        case GdiPolyBezier:
            Ret = IntGdiPolyBezier(dc, SafePoints, *SafeCounts);
            break;
        case GdiPolyLineTo:
            Ret = IntGdiPolylineTo(dc, SafePoints, *SafeCounts);
            break;
        case GdiPolyBezierTo:
            Ret = IntGdiPolyBezierTo(dc, SafePoints, *SafeCounts);
            break;
        default:
            EngSetLastError(ERROR_INVALID_PARAMETER);
            Ret = FALSE;
    }

    /* Cleanup and return */
    DC_vFinishBlit(dc, NULL);
    DC_UnlockDc(dc);
    ExFreePoolWithTag(pTemp, TAG_SHAPE);

    return (ULONG_PTR)Ret;
}
Пример #9
0
BOOL FASTCALL
IntGdiPolygon(PDC    dc,
              PPOINT Points,
              int    Count)
{
    SURFACE *psurf;
    PBRUSH pbrLine, pbrFill;
    BOOL ret = FALSE; // Default to failure
    RECTL DestRect;
    int CurrentPoint;
    PDC_ATTR pdcattr;
    POINTL BrushOrigin;
//    int Left;
//    int Top;

    ASSERT(dc); // Caller's responsibility to pass a valid dc

    if (!Points || Count < 2 )
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

/*
    // Find start x, y
    Left = Points[0].x;
    Top  = Points[0].y;
    for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint) {
      Left = min(Left, Points[CurrentPoint].x);
      Top  = min(Top, Points[CurrentPoint].y);
    }
*/

    pdcattr = dc->pdcattr;

    /* Convert to screen coordinates */
    IntLPtoDP(dc, Points, Count);
    for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++)
    {
        Points[CurrentPoint].x += dc->ptlDCOrig.x;
        Points[CurrentPoint].y += dc->ptlDCOrig.y;
    }
    // No need to have path here.
    {
        DestRect.left   = Points[0].x;
        DestRect.right  = Points[0].x;
        DestRect.top    = Points[0].y;
        DestRect.bottom = Points[0].y;

        for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
        {
            DestRect.left     = min(DestRect.left, Points[CurrentPoint].x);
            DestRect.right    = max(DestRect.right, Points[CurrentPoint].x);
            DestRect.top      = min(DestRect.top, Points[CurrentPoint].y);
            DestRect.bottom   = max(DestRect.bottom, Points[CurrentPoint].y);
        }

        if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
            DC_vUpdateFillBrush(dc);

        if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
            DC_vUpdateLineBrush(dc);

        /* Special locking order to avoid lock-ups */
        pbrFill = dc->dclevel.pbrFill;
        pbrLine = dc->dclevel.pbrLine;
        psurf = dc->dclevel.pSurface;
        /* FIXME: psurf can be NULL!!!! don't assert but handle this case gracefully! */
        ASSERT(psurf);

        /* Now fill the polygon with the current fill brush. */
        if (!(pbrFill->flAttrs & BR_IS_NULL))
        {
            BrushOrigin = *((PPOINTL)&pbrFill->ptOrigin);
            BrushOrigin.x += dc->ptlDCOrig.x;
            BrushOrigin.y += dc->ptlDCOrig.y;
            ret = IntFillPolygon (dc,
                                  psurf,
                                  &dc->eboFill.BrushObject,
                                  Points,
                                  Count,
                                  DestRect,
                                  &BrushOrigin);
        }

        // Draw the Polygon Edges with the current pen ( if not a NULL pen )
        if (!(pbrLine->flAttrs & BR_IS_NULL))
        {
            int i;

            for (i = 0; i < Count-1; i++)
            {

// DPRINT1("Polygon Making line from (%d,%d) to (%d,%d)\n",
//                                 Points[0].x, Points[0].y,
//                                 Points[1].x, Points[1].y );

                ret = IntEngLineTo(&psurf->SurfObj,
                                   dc->rosdc.CombinedClip,
                                   &dc->eboLine.BrushObject,
                                   Points[i].x,          /* From */
                                   Points[i].y,
                                   Points[i+1].x,        /* To */
                                   Points[i+1].y,
                                   &DestRect,
                                   ROP2_TO_MIX(pdcattr->jROP2)); /* MIX */
                if (!ret) break;
            }
            /* Close the polygon */
            if (ret)
            {
                ret = IntEngLineTo(&psurf->SurfObj,
                                   dc->rosdc.CombinedClip,
                                   &dc->eboLine.BrushObject,
                                   Points[Count-1].x, /* From */
                                   Points[Count-1].y,
                                   Points[0].x,       /* To */
                                   Points[0].y,
                                   &DestRect,
                                   ROP2_TO_MIX(pdcattr->jROP2)); /* MIX */
            }
        }
    }

    return ret;
}
Пример #10
0
BOOL APIENTRY
GreStretchBltMask(
    HDC hDCDest,
    INT XOriginDest,
    INT YOriginDest,
    INT WidthDest,
    INT HeightDest,
    HDC hDCSrc,
    INT XOriginSrc,
    INT YOriginSrc,
    INT WidthSrc,
    INT HeightSrc,
    DWORD ROP,
    IN DWORD dwBackColor,
    HDC hDCMask,
    INT XOriginMask,
    INT YOriginMask)
{
    PDC DCDest;
    PDC DCSrc  = NULL;
    PDC DCMask = NULL;
    HDC ahDC[3];
    PGDIOBJ apObj[3];
    PDC_ATTR pdcattr;
    SURFACE *BitmapDest, *BitmapSrc = NULL;
    SURFACE *BitmapMask = NULL;
    RECTL DestRect;
    RECTL SourceRect;
    POINTL MaskPoint;
    BOOL Status = FALSE;
    EXLATEOBJ exlo;
    XLATEOBJ *XlateObj = NULL;
    POINTL BrushOrigin;
    BOOL UsesSource;
    BOOL UsesMask;

    FIXUP_ROP(ROP);
    UsesSource = ROP_USES_SOURCE(ROP);
    UsesMask = ROP_USES_MASK(ROP);

    if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return TRUE;
    }

    if (!hDCDest || (UsesSource && !hDCSrc) || (UsesMask && !hDCMask))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    ahDC[0] = hDCDest;
    ahDC[1] = UsesSource ? hDCSrc : NULL;
    ahDC[2] = UsesMask ? hDCMask : NULL;
    if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
    {
        WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to GreStretchBltMask\n", hDCDest, hDCSrc);
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }
    DCDest = apObj[0];
    DCSrc = apObj[1];
    DCMask = apObj[2];

    if (DCDest->dctype == DC_TYPE_INFO)
    {
        if(DCSrc) GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
        if(DCMask) GDIOBJ_vUnlockObject(&DCMask->BaseObject);
        GDIOBJ_vUnlockObject(&DCDest->BaseObject);
        /* Yes, Windows really returns TRUE in this case */
        return TRUE;
    }

    if (UsesSource)
    {
        if (DCSrc->dctype == DC_TYPE_INFO)
        {
            GDIOBJ_vUnlockObject(&DCDest->BaseObject);
            GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
            if(DCMask) GDIOBJ_vUnlockObject(&DCMask->BaseObject);
            /* Yes, Windows really returns TRUE in this case */
            return TRUE;
        }
    }

    pdcattr = DCDest->pdcattr;

    DestRect.left   = XOriginDest;
    DestRect.top    = YOriginDest;
    DestRect.right  = XOriginDest+WidthDest;
    DestRect.bottom = YOriginDest+HeightDest;
    IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);

    DestRect.left   += DCDest->ptlDCOrig.x;
    DestRect.top    += DCDest->ptlDCOrig.y;
    DestRect.right  += DCDest->ptlDCOrig.x;
    DestRect.bottom += DCDest->ptlDCOrig.y;

    SourceRect.left   = XOriginSrc;
    SourceRect.top    = YOriginSrc;
    SourceRect.right  = XOriginSrc+WidthSrc;
    SourceRect.bottom = YOriginSrc+HeightSrc;

    if (UsesSource)
    {
        IntLPtoDP(DCSrc, (LPPOINT)&SourceRect, 2);

        SourceRect.left   += DCSrc->ptlDCOrig.x;
        SourceRect.top    += DCSrc->ptlDCOrig.y;
        SourceRect.right  += DCSrc->ptlDCOrig.x;
        SourceRect.bottom += DCSrc->ptlDCOrig.y;
    }

    BrushOrigin.x = 0;
    BrushOrigin.y = 0;

    /* Only prepare Source and Dest, hdcMask represents a DIB */
    DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);

    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(DCDest);

    /* Determine surfaces to be used in the bitblt */
    BitmapDest = DCDest->dclevel.pSurface;
    if (BitmapDest == NULL)
        goto failed;
    if (UsesSource)
    {
        BitmapSrc = DCSrc->dclevel.pSurface;
        if (BitmapSrc == NULL)
            goto failed;

        /* Create the XLATEOBJ. */
        EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
        XlateObj = &exlo.xlo;
    }

    /* Offset the brush */
    BrushOrigin.x += DCDest->ptlDCOrig.x;
    BrushOrigin.y += DCDest->ptlDCOrig.y;

    /* Make mask surface for source surface */
    if (BitmapSrc && DCMask)
    {
        BitmapMask = DCMask->dclevel.pSurface;
        if (BitmapMask &&
            (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
             BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
        {
            WARN("%dx%d mask is smaller than %dx%d bitmap\n",
                    BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
                    WidthSrc, HeightSrc);
            EXLATEOBJ_vCleanup(&exlo);
            goto failed;
        }
        /* Create mask offset point */
        MaskPoint.x = XOriginMask;
        MaskPoint.y = YOriginMask;
        IntLPtoDP(DCMask, &MaskPoint, 1);
        MaskPoint.x += DCMask->ptlDCOrig.x;
        MaskPoint.y += DCMask->ptlDCOrig.y;
    }

    /* Perform the bitblt operation */
    Status = IntEngStretchBlt(&BitmapDest->SurfObj,
                              BitmapSrc ? &BitmapSrc->SurfObj : NULL,
                              BitmapMask ? &BitmapMask->SurfObj : NULL,
                              &DCDest->co.ClipObj,
                              XlateObj,
                              &DCDest->dclevel.ca,
                              &DestRect,
                              &SourceRect,
                              BitmapMask ? &MaskPoint : NULL,
                              &DCDest->eboFill.BrushObject,
                              &BrushOrigin,
                              ROP_TO_ROP4(ROP));
    if (UsesSource)
    {
        EXLATEOBJ_vCleanup(&exlo);
    }

failed:
    DC_vFinishBlit(DCDest, DCSrc);
    if (UsesSource)
    {
        DC_UnlockDc(DCSrc);
    }
    if (DCMask)
    {
        DC_UnlockDc(DCMask);
    }
    DC_UnlockDc(DCDest);

    return Status;
}
Пример #11
0
BOOL APIENTRY
NtGdiTransparentBlt(
    HDC hdcDst,
    INT xDst,
    INT yDst,
    INT cxDst,
    INT cyDst,
    HDC hdcSrc,
    INT xSrc,
    INT ySrc,
    INT cxSrc,
    INT cySrc,
    COLORREF TransColor)
{
    PDC DCDest, DCSrc;
    HDC ahDC[2];
    PGDIOBJ apObj[2];
    RECTL rcDest, rcSrc;
    SURFACE *BitmapDest, *BitmapSrc = NULL;
    ULONG TransparentColor = 0;
    BOOL Ret = FALSE;
    EXLATEOBJ exlo;

    if ((hdcDst == NULL) || (hdcSrc == NULL))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    TRACE("Locking DCs\n");
    ahDC[0] = hdcDst;
    ahDC[1] = hdcSrc ;
    if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
    {
        WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc);
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }
    DCDest = apObj[0];
    DCSrc = apObj[1];

    if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
    {
        GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
        GDIOBJ_vUnlockObject(&DCDest->BaseObject);
        /* Yes, Windows really returns TRUE in this case */
        return TRUE;
    }

    rcDest.left   = xDst;
    rcDest.top    = yDst;
    rcDest.right  = rcDest.left + cxDst;
    rcDest.bottom = rcDest.top + cyDst;
    IntLPtoDP(DCDest, (LPPOINT)&rcDest, 2);

    rcDest.left   += DCDest->ptlDCOrig.x;
    rcDest.top    += DCDest->ptlDCOrig.y;
    rcDest.right  += DCDest->ptlDCOrig.x;
    rcDest.bottom += DCDest->ptlDCOrig.y;

    rcSrc.left   = xSrc;
    rcSrc.top    = ySrc;
    rcSrc.right  = rcSrc.left + cxSrc;
    rcSrc.bottom = rcSrc.top + cySrc;
    IntLPtoDP(DCSrc, (LPPOINT)&rcSrc, 2);

    rcSrc.left   += DCSrc->ptlDCOrig.x;
    rcSrc.top    += DCSrc->ptlDCOrig.y;
    rcSrc.right  += DCSrc->ptlDCOrig.x;
    rcSrc.bottom += DCSrc->ptlDCOrig.y;

    /* Prepare for blit */
    DC_vPrepareDCsForBlit(DCDest, &rcDest, DCSrc, &rcSrc);

    BitmapDest = DCDest->dclevel.pSurface;
    if (!BitmapDest)
    {
        goto done;
    }

    BitmapSrc = DCSrc->dclevel.pSurface;
    if (!BitmapSrc)
    {
        goto done;
    }

    /* Translate Transparent (RGB) Color to the source palette */
    EXLATEOBJ_vInitialize(&exlo, &gpalRGB, BitmapSrc->ppal, 0, 0, 0);
    TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor);
    EXLATEOBJ_vCleanup(&exlo);

    EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);

    Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
        &DCDest->co.ClipObj, &exlo.xlo, &rcDest, &rcSrc,
        TransparentColor, 0);

    EXLATEOBJ_vCleanup(&exlo);

done:
    DC_vFinishBlit(DCDest, DCSrc);
    GDIOBJ_vUnlockObject(&DCDest->BaseObject);
    GDIOBJ_vUnlockObject(&DCSrc->BaseObject);

    return Ret;
}
Пример #12
0
HPEN
APIENTRY
IntGdiExtCreatePen(
    DWORD dwPenStyle,
    DWORD dwWidth,
    IN ULONG ulBrushStyle,
    IN ULONG ulColor,
    IN ULONG_PTR ulClientHatch,
    IN ULONG_PTR ulHatch,
    DWORD dwStyleCount,
    PULONG pStyle,
    IN ULONG cjDIB,
    IN BOOL bOldStylePen,
    IN OPTIONAL HBRUSH hbrush)
{
    HPEN hPen;
    PBRUSH pbrushPen;
    static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55, 0};
    static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0, 0};
    static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38, 0};
    static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0, 0};
    static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38, 0};

    dwWidth = abs(dwWidth);

    if ( (dwPenStyle & PS_STYLE_MASK) == PS_NULL)
    {
        return StockObjects[NULL_PEN];
    }

    if (bOldStylePen)
    {
        pbrushPen = PEN_AllocPenWithHandle();
    }
    else
    {
        pbrushPen = PEN_AllocExtPenWithHandle();
    }

    if (!pbrushPen)
    {
        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        DPRINT("Can't allocate pen\n");
        return 0;
    }
    hPen = pbrushPen->BaseObject.hHmgr;

    // If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation.
    if ((bOldStylePen) && (!dwWidth) && ((dwPenStyle & PS_STYLE_MASK) != PS_SOLID))
        dwWidth = 1;

    pbrushPen->lWidth = dwWidth;
    pbrushPen->eWidth = (FLOAT)pbrushPen->lWidth;
    pbrushPen->ulPenStyle = dwPenStyle;
    pbrushPen->BrushAttr.lbColor = ulColor;
    pbrushPen->iBrushStyle = ulBrushStyle;
    // FIXME: Copy the bitmap first ?
    pbrushPen->hbmClient = (HANDLE)ulClientHatch;
    pbrushPen->dwStyleCount = dwStyleCount;
    pbrushPen->pStyle = pStyle;

    pbrushPen->flAttrs = bOldStylePen ? BR_IS_OLDSTYLEPEN : BR_IS_PEN;

    // If dwPenStyle is PS_COSMETIC, the width must be set to 1.
    if ( !(bOldStylePen) && ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC) && ( dwWidth != 1) )
        goto ExitCleanup;

    switch (dwPenStyle & PS_STYLE_MASK)
    {
    case PS_NULL:
        pbrushPen->flAttrs |= BR_IS_NULL;
        break;

    case PS_SOLID:
        pbrushPen->flAttrs |= BR_IS_SOLID;
        break;

    case PS_ALTERNATE:
        pbrushPen->flAttrs |= BR_IS_BITMAP;
        pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
        break;

    case PS_DOT:
        pbrushPen->flAttrs |= BR_IS_BITMAP;
        pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
        break;

    case PS_DASH:
        pbrushPen->flAttrs |= BR_IS_BITMAP;
        pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
        break;

    case PS_DASHDOT:
        pbrushPen->flAttrs |= BR_IS_BITMAP;
        pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
        break;

    case PS_DASHDOTDOT:
        pbrushPen->flAttrs |= BR_IS_BITMAP;
        pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
        break;

    case PS_INSIDEFRAME:
        pbrushPen->flAttrs |= (BR_IS_SOLID | BR_IS_INSIDEFRAME);
        break;

    case PS_USERSTYLE:
        if ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC)
        {
            /* FIXME: PS_USERSTYLE workaround */
            DPRINT1("PS_COSMETIC | PS_USERSTYLE not handled\n");
            pbrushPen->flAttrs |= BR_IS_SOLID;
            break;
        }
        else
        {
            UINT i;
            BOOL has_neg = FALSE, all_zero = TRUE;

            for(i = 0; (i < dwStyleCount) && !has_neg; i++)
            {
                has_neg = has_neg || (((INT)(pStyle[i])) < 0);
                all_zero = all_zero && (pStyle[i] == 0);
            }

            if(all_zero || has_neg)
            {
                goto ExitCleanup;
            }
        }
        /* FIXME: What style here? */
        pbrushPen->flAttrs |= 0;
        break;

    default:
        DPRINT1("IntGdiExtCreatePen unknown penstyle %x\n", dwPenStyle);
    }

    PEN_UnlockPen(pbrushPen);
    return hPen;

ExitCleanup:
    EngSetLastError(ERROR_INVALID_PARAMETER);
    pbrushPen->pStyle = NULL;
    GDIOBJ_vDeleteObject(&pbrushPen->BaseObject);

    return NULL;
}
Пример #13
0
HPEN
APIENTRY
NtGdiExtCreatePen(
    DWORD dwPenStyle,
    DWORD ulWidth,
    IN ULONG ulBrushStyle,
    IN ULONG ulColor,
    IN ULONG_PTR ulClientHatch,
    IN ULONG_PTR ulHatch,
    DWORD dwStyleCount,
    PULONG pUnsafeStyle,
    IN ULONG cjDIB,
    IN BOOL bOldStylePen,
    IN OPTIONAL HBRUSH hBrush)
{
    NTSTATUS Status = STATUS_SUCCESS;
    DWORD* pSafeStyle = NULL;
    HPEN hPen;

    if ((int)dwStyleCount < 0) return 0;
    if (dwStyleCount > 16)
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }

    if (dwStyleCount > 0)
    {
        if (pUnsafeStyle == NULL)
        {
            EngSetLastError(ERROR_INVALID_PARAMETER);
            return 0;
        }

        pSafeStyle = ExAllocatePoolWithTag(NonPagedPool,
                                           dwStyleCount * sizeof(DWORD),
                                           GDITAG_PENSTYLE);
        if (!pSafeStyle)
        {
            SetLastNtError(ERROR_NOT_ENOUGH_MEMORY);
            return 0;
        }
        _SEH2_TRY
        {
            ProbeForRead(pUnsafeStyle, dwStyleCount * sizeof(DWORD), 1);
            RtlCopyMemory(pSafeStyle,
            pUnsafeStyle,
            dwStyleCount * sizeof(DWORD));
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END
        if(!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            ExFreePoolWithTag(pSafeStyle, GDITAG_PENSTYLE);
            return 0;
        }
    }

    if (ulBrushStyle == BS_PATTERN)
    {
        _SEH2_TRY
        {
            ProbeForRead((PVOID)ulHatch, cjDIB, 1);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END
        if(!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            if (pSafeStyle) ExFreePoolWithTag(pSafeStyle, GDITAG_PENSTYLE);
            return 0;
        }
    }
Пример #14
0
HANDLE APIENTRY
NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd)
{
    HANDLE hRet = NULL;
    PCLIP pElement;
    PWINSTATION_OBJECT pWinStaObj = NULL;

    TRACE("NtUserGetClipboardData(%x, %p)\n", fmt, pgcd);

    UserEnterShared();

    pWinStaObj = IntGetWinStaForCbAccess();
    if (!pWinStaObj)
        goto cleanup;

    if (!IntIsClipboardOpenByMe(pWinStaObj))
    {
        EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN);
        goto cleanup;
    }

    pElement = IntIsFormatAvailable(pWinStaObj, fmt);
    if (pElement && IS_DATA_DELAYED(pElement) && pWinStaObj->spwndClipOwner)
    {
        /* Send WM_RENDERFORMAT message */
        pWinStaObj->fInDelayedRendering = TRUE;
        co_IntSendMessage(pWinStaObj->spwndClipOwner->head.h, WM_RENDERFORMAT, (WPARAM)fmt, 0);
        pWinStaObj->fInDelayedRendering = FALSE;

        /* Data should be in clipboard now */
        pElement = IntIsFormatAvailable(pWinStaObj, fmt);
    }

    if (!pElement || IS_DATA_DELAYED(pElement))
        goto cleanup;


    if (IS_DATA_SYNTHESIZED(pElement))
    {
        /* Note: Data is synthesized in usermode */
        /* TODO: Add more formats */
        switch (fmt)
        {
            case CF_UNICODETEXT:
            case CF_TEXT:
            case CF_OEMTEXT:
                pElement = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT);
                if (IS_DATA_SYNTHESIZED(pElement))
                    pElement = IntIsFormatAvailable(pWinStaObj, CF_TEXT);
                if (IS_DATA_SYNTHESIZED(pElement))
                    pElement = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT);
                break;
            case CF_BITMAP:
                IntSynthesizeBitmap(pWinStaObj, pElement);
                break;
            default:
                ASSERT(FALSE);
        }
    }

    _SEH2_TRY
    {
        ProbeForWrite(pgcd, sizeof(*pgcd), 1);
        pgcd->uFmtRet = pElement->fmt;
        pgcd->fGlobalHandle = pElement->fGlobalHandle;

        /* Text and bitmap needs more data */
        if (fmt == CF_TEXT)
        {
            PCLIP pLocaleEl;

            pLocaleEl = IntIsFormatAvailable(pWinStaObj, CF_LOCALE);
            if (pLocaleEl && !IS_DATA_DELAYED(pLocaleEl))
                pgcd->hLocale = pLocaleEl->hData;
        }
        else if (fmt == CF_BITMAP)
        {
            PCLIP pPaletteEl;

            pPaletteEl = IntIsFormatAvailable(pWinStaObj, CF_PALETTE);
            if (pPaletteEl && !IS_DATA_DELAYED(pPaletteEl))
                pgcd->hPalette = pPaletteEl->hData;
        }

        hRet = pElement->hData;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        SetLastNtError(_SEH2_GetExceptionCode());
    }
    _SEH2_END;

cleanup:
    if(pWinStaObj)
        ObDereferenceObject(pWinStaObj);

    UserLeave();

    TRACE("NtUserGetClipboardData returns %p\n", hRet);

    return hRet;
}
Пример #15
0
INT
APIENTRY
NtGdiDescribePixelFormat(HDC  hDC,
                         INT  PixelFormat,
                         UINT  BufSize,
                         LPPIXELFORMATDESCRIPTOR  pfd)
{
    PDC pdc;
    PPDEVOBJ ppdev;
    INT Ret = 0;
    PIXELFORMATDESCRIPTOR pfdSafe;
    NTSTATUS Status = STATUS_SUCCESS;

    if (!BufSize) return 0;

    pdc = DC_LockDc(hDC);
    if (!pdc)
    {
        EngSetLastError(ERROR_INVALID_HANDLE);
        return 0;
    }

    if (!pdc->ipfdDevMax) IntGetipfdDevMax(pdc);

    if ( BufSize < sizeof(PIXELFORMATDESCRIPTOR) ||
            PixelFormat < 1 ||
            PixelFormat > pdc->ipfdDevMax )
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        goto Exit;
    }

    ppdev = pdc->ppdev;

    if (ppdev->flFlags & PDEV_META_DEVICE)
    {
        UNIMPLEMENTED;
        goto Exit;
    }

    if (ppdev->DriverFunctions.DescribePixelFormat)
    {
        Ret = ppdev->DriverFunctions.DescribePixelFormat(
                  ppdev->dhpdev,
                  PixelFormat,
                  sizeof(PIXELFORMATDESCRIPTOR),
                  &pfdSafe);
    }

    _SEH2_TRY
    {
        ProbeForWrite( pfd,
        sizeof(PIXELFORMATDESCRIPTOR),
        1);
        RtlCopyMemory(&pfdSafe, pfd, sizeof(PIXELFORMATDESCRIPTOR));
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    if (!NT_SUCCESS(Status)) SetLastNtError(Status);

Exit:
    DC_UnlockDc(pdc);
    return Ret;
}
Пример #16
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;
}
Пример #17
0
BOOL APIENTRY
NtGdiAlphaBlend(
    HDC hDCDest,
    LONG XOriginDest,
    LONG YOriginDest,
    LONG WidthDest,
    LONG HeightDest,
    HDC hDCSrc,
    LONG XOriginSrc,
    LONG YOriginSrc,
    LONG WidthSrc,
    LONG HeightSrc,
    BLENDFUNCTION BlendFunc,
    HANDLE hcmXform)
{
    PDC DCDest;
    PDC DCSrc;
    HDC ahDC[2];
    PGDIOBJ apObj[2];
    SURFACE *BitmapDest, *BitmapSrc;
    RECTL DestRect, SourceRect;
    BOOL bResult;
    EXLATEOBJ exlo;
    BLENDOBJ BlendObj;
    BlendObj.BlendFunction = BlendFunc;

    if (WidthDest < 0 || HeightDest < 0 || WidthSrc < 0 || HeightSrc < 0)
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if ((hDCDest == NULL) || (hDCSrc == NULL))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    TRACE("Locking DCs\n");
    ahDC[0] = hDCDest;
    ahDC[1] = hDCSrc ;
    if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
    {
        WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }
    DCDest = apObj[0];
    DCSrc = apObj[1];

    if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
    {
        GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
        GDIOBJ_vUnlockObject(&DCDest->BaseObject);
        /* Yes, Windows really returns TRUE in this case */
        return TRUE;
    }

    DestRect.left   = XOriginDest;
    DestRect.top    = YOriginDest;
    DestRect.right  = XOriginDest + WidthDest;
    DestRect.bottom = YOriginDest + HeightDest;
    IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);

    DestRect.left   += DCDest->ptlDCOrig.x;
    DestRect.top    += DCDest->ptlDCOrig.y;
    DestRect.right  += DCDest->ptlDCOrig.x;
    DestRect.bottom += DCDest->ptlDCOrig.y;

    SourceRect.left   = XOriginSrc;
    SourceRect.top    = YOriginSrc;
    SourceRect.right  = XOriginSrc + WidthSrc;
    SourceRect.bottom = YOriginSrc + HeightSrc;
    IntLPtoDP(DCSrc, (LPPOINT)&SourceRect, 2);

    SourceRect.left   += DCSrc->ptlDCOrig.x;
    SourceRect.top    += DCSrc->ptlDCOrig.y;
    SourceRect.right  += DCSrc->ptlDCOrig.x;
    SourceRect.bottom += DCSrc->ptlDCOrig.y;

    if (!DestRect.right ||
        !DestRect.bottom ||
        !SourceRect.right ||
        !SourceRect.bottom)
    {
        GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
        GDIOBJ_vUnlockObject(&DCDest->BaseObject);
        return TRUE;
    }

    /* Prepare DCs for blit */
    TRACE("Preparing DCs for blit\n");
    DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);

    /* Determine surfaces to be used in the bitblt */
    BitmapDest = DCDest->dclevel.pSurface;
    if (!BitmapDest)
    {
        bResult = FALSE ;
        goto leave ;
    }

    BitmapSrc = DCSrc->dclevel.pSurface;
    if (!BitmapSrc)
    {
        bResult = FALSE;
        goto leave;
    }

    /* Create the XLATEOBJ. */
    EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);

    /* Perform the alpha blend operation */
    TRACE("Performing the alpha blend\n");
    bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
                               &BitmapSrc->SurfObj,
                               &DCDest->co.ClipObj,
                               &exlo.xlo,
                               &DestRect,
                               &SourceRect,
                               &BlendObj);

    EXLATEOBJ_vCleanup(&exlo);
leave :
    TRACE("Finishing blit\n");
    DC_vFinishBlit(DCDest, DCSrc);
    GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
    GDIOBJ_vUnlockObject(&DCDest->BaseObject);

    return bResult;
}
Пример #18
0
/*
 * @unimplemented
 */
DWORD_PTR
APIENTRY
NtUserCallNoParam(DWORD Routine)
{
   DWORD_PTR Result = 0;
   DECLARE_RETURN(DWORD_PTR);

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

   switch(Routine)
   {
      case NOPARAM_ROUTINE_CREATEMENU:
         Result = (DWORD_PTR)UserCreateMenu(FALSE);
         break;

      case NOPARAM_ROUTINE_CREATEMENUPOPUP:
         Result = (DWORD_PTR)UserCreateMenu(TRUE);
         break;

      case NOPARAM_ROUTINE_DESTROY_CARET:
         Result = (DWORD_PTR)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread);
         break;

      case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP:
         Result = (DWORD_PTR)IntInitMessagePumpHook();
         break;

      case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP:
         Result = (DWORD_PTR)IntUninitMessagePumpHook();
         break;

      case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO:
         Result = (DWORD_PTR)MsqGetMessageExtraInfo();
         break;

      case NOPARAM_ROUTINE_MSQCLEARWAKEMASK:
         RETURN( (DWORD_PTR)IntMsqClearWakeMask());

      case NOPARAM_ROUTINE_GETMSESSAGEPOS:
      {
         PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
         RETURN( (DWORD_PTR)MAKELONG(pti->ptLast.x, pti->ptLast.y));
      }

      case NOPARAM_ROUTINE_RELEASECAPTURE:
         RETURN( (DWORD_PTR)IntReleaseCapture());

      case NOPARAM_ROUTINE_LOADUSERAPIHOOK:
         RETURN(UserLoadApiHook());

      case NOPARAM_ROUTINE_ZAPACTIVEANDFOUS:
      {
         PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
         TRACE("Zapping the Active and Focus window out of the Queue!\n");
         pti->MessageQueue->spwndFocus = NULL;
         pti->MessageQueue->spwndActive = NULL;
         RETURN(0);
      }

      /* this is a Reactos only case and is needed for gui-on-demand */
      case NOPARAM_ROUTINE_ISCONSOLEMODE:
          RETURN( ScreenDeviceContext == NULL );

      default:
         ERR("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine);
         EngSetLastError(ERROR_INVALID_PARAMETER);
         break;
   }
   RETURN(Result);

CLEANUP:
   TRACE("Leave NtUserCallNoParam, ret=%p\n",(PVOID)_ret_);
   UserLeave();
   END_CLEANUP;
}
Пример #19
0
BOOL APIENTRY
NtGdiMaskBlt(
    HDC hdcDest,
    INT nXDest,
    INT nYDest,
    INT nWidth,
    INT nHeight,
    HDC hdcSrc,
    INT nXSrc,
    INT nYSrc,
    HBITMAP hbmMask,
    INT xMask,
    INT yMask,
    DWORD dwRop,
    IN DWORD crBackColor)
{
    PDC DCDest;
    PDC DCSrc = NULL;
    HDC ahDC[2];
    PGDIOBJ apObj[2];
    PDC_ATTR pdcattr = NULL;
    SURFACE *BitmapDest, *BitmapSrc = NULL, *psurfMask = NULL;
    RECTL DestRect, SourceRect;
    POINTL SourcePoint, MaskPoint;
    BOOL Status = FALSE;
    EXLATEOBJ exlo;
    XLATEOBJ *XlateObj = NULL;
    BOOL UsesSource;

    FIXUP_ROP(dwRop); // FIXME: why do we need this???

    //DPRINT1("dwRop : 0x%08x\n", dwRop);
    UsesSource = ROP_USES_SOURCE(dwRop);
    if (!hdcDest || (UsesSource && !hdcSrc))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Check if we need a mask and have a mask bitmap */
    if (ROP_USES_MASK(dwRop) && (hbmMask != NULL))
    {
        /* Reference the mask bitmap */
        psurfMask = SURFACE_ShareLockSurface(hbmMask);
        if (psurfMask == NULL)
        {
            EngSetLastError(ERROR_INVALID_HANDLE);
            return FALSE;
        }

        /* Make sure the mask bitmap is 1 BPP */
        if (gajBitsPerFormat[psurfMask->SurfObj.iBitmapFormat] != 1)
        {
            EngSetLastError(ERROR_INVALID_PARAMETER);
            SURFACE_ShareUnlockSurface(psurfMask);
            return FALSE;
        }
    }
    else
    {
        /* We use NULL, if we need a mask, the Eng function will take care of
           that and use the brushobject to get a mask */
        psurfMask = NULL;
    }

    MaskPoint.x = xMask;
    MaskPoint.y = yMask;

    /* Take care of source and destination bitmap */
    TRACE("Locking DCs\n");
    ahDC[0] = hdcDest;
    ahDC[1] = UsesSource ? hdcSrc : NULL;
    if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
    {
        WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDest, hdcSrc);
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }
    DCDest = apObj[0];
    DCSrc = apObj[1];

    ASSERT(DCDest);
    if (NULL == DCDest)
    {
        if(DCSrc) DC_UnlockDc(DCSrc);
        WARN("Invalid destination dc handle (0x%p) passed to NtGdiBitBlt\n", hdcDest);
        return FALSE;
    }

    if (DCDest->dctype == DC_TYPE_INFO)
    {
        if(DCSrc) DC_UnlockDc(DCSrc);
        DC_UnlockDc(DCDest);
        /* Yes, Windows really returns TRUE in this case */
        return TRUE;
    }

    if (UsesSource)
    {
        ASSERT(DCSrc);
        if (DCSrc->dctype == DC_TYPE_INFO)
        {
            DC_UnlockDc(DCDest);
            DC_UnlockDc(DCSrc);
            /* Yes, Windows really returns TRUE in this case */
            return TRUE;
        }
    }

    pdcattr = DCDest->pdcattr;

    DestRect.left   = nXDest;
    DestRect.top    = nYDest;
    DestRect.right  = nXDest + nWidth;
    DestRect.bottom = nYDest + nHeight;
    IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);

    DestRect.left   += DCDest->ptlDCOrig.x;
    DestRect.top    += DCDest->ptlDCOrig.y;
    DestRect.right  += DCDest->ptlDCOrig.x;
    DestRect.bottom += DCDest->ptlDCOrig.y;

    SourcePoint.x = nXSrc;
    SourcePoint.y = nYSrc;

    if (UsesSource)
    {
        IntLPtoDP(DCSrc, (LPPOINT)&SourcePoint, 1);

        SourcePoint.x += DCSrc->ptlDCOrig.x;
        SourcePoint.y += DCSrc->ptlDCOrig.y;
        /* Calculate Source Rect */
        SourceRect.left = SourcePoint.x;
        SourceRect.top = SourcePoint.y;
        SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left;
        SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ;
    }
    else
    {
        SourceRect.left = 0;
        SourceRect.top = 0;
        SourceRect.right = 0;
        SourceRect.bottom = 0;
    }

    /* Prepare blit */
    DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);

    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(DCDest);

    /* Determine surfaces to be used in the bitblt */
    BitmapDest = DCDest->dclevel.pSurface;
    if (!BitmapDest)
        goto cleanup;

    if (UsesSource)
    {
        {
            BitmapSrc = DCSrc->dclevel.pSurface;
            if (!BitmapSrc)
                goto cleanup;
        }
    }

    /* Create the XLATEOBJ. */
    if (UsesSource)
    {
        EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
        XlateObj = &exlo.xlo;
    }


    /* Perform the bitblt operation */
    Status = IntEngBitBlt(&BitmapDest->SurfObj,
                          BitmapSrc ? &BitmapSrc->SurfObj : NULL,
                          psurfMask ? &psurfMask->SurfObj : NULL,
                          &DCDest->co.ClipObj,
                          XlateObj,
                          &DestRect,
                          &SourcePoint,
                          &MaskPoint,
                          &DCDest->eboFill.BrushObject,
                          &DCDest->dclevel.pbrFill->ptOrigin,
                          ROP_TO_ROP4(dwRop));

    if (UsesSource)
        EXLATEOBJ_vCleanup(&exlo);
cleanup:
    DC_vFinishBlit(DCDest, DCSrc);
    if (UsesSource)
    {
        DC_UnlockDc(DCSrc);
    }
    DC_UnlockDc(DCDest);
    if(psurfMask) SURFACE_ShareUnlockSurface(psurfMask);

    return Status;
}
Пример #20
0
HBITMAP
APIENTRY
NtGdiCreateBitmap(
    IN INT nWidth,
    IN INT nHeight,
    IN UINT cPlanes,
    IN UINT cBitsPixel,
    IN OPTIONAL LPBYTE pUnsafeBits)
{
    HBITMAP hbmp;
    ULONG cRealBpp, cjWidthBytes, iFormat;
    ULONGLONG cjSize;
    PSURFACE psurf;

    /* Calculate bitmap format and real bits per pixel. */
    iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
    cRealBpp = gajBitsPerFormat[iFormat];

    /* Calculate width and image size in bytes */
    cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cRealBpp);
    cjSize = (ULONGLONG)cjWidthBytes * nHeight;

    /* Check parameters (possible overflow of cjSize!) */
    if ((iFormat == 0) || (nWidth <= 0) || (nWidth >= 0x8000000) || (nHeight <= 0) ||
        (cBitsPixel > 32) || (cPlanes > 32) || (cjSize >= 0x100000000ULL))
    {
        DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%u, Planes=%u\n",
                nWidth, nHeight, cBitsPixel, cPlanes);
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    /* Allocate the surface (but don't set the bits) */
    psurf = SURFACE_AllocSurface(STYPE_BITMAP,
                                 nWidth,
                                 nHeight,
                                 iFormat,
                                 0,
                                 0,
                                 NULL);
    if (!psurf)
    {
        DPRINT1("SURFACE_AllocSurface failed.\n");
        return NULL;
    }

    /* Mark as API and DDB bitmap */
    psurf->flags |= (API_BITMAP | DDB_SURFACE);

    /* Check if we have bits to set */
    if (pUnsafeBits)
    {
        /* Protect with SEH and copy the bits */
        _SEH2_TRY
        {
            ProbeForRead(pUnsafeBits, (SIZE_T)cjSize, 1);
            UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            GDIOBJ_vDeleteObject(&psurf->BaseObject);
            _SEH2_YIELD(return NULL;)
        }
        _SEH2_END
    }
    else
    {
Пример #21
0
BOOL APIENTRY
NtGdiExtFloodFill(
    HDC  hDC,
    INT  XStart,
    INT  YStart,
    COLORREF  Color,
    UINT  FillType)
{
    PDC dc;
    PDC_ATTR   pdcattr;
    SURFACE    *psurf = NULL;
    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;
    }

    pdcattr = dc->pdcattr;

    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(dc);

    if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
        DC_vUpdateLineBrush(dc);

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

    Ret = NtGdiPtInRegion(dc->rosdc.hGCClipRgn, Pt.x, Pt.y);
    if (Ret)
        IntGdiGetRgnBox(dc->rosdc.hGCClipRgn,(LPRECT)&DestRect);
    else
        goto cleanup;

    DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);

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

    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);

    EXLATEOBJ_vCleanup(&exlo);

cleanup:
    DC_vFinishBlit(dc, NULL);
    DC_UnlockDc(dc);
    return Ret;
}
Пример #22
0
LONG
APIENTRY
NtUserChangeDisplaySettings(
    PUNICODE_STRING pustrDevice,
    LPDEVMODEW lpDevMode,
    HWND hwnd,
    DWORD dwflags,
    LPVOID lParam)
{
    WCHAR awcDevice[CCHDEVICENAME];
    UNICODE_STRING ustrDevice;
    DEVMODEW dmLocal;
    LONG lRet;

    /* Check arguments */
    if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) ||
        (hwnd != NULL))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return DISP_CHANGE_BADPARAM;
    }

    /* Check flags */
    if ((dwflags & (CDS_GLOBAL|CDS_NORESET)) && !(dwflags & CDS_UPDATEREGISTRY))
    {
        return DISP_CHANGE_BADFLAGS;
    }

    /* Copy the device name */
    if (pustrDevice)
    {
        /* Initialize destination string */
        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));

        _SEH2_TRY
        {
            /* Probe the UNICODE_STRING and the buffer */
            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);

            /* Copy the string */
            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Set and return error */
            SetLastNtError(_SEH2_GetExceptionCode());
            _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
        }
        _SEH2_END

        pustrDevice = &ustrDevice;
   }

    /* Copy devmode */
    if (lpDevMode)
    {
        _SEH2_TRY
        {
            /* Probe the size field of the structure */
            ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1);

            /* Calculate usable size */
            dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize);

            /* Probe and copy the full DEVMODE */
            ProbeForRead(lpDevMode, dmLocal.dmSize, 1);
            RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Set and return error */
            SetLastNtError(_SEH2_GetExceptionCode());
            _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
        }
        _SEH2_END

        /* Check for extra parameters */
        if (dmLocal.dmDriverExtra > 0)
        {
            /* FIXME: TODO */
            ERR("lpDevMode->dmDriverExtra is IGNORED!\n");
            dmLocal.dmDriverExtra = 0;
        }

        /* Use the local structure */
        lpDevMode = &dmLocal;
    }

    // FIXME: Copy videoparameters

    /* Acquire global USER lock */
    UserEnterExclusive();

    /* Call internal function */
    lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL);

    /* Release lock */
    UserLeave();

    return lRet;
}
Пример #23
0
BOOL APIENTRY
NtGdiEllipse(
    HDC hDC,
    int Left,
    int Top,
    int Right,
    int Bottom)
{
    PDC dc;
    PDC_ATTR pdcattr;
    RECTL RectBounds;
    PBRUSH pbrush;
    BOOL ret = TRUE;
    LONG PenWidth, PenOrigWidth;
    LONG RadiusX, RadiusY, CenterX, CenterY;
    PBRUSH pFillBrushObj;
    BRUSH tmpFillBrushObj;

    if ((Left == Right) || (Top == Bottom)) return TRUE;

    dc = DC_LockDc(hDC);
    if (dc == NULL)
    {
       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 (PATH_IsPathOpen(dc->dclevel))
    {
        ret = PATH_Ellipse(dc, Left, Top, Right, Bottom);
        DC_UnlockDc(dc);
        return ret;
    }

    if (Right < Left)
    {
       INT tmp = Right; Right = Left; Left = tmp;
    }
    if (Bottom < Top)
    {
       INT tmp = Bottom; Bottom = Top; Top = tmp;
    }

    pdcattr = dc->pdcattr;

    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(dc);

    if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
        DC_vUpdateLineBrush(dc);

    pbrush = PEN_ShareLockPen(pdcattr->hpen);
    if (!pbrush)
    {
        DPRINT1("Ellipse Fail 1\n");
        DC_UnlockDc(dc);
        EngSetLastError(ERROR_INTERNAL_ERROR);
        return FALSE;
    }

    PenOrigWidth = PenWidth = pbrush->ptPenWidth.x;
    if (pbrush->ulPenStyle == PS_NULL) PenWidth = 0;

    if (pbrush->ulPenStyle == PS_INSIDEFRAME)
    {
       if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
       if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
       Left   += PenWidth / 2;
       Right  -= (PenWidth - 1) / 2;
       Top    += PenWidth / 2;
       Bottom -= (PenWidth - 1) / 2;
    }

    if (!PenWidth) PenWidth = 1;
    pbrush->ptPenWidth.x = PenWidth;

    RectBounds.left   = Left;
    RectBounds.right  = Right;
    RectBounds.top    = Top;
    RectBounds.bottom = Bottom;

    IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);

    RectBounds.left += dc->ptlDCOrig.x;
    RectBounds.right += dc->ptlDCOrig.x;
    RectBounds.top += dc->ptlDCOrig.y;
    RectBounds.bottom += dc->ptlDCOrig.y;

    // Setup for dynamic width and height.
    RadiusX = max((RectBounds.right - RectBounds.left) / 2, 2); // Needs room
    RadiusY = max((RectBounds.bottom - RectBounds.top) / 2, 2);
    CenterX = (RectBounds.right + RectBounds.left) / 2;
    CenterY = (RectBounds.bottom + RectBounds.top) / 2;

    DPRINT("Ellipse 1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
               RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom);

    DPRINT("Ellipse 2: XLeft: %d, YLeft: %d, Width: %d, Height: %d\n",
               CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);

    pFillBrushObj = BRUSH_ShareLockBrush(pdcattr->hbrush);
    if (NULL == pFillBrushObj)
    {
        DPRINT1("FillEllipse Fail\n");
        EngSetLastError(ERROR_INTERNAL_ERROR);
        ret = FALSE;
    }
    else
    {
        RtlCopyMemory(&tmpFillBrushObj, pFillBrushObj, sizeof(tmpFillBrushObj));
        //tmpFillBrushObj.ptOrigin.x += RectBounds.left - Left;
        //tmpFillBrushObj.ptOrigin.y += RectBounds.top - Top;
        tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x;
        tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y;

        DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);

        ret = IntFillEllipse( dc,
                              CenterX - RadiusX,
                              CenterY - RadiusY,
                              RadiusX*2, // Width
                              RadiusY*2, // Height
                              &tmpFillBrushObj);
        BRUSH_ShareUnlockBrush(pFillBrushObj);

        if (ret)
        {
           ret = IntDrawEllipse( dc,
                                 CenterX - RadiusX,
                                 CenterY - RadiusY,
                                 RadiusX*2, // Width
                                 RadiusY*2, // Height
                                 pbrush);
        }

        DC_vFinishBlit(dc, NULL);
    }

    pbrush->ptPenWidth.x = PenOrigWidth;
    PEN_ShareUnlockPen(pbrush);
    DC_UnlockDc(dc);
    DPRINT("Ellipse Exit.\n");
    return ret;
}
Пример #24
0
BOOL
APIENTRY
NtUserCreateCaret(
   HWND hWnd,
   HBITMAP hBitmap,
   int nWidth,
   int nHeight)
{
   PWND Window;
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;
   DECLARE_RETURN(BOOL);

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

   if(!(Window = UserGetWindowObject(hWnd)))
   {
      RETURN(FALSE);
   }

   if(Window->head.pti->pEThread != PsGetCurrentThread())
   {
      EngSetLastError(ERROR_ACCESS_DENIED);
      RETURN(FALSE);
   }

   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;

   if (ThreadQueue->CaretInfo->Visible)
   {
      IntKillTimer(Window, IDCARETTIMER, TRUE);
      co_IntHideCaret(ThreadQueue->CaretInfo);
   }

   ThreadQueue->CaretInfo->hWnd = hWnd;
   if(hBitmap)
   {
      ThreadQueue->CaretInfo->Bitmap = hBitmap;
      ThreadQueue->CaretInfo->Size.cx = ThreadQueue->CaretInfo->Size.cy = 0;
   }
   else
   {
      if (nWidth == 0)
      {
          nWidth = UserGetSystemMetrics(SM_CXBORDER);
      }
      if (nHeight == 0)
      {
          nHeight = UserGetSystemMetrics(SM_CYBORDER);
      }
      ThreadQueue->CaretInfo->Bitmap = (HBITMAP)0;
      ThreadQueue->CaretInfo->Size.cx = nWidth;
      ThreadQueue->CaretInfo->Size.cy = nHeight;
   }
   ThreadQueue->CaretInfo->Visible = 0;
   ThreadQueue->CaretInfo->Showing = 0;

   IntSetTimer( Window, IDCARETTIMER, gpsi->dtCaretBlink, CaretSystemTimerProc, TMRF_SYSTEM );

   IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);

   RETURN(TRUE);

CLEANUP:
   TRACE("Leave NtUserCreateCaret, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Пример #25
0
BOOL
FASTCALL
IntRoundRect(
    PDC  dc,
    int  Left,
    int  Top,
    int  Right,
    int  Bottom,
    int  xCurveDiameter,
    int  yCurveDiameter)
{
    PDC_ATTR pdcattr;
    PBRUSH   pbrLine, pbrFill;
    RECTL RectBounds;
    LONG PenWidth, PenOrigWidth;
    BOOL ret = TRUE; // Default to success
    BRUSH brushTemp;

    ASSERT ( dc ); // Caller's responsibility to set this up

    if ( PATH_IsPathOpen(dc->dclevel) )
        return PATH_RoundRect ( dc, Left, Top, Right, Bottom,
                                xCurveDiameter, yCurveDiameter );

    if ((Left == Right) || (Top == Bottom)) return TRUE;

    xCurveDiameter = max(abs( xCurveDiameter ), 1);
    yCurveDiameter = max(abs( yCurveDiameter ), 1);

    if (Right < Left)
    {
       INT tmp = Right; Right = Left; Left = tmp;
    }
    if (Bottom < Top)
    {
       INT tmp = Bottom; Bottom = Top; Top = tmp;
    }

    pdcattr = dc->pdcattr;

    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
        DC_vUpdateFillBrush(dc);

    if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
        DC_vUpdateLineBrush(dc);

    pbrLine = PEN_ShareLockPen(pdcattr->hpen);
    if (!pbrLine)
    {
        /* Nothing to do, as we don't have a bitmap */
        EngSetLastError(ERROR_INTERNAL_ERROR);
        return FALSE;
    }

    PenOrigWidth = PenWidth = pbrLine->ptPenWidth.x;
    if (pbrLine->ulPenStyle == PS_NULL) PenWidth = 0;

    if (pbrLine->ulPenStyle == PS_INSIDEFRAME)
    {
       if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
       if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
       Left   += PenWidth / 2;
       Right  -= (PenWidth - 1) / 2;
       Top    += PenWidth / 2;
       Bottom -= (PenWidth - 1) / 2;
    }

    if (!PenWidth) PenWidth = 1;
    pbrLine->ptPenWidth.x = PenWidth;

    RectBounds.left = Left;
    RectBounds.top = Top;
    RectBounds.right = Right;
    RectBounds.bottom = Bottom;

    IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);

    RectBounds.left   += dc->ptlDCOrig.x;
    RectBounds.top    += dc->ptlDCOrig.y;
    RectBounds.right  += dc->ptlDCOrig.x;
    RectBounds.bottom += dc->ptlDCOrig.y;

    pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
    if (!pbrFill)
    {
        DPRINT1("FillRound Fail\n");
        EngSetLastError(ERROR_INTERNAL_ERROR);
        ret = FALSE;
    }
    else
    {

        DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);

        RtlCopyMemory(&brushTemp, pbrFill, sizeof(brushTemp));
        brushTemp.ptOrigin.x += RectBounds.left - Left;
        brushTemp.ptOrigin.y += RectBounds.top - Top;
        ret = IntFillRoundRect( dc,
                                RectBounds.left,
                                RectBounds.top,
                                RectBounds.right,
                                RectBounds.bottom,
                                xCurveDiameter,
                                yCurveDiameter,
                                &brushTemp);
        BRUSH_ShareUnlockBrush(pbrFill);

        if (ret)
        {
           ret = IntDrawRoundRect( dc,
                      RectBounds.left,
                       RectBounds.top,
                     RectBounds.right,
                    RectBounds.bottom,
                       xCurveDiameter,
                       yCurveDiameter,
                       pbrLine);
        }

        DC_vFinishBlit(dc, NULL);
    }


    pbrLine->ptPenWidth.x = PenOrigWidth;
    PEN_ShareUnlockPen(pbrLine);
    return ret;
}
Пример #26
0
/*
 * @implemented
 */
DWORD_PTR
APIENTRY
NtUserCallOneParam(
   DWORD_PTR Param,
   DWORD Routine)
{
   DECLARE_RETURN(DWORD_PTR);

   TRACE("Enter NtUserCallOneParam\n");

   UserEnterExclusive();

   switch(Routine)
   {
      case ONEPARAM_ROUTINE_POSTQUITMESSAGE:
          {
                PTHREADINFO pti;
                pti = PsGetCurrentThreadWin32Thread();
                MsqPostQuitMessage(pti->MessageQueue, Param);
                RETURN(TRUE);
          }

      case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS:
         {
             PSMWP psmwp;
             HDWP hDwp = NULL;
             INT count = (INT)Param;

             if (count < 0)
             {
                EngSetLastError(ERROR_INVALID_PARAMETER);
                RETURN(0);
             }
             /* Windows allows zero count, in which case it allocates context for 8 moves */
             if (count == 0) count = 8;

             psmwp = (PSMWP) UserCreateObject( gHandleTable,
                                               NULL,
                                              (PHANDLE)&hDwp,
                                               otSMWP,
                                               sizeof(SMWP));
             if (!psmwp) RETURN(0);
             psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP);
             if (!psmwp->acvr)
             {
                UserDeleteObject(hDwp, otSMWP);
                RETURN(0);
             }
             RtlZeroMemory(psmwp->acvr, count * sizeof(CVR));
             psmwp->bHandle = TRUE;
             psmwp->ccvr = 0;          // actualCount
             psmwp->ccvrAlloc = count; // suggestedCount             
             RETURN((DWORD_PTR)hDwp);
         }

      case ONEPARAM_ROUTINE_SHOWCURSOR:
         RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );

      case ONEPARAM_ROUTINE_GETDESKTOPMAPPING:
         {
             PTHREADINFO ti;
             ti = GetW32ThreadInfo();
             if (ti != NULL)
             {
                /* Try convert the pointer to a user mode pointer if the desktop is
                   mapped into the process */
                RETURN((DWORD_PTR)DesktopHeapAddressToUser((PVOID)Param));
             }
             else
             {
                RETURN(0);
             }
         }

      case ONEPARAM_ROUTINE_WINDOWFROMDC:
         RETURN( (DWORD_PTR)IntWindowFromDC((HDC)Param));

      case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
         {
            DWORD_PTR Result;

            Result = gspv.bMouseBtnSwap;
            gspv.bMouseBtnSwap = Param ? TRUE : FALSE;
            gpsi->aiSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap;
            RETURN(Result);
         }

      case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
         RETURN( (DWORD_PTR)IntSwitchCaretShowing((PVOID)Param));

      case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
         RETURN( (DWORD_PTR)IntSetCaretBlinkTime((UINT)Param));

      case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
         RETURN( (DWORD_PTR)MsqSetMessageExtraInfo((LPARAM)Param));

      case ONEPARAM_ROUTINE_CREATEEMPTYCUROBJECT:
         {
            PCURICON_OBJECT CurIcon;
			DWORD_PTR Result ;

            if (!(CurIcon = IntCreateCurIconHandle()))
            {
               EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
               RETURN(0);
            }

            Result = (DWORD_PTR)CurIcon->Self;
			UserDereferenceObject(CurIcon);
			RETURN(Result);
         }

      case ONEPARAM_ROUTINE_GETCURSORPOSITION:
         {
             BOOL ret = TRUE;

            _SEH2_TRY
            {
               ProbeForWrite((POINT*)Param,sizeof(POINT),1);
               RtlCopyMemory((POINT*)Param,&gpsi->ptCursor,sizeof(POINT));
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                SetLastNtError(_SEH2_GetExceptionCode());
                ret = FALSE;
            }
            _SEH2_END;

            RETURN (ret);
         }

      case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
         {
            BOOL Enable;
            PPROCESSINFO Process = PsGetCurrentProcessWin32Process();

            if(Process != NULL)
            {
               Enable = (BOOL)(Param != 0);

               if(Enable)
               {
                  Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING;
               }
               else
               {
                  Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING;
               }

               RETURN( TRUE);
            }

            RETURN( FALSE);
         }

      case ONEPARAM_ROUTINE_GETINPUTEVENT:
         RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
         RETURN( UserGetKeyboardType(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
         RETURN( (DWORD_PTR)UserGetKeyboardLayout(Param));

      case ONEPARAM_ROUTINE_RELEASEDC:
         RETURN (UserReleaseDC(NULL, (HDC) Param, FALSE));

      case ONEPARAM_ROUTINE_REALIZEPALETTE:
         RETURN (UserRealizePalette((HDC) Param));

      case ONEPARAM_ROUTINE_GETQUEUESTATUS:
      {
         RETURN (IntGetQueueStatus((DWORD)Param));
      }
      case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
         /* FIXME: Should use UserEnterShared */
         RETURN(IntEnumClipboardFormats(Param));

      case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
          IntUserManualGuiCheck(Param);
          RETURN(TRUE);

      case ONEPARAM_ROUTINE_GETCURSORPOS:
      {
          BOOL Ret = TRUE;
          PPOINTL pptl;
          PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
          if (pti->hdesk != InputDesktopHandle) RETURN(FALSE);
          _SEH2_TRY
          {
             pptl = (PPOINTL)Param;
             *pptl = gpsi->ptCursor;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_SETPROCDEFLAYOUT:
      {
          PPROCESSINFO ppi;
          if (Param & LAYOUT_ORIENTATIONMASK)
          {
             ppi = PsGetCurrentProcessWin32Process();
             ppi->dwLayout = Param;
             RETURN(TRUE);
          }
          EngSetLastError(ERROR_INVALID_PARAMETER);
          RETURN(FALSE);
      }
      case ONEPARAM_ROUTINE_GETPROCDEFLAYOUT:
      {
          BOOL Ret = TRUE;
          PPROCESSINFO ppi;
          PDWORD pdwLayout;
          if ( PsGetCurrentProcess() == CsrProcess)
          {
             EngSetLastError(ERROR_INVALID_ACCESS);
             RETURN(FALSE);
          }
          ppi = PsGetCurrentProcessWin32Process();
          _SEH2_TRY
          {
             pdwLayout = (PDWORD)Param;
             *pdwLayout = ppi->dwLayout;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             SetLastNtError(_SEH2_GetExceptionCode());
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_REPLYMESSAGE:
          RETURN (co_MsqReplyMessage((LRESULT) Param));
      case ONEPARAM_ROUTINE_MESSAGEBEEP:
          RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) );
		  /* TODO: Implement sound sentry */
   }
   ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
           Routine, Param);
   EngSetLastError(ERROR_INVALID_PARAMETER);
   RETURN( 0);

CLEANUP:
   TRACE("Leave NtUserCallOneParam, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Пример #27
0
BOOL
APIENTRY
NtGdiGradientFill(
    HDC hdc,
    PTRIVERTEX pVertex,
    ULONG nVertex,
    PVOID pMesh,
    ULONG nMesh,
    ULONG ulMode)
{
    BOOL bRet;
    PTRIVERTEX SafeVertex;
    PVOID SafeMesh;
    ULONG cbVertex, cbMesh;

    /* Validate parameters */
    if (!pVertex || !nVertex || !pMesh || !nMesh)
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    switch (ulMode)
    {
        case GRADIENT_FILL_RECT_H:
        case GRADIENT_FILL_RECT_V:
            cbMesh = nMesh * sizeof(GRADIENT_RECT);
            break;
        case GRADIENT_FILL_TRIANGLE:
            cbMesh = nMesh * sizeof(GRADIENT_TRIANGLE);
            break;
        default:
            EngSetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
    }

    cbVertex = nVertex * sizeof(TRIVERTEX) ;
    if(cbVertex + cbMesh <= cbVertex)
    {
        /* Overflow */
        return FALSE ;
    }

    /* Allocate a kernel mode buffer */
    SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE);
    if(!SafeVertex)
    {
        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    SafeMesh = (PVOID)((ULONG_PTR)SafeVertex + cbVertex);

    /* Copy the parameters to kernel mode */
    _SEH2_TRY
    {
        ProbeForRead(pVertex, cbVertex, 1);
        ProbeForRead(pMesh, cbMesh, 1);
        RtlCopyMemory(SafeVertex, pVertex, cbVertex);
        RtlCopyMemory(SafeMesh, pMesh, cbMesh);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
        SetLastNtError(_SEH2_GetExceptionCode());
        _SEH2_YIELD(return FALSE;)
    }
    _SEH2_END;

    /* Call the internal function */
    bRet = GreGradientFill(hdc, SafeVertex, nVertex, SafeMesh, nMesh, ulMode);

    /* Cleanup and return result */
    ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
    return bRet;
}
Пример #28
0
/*
 * @implemented
 */
DWORD_PTR
APIENTRY
NtUserCallTwoParam(
   DWORD_PTR Param1,
   DWORD_PTR Param2,
   DWORD Routine)
{
   PWND Window;
   DECLARE_RETURN(DWORD_PTR);

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

   switch(Routine)
   {
      case TWOPARAM_ROUTINE_SETMENUBARHEIGHT:
         {
            DWORD_PTR Ret;
            PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
            if(!MenuObject)
               RETURN( 0);

            if(Param2 > 0)
            {
               Ret = (MenuObject->MenuInfo.Height == (int)Param2);
               MenuObject->MenuInfo.Height = (int)Param2;
            }
            else
               Ret = (DWORD_PTR)MenuObject->MenuInfo.Height;
            IntReleaseMenuObject(MenuObject);
            RETURN( Ret);
         }

      case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
         {
            PUSER_MESSAGE_QUEUE MsgQueue = ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->MessageQueue;

            ASSERT(MsgQueue);
            RETURN( (DWORD_PTR)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2));
         }

      case TWOPARAM_ROUTINE_ENABLEWINDOW:
         RETURN( IntEnableWindow((HWND)Param1, (BOOL)Param2));

      case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
      {
         Window = UserGetWindowObject((HWND)Param1);
         if (!Window) RETURN(0);

         RETURN( (DWORD_PTR)IntShowOwnedPopups(Window, (BOOL) Param2));
      }

      case TWOPARAM_ROUTINE_ROS_UPDATEUISTATE:
      {
          WPARAM wParam;
          Window = UserGetWindowObject((HWND)Param1);
          if (!Window) RETURN(0);

          /* Unpack wParam */
          wParam = MAKEWPARAM((Param2 >> 3) & 0x3,
                              Param2 & (UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE));

          RETURN( UserUpdateUiState(Window, wParam) );
      }

      case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
         STUB
         RETURN( 0);


      case TWOPARAM_ROUTINE_SETCARETPOS:
         RETURN( (DWORD_PTR)co_IntSetCaretPos((int)Param1, (int)Param2));

      case TWOPARAM_ROUTINE_REGISTERLOGONPROCESS:
         RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));

      case TWOPARAM_ROUTINE_SETCURSORPOS:
         RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, 0, 0, FALSE));

      case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK:
         RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2));
   }
   ERR("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
           Routine, Param1, Param2);
   EngSetLastError(ERROR_INVALID_PARAMETER);
   RETURN( 0);

CLEANUP:
   TRACE("Leave NtUserCallTwoParam, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Пример #29
0
DWORD
APIENTRY
NtUserGetGuiResources(
   HANDLE hProcess,
   DWORD uiFlags)
{
   PEPROCESS Process;
   PPROCESSINFO W32Process;
   NTSTATUS Status;
   DWORD Ret = 0;
   DECLARE_RETURN(DWORD);

   TRACE("Enter NtUserGetGuiResources\n");
   UserEnterShared();

   Status = ObReferenceObjectByHandle(hProcess,
                                      PROCESS_QUERY_INFORMATION,
                                      *PsProcessType,
                                      ExGetPreviousMode(),
                                      (PVOID*)&Process,
                                      NULL);

   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( 0);
   }

   W32Process = (PPROCESSINFO)Process->Win32Process;
   if(!W32Process)
   {
      ObDereferenceObject(Process);
      EngSetLastError(ERROR_INVALID_PARAMETER);
      RETURN( 0);
   }

   switch(uiFlags)
   {
      case GR_GDIOBJECTS:
         {
            Ret = (DWORD)W32Process->GDIHandleCount;
            break;
         }
      case GR_USEROBJECTS:
         {
            Ret = (DWORD)W32Process->UserHandleCount;
            break;
         }
      default:
         {
            EngSetLastError(ERROR_INVALID_PARAMETER);
            break;
         }
   }

   ObDereferenceObject(Process);

   RETURN( Ret);

CLEANUP:
   TRACE("Leave NtUserGetGuiResources, ret=%lu\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Пример #30
0
/*
 * @implemented
 */
BOOL
APIENTRY
EngAlphaBlend(IN SURFOBJ *psoDest,
              IN SURFOBJ *psoSource,
              IN CLIPOBJ *ClipRegion,
              IN XLATEOBJ *ColorTranslation,
              IN PRECTL DestRect,
              IN PRECTL SourceRect,
              IN BLENDOBJ *BlendObj)
{
    RECTL              InputRect;
    RECTL              OutputRect;
    RECTL              ClipRect;
    RECTL              CombinedRect;
    RECTL              Rect;
    POINTL             Translate;
    INTENG_ENTER_LEAVE EnterLeaveSource;
    INTENG_ENTER_LEAVE EnterLeaveDest;
    SURFOBJ*           InputObj;
    SURFOBJ*           OutputObj;
    LONG               ClippingType;
    RECT_ENUM          RectEnum;
    BOOL               EnumMore;
    INT                i;
    BOOLEAN            Ret;

    DPRINT("EngAlphaBlend(psoDest:0x%p, psoSource:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", psoDest, psoSource, ClipRegion, ColorTranslation);
    DPRINT("              DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n",
           DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
           SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
    DPRINT("              BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj->BlendFunction.BlendOp,
           BlendObj->BlendFunction.BlendFlags, BlendObj->BlendFunction.SourceConstantAlpha,
           BlendObj->BlendFunction.AlphaFormat);

    /* Validate output */
    OutputRect = *DestRect;
    if (OutputRect.right < OutputRect.left)
    {
        OutputRect.left = DestRect->right;
        OutputRect.right = DestRect->left;
    }
    if (OutputRect.bottom < OutputRect.top)
    {
        OutputRect.left = DestRect->right;
        OutputRect.right = DestRect->left;
    }

    /* Validate input */
    InputRect = *SourceRect;
    if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
         (InputRect.left < 0) || (InputRect.right < 0) ||
         InputRect.right > psoSource->sizlBitmap.cx ||
         InputRect.bottom > psoSource->sizlBitmap.cy )
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (psoDest == psoSource &&
            !(OutputRect.left >= SourceRect->right || InputRect.left >= OutputRect.right ||
              OutputRect.top >= SourceRect->bottom || InputRect.top >= OutputRect.bottom))
    {
        DPRINT1("Source and destination rectangles overlap!\n");
        return FALSE;
    }

    if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
    {
        DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj->BlendFunction.BlendOp);
        return FALSE;
    }
    if (BlendObj->BlendFunction.BlendFlags != 0)
    {
        DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj->BlendFunction.BlendFlags);
        return FALSE;
    }
    if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
    {
        DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj->BlendFunction.AlphaFormat);
        return FALSE;
    }

    /* Check if there is anything to draw */
    if (ClipRegion != NULL &&
            (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
             ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
    {
        /* Nothing to do */
        return TRUE;
    }

    /* Now call the DIB function */
    if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
    {
        return FALSE;
    }
    InputRect.left +=  Translate.x;
    InputRect.right +=  Translate.x;
    InputRect.top +=  Translate.y;
    InputRect.bottom +=  Translate.y;

    if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj))
    {
        return FALSE;
    }
    OutputRect.left += Translate.x;
    OutputRect.right += Translate.x;
    OutputRect.top += Translate.y;
    OutputRect.bottom += Translate.y;

    Ret = FALSE;
    ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
    switch (ClippingType)
    {
        case DC_TRIVIAL:
            Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                      OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion, ColorTranslation, BlendObj);
            break;

        case DC_RECT:
            ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
            ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
            ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
            ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
            if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
            {
                Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
                Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
                Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
                Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
                Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                          OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj);
            }
            break;

        case DC_COMPLEX:
            Ret = TRUE;
            CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
            do
            {
                EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
                                         (PVOID) &RectEnum);

                for (i = 0; i < RectEnum.c; i++)
                {
                    ClipRect.left = RectEnum.arcl[i].left + Translate.x;
                    ClipRect.right = RectEnum.arcl[i].right + Translate.x;
                    ClipRect.top = RectEnum.arcl[i].top + Translate.y;
                    ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
                    if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
                    {
                        Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
                        Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
                        Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
                        Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
                        Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
                                  OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj) && Ret;
                    }
                }
            }
            while (EnumMore);
            break;

        default:
            UNIMPLEMENTED;
            ASSERT(FALSE);
            break;
    }

    IntEngLeave(&EnterLeaveDest);
    IntEngLeave(&EnterLeaveSource);

    return Ret;
}