Changed some debug messages from one channel to another, to clean up a
[wine] / controls / desktop.c
1 /*
2  * Desktop window class.
3  *
4  * Copyright 1994 Alexandre Julliard
5  */
6
7 #include "x11drv.h"
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <unistd.h>
12
13 #include "desktop.h"
14 #include "windef.h"
15 #include "heap.h"
16 #include "monitor.h"
17 #include "win.h"
18 #include "wine/winuser16.h"
19
20 /***********************************************************************
21  *              DESKTOP_GetScreenWidth
22  *
23  * Return the width of the screen associated to the current desktop.
24  */
25 int DESKTOP_GetScreenWidth()
26 {
27     int retvalue;
28   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
29     retvalue = MONITOR_GetWidth(pDesktop->pPrimaryMonitor);
30     WIN_ReleaseDesktop();
31     return retvalue;
32     
33 }
34
35 /***********************************************************************
36  *              DESKTOP_GetScreenHeight
37  *
38  * Return the height of the screen associated to the current desktop.
39  */
40 int DESKTOP_GetScreenHeight()
41 {
42     int retvalue;
43   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
44     retvalue = MONITOR_GetHeight(pDesktop->pPrimaryMonitor);
45     WIN_ReleaseDesktop();
46     return retvalue;
47     
48 }
49
50 /***********************************************************************
51  *              DESKTOP_GetScreenDepth
52  *
53  * Return the depth of the screen associated to the current desktop.
54  */
55 int DESKTOP_GetScreenDepth()
56 {
57     int retvalue;
58   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
59     retvalue = MONITOR_GetDepth(pDesktop->pPrimaryMonitor);
60     WIN_ReleaseDesktop();
61     return retvalue;
62
63 }
64
65 /***********************************************************************
66  *           DESKTOP_LoadBitmap
67  *
68  * Load a bitmap from a file. Used by SetDeskWallPaper().
69  */
70 static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
71 {
72     BITMAPFILEHEADER *fileHeader;
73     BITMAPINFO *bitmapInfo;
74     HBITMAP hbitmap;
75     HFILE file;
76     LPSTR buffer;
77     LONG size;
78
79     /* Read all the file into memory */
80
81     if ((file = _lopen( filename, OF_READ )) == HFILE_ERROR)
82     {
83         UINT len = GetWindowsDirectoryA( NULL, 0 );
84         if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
85                                   len + strlen(filename) + 2 )))
86             return 0;
87         GetWindowsDirectoryA( buffer, len + 1 );
88         strcat( buffer, "\\" );
89         strcat( buffer, filename );
90         file = _lopen( buffer, OF_READ );
91         HeapFree( GetProcessHeap(), 0, buffer );
92     }
93     if (file == HFILE_ERROR) return 0;
94     size = _llseek( file, 0, 2 );
95     if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size )))
96     {
97         _lclose( file );
98         return 0;
99     }
100     _llseek( file, 0, 0 );
101     size = _lread( file, buffer, size );
102     _lclose( file );
103     fileHeader = (BITMAPFILEHEADER *)buffer;
104     bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
105     
106       /* Check header content */
107     if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
108     {
109         HeapFree( GetProcessHeap(), 0, buffer );
110         return 0;
111     }
112     hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
113                                 buffer + fileHeader->bfOffBits,
114                                 bitmapInfo, DIB_RGB_COLORS );
115     HeapFree( GetProcessHeap(), 0, buffer );
116     return hbitmap;
117 }
118
119
120 /***********************************************************************
121  *           DESKTOP_DoEraseBkgnd
122  *
123  * Handle the WM_ERASEBKGND message.
124  */
125 static LRESULT DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc,
126                                      DESKTOP *desktopPtr )
127 {
128     RECT rect;
129     WND*   Wnd = WIN_FindWndPtr( hwnd );
130
131     if (Wnd->hrgnUpdate > 1) DeleteObject( Wnd->hrgnUpdate );
132     Wnd->hrgnUpdate = 0;
133
134     WIN_ReleaseWndPtr(Wnd);
135     
136     GetClientRect( hwnd, &rect );    
137
138     /* Paint desktop pattern (only if wall paper does not cover everything) */
139
140     if (!desktopPtr->hbitmapWallPaper || 
141         (!desktopPtr->fTileWallPaper && ((desktopPtr->bitmapSize.cx < rect.right) ||
142          (desktopPtr->bitmapSize.cy < rect.bottom))))
143     {
144           /* Set colors in case pattern is a monochrome bitmap */
145         SetBkColor( hdc, RGB(0,0,0) );
146         SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
147         FillRect( hdc, &rect, desktopPtr->hbrushPattern );
148     }
149
150       /* Paint wall paper */
151
152     if (desktopPtr->hbitmapWallPaper)
153     {
154         INT x, y;
155         HDC hMemDC = CreateCompatibleDC( hdc );
156         
157         SelectObject( hMemDC, desktopPtr->hbitmapWallPaper );
158
159         if (desktopPtr->fTileWallPaper)
160         {
161             for (y = 0; y < rect.bottom; y += desktopPtr->bitmapSize.cy)
162                 for (x = 0; x < rect.right; x += desktopPtr->bitmapSize.cx)
163                     BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
164                               desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
165         }
166         else
167         {
168             x = (rect.left + rect.right - desktopPtr->bitmapSize.cx) / 2;
169             y = (rect.top + rect.bottom - desktopPtr->bitmapSize.cy) / 2;
170             if (x < 0) x = 0;
171             if (y < 0) y = 0;
172             BitBlt( hdc, x, y, desktopPtr->bitmapSize.cx,
173                       desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
174         }
175         DeleteDC( hMemDC );
176     }
177
178     return 1;
179 }
180
181
182 /***********************************************************************
183  *           DesktopWndProc
184  *
185  * Window procedure for the desktop window.
186  */
187 LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message,
188                                WPARAM wParam, LPARAM lParam )
189 {
190     LRESULT retvalue;
191     WND *wndPtr = WIN_FindWndPtr( hwnd );
192     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
193
194       /* Most messages are ignored (we DON'T call DefWindowProc) */
195
196     switch(message)
197     {
198         /* Warning: this message is sent directly by                     */
199         /* WIN_CreateDesktopWindow() and does not contain a valid lParam */
200     case WM_NCCREATE:
201         desktopPtr->hbrushPattern = 0;
202         desktopPtr->hbitmapWallPaper = 0;
203         SetDeskPattern();
204         SetDeskWallPaper( (LPSTR)-1 );
205         retvalue = 1;
206         goto END;
207         
208     case WM_ERASEBKGND:
209         if (X11DRV_WND_GetXRootWindow(wndPtr) == 
210             DefaultRootWindow(display))
211         {
212             retvalue = 1;
213             goto END;
214         }
215         retvalue = DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, desktopPtr );
216         goto END;
217
218     case WM_SYSCOMMAND:
219         if ((wParam & 0xfff0) != SC_CLOSE)
220         {
221             retvalue = 0;
222             goto END;
223         }
224         ExitWindows16( 0, 0 ); 
225
226     case WM_SETCURSOR:
227         retvalue = (LRESULT)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
228         goto END;
229     }
230     
231     retvalue = 0;
232 END:
233     WIN_ReleaseWndPtr(wndPtr);
234     return retvalue;
235 }
236
237 /***********************************************************************
238  *           PaintDesktop   (USER32.415)
239  *
240  */
241 BOOL WINAPI PaintDesktop(HDC hdc)
242 {
243     BOOL retvalue;
244     HWND hwnd = GetDesktopWindow();
245     WND *wndPtr = WIN_FindWndPtr( hwnd );
246     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
247     retvalue = DESKTOP_DoEraseBkgnd( hwnd, hdc, desktopPtr );
248     WIN_ReleaseWndPtr(wndPtr);
249     return retvalue;
250
251 }
252
253 /***********************************************************************
254  *           SetDeskPattern   (USER.279)
255  */
256 BOOL16 WINAPI SetDeskPattern(void)
257 {
258     char buffer[100];
259     GetProfileStringA( "desktop", "Pattern", "(None)", buffer, 100 );
260     return DESKTOP_SetPattern( buffer );
261 }
262
263
264 /***********************************************************************
265  *           SetDeskWallPaper16   (USER.285)
266  */
267 BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
268 {
269     return SetDeskWallPaper( filename );
270 }
271
272
273 /***********************************************************************
274  *           SetDeskWallPaper32   (USER32.475)
275  *
276  * FIXME: is there a unicode version?
277  */
278 BOOL WINAPI SetDeskWallPaper( LPCSTR filename )
279 {
280     HBITMAP hbitmap;
281     HDC hdc;
282     char buffer[256];
283     WND *wndPtr = WIN_GetDesktop();
284     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
285
286     if (filename == (LPSTR)-1)
287     {
288         GetProfileStringA( "desktop", "WallPaper", "(None)", buffer, 256 );
289         filename = buffer;
290     }
291     hdc = GetDC( 0 );
292     hbitmap = DESKTOP_LoadBitmap( hdc, filename );
293     ReleaseDC( 0, hdc );
294     if (desktopPtr->hbitmapWallPaper) DeleteObject( desktopPtr->hbitmapWallPaper );
295     desktopPtr->hbitmapWallPaper = hbitmap;
296     desktopPtr->fTileWallPaper = GetProfileIntA( "desktop", "TileWallPaper", 0 );
297     if (hbitmap)
298     {
299         BITMAP bmp;
300         GetObjectA( hbitmap, sizeof(bmp), &bmp );
301         desktopPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
302         desktopPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
303     }
304     WIN_ReleaseDesktop();
305     return TRUE;
306 }
307
308
309 /***********************************************************************
310  *           DESKTOP_SetPattern
311  *
312  * Set the desktop pattern.
313  */
314 BOOL DESKTOP_SetPattern( LPCSTR pattern )
315 {
316     WND *wndPtr = WIN_GetDesktop();
317     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
318     int pat[8];
319
320     if (desktopPtr->hbrushPattern) DeleteObject( desktopPtr->hbrushPattern );
321     memset( pat, 0, sizeof(pat) );
322     if (pattern && sscanf( pattern, " %d %d %d %d %d %d %d %d",
323                            &pat[0], &pat[1], &pat[2], &pat[3],
324                            &pat[4], &pat[5], &pat[6], &pat[7] ))
325     {
326         WORD pattern[8];
327         HBITMAP hbitmap;
328         int i;
329
330         for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
331         hbitmap = CreateBitmap( 8, 8, 1, 1, (LPSTR)pattern );
332         desktopPtr->hbrushPattern = CreatePatternBrush( hbitmap );
333         DeleteObject( hbitmap );
334     }
335     else desktopPtr->hbrushPattern = CreateSolidBrush( GetSysColor(COLOR_BACKGROUND) );
336     WIN_ReleaseDesktop();
337     return TRUE;
338 }
339