glut: Remove EOF characters.
[mesa.git] / src / glut / os2 / os2_winproc.cpp
1 /* os2_winproc.c */
2
3
4 #define INCL_DEV
5 #include "WarpGL.h"
6 #include "GL/os2mesa.h"
7
8
9 #define _MEERROR_H_
10 #include <mmioos2.h> /* It is from MMPM toolkit */
11 #include <dive.h>
12 #include <fourcc.h>
13
14
15 #include "os2mesadef.h"
16 #include "glutint.h"
17
18
19 #define POKA 0
20
21 #if POKA
22
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;
29
30 #endif
31
32 extern void _mesa_ResizeBuffersMESA( void );
33
34
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);
38
39 volatile extern HAB hab; /* PM anchor block handle */
40 volatile extern HPS hpsCurrent;
41
42 RECTL rCtls[52];
43 ULONG ulNumRcls;
44
45 MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
46 { MRESULT rc;
47 rc = GlutWindowProc(hwnd, msg, mp1, mp2 );
48 return rc;
49 }
50
51 MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
52 {
53 HPS hps = NULLHANDLE; /* presentation space handle */
54 GLUTwindow* window; /* GLUT window associated with message. */
55 GLUTmenu* menu; /* GLUT menu associated with message. */
56 RECTL rclClient;
57 POINTL point;
58 int button = -1,rc,key;
59
60
61 /* Process the message. */
62
63 switch( msg )
64 {
65 case WM_CREATE:
66 {
67 SIZEL sizl = { 0L, 0L };
68 LONG *alCaps;
69 HDC hdc;
70
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 );
77
78 hdc = WinOpenWindowDC(hwnd);
79
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,
87 hdc,
88 &sizl,
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;
93 // PaletteInit(3);
94 /* ¯¥p¥¢®¤ hpsBuffer ¢ p¥¦¨¬ RGB color table */
95
96 GpiCreateLogColorTable(hpsCurrent,0 ,LCOLF_RGB,0,0,NULL);
97 GpiSetPattern(hpsCurrent,PATSYM_SOLID);
98 GpiSetPatternSet(hpsCurrent,LCID_DEFAULT);
99
100 }
101 break;
102
103 return 0;
104 case WM_CLOSE:
105 WinPostMsg( hwnd, WM_QUIT, NULL, NULL );
106
107 return 0;
108
109 case WM_PAINT:
110 window = __glutGetWindow(hwnd);
111 if (window)
112 {
113 PWMC ctx;
114 // hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
115 hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
116 // blit Dive buffer to screen.
117
118 {
119 SWP swp; // Window position
120 POINTL pointl; // Point to offset from Desktop
121
122 // Convert the point to offset from desktop lower left.
123 pointl.x = 0;
124 pointl.y = 0;
125 WinMapWindowPoints ( hwnd, HWND_DESKTOP, &pointl, 1 );
126
127
128 // ctx = window->ctx;
129 // ctx->xDiveScr = pointl.x;
130 // ctx->yDiveScr = pointl.y;
131 }
132 // rc = DiveBlitImage (ctx->hDive,
133 // ctx->ulDiveBufferNumber,
134 // DIVE_BUFFER_SCREEN );
135 //
136
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);
141 }
142 WinEndPaint(hps);
143 } else {
144
145 hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
146 WinFillRect(hps, &rclClient, CLR_WHITE);
147 WinEndPaint(hps);
148 }
149 break;
150
151 case WM_VRNDISABLED:
152
153 // pwinData->fDataInProcess = TRUE;
154 // DiveSetupBlitter ( pwinData->hDive, 0 );
155 // pwinData->fVrnDisabled = TRUE;
156 break;
157
158 case WM_VRNENABLED:
159 { HRGN hrgn; /* Region handle */
160 RGNRECT rgnCtl; /* Processing control structure */
161 // RECTL rCtls[52];
162 // ULONG ulNumRcls;
163
164 // pwinData->fDataInProcess = TRUE;
165 hps = WinGetPS ( hwnd );
166 if ( !hps )
167 break;
168 hrgn = GpiCreateRegion ( hps, 0L, NULL );
169 if ( hrgn )
170 { /* NOTE: If mp1 is zero, then this was just a move message.
171 ** Illustrate the visible region on a WM_VRNENABLE.
172 */
173 WinQueryVisibleRegion ( hwnd, hrgn );
174 rgnCtl.ircStart = 0;
175 rgnCtl.crc = 50;
176 rgnCtl.ulDirection = 1;
177
178 /* Get the all ORed rectangles */
179 if ( GpiQueryRegionRects ( hps, hrgn, NULL,
180 &rgnCtl, rCtls) )
181 {
182 ulNumRcls = rgnCtl.crcReturned;
183
184 /* Now find the window position and size, relative to parent.
185 */
186 // WinQueryWindowPos ( pwinData->hwndClient, &pwinData->swp );
187
188 // rcl.xLeft = 0;
189 // rcl.yBottom = 0;
190
191 /* Convert the point to offset from desktop lower left.
192 */
193 // pointl.x = pwinData->swp.x;
194 // pointl.y = pwinData->swp.y;
195
196 // WinMapWindowPoints ( pwinData->hwndFrame,
197 // HWND_DESKTOP, &pointl, 1 );
198
199 // pwinData->cxWindowPos = pointl.x;
200 // pwinData->cyWindowPos = pointl.y;
201
202 }
203 GpiDestroyRegion( hps, hrgn );
204 }
205 WinReleasePS( hps );
206
207 }
208 break;
209
210 case WM_SIZE:
211 window = __glutGetWindow(hwnd);
212 if (window)
213 { int width,height;
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);
220 }
221 #endif
222 window->width = width;
223 window->height = height;
224 __glutSetWindow(window);
225 if(width <= 0 || height <= 0)
226 break;
227 _mesa_ResizeBuffersMESA();
228
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
234 repair request. */
235 __glutPostRedisplay(window, GLUT_REPAIR_WORK);
236 }
237 }
238 return 0;
239 case WM_SHOW:
240 window = __glutGetWindow(hwnd);
241 if (window) {
242 int visState;
243 visState = SHORT1FROMMP( mp1 );
244 updateWindowState(window, visState);
245 }
246 return 0;
247
248 case WM_ACTIVATE:
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);
253 // }
254 if (window) {
255 int visState;
256 visState = SHORT1FROMMP( mp1 );
257 updateWindowState(window, visState);
258 }
259 return 0;
260
261 case WM_CHAR:
262 { USHORT fsflags;
263 window = __glutGetWindow(hwnd);
264 if (!window) {
265 break;
266 }
267 fsflags = SHORT1FROMMP(mp1);
268 /* ?? */
269 if((fsflags & KC_KEYUP) ) /* ¨£­®p¨p㥬 ®â¦ â¨¥ ª­®¯ª¨, p¥ £¨p㥬 ⮫쪮 ­  ­ ¦ â¨¥ */
270 break;
271 ///////////////////////////////////////////////////
272 if(!(fsflags & KC_CHAR) )
273 {
274 if (!(fsflags & KC_VIRTUALKEY))
275 break;
276 key = 0;
277 /* Get the virtual key from mp2. */
278 switch (SHORT2FROMMP(mp2))
279 {
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;
285
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;
291
292 /* function keys */
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;
308 }
309 if(!key)
310 { break; /* Key Not implemented */
311 }
312 if(key > 0)
313 { if (!window->special) /* ­¥ ãáâ ­®¢«¥­® ®¡à ¡®â稪  */
314 break;
315
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;
328 return 0;
329 }
330
331 }
332 /////////////////////////////////////////////////////
333 /* If we are ignoring auto repeated key strokes for the window, bail. */
334 if (window->ignoreKeyRepeat && (CHAR3FROMMP(mp1)) )
335 break;
336 if(!((unsigned char)SHORT1FROMMP(mp2)) ) /* ¨£­®p¨p㥬 ­¥á¨¬¢®«ì­ë¥ ª®¤ë */
337 break;
338 if (window->keyboard) {
339 WinQueryPointerPos(HWND_DESKTOP,&point);
340
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;
352 }
353 return 0;
354 } /* endof case WM_CHAR: */
355 ////////////////////////////////////////////////
356 case WM_BUTTON1DOWN:
357 button = GLUT_LEFT_BUTTON;
358 case WM_BUTTON3DOWN:
359 if (button < 0)
360 button = GLUT_MIDDLE_BUTTON;
361 case WM_BUTTON2DOWN:
362 if (button < 0)
363 button = GLUT_RIGHT_BUTTON;
364 { POINTS psh;
365 psh = *((POINTS *)&mp1);
366 point.x = psh.x;
367 point.y = psh.y;
368 }
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
373 properly. */
374 if (button == GLUT_MIDDLE_BUTTON)
375 return 0;
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);
382 return 0;
383 }
384 window = __glutGetWindow(hwnd);
385 if (window) {
386 window->buttonDownState = button+1;
387 menu = __glutGetMenuByNum(window->menu[button]);
388 if (menu) {
389 //todo
390 // __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
391 // button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON :
392 // 0x0001;
393 // __glutStartMenu(menu, window, point.x, point.y, x, y);
394 } else if (window->mouse) {
395
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;
406 } else {
407 /* Stray mouse events. Ignore. */
408 }
409 }
410 return 0;
411
412 break;
413 /********************************************/
414 case WM_BUTTON1UP:
415 button = GLUT_LEFT_BUTTON;
416 case WM_BUTTON3UP:
417 if (button < 0)
418 button = GLUT_MIDDLE_BUTTON;
419 case WM_BUTTON2UP:
420 if (button < 0)
421 button = GLUT_RIGHT_BUTTON;
422 { POINTS psh;
423 psh = *((POINTS *)&mp1);
424 point.x = psh.x;
425 point.y = psh.y;
426 }
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) {
435 return 0;
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. */
440 #if 0
441 int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
442 if (item != -1)
443 __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
444 else
445 __glutItemSelected = NULL;
446 __glutFinishMenu(hwnd, point.x, point.y);
447 #endif
448 } else {
449 __glutItemSelected = NULL;
450 __glutFinishMenu(hwnd, point.x, point.y);
451 }
452 return 0;
453 }
454
455 window = __glutGetWindow(hwnd);
456 if(window)
457 window->buttonDownState = 0;
458
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);
469
470 __glutModifierMask = (unsigned int)~0;
471 } else {
472 /* Window might have been destroyed and all the
473 events for the window may not yet be received. */
474 }
475 return 0;
476
477
478 break;
479 //////////////////////////////////////////////////
480 case WM_COMMAND:
481 window = __glutGetWindow(hwnd);
482 if (window)
483 { if (window->wm_command)
484 window->wm_command(hwnd,mp1,mp2);
485 }
486 break;
487
488 case WM_MOUSEMOVE:
489 if (!__glutMappedMenu) {
490 window = __glutGetWindow(hwnd);
491 if (window) {
492 /* If motion function registered _and_ buttons held *
493 down, call motion function... */
494 { POINTS psh;
495 psh = *((POINTS *)&mp1);
496 point.x = psh.x;
497 point.y = psh.y;
498 }
499
500 if (window->motion && window->buttonDownState) {
501 __glutSetWindow(window);
502 window->motion(point.x, point.y);
503 }
504 /* If passive motion function registered _and_
505 buttons not held down, call passive motion
506 function... */
507 else if (window->passive && !window->buttonDownState) {
508 __glutSetWindow(window);
509 window->passive(point.x, point.y);
510 }
511 }
512 } else {
513 /* Motion events are thrown away when a pop up menu is
514 active. */
515 }
516 return 0;
517
518
519 default:
520 /* For all other messages, let the default window procedure process them. */
521 return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
522
523 } //endof switch( msg )
524 return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
525 // return NULL;
526 }
527
528 void APIENTRY glutCommandFunc(GLUTcommandCB Func)
529 {
530 extern GLUTwindow *__glutCurrentWindow;
531 __glutCurrentWindow->wm_command = Func;
532 }
533
534
535
536
537 void
538 updateWindowState(GLUTwindow *window, int visState)
539 {
540 GLUTwindow* child;
541
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);
549 }
550 }
551 /* Since Win32 only sends an activate for the toplevel window,
552 update the visibility for all the child windows. */
553 child = window->children;
554 while (child) {
555 updateWindowState(child, visState);
556 child = child->siblings;
557 }
558 }
559
560 #if POKA
561
562 LONG WINAPI
563 __glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
564 {
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;
571 int button = -1;
572
573 switch(msg) {
574 case WM_CREATE:
575 return 0;
576 case WM_CLOSE:
577 PostQuitMessage(0);
578 return 0;
579 #if 0
580 case WM_DESTROY:
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
587 data structures. */
588 window = __glutGetWindow(hwnd);
589 if (window) {
590 if (window->ctx) {
591 wglMakeCurrent(NULL, NULL);
592 wglDeleteContext(window->ctx);
593 }
594 }
595 return 0;
596 #endif
597
598 case WM_SYSKEYUP:
599 case WM_KEYUP:
600 window = __glutGetWindow(hwnd);
601 if (!window) {
602 break;
603 }
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);
612 }
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;
624 switch (wParam) {
625 /* *INDENT-OFF* */
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;
647 case VK_DELETE:
648 /* Delete is an ASCII character. */
649 if (window->keyboardUp) {
650 window->keyboardUp((unsigned char) 127, point.x, point.y);
651 }
652 return 0;
653 /* *INDENT-ON* */
654 default:
655 if (window->keyboardUp) {
656 key = MapVirtualKey(wParam, 2); /* Map to ASCII. */
657 if (isascii(key) && (key != 0)) {
658
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. */
662
663 if (!(__glutModifierMask & ShiftMask))
664 key = tolower(key);
665 window->keyboardUp((unsigned char) key, point.x, point.y);
666 }
667 }
668 __glutModifierMask = (unsigned int) ~0;
669 return 0;
670 }
671 if (window->specialUp) {
672 window->specialUp(key, point.x, point.y);
673 }
674 __glutModifierMask = (unsigned int) ~0;
675 }
676 return 0;
677
678 case WM_SYSCHAR:
679 case WM_CHAR:
680 window = __glutGetWindow(hwnd);
681 if (!window) {
682 break;
683 }
684
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)) ) {
688 break;
689 }
690
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);
699 }
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;
713 }
714 return 0;
715
716 case WM_SYSKEYDOWN:
717 case WM_KEYDOWN:
718 window = __glutGetWindow(hwnd);
719 if (!window) {
720 break;
721 }
722
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)) ) {
726 break;
727 }
728
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);
737 }
738 if (window->special) {
739 switch (wParam) {
740 /* *INDENT-OFF* */
741 /* function keys */
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;
759 /* *INDENT-ON* */
760
761 case VK_PRIOR:
762 /* VK_PRIOR is Win32's Page Up */
763 key = GLUT_KEY_PAGE_UP;
764 break;
765 case VK_NEXT:
766 /* VK_NEXT is Win32's Page Down */
767 key = GLUT_KEY_PAGE_DOWN;
768 break;
769 case VK_HOME:
770 key = GLUT_KEY_HOME;
771 break;
772 case VK_END:
773 key = GLUT_KEY_END;
774 break;
775 case VK_INSERT:
776 key = GLUT_KEY_INSERT;
777 break;
778 case VK_DELETE:
779 goto handleDelete;
780 default:
781 goto defproc;
782 }
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. */
798 switch (wParam) {
799 case VK_DELETE:
800 handleDelete:
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;
814 return 0;
815 default:
816 /* Let the following WM_SYSCHAR or WM_CHAR message generate
817 the keyboard callback. */
818 break;
819 }
820 }
821 return 0;
822
823 case WM_LBUTTONDOWN:
824 button = GLUT_LEFT_BUTTON;
825 case WM_MBUTTONDOWN:
826 if (button < 0)
827 button = GLUT_MIDDLE_BUTTON;
828 case WM_RBUTTONDOWN:
829 if (button < 0)
830 button = GLUT_RIGHT_BUTTON;
831
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
836 properly. */
837 if (button == GLUT_MIDDLE_BUTTON)
838 return 0;
839 GetCursorPos(&point);
840 ScreenToClient(hwnd, &point);
841 __glutItemSelected = NULL;
842 __glutFinishMenu(hwnd, point.x, point.y);
843 return 0;
844 }
845
846 /* set the capture so we can get mouse events outside the window */
847 SetCapture(hwnd);
848
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. */
852 x = LOWORD(lParam);
853 y = HIWORD(lParam);
854 if(x & 1 << 15) x -= (1 << 16);
855 if(y & 1 << 15) y -= (1 << 16);
856
857 window = __glutGetWindow(hwnd);
858 if (window) {
859 menu = __glutGetMenuByNum(window->menu[button]);
860 if (menu) {
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 :
865 0x0001;
866 __glutStartMenu(menu, window, point.x, point.y, x, y);
867 } else if (window->mouse) {
868
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;
879 } else {
880 /* Stray mouse events. Ignore. */
881 }
882 }
883 return 0;
884
885 case WM_LBUTTONUP:
886 button = GLUT_LEFT_BUTTON;
887 case WM_MBUTTONUP:
888 if (button < 0)
889 button = GLUT_MIDDLE_BUTTON;
890 case WM_RBUTTONUP:
891 if (button < 0)
892 button = GLUT_RIGHT_BUTTON;
893
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) {
901 return 0;
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. */
906 #if 0
907 int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
908 if (item != -1)
909 __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
910 else
911 __glutItemSelected = NULL;
912 __glutFinishMenu(hwnd, point.x, point.y);
913 #endif
914 } else {
915 __glutItemSelected = NULL;
916 __glutFinishMenu(hwnd, point.x, point.y);
917 }
918 return 0;
919 }
920
921 /* Release the mouse capture. */
922 ReleaseCapture();
923
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. */
929 x = LOWORD(lParam);
930 y = HIWORD(lParam);
931 if(x & 1 << 15) x -= (1 << 16);
932 if(y & 1 << 15) y -= (1 << 16);
933
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;
944 } else {
945 /* Window might have been destroyed and all the
946 events for the window may not yet be received. */
947 }
948 return 0;
949
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
954 idle func. */
955 SetTimer(hwnd, 1, 1, NULL);
956 return 0;
957
958 case WM_TIMER:
959 #if 0
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. */
964 if (wParam == 2)
965 return 0;
966 #endif
967
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. */
975 #if 0
976 if (__glutIdleFunc)
977 __glutIdleFunc();
978 #endif
979 if (__glutTimerList)
980 handleTimeouts();
981 return 0;
982
983 case WM_EXITMENULOOP:
984 /* nuke the above created timer...we don't need it anymore, since
985 the menu is gone now. */
986 KillTimer(hwnd, 1);
987 return 0;
988
989 case WM_MENUSELECT:
990 if (lParam != 0)
991 __glutHMenu = (HMENU)lParam;
992 return 0;
993
994 case WM_COMMAND:
995 if (__glutMappedMenu) {
996 if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
997 __glutItemSelected = NULL;
998 else
999 __glutItemSelected =
1000 __glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
1001 GetCursorPos(&point);
1002 ScreenToClient(hwnd, &point);
1003 __glutFinishMenu(hwnd, point.x, point.y);
1004 }
1005 return 0;
1006
1007 case WM_MOUSEMOVE:
1008 if (!__glutMappedMenu) {
1009 window = __glutGetWindow(hwnd);
1010 if (window) {
1011 /* If motion function registered _and_ buttons held *
1012 down, call motion function... */
1013 x = LOWORD(lParam);
1014 y = HIWORD(lParam);
1015
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);
1021
1022 if (window->motion && wParam &
1023 (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
1024 __glutSetWindow(window);
1025 window->motion(x, y);
1026 }
1027 /* If passive motion function registered _and_
1028 buttons not held down, call passive motion
1029 function... */
1030 else if (window->passive &&
1031 ((wParam &
1032 (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
1033 0)) {
1034 __glutSetWindow(window);
1035 window->passive(x, y);
1036 }
1037 }
1038 } else {
1039 /* Motion events are thrown away when a pop up menu is
1040 active. */
1041 }
1042 return 0;
1043
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);
1057 return 0;
1058
1059 case WM_SIZE:
1060 window = __glutGetWindow(hwnd);
1061 if (window) {
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);
1068 }
1069 #endif
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! */
1075 GdiFlush();
1076 window->reshape(width, height);
1077 window->forceReshape = FALSE;
1078 /* A reshape should be considered like posting a
1079 repair request. */
1080 __glutPostRedisplay(window, GLUT_REPAIR_WORK);
1081 }
1082 }
1083 return 0;
1084
1085 case WM_SETCURSOR:
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) {
1092 goto defproc;
1093 }
1094 window = __glutGetWindow(hwnd);
1095 if (window) {
1096 __glutSetCursor(window);
1097 }
1098 /* TODO: check out the info in DevStudio on WM_SETCURSOR in the
1099 DefaultAction section. */
1100 return 1;
1101
1102 case WM_SETFOCUS:
1103 window = __glutGetWindow(hwnd);
1104 if (window) {
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
1111 callbacks. */
1112 }
1113 if (window->joystick && __glutCurrentWindow) {
1114 if (__glutCurrentWindow->joyPollInterval > 0) {
1115 MMRESULT result;
1116
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) {
1123 return 0;
1124 }
1125 (void) joySetThreshold(JOYSTICKID1,
1126 __glutCurrentWindow->joyPollInterval);
1127 }
1128 }
1129 }
1130 return 0;
1131
1132 case WM_KILLFOCUS:
1133 window = __glutGetWindow(hwnd);
1134 if (window) {
1135 window->entryState = WM_KILLFOCUS;
1136 if (window->entry) {
1137 __glutSetWindow(window);
1138 window->entry(GLUT_LEFT);
1139 }
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);
1146 }
1147 }
1148 }
1149 return 0;
1150 case WM_ACTIVATE:
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);
1155 }
1156 if (window) {
1157 int visState;
1158
1159 /* HIWORD(wParam) is the minimized flag. */
1160 visState = !HIWORD(wParam);
1161 updateWindowState(window, visState);
1162 }
1163 return 0;
1164
1165 /* Colour Palette Management */
1166 case WM_PALETTECHANGED:
1167 if (hwnd == (HWND)wParam) {
1168 /* Don't respond to the message that we sent! */
1169 break;
1170 }
1171 /* fall through to WM_QUERYNEWPALETTE */
1172
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);
1179 return TRUE;
1180 }
1181 return FALSE;
1182
1183 case MM_JOY1MOVE:
1184 case MM_JOY1ZMOVE:
1185 window = __glutGetWindow(hwnd);
1186 if (window->joystick) {
1187 JOYINFOEX jix;
1188 int x, y, z;
1189
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);
1195
1196 #define SCALE(v) ((int) ((v - 32767)/32.768))
1197
1198 /* Convert to integer for scaling. */
1199 x = jix.dwXpos;
1200 y = jix.dwYpos;
1201 z = jix.dwZpos;
1202 window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));
1203
1204 return TRUE;
1205 }
1206 return FALSE;
1207 case MM_JOY1BUTTONDOWN:
1208 case MM_JOY1BUTTONUP:
1209 window = __glutGetWindow(hwnd);
1210 if (window->joystick) {
1211 JOYINFOEX jix;
1212
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);
1218
1219 return TRUE;
1220 }
1221 return FALSE;
1222
1223 #if 0
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:
1227 break;
1228 case WM_NCHITTEST:
1229 /* This event is generated by every mouse move event. */
1230 goto defproc;
1231 case WM_NCMOUSEMOVE:
1232 goto defproc;
1233 case WM_NCACTIVATE:
1234 goto defproc;
1235 case WM_NCPAINT:
1236 goto defproc;
1237 case WM_NCCALCSIZE:
1238 goto defproc;
1239 case WM_NCCREATE:
1240 goto defproc;
1241 case WM_NCDESTROY:
1242 goto defproc;
1243 case WM_NCLBUTTONDOWN:
1244 goto defproc;
1245 case WM_SETTEXT:
1246 goto defproc;
1247 case WM_GETTEXT:
1248 goto defproc;
1249 case WM_ACTIVATEAPP:
1250 goto defproc;
1251 case WM_GETICON:
1252 goto defproc;
1253 case WM_ERASEBKGND:
1254 goto defproc;
1255 case WM_WINDOWPOSCHANGING:
1256 goto defproc;
1257 case WM_WINDOWPOSCHANGED:
1258 goto defproc;
1259 case WM_MOUSEACTIVATE:
1260 goto defproc;
1261 case WM_SHOWWINDOW:
1262 goto defproc;
1263 case WM_MOVING:
1264 goto defproc;
1265 case WM_MOVE:
1266 goto defproc;
1267 case WM_KEYUP:
1268 goto defproc;
1269 case WM_CAPTURECHANGED:
1270 goto defproc;
1271 case WM_SYSCOMMAND:
1272 goto defproc;
1273 case WM_ENTERSIZEMOVE:
1274 goto defproc;
1275 case WM_ENTERIDLE:
1276 goto defproc;
1277 #endif
1278
1279 default:
1280 goto defproc;
1281 }
1282
1283 defproc:
1284 return DefWindowProc(hwnd, msg, wParam, lParam);
1285 }
1286
1287 #endif
1288
1289 #if defined(__OS2PM__)
1290 Bool __glutSetWindowText(Window window, char *text)
1291 {
1292 return WinSetWindowText(window, (PCSZ)text);
1293
1294 }
1295
1296 #endif