1 // SPDX-License-Identifier: GPL-2.0 2 #include "util/cache.h" 3 #include "util/debug.h" 4 #include "ui/browser.h" 5 #include "ui/keysyms.h" 6 #include "ui/ui.h" 7 #include "ui/util.h" 8 #include "ui/libslang.h" 9 #include "util/header.h" 10 #include "util/session.h" 11 12 #include <sys/ttydefaults.h> 13 14 static void ui_browser__argv_write(struct ui_browser *browser, 15 void *entry, int row) 16 { 17 char **arg = entry; 18 char *str = *arg; 19 char empty[] = " "; 20 bool current_entry = ui_browser__is_current_entry(browser, row); 21 unsigned long offset = (unsigned long)browser->priv; 22 23 if (offset >= strlen(str)) 24 str = empty; 25 else 26 str = str + offset; 27 28 ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : 29 HE_COLORSET_NORMAL); 30 31 ui_browser__write_nstring(browser, str, browser->width); 32 } 33 34 static int list_menu__run(struct ui_browser *menu) 35 { 36 int key; 37 unsigned long offset; 38 const char help[] = 39 "h/?/F1 Show this window\n" 40 "UP/DOWN/PGUP\n" 41 "PGDN/SPACE\n" 42 "LEFT/RIGHT Navigate\n" 43 "q/ESC/CTRL+C Exit browser"; 44 45 if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0) 46 return -1; 47 48 while (1) { 49 key = ui_browser__run(menu, 0); 50 51 switch (key) { 52 case K_RIGHT: 53 offset = (unsigned long)menu->priv; 54 offset += 10; 55 menu->priv = (void *)offset; 56 continue; 57 case K_LEFT: 58 offset = (unsigned long)menu->priv; 59 if (offset >= 10) 60 offset -= 10; 61 menu->priv = (void *)offset; 62 continue; 63 case K_F1: 64 case 'h': 65 case '?': 66 ui_browser__help_window(menu, help); 67 continue; 68 case K_ESC: 69 case 'q': 70 case CTRL('c'): 71 key = -1; 72 break; 73 default: 74 continue; 75 } 76 77 break; 78 } 79 80 ui_browser__hide(menu); 81 return key; 82 } 83 84 static int ui__list_menu(int argc, char * const argv[]) 85 { 86 struct ui_browser menu = { 87 .entries = (void *)argv, 88 .refresh = ui_browser__argv_refresh, 89 .seek = ui_browser__argv_seek, 90 .write = ui_browser__argv_write, 91 .nr_entries = argc, 92 }; 93 94 return list_menu__run(&menu); 95 } 96 97 int tui__header_window(struct perf_env *env) 98 { 99 int i, argc = 0; 100 char **argv; 101 struct perf_session *session; 102 char *ptr, *pos; 103 size_t size; 104 FILE *fp = open_memstream(&ptr, &size); 105 106 session = container_of(env, struct perf_session, header.env); 107 perf_header__fprintf_info(session, fp, true); 108 fclose(fp); 109 110 for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++) 111 argc++; 112 113 argv = calloc(argc + 1, sizeof(*argv)); 114 if (argv == NULL) 115 goto out; 116 117 argv[0] = pos = ptr; 118 for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) { 119 *pos++ = '\0'; 120 argv[i] = pos; 121 } 122 123 BUG_ON(i != argc + 1); 124 125 ui__list_menu(argc, argv); 126 127 out: 128 free(argv); 129 free(ptr); 130 return 0; 131 } 132