0001
0002 #include "ui/browser.h"
0003 #include "ui/keysyms.h"
0004 #include "ui/ui.h"
0005 #include "ui/util.h"
0006 #include "ui/libslang.h"
0007 #include "util/header.h"
0008 #include "util/session.h"
0009
0010 #include <sys/ttydefaults.h>
0011
0012 static void ui_browser__argv_write(struct ui_browser *browser,
0013 void *entry, int row)
0014 {
0015 char **arg = entry;
0016 char *str = *arg;
0017 char empty[] = " ";
0018 bool current_entry = ui_browser__is_current_entry(browser, row);
0019 unsigned long offset = (unsigned long)browser->priv;
0020
0021 if (offset >= strlen(str))
0022 str = empty;
0023 else
0024 str = str + offset;
0025
0026 ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
0027 HE_COLORSET_NORMAL);
0028
0029 ui_browser__write_nstring(browser, str, browser->width);
0030 }
0031
0032 static int list_menu__run(struct ui_browser *menu)
0033 {
0034 int key;
0035 unsigned long offset;
0036 static const char help[] =
0037 "h/?/F1 Show this window\n"
0038 "UP/DOWN/PGUP\n"
0039 "PGDN/SPACE\n"
0040 "LEFT/RIGHT Navigate\n"
0041 "q/ESC/CTRL+C Exit browser";
0042
0043 if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0)
0044 return -1;
0045
0046 while (1) {
0047 key = ui_browser__run(menu, 0);
0048
0049 switch (key) {
0050 case K_RIGHT:
0051 offset = (unsigned long)menu->priv;
0052 offset += 10;
0053 menu->priv = (void *)offset;
0054 continue;
0055 case K_LEFT:
0056 offset = (unsigned long)menu->priv;
0057 if (offset >= 10)
0058 offset -= 10;
0059 menu->priv = (void *)offset;
0060 continue;
0061 case K_F1:
0062 case 'h':
0063 case '?':
0064 ui_browser__help_window(menu, help);
0065 continue;
0066 case K_ESC:
0067 case 'q':
0068 case CTRL('c'):
0069 key = -1;
0070 break;
0071 default:
0072 continue;
0073 }
0074
0075 break;
0076 }
0077
0078 ui_browser__hide(menu);
0079 return key;
0080 }
0081
0082 static int ui__list_menu(int argc, char * const argv[])
0083 {
0084 struct ui_browser menu = {
0085 .entries = (void *)argv,
0086 .refresh = ui_browser__argv_refresh,
0087 .seek = ui_browser__argv_seek,
0088 .write = ui_browser__argv_write,
0089 .nr_entries = argc,
0090 };
0091
0092 return list_menu__run(&menu);
0093 }
0094
0095 int tui__header_window(struct perf_env *env)
0096 {
0097 int i, argc = 0;
0098 char **argv;
0099 struct perf_session *session;
0100 char *ptr, *pos;
0101 size_t size;
0102 FILE *fp = open_memstream(&ptr, &size);
0103
0104 session = container_of(env, struct perf_session, header.env);
0105 perf_header__fprintf_info(session, fp, true);
0106 fclose(fp);
0107
0108 for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++)
0109 argc++;
0110
0111 argv = calloc(argc + 1, sizeof(*argv));
0112 if (argv == NULL)
0113 goto out;
0114
0115 argv[0] = pos = ptr;
0116 for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) {
0117 *pos++ = '\0';
0118 argv[i] = pos;
0119 }
0120
0121 BUG_ON(i != argc + 1);
0122
0123 ui__list_menu(argc, argv);
0124
0125 out:
0126 free(argv);
0127 free(ptr);
0128 return 0;
0129 }