Implement dialog_prgbox() function which allows run program

(via pipe) with output to dialog box
This commit is contained in:
Andrey A. Chernov 1994-10-28 03:08:28 +00:00
parent 204218e079
commit 3f20de5a5f
14 changed files with 394 additions and 26 deletions

View File

@ -1,9 +1,9 @@
# Makefile for libdialog
# $Id: Makefile,v 1.3 1994/10/20 21:56:34 ache Exp $
# $Id: Makefile,v 1.4 1994/10/21 15:42:27 ache Exp $
LIB= dialog
SRCS= kernel.c rc.c checklist.c inputbox.c menubox.c msgbox.c \
lineedit.c radiolist.c textbox.c yesno.c
lineedit.c radiolist.c textbox.c yesno.c prgbox.c raw_popen.c
CFLAGS+= -Wall -Wstrict-prototypes -DLOCALE

View File

@ -81,7 +81,8 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
print_autowrap(dialog, prompt, width, 1, 3);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
list_width = width-6;
getyx(dialog, cur_y, cur_x);
@ -306,6 +307,7 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
break;
case ' ':
case '\n':
case '\r':
delwin(dialog);
if (!button) {
*result = '\0';

View File

@ -83,6 +83,7 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attrs,
void dialog_create_rc(unsigned char *filename);
int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int width);
int dialog_prgbox(unsigned char *title, const char *line, int height, int width, int pause, int use_shell);
int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause);
int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width);
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result);

View File

@ -155,5 +155,7 @@ extern int parse_rc(void);
void color_setup(void);
#endif
void attr_clear(WINDOW *win, int height, int width, chtype attr);
void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x);
void print_autowrap(WINDOW *win, unsigned char *prompt, int height, int width, int maxwidth, int y, int x, int center, int rawmode);
void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected);
FILE *raw_popen(const char *program, char * const *argv, const char *type);
int raw_pclose(FILE *iop);

View File

@ -64,7 +64,8 @@ int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
print_autowrap(dialog, prompt, width, 1, 3);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
/* Draw the input field box */
box_width = width-6;
@ -146,6 +147,7 @@ int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int
break;
case ' ':
case '\n':
case '\r':
delwin(dialog);
if (button < 1)
strcpy(result, instr);

View File

