X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Ffg_os.cxx;h=dfce9b2aaad59e61957e7b334271683764f90d6d;hb=49030e700ba276d5cd6ffa4f4e661a266fa0105c;hp=4a1eb9c0fbb9c1c578c7336b17ff7bfa6bf03ee2;hpb=ae2dbe4f25f07ee93bbadb91164d1373d8057252;p=flightgear.git diff --git a/src/Main/fg_os.cxx b/src/Main/fg_os.cxx index 4a1eb9c0f..dfce9b2aa 100644 --- a/src/Main/fg_os.cxx +++ b/src/Main/fg_os.cxx @@ -1,83 +1,104 @@ -// The mac puts this in a weird location (GLUT/glut.h), so the -// configure script detects the location and defines it as a macro. +#ifndef _MSC_VER // MSVC really needs a definition for wchar_t +#define _WCHAR_T_DEFINED 1 // Glut needs this, or else it tries to + // redefine it +#endif + #ifdef HAVE_CONFIG_H # include -# include FG_GLUT_H -#else -# include #endif -#include - -#include "fg_props.hxx" -#include "fg_os.hxx" +#include +#include +#include -// -// fg_os callback registration APIs -// (These are not glut-specific) -// - -static fgIdleHandler IdleHandler = 0; -static fgDrawHandler DrawHandler = 0; -static fgWindowResizeHandler WindowResizeHandler = 0; -static fgKeyHandler KeyHandler = 0; -static fgMouseClickHandler MouseClickHandler = 0; -static fgMouseMotionHandler MouseMotionHandler = 0; - -void fgRegisterIdleHandler(fgIdleHandler func) -{ - IdleHandler = func; -} +#include -void fgRegisterDrawHandler(fgDrawHandler func) -{ - DrawHandler = func; -} - -void fgRegisterWindowResizeHandler(fgWindowResizeHandler func) -{ - WindowResizeHandler = func; -} - -void fgRegisterKeyHandler(fgKeyHandler func) -{ - KeyHandler = func; -} +#if defined( __APPLE__) +# include +#else +# include +#endif +#include -void fgRegisterMouseClickHandler(fgMouseClickHandler func) -{ - MouseClickHandler = func; -} +#include +#include "fg_os.hxx" +#include "globals.hxx" +#include "renderer.hxx" +#include "fg_props.hxx" +#include "WindowSystemAdapter.hxx" +#include "CameraGroup.hxx" -void fgRegisterMouseMotionHandler(fgMouseMotionHandler func) -{ - MouseMotionHandler = func; -} +using namespace flightgear; // // Native glut callbacks. -// These translate the glut event model into fg*Handler callbacks +// These translate the glut event model into osgGA events // +static osg::ref_ptr viewer; +static osg::ref_ptr gw; + static int GlutModifiers = 0; +static unsigned int getOSGModifiers(int modifiers); static void callKeyHandler(int k, int mods, int x, int y) { - int puiup = mods & KEYMOD_RELEASED ? PU_UP : PU_DOWN; - if(puKeyboard(k, puiup)) - return; - if(KeyHandler) (*KeyHandler)(k, mods, x, y); + + int key = 0; + switch (k) { + case 0x1b: key = osgGA::GUIEventAdapter::KEY_Escape; break; + case '\n': key = osgGA::GUIEventAdapter::KEY_Return; break; + case '\b': key = osgGA::GUIEventAdapter::KEY_BackSpace; break; + case 0x7f: key = osgGA::GUIEventAdapter::KEY_Delete; break; + case '\t': key = osgGA::GUIEventAdapter::KEY_Tab; break; + case PU_KEY_LEFT: key = osgGA::GUIEventAdapter::KEY_Left; break; + case PU_KEY_UP: key = osgGA::GUIEventAdapter::KEY_Up; break; + case PU_KEY_RIGHT: key = osgGA::GUIEventAdapter::KEY_Right; break; + case PU_KEY_DOWN: key = osgGA::GUIEventAdapter::KEY_Down; break; + case PU_KEY_PAGE_UP: key = osgGA::GUIEventAdapter::KEY_Page_Up; break; + case PU_KEY_PAGE_DOWN: key = osgGA::GUIEventAdapter::KEY_Page_Down; break; + case PU_KEY_HOME: key = osgGA::GUIEventAdapter::KEY_Home; break; + case PU_KEY_END: key = osgGA::GUIEventAdapter::KEY_End; break; + case PU_KEY_INSERT: key = osgGA::GUIEventAdapter::KEY_Insert; break; + case PU_KEY_F1: key = osgGA::GUIEventAdapter::KEY_F1; break; + case PU_KEY_F2: key = osgGA::GUIEventAdapter::KEY_F2; break; + case PU_KEY_F3: key = osgGA::GUIEventAdapter::KEY_F3; break; + case PU_KEY_F4: key = osgGA::GUIEventAdapter::KEY_F4; break; + case PU_KEY_F5: key = osgGA::GUIEventAdapter::KEY_F5; break; + case PU_KEY_F6: key = osgGA::GUIEventAdapter::KEY_F6; break; + case PU_KEY_F7: key = osgGA::GUIEventAdapter::KEY_F7; break; + case PU_KEY_F8: key = osgGA::GUIEventAdapter::KEY_F8; break; + case PU_KEY_F9: key = osgGA::GUIEventAdapter::KEY_F9; break; + case PU_KEY_F10: key = osgGA::GUIEventAdapter::KEY_F10; break; + case PU_KEY_F11: key = osgGA::GUIEventAdapter::KEY_F11; break; + case PU_KEY_F12: key = osgGA::GUIEventAdapter::KEY_F12; break; + default: key = k; break; + } + unsigned int osgModifiers = getOSGModifiers(mods); + osgGA::EventQueue& queue = *gw->getEventQueue(); + queue.getCurrentEventState()->setModKeyMask(osgModifiers); + if (mods & KEYMOD_RELEASED) + queue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)key); + else + queue.keyPress((osgGA::GUIEventAdapter::KeySymbol)key); } static void GLUTmotion (int x, int y) { - if(MouseMotionHandler) (*MouseMotionHandler)(x, y); + if (!gw.valid()) + return; + gw->getEventQueue()->mouseMotion(x, y); } static void GLUTmouse (int button, int updown, int x, int y) { GlutModifiers = glutGetModifiers(); - if(MouseClickHandler) (*MouseClickHandler)(button, updown, x, y); + if (gw.valid()) { + if (updown == 0) + gw->getEventQueue()->mouseButtonPress(x, y, button+1); + else + gw->getEventQueue()->mouseButtonRelease(x, y, button+1); + } } static void GLUTspecialkeyup(int k, int x, int y) @@ -92,32 +113,44 @@ static void GLUTspecialkey(int k, int x, int y) callKeyHandler(256 + k, fgGetKeyModifiers(), x, y); } +static unsigned char release_keys[256]; + static void GLUTkeyup(unsigned char k, int x, int y) { GlutModifiers = glutGetModifiers(); - callKeyHandler(k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y); + callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y); } static void GLUTkey(unsigned char k, int x, int y) { GlutModifiers = glutGetModifiers(); + release_keys[k] = k; + if (k >= 1 && k <= 26) { + release_keys[k + '@'] = k; + release_keys[k + '`'] = k; + } else if (k >= 'A' && k <= 'Z') { + release_keys[k - '@'] = k; + release_keys[tolower(k)] = k; + } else if (k >= 'a' && k <= 'z') { + release_keys[k - '`'] = k; + release_keys[toupper(k)] = k; + } callKeyHandler(k, fgGetKeyModifiers(), x, y); } -static void GLUTidle() -{ - if(IdleHandler) (*IdleHandler)(); -} - static void GLUTdraw() { - if(DrawHandler) (*DrawHandler)(); + viewer->frame(); glutSwapBuffers(); + glutPostRedisplay(); } static void GLUTreshape(int w, int h) { - if(WindowResizeHandler) (*WindowResizeHandler)(w, h); + // update the window dimensions, in case the window has been resized. + gw->resized(gw->getTraits()->x, gw->getTraits()->y, w, h); + gw->getEventQueue()->windowResize(gw->getTraits()->x, gw->getTraits()->y, + w, h); } // @@ -127,6 +160,7 @@ static void GLUTreshape(int w, int h) void fgOSInit(int* argc, char** argv) { glutInit(argc, argv); + WindowSystemAdapter::setWSA(new WindowSystemAdapter); } void fgOSFullScreen() @@ -139,6 +173,11 @@ void fgOSMainLoop() glutMainLoop(); } +void fgOSExit(int code) +{ + exit(code); +} + static int CurrentCursor = MOUSE_CURSOR_POINTER; int fgGetMouseCursor() @@ -160,6 +199,7 @@ void fgSetMouseCursor(int cursor) void fgWarpMouse(int x, int y) { + globals->get_renderer()->getManipulator()->setMouseWarped(); glutWarpPointer(x, y); } @@ -172,23 +212,44 @@ int fgGetKeyModifiers() return result; } -void fgRequestRedraw() +static unsigned int getOSGModifiers(int glutModifiers) { - glutPostRedisplay(); + unsigned int result = 0; + if (glutModifiers & GLUT_ACTIVE_SHIFT) + result |= osgGA::GUIEventAdapter::MODKEY_SHIFT; + if (glutModifiers & GLUT_ACTIVE_CTRL) + result |= osgGA::GUIEventAdapter::MODKEY_CTRL; + if(glutModifiers & GLUT_ACTIVE_ALT) + result |= osgGA::GUIEventAdapter::MODKEY_ALT; + return result; } -void fgOSOpenWindow(int w, int h, int bpp, bool alpha) +void fgOSOpenWindow(bool stencil) { + int w = fgGetInt("/sim/startup/xsize"); + int h = fgGetInt("/sim/startup/ysize"); + int bpp = fgGetInt("/sim/rendering/bits-per-pixel"); + bool alpha = fgGetBool("/sim/rendering/clouds3d-enable"); + bool fullscreen = fgGetBool("/sim/startup/fullscreen"); + WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA(); int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE; + if(alpha) mode |= GLUT_ALPHA; + if(stencil && bpp > 16) mode |= GLUT_STENCIL; glutInitDisplayMode(mode); glutInitWindowSize(w, h); if(!fgGetBool("/sim/startup/game-mode")) { glutCreateWindow("FlightGear"); } else { - char game_mode_str[256]; - sprintf(game_mode_str, "width=%d height=%d bpp=%d", w, h, bpp); + char game_mode_str[20]; + SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false); + if (p) { + int hz = p->getIntValue(); + snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz); + } else { + snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp); + } glutGameModeString( game_mode_str ); glutEnterGameMode(); } @@ -202,8 +263,37 @@ void fgOSOpenWindow(int w, int h, int bpp, bool alpha) glutSpecialFunc(GLUTspecialkey); glutKeyboardUpFunc(GLUTkeyup); glutKeyboardFunc(GLUTkey); - glutIdleFunc(GLUTidle); glutDisplayFunc(GLUTdraw); glutReshapeFunc(GLUTreshape); - + // XXX + int realw = w; + int realh = h; + viewer = new osgViewer::Viewer; + gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh); + GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main")); + window->flags |= GraphicsWindow::GUI; + viewer->setDatabasePager(FGScenery::getPagerSingleton()); + // now the main camera ... + osg::Camera* camera = new osg::Camera; + // If a viewport isn't set on the camera, then it's hard to dig it + // out of the SceneView objects in the viewer, and the coordinates + // of mouse events are somewhat bizzare. + camera->setViewport(new osg::Viewport(0, 0, realw, realh)); + camera->setProjectionResizePolicy(osg::Camera::FIXED); + CameraGroup* cgroup = new CameraGroup(viewer.get()); + cgroup->addCamera(CameraGroup::DO_INTERSECTION_TEST, camera, + osg::Matrixd::identity(), osg::Matrixd::identity(), + true); + cgroup->buildGUICamera(0, window); + CameraGroup::setDefault(cgroup); + viewer->setCameraManipulator(globals->get_renderer()->getManipulator()); + // Let FG handle the escape key with a confirmation + viewer->setKeyEventSetsDone(0); + osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler; + statsHandler->setKeyEventTogglesOnScreenStats('*'); + statsHandler->setKeyEventPrintsOutStats(0); + viewer->addEventHandler(statsHandler); + // The viewer won't start without some root. + viewer->setSceneData(new osg::Group); + globals->get_renderer()->setViewer(viewer.get()); }