OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [mwin/] [winuser.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*
2
 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3
 *
4
 * Win32 API upper level window creation, management and msg routines
5
 */
6
#include "windows.h"
7
#include "wintern.h"
8
#include "device.h"
9
#include <stdlib.h>
10
#include <string.h>
11
 
12
#define PAINTONCE       1       /* =1 to queue paint msgs only once*/
13
#define MOUSETEST       1
14
 
15
MWLISTHEAD mwMsgHead;           /* application msg queue*/
16
MWLISTHEAD mwClassHead;         /* register class list*/
17
 
18
int     mwSYSMETRICS_CYCAPTION = 12;    /* Y caption height*/
19
int     mwSYSMETRICS_CXFRAME = 3;       /* width of frame border*/
20
int     mwSYSMETRICS_CYFRAME = 3;       /* height of frame border*/
21
int     mwSYSMETRICS_CXBORDER = 1;      /* width of single border*/
22
int     mwSYSMETRICS_CYBORDER = 1;      /* width of single border*/
23
int     mwSYSMETRICS_CXVSCROLL = 13;    /* width of vertical scrollbar*/
24
int     mwSYSMETRICS_CYHSCROLL = 13;    /* height of horizontal scrollbar*/
25
int     mwSYSMETRICS_CXHSCROLL = 13;    /* width of arrow on horz scrollbar*/
26
int     mwSYSMETRICS_CYVSCROLL = 13;    /* height of arrow on vert scrollbar*/
27
int     mwSYSMETRICS_CXDOUBLECLK = 2;   /* +/- X double click position*/
28
int     mwSYSMETRICS_CYDOUBLECLK = 2;   /* +/- Y double click position*/
29
int     mwpaintSerial = 1;              /* experimental alphablend sequencing*/
30
int     mwpaintNC = 1;                  /* experimental NC paint handling*/
31
BOOL    mwforceNCpaint = FALSE;         /* force NC paint when alpha blending*/
32
 
33
static void MwOffsetChildren(HWND hwnd, int offx, int offy);
34
 
35
LRESULT WINAPI
36
CallWindowProc(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam,
37
        LPARAM lParam)
38
{
39
        return (*lpPrevWndFunc)(hwnd, Msg, wParam, lParam);
40
}
41
 
42
LRESULT WINAPI
43
SendMessage(HWND hwnd, UINT Msg,WPARAM wParam,LPARAM lParam)
44
{
45
        if(hwnd && hwnd->pClass) {
46
                hwnd->paintSerial = mwpaintSerial; /* assign msg sequence #*/
47
                return (*hwnd->pClass->lpfnWndProc)(hwnd, Msg, wParam, lParam);
48
        }
49
        return 0;
50
}
51
 
52
BOOL WINAPI
53
PostMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
54
{
55
        MSG *   pMsg;
56
 
57
#if PAINTONCE
58
        /* don't queue paint msgs, set window paint status instead*/
59
        if(Msg == WM_PAINT) {
60
                hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
61
                return TRUE;
62
        }
63
#endif
64
#if MOUSETEST
65
        /* replace multiple mouse messages with one for better mouse handling*/
66
        if(Msg == WM_MOUSEMOVE) {
67
                PMWLIST p;
68
                for(p=mwMsgHead.head; p; p=p->next) {
69
                        pMsg = GdItemAddr(p, MSG, link);
70
                        if(pMsg->hwnd == hwnd && pMsg->message == Msg) {
71
                                pMsg->wParam = wParam;
72
                                pMsg->lParam = lParam;
73
                                pMsg->time = GetTickCount();
74
                                pMsg->pt.x = cursorx;
75
                                pMsg->pt.y = cursory;
76
                                return TRUE;
77
                        }
78
                }
79
        }
80
#endif
81
        pMsg = GdItemNew(MSG);
82
        if(!pMsg)
83
                return FALSE;
84
        pMsg->hwnd = hwnd;
85
        pMsg->message = Msg;
86
        pMsg->wParam = wParam;
87
        pMsg->lParam = lParam;
88
        pMsg->time = GetTickCount();
89
        pMsg->pt.x = cursorx;
90
        pMsg->pt.y = cursory;
91
        GdListAdd(&mwMsgHead, &pMsg->link);
92
        return TRUE;
93
}
94
 
95
/* currently, we post to the single message queue, regardless of thread*/
96
BOOL WINAPI
97
PostThreadMessage(DWORD dwThreadId, UINT Msg, WPARAM wParam, LPARAM lParam)
98
{
99
        return PostMessage(NULL, Msg, wParam, lParam);
100
}
101
 
102
VOID WINAPI
103
PostQuitMessage(int nExitCode)
104
{
105
        PostMessage(NULL, WM_QUIT, nExitCode, 0L);
106
}
107
 
108
static BOOL
109
chkPaintMsg(HWND wp, LPMSG lpMsg)
110
{
111
                /*
112
                 * Tricky: only repaint window if there
113
                 * isn't a mouse capture (window move) in progress,
114
                 * or the window is the moving window.
115
                 */
116
                if(wp->gotPaintMsg == PAINT_NEEDSPAINT &&
117
                    (!dragwp || dragwp == wp)) {
118
        paint:
119
                        wp->gotPaintMsg = PAINT_PAINTED;
120
                        lpMsg->hwnd = wp;
121
                        lpMsg->message = WM_PAINT;
122
                        lpMsg->wParam = 0;
123
                        lpMsg->lParam = 0;
124
                        lpMsg->time = 0;
125
                        lpMsg->pt.x = cursorx;
126
                        lpMsg->pt.y = cursory;
127
                        return TRUE;
128
                } else if(dragwp && wp->gotPaintMsg == PAINT_NEEDSPAINT) {
129
                        /* All other windows we'll check for
130
                         * event input first, then allow repaint.
131
                         */
132
                        MwSelect();
133
                        if(mwMsgHead.head == NULL)
134
                                goto paint;
135
                }
136
        return FALSE;
137
}
138
 
139
BOOL WINAPI
140
PeekMessage(LPMSG lpMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
141
        UINT wRemoveMsg)
142
{
143
        HWND    wp;
144
        PMSG    pNxtMsg;
145
 
146
        /* check if no messages in queue*/
147
        if(mwMsgHead.head == NULL) {
148
#if PAINTONCE
149
                /* check all windows for pending paint messages*/
150
                for(wp=listwp; wp; wp=wp->next) {
151
                        if(!(wp->style & WS_CHILD)) {
152
                                if(chkPaintMsg(wp, lpMsg))
153
                                        return TRUE;
154
                        }
155
                }
156
                for(wp=listwp; wp; wp=wp->next) {
157
                        if(wp->style & WS_CHILD) {
158
                                if(chkPaintMsg(wp, lpMsg))
159
                                        return TRUE;
160
                        }
161
                }
162
#endif
163
                MwSelect();
164
        }
165
 
166
        if(mwMsgHead.head == NULL)
167
                return FALSE;
168
 
169
        pNxtMsg = (PMSG)mwMsgHead.head;
170
        if(wRemoveMsg & PM_REMOVE)
171
                GdListRemove(&mwMsgHead, &pNxtMsg->link);
172
        *lpMsg = *pNxtMsg;
173
        if(wRemoveMsg & PM_REMOVE)
174
                GdItemFree(pNxtMsg);
175
        return TRUE;
176
}
177
 
178
BOOL WINAPI
179
GetMessage(LPMSG lpMsg,HWND hwnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
180
{
181
        /*
182
         * currently MwSelect() must poll for VT switch reasons,
183
         * so this code will work
184
         */
185
        while(!PeekMessage(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax,PM_REMOVE))
186
                continue;
187
        return lpMsg->message != WM_QUIT;
188
}
189
 
190
BOOL WINAPI
191
TranslateMessage(CONST MSG *lpMsg)
192
{
193
        return FALSE;
194
}
195
 
196
LONG WINAPI
197
DispatchMessage(CONST MSG *lpMsg)
198
{
199
        return SendMessage(lpMsg->hwnd, lpMsg->message, lpMsg->wParam,
200
                lpMsg->lParam);
201
}
202
 
203
/* find the registered window class struct by name*/
204
PWNDCLASS
205
MwFindClassByName(LPCSTR lpClassName)
206
{
207
        PMWLIST         p;
208
        PWNDCLASS       pClass;
209
 
210
        for(p=mwClassHead.head; p; p=p->next) {
211
                pClass = GdItemAddr(p, WNDCLASS, link);
212
                if(strcmpi(pClass->szClassName, lpClassName) == 0)
213
                        return pClass;
214
        }
215
        return NULL;
216
}
217
 
218
ATOM WINAPI
219
RegisterClass(CONST WNDCLASS *lpWndClass)
220
{
221
        PWNDCLASS       pClass;
222
 
223
        /* check if already present*/
224
        pClass = MwFindClassByName(lpWndClass->lpszClassName);
225
        if(pClass)
226
                return 0;
227
 
228
        /* copy class into new struct*/
229
        pClass = GdItemNew(WNDCLASS);
230
        if(!pClass)
231
                return 0;
232
        *pClass = *lpWndClass;
233
        strcpy(pClass->szClassName, lpWndClass->lpszClassName);
234
        GdListAdd(&mwClassHead, &pClass->link);
235
 
236
        return 1;
237
}
238
 
239
BOOL WINAPI
240
UnregisterClass(LPCSTR lpClassName, HINSTANCE hInstance)
241
{
242
        PWNDCLASS       pClass;
243
 
244
        pClass = MwFindClassByName(lpClassName);
245
        if(!pClass)
246
                return FALSE;
247
        GdListRemove(&mwClassHead, &pClass->link);
248
        DeleteObject(pClass->hbrBackground);
249
        GdItemFree(pClass);
250
        return TRUE;
251
}
252
 
253
HWND WINAPI
254
CreateWindowEx(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName,
255
        DWORD dwStyle, int x, int y, int nWidth, int nHeight,
256
        HWND hwndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
257
{
258
        HWND            pwp;            /* parent window */
259
        HWND            wp;             /* new window */
260
        HWND            hwndOwner;
261
        PWNDCLASS       pClass;
262
        CREATESTRUCT    cs;
263
        static int      nextx = 20;
264
        static int      nexty = 20;
265
 
266
        pClass = MwFindClassByName(lpClassName);
267
        if(!pClass)
268
                return NULL;
269
 
270
        if(x == CW_USEDEFAULT || y == CW_USEDEFAULT) {
271
                x = nextx;
272
                nextx += 10;
273
                y = nexty;
274
                nexty += 10;
275
                if(nextx > 200)
276
                        nextx = nexty = 20;
277
        }
278
        if(nWidth == CW_USEDEFAULT || nHeight == CW_USEDEFAULT) {
279
                nWidth = 250;
280
                nHeight = 250;
281
        }
282
 
283
        if(hwndParent == NULL) {
284
                if(dwStyle & WS_CHILD)
285
                        return NULL;
286
                pwp = rootwp;
287
        } else
288
                pwp = hwndParent;
289
 
290
        /* WS_POPUP z-order parent is the root window (passed parent is owner)*/
291
        if(dwStyle & WS_POPUP)
292
                pwp = rootwp;           /* force clip to root, not z-parent*/
293
 
294
        /* window owner is NULL for child windows, else it's the passed parent*/
295
        if(dwStyle & WS_CHILD)
296
                hwndOwner = NULL;
297
        else hwndOwner = hwndParent;
298
 
299
        wp = (HWND)GdItemAlloc(sizeof(struct hwnd) - 1 + pClass->cbWndExtra);
300
        if(!wp)
301
                return NULL;
302
 
303
        /* force all clipping on by default*/
304
        dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
305
 
306
        wp->pClass = pClass;
307
        wp->style = dwStyle;
308
        wp->exstyle = dwExStyle;
309
        wp->parent = pwp;
310
        wp->owner = hwndOwner;
311
        wp->children = NULL;
312
        wp->siblings = pwp->children;
313
        pwp->children = wp;
314
        wp->next = listwp;
315
        listwp = wp;
316
        wp->winrect.left = pwp->clirect.left + x;
317
        wp->winrect.top = pwp->clirect.top + y;
318
        wp->winrect.right = wp->winrect.left + nWidth;
319
        wp->winrect.bottom = wp->winrect.top + nHeight;
320
        wp->cursor = pwp->cursor;
321
        wp->cursor->usecount++;
322
        wp->unmapcount = pwp->unmapcount + 1;
323
        wp->id = (int)hMenu;
324
        wp->gotPaintMsg = PAINT_PAINTED;
325
        strzcpy(wp->szTitle, lpWindowName, sizeof(wp->szTitle));
326
#if UPDATEREGIONS
327
        wp->update = GdAllocRegion();
328
#endif
329
        wp->nextrabytes = pClass->cbWndExtra;
330
 
331
        /* calculate client area*/
332
        MwCalcClientRect(wp);
333
 
334
        cs.lpCreateParams = lpParam;
335
        cs.hInstance = hInstance;
336
        cs.hMenu = hMenu;
337
        cs.hwndParent = hwndParent;
338
        cs.cy = nHeight;
339
        cs.cx = nWidth;
340
        cs.y = y;
341
        cs.x = x;
342
        cs.style = dwStyle;
343
        cs.lpszName = lpWindowName;
344
        cs.lpszClass = lpClassName;
345
        cs.dwExStyle = dwExStyle;
346
 
347
        if(SendMessage(wp, WM_CREATE, 0, (LPARAM)(LPSTR)&cs) == -1) {
348
                MwDestroyWindow(wp, FALSE);
349
                return NULL;
350
        }
351
 
352
        /* send SIZE and MOVE msgs*/
353
        MwSendSizeMove(wp, TRUE, TRUE);
354
 
355
        if(wp->style & WS_VISIBLE) {
356
                MwShowWindow(wp, TRUE);
357
                SetFocus(wp);
358
        }
359
 
360
        return wp;
361
}
362
 
363
BOOL WINAPI
364
DestroyWindow(HWND hwnd)
365
{
366
        MwDestroyWindow(hwnd, TRUE);
367
        return TRUE;
368
}
369
 
370
/*
371
 * Destroy the specified window, and all of its children.
372
 * This is a recursive routine.
373
 */
374
void
375
MwDestroyWindow(HWND hwnd,BOOL bSendMsg)
376
{
377
        HWND    wp = hwnd;
378
        HWND    prevwp;
379
        PMWLIST p;
380
        PMSG    pmsg;
381
 
382
        if (wp == rootwp)
383
                return;
384
 
385
        /*
386
         * Unmap the window.
387
         */
388
        if (wp->unmapcount == 0)
389
                MwHideWindow(wp, FALSE, FALSE);
390
 
391
        if(bSendMsg)
392
                SendMessage(hwnd, WM_DESTROY, 0, 0L);
393
 
394
        /*
395
         * Disable all sendmessages to this window.
396
         */
397
        wp->pClass = NULL;
398
 
399
        /*
400
         * Destroy all children, sending WM_DESTROY messages.
401
         */
402
        while (wp->children)
403
                MwDestroyWindow(wp->children, bSendMsg);
404
 
405
        /*
406
         * Free any cursor associated with the window.
407
         */
408
        if (wp->cursor->usecount-- == 1) {
409
                free(wp->cursor);
410
                wp->cursor = NULL;
411
        }
412
 
413
        /*
414
         * Remove this window from the child list of its parent.
415
         */
416
        prevwp = wp->parent->children;
417
        if (prevwp == wp)
418
                wp->parent->children = wp->siblings;
419
        else {
420
                while (prevwp->siblings != wp)
421
                        prevwp = prevwp->siblings;
422
                prevwp->siblings = wp->siblings;
423
        }
424
        wp->siblings = NULL;
425
 
426
        /*
427
         * Remove this window from the complete list of windows.
428
         */
429
        prevwp = listwp;
430
        if (prevwp == wp)
431
                listwp = wp->next;
432
        else {
433
                while (prevwp->next != wp)
434
                        prevwp = prevwp->next;
435
                prevwp->next = wp->next;
436
        }
437
        wp->next = NULL;
438
 
439
        /*
440
         * Forget various information related to this window.
441
         * Then finally free the structure.
442
         */
443
 
444
        /* Remove all messages from msg queue for this window*/
445
        for(p=mwMsgHead.head; p; ) {
446
                pmsg = GdItemAddr(p, MSG, link);
447
                if(pmsg->hwnd == wp) {
448
                        p = p->next;
449
                        GdListRemove(&mwMsgHead, &pmsg->link);
450
                        GdItemFree(p);
451
                } else
452
                        p = p->next;
453
        }
454
 
455
        /* FIXME: destroy hdc's relating to window?*/
456
 
457
        if (wp == capturewp) {
458
                capturewp = NULL;
459
                MwCheckMouseWindow();
460
        }
461
 
462
        if (wp == MwGetTopWindow(focuswp))
463
                SetFocus(rootwp->children? rootwp->children: rootwp);
464
 
465
        /* destroy private DC*/
466
        if(wp->owndc) {
467
                HDC hdc = wp->owndc;
468
                wp->owndc = NULL;       /* force destroy with ReleaseDC*/
469
                ReleaseDC(wp, hdc);
470
        }
471
#if UPDATEREGIONS
472
        GdDestroyRegion(wp->update);
473
#endif
474
        GdItemFree(wp);
475
}
476
 
477
BOOL WINAPI
478
IsWindow(HWND hwnd)
479
{
480
        HWND    wp;
481
 
482
        for(wp=listwp; wp; wp=wp->next)
483
                if(wp == hwnd)
484
                        return TRUE;
485
        return FALSE;
486
}
487
 
488
BOOL WINAPI
489
ShowWindow(HWND hwnd, int nCmdShow)
490
{
491
        if(!hwnd)
492
                return FALSE;
493
 
494
        /* fix: send show msg*/
495
 
496
        switch(nCmdShow) {
497
        case SW_HIDE:
498
                if (!(hwnd->style & WS_VISIBLE))
499
                        return FALSE;
500
                MwHideWindow(hwnd, TRUE, TRUE);
501
                hwnd->style &= ~WS_VISIBLE;
502
                break;
503
 
504
        default:
505
                if (hwnd->style & WS_VISIBLE)
506
                        return FALSE;
507
                hwnd->style |= WS_VISIBLE;
508
                MwShowWindow(hwnd, TRUE);
509
        }
510
        return TRUE;
511
}
512
 
513
BOOL WINAPI
514
InvalidateRect(HWND hwnd, CONST RECT *lpRect, BOOL bErase)
515
{
516
        /* FIXME: handle bErase*/
517
        if(!hwnd)
518
                MwRedrawScreen();
519
        else {
520
#if UPDATEREGIONS
521
                RECT    rc;
522
 
523
                /* add to update region*/
524
                if(!lpRect)
525
                        GetClientRect(hwnd, &rc);
526
                else rc = *lpRect;
527
                rc.bottom += mwSYSMETRICS_CYCAPTION +
528
                        mwSYSMETRICS_CYFRAME + 1;
529
                rc.right += mwSYSMETRICS_CXFRAME;
530
                MwUnionUpdateRegion(hwnd, rc.left, rc.top,
531
                        rc.right-rc.left, rc.bottom-rc.top, TRUE);
532
 
533
                /* if update region not empty, mark as needing painting*/
534
                if(hwnd->update->numRects != 0)
535
#endif
536
                        if(hwnd->gotPaintMsg == PAINT_PAINTED)
537
                                hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
538
        }
539
        return TRUE;
540
}
541
 
542
#if UPDATEREGIONS
543
/* add region to window update region*/
544
BOOL WINAPI
545
InvalidateRgn(HWND hwnd, HRGN hrgn, BOOL bErase)
546
{
547
        /* FIXME: handle bErase*/
548
        if(hwnd) {
549
                if(!hrgn)
550
                        /* add client area to update region*/
551
                        return InvalidateRect(hwnd, NULL, bErase);
552
 
553
                /* passed region is in client coords, convert to screen*/
554
                GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
555
                        hwnd->clirect.left, hwnd->clirect.top);
556
                GdUnionRegion(hwnd->update, hwnd->update,
557
                        ((MWRGNOBJ *)hrgn)->rgn);
558
                GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
559
                        -hwnd->clirect.left, -hwnd->clirect.top);
560
 
561
                /* if update region not empty, mark as needing painting*/
562
                if(hwnd->update->numRects != 0)
563
                        if(hwnd->gotPaintMsg == PAINT_PAINTED)
564
                                hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
565
        }
566
        return TRUE;
567
}
568
 
569
BOOL WINAPI
570
ValidateRect(HWND hwnd, CONST RECT *lprc)
571
{
572
        RECT    rc;
573
 
574
        if(!hwnd)
575
                MwRedrawScreen();
576
        else {
577
                /* subtract from update region*/
578
                if(!lprc)
579
                        GetClientRect(hwnd, &rc);
580
                else rc = *lprc;
581
                rc.bottom += mwSYSMETRICS_CYCAPTION +
582
                        mwSYSMETRICS_CYFRAME + 1;
583
                rc.right += mwSYSMETRICS_CXFRAME;
584
                MwUnionUpdateRegion(hwnd, rc.left, rc.top,
585
                        rc.right-rc.left, rc.bottom-rc.top, FALSE);
586
 
587
                /* if update region empty, mark window as painted*/
588
                if(hwnd->update->numRects == 0)
589
                        if(hwnd->gotPaintMsg == PAINT_NEEDSPAINT)
590
                                hwnd->gotPaintMsg = PAINT_PAINTED;
591
        }
592
        return TRUE;
593
}
594
 
595
/* remove region from window update region*/
596
BOOL WINAPI
597
ValidateRgn(HWND hwnd, HRGN hrgn)
598
{
599
        if(hwnd) {
600
                if(!hrgn)
601
                        /* remove client area from update region*/
602
                        return ValidateRect(hwnd, NULL);
603
 
604
                /* passed region is in client coords, convert to screen*/
605
                GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
606
                        hwnd->clirect.left, hwnd->clirect.top);
607
                GdSubtractRegion(hwnd->update, hwnd->update,
608
                        ((MWRGNOBJ *)hrgn)->rgn);
609
                GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
610
                        -hwnd->clirect.left, -hwnd->clirect.top);
611
 
612
                /* if update region empty, mark window as painted*/
613
                if(hwnd->update->numRects == 0)
614
                        if(hwnd->gotPaintMsg == PAINT_NEEDSPAINT)
615
                                hwnd->gotPaintMsg = PAINT_PAINTED;
616
        }
