From a0689eedd71281caf6bb1b8da9b38cc5a154813c Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Tue, 28 Dec 2010 12:28:26 +0100
Subject: [PATCH 01/26] Cleanup: don't unbind unknown properties

---
 src/Main/fg_props.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx
index 3312889f0..b98f32805 100644
--- a/src/Main/fg_props.cxx
+++ b/src/Main/fg_props.cxx
@@ -527,8 +527,8 @@ FGProperties::unbind ()
 
 				// Misc. Temporary junk.
   fgUntie("/sim/temp/winding-ccw");
-  fgUntie("/sim/temp/full-screen");
-  fgUntie("/sim/temp/fdm-data-logging");
+//  fgUntie("/sim/temp/full-screen");
+//  fgUntie("/sim/temp/fdm-data-logging");
 }
 
 void

From 65301bf84eb6b035ffad65e23d2c56e43f08bc06 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 17:18:12 +0100
Subject: [PATCH 02/26] Replace plib/net.h by SimGear

---
 projects/VC90/GPSsmooth/GPSsmooth.vcproj   |  8 ++++----
 projects/VC90/MIDGsmooth/MIDGsmooth.vcproj |  8 ++++----
 projects/VC90/UGsmooth/UGsmooth.vcproj     |  8 ++++----
 utils/GPSsmooth/MIDG_main.cxx              | 10 +++++++---
 utils/GPSsmooth/UGear_main.cxx             | 10 +++++++---
 utils/GPSsmooth/UGear_telnet.cxx           | 19 +++++++++----------
 utils/GPSsmooth/UGear_telnet.hxx           |  4 ++--
 utils/GPSsmooth/gps_main.cxx               | 10 +++++++---
 8 files changed, 44 insertions(+), 33 deletions(-)

diff --git a/projects/VC90/GPSsmooth/GPSsmooth.vcproj b/projects/VC90/GPSsmooth/GPSsmooth.vcproj
index b1b37fc75..d804c8d6a 100644
--- a/projects/VC90/GPSsmooth/GPSsmooth.vcproj
+++ b/projects/VC90/GPSsmooth/GPSsmooth.vcproj
@@ -46,7 +46,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -126,7 +126,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90-64\OpenSceneGraph\include;..\..\..\..\3rdParty.x64\include"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -204,7 +204,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
@@ -282,7 +282,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90-64\OpenSceneGraph\include;..\..\..\..\3rdParty\include"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
diff --git a/projects/VC90/MIDGsmooth/MIDGsmooth.vcproj b/projects/VC90/MIDGsmooth/MIDGsmooth.vcproj
index 9e3fbd310..bb7ac9700 100644
--- a/projects/VC90/MIDGsmooth/MIDGsmooth.vcproj
+++ b/projects/VC90/MIDGsmooth/MIDGsmooth.vcproj
@@ -45,7 +45,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -126,7 +126,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90-64\OpenSceneGraph\include;..\..\..\..\3rdParty.x64\include"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -205,7 +205,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				RuntimeLibrary="2"
 				RuntimeTypeInfo="true"
 				UsePrecompiledHeader="0"
@@ -284,7 +284,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90-64\OpenSceneGraph\include;..\..\..\..\3rdParty.x64\include"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				RuntimeLibrary="2"
 				RuntimeTypeInfo="true"
 				UsePrecompiledHeader="0"
diff --git a/projects/VC90/UGsmooth/UGsmooth.vcproj b/projects/VC90/UGsmooth/UGsmooth.vcproj
index e9752829b..b334538ac 100644
--- a/projects/VC90/UGsmooth/UGsmooth.vcproj
+++ b/projects/VC90/UGsmooth/UGsmooth.vcproj
@@ -45,7 +45,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include;..\..\..\..\boost_1_44_0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -126,7 +126,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90-64\OpenSceneGraph\include;..\..\..\..\3rdParty.x64\include;..\..\..\..\boost_1_44_0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -205,7 +205,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include;..\..\..\..\boost_1_44_0"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				RuntimeLibrary="2"
 				RuntimeTypeInfo="true"
 				UsePrecompiledHeader="0"
@@ -284,7 +284,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="..\..\..\src;..\..\..\..\SimGear;..\..\..\..\install\msvc90-64\OpenSceneGraph\include;..\..\..\..\3rdParty.x64\include;..\..\..\..\boost_1_44_0"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_WINDOWS_H"
 				RuntimeLibrary="2"
 				RuntimeTypeInfo="true"
 				UsePrecompiledHeader="0"
diff --git a/utils/GPSsmooth/MIDG_main.cxx b/utils/GPSsmooth/MIDG_main.cxx
index 613f1d39d..7b8141254 100644
--- a/utils/GPSsmooth/MIDG_main.cxx
+++ b/utils/GPSsmooth/MIDG_main.cxx
@@ -2,16 +2,20 @@
 #  include <config.h>
 #endif
 
+#ifdef HAVE_WINDOWS_H
+#  include <windows.h>
+#endif
+
 #include <iostream>
 #include <string>
 
-#include <plib/net.h>
 #include <plib/sg.h>
 
 #include <simgear/constants.h>
 #include <simgear/io/lowlevel.hxx> // endian tests
 #include <simgear/io/sg_file.hxx>
 #include <simgear/io/sg_serial.hxx>
+#include <simgear/io/raw_socket.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/timing/timestamp.hxx>
 
@@ -27,7 +31,7 @@ using std::string;
 
 
 // Network channels
-static netSocket fdm_sock, ctrls_sock;
+static simgear::Socket fdm_sock, ctrls_sock;
 
 // midg data
 MIDGTrack track;
