18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include "ui/browser.h" 38c2ecf20Sopenharmony_ci#include "ui/keysyms.h" 48c2ecf20Sopenharmony_ci#include "ui/ui.h" 58c2ecf20Sopenharmony_ci#include "ui/util.h" 68c2ecf20Sopenharmony_ci#include "ui/libslang.h" 78c2ecf20Sopenharmony_ci#include "util/header.h" 88c2ecf20Sopenharmony_ci#include "util/session.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <sys/ttydefaults.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic void ui_browser__argv_write(struct ui_browser *browser, 138c2ecf20Sopenharmony_ci void *entry, int row) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci char **arg = entry; 168c2ecf20Sopenharmony_ci char *str = *arg; 178c2ecf20Sopenharmony_ci char empty[] = " "; 188c2ecf20Sopenharmony_ci bool current_entry = ui_browser__is_current_entry(browser, row); 198c2ecf20Sopenharmony_ci unsigned long offset = (unsigned long)browser->priv; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci if (offset >= strlen(str)) 228c2ecf20Sopenharmony_ci str = empty; 238c2ecf20Sopenharmony_ci else 248c2ecf20Sopenharmony_ci str = str + offset; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : 278c2ecf20Sopenharmony_ci HE_COLORSET_NORMAL); 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci ui_browser__write_nstring(browser, str, browser->width); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic int list_menu__run(struct ui_browser *menu) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci int key; 358c2ecf20Sopenharmony_ci unsigned long offset; 368c2ecf20Sopenharmony_ci static const char help[] = 378c2ecf20Sopenharmony_ci "h/?/F1 Show this window\n" 388c2ecf20Sopenharmony_ci "UP/DOWN/PGUP\n" 398c2ecf20Sopenharmony_ci "PGDN/SPACE\n" 408c2ecf20Sopenharmony_ci "LEFT/RIGHT Navigate\n" 418c2ecf20Sopenharmony_ci "q/ESC/CTRL+C Exit browser"; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0) 448c2ecf20Sopenharmony_ci return -1; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci while (1) { 478c2ecf20Sopenharmony_ci key = ui_browser__run(menu, 0); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci switch (key) { 508c2ecf20Sopenharmony_ci case K_RIGHT: 518c2ecf20Sopenharmony_ci offset = (unsigned long)menu->priv; 528c2ecf20Sopenharmony_ci offset += 10; 538c2ecf20Sopenharmony_ci menu->priv = (void *)offset; 548c2ecf20Sopenharmony_ci continue; 558c2ecf20Sopenharmony_ci case K_LEFT: 568c2ecf20Sopenharmony_ci offset = (unsigned long)menu->priv; 578c2ecf20Sopenharmony_ci if (offset >= 10) 588c2ecf20Sopenharmony_ci offset -= 10; 598c2ecf20Sopenharmony_ci menu->priv = (void *)offset; 608c2ecf20Sopenharmony_ci continue; 618c2ecf20Sopenharmony_ci case K_F1: 628c2ecf20Sopenharmony_ci case 'h': 638c2ecf20Sopenharmony_ci case '?': 648c2ecf20Sopenharmony_ci ui_browser__help_window(menu, help); 658c2ecf20Sopenharmony_ci continue; 668c2ecf20Sopenharmony_ci case K_ESC: 678c2ecf20Sopenharmony_ci case 'q': 688c2ecf20Sopenharmony_ci case CTRL('c'): 698c2ecf20Sopenharmony_ci key = -1; 708c2ecf20Sopenharmony_ci break; 718c2ecf20Sopenharmony_ci default: 728c2ecf20Sopenharmony_ci continue; 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci break; 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci ui_browser__hide(menu); 798c2ecf20Sopenharmony_ci return key; 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic int ui__list_menu(int argc, char * const argv[]) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci struct ui_browser menu = { 858c2ecf20Sopenharmony_ci .entries = (void *)argv, 868c2ecf20Sopenharmony_ci .refresh = ui_browser__argv_refresh, 878c2ecf20Sopenharmony_ci .seek = ui_browser__argv_seek, 888c2ecf20Sopenharmony_ci .write = ui_browser__argv_write, 898c2ecf20Sopenharmony_ci .nr_entries = argc, 908c2ecf20Sopenharmony_ci }; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci return list_menu__run(&menu); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ciint tui__header_window(struct perf_env *env) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci int i, argc = 0; 988c2ecf20Sopenharmony_ci char **argv; 998c2ecf20Sopenharmony_ci struct perf_session *session; 1008c2ecf20Sopenharmony_ci char *ptr, *pos; 1018c2ecf20Sopenharmony_ci size_t size; 1028c2ecf20Sopenharmony_ci FILE *fp = open_memstream(&ptr, &size); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci session = container_of(env, struct perf_session, header.env); 1058c2ecf20Sopenharmony_ci perf_header__fprintf_info(session, fp, true); 1068c2ecf20Sopenharmony_ci fclose(fp); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++) 1098c2ecf20Sopenharmony_ci argc++; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci argv = calloc(argc + 1, sizeof(*argv)); 1128c2ecf20Sopenharmony_ci if (argv == NULL) 1138c2ecf20Sopenharmony_ci goto out; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci argv[0] = pos = ptr; 1168c2ecf20Sopenharmony_ci for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) { 1178c2ecf20Sopenharmony_ci *pos++ = '\0'; 1188c2ecf20Sopenharmony_ci argv[i] = pos; 1198c2ecf20Sopenharmony_ci } 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci BUG_ON(i != argc + 1); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci ui__list_menu(argc, argv); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ciout: 1268c2ecf20Sopenharmony_ci free(argv); 1278c2ecf20Sopenharmony_ci free(ptr); 1288c2ecf20Sopenharmony_ci return 0; 1298c2ecf20Sopenharmony_ci} 130