]> git.mxchange.org Git - flightgear.git/blob - src/Main/WindowBuilder.cxx
Restore sky
[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 void WindowBuilder::initWindowBuilder(bool stencil)
39 {
40     windowBuilder = new WindowBuilder(stencil);
41 }
42
43 WindowBuilder::WindowBuilder(bool stencil) : defaultCounter(0)
44 {
45     defaultTraits = makeDefaultTraits(stencil);
46 }
47
48 GraphicsContext::Traits*
49 WindowBuilder::makeDefaultTraits(bool stencil)
50 {
51     GraphicsContext::WindowingSystemInterface* wsi
52         = osg::GraphicsContext::getWindowingSystemInterface();
53     int w = fgGetInt("/sim/startup/xsize");
54     int h = fgGetInt("/sim/startup/ysize");
55     int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
56     bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
57     bool fullscreen = fgGetBool("/sim/startup/fullscreen");
58
59     GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
60     traits->readDISPLAY();
61     int cbits = (bpp <= 16) ?  5 :  8;
62     int zbits = (bpp <= 16) ? 16 : 24;
63     traits->red = traits->green = traits->blue = cbits;
64     traits->depth = zbits;
65     if (alpha)
66         traits->alpha = 8;
67     if (stencil)
68         traits->stencil = 8;
69     traits->doubleBuffer = true;
70     traits->mipMapGeneration = true;
71     traits->windowName = "FlightGear";
72     // XXX should check per window too.
73     traits->sampleBuffers = fgGetBool("/sim/rendering/multi-sample-buffers", traits->sampleBuffers);
74     traits->samples = fgGetBool("/sim/rendering/multi-samples", traits->samples);
75     traits->vsync = fgGetBool("/sim/rendering/vsync-enable", traits->vsync);
76     if (fullscreen) {
77         unsigned width = 0;
78         unsigned height = 0;
79         wsi->getScreenResolution(*traits, width, height);
80         traits->windowDecoration = false;
81         traits->width = width;
82         traits->height = height;
83         traits->supportsResize = false;
84     } else {
85         traits->windowDecoration = true;
86         traits->width = w;
87         traits->height = h;
88 #if defined(WIN32) || defined(__APPLE__)
89         // Ugly Hack, why does CW_USEDEFAULT works like phase of the moon?
90         // Mac also needs this to show window frame, menubar and Docks
91         traits->x = 100;
92         traits->y = 100;
93 #endif
94         traits->supportsResize = true;
95     }
96     return traits;
97 }
98 }
99
100 namespace
101 {
102 // Helper functions that set a value based on a property if it exists,
103 // returning 1 if the value was set.
104
105 inline int setFromProperty(string& place, const SGPropertyNode* node,
106                             const char* name)
107 {
108     const SGPropertyNode* valNode = node->getNode(name);
109     if (valNode) {
110         place = valNode->getStringValue();
111         return 1;
112     }
113     return 0;
114 }
115
116 inline int setFromProperty(int& place, const SGPropertyNode* node,
117                             const char* name)
118 {
119     const SGPropertyNode* valNode = node->getNode(name);
120     if (valNode) {
121         place = valNode->getIntValue();
122         return 1;
123     }
124     return 0;
125 }
126
127 inline int setFromProperty(bool& place, const SGPropertyNode* node,
128                             const char* name)
129 {
130     const SGPropertyNode* valNode = node->getNode(name);
131     if (valNode) {
132         place = valNode->getBoolValue();
133         return 1;
134     }
135     return 0;
136 }
137 }
138
139 namespace flightgear
140 {
141 GraphicsWindow* WindowBuilder::buildWindow(const SGPropertyNode* winNode)
142 {
143     GraphicsContext::WindowingSystemInterface* wsi
144         = osg::GraphicsContext::getWindowingSystemInterface();
145     WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
146     string windowName;
147     if (winNode->hasChild("window-name"))
148         windowName = winNode->getStringValue("window-name");
149     else if (winNode->hasChild("name")) 
150         windowName = winNode->getStringValue("name");
151     GraphicsWindow* result = 0;
152     if (!windowName.empty()) {
153         result = wsa->findWindow(windowName);
154         if (result)
155             return result;
156     }
157     GraphicsContext::Traits* traits
158         = new GraphicsContext::Traits(*defaultTraits);
159     int traitsSet = setFromProperty(traits->hostName, winNode, "host-name");
160     traitsSet |= setFromProperty(traits->displayNum, winNode, "display");
161     traitsSet |= setFromProperty(traits->screenNum, winNode, "screen");
162     const SGPropertyNode* fullscreenNode = winNode->getNode("fullscreen");
163     if (fullscreenNode && fullscreenNode->getBoolValue()) {
164         unsigned width = 0;
165         unsigned height = 0;
166         wsi->getScreenResolution(*traits, width, height);
167         traits->windowDecoration = false;
168         traits->width = width;
169         traits->height = height;
170         traits->supportsResize = false;
171         traitsSet = 1;
172     } else {
173         int resizable = 0;
174         resizable |= setFromProperty(traits->windowDecoration, winNode,
175                                      "decoration");
176         resizable |= setFromProperty(traits->width, winNode, "width");
177         resizable |= setFromProperty(traits->height, winNode, "height");
178         if (resizable) {
179             traits->supportsResize = true;
180             traitsSet = 1;
181         }
182         // Otherwise use default values.
183     }
184     traitsSet |= setFromProperty(traits->x, winNode, "x");
185     traitsSet |= setFromProperty(traits->y, winNode, "y");
186     if (!windowName.empty() && windowName != traits->windowName) {
187         traits->windowName = windowName;
188         traitsSet = 1;
189     } else if (traitsSet) {
190         traits->windowName = makeName("FlightGear", defaultCounter++);
191     }
192     bool drawGUI = false;
193     traitsSet |= setFromProperty(drawGUI, winNode, "gui");
194     if (traitsSet) {
195         GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
196         if (gc) {
197             gc->realize();
198             GraphicsWindow* window = WindowSystemAdapter::getWSA()
199                 ->registerWindow(gc, traits->windowName);
200             if (drawGUI)
201                 window->flags |= GraphicsWindow::GUI;
202             return window;
203         } else {
204             return 0;
205         }
206     } else {
207         return getDefaultWindow();
208     }
209 }
210
211 GraphicsWindow* WindowBuilder::getDefaultWindow()
212 {
213     if (defaultWindow.valid())
214         return defaultWindow.get();
215     GraphicsContext::Traits* traits
216         = new GraphicsContext::Traits(*defaultTraits);
217     traits->windowName = "FlightGear";
218     GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
219     if (gc) {
220         gc->realize();
221         defaultWindow = WindowSystemAdapter::getWSA()
222             ->registerWindow(gc, traits->windowName);
223         return defaultWindow.get();
224     } else {
225         return 0;
226     }
227 }
228 }