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 <simgear/compiler.h>
16 #include "fg_props.hxx"
20 // fg_os callback registration APIs
21 // (These are not glut-specific)
24 static fgIdleHandler IdleHandler = 0;
25 static fgDrawHandler DrawHandler = 0;
26 static fgWindowResizeHandler WindowResizeHandler = 0;
27 static fgKeyHandler KeyHandler = 0;
28 static fgMouseClickHandler MouseClickHandler = 0;
29 static fgMouseMotionHandler MouseMotionHandler = 0;
31 // We need to flush all pending mouse move events past a mouse warp to avoid
32 // a race condition ending in warping twice and having huge increments for the
34 // I am not aware of such a flush function in glut. So we emulate that by
35 // ignoring mouse move events between a warp mouse and the next frame.
36 static bool mouseWarped = false;
38 void fgRegisterIdleHandler(fgIdleHandler func)
43 void fgRegisterDrawHandler(fgDrawHandler func)
48 void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
50 WindowResizeHandler = func;
53 void fgRegisterKeyHandler(fgKeyHandler func)
58 void fgRegisterMouseClickHandler(fgMouseClickHandler func)
60 MouseClickHandler = func;
63 void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
65 MouseMotionHandler = func;
69 // Native glut callbacks.
70 // These translate the glut event model into fg*Handler callbacks
73 static int GlutModifiers = 0;
75 static void callKeyHandler(int k, int mods, int x, int y)
77 int puiup = mods & KEYMOD_RELEASED ? PU_UP : PU_DOWN;
78 if(puKeyboard(k, puiup))
80 if(KeyHandler) (*KeyHandler)(k, mods, x, y);
83 static void GLUTmotion (int x, int y)
87 if(MouseMotionHandler) (*MouseMotionHandler)(x, y);
90 static void GLUTmouse (int button, int updown, int x, int y)
92 GlutModifiers = glutGetModifiers();
93 if(MouseClickHandler) (*MouseClickHandler)(button, updown, x, y, true, 0);
96 static void GLUTspecialkeyup(int k, int x, int y)
98 GlutModifiers = glutGetModifiers();
99 callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
102 static void GLUTspecialkey(int k, int x, int y)
104 GlutModifiers = glutGetModifiers();
105 callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
108 static unsigned char release_keys[256];
110 static void GLUTkeyup(unsigned char k, int x, int y)
112 GlutModifiers = glutGetModifiers();
113 callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
116 static void GLUTkey(unsigned char k, int x, int y)
118 GlutModifiers = glutGetModifiers();
120 if (k >= 1 && k <= 26) {
121 release_keys[k + '@'] = k;
122 release_keys[k + '`'] = k;
123 } else if (k >= 'A' && k <= 'Z') {
124 release_keys[k - '@'] = k;
125 release_keys[tolower(k)] = k;
126 } else if (k >= 'a' && k <= 'z') {
127 release_keys[k - '`'] = k;
128 release_keys[toupper(k)] = k;
130 callKeyHandler(k, fgGetKeyModifiers(), x, y);
133 static void GLUTidle()
135 if(IdleHandler) (*IdleHandler)();
139 static void GLUTdraw()
141 if(DrawHandler) (*DrawHandler)();
146 static void GLUTreshape(int w, int h)
148 if(WindowResizeHandler) (*WindowResizeHandler)(w, h);
152 // fg_os API definition
155 void fgOSInit(int* argc, char** argv)
157 glutInit(argc, argv);
160 void fgOSFullScreen()
170 void fgOSExit(int code)
175 static int CurrentCursor = MOUSE_CURSOR_POINTER;
177 int fgGetMouseCursor()
179 return CurrentCursor;
182 void fgSetMouseCursor(int cursor)
184 CurrentCursor = cursor;
185 if (cursor == MOUSE_CURSOR_NONE) cursor = GLUT_CURSOR_NONE;
186 else if(cursor == MOUSE_CURSOR_POINTER) cursor = GLUT_CURSOR_INHERIT;
187 else if(cursor == MOUSE_CURSOR_WAIT) cursor = GLUT_CURSOR_WAIT;
188 else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
189 else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
190 // Otherwise, pass it through unchanged...
191 glutSetCursor(cursor);
194 void fgWarpMouse(int x, int y)
197 glutWarpPointer(x, y);
200 int fgGetKeyModifiers()
203 if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
204 if(GlutModifiers & GLUT_ACTIVE_CTRL) result |= KEYMOD_CTRL;
205 if(GlutModifiers & GLUT_ACTIVE_ALT) result |= KEYMOD_ALT;
209 void fgRequestRedraw()
214 void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
215 bool stencil, bool fullscreen)
217 int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
218 if(alpha) mode |= GLUT_ALPHA;
219 if(stencil && bpp > 16) mode |= GLUT_STENCIL;
221 glutInitDisplayMode(mode);
222 glutInitWindowSize(w, h);
223 if(!fgGetBool("/sim/startup/game-mode")) {
224 glutCreateWindow("FlightGear");
226 char game_mode_str[20];
227 SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
229 int hz = p->getIntValue();
230 snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
232 snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
234 glutGameModeString( game_mode_str );
238 // Register these here. Calling them before the window is open
240 glutMotionFunc(GLUTmotion);
241 glutPassiveMotionFunc(GLUTmotion);
242 glutMouseFunc(GLUTmouse);
243 glutSpecialUpFunc(GLUTspecialkeyup);
244 glutSpecialFunc(GLUTspecialkey);
245 glutKeyboardUpFunc(GLUTkeyup);
246 glutKeyboardFunc(GLUTkey);
247 glutIdleFunc(GLUTidle);
248 glutDisplayFunc(GLUTdraw);
249 glutReshapeFunc(GLUTreshape);
252 // Noop; the graphics context is always current
257 bool fgOSIsMainCamera(const osg::Camera*)
262 bool fgOSIsMainContext(const osg::GraphicsContext*)