^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include "../util/string2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include "../util/config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include "libslang.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "ui.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sys/ttydefaults.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "browser.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "helpline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "keysyms.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "../util/color.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int ui_browser__percent_color(struct ui_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) double percent, bool current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) if (current && (!browser->use_navkeypressed || browser->navkeypressed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return HE_COLORSET_SELECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (percent >= MIN_RED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return HE_COLORSET_TOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (percent >= MIN_GREEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return HE_COLORSET_MEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return HE_COLORSET_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int ui_browser__set_color(struct ui_browser *browser, int color)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int ret = browser->current_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) browser->current_color = color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) SLsmg_set_color(color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) void ui_browser__set_percent_color(struct ui_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) double percent, bool current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int color = ui_browser__percent_color(browser, percent, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ui_browser__set_color(browser, color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) void ui_browser__gotorc_title(struct ui_browser *browser, int y, int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) SLsmg_gotorc(browser->y + y, browser->x + x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void ui_browser__gotorc(struct ui_browser *browser, int y, int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) SLsmg_gotorc(browser->y + y + browser->extra_title_lines, browser->x + x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const char *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) slsmg_write_nstring(msg, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void ui_browser__vprintf(struct ui_browser *browser __maybe_unused, const char *fmt, va_list args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) slsmg_vprintf(fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void ui_browser__printf(struct ui_browser *browser __maybe_unused, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ui_browser__vprintf(browser, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static struct list_head *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ui_browser__list_head_filter_entries(struct ui_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct list_head *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!browser->filter || !browser->filter(browser, pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) pos = pos->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) } while (pos != browser->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static struct list_head *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ui_browser__list_head_filter_prev_entries(struct ui_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct list_head *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (!browser->filter || !browser->filter(browser, pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) pos = pos->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } while (pos != browser->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct list_head *head = browser->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (browser->nr_entries == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case SEEK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) pos = ui_browser__list_head_filter_entries(browser, head->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pos = browser->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pos = ui_browser__list_head_filter_prev_entries(browser, head->prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) assert(pos != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (offset > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) while (offset-- != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) pos = ui_browser__list_head_filter_entries(browser, pos->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) while (offset++ != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pos = ui_browser__list_head_filter_prev_entries(browser, pos->prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) browser->top = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) void ui_browser__rb_tree_seek(struct ui_browser *browser, off_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct rb_root *root = browser->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct rb_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case SEEK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) nd = rb_first(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) nd = browser->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) nd = rb_last(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (offset > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) while (offset-- != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) nd = rb_next(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) while (offset++ != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) nd = rb_prev(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) browser->top = nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct rb_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int row = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (browser->top == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) browser->top = rb_first(browser->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) nd = browser->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) while (nd != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ui_browser__gotorc(browser, row, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) browser->write(browser, nd, row);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (++row == browser->rows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nd = rb_next(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return browser->top_idx + row == browser->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void ui_browser__refresh_dimensions(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) browser->width = SLtt_Screen_Cols - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) browser->height = browser->rows = SLtt_Screen_Rows - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) browser->rows -= browser->extra_title_lines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) browser->y = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) browser->x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void ui_browser__handle_resize(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ui__refresh_dimensions(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ui_browser__show(browser, browser->title, ui_helpline__current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ui_browser__refresh(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int ui_browser__warning(struct ui_browser *browser, int timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) const char *format, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) char *text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int key = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) va_start(args, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) err = vasprintf(&text, format, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) va_start(args, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ui_helpline__vpush(format, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) while ((key = ui__question_window("Warning!", text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) "Press any key...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) timeout)) == K_RESIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ui_browser__handle_resize(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) free(text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int ui_browser__help_window(struct ui_browser *browser, const char *text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) while ((key = ui__help_window(text)) == K_RESIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ui_browser__handle_resize(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) while ((key = ui__dialog_yesno(text)) == K_RESIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ui_browser__handle_resize(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return key == K_ENTER || toupper(key) == 'Y';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) void ui_browser__reset_index(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) browser->index = browser->top_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) browser->seek(browser, 0, SEEK_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) void __ui_browser__show_title(struct ui_browser *browser, const char *title)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) SLsmg_gotorc(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ui_browser__set_color(browser, HE_COLORSET_ROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ui_browser__write_nstring(browser, title, browser->width + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) void ui_browser__show_title(struct ui_browser *browser, const char *title)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) pthread_mutex_lock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) __ui_browser__show_title(browser, title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) pthread_mutex_unlock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int ui_browser__show(struct ui_browser *browser, const char *title,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) const char *helpline, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (browser->refresh_dimensions == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) browser->refresh_dimensions = ui_browser__refresh_dimensions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) browser->refresh_dimensions(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) pthread_mutex_lock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __ui_browser__show_title(browser, title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) browser->title = title;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) zfree(&browser->helpline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) va_start(ap, helpline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) err = vasprintf(&browser->helpline, helpline, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ui_helpline__push(browser->helpline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pthread_mutex_unlock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return err ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) void ui_browser__hide(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) pthread_mutex_lock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ui_helpline__pop();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) zfree(&browser->helpline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) pthread_mutex_unlock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static void ui_browser__scrollbar_set(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int height = browser->height, h = 0, pct = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) col = browser->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) row = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (browser->nr_entries > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pct = ((browser->index * (browser->height - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) (browser->nr_entries - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) SLsmg_set_char_set(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) while (h < height) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ui_browser__gotorc(browser, row++, col);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) SLsmg_write_char(h == pct ? SLSMG_DIAMOND_CHAR : SLSMG_CKBRD_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ++h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) SLsmg_set_char_set(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int __ui_browser__refresh(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int width = browser->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) row = browser->refresh(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ui_browser__set_color(browser, HE_COLORSET_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!browser->use_navkeypressed || browser->navkeypressed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ui_browser__scrollbar_set(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) width += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) SLsmg_fill_region(browser->y + row + browser->extra_title_lines, browser->x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) browser->rows - row, width, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (browser->nr_entries == 0 && browser->no_samples_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) __ui__info_window(NULL, browser->no_samples_msg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int ui_browser__refresh(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) pthread_mutex_lock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) __ui_browser__refresh(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pthread_mutex_unlock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * Here we're updating nr_entries _after_ we started browsing, i.e. we have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * forget about any reference to any entry in the underlying data structure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * that is why we do a SEEK_SET. Think about 'perf top' in the hists browser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * after an output_resort and hist decay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) off_t offset = nr_entries - browser->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) browser->nr_entries = nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (offset < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (browser->top_idx < (u64)-offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) offset = -browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) browser->index += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) browser->top_idx += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) browser->top = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) browser->seek(browser, browser->top_idx, SEEK_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int ui_browser__run(struct ui_browser *browser, int delay_secs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) int err, key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) off_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) pthread_mutex_lock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) err = __ui_browser__refresh(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) SLsmg_refresh();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) pthread_mutex_unlock(&ui__lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) key = ui__getch(delay_secs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (key == K_RESIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ui__refresh_dimensions(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) browser->refresh_dimensions(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) __ui_browser__show_title(browser, browser->title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ui_helpline__puts(browser->helpline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (browser->use_navkeypressed && !browser->navkeypressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (key == K_DOWN || key == K_UP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) (browser->columns && (key == K_LEFT || key == K_RIGHT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) key == K_PGDN || key == K_PGUP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) key == K_HOME || key == K_END ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) key == ' ') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) browser->navkeypressed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) switch (key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case K_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (browser->index == browser->nr_entries - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ++browser->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (browser->index == browser->top_idx + browser->rows) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ++browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) browser->seek(browser, +1, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) case K_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (browser->index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) --browser->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (browser->index < browser->top_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) --browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) browser->seek(browser, -1, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case K_RIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (!browser->columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (browser->horiz_scroll < browser->columns - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ++browser->horiz_scroll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case K_LEFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!browser->columns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (browser->horiz_scroll != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) --browser->horiz_scroll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case K_PGDN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case ' ':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (browser->top_idx + browser->rows > browser->nr_entries - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) offset = browser->rows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (browser->index + offset > browser->nr_entries - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) offset = browser->nr_entries - 1 - browser->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) browser->index += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) browser->top_idx += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) browser->seek(browser, +offset, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case K_PGUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (browser->top_idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (browser->top_idx < browser->rows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) offset = browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) offset = browser->rows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) browser->index -= offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) browser->top_idx -= offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) browser->seek(browser, -offset, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case K_HOME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ui_browser__reset_index(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case K_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) offset = browser->rows - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (offset >= browser->nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) offset = browser->nr_entries - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) browser->index = browser->nr_entries - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) browser->top_idx = browser->index - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) browser->seek(browser, -offset, SEEK_END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) unsigned int ui_browser__list_head_refresh(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct list_head *head = browser->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int row = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (browser->top == NULL || browser->top == browser->entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) browser->top = ui_browser__list_head_filter_entries(browser, head->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) pos = browser->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) list_for_each_from(pos, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!browser->filter || !browser->filter(browser, pos)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ui_browser__gotorc(browser, row, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) browser->write(browser, pos, row);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (++row == browser->rows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static struct ui_browser_colorset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) const char *name, *fg, *bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int colorset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) } ui_browser__colorsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .colorset = HE_COLORSET_TOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .name = "top",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .fg = "red",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .bg = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .colorset = HE_COLORSET_MEDIUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .name = "medium",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .fg = "green",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .bg = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .colorset = HE_COLORSET_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .name = "normal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .fg = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .bg = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .colorset = HE_COLORSET_SELECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .name = "selected",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .fg = "black",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .bg = "yellow",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .colorset = HE_COLORSET_JUMP_ARROWS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .name = "jump_arrows",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .fg = "blue",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .bg = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .colorset = HE_COLORSET_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .name = "addr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .fg = "magenta",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .bg = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .colorset = HE_COLORSET_ROOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .name = "root",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .fg = "white",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .bg = "blue",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .name = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int ui_browser__color_config(const char *var, const char *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) void *data __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) char *fg = NULL, *bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* same dir for all commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (!strstarts(var, "colors.") != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) const char *name = var + 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (strcmp(ui_browser__colorsets[i].name, name) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) fg = strdup(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (fg == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) bg = strchr(fg, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (bg == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) *bg = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) bg = skip_spaces(bg + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ui_browser__colorsets[i].bg = bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ui_browser__colorsets[i].fg = fg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) free(fg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) case SEEK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) browser->top = browser->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) browser->top = (char **)browser->top + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) browser->top = (char **)browser->entries + browser->nr_entries - 1 + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) assert((char **)browser->top < (char **)browser->entries + browser->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) assert((char **)browser->top >= (char **)browser->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned int row = 0, idx = browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) char **pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (browser->top == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) browser->top = browser->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) pos = (char **)browser->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) while (idx < browser->nr_entries &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) row < (unsigned)SLtt_Screen_Rows - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) assert(pos < (char **)browser->entries + browser->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (!browser->filter || !browser->filter(browser, *pos)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ui_browser__gotorc(browser, row, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) browser->write(browser, pos, row);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (++row == browser->rows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ++idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ++pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) void __ui_browser__vline(struct ui_browser *browser, unsigned int column,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) u16 start, u16 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) SLsmg_set_char_set(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ui_browser__gotorc(browser, start, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) SLsmg_draw_vline(end - start + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) SLsmg_set_char_set(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) void ui_browser__write_graph(struct ui_browser *browser __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int graph)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) SLsmg_set_char_set(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) SLsmg_write_char(graph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) SLsmg_set_char_set(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static void __ui_browser__line_arrow_up(struct ui_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) unsigned int column,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) u64 start, u64 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) unsigned int row, end_row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) SLsmg_set_char_set(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (start < browser->top_idx + browser->rows) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) row = start - browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ui_browser__gotorc(browser, row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) SLsmg_write_char(SLSMG_LLCORN_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) ui_browser__gotorc(browser, row, column + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) SLsmg_draw_hline(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (row-- == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) row = browser->rows - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (end > browser->top_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) end_row = end - browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) end_row = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ui_browser__gotorc(browser, end_row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) SLsmg_draw_vline(row - end_row + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ui_browser__gotorc(browser, end_row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (end >= browser->top_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) SLsmg_write_char(SLSMG_ULCORN_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ui_browser__gotorc(browser, end_row, column + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) SLsmg_write_char(SLSMG_HLINE_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ui_browser__gotorc(browser, end_row, column + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) SLsmg_write_char(SLSMG_RARROW_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) SLsmg_set_char_set(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static void __ui_browser__line_arrow_down(struct ui_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) unsigned int column,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u64 start, u64 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) unsigned int row, end_row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) SLsmg_set_char_set(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (start >= browser->top_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) row = start - browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ui_browser__gotorc(browser, row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) SLsmg_write_char(SLSMG_ULCORN_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ui_browser__gotorc(browser, row, column + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) SLsmg_draw_hline(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (++row == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) row = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (end >= browser->top_idx + browser->rows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) end_row = browser->rows - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) end_row = end - browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ui_browser__gotorc(browser, row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) SLsmg_draw_vline(end_row - row + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ui_browser__gotorc(browser, end_row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (end < browser->top_idx + browser->rows) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) SLsmg_write_char(SLSMG_LLCORN_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) ui_browser__gotorc(browser, end_row, column + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) SLsmg_write_char(SLSMG_HLINE_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ui_browser__gotorc(browser, end_row, column + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) SLsmg_write_char(SLSMG_RARROW_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) SLsmg_set_char_set(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) u64 start, u64 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (start > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) __ui_browser__line_arrow_up(browser, column, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) __ui_browser__line_arrow_down(browser, column, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) unsigned int row, bool arrow_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unsigned int end_row;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (row >= browser->top_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) end_row = row - browser->top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) SLsmg_set_char_set(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (arrow_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ui_browser__gotorc(browser, end_row, column - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) SLsmg_write_char(SLSMG_ULCORN_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ui_browser__gotorc(browser, end_row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) SLsmg_draw_hline(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ui_browser__gotorc(browser, end_row + 1, column - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) SLsmg_write_char(SLSMG_LTEE_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ui_browser__gotorc(browser, end_row, column - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) SLsmg_write_char(SLSMG_LTEE_CHAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) ui_browser__gotorc(browser, end_row, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) SLsmg_draw_hline(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) SLsmg_set_char_set(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) void ui_browser__init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) perf_config(ui_browser__color_config, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) while (ui_browser__colorsets[i].name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct ui_browser_colorset *c = &ui_browser__colorsets[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) sltt_set_color(c->colorset, c->name, c->fg, c->bg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }