00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <errno.h>
00011 #include <unistd.h>
00012 #include <assert.h>
00013 #ifdef __sgi
00014 #include <bstring.h>    
00015 #endif
00016 #ifdef AIXV3
00017 #include <sys/select.h> 
00018 #endif
00019 #include <sys/types.h>
00020 #ifndef __vms
00021 #include <sys/time.h>
00022 #endif
00023 #include <X11/Xlib.h>
00024 #include <X11/keysym.h>
00025 #ifdef __hpux
00026 
00027 
00028 
00029 
00030 #include <X11/HPkeysym.h>
00031 #endif
00032 #ifdef __vms
00033 #include <ssdef.h>
00034 #include <psldef.h>
00035 extern int SYS$CLREF(int efn);
00036 extern int SYS$SETIMR(unsigned int efn, struct timeval *timeout, void *ast,
00037   unsigned int request_id, unsigned int flags);
00038 extern int SYS$WFLOR(unsigned int efn, unsigned int mask);
00039 extern int SYS$CANTIM(unsigned int request_id, unsigned int mode);
00040 #endif 
00041 #include <GL/glut.h>
00042 #include "glutint.h"
00043 
00044 static GLUTtimer *freeTimerList = NULL;
00045 static int mappedMenuButton;
00046 
00047 GLUTidleCB __glutIdleFunc = NULL;
00048 GLUTtimer *__glutTimerList = NULL;
00049 #ifdef SUPPORT_FORTRAN
00050 GLUTtimer *__glutNewTimer;
00051 #endif
00052 GLUTwindow *__glutWindowWorkList = NULL;
00053 void (*__glutUpdateInputDeviceMaskFunc) (GLUTwindow *);
00054 Atom __glutMotifHints = None;
00055 unsigned int __glutModifierMask = ~0;  
00056 
00057 int __glutWindowDamaged = 0;
00058 
00059 void
00060 glutIdleFunc(GLUTidleCB idleFunc)
00061 {
00062   __glutIdleFunc = idleFunc;
00063 }
00064 
00065 void
00066 glutTimerFunc(unsigned int interval, GLUTtimerCB timerFunc, int 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   
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;  
00105 #endif
00106   *prevptr = timer;
00107 }
00108 
00109 static void
00110 handleTimeouts(void)
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 }
00128 
00129 void
00130 __glutPutOnWorkList(GLUTwindow * window, int workMask)
00131 {
00132   if (window->workMask) {
00133     
00134     window->workMask |= workMask;
00135   } else {
00136     
00137     window->workMask = workMask;
00138     window->prevWorkWin = __glutWindowWorkList;
00139     __glutWindowWorkList = window;
00140   }
00141 }
00142 
00143 void
00144 __glutPostRedisplay(GLUTwindow * window, int layerMask)
00145 {
00146   int shown = (layerMask == GLUT_REDISPLAY_WORK) ? window->shownState : window->overlay->shownState;
00147 
00148   
00149 
00150 
00151   if (window->visState != 0 && shown)
00152     __glutPutOnWorkList(window, layerMask);
00153 }
00154 
00155 void
00156 glutPostRedisplay(void)
00157 {
00158   __glutPostRedisplay(__glutCurrentWindow, GLUT_REDISPLAY_WORK);
00159 }
00160 
00161 static GLUTeventParser *eventParserList = NULL;
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 void
00170 __glutRegisterEventParser(GLUTeventParser * parser)
00171 {
00172   parser->next = eventParserList;
00173   eventParserList = parser;
00174 }
00175 
00176 static void
00177 updateWindowVisibility(GLUTwindow * window, int visState)
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     
00187 
00188     if (!visState) {
00189       GLUTwindow *child = window->children;
00190 
00191       while (child) {
00192         updateWindowVisibility(child, visState);
00193         child = child->siblings;
00194       }
00195     }
00196   }
00197 }
00198 
00199 static void
00200 purgeStaleWindow(Window win)
00201 {
00202   GLUTstale **pEntry = &__glutStaleWindowList;
00203   GLUTstale *entry = __glutStaleWindowList;
00204 
00205   
00206 
00207   while (entry) {
00208     if (entry->win == win) {
00209       
00210       *pEntry = entry->next;
00211       free(entry);
00212       return;
00213     } else {
00214       pEntry = &entry->next;
00215       entry = *pEntry;
00216     }
00217   }
00218 }
00219 
00220 static void
00221 processEvents(void)
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           
00239 
00240 
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           
00253 
00254           glXWaitX();
00255           window->reshape(width, height);
00256           window->forceReshape = False;
00257         }
00258       }
00259       break;
00260     case Expose:
00261       
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         
00290       }
00291       break;
00292     case ButtonPress:
00293     case ButtonRelease:
00294       if (__glutMappedMenu && event.type == ButtonRelease
00295         && mappedMenuButton == event.xbutton.button) {
00296         
00297 
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               
00314 
00315 
00316 
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             
00328           }
00329         } else {
00330           
00331 
00332         }
00333       }
00334       break;
00335     case MotionNotify:
00336       if (!__glutMappedMenu) {
00337         window = __glutGetWindow(event.xmotion.window);
00338         if (window) {
00339           
00340 
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           
00347 
00348 
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         
00360 
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         
00389 
00390         switch (ks) {
00391           
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           
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           
00411           key = GLUT_KEY_PAGE_UP;
00412           break;
00413         case XK_Next:
00414           
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           
00435           __glutSetWindow(window);
00436           window->keyboard(127, 
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         
00457 
00458 
00459 
00460 
00461 
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             
00482 
00483 
00484 
00485 
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                 
00498 
00499 
00500               } else {
00501 
00502                 
00503 
00504 
00505 
00506 
00507 
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               
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
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       
00551 
00552 
00553 
00554 
00555       window = __glutGetWindow(event.xunmap.window);
00556       if (window) {
00557         if (window->win != event.xconfigure.window) {
00558           
00559 
00560 
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       
00592 
00593       break;
00594     default:
00595       
00596 
00597 
00598 
00599 
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 }
00611 
00612 static void
00613 waitForSomething(void)
00614 {
00615 #ifdef __vms
00616   static struct timeval zerotime = {0};
00617   unsigned int timer_efn;
00618 #define timer_id 'glut'           
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   
00628 
00629   XFlush(__glutDisplay);
00630   if (XPending(__glutDisplay)) {
00631     
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
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     
00648     
00649 
00650 
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   
00666 
00667 #else 
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 
00682   
00683 
00684 
00685 
00686 
00687   while (XPending(__glutDisplay)) {
00688   immediatelyHandleXinput:
00689     processEvents();
00690   }
00691   handleTimeouts();
00692 }
00693 
00694 static void
00695 idleWait(void)
00696 {
00697   while (XPending(__glutDisplay)) {
00698     processEvents();
00699   }
00700   if (__glutTimerList)
00701     handleTimeouts();
00702   
00703   if (__glutIdleFunc)
00704     __glutIdleFunc();
00705 }
00706 
00707 static GLUTwindow **beforeEnd;
00708 
00709 static GLUTwindow *
00710 processWindowWorkList(GLUTwindow * window)
00711 {
00712   int workMask;
00713 
00714   if (window->prevWorkWin)
00715     window->prevWorkWin = processWindowWorkList(window->prevWorkWin);
00716   else
00717     beforeEnd = &window->prevWorkWin;
00718 
00719   
00720 
00721 
00722 
00723 
00724 
00725 
00726   workMask = window->workMask;
00727   assert((workMask & GLUT_DUMMY_WORK) == 0);
00728 
00729   
00730 
00731 
00732 
00733 
00734   window->workMask = GLUT_DUMMY_WORK;
00735 
00736   
00737 
00738 
00739 
00740 
00741   if (workMask & (GLUT_EVENT_MASK_WORK | GLUT_DEVICE_MASK_WORK |
00742       GLUT_CONFIGURE_WORK | GLUT_COLORMAP_WORK | GLUT_MAP_WORK)) {
00743     
00744     if (workMask & GLUT_EVENT_MASK_WORK) {
00745       long eventMask;
00746 
00747       
00748 
00749 
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     
00776     if (workMask & GLUT_DEVICE_MASK_WORK) {
00777       __glutUpdateInputDeviceMaskFunc(window);
00778     }
00779     
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;  
00798 
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         
00810 
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     
00822 
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       
00851 
00852       __glutSetWindow(window);
00853       window->reshape(window->width, window->height);
00854       window->forceReshape = False;
00855     }
00856     
00857 
00858 
00859 
00860 
00861 
00862 
00863 
00864 
00865 
00866     if (window->overlay && window->overlay->display) {
00867       int num = window->num;
00868       Window xid = window->overlay ? window->overlay->win : None;
00869 
00870       
00871 
00872 
00873 
00874 
00875 
00876       if (workMask & GLUT_REDISPLAY_WORK) {
00877 
00878         
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           
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           
00902 
00903 
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   
00919 
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   
00934   window->workMask &= ~(GLUT_DUMMY_WORK | GLUT_FINISH_WORK | GLUT_DEBUG_WORK);
00935   if (window->workMask) {
00936     
00937     return window;
00938   } else {
00939     
00940     return window->prevWorkWin;
00941   }
00942 }
00943 
00944 void
00945 glutMainLoop(void)
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 }