617
        return TRUE;
618
}
619
#endif /* UPDATEREGIONS*/
620
 
621
BOOL WINAPI
622
UpdateWindow(HWND hwnd)
623
{
624
#if PAINTONCE
625
        if(hwnd && hwnd->gotPaintMsg == PAINT_NEEDSPAINT) {
626
                SendMessage(hwnd, WM_PAINT, 0, 0L);
627
                hwnd->gotPaintMsg = PAINT_PAINTED;
628
                return TRUE;
629
        }
630
        return FALSE;
631
#else
632
        /* fix: remove other paint messages from queue*/
633
        SendMessage(hwnd, WM_PAINT, 0, 0L);
634
        return TRUE;
635
#endif
636
}
637
 
638
HWND WINAPI
639
GetFocus(VOID)
640
{
641
        return focuswp;
642
}
643
 
644
HWND WINAPI
645
SetFocus(HWND hwnd)
646
{
647
        HWND    oldfocus;
648
        HWND    top, top2;
649
 
650
        /* if NULL or hidden, set focus to desktop*/
651
        if(!hwnd || hwnd->unmapcount)
652
                hwnd = rootwp;
653
 
654
        if(hwnd == focuswp)
655
                return focuswp;
656
 
657
        oldfocus = focuswp;
658
        SendMessage(oldfocus, WM_KILLFOCUS, (WPARAM)hwnd, 0L);
659
        focuswp = hwnd;
660
        SendMessage(focuswp, WM_SETFOCUS, (WPARAM)oldfocus, 0L);
661
 
662
        /* FIXME SetActiveWindow() here?*/
663
        top = MwGetTopWindow(oldfocus);
664
        top2 = MwGetTopWindow(focuswp);
665
        if(top2 != top) {
666
                /* send deactivate*/
667
                SendMessage(top, WM_ACTIVATE, (WPARAM)MAKELONG(WA_INACTIVE, 0),
668
                        (LPARAM)top2);
669
                /* repaint captions*/
670
                MwPaintNCArea(top);
671
#if 0
672
                /* Make sure that caption area is fully invalidated,
673
                 * as repaint will be in active color.
674
                 * FIXME: this doesn't work; breaks terminal emulator
675
                 * on focus out/in
676
                 */
677
                MwUnionUpdateRegion(top2, 0, 0,
678
                        top2->winrect.right-top2->winrect.left,
679
                        mwSYSMETRICS_CYCAPTION+4, TRUE);
680
#endif
681
                /* send deactivate*/
682
                SendMessage(top, WM_ACTIVATE, (WPARAM)MAKELONG(WA_ACTIVE, 0),
683
                        (LPARAM)top);
684
                MwPaintNCArea(top2);
685
        }
686
 
687
        return oldfocus;
688
}
689
 
