]> git.mxchange.org Git - flightgear.git/blob - src/Main/WindowBuilder.cxx
Expose FGPositioned data via property tree, and make comm-stations a real FGPositione...
[flightgear.git] / src / Main / WindowBuilder.cxx
1 // Copyright (C) 2008  Tim Moore
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License as
5 // published by the Free Software Foundation; either version 2 of the
6 // License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16
17 #include "WindowBuilder.hxx"
18
19 #include "WindowSystemAdapter.hxx"
20 #include "fg_props.hxx"
21
22 #include <sstream>
23
24 using namespace std;
25 using namespace osg;
26
27 namespace flightgear
28 {
29 string makeName(const string& prefix, int num)
30 {
31     stringstream stream;
32     stream << prefix << num;
33     return stream.str();
34 }
35
36 ref_ptr<WindowBuilder> WindowBuilder::windowBuilder;
37
38 const string WindowBuilder::defaultWindowName("FlightGear");
39
40 void WindowBuilder::initWindowBuilder(bool stencil)
41 {
42     windowBuilder = new WindowBuilder(stencil);
43 }
44
45 WindowBuilder::WindowBuilder(bool stencil) : defaultCounter(0)
46 {
47     defaultTraits = makeDefaultTraits(stencil);
48 }
49
50 GraphicsContext::Traits*
51 WindowBuilder::makeDefaultTraits(bool stencil)
52 {
53     GraphicsContext::WindowingSystemInterface* wsi
54         = osg::GraphicsContext::getWindowingSystemInterface();
55     int w = fgGetInt("/sim/startup/xsize");
56     int h = fgGetInt("/sim/startup/ysize");
57     int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
58     bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
59     bool fullscreen = fgGetBool("/sim/startup/fullscreen");
60
61     GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
62     traits->readDISPLAY();
63     if (traits->displayNum < 0)
64         traits->displayNum = 0;
65     if (traits->screenNum < 0)
66         traits->screenNum = 0;
67     int cbits = (bpp <= 16) ?  5 :  8;
68     int zbits = (bpp <= 16) ? 16 : 24;
69     traits->red = traits->green = traits->blue = cbits;
70     traits->depth = zbits;
71     if (alpha)
72         traits->alpha = 8;
73     if (stencil)
74         traits->stencil = 8;
75     traits->doubleBuffer = true;
76     traits->mipMapGeneration = true;
77     traits->windowName = "FlightGear";
78     // XXX should check per window too.
79     traits->sampleBuffers = fgGetBool("/sim/rendering/multi-sample-buffers", traits->sampleBuffers);
80     traits->samples = fgGetInt("/sim/rendering/multi-samples", traits->samples);
81     traits->vsync = fgGetBool("/sim/rendering/vsync-enable", traits->vsync);
82     if (fullscreen) {
83         unsigned width = 0;
84         unsigned height = 0;
85         wsi->getScreenResolution(*traits, width, height);
86         traits->windowDecoration = false;
87         traits->width = width;
88         traits->height = height;
89         traits->supportsResize = false;
90     } else {
91         traits->windowDecoration = true;
92         traits->width = w;
93         traits->height = h;
94         unsigned screenwidth = 0;
95         unsigned screenheight = 0;
96         wsi->getScreenResolution(*traits, screenwidth, screenheight);
97         // Ugly Hack, why does CW_USEDEFAULT works like phase of the moon?
98         // Mac also needs this to show window frame, menubar and Docks
99         traits->x = (w>screenwidth) ? 0 : (screenwidth-w)/3;
100         traits->y = (h>screenheight) ? 0 : (screenheight-h)/3;
101         traits->supportsResize = true;
102     }
103     return traits;
104 }
105 }
106
107 namespace
108 {
109 // Helper functions that set a value based on a property if it exists,
110 // returning 1 if the value was set.
111
112 inline int setFromProperty(string& place, const SGPropertyNode* node,
113                             const char* name)
114 {
115     const SGPropertyNode* valNode = node->getNode(name);
116     if (valNode) {
117         place = valNode->getStringValue();
118         return 1;
119     }
120     return 0;
121 }
122
123 inline int setFromProperty(int& place, const SGPropertyNode* node,
124                             const char* name)
125 {
126     const SGPropertyNode* valNode = node->getNode(name);
127     if (valNode) {
128         place = valNode->getIntValue();
129         return 1;
130     }
131     return 0;
132 }
133
134 inline int setFromProperty(bool& place, const SGPropertyNode* node,
135                             const char* name)
136 {
137     const SGPropertyNode* valNode = node->getNode(name);
138     if (valNode) {
139         place = valNode->getBoolValue();
140         return 1;
141     }
142     return 0;
143 }
144 }
145
146 namespace flightgear
147 {
148 GraphicsWindow* WindowBuilder::buildWindow(const SGPropertyNode* winNode)
149 {
150     GraphicsContext::WindowingSystemInterface* wsi
151         = osg::GraphicsContext::getWindowingSystemInterface();
152     WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
153     string windowName;
154     if (winNode->hasChild("window-name"))
155         windowName = winNode->getStringValue("window-name");
156     else if (winNode->hasChild("name"))
157         windowName = winNode->getStringValue("name");
158     GraphicsWindow* result = 0;
159     if (!windowName.empty()) {
160         result = wsa->findWindow(windowName);
161         if (result)
162             return result;
163     }
164     GraphicsContext::Traits* traits
165         = new GraphicsContext::Traits(*defaultTraits);
166     int traitsSet = setFromProperty(traits->hostName, winNode, "host-name");
167     traitsSet |= setFromProperty(traits->displayNum, winNode, "display");
168     traitsSet |= setFromProperty(traits->screenNum, winNode, "screen");
169     const SGPropertyNode* fullscreenNode = winNode->getNode("fullscreen");
170     if (fullscreenNode && fullscreenNode->getBoolValue()) {
171         unsigned width = 0;
172         unsigned height = 0;
173         wsi->getScreenResolution(*traits, width, height);
174         traits->windowDecoration = false;
175         traits->width = width;
176         traits->height = height;
177         traits->supportsResize = false;
178         traitsSet = 1;
179     } else {
180         int resizable = 0;
181         resizable |= setFromProperty(traits->windowDecoration, winNode,
182                                      "decoration");
183         resizable |= setFromProperty(traits->width, winNode, "width");
184         resizable |= setFromProperty(traits->height, winNode, "height");
185         if (resizable) {
186             traits->supportsResize = true;
187             traitsSet = 1;
188         }
189         // Otherwise use default values.
190     }
191     traitsSet |= setFromProperty(traits->x, winNode, "x");
192     traitsSet |= setFromProperty(traits->y, winNode, "y");
193     if (!windowName.empty() && windowName != traits->windowName) {
194         traits->windowName = windowName;
195         traitsSet = 1;
196     } else if (traitsSet) {
197         traits->windowName = makeName("FlightGear", defaultCounter++);
198     }
199     bool drawGUI = false;
200     traitsSet |= setFromProperty(drawGUI, winNode, "gui");
201     if (traitsSet) {
202         GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
203         if (gc) {
204             GraphicsWindow* window = WindowSystemAdapter::getWSA()
205                 ->registerWindow(gc, traits->windowName);
206             if (drawGUI)
207                 window->flags |= GraphicsWindow::GUI;
208             return window;
209         } else {
210             return 0;
211         }
212     } else {
213         // XXX What if the window has no traits, but does have a name?
214         // We should create a "default window" registered with that name.
215         return getDefaultWindow();
216     }
217 }
218
219 GraphicsWindow* WindowBuilder::getDefaultWindow()
220 {
221     GraphicsWindow* defaultWindow
222         = WindowSystemAdapter::getWSA()->findWindow(defaultWindowName);
223     if (defaultWindow)
224         return defaultWindow;
225     GraphicsContext::Traits* traits
226         = new GraphicsContext::Traits(*defaultTraits);
227     traits->windowName = "FlightGear";
228     
229     GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
230     if (gc) {
231         defaultWindow = WindowSystemAdapter::getWSA()
232             ->registerWindow(gc, defaultWindowName);
233         return defaultWindow;
234     } else {
235         SG_LOG(SG_GENERAL, SG_ALERT, "getDefaultWindow: failed to create GraphicsContext");
236         return 0;
237     }
238 }
239 }