]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/mwin/windefw.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / mwin / windefw.c
1 /*
2  * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3  *
4  * DefWindowProc implementation for Micro-Windows
5  *      This file should ideally only include windows.h, and be built
6  *      on top of regular win32 api calls.  For speed, however,
7  *      certain knowledge of the internal hwnd is known...
8  */
9 #include "windows.h"
10 #include "wintern.h"
11 #include "device.h"
12 #include "wintools.h"           /* Draw3dBox, etc*/
13 #include <string.h>
14
15 /* desktop wallpaper image*/
16 static PMWIMAGEHDR      pImageWallpaper = NULL;
17
18 /* local routines*/
19 static void     GetCloseBoxRect(HWND hwnd, LPRECT lprc);
20 static void     DrawXORFrame(HWND hwnd,int x, int y, BOOL bDrawCurrent);
21 static RECT     lastrc;
22
23 BOOL
24 MwSetDesktopWallpaper(PMWIMAGEHDR pImage)
25 {
26         pImageWallpaper = pImage;
27         InvalidateRect(rootwp, NULL, TRUE);
28         return TRUE;
29 }
30
31 /* needed only for XORMOVE repaint algorithm*/
32 static void
33 DrawXORFrame(HWND hwnd,int x, int y, BOOL bDrawCurrent)
34 {
35         HDC     hdc;
36         RECT    rc;
37
38         hdc = GetDCEx(NULL, NULL, DCX_WINDOW|DCX_EXCLUDEUPDATE);
39         SelectObject(hdc, GetStockObject(NULL_BRUSH));
40         SelectObject(hdc, GetStockObject(WHITE_PEN));
41         GdSetMode(MWMODE_XOR);
42         if(!IsRectEmpty(&lastrc))
43                 Rectangle(hdc, lastrc.left, lastrc.top, lastrc.right,
44                         lastrc.bottom);
45         GetWindowRect(hwnd, &rc);
46         SetRect(&lastrc, rc.left+x, rc.top+y, rc.right+x, rc.bottom+y);
47         if(bDrawCurrent)
48                 Rectangle(hdc, lastrc.left, lastrc.top, lastrc.right,
49                         lastrc.bottom);
50         ReleaseDC(NULL, hdc);
51         GdSetMode(MWMODE_COPY);
52 }
53
54 /*
55  * This procedure implements the messages passed by the window
56  * manager for default processing on behalf of the window.
57  */
58 LRESULT WINAPI
59 DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
60 {
61         HDC             hdc;
62         RECT            rc;
63         DWORD           dwStyle;
64         HBRUSH          hbr;
65         HPEN            hpen, holdpen;
66         PAINTSTRUCT     ps;
67         POINT           curpt;
68         int             x, y;
69         HWND            wp;
70         HWND            oldActive;
71         COLORREF        crCaption;
72         LPNCCALCSIZE_PARAMS lpnc;
73         CHAR            szTitle[64];
74         static POINT    startpt;
75
76         switch(msg) {
77         case WM_NCCALCSIZE:
78                 /* calculate client rect from passed window rect in rgrc[0]*/
79                 lpnc = (LPNCCALCSIZE_PARAMS)lParam;
80                 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
81                 if(dwStyle & WS_BORDER) {
82                         if((dwStyle & WS_CAPTION) == WS_CAPTION) {
83                                 InflateRect(&lpnc->rgrc[0],
84                                         -mwSYSMETRICS_CXFRAME,
85                                         -mwSYSMETRICS_CYFRAME);
86                                 lpnc->rgrc[0].top += mwSYSMETRICS_CYCAPTION + 1;
87                         } else
88                                 InflateRect(&lpnc->rgrc[0], -1, -1);
89                 }
90                 break;
91
92         case WM_NCPAINT:
93                 /* repaint all non-client area*/
94                 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
95
96                 if(dwStyle & WS_BORDER) {
97                         hdc = GetWindowDC(hwnd);
98                         GetWindowRect(hwnd, &rc);
99
100                         if((dwStyle & WS_CAPTION) == WS_CAPTION) {
101                                 /* draw 2-line 3d border around window*/
102                                 Draw3dOutset(hdc, rc.left, rc.top,
103                                         rc.right-rc.left, rc.bottom-rc.top);
104                                 InflateRect(&rc, -2, -2);
105
106                                 /* draw 1-line inset inside border*/
107                                 hpen = CreatePen(PS_SOLID, 1,
108                                         GetSysColor(COLOR_BTNFACE));
109                                 holdpen = SelectObject(hdc, hpen);
110                                 SelectObject(hdc, GetStockObject(NULL_BRUSH));
111                                 Rectangle(hdc, rc.left, rc.top, rc.right,
112                                         rc.bottom);
113                                 InflateRect(&rc, -1, -1);
114
115                                 /* fill caption*/
116                                 rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION;
117                                 crCaption = GetActiveWindow()==hwnd?
118                                         GetSysColor(COLOR_ACTIVECAPTION):
119                                         GetSysColor(COLOR_INACTIVECAPTION);
120                                 hbr = CreateSolidBrush(crCaption);
121                                 FillRect(hdc, &rc, hbr);
122                                 DeleteObject(hbr);
123
124                                 /* draw 1 line under caption*/
125                                 MoveToEx(hdc, rc.left, rc.bottom, NULL);
126                                 LineTo(hdc, rc.right, rc.bottom);
127                                 DeleteObject(SelectObject(hdc, holdpen));
128
129                                 /* draw caption text*/
130                                 if(GetWindowText(hwnd, szTitle,
131                                    sizeof(szTitle))) {
132                                         SetBkMode(hdc, TRANSPARENT);
133                                         /* set background color even though
134                                          * transparent in case GdArea is used
135                                          * to draw text which compares
136                                          * gr_foreground != gr_background
137                                          * when transparent...
138                                          */
139                                         SetBkColor(hdc, crCaption);
140                                         SetTextColor(hdc,
141                                                 GetActiveWindow()==hwnd?
142                                                 GetSysColor(COLOR_CAPTIONTEXT):
143                                                 GetSysColor(COLOR_INACTIVECAPTIONTEXT));
144                                         SelectObject(hdc,
145                                             GetStockObject(DEFAULT_GUI_FONT));
146                                         GetWindowRect(hwnd, &rc);
147                                         TextOut(hdc, rc.left+4, rc.top+2,
148                                                 szTitle, strlen(szTitle));
149                                 }
150
151                                 /* draw close box*/
152                                 GetCloseBoxRect(hwnd, &rc);
153                                 /*DrawDIB(hdc, rc.right-XSIZE_CLOSEBOX-3,
154                                         rc.top+3, &image_close4);*/
155                                 Draw3dBox(hdc, rc.left, rc.top,
156                                         rc.right-rc.left, rc.bottom-rc.top,
157                                         GetSysColor(COLOR_BTNHIGHLIGHT),
158                                         GetSysColor(COLOR_WINDOWFRAME));
159                                 InflateRect(&rc, -1, -1);
160                                 hbr = CreateSolidBrush(
161                                         GetSysColor(COLOR_BTNFACE));
162                                 FillRect(hdc, &rc, hbr);
163                                 DeleteObject(hbr);
164
165                                 InflateRect(&rc, -1, -1);
166                                 MoveToEx(hdc, rc.left, rc.top, NULL);
167                                 LineTo(hdc, rc.right-1, rc.bottom-1);
168                                 MoveToEx(hdc, rc.left, rc.bottom-1, NULL);
169                                 LineTo(hdc, rc.right-1, rc.top);
170                         } else {
171                                 SelectObject(hdc, GetStockObject(NULL_BRUSH));
172                                 Rectangle(hdc, rc.left, rc.top, rc.right,
173                                         rc.bottom);
174                         }
175                         ReleaseDC(hwnd, hdc);
176                 }
177                 break;
178
179         case WM_NCHITTEST:
180                 /* if system is dragging a window, always return caption*/
181                 if(dragwp)
182                         return HTCAPTION;
183
184                 /* Determine what part of the window the mouse is over*/
185                 POINTSTOPOINT(curpt, lParam);
186
187                 if(PtInRect(&hwnd->clirect, curpt))
188                         return HTCLIENT;
189
190                 if(PtInRect(&hwnd->vscroll.rc, curpt))
191                         return HTVSCROLL;
192                 if(PtInRect(&hwnd->hscroll.rc, curpt))
193                         return HTHSCROLL; 
194
195                 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
196                 if((dwStyle & WS_CAPTION) == WS_CAPTION) {
197                         GetCloseBoxRect(hwnd, &rc);
198                         if(PtInRect(&rc, curpt))
199                                 return HTCLOSE;
200
201                         GetWindowRect(hwnd, &rc);
202                         InflateRect(&rc, -2, -2);
203                         rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION;
204                         if(PtInRect(&rc, curpt))
205                                 return HTCAPTION;
206
207                         GetWindowRect(hwnd, &rc);
208                         InflateRect(&rc, -2, -2);
209                         rc.top += mwSYSMETRICS_CYCAPTION;
210                         if(PtInRect(&rc, curpt))
211                                 return HTCLIENT;
212
213                         return HTBORDER;
214                 }
215                 return HTNOWHERE;
216
217         case WM_NCLBUTTONDOWN:
218                 /* Handle default actions for mouse down on window*/
219                 if(wParam == HTCLOSE) {
220                         SendMessage(hwnd, WM_CLOSE, 0, 0L);
221                         break;
222                 }
223
224                 /* set focus on mouse down, repaint if necessary*/
225                 oldActive = GetActiveWindow();
226                 if(wParam == HTCLIENT || wParam == HTVSCROLL ||
227                    wParam == HTHSCROLL)
228                         /* activate and raise window if in client area*/
229                         /* kaffe port requires this commented out*/
230                         SetForegroundWindow(hwnd);
231                 else {
232                         /* otherwise just change focus window, same z order*/
233                         /* this will activate it's top level parent*/
234                         SetFocus(hwnd);
235                 }
236                 /* repaint captions now because of activation change*/
237                 UpdateWindow(oldActive);
238                 UpdateWindow(hwnd);
239
240                 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
241                         MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
242                         break;
243                 }
244
245                 /* start window drag if in caption area*/
246                 if(wParam == HTCAPTION && hwnd != rootwp) {
247                         POINTSTOPOINT(startpt, lParam);
248                         if(!(GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZE))
249                                 dragwp = hwnd;
250                         SetRectEmpty(&lastrc);  /* XORMOVE only*/
251                 }
252                 break;
253
254         case WM_NCMOUSEMOVE:
255                 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
256                         MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
257                         break;
258                 }
259
260                 /* drag window with mousemove after mousedown*/
261                 if(dragwp == hwnd) {
262                         POINTSTOPOINT(curpt, lParam);
263                         x = curpt.x - startpt.x;
264                         y = curpt.y - startpt.y;
265
266                         if(mwERASEMOVE) {
267                                 GetWindowRect(hwnd, &rc);
268                                 MoveWindow(hwnd, rc.left+x, rc.top+y,
269                                         rc.right-rc.left, rc.bottom-rc.top,
270                                         TRUE);
271                                 startpt = curpt;
272                         } else
273                                 DrawXORFrame(hwnd, x, y, TRUE);
274                 }
275                 break;
276
277         case WM_NCLBUTTONUP:
278                 /* stop window drag*/
279                 if(dragwp == hwnd) {
280                         dragwp = NULL;
281
282                         if(mwERASEMOVE) {
283                                 /*
284                                  * User stopped moving window, repaint 
285                                  * windows previously queued for painting.
286                                  */
287                                 for(wp=listwp; wp; wp=wp->next)
288                                         if(wp->gotPaintMsg == PAINT_DELAYPAINT)
289                                             wp->gotPaintMsg = PAINT_NEEDSPAINT;
290                         } else {
291                                 POINTSTOPOINT(curpt, lParam);
292                                 x = curpt.x - startpt.x;
293                                 y = curpt.y - startpt.y;
294                                 DrawXORFrame(hwnd, x, y, FALSE);
295                                 GetWindowRect(hwnd, &rc);
296                                 MoveWindow(hwnd, rc.left+x, rc.top+y,
297                                     rc.right-rc.left, rc.bottom-rc.top, TRUE);
298                         }
299                 }
300
301                 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
302                         MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
303                         break;
304                 }
305                 break;
306
307         case WM_NCLBUTTONDBLCLK:
308                 if(wParam == HTVSCROLL || wParam == HTHSCROLL) {
309                         MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam);
310                         break;
311                 }
312
313                 /* maximize/restore processing*/
314                 if(wParam != HTCAPTION)
315                         break;
316
317                 if((hwnd->style & WS_CAPTION) == WS_CAPTION) {
318                         if(hwnd->style & WS_MAXIMIZE) {
319                                 rc = hwnd->restorerc;
320                                 MoveWindow(hwnd, rc.left, rc.top,
321                                         rc.right-rc.left, rc.bottom-rc.top,
322                                         TRUE);
323                                 hwnd->style &= ~WS_MAXIMIZE;
324                         } else {
325                                 hwnd->restorerc = hwnd->winrect;
326                                 GetWindowRect(rootwp, &rc);
327                                 MoveWindow(hwnd, -mwSYSMETRICS_CXFRAME,
328                                         -mwSYSMETRICS_CYFRAME,
329                                         rc.right+2*mwSYSMETRICS_CXFRAME,
330                                         rc.bottom+2*mwSYSMETRICS_CYFRAME, TRUE);
331                                 hwnd->style |= WS_MAXIMIZE;
332                         }
333                 }
334                 break;
335
336         case WM_GETTEXTLENGTH:
337                 /* Get window text length.  This routine requires
338                  * knowledge of the internal window structure
339                  */
340                 return strlen(hwnd->szTitle);
341
342         case WM_GETTEXT:
343                 /* Get window text.  This routine requires
344                  * knowledge of the internal window structure
345                  */
346                 return strzcpy((LPSTR)lParam, hwnd->szTitle, wParam);
347
348         case WM_SETTEXT:
349                 /* Set window text.  This routine requires
350                  * knowledge of the internal window structure.
351                  * Note that setting text doesn't invalidate the window.
352                  */
353                 strzcpy(hwnd->szTitle, (LPSTR)lParam, sizeof(hwnd->szTitle));
354                 return TRUE;
355
356         case WM_CLOSE:
357                 DestroyWindow(hwnd);
358                 if(hwnd == rootwp)
359                         PostQuitMessage(0);
360                 break;
361
362         case WM_ERASEBKGND:
363                 /* erase background with class background brush*/
364                 hbr = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND);
365                 if(!hbr)
366                         return 0;
367                 /* don't exclude update region*/
368                 hdc = GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP);
369                 FillRect(hdc, NULL, hbr);
370                 ReleaseDC(hwnd, hdc);
371                 return 1;
372
373         case WM_PAINT:
374                 /* required to send erasebkgnd for desktop window*/
375                 hdc = BeginPaint(hwnd, &ps);
376
377                 /* draw desktop wallpaper*/
378                 if(hwnd == rootwp && pImageWallpaper) {
379                         GetWindowRect(hwnd, &rc);
380                         DrawDIB(hdc,
381                                 (rc.right-rc.left-pImageWallpaper->width)/2,
382                                 (rc.bottom-rc.top-pImageWallpaper->height)/2,
383                                 pImageWallpaper);
384                 }
385
386                 EndPaint(hwnd, &ps);
387                 break;
388         }
389         return 0;
390 }
391
392 static void
393 GetCloseBoxRect(HWND hwnd, LPRECT lprc)
394 {
395 #define XSIZE_CLOSEBOX  9
396 #define YSIZE_CLOSEBOX  9
397         GetWindowRect(hwnd, lprc);
398         lprc->left = lprc->right - XSIZE_CLOSEBOX - 5;
399         lprc->top = lprc->top + 5;
400         lprc->right = lprc->left + XSIZE_CLOSEBOX;
401         lprc->bottom = lprc->top + YSIZE_CLOSEBOX;
402 }