Linux Perf
util.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 #include "../../util/util.h"
3 #include <signal.h>
4 #include <stdbool.h>
5 #include <string.h>
6 #include <sys/ttydefaults.h>
7 
8 #include "../../util/cache.h"
9 #include "../../util/debug.h"
10 #include "../browser.h"
11 #include "../keysyms.h"
12 #include "../helpline.h"
13 #include "../ui.h"
14 #include "../util.h"
15 #include "../libslang.h"
16 
17 static void ui_browser__argv_write(struct ui_browser *browser,
18  void *entry, int row)
19 {
20  char **arg = entry;
21  bool current_entry = ui_browser__is_current_entry(browser, row);
22 
23  ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
25  ui_browser__write_nstring(browser, *arg, browser->width);
26 }
27 
28 static int popup_menu__run(struct ui_browser *menu)
29 {
30  int key;
31 
32  if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
33  return -1;
34 
35  while (1) {
36  key = ui_browser__run(menu, 0);
37 
38  switch (key) {
39  case K_RIGHT:
40  case K_ENTER:
41  key = menu->index;
42  break;
43  case K_LEFT:
44  case K_ESC:
45  case 'q':
46  case CTRL('c'):
47  key = -1;
48  break;
49  default:
50  continue;
51  }
52 
53  break;
54  }
55 
56  ui_browser__hide(menu);
57  return key;
58 }
59 
60 int ui__popup_menu(int argc, char * const argv[])
61 {
62  struct ui_browser menu = {
63  .entries = (void *)argv,
67  .nr_entries = argc,
68  };
69 
70  return popup_menu__run(&menu);
71 }
72 
73 int ui_browser__input_window(const char *title, const char *text, char *input,
74  const char *exit_msg, int delay_secs)
75 {
76  int x, y, len, key;
77  int max_len = 60, nr_lines = 0;
78  static char buf[50];
79  const char *t;
80 
81  t = text;
82  while (1) {
83  const char *sep = strchr(t, '\n');
84 
85  if (sep == NULL)
86  sep = strchr(t, '\0');
87  len = sep - t;
88  if (max_len < len)
89  max_len = len;
90  ++nr_lines;
91  if (*sep == '\0')
92  break;
93  t = sep + 1;
94  }
95 
96  pthread_mutex_lock(&ui__lock);
97 
98  max_len += 2;
99  nr_lines += 8;
100  y = SLtt_Screen_Rows / 2 - nr_lines / 2;
101  x = SLtt_Screen_Cols / 2 - max_len / 2;
102 
103  SLsmg_set_color(0);
104  SLsmg_draw_box(y, x++, nr_lines, max_len);
105  if (title) {
106  SLsmg_gotorc(y, x + 1);
107  SLsmg_write_string((char *)title);
108  }
109  SLsmg_gotorc(++y, x);
110  nr_lines -= 7;
111  max_len -= 2;
112  SLsmg_write_wrapped_string((unsigned char *)text, y, x,
113  nr_lines, max_len, 1);
114  y += nr_lines;
115  len = 5;
116  while (len--) {
117  SLsmg_gotorc(y + len - 1, x);
118  SLsmg_write_nstring((char *)" ", max_len);
119  }
120  SLsmg_draw_box(y++, x + 1, 3, max_len - 2);
121 
122  SLsmg_gotorc(y + 3, x);
123  SLsmg_write_nstring((char *)exit_msg, max_len);
124  SLsmg_refresh();
125 
126  pthread_mutex_unlock(&ui__lock);
127 
128  x += 2;
129  len = 0;
130  key = ui__getch(delay_secs);
131  while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
132  pthread_mutex_lock(&ui__lock);
133 
134  if (key == K_BKSPC) {
135  if (len == 0) {
136  pthread_mutex_unlock(&ui__lock);
137  goto next_key;
138  }
139  SLsmg_gotorc(y, x + --len);
140  SLsmg_write_char(' ');
141  } else {
142  buf[len] = key;
143  SLsmg_gotorc(y, x + len++);
144  SLsmg_write_char(key);
145  }
146  SLsmg_refresh();
147 
148  pthread_mutex_unlock(&ui__lock);
149 
150  /* XXX more graceful overflow handling needed */
151  if (len == sizeof(buf) - 1) {
152  ui_helpline__push("maximum size of symbol name reached!");
153  key = K_ENTER;
154  break;
155  }
156 next_key:
157  key = ui__getch(delay_secs);
158  }
159 
160  buf[len] = '\0';
161  strncpy(input, buf, len+1);
162  return key;
163 }
164 
165 int ui__question_window(const char *title, const char *text,
166  const char *exit_msg, int delay_secs)
167 {
168  int x, y;
169  int max_len = 0, nr_lines = 0;
170  const char *t;
171 
172  t = text;
173  while (1) {
174  const char *sep = strchr(t, '\n');
175  int len;
176 
177  if (sep == NULL)
178  sep = strchr(t, '\0');
179  len = sep - t;
180  if (max_len < len)
181  max_len = len;
182  ++nr_lines;
183  if (*sep == '\0')
184  break;
185  t = sep + 1;
186  }
187 
188  pthread_mutex_lock(&ui__lock);
189 
190  max_len += 2;
191  nr_lines += 4;
192  y = SLtt_Screen_Rows / 2 - nr_lines / 2,
193  x = SLtt_Screen_Cols / 2 - max_len / 2;
194 
195  SLsmg_set_color(0);
196  SLsmg_draw_box(y, x++, nr_lines, max_len);
197  if (title) {
198  SLsmg_gotorc(y, x + 1);
199  SLsmg_write_string((char *)title);
200  }
201  SLsmg_gotorc(++y, x);
202  nr_lines -= 2;
203  max_len -= 2;
204  SLsmg_write_wrapped_string((unsigned char *)text, y, x,
205  nr_lines, max_len, 1);
206  SLsmg_gotorc(y + nr_lines - 2, x);
207  SLsmg_write_nstring((char *)" ", max_len);
208  SLsmg_gotorc(y + nr_lines - 1, x);
209  SLsmg_write_nstring((char *)exit_msg, max_len);
210  SLsmg_refresh();
211 
212  pthread_mutex_unlock(&ui__lock);
213 
214  return ui__getch(delay_secs);
215 }
216 
217 int ui__help_window(const char *text)
218 {
219  return ui__question_window("Help", text, "Press any key...", 0);
220 }
221 
222 int ui__dialog_yesno(const char *msg)
223 {
224  return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
225 }
226 
227 static int __ui__warning(const char *title, const char *format, va_list args)
228 {
229  char *s;
230 
231  if (vasprintf(&s, format, args) > 0) {
232  int key;
233 
234  key = ui__question_window(title, s, "Press any key...", 0);
235  free(s);
236  return key;
237  }
238 
239  fprintf(stderr, "%s\n", title);
240  vfprintf(stderr, format, args);
241  return K_ESC;
242 }
243 
244 static int perf_tui__error(const char *format, va_list args)
245 {
246  return __ui__warning("Error:", format, args);
247 }
248 
249 static int perf_tui__warning(const char *format, va_list args)
250 {
251  return __ui__warning("Warning:", format, args);
252 }
253 
256  .warning = perf_tui__warning,
257 };
static int __ui__warning(const char *title, const char *format, va_list args)
Definition: util.c:227
int ui__help_window(const char *text)
Definition: util.c:217
#define K_TIMER
Definition: keysyms.h:24
int ui_browser__input_window(const char *title, const char *text, char *input, const char *exit_msg, int delay_secs)
Definition: util.c:73
unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
Definition: browser.c:624
#define K_ESC
Definition: keysyms.h:10
#define HE_COLORSET_NORMAL
Definition: browser.h:10
int ui__getch(int delay_secs)
Definition: setup.c:56
int ui_browser__show(struct ui_browser *browser, const char *title, const char *helpline,...)
Definition: browser.c:277
static int popup_menu__run(struct ui_browser *menu)
Definition: util.c:28
static void ui_browser__argv_write(struct ui_browser *browser, void *entry, int row)
Definition: util.c:17
static int input(yyscan_t yyscanner)
u16 x
Definition: browser.h:19
const char * title
Definition: browser.h:23
pthread_mutex_t ui__lock
Definition: setup.c:10
void ui_helpline__push(const char *msg)
Definition: helpline.c:40
const char * key
Definition: bpf-loader.c:196
u64 index
Definition: browser.h:17
#define K_RIGHT
Definition: keysyms.h:16
bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row)
Definition: browser.c:190
static int entry(u64 ip, struct unwind_info *ui)
Definition: unwind-libdw.c:71
static int perf_tui__warning(const char *format, va_list args)
Definition: util.c:249
#define K_ENTER
Definition: keysyms.h:9
struct perf_error_ops perf_tui_eops
Definition: util.c:254
void(* write)(struct ui_browser *browser, void *entry, int row)
Definition: browser.h:27
unsigned int(* refresh)(struct ui_browser *browser)
Definition: browser.h:26
int(* error)(const char *format, va_list args)
Definition: util.h:15
void ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const char *msg, unsigned int width)
Definition: browser.c:58
#define K_LEFT
Definition: keysyms.h:13
u32 nr_entries
Definition: browser.h:30
u16 y
Definition: browser.h:19
#define HE_COLORSET_SELECTED
Definition: browser.h:11
int ui_browser__run(struct ui_browser *browser, int delay_secs)
Definition: browser.c:385
void free(void *)
void(* seek)(struct ui_browser *browser, off_t offset, int whence)
Definition: browser.h:28
int ui__dialog_yesno(const char *msg)
Definition: util.c:222
void ui_browser__hide(struct ui_browser *browser)
Definition: browser.c:303
int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs)
Definition: util.c:165
int ui_browser__set_color(struct ui_browser *browser, int color)
Definition: browser.c:33
static int perf_tui__error(const char *format, va_list args)
Definition: util.c:244
void * entries
Definition: browser.h:18
#define K_BKSPC
Definition: keysyms.h:20
int ui__popup_menu(int argc, char *const argv[])
Definition: util.c:60
void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence)
Definition: browser.c:607
u16 width
Definition: browser.h:19