| 1 | |
| 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 | ui_browser__warn_unhandled_hotkey(menu, key, 0, ", use 'h'/'?'/F1 to see actions");
|
| 73 | continue;
|
| 74 | }
|
| 75 |
|
| 76 | break;
|
| 77 | }
|
| 78 |
|
| 79 | ui_browser__hide(menu);
|
| 80 | return key;
|
| 81 | }
|
| 82 |
|
| 83 | static int ui__list_menu(int argc, char * const argv[])
|
| 84 | {
|
| 85 | struct ui_browser menu = {
|
| 86 | .entries = (void *)argv,
|
| 87 | .refresh = ui_browser__argv_refresh,
|
| 88 | .seek = ui_browser__argv_seek,
|
| 89 | .write = ui_browser__argv_write,
|
| 90 | .nr_entries = argc,
|
| 91 | };
|
| 92 |
|
| 93 | return list_menu__run(&menu);
|
| 94 | }
|
| 95 |
|
| 96 | int tui__header_window(struct perf_session *session)
|
| 97 | {
|
| 98 | int i, argc = 0;
|
| 99 | char **argv;
|
| 100 | char *ptr, *pos;
|
| 101 | size_t size;
|
| 102 | FILE *fp = open_memstream(&ptr, &size);
|
| 103 |
|
| 104 | perf_header__fprintf_info(session, fp, true);
|
| 105 | fclose(fp);
|
| 106 |
|
| 107 | for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++)
|
| 108 | argc++;
|
| 109 |
|
| 110 | argv = calloc(argc + 1, sizeof(*argv));
|
| 111 | if (argv == NULL)
|
| 112 | goto out;
|
| 113 |
|
| 114 | argv[0] = pos = ptr;
|
| 115 | for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) {
|
| 116 | *pos++ = '\0';
|
| 117 | argv[i] = pos;
|
| 118 | }
|
| 119 |
|
| 120 | BUG_ON(i != argc + 1);
|
| 121 |
|
| 122 | ui__list_menu(argc, argv);
|
| 123 |
|
| 124 | out:
|
| 125 | free(argv);
|
| 126 | free(ptr);
|
| 127 | return 0;
|
| 128 | }
|