On Wed, 2008-11-26 at 04:13 +0000, Ben Hutchings wrote:
> There's an easy way to fix this:
> 
> --- xine-ui-0.99.5+cvs20070914.orig/src/xitk/videowin.c
> +++ xine-ui-0.99.5+cvs20070914/src/xitk/videowin.c
> @@ -2275,6 +2275,7 @@
>  
>    if(gGui->ssaver_enabled && (xitk_get_last_keypressed_time() >= (long int) 
> gGui->ssaver_timeout)) {
>  
> +#if 0
>  #ifdef HAVE_XTESTEXTENSION
>      if(gVw->have_xtest == True) {
>        
> @@ -2291,6 +2292,7 @@
>      }
>      else 
>  #endif
> +#endif
>      {
>        /* Reset the gnome screensaver. Look up the command in PATH only once 
> to save time, */
>        /* assuming its location and permission will not change during run 
> time of xine-ui. */
> --- END ---
> 
> but then the feature only works for GNOME users.
> 
> Alternately, we can delegate the hackery to xdg-screensaver, which
> supports the X server screensaver, xscreensaver, GNOME and KDE:

I've made a few important fixes to avoid zombie processes (an existing
bug) and file descriptor leakage.  The new version of this patch is
below.

Unfortunately when I gave this code some serious testing I found a race
condition in xdg-screensaver that can leave child processes hanging
around if the user toggles between pause and play rapidly.  There also
seems to be a bug in xprop, which it relies on, that means the
screensaver might not be resumed when we quit.  So I can't recommend
this fix at the moment.

Ben.

diff -u xine-ui-0.99.5+cvs20070914/debian/control 
xine-ui-0.99.5+cvs20070914/debian/control
--- xine-ui-0.99.5+cvs20070914/debian/control
+++ xine-ui-0.99.5+cvs20070914/debian/control
@@ -17,6 +17,7 @@
 Package: xine-ui
 Architecture: any
 Depends: ${shlibs:Depends}, libxine1-ffmpeg, libxine1-x | libxine1 (<< 1.1.8-2)
+Recommends: xdg-utils
 Description: the xine video player, user interface
  This is an X11 based GUI for the libxine video player library.
  It provides xine, a skin based media player that can play all the
only in patch2:
unchanged:
--- xine-ui-0.99.5+cvs20070914.orig/src/xitk/common.h
+++ xine-ui-0.99.5+cvs20070914/src/xitk/common.h
@@ -332,7 +332,6 @@
   const char               *snapshot_location;
   
   int                       ssaver_enabled;
-  int                       ssaver_timeout;
 
   int                       skip_by_chapter;
 
only in patch2:
unchanged:
--- xine-ui-0.99.5+cvs20070914.orig/src/xitk/main.c
+++ xine-ui-0.99.5+cvs20070914/src/xitk/main.c
@@ -1385,6 +1385,8 @@
   if (sigprocmask (SIG_BLOCK,  &vo_mask, NULL))
     fprintf (stderr, "sigprocmask() failed.\n");
 
+  signal(SIGCHLD, SIG_IGN);
+
   gGui = (gGui_t *) xine_xmalloc(sizeof(gGui_t));
   
   gGui->stream                 = NULL;
only in patch2:
unchanged:
--- xine-ui-0.99.5+cvs20070914.orig/src/xitk/panel.c
+++ xine-ui-0.99.5+cvs20070914/src/xitk/panel.c
@@ -363,7 +363,6 @@
  * Update slider thread.
  */
 static void *slider_loop(void *dummy) {
-  int screensaver_timer = 0;
   int status, speed;
   int pos, secs;
   int i = 0;
@@ -450,20 +449,7 @@
        else
          video_window_set_mrl((char *)gGui->mmk.mrl);
        
-       if(!xitk_is_window_iconified(gGui->video_display, gGui->video_window)) {
-         
-         if(gGui->ssaver_timeout) {
-           
-           if(!(i % 2))
-             screensaver_timer++;
-           
-           if(screensaver_timer >= gGui->ssaver_timeout) {
-             screensaver_timer = 0;
-             video_window_reset_ssaver();
-             
-           }
-         }  
-       }
+       
video_window_suspend_ssaver(!xitk_is_window_iconified(gGui->video_display, 
gGui->video_window));
 
        if(gGui->logo_mode == 0) {
          
@@ -503,6 +489,8 @@
            stream_infos_update_infos();
 
        }
+      } else {
+       video_window_suspend_ssaver(0);
       }
     }
     
only in patch2:
unchanged:
--- xine-ui-0.99.5+cvs20070914.orig/src/xitk/videowin.c
+++ xine-ui-0.99.5+cvs20070914/src/xitk/videowin.c
@@ -1095,6 +1095,9 @@
 
   /* The old window should be destroyed now */
   if(old_video_window != None) {
+    /* Screensaver control is tied to our window id */
+    video_window_suspend_ssaver(0);
+
     XDestroyWindow(gGui->video_display, old_video_window);
      
     if(gGui->cursor_grabbed)
@@ -2271,68 +2274,34 @@
 
 }
 
