hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
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
// 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:
           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;
}