#include #include int nWindow, nChildWindow = -1; int nLoopMain = 0; GLboolean bChildPosDone = GL_FALSE, bChildSizeDone = GL_FALSE; void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY ); void Redisplay(); void Reshape(int width, int height); void Position(int x, int y); void WindowStatus(int state); void DrawQuad() { int width = glutGet(GLUT_WINDOW_WIDTH); int height = glutGet(GLUT_WINDOW_HEIGHT); glBegin(GL_QUADS); glVertex2d(width*.25, height*.75); glVertex2d(width*.75, height*.75); glVertex2d(width*.75, height*.25); glVertex2d(width*.25, height*.25); glEnd(); } void UnhideTimer(int window) { glutSetWindow(window); glutShowWindow(); } void ChangeTitleTimer(int unused) { glutSetIconTitle("new icon title"); glutSetWindowTitle("new test title"); } void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY ) { switch (cChar) { case 27: glutLeaveMainLoop(); break; case 'f': case 'F': printf("main window toggle fullscreen\n"); glutFullScreenToggle(); break; case 'r': case 'R': if (nChildWindow!=-1 && cChar=='r') /* Capital R always resizes the main window*/ { glutSetWindow(nChildWindow); printf("child window resize\n"); if (!bChildSizeDone) glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)+50,glutGet(GLUT_WINDOW_HEIGHT)+50); else glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)-50,glutGet(GLUT_WINDOW_HEIGHT)-50); bChildSizeDone = !bChildSizeDone; } else { glutSetWindow(nWindow); printf("main window resize\n"); if (glutGet(GLUT_WINDOW_WIDTH)<400) glutReshapeWindow(600,300); else glutReshapeWindow(300,300); } break; case 'm': case 'M': if (nChildWindow!=-1 && cChar=='m') /* Capital M always moves the main window*/ { glutSetWindow(nChildWindow); /* The window position you request is relative to the top-left * corner of the client area of the parent window. */ if (!bChildPosDone) glutPositionWindow(glutGet(GLUT_WINDOW_X)+50,glutGet(GLUT_WINDOW_Y)+50); else glutPositionWindow(glutGet(GLUT_WINDOW_X)-50,glutGet(GLUT_WINDOW_Y)-50); bChildPosDone = !bChildPosDone; } else { glutSetWindow(nWindow); printf("main window position\n"); /* The window position you request is the outer top-left of the window, * the client area is at a different position if the window has borders * and/or a title bar. */ if (glutGet(GLUT_WINDOW_X)<400) glutPositionWindow(600,300); else glutPositionWindow(300,300); } break; case 'd': case 'D': if (nChildWindow!=-1 && cChar=='d') /* Capital D always moves+resizes the main window*/ { glutSetWindow(nChildWindow); if (!bChildPosDone) glutPositionWindow(glutGet(GLUT_WINDOW_X)+50,glutGet(GLUT_WINDOW_Y)+50); else glutPositionWindow(glutGet(GLUT_WINDOW_X)-50,glutGet(GLUT_WINDOW_Y)-50); bChildPosDone = !bChildPosDone; if (!bChildSizeDone) glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)+50,glutGet(GLUT_WINDOW_HEIGHT)+50); else glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)-50,glutGet(GLUT_WINDOW_HEIGHT)-50); bChildSizeDone = !bChildSizeDone; } else { if (glutGet(GLUT_WINDOW_X)<400) glutPositionWindow(600,300); else glutPositionWindow(300,300); if (glutGet(GLUT_WINDOW_WIDTH)<400) glutReshapeWindow(600,300); else glutReshapeWindow(300,300); } break; case 'c': case 'C': if (nChildWindow==-1) { int width = glutGet(GLUT_WINDOW_WIDTH); int height = glutGet(GLUT_WINDOW_HEIGHT); /* open child window */ printf("open child window\n"); nChildWindow = glutCreateSubWindow(nWindow,(int)(width*.35),(int)(height*.35),(int)(width*.3),(int)(height*.3)); glutKeyboardFunc( SampleKeyboard ); glutDisplayFunc( Redisplay ); glutReshapeFunc( Reshape ); glutPositionFunc( Position ); glutWindowStatusFunc( WindowStatus ); } else { /* close child window */ printf("close child window\n"); glutSetWindow(nWindow); glutDestroyWindow(nChildWindow); nChildWindow = -1; bChildSizeDone = GL_FALSE; bChildPosDone = GL_FALSE; } break; case 'i': case 'I': glutIconifyWindow(); glutTimerFunc(1500, ChangeTitleTimer, 0); break; case 'h': case 'H': if (nChildWindow!=-1 && cChar=='h') /* Capital H always hides the main window*/ { glutSetWindow(nChildWindow); glutTimerFunc(2000, UnhideTimer, nChildWindow); } else { glutSetWindow(nWindow); glutTimerFunc(2000, UnhideTimer, nWindow); } glutHideWindow(); break; case 'p': case 'P': if (nChildWindow!=-1 && cChar=='p') /* Capital P always changes pointer for the main window*/ { glutSetWindow(nChildWindow); if (glutGet(GLUT_WINDOW_CURSOR)==GLUT_CURSOR_TOP_SIDE) { glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); printf("reverting child window cursor\n"); } else { glutSetCursor(GLUT_CURSOR_TOP_SIDE); printf("changing child window cursor\n"); } } else { glutSetWindow(nWindow); if (glutGet(GLUT_WINDOW_CURSOR)==GLUT_CURSOR_CYCLE) { glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); printf("reverting main window cursor\n"); } else { glutSetCursor(GLUT_CURSOR_CYCLE); printf("changing main window cursor\n"); } } break; default: break; } } void Idle(void) { glutPostRedisplay(); } void Reshape(int width, int height) { int win = glutGetWindow(); printf("reshape %s, client area: %dx%d\n",win==nWindow?"main":"child", width, height); glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,width,0,height); if (win==nWindow && nChildWindow!=-1) { /* Put child window in right place */ int x = (int)(width*.35), y=(int)(height*.35), w=(int)(width*.3), h = (int)(height*.3); if (bChildPosDone) { x += 50; y += 50; } if (bChildSizeDone) { w += 50; h += 50; } glutSetWindow(nChildWindow); glutPositionWindow(x,y); glutReshapeWindow(w,h); glutSetWindow(nWindow); } } void Position(int x, int y) { int win = glutGetWindow(); printf("position, %s: (%d,%d)\n",win==nWindow?"top-left (non-client) of main":"top-left of child relative to parent", x, y); } void WindowStatus(int state) { int win = glutGetWindow(); printf("windowstatus (win %i): %i\n",win,state); } void Redisplay(void) { int win = glutGetWindow(); int viewport[4]; if (win==nWindow) { glClearColor(.2f,0.f,0.f,0.f); glColor3f(1,1,1); } else { /* child window */ glClearColor(.0f,.2f,0.f,0.f); glColor3f(.5,.5,.5); glutPostWindowRedisplay(nWindow); } glClear(GL_COLOR_BUFFER_BIT); DrawQuad(); if (win==nWindow) { glColor3f(1, 1, 0); glGetIntegerv(GL_VIEWPORT, viewport); glRasterPos2i(2, -glutBitmapHeight(GLUT_BITMAP_9_BY_15)+3+viewport[3]); glutBitmapString(GLUT_BITMAP_9_BY_15, (unsigned char*)"press f/r/m/d/c/i/h/p"); } glutSwapBuffers(); glutPostWindowRedisplay(win); } void Timer(int unused) { int win = glutGetWindow(); int x, y; int width, height; int border, caption; x = glutGet(GLUT_WINDOW_X); y = glutGet(GLUT_WINDOW_Y); width = glutGet(GLUT_WINDOW_WIDTH); height = glutGet(GLUT_WINDOW_HEIGHT); border = glutGet(GLUT_WINDOW_BORDER_WIDTH); caption = glutGet(GLUT_WINDOW_HEADER_HEIGHT); /* returned position is top-left of client area, to get top-left of * of window you'll need to add the size of the border and caption * of the current window (can be 0). * Note that the window position is not necessarily positive (e.g. * when the window is on a monitor to the left of the primary monitor * or simply when maximized--try pressing the maximize button). * the returned size is the size of the client area * Note that the top-left of a child window is relative to the * top-left of the client area of the parent. */ /* printf("window border: %dpx, caption: %dpx\n",border,caption); */ if (win==nWindow) printf("main window %dx%d, top-left of client at: (%d,%d), of window at: (%d,%d)\n", width, height, x ,y, x-border, y-caption); else printf("child window %dx%d, top-left of client at: (%d,%d), relative to parent\n", width, height, x ,y); /* (re)set the timer callback and ask glut to call it in 500 ms */ glutTimerFunc(500, Timer, 0); } int main(int argc, char* argv[]) { int border, caption; glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE /*| GLUT_BORDERLESS*/); // do try as well with GLUT_BORDERLESS and GLUT_CAPTIONLESS glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS); /* Get border and caption size of default window style */ border = glutGet(GLUT_WINDOW_BORDER_WIDTH); caption = glutGet(GLUT_WINDOW_HEADER_HEIGHT); printf("default window style border: %dpx, caption: %dpx\n",border,caption); /* NB: The window position you request is the outer top-left of the * window, the client area is at a different position if the window has * borders and/or a title bar. */ glutInitWindowPosition(150,250); glutInitWindowSize(200,200); nWindow = glutCreateWindow("test"); glutSetIconTitle("test icon title"); printf("main window id: %d\n", nWindow); glutKeyboardFunc( SampleKeyboard ); glutDisplayFunc( Redisplay ); glutReshapeFunc( Reshape ); glutPositionFunc( Position ); glutWindowStatusFunc( WindowStatus ); glutTimerFunc(300, Timer, 0); glutMainLoop(); printf("glutMainLoop returned\n"); return EXIT_SUCCESS; }