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        ui_browser__write_nstring(browser, *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        pthread_mutex_lock(&ui__lock);
  96
  97        max_len += 2;
  98        nr_lines += 8;
  99        y = SLtt_Screen_Rows / 2 - nr_lines / 2;
 100        x = SLtt_Screen_Cols / 2 - max_len / 2;
 101
 102        SLsmg_set_color(0);
 103        SLsmg_draw_box(y, x++, nr_lines, max_len);
 104        if (title) {
 105                SLsmg_gotorc(y, x + 1);
 106                SLsmg_write_string((char *)title);
 107        }
 108        SLsmg_gotorc(++y, x);
 109        nr_lines -= 7;
 110        max_len -= 2;
 111        SLsmg_write_wrapped_string((unsigned char *)text, y, x,
 112                                   nr_lines, max_len, 1);
 113        y += nr_lines;
 114        len = 5;
 115        while (len--) {
 116                SLsmg_gotorc(y + len - 1, x);
 117                SLsmg_write_nstring((char *)" ", max_len);
 118        }
 119        SLsmg_draw_box(y++, x + 1, 3, max_len - 2);
 120
 121        SLsmg_gotorc(y + 3, x);
 122        SLsmg_write_nstring((char *)exit_msg, max_len);
 123        SLsmg_refresh();
 124
 125        pthread_mutex_unlock(&ui__lock);
 126
 127        x += 2;
 128        len = 0;
 129        key = ui__getch(delay_secs);
 130        while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
 131                pthread_mutex_lock(&ui__lock);
 132
 133                if (key == K_BKSPC) {
 134                        if (len == 0) {
 135                                pthread_mutex_unlock(&ui__lock);
 136                                goto next_key;
 137                        }
 138                        SLsmg_gotorc(y, x + --len);
 139                        SLsmg_write_char(' ');
 140                } else {
 141                        buf[len] = key;
 142                        SLsmg_gotorc(y, x + len++);
 143                        SLsmg_write_char(key);
 144                }
 145                SLsmg_refresh();
 146
 147                pthread_mutex_unlock(&ui__lock);
 148
 149                /* XXX more graceful overflow handling needed */
 150                if (len == sizeof(buf) - 1) {
 151                        ui_helpline__push("maximum size of symbol name reached!");
 152                        key = K_ENTER;
 153                        break;
 154                }
 155next_key:
 156                key = ui__getch(delay_secs);
 157        }
 158
 159        buf[len] = '\0';
 160        strncpy(input, buf, len+1);
 161        return key;
 162}
 163
 164int ui__question_window(const char *title, const char *text,
 165                        const char *exit_msg, int delay_secs)
 166{
 167        int x, y;
 168        int max_len = 0, nr_lines = 0;
 169        const char *t;
 170
 171        t = text;
 172        while (1) {
 173                const char *sep = strchr(t, '\n');
 174                int len;
 175
 176                if (sep == NULL)
 177                        sep = strchr(t, '\0');
 178                len = sep - t;
 179                if (max_len < len)
 180                        max_len = len;
 181                ++nr_lines;
 182                if (*sep == '\0')
 183                        break;
 184                t = sep + 1;
 185        }
 186
 187        pthread_mutex_lock(&ui__lock);
 188
 189        max_len += 2;
 190        nr_lines += 4;
 191        y = SLtt_Screen_Rows / 2 - nr_lines / 2,
 192        x = SLtt_Screen_Cols / 2 - max_len / 2;
 193
 194        SLsmg_set_color(0);
 195        SLsmg_draw_box(y, x++, nr_lines, max_len);
 196        if (title) {
 197                SLsmg_gotorc(y, x + 1);
 198                SLsmg_write_string((char *)title);
 199        }
 200        SLsmg_gotorc(++y, x);
 201        nr_lines -= 2;
 202        max_len -= 2;
 203        SLsmg_write_wrapped_string((unsigned char *)text, y, x,
 204                                   nr_lines, max_len, 1);
 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        SLsmg_refresh();
 210
 211        pthread_mutex_unlock(&ui__lock);
 212
 213        return ui__getch(delay_secs);
 214}
 215
 216int ui__help_window(const char *text)
 217{
 218        return ui__question_window("Help", text, "Press any key...", 0);
 219}
 220
 221int ui__dialog_yesno(const char *msg)
 222{
 223        return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
 224}
 225
 226static int __ui__warning(const char *title, const char *format, va_list args)
 227{
 228        char *s;
 229
 230        if (vasprintf(&s, format, args) > 0) {
 231                int key;
 232
 233                key = ui__question_window(title, s, "Press any key...", 0);
 234                free(s);
 235                return key;
 236        }
 237
 238        fprintf(stderr, "%s\n", title);
 239        vfprintf(stderr, format, args);
 240        return K_ESC;
 241}
 242
 243static int perf_tui__error(const char *format, va_list args)
 244{
 245        return __ui__warning("Error:", format, args);
 246}
 247
 248static int perf_tui__warning(const char *format, va_list args)
 249{
 250        return __ui__warning("Warning:", format, args);
 251}
 252
 253struct perf_error_ops perf_tui_eops = {
 254        .error          = perf_tui__error,
 255        .warning        = perf_tui__warning,
 256};
 257