]> git.mxchange.org Git - flightgear.git/blob - src/Main/fg_os.cxx
- Added ultra-light traffic is now a separate traffic class that can have its
[flightgear.git] / src / Main / fg_os.cxx
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
3                            // redefine it
4 #endif
5
6 #ifdef HAVE_CONFIG_H
7 #  include <config.h>
8 #endif
9
10 #include <simgear/compiler.h>
11
12 #include SG_GLUT_H
13
14 #include <plib/pu.h>
15
16 #include "fg_props.hxx"
17 #include "fg_os.hxx"
18
19 //
20 // fg_os callback registration APIs
21 // (These are not glut-specific)
22 //
23
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;
30
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
33 // second warp.
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;
37
38 void fgRegisterIdleHandler(fgIdleHandler func)
39 {
40     IdleHandler = func;
41 }
42
43 void fgRegisterDrawHandler(fgDrawHandler func)
44 {
45     DrawHandler = func;
46 }
47
48 void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
49 {
50     WindowResizeHandler = func;
51 }
52
53 void fgRegisterKeyHandler(fgKeyHandler func)
54 {
55     KeyHandler = func;
56 }
57
58 void fgRegisterMouseClickHandler(fgMouseClickHandler func)
59 {
60     MouseClickHandler = func;
61 }
62
63 void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
64 {
65     MouseMotionHandler = func;
66 }
67
68 //
69 // Native glut callbacks.
70 // These translate the glut event model into fg*Handler callbacks
71 //
72
73 static int GlutModifiers = 0;
74
75 static void callKeyHandler(int k, int mods, int x, int y)
76 {
77     int puiup = mods & KEYMOD_RELEASED ? PU_UP : PU_DOWN;
78     if(puKeyboard(k, puiup))
79         return;
80     if(KeyHandler) (*KeyHandler)(k, mods, x, y);
81 }
82
83 static void GLUTmotion (int x, int y)
84 {
85     if (mouseWarped)
86         return;
87     if(MouseMotionHandler) (*MouseMotionHandler)(x, y);
88 }
89
90 static void GLUTmouse (int button, int updown, int x, int y)
91 {
92     GlutModifiers = glutGetModifiers();
93     if(MouseClickHandler) (*MouseClickHandler)(button, updown, x, y, true, 0);
94 }
95
96 static void GLUTspecialkeyup(int k, int x, int y)
97 {
98     GlutModifiers = glutGetModifiers();
99     callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
100 }
101
102 static void GLUTspecialkey(int k, int x, int y)
103 {
104     GlutModifiers = glutGetModifiers();
105     callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
106 }
107
108 static void GLUTkeyup(unsigned char k, int x, int y)
109 {
110     GlutModifiers = glutGetModifiers();
111     callKeyHandler(k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
112 }
113
114 static void GLUTkey(unsigned char k, int x, int y)
115 {
116     GlutModifiers = glutGetModifiers();
117     callKeyHandler(k, fgGetKeyModifiers(), x, y);
118 }
119
120 static void GLUTidle()
121 {
122     if(IdleHandler) (*IdleHandler)();
123     mouseWarped = false;
124 }
125
126 static void GLUTdraw()
127 {
128     if(DrawHandler) (*DrawHandler)();
129     glutSwapBuffers();
130     mouseWarped = false;
131 }
132
133 static void GLUTreshape(int w, int h)
134 {
135     if(WindowResizeHandler) (*WindowResizeHandler)(w, h);
136 }
137
138 //
139 // fg_os API definition
140 //
141
142 void fgOSInit(int* argc, char** argv)
143 {
144     glutInit(argc, argv);
145 }
146
147 void fgOSFullScreen()
148 {
149     glutFullScreen();
150 }
151
152 void fgOSMainLoop()
153 {
154     glutMainLoop();
155 }
156
157 void fgOSExit(int code)
158 {
159     exit(code);
160 }
161
162 static int CurrentCursor = MOUSE_CURSOR_POINTER;
163
164 int fgGetMouseCursor()
165 {
166     return CurrentCursor;
167 }
168
169 void fgSetMouseCursor(int cursor)
170 {
171     CurrentCursor = cursor;
172     if     (cursor == MOUSE_CURSOR_NONE)      cursor = GLUT_CURSOR_NONE;
173     else if(cursor == MOUSE_CURSOR_POINTER)   cursor = GLUT_CURSOR_INHERIT;
174     else if(cursor == MOUSE_CURSOR_WAIT)      cursor = GLUT_CURSOR_WAIT;
175     else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
176     else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
177     // Otherwise, pass it through unchanged...
178     glutSetCursor(cursor);
179 }
180
181 void fgWarpMouse(int x, int y)
182 {
183     mouseWarped = true;
184     glutWarpPointer(x, y);
185 }
186
187 int fgGetKeyModifiers()
188 {
189     int result = 0;
190     if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
191     if(GlutModifiers & GLUT_ACTIVE_CTRL)  result |= KEYMOD_CTRL;
192     if(GlutModifiers & GLUT_ACTIVE_ALT)   result |= KEYMOD_ALT;
193     return result;
194 }
195
196 void fgRequestRedraw()
197 {
198     glutPostRedisplay();
199 }
200
201 void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
202                     bool stencil, bool fullscreen)
203 {
204     int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
205     if(alpha) mode |= GLUT_ALPHA;
206     if(stencil && bpp > 16) mode |= GLUT_STENCIL;
207
208     glutInitDisplayMode(mode);
209     glutInitWindowSize(w, h);
210     if(!fgGetBool("/sim/startup/game-mode")) {
211         glutCreateWindow("FlightGear");
212     } else {
213         char game_mode_str[20];
214         SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
215         if (p) {
216             int hz = p->getIntValue();
217             snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
218         } else {
219             snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
220         }
221         glutGameModeString( game_mode_str );
222         glutEnterGameMode();
223     }
224
225     // Register these here.  Calling them before the window is open
226     // crashes.
227     glutMotionFunc(GLUTmotion);
228     glutPassiveMotionFunc(GLUTmotion);
229     glutMouseFunc(GLUTmouse);
230     glutSpecialUpFunc(GLUTspecialkeyup);
231     glutSpecialFunc(GLUTspecialkey);
232     glutKeyboardUpFunc(GLUTkeyup);
233     glutKeyboardFunc(GLUTkey);
234     glutIdleFunc(GLUTidle);
235     glutDisplayFunc(GLUTdraw);
236     glutReshapeFunc(GLUTreshape);
237 }
238
239 // Noop; the graphics context is always current
240 void fgMakeCurrent()
241 {
242 }
243
244 bool fgOSIsMainCamera(const osg::Camera*)
245 {
246   return true;
247 }
248
249 bool fgOSIsMainContext(const osg::GraphicsContext*)
250 {
251   return true;
252 }