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

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [mwin/] [winevent.c] - Blame information for rev 673

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
3
 * Copyright (c) 1991 David I. Bell
4
 * Permission is granted to use, distribute, or modify this source,
5
 * provided that this copyright notice remains intact.
6
 *
7
 * Graphics server event routines for windows.
8
 */
9
#include "windows.h"
10
#include "wintern.h"
11
#include "device.h"
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <string.h>
15
 
16
#if !(DOS_TURBOC | DOS_QUICKC | _MINIX | VXWORKS)
17
static int
18
abs(int n)
19
{
20
        return n >= 0? n: -n;
21
}
22
#endif
23
 
24
/*
25
 * Update mouse status and issue events on it if necessary.
26
 * This function doesn't block, but is normally only called when
27
 * there is known to be some data waiting to be read from the mouse.
28
 */
29
BOOL
30
MwCheckMouseEvent(void)
31
{
32
        MWCOORD         rootx;          /* latest mouse x position */
33
        MWCOORD         rooty;          /* latest mouse y position */
34
        int             newbuttons;     /* latest buttons */
35
        int             mousestatus;    /* latest mouse status */
36
 
37
        /* Read the latest mouse status: */
38
        mousestatus = GdReadMouse(&rootx, &rooty, &newbuttons);
39
        if(mousestatus < 0) {
40
                /*MwError(GR_ERROR_MOUSE_ERROR, 0);*/
41
                return FALSE;
42
        } else if(mousestatus) {        /* Deliver events as appropriate: */
43
                MwHandleMouseStatus(rootx, rooty, newbuttons);
44
                return TRUE;
45
        }
46
        return FALSE;
47
}
48
 
49
/*
50
 * Update keyboard status and issue events on it if necessary.
51
 * This function doesn't block, but is normally only called when
52
 * there is known to be some data waiting to be read from the keyboard.
53
 */
54
BOOL
55
MwCheckKeyboardEvent(void)
56
{
57
        MWKEY           mwkey;          /* latest character */
58
        MWKEYMOD        modifiers;      /* latest modifiers */
59
        MWSCANCODE      scancode;
60
        int             keystatus;      /* latest keyboard status */
61
 
62
        /* Read the latest keyboard status: */
63
        keystatus = GdReadKeyboard(&mwkey, &modifiers, &scancode);
64
        if(keystatus < 0) {
65
                if(keystatus == -2)     /* special case for ESC pressed*/
66
                        MwTerminate();
67
                /*MwError(GR_ERROR_KEYBOARD_ERROR, 0);*/
68
                return FALSE;
69
        } else if(keystatus) {          /* Deliver events as appropriate: */
70
                switch (mwkey) {
71
                case MWKEY_QUIT:
72
                        MwTerminate();
73
                        /* no return*/
74
                case MWKEY_REDRAW:
75
                        MwRedrawScreen();
76
                        break;
77
                case MWKEY_PRINT:
78
                        if (keystatus == 1)
79
                                GdCaptureScreen("screen.bmp");
80
                        break;
81
                }
82
                MwDeliverKeyboardEvent(mwkey, modifiers, scancode,
83
                        keystatus==1? TRUE: FALSE);
84
                return TRUE;
85
        }
86
        return FALSE;
87
}
88
 
89
/*
90
 * Handle all mouse events.  These are mouse enter, mouse exit, mouse
91
 * motion, mouse position, button down, and button up.  This also moves
92
 * the cursor to the new mouse position and changes it shape if needed.
93
 */
