Commit 778460dc authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

xdg: use timer based reset instead of window ID

This is required to remove the dependency on the window provider.
parent b8f04c94
......@@ -26,6 +26,7 @@
#include <vlc_plugin.h>
#include <vlc_inhibit.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <spawn.h>
#include <sys/wait.h>
......@@ -44,15 +45,43 @@ vlc_module_end ()
struct vlc_inhibit_sys
{
vlc_thread_t thread;
vlc_cond_t update, inactive;
vlc_mutex_t lock;
vlc_timer_t timer;
posix_spawnattr_t attr;
bool suspend, suspended;
};
static void Inhibit (vlc_inhibit_t *ih, bool suspend);
static void *Thread (void *);
extern char **environ;
static void Timer (void *data)
{
vlc_inhibit_t *ih = data;
vlc_inhibit_sys_t *sys = ih->p_sys;
char *argv[3] = {
(char *)"xdg-screensaver", (char *)"reset", NULL
};
pid_t pid;
int err = posix_spawnp (&pid, "xdg-screensaver", NULL, &sys->attr,
argv, environ);
if (err == 0)
{
int status;
while (waitpid (pid, &status, 0) == -1);
}
else
{
errno = err;
msg_Warn (ih, "error starting xdg-screensaver: %m");
}
}
static void Inhibit (vlc_inhibit_t *ih, bool suspend)
{
vlc_inhibit_sys_t *sys = ih->p_sys;
mtime_t delay = suspend ? 30 * CLOCK_FREQ : INT64_C(0);
vlc_timer_schedule (sys->timer, false, delay, delay);
}
static int Open (vlc_object_t *obj)
{
......@@ -61,12 +90,6 @@ static int Open (vlc_object_t *obj)
if (p_sys == NULL)
return VLC_ENOMEM;
ih->p_sys = p_sys;
ih->inhibit = Inhibit;
vlc_mutex_init (&p_sys->lock);
vlc_cond_init (&p_sys->update);
vlc_cond_init (&p_sys->inactive);
posix_spawnattr_init (&p_sys->attr);
/* Reset signal handlers to default and clear mask in the child process */
{
......@@ -79,17 +102,16 @@ static int Open (vlc_object_t *obj)
posix_spawnattr_setflags (&p_sys->attr, POSIX_SPAWN_SETSIGDEF
| POSIX_SPAWN_SETSIGMASK);
}
p_sys->suspend = false;
p_sys->suspended = false;
if (vlc_clone (&p_sys->thread, Thread, ih, VLC_THREAD_PRIORITY_LOW))
ih->p_sys = p_sys;
if (vlc_timer_create (&p_sys->timer, Timer, ih))
{
vlc_cond_destroy (&p_sys->inactive);
vlc_cond_destroy (&p_sys->update);
vlc_mutex_destroy (&p_sys->lock);
posix_spawnattr_destroy (&p_sys->attr);
free (p_sys);
return VLC_ENOMEM;
}
ih->inhibit = Inhibit;
return VLC_SUCCESS;
}
......@@ -98,80 +120,7 @@ static void Close (vlc_object_t *obj)
vlc_inhibit_t *ih = (vlc_inhibit_t *)obj;
vlc_inhibit_sys_t *p_sys = ih->p_sys;
/* Make sure xdg-screensaver is gone for good */
vlc_mutex_lock (&p_sys->lock);
while (p_sys->suspended)
vlc_cond_wait (&p_sys->inactive, &p_sys->lock);
vlc_mutex_unlock (&p_sys->lock);
vlc_cancel (p_sys->thread);
vlc_join (p_sys->thread, NULL);
vlc_timer_destroy (p_sys->timer);
posix_spawnattr_destroy (&p_sys->attr);
vlc_cond_destroy (&p_sys->inactive);
vlc_cond_destroy (&p_sys->update);
vlc_mutex_destroy (&p_sys->lock);
free (p_sys);
}
static void Inhibit (vlc_inhibit_t *ih, bool suspend)
{
vlc_inhibit_sys_t *p_sys = ih->p_sys;
/* xdg-screensaver can take quite a while to start up (e.g. 1 second).
* So we avoid _waiting_ for it unless we really need to (clean up). */
vlc_mutex_lock (&p_sys->lock);
p_sys->suspend = suspend;
vlc_cond_signal (&p_sys->update);
vlc_mutex_unlock (&p_sys->lock);
}
extern char **environ;
VLC_NORETURN
static void *Thread (void *data)
{
vlc_inhibit_t *ih = data;
vlc_inhibit_sys_t *p_sys = ih->p_sys;
char id[11];
snprintf (id, sizeof (id), "0x%08"PRIx32, ih->window_id);
vlc_mutex_lock (&p_sys->lock);
mutex_cleanup_push (&p_sys->lock);
for (;;)
{ /* TODO: detach the thread, so we don't need one at all time */
while (p_sys->suspended == p_sys->suspend)
vlc_cond_wait (&p_sys->update, &p_sys->lock);
int canc = vlc_savecancel ();
char *argv[4] = {
(char *)"xdg-screensaver",
(char *)(p_sys->suspend ? "suspend" : "resume"),
id,
NULL,
};
pid_t pid;
vlc_mutex_unlock (&p_sys->lock);
if (!posix_spawnp (&pid, "xdg-screensaver", NULL, &p_sys->attr,
argv, environ))
{
int status;
msg_Dbg (ih, "started xdg-screensaver (PID = %d)", (int)pid);
/* Wait for command to complete */
while (waitpid (pid, &status, 0) == -1);
}
else/* We don't handle the error, but busy looping would be worse :( */
msg_Warn (ih, "could not start xdg-screensaver");
vlc_mutex_lock (&p_sys->lock);
p_sys->suspended = p_sys->suspend;
if (!p_sys->suspended)
vlc_cond_signal (&p_sys->inactive);
vlc_restorecancel (canc);
}
vlc_cleanup_pop ();
assert (0);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment