// -*- mode: c++; c-set-style: "stroustrup"; tab-width: 4; -*- // // CApp.c // // Copyright (C) 2004 Koji Nakamaru // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "common.h" #include "CApp.h" static CApp *_app; // public functions int main( int argc, char *argv[]) { setProgname(argv[0]); if (! _app) { error("the application object has not been initialized yet."); } #if defined (_WIN32) && !defined (__CYGWIN__) _fmode = _O_BINARY; _setmode(0, _O_BINARY); _setmode(1, _O_BINARY); _setmode(2, _O_BINARY); #endif atexit(_app->finalizeCB); glutInit(&argc, argv); int menu_id = glutCreateMenu(_app->menuCB); glutSetMenu(menu_id); _app->initialize(argc, argv); glutDisplayFunc(_app->displayCB); glutReshapeFunc(_app->reshapeCB); glutKeyboardFunc(_app->keyCB); glutSpecialFunc(_app->specialCB); glutMouseFunc(_app->mouseCB); glutMotionFunc(_app->motionCB); glutPassiveMotionFunc(_app->passiveCB); glutSetMenu(menu_id); glutAddMenuEntry("Toggle Full Screen (Z)", 65534); glutAddMenuEntry("Quit (Esc)", 65535); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); return 0; } // protected functions CApp::CApp() { _app = this; _is_dragging = false; _is_fullscreen = false; _view.w = 0; _view.h = 0; _view.w0 = 0; _view.h0 = 0; _timer.enable = false; _timer.millis = 0; _timer.tv0.tv_sec = 0; _timer.tv0.tv_usec = 0; } CApp::~CApp() { _app = NULL; } void CApp::initialize( int argc, char *argv[]) { } void CApp::finalize() { } void CApp::display() { } void CApp::reshape( int width, int height) { } void CApp::menu( int value) { switch (value) { case 65534: CApp::key('Z', 0, 0); break; case 65535: CApp::key(27, 0, 0); break; default: break; } } void CApp::key( unsigned char key, int x, int y) { switch (key) { case 'z': case 'Z': if ((_is_fullscreen = ! _is_fullscreen)) { // glutSetCursor(GLUT_CURSOR_NONE); _view.x0 = glutGet(GLUT_WINDOW_X); _view.y0 = glutGet(GLUT_WINDOW_Y); _view.w0 = glutGet(GLUT_WINDOW_WIDTH); _view.h0 = glutGet(GLUT_WINDOW_HEIGHT); glutFullScreen(); } else { // glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); glutPositionWindow(_view.x0, _view.y0); glutReshapeWindow(_view.w0, _view.h0); } break; case 27: // ESC exit(0); break; default: break; } } void CApp::special( int key, int x, int y) { switch (key) { case GLUT_KEY_F4: exit(0); break; default: break; } } void CApp::mouse( int button, int state, int x, int y) { } void CApp::drag( int x, int y) { } void CApp::passive( int x, int y) { } void CApp::timer( unsigned dmillis) { } void CApp::startTimer( unsigned millis) { _timer.enable = true; _timer.millis = millis; gettimeofday(&_timer.tv0, NULL); glutTimerFunc(_timer.millis, timerCB, 0); } void CApp::stopTimer() { _timer.enable = false; } // private functions void CApp::finalizeCB() { if (! _app) { return; } _app->finalize(); } void CApp::displayCB() { if (! _app) { return; } _app->display(); } void CApp::reshapeCB( int width, int height) { if (! _app) { return; } if (width == 0 || height == 0) { return; } _app->reshape(width, height); _app->_view.w = width; _app->_view.h = height; } void CApp::menuCB( int value) { if (! _app) { return; } _app->menu(value); } void CApp::keyCB( unsigned char key, int x, int y) { if (! _app) { return; } _app->key(key, x, y); } void CApp::specialCB( int key, int x, int y) { if (! _app) { return; } _app->special(key, x, y); } void CApp::mouseCB( int button, int state, int x, int y) { if (! _app) { return; } if ((state == GLUT_DOWN && _app->_is_dragging) || (state == GLUT_UP && ! _app->_is_dragging) || (button != GLUT_LEFT_BUTTON && button != GLUT_RIGHT_BUTTON)) { return; } switch (state) { case GLUT_DOWN: if (! (0 <= x && x < glutGet(GLUT_WINDOW_WIDTH) && 0 <= y && y < glutGet(GLUT_WINDOW_HEIGHT))) { return; } _app->_is_dragging = true; break; case GLUT_UP: _app->_is_dragging = false; break; default: break; } _app->mouse(button, state, x, y); } void CApp::motionCB( int x, int y) { if (! _app) { return; } if (_app->_is_dragging) { _app->drag(x, y); } } void CApp::passiveCB( int x, int y) { if (! _app) { return; } if (! _app->_is_dragging) { _app->passive(x, y); } } void CApp::timerCB( int value) { if (! _app) { return; } struct timeval tv; gettimeofday(&tv, NULL); _app->timer( (tv.tv_sec - _app->_timer.tv0.tv_sec) * 1000 + (tv.tv_usec - _app->_timer.tv0.tv_usec) / 1000); _app->_timer.tv0 = tv; if (_app->_timer.enable) { glutTimerFunc(_app->_timer.millis, timerCB, 0); } } // local functions