diff --git a/bin/vlc.c b/bin/vlc.c index 9546077832a5d82f97eb92bf3444a2900f4ea112..158878593a1ec4ae15e7c429169b1eaa6fc00f0a 100644 --- a/bin/vlc.c +++ b/bin/vlc.c @@ -246,7 +246,6 @@ int main( int i_argc, const char *ppsz_argv[] ) #endif #ifdef HAVE_DBUS libvlc_add_intf (vlc, "dbus,none"); - libvlc_add_intf (vlc, "inhibit,none"); #endif if (libvlc_add_intf (vlc, NULL)) goto out; diff --git a/modules/misc/Modules.am b/modules/misc/Modules.am index 11f9e824e3789c9d026fe863f36427b0b311a41f..25c1469e1fdfea74b4315f8bd3f8ea35dc7d503e 100644 --- a/modules/misc/Modules.am +++ b/modules/misc/Modules.am @@ -21,13 +21,6 @@ endif EXTRA_LTLIBRARIES += libgnutls_plugin.la libvlc_LTLIBRARIES += $(LTLIBgnutls) -libinhibit_plugin_la_SOURCES = inhibit.c -libinhibit_plugin_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -libinhibit_plugin_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) -if HAVE_DBUS -libvlc_LTLIBRARIES += libinhibit_plugin.la -endif - libosd_parser_plugin_la_SOURCES = \ osd/parser.c osd/osd_menu.c osd/osd_menu.h osd/simple.c osd/xml.c libosd_parser_plugin_la_CFLAGS = $(AM_CFLAGS) @@ -48,6 +41,13 @@ libvlc_LTLIBRARIES += \ libxscreensaver_plugin.la endif +libpower_plugin_la_SOURCES = inhibit/power.c +libpower_plugin_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) +libpower_plugin_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) +if HAVE_DBUS +libvlc_LTLIBRARIES += libpower_plugin.la +endif + libmce_plugin_la_SOURCES = inhibit/mce.c libmce_plugin_la_CFLAGS = $(AM_CLFAGS) $(DBUS_CFLAGS) $(MCE_CFLAGS) libmce_plugin_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) $(MCE_LIBS) diff --git a/modules/misc/inhibit.c b/modules/misc/inhibit.c deleted file mode 100644 index a2b58314453c20e995a3a104df2aeb1df674cd8c..0000000000000000000000000000000000000000 --- a/modules/misc/inhibit.c +++ /dev/null @@ -1,305 +0,0 @@ -/***************************************************************************** - * inhibit.c : prevents the computer from suspending when VLC is playing - ***************************************************************************** - * Copyright © 2007 Rafaël Carré - * $Id$ - * - * Author: Rafaël Carré <funman@videolanorg> - * - * 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 - *****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <vlc_common.h> -#include <vlc_plugin.h> -#include <vlc_input.h> -#include <vlc_interface.h> -#include <vlc_playlist.h> - -#include <dbus/dbus.h> - -enum { - FREEDESKTOP = 0, /* as used by KDE and gnome <= 2.26 */ - GNOME = 1, /* as used by gnome > 2.26 */ -}; - -static const char *dbus_service[] = { - [FREEDESKTOP] = "org.freedesktop.PowerManagement", - [GNOME] = "org.gnome.SessionManager", -}; - -static const char *dbus_path[] = { - [FREEDESKTOP] = "/org/freedesktop/PowerManagement", - [GNOME] = "/org/gnome/SessionManager", -}; - -static const char *dbus_interface[] = { - [FREEDESKTOP] = "org.freedesktop.PowerManagement.Inhibit", - [GNOME] = "org.gnome.SessionManager", -}; - -static const char *dbus_uninhibit_method[] = { - [FREEDESKTOP] = "UnInhibit", - [GNOME] = "Uninhibit", -}; - - -/***************************************************************************** - * Local prototypes - !*****************************************************************************/ -static int Activate ( vlc_object_t * ); -static void Deactivate ( vlc_object_t * ); - -static void UnInhibit( intf_thread_t *p_intf, int type ); - -static int InputChange( vlc_object_t *, const char *, - vlc_value_t, vlc_value_t, void * ); -static int StateChange( vlc_object_t *, const char *, - vlc_value_t, vlc_value_t, void * ); - -struct intf_sys_t -{ - playlist_t *p_playlist; - vlc_object_t *p_input; - DBusConnection *p_conn; - dbus_uint32_t i_cookie[2]; -}; - -/***************************************************************************** - * Module descriptor - *****************************************************************************/ -vlc_module_begin () - set_description( N_("Power Management Inhibitor") ) - 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; - intf_sys_t *p_sys; - DBusError error; - - p_sys = p_intf->p_sys = (intf_sys_t *) calloc( 1, sizeof( intf_sys_t ) ); - if( !p_sys ) - return VLC_ENOMEM; - - p_sys->i_cookie[FREEDESKTOP] = 0; - p_sys->i_cookie[GNOME] = 0; - p_sys->p_input = NULL; - - dbus_error_init( &error ); - - /* connect privately to the session bus - * the connection will not be shared with other vlc modules which use dbus, - * thus avoiding a whole class of concurrency issues */ - p_sys->p_conn = dbus_bus_get_private( DBUS_BUS_SESSION, &error ); - if( !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_sys ); - return VLC_EGENERIC; - } - - p_sys->p_playlist = pl_Get( p_intf ); - var_AddCallback( p_sys->p_playlist, "activity", InputChange, p_intf ); - 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; - intf_sys_t *p_sys = p_intf->p_sys; - - var_DelCallback( p_sys->p_playlist, "activity", InputChange, p_intf ); - - if( p_sys->p_input ) /* Do delete "state" after "item-changed"! */ - { - var_DelCallback( p_sys->p_input, "state", StateChange, p_intf ); - vlc_object_release( p_sys->p_input ); - } - - if( p_sys->i_cookie[FREEDESKTOP] ) - UnInhibit( p_intf, FREEDESKTOP ); - if( p_sys->i_cookie[GNOME] ) - UnInhibit( p_intf, GNOME ); - - /* The dbus connection is private, - * so we are responsible for closing it */ - dbus_connection_close( p_sys->p_conn ); - dbus_connection_unref( p_sys->p_conn ); - - free( p_sys ); -} - -/***************************************************************************** - * Inhibit: Notify the power management daemon that it shouldn't suspend - * the computer because of inactivity - *****************************************************************************/ -static void Inhibit( intf_thread_t *p_intf, int type ) -{ - intf_sys_t *p_sys = p_intf->p_sys; - - DBusMessage *msg = dbus_message_new_method_call( - dbus_service[type], dbus_path[type], dbus_interface[type], "Inhibit" ); - if( unlikely(msg == NULL) ) - return; - - const char *app = PACKAGE; - const char *reason = _("Playing some media."); - - p_sys->i_cookie[type] = 0; - - dbus_bool_t ret; - dbus_uint32_t xid = 0; // FIXME? - dbus_uint32_t flags = 8 /* Inhibit suspending the session or computer */ - | 4;/* Inhibit the session being marked as idle */ - switch( type ) { - case FREEDESKTOP: - ret = dbus_message_append_args( msg, DBUS_TYPE_STRING, &app, - DBUS_TYPE_STRING, &reason, - DBUS_TYPE_INVALID ); - break; - case GNOME: - default: - ret = dbus_message_append_args( msg, DBUS_TYPE_STRING, &app, - DBUS_TYPE_UINT32, &xid, - DBUS_TYPE_STRING, &reason, - DBUS_TYPE_UINT32, &flags, - DBUS_TYPE_INVALID ); - break; - } - - if( !ret ) - { - dbus_message_unref( msg ); - return; - } - - /* blocks 50ms maximum */ - DBusMessage *reply; - - reply = dbus_connection_send_with_reply_and_block( p_sys->p_conn, msg, - 50, NULL ); - dbus_message_unref( msg ); - if( reply == NULL ) - /* g-p-m is not active, or too slow. Better luck next time? */ - return; - - /* extract the cookie from the reply */ - dbus_uint32_t i_cookie; - - if( dbus_message_get_args( reply, NULL, - DBUS_TYPE_UINT32, &i_cookie, - DBUS_TYPE_INVALID ) ) - p_sys->i_cookie[type] = i_cookie; - - dbus_message_unref( reply ); -} - -/***************************************************************************** - * UnInhibit: Notify the power management daemon that we aren't active anymore - *****************************************************************************/ -static void UnInhibit( intf_thread_t *p_intf, int type ) -{ - intf_sys_t *p_sys = p_intf->p_sys; - - DBusMessage *msg = dbus_message_new_method_call( dbus_service[type], - dbus_path[type], dbus_interface[type], dbus_uninhibit_method[type] ); - if( unlikely(msg == NULL) ) - return; - - dbus_uint32_t i_cookie = p_sys->i_cookie[type]; - if( dbus_message_append_args( msg, DBUS_TYPE_UINT32, &i_cookie, - DBUS_TYPE_INVALID ) - && dbus_connection_send( p_sys->p_conn, msg, NULL ) ) - { - dbus_connection_flush( p_sys->p_conn ); - p_sys->i_cookie[type] = 0; - } - dbus_message_unref( msg ); -} - - -static int StateChange( vlc_object_t *p_input, const char *var, - vlc_value_t prev, vlc_value_t value, void *data ) -{ - intf_thread_t *p_intf = data; - intf_sys_t *p_sys = p_intf->p_sys; - const int old = prev.i_int, cur = value.i_int; - - if( ( old == PLAYING_S ) == ( cur == PLAYING_S ) ) - return VLC_SUCCESS; /* No interesting change */ - - if( cur == PLAYING_S ) { - if (p_sys->i_cookie[FREEDESKTOP] == 0) - Inhibit( p_intf, FREEDESKTOP ); - if (p_sys->i_cookie[GNOME] == 0) - Inhibit( p_intf, GNOME ); - } - else { - if (p_sys->i_cookie[FREEDESKTOP] != 0) - UnInhibit( p_intf, FREEDESKTOP ); - if (p_sys->i_cookie[GNOME] != 0) - UnInhibit( p_intf, GNOME ); - } - - (void)p_input; (void)var; (void)prev; - return VLC_SUCCESS; -} - -static int InputChange( vlc_object_t *p_playlist, const char *var, - vlc_value_t prev, vlc_value_t value, void *data ) -{ - intf_thread_t *p_intf = data; - intf_sys_t *p_sys = p_intf->p_sys; - - if( p_sys->p_input ) - { - var_DelCallback( p_sys->p_input, "state", StateChange, p_intf ); - vlc_object_release( p_sys->p_input ); - } - p_sys->p_input = VLC_OBJECT(playlist_CurrentInput( p_sys->p_playlist )); - if( p_sys->p_input ) - { - Inhibit( p_intf, FREEDESKTOP ); - Inhibit( p_intf, GNOME ); - - var_AddCallback( p_sys->p_input, "state", StateChange, p_intf ); - } - - (void)var; (void)prev; (void)value; (void)p_playlist; - return VLC_SUCCESS; -} diff --git a/modules/misc/inhibit/power.c b/modules/misc/inhibit/power.c new file mode 100644 index 0000000000000000000000000000000000000000..e08742bc3b17fa6a70a74066ca8ae9d5c84d53b9 --- /dev/null +++ b/modules/misc/inhibit/power.c @@ -0,0 +1,185 @@ +/***************************************************************************** + * power.c : prevents the computer from suspending when VLC is playing + ***************************************************************************** + * Copyright © 2009-2011 Rémi Denis-Courmont + * Copyright © 2007-2012 Rafaël Carré + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <vlc_common.h> +#include <vlc_plugin.h> +#include <vlc_inhibit.h> +#include <dbus/dbus.h> + +struct vlc_inhibit_sys +{ + DBusConnection *conn; + dbus_uint32_t cookie[2]; +}; + +static void Inhibit (vlc_inhibit_t *ih, unsigned flags) +{ + enum { + FREEDESKTOP = 0, /* as used by KDE and gnome <= 2.26 */ + GNOME = 1, /* as used by gnome > 2.26 */ + }; + + static const char dbus_service[2][32] = { + [FREEDESKTOP] = "org.freedesktop.PowerManagement", + [GNOME] = "org.gnome.SessionManager", + }; + + static const char dbus_path[2][33] = { + [FREEDESKTOP] = "/org/freedesktop/PowerManagement", + [GNOME] = "/org/gnome/SessionManager", + }; + + static const char dbus_interface[2][40] = { + [FREEDESKTOP] = "org.freedesktop.PowerManagement.Inhibit", + [GNOME] = "org.gnome.SessionManager", + }; + + static const char dbus_method[2][2][10] = { + { + [FREEDESKTOP] = "UnInhibit", + [GNOME] = "Uninhibit", + }, + { + [FREEDESKTOP] = "Inhibit", + [GNOME] = "Inhibit", + }, + }; + + static const char *app = PACKAGE; + static const char *reason = N_("Playing some media."); + + vlc_inhibit_sys_t *sys = ih->p_sys; + DBusConnection *conn = sys->conn; + + const bool suspend = !!flags; + const dbus_uint32_t xid = 0; // FIXME ? + const dbus_uint32_t gnome_flags = ((flags & VLC_INHIBIT_SUSPEND) ? 8 : 0) + | ((flags & VLC_INHIBIT_DISPLAY) ? 4 : 0); + for (int type = 0; type < 2; type++) { + dbus_bool_t ret; + + DBusMessage *msg = dbus_message_new_method_call(dbus_service[type], + dbus_path[type], dbus_interface[type], dbus_method[suspend][type]); + if (unlikely(msg == NULL)) + return; + + if (suspend) { + if (type == FREEDESKTOP) + ret = dbus_message_append_args (msg, DBUS_TYPE_STRING, &app, + DBUS_TYPE_STRING, &reason, + DBUS_TYPE_INVALID); + else if (type == GNOME) + ret = dbus_message_append_args (msg, DBUS_TYPE_STRING, &app, + DBUS_TYPE_UINT32, &xid, + DBUS_TYPE_STRING, &reason, + DBUS_TYPE_UINT32, &gnome_flags, + DBUS_TYPE_INVALID); + } else { + ret = false; + if (sys->cookie[type]) + ret = dbus_message_append_args (msg, DBUS_TYPE_UINT32, + &sys->cookie[type], DBUS_TYPE_INVALID); + } + + if (!ret) + goto end; + + if (suspend) { /* read reply */ + /* blocks 50ms maximum */ + DBusMessage *reply = dbus_connection_send_with_reply_and_block( + conn, msg, 50, NULL ); + + if (unlikely(reply == NULL)) + goto end; /* gpm is not active, or too slow. Better luck next time? */ + + if (!dbus_message_get_args(reply, NULL, + DBUS_TYPE_UINT32, &sys->cookie[type], + DBUS_TYPE_INVALID)) + sys->cookie[type] = 0; + + dbus_message_unref( reply ); + } else { /* just send and flush */ + if (dbus_connection_send (conn, msg, NULL)) { + sys->cookie[type] = 0; + dbus_connection_flush (conn); + } + } +end: + dbus_message_unref (msg); + } +} + +static int Open (vlc_object_t *obj) +{ + vlc_inhibit_t *ih = (vlc_inhibit_t *)obj; + vlc_inhibit_sys_t *sys = malloc (sizeof (*sys)); + if (unlikely(sys == NULL)) + return VLC_ENOMEM; + + DBusError err; + + dbus_error_init (&err); + sys->conn = dbus_bus_get_private (DBUS_BUS_SESSION, &err); + if (sys->conn == NULL) + { + msg_Err (obj, "cannot connect to session bus: %s", err.message); + dbus_error_free (&err); + free (sys); + return VLC_EGENERIC; + } + sys->cookie[0] = 0; + sys->cookie[1] = 0; + + ih->p_sys = sys; + ih->inhibit = Inhibit; + return VLC_SUCCESS; +} + +static void Close (vlc_object_t *obj) +{ + vlc_inhibit_t *ih = (vlc_inhibit_t *)obj; + vlc_inhibit_sys_t *sys = ih->p_sys; + + dbus_connection_close (sys->conn); + dbus_connection_unref (sys->conn); + free (sys); +} + +/* + * Module descriptor + */ +vlc_module_begin () + set_shortname (N_("Power")) + set_description (N_("Inhibits power suspend and session idle timeout.")) + set_category (CAT_ADVANCED) + set_subcategory (SUBCAT_ADVANCED_MISC) + set_capability ("inhibit", 20) + set_callbacks (Open, Close) +vlc_module_end () diff --git a/po/POTFILES.in b/po/POTFILES.in index a8185d156970d78020d535a7e1866e238bd15488..53254ed5fe4f7f4307142243440f51027123492f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -945,8 +945,8 @@ modules/meta_engine/taglib.cpp modules/misc/audioscrobbler.c modules/misc/dhparams.h modules/misc/gnutls.c -modules/misc/inhibit.c modules/misc/inhibit/mce.c +modules/misc/inhibit/power.c modules/misc/inhibit/xdg.c modules/misc/inhibit/xscreensaver.c modules/misc/logger.c