X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fmisc%2Fscreensaver.c;h=8c59f83328385a0092fd64a14ff9f7b19a62ddbb;hb=61642608126855b643de8456d8677d9b3a9a5c2f;hp=f5fe626d1a919e863e44c3b1185068391397e75e;hpb=c6b6537f4d82d799bb4ee6d4c8c1dc6b87c0542c;p=vlc diff --git a/modules/misc/screensaver.c b/modules/misc/screensaver.c index f5fe626d1a..8c59f83328 100644 --- a/modules/misc/screensaver.c +++ b/modules/misc/screensaver.c @@ -1,7 +1,7 @@ /***************************************************************************** * screensaver.c : disable screen savers when VLC is playing ***************************************************************************** - * Copyright (C) 2006 the VideoLAN team + * Copyright (C) 2006-2009 the VideoLAN team * $Id$ * * Authors: Sam Hocevar @@ -26,31 +26,20 @@ * Preamble *****************************************************************************/ -#include -#include -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include #include #include -#include - -#ifdef HAVE_DBUS - -#define DBUS_API_SUBJECT_TO_CHANGE -#include - -#define GS_SERVICE "org.gnome.ScreenSaver" -#define GS_PATH "/org/gnome/ScreenSaver" -#define GS_INTERFACE "org.gnome.ScreenSaver" - -#endif - -/* this is for dbus < 0.3 */ -#ifndef HAVE_DBUS_1 -#define dbus_bus_name_has_owner(connection, name, err) dbus_bus_service_exists(connection, name, err) -#endif +#include +#include +#include /***************************************************************************** * Local prototypes @@ -58,49 +47,62 @@ static int Activate ( vlc_object_t * ); static void Deactivate ( vlc_object_t * ); -static void Run ( intf_thread_t *p_intf ); - -#ifdef HAVE_DBUS +static void Timer( void * ); +static void Inhibit( vlc_inhibit_t *, bool ); -static DBusConnection * dbus_init( intf_thread_t *p_intf ); -static void poke_screensaver( intf_thread_t *p_intf, - DBusConnection *p_connection ); -static void screensaver_send_message_void ( intf_thread_t *p_intf, - DBusConnection *p_connection, - const char *psz_name ); -static vlc_bool_t screensaver_is_running( DBusConnection *p_connection ); - - -struct intf_sys_t +struct vlc_inhibit_sys { - DBusConnection *p_connection; + vlc_timer_t timer; + posix_spawn_file_actions_t actions; + posix_spawnattr_t attr; + int nullfd; }; -#endif +extern char **environ; /***************************************************************************** * Module descriptor *****************************************************************************/ -vlc_module_begin(); - set_description( _("X Screensaver disabler") ); - set_capability( "interface", 0 ); - set_callbacks( Activate, Deactivate ); -vlc_module_end(); +vlc_module_begin () + set_description( N_("X Screensaver disabler") ) + set_capability( "inhibit", 5 ) + 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; + vlc_inhibit_t *p_ih = (vlc_inhibit_t*)p_this; + vlc_inhibit_sys_t *p_sys; - p_intf->pf_run = Run; + p_sys = p_ih->p_sys = malloc( sizeof( *p_sys ) ); + if( !p_sys ) + return VLC_ENOMEM; -#ifdef HAVE_DBUS - p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) ); - if( !p_intf->p_sys ) return VLC_ENOMEM; -#endif + if( vlc_timer_create( &p_sys->timer, Timer, p_ih ) ) + { + free( p_sys ); + return VLC_ENOMEM; + } + p_ih->inhibit = Inhibit; + + int fd = vlc_open ("/dev/null", O_WRONLY); + posix_spawn_file_actions_init (&p_sys->actions); + if (fd != -1) + { + posix_spawn_file_actions_adddup2 (&p_sys->actions, fd, 1); + posix_spawn_file_actions_adddup2 (&p_sys->actions, fd, 2); + posix_spawn_file_actions_addclose (&p_sys->actions, fd); + } + p_sys->nullfd = fd; + sigset_t set; + posix_spawnattr_init (&p_sys->attr); + sigemptyset (&set); + posix_spawnattr_setsigmask (&p_sys->attr, &set); + return VLC_SUCCESS; } @@ -109,56 +111,35 @@ static int Activate( vlc_object_t *p_this ) *****************************************************************************/ static void Deactivate( vlc_object_t *p_this ) { -#ifdef HAVE_DBUS - intf_thread_t *p_intf = (intf_thread_t*)p_this; - - if( p_intf->p_sys->p_connection ) - { -# ifdef HAVE_DBUS_2 - dbus_connection_unref( p_intf->p_sys->p_connection ); -# else - dbus_connection_disconnect( p_intf->p_sys->p_connection ); -# endif - } + vlc_inhibit_t *p_ih = (vlc_inhibit_t*)p_this; + vlc_inhibit_sys_t *p_sys = p_ih->p_sys; + + vlc_timer_destroy( p_sys->timer ); + if (p_sys->nullfd != -1) + close (p_sys->nullfd); + posix_spawnattr_destroy (&p_sys->attr); + posix_spawn_file_actions_destroy (&p_sys->actions); + free( p_sys ); +} - if( p_intf->p_sys ) - { - free( p_intf->p_sys ); - p_intf->p_sys = NULL; - } -#endif +static void Inhibit( vlc_inhibit_t *p_ih, bool suspend ) +{ + mtime_t d = suspend ? 30*CLOCK_FREQ : 0; + vlc_timer_schedule( p_ih->p_sys->timer, false, d, d ); } /***************************************************************************** * Execute: Spawns a process using execv() *****************************************************************************/ -static void Execute( intf_thread_t *p_this, const char *const *ppsz_args ) +static void Execute (vlc_inhibit_t *p_ih, const char *const *argv) { - pid_t pid = fork(); - switch( pid ) - { - case 0: /* we're the child */ - { - sigset_t set; - sigemptyset (&set); - pthread_sigmask (SIG_SETMASK, &set, NULL); + vlc_inhibit_sys_t *p_sys = p_ih->p_sys; + pid_t pid; - /* We don't want output */ - freopen( "/dev/null", "w", stdout ); - freopen( "/dev/null", "w", stderr ); - execv( ppsz_args[0] , (char *const *)ppsz_args ); - /* If the file we want to execute doesn't exist we exit() */ - exit( EXIT_FAILURE ); - } - case -1: /* we're the error */ - msg_Dbg( p_this, "Couldn't fork() while launching %s", - ppsz_args[0] ); - break; - default: /* we're the parent */ - /* Wait for the child to exit. - * We will not deadlock because we ran "/bin/sh &" */ - while( waitpid( pid, NULL, 0 ) != pid); - break; + if (posix_spawn (&pid, argv[0], &p_sys->actions, &p_sys->attr, + (char **)argv, environ) == 0) + { + while (waitpid (pid, NULL, 0) != pid); } } @@ -168,138 +149,17 @@ static void Execute( intf_thread_t *p_this, const char *const *ppsz_args ) * This part of the module is in a separate thread so that we do not have * too much system() overhead. *****************************************************************************/ -static void Run( intf_thread_t *p_intf ) -{ - vlc_object_lock( p_intf ); - -#ifdef HAVE_DBUS - p_intf->p_sys->p_connection = dbus_init( p_intf ); -#endif - - while( vlc_object_alive( p_intf ) ) - { - vlc_object_t *p_vout; - - /* Check screensaver every 30 seconds */ - if( vlc_object_timedwait( p_intf, mdate() + 30000000 ) < 0 ) - continue; - - p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); - - /* If there is a video output, disable xscreensaver */ - if( p_vout ) - { - input_thread_t *p_input; - p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT ); - vlc_object_release( p_vout ); - if( p_input ) - { - if( PLAYING_S == p_input->i_state ) - { - /* http://www.jwz.org/xscreensaver/faq.html#dvd */ - const char *const ppsz_xsargs[] = { "/bin/sh", "-c", - "xscreensaver-command -deactivate &", (char*)NULL }; - Execute( p_intf, ppsz_xsargs ); - - /* If we have dbus support, let's communicate directly - with gnome-screensave else, run - gnome-screensaver-command */ -#ifdef HAVE_DBUS - poke_screensaver( p_intf, p_intf->p_sys->p_connection ); -#else - const char *const ppsz_gsargs[] = { "/bin/sh", "-c", - "gnome-screensaver-command --poke &", (char*)NULL }; - Execute( p_intf, ppsz_gsargs ); -#endif - /* FIXME: add support for other screensavers */ - } - vlc_object_release( p_input ); - } - } - } - vlc_object_unlock( p_intf ); -} - -#ifdef HAVE_DBUS - -static DBusConnection * dbus_init( intf_thread_t *p_intf ) +static void Timer( void *data ) { - DBusError dbus_error; + vlc_inhibit_t *p_ih = data; - dbus_error_init (&dbus_error); - DBusConnection * p_connection = dbus_bus_get( DBUS_BUS_SESSION, &dbus_error ); + /* If there is a playing video output, disable xscreensaver */ + /* http://www.jwz.org/xscreensaver/faq.html#dvd */ + const char *const ppsz_xsargs[] = { "/bin/sh", "-c", + "xscreensaver-command -deactivate &", (char*)NULL }; + Execute (p_ih, ppsz_xsargs); - if ( !p_connection ) - { - msg_Warn( p_intf, "failed to connect to the D-BUS daemon: %s", - dbus_error.message); - dbus_error_free( &dbus_error ); - return NULL; - } - - return p_connection; + const char *const ppsz_gsargs[] = { "/bin/sh", "-c", + "gnome-screensaver-command --poke &", (char*)NULL }; + Execute (p_ih, ppsz_gsargs); } - -static void poke_screensaver( intf_thread_t *p_intf, - DBusConnection *p_connection ) -{ - if( screensaver_is_running( p_connection ) ) - { -# ifdef SCREENSAVER_DEBUG - msg_Dbg( p_intf, "found a running gnome-screensaver instance" ); -# endif - /* gnome-screensaver changed it's D-Bus interface, so we need both */ - screensaver_send_message_void( p_intf, p_connection, "Poke" ); - screensaver_send_message_void( p_intf, p_connection, - "SimulateUserActivity" ); - } -# ifdef SCREENSAVER_DEBUG - else - { - msg_Dbg( p_intf, "found no running gnome-screensaver instance" ); - } -# endif -} - -static void screensaver_send_message_void ( intf_thread_t *p_intf, - DBusConnection *p_connection, - const char *psz_name ) -{ - DBusMessage *p_message; - - if( !p_connection || !psz_name ) return; - - p_message = dbus_message_new_method_call( GS_SERVICE, GS_PATH, - GS_INTERFACE, psz_name ); - if( p_message == NULL ) - { - msg_Err( p_intf, "DBUS initialization failed: message initialization" ); - return; - } - - if( !dbus_connection_send( p_connection, p_message, NULL ) ) - { - msg_Err( p_intf, "DBUS communication failed" ); - } - - dbus_connection_flush( p_connection ); - - dbus_message_unref( p_message ); -} - -static vlc_bool_t screensaver_is_running( DBusConnection *p_connection ) -{ - DBusError error; - vlc_bool_t b_return; - - if( !p_connection ) return VLC_FALSE; - - dbus_error_init( &error ); - b_return = dbus_bus_name_has_owner( p_connection, GS_SERVICE, &error ); - if( dbus_error_is_set( &error ) ) dbus_error_free (&error); - - return b_return; -} - -#endif -