1 // -*- mode: c++; c-set-style: "stroustrup"; tab-width: 4; -*-
2 //
3 // CApp.c
4 //
5 // Copyright (C) 2004 Koji Nakamaru
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software Foundation,
19 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 //
21 
22 #include "common.h"
23 #include "CApp.h"
24 
25 static CApp *_app;
26 
27 
28 // public functions
29 
main(int argc,char * argv[])30 int main(
31 	int argc,
32 	char *argv[])
33 {
34 	setProgname(argv[0]);
35 	if (! _app) {
36 		error("the application object has not been initialized yet.");
37 	}
38 #if defined (_WIN32) && !defined (__CYGWIN__)
39 	_fmode = _O_BINARY;
40 	_setmode(0, _O_BINARY);
41 	_setmode(1, _O_BINARY);
42 	_setmode(2, _O_BINARY);
43 #endif
44 	atexit(_app->finalizeCB);
45 	glutInit(&argc, argv);
46 	int menu_id = glutCreateMenu(_app->menuCB);
47 	glutSetMenu(menu_id);
48 	_app->initialize(argc, argv);
49 	glutDisplayFunc(_app->displayCB);
50 	glutReshapeFunc(_app->reshapeCB);
51 	glutKeyboardFunc(_app->keyCB);
52 	glutSpecialFunc(_app->specialCB);
53 	glutMouseFunc(_app->mouseCB);
54 	glutMotionFunc(_app->motionCB);
55 	glutPassiveMotionFunc(_app->passiveCB);
56 	glutSetMenu(menu_id);
57 	glutAddMenuEntry("Toggle Full Screen (Z)", 65534);
58 	glutAddMenuEntry("Quit (Esc)", 65535);
59 	glutAttachMenu(GLUT_RIGHT_BUTTON);
60 	glutMainLoop();
61 	return 0;
62 }
63 
64 
65 // protected functions
66 
CApp()67 CApp::CApp()
68 {
69 	_app = this;
70 	_is_dragging = false;
71 	_is_fullscreen = false;
72 	_view.w = 0;
73 	_view.h = 0;
74 	_view.w0 = 0;
75 	_view.h0 = 0;
76 	_timer.enable = false;
77 	_timer.millis = 0;
78 	_timer.tv0.tv_sec = 0;
79 	_timer.tv0.tv_usec = 0;
80 }
81 
~CApp()82 CApp::~CApp()
83 {
84 	_app = NULL;
85 }
86 
initialize(int argc,char * argv[])87 void CApp::initialize(
88 	int argc,
89 	char *argv[])
90 {
91 }
92 
finalize()93 void CApp::finalize()
94 {
95 }
96 
display()97 void CApp::display()
98 {
99 }
100 
reshape(int width,int height)101 void CApp::reshape(
102 	int width,
103 	int height)
104 {
105 }
106 
menu(int value)107 void CApp::menu(
108 	int value)
109 {
110 	switch (value) {
111 	case 65534:
112 		CApp::key('Z', 0, 0);
113 		break;
114 	case 65535:
115 		CApp::key(27, 0, 0);
116 		break;
117 	default:
118 		break;
119 	}
120 }
121 
key(unsigned char key,int x,int y)122 void CApp::key(
123 	unsigned char key,
124 	int x,
125 	int y)
126 {
127 	switch (key) {
128 	case 'z':
129 	case 'Z':
130 		if ((_is_fullscreen = ! _is_fullscreen)) {
131 // 			glutSetCursor(GLUT_CURSOR_NONE);
132 			_view.x0 = glutGet(GLUT_WINDOW_X);
133 			_view.y0 = glutGet(GLUT_WINDOW_Y);
134 			_view.w0 = glutGet(GLUT_WINDOW_WIDTH);
135 			_view.h0 = glutGet(GLUT_WINDOW_HEIGHT);
136 			glutFullScreen();
137 		} else {
138 // 			glutSetCursor(GLUT_CURSOR_RIGHT_ARROW);
139 			glutPositionWindow(_view.x0, _view.y0);
140 			glutReshapeWindow(_view.w0, _view.h0);
141 		}
142 		break;
143 	case 27:  // ESC
144 		exit(0);
145 		break;
146 	default:
147 		break;
148 	}
149 }
150 
special(int key,int x,int y)151 void CApp::special(
152 	int key,
153 	int x,
154 	int y)
155 {
156 	switch (key) {
157 	case GLUT_KEY_F4:
158 		exit(0);
159 		break;
160 	default:
161 		break;
162 	}
163 }
164 
mouse(int button,int state,int x,int y)165 void CApp::mouse(
166 	int button,
167 	int state,
168 	int x,
169 	int y)
170 {
171 }
172 
drag(int x,int y)173 void CApp::drag(
174 	int x,
175 	int y)
176 {
177 }
178 
passive(int x,int y)179 void CApp::passive(
180 	int x,
181 	int y)
182 {
183 }
184 
timer(unsigned dmillis)185 void CApp::timer(
186 	unsigned dmillis)
187 {
188 }
189 
startTimer(unsigned millis)190 void CApp::startTimer(
191 	unsigned millis)
192 {
193 	_timer.enable = true;
194 	_timer.millis = millis;
195 	gettimeofday(&_timer.tv0, NULL);
196 	glutTimerFunc(_timer.millis, timerCB, 0);
197 }
198 
stopTimer()199 void CApp::stopTimer()
200 {
201 	_timer.enable = false;
202 }
203 
204 
205 // private functions
206 
finalizeCB()207 void CApp::finalizeCB()
208 {
209 	if (! _app) {
210 		return;
211 	}
212 	_app->finalize();
213 }
214 
displayCB()215 void CApp::displayCB()
216 {
217 	if (! _app) {
218 		return;
219 	}
220 	_app->display();
221 }
222 
reshapeCB(int width,int height)223 void CApp::reshapeCB(
224 	int width,
225 	int height)
226 {
227 	if (! _app) {
228 		return;
229 	}
230 	if (width == 0 || height == 0) {
231 		return;
232 	}
233 	_app->reshape(width, height);
234 	_app->_view.w = width;
235 	_app->_view.h = height;
236 }
237 
menuCB(int value)238 void CApp::menuCB(
239 	int value)
240 {
241 	if (! _app) {
242 		return;
243 	}
244 	_app->menu(value);
245 }
246 
keyCB(unsigned char key,int x,int y)247 void CApp::keyCB(
248 	unsigned char key,
249 	int x,
250 	int y)
251 {
252 	if (! _app) {
253 		return;
254 	}
255 	_app->key(key, x, y);
256 }
257 
specialCB(int key,int x,int y)258 void CApp::specialCB(
259 	int key,
260 	int x,
261 	int y)
262 {
263 	if (! _app) {
264 		return;
265 	}
266 	_app->special(key, x, y);
267 }
268 
mouseCB(int button,int state,int x,int y)269 void CApp::mouseCB(
270 	int button,
271 	int state,
272 	int x,
273 	int y)
274 {
275 	if (! _app) {
276 		return;
277 	}
278 	if ((state == GLUT_DOWN && _app->_is_dragging)
279 		|| (state == GLUT_UP && ! _app->_is_dragging)
280 		|| (button != GLUT_LEFT_BUTTON && button != GLUT_RIGHT_BUTTON)) {
281 		return;
282 	}
283 	switch (state) {
284 	case GLUT_DOWN:
285 		if (! (0 <= x
286 			   && x < glutGet(GLUT_WINDOW_WIDTH)
287 			   && 0 <= y
288 			   && y < glutGet(GLUT_WINDOW_HEIGHT))) {
289 			return;
290 		}
291 		_app->_is_dragging = true;
292 		break;
293 	case GLUT_UP:
294 		_app->_is_dragging = false;
295 		break;
296 	default:
297 		break;
298 	}
299 	_app->mouse(button, state, x, y);
300 }
301 
motionCB(int x,int y)302 void CApp::motionCB(
303 	int x,
304 	int y)
305 {
306 	if (! _app) {
307 		return;
308 	}
309 	if (_app->_is_dragging) {
310 		_app->drag(x, y);
311 	}
312 }
313 
passiveCB(int x,int y)314 void CApp::passiveCB(
315 	int x,
316 	int y)
317 {
318 	if (! _app) {
319 		return;
320 	}
321 	if (! _app->_is_dragging) {
322 		_app->passive(x, y);
323 	}
324 }
325 
timerCB(int value)326 void CApp::timerCB(
327 	int value)
328 {
329 	if (! _app) {
330 		return;
331 	}
332 	struct timeval tv;
333 	gettimeofday(&tv, NULL);
334 	_app->timer(
335 		(tv.tv_sec - _app->_timer.tv0.tv_sec) * 1000
336 		+ (tv.tv_usec - _app->_timer.tv0.tv_usec) / 1000);
337 	_app->_timer.tv0 = tv;
338 	if (_app->_timer.enable) {
339 		glutTimerFunc(_app->_timer.millis, timerCB, 0);
340 	}
341 }
342 
343 
344 // local functions
345