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