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