1 #ifndef _MSC_VER // MSVC really needs a definition for wchar_t
2 #define _WCHAR_T_DEFINED 1 // Glut needs this, or else it tries to
10 #include <osgViewer/Viewer>
11 #include <osgViewer/ViewerEventHandlers>
13 #include <simgear/compiler.h>
15 #if defined( __APPLE__)
16 # include <GLUT/glut.h>
22 #include <Scenery/scenery.hxx>
24 #include "globals.hxx"
25 #include "renderer.hxx"
26 #include "fg_props.hxx"
27 #include "WindowSystemAdapter.hxx"
29 using namespace flightgear;
32 // Native glut callbacks.
33 // These translate the glut event model into osgGA events
36 static osg::ref_ptr<osgViewer::Viewer> viewer;
37 static osg::ref_ptr<osg::Camera> mainCamera;
38 static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
40 static int GlutModifiers = 0;
41 static unsigned int getOSGModifiers(int modifiers);
43 static void callKeyHandler(int k, int mods, int x, int y)
48 case 0x1b: key = osgGA::GUIEventAdapter::KEY_Escape; break;
49 case '\n': key = osgGA::GUIEventAdapter::KEY_Return; break;
50 case '\b': key = osgGA::GUIEventAdapter::KEY_BackSpace; break;
51 case 0x7f: key = osgGA::GUIEventAdapter::KEY_Delete; break;
52 case '\t': key = osgGA::GUIEventAdapter::KEY_Tab; break;
53 case PU_KEY_LEFT: key = osgGA::GUIEventAdapter::KEY_Left; break;
54 case PU_KEY_UP: key = osgGA::GUIEventAdapter::KEY_Up; break;
55 case PU_KEY_RIGHT: key = osgGA::GUIEventAdapter::KEY_Right; break;
56 case PU_KEY_DOWN: key = osgGA::GUIEventAdapter::KEY_Down; break;
57 case PU_KEY_PAGE_UP: key = osgGA::GUIEventAdapter::KEY_Page_Up; break;
58 case PU_KEY_PAGE_DOWN: key = osgGA::GUIEventAdapter::KEY_Page_Down; break;
59 case PU_KEY_HOME: key = osgGA::GUIEventAdapter::KEY_Home; break;
60 case PU_KEY_END: key = osgGA::GUIEventAdapter::KEY_End; break;
61 case PU_KEY_INSERT: key = osgGA::GUIEventAdapter::KEY_Insert; break;
62 case PU_KEY_F1: key = osgGA::GUIEventAdapter::KEY_F1; break;
63 case PU_KEY_F2: key = osgGA::GUIEventAdapter::KEY_F2; break;
64 case PU_KEY_F3: key = osgGA::GUIEventAdapter::KEY_F3; break;
65 case PU_KEY_F4: key = osgGA::GUIEventAdapter::KEY_F4; break;
66 case PU_KEY_F5: key = osgGA::GUIEventAdapter::KEY_F5; break;
67 case PU_KEY_F6: key = osgGA::GUIEventAdapter::KEY_F6; break;
68 case PU_KEY_F7: key = osgGA::GUIEventAdapter::KEY_F7; break;
69 case PU_KEY_F8: key = osgGA::GUIEventAdapter::KEY_F8; break;
70 case PU_KEY_F9: key = osgGA::GUIEventAdapter::KEY_F9; break;
71 case PU_KEY_F10: key = osgGA::GUIEventAdapter::KEY_F10; break;
72 case PU_KEY_F11: key = osgGA::GUIEventAdapter::KEY_F11; break;
73 case PU_KEY_F12: key = osgGA::GUIEventAdapter::KEY_F12; break;
74 default: key = k; break;
76 unsigned int osgModifiers = getOSGModifiers(mods);
77 osgGA::EventQueue& queue = *gw->getEventQueue();
78 queue.getCurrentEventState()->setModKeyMask(osgModifiers);
79 if (mods & KEYMOD_RELEASED)
80 queue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)key);
82 queue.keyPress((osgGA::GUIEventAdapter::KeySymbol)key);
85 static void GLUTmotion (int x, int y)
89 gw->getEventQueue()->mouseMotion(x, y);
92 static void GLUTmouse (int button, int updown, int x, int y)
94 GlutModifiers = glutGetModifiers();
97 gw->getEventQueue()->mouseButtonPress(x, y, button+1);
99 gw->getEventQueue()->mouseButtonRelease(x, y, button+1);
103 static void GLUTspecialkeyup(int k, int x, int y)
105 GlutModifiers = glutGetModifiers();
106 callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
109 static void GLUTspecialkey(int k, int x, int y)
111 GlutModifiers = glutGetModifiers();
112 callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
115 static unsigned char release_keys[256];
117 static void GLUTkeyup(unsigned char k, int x, int y)
119 GlutModifiers = glutGetModifiers();
120 callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
123 static void GLUTkey(unsigned char k, int x, int y)
125 GlutModifiers = glutGetModifiers();
127 if (k >= 1 && k <= 26) {
128 release_keys[k + '@'] = k;
129 release_keys[k + '`'] = k;
130 } else if (k >= 'A' && k <= 'Z') {
131 release_keys[k - '@'] = k;
132 release_keys[tolower(k)] = k;
133 } else if (k >= 'a' && k <= 'z') {
134 release_keys[k - '`'] = k;
135 release_keys[toupper(k)] = k;
137 callKeyHandler(k, fgGetKeyModifiers(), x, y);
140 static void GLUTdraw()
147 static void GLUTreshape(int w, int h)
149 // update the window dimensions, in case the window has been resized.
150 gw->resized(gw->getTraits()->x, gw->getTraits()->y, w, h);
151 gw->getEventQueue()->windowResize(gw->getTraits()->x, gw->getTraits()->y,
156 // fg_os API definition
159 void fgOSInit(int* argc, char** argv)
161 glutInit(argc, argv);
162 WindowSystemAdapter::setWSA(new WindowSystemAdapter);
165 void fgOSFullScreen()
175 void fgOSExit(int code)
180 static int CurrentCursor = MOUSE_CURSOR_POINTER;
182 int fgGetMouseCursor()
184 return CurrentCursor;
187 void fgSetMouseCursor(int cursor)
189 CurrentCursor = cursor;
190 if (cursor == MOUSE_CURSOR_NONE) cursor = GLUT_CURSOR_NONE;
191 else if(cursor == MOUSE_CURSOR_POINTER) cursor = GLUT_CURSOR_INHERIT;
192 else if(cursor == MOUSE_CURSOR_WAIT) cursor = GLUT_CURSOR_WAIT;
193 else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
194 else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
195 // Otherwise, pass it through unchanged...
196 glutSetCursor(cursor);
199 void fgWarpMouse(int x, int y)
201 globals->get_renderer()->getManipulator()->setMouseWarped();
202 glutWarpPointer(x, y);
205 int fgGetKeyModifiers()
208 if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
209 if(GlutModifiers & GLUT_ACTIVE_CTRL) result |= KEYMOD_CTRL;
210 if(GlutModifiers & GLUT_ACTIVE_ALT) result |= KEYMOD_ALT;
214 static unsigned int getOSGModifiers(int glutModifiers)
216 unsigned int result = 0;
217 if (glutModifiers & GLUT_ACTIVE_SHIFT)
218 result |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
219 if (glutModifiers & GLUT_ACTIVE_CTRL)
220 result |= osgGA::GUIEventAdapter::MODKEY_CTRL;
221 if(glutModifiers & GLUT_ACTIVE_ALT)
222 result |= osgGA::GUIEventAdapter::MODKEY_ALT;
226 void fgOSOpenWindow(bool stencil)
228 int w = fgGetInt("/sim/startup/xsize");
229 int h = fgGetInt("/sim/startup/ysize");
230 int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
231 bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
232 bool fullscreen = fgGetBool("/sim/startup/fullscreen");
233 WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
234 int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
236 if(alpha) mode |= GLUT_ALPHA;
237 if(stencil && bpp > 16) mode |= GLUT_STENCIL;
239 glutInitDisplayMode(mode);
240 glutInitWindowSize(w, h);
241 if(!fgGetBool("/sim/startup/game-mode")) {
242 glutCreateWindow("FlightGear");
244 char game_mode_str[20];
245 SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
247 int hz = p->getIntValue();
248 snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
250 snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
252 glutGameModeString( game_mode_str );
256 // Register these here. Calling them before the window is open
258 glutMotionFunc(GLUTmotion);
259 glutPassiveMotionFunc(GLUTmotion);
260 glutMouseFunc(GLUTmouse);
261 glutSpecialUpFunc(GLUTspecialkeyup);
262 glutSpecialFunc(GLUTspecialkey);
263 glutKeyboardUpFunc(GLUTkeyup);
264 glutKeyboardFunc(GLUTkey);
265 glutDisplayFunc(GLUTdraw);
266 glutReshapeFunc(GLUTreshape);
270 viewer = new osgViewer::Viewer;
271 gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
272 GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main"));
273 window->flags |= GraphicsWindow::GUI;
274 viewer->setDatabasePager(FGScenery::getPagerSingleton());
275 // now the main camera ...
276 osg::Camera* camera = new osg::Camera;
278 // If a viewport isn't set on the camera, then it's hard to dig it
279 // out of the SceneView objects in the viewer, and the coordinates
280 // of mouse events are somewhat bizzare.
281 camera->setViewport(new osg::Viewport(0, 0, realw, realh));
282 camera->setProjectionResizePolicy(osg::Camera::FIXED);
283 Camera3D* cam3D = wsa->registerCamera3D(window, camera, string("main"));
284 cam3D->flags |= Camera3D::MASTER;
285 // Add as a slave for compatibility with the non-embedded osgViewer.
286 viewer->addSlave(camera);
287 viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
288 // Let FG handle the escape key with a confirmation
289 viewer->setKeyEventSetsDone(0);
290 osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler;
291 statsHandler->setKeyEventTogglesOnScreenStats('*');
292 statsHandler->setKeyEventPrintsOutStats(0);
293 viewer->addEventHandler(statsHandler);
294 // The viewer won't start without some root.
295 viewer->setSceneData(new osg::Group);
296 globals->get_renderer()->setViewer(viewer.get());
299 bool fgOSIsMainCamera(const osg::Camera*)
304 bool fgOSIsMainContext(const osg::GraphicsContext*)
309 osg::GraphicsContext* fgOSGetMainContext()