📄 glutevent.cpp
字号:
/*********************************************************** * Copyright (C) 1997, Be Inc. Copyright (C) 1999, Jake Hamby. * * This program is freely distributable without licensing fees * and is provided without guarantee or warrantee expressed or * implied. This program is -not- in the public domain. * * * FILE: glutEvent.cpp * * DESCRIPTION: here it is, the BeOS GLUT event loop ***********************************************************//*********************************************************** * Headers ***********************************************************/#include <GL/glut.h>#include "glutint.h"#include "glutState.h"#include "glutBlocker.h"/*********************************************************** * CLASS: GLUTtimer * * DESCRIPTION: list of timer callbacks ***********************************************************/struct GLUTtimer { GLUTtimer *next; // list of timers bigtime_t timeout; // time to be called GLUTtimerCB func; // function to call int value; // value};/*********************************************************** * Private variables ***********************************************************/static GLUTtimer *__glutTimerList = 0; // list of timer callbacksstatic GLUTtimer *freeTimerList = 0;/*********************************************************** * FUNCTION: glutTimerFunc (7.19) * * DESCRIPTION: register a new timer callback ***********************************************************/void APIENTRY glutTimerFunc(unsigned int interval, GLUTtimerCB timerFunc, int value){ GLUTtimer *timer, *other; GLUTtimer **prevptr; if (!timerFunc) return; if (freeTimerList) { timer = freeTimerList; freeTimerList = timer->next; } else { timer = new GLUTtimer(); if (!timer) __glutFatalError("out of memory."); } timer->func = timerFunc; timer->value = value; timer->next = NULL; timer->timeout = system_time() + (interval*1000); // 1000 ticks in a millisecond prevptr = &__glutTimerList; other = *prevptr; while (other && (other->timeout < timer->timeout)) { prevptr = &other->next; other = *prevptr; } timer->next = other; *prevptr = timer;}/*********************************************************** * FUNCTION: handleTimeouts * * DESCRIPTION: private function to handle outstanding timeouts ***********************************************************/static voidhandleTimeouts(void){ bigtime_t now; GLUTtimer *timer; /* Assumption is that __glutTimerList is already determined to be non-NULL. */ now = system_time(); while (__glutTimerList->timeout <= now) { timer = __glutTimerList; if(gState.currentWindow) gState.currentWindow->LockGL(); timer->func(timer->value); if(gState.currentWindow) gState.currentWindow->UnlockGL(); __glutTimerList = timer->next; timer->next = freeTimerList; freeTimerList = timer; if (!__glutTimerList) break; }}/*********************************************************** * FUNCTION: processEventsAndTimeouts * * DESCRIPTION: clear gBlock, then check all windows for events ***********************************************************/static voidprocessEventsAndTimeouts(void){ gBlock.WaitEvent(); // if there is already an event, returns // immediately, otherwise wait forever gBlock.ClearEvents(); if(gState.quitAll) exit(0); // exit handler cleans up windows and quits nicely if (gState.currentWindow) gState.currentWindow->LockGL(); for(int i=0; i<gState.windowListSize; i++) { if (gState.windowList[i]) { GlutWindow *win = gState.windowList[i]; // NOTE: we can use win as a shortcut for gState.windowList[i] // in callbacks, EXCEPT we need to check the original variable // after each callback to make sure the window hasn't been destroyed if (win->anyevents) { win->anyevents = false; if (win->reshapeEvent) { win->reshapeEvent = false; __glutSetWindow(win); win->reshape(win->m_width, win->m_height); } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->displayEvent) { win->displayEvent = false; __glutSetWindow(win); win->display(); } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->mouseEvent) { win->mouseEvent = false; __glutSetWindow(win); if (win->mouse) { gState.modifierKeys = win->modifierKeys; win->mouse(win->button, win->mouseState, win->mouseX, win->mouseY); gState.modifierKeys = ~0; } } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->menuEvent) { win->menuEvent = false; __glutSetWindow(win); GlutMenu *menu = __glutGetMenuByNum(win->menuNumber); if (menu) { gState.currentMenu = menu; menu->select(win->menuValue); } } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->statusEvent) { win->statusEvent = false; __glutSetWindow(win); if (gState.menuStatus) { gState.currentMenu = __glutGetMenuByNum(win->menuNumber); gState.menuStatus(win->menuStatus, win->statusX, win->statusY); } } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->motionEvent) { win->motionEvent = false; __glutSetWindow(win); if (win->motion) win->motion(win->motionX, win->motionY); } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->passiveEvent) { win->passiveEvent = false; __glutSetWindow(win); if (win->passive) win->passive(win->passiveX, win->passiveY); } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->keybEvent) { win->keybEvent = false; __glutSetWindow(win); if (win->keyboard) { gState.modifierKeys = win->modifierKeys; win->keyboard(win->key, win->keyX, win->keyY); gState.modifierKeys = ~0; } } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->specialEvent) { win->specialEvent = false; __glutSetWindow(win); if (win->special) { gState.modifierKeys = win->modifierKeys; win->special(win->specialKey, win->specialX, win->specialY); gState.modifierKeys = ~0; } } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->entryEvent) { win->entryEvent = false; __glutSetWindow(win); if (win->entry) win->entry(win->entryState); } if (!gState.windowList[i]) continue; // window was destroyed by callback! if (win->windowStatusEvent) { win->windowStatusEvent = false; __glutSetWindow(win); if (win->windowStatus) win->windowStatus(win->visState); } if (!gState.windowList[i]) continue; // window was destroyed by callback! } } } if (gState.currentWindow) gState.currentWindow->UnlockGL(); // This code isn't necessary since BGLView automatically traps errors#if 0 if(gState.debug) { for(int i=0; i<gState.windowListSize; i++) { if (gState.windowList[i]) { gState.windowList[i]->LockGL(); glutReportErrors(); gState.windowList[i]->UnlockGL(); } } }#endif if (__glutTimerList) { handleTimeouts(); }}/*********************************************************** * FUNCTION: waitForSomething * * DESCRIPTION: use gBlock to wait for a new event or timeout ***********************************************************/static voidwaitForSomething(void){ bigtime_t timeout = __glutTimerList->timeout; bigtime_t now = system_time(); if (gBlock.PendingEvent()) goto immediatelyHandleEvent; if(timeout>now) gBlock.WaitEvent(timeout-now); if (gBlock.PendingEvent()) { immediatelyHandleEvent: processEventsAndTimeouts(); } else { if (__glutTimerList) handleTimeouts(); }}/*********************************************************** * FUNCTION: idleWait * * DESCRIPTION: check for events, then call idle function ***********************************************************/static voididleWait(void){ if (gBlock.PendingEvent()) { processEventsAndTimeouts(); } else { if (__glutTimerList) handleTimeouts(); } /* Make sure idle func still exists! */ if(gState.currentWindow) gState.currentWindow->LockGL(); if (gState.idle) { gState.idle(); } if(gState.currentWindow) gState.currentWindow->UnlockGL();}/*********************************************************** * FUNCTION: glutMainLoop (3.1) * * DESCRIPTION: enter the event processing loop ***********************************************************/void glutMainLoop(){ if (!gState.windowListSize) __glutFatalUsage("main loop entered with no windows created."); if(gState.currentWindow) gState.currentWindow->UnlockGL(); for (;;) { if (gState.idle) { idleWait(); } else { if (__glutTimerList) { waitForSomething(); } else { processEventsAndTimeouts(); } } }}/*********************************************************** * CLASS: GlutWindow * * FUNCTION: KeyDown * * DESCRIPTION: handles keyboard and special events ***********************************************************/void GlutWindow::KeyDown(const char *s, int32 slen){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -