13515Sache/* 23515Sache * msgbox.c -- implements the message box and info box 33515Sache * 43515Sache * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 53515Sache * 63515Sache * This program is free software; you can redistribute it and/or 73515Sache * modify it under the terms of the GNU General Public License 83515Sache * as published by the Free Software Foundation; either version 2 93515Sache * of the License, or (at your option) any later version. 103515Sache * 113515Sache * This program is distributed in the hope that it will be useful, 123515Sache * but WITHOUT ANY WARRANTY; without even the implied warranty of 133515Sache * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143515Sache * GNU General Public License for more details. 153515Sache * 163515Sache * You should have received a copy of the GNU General Public License 173515Sache * along with this program; if not, write to the Free Software 183515Sache * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 193515Sache */ 203515Sache 21114603Sobrien#include <sys/cdefs.h> 22114603Sobrien__FBSDID("$FreeBSD$"); 233515Sache 243740Sache#include <dialog.h> 253515Sache#include "dialog.priv.h" 263515Sache 273515Sache 286458Sache/* local prototypes */ 296458Sachestatic int getnlines(unsigned char *buf); 306458Sachestatic void print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll); 316458Sachestatic void print_perc(WINDOW *win, int y, int x, float p); 326458Sache 336458Sache 343515Sache/* 353515Sache * Display a message box. Program will pause and display an "OK" button 363515Sache * if the parameter 'pause' is non-zero. 373515Sache */ 383515Sacheint dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause) 393515Sache{ 404527Sache int i, j, x, y, key = 0; 413515Sache WINDOW *dialog; 423515Sache 434527Sache if (height < 0) 444527Sache height = strheight(prompt)+2+2*(!!pause); 454527Sache if (width < 0) { 464527Sache i = strwidth(prompt); 476035Sache j = ((title != NULL) ? strwidth(title) : 0); 484527Sache width = MAX(i,j)+4; 494527Sache } 506035Sache if (pause) 516035Sache width = MAX(width,10); 524527Sache 534658Sache if (width > COLS) 544658Sache width = COLS; 554658Sache if (height > LINES) 564658Sache height = LINES; 573515Sache /* center dialog box on screen */ 5813135Sjkh x = DialogX ? DialogX : (COLS - width)/2; 5913135Sjkh y = DialogY ? DialogY : (LINES - height)/2; 603515Sache 613515Sache#ifdef HAVE_NCURSES 623515Sache if (use_shadow) 633515Sache draw_shadow(stdscr, y, x, height, width); 643515Sache#endif 653515Sache dialog = newwin(height, width, y, x); 664024Sache if (dialog == NULL) { 674024Sache endwin(); 684024Sache fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x); 694024Sache exit(1); 704024Sache } 713515Sache keypad(dialog, TRUE); 723515Sache 733515Sache draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 743515Sache 753515Sache if (title != NULL) { 763515Sache wattrset(dialog, title_attr); 773515Sache wmove(dialog, 0, (width - strlen(title))/2 - 1); 783515Sache waddch(dialog, ' '); 793515Sache waddstr(dialog, title); 803515Sache waddch(dialog, ' '); 813515Sache } 823515Sache wattrset(dialog, dialog_attr); 833950Sache wmove(dialog, 1, 2); 843950Sache print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE); 853515Sache 863515Sache if (pause) { 873515Sache wattrset(dialog, border_attr); 883515Sache wmove(dialog, height-3, 0); 893515Sache waddch(dialog, ACS_LTEE); 903515Sache for (i = 0; i < width-2; i++) 913515Sache waddch(dialog, ACS_HLINE); 923515Sache wattrset(dialog, dialog_attr); 933515Sache waddch(dialog, ACS_RTEE); 943515Sache wmove(dialog, height-2, 1); 953515Sache for (i = 0; i < width-2; i++) 963515Sache waddch(dialog, ' '); 976458Sache display_helpline(dialog, height-1, width); 9820359Sjkh print_button(dialog, " OK ", height-2, width/2-6, TRUE); 993515Sache wrefresh(dialog); 1003950Sache while (key != ESC && key != '\n' && key != ' ' && key != '\r') 1013515Sache key = wgetch(dialog); 1023950Sache if (key == '\r') 1033950Sache key = '\n'; 1043515Sache } 1053515Sache else { 1063515Sache key = '\n'; 1073515Sache wrefresh(dialog); 1083515Sache } 1093515Sache 1103515Sache delwin(dialog); 1113515Sache return (key == ESC ? -1 : 0); 1123515Sache} 1133515Sache/* End of dialog_msgbox() */ 1146458Sache 1156458Sacheint 1166458Sachedialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width) 1176458Sache/* 1186458Sache * Desc: basically the same as dialog_msgbox, but ... can use PGUP, PGDN and 1196458Sache * arrowkeys to move around the text and pause is always enabled 1206458Sache */ 1216458Sache{ 1226458Sache int i, j, x, y, key=0; 1236458Sache int theight, startline, hscroll, max_lines; 1246458Sache WINDOW *dialog; 1256458Sache 1266458Sache if (height < 0) 1276674Sache height = strheight(prompt)+2+2; 1286458Sache if (width < 0) { 1296458Sache i = strwidth(prompt); 1306674Sache j = ((title != NULL) ? strwidth(title) : 0); 1316458Sache width = MAX(i,j)+4; 1326458Sache } 1336674Sache width = MAX(width,10); 1346458Sache 1356458Sache if (width > COLS) 1366458Sache width = COLS; 1376458Sache if (height > LINES) 1386458Sache height = LINES; 1396458Sache /* center dialog box on screen */ 1406458Sache x = (COLS - width)/2; 1416458Sache y = (LINES - height)/2; 1426458Sache 1436458Sache#ifdef HAVE_NCURSES 1446458Sache if (use_shadow) 1456458Sache draw_shadow(stdscr, y, x, height, width); 1466458Sache#endif 1476458Sache dialog = newwin(height, width, y, x); 1486458Sache if (dialog == NULL) { 1496458Sache endwin(); 1506458Sache fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x); 1516458Sache exit(1); 1526458Sache } 1536458Sache keypad(dialog, TRUE); 1546458Sache 1556458Sache draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 1566458Sache 1576458Sache if (title != NULL) { 1586458Sache wattrset(dialog, title_attr); 1596458Sache wmove(dialog, 0, (width - strlen(title))/2 - 1); 1606458Sache waddch(dialog, ' '); 1616458Sache waddstr(dialog, title); 1626458Sache waddch(dialog, ' '); 1636458Sache } 1646458Sache 1656674Sache wattrset(dialog, border_attr); 1666458Sache wmove(dialog, height-3, 0); 1676458Sache waddch(dialog, ACS_LTEE); 1686458Sache for (i = 0; i < width-2; i++) 1696458Sache waddch(dialog, ACS_HLINE); 1706458Sache wattrset(dialog, dialog_attr); 1716458Sache waddch(dialog, ACS_RTEE); 1726458Sache wmove(dialog, height-2, 1); 1736458Sache for (i = 0; i < width-2; i++) 1746458Sache waddch(dialog, ' '); 1756458Sache display_helpline(dialog, height-1, width); 17620359Sjkh print_button(dialog, " OK ", height-2, width/2-6, TRUE); 1776458Sache wattrset(dialog, dialog_attr); 1786458Sache 1796458Sache theight = height - 4; 1806458Sache startline = 0; 1816458Sache hscroll = 0; 1826458Sache max_lines = getnlines(prompt); 1836458Sache print_page(dialog, theight, width, prompt, startline, hscroll); 1846458Sache print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines); 18524389Sjkh wmove(dialog, height-2, width/2-3); 1866458Sache wrefresh(dialog); 18781331Seric while ((key != ESC) && (key != '\n') && (key != '\r') && (key != ' ')) { 1886458Sache key = wgetch(dialog); 1896458Sache switch(key) { 1906458Sache case KEY_HOME: 1916458Sache startline=0; 1926458Sache hscroll=0; 1936458Sache break; 1946458Sache case KEY_END: 1956458Sache startline = max_lines - theight; 1966458Sache if (startline < 0) startline = 0; 1976458Sache break; 19821697Sjkh case '\020': /* ^P */ 1996458Sache case KEY_UP: 2006458Sache if (startline > 0) startline--; 2016458Sache break; 20221697Sjkh case '\016': /* ^N */ 2036458Sache case KEY_DOWN: 2046458Sache if (startline < max_lines - theight) startline++; 2056458Sache break; 2066458Sache case KEY_RIGHT: 2077959Sache hscroll+=5; 2086458Sache break; 2096458Sache case KEY_LEFT: 2107959Sache if (hscroll > 0) hscroll-=5; 2117959Sache if (hscroll < 0) hscroll =0; 2126458Sache break; 2136458Sache case KEY_PPAGE: 2146458Sache if (startline - height > 0) { 2156458Sache startline -= theight; 2166458Sache } else { 2176458Sache startline = 0; 2186458Sache } 2196458Sache break; 2206458Sache case KEY_NPAGE: 2216458Sache if (startline + theight < max_lines - theight) { 2226458Sache startline += theight; 2236458Sache } else { 2246458Sache startline = max_lines - theight; 2256458Sache if (startline < 0) startline = 0; 2266458Sache } 2276458Sache break; 2286458Sache case KEY_F(1): 2296458Sache case '?': 2306458Sache display_helpfile(); 2316458Sache break; 2326458Sache } 2338858Srgrimes print_page(dialog, theight, width, prompt, startline, hscroll); 2346458Sache print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines); 23524389Sjkh wmove(dialog, height-2, width/2-3); 2366458Sache wrefresh(dialog); 2376458Sache } 2386458Sache 2396458Sache delwin(dialog); 2406458Sache return (key == ESC ? -1 : 0); 2416458Sache 2426458Sache} /* dialog_mesgbox() */ 2436458Sache 2446458Sachestatic void 2456458Sacheprint_perc(WINDOW *win, int y, int x, float p) 2466458Sache/* 2476458Sache * Desc: print p as a percentage at the coordinates (y,x) 2486458Sache */ 2496458Sache{ 2506458Sache char ps[10]; 2516458Sache 2526458Sache if (p>1.0) p=1.0; 2536458Sache sprintf(ps, "(%3d%%)", (int) (p*100)); 2546458Sache wmove(win, y, x); 2556458Sache waddstr(win, ps); 2566458Sache 2576458Sache return; 2586458Sache} /* print_perc() */ 2596458Sache 2606458Sachestatic int 2616458Sachegetnlines(unsigned char *buf) 2626458Sache/* 2636458Sache * Desc: count the # of lines in <buf> 2646458Sache */ 2656458Sache{ 2666458Sache int i = 0; 2676458Sache 2687959Sache if (*buf) 2697959Sache i++; 2706458Sache while (*buf) { 2717959Sache if (*buf == '\n' || *buf == '\r') 2726458Sache i++; 2736458Sache buf++; 2746458Sache } 2756458Sache return(i); 2766458Sache} /* getlines() */ 2776458Sache 2786458Sache 2796458Sacheunsigned char * 2806458Sachegetline(unsigned char *buf, int n) 2816458Sache/* 2826458Sache * Desc: return a pointer to the n'th line in <buf> or NULL if its 2836458Sache * not there 2846458Sache */ 2856458Sache{ 2866458Sache int i; 2876458Sache 2886458Sache if (n<0) { 2896458Sache return(NULL); 2906458Sache } 2918858Srgrimes 2926458Sache i=0; 2936458Sache while (*buf && i<n) { 2946458Sache if (*buf == '\n' || *buf == '\r') { 2956458Sache i++; 2966458Sache } 2976458Sache buf++; 2986458Sache } 2996458Sache if (i<n) { 3006458Sache return(NULL); 3016458Sache } else { 3026458Sache return(buf); 3036458Sache } 3046458Sache} /* getline() */ 3056458Sache 3066458Sachestatic void 3076458Sacheprint_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll) 3086458Sache/* 3096458Sache * Desc: Print a page of text in the current window, starting at line <startline> 3106458Sache * with a <horizontal> scroll of hscroll from buffer <buf> 3116458Sache */ 3126458Sache{ 3136458Sache int i, j; 3146458Sache unsigned char *b; 3156458Sache 3166458Sache b = getline(buf, startline); 3176458Sache for (i=0; i<height; i++) { 3186458Sache /* clear line */ 3196458Sache wmove(win, 1+i, 1); 3206458Sache for (j=0; j<width-2; j++) waddnstr(win, " ", 1); 3216458Sache wmove(win, 1+i, 1); 3228858Srgrimes j = 0; 3236458Sache /* scroll to the right */ 3246458Sache while (*b && (*b != '\n') && (*b != '\r') && (j<hscroll)) { 3256458Sache b++; 3266458Sache j++; 3276458Sache } 3286458Sache /* print new line */ 3296458Sache j = 0; 3306458Sache while (*b && (*b != '\n') && (*b != '\r') && (j<width-2)) { 3316458Sache waddnstr(win, b, 1); 3326458Sache if (*b != '\t') { /* check for tabs */ 3336458Sache j++; 3346458Sache } else { 3356458Sache j = ((int) (j+1)/8 + 1) * 8 - 1; 3366458Sache } 3376458Sache b++; 3386458Sache } 3396458Sache while (*b && (*b != '\n') && (*b != '\r')) b++; 3406458Sache if (*b) b++; /* skip over '\n', if it exists */ 3416458Sache } 3426458Sache} /* print_page() */ 3438858Srgrimes 3448858Srgrimes 3458858Srgrimes 3468858Srgrimes 347