1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4263660c0SAlfonso Siciliano * Copyright (c) 2021-2022 Alfonso Sabato Siciliano 5c76f0793SBaptiste Daroussin * 6c76f0793SBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 7c76f0793SBaptiste Daroussin * modification, are permitted provided that the following conditions 8c76f0793SBaptiste Daroussin * are met: 9c76f0793SBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 10c76f0793SBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 11c76f0793SBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 12c76f0793SBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 13c76f0793SBaptiste Daroussin * documentation and/or other materials provided with the distribution. 14c76f0793SBaptiste Daroussin * 15c76f0793SBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16c76f0793SBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17c76f0793SBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18c76f0793SBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19c76f0793SBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20c76f0793SBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21c76f0793SBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22c76f0793SBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23c76f0793SBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24c76f0793SBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25c76f0793SBaptiste Daroussin * SUCH DAMAGE. 26c76f0793SBaptiste Daroussin */ 27c76f0793SBaptiste Daroussin 28f499134dSBaptiste Daroussin #include <sys/param.h> 29f499134dSBaptiste Daroussin 30f499134dSBaptiste Daroussin #include <ctype.h> 31c76f0793SBaptiste Daroussin #include <form.h> 32d93b4d32SBaptiste Daroussin #include <stdlib.h> 33d93b4d32SBaptiste Daroussin #include <string.h> 34c76f0793SBaptiste Daroussin 35c76f0793SBaptiste Daroussin #include "bsddialog.h" 36c76f0793SBaptiste Daroussin #include "bsddialog_theme.h" 37263660c0SAlfonso Siciliano #include "lib_util.h" 38c76f0793SBaptiste Daroussin 39f499134dSBaptiste Daroussin #define ISFIELDHIDDEN(item) (item.flags & BSDDIALOG_FIELDHIDDEN) 40f499134dSBaptiste Daroussin #define ISFIELDREADONLY(item) (item.flags & BSDDIALOG_FIELDREADONLY) 41*bce40c02SAlfonso S. Siciliano #define REDRAWFORM 19860214 /* magic number */ 42c76f0793SBaptiste Daroussin 43263660c0SAlfonso Siciliano /* field_userptr for private buffer and view options */ 44f499134dSBaptiste Daroussin struct myfield { 45d93b4d32SBaptiste Daroussin int buflen; 46*bce40c02SAlfonso S. Siciliano wchar_t *buf; 47f499134dSBaptiste Daroussin int pos; 48d93b4d32SBaptiste Daroussin int maxpos; 49f499134dSBaptiste Daroussin bool secure; 50f499134dSBaptiste Daroussin int securech; 51263660c0SAlfonso Siciliano const char *bottomdesc; 52f499134dSBaptiste Daroussin }; 53f499134dSBaptiste Daroussin #define GETMYFIELD(field) ((struct myfield*)field_userptr(field)) 54f499134dSBaptiste Daroussin #define GETMYFIELD2(form) ((struct myfield*)field_userptr(current_field(form))) 55f499134dSBaptiste Daroussin 56f499134dSBaptiste Daroussin static void insertch(struct myfield *mf, int ch) 57c76f0793SBaptiste Daroussin { 58f499134dSBaptiste Daroussin int i; 59f499134dSBaptiste Daroussin 60d93b4d32SBaptiste Daroussin if (mf->buflen > mf->maxpos) 61f499134dSBaptiste Daroussin return; 62f499134dSBaptiste Daroussin 63d93b4d32SBaptiste Daroussin for (i = mf->buflen; i >= mf->pos; i--) { 64f499134dSBaptiste Daroussin mf->buf[i+1] = mf->buf[i]; 65c76f0793SBaptiste Daroussin } 66c76f0793SBaptiste Daroussin 67f499134dSBaptiste Daroussin mf->buf[mf->pos] = ch; 68f499134dSBaptiste Daroussin mf->pos += 1; 69d93b4d32SBaptiste Daroussin if (mf->pos > mf->maxpos) 70d93b4d32SBaptiste Daroussin mf->pos = mf->maxpos; 71d93b4d32SBaptiste Daroussin mf->buflen += 1; 72d93b4d32SBaptiste Daroussin mf->buf[mf->buflen] = '\0'; 73f499134dSBaptiste Daroussin } 74f499134dSBaptiste Daroussin 75f499134dSBaptiste Daroussin static void shiftleft(struct myfield *mf) 76f499134dSBaptiste Daroussin { 77f499134dSBaptiste Daroussin int i, last; 78f499134dSBaptiste Daroussin 79d93b4d32SBaptiste Daroussin for (i = mf->pos; i < mf->buflen -1; i++) { 80f499134dSBaptiste Daroussin mf->buf[i] = mf->buf[i+1]; 81f499134dSBaptiste Daroussin } 82f499134dSBaptiste Daroussin 83d93b4d32SBaptiste Daroussin last = mf->buflen > 0 ? mf->buflen -1 : 0; 84f499134dSBaptiste Daroussin mf->buf[last] = '\0'; 85d93b4d32SBaptiste Daroussin mf->buflen = last; 86f499134dSBaptiste Daroussin } 87c76f0793SBaptiste Daroussin 888c4f4028SBaptiste Daroussin static void print_bottomdesc(struct myfield *mf) 898c4f4028SBaptiste Daroussin { 90263660c0SAlfonso Siciliano move(SCREENLINES - 1, 2); 918c4f4028SBaptiste Daroussin clrtoeol(); 928c4f4028SBaptiste Daroussin if (mf->bottomdesc != NULL) { 938c4f4028SBaptiste Daroussin addstr(mf->bottomdesc); 948c4f4028SBaptiste Daroussin refresh(); 958c4f4028SBaptiste Daroussin } 968c4f4028SBaptiste Daroussin } 978c4f4028SBaptiste Daroussin 98*bce40c02SAlfonso S. Siciliano static char *w2c(wchar_t *string) 99*bce40c02SAlfonso S. Siciliano { 100*bce40c02SAlfonso S. Siciliano int i, len; 101*bce40c02SAlfonso S. Siciliano char *value; 102*bce40c02SAlfonso S. Siciliano 103*bce40c02SAlfonso S. Siciliano len = wcslen(string); 104*bce40c02SAlfonso S. Siciliano if ((value = calloc(len + 1, sizeof(char))) == NULL) 105*bce40c02SAlfonso S. Siciliano return NULL; 106*bce40c02SAlfonso S. Siciliano 107*bce40c02SAlfonso S. Siciliano for (i = 0; i < len; i++) 108*bce40c02SAlfonso S. Siciliano value[i] = string[i]; 109*bce40c02SAlfonso S. Siciliano value[i] = '\0'; 110*bce40c02SAlfonso S. Siciliano 111*bce40c02SAlfonso S. Siciliano return value; 112*bce40c02SAlfonso S. Siciliano } 113*bce40c02SAlfonso S. Siciliano 114*bce40c02SAlfonso S. Siciliano static int 115263660c0SAlfonso Siciliano return_values(struct bsddialog_conf *conf, int output, int nitems, 116d93b4d32SBaptiste Daroussin struct bsddialog_formitem *items, FORM *form, FIELD **cfield) 117d93b4d32SBaptiste Daroussin { 118263660c0SAlfonso Siciliano int i; 119d93b4d32SBaptiste Daroussin struct myfield *mf; 120d93b4d32SBaptiste Daroussin 121263660c0SAlfonso Siciliano if (output != BSDDIALOG_OK && conf->form.value_without_ok == false) 122263660c0SAlfonso Siciliano return (output); 123d93b4d32SBaptiste Daroussin 124*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_NEXT_FIELD); 125*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_PREV_FIELD); 126d93b4d32SBaptiste Daroussin for (i = 0; i < nitems; i++) { 127d93b4d32SBaptiste Daroussin mf = GETMYFIELD(cfield[i]); 128*bce40c02SAlfonso S. Siciliano if (conf->form.enable_wchar) { 129*bce40c02SAlfonso S. Siciliano items[i].value = (char*)wcsdup(mf->buf); 130*bce40c02SAlfonso S. Siciliano } else { 131*bce40c02SAlfonso S. Siciliano items[i].value = w2c(mf->buf); 132*bce40c02SAlfonso S. Siciliano } 133d93b4d32SBaptiste Daroussin if (items[i].value == NULL) 134d93b4d32SBaptiste Daroussin RETURN_ERROR("Cannot allocate memory for form value"); 135d93b4d32SBaptiste Daroussin } 136d93b4d32SBaptiste Daroussin 137d93b4d32SBaptiste Daroussin return (output); 138d93b4d32SBaptiste Daroussin } 139d93b4d32SBaptiste Daroussin 140c76f0793SBaptiste Daroussin static int 141263660c0SAlfonso Siciliano form_handler(struct bsddialog_conf *conf, WINDOW *widget, struct buttons bs, 142263660c0SAlfonso Siciliano WINDOW *formwin, FORM *form, FIELD **cfield, int nitems, 143f499134dSBaptiste Daroussin struct bsddialog_formitem *items) 144c76f0793SBaptiste Daroussin { 145263660c0SAlfonso Siciliano bool loop, buttupdate, informwin; 146*bce40c02SAlfonso S. Siciliano int i, chtype, output; 147*bce40c02SAlfonso S. Siciliano wint_t input; 148f499134dSBaptiste Daroussin struct myfield *mf; 149c76f0793SBaptiste Daroussin 150f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 1518c4f4028SBaptiste Daroussin print_bottomdesc(mf); 152d93b4d32SBaptiste Daroussin pos_form_cursor(form); 153*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_END_LINE); 154d93b4d32SBaptiste Daroussin mf->pos = MIN(mf->buflen, mf->maxpos); 155*bce40c02SAlfonso S. Siciliano curs_set(1); 156263660c0SAlfonso Siciliano informwin = true; 157263660c0SAlfonso Siciliano 158d93b4d32SBaptiste Daroussin bs.curr = -1; 159263660c0SAlfonso Siciliano buttupdate = true; 160263660c0SAlfonso Siciliano 161263660c0SAlfonso Siciliano loop = true; 162c76f0793SBaptiste Daroussin while (loop) { 163c76f0793SBaptiste Daroussin if (buttupdate) { 164263660c0SAlfonso Siciliano draw_buttons(widget, bs, !informwin); 165c76f0793SBaptiste Daroussin wrefresh(widget); 166c76f0793SBaptiste Daroussin buttupdate = false; 167c76f0793SBaptiste Daroussin } 168f499134dSBaptiste Daroussin wrefresh(formwin); 169*bce40c02SAlfonso S. Siciliano chtype = get_wch(&input); 170*bce40c02SAlfonso S. Siciliano if (chtype != KEY_CODE_YES && input > 127 && 171*bce40c02SAlfonso S. Siciliano conf->form.enable_wchar == false) 172*bce40c02SAlfonso S. Siciliano continue; 173c76f0793SBaptiste Daroussin switch(input) { 174*bce40c02SAlfonso S. Siciliano case KEY_HOME: 175*bce40c02SAlfonso S. Siciliano case KEY_PPAGE: 176*bce40c02SAlfonso S. Siciliano case KEY_END: 177*bce40c02SAlfonso S. Siciliano case KEY_NPAGE: 178*bce40c02SAlfonso S. Siciliano /* disabled keys */ 179*bce40c02SAlfonso S. Siciliano break; 180f499134dSBaptiste Daroussin case KEY_ENTER: 181f499134dSBaptiste Daroussin case 10: /* Enter */ 182f499134dSBaptiste Daroussin if (informwin) 183c76f0793SBaptiste Daroussin break; 184263660c0SAlfonso Siciliano output = return_values(conf, bs.value[bs.curr], nitems, 185263660c0SAlfonso Siciliano items, form, cfield); 1868c4f4028SBaptiste Daroussin loop = false; 187c76f0793SBaptiste Daroussin break; 188c76f0793SBaptiste Daroussin case 27: /* Esc */ 189263660c0SAlfonso Siciliano if (conf->key.enable_esc) { 190263660c0SAlfonso Siciliano output = return_values(conf, BSDDIALOG_ESC, 191263660c0SAlfonso Siciliano nitems, items, form, cfield); 192c76f0793SBaptiste Daroussin loop = false; 193263660c0SAlfonso Siciliano } 194c76f0793SBaptiste Daroussin break; 195f499134dSBaptiste Daroussin case '\t': /* TAB */ 196f499134dSBaptiste Daroussin if (informwin) { 197c76f0793SBaptiste Daroussin bs.curr = 0; 198f499134dSBaptiste Daroussin informwin = false; 199c76f0793SBaptiste Daroussin curs_set(0); 200c76f0793SBaptiste Daroussin } else { 201c76f0793SBaptiste Daroussin bs.curr++; 202f499134dSBaptiste Daroussin informwin = bs.curr >= (int)bs.nbuttons ? 203f499134dSBaptiste Daroussin true : false; 204f499134dSBaptiste Daroussin if (informwin) { 205*bce40c02SAlfonso S. Siciliano curs_set(1); 206c76f0793SBaptiste Daroussin pos_form_cursor(form); 207c76f0793SBaptiste Daroussin } 208c76f0793SBaptiste Daroussin } 209c76f0793SBaptiste Daroussin buttupdate = true; 210c76f0793SBaptiste Daroussin break; 211c76f0793SBaptiste Daroussin case KEY_LEFT: 212f499134dSBaptiste Daroussin if (informwin) { 213*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_PREV_CHAR); 214f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 215f499134dSBaptiste Daroussin if (mf->pos > 0) 216f499134dSBaptiste Daroussin mf->pos -= 1; 217c76f0793SBaptiste Daroussin } else { 218c76f0793SBaptiste Daroussin if (bs.curr > 0) { 219c76f0793SBaptiste Daroussin bs.curr--; 220c76f0793SBaptiste Daroussin buttupdate = true; 221c76f0793SBaptiste Daroussin } 222c76f0793SBaptiste Daroussin } 223c76f0793SBaptiste Daroussin break; 224c76f0793SBaptiste Daroussin case KEY_RIGHT: 225f499134dSBaptiste Daroussin if (informwin) { 226f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 227d93b4d32SBaptiste Daroussin if (mf->pos >= mf->buflen) 228f499134dSBaptiste Daroussin break; 229f499134dSBaptiste Daroussin mf->pos += 1; 230*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_NEXT_CHAR); 231c76f0793SBaptiste Daroussin } else { 232c76f0793SBaptiste Daroussin if (bs.curr < (int) bs.nbuttons - 1) { 233c76f0793SBaptiste Daroussin bs.curr++; 234c76f0793SBaptiste Daroussin buttupdate = true; 235c76f0793SBaptiste Daroussin } 236c76f0793SBaptiste Daroussin } 237c76f0793SBaptiste Daroussin break; 238c76f0793SBaptiste Daroussin case KEY_UP: 239c76f0793SBaptiste Daroussin if (nitems < 2) 240c76f0793SBaptiste Daroussin break; 241f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.fieldcolor); 242f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.fieldcolor); 243*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_PREV_FIELD); 244*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_END_LINE); 245f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 2468c4f4028SBaptiste Daroussin print_bottomdesc(mf); 247d93b4d32SBaptiste Daroussin mf->pos = MIN(mf->buflen, mf->maxpos); 248f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.f_fieldcolor); 249f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.f_fieldcolor); 250c76f0793SBaptiste Daroussin break; 251c76f0793SBaptiste Daroussin case KEY_DOWN: 252c76f0793SBaptiste Daroussin if (nitems < 2) 253c76f0793SBaptiste Daroussin break; 254f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.fieldcolor); 255f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.fieldcolor); 256*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_NEXT_FIELD); 257*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_END_LINE); 258f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 2598c4f4028SBaptiste Daroussin print_bottomdesc(mf); 260d93b4d32SBaptiste Daroussin mf->pos = MIN(mf->buflen, mf->maxpos); 261f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.f_fieldcolor); 262f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.f_fieldcolor); 263c76f0793SBaptiste Daroussin break; 264c76f0793SBaptiste Daroussin case KEY_BACKSPACE: 265f499134dSBaptiste Daroussin case 127: /* Backspace */ 266f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 267f499134dSBaptiste Daroussin if (mf->pos <= 0) 268f499134dSBaptiste Daroussin break; 269*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV); 270*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_BEG_LINE); 271d93b4d32SBaptiste Daroussin mf->pos = mf->pos - 1; 272d93b4d32SBaptiste Daroussin for (i = 0; i < mf->pos; i++) 273*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_NEXT_CHAR); 274f499134dSBaptiste Daroussin shiftleft(mf); 275c76f0793SBaptiste Daroussin break; 276c76f0793SBaptiste Daroussin case KEY_DC: 277*bce40c02SAlfonso S. Siciliano form_driver_w(form, KEY_CODE_YES, REQ_DEL_CHAR); 278f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 279d93b4d32SBaptiste Daroussin if (mf->pos < mf->buflen) 280f499134dSBaptiste Daroussin shiftleft(mf); 281f499134dSBaptiste Daroussin break; 282f499134dSBaptiste Daroussin case KEY_F(1): 283*bce40c02SAlfonso S. Siciliano if (conf->key.f1_file == NULL && 284*bce40c02SAlfonso S. Siciliano conf->key.f1_message == NULL) 285f499134dSBaptiste Daroussin break; 286f499134dSBaptiste Daroussin if (f1help(conf) != 0) 287263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 288f499134dSBaptiste Daroussin /* No Break */ 289f499134dSBaptiste Daroussin case KEY_RESIZE: 290f499134dSBaptiste Daroussin output = REDRAWFORM; 291f499134dSBaptiste Daroussin loop = false; 292c76f0793SBaptiste Daroussin break; 293c76f0793SBaptiste Daroussin default: 294f499134dSBaptiste Daroussin if (informwin) { 295*bce40c02SAlfonso S. Siciliano if (chtype == KEY_CODE_YES) 296*bce40c02SAlfonso S. Siciliano break; 297f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 298f499134dSBaptiste Daroussin if (mf->secure) 299*bce40c02SAlfonso S. Siciliano form_driver_w(form, chtype, mf->securech); 300f499134dSBaptiste Daroussin else 301*bce40c02SAlfonso S. Siciliano form_driver_w(form, chtype, input); 302f499134dSBaptiste Daroussin insertch(mf, input); 303f499134dSBaptiste Daroussin } 304f499134dSBaptiste Daroussin else { 305263660c0SAlfonso Siciliano if (shortcut_buttons(input, &bs)) { 306263660c0SAlfonso Siciliano output = return_values(conf, 307263660c0SAlfonso Siciliano bs.value[bs.curr], nitems, items, 308263660c0SAlfonso Siciliano form, cfield); 309f499134dSBaptiste Daroussin loop = false; 310f499134dSBaptiste Daroussin } 311f499134dSBaptiste Daroussin } 312c76f0793SBaptiste Daroussin break; 313c76f0793SBaptiste Daroussin } 314c76f0793SBaptiste Daroussin } 315c76f0793SBaptiste Daroussin 316c76f0793SBaptiste Daroussin curs_set(0); 317c76f0793SBaptiste Daroussin 318263660c0SAlfonso Siciliano return (output); 319f499134dSBaptiste Daroussin } 320f499134dSBaptiste Daroussin 321f499134dSBaptiste Daroussin static int 322263660c0SAlfonso Siciliano form_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, 323263660c0SAlfonso Siciliano const char *text, int linelen, unsigned int *formheight, int nitems, 324f499134dSBaptiste Daroussin struct buttons bs) 325f499134dSBaptiste Daroussin { 326263660c0SAlfonso Siciliano int htext, wtext, menusize; 327263660c0SAlfonso Siciliano 328263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) { 329263660c0SAlfonso Siciliano if (text_size(conf, rows, cols, text, &bs, *formheight + 2, 330263660c0SAlfonso Siciliano linelen + 2, &htext, &wtext) != 0) 331263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 332263660c0SAlfonso Siciliano } 333263660c0SAlfonso Siciliano 334263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE) 335263660c0SAlfonso Siciliano *w = widget_min_width(conf, wtext, linelen + 2, &bs); 336263660c0SAlfonso Siciliano 337263660c0SAlfonso Siciliano if (rows == BSDDIALOG_AUTOSIZE) { 338263660c0SAlfonso Siciliano if (*formheight == 0) { 339263660c0SAlfonso Siciliano menusize = widget_max_height(conf) - HBORDERS - 340263660c0SAlfonso Siciliano 2 /*buttons*/ - htext; 341263660c0SAlfonso Siciliano menusize = MIN(menusize, nitems + 2); 342263660c0SAlfonso Siciliano *formheight = menusize - 2 < 0 ? 0 : menusize - 2; 343263660c0SAlfonso Siciliano } 344263660c0SAlfonso Siciliano else /* h autosize with fixed formheight */ 345263660c0SAlfonso Siciliano menusize = *formheight + 2; 346263660c0SAlfonso Siciliano 347263660c0SAlfonso Siciliano *h = widget_min_height(conf, htext, menusize, true); 348263660c0SAlfonso Siciliano } else { 349263660c0SAlfonso Siciliano if (*formheight == 0) 350263660c0SAlfonso Siciliano *formheight = MIN(rows-6-htext, nitems); 351263660c0SAlfonso Siciliano } 352263660c0SAlfonso Siciliano 353263660c0SAlfonso Siciliano return (0); 354263660c0SAlfonso Siciliano } 355263660c0SAlfonso Siciliano 356263660c0SAlfonso Siciliano static int 357263660c0SAlfonso Siciliano form_checksize(int rows, int cols, const char *text, int formheight, int nitems, 358263660c0SAlfonso Siciliano unsigned int linelen, struct buttons bs) 359263660c0SAlfonso Siciliano { 360f499134dSBaptiste Daroussin int mincols, textrow, formrows; 361f499134dSBaptiste Daroussin 362f499134dSBaptiste Daroussin mincols = VBORDERS; 363f499134dSBaptiste Daroussin /* buttons */ 364*bce40c02SAlfonso S. Siciliano mincols += buttons_width(bs); 365263660c0SAlfonso Siciliano mincols = MAX(mincols, (int)linelen + 4); 366f499134dSBaptiste Daroussin 367f499134dSBaptiste Daroussin if (cols < mincols) 368263660c0SAlfonso Siciliano RETURN_ERROR("Few cols, width < size buttons or " 369263660c0SAlfonso Siciliano "forms (label + field)"); 370f499134dSBaptiste Daroussin 371f499134dSBaptiste Daroussin textrow = text != NULL && strlen(text) > 0 ? 1 : 0; 372f499134dSBaptiste Daroussin 373f499134dSBaptiste Daroussin if (nitems > 0 && formheight == 0) 374263660c0SAlfonso Siciliano RETURN_ERROR("fields > 0 but formheight == 0, probably " 375f499134dSBaptiste Daroussin "terminal too small"); 376f499134dSBaptiste Daroussin 377f499134dSBaptiste Daroussin formrows = nitems > 0 ? 3 : 0; 378f499134dSBaptiste Daroussin if (rows < 2 + 2 + formrows + textrow) 379f499134dSBaptiste Daroussin RETURN_ERROR("Few lines for this menus"); 380f499134dSBaptiste Daroussin 381263660c0SAlfonso Siciliano return (0); 382f499134dSBaptiste Daroussin } 383f499134dSBaptiste Daroussin 384f499134dSBaptiste Daroussin int 385263660c0SAlfonso Siciliano bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows, 386263660c0SAlfonso Siciliano int cols, unsigned int formheight, unsigned int nitems, 387f499134dSBaptiste Daroussin struct bsddialog_formitem *items) 388f499134dSBaptiste Daroussin { 389263660c0SAlfonso Siciliano int i, output, color, y, x, h, w; 390*bce40c02SAlfonso S. Siciliano unsigned long j, maxline, mybufsize; 391c76f0793SBaptiste Daroussin struct buttons bs; 392f499134dSBaptiste Daroussin struct myfield *myfields; 393*bce40c02SAlfonso S. Siciliano FIELD **cfield; 394*bce40c02SAlfonso S. Siciliano FORM *form; 395*bce40c02SAlfonso S. Siciliano WINDOW *widget, *formwin, *textpad, *shadow; 396c76f0793SBaptiste Daroussin 397263660c0SAlfonso Siciliano /* disable form scrolling */ 398f499134dSBaptiste Daroussin if (formheight < nitems) 399f499134dSBaptiste Daroussin formheight = nitems; 400c76f0793SBaptiste Daroussin 401d93b4d32SBaptiste Daroussin for (i = 0; i < (int)nitems; i++) { 402d93b4d32SBaptiste Daroussin if (items[i].maxvaluelen == 0) 403d93b4d32SBaptiste Daroussin RETURN_ERROR("maxvaluelen cannot be zero"); 404d93b4d32SBaptiste Daroussin if (items[i].fieldlen == 0) 405d93b4d32SBaptiste Daroussin RETURN_ERROR("fieldlen cannot be zero"); 406d93b4d32SBaptiste Daroussin if (items[i].fieldlen > items[i].maxvaluelen) 407d93b4d32SBaptiste Daroussin RETURN_ERROR("fieldlen cannot be > maxvaluelen"); 408d93b4d32SBaptiste Daroussin } 409d93b4d32SBaptiste Daroussin 410f499134dSBaptiste Daroussin maxline = 0; 411f499134dSBaptiste Daroussin myfields = malloc(nitems * sizeof(struct myfield)); 412f499134dSBaptiste Daroussin cfield = calloc(nitems + 1, sizeof(FIELD*)); 413f499134dSBaptiste Daroussin for (i = 0; i < (int)nitems; i++) { 414f499134dSBaptiste Daroussin cfield[i] = new_field(1, items[i].fieldlen, items[i].yfield-1, 415f499134dSBaptiste Daroussin items[i].xfield-1, 0, 0); 416f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_STATIC); 417f499134dSBaptiste Daroussin set_max_field(cfield[i], items[i].maxvaluelen); 418*bce40c02SAlfonso S. Siciliano /* setlocale() should handle set_field_buffer() */ 419f499134dSBaptiste Daroussin set_field_buffer(cfield[i], 0, items[i].init); 420f499134dSBaptiste Daroussin 421*bce40c02SAlfonso S. Siciliano mybufsize = (items[i].maxvaluelen + 1) * sizeof(wchar_t); 422*bce40c02SAlfonso S. Siciliano myfields[i].buf = malloc(mybufsize); 423*bce40c02SAlfonso S. Siciliano memset(myfields[i].buf, 0, mybufsize); 424*bce40c02SAlfonso S. Siciliano for (j = 0; j < items[i].maxvaluelen && j < strlen(items[i].init); 425*bce40c02SAlfonso S. Siciliano j++) 426*bce40c02SAlfonso S. Siciliano myfields[i].buf[j] = items[i].init[j]; 427d93b4d32SBaptiste Daroussin 428*bce40c02SAlfonso S. Siciliano myfields[i].buflen = wcslen(myfields[i].buf); 429d93b4d32SBaptiste Daroussin 430d93b4d32SBaptiste Daroussin myfields[i].maxpos = items[i].maxvaluelen -1; 431d93b4d32SBaptiste Daroussin myfields[i].pos = MIN(myfields[i].buflen, myfields[i].maxpos); 432d93b4d32SBaptiste Daroussin 4338c4f4028SBaptiste Daroussin myfields[i].bottomdesc = items[i].bottomdesc; 434f499134dSBaptiste Daroussin set_field_userptr(cfield[i], &myfields[i]); 435f499134dSBaptiste Daroussin 436f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_AUTOSKIP); 437f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_BLANK); 438f499134dSBaptiste Daroussin 439f499134dSBaptiste Daroussin if (ISFIELDHIDDEN(items[i])) { 440f499134dSBaptiste Daroussin myfields[i].secure = true; 441f499134dSBaptiste Daroussin myfields[i].securech = ' '; 442f499134dSBaptiste Daroussin if (conf->form.securech != '\0') 443f499134dSBaptiste Daroussin myfields[i].securech = conf->form.securech; 444f499134dSBaptiste Daroussin } 445263660c0SAlfonso Siciliano else 446263660c0SAlfonso Siciliano myfields[i].secure = false; 447f499134dSBaptiste Daroussin 448f499134dSBaptiste Daroussin if (ISFIELDREADONLY(items[i])) { 449f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_EDIT); 450f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_ACTIVE); 451f499134dSBaptiste Daroussin color = t.form.readonlycolor; 452f499134dSBaptiste Daroussin } else { 453f499134dSBaptiste Daroussin color = i == 0 ? t.form.f_fieldcolor : t.form.fieldcolor; 454f499134dSBaptiste Daroussin } 455f499134dSBaptiste Daroussin set_field_fore(cfield[i], color); 456f499134dSBaptiste Daroussin set_field_back(cfield[i], color); 457f499134dSBaptiste Daroussin 458f499134dSBaptiste Daroussin maxline = MAX(maxline, items[i].xlabel + strlen(items[i].label)); 459263660c0SAlfonso Siciliano maxline = MAX(maxline, items[i].xfield + items[i].fieldlen - 1); 460f499134dSBaptiste Daroussin } 461f499134dSBaptiste Daroussin cfield[i] = NULL; 462f499134dSBaptiste Daroussin 463f499134dSBaptiste Daroussin /* disable focus with 1 item (inputbox or passwordbox) */ 464f499134dSBaptiste Daroussin if (formheight == 1 && nitems == 1 && strlen(items[0].label) == 0 && 465f499134dSBaptiste Daroussin items[0].xfield == 1 ) { 4668c4f4028SBaptiste Daroussin set_field_fore(cfield[0], t.dialog.color); 4678c4f4028SBaptiste Daroussin set_field_back(cfield[0], t.dialog.color); 468f499134dSBaptiste Daroussin } 469c76f0793SBaptiste Daroussin 470263660c0SAlfonso Siciliano get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL); 471c76f0793SBaptiste Daroussin 472f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 473263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 474263660c0SAlfonso Siciliano if (form_autosize(conf, rows, cols, &h, &w, text, maxline, &formheight, 475263660c0SAlfonso Siciliano nitems, bs) != 0) 476263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 477263660c0SAlfonso Siciliano if (form_checksize(h, w, text, formheight, nitems, maxline, bs) != 0) 478263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 479f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 480263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 481c76f0793SBaptiste Daroussin 482263660c0SAlfonso Siciliano if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs, 483263660c0SAlfonso Siciliano true) != 0) 484263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 485c76f0793SBaptiste Daroussin 486263660c0SAlfonso Siciliano prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN, 487263660c0SAlfonso Siciliano y + h - formheight, x + 1 + w - TEXTHMARGIN); 488c76f0793SBaptiste Daroussin 489f499134dSBaptiste Daroussin formwin = new_boxed_window(conf, y + h - 3 - formheight -2, x +1, 490f499134dSBaptiste Daroussin formheight+2, w-2, LOWERED); 491c76f0793SBaptiste Daroussin 492f499134dSBaptiste Daroussin form = new_form(cfield); 493f499134dSBaptiste Daroussin set_form_win(form, formwin); 494f499134dSBaptiste Daroussin /* should be formheight */ 495f499134dSBaptiste Daroussin set_form_sub(form, derwin(formwin, nitems, w-4, 1, 1)); 496c76f0793SBaptiste Daroussin post_form(form); 497c76f0793SBaptiste Daroussin 498f499134dSBaptiste Daroussin for (i = 0; i < (int)nitems; i++) 499263660c0SAlfonso Siciliano mvwaddstr(formwin, items[i].ylabel, items[i].xlabel, 500263660c0SAlfonso Siciliano items[i].label); 501c76f0793SBaptiste Daroussin 502f499134dSBaptiste Daroussin wrefresh(formwin); 503c76f0793SBaptiste Daroussin 504f499134dSBaptiste Daroussin do { 505263660c0SAlfonso Siciliano output = form_handler(conf, widget, bs, formwin, form, cfield, 506263660c0SAlfonso Siciliano nitems, items); 507f499134dSBaptiste Daroussin 508263660c0SAlfonso Siciliano if (update_dialog(conf, shadow, widget, y, x, h, w, textpad, 509263660c0SAlfonso Siciliano text, &bs, true) != 0) 510263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 511f499134dSBaptiste Daroussin 512263660c0SAlfonso Siciliano doupdate(); 513f499134dSBaptiste Daroussin wrefresh(widget); 514f499134dSBaptiste Daroussin 515263660c0SAlfonso Siciliano prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN, 516263660c0SAlfonso Siciliano y + h - formheight, x + 1 + w - TEXTHMARGIN); 517f499134dSBaptiste Daroussin 518f499134dSBaptiste Daroussin draw_borders(conf, formwin, formheight+2, w-2, LOWERED); 519263660c0SAlfonso Siciliano wrefresh(formwin); 520263660c0SAlfonso Siciliano 521263660c0SAlfonso Siciliano refresh(); 522f499134dSBaptiste Daroussin } while (output == REDRAWFORM); 523c76f0793SBaptiste Daroussin 524c76f0793SBaptiste Daroussin unpost_form(form); 525c76f0793SBaptiste Daroussin free_form(form); 526f499134dSBaptiste Daroussin for (i = 0; i < (int)nitems; i++) { 527f499134dSBaptiste Daroussin free_field(cfield[i]); 528f499134dSBaptiste Daroussin free(myfields[i].buf); 529f499134dSBaptiste Daroussin } 530f499134dSBaptiste Daroussin free(cfield); 531f499134dSBaptiste Daroussin free(myfields); 532c76f0793SBaptiste Daroussin 533f499134dSBaptiste Daroussin delwin(formwin); 534263660c0SAlfonso Siciliano end_dialog(conf, shadow, widget, textpad); 535c76f0793SBaptiste Daroussin 536263660c0SAlfonso Siciliano return (output); 537c76f0793SBaptiste Daroussin } 538