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