#include "GlutWin.h" #include #include #include "jd_time.h" #include WindowPair *GlutWin::windowList=NULL; GlutWin *GlutWin::containerWindow = NULL; /*************************************************************************** G L U T W I N : : G L U T W I N ***************************************************************************/ GlutWin::GlutWin() { // Create Window if (containerWindow== NULL) glWindowNum=glutCreateWindow(""); else glWindowNum=glutCreateSubWindow(containerWindow->glWindowNum, 100, 100, 100, 100); // Add to windowList WindowPair *tmpPair=new WindowPair(); tmpPair->next=windowList; windowList=tmpPair; tmpPair->glWindowNum=glWindowNum; tmpPair->glutwin= this; // Init fields width=0; height=0; parentWindow=containerWindow; idleInterval=0; nextIdleTime=0; leftbuttonstate=middlebuttonstate=rightbuttonstate=GLUT_UP; keyModifiers=0; menuID[0]=menuID[1]=menuID[2]=0; // Register all callbacks glutDisplayFunc(::glutWinDisplay); glutReshapeFunc(::glutWinReshape); glutMouseFunc(::glutWinMouse); glutIdleFunc(::glutWinIdle); glutKeyboardFunc(::glutWinKeyboard); glutMotionFunc(::glutWinMotion); } /*************************************************************************** G L U T W I N : : ~ G L U T W I N ***************************************************************************/ GlutWin::~GlutWin() { // Delete the glut window glutDestroyWindow(glWindowNum); // Remove the window from the windowlist WindowPair *curwin = GlutWin::windowList; WindowPair *prev=NULL; while (curwin !=NULL) { if (curwin->glutwin == this) { // Set the prev to point to next unless // we are the head, then set the list to point to next if (prev!=NULL) { prev->next=curwin->next; } else { GlutWin::windowList=curwin->next; } delete curwin; printf ("windowlist remaining %p\n",GlutWin::windowList); break; } // Is the next element it? prev=curwin; curwin=curwin->next; } } /*************************************************************************** G L U T W I N S U B W I N D O W ***************************************************************************/ void glutWinSubWindow(GlutWin *winNum ) { if (winNum== NULL) winNum=getGlutWin(glutGetWindow()); GlutWin::containerWindow = winNum; } /*************************************************************************** G L U T W I N M A I N W I N D O W ***************************************************************************/ void glutWinMainWindow() { GlutWin::containerWindow = NULL; } /*************************************************************************** G L U T W I N : : S E T W I N D O W T I T L E ***************************************************************************/ void GlutWin::setWindowTitle(char *title) { // Only on top level windows if (parentWindow==NULL) { glutSetWindow(glWindowNum); glutSetWindowTitle(title); glutSetIconTitle(title); } windowTitle = title; } /*************************************************************************** G L U T W I N : : A C T I V A T E M E N U ***************************************************************************/ void GlutWin::activateMenu(int whichMenu) { int menuId = glutCreateMenu(glutWinMenu); glutAttachMenu(whichMenu); if (whichMenu==GLUT_LEFT_BUTTON) menuID[0]=menuId; else if (whichMenu==GLUT_MIDDLE_BUTTON) menuID[1]=menuId; else if (whichMenu==GLUT_RIGHT_BUTTON) menuID[2]=menuId; else { cout << "ActivateMenu: Err: unknown button specified" << endl; } } /*************************************************************************** G L U T W I N : : D E A C T I V A T E M E N U ***************************************************************************/ void GlutWin::deactivateMenu(int whichMenu) { cout << "menu deactivation not written yet" << endl; } /*************************************************************************** G L U T W I N : : A D D S U B M E N U ***************************************************************************/ int GlutWin::addSubMenu(char *mname) { int curMenu = glutGetMenu(); int mid = glutCreateMenu(glutWinMenu); glutSetMenu(curMenu); // cout << "submenu " << mid << endl; glutAddSubMenu(mname,mid); glutSetMenu(mid); return mid; } /*************************************************************************** G L U T W I N : : G E T M E N U I D ***************************************************************************/ int GlutWin::getMenuID(int whichMenu) { if (whichMenu==GLUT_LEFT_BUTTON) return menuID[0]; else if (whichMenu==GLUT_MIDDLE_BUTTON) return menuID[1]; else if (whichMenu==GLUT_RIGHT_BUTTON) return menuID[2]; else { cout << "GetMMenuIDMenu: Err: unknown button specified" << endl; return 0; } } /*************************************************************************** S E T I D L E I N T E R V A L Set this to -1 = No idle event processing 0 = Process whenever there is idle time i>0 = Process every i milliseconds ***************************************************************************/ void GlutWin::setIdleInterval(int interval) { static int timerFuncStarted=0; // Set the info for this window idleInterval = interval; nextIdleTime = Get_Milliseconds()+interval; // If we are activating idle turn on the idleFunc if (interval==0) glutIdleFunc(glutWinIdle); // Check if we ever started the timer before if (interval>0 && !timerFuncStarted) { timerFuncStarted=1; glutTimerFunc(interval,glutWinTimer,0); } } /*************************************************************************** I D L E ***************************************************************************/ void GlutWin::idle() { //This dropped through to default so this subclass doesn't //Need idle events setIdleInterval(-1); puts ("glutwin idle"); } /*************************************************************************** G L U T W I N : : D I S P L A Y ***************************************************************************/ void GlutWin::display() { // Clear the window printf ("main display %p\n",this); glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT); } /*************************************************************************** G L U T W I N : : R E S H A P E ***************************************************************************/ void GlutWin::reshape(int w, int h) { // Set up the correct orthographic projection glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, w, 0, h, -1.0, 1.0); glRasterPos2f(0, h ); glPixelZoom(1,-1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // puts ("base reshape"); } /*************************************************************************** G L U T W I N : : M O U S E ***************************************************************************/ void GlutWin::mouse(int button, int state, int x, int y) { // If we get here then we don't need mouse events and should shut // them off glutMouseFunc(NULL); puts ("base moouse"); } /*************************************************************************** G L U T W I N : : M O T I O N ***************************************************************************/ void GlutWin::motion(int x, int y) { glutMotionFunc(NULL); puts ("base motion"); } /*************************************************************************** G L U T W I N : : K E Y B O A R D ***************************************************************************/ void GlutWin::keyboard(unsigned char key, int x, int y) { glutKeyboardFunc(NULL); puts ("base keyboard"); } /*************************************************************************** G L U T W I N : : M E N U ***************************************************************************/ void GlutWin::menu(int whichMenu, int value) { int mnum; if (whichMenu==GLUT_LEFT_BUTTON) { mnum=0; cout << "LEFT_BUTTON "; } else if (whichMenu==GLUT_MIDDLE_BUTTON) { mnum=1; cout << "MIDDLE_BUTTON "; } else if (whichMenu==GLUT_RIGHT_BUTTON) { mnum=2; cout << "RIGHT_BUTTON "; } else { cout << "MENU BUTTON ERROR (Submenu?)" << endl; } cout << "mnuem " << mnum << "whichMenu" << whichMenu << " value:" << value << endl; } /*************************************************************************** * G E T G L U T W I N ***************************************************************************/ GlutWin *getGlutWin(int glWindowNum) { WindowPair *curwin = GlutWin::windowList; while (curwin !=NULL) { if (curwin->glWindowNum == glWindowNum) return curwin->glutwin; curwin=curwin->next; } return NULL; } /*************************************************************************** G L U T W I N I D L E ***************************************************************************/ void glutWinIdle() { WindowPair *curwin = GlutWin::windowList; int anythingIdle=0; // Loop through the window list while (curwin !=NULL) { // If current window processes idle events then call if (curwin->glutwin->idleInterval==0) { glutSetWindow(curwin->glutwin->glWindowNum); curwin->glutwin->idle(); anythingIdle=1; } curwin=curwin->next; } // If no windows have idle events then turn off this function if (!anythingIdle) glutIdleFunc(NULL); } /*************************************************************************** G L U T W I N T I M E R ***************************************************************************/ void glutWinTimer(int value) { WindowPair *curwin = GlutWin::windowList; long firstTimer=1000000000; long currentTime = Get_Milliseconds(); // Loop through the window list while (curwin !=NULL) { // If current window is ready process it if (curwin->glutwin->idleInterval>0 && curwin->glutwin->nextIdleTime < currentTime) { // Set next idle time curwin->glutwin->nextIdleTime = currentTime+curwin->glutwin->idleInterval; // Call idle routine glutSetWindow(curwin->glutwin->glWindowNum); curwin->glutwin->idle(); } // Is this the next thing to need attention? if (curwin->glutwin->idleInterval>0) { // Check for first timer needed if (curwin->glutwin->nextIdleTimeglutwin->nextIdleTime; } curwin=curwin->next; } // Set this timer to go off again at the necessary interval, but // Not more than .25 seconds from now firstTimer=firstTimer-Get_Milliseconds(); if (firstTimer>250) firstTimer=250; if (firstTimer<1) firstTimer=1; glutTimerFunc(firstTimer,glutWinTimer,0); } /*************************************************************************** G L U T W I N D I S P L A Y ***************************************************************************/ void glutWinDisplay() { GlutWin *win=getGlutWin(glutGetWindow()); if (win!=NULL) { win->display(); } } /*************************************************************************** G L U T W I N R E S H A P E ***************************************************************************/ void glutWinReshape(int width, int height) { GlutWin *win=getGlutWin(glutGetWindow()); if (win!=NULL) win->reshape(width, height); // Save the latest resize win->width=width; win->height=height; } /*************************************************************************** G L U T W I N M O U S E ***************************************************************************/ void glutWinMouse(int button, int state, int x, int y) { GlutWin *win=getGlutWin(glutGetWindow()); if (win!=NULL) { // save modifiers for use in motion callback win->keyModifiers=glutGetModifiers(); // save the button state for use in motion callback switch (button) { case GLUT_LEFT_BUTTON: win->leftbuttonstate=state; break; case GLUT_MIDDLE_BUTTON: win->middlebuttonstate=state; break; case GLUT_RIGHT_BUTTON: win->rightbuttonstate=state; break; } win->mouse(button,state,x,y); } } /*************************************************************************** G L U T W I N M O T I O N ***************************************************************************/ void glutWinMotion(int x, int y) { GlutWin *win=getGlutWin(glutGetWindow()); if (win!=NULL) win->motion(x,y); } /*************************************************************************** G L U T W I N K E Y B O A R D ***************************************************************************/ void glutWinKeyboard(unsigned char key, int x, int y) { GlutWin *win=getGlutWin(glutGetWindow()); if (win!=NULL) win->keyboard(key,x,y); } /*************************************************************************** G L U T W I N M E N U ***************************************************************************/ void glutWinMenu(int value) { GlutWin *win=getGlutWin(glutGetWindow()); if (win!=NULL) { int menu=glutGetMenu(); if (menu!=0) { // figure which menu this is if (menu==win->menuID[0]) win->menu(GLUT_LEFT_BUTTON,value); else if (menu==win->menuID[1]) win->menu(GLUT_MIDDLE_BUTTON,value); else if (menu==win->menuID[2]) win->menu(GLUT_RIGHT_BUTTON,value); else { win->menu(GLUTWIN_SUBMENU,value); } } } }