94
void
95
MwHandleMouseStatus(MWCOORD newx, MWCOORD newy, int newbuttons)
96
{
97
        int             changebuttons;  /* buttons that have changed */
98
        MWKEYMOD        modifiers;      /* latest modifiers */
99
        static int curbuttons;
100
 
101
        GdGetModifierInfo(NULL, &modifiers); /* Read kbd modifiers */
102
 
103
        /*
104
         * First, if the mouse has moved, then position the cursor to the
105
         * new location, which will send mouse enter, mouse exit, focus in,
106
         * and focus out events if needed.  Check here for mouse motion and
107
         * mouse position events.
108
         */
109
        if (newx != cursorx || newy != cursory) {
110
                MwMoveCursor(newx, newy);
111
                MwDeliverMouseEvent(newbuttons, 0, modifiers);
112
        }
113
 
114
        /*
115
         * Next, generate a button up event if any buttons have been released.
116
         */
117
        changebuttons = (curbuttons & ~newbuttons);
118
        if (changebuttons)
119
                MwDeliverMouseEvent(newbuttons, changebuttons, modifiers);
120
 
121
        /*
122
         * Finally, generate a button down event if any buttons have been
123
         * pressed.
124
         */
125
        changebuttons = (~curbuttons & newbuttons);
126
        if (changebuttons)
127
                MwDeliverMouseEvent(newbuttons, changebuttons, modifiers);
128
 
129
        curbuttons = newbuttons;
130
}
131
 
132
/*
133
 * Translate and deliver hardware mouse message to proper window.
134
 */
135
void
136
MwTranslateMouseMessage(HWND hwnd,UINT msg,int hittest)
137
{
138
        POINT           pt;
139
        DWORD           tick;
140
        static UINT     lastmsg = 0;
141
        static HWND     lasthwnd;
142
        static DWORD    lasttick;
143
        static int      lastx, lasty;
144
 
145
        /* determine double click eligibility*/
146
        if(msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN) {
147
                tick = GetTickCount();
148
                if((hwnd->pClass->style & CS_DBLCLKS) &&
149
                    msg == lastmsg && hwnd == lasthwnd &&
150
                    tick - lasttick < DBLCLICKSPEED &&
151
                    abs(cursorx-lastx) < mwSYSMETRICS_CXDOUBLECLK &&
152
                    abs(cursory-lasty) < mwSYSMETRICS_CYDOUBLECLK)
153
                        msg += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
154
                lastmsg = msg;
155
                lasthwnd = hwnd;
156
                lasttick = tick;
157
                lastx = cursorx;
158
                lasty = cursory;
159
        }
160
 
161
        /*
162
         * We always send nc mouse message
163
         * unlike Windows, for HTCLIENT default processing
164
         */
165
        PostMessage(hwnd, msg + (WM_NCMOUSEMOVE-WM_MOUSEMOVE), hittest,
166
                MAKELONG(cursorx, cursory));
167
 
168
        /* then possibly send user mouse message*/
169
        if(hittest == HTCLIENT) {
170
                pt.x = cursorx;
171
                pt.y = cursory;
172
                ScreenToClient(hwnd, &pt);
173
                PostMessage(hwnd, msg, 0, MAKELONG(pt.x, pt.y));
174
        }
175
}
176
 
177
/*
178
 * Deliver a mouse button or motion event.
179
 */
180
int mwCurrentButtons;
181
 
182
void
183
MwDeliverMouseEvent(int buttons, int changebuttons, MWKEYMOD modifiers)
184
{
185
        HWND    hwnd;
186
        int     hittest;
187
        UINT    msg;
188
 
189
        mwCurrentButtons = buttons;
190
 
191
        hwnd = GetCapture();
192
        if(!hwnd)
193
                hwnd = mousewp;
194
        hittest = SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(cursorx,cursory));
195
 
196
        if(!changebuttons)
197
                MwTranslateMouseMessage(hwnd, WM_MOUSEMOVE, hittest);
198
 
199
        if(changebuttons & MWBUTTON_L) {
200
                msg = (buttons&MWBUTTON_L)? WM_LBUTTONDOWN: WM_LBUTTONUP;
201
                MwTranslateMouseMessage(hwnd, msg, hittest);
202
        }
203
 
204
        if(changebuttons & MWBUTTON_M) {
205
                msg = (buttons&MWBUTTON_M)? WM_MBUTTONDOWN: WM_MBUTTONUP;
206
                MwTranslateMouseMessage(hwnd, msg, hittest);
207
        }
208
 
209
        if(changebuttons & MWBUTTON_R) {
210
                msg = (buttons&MWBUTTON_R)? WM_RBUTTONDOWN: WM_RBUTTONUP;
211
                MwTranslateMouseMessage(hwnd, msg, hittest);
212
        }
213
}
214
 
215
/*
216
 * Deliver a keyboard event.
217
 */