690
/* the foreground window is the top level window at the top of the z order*/
691
/* setting the foreground window sets focus and moves window to top*/
692
BOOL WINAPI
693
SetForegroundWindow(HWND hwnd)
694
{
695
        /* activate (set focus to) specified window*/
696
        SetFocus(hwnd);
697
 
698
        /* raise top level parent to top of z order*/
699
        SetWindowPos(MwGetTopWindow(hwnd), HWND_TOP, 0, 0, 0, 0,
700
                SWP_NOMOVE|SWP_NOSIZE);
701
 
702
        return TRUE;
703
}
704
 
705
/* our SetActiveWindow is the same as SetFocus, no z order change*/
706
HWND WINAPI
707
SetActiveWindow(HWND hwnd)
708
{
709
        HWND    oldActive;
710
 
711
        oldActive = GetActiveWindow();
712
        SetFocus(hwnd);          /* WM_ACTIVATE sent by SetFocus*/
713
        return oldActive;
714
}
715
 
716
/* The active window is the first non-child ancestor of focus window*/
717
HWND WINAPI
718
GetActiveWindow(VOID)
719
{
720
        return MwGetTopWindow(focuswp);
721
}
722
 
723
/* activate the top level window associated with window*/
724
BOOL WINAPI
725
BringWindowToTop(HWND hwnd)
726
{
727
        return SetForegroundWindow(hwnd);
728
}
729
 
