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