218
void
219
MwDeliverKeyboardEvent(MWKEY keyvalue, MWKEYMOD modifiers, MWSCANCODE scancode,
220
        BOOL pressed)
221
{
222
        WPARAM VK_Code = keyvalue;      /* default no translation*/
223
 
224
        /* Keysyms from 1-255 are mapped to ASCII*/
225
        if (keyvalue < 1 || keyvalue > 255)
226
          switch(keyvalue) {
227
 
228
        /* arrows + home/end pad*/
229
        case MWKEY_LEFT:
230
                VK_Code = VK_LEFT;
231
                break;
232
        case MWKEY_RIGHT:
233
                VK_Code = VK_RIGHT;
234
                break;
235
        case MWKEY_UP:
236
                VK_Code = VK_UP;
237
                break;
238
        case MWKEY_DOWN:
239
                VK_Code =  VK_DOWN;
240
                break;
241
        case MWKEY_INSERT:
242
                VK_Code = VK_INSERT;
243
                break;
244
        case MWKEY_DELETE:
245
                VK_Code = VK_DELETE;
246
                break;
247
        case MWKEY_HOME:
248
                VK_Code = VK_HOME;
249
                break;
250
        case MWKEY_END:
251
                VK_Code = VK_END;
252
                break;
253
        case MWKEY_PAGEUP:
254
                VK_Code = VK_PRIOR;
255
                break;
256
        case MWKEY_PAGEDOWN:
257
                VK_Code = VK_NEXT;
258
                break;
259
 
260
        /* Numeric keypad*/
261
        case MWKEY_KP0:
262
                VK_Code = VK_NUMPAD0;
263
                break;
264
        case MWKEY_KP1:
265
                VK_Code = VK_NUMPAD1;
266
                break;
267
        case MWKEY_KP2:
268
                VK_Code = VK_NUMPAD2;
269
                break;
270
        case MWKEY_KP3:
271
                VK_Code = VK_NUMPAD3;
272
                break;
273
        case MWKEY_KP4:
274
                VK_Code = VK_NUMPAD4;
275
                break;
276
        case MWKEY_KP5:
277
                VK_Code = VK_NUMPAD5;
278
                break;
279
        case MWKEY_KP6:
280
                VK_Code = VK_NUMPAD6;
281
                break;
282
        case MWKEY_KP7:
283
                VK_Code = VK_NUMPAD7;
284
                break;
285
        case MWKEY_KP8:
286
                VK_Code = VK_NUMPAD8;
287
                break;
288
        case MWKEY_KP9:
289
                VK_Code = VK_NUMPAD9;
290
                break;
291
        case MWKEY_KP_PERIOD:
292
                VK_Code = VK_DECIMAL;
293
                break;
294
        case MWKEY_KP_DIVIDE:
295
                VK_Code = VK_DIVIDE;
296
                break;
297
        case MWKEY_KP_MULTIPLY:
298
                VK_Code = VK_MULTIPLY;
299
                break;
300
        case MWKEY_KP_MINUS:
301
                VK_Code = VK_SUBTRACT;
302
                break;
303
        case MWKEY_KP_PLUS:
304
                VK_Code = VK_ADD;
305
                break;
306
        case MWKEY_KP_ENTER:
307
                VK_Code = VK_RETURN;
308
                break;
309
 
310
        /* Function keys */
311
        case MWKEY_F1:
312
                VK_Code = VK_F1;
313
                break;
314
        case MWKEY_F2:
315
                VK_Code = VK_F2;
316
                break;
317
        case MWKEY_F3:
318
                VK_Code = VK_F3;
319
                break;
320
        case MWKEY_F4:
321
                VK_Code = VK_F4;
322
                break;
323
        case MWKEY_F5:
324
                VK_Code = VK_F5;
325
                break;
326
        case MWKEY_F6:
327
                VK_Code = VK_F6;
328
                break;
329
        case MWKEY_F7:
330
                VK_Code = VK_F7;
331
                break;
332
        case MWKEY_F8:
333
                VK_Code = VK_F8;
334
                break;
335
        case MWKEY_F9:
336
                VK_Code = VK_F9;
337
                break;
338
        case MWKEY_F10:
339
                VK_Code = VK_F10;
340
                break;
341
        case MWKEY_F11:
342
                VK_Code = VK_F11;
343
                break;
344
        case MWKEY_F12:
345
                VK_Code = VK_F12;
346
                break;
347
 
348
        /* Key state modifier keys*/
349
        case MWKEY_NUMLOCK:
350
                VK_Code = VK_NUMLOCK;
351
                break;
352
        case MWKEY_CAPSLOCK:
353
                VK_Code = VK_CAPITAL;
354
                break;
355
        case MWKEY_SCROLLOCK:
356
                VK_Code = VK_CAPITAL;
357
                break;
358
        case MWKEY_LSHIFT:
359
                VK_Code = VK_LSHIFT;
360
                break;
361
        case MWKEY_RSHIFT:
362
                VK_Code = VK_RSHIFT;
363
                break;
364
        case MWKEY_LCTRL:
365
                VK_Code = VK_LCONTROL;
366
                break;
367
        case MWKEY_RCTRL:
368
                VK_Code = VK_RCONTROL;
369
                break;
370
        case MWKEY_LALT:
371
                VK_Code = VK_MENU;
372
                break;
373
        case MWKEY_RALT:
374
                VK_Code = VK_MENU;
375
                break;
376
 
377
        /* Misc function keys*/
378
        case MWKEY_PRINT:
379
                VK_Code = VK_PRINT;
380
                break;
381
        case MWKEY_PAUSE:
382
                VK_Code = VK_PAUSE;
383
                break;
384
        case MWKEY_MENU:
385
                VK_Code = VK_LMENU;     /* virtual key*/
386
                break;
387
 
388
        /* questionable mappings or no mappings...*/
389
        case MWKEY_KP_EQUALS:
390
                VK_Code = '=';  /* FIXME*/
391
                break;
392
 
393
        /* map all non-handled MWKEY values to VK_NONAME*/
394
#if 0
395
        case MWKEY_UNKNOWN:
396
        case MWKEY_SYSREQ:
397
        case MWKEY_BREAK
398
        case MWKEY_QUIT:
399
        case MWKEY_REDRAW:
400
        case MWKEY_LMETA:
401
        case MWKEY_RMETA:
402
        case MWKEY_ALTGR:
403
        /* Handheld function keys*/
404
        case MWKEY_RECORD:
405
        case MWKEY_PLAY:
406
        case MWKEY_CONTRAST:
407
        case MWKEY_BRIGHTNESS:
408
        case MWKEY_SELECTUP:
409
        case MWKEY_SELECTDOWN:
410
        case MWKEY_ACCEPT:
411
        case MWKEY_CANCEL:
412
        case MWKEY_APP1:
413
        case MWKEY_APP2:
414
        case MWKEY_LAST:
415
#endif
416
        default:
417
                VK_Code = VK_NONAME;
418
                break;
419
        }
420
 
421
        if (pressed)
422
                SendMessage(focuswp, WM_CHAR, VK_Code, 0L);
423
}
424
 
