[MPlayer-dev-eng] Re: [PATCH] xscreensaver

Tobias Diedrich td at sim.uni-hannover.de
Sat Mar 22 02:12:55 CET 2003


D Richard Felker III wrote:

> And it makes a nice zombie process every time it pings. Beautiful. Is
> there a reason this can't be done without forking???

Of course it can be done without forking, should be just a small change in
mplayer.c AFAICS. Most of the code is for getting the window id, sending
the Event is easy after that. I don't know how much time
XSendEvent+XSync may take, however.
Also I don't see any zomies here, maybe you mean the mplayer process
that lurks around for up to 30seconds after exit, until it polls the
sigs again?

(Half an hour later)

OK, so here is a new patch.

libvo/x11_common.c |  127 ++++++++++++++++++++++++++++++++++++++++++++++++-----
mplayer.c          |   12 +++++
2 files changed, 128 insertions(+), 11 deletions(-)

Over the weekend I'm at the Leipzig Book Fair, so don't expect any more
mails from me until monday. :-)
(http://www.leipziger-messe.de/LeMMon/buch_web_eng.nsf/pages/buch-eng?OpenDocument)

-- 
Tobias								PGP: 0x9AC7E0BC
This mail is made of 100% recycled bits
np: dream: EURO \"dream\" land 03 - Private wars
-------------- next part --------------
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.686
diff -u -r1.686 mplayer.c
--- mplayer.c	16 Mar 2003 20:13:06 -0000	1.686
+++ mplayer.c	22 Mar 2003 01:20:54 -0000
@@ -139,6 +139,12 @@
 #include "get_path.c"
 
 //**************************************************************************//
+//             XScreensaver
+//**************************************************************************//
+
+void xscreensaver_heartbeat(float time);
+
+//**************************************************************************//
 //**************************************************************************//
 //             Input media streaming & demultiplexer:
 //**************************************************************************//
@@ -3253,6 +3259,12 @@
       current_module=NULL;
   }
 #endif
+
+if (stop_xscreensaver && sh_video) {
+  current_module="stop_xscreensaver";
+  xscreensaver_heartbeat(sh_video->pts);
+  current_module=NULL;
+}
   
   // DVD sub:
 if(vo_config_count && vo_spudec) {
Index: libvo/x11_common.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/x11_common.c,v
retrieving revision 1.140
diff -u -r1.140 x11_common.c
--- libvo/x11_common.c	10 Feb 2003 14:08:37 -0000	1.140
+++ libvo/x11_common.c	22 Mar 2003 01:21:10 -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,119 @@
  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 Window xs_windowid = 0;
+static Atom deactivate;
+static Atom screensaver;
+
+static float time_last;
+
+void xscreensaver_heartbeat(float time)
+{
+    XEvent ev;
+
+    if (xs_windowid &&
+	((time - time_last)>30 ||
+	 (time - time_last)<0)) {
+	time_last = time;
+
+	ev.xany.type = ClientMessage;
+	ev.xclient.display = mDisplay;
+	ev.xclient.window = xs_windowid;
+	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;
+
+	mp_msg(MSGT_VO,MSGL_DBG2, "Pinging xscreensaver.\n");
+	XSendEvent(mDisplay, xs_windowid, False, 0L, &ev);
+	XSync(mDisplay, False);
+    }
+}
+
+static void xscreensaver_disable(Display *dpy)
+{
+    mp_msg(MSGT_VO,MSGL_DBG2, "xscreensaver_disable()\n");
+
+    xs_windowid = find_xscreensaver_window(dpy);
+    if (!xs_windowid) {
+	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", xs_windowid);
+
+    deactivate = XInternAtom(dpy, "DEACTIVATE", False);
+    screensaver = XInternAtom(dpy, "SCREENSAVER", False);
+}
+
+static void xscreensaver_enable(void)
+{
+    xs_windowid = 0;
+}
+
+/*
+ * End of XScreensaver stuff
+ */
+
 void saver_on(Display *mDisplay) {
 
 #ifdef HAVE_XDPMS
@@ -889,10 +1002,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 +1038,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/20030322/db81eb38/attachment.pgp>


More information about the MPlayer-dev-eng mailing list