Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^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) }