1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0+ */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * dialog.h -- common declarations for all dialog modules 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <sys/types.h> 9*4882a593Smuzhiyun #include <fcntl.h> 10*4882a593Smuzhiyun #include <unistd.h> 11*4882a593Smuzhiyun #include <ctype.h> 12*4882a593Smuzhiyun #include <stdlib.h> 13*4882a593Smuzhiyun #include <string.h> 14*4882a593Smuzhiyun #include <stdbool.h> 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun #ifdef __sun__ 17*4882a593Smuzhiyun #define CURS_MACROS 18*4882a593Smuzhiyun #endif 19*4882a593Smuzhiyun #include <ncurses.h> 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun /* 22*4882a593Smuzhiyun * Colors in ncurses 1.9.9e do not work properly since foreground and 23*4882a593Smuzhiyun * background colors are OR'd rather than separately masked. This version 24*4882a593Smuzhiyun * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible 25*4882a593Smuzhiyun * with standard curses. The simplest fix (to make this work with standard 26*4882a593Smuzhiyun * curses) uses the wbkgdset() function, not used in the original hack. 27*4882a593Smuzhiyun * Turn it off if we're building with 1.9.9e, since it just confuses things. 28*4882a593Smuzhiyun */ 29*4882a593Smuzhiyun #if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) 30*4882a593Smuzhiyun #define OLD_NCURSES 1 31*4882a593Smuzhiyun #undef wbkgdset 32*4882a593Smuzhiyun #define wbkgdset(w,p) /*nothing */ 33*4882a593Smuzhiyun #else 34*4882a593Smuzhiyun #define OLD_NCURSES 0 35*4882a593Smuzhiyun #endif 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun #define TR(params) _tracef params 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun #define KEY_ESC 27 40*4882a593Smuzhiyun #define TAB 9 41*4882a593Smuzhiyun #define MAX_LEN 2048 42*4882a593Smuzhiyun #define BUF_SIZE (10*1024) 43*4882a593Smuzhiyun #define MIN(x,y) (x < y ? x : y) 44*4882a593Smuzhiyun #define MAX(x,y) (x > y ? x : y) 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun #ifndef ACS_ULCORNER 47*4882a593Smuzhiyun #define ACS_ULCORNER '+' 48*4882a593Smuzhiyun #endif 49*4882a593Smuzhiyun #ifndef ACS_LLCORNER 50*4882a593Smuzhiyun #define ACS_LLCORNER '+' 51*4882a593Smuzhiyun #endif 52*4882a593Smuzhiyun #ifndef ACS_URCORNER 53*4882a593Smuzhiyun #define ACS_URCORNER '+' 54*4882a593Smuzhiyun #endif 55*4882a593Smuzhiyun #ifndef ACS_LRCORNER 56*4882a593Smuzhiyun #define ACS_LRCORNER '+' 57*4882a593Smuzhiyun #endif 58*4882a593Smuzhiyun #ifndef ACS_HLINE 59*4882a593Smuzhiyun #define ACS_HLINE '-' 60*4882a593Smuzhiyun #endif 61*4882a593Smuzhiyun #ifndef ACS_VLINE 62*4882a593Smuzhiyun #define ACS_VLINE '|' 63*4882a593Smuzhiyun #endif 64*4882a593Smuzhiyun #ifndef ACS_LTEE 65*4882a593Smuzhiyun #define ACS_LTEE '+' 66*4882a593Smuzhiyun #endif 67*4882a593Smuzhiyun #ifndef ACS_RTEE 68*4882a593Smuzhiyun #define ACS_RTEE '+' 69*4882a593Smuzhiyun #endif 70*4882a593Smuzhiyun #ifndef ACS_UARROW 71*4882a593Smuzhiyun #define ACS_UARROW '^' 72*4882a593Smuzhiyun #endif 73*4882a593Smuzhiyun #ifndef ACS_DARROW 74*4882a593Smuzhiyun #define ACS_DARROW 'v' 75*4882a593Smuzhiyun #endif 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* error return codes */ 78*4882a593Smuzhiyun #define ERRDISPLAYTOOSMALL (KEY_MAX + 1) 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /* 81*4882a593Smuzhiyun * Color definitions 82*4882a593Smuzhiyun */ 83*4882a593Smuzhiyun struct dialog_color { 84*4882a593Smuzhiyun chtype atr; /* Color attribute */ 85*4882a593Smuzhiyun int fg; /* foreground */ 86*4882a593Smuzhiyun int bg; /* background */ 87*4882a593Smuzhiyun int hl; /* highlight this item */ 88*4882a593Smuzhiyun }; 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun struct subtitle_list { 91*4882a593Smuzhiyun struct subtitle_list *next; 92*4882a593Smuzhiyun const char *text; 93*4882a593Smuzhiyun }; 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun struct dialog_info { 96*4882a593Smuzhiyun const char *backtitle; 97*4882a593Smuzhiyun struct subtitle_list *subtitles; 98*4882a593Smuzhiyun struct dialog_color screen; 99*4882a593Smuzhiyun struct dialog_color shadow; 100*4882a593Smuzhiyun struct dialog_color dialog; 101*4882a593Smuzhiyun struct dialog_color title; 102*4882a593Smuzhiyun struct dialog_color border; 103*4882a593Smuzhiyun struct dialog_color button_active; 104*4882a593Smuzhiyun struct dialog_color button_inactive; 105*4882a593Smuzhiyun struct dialog_color button_key_active; 106*4882a593Smuzhiyun struct dialog_color button_key_inactive; 107*4882a593Smuzhiyun struct dialog_color button_label_active; 108*4882a593Smuzhiyun struct dialog_color button_label_inactive; 109*4882a593Smuzhiyun struct dialog_color inputbox; 110*4882a593Smuzhiyun struct dialog_color inputbox_border; 111*4882a593Smuzhiyun struct dialog_color searchbox; 112*4882a593Smuzhiyun struct dialog_color searchbox_title; 113*4882a593Smuzhiyun struct dialog_color searchbox_border; 114*4882a593Smuzhiyun struct dialog_color position_indicator; 115*4882a593Smuzhiyun struct dialog_color menubox; 116*4882a593Smuzhiyun struct dialog_color menubox_border; 117*4882a593Smuzhiyun struct dialog_color item; 118*4882a593Smuzhiyun struct dialog_color item_selected; 119*4882a593Smuzhiyun struct dialog_color tag; 120*4882a593Smuzhiyun struct dialog_color tag_selected; 121*4882a593Smuzhiyun struct dialog_color tag_key; 122*4882a593Smuzhiyun struct dialog_color tag_key_selected; 123*4882a593Smuzhiyun struct dialog_color check; 124*4882a593Smuzhiyun struct dialog_color check_selected; 125*4882a593Smuzhiyun struct dialog_color uarrow; 126*4882a593Smuzhiyun struct dialog_color darrow; 127*4882a593Smuzhiyun }; 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun /* 130*4882a593Smuzhiyun * Global variables 131*4882a593Smuzhiyun */ 132*4882a593Smuzhiyun extern struct dialog_info dlg; 133*4882a593Smuzhiyun extern char dialog_input_result[]; 134*4882a593Smuzhiyun extern int saved_x, saved_y; /* Needed in signal handler in mconf.c */ 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* 137*4882a593Smuzhiyun * Function prototypes 138*4882a593Smuzhiyun */ 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun /* item list as used by checklist and menubox */ 141*4882a593Smuzhiyun void item_reset(void); 142*4882a593Smuzhiyun void item_make(const char *fmt, ...); 143*4882a593Smuzhiyun void item_add_str(const char *fmt, ...); 144*4882a593Smuzhiyun void item_set_tag(char tag); 145*4882a593Smuzhiyun void item_set_data(void *p); 146*4882a593Smuzhiyun void item_set_selected(int val); 147*4882a593Smuzhiyun int item_activate_selected(void); 148*4882a593Smuzhiyun void *item_data(void); 149*4882a593Smuzhiyun char item_tag(void); 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun /* item list manipulation for lxdialog use */ 152*4882a593Smuzhiyun #define MAXITEMSTR 200 153*4882a593Smuzhiyun struct dialog_item { 154*4882a593Smuzhiyun char str[MAXITEMSTR]; /* prompt displayed */ 155*4882a593Smuzhiyun char tag; 156*4882a593Smuzhiyun void *data; /* pointer to menu item - used by menubox+checklist */ 157*4882a593Smuzhiyun int selected; /* Set to 1 by dialog_*() function if selected. */ 158*4882a593Smuzhiyun }; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun /* list of lialog_items */ 161*4882a593Smuzhiyun struct dialog_list { 162*4882a593Smuzhiyun struct dialog_item node; 163*4882a593Smuzhiyun struct dialog_list *next; 164*4882a593Smuzhiyun }; 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun extern struct dialog_list *item_cur; 167*4882a593Smuzhiyun extern struct dialog_list item_nil; 168*4882a593Smuzhiyun extern struct dialog_list *item_head; 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun int item_count(void); 171*4882a593Smuzhiyun void item_set(int n); 172*4882a593Smuzhiyun int item_n(void); 173*4882a593Smuzhiyun const char *item_str(void); 174*4882a593Smuzhiyun int item_is_selected(void); 175*4882a593Smuzhiyun int item_is_tag(char tag); 176*4882a593Smuzhiyun #define item_foreach() \ 177*4882a593Smuzhiyun for (item_cur = item_head ? item_head: item_cur; \ 178*4882a593Smuzhiyun item_cur && (item_cur != &item_nil); item_cur = item_cur->next) 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun /* generic key handlers */ 181*4882a593Smuzhiyun int on_key_esc(WINDOW *win); 182*4882a593Smuzhiyun int on_key_resize(void); 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun /* minimum (re)size values */ 185*4882a593Smuzhiyun #define CHECKLIST_HEIGTH_MIN 6 /* For dialog_checklist() */ 186*4882a593Smuzhiyun #define CHECKLIST_WIDTH_MIN 6 187*4882a593Smuzhiyun #define INPUTBOX_HEIGTH_MIN 2 /* For dialog_inputbox() */ 188*4882a593Smuzhiyun #define INPUTBOX_WIDTH_MIN 2 189*4882a593Smuzhiyun #define MENUBOX_HEIGTH_MIN 15 /* For dialog_menu() */ 190*4882a593Smuzhiyun #define MENUBOX_WIDTH_MIN 65 191*4882a593Smuzhiyun #define TEXTBOX_HEIGTH_MIN 8 /* For dialog_textbox() */ 192*4882a593Smuzhiyun #define TEXTBOX_WIDTH_MIN 8 193*4882a593Smuzhiyun #define YESNO_HEIGTH_MIN 4 /* For dialog_yesno() */ 194*4882a593Smuzhiyun #define YESNO_WIDTH_MIN 4 195*4882a593Smuzhiyun #define WINDOW_HEIGTH_MIN 19 /* For init_dialog() */ 196*4882a593Smuzhiyun #define WINDOW_WIDTH_MIN 80 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun int init_dialog(const char *backtitle); 199*4882a593Smuzhiyun void set_dialog_backtitle(const char *backtitle); 200*4882a593Smuzhiyun void set_dialog_subtitles(struct subtitle_list *subtitles); 201*4882a593Smuzhiyun void end_dialog(int x, int y); 202*4882a593Smuzhiyun void attr_clear(WINDOW * win, int height, int width, chtype attr); 203*4882a593Smuzhiyun void dialog_clear(void); 204*4882a593Smuzhiyun void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); 205*4882a593Smuzhiyun void print_button(WINDOW * win, const char *label, int y, int x, int selected); 206*4882a593Smuzhiyun void print_title(WINDOW *dialog, const char *title, int width); 207*4882a593Smuzhiyun void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box, 208*4882a593Smuzhiyun chtype border); 209*4882a593Smuzhiyun void draw_shadow(WINDOW * win, int y, int x, int height, int width); 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun int first_alpha(const char *string, const char *exempt); 212*4882a593Smuzhiyun int dialog_yesno(const char *title, const char *prompt, int height, int width); 213*4882a593Smuzhiyun int dialog_msgbox(const char *title, const char *prompt, int height, 214*4882a593Smuzhiyun int width, int pause); 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void 218*4882a593Smuzhiyun *_data); 219*4882a593Smuzhiyun int dialog_textbox(const char *title, char *tbuf, int initial_height, 220*4882a593Smuzhiyun int initial_width, int *keys, int *_vscroll, int *_hscroll, 221*4882a593Smuzhiyun update_text_fn update_text, void *data); 222*4882a593Smuzhiyun int dialog_menu(const char *title, const char *prompt, 223*4882a593Smuzhiyun const void *selected, int *s_scroll); 224*4882a593Smuzhiyun int dialog_checklist(const char *title, const char *prompt, int height, 225*4882a593Smuzhiyun int width, int list_height); 226*4882a593Smuzhiyun int dialog_inputbox(const char *title, const char *prompt, int height, 227*4882a593Smuzhiyun int width, const char *init); 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun /* 230*4882a593Smuzhiyun * This is the base for fictitious keys, which activate 231*4882a593Smuzhiyun * the buttons. 232*4882a593Smuzhiyun * 233*4882a593Smuzhiyun * Mouse-generated keys are the following: 234*4882a593Smuzhiyun * -- the first 32 are used as numbers, in addition to '0'-'9' 235*4882a593Smuzhiyun * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') 236*4882a593Smuzhiyun * -- uppercase chars are used to invoke the button (M_EVENT + 'O') 237*4882a593Smuzhiyun */ 238*4882a593Smuzhiyun #define M_EVENT (KEY_MAX+1) 239