425
/*
426
 * Deliver a window expose event.
427
 * Most of the work is in calculating the update region
428
 * for better redraw look and feel, and then queuing a
429
 * WM_PAINT message to the window.
430
 */
431
void
432
MwDeliverExposureEvent(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width,
433
        MWCOORD height)
434
{
435
        if (wp->unmapcount)
436
                return;
437
 
438
        MwUnionUpdateRegion(wp, x, y, width, height, TRUE);
439
        PostMessage(wp, WM_PAINT, 0, 0L);
440
}
441
 
442
/*
443
 * Combine the passed rectangle with the update region for the given window.
444
 * Coordinates are passed relative to window.
445
 * If bUnion is TRUE, union the rectangle, otherwise subtract it.
446
 */
447
void
448
MwUnionUpdateRegion(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width,
449
        MWCOORD height, BOOL bUnion)
450
{
451
#if UPDATEREGIONS
452
        MWRECT rc;
453
 
454
        if (wp->unmapcount)
455
                return;
456
 
457
        /* convert window relative coords to screen coords*/
458
        rc.left = x + wp->winrect.left;
459
        rc.top = y + wp->winrect.top;
460
        rc.right = rc.left + width;
461
        rc.bottom = rc.top + height;
462
 
463
        if(bUnion)
464
                GdUnionRectWithRegion(&rc, wp->update);
465
        else
466
                GdSubtractRectFromRegion(&rc, wp->update);
467
#endif
468
}
469
 
