1
/*****************************************************************************
2
* inhibit.c : prevents the computer from suspending when VLC is playing
3
*****************************************************************************
4
* Copyright © 2007 Rafaël Carré
5
* $Id: b2c590fd471a9b4b3fd56e9000984d8f822cca03 $
7
* Author: Rafaël Carré <funman@videolanorg>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
*****************************************************************************/
25
* Based on freedesktop Power Management Specification version 0.2
26
* http://people.freedesktop.org/~hughsient/temp/power-management-spec-0.2.html
29
/*****************************************************************************
31
*****************************************************************************/
37
#include <vlc_common.h>
38
#include <vlc_plugin.h>
39
#include <vlc_input.h>
40
#include <vlc_interface.h>
42
#include <dbus/dbus.h>
44
#define PM_SERVICE "org.freedesktop.PowerManagement"
45
#define PM_PATH "/org/freedesktop/PowerManagement/Inhibit"
46
#define PM_INTERFACE "org.freedesktop.PowerManagement.Inhibit"
48
/*****************************************************************************
50
*****************************************************************************/
51
static int Activate ( vlc_object_t * );
52
static void Deactivate ( vlc_object_t * );
54
static void Run ( intf_thread_t *p_intf );
58
DBusConnection *p_conn;
59
dbus_uint32_t i_cookie;
62
/*****************************************************************************
64
*****************************************************************************/
66
set_description( N_("Power Management Inhibitor") );
67
set_capability( "interface", 0 );
68
set_callbacks( Activate, Deactivate );
71
/*****************************************************************************
72
* Activate: initialize and create stuff
73
*****************************************************************************/
74
static int Activate( vlc_object_t *p_this )
76
intf_thread_t *p_intf = (intf_thread_t*)p_this;
82
p_intf->p_sys = (intf_sys_t *) calloc( 1, sizeof( intf_sys_t ) );
87
p_intf->p_sys->i_cookie = 0;
89
dbus_error_init( &error );
90
p_intf->p_sys->p_conn = dbus_bus_get( DBUS_BUS_SESSION, &error );
91
if( !p_intf->p_sys->p_conn )
93
msg_Err( p_this, "Failed to connect to the D-Bus session daemon: %s",
95
dbus_error_free( &error );
96
free( p_intf->p_sys );
103
/*****************************************************************************
104
* Deactivate: uninitialize and cleanup
105
*****************************************************************************/
106
static void Deactivate( vlc_object_t *p_this )
108
intf_thread_t *p_intf = (intf_thread_t*)p_this;
109
dbus_connection_unref( p_intf->p_sys->p_conn );
110
free( p_intf->p_sys );
113
/*****************************************************************************
114
* Inhibit: Notify the power management daemon that it shouldn't suspend
115
* the computer because of inactivity
117
* returns false if Out of memory, else true
118
*****************************************************************************/
119
static int Inhibit( intf_thread_t *p_intf )
121
DBusConnection *p_conn;
123
DBusMessageIter args;
124
DBusMessage *p_reply;
126
dbus_error_init( &error );
127
dbus_uint32_t i_cookie;
129
p_conn = p_intf->p_sys->p_conn;
131
p_msg = dbus_message_new_method_call( PM_SERVICE, PM_PATH, PM_INTERFACE,
136
dbus_message_iter_init_append( p_msg, &args );
138
char *psz_app = strdup( PACKAGE );
139
if( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING, &psz_app ) )
142
dbus_message_unref( p_msg );
147
char *psz_inhibit_reason = strdup( "Playing some media." );
148
if( !psz_inhibit_reason )
150
dbus_message_unref( p_msg );
153
if( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING,
154
&psz_inhibit_reason ) )
156
free( psz_inhibit_reason );
157
dbus_message_unref( p_msg );
160
free( psz_inhibit_reason );
162
p_reply = dbus_connection_send_with_reply_and_block( p_conn, p_msg,
163
50, &error ); /* blocks 50ms maximum */
165
dbus_message_unref( p_msg );
166
if( p_reply == NULL )
167
{ /* g-p-m is not active, or too slow. Better luck next time? */
171
/* extract the cookie from the reply */
172
if( dbus_message_get_args( p_reply, &error,
173
DBUS_TYPE_UINT32, &i_cookie,
174
DBUS_TYPE_INVALID ) == FALSE )
179
/* Save the cookie */
180
p_intf->p_sys->i_cookie = i_cookie;
184
/*****************************************************************************
185
* UnInhibit: Notify the power management daemon that we aren't active anymore
187
* returns false if Out of memory, else true
188
*****************************************************************************/
189
static int UnInhibit( intf_thread_t *p_intf )
191
DBusConnection *p_conn;
193
DBusMessageIter args;
195
dbus_error_init( &error );
196
dbus_uint32_t i_cookie;
198
p_conn = p_intf->p_sys->p_conn;
200
p_msg = dbus_message_new_method_call( PM_SERVICE, PM_PATH, PM_INTERFACE,
205
dbus_message_iter_init_append( p_msg, &args );
207
i_cookie = p_intf->p_sys->i_cookie;
208
if( !dbus_message_iter_append_basic( &args, DBUS_TYPE_UINT32, &i_cookie ) )
210
dbus_message_unref( p_msg );
214
if( !dbus_connection_send( p_conn, p_msg, NULL ) )
216
dbus_connection_flush( p_conn );
218
dbus_message_unref( p_msg );
220
p_intf->p_sys->i_cookie = 0;
224
/*****************************************************************************
226
*****************************************************************************/
227
static void Run( intf_thread_t *p_intf )
229
vlc_object_lock( p_intf );
230
while( vlc_object_alive( p_intf ) )
232
input_thread_t *p_input;
234
/* Check playing state every 30 seconds */
235
vlc_object_timedwait( p_intf, mdate() + 30000000 );
237
p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
240
if( PLAYING_S == p_input->i_state && !p_intf->p_sys->i_cookie )
242
if( !Inhibit( p_intf ) )
244
vlc_object_release( p_input );
248
else if( p_intf->p_sys->i_cookie )
250
if( !UnInhibit( p_intf ) )
252
vlc_object_release( p_input );
256
vlc_object_release( p_input );
258
else if( p_intf->p_sys->i_cookie )
260
if( !UnInhibit( p_intf ) )
266
vlc_object_unlock( p_intf );