From d88d1e3f30fee6e93a8285bd157db666cd1455c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= <remi@remlab.net> Date: Sat, 19 May 2018 19:57:53 +0300 Subject: [PATCH] wl-idle-inhibit: add Wayland idle inhibitor --- include/vlc_inhibit.h | 7 ++ modules/MODULES_LIST | 1 + modules/misc/Makefile.am | 21 ++++ modules/misc/inhibit/wl-idle-inhibit.c | 152 +++++++++++++++++++++++++ po/POTFILES.in | 1 + 5 files changed, 182 insertions(+) create mode 100644 modules/misc/inhibit/wl-idle-inhibit.c diff --git a/include/vlc_inhibit.h b/include/vlc_inhibit.h index 73fb0b3835f9..00abfab0bd71 100644 --- a/include/vlc_inhibit.h +++ b/include/vlc_inhibit.h @@ -29,6 +29,8 @@ typedef struct vlc_inhibit vlc_inhibit_t; typedef struct vlc_inhibit_sys vlc_inhibit_sys_t; +struct vout_window_t; + enum vlc_inhibit_flags { VLC_INHIBIT_NONE=0 /*< No inhibition */, @@ -46,6 +48,11 @@ struct vlc_inhibit void (*inhibit) (vlc_inhibit_t *, unsigned flags); }; +static inline struct vout_window_t *vlc_inhibit_GetWindow(vlc_inhibit_t *ih) +{ + return (struct vout_window_t *)(ih->obj.parent); +} + static inline void vlc_inhibit_Set (vlc_inhibit_t *ih, unsigned flags) { ih->inhibit (ih, flags); diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST index 0cc554651c93..04ac47df066c 100644 --- a/modules/MODULES_LIST +++ b/modules/MODULES_LIST @@ -462,6 +462,7 @@ $Id$ * wingdi: WIN 32 / WIN CE GDI video output * winhibit: Win32 screensaver inhibition * winstore: Windows Store App audio output + * wl_idle_inhibit: Wayland idle inhibitor * wl_screenshooter: Wayland screen capture input * wl_shell: Wayland shell surface window provider * wl_shm: Wayland shared memory video output diff --git a/modules/misc/Makefile.am b/modules/misc/Makefile.am index b5a8db5379cd..90e72a00b84d 100644 --- a/modules/misc/Makefile.am +++ b/modules/misc/Makefile.am @@ -58,6 +58,27 @@ if HAVE_DBUS misc_LTLIBRARIES += libdbus_screensaver_plugin.la endif +libwl_idle_inhibit_plugin_la_SOURCES = misc/inhibit/wl-idle-inhibit.c +nodist_libwl_idle_inhibit_plugin_la_SOURCES = \ + misc/inhibit/idle-inhibit-client-protocol.h \ + misc/inhibit/idle-inhibit-protocol.c +libwl_idle_inhibit_plugin_la_CFLAGS = $(WAYLAND_CLIENT_CFLAGS) +libwl_idle_inhibit_plugin_la_LIBADD = $(WAYLAND_CLIENT_LIBS) +if HAVE_WAYLAND +misc_LTLIBRARIES += libwl_idle_inhibit_plugin.la +BUILT_SOURCES += $(nodist_libwl_idle_inhibit_plugin_la_SOURCES) +endif + +misc/inhibit/idle-inhibit-client-protocol.h: \ + $(WAYLAND_PROTOCOLS)/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml \ + misc/Makefile.am + $(AM_V_GEN)$(WAYLAND_SCANNER) client-header $< $@ + +misc/inhibit/idle-inhibit-protocol.c: \ + $(WAYLAND_PROTOCOLS)/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml \ + misc/Makefile.am + $(AM_V_GEN)$(WAYLAND_SCANNER) private-code $< $@ + libaddonsvorepository_plugin_la_SOURCES = \ misc/addons/vorepository.c misc/addons/xmlreading.h libaddonsfsstorage_plugin_la_SOURCES = \ diff --git a/modules/misc/inhibit/wl-idle-inhibit.c b/modules/misc/inhibit/wl-idle-inhibit.c new file mode 100644 index 000000000000..269c8bfdc2e3 --- /dev/null +++ b/modules/misc/inhibit/wl-idle-inhibit.c @@ -0,0 +1,152 @@ +/** + * @file idle-inhibit.c + * @brief Wayland idle inhibitor module for VLC media player + */ +/***************************************************************************** + * Copyright © 2018 Rémi Denis-Courmont + * + * 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. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <wayland-client.h> +#include "misc/inhibit/idle-inhibit-client-protocol.h" + +#include <vlc_common.h> +#include <vlc_plugin.h> +#include <vlc_vout_window.h> +#include <vlc_inhibit.h> + +struct vlc_inhibit_sys +{ + struct wl_event_queue *eventq; + struct zwp_idle_inhibit_manager_v1 *manager; + struct zwp_idle_inhibitor_v1 *inhibitor; +}; + +static void Inhibit (vlc_inhibit_t *ih, unsigned mask) +{ + vout_window_t *wnd = vlc_inhibit_GetWindow(ih); + vlc_inhibit_sys_t *sys = ih->p_sys; + bool suspend = (mask & VLC_INHIBIT_DISPLAY) != 0; + + if (sys->inhibitor != NULL) { + zwp_idle_inhibitor_v1_destroy(sys->inhibitor); + sys->inhibitor = NULL; + } + + if (suspend) + sys->inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor( + sys->manager, wnd->handle.wl); + +} + +static void registry_global_cb(void *data, struct wl_registry *registry, + uint32_t name, const char *iface, uint32_t vers) +{ + vlc_inhibit_t *ih = data; + vlc_inhibit_sys_t *sys = ih->p_sys; + + if (!strcmp(iface, "zwp_idle_inhibit_manager_v1")) + sys->manager = wl_registry_bind(registry, name, + &zwp_idle_inhibit_manager_v1_interface, 1); + (void) vers; +} + +static void registry_global_remove_cb(void *data, struct wl_registry *registry, + uint32_t name) +{ + (void) data; (void) registry; (void) name; +} + +static const struct wl_registry_listener registry_cbs = +{ + registry_global_cb, + registry_global_remove_cb, +}; + +static int Open(vlc_object_t *obj) +{ + vlc_inhibit_t *ih = (vlc_inhibit_t *)obj; + vout_window_t *wnd = vlc_inhibit_GetWindow(ih); + + if (wnd->type != VOUT_WINDOW_TYPE_WAYLAND) + return VLC_EGENERIC; + + vlc_inhibit_sys_t *sys = vlc_obj_malloc(obj, sizeof (*sys)); + if (unlikely(sys == NULL)) + return VLC_ENOMEM; + + sys->manager = NULL; + sys->inhibitor = NULL; + ih->p_sys = sys; + + struct wl_display *display = wnd->display.wl; + + sys->eventq = wl_display_create_queue(display); + if (sys->eventq == NULL) + return VLC_ENOMEM; + + struct wl_registry *registry = wl_display_get_registry(display); + if (registry == NULL) + goto error; + + wl_registry_add_listener(registry, ®istry_cbs, ih); + wl_proxy_set_queue((struct wl_proxy *)registry, sys->eventq); + wl_display_roundtrip_queue(display, sys->eventq); + wl_registry_destroy(registry); + + if (sys->manager == NULL) + goto error; + + ih->inhibit = Inhibit; + return VLC_SUCCESS; + +error: + if (sys->eventq != NULL) + wl_event_queue_destroy(sys->eventq); + return VLC_EGENERIC; +} + +static void Close(vlc_object_t *obj) +{ + vlc_inhibit_t *ih = (vlc_inhibit_t *)obj; + vlc_inhibit_sys_t *sys = ih->p_sys; + vout_window_t *wnd = vlc_inhibit_GetWindow(ih); + + if (sys->inhibitor != NULL) + zwp_idle_inhibitor_v1_destroy(sys->inhibitor); + + zwp_idle_inhibit_manager_v1_destroy(sys->manager); + wl_display_flush(wnd->display.wl); + wl_event_queue_destroy(sys->eventq); +} + +vlc_module_begin() + set_shortname(N_("WL idle")) + set_description(N_("Wayland idle inhibitor")) + set_category(CAT_ADVANCED) + set_subcategory(SUBCAT_ADVANCED_MISC) + set_capability("inhibit", 30) + set_callbacks(Open, Close) +vlc_module_end() diff --git a/po/POTFILES.in b/po/POTFILES.in index f0bda3384850..a2dbb435e725 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -990,6 +990,7 @@ modules/misc/audioscrobbler.c modules/misc/fingerprinter.c modules/misc/gnutls.c modules/misc/inhibit/dbus.c +modules/misc/inhibit/wl-idle-inhibit.c modules/misc/inhibit/xdg.c modules/misc/logger.c modules/misc/playlist/export.c -- GitLab