1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4*263660c0SAlfonso 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 30d93b4d32SBaptiste Daroussin #include <ctype.h> 31*263660c0SAlfonso Siciliano #include <curses.h> 32f499134dSBaptiste Daroussin #include <string.h> 33f499134dSBaptiste Daroussin 34c76f0793SBaptiste Daroussin #include "bsddialog.h" 35f499134dSBaptiste Daroussin #include "bsddialog_theme.h" 36*263660c0SAlfonso Siciliano #include "lib_util.h" 37c76f0793SBaptiste Daroussin 38*263660c0SAlfonso Siciliano #define MINWDATE 23 /* 3 windows and their borders */ 39*263660c0SAlfonso Siciliano #define MINWTIME 14 /* 3 windows and their borders */ 40f499134dSBaptiste Daroussin 41f499134dSBaptiste Daroussin extern struct bsddialog_theme t; 42f499134dSBaptiste Daroussin 43f499134dSBaptiste Daroussin static int 44f499134dSBaptiste Daroussin datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, 45*263660c0SAlfonso Siciliano int *w, int minw, const char *text, struct buttons bs) 46f499134dSBaptiste Daroussin { 47*263660c0SAlfonso Siciliano int htext, wtext; 48f499134dSBaptiste Daroussin 49*263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) { 50*263660c0SAlfonso Siciliano if (text_size(conf, rows, cols, text, &bs, 3, minw, &htext, 51*263660c0SAlfonso Siciliano &wtext) != 0) 52*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 53f499134dSBaptiste Daroussin } 54f499134dSBaptiste Daroussin 55*263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE) 56*263660c0SAlfonso Siciliano *w = widget_min_width(conf, htext,minw, &bs); 57f499134dSBaptiste Daroussin 58*263660c0SAlfonso Siciliano if (rows == BSDDIALOG_AUTOSIZE) 59*263660c0SAlfonso Siciliano *h = widget_min_height(conf, htext, 3 /* windows */, true); 60*263660c0SAlfonso Siciliano 61*263660c0SAlfonso Siciliano return (0); 62f499134dSBaptiste Daroussin } 63f499134dSBaptiste Daroussin 64f499134dSBaptiste Daroussin static int 65*263660c0SAlfonso Siciliano datetime_checksize(int rows, int cols, int minw, struct buttons bs) 66f499134dSBaptiste Daroussin { 67f499134dSBaptiste Daroussin int mincols; 68f499134dSBaptiste Daroussin 69f499134dSBaptiste Daroussin mincols = VBORDERS; 70f499134dSBaptiste Daroussin mincols += bs.nbuttons * bs.sizebutton; 71f499134dSBaptiste Daroussin mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; 72f499134dSBaptiste Daroussin mincols = MAX(minw, mincols); 73f499134dSBaptiste Daroussin 74f499134dSBaptiste Daroussin if (cols < mincols) 75f499134dSBaptiste Daroussin RETURN_ERROR("Few cols for this timebox/datebox"); 76f499134dSBaptiste Daroussin 77*263660c0SAlfonso Siciliano if (rows < 7) /* 2 button + 2 borders + 3 windows */ 78*263660c0SAlfonso Siciliano RETURN_ERROR("Few rows for this timebox/datebox, at least 7"); 79f499134dSBaptiste Daroussin 80*263660c0SAlfonso Siciliano return (0); 81f499134dSBaptiste Daroussin } 82f499134dSBaptiste Daroussin 83*263660c0SAlfonso Siciliano int 84*263660c0SAlfonso Siciliano bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows, 85*263660c0SAlfonso Siciliano int cols, unsigned int *hh, unsigned int *mm, unsigned int *ss) 86c76f0793SBaptiste Daroussin { 87f499134dSBaptiste Daroussin bool loop; 88*263660c0SAlfonso Siciliano int i, input, output, y, x, h, w, sel; 89*263660c0SAlfonso Siciliano WINDOW *widget, *textpad, *shadow; 90*263660c0SAlfonso Siciliano struct buttons bs; 91c76f0793SBaptiste Daroussin struct myclockstruct { 92c76f0793SBaptiste Daroussin unsigned int max; 93f499134dSBaptiste Daroussin unsigned int value; 94c76f0793SBaptiste Daroussin WINDOW *win; 95f499134dSBaptiste Daroussin }; 96c76f0793SBaptiste Daroussin 97f499134dSBaptiste Daroussin if (hh == NULL || mm == NULL || ss == NULL) 98f499134dSBaptiste Daroussin RETURN_ERROR("hh / mm / ss cannot be NULL"); 99c76f0793SBaptiste Daroussin 100f499134dSBaptiste Daroussin struct myclockstruct c[3] = { 101f499134dSBaptiste Daroussin {23, *hh, NULL}, 102f499134dSBaptiste Daroussin {59, *mm, NULL}, 103f499134dSBaptiste Daroussin {59, *ss, NULL} 104f499134dSBaptiste Daroussin }; 105f499134dSBaptiste Daroussin 106f499134dSBaptiste Daroussin for (i = 0 ; i < 3; i++) { 107f499134dSBaptiste Daroussin if (c[i].value > c[i].max) 108f499134dSBaptiste Daroussin c[i].value = c[i].max; 109f499134dSBaptiste Daroussin } 110c76f0793SBaptiste Daroussin 111*263660c0SAlfonso Siciliano get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL); 112c76f0793SBaptiste Daroussin 113f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 114*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 115*263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, 116*263660c0SAlfonso Siciliano bs) != 0) 117*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 118*263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWTIME, bs) != 0) 119*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 120f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 121*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 122f499134dSBaptiste Daroussin 123*263660c0SAlfonso Siciliano if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs, 124*263660c0SAlfonso Siciliano true) != 0) 125*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 126f499134dSBaptiste Daroussin 127*263660c0SAlfonso Siciliano pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 128*263660c0SAlfonso Siciliano doupdate(); 129f499134dSBaptiste Daroussin 130f499134dSBaptiste Daroussin c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 7, 3, 4, LOWERED); 131f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 3, ':'); 132f499134dSBaptiste Daroussin c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 2, 3, 4, LOWERED); 133f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 2, ':'); 134f499134dSBaptiste Daroussin c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 3, 3, 4, LOWERED); 135f499134dSBaptiste Daroussin 136f499134dSBaptiste Daroussin wrefresh(widget); 137f499134dSBaptiste Daroussin 138c76f0793SBaptiste Daroussin sel = 0; 139c76f0793SBaptiste Daroussin curs_set(2); 140f499134dSBaptiste Daroussin loop = true; 141c76f0793SBaptiste Daroussin while (loop) { 142c76f0793SBaptiste Daroussin for (i = 0; i < 3; i++) { 143f499134dSBaptiste Daroussin mvwprintw(c[i].win, 1, 1, "%2d", c[i].value); 144c76f0793SBaptiste Daroussin wrefresh(c[i].win); 145c76f0793SBaptiste Daroussin } 146c76f0793SBaptiste Daroussin wmove(c[sel].win, 1, 2); 147c76f0793SBaptiste Daroussin wrefresh(c[sel].win); 148c76f0793SBaptiste Daroussin 149c76f0793SBaptiste Daroussin input = getch(); 150c76f0793SBaptiste Daroussin switch(input) { 151f499134dSBaptiste Daroussin case KEY_ENTER: 152c76f0793SBaptiste Daroussin case 10: /* Enter */ 153c76f0793SBaptiste Daroussin output = bs.value[bs.curr]; 1548c4f4028SBaptiste Daroussin if (output == BSDDIALOG_OK) { 155f499134dSBaptiste Daroussin *hh = c[0].value; 156f499134dSBaptiste Daroussin *mm = c[1].value; 157f499134dSBaptiste Daroussin *ss = c[2].value; 158c76f0793SBaptiste Daroussin } 159c76f0793SBaptiste Daroussin loop = false; 160c76f0793SBaptiste Daroussin break; 161c76f0793SBaptiste Daroussin case 27: /* Esc */ 162*263660c0SAlfonso Siciliano if (conf->key.enable_esc) { 163c76f0793SBaptiste Daroussin output = BSDDIALOG_ESC; 164c76f0793SBaptiste Daroussin loop = false; 165*263660c0SAlfonso Siciliano } 166c76f0793SBaptiste Daroussin break; 167c76f0793SBaptiste Daroussin case '\t': /* TAB */ 168*263660c0SAlfonso Siciliano bs.curr = (bs.curr + 1) % bs.nbuttons; 169*263660c0SAlfonso Siciliano draw_buttons(widget, bs, true); 170*263660c0SAlfonso Siciliano wrefresh(widget); 171c76f0793SBaptiste Daroussin break; 172c76f0793SBaptiste Daroussin case KEY_LEFT: 173*263660c0SAlfonso Siciliano sel = sel == 0 ? 2 : (sel - 1); 174c76f0793SBaptiste Daroussin break; 175c76f0793SBaptiste Daroussin case KEY_RIGHT: 176*263660c0SAlfonso Siciliano sel = (sel + 1) % 3; 177c76f0793SBaptiste Daroussin break; 178c76f0793SBaptiste Daroussin case KEY_UP: 179*263660c0SAlfonso Siciliano c[sel].value = c[sel].value < c[sel].max ? 180*263660c0SAlfonso Siciliano c[sel].value + 1 : 0; 181c76f0793SBaptiste Daroussin break; 182c76f0793SBaptiste Daroussin case KEY_DOWN: 183*263660c0SAlfonso Siciliano c[sel].value = c[sel].value > 0 ? 184*263660c0SAlfonso Siciliano c[sel].value - 1 : c[sel].max; 185c76f0793SBaptiste Daroussin break; 186f499134dSBaptiste Daroussin case KEY_F(1): 1878c4f4028SBaptiste Daroussin if (conf->f1_file == NULL && conf->f1_message == NULL) 188f499134dSBaptiste Daroussin break; 189f499134dSBaptiste Daroussin curs_set(0); 190f499134dSBaptiste Daroussin if (f1help(conf) != 0) 191*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 192f499134dSBaptiste Daroussin curs_set(2); 193*263660c0SAlfonso Siciliano /* No break, screen size can change */ 194f499134dSBaptiste Daroussin case KEY_RESIZE: 195*263660c0SAlfonso Siciliano /* Important for decreasing screen */ 196f499134dSBaptiste Daroussin hide_widget(y, x, h, w, conf->shadow); 197f499134dSBaptiste Daroussin refresh(); 198f499134dSBaptiste Daroussin 199f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 200*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 201*263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, 202*263660c0SAlfonso Siciliano MINWTIME, text, bs) != 0) 203*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 204*263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWTIME, bs) != 0) 205*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 206f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 207*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 208f499134dSBaptiste Daroussin 209*263660c0SAlfonso Siciliano if (update_dialog(conf, shadow, widget, y, x, h, w, 210*263660c0SAlfonso Siciliano textpad, text, &bs, true) != 0) 211*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 212f499134dSBaptiste Daroussin 213*263660c0SAlfonso Siciliano doupdate(); 214f499134dSBaptiste Daroussin 215f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 3, ':'); 216f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 2, ':'); 217f499134dSBaptiste Daroussin wrefresh(widget); 218f499134dSBaptiste Daroussin 219f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 220f499134dSBaptiste Daroussin 221f499134dSBaptiste Daroussin wclear(c[0].win); 222f499134dSBaptiste Daroussin mvwin(c[0].win, y + h - 6, x + w/2 - 7); 223f499134dSBaptiste Daroussin draw_borders(conf, c[0].win, 3, 4, LOWERED); 224f499134dSBaptiste Daroussin wrefresh(c[0].win); 225f499134dSBaptiste Daroussin 226f499134dSBaptiste Daroussin wclear(c[1].win); 227f499134dSBaptiste Daroussin mvwin(c[1].win, y + h - 6, x + w/2 - 2); 228f499134dSBaptiste Daroussin draw_borders(conf, c[1].win, 3, 4, LOWERED); 229f499134dSBaptiste Daroussin wrefresh(c[1].win); 230f499134dSBaptiste Daroussin 231f499134dSBaptiste Daroussin wclear(c[2].win); 232f499134dSBaptiste Daroussin mvwin(c[2].win, y + h - 6, x + w/2 + 3); 233f499134dSBaptiste Daroussin draw_borders(conf, c[2].win, 3, 4, LOWERED); 234f499134dSBaptiste Daroussin wrefresh(c[2].win); 235f499134dSBaptiste Daroussin 236f499134dSBaptiste Daroussin /* Important to avoid grey lines expanding screen */ 237f499134dSBaptiste Daroussin refresh(); 238f499134dSBaptiste Daroussin break; 239f499134dSBaptiste Daroussin default: 240*263660c0SAlfonso Siciliano if (shortcut_buttons(input, &bs)) { 241*263660c0SAlfonso Siciliano output = bs.value[bs.curr]; 242f499134dSBaptiste Daroussin loop = false; 243f499134dSBaptiste Daroussin } 244c76f0793SBaptiste Daroussin } 245c76f0793SBaptiste Daroussin } 246c76f0793SBaptiste Daroussin 247c76f0793SBaptiste Daroussin curs_set(0); 248c76f0793SBaptiste Daroussin 249c76f0793SBaptiste Daroussin for (i = 0; i < 3; i++) 250c76f0793SBaptiste Daroussin delwin(c[i].win); 251*263660c0SAlfonso Siciliano end_dialog(conf, shadow, widget, textpad); 252c76f0793SBaptiste Daroussin 253*263660c0SAlfonso Siciliano return (output); 254c76f0793SBaptiste Daroussin } 255c76f0793SBaptiste Daroussin 256f499134dSBaptiste Daroussin int 257*263660c0SAlfonso Siciliano bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, 258*263660c0SAlfonso Siciliano int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd) 259c76f0793SBaptiste Daroussin { 260f499134dSBaptiste Daroussin bool loop; 261*263660c0SAlfonso Siciliano int i, input, output, y, x, h, w, sel; 262*263660c0SAlfonso Siciliano WINDOW *widget, *textpad, *shadow; 263*263660c0SAlfonso Siciliano struct buttons bs; 264c76f0793SBaptiste Daroussin struct calendar { 265f499134dSBaptiste Daroussin int max; 266f499134dSBaptiste Daroussin int value; 267c76f0793SBaptiste Daroussin WINDOW *win; 268c76f0793SBaptiste Daroussin unsigned int x; 269f499134dSBaptiste Daroussin }; 270c76f0793SBaptiste Daroussin struct month { 271c76f0793SBaptiste Daroussin char *name; 272c76f0793SBaptiste Daroussin unsigned int days; 273c76f0793SBaptiste Daroussin }; 274c76f0793SBaptiste Daroussin 275f499134dSBaptiste Daroussin if (yy == NULL || mm == NULL || dd == NULL) 276f499134dSBaptiste Daroussin RETURN_ERROR("yy / mm / dd cannot be NULL"); 277c76f0793SBaptiste Daroussin 278f499134dSBaptiste Daroussin struct calendar c[3] = { 279f499134dSBaptiste Daroussin {9999, *yy, NULL, 4 }, 280f499134dSBaptiste Daroussin {12, *mm, NULL, 9 }, 281f499134dSBaptiste Daroussin {31, *dd, NULL, 2 } 282f499134dSBaptiste Daroussin }; 283c76f0793SBaptiste Daroussin 284f499134dSBaptiste Daroussin struct month m[12] = { 285f499134dSBaptiste Daroussin { "January", 31 }, { "February", 28 }, { "March", 31 }, 286f499134dSBaptiste Daroussin { "April", 30 }, { "May", 31 }, { "June", 30 }, 287f499134dSBaptiste Daroussin { "July", 31 }, { "August", 31 }, { "September", 30 }, 288f499134dSBaptiste Daroussin { "October", 31 }, { "November", 30 }, { "December", 31 } 289f499134dSBaptiste Daroussin }; 290f499134dSBaptiste Daroussin 291f499134dSBaptiste Daroussin #define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) 292f499134dSBaptiste Daroussin 293f499134dSBaptiste Daroussin for (i = 0 ; i < 3; i++) { 294f499134dSBaptiste Daroussin if (c[i].value > c[i].max) 295f499134dSBaptiste Daroussin c[i].value = c[i].max; 296f499134dSBaptiste Daroussin if (c[i].value < 1) 297f499134dSBaptiste Daroussin c[i].value = 1; 298f499134dSBaptiste Daroussin } 299f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 300f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 301f499134dSBaptiste Daroussin c[2].max = 29; 302f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 303f499134dSBaptiste Daroussin c[2].value = c[2].max; 304c76f0793SBaptiste Daroussin 305*263660c0SAlfonso Siciliano get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL); 306c76f0793SBaptiste Daroussin 307f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 308*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 309*263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, 310*263660c0SAlfonso Siciliano bs) != 0) 311*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 312*263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWDATE, bs) != 0) 313*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 314f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 315*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 316f499134dSBaptiste Daroussin 317*263660c0SAlfonso Siciliano if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs, 318*263660c0SAlfonso Siciliano true) != 0) 319*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 320f499134dSBaptiste Daroussin 321*263660c0SAlfonso Siciliano pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 322*263660c0SAlfonso Siciliano doupdate(); 323f499134dSBaptiste Daroussin 324f499134dSBaptiste Daroussin c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 11, 3, 6, LOWERED); 325f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 5, '/'); 326f499134dSBaptiste Daroussin c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 4, 3, 11, LOWERED); 327f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 7, '/'); 328f499134dSBaptiste Daroussin c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 8, 3, 4, LOWERED); 329f499134dSBaptiste Daroussin 330f499134dSBaptiste Daroussin wrefresh(widget); 331f499134dSBaptiste Daroussin 332c76f0793SBaptiste Daroussin sel = 2; 333c76f0793SBaptiste Daroussin curs_set(2); 334f499134dSBaptiste Daroussin loop = true; 335c76f0793SBaptiste Daroussin while (loop) { 336f499134dSBaptiste Daroussin mvwprintw(c[0].win, 1, 1, "%4d", c[0].value); 337f499134dSBaptiste Daroussin mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].value-1].name); 338f499134dSBaptiste Daroussin mvwprintw(c[2].win, 1, 1, "%2d", c[2].value); 339c76f0793SBaptiste Daroussin for (i = 0; i < 3; i++) { 340c76f0793SBaptiste Daroussin wrefresh(c[i].win); 341c76f0793SBaptiste Daroussin } 342c76f0793SBaptiste Daroussin wmove(c[sel].win, 1, c[sel].x); 343c76f0793SBaptiste Daroussin wrefresh(c[sel].win); 344c76f0793SBaptiste Daroussin 345c76f0793SBaptiste Daroussin input = getch(); 346c76f0793SBaptiste Daroussin switch(input) { 347f499134dSBaptiste Daroussin case KEY_ENTER: 348f499134dSBaptiste Daroussin case 10: /* Enter */ 349f499134dSBaptiste Daroussin output = bs.value[bs.curr]; 3508c4f4028SBaptiste Daroussin if (output == BSDDIALOG_OK) { 351f499134dSBaptiste Daroussin *yy = c[0].value; 352f499134dSBaptiste Daroussin *mm = c[1].value; 353f499134dSBaptiste Daroussin *dd = c[2].value; 354c76f0793SBaptiste Daroussin } 355c76f0793SBaptiste Daroussin loop = false; 356c76f0793SBaptiste Daroussin break; 357f499134dSBaptiste Daroussin case 27: /* Esc */ 358*263660c0SAlfonso Siciliano if (conf->key.enable_esc) { 359c76f0793SBaptiste Daroussin output = BSDDIALOG_ESC; 360c76f0793SBaptiste Daroussin loop = false; 361*263660c0SAlfonso Siciliano } 362c76f0793SBaptiste Daroussin break; 363f499134dSBaptiste Daroussin case '\t': /* TAB */ 364*263660c0SAlfonso Siciliano bs.curr = (bs.curr + 1) % bs.nbuttons; 365*263660c0SAlfonso Siciliano draw_buttons(widget, bs, true); 366*263660c0SAlfonso Siciliano wrefresh(widget); 367c76f0793SBaptiste Daroussin break; 368c76f0793SBaptiste Daroussin case KEY_LEFT: 369*263660c0SAlfonso Siciliano sel = sel == 0 ? 2 : (sel - 1); 370c76f0793SBaptiste Daroussin break; 371c76f0793SBaptiste Daroussin case KEY_RIGHT: 372*263660c0SAlfonso Siciliano sel = (sel + 1) % 3; 373c76f0793SBaptiste Daroussin break; 374c76f0793SBaptiste Daroussin case KEY_UP: 375*263660c0SAlfonso Siciliano c[sel].value = c[sel].value > 1 ? 376*263660c0SAlfonso Siciliano c[sel].value - 1 : c[sel].max ; 377f499134dSBaptiste Daroussin /* if mount change */ 378f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 379f499134dSBaptiste Daroussin /* if year change */ 380f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 381f499134dSBaptiste Daroussin c[2].max = 29; 382f499134dSBaptiste Daroussin /* set new day */ 383f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 384f499134dSBaptiste Daroussin c[2].value = c[2].max; 385c76f0793SBaptiste Daroussin break; 386c76f0793SBaptiste Daroussin case KEY_DOWN: 387*263660c0SAlfonso Siciliano c[sel].value = c[sel].value < c[sel].max ? 388*263660c0SAlfonso Siciliano c[sel].value + 1 : 1; 389f499134dSBaptiste Daroussin /* if mount change */ 390f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 391f499134dSBaptiste Daroussin /* if year change */ 392f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 393f499134dSBaptiste Daroussin c[2].max = 29; 394f499134dSBaptiste Daroussin /* set new day */ 395f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 396f499134dSBaptiste Daroussin c[2].value = c[2].max; 397c76f0793SBaptiste Daroussin break; 398f499134dSBaptiste Daroussin case KEY_F(1): 3998c4f4028SBaptiste Daroussin if (conf->f1_file == NULL && conf->f1_message == NULL) 400f499134dSBaptiste Daroussin break; 401f499134dSBaptiste Daroussin curs_set(0); 402f499134dSBaptiste Daroussin if (f1help(conf) != 0) 403*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 404f499134dSBaptiste Daroussin curs_set(2); 405*263660c0SAlfonso Siciliano /* No break, screen size can change */ 406f499134dSBaptiste Daroussin case KEY_RESIZE: 407*263660c0SAlfonso Siciliano /* Important for decreasing screen */ 408f499134dSBaptiste Daroussin hide_widget(y, x, h, w, conf->shadow); 409f499134dSBaptiste Daroussin refresh(); 410f499134dSBaptiste Daroussin 411f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 412*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 413*263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, 414*263660c0SAlfonso Siciliano MINWDATE, text, bs) != 0) 415*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 416*263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWDATE, bs) != 0) 417*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 418f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 419*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 420f499134dSBaptiste Daroussin 421*263660c0SAlfonso Siciliano if (update_dialog(conf, shadow, widget, y, x, h, w, 422*263660c0SAlfonso Siciliano textpad, text, &bs, true) != 0) 423*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 424*263660c0SAlfonso Siciliano doupdate(); 425f499134dSBaptiste Daroussin 426f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 5, '/'); 427f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 7, '/'); 428f499134dSBaptiste Daroussin wrefresh(widget); 429f499134dSBaptiste Daroussin 430f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 431f499134dSBaptiste Daroussin 432f499134dSBaptiste Daroussin wclear(c[0].win); 433f499134dSBaptiste Daroussin mvwin(c[0].win, y + h - 6, x + w/2 - 11); 434f499134dSBaptiste Daroussin draw_borders(conf, c[0].win, 3, 6, LOWERED); 435f499134dSBaptiste Daroussin wrefresh(c[0].win); 436f499134dSBaptiste Daroussin 437f499134dSBaptiste Daroussin wclear(c[1].win); 438f499134dSBaptiste Daroussin mvwin(c[1].win, y + h - 6, x + w/2 - 4); 439f499134dSBaptiste Daroussin draw_borders(conf, c[1].win, 3, 11, LOWERED); 440f499134dSBaptiste Daroussin wrefresh(c[1].win); 441f499134dSBaptiste Daroussin 442f499134dSBaptiste Daroussin wclear(c[2].win); 443f499134dSBaptiste Daroussin mvwin(c[2].win, y + h - 6, x + w/2 + 8); 444f499134dSBaptiste Daroussin draw_borders(conf, c[2].win, 3, 4, LOWERED); 445f499134dSBaptiste Daroussin wrefresh(c[2].win); 446f499134dSBaptiste Daroussin 447f499134dSBaptiste Daroussin /* Important to avoid grey lines expanding screen */ 448f499134dSBaptiste Daroussin refresh(); 449f499134dSBaptiste Daroussin break; 450f499134dSBaptiste Daroussin default: 451*263660c0SAlfonso Siciliano if (shortcut_buttons(input, &bs)) { 452*263660c0SAlfonso Siciliano output = bs.value[bs.curr]; 453f499134dSBaptiste Daroussin loop = false; 454f499134dSBaptiste Daroussin } 455c76f0793SBaptiste Daroussin } 456c76f0793SBaptiste Daroussin } 457c76f0793SBaptiste Daroussin 458c76f0793SBaptiste Daroussin curs_set(0); 459c76f0793SBaptiste Daroussin 460c76f0793SBaptiste Daroussin for (i = 0; i < 3; i++) 461c76f0793SBaptiste Daroussin delwin(c[i].win); 462*263660c0SAlfonso Siciliano end_dialog(conf, shadow, widget, textpad); 463c76f0793SBaptiste Daroussin 464*263660c0SAlfonso Siciliano return (output); 465c76f0793SBaptiste Daroussin }