Doxygen Source Code Documentation
glut_event.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <GL/glut.h>
#include "glutint.h"
Go to the source code of this file.
Function Documentation
|
Definition at line 144 of file glut_event.c. References __glutPutOnWorkList(), GLUT_REDISPLAY_WORK, _GLUTwindow::overlay, _GLUTwindow::shownState, _GLUToverlay::shownState, and _GLUTwindow::visState. Referenced by glutPostOverlayRedisplay(), glutPostRedisplay(), and processEvents().
00145 { 00146 int shown = (layerMask == GLUT_REDISPLAY_WORK) ? window->shownState : window->overlay->shownState; 00147 00148 /* Post a redisplay if the window is visible (or the 00149 visibility of the window is unknown, ie. window->visState 00150 == -1) _and_ the layer is known to be shown. */ 00151 if (window->visState != 0 && shown) 00152 __glutPutOnWorkList(window, layerMask); 00153 } |
|
Definition at line 130 of file glut_event.c. References _GLUTwindow::prevWorkWin, and _GLUTwindow::workMask. Referenced by __glutChangeWindowEventMask(), __glutPostRedisplay(), __glutSetWindow(), glutButtonBoxFunc(), glutCopyColormap(), glutCreateSubWindow(), glutDestroyWindow(), glutDialsFunc(), glutEstablishOverlay(), glutFullScreen(), glutHideWindow(), glutIconifyWindow(), glutPopWindow(), glutPositionWindow(), glutPushWindow(), glutRemoveOverlay(), glutReshapeWindow(), glutSetColor(), glutShowWindow(), glutSpaceballButtonFunc(), glutSpaceballMotionFunc(), glutSpaceballRotateFunc(), glutTabletButtonFunc(), and glutTabletMotionFunc().
00131 { 00132 if (window->workMask) { 00133 /* Already on list; just OR in new workMask. */ 00134 window->workMask |= workMask; 00135 } else { 00136 /* Update work mask and add to window work list. */ 00137 window->workMask = workMask; 00138 window->prevWorkWin = __glutWindowWorkList; 00139 __glutWindowWorkList = window; 00140 } 00141 } |
|
Definition at line 170 of file glut_event.c. References _GLUTeventParser::next. Referenced by addDeviceEventParser().
00171 { 00172 parser->next = eventParserList; 00173 eventParserList = parser; 00174 } |
|
Definition at line 60 of file glut_event.c. References __glutIdleFunc, and GLUTidleCB.
00061 { 00062 __glutIdleFunc = idleFunc; 00063 } |
|
Definition at line 945 of file glut_event.c. References __glutFatalUsage(), __glutIdleFunc, idleWait(), processEvents(), processWindowWorkList(), and waitForSomething().
00946 { 00947 if (!__glutDisplay) 00948 __glutFatalUsage("main loop entered with out X connection."); 00949 if (!__glutWindowListSize) 00950 __glutFatalUsage( 00951 "main loop entered with no windows created."); 00952 for (;;) { 00953 if (__glutWindowWorkList) { 00954 GLUTwindow *remainder, *work; 00955 00956 work = __glutWindowWorkList; 00957 __glutWindowWorkList = NULL; 00958 if (work) { 00959 remainder = processWindowWorkList(work); 00960 if (remainder) { 00961 *beforeEnd = __glutWindowWorkList; 00962 __glutWindowWorkList = remainder; 00963 } 00964 } 00965 } 00966 if (__glutIdleFunc || __glutWindowWorkList) { 00967 idleWait(); 00968 } else { 00969 if (__glutTimerList) { 00970 waitForSomething(); 00971 } else { 00972 processEvents(); 00973 } 00974 } 00975 } 00976 } |
|
Definition at line 156 of file glut_event.c. References __glutPostRedisplay(), and GLUT_REDISPLAY_WORK.
00157 { 00158 __glutPostRedisplay(__glutCurrentWindow, GLUT_REDISPLAY_WORK); 00159 } |
|
Definition at line 66 of file glut_event.c. References __glutFatalError(), ADD_TIME, _GLUTtimer::func, GETTIMEOFDAY, GLUTtimerCB, IS_AFTER, malloc, _GLUTtimer::next, _GLUTtimer::timeout, and _GLUTtimer::value.
00067 { 00068 GLUTtimer *timer, *other; 00069 GLUTtimer **prevptr; 00070 struct timeval now; 00071 00072 if (!timerFunc) 00073 return; 00074 00075 if (freeTimerList) { 00076 timer = freeTimerList; 00077 freeTimerList = timer->next; 00078 } else { 00079 timer = (GLUTtimer *) malloc(sizeof(GLUTtimer)); 00080 if (!timer) 00081 __glutFatalError("out of memory."); 00082 } 00083 00084 timer->func = timerFunc; 00085 #ifdef __vms 00086 /* VMS time is expressed in units of 100 ns */ 00087 timer->timeout.val = interval * TICKS_PER_MILLISECOND; 00088 #else 00089 timer->timeout.tv_sec = (int) interval / 1000; 00090 timer->timeout.tv_usec = (int) (interval % 1000) * 1000; 00091 #endif 00092 timer->value = value; 00093 timer->next = NULL; 00094 GETTIMEOFDAY(&now); 00095 ADD_TIME(timer->timeout, timer->timeout, now); 00096 prevptr = &__glutTimerList; 00097 other = *prevptr; 00098 while (other && IS_AFTER(other->timeout, timer->timeout)) { 00099 prevptr = &other->next; 00100 other = *prevptr; 00101 } 00102 timer->next = other; 00103 #ifdef SUPPORT_FORTRAN 00104 __glutNewTimer = timer; /* for Fortran binding! */ 00105 #endif 00106 *prevptr = timer; 00107 } |
|
Definition at line 110 of file glut_event.c. References _GLUTtimer::func, GETTIMEOFDAY, IS_AT_OR_AFTER, _GLUTtimer::next, and _GLUTtimer::timeout. Referenced by idleWait(), and waitForSomething().
00111 { 00112 struct timeval now; 00113 GLUTtimer *timer; 00114 00115 if (__glutTimerList) { 00116 GETTIMEOFDAY(&now); 00117 while (IS_AT_OR_AFTER(__glutTimerList->timeout, now)) { 00118 timer = __glutTimerList; 00119 timer->func(timer->value); 00120 __glutTimerList = timer->next; 00121 timer->next = freeTimerList; 00122 freeTimerList = timer; 00123 if (!__glutTimerList) 00124 break; 00125 } 00126 } 00127 } |
|
Definition at line 695 of file glut_event.c. References __glutIdleFunc, handleTimeouts(), and processEvents(). Referenced by glutMainLoop().
00696 { 00697 while (XPending(__glutDisplay)) { 00698 processEvents(); 00699 } 00700 if (__glutTimerList) 00701 handleTimeouts(); 00702 /* Make sure idle func still exists! */ 00703 if (__glutIdleFunc) 00704 __glutIdleFunc(); 00705 } |
|
Definition at line 221 of file glut_event.c. References __glutFinishMenu(), __glutGetMenu(), __glutGetMenuByNum(), __glutGetMenuItem(), __glutGetWindow(), __glutMenuItemEnterOrLeave(), __glutModifierMask, __glutPaintMenu(), __glutPostRedisplay(), __glutSetWindow(), __glutStartMenu(), _GLUToverlay::damaged, _GLUTwindow::damaged, _GLUTwindow::entry, _GLUTwindow::entryState, event, _GLUTwindow::forceReshape, _GLUTeventParser::func, GLUT_DOWN, GLUT_ENTERED, GLUT_KEY_DOWN, GLUT_KEY_END, GLUT_KEY_F1, GLUT_KEY_F10, GLUT_KEY_F11, GLUT_KEY_F12, GLUT_KEY_F2, GLUT_KEY_F3, GLUT_KEY_F4, GLUT_KEY_F5, GLUT_KEY_F6, GLUT_KEY_F7, GLUT_KEY_F8, GLUT_KEY_F9, GLUT_KEY_HOME, GLUT_KEY_INSERT, GLUT_KEY_LEFT, GLUT_KEY_PAGE_DOWN, GLUT_KEY_PAGE_UP, GLUT_KEY_RIGHT, GLUT_KEY_UP, GLUT_LEFT, GLUT_NOT_VISIBLE, GLUT_OVERLAY_REDISPLAY_WORK, GLUT_REDISPLAY_WORK, GLUT_UP, GLUT_VISIBLE, _GLUTwindow::height, key, _GLUTwindow::keyboard, mappedMenuButton, _GLUTwindow::menu, _GLUTwindow::motion, _GLUTwindow::mouse, _GLUTeventParser::next, _GLUTwindow::num, _GLUTwindow::overlay, _GLUTwindow::passive, purgeStaleWindow(), _GLUTwindow::reshape, skip, _GLUTwindow::special, updateWindowVisibility(), _GLUTwindow::visibility, _GLUTwindow::visState, _GLUTwindow::width, _GLUToverlay::win, and _GLUTwindow::win. Referenced by glutMainLoop(), idleWait(), and waitForSomething().
00222 { 00223 XEvent event, ahead; 00224 GLUTwindow *window; 00225 int width, height; 00226 GLUTeventParser *parser; 00227 00228 do { 00229 XNextEvent(__glutDisplay, &event); 00230 switch (event.type) { 00231 case MappingNotify: 00232 XRefreshKeyboardMapping((XMappingEvent *) & event); 00233 break; 00234 case ConfigureNotify: 00235 window = __glutGetWindow(event.xconfigure.window); 00236 if (window) { 00237 if (window->win != event.xconfigure.window) { 00238 /* Ignore ConfigureNotify sent to the overlay planes. 00239 GLUT could get here because overlays select for 00240 StructureNotify events to receive DestroyNotify. */ 00241 break; 00242 } 00243 width = event.xconfigure.width; 00244 height = event.xconfigure.height; 00245 if (width != window->width || height != window->height) { 00246 if (window->overlay) { 00247 XResizeWindow(__glutDisplay, window->overlay->win, width, height); 00248 } 00249 window->width = width; 00250 window->height = height; 00251 __glutSetWindow(window); 00252 /* Do not execute OpenGL out of sequence with respect 00253 to the XResizeWindow request! */ 00254 glXWaitX(); 00255 window->reshape(width, height); 00256 window->forceReshape = False; 00257 } 00258 } 00259 break; 00260 case Expose: 00261 /* compress expose events */ 00262 while (XEventsQueued(__glutDisplay, QueuedAfterReading) 00263 > 0) { 00264 XPeekEvent(__glutDisplay, &ahead); 00265 if (ahead.type != Expose || 00266 ahead.xexpose.window != event.xexpose.window) 00267 break; 00268 XNextEvent(__glutDisplay, &event); 00269 } 00270 if (event.xexpose.count == 0) { 00271 GLUTmenu *menu; 00272 00273 if (__glutMappedMenu && 00274 (menu = __glutGetMenu(event.xexpose.window))) { 00275 __glutPaintMenu(menu); 00276 } else { 00277 window = __glutGetWindow(event.xexpose.window); 00278 if (window) { 00279 if (window->win == event.xexpose.window) { 00280 window->damaged = 1; 00281 __glutPostRedisplay(window, GLUT_REDISPLAY_WORK); 00282 } else if (window->overlay && window->overlay->win == event.xexpose.window) { 00283 __glutPostRedisplay(window, GLUT_OVERLAY_REDISPLAY_WORK); 00284 window->overlay->damaged = 1; 00285 } 00286 } 00287 } 00288 } else { 00289 /* there are more exposes to read; wait to redisplay */ 00290 } 00291 break; 00292 case ButtonPress: 00293 case ButtonRelease: 00294 if (__glutMappedMenu && event.type == ButtonRelease 00295 && mappedMenuButton == event.xbutton.button) { 00296 /* Menu is currently popped up and its button is 00297 released. */ 00298 __glutFinishMenu(event.xbutton.window, event.xbutton.x, event.xbutton.y); 00299 } else { 00300 window = __glutGetWindow(event.xbutton.window); 00301 if (window) { 00302 GLUTmenu *menu; 00303 00304 menu = __glutGetMenuByNum( 00305 window->menu[event.xbutton.button - 1]); 00306 if (menu) { 00307 if (event.type == ButtonPress && !__glutMappedMenu) { 00308 __glutStartMenu(menu, window, 00309 event.xbutton.x_root, event.xbutton.y_root, 00310 event.xbutton.x, event.xbutton.y); 00311 mappedMenuButton = event.xbutton.button; 00312 } else { 00313 /* Ignore a release of a button with a menu 00314 attatched to it when no menu is popped up, or 00315 ignore a press when another menu is already 00316 popped up. */ 00317 } 00318 } else if (window->mouse) { 00319 __glutSetWindow(window); 00320 __glutModifierMask = event.xbutton.state; 00321 window->mouse(event.xbutton.button - 1, 00322 event.type == ButtonRelease ? 00323 GLUT_UP : GLUT_DOWN, 00324 event.xbutton.x, event.xbutton.y); 00325 __glutModifierMask = ~0; 00326 } else { 00327 /* Stray mouse events. Ignore. */ 00328 } 00329 } else { 00330 /* Window might have been destroyed and all the 00331 events for the window may not yet be received. */ 00332 } 00333 } 00334 break; 00335 case MotionNotify: 00336 if (!__glutMappedMenu) { 00337 window = __glutGetWindow(event.xmotion.window); 00338 if (window) { 00339 /* If motion function registered _and_ buttons held * 00340 down, call motion function... */ 00341 if (window->motion && event.xmotion.state & 00342 (Button1Mask | Button2Mask | Button3Mask)) { 00343 __glutSetWindow(window); 00344 window->motion(event.xmotion.x, event.xmotion.y); 00345 } 00346 /* If passive motion function registered _and_ 00347 buttons not held down, call passive motion 00348 function... */ 00349 else if (window->passive && 00350 ((event.xmotion.state & 00351 (Button1Mask | Button2Mask | Button3Mask)) == 00352 0)) { 00353 __glutSetWindow(window); 00354 window->passive(event.xmotion.x, 00355 event.xmotion.y); 00356 } 00357 } 00358 } else { 00359 /* Motion events are thrown away when a pop up menu is 00360 active. */ 00361 } 00362 break; 00363 case KeyPress: 00364 window = __glutGetWindow(event.xkey.window); 00365 if (!window) { 00366 break; 00367 } 00368 if (window->keyboard) { 00369 char tmp[1]; 00370 int rc; 00371 00372 rc = XLookupString(&event.xkey, tmp, sizeof(tmp), 00373 NULL, NULL); 00374 if (rc) { 00375 __glutSetWindow(window); 00376 __glutModifierMask = event.xkey.state; 00377 window->keyboard(tmp[0], 00378 event.xkey.x, event.xkey.y); 00379 __glutModifierMask = ~0; 00380 break; 00381 } 00382 } 00383 if (window->special) { 00384 KeySym ks; 00385 int key; 00386 00387 ks = XLookupKeysym((XKeyEvent *) & event, 0); 00388 /* XXX Verbose, but makes no assumptions about keysym 00389 layout. */ 00390 switch (ks) { 00391 /* function keys */ 00392 case XK_F1: key = GLUT_KEY_F1; break; 00393 case XK_F2: key = GLUT_KEY_F2; break; 00394 case XK_F3: key = GLUT_KEY_F3; break; 00395 case XK_F4: key = GLUT_KEY_F4; break; 00396 case XK_F5: key = GLUT_KEY_F5; break; 00397 case XK_F6: key = GLUT_KEY_F6; break; 00398 case XK_F7: key = GLUT_KEY_F7; break; 00399 case XK_F8: key = GLUT_KEY_F8; break; 00400 case XK_F9: key = GLUT_KEY_F9; break; 00401 case XK_F10: key = GLUT_KEY_F10; break; 00402 case XK_F11: key = GLUT_KEY_F11; break; 00403 case XK_F12: key = GLUT_KEY_F12; break; 00404 /* directional keys */ 00405 case XK_Left: key = GLUT_KEY_LEFT; break; 00406 case XK_Up: key = GLUT_KEY_UP; break; 00407 case XK_Right: key = GLUT_KEY_RIGHT; break; 00408 case XK_Down: key = GLUT_KEY_DOWN; break; 00409 case XK_Prior: 00410 /* XK_Prior same as X11R6's XK_Page_Up */ 00411 key = GLUT_KEY_PAGE_UP; 00412 break; 00413 case XK_Next: 00414 /* XK_Next same as X11R6's XK_Page_Down */ 00415 key = GLUT_KEY_PAGE_DOWN; 00416 break; 00417 case XK_Home: 00418 key = GLUT_KEY_HOME; 00419 break; 00420 case XK_End: 00421 #ifdef __hpux 00422 case XK_Select: 00423 #endif 00424 key = GLUT_KEY_END; 00425 break; 00426 case XK_Insert: 00427 #ifdef __hpux 00428 case XK_InsertChar: 00429 #endif 00430 key = GLUT_KEY_INSERT; 00431 break; 00432 #ifdef __hpux 00433 case XK_DeleteChar: 00434 /* The Delete character is really an ASCII key. */ 00435 __glutSetWindow(window); 00436 window->keyboard(127, /* ASCII Delete character. */ 00437 event.xkey.x, event.xkey.y); 00438 goto skip; 00439 #endif 00440 default: 00441 goto skip; 00442 } 00443 __glutSetWindow(window); 00444 __glutModifierMask = event.xkey.state; 00445 window->special(key, event.xkey.x, event.xkey.y); 00446 __glutModifierMask = ~0; 00447 skip:; 00448 } 00449 break; 00450 case EnterNotify: 00451 case LeaveNotify: 00452 if (event.xcrossing.mode != NotifyNormal || 00453 event.xcrossing.detail == NotifyNonlinearVirtual || 00454 event.xcrossing.detail == NotifyVirtual) { 00455 00456 /* Careful to ignore Enter/LeaveNotify events that come 00457 from the pop-up menu pointer grab and ungrab. Also, 00458 ignore "virtual" Enter/LeaveNotify events since they 00459 represent the pointer passing through the window 00460 hierarchy without actually entering or leaving the 00461 actual real estate of a window. */ 00462 00463 break; 00464 } 00465 if (__glutMappedMenu) { 00466 GLUTmenuItem *item; 00467 int num; 00468 00469 item = __glutGetMenuItem(__glutMappedMenu, 00470 event.xcrossing.window, &num); 00471 if (item) { 00472 __glutMenuItemEnterOrLeave(item, num, event.type); 00473 break; 00474 } 00475 } 00476 window = __glutGetWindow(event.xcrossing.window); 00477 if (window) { 00478 if (window->entry) { 00479 if (event.type == EnterNotify) { 00480 00481 /* With overlays established, X can report two 00482 enter events for both the overlay and normal 00483 plane window. Do not generate a second enter 00484 callback if we reported one without an 00485 intervening leave. */ 00486 00487 if (window->entryState != EnterNotify) { 00488 int num = window->num; 00489 Window xid = window->win; 00490 00491 window->entryState = EnterNotify; 00492 __glutSetWindow(window); 00493 window->entry(GLUT_ENTERED); 00494 00495 if (__glutMappedMenu) { 00496 00497 /* Do not generate any passive motion events 00498 when menus are in use. */ 00499 00500 } else { 00501 00502 /* An EnterNotify event can result in a 00503 "compound" callback if a passive motion 00504 callback is also registered. In this case, 00505 be a little paranoid about the possibility 00506 the window could have been destroyed in the 00507 entry callback. */ 00508 00509 window = __glutWindowList[num]; 00510 if (window && window->passive && window->win == xid) { 00511 __glutSetWindow(window); 00512 window->passive(event.xcrossing.x, event.xcrossing.y); 00513 } 00514 } 00515 } 00516 } else { 00517 if (window->entryState != LeaveNotify) { 00518 00519 /* When an overlay is established for a window 00520 already mapped and with the pointer in it, the 00521 X server will generate a leave/enter event pair 00522 as the pointer leaves (without moving) from the 00523 normal plane X window to the newly mapped 00524 overlay X window (or vice versa). This 00525 enter/leave pair should not be reported to the 00526 GLUT program since the pair is a consequence of 00527 creating (or destroying) the overlay, not an 00528 actual leave from the GLUT window. */ 00529 00530 if (XEventsQueued(__glutDisplay, QueuedAfterReading)) { 00531 XPeekEvent(__glutDisplay, &ahead); 00532 if (ahead.type == EnterNotify && 00533 __glutGetWindow(ahead.xcrossing.window) == window) { 00534 XNextEvent(__glutDisplay, &event); 00535 break; 00536 } 00537 } 00538 window->entryState = LeaveNotify; 00539 __glutSetWindow(window); 00540 window->entry(GLUT_LEFT); 00541 } 00542 } 00543 } else if (window->passive) { 00544 __glutSetWindow(window); 00545 window->passive(event.xcrossing.x, event.xcrossing.y); 00546 } 00547 } 00548 break; 00549 case UnmapNotify: 00550 /* MapNotify events are not needed to maintain visibility 00551 state since VisibilityNotify events will be delivered 00552 when a window becomes visible from mapping. However, 00553 VisibilityNotify events are not delivered when a window 00554 is unmapped (for the window or its children). */ 00555 window = __glutGetWindow(event.xunmap.window); 00556 if (window) { 00557 if (window->win != event.xconfigure.window) { 00558 /* Ignore UnmapNotify sent to the overlay planes. 00559 GLUT could get here because overlays select for 00560 StructureNotify events to receive DestroyNotify. */ 00561 break; 00562 } 00563 updateWindowVisibility(window, 0); 00564 } 00565 break; 00566 case VisibilityNotify: 00567 window = __glutGetWindow(event.xvisibility.window); 00568 if (window) { 00569 int visState = (event.xvisibility.state != VisibilityFullyObscured); 00570 00571 if (visState != window->visState) { 00572 if (window->visibility) { 00573 window->visState = visState; 00574 __glutSetWindow(window); 00575 window->visibility(visState ? GLUT_VISIBLE : GLUT_NOT_VISIBLE); 00576 } 00577 } 00578 } 00579 break; 00580 case ClientMessage: 00581 if (event.xclient.data.l[0] == __glutWMDeleteWindow) 00582 exit(0); 00583 break; 00584 case DestroyNotify: 00585 purgeStaleWindow(event.xdestroywindow.window); 00586 break; 00587 case CirculateNotify: 00588 case CreateNotify: 00589 case GravityNotify: 00590 case ReparentNotify: 00591 /* Uninteresting to GLUT (but possible for GLUT to 00592 receive). */ 00593 break; 00594 default: 00595 /* Pass events not directly handled by the GLUT main 00596 event loop to any event parsers that have been 00597 registered. In this way, X Input extension events are 00598 passed to the correct handler without forcing all GLUT 00599 programs to support X Input event handling. */ 00600 parser = eventParserList; 00601 while (parser) { 00602 if (parser->func(&event)) 00603 break; 00604 parser = parser->next; 00605 } 00606 break; 00607 } 00608 } 00609 while (XPending(__glutDisplay)); 00610 } |
|
Definition at line 710 of file glut_event.c. References __glutEstablishColormapsProperty(), __glutMotifHints, __glutSetWindow(), __glutUpdateInputDeviceMaskFunc, __glutWarning(), __glutWindowDamaged, _GLUTwindow::children, _GLUToverlay::ctx, _GLUTwindow::ctx, _GLUToverlay::damaged, _GLUTwindow::damaged, MotifWmHints::decorations, _GLUTwindow::desiredConfMask, _GLUTwindow::desiredHeight, _GLUTwindow::desiredMapState, _GLUTwindow::desiredStack, _GLUTwindow::desiredWidth, _GLUTwindow::desiredX, _GLUTwindow::desiredY, _GLUTwindow::display, _GLUToverlay::display, _GLUTwindow::eventMask, MotifWmHints::flags, _GLUTwindow::forceReshape, GLUT_COLORMAP_WORK, GLUT_CONFIGURE_WORK, GLUT_DEBUG_WORK, GLUT_DEVICE_MASK_WORK, GLUT_DONT_PROPAGATE_FILTER_MASK, GLUT_DUMMY_WORK, GLUT_EVENT_MASK_WORK, GLUT_FINISH_WORK, GLUT_FULL_SCREEN_WORK, GLUT_HACK_STOP_PROPAGATE_MASK, GLUT_MAP_WORK, GLUT_OVERLAY_EVENT_FILTER_MASK, GLUT_OVERLAY_REDISPLAY_WORK, GLUT_REDISPLAY_WORK, _GLUTwindow::height, MWM_HINTS_DECORATIONS, _GLUTwindow::num, _GLUTwindow::overlay, _GLUTwindow::parent, _GLUTwindow::prevWorkWin, _GLUTwindow::renderCtx, _GLUTwindow::renderWin, _GLUTwindow::reshape, _GLUTwindow::shownState, _GLUTwindow::siblings, _GLUTwindow::width, _GLUToverlay::win, _GLUTwindow::win, and _GLUTwindow::workMask. Referenced by glutMainLoop().
00711 { 00712 int workMask; 00713 00714 if (window->prevWorkWin) 00715 window->prevWorkWin = processWindowWorkList(window->prevWorkWin); 00716 else 00717 beforeEnd = &window->prevWorkWin; 00718 00719 /* Capture work mask for work that needs to be done to this 00720 window, then clear the window's work mask (excepting the 00721 dummy work bit, see below). Then, process the captured 00722 work mask. This allows callbacks in the processing the 00723 captured work mask to set the window's work mask for 00724 subsequent processing. */ 00725 00726 workMask = window->workMask; 00727 assert((workMask & GLUT_DUMMY_WORK) == 0); 00728 00729 /* Set the dummy work bit, clearing all other bits, to 00730 indicate that the window is currently on the window work 00731 list _and_ that the window's work mask is currently being 00732 processed. This convinces __glutPutOnWorkList that this 00733 window is on the work list still. */ 00734 window->workMask = GLUT_DUMMY_WORK; 00735 00736 /* Optimization: most of the time, the work to do is a 00737 redisplay and not these other types of work. Check for 00738 the following cases as a group to before checking each one 00739 individually one by one. This saves about 25 MIPS 00740 instructions in the common redisplay only case. */ 00741 if (workMask & (GLUT_EVENT_MASK_WORK | GLUT_DEVICE_MASK_WORK | 00742 GLUT_CONFIGURE_WORK | GLUT_COLORMAP_WORK | GLUT_MAP_WORK)) { 00743 /* Be sure to set event mask *BEFORE* map window is done. */ 00744 if (workMask & GLUT_EVENT_MASK_WORK) { 00745 long eventMask; 00746 00747 /* Make sure children are not propogating events this 00748 window is selecting for. Be sure to do this before 00749 enabling events on the children's parent. */ 00750 if (window->children) { 00751 GLUTwindow *child = window->children; 00752 unsigned long attribMask = CWDontPropagate; 00753 XSetWindowAttributes wa; 00754 00755 wa.do_not_propagate_mask = window->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK; 00756 if (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) { 00757 wa.event_mask = child->eventMask | (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK); 00758 attribMask |= CWEventMask; 00759 } 00760 do { 00761 XChangeWindowAttributes(__glutDisplay, child->win, 00762 attribMask, &wa); 00763 child = child->siblings; 00764 } while (child); 00765 } 00766 eventMask = window->eventMask; 00767 if (window->parent && window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) 00768 eventMask |= (window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK); 00769 XSelectInput(__glutDisplay, window->win, eventMask); 00770 00771 if (window->overlay) 00772 XSelectInput(__glutDisplay, window->overlay->win, 00773 window->eventMask & GLUT_OVERLAY_EVENT_FILTER_MASK); 00774 } 00775 /* Be sure to set device mask *BEFORE* map window is done. */ 00776 if (workMask & GLUT_DEVICE_MASK_WORK) { 00777 __glutUpdateInputDeviceMaskFunc(window); 00778 } 00779 /* Be sure to configure window *BEFORE* map window is done. 00780 */ 00781 if (workMask & GLUT_CONFIGURE_WORK) { 00782 XWindowChanges changes; 00783 00784 changes.x = window->desiredX; 00785 changes.y = window->desiredY; 00786 if (window->desiredConfMask & (CWWidth | CWHeight)) { 00787 changes.width = window->desiredWidth; 00788 changes.height = window->desiredHeight; 00789 if (window->overlay) 00790 XResizeWindow(__glutDisplay, window->overlay->win, 00791 window->desiredWidth, window->desiredHeight); 00792 if (__glutMotifHints != None) { 00793 if (workMask & GLUT_FULL_SCREEN_WORK) { 00794 MotifWmHints hints; 00795 00796 hints.flags = MWM_HINTS_DECORATIONS; 00797 hints.decorations = 0; /* Absolutely no 00798 decorations. */ 00799 XChangeProperty(__glutDisplay, window->win, 00800 __glutMotifHints, __glutMotifHints, 32, 00801 PropModeReplace, (unsigned char *) &hints, 4); 00802 } else { 00803 XDeleteProperty(__glutDisplay, window->win, __glutMotifHints); 00804 } 00805 } 00806 } 00807 if (window->desiredConfMask & CWStackMode) { 00808 changes.stack_mode = window->desiredStack; 00809 /* Do not let glutPushWindow push window beneath the 00810 underlay. */ 00811 if (window->parent && window->parent->overlay && window->desiredStack == Below) { 00812 changes.stack_mode = Above; 00813 changes.sibling = window->parent->overlay->win; 00814 window->desiredConfMask |= CWSibling; 00815 } 00816 } 00817 XConfigureWindow(__glutDisplay, window->win, 00818 window->desiredConfMask, &changes); 00819 window->desiredConfMask = 0; 00820 } 00821 /* Be sure to establish the colormaps *BEFORE* map window 00822 is done. */ 00823 if (workMask & GLUT_COLORMAP_WORK) { 00824 __glutEstablishColormapsProperty(window); 00825 } 00826 if (workMask & GLUT_MAP_WORK) { 00827 switch (window->desiredMapState) { 00828 case WithdrawnState: 00829 if (window->parent) { 00830 XUnmapWindow(__glutDisplay, window->win); 00831 } else { 00832 XWithdrawWindow(__glutDisplay, window->win, 00833 __glutScreen); 00834 } 00835 window->shownState = 0; 00836 break; 00837 case NormalState: 00838 XMapWindow(__glutDisplay, window->win); 00839 window->shownState = 1; 00840 break; 00841 case IconicState: 00842 XIconifyWindow(__glutDisplay, window->win, __glutScreen); 00843 window->shownState = 0; 00844 break; 00845 } 00846 } 00847 } 00848 if (workMask & (GLUT_REDISPLAY_WORK | GLUT_OVERLAY_REDISPLAY_WORK)) { 00849 if (window->forceReshape) { 00850 /* Guarantee that before a display callback is generated 00851 for a window, a reshape callback must be generated. */ 00852 __glutSetWindow(window); 00853 window->reshape(window->width, window->height); 00854 window->forceReshape = False; 00855 } 00856 /* The code below is more involved than otherwise necessary 00857 because it is paranoid about the overlay or entire window 00858 being removed or destroyed in the course of the callbacks. 00859 Notice how the global __glutWindowDamaged is used to 00860 record the layers' damage status. See the code in 00861 glutLayerGet for how __glutWindowDamaged is used. The 00862 point is to not have to update the "damaged" field after 00863 the callback since the window (or overlay) may be 00864 destroyed (or removed) when the callback returns. */ 00865 00866 if (window->overlay && window->overlay->display) { 00867 int num = window->num; 00868 Window xid = window->overlay ? window->overlay->win : None; 00869 00870 /* If an overlay display callback is registered, we 00871 differentiate between a redisplay needed for the 00872 overlay and/or normal plane. If there is no overlay 00873 display callback registered, we simply use the 00874 standard display callback. */ 00875 00876 if (workMask & GLUT_REDISPLAY_WORK) { 00877 00878 /* Render to normal plane. */ 00879 window->renderWin = window->win; 00880 window->renderCtx = window->ctx; 00881 __glutWindowDamaged = window->damaged; 00882 window->damaged = 0; 00883 __glutSetWindow(window); 00884 window->display(); 00885 __glutWindowDamaged = 0; 00886 } 00887 if (workMask & GLUT_OVERLAY_REDISPLAY_WORK) { 00888 window = __glutWindowList[num]; 00889 if (window && window->overlay && 00890 window->overlay->win == xid && window->overlay->display) { 00891 00892 /* Render to overlay. */ 00893 window->renderWin = window->overlay->win; 00894 window->renderCtx = window->overlay->ctx; 00895 __glutWindowDamaged = window->overlay->damaged; 00896 window->overlay->damaged = 0; 00897 __glutSetWindow(window); 00898 window->overlay->display(); 00899 __glutWindowDamaged = 0; 00900 } else { 00901 /* Overlay may have since been destroyed or the 00902 overlay callback may have been disabled during 00903 normal display callback. */ 00904 } 00905 } 00906 } else { 00907 __glutWindowDamaged = window->damaged; 00908 window->damaged = 0; 00909 if (window->overlay) { 00910 __glutWindowDamaged |= window->overlay->damaged; 00911 window->overlay->damaged = 0; 00912 } 00913 __glutSetWindow(window); 00914 window->display(); 00915 __glutWindowDamaged = 0; 00916 } 00917 } 00918 /* Combine workMask with window->workMask to determine what 00919 finish and debug work there is. */ 00920 workMask |= window->workMask; 00921 00922 if (workMask & GLUT_FINISH_WORK) { 00923 __glutSetWindow(window); 00924 glFinish(); 00925 } 00926 if (workMask & GLUT_DEBUG_WORK) { 00927 GLenum error; 00928 00929 __glutSetWindow(window); 00930 while ((error = glGetError()) != GL_NO_ERROR) 00931 __glutWarning("GL error: %s", gluErrorString(error)); 00932 } 00933 /* Strip out dummy, finish, and debug work bits. */ 00934 window->workMask &= ~(GLUT_DUMMY_WORK | GLUT_FINISH_WORK | GLUT_DEBUG_WORK); 00935 if (window->workMask) { 00936 /* Leave on work list. */ 00937 return window; 00938 } else { 00939 /* Remove current window from work list. */ 00940 return window->prevWorkWin; 00941 } 00942 } |
|
Definition at line 200 of file glut_event.c. References free, _GLUTstale::next, _GLUTstale::win, and win. Referenced by processEvents().
00201 { 00202 GLUTstale **pEntry = &__glutStaleWindowList; 00203 GLUTstale *entry = __glutStaleWindowList; 00204 00205 /* Tranverse singly-linked stale window list look for the 00206 window ID. */ 00207 while (entry) { 00208 if (entry->win == win) { 00209 /* Found it; delete it. */ 00210 *pEntry = entry->next; 00211 free(entry); 00212 return; 00213 } else { 00214 pEntry = &entry->next; 00215 entry = *pEntry; 00216 } 00217 } 00218 } |
|
Definition at line 177 of file glut_event.c. References __glutSetWindow(), _GLUTwindow::children, GLUT_NOT_VISIBLE, GLUT_VISIBLE, _GLUTwindow::shownState, _GLUTwindow::siblings, _GLUTwindow::visibility, and _GLUTwindow::visState. Referenced by processEvents().
00178 { 00179 if (window->shownState && visState != window->visState) { 00180 if (window->visibility) { 00181 window->visState = visState; 00182 __glutSetWindow(window); 00183 window->visibility(visState ? 00184 GLUT_VISIBLE : GLUT_NOT_VISIBLE); 00185 } 00186 /* An unmap is only reported on a single window; its 00187 descendents need to know they are no longer visible. */ 00188 if (!visState) { 00189 GLUTwindow *child = window->children; 00190 00191 while (child) { 00192 updateWindowVisibility(child, visState); 00193 child = child->siblings; 00194 } 00195 } 00196 } 00197 } |
|
Definition at line 613 of file glut_event.c. References __glutFatalError(), GETTIMEOFDAY, handleTimeouts(), IS_AFTER, processEvents(), TIMEDELTA, and _GLUTtimer::timeout. Referenced by glutMainLoop().
00614 { 00615 #ifdef __vms 00616 static struct timeval zerotime = {0}; 00617 unsigned int timer_efn; 00618 #define timer_id 'glut' /* random :-) number */ 00619 unsigned int wait_mask; 00620 #else 00621 static struct timeval zerotime = {0, 0}; 00622 fd_set fds; 00623 #endif 00624 struct timeval now, timeout, waittime; 00625 int rc; 00626 00627 /* flush X protocol since XPending does not do this 00628 implicitly */ 00629 XFlush(__glutDisplay); 00630 if (XPending(__glutDisplay)) { 00631 /* It is possible (but quite rare) that XFlush may have 00632 needed to wait for a writable X connection file 00633 descriptor, and in the process, may have had to read off 00634 X protocol from the file descriptor. If XPending is true, 00635 this case occured and we should avoid waiting in select 00636 since X protocol buffered within Xlib is due to be 00637 processed and potentially no more X protocol is on the 00638 file descriptor, so we would risk waiting improperly in 00639 select. */ 00640 goto immediatelyHandleXinput; 00641 } 00642 #ifdef __vms 00643 timeout = __glutTimerList->timeout; 00644 GETTIMEOFDAY(&now); 00645 wait_mask = 1 << (__glutConnectionFD & 31); 00646 if (IS_AFTER(now, timeout)) { 00647 /* We need an event flag for the timer. */ 00648 /* XXX The `right' way to do this is to use LIB$GET_EF, but since it needs 00649 to be in the same cluster as the EFN for the display, we will have 00650 hack it. */ 00651 timer_efn = __glutConnectionFD - 1; 00652 if ((timer_efn / 32) != (__glutConnectionFD / 32) ) { 00653 timer_efn = __glutConnectionFD + 1; 00654 } 00655 rc = SYS$CLREF (timer_efn); 00656 rc = SYS$SETIMR (timer_efn, &timeout, NULL, timer_id, 0); 00657 wait_mask |= 1 << (timer_efn & 31); 00658 } else { 00659 timer_efn = 0; 00660 } 00661 rc = SYS$WFLOR (__glutConnectionFD, wait_mask); 00662 if (timer_efn != 0 && SYS$CLREF (timer_efn) == SS$_WASCLR) { 00663 rc = SYS$CANTIM (timer_id, PSL$C_USER); 00664 } 00665 /* XXX There does not seem to be checking of "rc" in the code 00666 above. Can any of the SYS$ routines above fail? */ 00667 #else /* not vms */ 00668 FD_ZERO(&fds); 00669 FD_SET(__glutConnectionFD, &fds); 00670 timeout = __glutTimerList->timeout; 00671 GETTIMEOFDAY(&now); 00672 if (IS_AFTER(now, timeout)) { 00673 TIMEDELTA(waittime, timeout, now); 00674 } else { 00675 waittime = zerotime; 00676 } 00677 rc = select(__glutConnectionFD + 1, &fds, 00678 NULL, NULL, &waittime); 00679 if (rc < 0 && errno != EINTR) 00680 __glutFatalError("select error."); 00681 #endif /* not vms */ 00682 /* Without considering the cause of select unblocking, check 00683 for pending X events *and* then handle any timeouts. We 00684 always look for X events even if select returned with 0 00685 (indicating a timeout); otherwise we risk starving X event 00686 processing by continous timeouts. */ 00687 while (XPending(__glutDisplay)) { 00688 immediatelyHandleXinput: 00689 processEvents(); 00690 } 00691 handleTimeouts(); 00692 } |
Variable Documentation
|
Definition at line 47 of file glut_event.c. Referenced by glutIdleFunc(), glutMainLoop(), and idleWait(). |
|
Definition at line 55 of file glut_event.c. Referenced by processEvents(). |
|
Definition at line 54 of file glut_event.c. Referenced by processWindowWorkList(). |
|
Definition at line 48 of file glut_event.c. |
|
Definition at line 53 of file glut_event.c. Referenced by processWindowWorkList(). |
|
Definition at line 57 of file glut_event.c. Referenced by processWindowWorkList(). |
|
Definition at line 52 of file glut_event.c. |
|
Definition at line 707 of file glut_event.c. |
|
Definition at line 161 of file glut_event.c. |
|
Definition at line 44 of file glut_event.c. |
|
Definition at line 45 of file glut_event.c. Referenced by processEvents(). |