10f66f451Sopenharmony_ci/* 20f66f451Sopenharmony_ci * util.c 30f66f451Sopenharmony_ci * 40f66f451Sopenharmony_ci * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 50f66f451Sopenharmony_ci * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 60f66f451Sopenharmony_ci * 70f66f451Sopenharmony_ci * This program is free software; you can redistribute it and/or 80f66f451Sopenharmony_ci * modify it under the terms of the GNU General Public License 90f66f451Sopenharmony_ci * as published by the Free Software Foundation; either version 2 100f66f451Sopenharmony_ci * of the License, or (at your option) any later version. 110f66f451Sopenharmony_ci * 120f66f451Sopenharmony_ci * This program is distributed in the hope that it will be useful, 130f66f451Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 140f66f451Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 150f66f451Sopenharmony_ci * GNU General Public License for more details. 160f66f451Sopenharmony_ci * 170f66f451Sopenharmony_ci * You should have received a copy of the GNU General Public License 180f66f451Sopenharmony_ci * along with this program; if not, write to the Free Software 190f66f451Sopenharmony_ci * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 200f66f451Sopenharmony_ci */ 210f66f451Sopenharmony_ci 220f66f451Sopenharmony_ci#include "dialog.h" 230f66f451Sopenharmony_ci 240f66f451Sopenharmony_cistruct dialog_info dlg; 250f66f451Sopenharmony_ci 260f66f451Sopenharmony_cistatic void set_mono_theme(void) 270f66f451Sopenharmony_ci{ 280f66f451Sopenharmony_ci dlg.screen.atr = A_NORMAL; 290f66f451Sopenharmony_ci dlg.shadow.atr = A_NORMAL; 300f66f451Sopenharmony_ci dlg.dialog.atr = A_NORMAL; 310f66f451Sopenharmony_ci dlg.title.atr = A_BOLD; 320f66f451Sopenharmony_ci dlg.border.atr = A_NORMAL; 330f66f451Sopenharmony_ci dlg.button_active.atr = A_REVERSE; 340f66f451Sopenharmony_ci dlg.button_inactive.atr = A_DIM; 350f66f451Sopenharmony_ci dlg.button_key_active.atr = A_REVERSE; 360f66f451Sopenharmony_ci dlg.button_key_inactive.atr = A_BOLD; 370f66f451Sopenharmony_ci dlg.button_label_active.atr = A_REVERSE; 380f66f451Sopenharmony_ci dlg.button_label_inactive.atr = A_NORMAL; 390f66f451Sopenharmony_ci dlg.inputbox.atr = A_NORMAL; 400f66f451Sopenharmony_ci dlg.inputbox_border.atr = A_NORMAL; 410f66f451Sopenharmony_ci dlg.searchbox.atr = A_NORMAL; 420f66f451Sopenharmony_ci dlg.searchbox_title.atr = A_BOLD; 430f66f451Sopenharmony_ci dlg.searchbox_border.atr = A_NORMAL; 440f66f451Sopenharmony_ci dlg.position_indicator.atr = A_BOLD; 450f66f451Sopenharmony_ci dlg.menubox.atr = A_NORMAL; 460f66f451Sopenharmony_ci dlg.menubox_border.atr = A_NORMAL; 470f66f451Sopenharmony_ci dlg.item.atr = A_NORMAL; 480f66f451Sopenharmony_ci dlg.item_selected.atr = A_REVERSE; 490f66f451Sopenharmony_ci dlg.tag.atr = A_BOLD; 500f66f451Sopenharmony_ci dlg.tag_selected.atr = A_REVERSE; 510f66f451Sopenharmony_ci dlg.tag_key.atr = A_BOLD; 520f66f451Sopenharmony_ci dlg.tag_key_selected.atr = A_REVERSE; 530f66f451Sopenharmony_ci dlg.check.atr = A_BOLD; 540f66f451Sopenharmony_ci dlg.check_selected.atr = A_REVERSE; 550f66f451Sopenharmony_ci dlg.uarrow.atr = A_BOLD; 560f66f451Sopenharmony_ci dlg.darrow.atr = A_BOLD; 570f66f451Sopenharmony_ci} 580f66f451Sopenharmony_ci 590f66f451Sopenharmony_ci#define DLG_COLOR(dialog, f, b, h) \ 600f66f451Sopenharmony_cido { \ 610f66f451Sopenharmony_ci dlg.dialog.fg = (f); \ 620f66f451Sopenharmony_ci dlg.dialog.bg = (b); \ 630f66f451Sopenharmony_ci dlg.dialog.hl = (h); \ 640f66f451Sopenharmony_ci} while (0) 650f66f451Sopenharmony_ci 660f66f451Sopenharmony_cistatic void set_classic_theme(void) 670f66f451Sopenharmony_ci{ 680f66f451Sopenharmony_ci DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true); 690f66f451Sopenharmony_ci DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true); 700f66f451Sopenharmony_ci DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false); 710f66f451Sopenharmony_ci DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true); 720f66f451Sopenharmony_ci DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true); 730f66f451Sopenharmony_ci DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true); 740f66f451Sopenharmony_ci DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false); 750f66f451Sopenharmony_ci DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true); 760f66f451Sopenharmony_ci DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false); 770f66f451Sopenharmony_ci DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true); 780f66f451Sopenharmony_ci DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true); 790f66f451Sopenharmony_ci DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false); 800f66f451Sopenharmony_ci DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false); 810f66f451Sopenharmony_ci DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false); 820f66f451Sopenharmony_ci DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true); 830f66f451Sopenharmony_ci DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true); 840f66f451Sopenharmony_ci DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true); 850f66f451Sopenharmony_ci DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false); 860f66f451Sopenharmony_ci DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true); 870f66f451Sopenharmony_ci DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false); 880f66f451Sopenharmony_ci DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true); 890f66f451Sopenharmony_ci DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true); 900f66f451Sopenharmony_ci DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true); 910f66f451Sopenharmony_ci DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true); 920f66f451Sopenharmony_ci DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true); 930f66f451Sopenharmony_ci DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false); 940f66f451Sopenharmony_ci DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true); 950f66f451Sopenharmony_ci DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true); 960f66f451Sopenharmony_ci DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true); 970f66f451Sopenharmony_ci} 980f66f451Sopenharmony_ci 990f66f451Sopenharmony_cistatic void set_blackbg_theme(void) 1000f66f451Sopenharmony_ci{ 1010f66f451Sopenharmony_ci DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true); 1020f66f451Sopenharmony_ci DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false); 1030f66f451Sopenharmony_ci DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false); 1040f66f451Sopenharmony_ci DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false); 1050f66f451Sopenharmony_ci DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true); 1060f66f451Sopenharmony_ci 1070f66f451Sopenharmony_ci DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false); 1080f66f451Sopenharmony_ci DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false); 1090f66f451Sopenharmony_ci DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true); 1100f66f451Sopenharmony_ci DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false); 1110f66f451Sopenharmony_ci DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false); 1120f66f451Sopenharmony_ci DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true); 1130f66f451Sopenharmony_ci 1140f66f451Sopenharmony_ci DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false); 1150f66f451Sopenharmony_ci DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false); 1160f66f451Sopenharmony_ci 1170f66f451Sopenharmony_ci DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false); 1180f66f451Sopenharmony_ci DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true); 1190f66f451Sopenharmony_ci DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true); 1200f66f451Sopenharmony_ci 1210f66f451Sopenharmony_ci DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false); 1220f66f451Sopenharmony_ci 1230f66f451Sopenharmony_ci DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false); 1240f66f451Sopenharmony_ci DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true); 1250f66f451Sopenharmony_ci 1260f66f451Sopenharmony_ci DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false); 1270f66f451Sopenharmony_ci DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false); 1280f66f451Sopenharmony_ci 1290f66f451Sopenharmony_ci DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false); 1300f66f451Sopenharmony_ci DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true); 1310f66f451Sopenharmony_ci DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false); 1320f66f451Sopenharmony_ci DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true); 1330f66f451Sopenharmony_ci 1340f66f451Sopenharmony_ci DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false); 1350f66f451Sopenharmony_ci DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true); 1360f66f451Sopenharmony_ci 1370f66f451Sopenharmony_ci DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false); 1380f66f451Sopenharmony_ci DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false); 1390f66f451Sopenharmony_ci} 1400f66f451Sopenharmony_ci 1410f66f451Sopenharmony_cistatic void set_bluetitle_theme(void) 1420f66f451Sopenharmony_ci{ 1430f66f451Sopenharmony_ci set_classic_theme(); 1440f66f451Sopenharmony_ci DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true); 1450f66f451Sopenharmony_ci DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true); 1460f66f451Sopenharmony_ci DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true); 1470f66f451Sopenharmony_ci DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true); 1480f66f451Sopenharmony_ci DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true); 1490f66f451Sopenharmony_ci DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true); 1500f66f451Sopenharmony_ci DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true); 1510f66f451Sopenharmony_ci 1520f66f451Sopenharmony_ci} 1530f66f451Sopenharmony_ci 1540f66f451Sopenharmony_ci/* 1550f66f451Sopenharmony_ci * Select color theme 1560f66f451Sopenharmony_ci */ 1570f66f451Sopenharmony_cistatic int set_theme(const char *theme) 1580f66f451Sopenharmony_ci{ 1590f66f451Sopenharmony_ci int use_color = 1; 1600f66f451Sopenharmony_ci if (!theme) 1610f66f451Sopenharmony_ci set_bluetitle_theme(); 1620f66f451Sopenharmony_ci else if (strcmp(theme, "classic") == 0) 1630f66f451Sopenharmony_ci set_classic_theme(); 1640f66f451Sopenharmony_ci else if (strcmp(theme, "bluetitle") == 0) 1650f66f451Sopenharmony_ci set_bluetitle_theme(); 1660f66f451Sopenharmony_ci else if (strcmp(theme, "blackbg") == 0) 1670f66f451Sopenharmony_ci set_blackbg_theme(); 1680f66f451Sopenharmony_ci else if (strcmp(theme, "mono") == 0) 1690f66f451Sopenharmony_ci use_color = 0; 1700f66f451Sopenharmony_ci 1710f66f451Sopenharmony_ci return use_color; 1720f66f451Sopenharmony_ci} 1730f66f451Sopenharmony_ci 1740f66f451Sopenharmony_cistatic void init_one_color(struct dialog_color *color) 1750f66f451Sopenharmony_ci{ 1760f66f451Sopenharmony_ci static int pair = 0; 1770f66f451Sopenharmony_ci 1780f66f451Sopenharmony_ci pair++; 1790f66f451Sopenharmony_ci init_pair(pair, color->fg, color->bg); 1800f66f451Sopenharmony_ci if (color->hl) 1810f66f451Sopenharmony_ci color->atr = A_BOLD | COLOR_PAIR(pair); 1820f66f451Sopenharmony_ci else 1830f66f451Sopenharmony_ci color->atr = COLOR_PAIR(pair); 1840f66f451Sopenharmony_ci} 1850f66f451Sopenharmony_ci 1860f66f451Sopenharmony_cistatic void init_dialog_colors(void) 1870f66f451Sopenharmony_ci{ 1880f66f451Sopenharmony_ci init_one_color(&dlg.screen); 1890f66f451Sopenharmony_ci init_one_color(&dlg.shadow); 1900f66f451Sopenharmony_ci init_one_color(&dlg.dialog); 1910f66f451Sopenharmony_ci init_one_color(&dlg.title); 1920f66f451Sopenharmony_ci init_one_color(&dlg.border); 1930f66f451Sopenharmony_ci init_one_color(&dlg.button_active); 1940f66f451Sopenharmony_ci init_one_color(&dlg.button_inactive); 1950f66f451Sopenharmony_ci init_one_color(&dlg.button_key_active); 1960f66f451Sopenharmony_ci init_one_color(&dlg.button_key_inactive); 1970f66f451Sopenharmony_ci init_one_color(&dlg.button_label_active); 1980f66f451Sopenharmony_ci init_one_color(&dlg.button_label_inactive); 1990f66f451Sopenharmony_ci init_one_color(&dlg.inputbox); 2000f66f451Sopenharmony_ci init_one_color(&dlg.inputbox_border); 2010f66f451Sopenharmony_ci init_one_color(&dlg.searchbox); 2020f66f451Sopenharmony_ci init_one_color(&dlg.searchbox_title); 2030f66f451Sopenharmony_ci init_one_color(&dlg.searchbox_border); 2040f66f451Sopenharmony_ci init_one_color(&dlg.position_indicator); 2050f66f451Sopenharmony_ci init_one_color(&dlg.menubox); 2060f66f451Sopenharmony_ci init_one_color(&dlg.menubox_border); 2070f66f451Sopenharmony_ci init_one_color(&dlg.item); 2080f66f451Sopenharmony_ci init_one_color(&dlg.item_selected); 2090f66f451Sopenharmony_ci init_one_color(&dlg.tag); 2100f66f451Sopenharmony_ci init_one_color(&dlg.tag_selected); 2110f66f451Sopenharmony_ci init_one_color(&dlg.tag_key); 2120f66f451Sopenharmony_ci init_one_color(&dlg.tag_key_selected); 2130f66f451Sopenharmony_ci init_one_color(&dlg.check); 2140f66f451Sopenharmony_ci init_one_color(&dlg.check_selected); 2150f66f451Sopenharmony_ci init_one_color(&dlg.uarrow); 2160f66f451Sopenharmony_ci init_one_color(&dlg.darrow); 2170f66f451Sopenharmony_ci} 2180f66f451Sopenharmony_ci 2190f66f451Sopenharmony_ci/* 2200f66f451Sopenharmony_ci * Setup for color display 2210f66f451Sopenharmony_ci */ 2220f66f451Sopenharmony_cistatic void color_setup(const char *theme) 2230f66f451Sopenharmony_ci{ 2240f66f451Sopenharmony_ci if (set_theme(theme)) { 2250f66f451Sopenharmony_ci if (has_colors()) { /* Terminal supports color? */ 2260f66f451Sopenharmony_ci start_color(); 2270f66f451Sopenharmony_ci init_dialog_colors(); 2280f66f451Sopenharmony_ci } 2290f66f451Sopenharmony_ci } 2300f66f451Sopenharmony_ci else 2310f66f451Sopenharmony_ci { 2320f66f451Sopenharmony_ci set_mono_theme(); 2330f66f451Sopenharmony_ci } 2340f66f451Sopenharmony_ci} 2350f66f451Sopenharmony_ci 2360f66f451Sopenharmony_ci/* 2370f66f451Sopenharmony_ci * Set window to attribute 'attr' 2380f66f451Sopenharmony_ci */ 2390f66f451Sopenharmony_civoid attr_clear(WINDOW * win, int height, int width, chtype attr) 2400f66f451Sopenharmony_ci{ 2410f66f451Sopenharmony_ci int i, j; 2420f66f451Sopenharmony_ci 2430f66f451Sopenharmony_ci wattrset(win, attr); 2440f66f451Sopenharmony_ci for (i = 0; i < height; i++) { 2450f66f451Sopenharmony_ci wmove(win, i, 0); 2460f66f451Sopenharmony_ci for (j = 0; j < width; j++) 2470f66f451Sopenharmony_ci waddch(win, ' '); 2480f66f451Sopenharmony_ci } 2490f66f451Sopenharmony_ci touchwin(win); 2500f66f451Sopenharmony_ci} 2510f66f451Sopenharmony_ci 2520f66f451Sopenharmony_civoid dialog_clear(void) 2530f66f451Sopenharmony_ci{ 2540f66f451Sopenharmony_ci attr_clear(stdscr, LINES, COLS, dlg.screen.atr); 2550f66f451Sopenharmony_ci /* Display background title if it exists ... - SLH */ 2560f66f451Sopenharmony_ci if (dlg.backtitle != NULL) { 2570f66f451Sopenharmony_ci int i; 2580f66f451Sopenharmony_ci 2590f66f451Sopenharmony_ci wattrset(stdscr, dlg.screen.atr); 2600f66f451Sopenharmony_ci mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); 2610f66f451Sopenharmony_ci wmove(stdscr, 1, 1); 2620f66f451Sopenharmony_ci for (i = 1; i < COLS - 1; i++) 2630f66f451Sopenharmony_ci waddch(stdscr, ACS_HLINE); 2640f66f451Sopenharmony_ci } 2650f66f451Sopenharmony_ci wnoutrefresh(stdscr); 2660f66f451Sopenharmony_ci} 2670f66f451Sopenharmony_ci 2680f66f451Sopenharmony_ci/* 2690f66f451Sopenharmony_ci * Do some initialization for dialog 2700f66f451Sopenharmony_ci */ 2710f66f451Sopenharmony_civoid init_dialog(const char *backtitle) 2720f66f451Sopenharmony_ci{ 2730f66f451Sopenharmony_ci dlg.backtitle = backtitle; 2740f66f451Sopenharmony_ci color_setup(getenv("MENUCONFIG_COLOR")); 2750f66f451Sopenharmony_ci} 2760f66f451Sopenharmony_ci 2770f66f451Sopenharmony_civoid reset_dialog(void) 2780f66f451Sopenharmony_ci{ 2790f66f451Sopenharmony_ci initscr(); /* Init curses */ 2800f66f451Sopenharmony_ci keypad(stdscr, TRUE); 2810f66f451Sopenharmony_ci cbreak(); 2820f66f451Sopenharmony_ci noecho(); 2830f66f451Sopenharmony_ci dialog_clear(); 2840f66f451Sopenharmony_ci} 2850f66f451Sopenharmony_ci 2860f66f451Sopenharmony_ci/* 2870f66f451Sopenharmony_ci * End using dialog functions. 2880f66f451Sopenharmony_ci */ 2890f66f451Sopenharmony_civoid end_dialog(void) 2900f66f451Sopenharmony_ci{ 2910f66f451Sopenharmony_ci endwin(); 2920f66f451Sopenharmony_ci} 2930f66f451Sopenharmony_ci 2940f66f451Sopenharmony_ci/* Print the title of the dialog. Center the title and truncate 2950f66f451Sopenharmony_ci * tile if wider than dialog (- 2 chars). 2960f66f451Sopenharmony_ci **/ 2970f66f451Sopenharmony_civoid print_title(WINDOW *dialog, const char *title, int width) 2980f66f451Sopenharmony_ci{ 2990f66f451Sopenharmony_ci if (title) { 3000f66f451Sopenharmony_ci int tlen = MIN(width - 2, strlen(title)); 3010f66f451Sopenharmony_ci wattrset(dialog, dlg.title.atr); 3020f66f451Sopenharmony_ci mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' '); 3030f66f451Sopenharmony_ci mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen); 3040f66f451Sopenharmony_ci waddch(dialog, ' '); 3050f66f451Sopenharmony_ci } 3060f66f451Sopenharmony_ci} 3070f66f451Sopenharmony_ci 3080f66f451Sopenharmony_ci/* 3090f66f451Sopenharmony_ci * Print a string of text in a window, automatically wrap around to the 3100f66f451Sopenharmony_ci * next line if the string is too long to fit on one line. Newline 3110f66f451Sopenharmony_ci * characters '\n' are replaced by spaces. We start on a new line 3120f66f451Sopenharmony_ci * if there is no room for at least 4 nonblanks following a double-space. 3130f66f451Sopenharmony_ci */ 3140f66f451Sopenharmony_civoid print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) 3150f66f451Sopenharmony_ci{ 3160f66f451Sopenharmony_ci int newl, cur_x, cur_y; 3170f66f451Sopenharmony_ci int i, prompt_len, room, wlen; 3180f66f451Sopenharmony_ci char tempstr[MAX_LEN + 1], *word, *sp, *sp2; 3190f66f451Sopenharmony_ci 3200f66f451Sopenharmony_ci strcpy(tempstr, prompt); 3210f66f451Sopenharmony_ci 3220f66f451Sopenharmony_ci prompt_len = strlen(tempstr); 3230f66f451Sopenharmony_ci 3240f66f451Sopenharmony_ci /* 3250f66f451Sopenharmony_ci * Remove newlines 3260f66f451Sopenharmony_ci */ 3270f66f451Sopenharmony_ci for (i = 0; i < prompt_len; i++) { 3280f66f451Sopenharmony_ci if (tempstr[i] == '\n') 3290f66f451Sopenharmony_ci tempstr[i] = ' '; 3300f66f451Sopenharmony_ci } 3310f66f451Sopenharmony_ci 3320f66f451Sopenharmony_ci if (prompt_len <= width - x * 2) { /* If prompt is short */ 3330f66f451Sopenharmony_ci wmove(win, y, (width - prompt_len) / 2); 3340f66f451Sopenharmony_ci waddstr(win, tempstr); 3350f66f451Sopenharmony_ci } else { 3360f66f451Sopenharmony_ci cur_x = x; 3370f66f451Sopenharmony_ci cur_y = y; 3380f66f451Sopenharmony_ci newl = 1; 3390f66f451Sopenharmony_ci word = tempstr; 3400f66f451Sopenharmony_ci while (word && *word) { 3410f66f451Sopenharmony_ci sp = index(word, ' '); 3420f66f451Sopenharmony_ci if (sp) 3430f66f451Sopenharmony_ci *sp++ = 0; 3440f66f451Sopenharmony_ci 3450f66f451Sopenharmony_ci /* Wrap to next line if either the word does not fit, 3460f66f451Sopenharmony_ci or it is the first word of a new sentence, and it is 3470f66f451Sopenharmony_ci short, and the next word does not fit. */ 3480f66f451Sopenharmony_ci room = width - cur_x; 3490f66f451Sopenharmony_ci wlen = strlen(word); 3500f66f451Sopenharmony_ci if (wlen > room || 3510f66f451Sopenharmony_ci (newl && wlen < 4 && sp 3520f66f451Sopenharmony_ci && wlen + 1 + strlen(sp) > room 3530f66f451Sopenharmony_ci && (!(sp2 = index(sp, ' ')) 3540f66f451Sopenharmony_ci || wlen + 1 + (sp2 - sp) > room))) { 3550f66f451Sopenharmony_ci cur_y++; 3560f66f451Sopenharmony_ci cur_x = x; 3570f66f451Sopenharmony_ci } 3580f66f451Sopenharmony_ci wmove(win, cur_y, cur_x); 3590f66f451Sopenharmony_ci waddstr(win, word); 3600f66f451Sopenharmony_ci getyx(win, cur_y, cur_x); 3610f66f451Sopenharmony_ci cur_x++; 3620f66f451Sopenharmony_ci if (sp && *sp == ' ') { 3630f66f451Sopenharmony_ci cur_x++; /* double space */ 3640f66f451Sopenharmony_ci while (*++sp == ' ') ; 3650f66f451Sopenharmony_ci newl = 1; 3660f66f451Sopenharmony_ci } else 3670f66f451Sopenharmony_ci newl = 0; 3680f66f451Sopenharmony_ci word = sp; 3690f66f451Sopenharmony_ci } 3700f66f451Sopenharmony_ci } 3710f66f451Sopenharmony_ci} 3720f66f451Sopenharmony_ci 3730f66f451Sopenharmony_ci/* 3740f66f451Sopenharmony_ci * Print a button 3750f66f451Sopenharmony_ci */ 3760f66f451Sopenharmony_civoid print_button(WINDOW * win, const char *label, int y, int x, int selected) 3770f66f451Sopenharmony_ci{ 3780f66f451Sopenharmony_ci int i, temp; 3790f66f451Sopenharmony_ci 3800f66f451Sopenharmony_ci wmove(win, y, x); 3810f66f451Sopenharmony_ci wattrset(win, selected ? dlg.button_active.atr 3820f66f451Sopenharmony_ci : dlg.button_inactive.atr); 3830f66f451Sopenharmony_ci waddstr(win, "<"); 3840f66f451Sopenharmony_ci temp = strspn(label, " "); 3850f66f451Sopenharmony_ci label += temp; 3860f66f451Sopenharmony_ci wattrset(win, selected ? dlg.button_label_active.atr 3870f66f451Sopenharmony_ci : dlg.button_label_inactive.atr); 3880f66f451Sopenharmony_ci for (i = 0; i < temp; i++) 3890f66f451Sopenharmony_ci waddch(win, ' '); 3900f66f451Sopenharmony_ci wattrset(win, selected ? dlg.button_key_active.atr 3910f66f451Sopenharmony_ci : dlg.button_key_inactive.atr); 3920f66f451Sopenharmony_ci waddch(win, label[0]); 3930f66f451Sopenharmony_ci wattrset(win, selected ? dlg.button_label_active.atr 3940f66f451Sopenharmony_ci : dlg.button_label_inactive.atr); 3950f66f451Sopenharmony_ci waddstr(win, (char *)label + 1); 3960f66f451Sopenharmony_ci wattrset(win, selected ? dlg.button_active.atr 3970f66f451Sopenharmony_ci : dlg.button_inactive.atr); 3980f66f451Sopenharmony_ci waddstr(win, ">"); 3990f66f451Sopenharmony_ci wmove(win, y, x + temp + 1); 4000f66f451Sopenharmony_ci} 4010f66f451Sopenharmony_ci 4020f66f451Sopenharmony_ci/* 4030f66f451Sopenharmony_ci * Draw a rectangular box with line drawing characters 4040f66f451Sopenharmony_ci */ 4050f66f451Sopenharmony_civoid 4060f66f451Sopenharmony_cidraw_box(WINDOW * win, int y, int x, int height, int width, 4070f66f451Sopenharmony_ci chtype box, chtype border) 4080f66f451Sopenharmony_ci{ 4090f66f451Sopenharmony_ci int i, j; 4100f66f451Sopenharmony_ci 4110f66f451Sopenharmony_ci wattrset(win, 0); 4120f66f451Sopenharmony_ci for (i = 0; i < height; i++) { 4130f66f451Sopenharmony_ci wmove(win, y + i, x); 4140f66f451Sopenharmony_ci for (j = 0; j < width; j++) 4150f66f451Sopenharmony_ci if (!i && !j) 4160f66f451Sopenharmony_ci waddch(win, border | ACS_ULCORNER); 4170f66f451Sopenharmony_ci else if (i == height - 1 && !j) 4180f66f451Sopenharmony_ci waddch(win, border | ACS_LLCORNER); 4190f66f451Sopenharmony_ci else if (!i && j == width - 1) 4200f66f451Sopenharmony_ci waddch(win, box | ACS_URCORNER); 4210f66f451Sopenharmony_ci else if (i == height - 1 && j == width - 1) 4220f66f451Sopenharmony_ci waddch(win, box | ACS_LRCORNER); 4230f66f451Sopenharmony_ci else if (!i) 4240f66f451Sopenharmony_ci waddch(win, border | ACS_HLINE); 4250f66f451Sopenharmony_ci else if (i == height - 1) 4260f66f451Sopenharmony_ci waddch(win, box | ACS_HLINE); 4270f66f451Sopenharmony_ci else if (!j) 4280f66f451Sopenharmony_ci waddch(win, border | ACS_VLINE); 4290f66f451Sopenharmony_ci else if (j == width - 1) 4300f66f451Sopenharmony_ci waddch(win, box | ACS_VLINE); 4310f66f451Sopenharmony_ci else 4320f66f451Sopenharmony_ci waddch(win, box | ' '); 4330f66f451Sopenharmony_ci } 4340f66f451Sopenharmony_ci} 4350f66f451Sopenharmony_ci 4360f66f451Sopenharmony_ci/* 4370f66f451Sopenharmony_ci * Draw shadows along the right and bottom edge to give a more 3D look 4380f66f451Sopenharmony_ci * to the boxes 4390f66f451Sopenharmony_ci */ 4400f66f451Sopenharmony_civoid draw_shadow(WINDOW * win, int y, int x, int height, int width) 4410f66f451Sopenharmony_ci{ 4420f66f451Sopenharmony_ci int i; 4430f66f451Sopenharmony_ci 4440f66f451Sopenharmony_ci if (has_colors()) { /* Whether terminal supports color? */ 4450f66f451Sopenharmony_ci wattrset(win, dlg.shadow.atr); 4460f66f451Sopenharmony_ci wmove(win, y + height, x + 2); 4470f66f451Sopenharmony_ci for (i = 0; i < width; i++) 4480f66f451Sopenharmony_ci waddch(win, winch(win) & A_CHARTEXT); 4490f66f451Sopenharmony_ci for (i = y + 1; i < y + height + 1; i++) { 4500f66f451Sopenharmony_ci wmove(win, i, x + width); 4510f66f451Sopenharmony_ci waddch(win, winch(win) & A_CHARTEXT); 4520f66f451Sopenharmony_ci waddch(win, winch(win) & A_CHARTEXT); 4530f66f451Sopenharmony_ci } 4540f66f451Sopenharmony_ci wnoutrefresh(win); 4550f66f451Sopenharmony_ci } 4560f66f451Sopenharmony_ci} 4570f66f451Sopenharmony_ci 4580f66f451Sopenharmony_ci/* 4590f66f451Sopenharmony_ci * Return the position of the first alphabetic character in a string. 4600f66f451Sopenharmony_ci */ 4610f66f451Sopenharmony_ciint first_alpha(const char *string, const char *exempt) 4620f66f451Sopenharmony_ci{ 4630f66f451Sopenharmony_ci int i, in_paren = 0, c; 4640f66f451Sopenharmony_ci 4650f66f451Sopenharmony_ci for (i = 0; i < strlen(string); i++) { 4660f66f451Sopenharmony_ci c = tolower(string[i]); 4670f66f451Sopenharmony_ci 4680f66f451Sopenharmony_ci if (strchr("<[(", c)) 4690f66f451Sopenharmony_ci ++in_paren; 4700f66f451Sopenharmony_ci if (strchr(">])", c) && in_paren > 0) 4710f66f451Sopenharmony_ci --in_paren; 4720f66f451Sopenharmony_ci 4730f66f451Sopenharmony_ci if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0) 4740f66f451Sopenharmony_ci return i; 4750f66f451Sopenharmony_ci } 4760f66f451Sopenharmony_ci 4770f66f451Sopenharmony_ci return 0; 4780f66f451Sopenharmony_ci} 4790f66f451Sopenharmony_ci 4800f66f451Sopenharmony_ci/* 4810f66f451Sopenharmony_ci * ncurses uses ESC to detect escaped char sequences. This resutl in 4820f66f451Sopenharmony_ci * a small timeout before ESC is actually delivered to the application. 4830f66f451Sopenharmony_ci * lxdialog suggest <ESC> <ESC> which is correctly translated to two 4840f66f451Sopenharmony_ci * times esc. But then we need to ignore the second esc to avoid stepping 4850f66f451Sopenharmony_ci * out one menu too much. Filter away all escaped key sequences since 4860f66f451Sopenharmony_ci * keypad(FALSE) turn off ncurses support for escape sequences - and thats 4870f66f451Sopenharmony_ci * needed to make notimeout() do as expected. 4880f66f451Sopenharmony_ci */ 4890f66f451Sopenharmony_ciint on_key_esc(WINDOW *win) 4900f66f451Sopenharmony_ci{ 4910f66f451Sopenharmony_ci int key; 4920f66f451Sopenharmony_ci int key2; 4930f66f451Sopenharmony_ci int key3; 4940f66f451Sopenharmony_ci 4950f66f451Sopenharmony_ci nodelay(win, TRUE); 4960f66f451Sopenharmony_ci keypad(win, FALSE); 4970f66f451Sopenharmony_ci key = wgetch(win); 4980f66f451Sopenharmony_ci key2 = wgetch(win); 4990f66f451Sopenharmony_ci do { 5000f66f451Sopenharmony_ci key3 = wgetch(win); 5010f66f451Sopenharmony_ci } while (key3 != ERR); 5020f66f451Sopenharmony_ci nodelay(win, FALSE); 5030f66f451Sopenharmony_ci keypad(win, TRUE); 5040f66f451Sopenharmony_ci if (key == KEY_ESC && key2 == ERR) 5050f66f451Sopenharmony_ci return KEY_ESC; 5060f66f451Sopenharmony_ci else if (key != ERR && key != KEY_ESC && key2 == ERR) 5070f66f451Sopenharmony_ci ungetch(key); 5080f66f451Sopenharmony_ci 5090f66f451Sopenharmony_ci return -1; 5100f66f451Sopenharmony_ci} 5110f66f451Sopenharmony_ci 5120f66f451Sopenharmony_ci/* redraw screen in new size */ 5130f66f451Sopenharmony_ciint on_key_resize(void) 5140f66f451Sopenharmony_ci{ 5150f66f451Sopenharmony_ci dialog_clear(); 5160f66f451Sopenharmony_ci return KEY_RESIZE; 5170f66f451Sopenharmony_ci} 5180f66f451Sopenharmony_ci 5190f66f451Sopenharmony_cistruct dialog_list *item_cur; 5200f66f451Sopenharmony_cistruct dialog_list item_nil; 5210f66f451Sopenharmony_cistruct dialog_list *item_head; 5220f66f451Sopenharmony_ci 5230f66f451Sopenharmony_civoid item_reset(void) 5240f66f451Sopenharmony_ci{ 5250f66f451Sopenharmony_ci struct dialog_list *p, *next; 5260f66f451Sopenharmony_ci 5270f66f451Sopenharmony_ci for (p = item_head; p; p = next) { 5280f66f451Sopenharmony_ci next = p->next; 5290f66f451Sopenharmony_ci free(p); 5300f66f451Sopenharmony_ci } 5310f66f451Sopenharmony_ci item_head = NULL; 5320f66f451Sopenharmony_ci item_cur = &item_nil; 5330f66f451Sopenharmony_ci} 5340f66f451Sopenharmony_ci 5350f66f451Sopenharmony_civoid item_make(const char *fmt, ...) 5360f66f451Sopenharmony_ci{ 5370f66f451Sopenharmony_ci va_list ap; 5380f66f451Sopenharmony_ci struct dialog_list *p = malloc(sizeof(*p)); 5390f66f451Sopenharmony_ci 5400f66f451Sopenharmony_ci if (item_head) 5410f66f451Sopenharmony_ci item_cur->next = p; 5420f66f451Sopenharmony_ci else 5430f66f451Sopenharmony_ci item_head = p; 5440f66f451Sopenharmony_ci item_cur = p; 5450f66f451Sopenharmony_ci memset(p, 0, sizeof(*p)); 5460f66f451Sopenharmony_ci 5470f66f451Sopenharmony_ci va_start(ap, fmt); 5480f66f451Sopenharmony_ci vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap); 5490f66f451Sopenharmony_ci va_end(ap); 5500f66f451Sopenharmony_ci} 5510f66f451Sopenharmony_ci 5520f66f451Sopenharmony_civoid item_add_str(const char *fmt, ...) 5530f66f451Sopenharmony_ci{ 5540f66f451Sopenharmony_ci va_list ap; 5550f66f451Sopenharmony_ci size_t avail; 5560f66f451Sopenharmony_ci 5570f66f451Sopenharmony_ci avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); 5580f66f451Sopenharmony_ci 5590f66f451Sopenharmony_ci va_start(ap, fmt); 5600f66f451Sopenharmony_ci vsnprintf(item_cur->node.str + strlen(item_cur->node.str), 5610f66f451Sopenharmony_ci avail, fmt, ap); 5620f66f451Sopenharmony_ci item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0'; 5630f66f451Sopenharmony_ci va_end(ap); 5640f66f451Sopenharmony_ci} 5650f66f451Sopenharmony_ci 5660f66f451Sopenharmony_civoid item_set_tag(char tag) 5670f66f451Sopenharmony_ci{ 5680f66f451Sopenharmony_ci item_cur->node.tag = tag; 5690f66f451Sopenharmony_ci} 5700f66f451Sopenharmony_civoid item_set_data(void *ptr) 5710f66f451Sopenharmony_ci{ 5720f66f451Sopenharmony_ci item_cur->node.data = ptr; 5730f66f451Sopenharmony_ci} 5740f66f451Sopenharmony_ci 5750f66f451Sopenharmony_civoid item_set_selected(int val) 5760f66f451Sopenharmony_ci{ 5770f66f451Sopenharmony_ci item_cur->node.selected = val; 5780f66f451Sopenharmony_ci} 5790f66f451Sopenharmony_ci 5800f66f451Sopenharmony_ciint item_activate_selected(void) 5810f66f451Sopenharmony_ci{ 5820f66f451Sopenharmony_ci item_foreach() 5830f66f451Sopenharmony_ci if (item_is_selected()) 5840f66f451Sopenharmony_ci return 1; 5850f66f451Sopenharmony_ci return 0; 5860f66f451Sopenharmony_ci} 5870f66f451Sopenharmony_ci 5880f66f451Sopenharmony_civoid *item_data(void) 5890f66f451Sopenharmony_ci{ 5900f66f451Sopenharmony_ci return item_cur->node.data; 5910f66f451Sopenharmony_ci} 5920f66f451Sopenharmony_ci 5930f66f451Sopenharmony_cichar item_tag(void) 5940f66f451Sopenharmony_ci{ 5950f66f451Sopenharmony_ci return item_cur->node.tag; 5960f66f451Sopenharmony_ci} 5970f66f451Sopenharmony_ci 5980f66f451Sopenharmony_ciint item_count(void) 5990f66f451Sopenharmony_ci{ 6000f66f451Sopenharmony_ci int n = 0; 6010f66f451Sopenharmony_ci struct dialog_list *p; 6020f66f451Sopenharmony_ci 6030f66f451Sopenharmony_ci for (p = item_head; p; p = p->next) 6040f66f451Sopenharmony_ci n++; 6050f66f451Sopenharmony_ci return n; 6060f66f451Sopenharmony_ci} 6070f66f451Sopenharmony_ci 6080f66f451Sopenharmony_civoid item_set(int n) 6090f66f451Sopenharmony_ci{ 6100f66f451Sopenharmony_ci int i = 0; 6110f66f451Sopenharmony_ci item_foreach() 6120f66f451Sopenharmony_ci if (i++ == n) 6130f66f451Sopenharmony_ci return; 6140f66f451Sopenharmony_ci} 6150f66f451Sopenharmony_ci 6160f66f451Sopenharmony_ciint item_n(void) 6170f66f451Sopenharmony_ci{ 6180f66f451Sopenharmony_ci int n = 0; 6190f66f451Sopenharmony_ci struct dialog_list *p; 6200f66f451Sopenharmony_ci 6210f66f451Sopenharmony_ci for (p = item_head; p; p = p->next) { 6220f66f451Sopenharmony_ci if (p == item_cur) 6230f66f451Sopenharmony_ci return n; 6240f66f451Sopenharmony_ci n++; 6250f66f451Sopenharmony_ci } 6260f66f451Sopenharmony_ci return 0; 6270f66f451Sopenharmony_ci} 6280f66f451Sopenharmony_ci 6290f66f451Sopenharmony_ciconst char *item_str(void) 6300f66f451Sopenharmony_ci{ 6310f66f451Sopenharmony_ci return item_cur->node.str; 6320f66f451Sopenharmony_ci} 6330f66f451Sopenharmony_ci 6340f66f451Sopenharmony_ciint item_is_selected(void) 6350f66f451Sopenharmony_ci{ 6360f66f451Sopenharmony_ci return (item_cur->node.selected != 0); 6370f66f451Sopenharmony_ci} 6380f66f451Sopenharmony_ci 6390f66f451Sopenharmony_ciint item_is_tag(char tag) 6400f66f451Sopenharmony_ci{ 6410f66f451Sopenharmony_ci return (item_cur->node.tag == tag); 6420f66f451Sopenharmony_ci} 643