root/tools/perf/ui/tui/util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ui_browser__argv_write
  2. popup_menu__run
  3. ui__popup_menu
  4. ui_browser__input_window
  5. __ui__info_window
  6. ui__info_window
  7. ui__question_window
  8. ui__help_window
  9. ui__dialog_yesno
  10. __ui__warning
  11. perf_tui__error
  12. perf_tui__warning

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

/* [<][>][^][v][top][bottom][index][help] */