summaryrefslogtreecommitdiffstats
path: root/video/out/x11_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/x11_common.c')
-rw-r--r--video/out/x11_common.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 392da3cee0..36a497055a 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -38,6 +38,10 @@
#include "vo.h"
#include "win_state.h"
#include "osdep/timer.h"
+#include "osdep/subprocess.h"
+
+// Specifically for mp_cancel
+#include "stream/stream.h"
#include <X11/Xmd.h>
#include <X11/Xlib.h>
@@ -470,6 +474,30 @@ static void vo_x11_get_bounding_monitors(struct vo_x11_state *x11, long b[4])
#endif
}
+static void *screensaver_thread(void *arg)
+{
+ struct vo_x11_state *x11 = arg;
+
+ for (;;) {
+ sem_wait(&x11->screensaver_sem);
+ // don't queue multiple wakeups
+ while (!sem_trywait(&x11->screensaver_sem)) {}
+
+ if (mp_cancel_test(x11->screensaver_terminate))
+ break;
+
+ char *args[] = {"xdg-screensaver", "reset", NULL};
+ if (mp_subprocess(args, x11->screensaver_terminate, NULL, NULL,
+ NULL, &(char*){0}))
+ {
+ MP_WARN(x11, "Disabling screensaver failed.\n");
+ break;
+ }
+ }
+
+ return NULL;
+}
+
int vo_x11_init(struct vo *vo)
{
struct mp_vo_opts *opts = vo->opts;
@@ -487,6 +515,14 @@ int vo_x11_init(struct vo *vo)
};
vo->x11 = x11;
+ x11->screensaver_terminate = mp_cancel_new(x11);
+ sem_init(&x11->screensaver_sem, 0, 0);
+ if (pthread_create(&x11->screensaver_thread, NULL, screensaver_thread, x11)) {
+ x11->screensaver_terminate = NULL;
+ sem_destroy(&x11->screensaver_sem);
+ goto error;
+ }
+
x11_error_output = x11->log;
XSetErrorHandler(x11_errorhandler);
@@ -498,13 +534,7 @@ int vo_x11_init(struct vo *vo)
if (!x11->display) {
MP_MSG(x11, vo->probing ? MSGL_V : MSGL_ERR,
"couldn't open the X11 display (%s)!\n", dispName);
-
- x11_error_output = NULL;
- XSetErrorHandler(NULL);
-
- talloc_free(x11);
- vo->x11 = NULL;
- return 0;
+ goto error;
}
x11->screen = DefaultScreen(x11->display); // screen ID
x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID
@@ -543,6 +573,10 @@ int vo_x11_init(struct vo *vo)
vo_x11_update_geometry(vo);
return 1;
+
+error:
+ vo_x11_uninit(vo);
+ return 0;
}
static const struct mp_keymap keymap[] = {
@@ -691,9 +725,18 @@ void vo_x11_uninit(struct vo *vo)
MP_VERBOSE(x11, "uninit ...\n");
if (x11->xim)
XCloseIM(x11->xim);
- x11_error_output = NULL;
- XSetErrorHandler(NULL);
- XCloseDisplay(x11->display);
+ if (x11->display) {
+ x11_error_output = NULL;
+ XSetErrorHandler(NULL);
+ XCloseDisplay(x11->display);
+ }
+
+ if (x11->screensaver_terminate) {
+ mp_cancel_trigger(x11->screensaver_terminate);
+ sem_post(&x11->screensaver_sem);
+ pthread_join(x11->screensaver_thread, NULL);
+ sem_destroy(&x11->screensaver_sem);
+ }
talloc_free(x11);
vo->x11 = NULL;
@@ -1766,7 +1809,7 @@ static void xscreensaver_heartbeat(struct vo_x11_state *x11)
(time - x11->screensaver_time_last) >= 10)
{
x11->screensaver_time_last = time;
-
+ sem_post(&x11->screensaver_sem);
XResetScreenSaver(x11->display);
}
}
@@ -1790,7 +1833,7 @@ static int xss_suspend(Display *mDisplay, Bool suspend)
static void set_screensaver(struct vo_x11_state *x11, bool enabled)
{
Display *mDisplay = x11->display;
- if (x11->screensaver_enabled == enabled)
+ if (!mDisplay || x11->screensaver_enabled == enabled)
return;
MP_VERBOSE(x11, "%s screensaver.\n", enabled ? "Enabling" : "Disabling");
x11->screensaver_enabled = enabled;