[Win32k]
[reactos.git] / reactos / win32ss / user / ntuser / layered.c
index 558aff1..0956369 100644 (file)
@@ -150,11 +150,11 @@ IntUpdateLayeredWindowI( PWND pWnd,
 
    if (info->hdcSrc)
    {
-      HBRUSH hBr;
-      HDC hdc;
+      HDC hdc, hdcBuffer;
       RECT Rect;
       BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
       COLORREF color_key = (info->dwFlags & ULW_COLORKEY) ? info->crKey : CLR_INVALID;
+      HBITMAP hBitmapBuffer, hOldBitmap;
 
       Rect = Window;
 
@@ -165,13 +165,24 @@ IntUpdateLayeredWindowI( PWND pWnd,
       if (!info->hdcDst) hdc = UserGetDCEx(pWnd, NULL, DCX_USESTYLE);
       else hdc = info->hdcDst;
 
-      hBr = NtGdiCreateSolidBrush(color_key, NULL);
-      if (hBr)
-      {
-         TRACE("Fill Color Key %x\n",color_key);
-         FillRect(hdc, &Rect, hBr);
-      }
-
+      hdcBuffer = NtGdiCreateCompatibleDC(hdc);
+      hBitmapBuffer = NtGdiCreateCompatibleBitmap(hdc, Rect.right - Rect.left, Rect.bottom - Rect.top);
+      hOldBitmap = (HBITMAP)NtGdiSelectBitmap(hdcBuffer, hBitmapBuffer);
+
+      NtGdiStretchBlt( hdcBuffer,
+                       Rect.left,
+                       Rect.top,
+                       Rect.right - Rect.left,
+                       Rect.bottom - Rect.top,
+                       info->hdcSrc,
+                       Rect.left + (info->pptSrc ? info->pptSrc->x : 0),
+                       Rect.top  + (info->pptSrc ? info->pptSrc->y : 0),
+                       Rect.right - Rect.left,
+                       Rect.bottom - Rect.top,
+                       SRCCOPY,
+                       color_key );
+
+      // Need to test this, Dirty before or after StretchBlt?
       if (info->prcDirty)
       {
          ERR("prcDirty\n");
@@ -182,7 +193,7 @@ IntUpdateLayeredWindowI( PWND pWnd,
       if (info->dwFlags & ULW_ALPHA)
       {
          blend = *info->pblend;
-         TRACE("ULW_ALPHA bop %d scA %d aF %d\n", blend.BlendOp, blend.SourceConstantAlpha, blend.AlphaFormat);
+         TRACE("ULW_ALPHA bop %d Alpha %d aF %d\n", blend.BlendOp, blend.SourceConstantAlpha, blend.AlphaFormat);
       }
 
       ret = NtGdiAlphaBlend( hdc,
@@ -190,14 +201,17 @@ IntUpdateLayeredWindowI( PWND pWnd,
                              Rect.top,
                              Rect.right - Rect.left,
                              Rect.bottom - Rect.top,
-                             info->hdcSrc,
+                             hdcBuffer,
                              Rect.left + (info->pptSrc ? info->pptSrc->x : 0),
-                             Rect.top + (info->pptSrc ? info->pptSrc->y : 0),
-                             Rect.right - Rect.left, Rect.bottom - Rect.top,
+                             Rect.top  + (info->pptSrc ? info->pptSrc->y : 0),
+                             Rect.right - Rect.left,
+                             Rect.bottom - Rect.top,
                              blend,
                              0);
 
-      if (hBr) GreDeleteObject(hBr);
+      NtGdiSelectBitmap(hdcBuffer, hOldBitmap);
+      if (hBitmapBuffer) GreDeleteObject(hBitmapBuffer);
+      if (hdcBuffer) IntGdiDeleteDC(hdcBuffer, FALSE);
       if (!info->hdcDst) UserReleaseDC(pWnd, hdc, FALSE);
    }
    else
@@ -224,15 +238,15 @@ NtUserGetLayeredWindowAttributes(
    BOOL Ret = FALSE;
 
    TRACE("Enter NtUserGetLayeredWindowAttributes\n");
+   UserEnterExclusive();
 
    if (!(pWnd = UserGetWindowObject(hwnd)) ||
        !(pWnd->ExStyle & WS_EX_LAYERED) )
    {
-      return FALSE;
+      ERR("Not a Layered Window!\n");
+      goto Exit;
    }
 
-   UserEnterExclusive();
-
    pLrdProp = UserGetProp(pWnd, AtomLayer);
 
    if (!pLrdProp)
@@ -248,9 +262,21 @@ NtUserGetLayeredWindowAttributes(
 
    _SEH2_TRY
    {
-      if (pcrKey)     *pcrKey = pLrdProp->Key;
-      if (pbAlpha)   *pbAlpha = pLrdProp->Alpha;
-      if (pdwFlags) *pdwFlags = pLrdProp->Flags;
+      if (pcrKey)
+      {
+          ProbeForWrite(pcrKey, sizeof(*pcrKey), 1);
+          *pcrKey = pLrdProp->Key;
+      }
+      if (pbAlpha)
+      {
+          ProbeForWrite(pbAlpha, sizeof(*pbAlpha), 1);
+          *pbAlpha = pLrdProp->Alpha;
+      }
+      if (pdwFlags)
+      {
+          ProbeForWrite(pdwFlags, sizeof(*pdwFlags), 1);
+          *pdwFlags = pLrdProp->Flags;
+      }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
@@ -322,10 +348,11 @@ NtUserUpdateLayeredWindow(
    BOOL Ret = FALSE;
 
    TRACE("Enter NtUserUpdateLayeredWindow\n");
+   UserEnterExclusive();
 
    if (!(pWnd = UserGetWindowObject(hwnd)))
    {
-      return FALSE;
+      goto Exit;
    }
 
    _SEH2_TRY
@@ -356,12 +383,10 @@ NtUserUpdateLayeredWindow(
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
       EngSetLastError( ERROR_INVALID_PARAMETER );
-      _SEH2_YIELD(return FALSE);
+      _SEH2_YIELD(goto Exit);
    }
    _SEH2_END;
 
-   UserEnterExclusive();
-
    if ( GetLayeredStatus(pWnd) ||
         dwFlags & ~(ULW_COLORKEY | ULW_ALPHA | ULW_OPAQUE | ULW_EX_NORESIZE) ||
        !(pWnd->ExStyle & WS_EX_LAYERED) )
@@ -373,14 +398,14 @@ NtUserUpdateLayeredWindow(
 
    info.cbSize   = sizeof(info);
    info.hdcDst   = hdcDst;
-   info.pptDst   = pptDst? &Dst : 0;
+   info.pptDst   = pptDst? &Dst : NULL;
    info.psize    = &Size;
    info.hdcSrc   = hdcSrc;
-   info.pptSrc   = pptSrc ? &Src : 0;
+   info.pptSrc   = pptSrc ? &Src : NULL;
    info.crKey    = crKey;
    info.pblend   = &blend;
    info.dwFlags  = dwFlags;
-   info.prcDirty = prcDirty ? &Dirty : 0;
+   info.prcDirty = prcDirty ? &Dirty : NULL;
    Ret = IntUpdateLayeredWindowI( pWnd, &info );
 Exit:
    TRACE("Leave NtUserUpdateLayeredWindow, ret=%i\n", Ret);