2 * Desktop window class.
4 * Copyright 1994 Alexandre Julliard
17 #include "wine/winuser16.h"
22 HBITMAP hbitmapWallPaper;
27 static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
30 /*********************************************************************
31 * desktop class descriptor
33 const struct builtin_class_descr DESKTOP_builtin_class =
35 DESKTOP_CLASS_ATOM, /* name */
36 CS_GLOBALCLASS, /* style */
37 NULL, /* procA (winproc is Unicode only) */
38 DesktopWndProc, /* procW */
39 sizeof(DESKTOP), /* extra */
40 IDC_ARROWA, /* cursor */
41 COLOR_BACKGROUND+1 /* brush */
45 /***********************************************************************
48 * Load a bitmap from a file. Used by SetDeskWallPaper().
50 static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
52 BITMAPFILEHEADER *fileHeader;
53 BITMAPINFO *bitmapInfo;
59 /* Read all the file into memory */
61 if ((file = _lopen( filename, OF_READ )) == HFILE_ERROR)
63 UINT len = GetWindowsDirectoryA( NULL, 0 );
64 if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
65 len + strlen(filename) + 2 )))
67 GetWindowsDirectoryA( buffer, len + 1 );
68 strcat( buffer, "\\" );
69 strcat( buffer, filename );
70 file = _lopen( buffer, OF_READ );
71 HeapFree( GetProcessHeap(), 0, buffer );
73 if (file == HFILE_ERROR) return 0;
74 size = _llseek( file, 0, 2 );
75 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size )))
80 _llseek( file, 0, 0 );
81 size = _lread( file, buffer, size );
83 fileHeader = (BITMAPFILEHEADER *)buffer;
84 bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
86 /* Check header content */
87 if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
89 HeapFree( GetProcessHeap(), 0, buffer );
92 hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
93 buffer + fileHeader->bfOffBits,
94 bitmapInfo, DIB_RGB_COLORS );
95 HeapFree( GetProcessHeap(), 0, buffer );
100 /***********************************************************************
101 * DESKTOP_DoEraseBkgnd
103 * Handle the WM_ERASEBKGND message.
105 static LRESULT DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc,
106 DESKTOP *desktopPtr )
109 WND* Wnd = WIN_FindWndPtr( hwnd );
111 if (Wnd->hrgnUpdate > 1) DeleteObject( Wnd->hrgnUpdate );
114 WIN_ReleaseWndPtr(Wnd);
116 GetClientRect( hwnd, &rect );
118 /* Paint desktop pattern (only if wall paper does not cover everything) */
120 if (!desktopPtr->hbitmapWallPaper ||
121 (!desktopPtr->fTileWallPaper && ((desktopPtr->bitmapSize.cx < rect.right) ||
122 (desktopPtr->bitmapSize.cy < rect.bottom))))
124 HBRUSH brush = desktopPtr->hbrushPattern;
125 if (!brush) brush = GetClassLongA( hwnd, GCL_HBRBACKGROUND );
126 /* Set colors in case pattern is a monochrome bitmap */
127 SetBkColor( hdc, RGB(0,0,0) );
128 SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
129 FillRect( hdc, &rect, brush );
132 /* Paint wall paper */
134 if (desktopPtr->hbitmapWallPaper)
137 HDC hMemDC = CreateCompatibleDC( hdc );
139 SelectObject( hMemDC, desktopPtr->hbitmapWallPaper );
141 if (desktopPtr->fTileWallPaper)
143 for (y = 0; y < rect.bottom; y += desktopPtr->bitmapSize.cy)
144 for (x = 0; x < rect.right; x += desktopPtr->bitmapSize.cx)
145 BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
146 desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
150 x = (rect.left + rect.right - desktopPtr->bitmapSize.cx) / 2;
151 y = (rect.top + rect.bottom - desktopPtr->bitmapSize.cy) / 2;
154 BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
155 desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
164 /***********************************************************************
165 * DesktopWndProc_locked
167 * Window procedure for the desktop window.
169 static inline LRESULT WINAPI DesktopWndProc_locked( WND *wndPtr, UINT message,
170 WPARAM wParam, LPARAM lParam )
172 DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
173 HWND hwnd = wndPtr->hwndSelf;
175 /* Most messages are ignored (we DON'T call DefWindowProc) */
179 /* Warning: this message is sent directly by */
180 /* WIN_CreateDesktopWindow() and does not contain a valid lParam */
182 desktopPtr->hbrushPattern = 0;
183 desktopPtr->hbitmapWallPaper = 0;
185 SetDeskWallPaper( (LPSTR)-1 );
189 if(!USER_Driver.pIsSingleWindow())
191 return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, desktopPtr );
194 if ((wParam & 0xfff0) != SC_CLOSE)
196 ExitWindows16( 0, 0 );
199 return (LRESULT)SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
205 /***********************************************************************
208 * This is just a wrapper for the DesktopWndProc which does windows
209 * locking and unlocking.
211 static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
213 WND *wndPtr = WIN_FindWndPtr( hwnd );
214 LRESULT retvalue = DesktopWndProc_locked(wndPtr,message,wParam,lParam);
216 WIN_ReleaseWndPtr(wndPtr);
220 /***********************************************************************
221 * PaintDesktop (USER32.415)
224 BOOL WINAPI PaintDesktop(HDC hdc)
227 HWND hwnd = GetDesktopWindow();
228 WND *wndPtr = WIN_FindWndPtr( hwnd );
229 DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
230 retvalue = DESKTOP_DoEraseBkgnd( hwnd, hdc, desktopPtr );
231 WIN_ReleaseWndPtr(wndPtr);
236 /***********************************************************************
237 * SetDeskPattern (USER.279)
239 BOOL16 WINAPI SetDeskPattern(void)
242 GetProfileStringA( "desktop", "Pattern", "(None)", buffer, 100 );
243 return DESKTOP_SetPattern( buffer );
247 /***********************************************************************
248 * SetDeskWallPaper16 (USER.285)
250 BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
252 return SetDeskWallPaper( filename );
256 /***********************************************************************
257 * SetDeskWallPaper (USER32.475)
259 * FIXME: is there a unicode version?
261 BOOL WINAPI SetDeskWallPaper( LPCSTR filename )
266 WND *wndPtr = WIN_GetDesktop();
267 DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
269 if (filename == (LPSTR)-1)
271 GetProfileStringA( "desktop", "WallPaper", "(None)", buffer, 256 );
275 hbitmap = DESKTOP_LoadBitmap( hdc, filename );
277 if (desktopPtr->hbitmapWallPaper) DeleteObject( desktopPtr->hbitmapWallPaper );
278 desktopPtr->hbitmapWallPaper = hbitmap;
279 desktopPtr->fTileWallPaper = GetProfileIntA( "desktop", "TileWallPaper", 0 );
283 GetObjectA( hbitmap, sizeof(bmp), &bmp );
284 desktopPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
285 desktopPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
287 WIN_ReleaseDesktop();
292 /***********************************************************************
295 * Set the desktop pattern.
297 BOOL DESKTOP_SetPattern( LPCSTR pattern )
299 WND *wndPtr = WIN_GetDesktop();
300 DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
303 if (desktopPtr->hbrushPattern) DeleteObject( desktopPtr->hbrushPattern );
304 memset( pat, 0, sizeof(pat) );
305 if (pattern && sscanf( pattern, " %d %d %d %d %d %d %d %d",
306 &pat[0], &pat[1], &pat[2], &pat[3],
307 &pat[4], &pat[5], &pat[6], &pat[7] ))
313 for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
314 hbitmap = CreateBitmap( 8, 8, 1, 1, (LPSTR)pattern );
315 desktopPtr->hbrushPattern = CreatePatternBrush( hbitmap );
316 DeleteObject( hbitmap );
318 else desktopPtr->hbrushPattern = 0;
319 WIN_ReleaseDesktop();