diff --git a/CMakeLists.txt b/CMakeLists.txt index 3806ea09b..f3540fbb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,7 @@ IF(APPLE) list(APPEND PLATFORM_LIBS ${COCOA_LIBRARY} ${CORESERVICES_LIBRARY}) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") + set(USE_DBUS_DEFAULT 1) find_package(UDev) if(UDEV_FOUND) @@ -141,6 +142,7 @@ option(ENABLE_PROFILE "Set to ON to build FlightGear with gperftools profilin option(JPEG_FACTORY "Set to ON to build FlightGear with JPEG-factory support" OFF) option(SYSTEM_SQLITE "Set to ON to build FlightGear with the system's SQLite3 library" OFF) option(ENABLE_IAX "Set to ON to build FlightGear with IAXClient/fgcom built-in (default)" ON) +option(USE_DBUS "Set to ON to build FlightGear with DBus screensaver interaction (default on Linux)" ${USE_DBUS_DEFAULT}) # additional utilities option(ENABLE_FGADMIN "Set to ON to build the FGADMIN application (default)" ON) @@ -239,6 +241,27 @@ endif (SYSTEM_SQLITE) # Sqlite always depends on the threading lib list(APPEND SQLITE3_LIBRARY ${CMAKE_THREAD_LIBS_INIT}) +############################################################################## +## DBus setup + +if (USE_DBUS) + include(FindPkgConfig) + if (PKG_CONFIG_FOUND) + pkg_check_modules(DBUS dbus-1) + endif (PKG_CONFIG_FOUND) #if we don't have pkg-config, assume we don't have libdbus-1-dev either http://packages.debian.org/sid/libdbus-1-dev + if (DBUS_FOUND) + set(HAVE_DBUS 1) + message(STATUS "Using DBus") + include_directories( ${DBUS_INCLUDE_DIRS}) + else() + message(STATUS "DBus not found, screensaver control disabled") + endif (DBUS_FOUND) +else() +endif (USE_DBUS) + +# Sqlite always depends on the threading lib +list(APPEND SQLITE3_LIBRARY ${CMAKE_THREAD_LIBS_INIT}) + ############################################################################## find_package(PLIB REQUIRED puaux pu js fnt) diff --git a/src/Include/config_cmake.h.in b/src/Include/config_cmake.h.in index 7f3ee6a04..1485016ce 100644 --- a/src/Include/config_cmake.h.in +++ b/src/Include/config_cmake.h.in @@ -40,3 +40,5 @@ #cmakedefine SYSTEM_SQLITE #cmakedefine ENABLE_IAX + +#cmakedefine HAVE_DBUS diff --git a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt index aeade6aa0..9167ec960 100644 --- a/src/Main/CMakeLists.txt +++ b/src/Main/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCES util.cxx positioninit.cxx subsystemFactory.cxx + screensaver_control.cxx ${RESOURCE_FILE} ) @@ -37,6 +38,7 @@ set(HEADERS positioninit.hxx subsystemFactory.hxx AircraftDirVisitorBase.hxx + screensaver_control.hxx ) get_property(FG_SOURCES GLOBAL PROPERTY FG_SOURCES) @@ -90,6 +92,9 @@ endif() if(ENABLE_IAX) target_link_libraries(fgfs iaxclient_lib ${OPENAL_LIBRARY}) endif() +if(USE_DBUS) + target_link_libraries(fgfs ${DBUS_LIBRARIES}) +endif() if(FG_HAVE_GPERFTOOLS) include_directories(${GooglePerfTools_INCLUDE_DIR}) target_link_libraries(fgfs ${GooglePerfTools_LIBRARIES}) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index f64e0d38a..40af6e292 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -65,9 +65,11 @@ #include "fg_os.hxx" #include "fg_props.hxx" #include "positioninit.hxx" +#include "screensaver_control.hxx" #include "subsystemFactory.hxx" #include "options.hxx" + using namespace flightgear; using std::cerr; @@ -429,6 +431,9 @@ int fgMainInit( int argc, char **argv ) { fgOutputSettings(); + //try to disable the screensaver + fgOSDisableScreensaver(); + // pass control off to the master event handler int result = fgOSMainLoop(); frame_signal.clear(); diff --git a/src/Main/screensaver_control.cxx b/src/Main/screensaver_control.cxx new file mode 100644 index 000000000..0af20eb42 --- /dev/null +++ b/src/Main/screensaver_control.cxx @@ -0,0 +1,66 @@ +// screensaver_control.cxx -- disable the screensaver +// +// Written by Rebecca Palmer, December 2013. +// +// Copyright (C) 2013 Rebecca Palmer +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + +#ifdef HAVE_CONFIG_H +# include +#endif +#ifdef HAVE_DBUS +#include //Uses the low-level libdbus rather than GDBus/QtDBus to avoid adding more dependencies than necessary. http://dbus.freedesktop.org/doc/api/html/index.html +#endif +/** Attempt to disable the screensaver. +* +* Screensavers/powersavers often do not monitor the joystick, and it is hence advisable to disable them while FlightGear is running. +* This function always exists, but currently only actually does anything on Linux, where it will disable gnome-screensaver/kscreensaver until FlightGear exits. +* +* The following might be useful to anyone wishing to add Windows support: +* http://msdn.microsoft.com/en-us/library/windows/desktop/aa373233%28v=vs.85%29.aspx +* http://msdn.microsoft.com/en-us/library/windows/desktop/aa373208%28v=vs.85%29.aspx (While this documentation says it only disables powersave, it is elsewhere reported to also disable screensaver) +* http://msdn.microsoft.com/en-us/library/windows/desktop/dd405534%28v=vs.85%29.aspx +*/ +void fgOSDisableScreensaver() +{ +#ifdef HAVE_DBUS + DBusConnection *dbus_connection; + DBusMessage *dbus_inhibit_screenlock; + unsigned int window_id=1000;//fake-it doesn't seem to care + unsigned int inhibit_idle=8;//8=idle inhibit flag + const char *app_name="org.flightgear"; + const char *inhibit_reason="Uses joystick input"; + + dbus_connection=dbus_bus_get(DBUS_BUS_SESSION,NULL); + dbus_connection_set_exit_on_disconnect(dbus_connection,FALSE);//Don't close us if we lose the DBus connection + + //Two possible interfaces; we send on both, as that is easier than trying to determine which will work + //GNOME: https://people.gnome.org/~mccann/gnome-session/docs/gnome-session.html + dbus_inhibit_screenlock=dbus_message_new_method_call("org.gnome.SessionManager","/org/gnome/SessionManager","org.gnome.SessionManager","Inhibit"); + dbus_message_append_args(dbus_inhibit_screenlock,DBUS_TYPE_STRING,&app_name,DBUS_TYPE_UINT32,&window_id,DBUS_TYPE_STRING,&inhibit_reason,DBUS_TYPE_UINT32,&inhibit_idle,DBUS_TYPE_INVALID); + dbus_connection_send(dbus_connection,dbus_inhibit_screenlock,NULL); + + //KDE, GNOME 3.6+: http://standards.freedesktop.org/idle-inhibit-spec/0.1/re01.html + dbus_inhibit_screenlock=dbus_message_new_method_call("org.freedesktop.ScreenSaver","/ScreenSaver","org.freedesktop.ScreenSaver","Inhibit"); + dbus_message_append_args(dbus_inhibit_screenlock,DBUS_TYPE_STRING,&app_name,DBUS_TYPE_STRING,&inhibit_reason,DBUS_TYPE_INVALID); + dbus_connection_send(dbus_connection,dbus_inhibit_screenlock,NULL); + dbus_connection_flush(dbus_connection); + //Currently ignores the reply; it would need to read it if we wanted to determine whether we've succeeded and/or allow explicitly re-enabling the screensaver + //Don't disconnect, that ends the inhibition +#endif +} diff --git a/src/Main/screensaver_control.hxx b/src/Main/screensaver_control.hxx new file mode 100644 index 000000000..5f68145af --- /dev/null +++ b/src/Main/screensaver_control.hxx @@ -0,0 +1,24 @@ +// screensaver_control.hxx -- disable the screensaver +// +// Written by Rebecca Palmer, December 2013. +// +// Copyright (C) 2013 Rebecca Palmer +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +void fgOSDisableScreensaver();