730
HWND WINAPI
731
GetDesktopWindow(VOID)
732
{
733
        return rootwp;
734
}
735
 
736
HWND
737
MwGetTopWindow(HWND hwnd)
738
{
739
        while(hwnd->style & WS_CHILD)
740
                hwnd = hwnd->parent;
741
        return hwnd;
742
}
743
 
744
HWND WINAPI
745
GetParent(HWND hwnd)
746
{
747
        /* top level windows return NULL instead of rootwp*/
748
        if(!hwnd || !(hwnd->style & (WS_POPUP|WS_CHILD)))
749
                return NULL;            /* toplevel window*/
750
        if(hwnd->style & WS_POPUP)
751
                return hwnd->owner;     /* popup window*/
752
        return hwnd->parent;            /* child window*/
753
}
754
 
755
BOOL WINAPI
756
EnableWindow(HWND hwnd, BOOL bEnable)
757
{
758
        if(bEnable && (hwnd->style & WS_DISABLED)) {
759
                /* enable window*/
760
                hwnd->style &= ~WS_DISABLED;
761
                SendMessage(hwnd, WM_ENABLE, TRUE, 0L);
762
                return TRUE;
763
        }
764
        if(!bEnable && !(hwnd->style & WS_DISABLED)) {
765
                /* disable window*/
766
                hwnd->style |= WS_DISABLED;
767
                /* FIXME: handle lost focus for child window of hwnd*/
768
                /* FIXME: handle lost focus for capture window*/
769
                if(hwnd == focuswp)
770
                        SetFocus(NULL);
771
                SendMessage(hwnd, WM_ENABLE, FALSE, 0L);
772
                return FALSE;
773
        }
774
        return (hwnd->style & WS_DISABLED) != 0;
775
}
776
 
