162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include "../util/string2.h" 362306a36Sopenharmony_ci#include "../util/config.h" 462306a36Sopenharmony_ci#include "libslang.h" 562306a36Sopenharmony_ci#include "ui.h" 662306a36Sopenharmony_ci#include "util.h" 762306a36Sopenharmony_ci#include <linux/compiler.h> 862306a36Sopenharmony_ci#include <linux/list.h> 962306a36Sopenharmony_ci#include <linux/rbtree.h> 1062306a36Sopenharmony_ci#include <linux/string.h> 1162306a36Sopenharmony_ci#include <stdlib.h> 1262306a36Sopenharmony_ci#include <sys/ttydefaults.h> 1362306a36Sopenharmony_ci#include "browser.h" 1462306a36Sopenharmony_ci#include "helpline.h" 1562306a36Sopenharmony_ci#include "keysyms.h" 1662306a36Sopenharmony_ci#include "../util/color.h" 1762306a36Sopenharmony_ci#include <linux/ctype.h> 1862306a36Sopenharmony_ci#include <linux/zalloc.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic int ui_browser__percent_color(struct ui_browser *browser, 2162306a36Sopenharmony_ci double percent, bool current) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci if (current && (!browser->use_navkeypressed || browser->navkeypressed)) 2462306a36Sopenharmony_ci return HE_COLORSET_SELECTED; 2562306a36Sopenharmony_ci if (percent >= MIN_RED) 2662306a36Sopenharmony_ci return HE_COLORSET_TOP; 2762306a36Sopenharmony_ci if (percent >= MIN_GREEN) 2862306a36Sopenharmony_ci return HE_COLORSET_MEDIUM; 2962306a36Sopenharmony_ci return HE_COLORSET_NORMAL; 3062306a36Sopenharmony_ci} 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ciint ui_browser__set_color(struct ui_browser *browser, int color) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci int ret = browser->current_color; 3562306a36Sopenharmony_ci browser->current_color = color; 3662306a36Sopenharmony_ci SLsmg_set_color(color); 3762306a36Sopenharmony_ci return ret; 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_civoid ui_browser__set_percent_color(struct ui_browser *browser, 4162306a36Sopenharmony_ci double percent, bool current) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci int color = ui_browser__percent_color(browser, percent, current); 4462306a36Sopenharmony_ci ui_browser__set_color(browser, color); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_civoid ui_browser__gotorc_title(struct ui_browser *browser, int y, int x) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci SLsmg_gotorc(browser->y + y, browser->x + x); 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_civoid ui_browser__gotorc(struct ui_browser *browser, int y, int x) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci SLsmg_gotorc(browser->y + y + browser->extra_title_lines, browser->x + x); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_civoid ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const char *msg, 5862306a36Sopenharmony_ci unsigned int width) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci SLsmg_write_nstring(msg, width); 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_civoid ui_browser__vprintf(struct ui_browser *browser __maybe_unused, const char *fmt, va_list args) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci SLsmg_vprintf(fmt, args); 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_civoid ui_browser__printf(struct ui_browser *browser __maybe_unused, const char *fmt, ...) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci va_list args; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci va_start(args, fmt); 7362306a36Sopenharmony_ci ui_browser__vprintf(browser, fmt, args); 7462306a36Sopenharmony_ci va_end(args); 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic struct list_head * 7862306a36Sopenharmony_ciui_browser__list_head_filter_entries(struct ui_browser *browser, 7962306a36Sopenharmony_ci struct list_head *pos) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci do { 8262306a36Sopenharmony_ci if (!browser->filter || !browser->filter(browser, pos)) 8362306a36Sopenharmony_ci return pos; 8462306a36Sopenharmony_ci pos = pos->next; 8562306a36Sopenharmony_ci } while (pos != browser->entries); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci return NULL; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic struct list_head * 9162306a36Sopenharmony_ciui_browser__list_head_filter_prev_entries(struct ui_browser *browser, 9262306a36Sopenharmony_ci struct list_head *pos) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci do { 9562306a36Sopenharmony_ci if (!browser->filter || !browser->filter(browser, pos)) 9662306a36Sopenharmony_ci return pos; 9762306a36Sopenharmony_ci pos = pos->prev; 9862306a36Sopenharmony_ci } while (pos != browser->entries); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci return NULL; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_civoid ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int whence) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci struct list_head *head = browser->entries; 10662306a36Sopenharmony_ci struct list_head *pos; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci if (browser->nr_entries == 0) 10962306a36Sopenharmony_ci return; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci switch (whence) { 11262306a36Sopenharmony_ci case SEEK_SET: 11362306a36Sopenharmony_ci pos = ui_browser__list_head_filter_entries(browser, head->next); 11462306a36Sopenharmony_ci break; 11562306a36Sopenharmony_ci case SEEK_CUR: 11662306a36Sopenharmony_ci pos = browser->top; 11762306a36Sopenharmony_ci break; 11862306a36Sopenharmony_ci case SEEK_END: 11962306a36Sopenharmony_ci pos = ui_browser__list_head_filter_prev_entries(browser, head->prev); 12062306a36Sopenharmony_ci break; 12162306a36Sopenharmony_ci default: 12262306a36Sopenharmony_ci return; 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci assert(pos != NULL); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci if (offset > 0) { 12862306a36Sopenharmony_ci while (offset-- != 0) 12962306a36Sopenharmony_ci pos = ui_browser__list_head_filter_entries(browser, pos->next); 13062306a36Sopenharmony_ci } else { 13162306a36Sopenharmony_ci while (offset++ != 0) 13262306a36Sopenharmony_ci pos = ui_browser__list_head_filter_prev_entries(browser, pos->prev); 13362306a36Sopenharmony_ci } 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci browser->top = pos; 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_civoid ui_browser__rb_tree_seek(struct ui_browser *browser, off_t offset, int whence) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci struct rb_root *root = browser->entries; 14162306a36Sopenharmony_ci struct rb_node *nd; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci switch (whence) { 14462306a36Sopenharmony_ci case SEEK_SET: 14562306a36Sopenharmony_ci nd = rb_first(root); 14662306a36Sopenharmony_ci break; 14762306a36Sopenharmony_ci case SEEK_CUR: 14862306a36Sopenharmony_ci nd = browser->top; 14962306a36Sopenharmony_ci break; 15062306a36Sopenharmony_ci case SEEK_END: 15162306a36Sopenharmony_ci nd = rb_last(root); 15262306a36Sopenharmony_ci break; 15362306a36Sopenharmony_ci default: 15462306a36Sopenharmony_ci return; 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci if (offset > 0) { 15862306a36Sopenharmony_ci while (offset-- != 0) 15962306a36Sopenharmony_ci nd = rb_next(nd); 16062306a36Sopenharmony_ci } else { 16162306a36Sopenharmony_ci while (offset++ != 0) 16262306a36Sopenharmony_ci nd = rb_prev(nd); 16362306a36Sopenharmony_ci } 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci browser->top = nd; 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ciunsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci struct rb_node *nd; 17162306a36Sopenharmony_ci int row = 0; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci if (browser->top == NULL) 17462306a36Sopenharmony_ci browser->top = rb_first(browser->entries); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci nd = browser->top; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci while (nd != NULL) { 17962306a36Sopenharmony_ci ui_browser__gotorc(browser, row, 0); 18062306a36Sopenharmony_ci browser->write(browser, nd, row); 18162306a36Sopenharmony_ci if (++row == browser->rows) 18262306a36Sopenharmony_ci break; 18362306a36Sopenharmony_ci nd = rb_next(nd); 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci return row; 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cibool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci return browser->top_idx + row == browser->index; 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_civoid ui_browser__refresh_dimensions(struct ui_browser *browser) 19562306a36Sopenharmony_ci{ 19662306a36Sopenharmony_ci browser->width = SLtt_Screen_Cols - 1; 19762306a36Sopenharmony_ci browser->height = browser->rows = SLtt_Screen_Rows - 2; 19862306a36Sopenharmony_ci browser->rows -= browser->extra_title_lines; 19962306a36Sopenharmony_ci browser->y = 1; 20062306a36Sopenharmony_ci browser->x = 0; 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_civoid ui_browser__handle_resize(struct ui_browser *browser) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci ui__refresh_dimensions(false); 20662306a36Sopenharmony_ci ui_browser__show(browser, browser->title, ui_helpline__current); 20762306a36Sopenharmony_ci ui_browser__refresh(browser); 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciint ui_browser__warning(struct ui_browser *browser, int timeout, 21162306a36Sopenharmony_ci const char *format, ...) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci va_list args; 21462306a36Sopenharmony_ci char *text; 21562306a36Sopenharmony_ci int key = 0, err; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci va_start(args, format); 21862306a36Sopenharmony_ci err = vasprintf(&text, format, args); 21962306a36Sopenharmony_ci va_end(args); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci if (err < 0) { 22262306a36Sopenharmony_ci va_start(args, format); 22362306a36Sopenharmony_ci ui_helpline__vpush(format, args); 22462306a36Sopenharmony_ci va_end(args); 22562306a36Sopenharmony_ci } else { 22662306a36Sopenharmony_ci while ((key = ui__question_window("Warning!", text, 22762306a36Sopenharmony_ci "Press any key...", 22862306a36Sopenharmony_ci timeout)) == K_RESIZE) 22962306a36Sopenharmony_ci ui_browser__handle_resize(browser); 23062306a36Sopenharmony_ci free(text); 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci return key; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ciint ui_browser__help_window(struct ui_browser *browser, const char *text) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci int key; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci while ((key = ui__help_window(text)) == K_RESIZE) 24162306a36Sopenharmony_ci ui_browser__handle_resize(browser); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci return key; 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cibool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci int key; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci while ((key = ui__dialog_yesno(text)) == K_RESIZE) 25162306a36Sopenharmony_ci ui_browser__handle_resize(browser); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci return key == K_ENTER || toupper(key) == 'Y'; 25462306a36Sopenharmony_ci} 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_civoid ui_browser__reset_index(struct ui_browser *browser) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci browser->index = browser->top_idx = 0; 25962306a36Sopenharmony_ci browser->seek(browser, 0, SEEK_SET); 26062306a36Sopenharmony_ci} 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_civoid __ui_browser__show_title(struct ui_browser *browser, const char *title) 26362306a36Sopenharmony_ci{ 26462306a36Sopenharmony_ci SLsmg_gotorc(0, 0); 26562306a36Sopenharmony_ci ui_browser__set_color(browser, HE_COLORSET_ROOT); 26662306a36Sopenharmony_ci ui_browser__write_nstring(browser, title, browser->width + 1); 26762306a36Sopenharmony_ci} 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_civoid ui_browser__show_title(struct ui_browser *browser, const char *title) 27062306a36Sopenharmony_ci{ 27162306a36Sopenharmony_ci mutex_lock(&ui__lock); 27262306a36Sopenharmony_ci __ui_browser__show_title(browser, title); 27362306a36Sopenharmony_ci mutex_unlock(&ui__lock); 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ciint ui_browser__show(struct ui_browser *browser, const char *title, 27762306a36Sopenharmony_ci const char *helpline, ...) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci int err; 28062306a36Sopenharmony_ci va_list ap; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci if (browser->refresh_dimensions == NULL) 28362306a36Sopenharmony_ci browser->refresh_dimensions = ui_browser__refresh_dimensions; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci browser->refresh_dimensions(browser); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci mutex_lock(&ui__lock); 28862306a36Sopenharmony_ci __ui_browser__show_title(browser, title); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci browser->title = title; 29162306a36Sopenharmony_ci zfree(&browser->helpline); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci va_start(ap, helpline); 29462306a36Sopenharmony_ci err = vasprintf(&browser->helpline, helpline, ap); 29562306a36Sopenharmony_ci va_end(ap); 29662306a36Sopenharmony_ci if (err > 0) 29762306a36Sopenharmony_ci ui_helpline__push(browser->helpline); 29862306a36Sopenharmony_ci mutex_unlock(&ui__lock); 29962306a36Sopenharmony_ci return err ? 0 : -1; 30062306a36Sopenharmony_ci} 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_civoid ui_browser__hide(struct ui_browser *browser) 30362306a36Sopenharmony_ci{ 30462306a36Sopenharmony_ci mutex_lock(&ui__lock); 30562306a36Sopenharmony_ci ui_helpline__pop(); 30662306a36Sopenharmony_ci zfree(&browser->helpline); 30762306a36Sopenharmony_ci mutex_unlock(&ui__lock); 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic void ui_browser__scrollbar_set(struct ui_browser *browser) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci int height = browser->height, h = 0, pct = 0, 31362306a36Sopenharmony_ci col = browser->width, 31462306a36Sopenharmony_ci row = 0; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci if (browser->nr_entries > 1) { 31762306a36Sopenharmony_ci pct = ((browser->index * (browser->height - 1)) / 31862306a36Sopenharmony_ci (browser->nr_entries - 1)); 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci SLsmg_set_char_set(1); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci while (h < height) { 32462306a36Sopenharmony_ci ui_browser__gotorc(browser, row++, col); 32562306a36Sopenharmony_ci SLsmg_write_char(h == pct ? SLSMG_DIAMOND_CHAR : SLSMG_CKBRD_CHAR); 32662306a36Sopenharmony_ci ++h; 32762306a36Sopenharmony_ci } 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci SLsmg_set_char_set(0); 33062306a36Sopenharmony_ci} 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic int __ui_browser__refresh(struct ui_browser *browser) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci int row; 33562306a36Sopenharmony_ci int width = browser->width; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci row = browser->refresh(browser); 33862306a36Sopenharmony_ci ui_browser__set_color(browser, HE_COLORSET_NORMAL); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci if (!browser->use_navkeypressed || browser->navkeypressed) 34162306a36Sopenharmony_ci ui_browser__scrollbar_set(browser); 34262306a36Sopenharmony_ci else 34362306a36Sopenharmony_ci width += 1; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci SLsmg_fill_region(browser->y + row + browser->extra_title_lines, browser->x, 34662306a36Sopenharmony_ci browser->rows - row, width, ' '); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (browser->nr_entries == 0 && browser->no_samples_msg) 34962306a36Sopenharmony_ci __ui__info_window(NULL, browser->no_samples_msg, NULL); 35062306a36Sopenharmony_ci return 0; 35162306a36Sopenharmony_ci} 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ciint ui_browser__refresh(struct ui_browser *browser) 35462306a36Sopenharmony_ci{ 35562306a36Sopenharmony_ci mutex_lock(&ui__lock); 35662306a36Sopenharmony_ci __ui_browser__refresh(browser); 35762306a36Sopenharmony_ci mutex_unlock(&ui__lock); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci return 0; 36062306a36Sopenharmony_ci} 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/* 36362306a36Sopenharmony_ci * Here we're updating nr_entries _after_ we started browsing, i.e. we have to 36462306a36Sopenharmony_ci * forget about any reference to any entry in the underlying data structure, 36562306a36Sopenharmony_ci * that is why we do a SEEK_SET. Think about 'perf top' in the hists browser 36662306a36Sopenharmony_ci * after an output_resort and hist decay. 36762306a36Sopenharmony_ci */ 36862306a36Sopenharmony_civoid ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries) 36962306a36Sopenharmony_ci{ 37062306a36Sopenharmony_ci off_t offset = nr_entries - browser->nr_entries; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci browser->nr_entries = nr_entries; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci if (offset < 0) { 37562306a36Sopenharmony_ci if (browser->top_idx < (u64)-offset) 37662306a36Sopenharmony_ci offset = -browser->top_idx; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci browser->index += offset; 37962306a36Sopenharmony_ci browser->top_idx += offset; 38062306a36Sopenharmony_ci } 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci browser->top = NULL; 38362306a36Sopenharmony_ci browser->seek(browser, browser->top_idx, SEEK_SET); 38462306a36Sopenharmony_ci} 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ciint ui_browser__run(struct ui_browser *browser, int delay_secs) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci int err, key; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci while (1) { 39162306a36Sopenharmony_ci off_t offset; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci mutex_lock(&ui__lock); 39462306a36Sopenharmony_ci err = __ui_browser__refresh(browser); 39562306a36Sopenharmony_ci SLsmg_refresh(); 39662306a36Sopenharmony_ci mutex_unlock(&ui__lock); 39762306a36Sopenharmony_ci if (err < 0) 39862306a36Sopenharmony_ci break; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci key = ui__getch(delay_secs); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci if (key == K_RESIZE) { 40362306a36Sopenharmony_ci ui__refresh_dimensions(false); 40462306a36Sopenharmony_ci browser->refresh_dimensions(browser); 40562306a36Sopenharmony_ci __ui_browser__show_title(browser, browser->title); 40662306a36Sopenharmony_ci ui_helpline__puts(browser->helpline); 40762306a36Sopenharmony_ci continue; 40862306a36Sopenharmony_ci } 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci if (browser->use_navkeypressed && !browser->navkeypressed) { 41162306a36Sopenharmony_ci if (key == K_DOWN || key == K_UP || 41262306a36Sopenharmony_ci (browser->columns && (key == K_LEFT || key == K_RIGHT)) || 41362306a36Sopenharmony_ci key == K_PGDN || key == K_PGUP || 41462306a36Sopenharmony_ci key == K_HOME || key == K_END || 41562306a36Sopenharmony_ci key == ' ') { 41662306a36Sopenharmony_ci browser->navkeypressed = true; 41762306a36Sopenharmony_ci continue; 41862306a36Sopenharmony_ci } else 41962306a36Sopenharmony_ci return key; 42062306a36Sopenharmony_ci } 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci switch (key) { 42362306a36Sopenharmony_ci case K_DOWN: 42462306a36Sopenharmony_ci if (browser->index == browser->nr_entries - 1) 42562306a36Sopenharmony_ci break; 42662306a36Sopenharmony_ci ++browser->index; 42762306a36Sopenharmony_ci if (browser->index == browser->top_idx + browser->rows) { 42862306a36Sopenharmony_ci ++browser->top_idx; 42962306a36Sopenharmony_ci browser->seek(browser, +1, SEEK_CUR); 43062306a36Sopenharmony_ci } 43162306a36Sopenharmony_ci break; 43262306a36Sopenharmony_ci case K_UP: 43362306a36Sopenharmony_ci if (browser->index == 0) 43462306a36Sopenharmony_ci break; 43562306a36Sopenharmony_ci --browser->index; 43662306a36Sopenharmony_ci if (browser->index < browser->top_idx) { 43762306a36Sopenharmony_ci --browser->top_idx; 43862306a36Sopenharmony_ci browser->seek(browser, -1, SEEK_CUR); 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci break; 44162306a36Sopenharmony_ci case K_RIGHT: 44262306a36Sopenharmony_ci if (!browser->columns) 44362306a36Sopenharmony_ci goto out; 44462306a36Sopenharmony_ci if (browser->horiz_scroll < browser->columns - 1) 44562306a36Sopenharmony_ci ++browser->horiz_scroll; 44662306a36Sopenharmony_ci break; 44762306a36Sopenharmony_ci case K_LEFT: 44862306a36Sopenharmony_ci if (!browser->columns) 44962306a36Sopenharmony_ci goto out; 45062306a36Sopenharmony_ci if (browser->horiz_scroll != 0) 45162306a36Sopenharmony_ci --browser->horiz_scroll; 45262306a36Sopenharmony_ci break; 45362306a36Sopenharmony_ci case K_PGDN: 45462306a36Sopenharmony_ci case ' ': 45562306a36Sopenharmony_ci if (browser->top_idx + browser->rows > browser->nr_entries - 1) 45662306a36Sopenharmony_ci break; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci offset = browser->rows; 45962306a36Sopenharmony_ci if (browser->index + offset > browser->nr_entries - 1) 46062306a36Sopenharmony_ci offset = browser->nr_entries - 1 - browser->index; 46162306a36Sopenharmony_ci browser->index += offset; 46262306a36Sopenharmony_ci browser->top_idx += offset; 46362306a36Sopenharmony_ci browser->seek(browser, +offset, SEEK_CUR); 46462306a36Sopenharmony_ci break; 46562306a36Sopenharmony_ci case K_PGUP: 46662306a36Sopenharmony_ci if (browser->top_idx == 0) 46762306a36Sopenharmony_ci break; 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci if (browser->top_idx < browser->rows) 47062306a36Sopenharmony_ci offset = browser->top_idx; 47162306a36Sopenharmony_ci else 47262306a36Sopenharmony_ci offset = browser->rows; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci browser->index -= offset; 47562306a36Sopenharmony_ci browser->top_idx -= offset; 47662306a36Sopenharmony_ci browser->seek(browser, -offset, SEEK_CUR); 47762306a36Sopenharmony_ci break; 47862306a36Sopenharmony_ci case K_HOME: 47962306a36Sopenharmony_ci ui_browser__reset_index(browser); 48062306a36Sopenharmony_ci break; 48162306a36Sopenharmony_ci case K_END: 48262306a36Sopenharmony_ci offset = browser->rows - 1; 48362306a36Sopenharmony_ci if (offset >= browser->nr_entries) 48462306a36Sopenharmony_ci offset = browser->nr_entries - 1; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci browser->index = browser->nr_entries - 1; 48762306a36Sopenharmony_ci browser->top_idx = browser->index - offset; 48862306a36Sopenharmony_ci browser->seek(browser, -offset, SEEK_END); 48962306a36Sopenharmony_ci break; 49062306a36Sopenharmony_ci default: 49162306a36Sopenharmony_ci out: 49262306a36Sopenharmony_ci return key; 49362306a36Sopenharmony_ci } 49462306a36Sopenharmony_ci } 49562306a36Sopenharmony_ci return -1; 49662306a36Sopenharmony_ci} 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ciunsigned int ui_browser__list_head_refresh(struct ui_browser *browser) 49962306a36Sopenharmony_ci{ 50062306a36Sopenharmony_ci struct list_head *pos; 50162306a36Sopenharmony_ci struct list_head *head = browser->entries; 50262306a36Sopenharmony_ci int row = 0; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci if (browser->top == NULL || browser->top == browser->entries) 50562306a36Sopenharmony_ci browser->top = ui_browser__list_head_filter_entries(browser, head->next); 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci pos = browser->top; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci list_for_each_from(pos, head) { 51062306a36Sopenharmony_ci if (!browser->filter || !browser->filter(browser, pos)) { 51162306a36Sopenharmony_ci ui_browser__gotorc(browser, row, 0); 51262306a36Sopenharmony_ci browser->write(browser, pos, row); 51362306a36Sopenharmony_ci if (++row == browser->rows) 51462306a36Sopenharmony_ci break; 51562306a36Sopenharmony_ci } 51662306a36Sopenharmony_ci } 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci return row; 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_cistatic struct ui_browser_colorset { 52262306a36Sopenharmony_ci const char *name, *fg, *bg; 52362306a36Sopenharmony_ci int colorset; 52462306a36Sopenharmony_ci} ui_browser__colorsets[] = { 52562306a36Sopenharmony_ci { 52662306a36Sopenharmony_ci .colorset = HE_COLORSET_TOP, 52762306a36Sopenharmony_ci .name = "top", 52862306a36Sopenharmony_ci .fg = "red", 52962306a36Sopenharmony_ci .bg = "default", 53062306a36Sopenharmony_ci }, 53162306a36Sopenharmony_ci { 53262306a36Sopenharmony_ci .colorset = HE_COLORSET_MEDIUM, 53362306a36Sopenharmony_ci .name = "medium", 53462306a36Sopenharmony_ci .fg = "green", 53562306a36Sopenharmony_ci .bg = "default", 53662306a36Sopenharmony_ci }, 53762306a36Sopenharmony_ci { 53862306a36Sopenharmony_ci .colorset = HE_COLORSET_NORMAL, 53962306a36Sopenharmony_ci .name = "normal", 54062306a36Sopenharmony_ci .fg = "default", 54162306a36Sopenharmony_ci .bg = "default", 54262306a36Sopenharmony_ci }, 54362306a36Sopenharmony_ci { 54462306a36Sopenharmony_ci .colorset = HE_COLORSET_SELECTED, 54562306a36Sopenharmony_ci .name = "selected", 54662306a36Sopenharmony_ci .fg = "black", 54762306a36Sopenharmony_ci .bg = "yellow", 54862306a36Sopenharmony_ci }, 54962306a36Sopenharmony_ci { 55062306a36Sopenharmony_ci .colorset = HE_COLORSET_JUMP_ARROWS, 55162306a36Sopenharmony_ci .name = "jump_arrows", 55262306a36Sopenharmony_ci .fg = "blue", 55362306a36Sopenharmony_ci .bg = "default", 55462306a36Sopenharmony_ci }, 55562306a36Sopenharmony_ci { 55662306a36Sopenharmony_ci .colorset = HE_COLORSET_ADDR, 55762306a36Sopenharmony_ci .name = "addr", 55862306a36Sopenharmony_ci .fg = "magenta", 55962306a36Sopenharmony_ci .bg = "default", 56062306a36Sopenharmony_ci }, 56162306a36Sopenharmony_ci { 56262306a36Sopenharmony_ci .colorset = HE_COLORSET_ROOT, 56362306a36Sopenharmony_ci .name = "root", 56462306a36Sopenharmony_ci .fg = "white", 56562306a36Sopenharmony_ci .bg = "blue", 56662306a36Sopenharmony_ci }, 56762306a36Sopenharmony_ci { 56862306a36Sopenharmony_ci .name = NULL, 56962306a36Sopenharmony_ci } 57062306a36Sopenharmony_ci}; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_cistatic int ui_browser__color_config(const char *var, const char *value, 57462306a36Sopenharmony_ci void *data __maybe_unused) 57562306a36Sopenharmony_ci{ 57662306a36Sopenharmony_ci char *fg = NULL, *bg; 57762306a36Sopenharmony_ci int i; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci /* same dir for all commands */ 58062306a36Sopenharmony_ci if (!strstarts(var, "colors.") != 0) 58162306a36Sopenharmony_ci return 0; 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) { 58462306a36Sopenharmony_ci const char *name = var + 7; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci if (strcmp(ui_browser__colorsets[i].name, name) != 0) 58762306a36Sopenharmony_ci continue; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci fg = strdup(value); 59062306a36Sopenharmony_ci if (fg == NULL) 59162306a36Sopenharmony_ci break; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci bg = strchr(fg, ','); 59462306a36Sopenharmony_ci if (bg == NULL) 59562306a36Sopenharmony_ci break; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci *bg = '\0'; 59862306a36Sopenharmony_ci bg = skip_spaces(bg + 1); 59962306a36Sopenharmony_ci ui_browser__colorsets[i].bg = bg; 60062306a36Sopenharmony_ci ui_browser__colorsets[i].fg = fg; 60162306a36Sopenharmony_ci return 0; 60262306a36Sopenharmony_ci } 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci free(fg); 60562306a36Sopenharmony_ci return -1; 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_civoid ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence) 60962306a36Sopenharmony_ci{ 61062306a36Sopenharmony_ci switch (whence) { 61162306a36Sopenharmony_ci case SEEK_SET: 61262306a36Sopenharmony_ci browser->top = browser->entries; 61362306a36Sopenharmony_ci break; 61462306a36Sopenharmony_ci case SEEK_CUR: 61562306a36Sopenharmony_ci browser->top = (char **)browser->top + offset; 61662306a36Sopenharmony_ci break; 61762306a36Sopenharmony_ci case SEEK_END: 61862306a36Sopenharmony_ci browser->top = (char **)browser->entries + browser->nr_entries - 1 + offset; 61962306a36Sopenharmony_ci break; 62062306a36Sopenharmony_ci default: 62162306a36Sopenharmony_ci return; 62262306a36Sopenharmony_ci } 62362306a36Sopenharmony_ci assert((char **)browser->top < (char **)browser->entries + browser->nr_entries); 62462306a36Sopenharmony_ci assert((char **)browser->top >= (char **)browser->entries); 62562306a36Sopenharmony_ci} 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ciunsigned int ui_browser__argv_refresh(struct ui_browser *browser) 62862306a36Sopenharmony_ci{ 62962306a36Sopenharmony_ci unsigned int row = 0, idx = browser->top_idx; 63062306a36Sopenharmony_ci char **pos; 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci if (browser->top == NULL) 63362306a36Sopenharmony_ci browser->top = browser->entries; 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci pos = (char **)browser->top; 63662306a36Sopenharmony_ci while (idx < browser->nr_entries && 63762306a36Sopenharmony_ci row < (unsigned)SLtt_Screen_Rows - 1) { 63862306a36Sopenharmony_ci assert(pos < (char **)browser->entries + browser->nr_entries); 63962306a36Sopenharmony_ci if (!browser->filter || !browser->filter(browser, *pos)) { 64062306a36Sopenharmony_ci ui_browser__gotorc(browser, row, 0); 64162306a36Sopenharmony_ci browser->write(browser, pos, row); 64262306a36Sopenharmony_ci if (++row == browser->rows) 64362306a36Sopenharmony_ci break; 64462306a36Sopenharmony_ci } 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci ++idx; 64762306a36Sopenharmony_ci ++pos; 64862306a36Sopenharmony_ci } 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci return row; 65162306a36Sopenharmony_ci} 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_civoid __ui_browser__vline(struct ui_browser *browser, unsigned int column, 65462306a36Sopenharmony_ci u16 start, u16 end) 65562306a36Sopenharmony_ci{ 65662306a36Sopenharmony_ci SLsmg_set_char_set(1); 65762306a36Sopenharmony_ci ui_browser__gotorc(browser, start, column); 65862306a36Sopenharmony_ci SLsmg_draw_vline(end - start + 1); 65962306a36Sopenharmony_ci SLsmg_set_char_set(0); 66062306a36Sopenharmony_ci} 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_civoid ui_browser__write_graph(struct ui_browser *browser __maybe_unused, 66362306a36Sopenharmony_ci int graph) 66462306a36Sopenharmony_ci{ 66562306a36Sopenharmony_ci SLsmg_set_char_set(1); 66662306a36Sopenharmony_ci SLsmg_write_char(graph); 66762306a36Sopenharmony_ci SLsmg_set_char_set(0); 66862306a36Sopenharmony_ci} 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_cistatic void __ui_browser__line_arrow_up(struct ui_browser *browser, 67162306a36Sopenharmony_ci unsigned int column, 67262306a36Sopenharmony_ci u64 start, u64 end) 67362306a36Sopenharmony_ci{ 67462306a36Sopenharmony_ci unsigned int row, end_row; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci SLsmg_set_char_set(1); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci if (start < browser->top_idx + browser->rows) { 67962306a36Sopenharmony_ci row = start - browser->top_idx; 68062306a36Sopenharmony_ci ui_browser__gotorc(browser, row, column); 68162306a36Sopenharmony_ci SLsmg_write_char(SLSMG_LLCORN_CHAR); 68262306a36Sopenharmony_ci ui_browser__gotorc(browser, row, column + 1); 68362306a36Sopenharmony_ci SLsmg_draw_hline(2); 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci if (row-- == 0) 68662306a36Sopenharmony_ci goto out; 68762306a36Sopenharmony_ci } else 68862306a36Sopenharmony_ci row = browser->rows - 1; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci if (end > browser->top_idx) 69162306a36Sopenharmony_ci end_row = end - browser->top_idx; 69262306a36Sopenharmony_ci else 69362306a36Sopenharmony_ci end_row = 0; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column); 69662306a36Sopenharmony_ci SLsmg_draw_vline(row - end_row + 1); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column); 69962306a36Sopenharmony_ci if (end >= browser->top_idx) { 70062306a36Sopenharmony_ci SLsmg_write_char(SLSMG_ULCORN_CHAR); 70162306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column + 1); 70262306a36Sopenharmony_ci SLsmg_write_char(SLSMG_HLINE_CHAR); 70362306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column + 2); 70462306a36Sopenharmony_ci SLsmg_write_char(SLSMG_RARROW_CHAR); 70562306a36Sopenharmony_ci } 70662306a36Sopenharmony_ciout: 70762306a36Sopenharmony_ci SLsmg_set_char_set(0); 70862306a36Sopenharmony_ci} 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_cistatic void __ui_browser__line_arrow_down(struct ui_browser *browser, 71162306a36Sopenharmony_ci unsigned int column, 71262306a36Sopenharmony_ci u64 start, u64 end) 71362306a36Sopenharmony_ci{ 71462306a36Sopenharmony_ci unsigned int row, end_row; 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci SLsmg_set_char_set(1); 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci if (start >= browser->top_idx) { 71962306a36Sopenharmony_ci row = start - browser->top_idx; 72062306a36Sopenharmony_ci ui_browser__gotorc(browser, row, column); 72162306a36Sopenharmony_ci SLsmg_write_char(SLSMG_ULCORN_CHAR); 72262306a36Sopenharmony_ci ui_browser__gotorc(browser, row, column + 1); 72362306a36Sopenharmony_ci SLsmg_draw_hline(2); 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci if (++row == 0) 72662306a36Sopenharmony_ci goto out; 72762306a36Sopenharmony_ci } else 72862306a36Sopenharmony_ci row = 0; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci if (end >= browser->top_idx + browser->rows) 73162306a36Sopenharmony_ci end_row = browser->rows - 1; 73262306a36Sopenharmony_ci else 73362306a36Sopenharmony_ci end_row = end - browser->top_idx; 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci ui_browser__gotorc(browser, row, column); 73662306a36Sopenharmony_ci SLsmg_draw_vline(end_row - row + 1); 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column); 73962306a36Sopenharmony_ci if (end < browser->top_idx + browser->rows) { 74062306a36Sopenharmony_ci SLsmg_write_char(SLSMG_LLCORN_CHAR); 74162306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column + 1); 74262306a36Sopenharmony_ci SLsmg_write_char(SLSMG_HLINE_CHAR); 74362306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column + 2); 74462306a36Sopenharmony_ci SLsmg_write_char(SLSMG_RARROW_CHAR); 74562306a36Sopenharmony_ci } 74662306a36Sopenharmony_ciout: 74762306a36Sopenharmony_ci SLsmg_set_char_set(0); 74862306a36Sopenharmony_ci} 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_civoid __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, 75162306a36Sopenharmony_ci u64 start, u64 end) 75262306a36Sopenharmony_ci{ 75362306a36Sopenharmony_ci if (start > end) 75462306a36Sopenharmony_ci __ui_browser__line_arrow_up(browser, column, start, end); 75562306a36Sopenharmony_ci else 75662306a36Sopenharmony_ci __ui_browser__line_arrow_down(browser, column, start, end); 75762306a36Sopenharmony_ci} 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_civoid ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, 76062306a36Sopenharmony_ci unsigned int row, int diff, bool arrow_down) 76162306a36Sopenharmony_ci{ 76262306a36Sopenharmony_ci int end_row; 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci if (diff <= 0) 76562306a36Sopenharmony_ci return; 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci SLsmg_set_char_set(1); 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci if (arrow_down) { 77062306a36Sopenharmony_ci if (row + diff <= browser->top_idx) 77162306a36Sopenharmony_ci return; 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci end_row = row + diff - browser->top_idx; 77462306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column - 1); 77562306a36Sopenharmony_ci SLsmg_write_char(SLSMG_LTEE_CHAR); 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci while (--end_row >= 0 && end_row > (int)(row - browser->top_idx)) { 77862306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column - 1); 77962306a36Sopenharmony_ci SLsmg_draw_vline(1); 78062306a36Sopenharmony_ci } 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci end_row = (int)(row - browser->top_idx); 78362306a36Sopenharmony_ci if (end_row >= 0) { 78462306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column - 1); 78562306a36Sopenharmony_ci SLsmg_write_char(SLSMG_ULCORN_CHAR); 78662306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column); 78762306a36Sopenharmony_ci SLsmg_draw_hline(2); 78862306a36Sopenharmony_ci } 78962306a36Sopenharmony_ci } else { 79062306a36Sopenharmony_ci if (row < browser->top_idx) 79162306a36Sopenharmony_ci return; 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci end_row = row - browser->top_idx; 79462306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column - 1); 79562306a36Sopenharmony_ci SLsmg_write_char(SLSMG_LTEE_CHAR); 79662306a36Sopenharmony_ci ui_browser__gotorc(browser, end_row, column); 79762306a36Sopenharmony_ci SLsmg_draw_hline(2); 79862306a36Sopenharmony_ci } 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_ci SLsmg_set_char_set(0); 80162306a36Sopenharmony_ci} 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_civoid ui_browser__init(void) 80462306a36Sopenharmony_ci{ 80562306a36Sopenharmony_ci int i = 0; 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci perf_config(ui_browser__color_config, NULL); 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci while (ui_browser__colorsets[i].name) { 81062306a36Sopenharmony_ci struct ui_browser_colorset *c = &ui_browser__colorsets[i++]; 81162306a36Sopenharmony_ci SLtt_set_color(c->colorset, c->name, c->fg, c->bg); 81262306a36Sopenharmony_ci } 81362306a36Sopenharmony_ci} 814