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.
21 #include "WindowBuilder.hxx"
23 #include "WindowSystemAdapter.hxx"
24 #include <Main/fg_props.hxx>
28 #if defined(HAVE_QT) && defined(SG_MAC)
29 #include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
37 string makeName(const string& prefix, int num)
40 stream << prefix << num;
44 ref_ptr<WindowBuilder> WindowBuilder::windowBuilder;
46 const string WindowBuilder::defaultWindowName("FlightGear");
48 // default to true (historical behaviour), we will clear the flag if
49 // we run another GUI.
50 bool WindowBuilder::poseAsStandaloneApp = true;
52 void WindowBuilder::initWindowBuilder(bool stencil)
54 windowBuilder = new WindowBuilder(stencil);
57 WindowBuilder::WindowBuilder(bool stencil) : defaultCounter(0)
59 defaultTraits = makeDefaultTraits(stencil);
62 GraphicsContext::Traits*
63 WindowBuilder::makeDefaultTraits(bool stencil)
65 GraphicsContext::WindowingSystemInterface* wsi
66 = osg::GraphicsContext::getWindowingSystemInterface();
67 GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
69 traits->readDISPLAY();
70 if (traits->displayNum < 0)
71 traits->displayNum = 0;
72 if (traits->screenNum < 0)
73 traits->screenNum = 0;
75 int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
76 int cbits = (bpp <= 16) ? 5 : 8;
77 int zbits = (bpp <= 16) ? 16 : 24;
78 traits->red = traits->green = traits->blue = cbits;
79 traits->depth = zbits;
84 unsigned screenwidth = 0;
85 unsigned screenheight = 0;
86 wsi->getScreenResolution(*traits, screenwidth, screenheight);
88 traits->doubleBuffer = true;
89 traits->mipMapGeneration = true;
90 traits->windowName = "FlightGear";
91 // XXX should check per window too.
92 traits->sampleBuffers = fgGetInt("/sim/rendering/multi-sample-buffers", traits->sampleBuffers);
93 traits->samples = fgGetInt("/sim/rendering/multi-samples", traits->samples);
94 traits->vsync = fgGetBool("/sim/rendering/vsync-enable", traits->vsync);
95 traits->windowDecoration = !fgGetBool("/sim/startup/fullscreen");
97 if (!traits->windowDecoration) {
99 traits->supportsResize = false;
100 traits->width = screenwidth;
101 traits->height = screenheight;
102 SG_LOG(SG_VIEW,SG_DEBUG,"Using full screen size for window: " << screenwidth << " x " << screenheight);
105 int w = fgGetInt("/sim/startup/xsize");
106 int h = fgGetInt("/sim/startup/ysize");
107 traits->supportsResize = true;
112 traits->x = ((unsigned)w>screenwidth) ? 0 : (screenwidth-w)/3;
113 traits->y = ((unsigned)h>screenheight) ? 0 : (screenheight-h)/3;
115 SG_LOG(SG_VIEW,SG_DEBUG,"Using initial window size: " << w << " x " << h);
123 // Helper functions that set a value based on a property if it exists,
124 // returning 1 if the value was set.
126 inline int setFromProperty(string& place, const SGPropertyNode* node,
129 const SGPropertyNode* valNode = node->getNode(name);
131 place = valNode->getStringValue();
137 inline int setFromProperty(int& place, const SGPropertyNode* node,
140 const SGPropertyNode* valNode = node->getNode(name);
142 place = valNode->getIntValue();
148 inline int setFromProperty(bool& place, const SGPropertyNode* node,
151 const SGPropertyNode* valNode = node->getNode(name);
153 place = valNode->getBoolValue();
162 GraphicsWindow* WindowBuilder::buildWindow(const SGPropertyNode* winNode)
164 GraphicsContext::WindowingSystemInterface* wsi
165 = osg::GraphicsContext::getWindowingSystemInterface();
166 WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
168 if (winNode->hasChild("window-name"))
169 windowName = winNode->getStringValue("window-name");
170 else if (winNode->hasChild("name"))
171 windowName = winNode->getStringValue("name");
172 GraphicsWindow* result = 0;
173 if (!windowName.empty()) {
174 result = wsa->findWindow(windowName);
178 GraphicsContext::Traits* traits
179 = new GraphicsContext::Traits(*defaultTraits);
180 int traitsSet = setFromProperty(traits->hostName, winNode, "host-name");
181 traitsSet |= setFromProperty(traits->displayNum, winNode, "display");
182 traitsSet |= setFromProperty(traits->screenNum, winNode, "screen");
184 const SGPropertyNode* fullscreenNode = winNode->getNode("fullscreen");
185 const SGPropertyNode* orrNode = winNode->getNode("overrideRedirect");
187 if (fullscreenNode && fullscreenNode->getBoolValue()) {
191 wsi->getScreenResolution(*traits, width, height);
192 traits->windowDecoration = false;
193 traits->width = width;
194 traits->height = height;
195 traits->supportsResize = false;
196 bool overrideRedirect = orrNode && orrNode->getBoolValue();
197 traits->overrideRedirect = overrideRedirect;
203 if (fullscreenNode && !fullscreenNode->getBoolValue())
205 traits->windowDecoration = true;
208 resizable |= setFromProperty(traits->windowDecoration, winNode,
210 resizable |= setFromProperty(traits->width, winNode, "width");
211 resizable |= setFromProperty(traits->height, winNode, "height");
213 traits->supportsResize = true;
216 // Otherwise use default values.
218 traitsSet |= setFromProperty(traits->x, winNode, "x");
219 traitsSet |= setFromProperty(traits->y, winNode, "y");
220 if (!windowName.empty() && windowName != traits->windowName) {
221 traits->windowName = windowName;
223 } else if (traitsSet) {
224 traits->windowName = makeName("FlightGear", defaultCounter++);
226 bool drawGUI = false;
227 traitsSet |= setFromProperty(drawGUI, winNode, "gui");
229 GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
231 GraphicsWindow* window = WindowSystemAdapter::getWSA()
232 ->registerWindow(gc, traits->windowName);
234 window->flags |= GraphicsWindow::GUI;
240 // XXX What if the window has no traits, but does have a name?
241 // We should create a "default window" registered with that name.
242 return getDefaultWindow();
246 GraphicsWindow* WindowBuilder::getDefaultWindow()
248 GraphicsWindow* defaultWindow
249 = WindowSystemAdapter::getWSA()->findWindow(defaultWindowName);
251 return defaultWindow;
252 GraphicsContext::Traits* traits
253 = new GraphicsContext::Traits(*defaultTraits);
254 traits->windowName = "FlightGear";
256 #if defined(HAVE_QT) && defined(SG_MAC)
257 int flags = osgViewer::GraphicsWindowCocoa::WindowData::CheckForEvents;
259 // avoid both QApplication and OSG::CocoaViewer doing single-application
260 // init (Apple menu, making front process, etc)
261 if (poseAsStandaloneApp) {
262 flags |= osgViewer::GraphicsWindowCocoa::WindowData::PoseAsStandaloneApp;
264 traits->inheritedWindowData = new osgViewer::GraphicsWindowCocoa::WindowData(flags);
267 GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
269 defaultWindow = WindowSystemAdapter::getWSA()
270 ->registerWindow(gc, defaultWindowName);
271 return defaultWindow;
273 SG_LOG(SG_VIEW, SG_ALERT, "getDefaultWindow: failed to create GraphicsContext");
278 void WindowBuilder::setPoseAsStandaloneApp(bool b)
280 poseAsStandaloneApp = b;
283 } // of namespace flightgear