777
/* calc window rect from client rect in screen coords*/
778
BOOL WINAPI
779
AdjustWindowRectEx(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
780
{
781
        int     yoffset;
782
 
783
        if(dwStyle & WS_BORDER) {
784
                if((dwStyle & WS_CAPTION) == WS_CAPTION) {
785
                        InflateRect(lpRect, mwSYSMETRICS_CXFRAME,
786
                                mwSYSMETRICS_CYFRAME);
787
                        yoffset = mwSYSMETRICS_CYCAPTION + 1;
788
                        lpRect->top -= yoffset;
789
                        lpRect->bottom -= yoffset;
790
                } else
791
                        InflateRect(lpRect, 1, 1);
792
 
793
                /* make sure upper left is on screen*/
794
                if(lpRect->left < 0) {
795
                        lpRect->right -= lpRect->left;
796
                        lpRect->left = 0;
797
                }
798
                if(lpRect->top < 0) {
799
                        lpRect->bottom -= lpRect->top;
800
                        lpRect->top = 0;
801
                }
802
        }
803
        return TRUE;
804
}
805
 
806
/* set the client rect for a window from the window position*/
807
void
808
MwCalcClientRect(HWND hwnd)
809
{
810
        NCCALCSIZE_PARAMS       nccs;
811
 
812
        /* set first rectangle to window rect*/
813
        nccs.rgrc[0] = hwnd->winrect;
814
        SendMessage(hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)(LPSTR)&nccs);
815
        hwnd->clirect = nccs.rgrc[0];
816
 
817
        /* adjust client area if scrollbar(s) visible*/
818
        MwAdjustNCScrollbars(hwnd);
819
}
820
 
821
BOOL WINAPI
822
GetClientRect(HWND hwnd, LPRECT lpRect)
823
{
824
        if(!hwnd || !lpRect)
825
                return FALSE;
826
 
827
        /* convert client area rect from screen coordinates*/
828
        lpRect->left = 0;
829
        lpRect->top = 0;
830
        lpRect->right = hwnd->clirect.right - hwnd->clirect.left;
831
        lpRect->bottom = hwnd->clirect.bottom - hwnd->clirect.top;
832
        return TRUE;
833
}
834
 
835
BOOL WINAPI
836
GetWindowRect(HWND hwnd, LPRECT lpRect)
837
{
838
        if(!hwnd || !lpRect)
839
                return FALSE;
840
 
841
        /* window rect is already in screen coordinates*/
842
        *lpRect = hwnd->winrect;
843
        return TRUE;
844
}
845
 
846
BOOL WINAPI
847
ClientToScreen(HWND hwnd, LPPOINT lpPoint)
848
{
849
        if(!hwnd || !lpPoint)
850
                return FALSE;
851
        MapWindowPoints(hwnd, NULL, lpPoint, 1);
852
        return TRUE;
853
}
854
 
855
BOOL WINAPI
856
ScreenToClient(HWND hwnd, LPPOINT lpPoint)
857
{
858
        if(!hwnd || !lpPoint)
859
                return FALSE;
860
        MapWindowPoints(NULL, hwnd, lpPoint, 1);
861
        return TRUE;
862
}
863
 
864
int WINAPI
865
MapWindowPoints(HWND hwndFrom, HWND hwndTo, LPPOINT lpPoints, UINT cPoints)
866
{
867
        MWCOORD offx = 0;
868
        MWCOORD offy = 0;
869
 
870
        /* map src window to screen coords*/
871
        if(hwndFrom) {
872
                offx = hwndFrom->clirect.left;
873
                offy = hwndFrom->clirect.top;
874
        }
875
 
876
        /* map to dst window client coords*/
877
        if(hwndTo) {
878
                offx -= hwndTo->clirect.left;
879
                offy -= hwndTo->clirect.top;
880
        }
881
 
882
        /* adjust points*/
883
        while(cPoints--) {
884
                lpPoints->x += offx;
885
                lpPoints->y += offy;
886
                ++lpPoints;
887
        }
888
        return (int)MAKELONG(offx, offy);
889
}
890
 
891
BOOL WINAPI
892
SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom)
893
{
894
        lprc->left = xLeft;
895
        lprc->top = yTop;
896
        lprc->right = xRight;
897
        lprc->bottom = yBottom;
898
        return TRUE;
899
}
900
 
901
BOOL WINAPI
902
SetRectEmpty(LPRECT lprc)
903
{
904
        lprc->left = lprc->right = lprc->top = lprc->bottom = 0;
905
        return TRUE;
906
}
907
 