@@ -394,7 +398,7 @@ int main( int argc, char **argv ) {
 
     // Setup up outgoing network connections
 
-    netInit( &argc,argv ); // We must call this before any other net stuff
+    simgear::Socket::initSockets(); // We must call this before any other net stuff
 
     if ( ! fdm_sock.open( false ) ) {  // open a UDP socket
         cout << "error opening fdm output socket" << endl;
diff --git a/utils/GPSsmooth/UGear_main.cxx b/utils/GPSsmooth/UGear_main.cxx
index e814c2e07..faf5d725f 100644
--- a/utils/GPSsmooth/UGear_main.cxx
+++ b/utils/GPSsmooth/UGear_main.cxx
@@ -2,6 +2,10 @@
 #  include <config.h>
 #endif
 
+#ifdef HAVE_WINDOWS_H
+#  include <windows.h>
+#endif
+
 #ifndef _WIN32
 #  include <strings.h>		// for bzero()
 #else
@@ -10,12 +14,12 @@
 #include <iostream>
 #include <string>
 
-#include <plib/net.h>
 #include <plib/sg.h>
 
 #include <simgear/constants.h>
 #include <simgear/io/lowlevel.hxx> // endian tests
 #include <simgear/io/sg_file.hxx>
+#include <simgear/io/raw_socket.hxx>
 #include <simgear/serial/serial.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/timing/timestamp.hxx>
@@ -35,7 +39,7 @@ using std::string;
 
 
 // Network channels
-static netSocket fdm_sock, ctrls_sock, opengc_sock;
+static simgear::Socket fdm_sock, ctrls_sock, opengc_sock;
 
 // ugear data
 UGTrack track;
@@ -658,7 +662,7 @@ int main( int argc, char **argv ) {
 
     // Setup up outgoing network connections
 
-    netInit( &argc,argv ); // We must call this before any other net stuff
+    simgear::Socket::initSockets(); // We must call this before any other net stuff
 
     if ( ! opengc_sock.open( false ) ) {  // open a UDP socket
         cout << "error opening opengc output socket" << endl;
diff --git a/utils/GPSsmooth/UGear_telnet.cxx b/utils/GPSsmooth/UGear_telnet.cxx
index 602a6a9d8..be5b02e9f 100644
--- a/utils/GPSsmooth/UGear_telnet.cxx
+++ b/utils/GPSsmooth/UGear_telnet.cxx
@@ -23,14 +23,13 @@
 // $Id$
 
 
+#include <simgear/io/sg_netChat.hxx>
 #include <simgear/structure/commands.hxx>
 #include <simgear/misc/strutils.hxx>
 #include <simgear/math/SGMath.hxx>
 
 #include <sstream>
 
-#include <plib/netChat.h>
-
 #include "UGear_command.hxx"
 #include "UGear_telnet.hxx"
 
@@ -41,9 +40,9 @@ using std::ends;
  * Props connection class.
  * This class represents a connection to props client.
  */
-class PropsChannel : public netChat
+class PropsChannel : public simgear::NetChat
 {
-    netBuffer buffer;
+    simgear::NetBuffer buffer;
 
     /**
      * Current property node name.
@@ -188,9 +187,9 @@ UGTelnet::open()
 	return false;
     }
 
-    netChannel::open();
-    netChannel::bind( "", port );
-    netChannel::listen( 5 );
+    simgear::NetChannel::open();
+    simgear::NetChannel::bind( "", port );
+    simgear::NetChannel::listen( 5 );
     printf("Telnet server started on port %d\n", port );
 
     enabled = true;
@@ -214,7 +213,7 @@ UGTelnet::close()
 bool
 UGTelnet::process()
 {
-    netChannel::poll();
+    simgear::NetChannel::poll();
     return true;
 }
 
@@ -224,8 +223,8 @@ UGTelnet::process()
 void
 UGTelnet::handleAccept()
 {
-    netAddress addr;
-    int handle = netChannel::accept( &addr );
+    simgear::IPAddress addr;
+    int handle = simgear::NetChannel::accept( &addr );
     printf("Telent server accepted connection from %s:%d\n",
            addr.getHost(), addr.getPort() );
     PropsChannel* channel = new PropsChannel();
diff --git a/utils/GPSsmooth/UGear_telnet.hxx b/utils/GPSsmooth/UGear_telnet.hxx
index 34500a5c9..15e88633e 100644
--- a/utils/GPSsmooth/UGear_telnet.hxx
+++ b/utils/GPSsmooth/UGear_telnet.hxx
@@ -33,7 +33,7 @@
 using std::string;
 using std::vector;
 
-#include <plib/netChannel.h>
+#include <simgear/io/sg_netChannel.hxx>
 
 
 /**
@@ -41,7 +41,7 @@ using std::vector;
  * This class provides a telnet-like server for remote access to
  * FlightGear properties.
  */
-class UGTelnet: netChannel
+class UGTelnet: simgear::NetChannel
 {
 
 private:
diff --git a/utils/GPSsmooth/gps_main.cxx b/utils/GPSsmooth/gps_main.cxx
index f5a10d7ac..1b98b04a3 100644
--- a/utils/GPSsmooth/gps_main.cxx
+++ b/utils/GPSsmooth/gps_main.cxx
@@ -2,13 +2,17 @@
 #  include <config.h>
 #endif
 
+#ifdef HAVE_WINDOWS_H
+#  include <windows.h>
+#endif
+
 #include <iostream>
 #include <string>
 
-#include <plib/net.h>
 #include <plib/sg.h>
 
 #include <simgear/io/lowlevel.hxx> // endian tests
+#include <simgear/io/raw_socket.hxx>
 #include <simgear/timing/timestamp.hxx>
 
 #include <Network/net_ctrls.hxx>
@@ -23,7 +27,7 @@ using std::string;
 
 
 // Network channels
-static netSocket fdm_sock, ctrls_sock;
+static simgear::Socket fdm_sock, ctrls_sock;
 
 // gps data
 GPSTrack track;
@@ -369,7 +373,7 @@ int main( int argc, char **argv ) {
 
     // Setup up outgoing network connections
 
-    netInit( &argc,argv ); // We must call this before any other net stuff
+    simgear::Socket::initSockets(); // We must call this before any other net stuff
 
     if ( ! fdm_sock.open( false ) ) {  // open a UDP socket
         cout << "error opening fdm output socket" << endl;

From 402982f90159c2fbca31388b9fa7a5f085c89009 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 17:19:42 +0100
Subject: [PATCH 03/26] Cmake: add more utilities to the build system

---
 CMakeLists.txt                 |  7 +++++
 utils/CMakeLists.txt           |  2 +-
 utils/GPSsmooth/CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 utils/GPSsmooth/CMakeLists.txt

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ef8b6ade3..b8085c772 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,6 +8,11 @@ include (CPack)
 
 project(FlightGear)
 
+set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows")
+set(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
+set(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "add a postfix, usually empty on windows")
+set(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, usually empty on windows")
+
 # read 'version' file into a variable (stripping any newlines or spaces)
 file(READ version versionFile)
 string(STRIP ${versionFile} FLIGHTGEAR_VERSION) 
@@ -93,6 +98,7 @@ find_package(OpenGL REQUIRED)
 find_package(OpenAL REQUIRED)
 find_package(ALUT REQUIRED)
 find_package(OpenSceneGraph 2.8.2 REQUIRED osgText osgSim osgDB osgParticle osgFX osgUtil osgViewer osgGA)
+find_package(FLTK)
 
 find_package(PLIB REQUIRED puaux pu js fnt)
 find_package(SimGear 2.0.0 REQUIRED)
@@ -157,6 +163,7 @@ if(WIN32)
     endif(MSVC)
 
     set(NOMINMAX 1)
+    set( WINSOCK_LIBRARY "ws2_32.lib" )
 endif(WIN32)    
 
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS} -D_REENTRANT")
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index f7fad8a71..bcf0fcbc0 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -1,3 +1,3 @@
 add_subdirectory(TerraSync)
 add_subdirectory(fgviewer)
-
+add_subdirectory(GPSsmooth)
diff --git a/utils/GPSsmooth/CMakeLists.txt b/utils/GPSsmooth/CMakeLists.txt
new file mode 100644
index 000000000..78bc778ef
--- /dev/null
+++ b/utils/GPSsmooth/CMakeLists.txt
@@ -0,0 +1,48 @@
+
+add_executable(GPSsmooth gps.cxx gps_main.cxx)
+add_executable(MIDGsmooth MIDG-II.cxx MIDG_main.cxx)
+add_executable(UGsmooth UGear.cxx UGear_command.cxx UGear_main.cxx UGear_telnet.cxx)
+
+target_link_libraries(GPSsmooth 
+	${SIMGEAR_DEBUG_LIBRARY}
+	${SIMGEAR_IO_LIBRARY}
+	${SIMGEAR_MISC_LIBRARY}
+	${SIMGEAR_STRUCTURE_LIBRARY}
+	${SIMGEAR_TIMING_LIBRARY}
+	${PLIB_SG_LIBRARY}
+	${PLIB_UL_LIBRARY}
+	${ZLIB_LIBRARIES}
+	${WINMM_LIBRARY}
+	${WINSOCK_LIBRARY}
+	${ZLIB_LIBRARIES}
+)
+
+target_link_libraries(MIDGsmooth 
+	${SIMGEAR_DEBUG_LIBRARY}
+	${SIMGEAR_IO_LIBRARY}
+	${SIMGEAR_MATH_LIBRARY}
+	${SIMGEAR_SERIAL_LIBRARY}
+	${SIMGEAR_STRUCTURE_LIBRARY}
+	${SIMGEAR_TIMING_LIBRARY}
+	${PLIB_SG_LIBRARY}
+	${PLIB_UL_LIBRARY}
+	${WINMM_LIBRARY}
+	${WINSOCK_LIBRARY}
+)
+
+target_link_libraries(UGsmooth 
+	${SIMGEAR_DEBUG_LIBRARY}
+	${SIMGEAR_IO_LIBRARY}
+	${SIMGEAR_MATH_LIBRARY}
+	${SIMGEAR_MISC_LIBRARY}
+	${SIMGEAR_SERIAL_LIBRARY}
+	${SIMGEAR_STRUCTURE_LIBRARY}
+	${SIMGEAR_TIMING_LIBRARY}
+	${PLIB_SG_LIBRARY}
+	${PLIB_UL_LIBRARY}
+	${WINMM_LIBRARY}
+	${WINSOCK_LIBRARY}
+	${ZLIB_LIBRARIES}
+)
+
+install(TARGETS GPSsmooth MIDGsmooth UGsmooth RUNTIME DESTINATION bin)

From 1c792fb97c9f6edf62aefbeeaf5c1f315d78c709 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 17:38:15 +0100
Subject: [PATCH 04/26] Provide declarations of hton*() and ntoh*()

---
 utils/GPSsmooth/MIDG_main.cxx  | 2 ++
 utils/GPSsmooth/UGear_main.cxx | 2 ++
 utils/GPSsmooth/gps_main.cxx   | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/utils/GPSsmooth/MIDG_main.cxx b/utils/GPSsmooth/MIDG_main.cxx
index 7b8141254..118c6198b 100644
--- a/utils/GPSsmooth/MIDG_main.cxx
+++ b/utils/GPSsmooth/MIDG_main.cxx
@@ -4,6 +4,8 @@
 
 #ifdef HAVE_WINDOWS_H
 #  include <windows.h>
+#else
+#  include <netinet/in.h>       // htonl() ntohl()
 #endif
 
 #include <iostream>
diff --git a/utils/GPSsmooth/UGear_main.cxx b/utils/GPSsmooth/UGear_main.cxx
index faf5d725f..43d44b6f2 100644
--- a/utils/GPSsmooth/UGear_main.cxx
+++ b/utils/GPSsmooth/UGear_main.cxx
@@ -4,6 +4,8 @@
 
 #ifdef HAVE_WINDOWS_H
 #  include <windows.h>
+#else
+#  include <netinet/in.h>       // htonl() ntohl()
 #endif
 
 #ifndef _WIN32
diff --git a/utils/GPSsmooth/gps_main.cxx b/utils/GPSsmooth/gps_main.cxx
index 1b98b04a3..5dfc76c67 100644
--- a/utils/GPSsmooth/gps_main.cxx
+++ b/utils/GPSsmooth/gps_main.cxx
@@ -4,6 +4,8 @@
 
 #ifdef HAVE_WINDOWS_H
 #  include <windows.h>
+#else
+#  include <netinet/in.h>       // htonl() ntohl()
 #endif
 
 #include <iostream>

From ef4c4ac1f503b26954b2972bb51f78b63e88078c Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 17:51:46 +0100
Subject: [PATCH 05/26] Cmake: add fgadmin to the project

---
 utils/CMakeLists.txt             |  1 +
 utils/fgadmin/CMakeLists.txt     |  1 +
 utils/fgadmin/src/CMakeLists.txt | 11 +++++++++++
 3 files changed, 13 insertions(+)
 create mode 100644 utils/fgadmin/CMakeLists.txt
 create mode 100644 utils/fgadmin/src/CMakeLists.txt

diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index bcf0fcbc0..dffd090db 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -1,3 +1,4 @@
 add_subdirectory(TerraSync)
 add_subdirectory(fgviewer)
 add_subdirectory(GPSsmooth)
+add_subdirectory(fgadmin)
diff --git a/utils/fgadmin/CMakeLists.txt b/utils/fgadmin/CMakeLists.txt
new file mode 100644
index 000000000..febd4f0ab
--- /dev/null
+++ b/utils/fgadmin/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(src)
diff --git a/utils/fgadmin/src/CMakeLists.txt b/utils/fgadmin/src/CMakeLists.txt
new file mode 100644
index 000000000..045ab0b4f
--- /dev/null
+++ b/utils/fgadmin/src/CMakeLists.txt
@@ -0,0 +1,11 @@
+
+add_executable(fgadmin fgadmin.cxx fgadmin_funcs.cxx main.cxx untarka.c)
+
+target_link_libraries(fgadmin 
+	${SIMGEAR_LIBRARIES}
+	${ZLIB_LIBRARIES}
+	${PLIB_LIBRARIES}
+	${FLTK_LIBRARIES}
+)
+	
+install(TARGETS fgadmin RUNTIME DESTINATION bin)

From 4d4c12bfa0d9d089ec456b117443d7428e958455 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 17:54:38 +0100
Subject: [PATCH 06/26] Replace plib/net.h by SimGear

---
 utils/GPSsmooth/Makefile.am | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/utils/GPSsmooth/Makefile.am b/utils/GPSsmooth/Makefile.am
index c0d4edebd..fb4127c1a 100644
--- a/utils/GPSsmooth/Makefile.am
+++ b/utils/GPSsmooth/Makefile.am
@@ -5,9 +5,9 @@ GPSsmooth_LDFLAGS = $(plib_FRAMEWORK)
 MIDGsmooth_LDFLAGS = $(plib_FRAMEWORK)
 UGsmooth_LDFLAGS = $(plib_FRAMEWORK)
 else
-GPSsmooth_PLIB_LIBS = -lplibnet -lplibul
-MIDGsmooth_PLIB_LIBS = -lplibnet -lplibul
-UGsmooth_PLIB_LIBS = -lplibnet -lplibul
+GPSsmooth_PLIB_LIBS = -lplibul
+MIDGsmooth_PLIB_LIBS = -lplibul
+UGsmooth_PLIB_LIBS = -plibul
 endif
 
 
@@ -16,7 +16,7 @@ GPSsmooth_SOURCES = \
 	gps_main.cxx
 
 GPSsmooth_LDADD = \
-        $(GPSsmooth_PLIB_LIBS) -lsgtiming -lsgmisc -lsgdebug \
+        $(GPSsmooth_PLIB_LIBS) -lsgtiming -lsgmisc -lsgdebug -lsgio \
 	$(joystick_LIBS) $(network_LIBS) $(base_LIBS) -lz
 
 MIDGsmooth_SOURCES = \

From ceabadacc2c6ef6f8c1794ee2e93c6adce35c815 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 17:58:20 +0100
Subject: [PATCH 07/26] Cmake: test the presence of FLTK

---
 utils/CMakeLists.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index dffd090db..f3caabb8b 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -1,4 +1,7 @@
 add_subdirectory(TerraSync)
 add_subdirectory(fgviewer)
 add_subdirectory(GPSsmooth)
-add_subdirectory(fgadmin)
+
+if (FLTK_FOUND)
+    add_subdirectory(fgadmin)
+endif (FLTK_FOUND)

From 9a3e22d84260ab6e0b33e80178a526a1e5e17a33 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 18:10:57 +0100
Subject: [PATCH 08/26] Trying to fix Linux compilation

---
 utils/GPSsmooth/Makefile.am | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/utils/GPSsmooth/Makefile.am b/utils/GPSsmooth/Makefile.am
index fb4127c1a..ed07353c9 100644
--- a/utils/GPSsmooth/Makefile.am
+++ b/utils/GPSsmooth/Makefile.am
@@ -5,9 +5,9 @@ GPSsmooth_LDFLAGS = $(plib_FRAMEWORK)
 MIDGsmooth_LDFLAGS = $(plib_FRAMEWORK)
 UGsmooth_LDFLAGS = $(plib_FRAMEWORK)
 else
-GPSsmooth_PLIB_LIBS = -lplibul
-MIDGsmooth_PLIB_LIBS = -lplibul
-UGsmooth_PLIB_LIBS = -plibul
+GPSsmooth_PLIB_LIBS = -lplibnet -lplibul
+MIDGsmooth_PLIB_LIBS = -lplibnet -lplibul
+UGsmooth_PLIB_LIBS = -lplibnet -lplibul
 endif
 
 
@@ -16,7 +16,7 @@ GPSsmooth_SOURCES = \
 	gps_main.cxx
 
 GPSsmooth_LDADD = \
-        $(GPSsmooth_PLIB_LIBS) -lsgtiming -lsgmisc -lsgdebug -lsgio \
+        $(GPSsmooth_PLIB_LIBS) -lsgio -lsgtiming -lsgmisc -lsgdebug \
 	$(joystick_LIBS) $(network_LIBS) $(base_LIBS) -lz
 
 MIDGsmooth_SOURCES = \

From d4c9a393d1c628c1b834ad5d436ca1b0c37d66de Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 18:24:49 +0100
Subject: [PATCH 09/26] Trying to fix Linux compilation

---
 utils/GPSsmooth/Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/utils/GPSsmooth/Makefile.am b/utils/GPSsmooth/Makefile.am
index ed07353c9..06a9330db 100644
--- a/utils/GPSsmooth/Makefile.am
+++ b/utils/GPSsmooth/Makefile.am
@@ -16,7 +16,7 @@ GPSsmooth_SOURCES = \
 	gps_main.cxx
 
 GPSsmooth_LDADD = \
-        $(GPSsmooth_PLIB_LIBS) -lsgio -lsgtiming -lsgmisc -lsgdebug \
+        $(GPSsmooth_PLIB_LIBS) -lsgio -lsgtiming -lsgmisc -lsgdebug -lsgstructure \
 	$(joystick_LIBS) $(network_LIBS) $(base_LIBS) -lz
 
 MIDGsmooth_SOURCES = \

From 6939abc9aff2def44f2b594d2a47e029b824ad5c Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 18:43:55 +0100
Subject: [PATCH 10/26] Trying to fix Linux compilation

---
 utils/GPSsmooth/Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/utils/GPSsmooth/Makefile.am b/utils/GPSsmooth/Makefile.am
index 06a9330db..b3c7ee6b4 100644
--- a/utils/GPSsmooth/Makefile.am
+++ b/utils/GPSsmooth/Makefile.am
@@ -37,7 +37,7 @@ UGsmooth_SOURCES = \
 
 UGsmooth_LDADD = \
         $(UGsmooth_PLIB_LIBS) -lsgio -lsgserial -lsgtiming \
-        -lsgmath -lsgbucket -lsgmisc -lsgdebug \
+        -lsgmath -lsgbucket -lsgmisc -lsgdebug -lsgstructure \
         $(joystick_LIBS) $(network_LIBS) $(base_LIBS) -lz
 
 INCLUDES = -I$(top_srcdir)/src

From f7c487fd4e3eb5daa8b4a24a9298ebab0d0eafe8 Mon Sep 17 00:00:00 2001
From: Dave Luff <daveluff@ntlworld.com>
Date: Wed, 5 Jan 2011 00:32:21 +0000
Subject: [PATCH 11/26] ATIS: revert to using inches globally by default.

Revert to using inches globally by default, unless the user sets the
property /sim/atc/use-millibars.  Whilst this is therefore wrong by
default, it is probably the best thing in the short term since
FlightGear's altimeter dialog and the altimeters on the default
aircraft set using inches.
---
 src/ATCDCL/atis.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ATCDCL/atis.cxx b/src/ATCDCL/atis.cxx
index 16e94f67a..53973a7a7 100644
--- a/src/ATCDCL/atis.cxx
+++ b/src/ATCDCL/atis.cxx
@@ -462,7 +462,7 @@ int FGATIS::GenTransmission(const int regen, const int special) {
   }
 
 // Convert to millibars for most of the world (not US, not CA)
-  if((!US_CA) || fgGetBool("/sim/atc/use-millibars")) {
+  if((!US_CA) && fgGetBool("/sim/atc/use-millibars")) {
     transmission += QNH + ": ";
     myQNH /= mbar;
     if  (myQNH > 1000) myQNH -= 1000;       // drop high digit

From b0a61f61101ecdd18f506393d5cd51db0a5304df Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 5 Jan 2011 23:47:08 +0100
Subject: [PATCH 12/26] Cmake: finally build terrasync under Windows

---
 utils/TerraSync/CMakeLists.txt | 3 ++-
 utils/TerraSync/terrasync.cxx  | 6 +++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt
index ae3af2f99..bedc1018d 100644
--- a/utils/TerraSync/CMakeLists.txt
+++ b/utils/TerraSync/CMakeLists.txt
@@ -5,7 +5,8 @@ add_executable(terrasync terrasync.cxx)
 
 target_link_libraries(terrasync 
 	${SIMGEAR_LIBRARIES}
-	${ZLIB_LIBRARIES})
+	${ZLIB_LIBRARIES}
+    ${WINSOCK_LIBRARY})
 
 if(HAVE_SVN_CLIENT)
 	target_link_libraries(terrasync ${SVN_CLIENT_LIBRARIES})
diff --git a/utils/TerraSync/terrasync.cxx b/utils/TerraSync/terrasync.cxx
index d48e43f77..bcf6e0ca8 100644
--- a/utils/TerraSync/terrasync.cxx
+++ b/utils/TerraSync/terrasync.cxx
@@ -33,7 +33,11 @@
 #include <time.h>
 #include <unistd.h>
 #elif defined(_MSC_VER)
-#include <io.h>
+#   include <io.h>
+#   ifndef HAVE_SVN_CLIENT_H
+#       include <time.h>
+#       include <process.h>
+#   endif
 #endif
 
 #include <stdlib.h>             // atoi() atof() abs() system()

From 45d33ef60c66330d5147842d704c0609f5623f09 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Thu, 6 Jan 2011 16:56:07 +0000
Subject: [PATCH 13/26] Make fgadmin optional (and hence, the FLTK dependency)
 Also bump SimGear version to 2.2.0

---
 CMakeLists.txt | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b8085c772..291656ed9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,7 @@ option(ENABLE_UIUC_MODEL "Set to ON to build FlightGear with UIUCModel FDM" ON)
 option(ENABLE_LARCSIM "Set to ON to build FlightGear with LaRCsim FDM" ON)
 option(ENABLE_YASIM "Set to ON to build FlightGear with YASIM FDM" ON)
 option(ENABLE_JSBSIM "Set to ON to build FlightGear with JSBSim FDM" ON)
+option(ENABLE_FGADMIN "Set to ON to build FlightGear with FGADMIN" ON)
 option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" OFF)
 set(MSVC_3RDPARTY_DIR NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
 
@@ -98,10 +99,13 @@ find_package(OpenGL REQUIRED)
 find_package(OpenAL REQUIRED)
 find_package(ALUT REQUIRED)
 find_package(OpenSceneGraph 2.8.2 REQUIRED osgText osgSim osgDB osgParticle osgFX osgUtil osgViewer osgGA)
-find_package(FLTK)
+
+if(ENABLE_FGADMIN)
+  find_package(FLTK)
+endif(ENABLE_FGADMIN)
 
 find_package(PLIB REQUIRED puaux pu js fnt)
-find_package(SimGear 2.0.0 REQUIRED)
+find_package(SimGear 2.2.0 REQUIRED)
 
 check_include_file(unistd.h HAVE_UNISTD_H)
 check_include_file(sys/time.h HAVE_SYS_TIME_H)

From 9337584df02f7856843a7b0d67eb260cf565d3fc Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Fri, 7 Jan 2011 13:11:06 +0100
Subject: [PATCH 14/26] METAR: enable reports from multiple stations

This patch enables multiple MetarProperties instances tied to the
property tree. For each node's value of /environment/realwx/metar
one MetarProperties instance is created and tied to the property
tree named there. (See FGDATA/Environment/environment.xml for details)

At least one instance will be created to provice backward compatibility
to the existing live-data weather system. This instance (tied to
/environment/metar) fetches a METAR for the nearest airport at a regular
schedule. All other instances fetch a report for airports named in the
property station-id. It re-reads the report every 15 minutes, the
remaining time until the next fetch will be scheduled is in the property
time-to-live. This property can be written to, to extend the live of
this report or schedule an immediate reload by setting it's value to zero.

This patch also provides magnetic variation for the station's location.
---
 src/Environment/metarproperties.cxx |  92 ++++++++++++-
 src/Environment/metarproperties.hxx |  17 ++-
 src/Environment/realwx_ctrl.cxx     | 203 ++++++++++++++++++++--------
 3 files changed, 256 insertions(+), 56 deletions(-)

diff --git a/src/Environment/metarproperties.cxx b/src/Environment/metarproperties.cxx
index 9582c9ee6..63071d02c 100644
--- a/src/Environment/metarproperties.cxx
+++ b/src/Environment/metarproperties.cxx
@@ -31,6 +31,9 @@
 #include "metarairportfilter.hxx"
 #include <simgear/scene/sky/cloud.hxx>
 #include <simgear/structure/exception.hxx>
+#include <simgear/misc/strutils.hxx>
+#include <simgear/magvar/magvar.hxx>
+#include <simgear/timing/sg_time.hxx>
 #include <Main/fg_props.hxx>
 
 using std::string;
@@ -39,6 +42,72 @@ namespace Environment {
 
 static vector<string> coverage_string;
 
+/**
+ * @brief Helper class to wrap SGMagVar functionality and cache the variation and dip for
+ *        a certain position. 
+ */
+class MagneticVariation : public SGMagVar {
+public:
+  /**
+   * Constructor
+   */
+  MagneticVariation() : _lat(1), _lon(1), _alt(1) {
+    recalc( 0.0, 0.0, 0.0 );
+  }
+
+  /**
+   * @brief get the magnetic variation for a specific position at the current time
+   * @param lon the positions longitude in degrees
+   * @param lat the positions latitude in degrees
+   * @param alt the positions height above MSL (aka altitude) in feet
+   * @return the magnetic variation in degrees
+   */
+  double get_variation_deg( double lon, double lat, double alt );
+
+  /**
+   * @brief get the magnetic dip for a specific position at the current time
+   * @param lon the positions longitude in degrees
+   * @param lat the positions latitude in degrees
+   * @param alt the positions height above MSL (aka altitude) in feet
+   * @return the magnetic dip in degrees
+   */
+  double get_dip_deg( double lon, double lat, double alt );
+private:
+  void recalc( double lon, double lat, double alt );
+  SGTime _time;
+  double _lat, _lon, _alt;
+};
+
+inline void MagneticVariation::recalc( double lon, double lat, double alt )
+{
+  // calculation of magnetic variation is expensive. Cache the position
+  // and perform this calculation only if it has changed
+  if( _lon != lon || _lat != lat || _alt != alt ) {
+    SG_LOG(SG_ALL, SG_DEBUG, "Recalculating magvar for lon=" << lon << ", lat=" << lat << ", alt=" << alt );
+    _lon = lon;
+    _lat = lat;
+    _alt = alt;
+
+    lon *= SGD_DEGREES_TO_RADIANS;
+    lat *= SGD_DEGREES_TO_RADIANS;
+    alt *= SG_FEET_TO_METER;
+   _time.update( lon, lat, 0, 0 );
+    update( lon, lat, alt, _time.getJD() );
+  }
+}
+
+inline double MagneticVariation::get_variation_deg( double lon, double lat, double alt )
+{
+  recalc( lon, lat, alt );
+  return get_magvar() * SGD_RADIANS_TO_DEGREES;
+}
+
+inline double MagneticVariation::get_dip_deg( double lon, double lat, double alt )
+{
+  recalc( lon, lat, alt );
+  return get_magdip() * SGD_RADIANS_TO_DEGREES;
+}
+
 MetarProperties::MetarProperties( SGPropertyNode_ptr rootNode ) :
   _rootNode(rootNode),
   _metarValidNode( rootNode->getNode( "valid", true ) ),
@@ -64,7 +133,8 @@ MetarProperties::MetarProperties( SGPropertyNode_ptr rootNode ) :
   _rain(0.0),
   _hail(0.0),
   _snow(0.0),
-  _snow_cover(false)
+  _snow_cover(false),
+  _magneticVariation(new MagneticVariation())
 {
   // Hack to avoid static initialization order problems on OSX
   if( coverage_string.size() == 0 ) {
@@ -78,10 +148,12 @@ MetarProperties::MetarProperties( SGPropertyNode_ptr rootNode ) :
   _metarValidNode->setBoolValue( false );
   _tiedProperties.setRoot( _rootNode );
   _tiedProperties.Tie("data", this, &MetarProperties::get_metar, &MetarProperties::set_metar );
-  _tiedProperties.Tie("station-id", this, &MetarProperties::get_station_id );
+  _tiedProperties.Tie("station-id", this, &MetarProperties::get_station_id, &MetarProperties::set_station_id );
   _tiedProperties.Tie("station-elevation-ft", &_station_elevation );
   _tiedProperties.Tie("station-latitude-deg", &_station_latitude );
   _tiedProperties.Tie("station-longitude-deg", &_station_longitude );
+  _tiedProperties.Tie("station-magnetic-variation-deg", this, &MetarProperties::get_magnetic_variation_deg );
+  _tiedProperties.Tie("station-magnetic-dip-deg", this, &MetarProperties::get_magnetic_dip_deg );
   _tiedProperties.Tie("min-visibility-m", &_min_visibility );
   _tiedProperties.Tie("max-visibility-m", &_max_visibility );
   _tiedProperties.Tie("base-wind-range-from", &_base_wind_range_from );
@@ -107,6 +179,7 @@ MetarProperties::MetarProperties( SGPropertyNode_ptr rootNode ) :
 
 MetarProperties::~MetarProperties()
 {
+  delete _magneticVariation;
 }
 
 
@@ -320,4 +393,19 @@ void MetarProperties::set_metar( const char * metar )
     _metarValidNode->setBoolValue(true);
 }
 
+void MetarProperties::setStationId( const std::string & value )
+{ 
+    set_station_id(simgear::strutils::strip(value).c_str());
+}
+
+double MetarProperties::get_magnetic_variation_deg() const 
+{
+  return _magneticVariation->get_variation_deg( _station_longitude, _station_latitude, _station_elevation );
+}
+
+double MetarProperties::get_magnetic_dip_deg() const
+{
+  return _magneticVariation->get_dip_deg( _station_longitude, _station_latitude, _station_elevation );
+}
+
 } // namespace Environment
diff --git a/src/Environment/metarproperties.hxx b/src/Environment/metarproperties.hxx
index 221219f98..bec445b15 100644
--- a/src/Environment/metarproperties.hxx
+++ b/src/Environment/metarproperties.hxx
@@ -29,6 +29,8 @@
 
 namespace Environment {
 
+class MagneticVariation;
+
 class MetarProperties : public SGReferenced
 {
 public:
@@ -36,12 +38,19 @@ public:
     virtual ~MetarProperties();
 
     SGPropertyNode_ptr get_root_node() const { return _rootNode; }
+    virtual bool isValid() const { return _metarValidNode->getBoolValue(); }
+    virtual const std::string & getStationId() const { return _station_id; }
+    virtual void setStationId( const std::string & value );
+    virtual void setMetar( const std::string & value ) { set_metar( value.c_str() ); }
 
 private:
     const char * get_metar() const { return _metar.c_str(); }
     void set_metar( const char * metar );
     const char * get_station_id() const { return _station_id.c_str(); }
+    void set_station_id( const char * value );
     const char * get_decoded() const { return _decoded.c_str(); }
+    double get_magnetic_variation_deg() const;
+    double get_magnetic_dip_deg() const;
 
     SGPropertyNode_ptr _rootNode;
     SGPropertyNode_ptr _metarValidNode;
@@ -71,9 +80,15 @@ private:
     double _snow;
     bool _snow_cover;
     std::string _decoded;
-
+protected:
     TiedPropertyList _tiedProperties;
+    MagneticVariation * _magneticVariation;
 };
 
+inline void MetarProperties::set_station_id( const char * value )
+{ 
+    _station_id = value; 
+}
+
 } // namespace
 #endif // __METARPROPERTIES_HXX
diff --git a/src/Environment/realwx_ctrl.cxx b/src/Environment/realwx_ctrl.cxx
index cd315eea5..a547ef7e5 100644
--- a/src/Environment/realwx_ctrl.cxx
+++ b/src/Environment/realwx_ctrl.cxx
@@ -43,6 +43,42 @@
 
 namespace Environment {
 
+/* -------------------------------------------------------------------------------- */
+
+class LiveMetarProperties : public MetarProperties {
+public:
+    LiveMetarProperties( SGPropertyNode_ptr rootNode );
+    virtual ~LiveMetarProperties();
+    virtual void update( double dt );
+
+    virtual double getTimeToLive() const { return _timeToLive; }
+    virtual void setTimeToLive( double value ) { _timeToLive = value; }
+private:
+    double _timeToLive;
+
+};
+
+typedef SGSharedPtr<LiveMetarProperties> LiveMetarProperties_ptr;
+
+LiveMetarProperties::LiveMetarProperties( SGPropertyNode_ptr rootNode ) :
+    MetarProperties( rootNode ),
+    _timeToLive(0.0)
+{
+    _tiedProperties.Tie("time-to-live", &_timeToLive );
+}
+
+LiveMetarProperties::~LiveMetarProperties()
+{
+}
+
+void LiveMetarProperties::update( double dt )
+{
+    _timeToLive -= dt;
+    if( _timeToLive < 0.0 ) _timeToLive = 0.0;
+}
+
+/* -------------------------------------------------------------------------------- */
+
 class BasicRealWxController : public RealWxController
 {
 public:
@@ -70,7 +106,8 @@ protected:
     bool _enabled;
     bool __enabled;
     TiedPropertyList _tiedProperties;
-    MetarProperties  _metarProperties;
+ ;   typedef std::vector<LiveMetarProperties_ptr> MetarPropertiesList;
+    MetarPropertiesList _metarProperties;
 };
 
 /* -------------------------------------------------------------------------------- */
@@ -87,9 +124,18 @@ BasicRealWxController::BasicRealWxController( SGPropertyNode_ptr rootNode ) :
   _ground_elevation_n( fgGetNode( "/position/ground-elev-m", true )),
   _max_age_n( fgGetNode( "/environment/params/metar-max-age-min", false ) ),
   _enabled(true),
-  __enabled(false),
-  _metarProperties( fgGetNode( rootNode->getStringValue("metar", "/environment/metar"), true ) )
+  __enabled(false)
 {
+    // at least instantiate MetarProperties for /environment/metar
+    _metarProperties.push_back( new LiveMetarProperties( 
+            fgGetNode( rootNode->getStringValue("metar", "/environment/metar"), true ) ) );
+
+    PropertyList metars = rootNode->getChildren("metar");
+    for( PropertyList::size_type i = 1; i < metars.size(); i++ ) {
+       SG_LOG( SG_ALL, SG_INFO, "Adding metar properties at " << metars[i]->getStringValue() );
+        _metarProperties.push_back( new LiveMetarProperties( 
+            fgGetNode( metars[i]->getStringValue(), true )));
+    }
 }
 
 BasicRealWxController::~BasicRealWxController()
@@ -121,7 +167,17 @@ void BasicRealWxController::unbind()
 void BasicRealWxController::update( double dt )
 {
   if( _enabled ) {
-    update( !__enabled, dt );
+    bool firstIteration = !__enabled; // first iteration after being enabled?
+
+    // clock tick for every METAR in stock
+    for( MetarPropertiesList::iterator it = _metarProperties.begin();
+          it != _metarProperties.end(); it++ ) {
+      // first round? All received METARs are outdated
+      if( firstIteration ) (*it)->setTimeToLive( 0.0 );
+      (*it)->update(dt);
+    }
+
+    update( firstIteration, dt );
     __enabled = true;
   } else {
     __enabled = false;
@@ -144,21 +200,35 @@ public:
             _proxyPort = fgGetNode("/sim/presets/proxy/port", true)->getStringValue();
             _proxyAuth = fgGetNode("/sim/presets/proxy/authentication", true)->getStringValue();
         }
+        MetarLoadRequest( const MetarLoadRequest & other ) {
+            _stationId = other._stationId;
+            _proxyHost = other._proxyAuth;
+            _proxyPort = other._proxyPort;
+            _proxyAuth = other._proxyAuth;
+        }
         string _stationId;
         string _proxyHost;
         string _proxyPort;
         string _proxyAuth;
     private:
     };
-private:
-    double _metarTimeToLive;
-    double _positionTimeToLive;
-    double _minimumRequestInterval;
-    
-    SGPropertyNode_ptr _metarDataNode;
-    SGPropertyNode_ptr _metarValidNode;
-    SGPropertyNode_ptr _metarStationIdNode;
 
+    class MetarLoadResponse {
+    public:
+        MetarLoadResponse( const string & stationId, const string metar ) {
+            _stationId = stationId;
+            _metar = metar;
+        }
+        MetarLoadResponse( const MetarLoadResponse & other ) {
+            _stationId = other._stationId;
+            _metar = other._metar;
+        }
+        string _stationId;
+        string _metar;
+    };
+private:
+    double _positionTimeToLive;
+    double _requestTimer;
 
 #if defined(ENABLE_THREADS)
      class MetarLoadThread : public OpenThreads::Thread {
@@ -166,13 +236,14 @@ private:
         MetarLoadThread( long maxAge );
         void requestMetar( const MetarLoadRequest & metarRequest, bool background = true );
         bool hasMetar() { return _responseQueue.size() > 0; }
-        string getMetar() { return _responseQueue.pop(); }
+        MetarLoadResponse getMetar() { return _responseQueue.pop(); }
         virtual void run();
      private:
         void fetch( const MetarLoadRequest & );
         long _maxAge;
+        long _minRequestInterval;
         SGBlockingQueue <MetarLoadRequest> _requestQueue;
-        SGBlockingQueue <string> _responseQueue;
+        SGBlockingQueue <MetarLoadResponse> _responseQueue;
      };
 
      MetarLoadThread * _metarLoadThread;
@@ -181,12 +252,8 @@ private:
 
 NoaaMetarRealWxController::NoaaMetarRealWxController( SGPropertyNode_ptr rootNode ) :
   BasicRealWxController(rootNode),
-  _metarTimeToLive(0.0),
   _positionTimeToLive(0.0),
-  _minimumRequestInterval(0.0),
-  _metarDataNode(_metarProperties.get_root_node()->getNode("data",true)),
-  _metarValidNode(_metarProperties.get_root_node()->getNode("valid",true)),
-  _metarStationIdNode(_metarProperties.get_root_node()->getNode("station-id",true))
+  _requestTimer(0.0)
 {
 #if defined(ENABLE_THREADS)
     _metarLoadThread = new MetarLoadThread(getMetarMaxAgeMin());
@@ -208,22 +275,12 @@ NoaaMetarRealWxController::~NoaaMetarRealWxController()
 
 void NoaaMetarRealWxController::update( bool first, double dt )
 {
-    _metarTimeToLive -= dt;
     _positionTimeToLive -= dt;
-    _minimumRequestInterval -= dt;
+    _requestTimer -= dt;
 
-    bool valid = _metarValidNode->getBoolValue();
-    string stationId = valid ? _metarStationIdNode->getStringValue() : "";
-
-    if( first ) _metarTimeToLive = 0.0;
-
-    if( _metarTimeToLive <= 0.0 ) {
-        valid = false;
-        _metarTimeToLive = 900;
-        _positionTimeToLive = 0;
-    }
-
-    if( _positionTimeToLive <= 0.0 || valid == false ) {
+    if( _positionTimeToLive <= 0.0 ) {
+        // check nearest airport
+        SG_LOG(SG_ALL, SG_INFO, "NoaaMetarRealWxController::update(): (re) checking nearby airport with METAR" );
         _positionTimeToLive = 60.0;
 
         SGGeod pos = SGGeod::fromDeg(_longitude_n->getDoubleValue(), _latitude_n->getDoubleValue());
@@ -234,38 +291,64 @@ void NoaaMetarRealWxController::update( bool first, double dt )
             return;
         }
 
-        if( stationId != nearestAirport->ident() ) {
-            valid = false;
-            stationId = nearestAirport->ident();
+        SG_LOG(SG_ALL, SG_INFO, 
+            "NoaaMetarRealWxController::update(): nearest airport with METAR is: " << nearestAirport->ident() );
+
+        // if it has changed, invalidate the associated METAR
+        if( _metarProperties[0]->getStationId() != nearestAirport->ident() ) {
+            SG_LOG(SG_ALL, SG_INFO, 
+                "NoaaMetarRealWxController::update(): nearest airport with METAR has changed. Old: '" << 
+                _metarProperties[0]->getStationId() <<
+                "', new: '" << nearestAirport->ident() << "'" );
+            _metarProperties[0]->setStationId( nearestAirport->ident() );
+            _metarProperties[0]->setTimeToLive( 0.0 );
         }
-
     }
+  
+    if( _requestTimer <= 0.0 ) {
+        _requestTimer = 10.0;
 
-    if( !valid ) {
-        if( _minimumRequestInterval <= 0 && stationId.length() > 0 ) {
-            MetarLoadRequest request( stationId );
-            // load the first metar in the foreground to make sure a metar is received
-            // before the automatic runway selection code runs. All subsequent calls
-            // run in the background
-            _metarLoadThread->requestMetar( request, !first );
-            _minimumRequestInterval = 10;
+        for( MetarPropertiesList::iterator it = _metarProperties.begin(); 
+            it != _metarProperties.end(); it++ ) {
+
+                if( (*it)->getTimeToLive() > 0.0 ) continue;
+                const std::string & stationId = (*it)->getStationId();
+                if( stationId.empty() ) continue;
+
+                SG_LOG(SG_ALL, SG_INFO, 
+                    "NoaaMetarRealWxController::update(): spawning load request for station-id '" << stationId << "'" );
+            
+                MetarLoadRequest request( stationId );
+                // load the metar for the neares airport in the foreground if the fdm is uninitialized
+                // to make sure a metar is received
+                // before the automatic runway selection code runs. All subsequent calls
+                // run in the background
+                bool background = fgGetBool("/sim/fdm-initialized", false ) || it != _metarProperties.begin();
+                _metarLoadThread->requestMetar( request, background );
         }
     }
 
-    if( _metarLoadThread->hasMetar() ) {
-        string metar = _metarLoadThread->getMetar();
-        SG_LOG( SG_ALL, SG_ALERT, "NoaaMetarRwalWxController::update() received METAR " << metar );
-        _metarDataNode->setStringValue( metar );
+    // pick all the received responses from the result queue and update the associated
+    // property tree
+    while( _metarLoadThread->hasMetar() ) {
+        MetarLoadResponse metar = _metarLoadThread->getMetar();
+        SG_LOG( SG_ALL, SG_INFO, "NoaaMetarRwalWxController::update() received METAR for " << metar._stationId << ": " << metar._metar );
+        for( MetarPropertiesList::iterator it = _metarProperties.begin(); 
+            it != _metarProperties.end(); it++ ) {
+                if( (*it)->getStationId() != metar._stationId )
+                    continue;
+                (*it)->setTimeToLive(900);
+                (*it)->setMetar( metar._metar );
+        }
     }
-
-
 }
 
 /* -------------------------------------------------------------------------------- */
 
 #if defined(ENABLE_THREADS)
 NoaaMetarRealWxController::MetarLoadThread::MetarLoadThread( long maxAge ) :
-  _maxAge(maxAge)
+  _maxAge(maxAge),
+  _minRequestInterval(2000)
 {
 }
 
@@ -287,13 +370,22 @@ void NoaaMetarRealWxController::MetarLoadThread::requestMetar( const MetarLoadRe
 
 void NoaaMetarRealWxController::MetarLoadThread::run()
 {
+    SGTimeStamp lastRun = SGTimeStamp::fromSec(0);
     for( ;; ) {
+        SGTimeStamp dt = SGTimeStamp::now() - lastRun;
+
+        if( dt.getSeconds() * 1000 < _minRequestInterval )
+            microSleep( (_minRequestInterval - dt.getSeconds() * 1000 ) * 1000 );
+        
+        lastRun = SGTimeStamp::now();
+
         const MetarLoadRequest request = _requestQueue.pop();
 
         if( request._stationId.size() == 0 )
             break;
 
         fetch( request );
+
     }
 }
 
@@ -303,9 +395,13 @@ void NoaaMetarRealWxController::MetarLoadThread::fetch( const MetarLoadRequest &
 
     try {
         result = new FGMetar( request._stationId, request._proxyHost, request._proxyPort, request._proxyAuth );
+        _minRequestInterval = 2000;
     } catch (const sg_io_exception& e) {
         SG_LOG( SG_GENERAL, SG_WARN, "NoaaMetarRealWxController::fetchMetar(): can't get METAR for " 
                                     << request._stationId << ":" << e.getFormattedMessage().c_str() );
+        _minRequestInterval += _minRequestInterval/2; 
+        if( _minRequestInterval > 30000 )
+            _minRequestInterval = 30000;
         return;
     }
 
@@ -325,7 +421,8 @@ void NoaaMetarRealWxController::MetarLoadThread::fetch( const MetarLoadRequest &
         return;
     }
 
-    _responseQueue.push( metar );
+    MetarLoadResponse response( request._stationId, metar );
+    _responseQueue.push( response );
 }
 #endif
 

From 7fb8114feb83032d39b440910fd915853841c62e Mon Sep 17 00:00:00 2001
From: "Curtis L. Olson" <curtolson@gmail.com>
Date: Fri, 7 Jan 2011 13:05:47 -0600
Subject: [PATCH 15/26] Add code to draw AI ships on the map widget (useful for
 carrier ops.)

An AI Tanker requested from the AI menu has an id of -2, so change the code to
only ignore AI models with an ID of -1.
---
 src/GUI/MapWidget.cxx | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/GUI/MapWidget.cxx b/src/GUI/MapWidget.cxx
index fd02ebe0b..0b786f5a3 100644
--- a/src/GUI/MapWidget.cxx
+++ b/src/GUI/MapWidget.cxx
@@ -1318,7 +1318,7 @@ void MapWidget::drawTraffic()
   for (int i = 0; i < ai->nChildren(); ++i) {
     const SGPropertyNode *model = ai->getChild(i);
     // skip bad or dead entries
-    if (!model || model->getIntValue("id", -1) < 0) {
+    if (!model || model->getIntValue("id", -1) == -1) {
       continue;
     }
 
@@ -1392,7 +1392,47 @@ void MapWidget::drawAIAircraft(const SGPropertyNode* model, const SGGeod& pos, d
 
 void MapWidget::drawAIShip(const SGPropertyNode* model, const SGGeod& pos, double hdg)
 {
+  SGVec2d p = project(pos);
 
+  glColor3f(0.0, 0.0, 0.0);
+  glLineWidth(2.0);
+  circleAt(p, 4, 6.0); // black diamond
+  
+// draw heading vector
+  int speedKts = static_cast<int>(model->getDoubleValue("velocities/true-airspeed-kt"));
+  if (speedKts > 1) {
+    glLineWidth(1.0);
+
+    const double dt = 15.0 / (3600.0); // 15 seconds look-ahead
+    double distanceM = speedKts * SG_NM_TO_METER * dt;
+    
+    SGGeod advance;
+    double az2;
+    SGGeodesy::direct(pos, hdg, distanceM, advance, az2);
+    
+    drawLine(p, project(advance));
+  }
+    
+  if (validDataForKey((void*) model)) {
+    setAnchorForKey((void*) model, p);
+    return;
+  }
+  
+  // draw callsign / altitude / speed
+
+  
+  char buffer[1024];
+	::snprintf(buffer, 1024, "%s\n%d'\n%dkts",
+		model->getStringValue("callsign", "<>"),
+		static_cast<int>(pos.getElevationFt() / 50.0) * 50,
+    speedKts);
+	
+  MapData* d = createDataForKey((void*) model);
+  d->setText(buffer);
+  d->setLabel(model->getStringValue("callsign", "<>"));
+  d->setPriority(speedKts > 5 ? 60 : 10); // low priority for parked aircraft
+  d->setOffset(MapData::VALIGN_CENTER | MapData::HALIGN_LEFT, 10);
+  d->setAnchor(p);
 }
 
 SGVec2d MapWidget::project(const SGGeod& geod) const

From 0361f136fe5c81576bc426d218f4dec2366ea086 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Fri, 7 Jan 2011 21:05:17 +0100
Subject: [PATCH 16/26] MouseInput: Add accel-x and accel-y

Syd Adams:
Is there any interest in mouse acceleration properties, besides myself ?

Obviously there is. Some code cleanup comes with it.
---
 src/Input/FGMouseInput.cxx | 46 ++++++++++++++++++++++++--------------
 src/Input/FGMouseInput.hxx |  7 ++++++
 2 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/src/Input/FGMouseInput.cxx b/src/Input/FGMouseInput.cxx
index 16bb7883e..5d3f7ae2a 100644
--- a/src/Input/FGMouseInput.cxx
+++ b/src/Input/FGMouseInput.cxx
@@ -74,7 +74,13 @@ const FGMouseInput::MouseCursorMap FGMouseInput::mouse_cursor_map[] = {
 
 FGMouseInput * FGMouseInput::mouseInput = NULL;
 
-FGMouseInput::FGMouseInput()
+FGMouseInput::FGMouseInput() :
+  xSizeNode(fgGetNode("/sim/startup/xsize", false ) ),
+  ySizeNode(fgGetNode("/sim/startup/ysize", false ) ),
+  xAccelNode(fgGetNode("/devices/status/mice/mouse/accel-x", true ) ),
+  yAccelNode(fgGetNode("/devices/status/mice/mouse/accel-y", true ) ),
+  hideCursorNode(fgGetNode("/sim/mouse/hide-cursor", true ) ),
+  cursorTimeoutNode(fgGetNode("/sim/mouse/cursor-timeout-sec", true ) )
 {
   if( mouseInput == NULL )
     mouseInput = this;
@@ -103,16 +109,17 @@ void FGMouseInput::init()
     mouse &m = bindings[i];
 
                                 // Grab node pointers
-    char buf[64];
-    sprintf(buf, "/devices/status/mice/mouse[%d]/mode", i);
-    m.mode_node = fgGetNode(buf);
+    std::ostringstream buf;
+    buf <<  "/devices/status/mice/mouse[" << i << "]/mode";
+    m.mode_node = fgGetNode(buf.str().c_str());
     if (m.mode_node == NULL) {
-      m.mode_node = fgGetNode(buf, true);
+      m.mode_node = fgGetNode(buf.str().c_str(), true);
       m.mode_node->setIntValue(0);
     }
     for (j = 0; j < MAX_MOUSE_BUTTONS; j++) {
-      sprintf(buf, "/devices/status/mice/mouse[%d]/button[%d]", i, j);
-      m.mouse_button_nodes[j] = fgGetNode(buf, true);
+      buf.clear();
+      buf << "/devices/status/mice/mouse["<< i << "]/button[" << j << "]";
+      m.mouse_button_nodes[j] = fgGetNode(buf.str().c_str(), true);
       m.mouse_button_nodes[j]->setBoolValue(false);
     }
 
@@ -141,11 +148,12 @@ void FGMouseInput::init()
 
                                 // Read the button bindings for this mode
       m.modes[j].buttons = new FGButton[MAX_MOUSE_BUTTONS];
-      char buf[32];
+      std::ostringstream buf;
       for (k = 0; k < MAX_MOUSE_BUTTONS; k++) {
-        sprintf(buf, "mouse button %d", k);
+        buf.clear();
+        buf << "mouse button " << k;
         SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse button " << k);
-        m.modes[j].buttons[k].init( mode_node->getChild("button", k), buf, module );
+        m.modes[j].buttons[k].init( mode_node->getChild("button", k), buf.str(), module );
       }
 
                                 // Read the axis bindings for this mode
@@ -160,15 +168,17 @@ void FGMouseInput::init()
 
 void FGMouseInput::update ( double dt )
 {
+  double cursorTimeout = cursorTimeoutNode ? cursorTimeoutNode->getDoubleValue() : 10.0;
+
   mouse &m = bindings[0];
   int mode =  m.mode_node->getIntValue();
   if (mode != m.current_mode) {
     m.current_mode = mode;
-    m.timeout = fgGetDouble( "/sim/mouse/cursor-timeout-sec", 10.0 );
+    m.timeout = cursorTimeout;
     if (mode >= 0 && mode < m.nModes) {
       fgSetMouseCursor(m.modes[mode].cursor);
-      m.x = fgGetInt("/sim/startup/xsize", 800) / 2;
-      m.y = fgGetInt("/sim/startup/ysize", 600) / 2;
+      m.x = (xSizeNode ? xSizeNode->getIntValue() : 800) / 2;
+      m.y = (ySizeNode ? ySizeNode->getIntValue() : 600) / 2;
       fgWarpMouse(m.x, m.y);
     } else {
       SG_LOG(SG_INPUT, SG_DEBUG, "Mouse mode " << mode << " out of range");
@@ -176,9 +186,9 @@ void FGMouseInput::update ( double dt )
     }
   }
 
-  if ( fgGetBool( "/sim/mouse/hide-cursor", true ) ) {
+  if ( hideCursorNode ==NULL || hideCursorNode->getBoolValue() ) {
       if ( m.x != m.save_x || m.y != m.save_y ) {
-          m.timeout = fgGetDouble( "/sim/mouse/cursor-timeout-sec", 10.0 );
+          m.timeout = cursorTimeout;
           if (fgGetMouseCursor() == MOUSE_CURSOR_NONE)
               fgSetMouseCursor(m.modes[mode].cursor);
       } else {
@@ -292,8 +302,8 @@ void FGMouseInput::doMouseMotion (int x, int y)
   // callback.  Glut doesn't.
   int modifiers = KEYMOD_NONE;
 
-  int xsize = fgGetInt("/sim/startup/xsize", 800);
-  int ysize = fgGetInt("/sim/startup/ysize", 600);
+  int xsize = xSizeNode ? xSizeNode->getIntValue() : 800;
+  int ysize = ySizeNode ? ySizeNode->getIntValue() : 600;
 
   mouse &m = bindings[0];
 
@@ -316,11 +326,13 @@ void FGMouseInput::doMouseMotion (int x, int y)
                                 // so we can play with it.
   if (x != m.x) {
     int delta = x - m.x;
+    xAccelNode->setIntValue( delta );
     for (unsigned int i = 0; i < mode.x_bindings[modifiers].size(); i++)
       mode.x_bindings[modifiers][i]->fire(double(delta), double(xsize));
   }
   if (y != m.y) {
     int delta = y - m.y;
+    yAccelNode->setIntValue( delta );
     for (unsigned int i = 0; i < mode.y_bindings[modifiers].size(); i++)
       mode.y_bindings[modifiers][i]->fire(double(delta), double(ysize));
   }
diff --git a/src/Input/FGMouseInput.hxx b/src/Input/FGMouseInput.hxx
index 7e1d5abb2..5145c513b 100644
--- a/src/Input/FGMouseInput.hxx
+++ b/src/Input/FGMouseInput.hxx
@@ -118,6 +118,13 @@ private:
   } mouse_cursor_map[];
 
   mouse bindings[MAX_MICE];
+
+  SGPropertyNode_ptr xSizeNode;
+  SGPropertyNode_ptr ySizeNode;
+  SGPropertyNode_ptr xAccelNode;
+  SGPropertyNode_ptr yAccelNode;
+  SGPropertyNode_ptr hideCursorNode;
+  SGPropertyNode_ptr cursorTimeoutNode;
 };
 
 #endif

From 8a08507282941e6dd6dfccf63e3356f87e6d0114 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Sat, 8 Jan 2011 09:11:46 +0100
Subject: [PATCH 17/26] MouseInput: invert y-accel property

Syd Adams:  It could be inverted with nasal for use,
but it feels more natural with positive /forward , negative /
back.
---
 src/Input/FGMouseInput.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Input/FGMouseInput.cxx b/src/Input/FGMouseInput.cxx
index 5d3f7ae2a..b171e021b 100644
--- a/src/Input/FGMouseInput.cxx
+++ b/src/Input/FGMouseInput.cxx
@@ -332,7 +332,7 @@ void FGMouseInput::doMouseMotion (int x, int y)
   }
   if (y != m.y) {
     int delta = y - m.y;
-    yAccelNode->setIntValue( delta );
+    yAccelNode->setIntValue( -delta );
     for (unsigned int i = 0; i < mode.y_bindings[modifiers].size(); i++)
       mode.y_bindings[modifiers][i]->fire(double(delta), double(ysize));
   }

From 8cab5f9e60be3f0dbdb1fe18e5c475f5eb94a9cf Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Sat, 8 Jan 2011 12:50:55 +0100
Subject: [PATCH 18/26] Make mouse buttons work again.

---
 src/Input/FGMouseInput.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Input/FGMouseInput.cxx b/src/Input/FGMouseInput.cxx
index b171e021b..8ab430653 100644
--- a/src/Input/FGMouseInput.cxx
+++ b/src/Input/FGMouseInput.cxx
@@ -117,7 +117,7 @@ void FGMouseInput::init()
       m.mode_node->setIntValue(0);
     }
     for (j = 0; j < MAX_MOUSE_BUTTONS; j++) {
-      buf.clear();
+      buf.seekp(ios_base::beg);
       buf << "/devices/status/mice/mouse["<< i << "]/button[" << j << "]";
       m.mouse_button_nodes[j] = fgGetNode(buf.str().c_str(), true);
       m.mouse_button_nodes[j]->setBoolValue(false);
@@ -150,7 +150,7 @@ void FGMouseInput::init()
       m.modes[j].buttons = new FGButton[MAX_MOUSE_BUTTONS];
       std::ostringstream buf;
       for (k = 0; k < MAX_MOUSE_BUTTONS; k++) {
-        buf.clear();
+        buf.seekp(ios_base::beg);
         buf << "mouse button " << k;
         SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse button " << k);
         m.modes[j].buttons[k].init( mode_node->getChild("button", k), buf.str(), module );

From 311925ecb4df84ce0579f3bceb4b52e456ccb5da Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sat, 8 Jan 2011 15:02:30 +0100
Subject: [PATCH 19/26] Cmake: use debug version of simgear when building in
 debug mode

---
 CMakeModules/FindSimGear.cmake | 38 ++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake
index 71ce82e09..b17a4cb7f 100644
--- a/CMakeModules/FindSimGear.cmake
+++ b/CMakeModules/FindSimGear.cmake
@@ -33,6 +33,8 @@
 # People will have to manually change the cache values of 
 # SimGear_LIBRARIES to override this selection or set the CMake environment
 # CMAKE_INCLUDE_PATH to modify the search paths.
+    
+include(SelectLibraryConfigurations)
 
 FIND_PATH(SIMGEAR_INCLUDE_DIR simgear/math/SGMath.hxx
   HINTS $ENV{SIMGEAR_DIR}
@@ -63,10 +65,11 @@ FIND_LIBRARY(SIMGEAR_LIBRARIES
 
 macro(find_sg_component comp libs)
     set(compLib "sg${comp}")
-    string(TOUPPER "SIMGEAR_${comp}_LIBRARY" compLibName)
-    
-    FIND_LIBRARY(${compLibName}
-      NAMES ${compLib}
+    string(TOUPPER "SIMGEAR_${comp}" compLibBase)
+    set( compLibName ${compLibBase}_LIBRARY )
+
+    FIND_LIBRARY(${compLibName}_DEBUG
+      NAMES ${compLib}${CMAKE_DEBUG_POSTFIX}
       HINTS $ENV{SIMGEAR_DIR}
       PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
       PATHS
@@ -74,11 +77,28 @@ macro(find_sg_component comp libs)
       /usr
       /opt
     )
-    
-    set(componentLib ${${compLibName}})
-    if (NOT ${componentLib} STREQUAL "componentLib-NOTFOUND")
-        #message(STATUS "found ${componentLib}")
-        list(APPEND ${libs} ${componentLib})
+    FIND_LIBRARY(${compLibName}_RELEASE
+      NAMES ${compLib}${CMAKE_RELEASE_POSTFIX}
+      HINTS $ENV{SIMGEAR_DIR}
+      PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
+      PATHS
+      /usr/local
+      /usr
+      /opt
+    )
+    select_library_configurations( ${compLibBase} )
+
+    set(componentLibRelease ${${compLibName}_RELEASE})
+    message(STATUS "Simgear ${compLibName}_RELEASE ${componentLibRelease}")
+    set(componentLibDebug ${${compLibName}_DEBUG})
+    message(STATUS "Simgear ${compLibName}_DEBUG ${componentLibDebug}")
+    if (NOT ${compLibName}_DEBUG)
+        if (NOT ${compLibName}_RELEASE)
+            #message(STATUS "found ${componentLib}")
+            list(APPEND ${libs} ${componentLibRelease})
+        endif()
+    else()
+        list(APPEND ${libs} optimized ${componentLibRelease} debug ${componentLibDebug})
     endif()
 endmacro()
 

From 39ecaf0ca8304bd953853b5f1cc13c53e93bbe42 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sat, 8 Jan 2011 15:17:49 +0100
Subject: [PATCH 20/26] Cmake: use debug version of plib when building in debug
 mode

---
 CMakeModules/FindPLIB.cmake    | 39 ++++++++++++++++++++++++++--------
 CMakeModules/FindSimGear.cmake |  6 +++---
 2 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/CMakeModules/FindPLIB.cmake b/CMakeModules/FindPLIB.cmake
index 09188948f..1fe81b200 100644
--- a/CMakeModules/FindPLIB.cmake
+++ b/CMakeModules/FindPLIB.cmake
@@ -34,6 +34,8 @@
 # OPENAL_LIBRARY to override this selection or set the CMake environment
 # CMAKE_INCLUDE_PATH to modify the search paths.
 
+include(SelectLibraryConfigurations)
+
 set(save_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
 set(CMAKE_FIND_FRAMEWORK ONLY)
 FIND_PATH(PLIB_INCLUDE_DIR ul.h
@@ -82,21 +84,40 @@ macro(find_static_component comp libs)
       set(compLib "plib${comp}")
     endif(MSVC)
     
-    string(TOUPPER "PLIB_${comp}_LIBRARY" compLibName)
-    
-    FIND_LIBRARY(${compLibName}
-      NAMES ${compLib}
-      HINTS $ENV{PLIBDIR}
+    string(TOUPPER "PLIB_${comp}" compLibBase)
+    set( compLibName ${compLibBase}_LIBRARY )
+
+    FIND_LIBRARY(${compLibName}_DEBUG
+      NAMES ${compLib}_d
+      HINTS $ENV{SIMGEAR_DIR}
       PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
       PATHS
       /usr/local
       /usr
       /opt
     )
-    
-    set(componentLib ${${compLibName}})
-    if (NOT ${componentLib} STREQUAL "componentLib-NOTFOUND")
-        list(APPEND ${libs} ${componentLib})
+    FIND_LIBRARY(${compLibName}_RELEASE
+      NAMES ${compLib}
+      HINTS $ENV{SIMGEAR_DIR}
+      PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
+      PATHS
+      /usr/local
+      /usr
+      /opt
+    )
+    select_library_configurations( ${compLibBase} )
+
+    set(componentLibRelease ${${compLibName}_RELEASE})
+    #message(STATUS "Simgear ${compLibName}_RELEASE ${componentLibRelease}")
+    set(componentLibDebug ${${compLibName}_DEBUG})
+    #message(STATUS "Simgear ${compLibName}_DEBUG ${componentLibDebug}")
+    if (NOT ${compLibName}_DEBUG)
+        if (NOT ${compLibName}_RELEASE)
+            #message(STATUS "found ${componentLib}")
+            list(APPEND ${libs} ${componentLibRelease})
+        endif()
+    else()
+        list(APPEND ${libs} optimized ${componentLibRelease} debug ${componentLibDebug})
     endif()
 endmacro()
 
diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake
index b17a4cb7f..8a494dde7 100644
--- a/CMakeModules/FindSimGear.cmake
+++ b/CMakeModules/FindSimGear.cmake
@@ -33,7 +33,7 @@
 # People will have to manually change the cache values of 
 # SimGear_LIBRARIES to override this selection or set the CMake environment
 # CMAKE_INCLUDE_PATH to modify the search paths.
-    
+
 include(SelectLibraryConfigurations)
 
 FIND_PATH(SIMGEAR_INCLUDE_DIR simgear/math/SGMath.hxx
@@ -89,9 +89,9 @@ macro(find_sg_component comp libs)
     select_library_configurations( ${compLibBase} )
 
     set(componentLibRelease ${${compLibName}_RELEASE})
-    message(STATUS "Simgear ${compLibName}_RELEASE ${componentLibRelease}")
+    #message(STATUS "Simgear ${compLibName}_RELEASE ${componentLibRelease}")
     set(componentLibDebug ${${compLibName}_DEBUG})
-    message(STATUS "Simgear ${compLibName}_DEBUG ${componentLibDebug}")
+    #message(STATUS "Simgear ${compLibName}_DEBUG ${componentLibDebug}")
     if (NOT ${compLibName}_DEBUG)
         if (NOT ${compLibName}_RELEASE)
             #message(STATUS "found ${componentLib}")

From 9a0f0cb15a235f5e6053b9df0a70a625b1df8798 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sat, 8 Jan 2011 16:45:40 +0100
Subject: [PATCH 21/26] Cmake: fix copy/paste typo

---
 CMakeModules/FindPLIB.cmake | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CMakeModules/FindPLIB.cmake b/CMakeModules/FindPLIB.cmake
index 1fe81b200..987943eb1 100644
--- a/CMakeModules/FindPLIB.cmake
+++ b/CMakeModules/FindPLIB.cmake
@@ -89,7 +89,7 @@ macro(find_static_component comp libs)
 
     FIND_LIBRARY(${compLibName}_DEBUG
       NAMES ${compLib}_d
-      HINTS $ENV{SIMGEAR_DIR}
+      HINTS $ENV{PLIBDIR}
       PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
       PATHS
       /usr/local
@@ -98,7 +98,7 @@ macro(find_static_component comp libs)
     )
     FIND_LIBRARY(${compLibName}_RELEASE
       NAMES ${compLib}
-      HINTS $ENV{SIMGEAR_DIR}
+      HINTS $ENV{PLIBDIR}
       PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
       PATHS
       /usr/local

From 4458f7ce7377a5fb718164911703cefcd946ccd0 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sat, 8 Jan 2011 21:38:26 +0100
Subject: [PATCH 22/26] Enable AI traffic for offline users and issue #248 -
 #248: new enable/disable-ai-traffic command-line option - AI traffic: don't
 wait for METAR when real-wx-fetch disabled, to enable AI traffic when running
 offline

---
 src/Main/options.cxx       | 8 +++++---
 src/Traffic/TrafficMgr.cxx | 3 ++-
 src/Traffic/TrafficMgr.hxx | 2 +-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/Main/options.cxx b/src/Main/options.cxx
index b5b28a0ec..1931bb341 100644
--- a/src/Main/options.cxx
+++ b/src/Main/options.cxx
@@ -1334,6 +1334,8 @@ struct OptionDesc {
     {"metar",                        true,  OPTION_STRING, "/environment/metar/data", false, "", 0 },
     {"disable-ai-models",            false, OPTION_BOOL,   "/sim/ai/enabled", false, "", 0 },
     {"enable-ai-models",             false, OPTION_BOOL,   "/sim/ai/enabled", true, "", 0 },
+    {"disable-ai-traffic",           false, OPTION_BOOL,   "/sim/traffic-manager/enabled", false, "", 0 },
+    {"enable-ai-traffic",            false, OPTION_BOOL,   "/sim/traffic-manager/enabled", true,  "", 0 },
     {"disable-freeze",               false, OPTION_BOOL,   "/sim/freeze/master", false, "", 0 },
     {"enable-freeze",                false, OPTION_BOOL,   "/sim/freeze/master", true, "", 0 },
     {"disable-fuel-freeze",          false, OPTION_BOOL,   "/sim/freeze/fuel", false, "", 0 },
@@ -1419,7 +1421,7 @@ struct OptionDesc {
     {"enable-skyblend",              false, OPTION_BOOL,   "/sim/rendering/skyblend", true, "", 0 },
     {"disable-textures",             false, OPTION_BOOL,   "/sim/rendering/textures", false, "", 0 },
     {"enable-textures",              false, OPTION_BOOL,   "/sim/rendering/textures", true, "", 0 },
-    {"texture-filtering",	     false, OPTION_INT,    "/sim/rendering/filtering", 1, "", 0 },
+    {"texture-filtering",            false, OPTION_INT,    "/sim/rendering/filtering", 1, "", 0 },
     {"disable-wireframe",            false, OPTION_BOOL,   "/sim/rendering/wireframe", false, "", 0 },
     {"enable-wireframe",             false, OPTION_BOOL,   "/sim/rendering/wireframe", true, "", 0 },
     {"geometry",                     true,  OPTION_FUNC,   "", false, "", fgOptGeometry },
@@ -1489,8 +1491,8 @@ struct OptionDesc {
     {"ai-scenario",                  true,  OPTION_FUNC,   "", false, "", fgOptScenario },
     {"parking-id",                   true,  OPTION_FUNC,   "", false, "", fgOptParking  },
     {"version",                      false, OPTION_FUNC,   "", false, "", fgOptVersion },
-    {"enable-fpe", 		     false, OPTION_FUNC,   "", false, "", fgOptFpe},
-    {"fgviewer", 		     false, OPTION_FUNC,   "", false, "", fgOptFgviewer},
+    {"enable-fpe",                   false, OPTION_FUNC,   "", false, "", fgOptFpe},
+    {"fgviewer",                     false, OPTION_FUNC,   "", false, "", fgOptFgviewer},
     {0}
 };
 
diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx
index 765c870fd..4abbc1a20 100644
--- a/src/Traffic/TrafficMgr.cxx
+++ b/src/Traffic/TrafficMgr.cxx
@@ -79,6 +79,7 @@ FGTrafficManager::FGTrafficManager() :
   inited(false),
   enabled("/sim/traffic-manager/enabled"),
   aiEnabled("/sim/ai/enabled"),
+  realWxEnabled("/environment/realwx/enabled"),
   metarValid("/environment/metar/valid")
 {
     //score = 0;
@@ -232,7 +233,7 @@ void FGTrafficManager::init()
 
 void FGTrafficManager::update(double /*dt */ )
 {
-    if (!enabled || !aiEnabled || !metarValid) {
+    if (!enabled || !aiEnabled || (realWxEnabled && !metarValid)) {
         return;
     }
         
diff --git a/src/Traffic/TrafficMgr.hxx b/src/Traffic/TrafficMgr.hxx
index a9bb9a305..ab1e19880 100644
--- a/src/Traffic/TrafficMgr.hxx
+++ b/src/Traffic/TrafficMgr.hxx
@@ -99,7 +99,7 @@ private:
   void readTimeTableFromFile(SGPath infilename);
   void Tokenize(const string& str, vector<string>& tokens, const string& delimiters = " ");
 
-  simgear::PropertyObject<bool> enabled, aiEnabled, metarValid;
+  simgear::PropertyObject<bool> enabled, aiEnabled, realWxEnabled, metarValid;
 public:
   FGTrafficManager();
   ~FGTrafficManager();

From 8efe895355d6a72dd32ca0dfd484027ac55e776d Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sat, 8 Jan 2011 22:34:43 +0100
Subject: [PATCH 23/26] Added several include files, thanks to Roland Haeder
 Added includes missing for some compiler/platform.

---
 src/Input/FGEventInput.cxx      | 1 +
 src/Input/FGLinuxEventInput.cxx | 6 ++++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/Input/FGEventInput.cxx b/src/Input/FGEventInput.cxx
index 29ee0977c..8bf9f304e 100644
--- a/src/Input/FGEventInput.cxx
+++ b/src/Input/FGEventInput.cxx
@@ -24,6 +24,7 @@
 #  include <config.h>
 #endif
 
+#include <cstring>
 #include "FGEventInput.hxx"
 #include <Main/fg_props.hxx>
 #include <simgear/io/sg_file.hxx>
diff --git a/src/Input/FGLinuxEventInput.cxx b/src/Input/FGLinuxEventInput.cxx
index 621e15fd8..03e7e0581 100644
--- a/src/Input/FGLinuxEventInput.cxx
+++ b/src/Input/FGLinuxEventInput.cxx
@@ -24,12 +24,14 @@
 #  include <config.h>
 #endif
 
-#include "FGLinuxEventInput.hxx"
-
+#include <cstring>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <poll.h>
 #include <linux/input.h>
 #include <dbus/dbus.h>
 #include <fcntl.h>
+#include "FGLinuxEventInput.hxx"
 
 
 struct TypeCode {

From e3d317d31ebec24077f9adc549ed3694403047f1 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 8 Jan 2011 21:43:23 +0000
Subject: [PATCH 24/26] Add FindGit from CMake 2.8.3 distribution

---
 CMakeModules/FindGit.cmake | 46 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 CMakeModules/FindGit.cmake

diff --git a/CMakeModules/FindGit.cmake b/CMakeModules/FindGit.cmake
new file mode 100644
index 000000000..818871516
--- /dev/null
+++ b/CMakeModules/FindGit.cmake
@@ -0,0 +1,46 @@
+# The module defines the following variables:
+#   GIT_EXECUTABLE - path to git command line client
+#   GIT_FOUND - true if the command line client was found
+# Example usage:
+#   find_package(Git)
+#   if(GIT_FOUND)
+#     message("git found: ${GIT_EXECUTABLE}")
+#   endif()
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# Look for 'git' or 'eg' (easy git)
+#
+set(git_names git eg)
+
+# Prefer .cmd variants on Windows unless running in a Makefile
+# in the MSYS shell.
+#
+if(WIN32)
+  if(NOT CMAKE_GENERATOR MATCHES "MSYS")
+    set(git_names git.cmd git eg.cmd eg)
+  endif()
+endif()
+
+find_program(GIT_EXECUTABLE
+  NAMES ${git_names}
+  DOC "git command line client"
+  )
+mark_as_advanced(GIT_EXECUTABLE)
+
+# Handle the QUIETLY and REQUIRED arguments and set GIT_FOUND to TRUE if
+# all listed variables are TRUE
+
+include("${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake")
+find_package_handle_standard_args(Git DEFAULT_MSG GIT_EXECUTABLE)

From 6564a9858b7d9c4038c34d5c89fed3c82199f856 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sun, 9 Jan 2011 00:04:59 +0000
Subject: [PATCH 25/26] Fix CMake inclusion for copied FindGit.cmake

---
 CMakeModules/FindGit.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeModules/FindGit.cmake b/CMakeModules/FindGit.cmake
index 818871516..06df3b091 100644
--- a/CMakeModules/FindGit.cmake
+++ b/CMakeModules/FindGit.cmake
@@ -42,5 +42,5 @@ mark_as_advanced(GIT_EXECUTABLE)
 # Handle the QUIETLY and REQUIRED arguments and set GIT_FOUND to TRUE if
 # all listed variables are TRUE
 
-include("${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake")
+include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Git DEFAULT_MSG GIT_EXECUTABLE)

From 5deec69e000d34bb93426ee3f14f4cb9731a3462 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sun, 9 Jan 2011 00:15:29 +0000
Subject: [PATCH 26/26] First attempt at libsvn support in terrasync with CMake
  - not yet working!

---
 CMakeLists.txt                   | 12 +++++++++
 CMakeModules/FindSvnClient.cmake | 46 ++++++++++++++++++++++++++++++++
 src/Include/config_cmake.h.in    |  3 +++
 utils/TerraSync/CMakeLists.txt   | 12 ++++++---
 4 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 291656ed9..f3576060e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -55,6 +55,8 @@ option(ENABLE_YASIM "Set to ON to build FlightGear with YASIM FDM" ON)
 option(ENABLE_JSBSIM "Set to ON to build FlightGear with JSBSim FDM" ON)
 option(ENABLE_FGADMIN "Set to ON to build FlightGear with FGADMIN" ON)
 option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" OFF)
+option(ENABLE_LIBSVN "Set to ON to build terrasync with libsvnclient support" OFF)
+
 set(MSVC_3RDPARTY_DIR NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
 
 if(LOGGING)
@@ -104,6 +106,16 @@ if(ENABLE_FGADMIN)
   find_package(FLTK)
 endif(ENABLE_FGADMIN)
 
+if(ENABLE_LIBSVN)
+	find_package(SvnClient)
+	
+	if(LIBSVN_FOUND)
+		message(STATUS "libsvn found, enabling in terrasync")
+		set(HAVE_SVN_CLIENT_H 1)
+		set(HAVE_LIBSVN_CLIENT_1 1)
+	endif(LIBSVN_FOUND)
+endif(ENABLE_LIBSVN)
+
 find_package(PLIB REQUIRED puaux pu js fnt)
 find_package(SimGear 2.2.0 REQUIRED)
 
diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake
index 383ef6f6d..51f4452bf 100644
--- a/CMakeModules/FindSvnClient.cmake
+++ b/CMakeModules/FindSvnClient.cmake
@@ -1,3 +1,49 @@
 # Find Subversion client libraries, and dependencies
 # including APR (Apache Portable Runtime)
 
+include (CheckFunctionExists)
+include (CheckIncludeFile)
+
+find_program(HAVE_APR_CONFIG apr-1-config)
+if(HAVE_APR_CONFIG) 
+    execute_process(COMMAND apr-1-config --includes
+        OUTPUT_VARIABLE RAW_APR_INCLUDES
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
+        
+    execute_process(COMMAND apr-1-config --cppflags
+        OUTPUT_VARIABLE APR_CFLAGS
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
+        
+    execute_process(COMMAND apr-1-config --link-ld
+        OUTPUT_VARIABLE RAW_APR_LIBS
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
+    
+# clean up some vars, or other CMake pieces complain
+	string(STRIP ${RAW_APR_LIBS} APR_LIBS)
+	string(STRIP ${RAW_APR_INCLUDES} APR_INCLUDES)
+
+else(HAVE_APR_CONFIG)
+    message(STATUS "apr-1-config not found, implement manual search for APR")
+endif(HAVE_APR_CONFIG)
+
+find_path(LIBSVN_INCLUDE_DIR svn_client.h
+  HINTS
+  $ENV{LIBSVN_DIR}
+  PATH_SUFFIXES include/subversion-1
+  PATHS
+  /usr/local
+  /usr
+  /opt
+)
+
+check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
+check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG HAVE_LIB_SVNSUBR 
+    HAVE_LIB_SVNCLIENT LIBSVN_INCLUDE_DIR)
+
+if(LIBSVN_FOUND)
+    set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" ${APR_LIBS})
+	set(LIBSVN_INCLUDE_DIRS ${LIBSVN_INCLUDE_DIR} ${APR_INCLUDES})
+endif(LIBSVN_FOUND)
diff --git a/src/Include/config_cmake.h.in b/src/Include/config_cmake.h.in
index 4505aa2dc..734b4dc5e 100644
--- a/src/Include/config_cmake.h.in
+++ b/src/Include/config_cmake.h.in
@@ -29,4 +29,7 @@
 #cmakedefine ENABLE_YASIM
 #cmakedefine ENABLE_JSBSIM
 
+#cmakedefine HAVE_SVN_CLIENT_H
+#cmakedefine HAVE_LIBSVN_CLIENT_1
+
 #define PKGLIBDIR "@PKGLIBDIR"
diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt
index bedc1018d..c44af48bf 100644
--- a/utils/TerraSync/CMakeLists.txt
+++ b/utils/TerraSync/CMakeLists.txt
@@ -1,6 +1,10 @@
 
-find_package(SvnClient)
-
+if(LIBSVN_FOUND)
+	message(STATUS "includes '${LIBSVN_INCLUDE_DIRS}'")
+	include_directories(${LIBSVN_INCLUDE_DIRS})
+	add_definitions(${APR_CFLAGS})
+endif(LIBSVN_FOUND)
+	
 add_executable(terrasync terrasync.cxx)
 
 target_link_libraries(terrasync 
@@ -8,8 +12,8 @@ target_link_libraries(terrasync
 	${ZLIB_LIBRARIES}
     ${WINSOCK_LIBRARY})
 
-if(HAVE_SVN_CLIENT)
-	target_link_libraries(terrasync ${SVN_CLIENT_LIBRARIES})
+if(LIBSVN_FOUND)
+	target_link_libraries(terrasync ${LIBSVN_LIBRARIES})
 endif()