1 #include <stdio.h>
2 
3 #include <GL/freeglut.h>
4 
5 int nWindow, nChildWindow = -1;
6 int nLoopMain = 0;
7 GLboolean bChildPosDone = GL_FALSE, bChildSizeDone = GL_FALSE;
8 
9 void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY );
10 void Redisplay();
11 void Reshape(int width, int height);
12 void Position(int x, int y);
13 void WindowStatus(int state);
14 
15 
16 
17 
DrawQuad()18 void DrawQuad()
19 {
20     int width  = glutGet(GLUT_WINDOW_WIDTH);
21     int height = glutGet(GLUT_WINDOW_HEIGHT);
22 
23     glBegin(GL_QUADS);
24         glVertex2d(width*.25, height*.75);
25         glVertex2d(width*.75, height*.75);
26         glVertex2d(width*.75, height*.25);
27         glVertex2d(width*.25, height*.25);
28     glEnd();
29 }
30 
UnhideTimer(int window)31 void UnhideTimer(int window)
32 {
33     glutSetWindow(window);
34     glutShowWindow();
35 }
36 
ChangeTitleTimer(int unused)37 void ChangeTitleTimer(int unused)
38 {
39     glutSetIconTitle("new icon title");
40     glutSetWindowTitle("new test title");
41 }
42 
SampleKeyboard(unsigned char cChar,int nMouseX,int nMouseY)43 void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY )
44 {
45     switch (cChar)
46     {
47     case 27:
48         glutLeaveMainLoop();
49 
50         break;
51 
52 
53     case 'f':
54     case 'F':
55         printf("main window toggle fullscreen\n");
56         glutFullScreenToggle();
57 
58         break;
59 
60 
61     case 'r':
62     case 'R':
63         if (nChildWindow!=-1 && cChar=='r') /* Capital R always resizes the main window*/
64         {
65             glutSetWindow(nChildWindow);
66             printf("child window resize\n");
67             if (!bChildSizeDone)
68                 glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)+50,glutGet(GLUT_WINDOW_HEIGHT)+50);
69             else
70                 glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)-50,glutGet(GLUT_WINDOW_HEIGHT)-50);
71             bChildSizeDone = !bChildSizeDone;
72         }
73         else
74         {
75             glutSetWindow(nWindow);
76             printf("main window resize\n");
77             if (glutGet(GLUT_WINDOW_WIDTH)<400)
78                 glutReshapeWindow(600,300);
79             else
80                 glutReshapeWindow(300,300);
81         }
82 
83         break;
84 
85 
86     case 'm':
87     case 'M':
88         if (nChildWindow!=-1 && cChar=='m') /* Capital M always moves the main window*/
89         {
90             glutSetWindow(nChildWindow);
91             /* The window position you request is relative to the top-left
92              * corner of the client area of the parent window.
93              */
94             if (!bChildPosDone)
95                 glutPositionWindow(glutGet(GLUT_WINDOW_X)+50,glutGet(GLUT_WINDOW_Y)+50);
96             else
97                 glutPositionWindow(glutGet(GLUT_WINDOW_X)-50,glutGet(GLUT_WINDOW_Y)-50);
98             bChildPosDone = !bChildPosDone;
99         }
100         else
101         {
102             glutSetWindow(nWindow);
103             printf("main window position\n");
104             /* The window position you request is the outer top-left of the window,
105              * the client area is at a different position if the window has borders
106              * and/or a title bar.
107              */
108             if (glutGet(GLUT_WINDOW_X)<400)
109                 glutPositionWindow(600,300);
110             else
111                 glutPositionWindow(300,300);
112         }
113 
114         break;
115 
116 
117     case 'd':
118     case 'D':
119         if (nChildWindow!=-1 && cChar=='d') /* Capital D always moves+resizes the main window*/
120         {
121             glutSetWindow(nChildWindow);
122             if (!bChildPosDone)
123                 glutPositionWindow(glutGet(GLUT_WINDOW_X)+50,glutGet(GLUT_WINDOW_Y)+50);
124             else
125                 glutPositionWindow(glutGet(GLUT_WINDOW_X)-50,glutGet(GLUT_WINDOW_Y)-50);
126             bChildPosDone = !bChildPosDone;
127             if (!bChildSizeDone)
128                 glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)+50,glutGet(GLUT_WINDOW_HEIGHT)+50);
129             else
130                 glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)-50,glutGet(GLUT_WINDOW_HEIGHT)-50);
131             bChildSizeDone = !bChildSizeDone;
132         }
133         else
134         {
135             if (glutGet(GLUT_WINDOW_X)<400)
136                 glutPositionWindow(600,300);
137             else
138                 glutPositionWindow(300,300);
139             if (glutGet(GLUT_WINDOW_WIDTH)<400)
140                 glutReshapeWindow(600,300);
141             else
142                 glutReshapeWindow(300,300);
143         }
144         break;
145 
146 
147     case 'c':
148     case 'C':
149         if (nChildWindow==-1)
150         {
151             int width  = glutGet(GLUT_WINDOW_WIDTH);
152             int height = glutGet(GLUT_WINDOW_HEIGHT);
153 
154             /* open child window */
155             printf("open child window\n");
156 
157             nChildWindow = glutCreateSubWindow(nWindow,(int)(width*.35),(int)(height*.35),(int)(width*.3),(int)(height*.3));
158             glutKeyboardFunc( SampleKeyboard );
159             glutDisplayFunc( Redisplay );
160             glutReshapeFunc( Reshape );
161             glutPositionFunc( Position );
162             glutWindowStatusFunc( WindowStatus );
163         }
164         else
165         {
166             /* close child window */
167             printf("close child window\n");
168             glutSetWindow(nWindow);
169             glutDestroyWindow(nChildWindow);
170             nChildWindow = -1;
171             bChildSizeDone = GL_FALSE;
172             bChildPosDone  = GL_FALSE;
173         }
174         break;
175 
176 
177     case 'i':
178     case 'I':
179         glutIconifyWindow();
180         glutTimerFunc(1500, ChangeTitleTimer, 0);
181         break;
182 
183 
184     case 'h':
185     case 'H':
186         if (nChildWindow!=-1 && cChar=='h') /* Capital H always hides the main window*/
187         {
188             glutSetWindow(nChildWindow);
189             glutTimerFunc(2000, UnhideTimer, nChildWindow);
190         }
191         else
192         {
193             glutSetWindow(nWindow);
194             glutTimerFunc(2000, UnhideTimer, nWindow);
195         }
196         glutHideWindow();
197         break;
198 
199     case 'p':
200     case 'P':
201         if (nChildWindow!=-1 && cChar=='p') /* Capital P always changes pointer for the main window*/
202         {
203             glutSetWindow(nChildWindow);
204 			if (glutGet(GLUT_WINDOW_CURSOR)==GLUT_CURSOR_TOP_SIDE)
205 			{
206 				glutSetCursor(GLUT_CURSOR_RIGHT_ARROW);
207 				printf("reverting child window cursor\n");
208 			}
209             else
210 			{
211 				glutSetCursor(GLUT_CURSOR_TOP_SIDE);
212 				printf("changing child window cursor\n");
213 			}
214         }
215         else
216         {
217             glutSetWindow(nWindow);
218             if (glutGet(GLUT_WINDOW_CURSOR)==GLUT_CURSOR_CYCLE)
219 			{
220 				glutSetCursor(GLUT_CURSOR_RIGHT_ARROW);
221 				printf("reverting main window cursor\n");
222 			}
223             else
224 			{
225 				glutSetCursor(GLUT_CURSOR_CYCLE);
226 				printf("changing main window cursor\n");
227 			}
228         }
229         break;
230 
231     default:
232         break;
233     }
234 }
235 
Idle(void)236 void Idle(void)
237 {
238     glutPostRedisplay();
239 }
240 
Reshape(int width,int height)241 void Reshape(int width, int height)
242 {
243     int win = glutGetWindow();
244 
245     printf("reshape %s, client area: %dx%d\n",win==nWindow?"main":"child",
246         width, height);
247 
248     glViewport(0,0,width,height);
249     glMatrixMode(GL_PROJECTION);
250     glLoadIdentity();
251     gluOrtho2D(0,width,0,height);
252 
253     if (win==nWindow && nChildWindow!=-1)
254     {
255         /* Put child window in right place */
256         int x = (int)(width*.35), y=(int)(height*.35), w=(int)(width*.3), h = (int)(height*.3);
257         if (bChildPosDone)
258         {
259             x += 50;
260             y += 50;
261         }
262         if (bChildSizeDone)
263         {
264             w += 50;
265             h += 50;
266         }
267         glutSetWindow(nChildWindow);
268         glutPositionWindow(x,y);
269         glutReshapeWindow(w,h);
270         glutSetWindow(nWindow);
271     }
272 }
273 
Position(int x,int y)274 void Position(int x, int y)
275 {
276     int win = glutGetWindow();
277 
278     printf("position, %s: (%d,%d)\n",win==nWindow?"top-left (non-client) of main":"top-left of child relative to parent",
279         x, y);
280 }
281 
WindowStatus(int state)282 void WindowStatus(int state)
283 {
284     int win = glutGetWindow();
285     printf("windowstatus (win %i): %i\n",win,state);
286 }
287 
Redisplay(void)288 void Redisplay(void)
289 {
290     int win = glutGetWindow();
291     int viewport[4];
292 
293     if (win==nWindow)
294     {
295         glClearColor(.2f,0.f,0.f,0.f);
296         glColor3f(1,1,1);
297     }
298     else
299     {
300         /* child window */
301         glClearColor(.0f,.2f,0.f,0.f);
302         glColor3f(.5,.5,.5);
303         glutPostWindowRedisplay(nWindow);
304     }
305     glClear(GL_COLOR_BUFFER_BIT);
306     DrawQuad();
307 
308     if (win==nWindow)
309     {
310         glColor3f(1, 1, 0);
311         glGetIntegerv(GL_VIEWPORT, viewport);
312         glRasterPos2i(2, -glutBitmapHeight(GLUT_BITMAP_9_BY_15)+3+viewport[3]);
313         glutBitmapString(GLUT_BITMAP_9_BY_15, (unsigned char*)"press f/r/m/d/c/i/h/p");
314     }
315 
316     glutSwapBuffers();
317     glutPostWindowRedisplay(win);
318 }
319 
Timer(int unused)320 void Timer(int unused)
321 {
322     int win = glutGetWindow();
323     int x, y;
324     int width, height;
325     int border, caption;
326 
327     x       = glutGet(GLUT_WINDOW_X);
328     y       = glutGet(GLUT_WINDOW_Y);
329     width   = glutGet(GLUT_WINDOW_WIDTH);
330     height  = glutGet(GLUT_WINDOW_HEIGHT);
331     border  = glutGet(GLUT_WINDOW_BORDER_WIDTH);
332     caption = glutGet(GLUT_WINDOW_HEADER_HEIGHT);
333     /* returned position is top-left of client area, to get top-left of
334      * of window you'll need to add the size of the border and caption
335      * of the current window (can be 0).
336      * Note that the window position is not necessarily positive (e.g.
337      * when the window is on a monitor to the left of the primary monitor
338      * or simply when maximized--try pressing the maximize button).
339      * the returned size is the size of the client area
340      * Note that the top-left of a child window is relative to the
341      * top-left of the client area of the parent.
342      */
343     /* printf("window border: %dpx, caption: %dpx\n",border,caption); */
344     if (win==nWindow)
345         printf("main  window %dx%d, top-left of client at: (%d,%d), of window at: (%d,%d)\n",
346             width, height,
347             x ,y,
348             x-border,
349             y-caption);
350     else
351         printf("child window %dx%d, top-left of client at: (%d,%d), relative to parent\n",
352         width, height,
353         x ,y);
354 
355     /* (re)set the timer callback and ask glut to call it in 500 ms */
356     glutTimerFunc(500, Timer, 0);
357 }
358 
359 
main(int argc,char * argv[])360 int main(int argc, char* argv[])
361 {
362     int border, caption;
363     glutInit( &argc, argv );
364     glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE /*| GLUT_BORDERLESS*/); // do try as well with GLUT_BORDERLESS and GLUT_CAPTIONLESS
365     glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);
366 
367     /* Get border and caption size of default window style */
368     border  = glutGet(GLUT_WINDOW_BORDER_WIDTH);
369     caption = glutGet(GLUT_WINDOW_HEADER_HEIGHT);
370     printf("default window style border: %dpx, caption: %dpx\n",border,caption);
371 
372     /* NB: The window position you request is the outer top-left of the
373      * window, the client area is at a different position if the window has
374      * borders and/or a title bar.
375      */
376     glutInitWindowPosition(150,250);
377     glutInitWindowSize(200,200);
378 
379     nWindow = glutCreateWindow("test");
380     glutSetIconTitle("test icon title");
381     printf("main window id: %d\n", nWindow);
382 
383     glutKeyboardFunc( SampleKeyboard );
384     glutDisplayFunc( Redisplay );
385     glutReshapeFunc( Reshape );
386     glutPositionFunc( Position );
387     glutWindowStatusFunc( WindowStatus );
388 
389     glutTimerFunc(300, Timer, 0);
390 
391     glutMainLoop();
392     printf("glutMainLoop returned\n");
393 
394     return EXIT_SUCCESS;
395 }
396