908
BOOL WINAPI
909
CopyRect(LPRECT lprcDst, CONST RECT *lprcSrc)
910
{
911
        *lprcDst = *lprcSrc;
912
        return TRUE;
913
}
914
 
915
BOOL WINAPI
916
IsRectEmpty(CONST RECT *lprc)
917
{
918
        /* FIXME: should this just be ==, not <= ?*/
919
        /*return lprc->left == lprc->right || lprc->top == lprc->bottom;*/
920
        return lprc->right <= lprc->left || lprc->bottom <= lprc->top;
921
}
922
 
923
BOOL WINAPI
924
InflateRect(LPRECT lprc, int dx, int dy)
925
{
926
        lprc->left -= dx;
927
        lprc->top -= dy;
928
        lprc->right += dx;
929
        lprc->bottom += dy;
930
        return TRUE;
931
}
932
 
933
BOOL WINAPI
934
OffsetRect(LPRECT lprc, int dx, int dy)
935
{
936
        lprc->left += dx;
937
        lprc->right += dx;
938
        lprc->top += dy;
939
        lprc->bottom += dy;
940
        return TRUE;
941
}
942
 
943
/* PtInRect is #defined to MwPTINRECT because of bcc struct passing bug*/
944
BOOL WINAPI
945
MwPTINRECT(CONST RECT *lprc, POINT pt)
946
{
947
        return (pt.x >= lprc->left && pt.x < lprc->right &&
948
                pt.y >= lprc->top && pt.y < lprc->bottom);
949
}
950
 
951
LONG WINAPI
952
GetWindowLong(HWND hwnd, int nIndex)
953
{
954
        switch(nIndex) {
955
        case GWL_WNDPROC:
956
                return (LONG)hwnd->pClass->lpfnWndProc;
957
        case GWL_HINSTANCE:
958
                /* nyi*/
959
                break;
960
        case GWL_HWNDPARENT:
961
                return (LONG)hwnd->parent;
962
        case GWL_ID:
963
                return hwnd->id;
964
        case GWL_STYLE:
965
                return hwnd->style;
966
        case GWL_EXSTYLE:
967
                return hwnd->exstyle;
968
        case GWL_USERDATA:
969
                return hwnd->userdata;
970
        default:
971
                if(nIndex+3 < hwnd->nextrabytes)
972
                        return *(LONG *)&hwnd->extrabytes[nIndex];
973
        }
974
        return 0;
975
}
976
 
977
LONG WINAPI
978
SetWindowLong(HWND hwnd, int nIndex, LONG lNewLong)
979
{
980
        LONG    oldval = 0;
981
 
982
        switch(nIndex) {
983
        case GWL_USERDATA:
984
                oldval = hwnd->userdata;
985
                hwnd->userdata = lNewLong;
986
                break;
987
        case GWL_WNDPROC:
988
                oldval = (LONG)hwnd->pClass->lpfnWndProc;
989
                hwnd->pClass->lpfnWndProc = (WNDPROC)lNewLong;
990
                break;
991
        case GWL_HINSTANCE:
992
        case GWL_HWNDPARENT:
993
        case GWL_ID:
994
        case GWL_STYLE:
995
        case GWL_EXSTYLE:
996
                /* nyi*/
997
                break;
998
        default:
999
                if(nIndex+3 < hwnd->nextrabytes) {
1000
                        oldval = GetWindowLong(hwnd, nIndex);
1001
                        *(LONG *)&hwnd->extrabytes[nIndex] = lNewLong;
1002
                }
1003
                break;
1004
        }
1005
        return oldval;
1006
}
1007
 
1008
WORD WINAPI
1009
GetWindowWord(HWND hwnd, int nIndex)
1010
{
1011
        if(nIndex+1 < hwnd->nextrabytes)
1012
                return *(WORD *)&hwnd->extrabytes[nIndex];
1013
        return 0;
1014
}
1015
 
1016
WORD WINAPI
1017
SetWindowWord(HWND hwnd, int nIndex, WORD wNewWord)
1018
{
1019
        WORD    oldval = 0;
1020
 
1021
        if(nIndex+1 < hwnd->nextrabytes) {
1022
                oldval = GetWindowWord(hwnd, nIndex);
1023
                *(WORD *)&hwnd->extrabytes[nIndex] = wNewWord;
1024
        }
1025
        return oldval;
1026
}
1027
 
1028
DWORD WINAPI
1029
GetClassLong(HWND hwnd, int nIndex)
1030
{
1031
        switch(nIndex) {
1032
        case GCL_HBRBACKGROUND:
1033
                return (DWORD)hwnd->pClass->hbrBackground;
1034
        case GCL_CBWNDEXTRA:
1035
                return (DWORD)hwnd->pClass->cbWndExtra;
1036
        }
1037
        return 0;
1038
}
1039
 
1040
int WINAPI
1041
GetWindowTextLength(HWND hwnd)
1042
{
1043
        return SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0L);
1044
}
1045
 
1046
int WINAPI
1047
GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
1048
{
1049
        return SendMessage(hwnd, WM_GETTEXT, nMaxCount,(LPARAM)(LPSTR)lpString);
1050
}
1051
 
1052
BOOL WINAPI
1053
SetWindowText(HWND hwnd, LPCSTR lpString)
1054
{
1055
        return SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)(LPCSTR)lpString);
1056
}
1057
 
1058
/* Recursively offset all children of passed window*/
1059
static void
1060
MwOffsetChildren(HWND hwnd, int offx, int offy)
1061
{
1062
        HWND    cp;
1063
 
1064
        /* offset all child windows for move*/
1065
        for(cp=hwnd->children; cp; cp=cp->siblings) {
1066
 
1067
                /* offset window and client area rects*/
1068
                OffsetRect(&cp->winrect, offx, offy);
1069
                OffsetRect(&cp->clirect, offx, offy);
1070
 
1071
                /* offset scrollbar NC hittest rects*/
1072
                if(!IsRectEmpty(&cp->vscroll.rc))
1073
                        OffsetRect(&cp->vscroll.rc, offx, offy);
1074
                if(!IsRectEmpty(&cp->hscroll.rc))
1075
                        OffsetRect(&cp->hscroll.rc, offx, offy);
1076
                MwOffsetChildren(cp, offx, offy);
1077
        }
1078
}
1079
 
1080
BOOL
1081
SetWindowPos(HWND hwnd, HWND hwndInsertAfter, int x, int y, int cx, int cy,
1082
        UINT fuFlags)
