⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 This version of dialog, formerly known as cdialog is based on the Debian package for dialog 0.9a (se
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Print one line of the prompt in the window within the limits of the * specified right margin.  The line will end on a word boundary and a pointer * to the start of the next line is returned, or a NULL pointer if the end of * *prompt is reached. */static const char *print_line(WINDOW *win, chtype *attr, const char *prompt, int lm, int rm, int *x){    const char *wrap_ptr = prompt;    const char *test_ptr = prompt;    const int *cols = dlg_index_columns(prompt);    const int *indx = dlg_index_wchars(prompt);    int cur_x = lm;    int hidden = 0;    int limit = dlg_count_wchars(prompt);    int n;    *x = 1;    /*     * Set *test_ptr to the end of the line or the right margin (rm), whichever     * is less, and set *wrap_ptr to the end of the last word in the line.     */    for (n = 0; n < limit; ++n) {	if (*test_ptr == '\n' || *test_ptr == '\0' || cur_x >= (rm + hidden))	    break;	if (*test_ptr == ' ' && n != 0 && prompt[indx[n - 1]] != ' ') {	    wrap_ptr = prompt + indx[n];	    *x = cur_x;	} else if (isOurEscape(test_ptr)) {	    hidden += 3;	    n += 2;	}	cur_x = lm + cols[n + 1];	if (cur_x > (rm + hidden))	    break;	test_ptr = prompt + indx[n + 1];    }    /*     * If the line doesn't reach the right margin in the middle of a word, then     * we don't have to wrap it at the end of the previous word.     */    if (*test_ptr == '\n' || *test_ptr == ' ' || *test_ptr == '\0') {	int i = 0;	while (&wrap_ptr[++i] < test_ptr) {	    ;	}	while (wrap_ptr[i - 1] == ' ') {	    i--;	}	wrap_ptr += i;	*x += i;    }    /*     * If the line has no spaces, then wrap it anyway at the right margin     */    else if (*x == 1 && cur_x >= rm) {	*x = rm;	wrap_ptr = test_ptr;    }    /*     * Print the line if we have a window pointer.  Otherwise this routine     * is just being called for sizing the window.     */    if (win) {	dlg_print_text(win, prompt, (wrap_ptr - prompt - hidden), attr);    }    /* *x tells the calling function how long the line was */    if (*x == 1)	*x = rm;    /* Find the start of the next line and return a pointer to it */    test_ptr = wrap_ptr;    while (*test_ptr == ' ')	test_ptr++;    if (*test_ptr == '\n')	test_ptr++;    return (test_ptr);}static voidjustify_text(WINDOW *win,	     const char *prompt,	     int limit_y,	     int limit_x,	     int *high, int *wide){    chtype attr = A_NORMAL;    int x = (2 * MARGIN);    int y = 1;    int max_x = 2;    int lm = (2 * MARGIN);	/* left margin */    int rm = limit_x;		/* right margin */    int bm = limit_y;		/* bottom margin */    if (win) {	rm -= (2 * MARGIN);	bm -= (2 * MARGIN);    }    if (prompt == 0)	prompt = "";    while (y <= bm && *prompt) {	x = lm;	if (*prompt == '\n') {	    while (*prompt == '\n' && y < bm) {		if (*(prompt + 1) != '\0') {		    ++y;		    if (win != 0)			(void) wmove(win, y, lm);		}		prompt++;	    }	} else if (win != 0)	    (void) wmove(win, y, lm);	if (*prompt)	    prompt = print_line(win, &attr, prompt, lm, rm, &x);	if (*prompt) {	    ++y;	    if (win != 0)		(void) wmove(win, y, lm);	}	max_x = MAX(max_x, x);    }    /* Set the final height and width for the calling function */    if (high != 0)	*high = y;    if (wide != 0)	*wide = max_x;}/* * Print a string of text in a window, automatically wrap around to the * next line if the string is too long to fit on one line. Note that the * string may contain embedded newlines. */voiddlg_print_autowrap(WINDOW *win, const char *prompt, int height, int width){    justify_text(win, prompt,		 height,		 width,		 (int *) 0, (int *) 0);}/* * Calculate the window size for preformatted text.  This will calculate box * dimensions that are at or close to the specified aspect ratio for the prompt * string with all spaces and newlines preserved and additional newlines added * as necessary. */static voidauto_size_preformatted(const char *prompt, int *height, int *width){    int high = 0, wide = 0;    float car;			/* Calculated Aspect Ratio */    float diff;    int max_y = SLINES - 1;    int max_x = SCOLS - 2;    int max_width = max_x;    int ar = dialog_state.aspect_ratio;    /* Get the initial dimensions */    justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);    car = (float) (wide / high);    /*     * If the aspect ratio is greater than it should be, then decrease the     * width proportionately.     */    if (car > ar) {	diff = car / (float) ar;	max_x = wide / diff + 4;	justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);	car = (float) wide / high;    }    /*     * If the aspect ratio is too small after decreasing the width, then     * incrementally increase the width until the aspect ratio is equal to or     * greater than the specified aspect ratio.     */    while (car < ar && max_x < max_width) {	max_x += 4;	justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);	car = (float) (wide / high);    }    *height = high;    *width = wide;}/* * Find the length of the longest "word" in the given string.  By setting the * widget width at least this long, we can avoid splitting a word on the * margin. */static intlongest_word(const char *string){    int length, result = 0;    while (*string != '\0') {	length = 0;	while (*string != '\0' && !isspace(*string)) {	    length++;	    string++;	}	result = MAX(result, length);	string++;    }    return result;}/* * if (height or width == -1) Maximize() * if (height or width == 0), justify and return actual limits. */static voidreal_auto_size(const char *title,	       const char *prompt,	       int *height, int *width,	       int boxlines, int mincols){    int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2);    int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1);    int title_length = title ? strlen(title) : 0;    int nc = 4;    int high;    int wide;    int save_high = *height;    int save_wide = *width;    if (prompt == 0) {	if (*height == 0)	    *height = -1;	if (*width == 0)	    *width = -1;    }    if (*height > 0) {	high = *height;    } else {	high = SLINES - y;    }    if (*width > 0) {	wide = *width;    } else if (prompt != 0) {	wide = MAX(title_length, mincols);	if (strchr(prompt, '\n') == 0) {	    double val = dialog_state.aspect_ratio * strlen(prompt);	    int tmp = sqrt(val);	    wide = MAX(wide, tmp);	    wide = MAX(wide, longest_word(prompt));	    justify_text((WINDOW *) 0, prompt, high, wide, height, width);	} else {	    auto_size_preformatted(prompt, height, width);	}    } else {	wide = SCOLS - x;	justify_text((WINDOW *) 0, prompt, high, wide, height, width);    }    if (*width < title_length) {	justify_text((WINDOW *) 0, prompt, high, title_length, height, width);	*width = title_length;    }    if (*width < mincols && save_wide == 0)	*width = mincols;    if (prompt != 0) {	*width += nc;	*height += boxlines + 2;    }    if (save_high > 0)	*height = save_high;    if (save_wide > 0)	*width = save_wide;}/* End of real_auto_size() */voiddlg_auto_size(const char *title,	      const char *prompt,	      int *height,	      int *width,	      int boxlines,	      int mincols){    real_auto_size(title, prompt, height, width, boxlines, mincols);    if (*width > SCOLS) {	(*height)++;	*width = SCOLS;    }    if (*height > SLINES)	*height = SLINES;}/* * if (height or width == -1) Maximize() * if (height or width == 0) *    height=MIN(SLINES, num.lines in fd+n); *    width=MIN(SCOLS, MAX(longer line+n, mincols)); */voiddlg_auto_sizefile(const char *title,		  const char *file,		  int *height,		  int *width,		  int boxlines,		  int mincols){    int count = 0, len = title ? strlen(title) : 0, nc = 4, numlines = 2;    long offset;    char ch;    FILE *fd;    /* Open input file for reading */    if ((fd = fopen(file, "rb")) == NULL)	dlg_exiterr("dlg_auto_sizefile: Cannot open input file %s", file);    if ((*height == -1) || (*width == -1)) {	*height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);	*width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);    }    if ((*height != 0) && (*width != 0)) {	(void) fclose(fd);	return;    }    while (!feof(fd)) {	offset = 0;	while (((ch = getc(fd)) != '\n') && !feof(fd))	    if ((ch == TAB) && (dialog_vars.tab_correct))		offset += dialog_state.tab_len - (offset % dialog_state.tab_len);	    else		offset++;	if (offset > len)	    len = offset;	count++;    }    /* now 'count' has the number of lines of fd and 'len' the max lenght */    *height = MIN(SLINES, count + numlines + boxlines);    *width = MIN(SCOLS, MAX((len + nc), mincols));    /* here width and height can be maximized if > SCOLS|SLINES because       textbox-like widgets don't put all <file> on the screen.       Msgbox-like widget instead have to put all <text> correctly. */    (void) fclose(fd);}/* * Draw a rectangular box with line drawing characters. * * borderchar is used to color the upper/left edges. * * boxchar is used to color the right/lower edges.  It also is fill-color used * for the box contents. * * Normally, if you are drawing a scrollable box, use menubox_border_attr for * boxchar, and menubox_attr for borderchar since the scroll-arrows are drawn * with menubox_attr at the top, and menubox_border_attr at the bottom.  That * also (given the default color choices) produces a recessed effect. * * If you want a raised effect (and are not going to use the scroll-arrows), * reverse this choice. */voiddlg_draw_box(WINDOW *win, int y, int x, int height, int width,	     chtype boxchar, chtype borderchar){    int i, j;    chtype save = getattrs(win);    wattrset(win, 0);    for (i = 0; i < height; i++) {	(void) wmove(win, y + i, x);	for (j = 0; j < width; j++)	    if (!i && !j)		(void) waddch(win, borderchar | ACS_ULCORNER);	    else if (i == height - 1 && !j)		(void) waddch(win, borderchar | ACS_LLCORNER);	    else if (!i && j == width - 1)		(void) waddch(win, boxchar | ACS_URCORNER);	    else if (i == height - 1 && j == width - 1)		(void) waddch(win, boxchar | ACS_LRCORNER);	    else if (!i)		(void) waddch(win, borderchar | ACS_HLINE);	    else if (i == height - 1)		(void) waddch(win, boxchar | ACS_HLINE);	    else if (!j)		(void) waddch(win, borderchar | ACS_VLINE);	    else if (j == width - 1)		(void) waddch(win, boxchar | ACS_VLINE);	    else		(void) waddch(win, boxchar | ' ');    }    wattrset(win, save);}#ifdef HAVE_COLOR/* * Draw shadows along the right and bottom edge to give a more 3D look * to the boxes */voiddlg_draw_shadow(WINDOW *win, int y, int x, int height, int width){    int i, j;    if (has_colors()) {		/* Whether terminal supports color? */	wattrset(win, shadow_attr);	for (i = y + height; i < y + height + SHADOW_ROWS; ++i) {	    (void) wmove(win, i, x + SHADOW_COLS);	    for (j = 0; j < width; ++j)		(void) waddch(win, CharOf(winch(win)));	}	for (i = y + SHADOW_ROWS; i < y + height + SHADOW_ROWS; i++) {	    (void) wmove(win, i, x + width);	    for (j = 0; j < SHADOW_COLS; ++j)		(void) waddch(win, CharOf(winch(win)));	}	(void) wnoutrefresh(win);    }}#endif/* * Allow shell scripts to remap the exit codes so they can distinguish ESC * from ERROR. */voiddlg_exit(int code){    /* *INDENT-OFF* */    static const struct {	int code;	const char *name;    } table[] = {	{ DLG_EXIT_CANCEL, "DIALOG_CANCEL" },	{ DLG_EXIT_ERROR,  "DIALOG_ERROR" },	{ DLG_EXIT_ESC,	   "DIALOG_ESC" },	{ DLG_EXIT_EXTRA,  "DIALOG_EXTRA" },	{ DLG_EXIT_HELP,   "DIALOG_HELP" },	{ DLG_EXIT_OK,	   "DIALOG_OK" },    };    /* *INDENT-ON* */    unsigned n;    char *name;    char *temp;    long value;    for (n = 0; n < sizeof(table) / sizeof(table[0]); n++) {	if (table[n].code == code) {	    if ((name = getenv(table[n].name)) != 0) {		value = strtol(name, &temp, 0);		if (temp != 0 && temp != name && *temp == '\0')		    code = value;	    }	    break;	}    }    exit(code);}/* quit program killing all tailbg */voiddlg_exiterr(const char *fmt,...){    int retval;    va_list ap;    end_dialog();    (void) fputc('\n', stderr);    va_start(ap, fmt);    (void) vfprintf(stderr, fmt, ap);    va_end(ap);    (void) fputc('\n', stderr);    dlg_killall_bg(&retval);    (void) fflush(stderr);    (void) fflush(stdout);    dlg_exit(DLG_EXIT_ERROR);}voiddlg_beeping(void){    if (dialog_vars.beep_signal) {	(void) beep();	dialog_vars.beep_signal = 0;    }}voiddlg_print_size(int height, int width){    if (dialog_vars.print_siz)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -