diff --git a/packages/mediacenter/xbmc/patches/12.2-e40d13d/xbmc-990.10-PR2971.patch b/packages/mediacenter/xbmc/patches/12.2-e40d13d/xbmc-990.10-PR2971.patch new file mode 100644 index 0000000000..e0539c14cd --- /dev/null +++ b/packages/mediacenter/xbmc/patches/12.2-e40d13d/xbmc-990.10-PR2971.patch @@ -0,0 +1,582 @@ +diff -Naur xbmc-12.2-e40d13d/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp +--- xbmc-12.2-e40d13d/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp 2013-08-05 10:02:45.904395105 +0200 +@@ -0,0 +1,302 @@ ++/* ++ * Copyright (C) 2012 Denis Yantarev ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://www.xbmc.org ++ * ++ * 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, 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 XBMC; see the file COPYING. If not, write to ++ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++ * http://www.gnu.org/copyleft/gpl.html ++ * ++ */ ++ ++#include "system.h" ++#include "LogindUPowerSyscall.h" ++#include "utils/log.h" ++ ++#ifdef HAS_DBUS ++ ++// logind DBus interface specification: ++// http://www.freedesktop.org/wiki/Software/Logind/logind ++// ++// Inhibitor Locks documentation: ++// http://www.freedesktop.org/wiki/Software/Logind/inhibit/ ++ ++#define LOGIND_DEST "org.freedesktop.login1" ++#define LOGIND_PATH "/org/freedesktop/login1" ++#define LOGIND_IFACE "org.freedesktop.login1.Manager" ++ ++CLogindUPowerSyscall::CLogindUPowerSyscall() ++{ ++ CLog::Log(LOGINFO, "Selected Logind/UPower as PowerSyscall"); ++ ++ // Check if we have UPower. If not, we avoid any battery related operations. ++ CDBusMessage message("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "EnumerateDevices"); ++ m_hasUPower = message.SendSystem() != NULL; ++ ++ if (!m_hasUPower) ++ CLog::Log(LOGINFO, "LogindUPowerSyscall - UPower not found, battery information will not be available"); ++ ++ m_canPowerdown = LogindCheckCapability("CanPowerOff"); ++ m_canReboot = LogindCheckCapability("CanReboot"); ++ m_canHibernate = LogindCheckCapability("CanHibernate"); ++ m_canSuspend = LogindCheckCapability("CanSuspend"); ++ ++ InhibitDelayLock(); ++ ++ m_batteryLevel = 0; ++ if (m_hasUPower) ++ UpdateBatteryLevel(); ++ ++ DBusError error; ++ dbus_error_init(&error); ++ m_connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); ++ ++ if (dbus_error_is_set(&error)) ++ { ++ CLog::Log(LOGERROR, "LogindUPowerSyscall: Failed to get dbus connection: %s", error.message); ++ dbus_connection_close(m_connection); ++ dbus_connection_unref(m_connection); ++ m_connection = NULL; ++ dbus_error_free(&error); ++ return; ++ } ++ ++ dbus_connection_set_exit_on_disconnect(m_connection, false); ++ dbus_bus_add_match(m_connection, "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForSleep'", NULL); ++ ++ if (m_hasUPower) ++ dbus_bus_add_match(m_connection, "type='signal',interface='org.freedesktop.UPower',member='DeviceChanged'", NULL); ++ ++ dbus_connection_flush(m_connection); ++ dbus_error_free(&error); ++} ++ ++CLogindUPowerSyscall::~CLogindUPowerSyscall() ++{ ++ if (m_connection) ++ { ++ dbus_connection_close(m_connection); ++ dbus_connection_unref(m_connection); ++ } ++ ++ ReleaseDelayLock(); ++} ++ ++bool CLogindUPowerSyscall::Powerdown() ++{ ++ return LogindSetPowerState("PowerOff"); ++} ++ ++bool CLogindUPowerSyscall::Reboot() ++{ ++ return LogindSetPowerState("Reboot"); ++} ++ ++bool CLogindUPowerSyscall::Suspend() ++{ ++ return LogindSetPowerState("Suspend"); ++} ++ ++bool CLogindUPowerSyscall::Hibernate() ++{ ++ return LogindSetPowerState("Hibernate"); ++} ++ ++bool CLogindUPowerSyscall::CanPowerdown() ++{ ++ return m_canPowerdown; ++} ++ ++bool CLogindUPowerSyscall::CanSuspend() ++{ ++ return m_canSuspend; ++} ++ ++bool CLogindUPowerSyscall::CanHibernate() ++{ ++ return m_canHibernate; ++} ++ ++bool CLogindUPowerSyscall::CanReboot() ++{ ++ return m_canReboot; ++} ++ ++bool CLogindUPowerSyscall::HasLogind() ++{ ++ // recommended method by systemd devs. The seats directory ++ // doesn't exist unless logind created it and therefore is running. ++ // see also https://mail.gnome.org/archives/desktop-devel-list/2013-March/msg00092.html ++ return (access("/run/systemd/seats/", F_OK) >= 0); ++} ++ ++bool CLogindUPowerSyscall::LogindSetPowerState(const char *state) ++{ ++ CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, state); ++ // The user_interaction boolean parameters can be used to control ++ // wether PolicyKit should interactively ask the user for authentication ++ // credentials if it needs to. ++ message.AppendArgument(false); ++ return message.SendSystem() != NULL; ++} ++ ++bool CLogindUPowerSyscall::LogindCheckCapability(const char *capability) ++{ ++ char *arg; ++ CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, capability); ++ DBusMessage *reply = message.SendSystem(); ++ if(reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID)) ++ { ++ // Returns one of "yes", "no" or "challenge". If "challenge" is ++ // returned the operation is available, but only after authorization. ++ return (strcmp(arg, "yes") == 0); ++ } ++ return false; ++} ++ ++int CLogindUPowerSyscall::BatteryLevel() ++{ ++ return m_batteryLevel; ++} ++ ++void CLogindUPowerSyscall::UpdateBatteryLevel() ++{ ++ char** source = NULL; ++ int length = 0; ++ double batteryLevelSum = 0; ++ int batteryCount = 0; ++ ++ CDBusMessage message("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "EnumerateDevices"); ++ DBusMessage *reply = message.SendSystem(); ++ ++ if (!reply) ++ return; ++ ++ if (!dbus_message_get_args(reply, NULL, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &source, &length, DBUS_TYPE_INVALID)) ++ { ++ CLog::Log(LOGWARNING, "LogindUPowerSyscall: failed to enumerate devices"); ++ return; ++ } ++ ++ for (int i = 0; i < length; i++) ++ { ++ CVariant properties = CDBusUtil::GetAll("org.freedesktop.UPower", source[i], "org.freedesktop.UPower.Device"); ++ bool isRechargeable = properties["IsRechargeable"].asBoolean(); ++ ++ if (isRechargeable) ++ { ++ batteryCount++; ++ batteryLevelSum += properties["Percentage"].asDouble(); ++ } ++ } ++ ++ dbus_free_string_array(source); ++ ++ if (batteryCount > 0) ++ m_batteryLevel = (int)(batteryLevelSum / (double)batteryCount); ++ ++ m_lowBattery = CDBusUtil::GetVariant("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "OnLowBattery").asBoolean(); ++} ++ ++bool CLogindUPowerSyscall::PumpPowerEvents(IPowerEventsCallback *callback) ++{ ++ bool result = false; ++ bool releaseLock = false; ++ ++ if (m_connection) ++ { ++ dbus_connection_read_write(m_connection, 0); ++ DBusMessage *msg = dbus_connection_pop_message(m_connection); ++ ++ if (msg) ++ { ++ if (dbus_message_is_signal(msg, "org.freedesktop.login1.Manager", "PrepareForSleep")) ++ { ++ bool arg; ++ // the boolean argument defines whether we are going to sleep (true) or just woke up (false) ++ dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &arg, DBUS_TYPE_INVALID); ++ CLog::Log(LOGDEBUG, "LogindUPowerSyscall: Received PrepareForSleep with arg %i", arg); ++ if (arg) ++ { ++ callback->OnSleep(); ++ releaseLock = true; ++ } ++ else ++ { ++ callback->OnWake(); ++ InhibitDelayLock(); ++ } ++ ++ result = true; ++ } ++ else if (dbus_message_is_signal(msg, "org.freedesktop.UPower", "DeviceChanged")) ++ { ++ bool lowBattery = m_lowBattery; ++ UpdateBatteryLevel(); ++ if (m_lowBattery && !lowBattery) ++ callback->OnLowBattery(); ++ ++ result = true; ++ } ++ else ++ CLog::Log(LOGDEBUG, "LogindUPowerSyscall - Received unknown signal %s", dbus_message_get_member(msg)); ++ ++ dbus_message_unref(msg); ++ } ++ } ++ ++ if (releaseLock) ++ ReleaseDelayLock(); ++ ++ return result; ++} ++ ++void CLogindUPowerSyscall::InhibitDelayLock() ++{ ++ CDBusMessage message("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "Inhibit"); ++ message.AppendArgument("sleep"); // what to inhibit ++ message.AppendArgument("XBMC"); // who ++ message.AppendArgument(""); // reason ++ message.AppendArgument("delay"); // mode ++ ++ DBusMessage *reply = message.SendSystem(); ++ ++ if (!reply) ++ { ++ CLog::Log(LOGWARNING, "LogindUPowerSyscall - failed to inhibit sleep delay lock"); ++ m_delayLockFd = -1; ++ return; ++ } ++ ++ if (!dbus_message_get_args(reply, NULL, DBUS_TYPE_UNIX_FD, &m_delayLockFd, DBUS_TYPE_INVALID)) ++ { ++ CLog::Log(LOGWARNING, "LogindUPowerSyscall - failed to get inhibit file descriptor"); ++ m_delayLockFd = -1; ++ return; ++ } ++ ++ CLog::Log(LOGDEBUG, "LogindUPowerSyscall - inhibit lock taken, fd %i", m_delayLockFd); ++} ++ ++void CLogindUPowerSyscall::ReleaseDelayLock() ++{ ++ if (m_delayLockFd != -1) ++ { ++ close(m_delayLockFd); ++ m_delayLockFd = -1; ++ CLog::Log(LOGDEBUG, "LogindUPowerSyscall - delay lock released"); ++ } ++} ++ ++#endif +diff -Naur xbmc-12.2-e40d13d/xbmc/powermanagement/linux/LogindUPowerSyscall.h xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/LogindUPowerSyscall.h +--- xbmc-12.2-e40d13d/xbmc/powermanagement/linux/LogindUPowerSyscall.h 1970-01-01 01:00:00.000000000 +0100 ++++ xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/LogindUPowerSyscall.h 2013-08-05 10:02:45.905395106 +0200 +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) 2012 Denis Yantarev ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * 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, 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 XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#ifdef HAS_DBUS ++ ++#include "powermanagement/IPowerSyscall.h" ++#include "DBusUtil.h" ++ ++class CLogindUPowerSyscall : public IPowerSyscall ++{ ++public: ++ CLogindUPowerSyscall(); ++ ~CLogindUPowerSyscall(); ++ virtual bool Powerdown(); ++ virtual bool Suspend(); ++ virtual bool Hibernate(); ++ virtual bool Reboot(); ++ virtual bool CanPowerdown(); ++ virtual bool CanSuspend(); ++ virtual bool CanHibernate(); ++ virtual bool CanReboot(); ++ virtual int BatteryLevel(); ++ virtual bool PumpPowerEvents(IPowerEventsCallback *callback); ++ // we don't require UPower because everything except the battery level works fine without it ++ static bool HasLogind(); ++private: ++ DBusConnection *m_connection; ++ bool m_canPowerdown; ++ bool m_canSuspend; ++ bool m_canHibernate; ++ bool m_canReboot; ++ bool m_hasUPower; ++ bool m_lowBattery; ++ int m_batteryLevel; ++ int m_delayLockFd; // file descriptor for the logind sleep delay lock ++ void UpdateBatteryLevel(); ++ void InhibitDelayLock(); ++ void ReleaseDelayLock(); ++ static bool LogindSetPowerState(const char *state); ++ static bool LogindCheckCapability(const char *capability); ++}; ++ ++#endif +diff -Naur xbmc-12.2-e40d13d/xbmc/powermanagement/linux/Makefile xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/Makefile +--- xbmc-12.2-e40d13d/xbmc/powermanagement/linux/Makefile 2013-07-30 13:29:21.000000000 +0200 ++++ xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/Makefile 2013-08-05 10:02:45.905395106 +0200 +@@ -2,7 +2,7 @@ + ConsoleUPowerSyscall.cpp \ + HALPowerSyscall.cpp \ + UPowerSyscall.cpp \ +- SystemdUPowerSyscall.cpp ++ LogindUPowerSyscall.cpp + + LIB=powermanagement_linux.a + +diff -Naur xbmc-12.2-e40d13d/xbmc/powermanagement/linux/SystemdUPowerSyscall.cpp xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/SystemdUPowerSyscall.cpp +--- xbmc-12.2-e40d13d/xbmc/powermanagement/linux/SystemdUPowerSyscall.cpp 2013-07-30 13:29:21.000000000 +0200 ++++ xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/SystemdUPowerSyscall.cpp 1970-01-01 01:00:00.000000000 +0100 +@@ -1,125 +0,0 @@ +-/* +- * Copyright (C) 2012 Denis Yantarev +- * Copyright (C) 2005-2009 Team XBMC +- * http://www.xbmc.org +- * +- * 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, 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 XBMC; see the file COPYING. If not, write to +- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +- * http://www.gnu.org/copyleft/gpl.html +- * +- */ +- +-#include "system.h" +-#include "SystemdUPowerSyscall.h" +-#include "utils/log.h" +- +-#ifdef HAS_DBUS +-#include "Application.h" +- +-// logind DBus interface specification: +-// http://www.freedesktop.org/wiki/Software/systemd/logind +- +-#define LOGIND_DEST "org.freedesktop.login1" +-#define LOGIND_PATH "/org/freedesktop/login1" +-#define LOGIND_IFACE "org.freedesktop.login1.Manager" +- +-CSystemdUPowerSyscall::CSystemdUPowerSyscall() +-{ +- UpdateCapabilities(); +-} +- +-bool CSystemdUPowerSyscall::Powerdown() +-{ +- return SystemdSetPowerState("PowerOff"); +-} +- +-bool CSystemdUPowerSyscall::Reboot() +-{ +- return SystemdSetPowerState("Reboot"); +-} +- +-bool CSystemdUPowerSyscall::Suspend() +-{ +- return SystemdSetPowerState("Suspend"); +-} +- +-bool CSystemdUPowerSyscall::Hibernate() +-{ +- return SystemdSetPowerState("Hibernate"); +-} +- +-void CSystemdUPowerSyscall::UpdateCapabilities() +-{ +- m_CanPowerdown = SystemdCheckCapability("CanPowerOff"); +- m_CanReboot = SystemdCheckCapability("CanReboot"); +- m_CanHibernate = SystemdCheckCapability("CanHibernate"); +- m_CanSuspend = SystemdCheckCapability("CanSuspend"); +-} +- +-bool CSystemdUPowerSyscall::HasSystemdAndUPower() +-{ +- DBusConnection *con; +- DBusError error; +- bool hasSystemd = false; +- +- dbus_error_init(&error); +- con = dbus_bus_get(DBUS_BUS_SYSTEM, &error); +- +- if(dbus_error_is_set(&error)) +- { +- CLog::Log(LOGDEBUG, "SystemdUPowerSyscall: %s: %s", error.name, error.message); +- dbus_error_free(&error); +- return false; +- } +- +- CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, "CanPowerOff"); +- message.Send(con, &error); +- +- if(!dbus_error_is_set(&error)) +- hasSystemd = true; +- else +- CLog::Log(LOGDEBUG, "Systemd error: %s: %s", error.name, error.message); +- +- dbus_error_free(&error); +- +- return HasUPower() && hasSystemd; +-} +- +-bool CSystemdUPowerSyscall::SystemdSetPowerState(const char *state) +-{ +- bool arg = false; +- CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, state); +- // The user_interaction boolean parameters can be used to control +- // wether PolicyKit should interactively ask the user for authentication +- // credentials if it needs to. +- message.AppendArgument(arg); +- return message.SendSystem() != NULL; +-} +- +-bool CSystemdUPowerSyscall::SystemdCheckCapability(const char *capability) +-{ +- bool result = false; +- char *arg; +- CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, capability); +- DBusMessage *reply = message.SendSystem(); +- if(reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID)) +- { +- // Returns one of "yes", "no" or "challenge". If "challenge" is +- // returned the operation is available, but only after authorization. +- result = (strcmp(arg, "yes") == 0); +- } +- return result; +-} +- +-#endif +diff -Naur xbmc-12.2-e40d13d/xbmc/powermanagement/linux/SystemdUPowerSyscall.h xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/SystemdUPowerSyscall.h +--- xbmc-12.2-e40d13d/xbmc/powermanagement/linux/SystemdUPowerSyscall.h 2013-07-30 13:29:21.000000000 +0200 ++++ xbmc-12.2-e40d13d.patch/xbmc/powermanagement/linux/SystemdUPowerSyscall.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,43 +0,0 @@ +-/* +- * Copyright (C) 2012 Denis Yantarev +- * Copyright (C) 2005-2009 Team XBMC +- * http://www.xbmc.org +- * +- * 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, 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 XBMC; see the file COPYING. If not, write to +- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +- * http://www.gnu.org/copyleft/gpl.html +- * +- */ +- +-#ifdef HAS_DBUS +- +-#include "UPowerSyscall.h" +- +-class CSystemdUPowerSyscall : public CUPowerSyscall +-{ +-public: +- CSystemdUPowerSyscall(); +- virtual bool Powerdown(); +- virtual bool Suspend(); +- virtual bool Hibernate(); +- virtual bool Reboot(); +- static bool HasSystemdAndUPower(); +-protected: +- void UpdateCapabilities(); +-private: +- static bool SystemdSetPowerState(const char *state); +- static bool SystemdCheckCapability(const char *capability); +-}; +- +-#endif +diff -Naur xbmc-12.2-e40d13d/xbmc/powermanagement/PowerManager.cpp xbmc-12.2-e40d13d.patch/xbmc/powermanagement/PowerManager.cpp +--- xbmc-12.2-e40d13d/xbmc/powermanagement/PowerManager.cpp 2013-07-30 13:29:21.000000000 +0200 ++++ xbmc-12.2-e40d13d.patch/xbmc/powermanagement/PowerManager.cpp 2013-08-05 10:02:45.904395105 +0200 +@@ -46,7 +46,7 @@ + #if defined(HAS_DBUS) + #include "linux/ConsoleUPowerSyscall.h" + #include "linux/ConsoleDeviceKitPowerSyscall.h" +-#include "linux/SystemdUPowerSyscall.h" ++#include "linux/LogindUPowerSyscall.h" + #include "linux/UPowerSyscall.h" + #if defined(HAS_HAL) + #include "linux/HALPowerSyscall.h" +@@ -83,8 +83,8 @@ + m_instance = new CConsoleUPowerSyscall(); + else if (CConsoleDeviceKitPowerSyscall::HasDeviceConsoleKit()) + m_instance = new CConsoleDeviceKitPowerSyscall(); +- else if (CSystemdUPowerSyscall::HasSystemdAndUPower()) +- m_instance = new CSystemdUPowerSyscall(); ++ else if (CLogindUPowerSyscall::HasLogind()) ++ m_instance = new CLogindUPowerSyscall(); + else if (CUPowerSyscall::HasUPower()) + m_instance = new CUPowerSyscall(); + #if defined(HAS_HAL)