ReactOS 0.4.16-dev-109-gf4cb10f
layered.c
Go to the documentation of this file.
1/*
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
6 * PROGRAMER:
7 */
8
9#include <win32k.h>
11
12
13typedef struct _LRD_PROP
14{
21
24{
25 PLRD_PROP pLrdProp = UserGetProp(pWnd, AtomLayer, TRUE);
26 if (pLrdProp)
27 {
28 return pLrdProp->is_Layered;
29 }
30 return FALSE;
31}
32
35{
36 PLRD_PROP pLrdProp = UserGetProp(pWnd, AtomLayer, TRUE);
37 if (pLrdProp)
38 {
39 pLrdProp->is_Layered = set;
40 return TRUE;
41 }
42 return FALSE;
43}
44
47 COLORREF crKey,
48 BYTE bAlpha,
50{
51 PLRD_PROP pLrdProp;
52 INT was_Layered;
53
54 if (!(pWnd->ExStyle & WS_EX_LAYERED) )
55 {
56 ERR("Not a Layered Window!\n");
57 return FALSE;
58 }
59
60 pLrdProp = UserGetProp(pWnd, AtomLayer, TRUE);
61
62 if (!pLrdProp)
63 {
65 if (pLrdProp == NULL)
66 {
67 ERR("failed to allocate LRD_PROP\n");
68 return FALSE;
69 }
70 RtlZeroMemory(pLrdProp, sizeof(LRD_PROP));
71 UserSetProp(pWnd, AtomLayer, (HANDLE)pLrdProp, TRUE);
72 }
73
74 if (pLrdProp)
75 {
76 was_Layered = pLrdProp->is_Layered;
77
78 pLrdProp->Key = crKey;
79
80 if (dwFlags & LWA_ALPHA)
81 {
82 pLrdProp->Alpha = bAlpha;
83 }
84 else
85 {
86 if (!pLrdProp->is_Layered) pLrdProp->Alpha = 0;
87 }
88
89 pLrdProp->Flags = dwFlags;
90
91 pLrdProp->is_Layered = 1;
92
93 if (!was_Layered)
95 }
96 // FIXME: Now set some bits to the Window DC!!!!
97 return TRUE;
98}
99
102 UPDATELAYEREDWINDOWINFO *info )
103{
104 PWND Parent;
106 SIZE Offset;
107 BOOL ret = FALSE;
109
110 Window = pWnd->rcWindow;
111 Client = pWnd->rcClient;
112
113 Parent = pWnd->spwndParent;
114 if (pWnd->style & WS_CHILD && Parent)
115 {
116 RECTL_vOffsetRect(&Window, - Parent->rcClient.left, - Parent->rcClient.top);
117 RECTL_vOffsetRect(&Client, - Parent->rcClient.left, - Parent->rcClient.top);
118 }
119
120 if (info->pptDst)
121 {
122 Offset.cx = info->pptDst->x - Window.left;
123 Offset.cy = info->pptDst->y - Window.top;
126 flags &= ~SWP_NOMOVE;
127 }
128 if (info->psize)
129 {
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)
133 {
134 ERR("Update Layered Invalid Parameters\n");
136 return FALSE;
137 }
138 if ((info->dwFlags & ULW_EX_NORESIZE) && (Offset.cx || Offset.cy))
139 {
140 ERR("Wrong Size\n");
142 return FALSE;
143 }
144 Client.right += Offset.cx;
145 Client.bottom += Offset.cy;
146 Window.right += Offset.cx;
147 Window.bottom += Offset.cy;
148 flags &= ~SWP_NOSIZE;
149 }
150
151 if (info->hdcSrc)
152 {
154 RECT Rect;
155 BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
156 COLORREF color_key = (info->dwFlags & ULW_COLORKEY) ? info->crKey : CLR_INVALID;
157 HBITMAP hOldBitmap, hOldBitmap1, hbmSrc, hbmDst;
158 DIBSECTION dibs;
159
160 Rect = Window;
161
162 RECTL_vOffsetRect( &Rect, -Window.left, -Window.top );
163
164 TRACE("H %d W %d\n",Rect.bottom - Rect.top,Rect.right - Rect.left);
165
166 if (!info->hdcDst) hdc = UserGetDCEx(pWnd, NULL, DCX_USESTYLE);
167 else hdc = info->hdcDst;
168
169 hbmSrc = NtGdiCreateCompatibleBitmap(info->hdcSrc, Rect.right - Rect.left, Rect.bottom - Rect.top);
170 hbmDst = NtGdiCreateCompatibleBitmap(info->hdcSrc, Rect.right - Rect.left, Rect.bottom - Rect.top);
171
172 GreGetObject(hbmSrc, sizeof(DIBSECTION), &dibs);
173
174 TRACE("Source Bitmap bc %d\n",dibs.dsBmih.biBitCount);
175
177
178 hOldBitmap = (HBITMAP)NtGdiSelectBitmap(hdcBuffer, hbmSrc);
179 hOldBitmap1 = (HBITMAP)NtGdiSelectBitmap(hdc, hbmDst);
180
182 Rect.left,
183 Rect.top,
184 Rect.right - Rect.left,
185 Rect.bottom - Rect.top,
186 info->hdcSrc,
187 Rect.left + (info->pptSrc ? info->pptSrc->x : 0),
188 Rect.top + (info->pptSrc ? info->pptSrc->y : 0),
189 Rect.right - Rect.left,
190 Rect.bottom - Rect.top,
191 SRCCOPY,
192 color_key );
193
194 // Need to test this, Dirty before or after StretchBlt?
195 if (info->prcDirty)
196 {
197 ERR("prcDirty\n");
198 RECTL_bIntersectRect( &Rect, &Rect, info->prcDirty );
199 NtGdiPatBlt( hdc, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top, BLACKNESS );
200 }
201
202 if (info->dwFlags & ULW_ALPHA)
203 {
204 blend = *info->pblend;
205 TRACE("ULW_ALPHA bop %d Alpha %d aF %d\n", blend.BlendOp, blend.SourceConstantAlpha, blend.AlphaFormat);
206 }
207
209 Rect.left,
210 Rect.top,
211 Rect.right - Rect.left,
212 Rect.bottom - Rect.top,
213 hdcBuffer,
214 Rect.left + (info->pptSrc ? info->pptSrc->x : 0),
215 Rect.top + (info->pptSrc ? info->pptSrc->y : 0),
216 Rect.right - Rect.left,
217 Rect.bottom - Rect.top,
218 blend,
219 0);
220
221 NtGdiSelectBitmap(hdc, hOldBitmap1);
222 NtGdiSelectBitmap(hdcBuffer, hOldBitmap);
223 if (hbmSrc) GreDeleteObject(hbmSrc);
224 if (hbmDst) GreDeleteObject(hbmDst);
226 if (!info->hdcDst) UserReleaseDC(pWnd, hdc, FALSE);
227 }
228 else
229 ret = TRUE;
230
231 co_WinPosSetWindowPos(pWnd, 0, Window.left, Window.top, Window.right - Window.left, Window.bottom - Window.top, flags);
232 return ret;
233}
234
235
236/*
237 * @implemented
238 */
239BOOL
242 HWND hwnd,
243 COLORREF *pcrKey,
244 BYTE *pbAlpha,
245 DWORD *pdwFlags)
246{
247 PLRD_PROP pLrdProp;
248 PWND pWnd;
249 BOOL Ret = FALSE;
250
251 TRACE("Enter NtUserGetLayeredWindowAttributes\n");
253
254 if (!(pWnd = UserGetWindowObject(hwnd)) ||
255 !(pWnd->ExStyle & WS_EX_LAYERED) )
256 {
257 ERR("Not a Layered Window!\n");
258 goto Exit;
259 }
260
261 pLrdProp = UserGetProp(pWnd, AtomLayer, TRUE);
262
263 if (!pLrdProp)
264 {
265 TRACE("No Prop!\n");
266 goto Exit;
267 }
268
269 if (pLrdProp->is_Layered == 0)
270 {
271 goto Exit;
272 }
273
275 {
276 if (pcrKey)
277 {
278 ProbeForWrite(pcrKey, sizeof(*pcrKey), 1);
279 *pcrKey = pLrdProp->Key;
280 }
281 if (pbAlpha)
282 {
283 ProbeForWrite(pbAlpha, sizeof(*pbAlpha), 1);
284 *pbAlpha = pLrdProp->Alpha;
285 }
286 if (pdwFlags)
287 {
288 ProbeForWrite(pdwFlags, sizeof(*pdwFlags), 1);
289 *pdwFlags = pLrdProp->Flags;
290 }
291 }
293 {
295 _SEH2_YIELD(goto Exit);
296 }
297 _SEH2_END;
298
299 Ret = TRUE;
300
301Exit:
302 TRACE("Leave NtUserGetLayeredWindowAttributes, ret=%i\n", Ret);
303 UserLeave();
304 return Ret;
305}
306
307/*
308 * @implemented
309 */
312 COLORREF crKey,
313 BYTE bAlpha,
315{
316 PWND pWnd;
317 BOOL Ret = FALSE;
318
319 TRACE("Enter NtUserSetLayeredWindowAttributes\n");
321
322 if (!(pWnd = UserGetWindowObject(hwnd)) ||
323 !(pWnd->ExStyle & WS_EX_LAYERED) )
324 {
325 ERR("Not a Layered Window!\n");
326 goto Exit;
327 }
328
329 Ret = IntSetLayeredWindowAttributes(pWnd, crKey, bAlpha, dwFlags);
330Exit:
331 TRACE("Leave NtUserSetLayeredWindowAttributes, ret=%i\n", Ret);
332 UserLeave();
333 return Ret;
334}
335
336/*
337 * @implemented
338 */
339BOOL
342 HWND hwnd,
343 HDC hdcDst,
344 POINT *pptDst,
345 SIZE *psize,
346 HDC hdcSrc,
347 POINT *pptSrc,
348 COLORREF crKey,
349 BLENDFUNCTION *pblend,
351 RECT *prcDirty)
352{
353 UPDATELAYEREDWINDOWINFO info;
354 POINT Dst, Src;
355 SIZE Size;
356 RECT Dirty;
357 BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
358 PWND pWnd;
359 BOOL Ret = FALSE;
360
361 TRACE("Enter NtUserUpdateLayeredWindow\n");
363
364 if (!(pWnd = UserGetWindowObject(hwnd)))
365 {
366 goto Exit;
367 }
368
370 {
371 if (pptDst)
372 {
373 ProbeForRead(pptDst, sizeof(POINT), 1);
374 Dst = *pptDst;
375 }
376 if (pptSrc)
377 {
378 ProbeForRead(pptSrc, sizeof(POINT), 1);
379 Src = *pptSrc;
380 }
381 ProbeForRead(psize, sizeof(SIZE), 1);
382 Size = *psize;
383 if (pblend)
384 {
385 ProbeForRead(pblend, sizeof(BLENDFUNCTION), 1);
386 blend = *pblend;
387 }
388 if (prcDirty)
389 {
390 ProbeForRead(prcDirty, sizeof(RECT), 1);
391 Dirty = *prcDirty;
392 }
393 }
395 {
397 _SEH2_YIELD(goto Exit);
398 }
399 _SEH2_END;
400
401 if ( GetLayeredStatus(pWnd) ||
403 !(pWnd->ExStyle & WS_EX_LAYERED) )
404 {
405 ERR("Layered Window Invalid Parameters\n");
407 goto Exit;
408 }
409
410 info.cbSize = sizeof(info);
411 info.hdcDst = hdcDst;
412 info.pptDst = pptDst? &Dst : NULL;
413 info.psize = &Size;
414 info.hdcSrc = hdcSrc;
415 info.pptSrc = pptSrc ? &Src : NULL;
416 info.crKey = crKey;
417 info.pblend = &blend;
418 info.dwFlags = dwFlags;
419 info.prcDirty = prcDirty ? &Dirty : NULL;
420 Ret = IntUpdateLayeredWindowI( pWnd, &info );
421Exit:
422 TRACE("Leave NtUserUpdateLayeredWindow, ret=%i\n", Ret);
423 UserLeave();
424 return Ret;
425}
426
427/* EOF */
#define DCX_USESTYLE
Definition: GetDCEx.c:10
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
#define ERR(fmt,...)
Definition: precomp.h:57
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
Definition: _set.h:50
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL)
Definition: dclife.c:892
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define APIENTRY
Definition: api.h:79
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL APIENTRY NtUserSetLayeredWindowAttributes(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
Definition: layered.c:311
struct _LRD_PROP * PLRD_PROP
BOOL APIENTRY NtUserGetLayeredWindowAttributes(HWND hwnd, COLORREF *pcrKey, BYTE *pbAlpha, DWORD *pdwFlags)
Definition: layered.c:241
BOOL APIENTRY NtUserUpdateLayeredWindow(HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags, RECT *prcDirty)
Definition: layered.c:341
BOOL FASTCALL IntSetLayeredWindowAttributes(PWND pWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
Definition: layered.c:46
BOOL FASTCALL IntUpdateLayeredWindowI(PWND pWnd, UPDATELAYEREDWINDOWINFO *info)
Definition: layered.c:101
BOOL FASTCALL SetLayeredStatus(PWND pWnd, BYTE set)
Definition: layered.c:34
BOOL FASTCALL GetLayeredStatus(PWND pWnd)
Definition: layered.c:23
struct _LRD_PROP LRD_PROP
#define Dst
Definition: mesh.h:153
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
#define FASTCALL
Definition: nt_native.h:50
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiAlphaBlend(_In_ HDC hdcDst, _In_ LONG DstX, _In_ LONG DstY, _In_ LONG DstCx, _In_ LONG DstCy, _In_ HDC hdcSrc, _In_ LONG SrcX, _In_ LONG SrcY, _In_ LONG SrcCx, _In_ LONG SrcCy, _In_ BLENDFUNCTION BlendFunction, _In_ HANDLE hcmXform)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiStretchBlt(_In_ HDC hdcDst, _In_ INT xDst, _In_ INT yDst, _In_ INT cxDst, _In_ INT cyDst, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ INT cxSrc, _In_ INT cySrc, _In_ DWORD dwRop, _In_ DWORD dwBackColor)
_Must_inspect_result_ _Out_ LPSIZE psize
Definition: ntgdi.h:1569
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiPatBlt(_In_ HDC hdcDest, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_ DWORD dwRop)
Definition: bitblt.c:992
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1792
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
ATOM AtomLayer
Definition: ntuser.c:21
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
#define WS_CHILD
Definition: pedump.c:617
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
HDC hdcBuffer
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
Definition: client.c:28
Definition: window.c:28
BYTE BlendOp
Definition: wingdi.h:2759
BYTE AlphaFormat
Definition: wingdi.h:2762
BYTE SourceConstantAlpha
Definition: wingdi.h:2761
BYTE is_Layered
Definition: layered.c:17
DWORD Flags
Definition: layered.c:19
BYTE Alpha
Definition: layered.c:16
BYTE NoUsed[2]
Definition: layered.c:18
COLORREF Key
Definition: layered.c:15
Definition: ntuser.h:694
DWORD ExStyle
Definition: ntuser.h:704
DWORD style
Definition: ntuser.h:706
RECT rcClient
Definition: ntuser.h:717
RECT rcWindow
Definition: ntuser.h:716
struct _WND * spwndParent
Definition: ntuser.h:713
int32_t INT
Definition: typedefs.h:58
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
BOOL FASTCALL co_UserRedrawWindow(PWND Window, const RECTL *UpdateRect, PREGION UpdateRgn, ULONG Flags)
Definition: painting.c:894
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:124
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:918
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
INT NTAPI GreGetObject(IN HGDIOBJ hobj, IN INT cbCount, OUT PVOID pvBuffer)
Definition: gdiobj.c:1264
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46
#define USERTAG_REDIRECT
Definition: tags.h:195
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
DWORD COLORREF
Definition: windef.h:300
#define ERROR_INCORRECT_SIZE
Definition: winerror.h:943
#define BLACKNESS
Definition: wingdi.h:323
#define AC_SRC_OVER
Definition: wingdi.h:1369
#define CLR_INVALID
Definition: wingdi.h:883
#define SRCCOPY
Definition: wingdi.h:333
#define ULW_ALPHA
Definition: winuser.h:2788
#define SWP_NOACTIVATE
Definition: winuser.h:1245
#define SWP_NOREDRAW
Definition: winuser.h:1249
#define SWP_NOMOVE
Definition: winuser.h:1247
#define SWP_NOSIZE
Definition: winuser.h:1248
#define RDW_ERASE
Definition: winuser.h:1214
#define ULW_OPAQUE
Definition: winuser.h:2789
#define ULW_COLORKEY
Definition: winuser.h:2787
#define ULW_EX_NORESIZE
Definition: winuser.h:2790
#define RDW_FRAME
Definition: winuser.h:1215
#define WS_EX_LAYERED
Definition: winuser.h:389
#define SWP_NOZORDER
Definition: winuser.h:1250
#define RDW_INVALIDATE
Definition: winuser.h:1217
static HDC hdcSrc
Definition: xlate.c:32
static HDC hdcDst
Definition: xlate.c:32
unsigned char BYTE
Definition: xxhash.c:193