-void video_window_reset_ssaver(void) {
+void video_window_suspend_ssaver(int do_suspend) {
+  static int was_suspended;
 
-  if(gGui->ssaver_enabled && (xitk_get_last_keypressed_time() >= (long int) 
gGui->ssaver_timeout)) {
+  do_suspend = do_suspend && gGui->ssaver_enabled;
 
-#ifdef HAVE_XTESTEXTENSION
-    if(gVw->have_xtest == True) {
-      
-      gVw->fake_key_cur++;
-      
-      if(gVw->fake_key_cur >= 2)
-       gVw->fake_key_cur = 0;
-
-      XLockDisplay(gGui->video_display);
-      XTestFakeKeyEvent(gGui->video_display, 
gVw->fake_keys[gVw->fake_key_cur], True, CurrentTime);
-      XTestFakeKeyEvent(gGui->video_display, 
gVw->fake_keys[gVw->fake_key_cur], False, CurrentTime);
-      XSync(gGui->video_display, False);
-      XUnlockDisplay(gGui->video_display);
+  if(was_suspended != do_suspend) {
+    if(fork() == 0) {
+      char window_id[30];
+      char *args[] = { "xdg-screensaver", NULL, window_id, NULL };
+      int fd;
+
+      for(fd = 3; fd < 256; fd++)
+       close(fd);
+
+      args[1] = do_suspend ? "suspend" : "resume";
+      sprintf(window_id, "%lu", (unsigned long)gGui->video_window);
+      execvp(args[0], args);
+      _exit(0);
     }
-    else 
-#endif
-    {
-      /* Reset the gnome screensaver. Look up the command in PATH only once to 
save time, */
-      /* assuming its location and permission will not change during run time 
of xine-ui. */
-      {
-       static char *gssaver_args[] = { "gnome-screensaver-command", "--poke", 
NULL };
-       static char *gssaver_path   = NULL;
-
-       if(!gssaver_path) {
-         char *path = getenv("PATH");
-
-         if(!path)
-           path = "/usr/local/bin:/usr/bin";
-         do {
-           char *p, pbuf[XITK_PATH_MAX + XITK_NAME_MAX + 2];
-           int   plen;
-
-           for(p = path; *path && *path != ':'; path++)
-             ;
-           if(p == path)
-             plen = 1, p = ".";
-           else
-             plen = path - p;
-           plen = snprintf(pbuf, sizeof(pbuf), "%.*s/%s", plen, p, 
gssaver_args[0]);
-           if (plen <= -1 || plen >= sizeof(pbuf))
-             gssaver_path = "";
-           else
-             gssaver_path = (access(pbuf, X_OK)) ? "" : strdup(pbuf);
-         } while(!gssaver_path[0] && *path++);
-       }
-       if(gssaver_path[0] && (fork() == 0)) {
-         execv(gssaver_path, gssaver_args);
-         exit(0);
-       }
-      }
 
-      XLockDisplay(gGui->video_display);
-      XResetScreenSaver(gGui->video_display);
-      XUnlockDisplay(gGui->video_display);
-    }
+    was_suspended = do_suspend;
   }
 }
 
+void video_window_reset_ssaver(void) {
+  video_window_suspend_ssaver(1);
+}
+
 void video_window_get_frame_size(int *w, int *h) {
   if(w)
     *w = gVw->frame_width;
only in patch2:
unchanged:
--- xine-ui-0.99.5+cvs20070914.orig/src/xitk/videowin.h
+++ xine-ui-0.99.5+cvs20070914/src/xitk/videowin.h
@@ -83,6 +83,7 @@
 void video_window_update_logo(void);
 void video_window_change_skins(int);
 
+void video_window_suspend_ssaver(int do_suspend);
 void video_window_reset_ssaver(void);
 
 void video_window_get_frame_size(int *w, int *h);
only in patch2:
unchanged:
--- xine-ui-0.99.5+cvs20070914.orig/src/xitk/event.c
+++ xine-ui-0.99.5+cvs20070914/src/xitk/event.c
@@ -135,9 +135,6 @@
   gGui->skip_by_chapter = cfg->num_value;
   panel_update_nextprev_tips();
 }
-static void ssaver_timeout_cb(void *data, xine_cfg_entry_t *cfg) {
-  gGui->ssaver_timeout = cfg->num_value;
-}
 
 static void visual_anim_cb(void *data, xine_cfg_entry_t *cfg) {
   
@@ -1454,14 +1451,6 @@
                                         snapshot_loc_cb,
                                         CONFIG_NO_DATA);
   
-  gGui->ssaver_timeout =
-    xine_config_register_num (gGui->xine, "gui.screensaver_timeout", 10,
-                             _("Screensaver reset interval (s)"),
-                             _("Time, in seconds, between two faked events to 
keep a screensaver quiet, 0 to disable."),
-                             CONFIG_LEVEL_ADV,
-                             ssaver_timeout_cb,
-                             CONFIG_NO_DATA);
-  
   gGui->skip_by_chapter = 
     xine_config_register_bool (gGui->xine, "gui.skip_by_chapter", 1,
                               _("Chapter hopping"),
--- END ---

-- 
Ben Hutchings
All extremists should be taken out and shot.

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to