⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glut_event.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    waittime = zerotime;  }#if !defined(_WIN32)  rc = select(__glutConnectionFD + 1, &fds,    NULL, NULL, &waittime);  if (rc < 0 && errno != EINTR)    __glutFatalError("select error.");#else  MsgWaitForMultipleObjects(0, NULL, FALSE,    waittime.tv_sec*1000 + waittime.tv_usec/1000, QS_ALLINPUT);#endif#endif /* not vms6.2 or lower */  /* Without considering the cause of select unblocking, check     for pending X events and handle any timeouts (by calling     processEventsAndTimeouts).  We always look for X events     even if select returned with 0 (indicating a timeout);     otherwise we risk starving X event processing by continous     timeouts. */  if (XPending(__glutDisplay)) {  immediatelyHandleXinput:    processEventsAndTimeouts();  } else {    if (__glutTimerList)      handleTimeouts();  }}static voididleWait(void){  if (XPending(__glutDisplay)) {    processEventsAndTimeouts();  } else {    if (__glutTimerList) {      handleTimeouts();    }  }  /* Make sure idle func still exists! */  if (__glutIdleFunc) {    __glutIdleFunc();  }}static GLUTwindow **beforeEnd;static GLUTwindow *processWindowWorkList(GLUTwindow * window){  int workMask;  if (window->prevWorkWin) {    window->prevWorkWin = processWindowWorkList(window->prevWorkWin);  } else {    beforeEnd = &window->prevWorkWin;  }  /* Capture work mask for work that needs to be done to this     window, then clear the window's work mask (excepting the     dummy work bit, see below).  Then, process the captured     work mask.  This allows callbacks in the processing the     captured work mask to set the window's work mask for     subsequent processing. */  workMask = window->workMask;  assert((workMask & GLUT_DUMMY_WORK) == 0);  /* Set the dummy work bit, clearing all other bits, to     indicate that the window is currently on the window work     list _and_ that the window's work mask is currently being     processed.  This convinces __glutPutOnWorkList that this     window is on the work list still. */  window->workMask = GLUT_DUMMY_WORK;  /* Optimization: most of the time, the work to do is a     redisplay and not these other types of work.  Check for     the following cases as a group to before checking each one     individually one by one. This saves about 25 MIPS     instructions in the common redisplay only case. */  if (workMask & (GLUT_EVENT_MASK_WORK | GLUT_DEVICE_MASK_WORK |      GLUT_CONFIGURE_WORK | GLUT_COLORMAP_WORK | GLUT_MAP_WORK)) {#if !defined(_WIN32)    /* Be sure to set event mask BEFORE map window is done. */    if (workMask & GLUT_EVENT_MASK_WORK) {      long eventMask;      /* Make sure children are not propogating events this         window is selecting for.  Be sure to do this before         enabling events on the children's parent. */      if (window->children) {        GLUTwindow *child = window->children;        unsigned long attribMask = CWDontPropagate;        XSetWindowAttributes wa;        wa.do_not_propagate_mask = window->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;        if (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) {          wa.event_mask = child->eventMask | (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK);          attribMask |= CWEventMask;        }        do {          XChangeWindowAttributes(__glutDisplay, child->win,            attribMask, &wa);          child = child->siblings;        } while (child);      }      eventMask = window->eventMask;      if (window->parent && window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)        eventMask |= (window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK);      XSelectInput(__glutDisplay, window->win, eventMask);      if (window->overlay)        XSelectInput(__glutDisplay, window->overlay->win,          window->eventMask & GLUT_OVERLAY_EVENT_FILTER_MASK);    }#endif /* !_WIN32 */    /* Be sure to set device mask BEFORE map window is done. */    if (workMask & GLUT_DEVICE_MASK_WORK) {      __glutUpdateInputDeviceMaskFunc(window);    }    /* Be sure to configure window BEFORE map window is done. */    if (workMask & GLUT_CONFIGURE_WORK) {#if defined(_WIN32)      RECT changes;      POINT point;      UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER	| SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER;      GetClientRect(window->win, &changes);            /* If this window is a toplevel window, translate the 0,0 client         coordinate into a screen coordinate for proper placement. */      if (!window->parent) {        point.x = 0;        point.y = 0;        ClientToScreen(window->win, &point);        changes.left = point.x;        changes.top = point.y;      }      if (window->desiredConfMask & (CWX | CWY)) {        changes.left = window->desiredX;        changes.top = window->desiredY;	flags &= ~SWP_NOMOVE;      }      if (window->desiredConfMask & (CWWidth | CWHeight)) {        changes.right = changes.left + window->desiredWidth;        changes.bottom = changes.top + window->desiredHeight;	flags &= ~SWP_NOSIZE;	/* XXX If overlay exists, resize the overlay here, ie.	   if (window->overlay) ... */      }      if (window->desiredConfMask & CWStackMode) {	flags &= ~SWP_NOZORDER;	/* XXX Overlay support might require something special here. */      }      /* Adjust the window rectangle because Win32 thinks that the x, y,         width & height are the WHOLE window (including decorations),         whereas GLUT treats the x, y, width & height as only the CLIENT         area of the window.  Only do this to top level windows         that are not in game mode (since game mode windows do         not have any decorations). */      if (!window->parent && window != __glutGameModeWindow) {        AdjustWindowRect(&changes,          WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,          FALSE);      }      /* Do the repositioning, moving, and push/pop. */      SetWindowPos(window->win,        window->desiredStack == Above ? HWND_TOP : HWND_NOTOPMOST,        changes.left, changes.top,        changes.right - changes.left, changes.bottom - changes.top,        flags);      /* Zero out the mask. */      window->desiredConfMask = 0;      /* This hack causes the window to go back to the right position         when it is taken out of fullscreen mode. */      if (workMask & GLUT_FULL_SCREEN_WORK) {        window->desiredConfMask |= CWX | CWY;        window->desiredX = point.x;        window->desiredY = point.y;      }#else /* !_WIN32 */      XWindowChanges changes;      changes.x = window->desiredX;      changes.y = window->desiredY;      if (window->desiredConfMask & (CWWidth | CWHeight)) {        changes.width = window->desiredWidth;        changes.height = window->desiredHeight;        if (window->overlay)          XResizeWindow(__glutDisplay, window->overlay->win,            window->desiredWidth, window->desiredHeight);        if (__glutMotifHints != None) {          if (workMask & GLUT_FULL_SCREEN_WORK) {            MotifWmHints hints;            hints.flags = MWM_HINTS_DECORATIONS;            hints.decorations = 0;  /* Absolutely no                                       decorations. */            XChangeProperty(__glutDisplay, window->win,              __glutMotifHints, __glutMotifHints, 32,              PropModeReplace, (unsigned char *) &hints, 4);            if (workMask & GLUT_MAP_WORK) {              /* Handle case where glutFullScreen is called                 before the first time that the window is                 mapped. Some window managers will randomly or                 interactively position the window the first                 time it is mapped if the window's                 WM_NORMAL_HINTS property does not request an                 explicit position. We don't want any such                 window manager interaction when going                 fullscreen.  Overwrite the WM_NORMAL_HINTS                 property installed by glutCreateWindow's                 XSetWMProperties property with one explicitly                 requesting a fullscreen window. */              XSizeHints hints;              hints.flags = USPosition | USSize;              hints.x = 0;              hints.y = 0;              hints.width = window->desiredWidth;              hints.height = window->desiredHeight;              XSetWMNormalHints(__glutDisplay, window->win, &hints);            }          } else {            XDeleteProperty(__glutDisplay, window->win, __glutMotifHints);          }        }      }      if (window->desiredConfMask & CWStackMode) {        changes.stack_mode = window->desiredStack;        /* Do not let glutPushWindow push window beneath the           underlay. */        if (window->parent && window->parent->overlay          && window->desiredStack == Below) {          changes.stack_mode = Above;          changes.sibling = window->parent->overlay->win;          window->desiredConfMask |= CWSibling;        }      }      XConfigureWindow(__glutDisplay, window->win,        window->desiredConfMask, &changes);      window->desiredConfMask = 0;#endif    }#if !defined(_WIN32)    /* Be sure to establish the colormaps BEFORE map window is       done. */    if (workMask & GLUT_COLORMAP_WORK) {      __glutEstablishColormapsProperty(window);    }#endif    if (workMask & GLUT_MAP_WORK) {      switch (window->desiredMapState) {      case WithdrawnState:        if (window->parent) {          XUnmapWindow(__glutDisplay, window->win);        } else {          XWithdrawWindow(__glutDisplay, window->win,            __glutScreen);        }        window->shownState = 0;        break;      case NormalState:        XMapWindow(__glutDisplay, window->win);        window->shownState = 1;        break;#ifdef _WIN32      case GameModeState:  /* Not an Xlib value. */        ShowWindow(window->win, SW_SHOW);        window->shownState = 1;        break;#endif      case IconicState:        XIconifyWindow(__glutDisplay, window->win, __glutScreen);        window->shownState = 0;        break;      }    }  }  if (workMask & (GLUT_REDISPLAY_WORK | GLUT_OVERLAY_REDISPLAY_WORK | GLUT_REPAIR_WORK | GLUT_OVERLAY_REPAIR_WORK)) {    if (window->forceReshape) {      /* Guarantee that before a display callback is generated         for a window, a reshape callback must be generated. */      __glutSetWindow(window);      window->reshape(window->width, window->height);      window->forceReshape = False;      /* Setting the redisplay bit on the first reshape is         necessary to make the "Mesa glXSwapBuffers to repair         damage" hack operate correctly.  Without indicating a         redisplay is necessary, there's not an initial back         buffer render from which to blit from when damage         happens to the window. */      workMask |= GLUT_REDISPLAY_WORK;    }    /* The code below is more involved than otherwise necessary       because it is paranoid about the overlay or entire window       being removed or destroyed in the course of the callbacks.       Notice how the global __glutWindowDamaged is used to record       the layers' damage status.  See the code in glutLayerGet for       how __glutWindowDamaged is used. The  point is to not have to       update the "damaged" field after  the callback since the       window (or overlay) may be destroyed (or removed) when the       callback returns. */    if (window->overlay && window->overlay->display) {      int num = window->num;      Window xid = window->overlay ? window->overlay->win : None;      /* If an overlay display callback is registered, we         differentiate between a redisplay needed for the         overlay and/or normal plane.  If there is no overlay         display callback registered, we simply use the         standard display callback. */      if (workMask & (GLUT_REDISPLAY_WORK | GLUT_REPAIR_WORK)) {        if (__glutMesaSwapHackSupport) {          if (window->usedSwapBuffers) {            if ((workMask & (GLUT_REPAIR_WORK | GLUT_REDISPLAY_WORK)) == GLUT_REPAIR_WORK) {	      SWAP_BUFFERS_WINDOW(window);              goto skippedDisplayCallback1;            }          }        }        /* Render to normal plane. */#ifdef _WIN32        window->renderDc = window->hdc;#endif        window->renderWin = window->win;        window->renderCtx = window->ctx;        __glutWindowDamaged = (workMask & GLUT_REPAIR_WORK);        __glutSetWindow(window);        window->usedSwapBuffers = 0;        window->display();        __glutWindowDamaged = 0;      skippedDisplayCallback1:;      }      if (workMask & (GLUT_OVERLAY_REDISPLAY_WORK | GLUT_OVERLAY_REPAIR_WORK)) {        window = __glutWindowList[num];        if (window && window->overlay &&          window->overlay->win == xid && window->overlay->display) {          /* Render to overlay. */#ifdef _WIN32          window->renderDc = window->overlay->hdc;#endif          window->renderWin = window->overlay->win;          window->renderCtx = window->overlay->ctx;          __glutWindowDamaged = (workMask & GLUT_OVERLAY_REPAIR_WORK);          __glutSetWindow(window);          window->overlay->display();          __glutWindowDamaged = 0;        } else {          /* Overlay may have since been destroyed or the             overlay callback may have been disabled during             normal display callback. */        }      }    } else {      if (__glutMesaSwapHackSupport) {        if (!window->overlay && window->usedSwapBuffers) {          if ((workMask & (GLUT_REPAIR_WORK | GLUT_REDISPLAY_WORK)) == GLUT_REPAIR_WORK) {	    SWAP_BUFFERS_WINDOW(window);            goto skippedDisplayCallback2;          }        }      }      /* Render to normal plane (and possibly overlay). */      __glutWindowDamaged = (workMask & (GLUT_OVERLAY_REPAIR_WORK | GLUT_REPAIR_WORK));      __glutSetWindow(window);      window->usedSwapBuffers = 0;      window->display();      __glutWindowDamaged = 0;    skippedDisplayCallback2:;    }  }  /* Combine workMask with window->workMask to determine what     finish and debug work there is. */  workMask |= window->workMask;  if (workMask & GLUT_FINISH_WORK) {    /* Finish work makes sure a glFinish gets done to indirect       rendering contexts.  Indirect contexts tend to have much        longer latency because lots of OpenGL extension requests        can queue up in the X protocol stream. __glutSetWindow       is where the finish works gets queued for indirect       contexts. */    __glutSetWindow(window);    glFinish();  }  if (workMask & GLUT_DEBUG_WORK) {    __glutSetWindow(window);    glutReportErrors();  }  /* Strip out dummy, finish, and debug work bits. */  window->workMask &= ~(GLUT_DUMMY_WORK | GLUT_FINISH_WORK | GLUT_DEBUG_WORK);  if (window->workMask) {    /* Leave on work list. */    return window;  } else {    /* Remove current window from work list. */    return window->prevWorkWin;  }}#ifndef _WIN32static  /* X11 implementations do not need this global. */#endifvoid__glutProcessWindowWorkLists(void){  if (__glutWindowWorkList) {    GLUTwindow *remainder, *work;    work = __glutWindowWorkList;    __glutWindowWorkList = NULL;    if (work) {      remainder = processWindowWorkList(work);      if (remainder) {        *beforeEnd = __glutWindowWorkList;        __glutWindowWorkList = remainder;      }    }  }}/* CENTRY */void GLUTAPIENTRYglutMainLoop(void){#if !defined(_WIN32)  if (!__glutDisplay)    __glutFatalUsage("main loop entered with out proper initialization.");#endif  if (!__glutWindowListSize)    __glutFatalUsage(      "main loop entered with no windows created.");  for (;;) {    __glutProcessWindowWorkLists();    if (__glutIdleFunc || __glutWindowWorkList) {      idleWait();    } else {      if (__glutTimerList) {        waitForSomething();      } else {        processEventsAndTimeouts();      }    }  }}/* ENDCENTRY */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -