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