[MPlayer-dev-eng] [PATCH] xscreensaver

Tobias Diedrich td at sim.uni-hannover.de
Fri Mar 21 21:35:59 CET 2003


Hi all,

because the xscreensaver fd inheritance problem always crops up again
and again I tried to find a solution to the problem which is hopefully
acceptable.

I extracted the code needed to send a 'ping' to xscreensaver from
xscreensaver-command. It first looks for the xscreensaver window and if
it was found it forks and sends the message to the xscreensaver window
once every 30 seconds.

All in all this adds 114 lines of code. ^^;

x11_common.c |  136
++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 125 insertions(+), 11 deletions(-)

Seems to work fine over here, testers welcome. :-)

-- 
Tobias								PGP: 0x9AC7E0BC
This mail is made of 100% recycled bits
np: aikawananase: FOXTROT 11 - Crying
-------------- next part --------------
Index: x11_common.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/x11_common.c,v
retrieving revision 1.140
diff -u -r1.140 x11_common.c
--- x11_common.c	10 Feb 2003 14:08:37 -0000	1.140
+++ x11_common.c	21 Mar 2003 20:35:53 -0000
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include <signal.h>
 
 #include "video_out.h"
 #include "help_mp.h"
@@ -54,7 +55,6 @@
 
 static int dpms_disabled=0;
 static int timeout_save=0;
-static int xscreensaver_was_running=0;
 static int kdescreensaver_was_running=0;
 
 char* mDisplayName=NULL;
@@ -853,6 +853,128 @@
  XFlush( mDisplay );
 }
 
+/*
+ * XScreensaver stuff
+ */
+
+static int got_badwindow;
+static XErrorHandler old_handler;
+
+static int badwindow_handler(Display *dpy, XErrorEvent *error)
+{
+    if (error->error_code != BadWindow)
+	return (*old_handler)(dpy, error);
+
+    got_badwindow = True;
+    return 0;
+}
+
+static Window find_xscreensaver_window(Display *dpy)
+{
+    int i;
+    Window root = RootWindowOfScreen(DefaultScreenOfDisplay(dpy));
+    Window root2, parent, *kids;
+    Window retval = 0;
+    Atom xs_version;
+    unsigned int nkids = 0;
+
+    xs_version = XInternAtom(dpy, "_SCREENSAVER_VERSION", True);
+
+    if (!(xs_version != None &&
+          XQueryTree(dpy, root, &root2, &parent, &kids, &nkids) &&
+          kids && nkids)) return 0;
+
+    old_handler = XSetErrorHandler(badwindow_handler);
+
+    for (i = 0; i < nkids; i++) {
+	Atom type;
+	int format;
+	unsigned long nitems, bytesafter;
+	char *v;
+	int status;
+
+        got_badwindow = False;
+	status = XGetWindowProperty(dpy, kids[i], xs_version, 0, 200, False,
+	                            XA_STRING, &type, &format, &nitems,
+	                            &bytesafter, (unsigned char**) &v);
+	XSync(dpy, False);
+	if (got_badwindow) status = BadWindow;
+
+	if (status == Success && type != None) {
+	    retval = kids[i];
+	    break;
+	}
+    }
+    XFree(kids);
+    XSetErrorHandler(old_handler);
+
+    return retval;
+}
+
+static int xs_childpid = 0;
+
+static void xscreensaver_disable(Display *dpy)
+{
+    Window w = find_xscreensaver_window(dpy);
+    XEvent ev;
+    Atom deactivate = XInternAtom(dpy, "DEACTIVATE", False);
+    Atom screensaver = XInternAtom(dpy, "SCREENSAVER", False);
+
+
+    mp_msg(MSGT_VO,MSGL_DBG2, "xscreensaver_disable()\n");
+
+    if (xs_childpid) return;
+
+    if (!w) {
+	mp_msg(MSGT_VO,MSGL_INFO,
+	       "xscreensaver_disable: Could not find xscreensaver window.\n");
+	return;
+    }
+    mp_msg(MSGT_VO,MSGL_INFO,
+           "xscreensaver_disable: xscreensaver wid=%d.\n", w);
+
+    ev.xany.type = ClientMessage;
+    ev.xclient.display = dpy;
+    ev.xclient.window = w;
+    ev.xclient.message_type = screensaver;
+    ev.xclient.format = 32;
+    memset(&ev.xclient.data, 0, sizeof(ev.xclient.data));
+    ev.xclient.data.l[0] = (long) deactivate;
+    
+    if ((xs_childpid = fork()) == 0) {
+	Display *childdpy = XOpenDisplay(XDisplayName(mDisplayName));
+	sigset_t old_sigs, sigs;
+	mp_msg(MSGT_VO,MSGL_DBG2, "xscreensaver ping child startup\n");
+	sigfillset(&sigs);
+	sigprocmask(SIG_BLOCK, &sigs, &old_sigs);
+	sigemptyset(&sigs);
+	while (!sigismember(&sigs, SIGTERM)) {
+	    mp_msg(MSGT_VO,MSGL_DBG2, "Pinging xscreensaver.\n");
+	    XSendEvent(childdpy, w, False, 0L, &ev);
+	    XSync(childdpy, False);
+	    sleep(30);
+	    sigpending(&sigs);
+	}
+	mp_msg(MSGT_VO,MSGL_DBG2, "xscreensaver ping child exit\n");
+	XCloseDisplay(childdpy);
+	exit(0);
+    }
+}
+
+static void xscreensaver_enable(void)
+{
+    mp_msg(MSGT_VO,MSGL_DBG2, "xscreensaver_enable()\n");
+    if (xs_childpid) {
+	mp_msg(MSGT_VO,MSGL_DBG2, "Sending SIGTERM to pid %d.\n", xs_childpid);
+	kill(xs_childpid, SIGTERM);
+	xs_childpid=0;
+    }
+}
+
+/*
+ * End of XScreensaver stuff
+ */
+
 void saver_on(Display *mDisplay) {
 
 #ifdef HAVE_XDPMS
@@ -889,10 +1011,7 @@
 	timeout_save=0;
     }
 
-    if (xscreensaver_was_running && stop_xscreensaver) {
-	system("cd /; xscreensaver -no-splash &");
-	xscreensaver_was_running = 0;
-    }
+    if (stop_xscreensaver) xscreensaver_enable();
     if (kdescreensaver_was_running && stop_xscreensaver) {
 	system("dcop kdesktop KScreensaverIface enable true 2>/dev/null >/dev/null");
 	kdescreensaver_was_running = 0;
@@ -928,12 +1047,7 @@
 	    XSetScreenSaver(mDisplay, 0, interval, prefer_blank, allow_exp);
     }
 		    // turning off screensaver
-    if (stop_xscreensaver && !xscreensaver_was_running)
-    {
-      xscreensaver_was_running = (system("xscreensaver-command -version 2>/dev/null >/dev/null")==0);
-      if (xscreensaver_was_running)
-	 system("xscreensaver-command -exit 2>/dev/null >/dev/null");    
-    }
+    if (stop_xscreensaver) xscreensaver_disable(mDisplay);
     if (stop_xscreensaver && !kdescreensaver_was_running)
     {
       kdescreensaver_was_running=(system("dcop kdesktop KScreensaverIface isEnabled 2>/dev/null | sed 's/1/true/g' | grep true 2>/dev/null >/dev/null")==0);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20030321/27052dbe/attachment.pgp>


More information about the MPlayer-dev-eng mailing list