summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-08-15 20:32:44 +0200
committerwm4 <wm4@nowhere>2017-08-15 20:32:44 +0200
commit6694048272619b7f91d161c040b818ff63e65279 (patch)
tree1f77460e4593f9682a25d6a334b311ceff4ff37c /video
parent34ab0386cb1f28197ca11e90cd0236e352083758 (diff)
downloadmpv-6694048272619b7f91d161c040b818ff63e65279.tar.bz2
mpv-6694048272619b7f91d161c040b818ff63e65279.tar.xz
x11: use xdg-screensaver suspend/resume
If it doesn't work this time, I'll remove all X11 screensaver code. Fixes #4763.
Diffstat (limited to 'video')
-rw-r--r--video/out/x11_common.c94
-rw-r--r--video/out/x11_common.h11
2 files changed, 65 insertions, 40 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 41c9d8b00a..a8e8d1f829 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -37,6 +37,8 @@
#include <X11/extensions/Xinerama.h>
#include <X11/extensions/Xrandr.h>
+#include "osdep/atomic.h"
+
#include "config.h"
#include "misc/bstr.h"
#include "options/options.h"
@@ -135,7 +137,6 @@ static atomic_int x11_error_silence;
static void vo_x11_update_geometry(struct vo *vo);
static void vo_x11_fullscreen(struct vo *vo);
-static void xscreensaver_heartbeat(struct vo_x11_state *x11);
static void set_screensaver(struct vo_x11_state *x11, bool enabled);
static void vo_x11_selectinput_witherr(struct vo *vo, Display *display,
Window w, long event_mask);
@@ -503,27 +504,63 @@ static void vo_x11_get_bounding_monitors(struct vo_x11_state *x11, long b[4])
static void *screensaver_thread(void *arg)
{
struct vo_x11_state *x11 = arg;
+ bool suspend = false;
+ bool run = true;
+
+ while (run) {
+ pthread_mutex_lock(&x11->screensaver_thread_lock);
+ bool suspend_new = suspend;
+ for (;;) {
+ run = x11->screensaver_thread_running;
+ suspend_new = x11->screensaver_thread_suspend;
+ if (!run || suspend != suspend_new)
+ break;
+ pthread_cond_wait(&x11->screensaver_thread_wakeup,
+ &x11->screensaver_thread_lock);
+ }
+ pthread_mutex_unlock(&x11->screensaver_thread_lock);
- for (;;) {
- sem_wait(&x11->screensaver_sem);
- // don't queue multiple wakeups
- while (!sem_trywait(&x11->screensaver_sem)) {}
-
- if (atomic_load(&x11->screensaver_terminate))
- break;
+ if (!run) {
+ suspend_new = false; // make sure to resume on exit
+ if (suspend == suspend_new)
+ break;
+ }
- char *args[] = {"xdg-screensaver", "reset", NULL};
- int status = mp_subprocess(args, NULL, NULL, mp_devnull, mp_devnull, &(char*){0});
+ char *args[] = {"xdg-screensaver", suspend_new ? "suspend" : "resume",
+ mp_tprintf(32, "%lx", x11->screensaver_thread_window),
+ NULL};
+ int status = mp_subprocess(args, NULL, NULL, mp_devnull, mp_devnull,
+ &(char*){0});
if (status) {
- MP_VERBOSE(x11, "Disabling screensaver failed (%d). Make sure the "
+ MP_VERBOSE(x11, "Updating screensaver failed (%d). Make sure the "
"xdg-screensaver script is installed.\n", status);
break;
}
+
+ suspend = suspend_new;
}
return NULL;
}
+static void screensaver_thread_update(struct vo_x11_state *x11)
+{
+ if (!x11->screensaver_thread_running && x11->window) {
+ x11->screensaver_thread_window = x11->window;
+ x11->screensaver_thread_running = true;
+ if (pthread_create(&x11->screensaver_thread, NULL, screensaver_thread, x11))
+ x11->screensaver_thread_running = false;
+ }
+
+ if (!x11->screensaver_thread_running)
+ return;
+
+ pthread_mutex_lock(&x11->screensaver_thread_lock);
+ x11->screensaver_thread_suspend = !x11->screensaver_enabled;
+ pthread_cond_signal(&x11->screensaver_thread_wakeup);
+ pthread_mutex_unlock(&x11->screensaver_thread_lock);
+}
+
int vo_x11_init(struct vo *vo)
{
struct mp_vo_opts *opts = vo->opts;
@@ -544,12 +581,8 @@ int vo_x11_init(struct vo *vo)
};
vo->x11 = x11;
- sem_init(&x11->screensaver_sem, 0, 0);
- if (pthread_create(&x11->screensaver_thread, NULL, screensaver_thread, x11)) {
- sem_destroy(&x11->screensaver_sem);
- goto error;
- }
- x11->screensaver_thread_running = true;
+ pthread_mutex_init(&x11->screensaver_thread_lock, NULL);
+ pthread_cond_init(&x11->screensaver_thread_wakeup, NULL);
x11_error_output = x11->log;
XSetErrorHandler(x11_errorhandler);
@@ -773,12 +806,16 @@ void vo_x11_uninit(struct vo *vo)
}
if (x11->screensaver_thread_running) {
- atomic_store(&x11->screensaver_terminate, true);
- sem_post(&x11->screensaver_sem);
+ pthread_mutex_lock(&x11->screensaver_thread_lock);
+ x11->screensaver_thread_running = false;
+ pthread_cond_signal(&x11->screensaver_thread_wakeup);
+ pthread_mutex_unlock(&x11->screensaver_thread_lock);
pthread_join(x11->screensaver_thread, NULL);
- sem_destroy(&x11->screensaver_sem);
}
+ pthread_mutex_destroy(&x11->screensaver_thread_lock);
+ pthread_cond_destroy(&x11->screensaver_thread_wakeup);
+
if (x11->wakeup_pipe[0] >= 0) {
close(x11->wakeup_pipe[0]);
close(x11->wakeup_pipe[1]);
@@ -1041,8 +1078,6 @@ void vo_x11_check_events(struct vo *vo)
Display *display = vo->x11->display;
XEvent Event;
- xscreensaver_heartbeat(vo->x11);
-
while (XPending(display)) {
XNextEvent(display, &Event);
MP_TRACE(x11, "XEvent: %d\n", Event.type);
@@ -1424,6 +1459,8 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis,
vo_x11_set_property_utf8(vo, XA(x11, _GTK_THEME_VARIANT), "dark");
}
vo_x11_xembed_update(x11, 0);
+
+ screensaver_thread_update(x11);
}
static void vo_x11_map_window(struct vo *vo, struct mp_rect rc)
@@ -1898,18 +1935,6 @@ void vo_x11_wait_events(struct vo *vo, int64_t until_time_us)
mp_flush_wakeup_pipe(x11->wakeup_pipe[0]);
}
-static void xscreensaver_heartbeat(struct vo_x11_state *x11)
-{
- double time = mp_time_sec();
-
- if (x11->display && !x11->screensaver_enabled &&
- (time - x11->screensaver_time_last) >= 10)
- {
- x11->screensaver_time_last = time;
- sem_post(&x11->screensaver_sem);
- }
-}
-
static void set_screensaver(struct vo_x11_state *x11, bool enabled)
{
Display *mDisplay = x11->display;
@@ -1917,6 +1942,7 @@ static void set_screensaver(struct vo_x11_state *x11, bool enabled)
return;
MP_VERBOSE(x11, "%s screensaver.\n", enabled ? "Enabling" : "Disabling");
x11->screensaver_enabled = enabled;
+ screensaver_thread_update(x11);
int nothing;
if (DPMSQueryExtension(mDisplay, &nothing, &nothing)) {
BOOL onoff = 0;
diff --git a/video/out/x11_common.h b/video/out/x11_common.h
index e69640cc64..b2f6336d25 100644
--- a/video/out/x11_common.h
+++ b/video/out/x11_common.h
@@ -24,9 +24,6 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include "osdep/atomic.h"
-#include "osdep/semaphore.h"
-
#include "common/common.h"
struct vo;
@@ -66,11 +63,13 @@ struct vo_x11_state {
bool screensaver_enabled;
bool dpms_touched;
- double screensaver_time_last;
+
+ long screensaver_thread_window;
pthread_t screensaver_thread;
+ pthread_mutex_t screensaver_thread_lock;
+ pthread_cond_t screensaver_thread_wakeup;
bool screensaver_thread_running;
- sem_t screensaver_sem;
- atomic_bool screensaver_terminate;
+ bool screensaver_thread_suspend;
XIM xim;
XIC xic;