Moved some more code to the X11 driver.
[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 "heap.h"
15 #include "monitor.h"
16 #include "win.h"
17 #include "wine/winuser16.h"
18
19 /***********************************************************************
20  *              DESKTOP_GetScreenWidth
21  *
22  * Return the width of the screen associated to the current desktop.
23  */
24 int DESKTOP_GetScreenWidth()
25 {
26   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
27   return MONITOR_GetWidth(pDesktop->pPrimaryMonitor);
28 }
29
30 /***********************************************************************
31  *              DESKTOP_GetScreenHeight
32  *
33  * Return the height of the screen associated to the current desktop.
34  */
35 int DESKTOP_GetScreenHeight()
36 {
37   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
38   return MONITOR_GetHeight(pDesktop->pPrimaryMonitor);
39 }
40
41 /***********************************************************************
42  *              DESKTOP_GetScreenDepth
43  *
44  * Return the depth of the screen associated to the current desktop.
45  */
46 int DESKTOP_GetScreenDepth()
47 {
48   DESKTOP *pDesktop = (DESKTOP *) WIN_GetDesktop()->wExtra;
49   return MONITOR_GetDepth(pDesktop->pPrimaryMonitor);
50 }
51
52 /***********************************************************************
53  *           DESKTOP_LoadBitmap
54  *
55  * Load a bitmap from a file. Used by SetDeskWallPaper().
56  */
57 static HBITMAP32 DESKTOP_LoadBitmap( HDC32 hdc, const char *filename )
58 {
59     BITMAPFILEHEADER *fileHeader;
60     BITMAPINFO *bitmapInfo;
61     HBITMAP32 hbitmap;
62     HFILE32 file;
63     LPSTR buffer;
64     LONG size;
65
66     /* Read all the file into memory */
67
68     if ((file = _lopen32( filename, OF_READ )) == HFILE_ERROR32)
69     {
70         UINT32 len = GetWindowsDirectory32A( NULL, 0 );
71         if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
72                                   len + strlen(filename) + 2 )))
73             return 0;
74         GetWindowsDirectory32A( buffer, len + 1 );
75         strcat( buffer, "\\" );
76         strcat( buffer, filename );
77         file = _lopen32( buffer, OF_READ );
78         HeapFree( GetProcessHeap(), 0, buffer );
79     }
80     if (file == HFILE_ERROR32) return 0;
81     size = _llseek32( file, 0, 2 );
82     if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size )))
83     {
84         _lclose32( file );
85         return 0;
86     }
87     _llseek32( file, 0, 0 );
88     size = _lread32( file, buffer, size );
89     _lclose32( file );
90     fileHeader = (BITMAPFILEHEADER *)buffer;
91     bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
92     
93       /* Check header content */
94     if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
95     {
96         HeapFree( GetProcessHeap(), 0, buffer );
97         return 0;
98     }
99     hbitmap = CreateDIBitmap32( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
100                                 buffer + fileHeader->bfOffBits,
101                                 bitmapInfo, DIB_RGB_COLORS );
102     HeapFree( GetProcessHeap(), 0, buffer );
103     return hbitmap;
104 }
105
106
107 /***********************************************************************
108  *           DESKTOP_DoEraseBkgnd
109  *
110  * Handle the WM_ERASEBKGND message.
111  */
112 static LRESULT DESKTOP_DoEraseBkgnd( HWND32 hwnd, HDC32 hdc,
113                                      DESKTOP *desktopPtr )
114 {
115     RECT32 rect;
116     WND*   Wnd = WIN_FindWndPtr( hwnd );
117
118     if (Wnd->hrgnUpdate > 1) DeleteObject32( Wnd->hrgnUpdate );
119     Wnd->hrgnUpdate = 0;
120
121     GetClientRect32( hwnd, &rect );    
122
123     /* Paint desktop pattern (only if wall paper does not cover everything) */
124
125     if (!desktopPtr->hbitmapWallPaper || 
126         (!desktopPtr->fTileWallPaper && ((desktopPtr->bitmapSize.cx < rect.right) ||
127          (desktopPtr->bitmapSize.cy < rect.bottom))))
128     {
129           /* Set colors in case pattern is a monochrome bitmap */
130         SetBkColor32( hdc, RGB(0,0,0) );
131         SetTextColor32( hdc, GetSysColor32(COLOR_BACKGROUND) );
132         FillRect32( hdc, &rect, desktopPtr->hbrushPattern );
133     }
134
135       /* Paint wall paper */
136
137     if (desktopPtr->hbitmapWallPaper)
138     {
139         INT32 x, y;
140         HDC32 hMemDC = CreateCompatibleDC32( hdc );
141         
142         SelectObject32( hMemDC, desktopPtr->hbitmapWallPaper );
143
144         if (desktopPtr->fTileWallPaper)
145         {
146             for (y = 0; y < rect.bottom; y += desktopPtr->bitmapSize.cy)
147                 for (x = 0; x < rect.right; x += desktopPtr->bitmapSize.cx)
148                     BitBlt32( hdc, x, y, desktopPtr->bitmapSize.cx,
149                               desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
150         }
151         else
152         {
153             x = (rect.left + rect.right - desktopPtr->bitmapSize.cx) / 2;
154             y = (rect.top + rect.bottom - desktopPtr->bitmapSize.cy) / 2;
155             if (x < 0) x = 0;
156             if (y < 0) y = 0;
157             BitBlt32( hdc, x, y, desktopPtr->bitmapSize.cx,
158                       desktopPtr->bitmapSize.cy, hMemDC, 0, 0, SRCCOPY );
159         }
160         DeleteDC32( hMemDC );
161     }
162
163     return 1;
164 }
165
166
167 /***********************************************************************
168  *           DesktopWndProc
169  *
170  * Window procedure for the desktop window.
171  */
172 LRESULT WINAPI DesktopWndProc( HWND32 hwnd, UINT32 message,
173                                WPARAM32 wParam, LPARAM lParam )
174 {
175     WND *wndPtr = WIN_FindWndPtr( hwnd );
176     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
177
178       /* Most messages are ignored (we DON'T call DefWindowProc) */
179
180     switch(message)
181     {
182         /* Warning: this message is sent directly by                     */
183         /* WIN_CreateDesktopWindow() and does not contain a valid lParam */
184     case WM_NCCREATE:
185         desktopPtr->hbrushPattern = 0;
186         desktopPtr->hbitmapWallPaper = 0;
187         SetDeskPattern();
188         SetDeskWallPaper32( (LPSTR)-1 );
189         return 1;
190         
191     case WM_ERASEBKGND:
192         if (X11DRV_WND_GetXRootWindow(wndPtr) == 
193             DefaultRootWindow(display))
194           return 1;
195         return DESKTOP_DoEraseBkgnd( hwnd, (HDC32)wParam, desktopPtr );
196
197     case WM_SYSCOMMAND:
198         if ((wParam & 0xfff0) != SC_CLOSE) return 0;
199         ExitWindows16( 0, 0 ); 
200
201     case WM_SETCURSOR:
202         return (LRESULT)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
203     }
204     
205     return 0;
206 }
207
208 /***********************************************************************
209  *           PaintDesktop   (USER32.415)
210  *
211  */
212 BOOL32 WINAPI PaintDesktop(HDC32 hdc)
213 {
214     HWND32 hwnd = GetDesktopWindow32();
215     WND *wndPtr = WIN_FindWndPtr( hwnd );
216     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
217
218     return DESKTOP_DoEraseBkgnd( hwnd, hdc, desktopPtr );
219 }
220
221 /***********************************************************************
222  *           SetDeskPattern   (USER.279)
223  */
224 BOOL16 WINAPI SetDeskPattern(void)
225 {
226     char buffer[100];
227     GetProfileString32A( "desktop", "Pattern", "(None)", buffer, 100 );
228     return DESKTOP_SetPattern( buffer );
229 }
230
231
232 /***********************************************************************
233  *           SetDeskWallPaper16   (USER.285)
234  */
235 BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
236 {
237     return SetDeskWallPaper32( filename );
238 }
239
240
241 /***********************************************************************
242  *           SetDeskWallPaper32   (USER32.475)
243  *
244  * FIXME: is there a unicode version?
245  */
246 BOOL32 WINAPI SetDeskWallPaper32( LPCSTR filename )
247 {
248     HBITMAP32 hbitmap;
249     HDC32 hdc;
250     char buffer[256];
251     WND *wndPtr = WIN_GetDesktop();
252     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
253
254     if (filename == (LPSTR)-1)
255     {
256         GetProfileString32A( "desktop", "WallPaper", "(None)", buffer, 256 );
257         filename = buffer;
258     }
259     hdc = GetDC32( 0 );
260     hbitmap = DESKTOP_LoadBitmap( hdc, filename );
261     ReleaseDC32( 0, hdc );
262     if (desktopPtr->hbitmapWallPaper) DeleteObject32( desktopPtr->hbitmapWallPaper );
263     desktopPtr->hbitmapWallPaper = hbitmap;
264     desktopPtr->fTileWallPaper = GetProfileInt32A( "desktop", "TileWallPaper", 0 );
265     if (hbitmap)
266     {
267         BITMAP32 bmp;
268         GetObject32A( hbitmap, sizeof(bmp), &bmp );
269         desktopPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
270         desktopPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
271     }
272     return TRUE;
273 }
274
275
276 /***********************************************************************
277  *           DESKTOP_SetPattern
278  *
279  * Set the desktop pattern.
280  */
281 BOOL32 DESKTOP_SetPattern( LPCSTR pattern )
282 {
283     WND *wndPtr = WIN_GetDesktop();
284     DESKTOP *desktopPtr = (DESKTOP *)wndPtr->wExtra;
285     int pat[8];
286
287     if (desktopPtr->hbrushPattern) DeleteObject32( desktopPtr->hbrushPattern );
288     memset( pat, 0, sizeof(pat) );
289     if (pattern && sscanf( pattern, " %d %d %d %d %d %d %d %d",
290                            &pat[0], &pat[1], &pat[2], &pat[3],
291                            &pat[4], &pat[5], &pat[6], &pat[7] ))
292     {
293         WORD pattern[8];
294         HBITMAP32 hbitmap;
295         int i;
296
297         for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
298         hbitmap = CreateBitmap32( 8, 8, 1, 1, (LPSTR)pattern );
299         desktopPtr->hbrushPattern = CreatePatternBrush32( hbitmap );
300         DeleteObject32( hbitmap );
301     }
302     else desktopPtr->hbrushPattern = CreateSolidBrush32( GetSysColor32(COLOR_BACKGROUND) );
303     return TRUE;
304 }
305