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.
signature.asc
Description: This is a digitally signed message part