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