+
+ if (dltime - bp->last_screen_update < REFRESH_INTERVAL && !force_screen_update)
+ /* Don't update more often than five times per second. */
+ return;
+
+ create_image (bp, dltime, false);
+ display_image (bp->buffer);
+ bp->last_screen_update = dltime;
+}
+
+static void
+bar_finish (void *progress, double dltime)
+{
+ struct bar_progress *bp = progress;
+
+ if (bp->total_length > 0
+ && bp->count + bp->initial_length > bp->total_length)
+ /* See bar_update() for explanation. */
+ bp->total_length = bp->initial_length + bp->count;
+
+ create_image (bp, dltime, true);
+ display_image (bp->buffer);
+
+ logputs (LOG_VERBOSE, "\n\n");
+
+ xfree (bp->buffer);
+ xfree (bp);
+}
+
+/* This code attempts to maintain the notion of a "current" download
+ speed, over the course of no less than 3s. (Shorter intervals
+ produce very erratic results.)
+
+ To do so, it samples the speed in 150ms intervals and stores the
+ recorded samples in a FIFO history ring. The ring stores no more
+ than 20 intervals, hence the history covers the period of at least
+ three seconds and at most 20 reads into the past. This method
+ should produce reasonable results for downloads ranging from very
+ slow to very fast.
+
+ The idea is that for fast downloads, we get the speed over exactly
+ the last three seconds. For slow downloads (where a network read
+ takes more than 150ms to complete), we get the speed over a larger
+ time period, as large as it takes to complete thirty reads. This
+ is good because slow downloads tend to fluctuate more and a
+ 3-second average would be too erratic. */
+
+static void
+update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
+{
+ struct bar_progress_hist *hist = &bp->hist;
+ double recent_age = dltime - bp->recent_start;
+
+ /* Update the download count. */
+ bp->recent_bytes += howmuch;
+
+ /* For very small time intervals, we return after having updated the
+ "recent" download count. When its age reaches or exceeds minimum
+ sample time, it will be recorded in the history ring. */
+ if (recent_age < DLSPEED_SAMPLE_MIN)
+ return;
+
+ if (howmuch == 0)