source: trunk/src/opengl/glut/win32_winproc.c

Last change on this file was 3083, checked in by sandervl, 25 years ago

compile fixes + cleanup

File size: 26.0 KB
Line 
1/* $Id: win32_winproc.c,v 1.5 2000-03-11 15:07:48 sandervl Exp $ */
2/* Copyright (c) Nate Robins, 1997. */
3/* portions Copyright (c) Mark Kilgard, 1997, 1998. */
4
5/* This program is freely distributable without licensing fees
6 and is provided without guarantee or warrantee expressed or
7 implied. This program is -not- in the public domain. */
8
9
10#include "glutint.h"
11#if defined(__WIN32OS2__)
12//#include "wgl.h"
13#include <ctype.h>
14#endif
15#if defined(__CYGWIN32__)
16typedef MINMAXINFO* LPMINMAXINFO;
17#else
18#include <sys/timeb.h>
19#endif
20
21#if defined(_WIN32) || defined(__WIN32OS2__)
22#include <mmsystem.h> /* Win32 Multimedia API header. */
23#endif
24
25extern unsigned __glutMenuButton;
26extern GLUTidleCB __glutIdleFunc;
27extern GLUTtimer *__glutTimerList;
28extern void handleTimeouts(void);
29extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, UINT unique);
30static HMENU __glutHMenu;
31
32void
33updateWindowState(GLUTwindow *window, int visState)
34{
35 GLUTwindow* child;
36
37 /* XXX shownState and visState are the same in Win32. */
38 window->shownState = visState;
39 if (visState != window->visState) {
40 if (window->windowStatus) {
41 window->visState = visState;
42 __glutSetWindow(window);
43 ((GLUTwindowStatusCB)(window->windowStatus))(visState);
44 }
45 }
46 /* Since Win32 only sends an activate for the toplevel window,
47 update the visibility for all the child windows. */
48 child = window->children;
49 while (child) {
50 updateWindowState(child, visState);
51 child = child->siblings;
52 }
53}
54
55LONG WINAPI
56__glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
57{
58 POINT point; /* Point structure. */
59 PAINTSTRUCT ps; /* Paint structure. */
60 LPMINMAXINFO minmax; /* Minimum/maximum info structure. */
61 GLUTwindow* window; /* GLUT window associated with message. */
62 GLUTmenu* menu; /* GLUT menu associated with message.*/
63 int x, y, width, height, key;
64 int button = -1;
65 int fSendKeyStroke=1;
66
67 switch(msg) {
68 case WM_CREATE:
69 return 0;
70 case WM_CLOSE:
71 PostQuitMessage(0);
72 return 0;
73#if defined(__WIN32OS2__)
74 case WM_DESTROY:
75 /* XXX NVidia's NT OpenGL can have problems closing down
76 its OpenGL internal data structures if we just allow
77 the process to terminate without unbinding and deleting
78 the windows context. Apparently, DirectDraw unloads
79 before OPENGL32.DLL in the close down sequence, but
80 NVidia's NT OpenGL needs DirectDraw to close down its
81 data structures. */
82 window = __glutGetWindow(hwnd);
83 if (window) {
84 if (window->ctx) {
85 wglMakeCurrent(NULL, NULL);
86 wglDeleteContext(window->ctx);
87 }
88 }
89 return 0;
90#endif
91 case WM_PAINT:
92 window = __glutGetWindow(hwnd);
93 if (window) {
94/*
95#ifndef __WIN32OS2__
96 BeginPaint(hwnd, &ps);
97 EndPaint(hwnd, &ps);
98#endif */
99 if (window->win == hwnd) {
100 __glutPostRedisplay(window, GLUT_REPAIR_WORK);
101 } else if (window->overlay && window->overlay->win == hwnd) {
102 __glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);
103 }
104 }
105 return 0;
106
107 case WM_SYSKEYUP:
108 case WM_KEYUP:
109 window = __glutGetWindow(hwnd);
110 if (!window) {
111 break;
112 }
113 /* Win32 is dumb and sends these messages only to the parent
114 window. Therefore, find out if we're in a child window and
115 call the child windows keyboard callback if we are. */
116 if (window->parent) {
117 GetCursorPos(&point);
118 ScreenToClient(hwnd, &point);
119 hwnd = ChildWindowFromPoint(hwnd, point);
120 window = __glutGetWindow(hwnd);
121 }
122 if (window->specialUp || window->keyboardUp) {
123 GetCursorPos(&point);
124 ScreenToClient(window->win, &point);
125 __glutSetWindow(window);
126 __glutModifierMask = 0;
127 if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
128 __glutModifierMask |= ShiftMask;
129 if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
130 __glutModifierMask |= ControlMask;
131 if (GetKeyState(VK_MENU) < 0)
132 __glutModifierMask |= Mod1Mask;
133 switch (wParam) {
134 /* *INDENT-OFF* */
135 case VK_F1: key = GLUT_KEY_F1; break;
136 case VK_F2: key = GLUT_KEY_F2; break;
137 case VK_F3: key = GLUT_KEY_F3; break;
138 case VK_F4: key = GLUT_KEY_F4; break;
139 case VK_F5: key = GLUT_KEY_F5; break;
140 case VK_F6: key = GLUT_KEY_F6; break;
141 case VK_F7: key = GLUT_KEY_F7; break;
142 case VK_F8: key = GLUT_KEY_F8; break;
143 case VK_F9: key = GLUT_KEY_F9; break;
144 case VK_F10: key = GLUT_KEY_F10; break;
145 case VK_F11: key = GLUT_KEY_F11; break;
146 case VK_F12: key = GLUT_KEY_F12; break;
147 case VK_LEFT: key = GLUT_KEY_LEFT; break;
148 case VK_UP: key = GLUT_KEY_UP; break;
149 case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
150 case VK_DOWN: key = GLUT_KEY_DOWN; break;
151 case VK_PRIOR: key = GLUT_KEY_PAGE_UP; break;
152 case VK_NEXT: key = GLUT_KEY_PAGE_DOWN; break;
153 case VK_HOME: key = GLUT_KEY_HOME; break;
154 case VK_END: key = GLUT_KEY_END; break;
155 case VK_INSERT: key = GLUT_KEY_INSERT; break;
156 case VK_DELETE:
157 /* Delete is an ASCII character. */
158 if (window->keyboardUp) {
159 ((GLUTkeyboardCB)(window->keyboardUp))((unsigned char) 127, point.x, point.y);
160 }
161 return 0;
162 /* *INDENT-ON* */
163 default:
164 if (window->keyboardUp) {
165 key = MapVirtualKey(wParam, 2); /* Map to ASCII.*/
166 if (isascii(key) && (key != 0)) {
167
168 /* XXX Attempt to determine modified ASCII character
169 is quite incomplete. Digits, symbols, CapsLock,
170 Ctrl, and numeric keypad are all ignored. Fix this. */
171
172 if (!(__glutModifierMask & ShiftMask))
173 key = tolower(key);
174 ((GLUTkeyboardCB)(window->keyboardUp))((unsigned char) key, point.x, point.y);
175 }
176 }
177 __glutModifierMask = (unsigned int) ~0;
178 return 0;
179 }
180 if (window->specialUp) {
181 window->specialUp(key, point.x, point.y);
182 }
183 __glutModifierMask = (unsigned int) ~0;
184 }
185 return 0;
186
187 case WM_SYSCHAR:
188 case WM_CHAR:
189 window = __glutGetWindow(hwnd);
190 if (!window) {
191 break;
192 }
193
194 /* Bit 30 of lParam is set if key already held down. If
195 we are ignoring auto repeated key strokes for the window, bail. */
196 if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
197 break;
198 }
199
200 /* Win32 is dumb and sends these messages only to the parent
201 window. Therefore, find out if we're in a child window and
202 call the child windows keyboard callback if we are. */
203 if (window->parent) {
204 GetCursorPos(&point);
205 ScreenToClient(hwnd, &point);
206 hwnd = ChildWindowFromPoint(hwnd, point);
207 window = __glutGetWindow(hwnd);
208 }
209 if (window->keyboard) {
210 GetCursorPos(&point);
211 ScreenToClient(window->win, &point);
212 __glutSetWindow(window);
213 __glutModifierMask = 0;
214 if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on*/
215 __glutModifierMask |= ShiftMask;
216 if (GetKeyState(VK_CONTROL) < 0)
217 __glutModifierMask |= ControlMask;
218 if (GetKeyState(VK_MENU) < 0)
219 __glutModifierMask |= Mod1Mask;
220 ((GLUTkeyboardCB)(window->keyboard))((unsigned char)wParam, point.x, point.y);
221 __glutModifierMask = (unsigned int) ~0;
222 }
223 return 0;
224
225 case WM_SYSKEYDOWN:
226 case WM_KEYDOWN:
227 window = __glutGetWindow(hwnd);
228 if (!window) {
229 break;
230 }
231
232 /* Bit 30 of lParam is set if key already held down. If
233 we are ignoring auto repeated key strokes for the window, bail. */
234 if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
235 break;
236 }
237
238 /* Win32 is dumb and sends these messages only to the parent
239 window. Therefore, find out if we're in a child window and
240 call the child windows keyboard callback if we are. */
241 if (window->parent) {
242 GetCursorPos(&point);
243 ScreenToClient(hwnd, &point);
244 hwnd = ChildWindowFromPoint(hwnd, point);
245 window = __glutGetWindow(hwnd);
246 }
247 if (window->special) {
248 switch (wParam) {
249 /* *INDENT-OFF* */
250 /* function keys */
251 case VK_F1: key = GLUT_KEY_F1; break;
252 case VK_F2: key = GLUT_KEY_F2; break;
253 case VK_F3: key = GLUT_KEY_F3; break;
254 case VK_F4: key = GLUT_KEY_F4; break;
255 case VK_F5: key = GLUT_KEY_F5; break;
256 case VK_F6: key = GLUT_KEY_F6; break;
257 case VK_F7: key = GLUT_KEY_F7; break;
258 case VK_F8: key = GLUT_KEY_F8; break;
259 case VK_F9: key = GLUT_KEY_F9; break;
260 case VK_F10: key = GLUT_KEY_F10; break;
261 case VK_F11: key = GLUT_KEY_F11; break;
262 case VK_F12: key = GLUT_KEY_F12; break;
263 /* directional keys */
264 case VK_LEFT: key = GLUT_KEY_LEFT; break;
265 case VK_UP: key = GLUT_KEY_UP; break;
266 case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
267 case VK_DOWN: key = GLUT_KEY_DOWN; break;
268 /* *INDENT-ON* */
269
270 case VK_PRIOR:
271 /* VK_PRIOR is Win32's Page Up */
272 key = GLUT_KEY_PAGE_UP;
273 break;
274 case VK_NEXT:
275 /* VK_NEXT is Win32's Page Down */
276 key = GLUT_KEY_PAGE_DOWN;
277 break;
278 case VK_HOME:
279 key = GLUT_KEY_HOME;
280 break;
281 case VK_END:
282 key = GLUT_KEY_END;
283 break;
284 case VK_INSERT:
285 key = GLUT_KEY_INSERT;
286 break;
287 case VK_DELETE:
288 goto handleDelete;
289 default:
290 goto defproc;
291 }
292 GetCursorPos(&point);
293 ScreenToClient(window->win, &point);
294 __glutSetWindow(window);
295 __glutModifierMask = 0;
296 if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on*/
297 __glutModifierMask |= ShiftMask;
298 if (GetKeyState(VK_CONTROL) < 0)
299 __glutModifierMask |= ControlMask;
300 if (GetKeyState(VK_MENU) < 0)
301 __glutModifierMask |= Mod1Mask;
302 window->special(key, point.x, point.y);
303 __glutModifierMask = (unsigned int) ~0;
304 } else if (window->keyboard) {
305 /* Specially handle any keys that match ASCII values but
306 do not generate Windows WM_SYSCHAR or WM_CHAR messages. */
307
308 switch (wParam) {
309 case VK_DELETE:
310 handleDelete:
311 /* Delete is an ASCII character. */
312 key=(unsigned char)127;
313 break;
314
315#ifdef __WIN32OS2__
316 /* For some reason Odin doesn't generate WM_CHARS for 'special' keys */
317 /* at least - none that are received here. Create 'em here!! */
318 case VK_F1:
319 case VK_F2:
320 case VK_F3:
321 case VK_F4:
322 case VK_F5:
323 case VK_F6:
324 case VK_F7:
325 case VK_F8:
326 case VK_F9:
327 case VK_F10:
328 case VK_F11:
329 case VK_F12:
330 case VK_LEFT:
331 case VK_UP:
332 case VK_RIGHT:
333 case VK_DOWN:
334 case VK_PRIOR:
335 case VK_NEXT:
336 case VK_HOME:
337 case VK_END:
338 case VK_INSERT:
339 case VK_ESCAPE:
340 key=wParam;
341 break;
342#endif
343
344 default:
345 /* Let the following WM_SYSCHAR or WM_CHAR message generate
346 the keyboard callback. */
347 fSendKeyStroke=0;
348 break;
349 }
350
351 if(fSendKeyStroke)
352 {
353 GetCursorPos(&point);
354 ScreenToClient(window->win, &point);
355 __glutSetWindow(window);
356 __glutModifierMask = 0;
357 if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on*/
358 __glutModifierMask |= ShiftMask;
359 if (GetKeyState(VK_CONTROL) < 0)
360 __glutModifierMask |= ControlMask;
361 if (GetKeyState(VK_MENU) < 0)
362 __glutModifierMask |= Mod1Mask;
363 ((GLUTkeyboardCB)(window->keyboard))(key, point.x, point.y);
364 __glutModifierMask = (unsigned int) ~0;
365
366 return 0;
367 }
368 }
369 return 0;
370
371 case WM_LBUTTONDOWN:
372 button = GLUT_LEFT_BUTTON;
373 case WM_MBUTTONDOWN:
374 if (button < 0)
375 button = GLUT_MIDDLE_BUTTON;
376 case WM_RBUTTONDOWN:
377 if (button < 0)
378 button = GLUT_RIGHT_BUTTON;
379
380 /* finish the menu if we get a button down message (user must have
381 cancelled the menu). */
382 if (__glutMappedMenu) {
383 /* TODO: take this out once the menu on middle mouse stuff works
384 properly. */
385/*
386 if (button == GLUT_MIDDLE_BUTTON)
387 return 0;*/
388 GetCursorPos(&point);
389 ScreenToClient(hwnd, &point);
390 __glutItemSelected = NULL;
391 __glutFinishMenu(hwnd, point.x, point.y);
392 return 0;
393 }
394
395 /* set the capture so we can get mouse events outside the window */
396 SetCapture(hwnd);
397
398 /* Win32 doesn't return the same numbers as X does when the mouse
399 goes beyond the upper or left side of the window. roll the
400 Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
401 x = LOWORD(lParam);
402 y = HIWORD(lParam);
403 if(x & 1 << 15) x -= (1 << 16);
404 if(y & 1 << 15) y -= (1 << 16);
405
406 window = __glutGetWindow(hwnd);
407 if (window) {
408 menu = __glutGetMenuByNum(window->menu[button]);
409 if (menu) {
410 point.x = LOWORD(lParam); point.y = HIWORD(lParam);
411 ClientToScreen(window->win, &point);
412 __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
413 button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON :
414 0x0001;
415 __glutStartMenu(menu, window, point.x, point.y, x, y);
416 } else if (window->mouse) {
417
418 __glutSetWindow(window);
419 __glutModifierMask = 0;
420 if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on. */
421 __glutModifierMask |= ShiftMask;
422 if (GetKeyState(VK_CONTROL) < 0)
423 __glutModifierMask |= ControlMask;
424 if (GetKeyState(VK_MENU) < 0)
425 __glutModifierMask |= Mod1Mask;
426 ((GLUTmouseCB)(window->mouse))(button, GLUT_DOWN, x, y);
427 __glutModifierMask = (unsigned int)~0;
428 } else {
429 /* Stray mouse events. Ignore. */
430 }
431 }
432 return 0;
433
434 case WM_LBUTTONUP:
435 button = GLUT_LEFT_BUTTON;
436 case WM_MBUTTONUP:
437 if (button < 0)
438 button = GLUT_MIDDLE_BUTTON;
439 case WM_RBUTTONUP:
440 if (button < 0)
441 button = GLUT_RIGHT_BUTTON;
442
443 /* Bail out if we're processing a menu. */
444 if (__glutMappedMenu) {
445 GetCursorPos(&point);
446 ScreenToClient(hwnd, &point);
447 /* if we're getting the middle button up signal, then something
448 on the menu was selected. */
449 if (button == GLUT_MIDDLE_BUTTON) {
450 return 0;
451 /* For some reason, the code below always returns -1 even
452 though the point IS IN THE ITEM! Therefore, just bail out if
453 we get a middle mouse up. The user must select using the
454 left mouse button. Stupid Win32. */
455#if 0
456 int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
457 if (item != -1)
458 __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
459 else
460 __glutItemSelected = NULL;
461 __glutFinishMenu(hwnd, point.x, point.y);
462#endif
463 } else {
464 __glutItemSelected = NULL;
465 __glutFinishMenu(hwnd, point.x, point.y);
466 }
467 return 0;
468 }
469
470 /* Release the mouse capture. */
471 ReleaseCapture();
472
473 window = __glutGetWindow(hwnd);
474 if (window && window->mouse) {
475 /* Win32 doesn't return the same numbers as X does when the
476 mouse goes beyond the upper or left side of the window. roll
477 the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
478 x = LOWORD(lParam);
479 y = HIWORD(lParam);
480 if(x & 1 << 15) x -= (1 << 16);
481 if(y & 1 << 15) y -= (1 << 16);
482
483 __glutSetWindow(window);
484 __glutModifierMask = 0;
485 if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
486 __glutModifierMask |= ShiftMask;
487 if (GetKeyState(VK_CONTROL) < 0)
488 __glutModifierMask |= ControlMask;
489 if (GetKeyState(VK_MENU) < 0)
490 __glutModifierMask |= Mod1Mask;
491 ((GLUTmouseCB)(window->mouse))(button, GLUT_UP, x, y);
492 __glutModifierMask = (unsigned int)~0;
493 } else {
494 /* Window might have been destroyed and all the
495 events for the window may not yet be received. */
496 }
497 return 0;
498
499 case WM_ENTERMENULOOP:
500 /* KLUDGE: create a timer that fires every 100 ms when we start a
501 menu so that we can still process the idle & timer events (that
502 way, the timers will fire during a menu pick and so will the
503 idle func. */
504 SetTimer(hwnd, 1, 1, NULL);
505 return 0;
506
507 case WM_TIMER:
508#if 0
509 /* If the timer id is 2, then this is the timer that is set up in
510 the main glut message processing loop, and we don't want to do
511 anything but acknowledge that we got it. It is used to prevent
512 CPU spiking when an idle function is installed. */
513 if (wParam == 2)
514 return 0;
515#endif
516
517 /* only worry about the idle function and the timeouts, since
518 these are the only events we expect to process during
519 processing of a menu. */
520 /* we no longer process the idle functions (as outlined in the
521 README), since drawing can't be done until the menu has
522 finished...it's pretty lame when the animation goes on, but
523 doesn't update, so you get this weird jerkiness. */
524#if 0
525 if (__glutIdleFunc)
526 ((GLUTidleCB)(__glutIdleFunc))();
527#endif
528 if (__glutTimerList)
529 handleTimeouts();
530 return 0;
531
532 case WM_EXITMENULOOP:
533 /* nuke the above created timer...we don't need it anymore, since
534 the menu is gone now. */
535 KillTimer(hwnd, 1);
536 return 0;
537
538 case WM_MENUSELECT:
539 if (lParam != 0)
540 __glutHMenu = (HMENU)lParam;
541 return 0;
542
543 case WM_COMMAND:
544 if (__glutMappedMenu) {
545 if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
546 __glutItemSelected = NULL;
547 else
548 __glutItemSelected =
549 __glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
550 GetCursorPos(&point);
551 ScreenToClient(hwnd, &point);
552 __glutFinishMenu(hwnd, point.x, point.y);
553 }
554 return 0;
555
556 case WM_MOUSEMOVE:
557 if (!__glutMappedMenu) {
558 window = __glutGetWindow(hwnd);
559 if (window) {
560 /* If motion function registered _and_ buttons held *
561 down, call motion function... */
562 x = LOWORD(lParam);
563 y = HIWORD(lParam);
564
565 /* Win32 doesn't return the same numbers as X does when the
566 mouse goes beyond the upper or left side of the window.
567 roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */
568 if(x & 1 << 15) x -= (1 << 16);
569 if(y & 1 << 15) y -= (1 << 16);
570
571 if (window->motion && wParam &
572 (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
573 __glutSetWindow(window);
574 ((GLUTmotionCB)(window->motion))(x, y);
575 }
576 /* If passive motion function registered _and_
577 buttons not held down, call passive motion
578 function... */
579 else if (window->passive &&
580 ((wParam &
581 (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
582 0)) {
583 __glutSetWindow(window);
584 ((GLUTpassiveCB)(window->passive))(x, y);
585 }
586 }
587 } else {
588 /* Motion events are thrown away when a pop up menu is
589 active. */
590 }
591 return 0;
592
593 case WM_GETMINMAXINFO:
594 /* this voodoo is brought to you by Win32 (again). It allows the
595 window to be bigger than the screen, and smaller than 100x100
596 (although it doesn't seem to help the y minimum). */
597 minmax = (LPMINMAXINFO)lParam;
598 minmax->ptMaxSize.x = __glutScreenWidth;
599 minmax->ptMaxSize.y = __glutScreenHeight;
600 minmax->ptMinTrackSize.x = 0;
601 minmax->ptMinTrackSize.y = 0;
602 minmax->ptMaxTrackSize.x = __glutScreenWidth +
603 GetSystemMetrics(SM_CXSIZE) * 2;
604 minmax->ptMaxTrackSize.y = __glutScreenHeight +
605 GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);
606 return 0;
607
608 case WM_SIZE:
609 window = __glutGetWindow(hwnd);
610 if (window) {
611 width = LOWORD(lParam);
612 height = HIWORD(lParam);
613 if (width != window->width || height != window->height) {
614#if 0 /* Win32 GLUT does not support overlays for now.*/
615 if (window->overlay) {
616 XResizeWindow(__glutDisplay, window->overlay->win, width, height);
617 }
618#endif
619 window->width = width;
620 window->height = height;
621 __glutSetWindow(window);
622 /* Do not execute OpenGL out of sequence with respect
623 to the SetWindowPos request! */
624 GdiFlush();
625 ((GLUTreshapeCB)(window->reshape))(width, height);
626 window->forceReshape = FALSE;
627 /* A reshape should be considered like posting a
628 repair request. */
629 __glutPostRedisplay(window, GLUT_REPAIR_WORK);
630 }
631 }
632 return 0;
633
634 case WM_SETCURSOR:
635 /* If the cursor is not in the client area, then we want to send
636 this message to the default window procedure ('cause its
637 probably in the border or title, and we don't handle that
638 cursor. otherwise, set our cursor. Win32 makes us set the
639 cursor every time the mouse moves (DUMB!). */
640 if(LOWORD(lParam) != HTCLIENT) {
641 goto defproc;
642 }
643 window = __glutGetWindow(hwnd);
644 if (window) {
645 __glutSetCursor(window);
646 }
647 /* TODO: check out the info in DevStudio on WM_SETCURSOR in the
648 DefaultAction section. */
649 return 1;
650
651 case WM_SETFOCUS:
652 window = __glutGetWindow(hwnd);
653 if (window) {
654 window->entryState = WM_SETFOCUS;
655 if (window->entry) {
656 __glutSetWindow(window);
657 ((GLUTentryCB)(window->entry))(GLUT_ENTERED);
658 /* XXX Generation of fake passive notify? See how much
659 work the X11 code does to support fake passive notify
660 callbacks. */
661 }
662 if (window->joystick && __glutCurrentWindow) {
663 if (__glutCurrentWindow->joyPollInterval > 0) {
664 MMRESULT result;
665
666 /* Because Win32 will only let one window capture the
667 joystick at a time, we must capture it when we get the
668 focus and release it when we lose the focus. */
669 result = joySetCapture(__glutCurrentWindow->win,
670 JOYSTICKID1, 0, TRUE);
671 if (result != JOYERR_NOERROR) {
672 return 0;
673 }
674 (void) joySetThreshold(JOYSTICKID1,
675 __glutCurrentWindow->joyPollInterval);
676 }
677 }
678 }
679 return 0;
680
681 case WM_KILLFOCUS:
682 window = __glutGetWindow(hwnd);
683 if (window) {
684 window->entryState = WM_KILLFOCUS;
685 if (window->entry) {
686 __glutSetWindow(window);
687 ((GLUTentryCB)(window->entry))(GLUT_LEFT);
688 }
689 if (window->joystick && __glutCurrentWindow) {
690 if (__glutCurrentWindow->joyPollInterval > 0) {
691 /* Because Win32 will only let one window capture the
692 joystick at a time, we must capture it when we get the
693 focus and release it when we lose the focus. */
694 (void) joyReleaseCapture(JOYSTICKID1);
695 }
696 }
697 }
698 return 0;
699 case WM_ACTIVATE:
700 window = __glutGetWindow(hwnd);
701 /* Make sure we re-select the correct palette if needed. */
702 if (LOWORD(wParam)) {
703 PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
704 }
705 if (window) {
706 int visState;
707
708 /* HIWORD(wParam) is the minimized flag. */
709 visState = !HIWORD(wParam);
710 updateWindowState(window, visState);
711 }
712 return 0;
713
714 /* Colour Palette Management */
715 case WM_PALETTECHANGED:
716 if (hwnd == (HWND)wParam) {
717 /* Don't respond to the message that we sent! */
718 break;
719 }
720 /* fall through to WM_QUERYNEWPALETTE */
721
722 case WM_QUERYNEWPALETTE:
723 window = __glutGetWindow(hwnd);
724 if (window && window->colormap) {
725 UnrealizeObject(window->colormap->cmap);
726 SelectPalette(window->hdc, window->colormap->cmap, FALSE);
727 RealizePalette(window->hdc);
728 return TRUE;
729 }
730 return FALSE;
731
732 case MM_JOY1MOVE:
733 case MM_JOY1ZMOVE:
734 window = __glutGetWindow(hwnd);
735 if (window->joystick) {
736 JOYINFOEX jix;
737 int x, y, z;
738
739 /* Because WIN32 only supports messages for X, Y, and Z
740 translations, we must poll for the rest */
741 jix.dwSize = sizeof(jix);
742 jix.dwFlags = JOY_RETURNALL;
743 joyGetPosEx(JOYSTICKID1,&jix);
744
745#define SCALE(v) ((int) ((v - 32767)/32.768))
746
747 /* Convert to integer for scaling. */
748 x = jix.dwXpos;
749 y = jix.dwYpos;
750 z = jix.dwZpos;
751 window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));
752
753 return TRUE;
754 }
755 return FALSE;
756 case MM_JOY1BUTTONDOWN:
757 case MM_JOY1BUTTONUP:
758 window = __glutGetWindow(hwnd);
759 if (window->joystick) {
760 JOYINFOEX jix;
761
762 /* Because WIN32 only supports messages for X, Y, and Z
763 translations, we must poll for the rest */
764 jix.dwSize = sizeof(jix);
765 jix.dwFlags = JOY_RETURNALL;
766 joyGetPosEx(JOYSTICKID1,&jix);
767
768 return TRUE;
769 }
770 return FALSE;
771
772#if 0
773 /* Miscellaneous messages (don't really need to enumerate them,
774 but it's good to know what you're not getting sometimes). */
775 case WM_DISPLAYCHANGE:
776 break;
777 case WM_NCHITTEST:
778 /* This event is generated by every mouse move event. */
779 goto defproc;
780 case WM_NCMOUSEMOVE:
781 goto defproc;
782 case WM_NCACTIVATE:
783 goto defproc;
784 case WM_NCPAINT:
785 goto defproc;
786 case WM_NCCALCSIZE:
787 goto defproc;
788 case WM_NCCREATE:
789 goto defproc;
790 case WM_NCDESTROY:
791 goto defproc;
792 case WM_NCLBUTTONDOWN:
793 goto defproc;
794 case WM_SETTEXT:
795 goto defproc;
796 case WM_GETTEXT:
797 goto defproc;
798 case WM_ACTIVATEAPP:
799 goto defproc;
800 case WM_GETICON:
801 goto defproc;
802 case WM_ERASEBKGND:
803 goto defproc;
804 case WM_WINDOWPOSCHANGING:
805 goto defproc;
806 case WM_WINDOWPOSCHANGED:
807 goto defproc;
808 case WM_MOUSEACTIVATE:
809 goto defproc;
810 case WM_SHOWWINDOW:
811 goto defproc;
812 case WM_MOVING:
813 goto defproc;
814 case WM_MOVE:
815 goto defproc;
816 case WM_KEYUP:
817 goto defproc;
818 case WM_CAPTURECHANGED:
819 goto defproc;
820 case WM_SYSCOMMAND:
821 goto defproc;
822 case WM_ENTERSIZEMOVE:
823 goto defproc;
824 case WM_ENTERIDLE:
825 goto defproc;
826#endif
827
828 default:
829 goto defproc;
830 }
831
832defproc:
833 return DefWindowProc(hwnd, msg, wParam, lParam);
834}
Note: See TracBrowser for help on using the repository browser.