void erase_arrow( void) { int line = INDEX_TOP + currmenu->curr - currmenu->first; if (!currmenu->max) return; MoveCursor(line, 0); if (tinrc.draw_arrow) my_fputs(" ", stdout); else { #ifdef USE_CURSES char buffer[BUFSIZ]; char *s = screen_contents(line, 0, buffer); #else char *s; if (line - INDEX_TOP < 0) /* avoid underruns */ line = INDEX_TOP; s = screen[line - INDEX_TOP].col; #endif /* USE_CURSES */ EndInverse(); my_fputs(s, stdout); if (s[MARK_OFFSET] == tinrc.art_marked_selected) { MoveCursor(line, MARK_OFFSET); StartInverse(); my_fputc(s[MARK_OFFSET], stdout); EndInverse(); } } }
void draw_arrow_mark( int line) { MoveCursor(line, 0); if (tinrc.draw_arrow) my_fputs("->", stdout); else { #ifdef USE_CURSES char buffer[BUFSIZ]; char *s = screen_contents(line, 0, buffer); #else char *s = screen[line - INDEX_TOP].col; #endif /* USE_CURSES */ StartInverse(); my_fputs(s, stdout); EndInverse(); if (s[MARK_OFFSET] == tinrc.art_marked_selected) { MoveCursor(line, MARK_OFFSET); EndInverse(); my_fputc(s[MARK_OFFSET], stdout); } } stow_cursor(); }
/* * Print a formatted message to stderr, no colour is added. * Interesting - this function implicitly clears 'errno' */ void error_message( const char *fmt, ...) { va_list ap; va_start(ap, fmt); errno = 0; clear_message(); vsnprintf(mesg, sizeof(mesg), fmt, ap); my_fputs(mesg, stderr); /* don't use my_fprintf() here due to %format chars */ my_fflush(stderr); if (cmd_line) { my_fputc('\n', stderr); fflush(stderr); } else { stow_cursor(); (void) sleep(2); clear_message(); } va_end(ap); }
/* * emit a newline, reset and redraw prompt and current input line */ static void gl_redraw( void) { if (gl_init_done == -1) { my_fputc('\n', stdout); my_fputs(gl_prompt, stdout); gl_pos = 0; gl_fixup(0, BUF_SIZE); } }
/* * Read .newsrc into my_group[]. my_group[] ints point to active[] entries. * If allgroups is set, then my_group[] is completely overwritten, * otherwise, groups are appended. Any bogus groups will be handled * accordingly. Bogus groups will _not_ be subscribed to as a design * principle. * * Returns the numer of lines read(useful for a check newsrc >= oldnewsrc) * < 0 error * >=0 number of lines read */ signed long int read_newsrc( char *newsrc_file, t_bool allgroups) { FILE *fp; char *grp, *seq; int sub, i; signed long line_count = 0; struct stat statbuf; if (allgroups) selmenu.max = skip_newgroups(); /* * make a .newsrc if one doesn't exist & auto subscribe to set groups */ if (stat(newsrc_file, &statbuf) == -1) { if (!create_newsrc(newsrc_file)) return -1L; /* ouch */ auto_subscribe_groups(newsrc_file); } else newsrc_mode = statbuf.st_mode; if ((fp = fopen(newsrc_file, "r")) != NULL) { if (!batch_mode || verbose) wait_message(0, _(txt_reading_newsrc)); while ((grp = tin_fgets(fp, FALSE)) != NULL) { seq = parse_newsrc_line(grp, &sub); line_count++; if (sub == SUBSCRIBED) { if ((i = my_group_add(grp)) >= 0) { if (!active[my_group[i]].bogus) { active[my_group[i]].subscribed = SUB_BOOL(sub); parse_bitmap_seq(&active[my_group[i]], seq); } } else process_bogus(grp); } } fclose(fp); /* If you aborted with 'q', then you get what you get. */ if (cmd_line) { my_fputc('\n', stdout); my_flush(); } } return line_count; }
void ring_bell( void) { #ifdef USE_CURSES if (!cmd_line) beep(); else { #endif /* USE_CURSES */ my_fputc('\007', stdout); my_flush(); #ifdef USE_CURSES } #endif /* USE_CURSES */ }
_ssize_t _write_r ( struct _reent *r, int file, const void *ptr, size_t len) { size_t todo; const unsigned char *p; todo = len; p = ptr; for( ; todo != 0; todo--) { my_fputc(*p++, stdout); } return (_ssize_t)len; /* Number of bytes written. */ }
char * tin_getline( const char *prompt, int number_only, /* 1=positive numbers only, 2=negative too */ const char *str, int max_chars, t_bool passwd, int which_hist) { int c, i, loc, tmp, gl_max; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wint_t wc; #else char *buf = gl_buf; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ is_passwd = passwd; set_xclick_off(); if (prompt == NULL) prompt = ""; gl_buf[0] = 0; /* used as end of input indicator */ gl_fixup(-1, 0); /* this resets gl_fixup */ gl_width = cCOLS - strlen(prompt); gl_prompt = prompt; gl_pos = gl_cnt = 0; if (max_chars == 0) { if (number_only) gl_max = 6; else gl_max = BUF_SIZE; } else gl_max = max_chars; my_fputs(prompt, stdout); cursoron(); my_flush(); if (gl_in_hook) { loc = gl_in_hook(gl_buf); if (loc >= 0) gl_fixup(0, BUF_SIZE); } if (!cmd_line && gl_max == BUF_SIZE) CleartoEOLN(); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if (str != NULL) { wchar_t wbuf[LEN]; if (mbstowcs(wbuf, str, ARRAY_SIZE(wbuf) - 1) != (size_t) -1) { wbuf[ARRAY_SIZE(wbuf) - 1] = (wchar_t) '\0'; for (i = 0; wbuf[i]; i++) gl_addwchar(wbuf[i]); } } while ((wc = ReadWch()) != WEOF) { if ((gl_cnt < gl_max) && iswprint(wc)) { if (number_only) { if (iswdigit(wc)) { gl_addwchar(wc); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && wc == (wint_t) '-') { gl_addwchar(wc); } else { ring_bell(); } } else gl_addwchar(wc); } else { c = (int) wc; switch (wc) { #else if (str != NULL) { for (i = 0; str[i]; i++) gl_addchar(str[i]); } while ((c = ReadCh()) != EOF) { c &= 0xff; if ((gl_cnt < gl_max) && my_isprint(c)) { if (number_only) { if (isdigit(c)) { gl_addchar(c); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && c == '-') { gl_addchar(c); } else { ring_bell(); } } else gl_addchar(c); } else { switch (c) { #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ case ESC: /* abort */ #ifdef HAVE_KEY_PREFIX case KEY_PREFIX: #endif /* HAVE_KEY_PREFIX */ switch (get_arrow_key(c)) { case KEYMAP_UP: case KEYMAP_PAGE_UP: hist_prev(which_hist); break; case KEYMAP_PAGE_DOWN: case KEYMAP_DOWN: hist_next(which_hist); break; case KEYMAP_RIGHT: gl_fixup(-1, gl_pos + 1); break; case KEYMAP_LEFT: gl_fixup(-1, gl_pos - 1); break; case KEYMAP_HOME: gl_fixup(-1, 0); break; case KEYMAP_END: gl_fixup(-1, gl_cnt); break; case KEYMAP_DEL: gl_del(0); break; case KEYMAP_INS: #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar((wint_t) ' '); #else gl_addchar(' '); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ break; default: return (char *) 0; } break; case '\n': /* newline */ case '\r': gl_newline(which_hist); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; case CTRL_A: gl_fixup(-1, 0); break; case CTRL_B: gl_fixup(-1, gl_pos - 1); break; case CTRL_D: if (gl_cnt == 0) { gl_buf[0] = 0; my_fputc('\n', stdout); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } else gl_del(0); break; case CTRL_E: gl_fixup(-1, gl_cnt); break; case CTRL_F: gl_fixup(-1, gl_pos + 1); break; case CTRL_H: case DEL: gl_del(-1); break; case TAB: if (gl_tab_hook) { tmp = gl_pos; loc = gl_tab_hook(gl_buf, strlen(gl_prompt), &tmp); if (loc >= 0 || tmp != gl_pos) gl_fixup(loc, tmp); } break; case CTRL_W: gl_kill_back_word(); break; case CTRL_U: gl_fixup(-1, 0); /* FALLTHROUGH */ case CTRL_K: gl_kill(); break; case CTRL_L: case CTRL_R: gl_redraw(); break; case CTRL_N: hist_next(which_hist); break; case CTRL_P: hist_prev(which_hist); break; default: ring_bell(); break; } } } #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } /* * adds the character c to the input buffer at current location if * the character is in the allowed template of characters */ static void #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar( wint_t wc) #else gl_addchar( int c) #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ { int i; /* * Crashing is always the worst solution IMHO. So as a quick hack, * ignore characters silently, if buffer is full. To allow a final * newline, leave space for one more character. Just a hack too. * This was the original code: * if (gl_cnt >= BUF_SIZE - 1) { error_message("tin_getline: input buffer overflow"); giveup(); } */ if (gl_cnt >= BUF_SIZE - 2) return; for (i = gl_cnt; i >= gl_pos; i--) gl_buf[i + 1] = gl_buf[i]; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[gl_pos] = (wchar_t) wc; #else gl_buf[gl_pos] = c; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ gl_fixup(gl_pos, gl_pos + 1); } /* * Cleans up entire line before returning to caller. A \n is appended. * If line longer than screen, we redraw starting at beginning */ static void gl_newline( int w) { int change = gl_cnt; int len = gl_cnt; int loc = gl_width - 5; /* shifts line back to start position */ if (gl_cnt >= BUF_SIZE - 1) { /* * Like above: avoid crashing if possible. gl_addchar() now * leaves one space left for the newline, so this part of the * code should never be reached. A proper implementation is * desirable though. */ error_message("tin_getline: input buffer overflow"); giveup(); } hist_add(w); /* only adds if nonblank */ if (gl_out_hook) { change = gl_out_hook(gl_buf); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) len = wcslen(gl_buf); #else len = strlen(gl_buf); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } if (loc > len) loc = len; gl_fixup(change, loc); /* must do this before appending \n */ #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[len] = (wchar_t) '\0'; #else gl_buf[len] = '\0'; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } /* * Delete a character. The loc variable can be: * -1 : delete character to left of cursor * 0 : delete character under cursor */ static void gl_del( int loc) { int i; if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) { for (i = gl_pos + loc; i < gl_cnt; i++) gl_buf[i] = gl_buf[i + 1]; gl_fixup(gl_pos + loc, gl_pos + loc); } else ring_bell(); }
/* * This function is used both for redrawing when input changes or for * moving within the input line. The parameters are: * change : the index of the start of changes in the input buffer, * with -1 indicating no changes. * cursor : the desired location of the cursor after the call. * A value of BUF_SIZE can be used to indicate the cursor * should move just past the end of the input line. */ static void gl_fixup( int change, int cursor) { static int gl_shift; /* index of first on screen character */ static int off_right; /* true if more text right of screen */ static int off_left; /* true if more text left of screen */ int left = 0, right = -1; /* bounds for redraw */ int pad; /* how much to erase at end of line */ int backup; /* how far to backup before fixing */ int new_shift; /* value of shift based on cursor */ int extra; /* adjusts when shift (scroll) happens */ int i; if (change == -1 && cursor == 0 && gl_buf[0] == 0) { /* reset */ gl_shift = off_right = off_left = 0; return; } pad = (off_right) ? gl_width - 1 : gl_cnt - gl_shift; /* old length */ backup = gl_pos - gl_shift; if (change >= 0) { #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_cnt = wcslen(gl_buf); #else gl_cnt = strlen(gl_buf); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ if (change > gl_cnt) change = gl_cnt; } if (cursor > gl_cnt) { if (cursor != BUF_SIZE) /* BUF_SIZE means end of line */ ring_bell(); cursor = gl_cnt; } if (cursor < 0) { ring_bell(); cursor = 0; } if (!is_passwd) { if (off_right || (off_left && (cursor < gl_shift + gl_width - SCROLL / 2))) extra = 2; /* shift the scrolling boundary */ else extra = 0; new_shift = cursor + extra + SCROLL - gl_width; if (new_shift > 0) { new_shift /= SCROLL; new_shift *= SCROLL; } else new_shift = 0; if (new_shift != gl_shift) { /* scroll occurs */ gl_shift = new_shift; off_left = (gl_shift) ? 1 : 0; off_right = (gl_cnt > gl_shift + gl_width - 1) ? 1 : 0; left = gl_shift; right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt; } else if (change >= 0) { /* no scroll, but text changed */ if (change < gl_shift + off_left) left = gl_shift; else { left = change; backup = gl_pos - change; } off_right = (gl_cnt > gl_shift + gl_width - 1) ? 1 : 0; right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt; } pad -= (off_right) ? gl_width - 1 : gl_cnt - gl_shift; pad = (pad < 0) ? 0 : pad; if (left <= right) { /* clean up screen */ for (i = 0; i < backup; i++) my_fputc('\b', stdout); if (left == gl_shift && off_left) { my_fputc('$', stdout); left++; } for (i = left; i < right; i++) { #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) my_fputwc((wint_t) gl_buf[i], stdout); #else my_fputc(gl_buf[i], stdout); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } if (off_right) { my_fputc('$', stdout); gl_pos = right + 1; } else { for (i = 0; i < pad; i++) /* erase remains of prev line */ my_fputc(' ', stdout); gl_pos = right + pad; } } i = gl_pos - cursor; /* move to final cursor location */ if (i > 0) { while (i--) my_fputc('\b', stdout); } else { for (i = gl_pos; i < cursor; i++) { #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) my_fputwc((wint_t) gl_buf[i], stdout); #else my_fputc(gl_buf[i], stdout); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } } my_flush(); } gl_pos = cursor; }