vlc | branch: master | Marvin Scholz <[email protected]> | Sat Mar 2 00:44:12 2019 +0100| [5fd031e33e6063afbd2bfb6e6f3f56f9a389ed6e] | committer: Thomas Guillem
misc: Add macOS IOKit inhibit module Signed-off-by: Thomas Guillem <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5fd031e33e6063afbd2bfb6e6f3f56f9a389ed6e --- modules/MODULES_LIST | 1 + modules/misc/Makefile.am | 6 ++ modules/misc/inhibit/iokit-inhibit.c | 156 +++++++++++++++++++++++++++++++++++ po/POTFILES.in | 1 + 4 files changed, 164 insertions(+) diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST index 0de973a9cc..bfbfae6e28 100644 --- a/modules/MODULES_LIST +++ b/modules/MODULES_LIST @@ -204,6 +204,7 @@ $Id$ * inflate: zlib decompression stream_filter module * integer_mixer: Integer audio mixer * invert: inverse video filter + * iokit_inhibit: macOS sleep inhibition with IOKit * jack: jack server audio output * jpeg: JPEG image decoder * kai: OS/2 audio output diff --git a/modules/misc/Makefile.am b/modules/misc/Makefile.am index 7848080109..506dacaa53 100644 --- a/modules/misc/Makefile.am +++ b/modules/misc/Makefile.am @@ -45,6 +45,12 @@ libsecuretransport_plugin_la_LDFLAGS += -Wl,-U,_SSLCopyALPNProtocols,-U,_SSLSetA misc_LTLIBRARIES += libsecuretransport_plugin.la endif +if HAVE_OSX +libiokit_inhibit_plugin_la_SOURCES = misc/inhibit/iokit-inhibit.c +libiokit_inhibit_plugin_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-framework,CoreFoundation,-framework,IOKit +misc_LTLIBRARIES += libiokit_inhibit_plugin.la +endif + libxdg_screensaver_plugin_la_SOURCES = misc/inhibit/xdg.c if HAVE_XCB misc_LTLIBRARIES += libxdg_screensaver_plugin.la diff --git a/modules/misc/inhibit/iokit-inhibit.c b/modules/misc/inhibit/iokit-inhibit.c new file mode 100644 index 0000000000..28ce1d94c2 --- /dev/null +++ b/modules/misc/inhibit/iokit-inhibit.c @@ -0,0 +1,156 @@ +/***************************************************************************** + * Copyright © 2018 VLC authors and VideoLAN + * + * Authors: Marvin Scholz <epirat07 at gmail dot com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/** + * \file iokit-inhibit.c + * \brief macOS display and idle sleep inhibitor using IOKit + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <vlc_common.h> +#include <vlc_plugin.h> +#include <vlc_inhibit.h> + +#include <IOKit/pwr_mgt/IOPMLib.h> + +struct vlc_inhibit_sys +{ + // Activity IOPMAssertion to wake the display if sleeping + IOPMAssertionID act_assertion_id; + + // Inhibition IOPMAssertion to keep display or machine from sleeping + IOPMAssertionID inh_assertion_id; +}; + +static void UpdateInhibit(vlc_inhibit_t *ih, unsigned mask) +{ + vlc_inhibit_sys_t* sys = ih->p_sys; + + // Release existing inhibition, if any + if (sys->inh_assertion_id != kIOPMNullAssertionID) { + msg_Dbg(ih, "Releasing previous IOPMAssertion"); + if (IOPMAssertionRelease(sys->inh_assertion_id) != kIOReturnSuccess) { + msg_Err(ih, "Failed releasing previous IOPMAssertion, " + "not acquiring new one!"); + } + } + + // Order is important here, if we prevent display sleep, it means + // we automatically prevent idle sleep too. + + IOReturn ret; + if ((mask & VLC_INHIBIT_DISPLAY) == VLC_INHIBIT_DISPLAY) { + + // Display inhibition + CFStringRef activity_reason = CFSTR("VLC video playback"); + + msg_Dbg(ih, "Inhibiting display sleep"); + + // Wake up display + ret = IOPMAssertionDeclareUserActivity(activity_reason, + kIOPMUserActiveLocal, + &(sys->act_assertion_id)); + if (ret != kIOReturnSuccess) { + msg_Warn(ih, "Failed to declare user activity (%i)", ret); + } + + // Actual display inhibition assertion + ret = IOPMAssertionCreateWithName(kIOPMAssertPreventUserIdleDisplaySleep, + kIOPMAssertionLevelOn, + activity_reason, + &(sys->inh_assertion_id)); + + } else if ((mask & VLC_INHIBIT_SUSPEND) == VLC_INHIBIT_SUSPEND) { + + // Idle sleep inhibition + CFStringRef activity_reason = CFSTR("VLC audio playback"); + + msg_Dbg(ih, "Inhibiting idle sleep"); + + ret = IOPMAssertionCreateWithName(kIOPMAssertPreventUserIdleSystemSleep, + kIOPMAssertionLevelOn, + activity_reason, + &(sys->inh_assertion_id)); + + } else { + msg_Warn(ih, "Unhandled inhibiton mask (%i)", mask); + return; + } + + if (ret != kIOReturnSuccess) { + msg_Err(ih, "Failed creating IOPMAssertion (%i)", ret); + return; + } +} + +static int OpenInhibit(vlc_object_t *obj) +{ + vlc_inhibit_t *ih = (vlc_inhibit_t *)obj; + + // Intialize module private storage + vlc_inhibit_sys_t *sys = ih->p_sys = + vlc_obj_malloc(obj, sizeof(vlc_inhibit_sys_t)); + if (unlikely(ih->p_sys == NULL)) + return VLC_ENOMEM; + + sys->act_assertion_id = kIOPMNullAssertionID; + sys->inh_assertion_id = kIOPMNullAssertionID; + + ih->inhibit = UpdateInhibit; + return VLC_SUCCESS; +} + +static void CloseInhibit(vlc_object_t *obj) +{ + vlc_inhibit_t *ih = (vlc_inhibit_t*)obj; + vlc_inhibit_sys_t* sys = ih->p_sys; + + // Release remaining IOPMAssertion for inhibition, if any + if (sys->inh_assertion_id != kIOPMNullAssertionID) { + msg_Dbg(ih, "Releasing remaining IOPMAssertion (inhibition)"); + + if (IOPMAssertionRelease(sys->inh_assertion_id) != kIOReturnSuccess) { + msg_Warn(ih, "Failed releasing IOPMAssertion on termination"); + } + sys->inh_assertion_id = kIOPMNullAssertionID; + } + + // Release remaining IOPMAssertion for activity, if any + if (sys->act_assertion_id != kIOPMNullAssertionID) { + msg_Dbg(ih, "Releasing remaining IOPMAssertion (activity)"); + + if (IOPMAssertionRelease(sys->act_assertion_id) != kIOReturnSuccess) { + msg_Warn(ih, "Failed releasing IOPMAssertion on termination"); + } + sys->act_assertion_id = kIOPMNullAssertionID; + } +} + +vlc_module_begin() + set_shortname(N_("macOS sleep inhibition")) + set_description(N_("macOS screen and idle sleep inhibition")) + set_category(CAT_ADVANCED) + set_subcategory(SUBCAT_ADVANCED_MISC) + set_capability("inhibit", 10) + set_callbacks(OpenInhibit, CloseInhibit) +vlc_module_end() diff --git a/po/POTFILES.in b/po/POTFILES.in index 746aa430b3..96d7a0254e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1043,6 +1043,7 @@ modules/misc/audioscrobbler.c modules/misc/fingerprinter.c modules/misc/gnutls.c modules/misc/inhibit/dbus.c +modules/misc/inhibit/iokit-inhibit.c modules/misc/inhibit/wl-idle-inhibit.c modules/misc/inhibit/xdg.c modules/misc/medialibrary/medialib.cpp _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