@ -166,19 +166,21 @@ void attr_clear(WINDOW *win, int height, int width, chtype attr)
* string may contain "\n" to represent a newline character or the real
* newline '\n', but in that case, auto wrap around will be disabled.
*/
void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x)
void print_autowrap(WINDOW *win, unsigned char *prompt, int height, int width, int maxwidth, int y, int x, int center, int rawmode)
{
int first = 1, cur_x, cur_y;
int first = 1, cur_x, cur_y, i;
unsigned char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
chtype ostuff[132], attrs = 0, init_bottom = 0;
wsetscrreg(win, y, height);
getyx(win, cur_y, cur_x);
strcpy(tempstr, prompt);
if ((strstr(tempstr, "\\n") != NULL) ||
if ((!rawmode && strstr(tempstr, "\\n") != NULL) ||
(strchr(tempstr, '\n') != NULL)) { /* Prompt contains "\n" or '\n' */
word = tempstr;
cur_y = y;
wmove(win, cur_y, x);
while (1) {
tempptr = strstr(word, "\\n");
tempptr = rawmode ? NULL : strstr(word, "\\n");
tempptr1 = strchr(word, '\n');
if (tempptr == NULL && tempptr1 == NULL)
break;
@ -203,25 +205,99 @@ void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x)
waddstr(win, word);
word = tempptr + 1;
wmove(win, ++cur_y, x);
if (++cur_y > height) {
cur_y--;
if (!init_bottom) {
for (i = 0; i < x; i++)
ostuff[i] = mvwinch(win, cur_y, i);
for (i = width; i < maxwidth; i++)
ostuff[i] = mvwinch(win, cur_y, i);
attrs = getattrs(win);
init_bottom = 1;
}
scrollok(win, TRUE);
scroll(win);
scrollok(win, FALSE);
wmove(win, cur_y, 0);
for (i = 0; i < x; i++) {
wattrset(win, ostuff[i]&A_ATTRIBUTES);
waddch(win, ostuff[i]);
}
wattrset(win, attrs);
for ( ; i < width; i++)
waddch(win, ' ');
for ( ; i < maxwidth; i++) {
wattrset(win, ostuff[i]&A_ATTRIBUTES);
waddch(win, ostuff[i]);
}
wattrset(win, attrs);
wrefresh(win);
}
wmove(win, cur_y, cur_x = x);
}
waddstr(win, word);
}
else if (strlen(tempstr) <= width-x*2) { /* If prompt is short */
wmove(win, y, (width - strlen(tempstr)) / 2);
else if (center && strlen(tempstr) <= width-x*2) { /* If prompt is short */
wmove(win, cur_y, (width - strlen(tempstr)) / 2);
waddstr(win, tempstr);
}
else if (!center && strlen(tempstr) <= width-cur_x) { /* If prompt is short */
waddstr(win, tempstr);
}
else {
cur_x = x;
cur_y = y;
/* Print prompt word by word, wrap around if necessary */
while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) {
while ((word = strtok(first ? tempstr : NULL, "\t\n ")) != NULL) {
int loop;
unsigned char sc;
if (first) /* First iteration */
first = 0;
if (cur_x+strlen(word) >= width) { /* wrap around to next line */
cur_y++;
cur_x = x;
do {
loop = 0;
if (cur_x+strlen(word) >= width+1) { /* wrap around to next line */
if (x+strlen(word) >= width+1) {
sc = word[width-cur_x-1];
word[width-cur_x-1] = '\0';
wmove(win, cur_y, cur_x);
waddstr(win, word);
word[width-cur_x-1] = sc;
word += width-cur_x-1;
getyx(win, cur_y, cur_x);
loop = 1;
}
cur_y++;
cur_x = x;
if (cur_y > height) {
cur_y--;
if (!init_bottom) {
for (i = 0; i < x; i++)
ostuff[i] = mvwinch(win, cur_y, i);
for (i = width; i < maxwidth; i++)
ostuff[i] = mvwinch(win, cur_y, i);
attrs = getattrs(win);
init_bottom = 1;
}
scrollok(win, TRUE);
scroll(win);
scrollok(win, FALSE);
wmove(win, cur_y, 0);
for (i = 0; i < x; i++) {
wattrset(win, ostuff[i]&A_ATTRIBUTES);
waddch(win, ostuff[i]);
}
wattrset(win, attrs);
for ( ; i < width; i++)
waddch(win, ' ');
for ( ; i < maxwidth; i++) {
wattrset(win, ostuff[i]&A_ATTRIBUTES);
waddch(win, ostuff[i]);
}
wattrset(win, attrs);
wrefresh(win);
}
}
}
while(loop);
wmove(win, cur_y, cur_x);
waddstr(win, word);
getyx(win, cur_y, cur_x);

View File

@ -49,9 +49,12 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attr,
case KEY_UP:
case KEY_DOWN:
case ESC:
case '\r':
case '\n':
for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
instr[i] = '\0';
if (key == '\r')
key = '\n';
goto ret;
case KEY_HOME:
input_x = scroll = 0;

View File

@ -71,7 +71,8 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
print_autowrap(dialog, prompt, width, 1, 3);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
menu_width = width-6;
getyx(dialog, cur_y, cur_x);
@ -271,6 +272,7 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
wrefresh(dialog);
break;
case ' ':
case '\r':
case '\n':
delwin(dialog);
if (!button)

View File

@ -53,7 +53,8 @@ int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int w
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
print_autowrap(dialog, prompt, width-2, 1, 2);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
if (pause) {
wattrset(dialog, border_attr);
@ -68,8 +69,10 @@ int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int w
waddch(dialog, ' ');
print_button(dialog, " OK ", height-2, width/2-4, TRUE);
wrefresh(dialog);
while (key != ESC && key != '\n' && key != ' ')
while (key != ESC && key != '\n' && key != ' ' && key != '\r')
key = wgetch(dialog);
if (key == '\r')
key = '\n';
}
else {
key = '\n';

113
gnu/lib/libdialog/prgbox.c Normal file
View File

@ -0,0 +1,113 @@
/*
* msgbox.c -- implements the message box and info box
*
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <dialog.h>
#include "dialog.priv.h"
/*
* Display a message box. Program will pause and display an "OK" button
* if the parameter 'pause' is non-zero.
*/
int dialog_prgbox(unsigned char *title, const char *line, int height, int width, int pause, int use_shell)
{
int i, x, y, key = 0;
WINDOW *dialog;
FILE *f;
unsigned char *s, buf[MAX_LEN];
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
if (title != NULL) {
wattrset(dialog, title_attr);
wmove(dialog, 0, (width - strlen(title))/2 - 1);
waddch(dialog, ' ');
waddstr(dialog, title);
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
wmove(dialog, 1, 2);
if (!use_shell) {
char cmdline[MAX_LEN];
char *av[51], **ap = av, *val;
int first = 1;
strcpy(cmdline, line);
while ((val = strtok(first ? cmdline : NULL, " \t")) != NULL) {
first = 0;
*ap++ = val;
}
*ap = NULL;
f = raw_popen(av[0], av, "r");
} else
f = raw_popen(line, NULL, "r");
while (fgets(buf, sizeof(buf), f) != NULL) {
i = strlen(buf);
if (buf[i-1] == '\n')
buf[i-1] = '\0';
s = buf;
while ((s = strchr(s, '\t')) != NULL)
*s++ = ' ';
print_autowrap(dialog, buf, height-(pause?3:1), width-2, width, 1, 2, FALSE, TRUE);
print_autowrap(dialog, "\n", height-(pause?3:1), width-2, width, 1, 2, FALSE, FALSE);
}
raw_pclose(f);
if (pause) {
wattrset(dialog, border_attr);
wmove(dialog, height-3, 0);
waddch(dialog, ACS_LTEE);
for (i = 0; i < width-2; i++)
waddch(dialog, ACS_HLINE);
wattrset(dialog, dialog_attr);
waddch(dialog, ACS_RTEE);
wmove(dialog, height-2, 1);
for (i = 0; i < width-2; i++)
waddch(dialog, ' ');
print_button(dialog, " OK ", height-2, width/2-4, TRUE);
wrefresh(dialog);
while (key != ESC && key != '\n' && key != ' ' && key != '\r')
key = wgetch(dialog);
if (key == '\r')
key = '\n';
}
else {
key = '\n';
wrefresh(dialog);
}
delwin(dialog);
return (key == ESC ? -1 : 0);
}
/* End of dialog_msgbox() */

View File

@ -89,7 +89,8 @@ int dialog_radiolist(char *title, char *prompt, int height, int width, int list_
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
print_autowrap(dialog, prompt, width, 1, 3);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
list_width = width-6;
getyx(dialog, cur_y, cur_x);
@ -316,6 +317,7 @@ int dialog_radiolist(char *title, char *prompt, int height, int width, int list_
wrefresh(dialog);
break;
case ' ':
case '\r':
case '\n':
delwin(dialog);
if (!button) {

View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software written by Ken Arnold and
* published in UNIX Review, Vol. 6, No. 8.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
static struct pid {
struct pid *next;
FILE *fp;
pid_t pid;
} *pidlist;
FILE *
raw_popen(const char *program, char * const *argv, const char *type)
{
struct pid *cur;
FILE *iop;
int pdes[2], pid;
if ((*type != 'r' && *type != 'w') || type[1])
return (NULL);
if ((cur = malloc(sizeof(struct pid))) == NULL)
return (NULL);
if (pipe(pdes) < 0) {
(void)free(cur);
return (NULL);
}
switch (pid = vfork()) {
case -1: /* Error. */
(void)close(pdes[0]);
(void)close(pdes[1]);
(void)free(cur);
return (NULL);
/* NOTREACHED */
case 0: /* Child. */
if (*type == 'r') {
if (pdes[1] != STDOUT_FILENO) {
(void)dup2(pdes[1], STDOUT_FILENO);
(void)close(pdes[1]);
}
(void) close(pdes[0]);
} else {
if (pdes[0] != STDIN_FILENO) {
(void)dup2(pdes[0], STDIN_FILENO);
(void)close(pdes[0]);
}
(void)close(pdes[1]);
}
if (argv == NULL)
execl(_PATH_BSHELL, "sh", "-c", program, NULL);
else
execvp(program, argv);
_exit(127);
/* NOTREACHED */
}
/* Parent; assume fdopen can't fail. */
if (*type == 'r') {
iop = fdopen(pdes[0], type);
(void)close(pdes[1]);
} else {
iop = fdopen(pdes[1], type);
(void)close(pdes[0]);
}
/* Link into list of file descriptors. */
cur->fp = iop;
cur->pid = pid;
cur->next = pidlist;
pidlist = cur;
return (iop);
}
/*
* pclose --
* Pclose returns -1 if stream is not associated with a `popened' command,
* if already `pclosed', or waitpid returns an error.
*/
int
raw_pclose(FILE *iop)
{
register struct pid *cur, *last;
int omask;
union wait pstat;
pid_t pid;
(void)fclose(iop);
/* Find the appropriate file pointer. */
for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
if (cur->fp == iop)
break;
if (cur == NULL)
return (-1);
/* Get the status of the process. */
omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
do {
pid = waitpid(cur->pid, (int *) &pstat, 0);
} while (pid == -1 && errno == EINTR);
(void)sigsetmask(omask);
/* Remove the entry from the linked list. */
if (last == NULL)
pidlist = cur->next;
else
last->next = cur->next;
free(cur);
return (pid == -1 ? -1 : pstat.w_status);
}

View File

@ -130,7 +130,7 @@ int dialog_textbox(unsigned char *title, unsigned char *file, int height, int wi
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
while ((key != ESC) && (key != '\n')) {
while ((key != ESC) && (key != '\n') && (key != '\r')) {
key = wgetch(dialog);
switch (key) {
case 'E': /* Exit */

View File

@ -62,7 +62,8 @@ int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int w
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
print_autowrap(dialog, prompt, width, 1, 3);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
x = width/2-10;
y = height-2;
@ -100,6 +101,7 @@ int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int w
wrefresh(dialog);
break;
case ' ':
case '\r':
case '\n':
delwin(dialog);
return button;