+
+ /* This will (hopefully, supposedly) tell the server to re-set its
+ DPMS timer. Without this, the -deactivate clientmessage would
+ prevent xscreensaver from blanking, but would not prevent the
+ monitor from powering down. */
+#if 0
+ /* #### With some servers, this causes the screen to flicker every
+ time a key is pressed! Ok, I surrender. I give up on ever
+ having DPMS work properly.
+ */
+ XForceScreenSaver (si->dpy, ScreenSaverReset);
+
+ /* And if the monitor is already powered off, turn it on.
+ You'd think the above would do that, but apparently not? */
+ monitor_power_on (si, True);
+#endif
+
+}
+
+
+/* Returns true if the mouse has moved since the last time we checked.
+ Small motions (of less than "hysteresis" pixels/second) are ignored.
+ */
+static Bool
+pointer_moved_p (saver_screen_info *ssi, Bool mods_p)
+{
+ saver_info *si = ssi->global;
+ saver_preferences *p = &si->prefs;
+
+ Window root, child;
+ int root_x, root_y, x, y;
+ unsigned int mask;
+ time_t now = time ((time_t *) 0);
+ unsigned int distance, dps;
+ unsigned long seconds = 0;
+ Bool moved_p = False;
+
+ /* don't check xinerama pseudo-screens. */
+ if (!ssi->real_screen_p) return False;
+
+ if (!XQueryPointer (si->dpy, ssi->screensaver_window, &root, &child,
+ &root_x, &root_y, &x, &y, &mask))
+ {
+ /* If XQueryPointer() returns false, the mouse is not on this screen.
+ */
+ x = root_x = -1;
+ y = root_y = -1;
+ root = child = 0;
+ mask = 0;
+ }
+
+ distance = MAX (ABS (ssi->poll_mouse_last_root_x - root_x),
+ ABS (ssi->poll_mouse_last_root_y - root_y));
+ seconds = (now - ssi->poll_mouse_last_time);
+
+
+ /* When the screen is blanked, we get MotionNotify events, but when not
+ blanked, we poll only every 5 seconds, and that's not enough resolution
+ to do hysteresis based on a 1 second interval. So, assume that any
+ motion we've seen during the 5 seconds when our eyes were closed happened
+ in the last 1 second instead.
+ */
+ if (seconds > 1) seconds = 1;
+
+ dps = (seconds <= 0 ? distance : (distance / seconds));
+
+ /* Motion only counts if the rate is more than N pixels per second.
+ */
+ if (dps >= p->pointer_hysteresis &&
+ distance > 0)
+ moved_p = True;
+
+ /* If the mouse is not on this screen but used to be, that's motion.
+ If the mouse was not on this screen, but is now, that's motion.
+ */
+ {
+ Bool on_screen_p = (root_x != -1 && root_y != -1);
+ Bool was_on_screen_p = (ssi->poll_mouse_last_root_x != -1 &&
+ ssi->poll_mouse_last_root_y != -1);
+
+ if (on_screen_p != was_on_screen_p)
+ moved_p = True;
+ }
+
+ if (p->debug_p && (distance != 0 || moved_p))
+ {
+ fprintf (stderr, "%s: %d: pointer %s", blurb(), ssi->number,
+ (moved_p ? "moved: " : "ignored:"));
+ if (ssi->poll_mouse_last_root_x == -1)
+ fprintf (stderr, "off screen");
+ else
+ fprintf (stderr, "%d,%d",
+ ssi->poll_mouse_last_root_x,
+ ssi->poll_mouse_last_root_y);
+ fprintf (stderr, " -> ");
+ if (root_x == -1)
+ fprintf (stderr, "off screen");
+ else
+ fprintf (stderr, "%d,%d", root_x, root_y);
+ if (ssi->poll_mouse_last_root_x != -1 && root_x != -1)
+ fprintf (stderr, " (%d,%d; %d/%lu=%d)",
+ ABS(ssi->poll_mouse_last_root_x - root_x),
+ ABS(ssi->poll_mouse_last_root_y - root_y),
+ distance, seconds, dps);
+
+ fprintf (stderr, ".\n");
+ }
+
+ if (!moved_p &&
+ mods_p &&
+ mask != ssi->poll_mouse_last_mask)
+ {
+ moved_p = True;
+
+ if (p->debug_p)
+ fprintf (stderr, "%s: %d: modifiers changed: 0x%04x -> 0x%04x.\n",
+ blurb(), ssi->number, ssi->poll_mouse_last_mask, mask);
+ }
+
+ si->last_activity_screen = ssi;
+ ssi->poll_mouse_last_child = child;
+ ssi->poll_mouse_last_mask = mask;
+
+ if (moved_p || seconds > 0)
+ {
+ ssi->poll_mouse_last_time = now;
+ ssi->poll_mouse_last_root_x = root_x;
+ ssi->poll_mouse_last_root_y = root_y;
+ }
+
+ return moved_p;