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