+static _Bool has_utf8() /* {{{ */
+{
+# if HAVE_NCURSESW_NCURSES_H
+ if (!opt_utf8)
+ {
+ /* Automatically determine */
+ if (strcasecmp ("UTF-8", nl_langinfo (CODESET)) == 0)
+ opt_utf8 = 2;
+ else
+ opt_utf8 = 1;
+ }
+ return ((_Bool) (opt_utf8 - 1));
+# else
+ return (0);
+# endif
+} /* }}} _Bool has_utf8 */
+
+static int update_graph_boxplot (ping_context_t *ctx) /* {{{ */
+{
+ uint32_t *counters;
+ double *ratios;
+ size_t i;
+ size_t x_max;
+ size_t x;
+
+ clean_history (ctx);
+
+ if (ctx->history_received == 0)
+ return (ENOENT);
+
+ x_max = (size_t) getmaxx (ctx->window);
+ if (x_max <= 8)
+ return (EINVAL);
+ x_max -= 4;
+
+ counters = calloc (x_max, sizeof (*counters));
+ ratios = calloc (x_max, sizeof (*ratios));
+
+ /* Bucketize */
+ for (i = 0; i < ctx->history_received; i++)
+ {
+ double latency = ctx->history_by_value[i] / 1000.0;
+ size_t index = (size_t) (((double) x_max) * latency / opt_interval);
+
+ if (index >= x_max)
+ index = x_max - 1;
+
+ counters[index]++;
+ }
+
+ /* Sum and calc ratios */
+ ratios[0] = ((double) counters[0]) / ((double) ctx->history_received);
+ for (x = 1; x < x_max; x++)
+ {
+ counters[x] += counters[x - 1];
+ ratios[x] = ((double) counters[x]) / ((double) ctx->history_received);
+ }
+
+ for (x = 0; x < x_max; x++)
+ {
+ int symbol = ' ';
+ _Bool reverse = 0;
+
+ if (x == 0)
+ {
+ if (ratios[x] >= 0.5)
+ {
+ symbol = BOXPLOT_MEDIAN;
+ reverse = 1;
+ }
+ else if (ratios[x] > 0.25)
+ {
+ symbol = BOXPLOT_BOX;
+ reverse = 1;
+ }
+ else if (ratios[x] > 0.025)
+ symbol = BOXPLOT_WHISKER_BAR;
+ else
+ symbol = ' '; /* NOP */
+ }
+ else /* (x != 0) */
+ {
+ if ((ratios[x - 1] < 0.5) && (ratios[x] >= 0.5))
+ {
+ symbol = BOXPLOT_MEDIAN;
+ reverse = 1;
+ }
+ else if (((ratios[x] >= 0.25) && (ratios[x] <= 0.75))
+ || ((ratios[x - 1] < 0.75) && (ratios[x] > 0.75)))
+ {
+ symbol = BOXPLOT_BOX;
+ reverse = 1;
+ }
+ else if ((ratios[x] < 0.5) && (ratios[x] >= 0.025))
+ {
+ if (ratios[x - 1] < 0.025)
+ symbol = BOXPLOT_WHISKER_LEFT_END;
+ else
+ symbol = BOXPLOT_WHISKER_BAR;
+ }
+ else if ((ratios[x] > .5) && (ratios[x] < 0.975))
+ {
+ symbol = BOXPLOT_WHISKER_BAR;
+ }
+ else if ((ratios[x] >= 0.975) && (ratios[x - 1] < 0.975))
+ symbol = BOXPLOT_WHISKER_RIGHT_END;
+ }
+
+ if (reverse)
+ wattron (ctx->window, A_REVERSE);
+ mvwaddch (ctx->window, /* y = */ 3, /* x = */ (int) (x + 2), symbol);
+ // mvwprintw (ctx->window, /* y = */ 3, /* x = */ (int) (x + 2), symbol);
+ if (reverse)
+ wattroff (ctx->window, A_REVERSE);
+ }
+
+ free (counters);
+ free (ratios);
+ return (0);
+} /* }}} int update_graph_boxplot */
+
+static int update_graph_prettyping (ping_context_t *ctx, /* {{{ */