1083
{
1084
        int             hidden;
1085
        BOOL            bMove, bSize, bZorder;
1086
        MWCOORD         offx = 0, offy = 0;       /* = 0 for bad gcc warning*/
1087
        WINDOWPOS       winpos;
1088
 
1089
        if(!hwnd || hwnd == rootwp || cx < 0 || cy < 0)
1090
                return FALSE;
1091
 
1092
        /* FIXME SWP_NOACTIVATE*/
1093
 
1094
        if((fuFlags & SWP_SHOWWINDOW))
1095
                return ShowWindow(hwnd, SW_SHOW);
1096
 
1097
        if((fuFlags & SWP_HIDEWINDOW))
1098
                return ShowWindow(hwnd, SW_HIDE);
1099
 
1100
        /* move is relative to parent's client rect for child windows*/
1101
        if(hwnd->style & WS_CHILD) {
1102
                x += hwnd->parent->clirect.left;
1103
                y += hwnd->parent->clirect.top;
1104
        } else {
1105
                x += hwnd->parent->winrect.left;
1106
                y += hwnd->parent->winrect.top;
1107
        }
1108
 
1109
        bMove = !(fuFlags & SWP_NOMOVE) &&
1110
                        (hwnd->winrect.left != x || hwnd->winrect.top != y);
1111
        bSize = !(fuFlags & SWP_NOSIZE) &&
1112
                        ((hwnd->winrect.right - hwnd->winrect.left) != cx ||
1113
                        (hwnd->winrect.bottom - hwnd->winrect.top) != cy);
1114
        bZorder = !(fuFlags & SWP_NOZORDER);
1115
        if(!bMove && !bSize && !bZorder)
1116
                return TRUE;
1117
 
1118
        /* could optimize to not require redraw when possible*/
1119
        hidden = hwnd->unmapcount || (fuFlags & SWP_NOREDRAW);
1120
 
1121
        if(bZorder) {
1122
                switch((int)hwndInsertAfter) {
1123
                case (int)HWND_TOP:
1124
                        MwRaiseWindow(hwnd);
1125
                        break;
1126
                case (int)HWND_BOTTOM:
1127
                        MwLowerWindow(hwnd);
1128
                        break;
1129
                default:
1130
                        /* FIXME for non top/bottom zorder*/
1131
                        break;
1132
                }
1133
        } else {
1134
                if(!hidden)
1135
                        MwHideWindow(hwnd, FALSE, FALSE);
1136
        }
1137
 
1138
        if(bMove) {
1139
                offx = x - hwnd->winrect.left;
1140
                offy = y - hwnd->winrect.top;
1141
        }
1142
        if(bMove || bSize) {
1143
                hwnd->winrect.left = x;
1144
                hwnd->winrect.top = y;
1145
                hwnd->winrect.right = x + cx;
1146
                hwnd->winrect.bottom = y + cy;
1147
        }
1148
        if(bMove)
1149
                MwOffsetChildren(hwnd, offx, offy);
1150
 
1151
        if(bMove || bSize) {
1152
                MwCalcClientRect(hwnd);
1153
 
1154
                /* send windowposchanged message*/
1155
                /* FIXME: move WM_MOVE, WM_SIZE to defwndproc*/
1156
                winpos.hwnd = hwnd;
1157
                winpos.hwndInsertAfter = hwndInsertAfter;
1158
                winpos.x = x;
1159
                winpos.y = y;
1160
                winpos.cx = cx;
1161
                winpos.cy = cy;
1162
                winpos.flags = fuFlags;
1163
                SendMessage(hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos);
1164
 
1165
                MwSendSizeMove(hwnd, bSize, bMove);
1166
        }
1167
 
1168
        ++mwpaintSerial;        /* increment paint serial # for alphablending*/
1169
        ++mwpaintNC;            /* increment paint serial # for NC painting*/
1170
        if(!bZorder && !hidden)
1171
                MwShowWindow(hwnd, FALSE);
1172
 
1173
        return TRUE;
1174
}
1175
 
1176
BOOL WINAPI
1177
MoveWindow(HWND hwnd, int x, int y, int nWidth, int nHeight, BOOL bRepaint)
1178
{
1179
        UINT    flags = SWP_NOZORDER | SWP_NOACTIVATE;
1180
 
1181
        if(!bRepaint)
1182
                flags |= SWP_NOREDRAW;
1183
        return SetWindowPos(hwnd, 0, x, y, nWidth, nHeight, flags);
1184
}
1185
 
1186
void
1187
MwSendSizeMove(HWND hwnd, BOOL bSize, BOOL bMove)
1188
{
1189
        DWORD   dwStyle;
1190
        RECT    rc;
1191
 
1192
        if(bSize) {
1193
                GetClientRect(hwnd, &rc);
1194
                SendMessage(hwnd, WM_SIZE, SIZE_RESTORED,
1195
                        MAKELONG(rc.right, rc.bottom));
1196
        }
1197
        if(bMove) {
1198
                dwStyle = GetWindowLong(hwnd, GWL_STYLE);
1199
                GetWindowRect(hwnd, &rc);
1200
                /* return parent coords for child windows*/
1201
                if(dwStyle & WS_CHILD)
1202
                        ScreenToClient(hwnd->parent, (LPPOINT)&rc.left);
1203
                SendMessage(hwnd, WM_MOVE, 0, MAKELONG(rc.left, rc.top));
1204
        }
1205
}
1206
 
1207
/*
1208
 * Specify a cursor for a window.
1209
 * This cursor will only be used within that window, and by default
1210
 * for its new children.  If the cursor is currently within this
1211
 * window, it will be changed to the new one immediately.
1212
 */
1213
void
1214
MwSetCursor(HWND wp, PMWCURSOR pcursor)
1215
{
1216
        HCURSOR cp;
1217
        int     bytes;
1218
 
1219
        if(!wp || !pcursor)
1220
                return;
1221
 
1222
        bytes = MWIMAGE_SIZE(pcursor->width,pcursor->height)
1223
                * sizeof(MWIMAGEBITS);
1224
 
1225
        /*
1226
         * See if the window is using a shared cursor definition.
1227
         * If so, then allocate a new private one, otherwise reuse it.
1228
         */
1229
        cp = wp->cursor;
1230
        if (!cp || cp->usecount-- > 1) {
1231
                cp = GdItemNew(struct hcursor);
1232
                if(!cp)
1233
                        return;
1234
        }
1235
 
1236
        cp->usecount = 1;
1237
        cp->cursor.width = pcursor->width;
1238
        cp->cursor.height = pcursor->height;
1239
        cp->cursor.hotx = pcursor->hotx;
1240
        cp->cursor.hoty = pcursor->hoty;
1241
        cp->cursor.fgcolor = pcursor->fgcolor;
1242
        cp->cursor.bgcolor = pcursor->bgcolor;
1243
        memcpy(cp->cursor.image, pcursor->image, bytes);
1244
        memcpy(cp->cursor.mask, pcursor->mask, bytes);
1245
        wp->cursor = cp;
1246
 
1247
        /*
1248
         * If this was the current cursor, then draw the new one.
1249
         */
1250
        if (cp == curcursor || curcursor == NULL) {
1251
                GdMoveCursor(cursorx - cp->cursor.hotx,
1252
                        cursory - cp->cursor.hoty);
1253
                GdSetCursor(&cp->cursor);
1254
        }
1255
}
1256
 
