2004-01-17 15:18:25 +00:00
|
|
|
/* $Id: desktopbg.c,v 1.6 2004/01/17 15:18:25 navaraf Exp $
|
2003-12-07 23:02:57 +00:00
|
|
|
*
|
|
|
|
* reactos/subsys/csrss/win32csr/desktopbg.c
|
|
|
|
*
|
|
|
|
* Desktop background window functions
|
|
|
|
*
|
|
|
|
* ReactOS Operating System
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
#include <csrss/csrss.h>
|
|
|
|
|
|
|
|
#include "api.h"
|
|
|
|
#include "desktopbg.h"
|
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
#define DESKTOP_WINDOW_ATOM 32880
|
|
|
|
|
|
|
|
#ifndef WM_APP
|
|
|
|
#define WM_APP 0x8000
|
|
|
|
#endif
|
|
|
|
#define PM_SHOW_DESKTOP (WM_APP + 1)
|
|
|
|
#define PM_HIDE_DESKTOP (WM_APP + 2)
|
|
|
|
|
|
|
|
typedef struct tagDTBG_THREAD_DATA
|
|
|
|
{
|
|
|
|
HDESK Desktop;
|
|
|
|
HANDLE Event;
|
|
|
|
NTSTATUS Status;
|
|
|
|
} DTBG_THREAD_DATA, *PDTBG_THREAD_DATA;
|
|
|
|
|
|
|
|
static BOOL Initialized = FALSE;
|
2004-01-11 17:31:16 +00:00
|
|
|
static HWND VisibleDesktopWindow = NULL;
|
2003-12-07 23:02:57 +00:00
|
|
|
|
|
|
|
static LRESULT CALLBACK
|
|
|
|
DtbgWindowProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
LRESULT Result;
|
|
|
|
|
|
|
|
switch(Msg)
|
|
|
|
{
|
|
|
|
case WM_NCCREATE:
|
|
|
|
Result = (LRESULT) TRUE;
|
|
|
|
break;
|
|
|
|
case WM_CREATE:
|
|
|
|
Result = 0;
|
|
|
|
break;
|
|
|
|
case WM_PAINT:
|
2003-12-13 16:04:36 +00:00
|
|
|
{
|
|
|
|
PAINTSTRUCT PS;
|
|
|
|
BeginPaint(Wnd, &PS);
|
2003-12-27 15:09:51 +00:00
|
|
|
/* No need to paint, already done in WM_ERASEBKGND. */
|
2003-12-13 16:04:36 +00:00
|
|
|
EndPaint(Wnd, &PS);
|
|
|
|
Result = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
|
|
{
|
2003-12-22 15:30:21 +00:00
|
|
|
PaintDesktop((HDC)wParam);
|
2003-12-13 16:04:36 +00:00
|
|
|
Result = 1;
|
|
|
|
}
|
2003-12-07 23:02:57 +00:00
|
|
|
break;
|
|
|
|
case PM_SHOW_DESKTOP:
|
|
|
|
Result = ! SetWindowPos(Wnd,
|
|
|
|
NULL, 0, 0,
|
|
|
|
(int)(short) LOWORD(lParam),
|
|
|
|
(int)(short) HIWORD(lParam),
|
|
|
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOREDRAW);
|
|
|
|
UpdateWindow(Wnd);
|
2004-01-11 17:31:16 +00:00
|
|
|
VisibleDesktopWindow = Wnd;
|
2003-12-07 23:02:57 +00:00
|
|
|
break;
|
|
|
|
case PM_HIDE_DESKTOP:
|
|
|
|
Result = ! SetWindowPos(Wnd,
|
|
|
|
NULL, 0, 0, 0, 0,
|
|
|
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
|
|
|
|
SWP_HIDEWINDOW);
|
|
|
|
UpdateWindow(Wnd);
|
2004-01-11 17:31:16 +00:00
|
|
|
VisibleDesktopWindow = NULL;
|
2003-12-07 23:02:57 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Result = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL FASTCALL
|
|
|
|
DtbgInit()
|
|
|
|
{
|
|
|
|
WNDCLASSEXW Class;
|
|
|
|
HWINSTA WindowStation;
|
|
|
|
ATOM ClassAtom;
|
|
|
|
|
|
|
|
/* Attach to window station */
|
|
|
|
WindowStation = OpenWindowStationW(L"WinSta0", FALSE, GENERIC_ALL);
|
|
|
|
if (NULL == WindowStation)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Failed to open window station\n");
|
2003-12-07 23:02:57 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (! SetProcessWindowStation(WindowStation))
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Failed to set process window station\n");
|
2003-12-07 23:02:57 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create the desktop window class
|
|
|
|
*/
|
|
|
|
Class.cbSize = sizeof(WNDCLASSEXW);
|
|
|
|
Class.style = 0;
|
|
|
|
Class.lpfnWndProc = DtbgWindowProc;
|
|
|
|
Class.cbClsExtra = 0;
|
|
|
|
Class.cbWndExtra = 0;
|
|
|
|
Class.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
|
|
|
|
Class.hIcon = NULL;
|
|
|
|
Class.hCursor = NULL;
|
2003-12-22 15:30:21 +00:00
|
|
|
Class.hbrBackground = GetSysColorBrush(COLOR_BACKGROUND);
|
2003-12-07 23:02:57 +00:00
|
|
|
Class.lpszMenuName = NULL;
|
|
|
|
Class.lpszClassName = (LPCWSTR) DESKTOP_WINDOW_ATOM;
|
|
|
|
ClassAtom = RegisterClassExW(&Class);
|
|
|
|
if ((ATOM) 0 == ClassAtom)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Unable to register desktop background class (error %d)\n",
|
2003-12-07 23:02:57 +00:00
|
|
|
GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
VisibleDesktopWindow = NULL;
|
2003-12-07 23:02:57 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD STDCALL
|
|
|
|
DtbgDesktopThread(PVOID Data)
|
|
|
|
{
|
|
|
|
HWND BackgroundWnd;
|
|
|
|
MSG msg;
|
|
|
|
PDTBG_THREAD_DATA ThreadData = (PDTBG_THREAD_DATA) Data;
|
|
|
|
|
|
|
|
if (! SetThreadDesktop(ThreadData->Desktop))
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Failed to set thread desktop\n");
|
2003-12-07 23:02:57 +00:00
|
|
|
ThreadData->Status = STATUS_UNSUCCESSFUL;
|
|
|
|
SetEvent(ThreadData->Event);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
BackgroundWnd = CreateWindowW((LPCWSTR) DESKTOP_WINDOW_ATOM,
|
|
|
|
L"",
|
2004-01-17 15:18:25 +00:00
|
|
|
WS_POPUP | WS_CLIPCHILDREN,
|
2003-12-07 23:02:57 +00:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(HINSTANCE) GetModuleHandleW(NULL),
|
|
|
|
NULL);
|
|
|
|
if (NULL == BackgroundWnd)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Failed to create desktop background window\n");
|
2003-12-07 23:02:57 +00:00
|
|
|
ThreadData->Status = STATUS_UNSUCCESSFUL;
|
|
|
|
SetEvent(ThreadData->Event);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadData->Status = STATUS_SUCCESS;
|
|
|
|
SetEvent(ThreadData->Event);
|
|
|
|
|
|
|
|
while (GetMessageW(&msg, NULL, 0, 0))
|
|
|
|
{
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessageW(&msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrCreateDesktop)
|
|
|
|
{
|
|
|
|
HDESK Desktop;
|
|
|
|
DTBG_THREAD_DATA ThreadData;
|
|
|
|
HANDLE ThreadHandle;
|
|
|
|
|
|
|
|
DPRINT("CsrCreateDesktop\n");
|
|
|
|
|
|
|
|
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
|
|
|
|
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
|
|
|
|
|
|
|
|
if (! Initialized)
|
|
|
|
{
|
|
|
|
Initialized = TRUE;
|
|
|
|
if (! DtbgInit())
|
|
|
|
{
|
|
|
|
return Reply->Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Desktop = OpenDesktopW(Request->Data.CreateDesktopRequest.DesktopName,
|
|
|
|
0, FALSE, GENERIC_ALL);
|
|
|
|
if (NULL == Desktop)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Failed to open desktop %S\n",
|
2003-12-07 23:02:57 +00:00
|
|
|
Request->Data.CreateDesktopRequest.DesktopName);
|
|
|
|
return Reply->Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadData.Desktop = Desktop;
|
|
|
|
ThreadData.Event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
|
|
|
if (NULL == ThreadData.Event)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Failed to create event (error %d)\n", GetLastError());
|
2003-12-07 23:02:57 +00:00
|
|
|
return Reply->Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
ThreadHandle = CreateThread(NULL,
|
|
|
|
0,
|
|
|
|
DtbgDesktopThread,
|
|
|
|
(PVOID) &ThreadData,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
if (NULL == ThreadHandle)
|
|
|
|
{
|
|
|
|
CloseHandle(ThreadData.Event);
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Failed to create desktop window thread.\n");
|
2003-12-07 23:02:57 +00:00
|
|
|
return Reply->Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
CloseHandle(ThreadHandle);
|
|
|
|
|
|
|
|
WaitForSingleObject(ThreadData.Event, INFINITE);
|
|
|
|
CloseHandle(ThreadData.Event);
|
|
|
|
|
|
|
|
Reply->Status = ThreadData.Status;
|
|
|
|
|
|
|
|
return Reply->Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrShowDesktop)
|
|
|
|
{
|
|
|
|
DPRINT("CsrShowDesktop\n");
|
|
|
|
|
|
|
|
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
|
|
|
|
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
|
|
|
|
|
|
|
|
Reply->Status = SendMessageW(Request->Data.ShowDesktopRequest.DesktopWindow,
|
|
|
|
PM_SHOW_DESKTOP,
|
|
|
|
0,
|
|
|
|
MAKELONG(Request->Data.ShowDesktopRequest.Width,
|
|
|
|
Request->Data.ShowDesktopRequest.Height))
|
|
|
|
? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
|
|
|
|
|
|
|
|
return Reply->Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrHideDesktop)
|
|
|
|
{
|
|
|
|
DPRINT("CsrHideDesktop\n");
|
|
|
|
|
|
|
|
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
|
|
|
|
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
|
|
|
|
|
|
|
|
Reply->Status = SendMessageW(Request->Data.ShowDesktopRequest.DesktopWindow,
|
|
|
|
PM_HIDE_DESKTOP, 0, 0)
|
|
|
|
? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
|
|
|
|
|
|
|
|
return Reply->Status;
|
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
BOOL FASTCALL
|
|
|
|
DtbgIsDesktopVisible(VOID)
|
|
|
|
{
|
|
|
|
if (NULL != VisibleDesktopWindow && ! IsWindowVisible(VisibleDesktopWindow))
|
|
|
|
{
|
|
|
|
VisibleDesktopWindow = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL != VisibleDesktopWindow;
|
|
|
|
}
|
|
|
|
|
2003-12-07 23:02:57 +00:00
|
|
|
/* EOF */
|