2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Layered window support
5 * FILE: win32ss/user/ntuser/layered.c
10 DBG_DEFAULT_CHANNEL(UserMisc
);
13 typedef struct _LRD_PROP
20 } LRD_PROP
, *PLRD_PROP
;
23 GetLayeredStatus(PWND pWnd
)
25 PLRD_PROP pLrdProp
= UserGetProp(pWnd
, AtomLayer
);
28 return pLrdProp
->is_Layered
;
34 SetLayeredStatus(PWND pWnd
, BYTE set
)
36 PLRD_PROP pLrdProp
= UserGetProp(pWnd
, AtomLayer
);
39 pLrdProp
->is_Layered
= set
;
46 IntSetLayeredWindowAttributes(PWND pWnd
,
54 if (!(pWnd
->ExStyle
& WS_EX_LAYERED
) )
56 ERR("Not a Layered Window!\n");
60 pLrdProp
= UserGetProp(pWnd
, AtomLayer
);
64 pLrdProp
= ExAllocatePoolWithTag(PagedPool
, sizeof(LRD_PROP
), USERTAG_REDIRECT
);
67 ERR("failed to allocate LRD_PROP\n");
70 RtlZeroMemory(pLrdProp
, sizeof(LRD_PROP
));
71 IntSetProp(pWnd
, AtomLayer
, (HANDLE
)pLrdProp
);
76 was_Layered
= pLrdProp
->is_Layered
;
78 pLrdProp
->Key
= crKey
;
80 if (dwFlags
& LWA_ALPHA
)
82 pLrdProp
->Alpha
= bAlpha
;
86 if (!pLrdProp
->is_Layered
) pLrdProp
->Alpha
= 0;
89 pLrdProp
->Flags
= dwFlags
;
91 pLrdProp
->is_Layered
= 1;
94 co_UserRedrawWindow(pWnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
96 // FIXME: Now set some bits to the Window DC!!!!
101 IntUpdateLayeredWindowI( PWND pWnd
,
102 UPDATELAYEREDWINDOWINFO
*info
)
108 DWORD flags
= SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOREDRAW
;
110 Window
= pWnd
->rcWindow
;
111 Client
= pWnd
->rcClient
;
113 Parent
= pWnd
->spwndParent
;
114 if (pWnd
->style
& WS_CHILD
&& Parent
)
116 RECTL_vOffsetRect(&Window
, - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
117 RECTL_vOffsetRect(&Client
, - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
122 Offset
.cx
= info
->pptDst
->x
- Window
.left
;
123 Offset
.cy
= info
->pptDst
->y
- Window
.top
;
124 RECTL_vOffsetRect( &Client
, Offset
.cx
, Offset
.cy
);
125 RECTL_vOffsetRect( &Window
, Offset
.cx
, Offset
.cy
);
126 flags
&= ~SWP_NOMOVE
;
130 Offset
.cx
= info
->psize
->cx
- (Window
.right
- Window
.left
);
131 Offset
.cy
= info
->psize
->cy
- (Window
.bottom
- Window
.top
);
132 if (info
->psize
->cx
<= 0 || info
->psize
->cy
<= 0)
134 ERR("Update Layered Invalid Parameters\n");
135 EngSetLastError( ERROR_INVALID_PARAMETER
);
138 if ((info
->dwFlags
& ULW_EX_NORESIZE
) && (Offset
.cx
|| Offset
.cy
))
141 EngSetLastError( ERROR_INCORRECT_SIZE
);
144 Client
.right
+= Offset
.cx
;
145 Client
.bottom
+= Offset
.cy
;
146 Window
.right
+= Offset
.cx
;
147 Window
.bottom
+= Offset
.cy
;
148 flags
&= ~SWP_NOSIZE
;
156 BLENDFUNCTION blend
= { AC_SRC_OVER
, 0, 255, 0 };
157 COLORREF color_key
= (info
->dwFlags
& ULW_COLORKEY
) ? info
->crKey
: CLR_INVALID
;
161 RECTL_vOffsetRect( &Rect
, -Window
.left
, -Window
.top
);
163 TRACE("H %d W %d\n",Rect
.bottom
- Rect
.top
,Rect
.right
- Rect
.left
);
165 if (!info
->hdcDst
) hdc
= UserGetDCEx(pWnd
, NULL
, DCX_USESTYLE
);
166 else hdc
= info
->hdcDst
;
168 hBr
= NtGdiCreateSolidBrush(color_key
, NULL
);
171 TRACE("Fill Color Key %x\n",color_key
);
172 FillRect(hdc
, &Rect
, hBr
);
178 RECTL_bIntersectRect( &Rect
, &Rect
, info
->prcDirty
);
179 NtGdiPatBlt( hdc
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
, BLACKNESS
);
182 if (info
->dwFlags
& ULW_ALPHA
)
184 blend
= *info
->pblend
;
185 TRACE("ULW_ALPHA bop %d scA %d aF %d\n", blend
.BlendOp
, blend
.SourceConstantAlpha
, blend
.AlphaFormat
);
188 ret
= NtGdiAlphaBlend( hdc
,
191 Rect
.right
- Rect
.left
,
192 Rect
.bottom
- Rect
.top
,
194 Rect
.left
+ (info
->pptSrc
? info
->pptSrc
->x
: 0),
195 Rect
.top
+ (info
->pptSrc
? info
->pptSrc
->y
: 0),
196 Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
,
200 if (hBr
) GreDeleteObject(hBr
);
201 if (!info
->hdcDst
) UserReleaseDC(pWnd
, hdc
, FALSE
);
206 co_WinPosSetWindowPos(pWnd
, 0, Window
.left
, Window
.top
, Window
.right
- Window
.left
, Window
.bottom
- Window
.top
, flags
);
216 NtUserGetLayeredWindowAttributes(
226 TRACE("Enter NtUserGetLayeredWindowAttributes\n");
227 UserEnterExclusive();
229 if (!(pWnd
= UserGetWindowObject(hwnd
)) ||
230 !(pWnd
->ExStyle
& WS_EX_LAYERED
) )
232 ERR("Not a Layered Window!\n");
236 pLrdProp
= UserGetProp(pWnd
, AtomLayer
);
244 if (pLrdProp
->is_Layered
== 0)
253 ProbeForWrite(pcrKey
, sizeof(*pcrKey
), 1);
254 *pcrKey
= pLrdProp
->Key
;
258 ProbeForWrite(pbAlpha
, sizeof(*pbAlpha
), 1);
259 *pbAlpha
= pLrdProp
->Alpha
;
263 ProbeForWrite(pdwFlags
, sizeof(*pdwFlags
), 1);
264 *pdwFlags
= pLrdProp
->Flags
;
267 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
269 SetLastNtError(_SEH2_GetExceptionCode());
270 _SEH2_YIELD(goto Exit
);
277 TRACE("Leave NtUserGetLayeredWindowAttributes, ret=%i\n", Ret
);
286 NtUserSetLayeredWindowAttributes(HWND hwnd
,
294 TRACE("Enter NtUserSetLayeredWindowAttributes\n");
295 UserEnterExclusive();
297 if (!(pWnd
= UserGetWindowObject(hwnd
)) ||
298 !(pWnd
->ExStyle
& WS_EX_LAYERED
) )
300 ERR("Not a Layered Window!\n");
304 Ret
= IntSetLayeredWindowAttributes(pWnd
, crKey
, bAlpha
, dwFlags
);
306 TRACE("Leave NtUserSetLayeredWindowAttributes, ret=%i\n", Ret
);
316 NtUserUpdateLayeredWindow(
324 BLENDFUNCTION
*pblend
,
328 UPDATELAYEREDWINDOWINFO info
;
332 BLENDFUNCTION blend
= { AC_SRC_OVER
, 0, 255, 0 };
336 TRACE("Enter NtUserUpdateLayeredWindow\n");
337 UserEnterExclusive();
339 if (!(pWnd
= UserGetWindowObject(hwnd
)))
348 ProbeForRead(pptDst
, sizeof(POINT
), 1);
353 ProbeForRead(pptSrc
, sizeof(POINT
), 1);
356 ProbeForRead(psize
, sizeof(SIZE
), 1);
360 ProbeForRead(pblend
, sizeof(BLENDFUNCTION
), 1);
365 ProbeForRead(prcDirty
, sizeof(RECT
), 1);
369 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
371 EngSetLastError( ERROR_INVALID_PARAMETER
);
372 _SEH2_YIELD(goto Exit
);
376 if ( GetLayeredStatus(pWnd
) ||
377 dwFlags
& ~(ULW_COLORKEY
| ULW_ALPHA
| ULW_OPAQUE
| ULW_EX_NORESIZE
) ||
378 !(pWnd
->ExStyle
& WS_EX_LAYERED
) )
380 ERR("Layered Window Invalid Parameters\n");
381 EngSetLastError( ERROR_INVALID_PARAMETER
);
385 info
.cbSize
= sizeof(info
);
386 info
.hdcDst
= hdcDst
;
387 info
.pptDst
= pptDst
? &Dst
: NULL
;
389 info
.hdcSrc
= hdcSrc
;
390 info
.pptSrc
= pptSrc
? &Src
: NULL
;
392 info
.pblend
= &blend
;
393 info
.dwFlags
= dwFlags
;
394 info
.prcDirty
= prcDirty
? &Dirty
: NULL
;
395 Ret
= IntUpdateLayeredWindowI( pWnd
, &info
);
397 TRACE("Leave NtUserUpdateLayeredWindow, ret=%i\n", Ret
);