3 * reactos/subsys/csrss/win32csr/desktopbg.c
5 * Desktop background window functions
7 * ReactOS Operating System
15 #define DESKTOP_WINDOW_ATOM 32769
17 #define PM_SHOW_DESKTOP 1
18 #define PM_HIDE_DESKTOP 2
20 typedef struct tagDTBG_THREAD_DATA
25 } DTBG_THREAD_DATA
, *PDTBG_THREAD_DATA
;
27 typedef struct tagPRIVATE_NOTIFY_DESKTOP
30 struct /* PM_SHOW_DESKTOP */
35 } PRIVATE_NOTIFY_DESKTOP
, *PPRIVATE_NOTIFY_DESKTOP
;
37 static BOOL BgInitialized
= FALSE
;
38 static HWND VisibleDesktopWindow
= NULL
;
43 DtbgWindowProc(HWND Wnd
,
53 PaintDesktop((HDC
)wParam
);
57 if (BeginPaint(Wnd
, &PS
))
62 return (LRESULT
)SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_ARROW
));
73 PPRIVATE_NOTIFY_DESKTOP nmh
= (PPRIVATE_NOTIFY_DESKTOP
)lParam
;
75 /* Use WM_NOTIFY for private messages since
76 * it can't be sent between processes!
78 switch (nmh
->hdr
.code
)
84 Result
= !SetWindowPos(Wnd
, NULL
, 0, 0,
85 nmh
->ShowDesktop
.Width
,
86 nmh
->ShowDesktop
.Height
,
87 SWP_NOACTIVATE
| SWP_NOZORDER
|
91 VisibleDesktopWindow
= Wnd
;
99 Result
= !SetWindowPos(Wnd
, NULL
, 0, 0, 0, 0,
100 SWP_NOACTIVATE
| SWP_NOZORDER
|
101 SWP_NOMOVE
| SWP_NOSIZE
| SWP_HIDEWINDOW
);
104 VisibleDesktopWindow
= NULL
;
109 DPRINT("Unknown notification code 0x%x sent to the desktop window!\n",
116 return DefWindowProcW(Wnd
, Msg
, wParam
, lParam
);
131 * Create the desktop window class
133 Class
.cbSize
= sizeof(WNDCLASSEXW
);
134 Class
.style
= CS_GLOBALCLASS
;
135 Class
.lpfnWndProc
= DtbgWindowProc
;
136 Class
.cbClsExtra
= 0;
137 Class
.cbWndExtra
= 0;
138 Class
.hInstance
= (HINSTANCE
)GetModuleHandleW(NULL
);
140 Class
.hCursor
= NULL
;
141 Class
.hbrBackground
= GetSysColorBrush(COLOR_BACKGROUND
);
142 Class
.lpszMenuName
= NULL
;
143 Class
.lpszClassName
= (LPCWSTR
)DESKTOP_WINDOW_ATOM
;
144 ClassAtom
= RegisterClassExW(&Class
);
146 if (ClassAtom
== INVALID_ATOM
)
148 DPRINT1("Unable to register desktop background class (error %d)\n",
154 VisibleDesktopWindow
= NULL
;
162 DtbgDesktopThread(PVOID Data
)
166 PDTBG_THREAD_DATA ThreadData
= (PDTBG_THREAD_DATA
)Data
;
168 if (!SetThreadDesktop(ThreadData
->Desktop
))
170 DPRINT1("Failed to set thread desktop\n");
171 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
172 SetEvent(ThreadData
->Event
);
176 BackgroundWnd
= CreateWindowW((LPCWSTR
)DESKTOP_WINDOW_ATOM
,
178 WS_POPUP
| WS_CLIPCHILDREN
,
181 (HINSTANCE
)GetModuleHandleW(NULL
),
184 if (NULL
== BackgroundWnd
)
186 DPRINT1("Failed to create desktop background window\n");
187 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
188 SetEvent(ThreadData
->Event
);
192 ThreadData
->Status
= STATUS_SUCCESS
;
193 SetEvent(ThreadData
->Event
);
195 while (GetMessageW(&msg
, NULL
, 0, 0))
197 TranslateMessage(&msg
);
198 DispatchMessageW(&msg
);
204 CSR_API(CsrCreateDesktop
)
206 DTBG_THREAD_DATA ThreadData
;
209 DPRINT("CsrCreateDesktop\n");
211 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
212 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
216 BgInitialized
= TRUE
;
219 return STATUS_UNSUCCESSFUL
;
223 * The desktop handle we got from win32k is in
224 * the scope of CSRSS so we can just use it.
226 ThreadData
.Desktop
= Request
->Data
.CreateDesktopRequest
.DesktopHandle
;
228 ThreadData
.Event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
230 if (NULL
== ThreadData
.Event
)
232 DPRINT1("Failed to create event (error %d)\n", GetLastError());
233 return STATUS_UNSUCCESSFUL
;
236 ThreadHandle
= CreateThread(NULL
,
243 if (NULL
== ThreadHandle
)
245 CloseHandle(ThreadData
.Event
);
246 DPRINT1("Failed to create desktop window thread.\n");
247 return STATUS_UNSUCCESSFUL
;
250 CloseHandle(ThreadHandle
);
252 WaitForSingleObject(ThreadData
.Event
, INFINITE
);
253 CloseHandle(ThreadData
.Event
);
255 return ThreadData
.Status
;
258 CSR_API(CsrShowDesktop
)
260 PRIVATE_NOTIFY_DESKTOP nmh
;
261 DPRINT("CsrShowDesktop\n");
263 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
264 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
266 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
268 nmh
.hdr
.code
= PM_SHOW_DESKTOP
;
270 nmh
.ShowDesktop
.Width
= (int)Request
->Data
.ShowDesktopRequest
.Width
;
271 nmh
.ShowDesktop
.Height
= (int)Request
->Data
.ShowDesktopRequest
.Height
;
273 if (SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
275 (WPARAM
)nmh
.hdr
.hwndFrom
,
278 return STATUS_UNSUCCESSFUL
;
281 return STATUS_SUCCESS
;
284 CSR_API(CsrHideDesktop
)
286 PRIVATE_NOTIFY_DESKTOP nmh
;
287 DPRINT("CsrHideDesktop\n");
289 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
290 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
292 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
294 nmh
.hdr
.code
= PM_HIDE_DESKTOP
;
296 if (SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
298 (WPARAM
)nmh
.hdr
.hwndFrom
,
301 return STATUS_UNSUCCESSFUL
;
304 return STATUS_SUCCESS
;
309 DtbgIsDesktopVisible(VOID
)
311 if (VisibleDesktopWindow
!= NULL
&&
312 !IsWindowVisible(VisibleDesktopWindow
))
314 VisibleDesktopWindow
= NULL
;
317 return VisibleDesktopWindow
!= NULL
;