470
/*
471
 * Move the cursor to the specified absolute screen coordinates.
472
 * The coordinates are that of the defined hot spot of the cursor.
473
 * The cursor's appearance is changed to that defined for the window
474
 * in which the cursor is moved to.  In addition, the window the
475
 * cursor is in is recalculated.
476
 */
477
void MwMoveCursor(MWCOORD x, MWCOORD y)
478
{
479
        /*
480
         * Move the cursor only if necessary, offsetting it to
481
         * place the hot spot at the specified coordinates.
482
         */
483
        if (x != cursorx || y != cursory) {
484
                if(curcursor)
485
                        GdMoveCursor(x - curcursor->cursor.hotx,
486
                                y - curcursor->cursor.hoty);
487
                cursorx = x;
488
                cursory = y;
489
        }
490
 
491
        /*
492
         * Now check to see which window the mouse is in and whether or
493
         * not the cursor shape should be changed.
494
         */
495
        MwCheckMouseWindow();
496
        MwCheckCursor();
497
}
498
 
499
/*
500
 * Check to see if the cursor shape is the correct shape for its current
501
 * location.  If not, its shape is changed.
502
 */
503
void MwCheckCursor(void)
504
{
505
        HWND            wp;             /* window cursor is in */
506
        HCURSOR         cp;             /* cursor definition */
507
 
508
        /*
509
         * Get the cursor at its current position, and if it is not the
510
         * currently defined one, then set the new cursor.  However,
511
         * if the window is currently captured, then leave it alone.
512
         */
513
        wp = capturewp;
514
        if (wp == NULL)
515
                wp = mousewp;
516
 
517
        cp = wp->cursor;
518
        if (cp == curcursor)
519
                return;
520
 
521
        /*
522
         * It needs redefining, so do it.
523
         */
524
        curcursor = cp;
525
        GdMoveCursor(cursorx - cp->cursor.hotx, cursory - cp->cursor.hoty);
526
        GdSetCursor(&cp->cursor);
527
}
528
 
529
/*
530
 * Find the window which is currently visible for the specified coordinates.
531
 * This just walks down the window tree looking for the deepest mapped
532
 * window which contains the specified point.  If the coordinates are
533
 * off the screen, the root window is returned.
534
 */
535
HWND
536
MwFindVisibleWindow(MWCOORD x, MWCOORD y)
537
{
538
        HWND    wp;             /* current window */
539
        HWND    retwp;          /* returned window */
540
 
541
        wp = rootwp;
542
        retwp = wp;
543
        while (wp) {
544
                if (!wp->unmapcount &&
545
                    wp->winrect.left <= x && wp->winrect.top <= y &&
546
                    wp->winrect.right > x && wp->winrect.bottom > y) {
547
                        retwp = wp;
548
                        wp = wp->children;
549
                        continue;
550
                }
551
                wp = wp->siblings;
552
        }
553
        return retwp;
554
}
555
 
556
/*
557
 * Check to see if the window the mouse is currently in has changed.
558
 */
559
void MwCheckMouseWindow(void)
560
{
561
        HWND    wp;
562
 
563
        /* Don't change if window drag or capture in progress*/
564
        wp = dragwp;
565
        if(!wp)
566
                wp = capturewp;
567
        if(!wp)
568
                wp = MwFindVisibleWindow(cursorx, cursory);
569
        mousewp = wp;
570
}
571
 
572
/*
573
 *  Copy dstsiz bytes, including nul, from src to dst.
574
 *  Return # bytes, excluding nul, copied.
575
 */
576
int
577
strzcpy(char *dst,const char *src,int dstsiz)
578
{
579
        int     cc = dstsiz;
580
 
581
        /* return 0 on NULL src*/
582
        if(!src)
583
                cc = dstsiz = 1;
584
 
585
        while(--dstsiz > 0) {
586
                if((*dst++ = *src++) == '\0')
587
                        return cc - dstsiz - 1;
588
        }
589
        *dst = 0;
590
        return cc - dstsiz - 1;
591
}

powered by: WebSVN 2.1.0

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