1257
BOOL WINAPI
1258
GetCursorPos(LPPOINT lpPoint)
1259
{
1260
        MWCOORD x, y;
1261
 
1262
        if(lpPoint) {
1263
                GdGetCursorPos(&x, &y);
1264
                lpPoint->x = x;
1265
                lpPoint->y = y;
1266
                return TRUE;
1267
        }
1268
        return FALSE;
1269
}
1270
 
1271
HWND WINAPI
1272
GetCapture(VOID)
1273
{
1274
        return capturewp;
1275
}
1276
 
1277
HWND WINAPI
1278
SetCapture(HWND hwnd)
1279
{
1280
        HWND    oldCapture = capturewp;
1281
 
1282
        capturewp = hwnd;
1283
        MwCheckMouseWindow();
1284
        return oldCapture;
1285
}
1286
 
1287
BOOL WINAPI
1288
ReleaseCapture(VOID)
1289
{
1290
        capturewp = NULL;
1291
        MwCheckMouseWindow();
1292
        return TRUE;
1293
}
1294
 
1295
struct timer {                  /* private timer structure*/
1296
        HWND    hwnd;           /* window associated with timer, NULL if none*/
1297
        UINT    idTimer;        /* id for timer*/
1298
        UINT    uTimeout;       /* timeout value, in msecs*/
1299
        DWORD   dwClockExpires; /* GetTickCount timer expiration value*/
1300
        TIMERPROC lpTimerFunc;  /* callback function*/
1301
};
1302
 
1303
static struct timer timer;      /* single global timer FIXME*/
1304
 
1305
UINT WINAPI
1306
SetTimer(HWND hwnd, UINT idTimer, UINT uTimeout, TIMERPROC lpTimerFunc)
1307
{
1308
        static UINT nextID = 0;  /* next ID when hwnd is NULL*/
1309
 
1310
        /* assign timer id based on valid window handle*/
1311
        timer.hwnd = hwnd;
1312
        timer.idTimer = hwnd? idTimer: ++nextID;
1313
        timer.uTimeout = uTimeout;
1314
        timer.dwClockExpires = GetTickCount() + uTimeout;
1315
        timer.lpTimerFunc = lpTimerFunc;
1316
 
1317
        return timer.idTimer;
1318
}
1319
 
1320
BOOL WINAPI
1321
KillTimer(HWND hwnd, UINT idTimer)
1322
{
1323
        if(timer.hwnd == hwnd && timer.idTimer == idTimer) {
1324
                timer.uTimeout = 0;
1325
                return TRUE;
1326
        }
1327
        return FALSE;
1328
}
1329
 
1330
/*
1331
 * Return the next timeout value in msecs
1332
 */
1333
UINT
1334
MwGetNextTimeoutValue(void)
1335
{
1336
        int     timeout;
1337
 
1338
        if(timer.uTimeout) {
1339
                timeout = timer.dwClockExpires - GetTickCount();
1340
                if(timeout > 0)
1341
                        return timeout;
1342
        }
1343
        return 0;
1344
}
1345
 
1346
/*
1347
 * Check if any timers have expired by looking at current system ticks
1348
 */
1349
void
1350
MwHandleTimers(void)
1351
{
1352
        int     timeout;
1353
        DWORD   dwTime;
1354
 
1355
        /* check if timer running*/
1356
        if(timer.uTimeout == 0)
1357
                return;
1358
 
1359
        /* determine if timer expired*/
1360
        dwTime = GetTickCount();
1361
        timeout = timer.dwClockExpires - dwTime;
1362
        if(timeout > 0)
1363
                return;
1364
 
1365
        /* call timer function or post timer message*/
1366
        if(timer.lpTimerFunc)
1367
                timer.lpTimerFunc(timer.hwnd, WM_TIMER, timer.idTimer, dwTime);
1368
        else PostMessage(timer.hwnd, WM_TIMER, timer.idTimer, 0);
1369
 
1370
        /* reset timer*/
1371
        timer.dwClockExpires = dwTime + timer.uTimeout;
1372
}
1373
 
1374
int WINAPI
1375
GetSystemMetrics(int nIndex)
1376
{
1377
        switch(nIndex) {
1378
        case SM_CXSCREEN:
1379
                return scrdev.xvirtres;
1380
        case SM_CYSCREEN:
1381
                return scrdev.yvirtres;
1382
        case SM_CXVSCROLL:
1383
                return mwSYSMETRICS_CXVSCROLL;
1384
        case SM_CYHSCROLL:
1385
                return mwSYSMETRICS_CYHSCROLL;
1386
        case SM_CYCAPTION:
1387
                /* + 1 for line under caption*/
1388
                return mwSYSMETRICS_CYCAPTION + 1;
1389
        case SM_CXBORDER:
1390
                return mwSYSMETRICS_CXBORDER;
1391
        case SM_CYBORDER:
1392
                return mwSYSMETRICS_CYBORDER;
1393
        case SM_CYMENU:
1394
                break;          /* FIXME: 19 when menubars work*/
1395
        case SM_CYVSCROLL:
1396
                return mwSYSMETRICS_CYVSCROLL;
1397
        case SM_CXHSCROLL:
1398
                return mwSYSMETRICS_CXHSCROLL;
1399
        case SM_CXFRAME:
1400
        case SM_CXDLGFRAME:
1401
                return mwSYSMETRICS_CXFRAME;
1402
        case SM_CYFRAME:
1403
        case SM_CYDLGFRAME:
1404
                return mwSYSMETRICS_CYFRAME;
1405
        }
1406
        return 0;
1407
}
1408
 
1409
HWND WINAPI
1410
GetDlgItem(HWND hDlg, int nIDDlgItem)
1411
{
1412
        HWND    wp;
1413
 
1414
        if(hDlg) {
1415
                for(wp=hDlg->children; wp; wp=wp->siblings)
1416
                        if(wp->id == nIDDlgItem)
1417
                                return wp;
1418
        }
1419
        return 0;
1420
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.