Release 950430
[wine] / controls / desktop.c
1 /*
2  * Desktop window class.
3  *
4  * Copyright 1994 Alexandre Julliard
5
6 static char Copyright[] = "Copyright  Alexandre Julliard, 1994";
7 */
8
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include "win.h"
15 #include "desktop.h"
16 #include "dos_fs.h"
17 #include "graphics.h"
18
19
20 /***********************************************************************
21  *           DESKTOP_LoadBitmap
22  *
23  * Load a bitmap from a file. Used by SetDeskWallPaper().
24  */
25 static HBITMAP DESKTOP_LoadBitmap( HDC hdc, char *filename )
26 {
27     BITMAPFILEHEADER *fileHeader;
28     BITMAPINFO *bitmapInfo;
29     HBITMAP hbitmap;
30     char *unixFileName, *buffer;
31     int file;
32     long size;
33
34       /* Read all the file into memory */
35
36     if (!(unixFileName = DOS_GetUnixFileName( filename ))) return 0;
37     if ((file = open( unixFileName, O_RDONLY )) == -1) return 0;
38     size = lseek( file, 0, SEEK_END );
39     if (!(buffer = (char *)malloc( size )))
40     {
41         close( file );
42         return 0;
43     }
44     lseek( file, 0, SEEK_SET );
45     size = read( file, buffer, size );
46     close( file );
47     fileHeader = (BITMAPFILEHEADER *)buffer;
48     bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
49     
50       /* Check header content */
51     if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
52     {
53         free( buffer );
54         return 0;
55     }
56     hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
57                               buffer + fileHeader->bfOffBits,
58                               bitmapInfo, DIB_RGB_COLORS );
59     free( buffer );
60     return hbitmap;
61 }
62
63
64 /***********************************************************************
65  *           DESKTOP_DoEraseBkgnd
66  *
67  * Handle the WM_ERASEBKGND message.
68  */
69 static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
70 {
71     RECT rect;
72     GetClientRect( hwnd, &rect );    
73
74     /* Paint desktop pattern (only if wall paper does not cover everything) */
75
76     if (!infoPtr->hbitmapWallPaper || 
77         (!infoPtr->fTileWallPaper && ((infoPtr->bitmapSize.cx < rect.right) ||
78          (infoPtr->bitmapSize.cy < rect.bottom))))
79     {
80           /* Set colors in case pattern is a monochrome bitmap */
81         SetBkColor( hdc, RGB(0,0,0) );
82         SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
83         FillRect( hdc, &rect, infoPtr->hbrushPattern );
84     }
85
86       /* Paint wall paper */
87
88     if (infoPtr->hbitmapWallPaper)
89     {
90         int x, y;
91
92         if (infoPtr->fTileWallPaper)
93         {
94             for (y = 0; y < rect.bottom; y += infoPtr->bitmapSize.cy)
95                 for (x = 0; x < rect.right; x += infoPtr->bitmapSize.cx)
96                     GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper,
97                                       x, y, 0, 0, 
98                                       infoPtr->bitmapSize.cx,
99                                       infoPtr->bitmapSize.cy );
100         }
101         else
102         {
103             x = (rect.left + rect.right - infoPtr->bitmapSize.cx) / 2;
104             y = (rect.top + rect.bottom - infoPtr->bitmapSize.cy) / 2;
105             if (x < 0) x = 0;
106             if (y < 0) y = 0;
107             GRAPH_DrawBitmap( hdc, infoPtr->hbitmapWallPaper, x, y, 0, 0, 
108                               infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy );
109         }
110     }
111
112     return 1;
113 }
114
115
116 /***********************************************************************
117  *           DESKTOP_Init
118  *
119  * Initialize the desktop window private information.
120  */
121 BOOL DESKTOP_Init()
122 {
123     HWND hwnd = GetDesktopWindow();
124     WND *wndPtr = WIN_FindWndPtr( hwnd );
125     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
126
127     infoPtr->hbrushPattern = 0;
128     infoPtr->hbitmapWallPaper = 0;
129     SetDeskPattern();
130     SetDeskWallPaper( (LPSTR)-1 );
131     if (rootWindow != DefaultRootWindow(display))
132     {
133         HDC hdc = GetDC( hwnd );
134         DESKTOP_DoEraseBkgnd( hwnd, hdc, infoPtr );
135         ReleaseDC( hwnd, hdc );
136     }
137     return TRUE;
138 }
139
140
141 /***********************************************************************
142  *           DesktopWndProc
143  *
144  * Window procedure for the desktop window.
145  */
146 LONG DesktopWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam )
147 {
148     WND *wndPtr = WIN_FindWndPtr( hwnd );
149     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
150
151       /* Most messages are ignored (we DON'T call DefWindowProc) */
152
153     switch(message)
154     {
155         /* Warning: this message is sent directly by                     */
156         /* WIN_CreateDesktopWindow() and does not contain a valid lParam */
157     case WM_NCCREATE:
158         infoPtr->hbrushPattern = 0;
159         infoPtr->hbitmapWallPaper = 0;
160         SetDeskPattern();
161         SetDeskWallPaper( (LPSTR)-1 );
162         break;
163         
164     case WM_ERASEBKGND:
165         if (rootWindow == DefaultRootWindow(display)) return 1;
166         return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, infoPtr );
167     }
168     
169     return 0;
170 }
171
172
173 /***********************************************************************
174  *           SetDeskPattern   (USER.279)
175  */
176 BOOL SetDeskPattern(void)
177 {
178     char buffer[100];
179     GetProfileString( "desktop", "Pattern", "(None)", buffer, 100 );
180     return DESKTOP_SetPattern( buffer );
181 }
182
183
184 /***********************************************************************
185  *           SetDeskWallPaper   (USER.285)
186  */
187 BOOL SetDeskWallPaper( LPSTR filename )
188 {
189     HBITMAP hbitmap;
190     HDC hdc;
191     char buffer[256];
192     WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() );
193     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
194
195     if (filename == (LPSTR)-1)
196     {
197         GetProfileString( "desktop", "WallPaper", "(None)", buffer, 256 );
198         filename = buffer;
199     }
200     hdc = GetDC( 0 );
201     hbitmap = DESKTOP_LoadBitmap( hdc, filename );
202     ReleaseDC( 0, hdc );
203     if (infoPtr->hbitmapWallPaper) DeleteObject( infoPtr->hbitmapWallPaper );
204     infoPtr->hbitmapWallPaper = hbitmap;
205     infoPtr->fTileWallPaper = GetProfileInt( "desktop", "TileWallPaper", 0 );
206     if (hbitmap)
207     {
208         BITMAP bmp;
209         GetObject( hbitmap, sizeof(bmp), (LPSTR)&bmp );
210         infoPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
211         infoPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
212     }
213     return TRUE;
214 }
215
216
217 /***********************************************************************
218  *           DESKTOP_SetPattern
219  *
220  * Set the desktop pattern.
221  */
222 BOOL DESKTOP_SetPattern(char *pattern )
223 {
224     WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() );
225     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
226     int pat[8];
227
228     if (infoPtr->hbrushPattern) DeleteObject( infoPtr->hbrushPattern );
229     memset( pat, 0, sizeof(pat) );
230     if (pattern && sscanf( pattern, " %d %d %d %d %d %d %d %d",
231                            &pat[0], &pat[1], &pat[2], &pat[3],
232                            &pat[4], &pat[5], &pat[6], &pat[7] ))
233     {
234         WORD pattern[8];
235         HBITMAP hbitmap;
236         int i;
237
238         for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
239         hbitmap = CreateBitmap( 8, 8, 1, 1, (LPSTR)pattern );
240         infoPtr->hbrushPattern = CreatePatternBrush( hbitmap );
241         DeleteObject( hbitmap );
242     }
243     else infoPtr->hbrushPattern = CreateSolidBrush( GetSysColor(COLOR_BACKGROUND) );
244     return TRUE;
245 }
246