3 * reactos/subsys/csrss/win32csr/desktopbg.c
5 * Desktop background window functions
7 * ReactOS Operating System
15 #define DESKTOP_WINDOW_ATOM 32880
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
32 struct /* PM_SHOW_DESKTOP */
38 } PRIVATE_NOTIFY_DESKTOP
, *PPRIVATE_NOTIFY_DESKTOP
;
40 static BOOL BgInitialized
= FALSE
;
41 static HWND VisibleDesktopWindow
= NULL
;
43 static LRESULT CALLBACK
44 DtbgWindowProc(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
57 if(GetUpdateRect(Wnd
, &rc
, FALSE
) &&
58 (hDC
= BeginPaint(Wnd
, &PS
)))
67 return (LRESULT
) SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_ARROW
));
70 return (LRESULT
) TRUE
;
77 PPRIVATE_NOTIFY_DESKTOP nmh
= (PPRIVATE_NOTIFY_DESKTOP
)lParam
;
79 /* Use WM_NOTIFY for private messages since it can't be sent between
87 Result
= ! SetWindowPos(Wnd
,
89 nmh
->ShowDesktop
.Width
,
90 nmh
->ShowDesktop
.Height
,
91 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_SHOWWINDOW
);
93 VisibleDesktopWindow
= Wnd
;
101 Result
= ! SetWindowPos(Wnd
,
103 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
|
106 VisibleDesktopWindow
= NULL
;
111 DPRINT("Unknown notification code 0x%x sent to the desktop window!\n", nmh
->hdr
.code
);
127 * Create the desktop window class
129 Class
.cbSize
= sizeof(WNDCLASSEXW
);
131 Class
.lpfnWndProc
= DtbgWindowProc
;
132 Class
.cbClsExtra
= 0;
133 Class
.cbWndExtra
= 0;
134 Class
.hInstance
= (HINSTANCE
) GetModuleHandleW(NULL
);
136 Class
.hCursor
= NULL
;
137 Class
.hbrBackground
= GetSysColorBrush(COLOR_BACKGROUND
);
138 Class
.lpszMenuName
= NULL
;
139 Class
.lpszClassName
= (LPCWSTR
) DESKTOP_WINDOW_ATOM
;
140 ClassAtom
= RegisterClassExW(&Class
);
141 if ((ATOM
) 0 == ClassAtom
)
143 DPRINT1("Unable to register desktop background class (error %d)\n",
147 VisibleDesktopWindow
= NULL
;
153 DtbgDesktopThread(PVOID Data
)
157 PDTBG_THREAD_DATA ThreadData
= (PDTBG_THREAD_DATA
) Data
;
159 if (! SetThreadDesktop(ThreadData
->Desktop
))
161 DPRINT1("Failed to set thread desktop\n");
162 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
163 SetEvent(ThreadData
->Event
);
166 BackgroundWnd
= CreateWindowW((LPCWSTR
) DESKTOP_WINDOW_ATOM
,
168 WS_POPUP
| WS_CLIPCHILDREN
,
175 (HINSTANCE
) GetModuleHandleW(NULL
),
177 if (NULL
== BackgroundWnd
)
179 DPRINT1("Failed to create desktop background window\n");
180 ThreadData
->Status
= STATUS_UNSUCCESSFUL
;
181 SetEvent(ThreadData
->Event
);
185 ThreadData
->Status
= STATUS_SUCCESS
;
186 SetEvent(ThreadData
->Event
);
188 while (GetMessageW(&msg
, NULL
, 0, 0))
190 TranslateMessage(&msg
);
191 DispatchMessageW(&msg
);
197 CSR_API(CsrCreateDesktop
)
199 DTBG_THREAD_DATA ThreadData
;
202 DPRINT("CsrCreateDesktop\n");
204 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
205 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
209 BgInitialized
= TRUE
;
212 return Request
->Status
= STATUS_UNSUCCESSFUL
;
217 * the desktop handle we got from win32k is in the scope of CSRSS so we can just use it
219 ThreadData
.Desktop
= Request
->Data
.CreateDesktopRequest
.DesktopHandle
;
221 ThreadData
.Event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
222 if (NULL
== ThreadData
.Event
)
224 DPRINT1("Failed to create event (error %d)\n", GetLastError());
225 return Request
->Status
= STATUS_UNSUCCESSFUL
;
227 ThreadHandle
= CreateThread(NULL
,
233 if (NULL
== ThreadHandle
)
235 CloseHandle(ThreadData
.Event
);
236 DPRINT1("Failed to create desktop window thread.\n");
237 return Request
->Status
= STATUS_UNSUCCESSFUL
;
239 CloseHandle(ThreadHandle
);
241 WaitForSingleObject(ThreadData
.Event
, INFINITE
);
242 CloseHandle(ThreadData
.Event
);
244 Request
->Status
= ThreadData
.Status
;
246 return Request
->Status
;
249 CSR_API(CsrShowDesktop
)
251 PRIVATE_NOTIFY_DESKTOP nmh
;
252 DPRINT("CsrShowDesktop\n");
254 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
255 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
257 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
259 nmh
.hdr
.code
= PM_SHOW_DESKTOP
;
261 nmh
.ShowDesktop
.Width
= (int)Request
->Data
.ShowDesktopRequest
.Width
;
262 nmh
.ShowDesktop
.Height
= (int)Request
->Data
.ShowDesktopRequest
.Height
;
264 Request
->Status
= SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
266 (WPARAM
)nmh
.hdr
.hwndFrom
,
268 ? STATUS_UNSUCCESSFUL
: STATUS_SUCCESS
;
270 return Request
->Status
;
273 CSR_API(CsrHideDesktop
)
275 PRIVATE_NOTIFY_DESKTOP nmh
;
276 DPRINT("CsrHideDesktop\n");
278 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
279 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
281 nmh
.hdr
.hwndFrom
= Request
->Data
.ShowDesktopRequest
.DesktopWindow
;
283 nmh
.hdr
.code
= PM_HIDE_DESKTOP
;
285 Request
->Status
= SendMessageW(Request
->Data
.ShowDesktopRequest
.DesktopWindow
,
287 (WPARAM
)nmh
.hdr
.hwndFrom
,
289 ? STATUS_UNSUCCESSFUL
: STATUS_SUCCESS
;
291 return Request
->Status
;
295 DtbgIsDesktopVisible(VOID
)
297 if (NULL
!= VisibleDesktopWindow
&& ! IsWindowVisible(VisibleDesktopWindow
))
299 VisibleDesktopWindow
= NULL
;
302 return NULL
!= VisibleDesktopWindow
;