/* Print the part of the cursor row before the cursor. */ void dumb_show_prompt(bool show_cursor, char line_type) { int i; show_line_prefix(show_cursor ? cursor_row : -1, line_type); if (show_cursor) for (i = 0; i < cursor_col; i++) show_cell(dumb_row(cursor_row)[i]); }
/* Print a row to stdout. */ static void show_row(int r) { if (r == -1) { show_line_prefix(-1, '.'); } else { int c, last; show_line_prefix(r, (r == cursor_row) ? ']' : ' '); /* Don't print spaces at end of line. */ /* (Saves bandwidth and printhead wear.) */ /* TODO: compress spaces to tabs. */ for (last = h_screen_cols - 1; last >= 0; last--) if (!will_print_blank(dumb_row(r)[last])) break; for (c = 0; c <= last; c++) show_cell(dumb_row(r)[c]); } putchar('\n'); }
void create_status_window( void ) { if ( status_size > dumb_status_max ) dumb_status_max = status_size; if ( status_size > dumb_status_size ) { /* If expanding, blank out new lines. */ memset( dumb_row( dumb_status_size ), ' ', ( status_size - dumb_status_size ) * screen_cols ); } dumb_status_size = status_size; } /* create_status_window */
void display_char( int c ) { if ( c == '\a' ) { outc( '\a' ); return; } if ( status_mode ) { if ( c == '\n' ) { status_col = 0; status_row++; } else dumb_row( status_row )[status_col++] = c; } else { dumb_prompt[text_col++] = c; } } /* display_char */
/* Show the current screen contents, or what's changed since the last * call. * * If compressing, and show_cursor is true, and the cursor is past the * last nonblank character on the last line that would be shown, then * don't show that line (because it will be redundant with the prompt * line just below it). */ void dumb_show_screen(bool show_cursor) { int r, c, first, last; char changed_rows[0x100]; /* Easy case */ if (compression_mode == COMPRESSION_NONE) { for (r = hide_lines; r < h_screen_rows; r++) show_row(r); mark_all_unchanged(); return; } /* Check which rows changed, and where the first and last change is. */ first = last = -1; memset(changed_rows, 0, h_screen_rows); for (r = hide_lines; r < h_screen_rows; r++) { for (c = 0; c < h_screen_cols; c++) if (dumb_changes_row(r)[c] && !is_blank(dumb_row(r)[c])) break; changed_rows[r] = (c != h_screen_cols); if (changed_rows[r]) { first = (first != -1) ? first : r; last = r; } } if (first == -1) return; /* The show_cursor rule described above */ if (show_cursor && (cursor_row == last)) { for (c = cursor_col; c < h_screen_cols; c++) if (!is_blank(dumb_row(last)[c])) break; if (c == h_screen_cols) last--; } /* Display the appropriate rows. */ if (compression_mode == COMPRESSION_MAX) { for (r = first; r <= last; r++) if (changed_rows[r]) show_row(r); } else { /* COMPRESSION_SPANS */ for (r = first; r <= last; r++) { if (changed_rows[r] || changed_rows[r + 1]) show_row(r); else { while (!changed_rows[r + 1]) r++; show_row(-1); } } if (show_cursor && (cursor_row > last + 1)) show_row((cursor_row == last + 2) ? (last + 1) : -1); } mark_all_unchanged(); }
void dumb_display_user_input(char *s) { /* copy to screen without marking it as a change. */ while (*s) dumb_row(cursor_row)[cursor_col++] = make_cell(0, *s++); }
/* Copy a cell and copy its changedness state. * This is used for scrolling. */ static void dumb_copy_cell(int dest_row, int dest_col, int src_row, int src_col) { dumb_row(dest_row)[dest_col] = dumb_row(src_row)[src_col]; dumb_changes_row(dest_row)[dest_col] = dumb_changes_row(src_row)[src_col]; }
/* Set a cell and update screen_changes. */ static void dumb_set_cell(int row, int col, cell c) { dumb_changes_row(row)[col] = (c != dumb_row(row)[col]); dumb_row(row)[col] = c; }
static char *dumb_row_copy( int r ) { return strncpy( dumb_old_row( r ), dumb_row( r ), screen_cols ); }
static int dumb_row_changed( int r ) { return ( strncmp( dumb_row( r ), dumb_old_row( r ), screen_cols ) != 0 ); }
/* Print status line and prompt for input. */ static void prompt_flush( void ) { int r, c, display_status_size, start, end; display_status_size = ( dumb_status_max == 0 ) ? status_size : dumb_status_max; dumb_status_max = 0; switch ( status_compression ) { case COMPRESSION_SPAN: /* Find first and last change. */ for ( start = 0; start < display_status_size; start++ ) if ( dumb_row_changed( start ) ) break; for ( end = display_status_size - 1; end >= 0; end-- ) if ( dumb_row_changed( end ) ) break; /* If status window grew, consider the new lines (the bottom ones) as * changed. */ if ( display_status_size > last_display_status_size ) { end = display_status_size - 1; if ( start > last_display_status_size ) start = last_display_status_size; } break; case COMPRESSION_NONE: case COMPRESSION_CHANGED: start = 0; end = display_status_size - 1; break; } /* Display the appropriate region. */ for ( r = start; r <= end; r++ ) { if ( ( status_compression == COMPRESSION_CHANGED ) && ( r < last_display_status_size ) && ( !dumb_row_changed( r ) ) ) continue; dumb_row_copy( r ); print_status_prefix( r ); for ( c = 0; c < screen_cols; c++ ) { outc( dumb_row( r )[c] ); } print_status_suffix( r ); outc( '\n' ); } last_display_status_size = display_status_size; /* Choose a prompt. */ if ( status_mode ) { /* Use current line, up to the cursor, as our prompt. */ /* This is the Right Thing for Bureaucracy forms. */ print_status_prefix( r ); for ( c = 0; c < status_col; c++ ) { outc( dumb_row( status_row )[c] ); } } else { /* Show the text window prompt buffer. */ for ( c = 0; c < text_col; c++ ) { outc( dumb_prompt[c] ); } } }
void clear_line( ) { if ( status_mode ) memset( dumb_row( status_row ), ' ', screen_cols ); } /* clear_line */