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