1 /*****************************************************************************
2 * power.c : prevents the computer from suspending when VLC is playing
3 *****************************************************************************
4 * Copyright © 2009-2011 Rémi Denis-Courmont
5 * Copyright © 2007-2012 Rafaël Carré
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20 *****************************************************************************/
23 * Based on freedesktop Power Management Specification version 0.2
24 * http://people.freedesktop.org/~hughsient/temp/power-management-spec-0.2.html
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_inhibit.h>
34 #include <dbus/dbus.h>
38 FREEDESKTOP, /* KDE and GNOME <= 2.26 */
39 GNOME, /**< GNOME 2.26..3.4 */
42 static const char dbus_service[][32] =
44 [FREEDESKTOP] = "org.freedesktop.PowerManagement",
45 [GNOME] = "org.gnome.SessionManager",
48 static const char dbus_path[][33] =
50 [FREEDESKTOP] = "/org/freedesktop/PowerManagement",
51 [GNOME] = "/org/gnome/SessionManager",
54 static const char dbus_interface[][40] =
56 [FREEDESKTOP] = "org.freedesktop.PowerManagement.Inhibit",
57 [GNOME] = "org.gnome.SessionManager",
60 static const char dbus_method_uninhibit[][10] =
62 [FREEDESKTOP] = "UnInhibit",
63 [GNOME] = "Uninhibit",
66 struct vlc_inhibit_sys
69 dbus_uint32_t cookie[2];
72 static void InhibitAPI(vlc_inhibit_t *ih, unsigned flags,
73 enum vlc_inhibit_api type)
75 vlc_inhibit_sys_t *sys = ih->p_sys;
76 DBusConnection *conn = sys->conn;
78 const char *method = flags ? "Inhibit" : dbus_method_uninhibit[type];
81 DBusMessage *msg = dbus_message_new_method_call(dbus_service[type],
82 dbus_path[type], dbus_interface[type], method);
83 if (unlikely(msg == NULL))
87 const char *app = PACKAGE;
88 const char *reason = N_("Playing some media.");
93 ret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &app,
94 DBUS_TYPE_STRING, &reason,
99 dbus_uint32_t xid = 0; // FIXME ?
100 dbus_uint32_t gflags =
101 ((flags & VLC_INHIBIT_SUSPEND) ? 8 : 0) |
102 ((flags & VLC_INHIBIT_DISPLAY) ? 4 : 0);
104 ret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &app,
105 DBUS_TYPE_UINT32, &xid,
106 DBUS_TYPE_STRING, &reason,
107 DBUS_TYPE_UINT32, &gflags,
113 if (sys->cookie[type])
114 ret = dbus_message_append_args(msg, DBUS_TYPE_UINT32,
124 if (flags) { /* read reply */
125 DBusMessage *reply = dbus_connection_send_with_reply_and_block(
126 conn, msg, 50, NULL);
127 if (unlikely(reply == NULL))
128 goto giveup; /* no reponse?! */
130 if (!dbus_message_get_args(reply, NULL,
131 DBUS_TYPE_UINT32, &sys->cookie[type],
133 sys->cookie[type] = 0;
135 dbus_message_unref(reply);
136 } else { /* just send and flush */
137 if (dbus_connection_send (conn, msg, NULL)) {
138 sys->cookie[type] = 0;
139 dbus_connection_flush(conn);
143 dbus_message_unref(msg);
146 static void Inhibit (vlc_inhibit_t *ih, unsigned flags)
148 for (int type = 0; type < 2; type++)
149 InhibitAPI (ih, flags, type);
152 static int Open (vlc_object_t *obj)
154 vlc_inhibit_t *ih = (vlc_inhibit_t *)obj;
155 vlc_inhibit_sys_t *sys = malloc (sizeof (*sys));
156 if (unlikely(sys == NULL))
161 dbus_error_init (&err);
162 sys->conn = dbus_bus_get_private (DBUS_BUS_SESSION, &err);
163 if (sys->conn == NULL)
165 msg_Err (obj, "cannot connect to session bus: %s", err.message);
166 dbus_error_free (&err);
174 ih->inhibit = Inhibit;
178 static void Close (vlc_object_t *obj)
180 vlc_inhibit_t *ih = (vlc_inhibit_t *)obj;
181 vlc_inhibit_sys_t *sys = ih->p_sys;
183 dbus_connection_close (sys->conn);
184 dbus_connection_unref (sys->conn);
192 set_shortname (N_("Power"))
193 set_description (N_("Inhibits power suspend and session idle timeout."))
194 set_category (CAT_ADVANCED)
195 set_subcategory (SUBCAT_ADVANCED_MISC)
196 set_capability ("inhibit", 20)
197 set_callbacks (Open, Close)