]> git.sesse.net Git - vlc/blob - modules/misc/screensaver.c
screensaver: wait for process
[vlc] / modules / misc / screensaver.c
1 /*****************************************************************************
2  * screensaver.c : disable screen savers when VLC is playing
3  *****************************************************************************
4  * Copyright (C) 2006-2009 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Sam Hocevar <sam@zoy.org>
8  *          Benjamin Pracht <bigben AT videolan DOT org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_inhibit.h>
36 #include <vlc_fs.h>
37
38 #include <sys/types.h>
39 #include <sys/wait.h>
40 #include <fcntl.h>
41 #include <signal.h>
42 #include <spawn.h>
43
44 /*****************************************************************************
45  * Local prototypes
46  *****************************************************************************/
47 static int  Activate     ( vlc_object_t * );
48 static void  Deactivate   ( vlc_object_t * );
49
50 static void Timer( void * );
51 static void Inhibit( vlc_inhibit_t *, bool );
52
53 struct vlc_inhibit_sys
54 {
55     vlc_timer_t timer;
56     posix_spawn_file_actions_t actions;
57     posix_spawnattr_t attr;
58     int nullfd;
59 };
60
61 extern char **environ;
62
63 /*****************************************************************************
64  * Module descriptor
65  *****************************************************************************/
66 vlc_module_begin ()
67     set_description( N_("X Screensaver disabler") )
68     set_capability( "inhibit", 5 )
69     set_callbacks( Activate, Deactivate )
70 vlc_module_end ()
71
72 /*****************************************************************************
73  * Activate: initialize and create stuff
74  *****************************************************************************/
75 static int Activate( vlc_object_t *p_this )
76 {
77     vlc_inhibit_t *p_ih = (vlc_inhibit_t*)p_this;
78     vlc_inhibit_sys_t *p_sys;
79
80     p_sys = p_ih->p_sys = malloc( sizeof( *p_sys ) );
81     if( !p_sys )
82         return VLC_ENOMEM;
83
84     if( vlc_timer_create( &p_sys->timer, Timer, p_ih ) )
85     {
86         free( p_sys );
87         return VLC_ENOMEM;
88     }
89     p_ih->inhibit = Inhibit;
90
91     int fd = vlc_open ("/dev/null", O_WRONLY);
92     posix_spawn_file_actions_init (&p_sys->actions);
93     if (fd != -1)
94     {
95         posix_spawn_file_actions_adddup2 (&p_sys->actions, fd, 1);
96         posix_spawn_file_actions_adddup2 (&p_sys->actions, fd, 2);
97         posix_spawn_file_actions_addclose (&p_sys->actions, fd);
98     }
99     p_sys->nullfd = fd;
100
101     sigset_t set;
102     posix_spawnattr_init (&p_sys->attr);
103     sigemptyset (&set);
104     posix_spawnattr_setsigmask (&p_sys->attr, &set);
105    
106     return VLC_SUCCESS;
107 }
108
109 /*****************************************************************************
110  * Deactivate: uninitialize and cleanup
111  *****************************************************************************/
112 static void Deactivate( vlc_object_t *p_this )
113 {
114     vlc_inhibit_t *p_ih = (vlc_inhibit_t*)p_this;
115     vlc_inhibit_sys_t *p_sys = p_ih->p_sys;
116
117     vlc_timer_destroy( p_sys->timer );
118     if (p_sys->nullfd != -1)
119         close (p_sys->nullfd);
120     posix_spawnattr_destroy (&p_sys->attr);
121     posix_spawn_file_actions_destroy (&p_sys->actions);
122     free( p_sys );
123 }
124
125 static void Inhibit( vlc_inhibit_t *p_ih, bool suspend )
126 {
127     mtime_t d = suspend ? 30*CLOCK_FREQ : 0;
128     vlc_timer_schedule( p_ih->p_sys->timer, false, d, d );
129 }
130
131 /*****************************************************************************
132  * Execute: Spawns a process using execv()
133  *****************************************************************************/
134 static void Execute (vlc_inhibit_t *p_ih, const char *const *argv)
135 {
136     vlc_inhibit_sys_t *p_sys = p_ih->p_sys;
137     pid_t pid;
138
139     if (posix_spawnp (&pid, argv[0], &p_sys->actions, &p_sys->attr,
140                       (char **)argv, environ) == 0)
141     {
142         while (waitpid (pid, NULL, 0) != pid);
143     }
144 }
145
146 /*****************************************************************************
147  * Run: main thread
148  *****************************************************************************
149  * This part of the module is in a separate thread so that we do not have
150  * too much system() overhead.
151  *****************************************************************************/
152 static void Timer( void *data )
153 {
154     vlc_inhibit_t *p_ih = data;
155
156     /* If there is a playing video output, disable xscreensaver */
157     /* http://www.jwz.org/xscreensaver/faq.html#dvd */
158     const char *const ppsz_xsargs[] = {
159         "xscreensaver-command", "-deactivate", (char*)NULL };
160     Execute (p_ih, ppsz_xsargs);
161
162     const char *const ppsz_gsargs[] = {
163         "gnome-screensaver-command", "--poke", (char*)NULL };
164     Execute (p_ih, ppsz_gsargs);
165 }