6
#include "GL/os2mesa.h"
10
#include <mmioos2.h> /* It is from MMPM toolkit */
15
#include "os2mesadef.h"
23
extern unsigned __glutMenuButton;
24
extern GLUTidleCB __glutIdleFunc;
25
extern GLUTtimer *__glutTimerList;
26
extern void handleTimeouts(void);
27
extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, int unique);
28
static HMENU __glutHMenu;
32
extern void _mesa_ResizeBuffersMESA( void );
35
MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
36
MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
37
void updateWindowState(GLUTwindow *window, int visState);
39
volatile extern HAB hab; /* PM anchor block handle */
40
volatile extern HPS hpsCurrent;
45
MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
47
rc = GlutWindowProc(hwnd, msg, mp1, mp2 );
51
MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
53
HPS hps = NULLHANDLE; /* presentation space handle */
54
GLUTwindow* window; /* GLUT window associated with message. */
55
GLUTmenu* menu; /* GLUT menu associated with message. */
58
int button = -1,rc,key;
61
/* Process the message. */
67
SIZEL sizl = { 0L, 0L };
71
/*+-----------------------------------------------------------------+*/
72
/*| The client window is being created. Create the semaphore to |*/
73
/*| control access to the presentation space. Then create the |*/
74
/*| thread that will draw the lines. |*/
75
/*+-----------------------------------------------------------------+*/
76
// DosCreateMutexSem( (PSZ)NULL, &hmtxPS, 0UL, FALSE );
78
hdc = WinOpenWindowDC(hwnd);
80
/*+-----------------------------------------------------------------+*/
81
/*| Create a non-cached presentation space. We will not release |*/
82
/*| this PS, as we will be Selecting a Palette to this PS and then |*/
83
/*| animating the palette. Upon releasing a PS the palette is no |*/
84
/*| longer selected for obvious reasons. |*/
85
/*+-----------------------------------------------------------------+*/
86
hpsCurrent = GpiCreatePS( hab,
89
PU_PELS | GPIF_DEFAULT |
90
GPIT_MICRO | GPIA_ASSOC );
91
// DevQueryCaps( hdc, lStart, lCount, alCaps );
92
// fPaletteCaps = alCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER;
94
/* ļæ½ļæ½pļæ½ļæ½ļæ½ļæ½ hpsBuffer ļæ½ pļæ½ļæ½ļæ½ļæ½ RGB color table */
96
GpiCreateLogColorTable(hpsCurrent,0 ,LCOLF_RGB,0,0,NULL);
97
GpiSetPattern(hpsCurrent,PATSYM_SOLID);
98
GpiSetPatternSet(hpsCurrent,LCID_DEFAULT);
105
WinPostMsg( hwnd, WM_QUIT, NULL, NULL );
110
window = __glutGetWindow(hwnd);
114
// hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
115
hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
116
// blit Dive buffer to screen.
119
SWP swp; // Window position
120
POINTL pointl; // Point to offset from Desktop
122
// Convert the point to offset from desktop lower left.
125
WinMapWindowPoints ( hwnd, HWND_DESKTOP, &pointl, 1 );
128
// ctx = window->ctx;
129
// ctx->xDiveScr = pointl.x;
130
// ctx->yDiveScr = pointl.y;
132
// rc = DiveBlitImage (ctx->hDive,
133
// ctx->ulDiveBufferNumber,
134
// DIVE_BUFFER_SCREEN );
137
if (window->win == hwnd) {
138
__glutPostRedisplay(window, GLUT_REPAIR_WORK);
139
} else if (window->overlay && window->overlay->win == hwnd) {
140
__glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);
145
hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
146
WinFillRect(hps, &rclClient, CLR_WHITE);
153
// pwinData->fDataInProcess = TRUE;
154
// DiveSetupBlitter ( pwinData->hDive, 0 );
155
// pwinData->fVrnDisabled = TRUE;
159
{ HRGN hrgn; /* Region handle */
160
RGNRECT rgnCtl; /* Processing control structure */
164
// pwinData->fDataInProcess = TRUE;
165
hps = WinGetPS ( hwnd );
168
hrgn = GpiCreateRegion ( hps, 0L, NULL );
170
{ /* NOTE: If mp1 is zero, then this was just a move message.
171
** Illustrate the visible region on a WM_VRNENABLE.
173
WinQueryVisibleRegion ( hwnd, hrgn );
176
rgnCtl.ulDirection = 1;
178
/* Get the all ORed rectangles */
179
if ( GpiQueryRegionRects ( hps, hrgn, NULL,
182
ulNumRcls = rgnCtl.crcReturned;
184
/* Now find the window position and size, relative to parent.
186
// WinQueryWindowPos ( pwinData->hwndClient, &pwinData->swp );
191
/* Convert the point to offset from desktop lower left.
193
// pointl.x = pwinData->swp.x;
194
// pointl.y = pwinData->swp.y;
196
// WinMapWindowPoints ( pwinData->hwndFrame,
197
// HWND_DESKTOP, &pointl, 1 );
199
// pwinData->cxWindowPos = pointl.x;
200
// pwinData->cyWindowPos = pointl.y;
203
GpiDestroyRegion( hps, hrgn );
211
window = __glutGetWindow(hwnd);
214
width = SHORT1FROMMP(mp2);
215
height = SHORT2FROMMP(mp2);
216
if (width != window->width || height != window->height) {
217
#if 0 /* Win32 GLUT does not support overlays for now. */
218
if (window->overlay) {
219
XResizeWindow(__glutDisplay, window->overlay->win, width, height);
222
window->width = width;
223
window->height = height;
224
__glutSetWindow(window);
225
if(width <= 0 || height <= 0)
227
_mesa_ResizeBuffersMESA();
229
/* Do not execute OpenGL out of sequence with respect
230
to the SetWindowPos request! */
231
window->reshape(width, height);
232
window->forceReshape = FALSE;
233
/* A reshape should be considered like posting a
235
__glutPostRedisplay(window, GLUT_REPAIR_WORK);
240
window = __glutGetWindow(hwnd);
243
visState = SHORT1FROMMP( mp1 );
244
updateWindowState(window, visState);
249
window = __glutGetWindow(hwnd);
250
// /* Make sure we re-select the correct palette if needed. */
251
// if (LOWORD(wParam)) {
252
// PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
256
visState = SHORT1FROMMP( mp1 );
257
updateWindowState(window, visState);
263
window = __glutGetWindow(hwnd);
267
fsflags = SHORT1FROMMP(mp1);
269
if((fsflags & KC_KEYUP) ) /* ļæ½ļæ½ļæ½ļæ½pļæ½p愬 ļæ½ā¦ āØ„ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½, pļæ½ļæ½ļæ½ļæ½p愬 ā®«ģŖ® ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½āØ„ */
271
///////////////////////////////////////////////////
272
if(!(fsflags & KC_CHAR) )
274
if (!(fsflags & KC_VIRTUALKEY))
277
/* Get the virtual key from mp2. */
278
switch (SHORT2FROMMP(mp2))
280
/* directional keys */
281
case VK_LEFT: key = GLUT_KEY_LEFT; break;
282
case VK_UP: key = GLUT_KEY_UP; break;
283
case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
284
case VK_DOWN: key = GLUT_KEY_DOWN; break;
286
case VK_PAGEUP: key = GLUT_KEY_PAGE_UP; break;
287
case VK_PAGEDOWN:key = GLUT_KEY_PAGE_DOWN; break;
288
case VK_HOME: key = GLUT_KEY_HOME;break;
289
case VK_END: key = GLUT_KEY_END; break;
290
case VK_INSERT: key = GLUT_KEY_INSERT; break;
293
case VK_F1 : key = GLUT_KEY_F1; break;
294
case VK_F2 : key = GLUT_KEY_F2; break;
295
case VK_F3 : key = GLUT_KEY_F3; break;
296
case VK_F4 : key = GLUT_KEY_F4; break;
297
case VK_F5 : key = GLUT_KEY_F5; break;
298
case VK_F6 : key = GLUT_KEY_F6; break;
299
case VK_F7 : key = GLUT_KEY_F7; break;
300
case VK_F8 : key = GLUT_KEY_F8; break;
301
case VK_F9 : key = GLUT_KEY_F9; break;
302
case VK_F10: key = GLUT_KEY_F10;break;
303
case VK_F11: key = GLUT_KEY_F11; break;
304
case VK_F12: key = GLUT_KEY_F12; break;
305
case VK_ESC: key = -1; break; /* Character codes */
306
case VK_SPACE: key = -1; break;
307
case VK_TAB: key = -1; break;
310
{ break; /* Key Not implemented */
313
{ if (!window->special) /* ļæ½ļæ½ ļæ½ļæ½ā ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ą ”ļæ½ļæ½ēØŖļæ½ */
316
WinQueryPointerPos(HWND_DESKTOP,&point);
317
ScreenToClient(window->win, &point);
318
__glutSetWindow(window);
319
__glutModifierMask = 0;
320
if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* high order bit is on */
321
__glutModifierMask |= ShiftMask;
322
if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
323
__glutModifierMask |= ControlMask;
324
if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
325
__glutModifierMask |= Mod1Mask;
326
window->special(key, point.x, point.y);
327
__glutModifierMask = (unsigned int) ~0;
332
/////////////////////////////////////////////////////
333
/* If we are ignoring auto repeated key strokes for the window, bail. */
334
if (window->ignoreKeyRepeat && (CHAR3FROMMP(mp1)) )
336
if(!((unsigned char)SHORT1FROMMP(mp2)) ) /* ļæ½ļæ½ļæ½ļæ½pļæ½p愬 ļæ½ļæ½įجļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ */
338
if (window->keyboard) {
339
WinQueryPointerPos(HWND_DESKTOP,&point);
341
ScreenToClient(window->win, &point);
342
__glutSetWindow(window);
343
__glutModifierMask = 0;
344
if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* high order bit is on */
345
__glutModifierMask |= ShiftMask;
346
if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
347
__glutModifierMask |= ControlMask;
348
if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
349
__glutModifierMask |= Mod1Mask;
350
window->keyboard((unsigned char)SHORT1FROMMP(mp2), point.x, point.y);
351
__glutModifierMask = (unsigned int) ~0;
354
} /* endof case WM_CHAR: */
355
////////////////////////////////////////////////
357
button = GLUT_LEFT_BUTTON;
360
button = GLUT_MIDDLE_BUTTON;
363
button = GLUT_RIGHT_BUTTON;
365
psh = *((POINTS *)&mp1);
369
/* finish the menu if we get a button down message (user must have
370
cancelled the menu). */
371
if (__glutMappedMenu) {
372
/* TODO: take this out once the menu on middle mouse stuff works
374
if (button == GLUT_MIDDLE_BUTTON)
376
/* get current mouse pointer position */
377
// WinQueryPointerPos(HWND_DESKTOP,&point);
378
/* map from desktop to client window */
379
// WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);
380
__glutItemSelected = NULL;
381
__glutFinishMenu(hwnd, point.x, point.y);
384
window = __glutGetWindow(hwnd);
386
window->buttonDownState = button+1;
387
menu = __glutGetMenuByNum(window->menu[button]);
390
// __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
391
// button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON :
393
// __glutStartMenu(menu, window, point.x, point.y, x, y);
394
} else if (window->mouse) {
396
__glutSetWindow(window);
397
__glutModifierMask = 0;
398
if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* < 0 = high order bit is on. */
399
__glutModifierMask |= ShiftMask;
400
if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
401
__glutModifierMask |= ControlMask;
402
if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
403
__glutModifierMask |= Mod1Mask;
404
window->mouse(button, GLUT_DOWN, point.x, point.y);
405
__glutModifierMask = (unsigned int)~0;
407
/* Stray mouse events. Ignore. */
413
/********************************************/
415
button = GLUT_LEFT_BUTTON;
418
button = GLUT_MIDDLE_BUTTON;
421
button = GLUT_RIGHT_BUTTON;
423
psh = *((POINTS *)&mp1);
427
/* Bail out if we're processing a menu. */
428
/* Bail out = ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ā®¬ */
429
if (__glutMappedMenu) {
430
WinQueryPointerPos(HWND_DESKTOP,&point);
431
WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);
432
/* if we're getting the middle button up signal, then something
433
on the menu was selected. */
434
if (button == GLUT_MIDDLE_BUTTON) {
436
/* For some reason, the code below always returns -1 even
437
though the point IS IN THE ITEM! Therefore, just bail out if
438
we get a middle mouse up. The user must select using the
439
left mouse button. Stupid Win32. */
441
int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
443
__glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
445
__glutItemSelected = NULL;
446
__glutFinishMenu(hwnd, point.x, point.y);
449
__glutItemSelected = NULL;
450
__glutFinishMenu(hwnd, point.x, point.y);
455
window = __glutGetWindow(hwnd);
457
window->buttonDownState = 0;
459
if (window && window->mouse) {
460
__glutSetWindow(window);
461
__glutModifierMask = 0;
462
if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* < 0 = high order bit is on */
463
__glutModifierMask |= ShiftMask;
464
if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
465
__glutModifierMask |= ControlMask;
466
if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
467
__glutModifierMask |= Mod1Mask;
468
window->mouse(button, GLUT_UP, point.x, point.y);
470
__glutModifierMask = (unsigned int)~0;
472
/* Window might have been destroyed and all the
473
events for the window may not yet be received. */
479
//////////////////////////////////////////////////
481
window = __glutGetWindow(hwnd);
483
{ if (window->wm_command)
484
window->wm_command(hwnd,mp1,mp2);
489
if (!__glutMappedMenu) {
490
window = __glutGetWindow(hwnd);
492
/* If motion function registered _and_ buttons held *
493
down, call motion function... */
495
psh = *((POINTS *)&mp1);
500
if (window->motion && window->buttonDownState) {
501
__glutSetWindow(window);
502
window->motion(point.x, point.y);
504
/* If passive motion function registered _and_
505
buttons not held down, call passive motion
507
else if (window->passive && !window->buttonDownState) {
508
__glutSetWindow(window);
509
window->passive(point.x, point.y);
513
/* Motion events are thrown away when a pop up menu is
520
/* For all other messages, let the default window procedure process them. */
521
return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
523
} //endof switch( msg )
524
return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
528
void APIENTRY glutCommandFunc(GLUTcommandCB Func)
530
extern GLUTwindow *__glutCurrentWindow;
531
__glutCurrentWindow->wm_command = Func;
538
updateWindowState(GLUTwindow *window, int visState)
542
/* XXX shownState and visState are the same in Win32. */
543
window->shownState = visState;
544
if (visState != window->visState) {
545
if (window->windowStatus) {
546
window->visState = visState;
547
__glutSetWindow(window);
548
window->windowStatus(visState);
551
/* Since Win32 only sends an activate for the toplevel window,
552
update the visibility for all the child windows. */
553
child = window->children;
555
updateWindowState(child, visState);
556
child = child->siblings;
563
__glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
565
POINT point; /* Point structure. */
566
PAINTSTRUCT ps; /* Paint structure. */
567
LPMINMAXINFO minmax; /* Minimum/maximum info structure. */
568
GLUTwindow* window; /* GLUT window associated with message. */
569
GLUTmenu* menu; /* GLUT menu associated with message. */
570
int x, y, width, height, key;
581
/* XXX NVidia's NT OpenGL can have problems closing down
582
its OpenGL internal data structures if we just allow
583
the process to terminate without unbinding and deleting
584
the windows context. Apparently, DirectDraw unloads
585
before OPENGL32.DLL in the close down sequence, but
586
NVidia's NT OpenGL needs DirectDraw to close down its
588
window = __glutGetWindow(hwnd);
591
wglMakeCurrent(NULL, NULL);
592
wglDeleteContext(window->ctx);
600
window = __glutGetWindow(hwnd);
604
/* Win32 is dumb and sends these messages only to the parent
605
window. Therefore, find out if we're in a child window and
606
call the child windows keyboard callback if we are. */
607
if (window->parent) {
608
GetCursorPos(&point);
609
ScreenToClient(hwnd, &point);
610
hwnd = ChildWindowFromPoint(hwnd, point);
611
window = __glutGetWindow(hwnd);
613
if (window->specialUp || window->keyboardUp) {
614
GetCursorPos(&point);
615
ScreenToClient(window->win, &point);
616
__glutSetWindow(window);
617
__glutModifierMask = 0;
618
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
619
__glutModifierMask |= ShiftMask;
620
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
621
__glutModifierMask |= ControlMask;
622
if (GetKeyState(VK_MENU) < 0)
623
__glutModifierMask |= Mod1Mask;
626
case VK_F1: key = GLUT_KEY_F1; break;
627
case VK_F2: key = GLUT_KEY_F2; break;
628
case VK_F3: key = GLUT_KEY_F3; break;
629
case VK_F4: key = GLUT_KEY_F4; break;
630
case VK_F5: key = GLUT_KEY_F5; break;
631
case VK_F6: key = GLUT_KEY_F6; break;
632
case VK_F7: key = GLUT_KEY_F7; break;
633
case VK_F8: key = GLUT_KEY_F8; break;
634
case VK_F9: key = GLUT_KEY_F9; break;
635
case VK_F10: key = GLUT_KEY_F10; break;
636
case VK_F11: key = GLUT_KEY_F11; break;
637
case VK_F12: key = GLUT_KEY_F12; break;
638
case VK_LEFT: key = GLUT_KEY_LEFT; break;
639
case VK_UP: key = GLUT_KEY_UP; break;
640
case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
641
case VK_DOWN: key = GLUT_KEY_DOWN; break;
642
case VK_PRIOR: key = GLUT_KEY_PAGE_UP; break;
643
case VK_NEXT: key = GLUT_KEY_PAGE_DOWN; break;
644
case VK_HOME: key = GLUT_KEY_HOME; break;
645
case VK_END: key = GLUT_KEY_END; break;
646
case VK_INSERT: key = GLUT_KEY_INSERT; break;
648
/* Delete is an ASCII character. */
649
if (window->keyboardUp) {
650
window->keyboardUp((unsigned char) 127, point.x, point.y);
655
if (window->keyboardUp) {
656
key = MapVirtualKey(wParam, 2); /* Map to ASCII. */
657
if (isascii(key) && (key != 0)) {
659
/* XXX Attempt to determine modified ASCII character
660
is quite incomplete. Digits, symbols, CapsLock,
661
Ctrl, and numeric keypad are all ignored. Fix this. */
663
if (!(__glutModifierMask & ShiftMask))
665
window->keyboardUp((unsigned char) key, point.x, point.y);
668
__glutModifierMask = (unsigned int) ~0;
671
if (window->specialUp) {
672
window->specialUp(key, point.x, point.y);
674
__glutModifierMask = (unsigned int) ~0;
680
window = __glutGetWindow(hwnd);
685
/* Bit 30 of lParam is set if key already held down. If
686
we are ignoring auto repeated key strokes for the window, bail. */
687
if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
691
/* Win32 is dumb and sends these messages only to the parent
692
window. Therefore, find out if we're in a child window and
693
call the child windows keyboard callback if we are. */
694
if (window->parent) {
695
GetCursorPos(&point);
696
ScreenToClient(hwnd, &point);
697
hwnd = ChildWindowFromPoint(hwnd, point);
698
window = __glutGetWindow(hwnd);
700
if (window->keyboard) {
701
GetCursorPos(&point);
702
ScreenToClient(window->win, &point);
703
__glutSetWindow(window);
704
__glutModifierMask = 0;
705
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
706
__glutModifierMask |= ShiftMask;
707
if (GetKeyState(VK_CONTROL) < 0)
708
__glutModifierMask |= ControlMask;
709
if (GetKeyState(VK_MENU) < 0)
710
__glutModifierMask |= Mod1Mask;
711
window->keyboard((unsigned char)wParam, point.x, point.y);
712
__glutModifierMask = (unsigned int) ~0;
718
window = __glutGetWindow(hwnd);
723
/* Bit 30 of lParam is set if key already held down. If
724
we are ignoring auto repeated key strokes for the window, bail. */
725
if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
729
/* Win32 is dumb and sends these messages only to the parent
730
window. Therefore, find out if we're in a child window and
731
call the child windows keyboard callback if we are. */
732
if (window->parent) {
733
GetCursorPos(&point);
734
ScreenToClient(hwnd, &point);
735
hwnd = ChildWindowFromPoint(hwnd, point);
736
window = __glutGetWindow(hwnd);
738
if (window->special) {
742
case VK_F1: key = GLUT_KEY_F1; break;
743
case VK_F2: key = GLUT_KEY_F2; break;
744
case VK_F3: key = GLUT_KEY_F3; break;
745
case VK_F4: key = GLUT_KEY_F4; break;
746
case VK_F5: key = GLUT_KEY_F5; break;
747
case VK_F6: key = GLUT_KEY_F6; break;
748
case VK_F7: key = GLUT_KEY_F7; break;
749
case VK_F8: key = GLUT_KEY_F8; break;
750
case VK_F9: key = GLUT_KEY_F9; break;
751
case VK_F10: key = GLUT_KEY_F10; break;
752
case VK_F11: key = GLUT_KEY_F11; break;
753
case VK_F12: key = GLUT_KEY_F12; break;
754
/* directional keys */
755
case VK_LEFT: key = GLUT_KEY_LEFT; break;
756
case VK_UP: key = GLUT_KEY_UP; break;
757
case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
758
case VK_DOWN: key = GLUT_KEY_DOWN; break;
762
/* VK_PRIOR is Win32's Page Up */
763
key = GLUT_KEY_PAGE_UP;
766
/* VK_NEXT is Win32's Page Down */
767
key = GLUT_KEY_PAGE_DOWN;
776
key = GLUT_KEY_INSERT;
783
GetCursorPos(&point);
784
ScreenToClient(window->win, &point);
785
__glutSetWindow(window);
786
__glutModifierMask = 0;
787
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
788
__glutModifierMask |= ShiftMask;
789
if (GetKeyState(VK_CONTROL) < 0)
790
__glutModifierMask |= ControlMask;
791
if (GetKeyState(VK_MENU) < 0)
792
__glutModifierMask |= Mod1Mask;
793
window->special(key, point.x, point.y);
794
__glutModifierMask = (unsigned int) ~0;
795
} else if (window->keyboard) {
796
/* Specially handle any keys that match ASCII values but
797
do not generate Windows WM_SYSCHAR or WM_CHAR messages. */
801
/* Delete is an ASCII character. */
802
GetCursorPos(&point);
803
ScreenToClient(window->win, &point);
804
__glutSetWindow(window);
805
__glutModifierMask = 0;
806
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
807
__glutModifierMask |= ShiftMask;
808
if (GetKeyState(VK_CONTROL) < 0)
809
__glutModifierMask |= ControlMask;
810
if (GetKeyState(VK_MENU) < 0)
811
__glutModifierMask |= Mod1Mask;
812
window->keyboard((unsigned char) 127, point.x, point.y);
813
__glutModifierMask = (unsigned int) ~0;
816
/* Let the following WM_SYSCHAR or WM_CHAR message generate
817
the keyboard callback. */
824
button = GLUT_LEFT_BUTTON;
827
button = GLUT_MIDDLE_BUTTON;
830
button = GLUT_RIGHT_BUTTON;
832
/* finish the menu if we get a button down message (user must have
833
cancelled the menu). */
834
if (__glutMappedMenu) {
835
/* TODO: take this out once the menu on middle mouse stuff works
837
if (button == GLUT_MIDDLE_BUTTON)
839
GetCursorPos(&point);
840
ScreenToClient(hwnd, &point);
841
__glutItemSelected = NULL;
842
__glutFinishMenu(hwnd, point.x, point.y);
846
/* set the capture so we can get mouse events outside the window */
849
/* Win32 doesn't return the same numbers as X does when the mouse
850
goes beyond the upper or left side of the window. roll the
851
Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
854
if(x & 1 << 15) x -= (1 << 16);
855
if(y & 1 << 15) y -= (1 << 16);
857
window = __glutGetWindow(hwnd);
859
menu = __glutGetMenuByNum(window->menu[button]);
861
point.x = LOWORD(lParam); point.y = HIWORD(lParam);
862
ClientToScreen(window->win, &point);
863
__glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
864
button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON :
866
__glutStartMenu(menu, window, point.x, point.y, x, y);
867
} else if (window->mouse) {
869
__glutSetWindow(window);
870
__glutModifierMask = 0;
871
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on. */
872
__glutModifierMask |= ShiftMask;
873
if (GetKeyState(VK_CONTROL) < 0)
874
__glutModifierMask |= ControlMask;
875
if (GetKeyState(VK_MENU) < 0)
876
__glutModifierMask |= Mod1Mask;
877
window->mouse(button, GLUT_DOWN, x, y);
878
__glutModifierMask = (unsigned int)~0;
880
/* Stray mouse events. Ignore. */
886
button = GLUT_LEFT_BUTTON;
889
button = GLUT_MIDDLE_BUTTON;
892
button = GLUT_RIGHT_BUTTON;
894
/* Bail out if we're processing a menu. */
895
if (__glutMappedMenu) {
896
GetCursorPos(&point);
897
ScreenToClient(hwnd, &point);
898
/* if we're getting the middle button up signal, then something
899
on the menu was selected. */
900
if (button == GLUT_MIDDLE_BUTTON) {
902
/* For some reason, the code below always returns -1 even
903
though the point IS IN THE ITEM! Therefore, just bail out if
904
we get a middle mouse up. The user must select using the
905
left mouse button. Stupid Win32. */
907
int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
909
__glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
911
__glutItemSelected = NULL;
912
__glutFinishMenu(hwnd, point.x, point.y);
915
__glutItemSelected = NULL;
916
__glutFinishMenu(hwnd, point.x, point.y);
921
/* Release the mouse capture. */
924
window = __glutGetWindow(hwnd);
925
if (window && window->mouse) {
926
/* Win32 doesn't return the same numbers as X does when the
927
mouse goes beyond the upper or left side of the window. roll
928
the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
931
if(x & 1 << 15) x -= (1 << 16);
932
if(y & 1 << 15) y -= (1 << 16);
934
__glutSetWindow(window);
935
__glutModifierMask = 0;
936
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
937
__glutModifierMask |= ShiftMask;
938
if (GetKeyState(VK_CONTROL) < 0)
939
__glutModifierMask |= ControlMask;
940
if (GetKeyState(VK_MENU) < 0)
941
__glutModifierMask |= Mod1Mask;
942
window->mouse(button, GLUT_UP, x, y);
943
__glutModifierMask = (unsigned int)~0;
945
/* Window might have been destroyed and all the
946
events for the window may not yet be received. */
950
case WM_ENTERMENULOOP:
951
/* KLUDGE: create a timer that fires every 100 ms when we start a
952
menu so that we can still process the idle & timer events (that
953
way, the timers will fire during a menu pick and so will the
955
SetTimer(hwnd, 1, 1, NULL);
960
/* If the timer id is 2, then this is the timer that is set up in
961
the main glut message processing loop, and we don't want to do
962
anything but acknowledge that we got it. It is used to prevent
963
CPU spiking when an idle function is installed. */
968
/* only worry about the idle function and the timeouts, since
969
these are the only events we expect to process during
970
processing of a menu. */
971
/* we no longer process the idle functions (as outlined in the
972
README), since drawing can't be done until the menu has
973
finished...it's pretty lame when the animation goes on, but
974
doesn't update, so you get this weird jerkiness. */
983
case WM_EXITMENULOOP:
984
/* nuke the above created timer...we don't need it anymore, since
985
the menu is gone now. */
991
__glutHMenu = (HMENU)lParam;
995
if (__glutMappedMenu) {
996
if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
997
__glutItemSelected = NULL;
1000
__glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
1001
GetCursorPos(&point);
1002
ScreenToClient(hwnd, &point);
1003
__glutFinishMenu(hwnd, point.x, point.y);
1008
if (!__glutMappedMenu) {
1009
window = __glutGetWindow(hwnd);
1011
/* If motion function registered _and_ buttons held *
1012
down, call motion function... */
1016
/* Win32 doesn't return the same numbers as X does when the
1017
mouse goes beyond the upper or left side of the window.
1018
roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */
1019
if(x & 1 << 15) x -= (1 << 16);
1020
if(y & 1 << 15) y -= (1 << 16);
1022
if (window->motion && wParam &
1023
(MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
1024
__glutSetWindow(window);
1025
window->motion(x, y);
1027
/* If passive motion function registered _and_
1028
buttons not held down, call passive motion
1030
else if (window->passive &&
1032
(MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
1034
__glutSetWindow(window);
1035
window->passive(x, y);
1039
/* Motion events are thrown away when a pop up menu is
1044
case WM_GETMINMAXINFO:
1045
/* this voodoo is brought to you by Win32 (again). It allows the
1046
window to be bigger than the screen, and smaller than 100x100
1047
(although it doesn't seem to help the y minimum). */
1048
minmax = (LPMINMAXINFO)lParam;
1049
minmax->ptMaxSize.x = __glutScreenWidth;
1050
minmax->ptMaxSize.y = __glutScreenHeight;
1051
minmax->ptMinTrackSize.x = 0;
1052
minmax->ptMinTrackSize.y = 0;
1053
minmax->ptMaxTrackSize.x = __glutScreenWidth +
1054
GetSystemMetrics(SM_CXSIZE) * 2;
1055
minmax->ptMaxTrackSize.y = __glutScreenHeight +
1056
GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);
1060
window = __glutGetWindow(hwnd);
1062
width = LOWORD(lParam);
1063
height = HIWORD(lParam);
1064
if (width != window->width || height != window->height) {
1065
#if 0 /* Win32 GLUT does not support overlays for now. */
1066
if (window->overlay) {
1067
XResizeWindow(__glutDisplay, window->overlay->win, width, height);
1070
window->width = width;
1071
window->height = height;
1072
__glutSetWindow(window);
1073
/* Do not execute OpenGL out of sequence with respect
1074
to the SetWindowPos request! */
1076
window->reshape(width, height);
1077
window->forceReshape = FALSE;
1078
/* A reshape should be considered like posting a
1080
__glutPostRedisplay(window, GLUT_REPAIR_WORK);
1086
/* If the cursor is not in the client area, then we want to send
1087
this message to the default window procedure ('cause its
1088
probably in the border or title, and we don't handle that
1089
cursor. otherwise, set our cursor. Win32 makes us set the
1090
cursor every time the mouse moves (DUMB!). */
1091
if(LOWORD(lParam) != HTCLIENT) {
1094
window = __glutGetWindow(hwnd);
1096
__glutSetCursor(window);
1098
/* TODO: check out the info in DevStudio on WM_SETCURSOR in the
1099
DefaultAction section. */
1103
window = __glutGetWindow(hwnd);
1105
window->entryState = WM_SETFOCUS;
1106
if (window->entry) {
1107
__glutSetWindow(window);
1108
window->entry(GLUT_ENTERED);
1109
/* XXX Generation of fake passive notify? See how much
1110
work the X11 code does to support fake passive notify
1113
if (window->joystick && __glutCurrentWindow) {
1114
if (__glutCurrentWindow->joyPollInterval > 0) {
1117
/* Because Win32 will only let one window capture the
1118
joystick at a time, we must capture it when we get the
1119
focus and release it when we lose the focus. */
1120
result = joySetCapture(__glutCurrentWindow->win,
1121
JOYSTICKID1, 0, TRUE);
1122
if (result != JOYERR_NOERROR) {
1125
(void) joySetThreshold(JOYSTICKID1,
1126
__glutCurrentWindow->joyPollInterval);
1133
window = __glutGetWindow(hwnd);
1135
window->entryState = WM_KILLFOCUS;
1136
if (window->entry) {
1137
__glutSetWindow(window);
1138
window->entry(GLUT_LEFT);
1140
if (window->joystick && __glutCurrentWindow) {
1141
if (__glutCurrentWindow->joyPollInterval > 0) {
1142
/* Because Win32 will only let one window capture the
1143
joystick at a time, we must capture it when we get the
1144
focus and release it when we lose the focus. */
1145
(void) joyReleaseCapture(JOYSTICKID1);
1151
window = __glutGetWindow(hwnd);
1152
/* Make sure we re-select the correct palette if needed. */
1153
if (LOWORD(wParam)) {
1154
PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
1159
/* HIWORD(wParam) is the minimized flag. */
1160
visState = !HIWORD(wParam);
1161
updateWindowState(window, visState);
1165
/* Colour Palette Management */
1166
case WM_PALETTECHANGED:
1167
if (hwnd == (HWND)wParam) {
1168
/* Don't respond to the message that we sent! */
1171
/* fall through to WM_QUERYNEWPALETTE */
1173
case WM_QUERYNEWPALETTE:
1174
window = __glutGetWindow(hwnd);
1175
if (window && window->colormap) {
1176
UnrealizeObject(window->colormap->cmap);
1177
SelectPalette(window->hdc, window->colormap->cmap, FALSE);
1178
RealizePalette(window->hdc);
1185
window = __glutGetWindow(hwnd);
1186
if (window->joystick) {
1190
/* Because WIN32 only supports messages for X, Y, and Z
1191
translations, we must poll for the rest */
1192
jix.dwSize = sizeof(jix);
1193
jix.dwFlags = JOY_RETURNALL;
1194
joyGetPosEx(JOYSTICKID1,&jix);
1196
#define SCALE(v) ((int) ((v - 32767)/32.768))
1198
/* Convert to integer for scaling. */
1202
window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));
1207
case MM_JOY1BUTTONDOWN:
1208
case MM_JOY1BUTTONUP:
1209
window = __glutGetWindow(hwnd);
1210
if (window->joystick) {
1213
/* Because WIN32 only supports messages for X, Y, and Z
1214
translations, we must poll for the rest */
1215
jix.dwSize = sizeof(jix);
1216
jix.dwFlags = JOY_RETURNALL;
1217
joyGetPosEx(JOYSTICKID1,&jix);
1224
/* Miscellaneous messages (don't really need to enumerate them,
1225
but it's good to know what you're not getting sometimes). */
1226
case WM_DISPLAYCHANGE:
1229
/* This event is generated by every mouse move event. */
1231
case WM_NCMOUSEMOVE:
1243
case WM_NCLBUTTONDOWN:
1249
case WM_ACTIVATEAPP:
1255
case WM_WINDOWPOSCHANGING:
1257
case WM_WINDOWPOSCHANGED:
1259
case WM_MOUSEACTIVATE:
1269
case WM_CAPTURECHANGED:
1273
case WM_ENTERSIZEMOVE:
1284
return DefWindowProc(hwnd, msg, wParam, lParam);
1289
#if defined(__OS2PM__)
1290
Bool __glutSetWindowText(Window window, char *text)
1292
return WinSetWindowText(window, (PCSZ)text);
b'\\ No newline at end of file'