From: Rafaël Carré Date: Sat, 20 Oct 2007 23:47:34 +0000 (+0000) Subject: New inhibit module to prevent the power management daemon (usually gnome-power-manage... X-Git-Tag: 0.9.0-test0~4903 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=1995f882d45bf8f9bd167f9ba549ca7d1efb664e;p=vlc New inhibit module to prevent the power management daemon (usually gnome-power-manager) to suspend/hibernate the laptop while VLC is active. --- diff --git a/configure.ac b/configure.ac index 5fd74ff352..1ae0deec30 100644 --- a/configure.ac +++ b/configure.ac @@ -899,8 +899,12 @@ then VLC_ADD_PLUGINS([telepathy]) VLC_ADD_LIBS([telepathy],[$DBUS_LIBS]) VLC_ADD_CFLAGS([telepathy],[$DBUS_CFLAGS]) - fi], - + fi + dnl Power Management Inhibiter + VLC_ADD_PLUGINS([inhibit]) + VLC_ADD_LIBS([inhibit],[$DBUS_LIBS]) + VLC_ADD_CFLAGS([inhibit],[$DBUS_CFLAGS]) + ], if ${PKG_CONFIG} --exists dbus-1 then [AC_ARG_ENABLE(old-dbus, diff --git a/modules/misc/Modules.am b/modules/misc/Modules.am index adfbf9613e..db282b66df 100644 --- a/modules/misc/Modules.am +++ b/modules/misc/Modules.am @@ -13,3 +13,4 @@ SOURCES_gnutls = gnutls.c dhparams.h SOURCES_svg = svg.c SOURCES_profile_parser = profile_parser.c SOURCES_audioscrobbler = audioscrobbler.c +SOURCES_inhibit = inhibit.c diff --git a/modules/misc/inhibit.c b/modules/misc/inhibit.c new file mode 100644 index 0000000000..1103bd0c4f --- /dev/null +++ b/modules/misc/inhibit.c @@ -0,0 +1,263 @@ +/***************************************************************************** + * inhibit.c : prevents the computer from suspending when VLC is playing + ***************************************************************************** + * Copyright © 2007 Rafaël Carré + * $Id$ + * + * Author: Rafaël Carré + * + * 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. + *****************************************************************************/ + +/* + * Based on freedesktop Power Management Specification version 0.2 + * http://people.freedesktop.org/~hughsient/temp/power-management-spec-0.2.html + */ + +/***************************************************************************** + * Preamble + *****************************************************************************/ + +#include +#include +#include + +#include + +#define PM_SERVICE "org.freedesktop.PowerManagement" +#define PM_PATH "/org/freedesktop/PowerManagement/Inhibit" +#define PM_INTERFACE "org.freedesktop.PowerManagement.Inhibit" + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ +static int Activate ( vlc_object_t * ); +static void Deactivate ( vlc_object_t * ); + +static void Run ( intf_thread_t *p_intf ); + +struct intf_sys_t +{ + DBusConnection *p_conn; + dbus_uint32_t i_cookie; +}; + +/***************************************************************************** + * Module descriptor + *****************************************************************************/ +vlc_module_begin(); + set_description( _("Power Management Inhibiter") ); + set_capability( "interface", 0 ); + set_callbacks( Activate, Deactivate ); +vlc_module_end(); + +/***************************************************************************** + * Activate: initialize and create stuff + *****************************************************************************/ +static int Activate( vlc_object_t *p_this ) +{ + intf_thread_t *p_intf = (intf_thread_t*)p_this; + DBusError error; + + + p_intf->pf_run = Run; + + p_intf->p_sys = (intf_sys_t *) calloc( 1, sizeof( intf_sys_t ) ); + + if( !p_intf->p_sys ) + return VLC_ENOMEM; + + p_intf->p_sys->i_cookie = 0; + + dbus_error_init( &error ); + p_intf->p_sys->p_conn = dbus_bus_get( DBUS_BUS_SESSION, &error ); + if( !p_intf->p_sys->p_conn ) + { + msg_Err( p_this, "Failed to connect to the D-Bus session daemon: %s", + error.message ); + dbus_error_free( &error ); + free( p_intf->p_sys ); + return VLC_EGENERIC; + } + + return VLC_SUCCESS; +} + +/***************************************************************************** + * Deactivate: uninitialize and cleanup + *****************************************************************************/ +static void Deactivate( vlc_object_t *p_this ) +{ + intf_thread_t *p_intf = (intf_thread_t*)p_this; + dbus_connection_unref( p_intf->p_sys->p_conn ); + free( p_intf->p_sys ); +} + +/***************************************************************************** + * Inhibit: Notify the power management daemon that it shouldn't suspend + * the computer because of inactivity + * + * returns VLC_FALSE if Out of memory, else VLC_TRUE + *****************************************************************************/ +static int Inhibit( intf_thread_t *p_intf ) +{ + DBusConnection *p_conn; + DBusMessage *p_msg; + DBusMessageIter args; + DBusMessage *p_reply; + DBusError error; + dbus_error_init( &error ); + dbus_uint32_t i_cookie; + + p_conn = p_intf->p_sys->p_conn; + + p_msg = dbus_message_new_method_call( PM_SERVICE, PM_PATH, PM_INTERFACE, + "Inhibit" ); + if( !p_msg ) + return VLC_FALSE; + + dbus_message_iter_init_append( p_msg, &args ); + + char *psz_app = strdup( PACKAGE ); + if( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING, &psz_app ) ) + { + free( psz_app ); + dbus_message_unref( p_msg ); + return VLC_FALSE; + } + free( psz_app ); + + char *psz_inhibit_reason = strdup( "Playing some media." ); + if( !psz_inhibit_reason ) + { + dbus_message_unref( p_msg ); + return VLC_FALSE; + } + if( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING, + &psz_inhibit_reason ) ) + { + free( psz_inhibit_reason ); + dbus_message_unref( p_msg ); + return VLC_FALSE; + } + free( psz_inhibit_reason ); + + p_reply = dbus_connection_send_with_reply_and_block( p_conn, p_msg, + 50, &error ); /* blocks 50ms maximum */ + + dbus_message_unref( p_msg ); + if( p_reply == NULL ) + { /* g-p-m is not active, or too slow. Better luck next time? */ + return VLC_TRUE; + } + + /* extract the cookie from the reply */ + if( dbus_message_get_args( p_reply, &error, + DBUS_TYPE_UINT32, &i_cookie, + DBUS_TYPE_INVALID ) == FALSE ) + { + return VLC_FALSE; + } + + /* Save the cookie */ + p_intf->p_sys->i_cookie = i_cookie; + return VLC_TRUE; +} + +/***************************************************************************** + * UnInhibit: Notify the power management daemon that we aren't active anymore + * + * returns VLC_FALSE if Out of memory, else VLC_TRUE + *****************************************************************************/ +static int UnInhibit( intf_thread_t *p_intf ) +{ + DBusConnection *p_conn; + DBusMessage *p_msg; + DBusMessageIter args; + DBusError error; + dbus_error_init( &error ); + dbus_uint32_t i_cookie; + + p_conn = p_intf->p_sys->p_conn; + + p_msg = dbus_message_new_method_call( PM_SERVICE, PM_PATH, PM_INTERFACE, + "UnInhibit" ); + if( !p_msg ) + return VLC_FALSE; + + dbus_message_iter_init_append( p_msg, &args ); + + i_cookie = p_intf->p_sys->i_cookie; + if( !dbus_message_iter_append_basic( &args, DBUS_TYPE_UINT32, &i_cookie ) ) + { + dbus_message_unref( p_msg ); + return VLC_FALSE; + } + + if( !dbus_connection_send( p_conn, p_msg, NULL ) ) + return VLC_FALSE; + dbus_connection_flush( p_conn ); + + dbus_message_unref( p_msg ); + + return VLC_TRUE; +} + +/***************************************************************************** + * Run: main thread + *****************************************************************************/ +static void Run( intf_thread_t *p_intf ) +{ + for(;;) + { + input_thread_t *p_input; + vlc_bool_t b_quit; + + /* Check playing state every 30 seconds */ + vlc_object_lock( p_intf ); + b_quit = vlc_object_timedwait( p_intf, mdate() + 30000000 ) < 0; + vlc_object_unlock( p_intf ); + + if( b_quit ) + break; + + p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE ); + if( p_input ) + { + if( PLAYING_S == p_input->i_state && !p_intf->p_sys->i_cookie ) + { + if( !Inhibit( p_intf ) ) + { + vlc_object_release( p_input ); + return; + } + } + else if( p_intf->p_sys->i_cookie ) + { + if( !UnInhibit( p_intf ) ) + { + vlc_object_release( p_input ); + return; + } + } + vlc_object_release( p_input ); + } + else if( p_intf->p_sys->i_cookie ) + { + if( !UnInhibit( p_intf ) ) + return; + } + } +} diff --git a/src/libvlc-common.c b/src/libvlc-common.c index 01a329fdd5..e087faf8eb 100644 --- a/src/libvlc-common.c +++ b/src/libvlc-common.c @@ -854,6 +854,11 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] ) * we do it only when playlist exists, because dbus module needs it */ if( config_GetInt( p_libvlc, "one-instance" ) ) VLC_AddIntf( 0, "dbus,none", VLC_FALSE, VLC_FALSE ); + + /* Prevents the power management daemon to suspend the computer + * when VLC is active */ + if( config_GetInt( p_libvlc, "inhibit" ) ) + VLC_AddIntf( 0, "inhibit,none", VLC_FALSE, VLC_FALSE ); #endif /* diff --git a/src/libvlc-module.c b/src/libvlc-module.c index 4bd39139d3..0ac83a85cd 100644 --- a/src/libvlc-module.c +++ b/src/libvlc-module.c @@ -403,6 +403,10 @@ static const char *ppsz_pos_descriptions[] = #define SS_TEXT N_("Disable screensaver") #define SS_LONGTEXT N_("Disable the screensaver during video playback." ) +#define INHIBIT_TEXT N_("Inhibits the power management daemon during playback.") +#define INHIBIT_LONGTEXT N_("Inhibits the power management daemon during any" \ + "playback, to avoid the computer being suspended because of inactivity.") + #define VIDEO_DECO_TEXT N_("Window decorations") #define VIDEO_DECO_LONGTEXT N_( \ "VLC can avoid creating window caption, frames, etc... around the video" \ @@ -1787,6 +1791,9 @@ vlc_module_begin(); add_bool( "playlist-enqueue", 0, NULL, PLAYLISTENQUEUE_TEXT, PLAYLISTENQUEUE_LONGTEXT, VLC_TRUE ); change_unsaveable(); + + add_bool( "inhibit", 1, NULL, INHIBIT_TEXT, + INHIBIT_LONGTEXT, VLC_TRUE ); #endif #if defined(WIN32)