1 // Copyright (C) 2008 Tim Moore
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.
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.
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.
17 #include "WindowBuilder.hxx"
19 #include "WindowSystemAdapter.hxx"
20 #include "fg_props.hxx"
29 string makeName(const string& prefix, int num)
32 stream << prefix << num;
36 ref_ptr<WindowBuilder> WindowBuilder::windowBuilder;
38 const string WindowBuilder::defaultWindowName("FlightGear");
40 void WindowBuilder::initWindowBuilder(bool stencil)
42 windowBuilder = new WindowBuilder(stencil);
45 WindowBuilder::WindowBuilder(bool stencil) : defaultCounter(0)
47 defaultTraits = makeDefaultTraits(stencil);
50 GraphicsContext::Traits*
51 WindowBuilder::makeDefaultTraits(bool stencil)
53 GraphicsContext::WindowingSystemInterface* wsi
54 = osg::GraphicsContext::getWindowingSystemInterface();
55 GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
57 traits->readDISPLAY();
58 if (traits->displayNum < 0)
59 traits->displayNum = 0;
60 if (traits->screenNum < 0)
61 traits->screenNum = 0;
63 int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
64 bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
65 int cbits = (bpp <= 16) ? 5 : 8;
66 int zbits = (bpp <= 16) ? 16 : 24;
67 traits->red = traits->green = traits->blue = cbits;
68 traits->depth = zbits;
75 unsigned screenwidth = 0;
76 unsigned screenheight = 0;
77 wsi->getScreenResolution(*traits, screenwidth, screenheight);
79 traits->doubleBuffer = true;
80 traits->mipMapGeneration = true;
81 traits->windowName = "FlightGear";
82 // XXX should check per window too.
83 traits->sampleBuffers = fgGetBool("/sim/rendering/multi-sample-buffers", traits->sampleBuffers);
84 traits->samples = fgGetInt("/sim/rendering/multi-samples", traits->samples);
85 traits->vsync = fgGetBool("/sim/rendering/vsync-enable", traits->vsync);
86 traits->windowDecoration = !fgGetBool("/sim/startup/fullscreen");
88 if (!traits->windowDecoration) {
90 traits->supportsResize = false;
91 traits->width = screenwidth;
92 traits->height = screenheight;
93 SG_LOG(SG_VIEW,SG_DEBUG,"Using full screen size for window: " << screenwidth << " x " << screenheight);
96 int w = fgGetInt("/sim/startup/xsize");
97 int h = fgGetInt("/sim/startup/ysize");
98 traits->supportsResize = true;
103 traits->x = ((unsigned)w>screenwidth) ? 0 : (screenwidth-w)/3;
104 traits->y = ((unsigned)h>screenheight) ? 0 : (screenheight-h)/3;
106 SG_LOG(SG_VIEW,SG_DEBUG,"Using initial window size: " << w << " x " << h);
114 // Helper functions that set a value based on a property if it exists,
115 // returning 1 if the value was set.
117 inline int setFromProperty(string& place, const SGPropertyNode* node,
120 const SGPropertyNode* valNode = node->getNode(name);
122 place = valNode->getStringValue();
128 inline int setFromProperty(int& place, const SGPropertyNode* node,
131 const SGPropertyNode* valNode = node->getNode(name);
133 place = valNode->getIntValue();
139 inline int setFromProperty(bool& place, const SGPropertyNode* node,
142 const SGPropertyNode* valNode = node->getNode(name);
144 place = valNode->getBoolValue();
153 GraphicsWindow* WindowBuilder::buildWindow(const SGPropertyNode* winNode)
155 GraphicsContext::WindowingSystemInterface* wsi
156 = osg::GraphicsContext::getWindowingSystemInterface();
157 WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
159 if (winNode->hasChild("window-name"))
160 windowName = winNode->getStringValue("window-name");
161 else if (winNode->hasChild("name"))
162 windowName = winNode->getStringValue("name");
163 GraphicsWindow* result = 0;
164 if (!windowName.empty()) {
165 result = wsa->findWindow(windowName);
169 GraphicsContext::Traits* traits
170 = new GraphicsContext::Traits(*defaultTraits);
171 int traitsSet = setFromProperty(traits->hostName, winNode, "host-name");
172 traitsSet |= setFromProperty(traits->displayNum, winNode, "display");
173 traitsSet |= setFromProperty(traits->screenNum, winNode, "screen");
175 const SGPropertyNode* fullscreenNode = winNode->getNode("fullscreen");
177 if (fullscreenNode && fullscreenNode->getBoolValue()) {
181 wsi->getScreenResolution(*traits, width, height);
182 traits->windowDecoration = false;
183 traits->width = width;
184 traits->height = height;
185 traits->supportsResize = false;
191 if (fullscreenNode && !fullscreenNode->getBoolValue())
193 traits->windowDecoration = true;
196 resizable |= setFromProperty(traits->windowDecoration, winNode,
198 resizable |= setFromProperty(traits->width, winNode, "width");
199 resizable |= setFromProperty(traits->height, winNode, "height");
201 traits->supportsResize = true;
204 // Otherwise use default values.
206 traitsSet |= setFromProperty(traits->x, winNode, "x");
207 traitsSet |= setFromProperty(traits->y, winNode, "y");
208 if (!windowName.empty() && windowName != traits->windowName) {
209 traits->windowName = windowName;
211 } else if (traitsSet) {
212 traits->windowName = makeName("FlightGear", defaultCounter++);
214 bool drawGUI = false;
215 traitsSet |= setFromProperty(drawGUI, winNode, "gui");
217 GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
219 GraphicsWindow* window = WindowSystemAdapter::getWSA()
220 ->registerWindow(gc, traits->windowName);
222 window->flags |= GraphicsWindow::GUI;
228 // XXX What if the window has no traits, but does have a name?
229 // We should create a "default window" registered with that name.
230 return getDefaultWindow();
234 GraphicsWindow* WindowBuilder::getDefaultWindow()
236 GraphicsWindow* defaultWindow
237 = WindowSystemAdapter::getWSA()->findWindow(defaultWindowName);
239 return defaultWindow;
240 GraphicsContext::Traits* traits
241 = new GraphicsContext::Traits(*defaultTraits);
242 traits->windowName = "FlightGear";
244 GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
246 defaultWindow = WindowSystemAdapter::getWSA()
247 ->registerWindow(gc, defaultWindowName);
248 return defaultWindow;
250 SG_LOG(SG_VIEW, SG_ALERT, "getDefaultWindow: failed to create GraphicsContext");