#include <simgear/compiler.h>
-#ifdef HAVE_WINDOWS_H
-# include <windows.h>
-#endif
-
-#include SG_GL_H
-
#include <fstream>
#include <string>
+#include <cstring>
+#include <sstream>
#include <stdlib.h>
-#include <string.h>
-// for help call back
-#ifdef WIN32
-# include <shellapi.h>
-# ifdef __CYGWIN__
-# include <sys/cygwin.h>
-# endif
-#endif
-
-#include <sstream>
-
-#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/screen/screen-dump.hxx>
+#include <simgear/structure/event_mgr.hxx>
+#include <simgear/props/props_io.hxx>
-#include <Include/general.hxx>
-#include <Aircraft/aircraft.hxx>
-#include <Aircraft/controls.hxx>
-#include <Airports/simple.hxx>
#include <Cockpit/panel.hxx>
-#include <FDM/flight.hxx>
-#include <Main/main.hxx>
-#include <Main/fg_init.hxx>
-#include <Main/fg_io.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
-#include <Main/renderer.hxx>
-#include <Main/viewmgr.hxx>
+#include <Main/fg_os.hxx>
+#include <Viewer/renderer.hxx>
+#include <Viewer/viewmgr.hxx>
+#include <Viewer/WindowSystemAdapter.hxx>
+#include <Viewer/CameraGroup.hxx>
#include <GUI/new_gui.hxx>
-#if defined( WIN32 ) && !defined( __CYGWIN__ ) && !defined(__MINGW32__)
-# include <simgear/screen/win32-printer.h>
-# include <simgear/screen/GlBitmaps.h>
+
+#ifdef _WIN32
+# include <shellapi.h>
+#endif
+
+#ifdef SG_MAC
+# include "FGCocoaMenuBar.hxx" // for cocoaOpenUrl
#endif
#include "gui.h"
-SG_USING_STD(string);
-SG_USING_STD(cout);
+using std::string;
#if defined( TR_HIRES_SNAP)
{"dumpHiResSnapShot", fgHiResDumpWrapper},
#endif
{"dumpSnapShot", fgDumpSnapShotWrapper},
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
- {"printScreen", printScreen},
-#endif
// Help
{"helpCb", helpCb},
string msg = txt;
msg += '\n';
msg += throwable.getFormattedMessage();
- if (!throwable.getOrigin().empty()) {
+ if (!std::strlen(throwable.getOrigin()) != 0) {
msg += "\n (reported by ";
msg += throwable.getOrigin();
msg += ')';
the Gui callback functions
____________________________________________________________________*/
-
-// Hier Neu :-) This is my newly added code
-// Added by David Findlay <nedz@bigpond.com>
-// on Sunday 3rd of December
-
-
-void helpCb ()
+void helpCb()
{
- string command;
-
- SGPath path( globals->get_fg_root() );
- path.append( "Docs/index.html" );
-
-#if !defined(WIN32)
-
- command = globals->get_browser();
- string::size_type pos;
- if ((pos = command.find("%u", 0)) != string::npos)
- command.replace(pos, 2, path.str());
- else
- command += " " + path.str();
+ openBrowser( "Docs/index.html" );
+}
- command += " &";
- system( command.c_str() );
+bool openBrowser(const std::string& aAddress)
+{
+ bool ok = true;
+ string address(aAddress);
+
+ // do not resolve addresses with given protocol, i.e. "http://...", "ftp://..."
+ if (address.find("://")==string::npos)
+ {
+ // resolve local file path
+ SGPath path(address);
+ path = globals->resolve_maybe_aircraft_path(address);
+ if (!path.isNull())
+ address = path.str();
+ else
+ {
+ mkDialog ("Sorry, file not found!");
+ SG_LOG(SG_GENERAL, SG_ALERT, "openBrowser: Cannot find requested file '"
+ << address << "'.");
+ return false;
+ }
+ }
-#else // WIN32
+#ifdef SG_MAC
+ if (address.find("://")==string::npos) {
+ address = "file://" + address;
+ }
+
+ cocoaOpenUrl(address);
+#elif defined _WIN32
// Look for favorite browser
- char Dummy[1024], ExecName[1024], browserParameter[1024];
char win32_name[1024];
# ifdef __CYGWIN__
- cygwin32_conv_to_full_win32_path(path.c_str(),win32_name);
+ cygwin32_conv_to_full_win32_path(address.c_str(),win32_name);
# else
- strncpy(win32_name,path.c_str(), 1024);
+ strncpy(win32_name,address.c_str(), 1024);
# endif
- Dummy[0] = 0;
- FindExecutable(win32_name, Dummy, ExecName);
- snprintf(browserParameter, 1024, "file:///%s", win32_name);
- ShellExecute ( NULL, "open", ExecName, browserParameter, Dummy,
+ ShellExecute ( NULL, "open", win32_name, NULL, NULL,
SW_SHOWNORMAL ) ;
+#else
+ // Linux, BSD, SGI etc
+ string command = globals->get_browser();
+ string::size_type pos;
+ if ((pos = command.find("%u", 0)) != string::npos)
+ command.replace(pos, 2, address);
+ else
+ command += " \"" + address +"\"";
+ command += " &";
+ ok = (system( command.c_str() ) == 0);
#endif
-
- mkDialog ("Help started in your web browser window.");
+
+ mkDialog("The file is shown in your web browser window.");
+ return ok;
}
#if defined( TR_HIRES_SNAP)
{
FILE *f;
string message;
- bool show_pu_cursor = false;
bool menu_status = fgGetBool("/sim/menubar/visibility");
char *filename = new char [24];
static int count = 1;
}
fgSetBool("/sim/menubar/visibility", false);
- TurnCursorOff();
- if ( !puCursorIsHidden() ) {
- show_pu_cursor = true;
- puHideCursor();
- }
+ int mouse = fgGetMouseCursor();
+ fgSetMouseCursor(MOUSE_CURSOR_NONE);
FGRenderer *renderer = globals->get_renderer();
// renderer->init();
/* allocate buffer large enough to store one tile */
GLubyte *tile = (GLubyte *)malloc(width * height * 3 * sizeof(GLubyte));
if (!tile) {
+ delete [] filename;
printf("Malloc of tile buffer failed!\n");
return;
}
GLubyte *buffer
= (GLubyte *)malloc(imageWidth * height * 3 * sizeof(GLubyte));
if (!buffer) {
+ delete [] filename;
free(tile);
printf("Malloc of tile row buffer failed!\n");
return;
f = fopen(filename, "wb");
if (!f) {
printf("Couldn't open image file: %s\n", filename);
+ delete [] filename;
free(buffer);
free(tile);
return;
/* just to be safe... */
glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ // OSGFIXME
+#if 0
/* Because the HUD and Panel change the ViewPort we will
* need to handle some lowlevel stuff ourselves */
int ncols = trGet(tr, TR_COLUMNS);
bool do_panel = fgPanelVisible();
GLfloat panel_col_step = globals->get_current_panel()->getWidth() / ncols;
GLfloat panel_row_step = globals->get_current_panel()->getHeight() / nrows;
-
+#endif
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
while (more) {
trBeginTile(tr);
int curColumn = trGet(tr, TR_CURRENT_COLUMN);
- int curRow = trGet(tr, TR_CURRENT_ROW);
+ // int curRow = trGet(tr, TR_CURRENT_ROW);
- renderer->update( false );
+ renderer->update();
// OSGFIXME
// if ( do_hud )
// fgUpdateHUD( curColumn*hud_col_step, curRow*hud_row_step,
delete [] filename;
- if ( show_pu_cursor ) {
- puShowCursor();
- }
-
- TurnCursorOn();
+ fgSetMouseCursor(mouse);
fgSetBool("/sim/menubar/visibility", menu_status);
if ( !freeze ) {
}
#endif // #if defined( TR_HIRES_SNAP)
+void fgDumpSnapShotWrapper () {
+ fgDumpSnapShot();
+}
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
-void rotateView( double roll, double pitch, double yaw )
-{
- // rotate view
+void fgHiResDumpWrapper () {
+ fgHiResDump();
}
-GlBitmap *b1 = NULL;
-GLubyte *hiResScreenCapture( int multiplier )
+namespace
{
- float oldfov = fgGetDouble("/sim/current-view/field-of-view");
- float fov = oldfov / multiplier;
- FGViewer *v = globals->get_current_view();
- fgSetDouble("/sim/current-view/field-of-view", fov);
-// globals->get_renderer()->init();
- int cur_width = fgGetInt("/sim/startup/xsize");
- int cur_height = fgGetInt("/sim/startup/ysize");
- delete( b1 );
- // New empty (mostly) bitmap
- b1 = new GlBitmap( GL_RGB, 1, 1, (unsigned char *)"123" );
- int x,y;
- for ( y = 0; y < multiplier; y++ ) {
- for ( x = 0; x < multiplier; x++ ) {
- globals->get_renderer()->resize( cur_width, cur_height );
- // pan to tile
- rotateView( 0, (y*fov)-((multiplier-1)*fov/2), (x*fov)-((multiplier-1)*fov/2) );
- globals->get_renderer()->update( false );
- // restore view
- GlBitmap b2;
- b1->copyBitmap( &b2, cur_width*x, cur_height*y );
- }
- }
- fgSetDouble("/sim/current-view/field-of-view", oldfov);
- return b1->getBitmap();
-}
-#endif
+ using namespace flightgear;
+
+ class GUISnapShotOperation :
+ public GraphicsContextOperation
+ {
+ public:
+
+ // start new snap shot
+ static bool start()
+ {
+ // allow only one snapshot at a time
+ if (_snapShotOp.valid())
+ return false;
+ _snapShotOp = new GUISnapShotOperation();
+ /* register with graphics context so actual snap shot is done
+ * in the graphics context (thread) */
+ osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
+ WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
+ osg::GraphicsContext* gc = 0;
+ if (guiCamera)
+ gc = guiCamera->getGraphicsContext();
+ if (gc) {
+ gc->add(_snapShotOp.get());
+ } else {
+ wsa->windows[0]->gc->add(_snapShotOp.get());
+ }
+ return true;
+ }
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
-// win32 print screen function
-void printScreen () {
- bool show_pu_cursor = false;
- TurnCursorOff();
- if ( !puCursorIsHidden() ) {
- show_pu_cursor = true;
- puHideCursor();
- }
+ private:
+ // constructor to be executed in main loop's thread
+ GUISnapShotOperation() :
+ flightgear::GraphicsContextOperation(std::string("GUI snap shot")),
+ _master_freeze(fgGetNode("/sim/freeze/master", true)),
+ _freeze(_master_freeze->getBoolValue()),
+ _result(false),
+ _mouse(fgGetMouseCursor())
+ {
+ if (!_freeze)
+ _master_freeze->setBoolValue(true);
+
+ fgSetMouseCursor(MOUSE_CURSOR_NONE);
+
+ string dir = fgGetString("/sim/paths/screenshot-dir");
+ if (dir.empty())
+ dir = fgGetString("/sim/fg-current");
+
+ _path.set(dir + '/');
+ if (_path.create_dir( 0755 )) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '"
+ << dir << "'. Trying home directory.");
+ dir = globals->get_fg_home();
+ }
- CGlPrinter p( CGlPrinter::PRINT_BITMAP );
- int cur_width = fgGetInt("/sim/startup/xsize");
- int cur_height = fgGetInt("/sim/startup/ysize");
- p.Begin( "FlightGear", cur_width*3, cur_height*3 );
- p.End( hiResScreenCapture(3) );
+ char filename[24];
+ static int count = 1;
+ while (count < 1000) {
+ snprintf(filename, 24, "fgfs-screen-%03d.png", count++);
+
+ SGPath p(dir);
+ p.append(filename);
+ if (!p.exists()) {
+ _path.set(p.str());
+ break;
+ }
+ }
- if ( show_pu_cursor ) {
- puShowCursor();
- }
- TurnCursorOn();
-}
-#endif // #ifdef WIN32
+ _xsize = fgGetInt("/sim/startup/xsize");
+ _ysize = fgGetInt("/sim/startup/ysize");
+ FGRenderer *renderer = globals->get_renderer();
+ renderer->resize(_xsize, _ysize);
+ globals->get_event_mgr()->addTask("SnapShotTimer",
+ this, &GUISnapShotOperation::timerExpired,
+ 0.1, false);
+ }
-void fgDumpSnapShotWrapper () {
- fgDumpSnapShot();
-}
+ // to be executed in graphics context (maybe separate thread)
+ void run(osg::GraphicsContext* gc)
+ {
+ _result = sg_glDumpWindow(_path.c_str(),
+ _xsize,
+ _ysize);
+ }
+ // timer method, to be executed in main loop's thread
+ virtual void timerExpired()
+ {
+ if (isFinished())
+ {
+ globals->get_event_mgr()->removeTask("SnapShotTimer");
+
+ fgSetString("/sim/paths/screenshot-last", _path.c_str());
+ fgSetBool("/sim/signals/screenshot", _result);
+
+ fgSetMouseCursor(_mouse);
+
+ if ( !_freeze )
+ _master_freeze->setBoolValue(false);
+
+ _snapShotOp = 0;
+ }
+ }
+
+ static osg::ref_ptr<GUISnapShotOperation> _snapShotOp;
+ SGPropertyNode_ptr _master_freeze;
+ bool _freeze;
+ bool _result;
+ int _mouse;
+ int _xsize, _ysize;
+ SGPath _path;
+ };
-void fgHiResDumpWrapper () {
- fgHiResDump();
}
+osg::ref_ptr<GUISnapShotOperation> GUISnapShotOperation::_snapShotOp;
// do a screen snap shot
-bool fgDumpSnapShot () {
- bool show_pu_cursor = false;
+bool fgDumpSnapShot ()
+{
+#if 1
+ // start snap shot operation, while needs to be executed in
+ // graphics context
+ return GUISnapShotOperation::start();
+#else
+ // obsolete code => remove when new code is stable
static SGConstPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master");
bool freeze = master_freeze->getBoolValue();
fgSetBool("/sim/freeze/master", true);
}
- TurnCursorOff();
- if ( !puCursorIsHidden() ) {
- show_pu_cursor = true;
- puHideCursor();
- }
+ int mouse = fgGetMouseCursor();
+ fgSetMouseCursor(MOUSE_CURSOR_NONE);
+
fgSetBool("/sim/signals/screenshot", true);
FGRenderer *renderer = globals->get_renderer();
renderer->update( true );
renderer->update( true );
- string dir = fgGetString("/sim/paths/screenshot-dir", fgGetString("/sim/fg-current"));
+ string dir = fgGetString("/sim/paths/screenshot-dir");
+ if (dir.empty())
+ dir = fgGetString("/sim/fg-current");
+
SGPath path(dir + '/');
if (path.create_dir( 0755 )) {
SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '"
<< dir << "'. Trying home directory.");
- dir = fgGetString("/sim/fg-home");
+ dir = globals->get_fg_home();
}
char filename[24];
static int count = 1;
while (count < 1000) {
- snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
+ snprintf(filename, 24, "fgfs-screen-%03d.png", count++);
SGPath p(dir);
p.append(filename);
}
}
- int result = sg_glDumpWindow(path.c_str(),
+ bool result = sg_glDumpWindow(path.c_str(),
fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize"));
fgSetString("/sim/paths/screenshot-last", path.c_str());
fgSetBool("/sim/signals/screenshot", false);
- if ( show_pu_cursor ) {
- puShowCursor();
- }
-
- TurnCursorOn();
+ fgSetMouseCursor(mouse);
if ( !freeze ) {
fgSetBool("/sim/freeze/master", false);
}
- return result != 0;
+ return result;
+#endif
}
// do an entire scenegraph dump
string message;
static int count = 1;
- FGRenderer *renderer = globals->get_renderer();
-
static const SGPropertyNode *master_freeze
= fgGetNode("/sim/freeze/master");
string message;
static int count = 1;
- FGRenderer *renderer = globals->get_renderer();
-
static const SGPropertyNode *master_freeze
= fgGetNode("/sim/freeze/master");
}
}
+void fgPrintVisibleSceneInfoCommand()
+{
+ static const SGPropertyNode *master_freeze
+ = fgGetNode("/sim/freeze/master");
+
+ bool freeze = master_freeze->getBoolValue();
+ if ( !freeze ) {
+ fgSetBool("/sim/freeze/master", true);
+ }
+
+ flightgear::printVisibleSceneInfo(globals->get_renderer());
+
+ if ( !freeze ) {
+ fgSetBool("/sim/freeze/master", false);
+ }
+}
+