ReactOS  0.4.13-dev-235-g7373cb3
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>
10 DBG_DEFAULT_CHANNEL(UserMisc);
11 
12 
13 typedef 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,
49  DWORD dwFlags)
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;
105  RECT Window, Client;
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  {
153  HDC hdc, hdcBuffer;
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  */
239 BOOL
240 APIENTRY
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 
274  _SEH2_TRY
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 
301 Exit:
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,
314  DWORD dwFlags)
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);
330 Exit:
331  TRACE("Leave NtUserSetLayeredWindowAttributes, ret=%i\n", Ret);
332  UserLeave();
333  return Ret;
334 }
335 
336 /*
337  * @implemented
338  */
339 BOOL
340 APIENTRY
342  HWND hwnd,
343  HDC hdcDst,
344  POINT *pptDst,
345  SIZE *psize,
346  HDC hdcSrc,
347  POINT *pptSrc,
348  COLORREF crKey,
349  BLENDFUNCTION *pblend,
350  DWORD dwFlags,
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 
369  _SEH2_TRY
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 );
421 Exit:
422  TRACE("Leave NtUserUpdateLayeredWindow, ret=%i\n", Ret);
423  UserLeave();
424  return Ret;
425 }
426 
427 /* EOF */
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
DWORD ExStyle
Definition: ntuser.h:668
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1153
#define TRUE
Definition: types.h:120
Definition: client.c:29
_Must_inspect_result_ _Out_ LPSIZE psize
Definition: ntgdi.h:1569
__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:924
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL)
Definition: dclife.c:892
#define ERROR_INCORRECT_SIZE
Definition: winerror.h:943
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1720
static HDC
Definition: imagelist.c:92
#define CLR_INVALID
Definition: wingdi.h:882
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
DWORD Flags
Definition: layered.c:19
#define DCX_USESTYLE
Definition: GetDCEx.c:10
#define USERTAG_REDIRECT
Definition: tags.h:194
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
#define WS_CHILD
Definition: pedump.c:617
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:716
RECT rcClient
Definition: ntuser.h:681
#define RDW_FRAME
Definition: winuser.h:1198
#define SWP_NOZORDER
Definition: winuser.h:1232
static HDC hdcSrc
Definition: xlate.c:32
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
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:56
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
BYTE BlendOp
Definition: wingdi.h:2737
BOOL APIENTRY NtUserSetLayeredWindowAttributes(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
Definition: layered.c:311
_SEH2_TRY
Definition: create.c:4250
struct _test_info info[]
Definition: SetCursorPos.c:19
#define ULW_EX_NORESIZE
Definition: winuser.h:2741
Definition: window.c:29
BOOL FASTCALL IntSetLayeredWindowAttributes(PWND pWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
Definition: layered.c:46
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
BYTE NoUsed[2]
Definition: layered.c:18
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define ULW_OPAQUE
Definition: winuser.h:2740
#define TRACE(s)
Definition: solgame.cpp:4
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define SWP_NOACTIVATE
Definition: winuser.h:1227
DWORD COLORREF
Definition: windef.h:285
static void Exit(void)
Definition: sock.c:1331
#define RDW_ERASE
Definition: winuser.h:1197
BYTE SourceConstantAlpha
Definition: wingdi.h:2739
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46
static UINT set(struct ID3DXConstantTableImpl *table, IDirect3DDevice9 *device, struct ctab_constant *constant, const void **indata, D3DXPARAMETER_TYPE intype, UINT *size, UINT incol, D3DXPARAMETER_CLASS inclass, UINT index, BOOL is_pointer)
Definition: shader.c:1095
#define WS_EX_LAYERED
Definition: winuser.h:389
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
unsigned long DWORD
Definition: ntddk_ex.h:95
int Window
Definition: x11stubs.h:26
GLbitfield flags
Definition: glext.h:7161
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
int ret
HDC hdcBuffer
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
HDC hdc
Definition: main.c:9
__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)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define AC_SRC_OVER
Definition: wingdi.h:1351
unsigned char BYTE
Definition: mem.h:68
RECT rcWindow
Definition: ntuser.h:680
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define ULW_ALPHA
Definition: winuser.h:2739
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
#define Dst
Definition: mesh.h:153
BOOL FASTCALL IntUpdateLayeredWindowI(PWND pWnd, UPDATELAYEREDWINDOWINFO *info)
Definition: layered.c:101
#define SWP_NOSIZE
Definition: winuser.h:1230
#define ERR(fmt,...)
Definition: debug.h:109
Definition: ntuser.h:657
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
static HDC hdcDst
Definition: xlate.c:32
#define BLACKNESS
Definition: wingdi.h:322
struct _LRD_PROP LRD_PROP
BOOL FASTCALL co_UserRedrawWindow(PWND Window, const RECTL *UpdateRect, PREGION UpdateRgn, ULONG Flags)
Definition: painting.c:876
BYTE is_Layered
Definition: layered.c:17
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:917
#define SWP_NOREDRAW
Definition: winuser.h:1231
BYTE Alpha
Definition: layered.c:16
__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)
BOOL FASTCALL GetLayeredStatus(PWND pWnd)
Definition: layered.c:23
ATOM AtomLayer
Definition: ntuser.c:21
struct _WND * spwndParent
Definition: ntuser.h:677
DBG_DEFAULT_CHANNEL(UserMisc)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOL FASTCALL SetLayeredStatus(PWND pWnd, BYTE set)
Definition: layered.c:34
#define SWP_NOMOVE
Definition: winuser.h:1229
static HBITMAP
Definition: button.c:44
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
struct _LRD_PROP * PLRD_PROP
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
BYTE AlphaFormat
Definition: wingdi.h:2740
Definition: _set.h:46
#define SRCCOPY
Definition: wingdi.h:332
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
INT NTAPI GreGetObject(IN HGDIOBJ hobj, IN INT cbCount, OUT PVOID pvBuffer)
Definition: gdiobj.c:1259
#define APIENTRY
Definition: api.h:79
struct Rect Rect
#define RDW_INVALIDATE
Definition: winuser.h:1200
#define ULW_COLORKEY
Definition: winuser.h:2738
COLORREF Key
Definition: layered.c:15
BOOL APIENTRY NtUserGetLayeredWindowAttributes(HWND hwnd, COLORREF *pcrKey, BYTE *pbAlpha, DWORD *pdwFlags)
Definition: layered.c:241
DWORD style
Definition: ntuser.h:670