ftp://ftp.linux.ncsu.edu/mirror/ftp.redhat.com/pub/redhat/linux/enterprise/4/en/os...
[xscreensaver] / driver / xscreensaver.c
index 5d948f655fd665e68b6e2a4eeda76da01251e107..ab39b84e62341db668725061a05b382b7e0bc23c 100644 (file)
@@ -1194,6 +1194,24 @@ main_loop (saver_info *si)
           continue;
         }
 
           continue;
         }
 
+      /* Since we're about to blank the screen, kill the de-race timer,
+         if any.  It might still be running if we have unblanked and then
+         re-blanked in a short period (e.g., when using the "next" button
+         in xscreensaver-demo.)
+       */
+      if (si->de_race_id)
+        {
+          if (p->verbose_p)
+            fprintf (stderr, "%s: stopping de-race timer (%d remaining.)\n",
+                     blurb(), si->de_race_ticks);
+          XtRemoveTimeOut (si->de_race_id);
+          si->de_race_id = 0;
+        }
+
+
+      /* Now, try to blank.
+       */
+
       if (! blank_screen (si))
         {
           /* We were unable to grab either the keyboard or mouse.
       if (! blank_screen (si))
         {
           /* We were unable to grab either the keyboard or mouse.
@@ -1204,13 +1222,29 @@ main_loop (saver_info *si)
              see any events, and the display would be wedged.
 
              So, just go around the loop again and wait for the
              see any events, and the display would be wedged.
 
              So, just go around the loop again and wait for the
-             next bout of idleness.
+             next bout of idleness.  (If the user remains idle, we
+             will next try to blank the screen again in no more than
+             60 seconds.)
           */
           */
+          Time retry = 60 * 1000;
+          if (p->timeout < retry)
+            retry = p->timeout;
 
 
-          fprintf (stderr,
+          if (p->debug_p)
+            {
+              fprintf (stderr,
+                  "%s: DEBUG MODE: unable to grab -- BLANKING ANYWAY.\n",
+                       blurb());
+            }
+          else
+            {
+              fprintf (stderr,
                   "%s: unable to grab keyboard or mouse!  Blanking aborted.\n",
                   "%s: unable to grab keyboard or mouse!  Blanking aborted.\n",
-                   blurb());
-          continue;
+                       blurb());
+
+              schedule_wakeup_event (si, retry, p->debug_p);
+              continue;
+            }
         }
 
       kill_screenhack (si);
         }
 
       kill_screenhack (si);
@@ -1352,58 +1386,10 @@ main_loop (saver_info *si)
          si->lock_id = 0;
        }
 
          si->lock_id = 0;
        }
 
-      /* It's possible that a race condition could have led to the saver
-         window being unexpectedly still mapped.  This can happen like so:
-
-          - screen is blanked
-          - hack is launched
-          - that hack tries to grab a screen image (it does this by
-            first unmapping the saver window, then remapping it.)
-          - hack unmaps window
-          - hack waits
-          - user becomes active
-          - hack re-maps window (*)
-          - driver kills subprocess
-          - driver unmaps window (**)
-
-         The race is that (*) might have been sent to the server before
-         the client process was killed, but, due to scheduling randomness,
-         might not have been received by the server until after (**).
-         In other words, (*) and (**) might happen out of order, meaning
-         the driver will unmap the window, and then after that, the
-         recently-dead client will re-map it.  This leaves the user
-         locked out (it looks like a desktop, but it's not!)
-
-         To avoid this: after un-blanking the screen, sleep for a second,
-         and then really make sure the window is unmapped.
-
-         Update: actually, let's do that once a second for 8 seconds,
-         because sometimes the machine is slow, and we miss...
-       */
-      {
-        int i, j;
-        for (j = 0; j < 8; j++)
-          {
-            XSync (si->dpy, False);
-            sleep (1);
-            for (i = 0; i < si->nscreens; i++)
-              {
-                saver_screen_info *ssi = &si->screens[i];
-                Window w = ssi->screensaver_window;
-                XWindowAttributes xgwa;
-                XGetWindowAttributes (si->dpy, w, &xgwa);
-                if (xgwa.map_state != IsUnmapped)
-                  {
-                    if (p->verbose_p)
-                      fprintf (stderr,
-                               "%s: %d: client race! emergency unmap 0x%lx.\n",
-                               blurb(), i, (unsigned long) w);
-                    XUnmapWindow (si->dpy, w);
-                  }
-              }
-            XSync (si->dpy, False);
-          }
-      }
+      /* Since we're unblanked now, break race conditions and make
+         sure we stay that way (see comment in timers.c.) */
+      if (! si->de_race_id)
+        de_race_timer ((XtPointer) si, 0);
     }
 }
 
     }
 }