/* Updates the status bar */ static void update_status_win(enum win_refresh dorefresh) { int pos; int attr; attr = hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR); /* Print white background */ swin_wattron(status_win, attr); for (pos = 0; pos < WIDTH; pos++) swin_mvwprintw(status_win, 0, pos, " "); /* Show the user which window is focused */ if (focus == GDB) swin_mvwprintw(status_win, 0, WIDTH - 1, "*"); else if (focus == CGDB || focus == CGDB_STATUS_BAR) swin_mvwprintw(status_win, 0, WIDTH - 1, " "); swin_wattroff(status_win, attr); /* Print the regex that the user is looking for Forward */ if (sbc_kind == SBC_REGEX && regex_direction_cur) { if_display_message("/", dorefresh, WIDTH - 1, "%s", ibuf_get(regex_cur)); swin_curs_set(1); } /* Regex backwards */ else if (sbc_kind == SBC_REGEX) { if_display_message("?", dorefresh, WIDTH - 1, "%s", ibuf_get(regex_cur)); swin_curs_set(1); } /* A colon command typed at the status bar */ else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { const char *command = ibuf_get(cur_sbc); if (!command) command = ""; if_display_message(":", dorefresh, WIDTH - 1, "%s", command); swin_curs_set(1); } /* Default: Current Filename */ else { /* Print filename */ const char *filename = source_current_file(src_viewer); if (filename) { if_display_message("", dorefresh, WIDTH - 1, "%s", filename); } } if (dorefresh == WIN_REFRESH) swin_wrefresh(status_win); else swin_wnoutrefresh(status_win); }
void if_display_message(const char *msg, enum win_refresh dorefresh, int width, const char *fmt, ...) { va_list ap; char va_buf[MAXLINE]; char buf_display[MAXLINE]; int pos, error_length, length; int attr; attr = hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR); swin_curs_set(0); if (!width) width = WIDTH; /* Get the buffer with format */ va_start(ap, fmt); #ifdef HAVE_VSNPRINTF vsnprintf(va_buf, sizeof (va_buf), fmt, ap); /* this is safe */ #else vsprintf(va_buf, fmt, ap); /* this is not safe */ #endif va_end(ap); error_length = strlen(msg); length = strlen(va_buf); if (error_length > width) strcat(strncpy(buf_display, msg, width - 1), ">"); else if (error_length + length > width) snprintf(buf_display, sizeof(buf_display), "%s>%s", msg, va_buf + (length - (width - error_length) + 1)); else snprintf(buf_display, sizeof(buf_display), "%s%s", msg, va_buf); /* Print white background */ swin_wattron(status_win, attr); for (pos = 0; pos < WIDTH; pos++) swin_mvwprintw(status_win, 0, pos, " "); swin_mvwprintw(status_win, 0, 0, "%s", buf_display); swin_wattroff(status_win, attr); if (dorefresh == WIN_REFRESH) swin_wrefresh(status_win); else swin_wnoutrefresh(status_win); }
void filedlg_display_message(struct filedlg *fd, char *message) { int height, width, i; int attr; if (hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR, &attr) == -1) return; getmaxyx(fd->win, height, width); /* Print white background */ wattron(fd->win, attr); for (i = 0; i < width; i++) mvwprintw(fd->win, height - 1, i, " "); mvwprintw(fd->win, height - 1, 0, "%s", message); wattroff(fd->win, attr); wrefresh(fd->win); }
void filedlg_display_message(struct filedlg *fd, char *message) { int height, width, i; int attr; attr = hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR); height = swin_getmaxy(fd->win); width = swin_getmaxx(fd->win); /* Print white background */ swin_wattron(fd->win, attr); for (i = 0; i < width; i++) swin_mvwprintw(fd->win, height - 1, i, " "); swin_mvwprintw(fd->win, height - 1, 0, "%s", message); swin_wattroff(fd->win, attr); swin_wrefresh(fd->win); }
int filedlg_display(struct filedlg *fd) { char fmt[5]; int width, height; int lwidth; int file; int i; int attr; static char *label = "Select a file or press q to cancel."; curs_set(0); /* Check that a file is loaded */ if (fd == NULL || fd->buf == NULL || fd->buf->files == NULL) { wrefresh(fd->win); return 0; } /* Initialize variables */ getmaxyx(fd->win, height, width); /* The status bar and display line * Fake the display function to think the height is 2 lines less */ height -= 2; /* Set starting line number (center source file if it's small enough) */ if (fd->buf->length < height) file = (fd->buf->length - height) / 2; else { file = fd->buf->sel_line - height / 2; if (file > fd->buf->length - height) file = fd->buf->length - height; else if (file < 0) file = 0; } /* Print 'height' lines of the file, starting at 'file' */ lwidth = (int) log10(fd->buf->length) + 1; sprintf(fmt, "%%%dd", lwidth); print_in_middle(fd->win, 0, width, label); wmove(fd->win, 0, 0); for (i = 1; i < height + 1; i++, file++) { wmove(fd->win, i, 0); if (has_colors()) { /* Outside of filename, just finish drawing the vertical file */ if (file < 0 || file >= fd->buf->length) { int j; for (j = 1; j < lwidth; j++) waddch(fd->win, ' '); waddch(fd->win, '~'); wattron(fd->win, A_BOLD); waddch(fd->win, VERT_LINE); wattroff(fd->win, A_BOLD); for (j = 2 + lwidth; j < width; j++) waddch(fd->win, ' '); } /* Mark the current file with an arrow */ else if (file == fd->buf->sel_line) { wattron(fd->win, A_BOLD); wprintw(fd->win, fmt, file + 1); wattroff(fd->win, A_BOLD); if (hl_groups_get_attr(hl_groups_instance, HLG_ARROW, &attr) == -1) return -1; wattron(fd->win, attr); waddch(fd->win, '-'); waddch(fd->win, '>'); wattroff(fd->win, attr); if (fd->buf->cur_line != NULL) hl_wprintw(fd->win, fd->buf->cur_line, width - lwidth - 2, fd->buf->sel_col); else hl_wprintw(fd->win, fd->buf->files[file], width - lwidth - 2, fd->buf->sel_col); } /* Ordinary file */ else { wprintw(fd->win, fmt, file + 1); wattron(fd->win, A_BOLD); waddch(fd->win, VERT_LINE); wattroff(fd->win, A_BOLD); waddch(fd->win, ' '); /* No special file information */ if (file == fd->buf->sel_line && fd->buf->cur_line != NULL) hl_wprintw(fd->win, fd->buf->cur_line, width - lwidth - 2, fd->buf->sel_col); else hl_wprintw(fd->win, fd->buf->files[file], width - lwidth - 2, fd->buf->sel_col); } } else { wprintw(fd->win, "%s\n", fd->buf->files[file]); } } /* Add the 2 lines back in so the status bar can be drawn */ height += 2; /* Update status bar */ wmove(fd->win, height, 0); /* Print white background */ if (hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR, &attr) == -1) return -1; wattron(fd->win, attr); for (i = 0; i < width; i++) mvwprintw(fd->win, height - 1, i, " "); if (regex_search && regex_direction) mvwprintw(fd->win, height - 1, 0, "Search:%s", regex_line); else if (regex_search) mvwprintw(fd->win, height - 1, 0, "RSearch:%s", regex_line); wattroff(fd->win, attr); wmove(fd->win, height - (file - fd->buf->sel_line) - 1, lwidth + 2); wrefresh(fd->win); return 0; }
/** * Display the source. * * A line in the source viewer looks like, * # │ marker text * where, * # is the line number to display or ~ if no line number * │ is the divider between the line number or it is a mark * marker is shortarrow, longarrow, highlight, block, etc * text is the source code to display * * The syntax highlighting works as follows, * * The # * - If breakpoint is set, use Breakpoint * - If breakpoint is disabled, use DisabledBreakpoint * - If selected line, use SelectedLineNr * - If executing line, use ExecutingLineNr * - Otherwise, no highlighting group * * The │ * - When source window is in focus, the character is bolded, otherwise normal * - If the user has a mark set, the mark will be displayed instead of any * other character. * - Edge case: When the marker is long or short arrow, CGDB prints ├ * instead of │ the ├ is colored based on highlighting group for * the selected or executing arrow. * * The marker * - The marker is the shortarrow, longarrow, highlight or block * - The color is based off the corresponding highlighting group * * The text * - The syntax highlighting source code to display * - Will be colored with SelectedLineHighlight or ExecutingLineHighlight * if the line is the selected or executing line and the display is set * to highlight. */ int source_display(struct sviewer *sview, int focus, enum win_refresh dorefresh) { int i; int lwidth; int line; int count; enum LineDisplayStyle exe_display_style, sel_display_style; int sellineno, exelineno; int enabled_bp, disabled_bp; int exe_line_display_is_arrow, sel_line_display_is_arrow; int exe_arrow_attr, sel_arrow_attr; int exe_block_attr, sel_block_attr; char fmt[16]; int width, height; int focus_attr = focus ? SWIN_A_BOLD : 0; int showmarks = cgdbrc_get_int(CGDBRC_SHOWMARKS); int hlsearch = cgdbrc_get_int(CGDBRC_HLSEARCH); int mark_attr; struct hl_line_attr *sel_highlight_attrs = 0; struct hl_line_attr *exe_highlight_attrs = 0; /* Check that a file is loaded */ if (!sview->cur || !sview->cur->file_buf.lines) { logo_display(sview->win); if (dorefresh == WIN_REFRESH) swin_wrefresh(sview->win); else swin_wnoutrefresh(sview->win); return 0; } sellineno = hl_groups_get_attr( hl_groups_instance, HLG_SELECTED_LINE_NUMBER); exelineno = hl_groups_get_attr( hl_groups_instance, HLG_EXECUTING_LINE_NUMBER); enabled_bp = hl_groups_get_attr( hl_groups_instance, HLG_ENABLED_BREAKPOINT); disabled_bp = hl_groups_get_attr( hl_groups_instance, HLG_DISABLED_BREAKPOINT); exe_display_style = cgdbrc_get_displaystyle(CGDBRC_EXECUTING_LINE_DISPLAY); exe_arrow_attr = hl_groups_get_attr( hl_groups_instance, HLG_EXECUTING_LINE_ARROW); exe_block_attr = hl_groups_get_attr( hl_groups_instance, HLG_EXECUTING_LINE_BLOCK); sel_display_style = cgdbrc_get_displaystyle(CGDBRC_SELECTED_LINE_DISPLAY); sel_arrow_attr = hl_groups_get_attr( hl_groups_instance, HLG_SELECTED_LINE_ARROW); sel_block_attr = hl_groups_get_attr( hl_groups_instance, HLG_SELECTED_LINE_BLOCK); exe_line_display_is_arrow = exe_display_style == LINE_DISPLAY_SHORT_ARROW || exe_display_style == LINE_DISPLAY_LONG_ARROW; sel_line_display_is_arrow = sel_display_style == LINE_DISPLAY_SHORT_ARROW || sel_display_style == LINE_DISPLAY_LONG_ARROW; mark_attr = hl_groups_get_attr(hl_groups_instance, HLG_MARK); sbpush(sel_highlight_attrs, hl_line_attr(0, HLG_SELECTED_LINE_HIGHLIGHT)); sbpush(exe_highlight_attrs, hl_line_attr(0, HLG_EXECUTING_LINE_HIGHLIGHT)); /* Make sure cursor is visible */ swin_curs_set(!!focus); /* Initialize variables */ height = swin_getmaxy(sview->win); width = swin_getmaxx(sview->win); /* Set starting line number (center source file if it's small enough) */ count = sbcount(sview->cur->file_buf.lines); if (count < height) { line = (count - height) / 2; } else { line = sview->cur->sel_line - height / 2; if (line > count - height) line = count - height; else if (line < 0) line = 0; } /* Print 'height' lines of the file, starting at 'line' */ lwidth = log10_uint(count) + 1; snprintf(fmt, sizeof(fmt), "%%%dd", lwidth); for (i = 0; i < height; i++, line++) { int column_offset = 0; /* Is this the current selected line? */ int is_sel_line = (line >= 0 && sview->cur->sel_line == line); /* Is this the current executing line */ int is_exe_line = (line >= 0 && sview->cur->exe_line == line); struct source_line *sline = (line < 0 || line >= count)? NULL:&sview->cur->file_buf.lines[line]; struct hl_line_attr *printline_attrs = (sline)?sline->attrs:0; swin_wmove(sview->win, i, 0); /* Print the line number */ if (line < 0 || line >= count) { for (int j = 1; j < lwidth; j++) swin_waddch(sview->win, ' '); swin_waddch(sview->win, '~'); } else { int line_attr = 0; int bp_val = sview->cur->lflags[line].breakpt; if (bp_val == 1) { line_attr = enabled_bp; } else if (bp_val == 2) { line_attr = disabled_bp; } else if (bp_val == 0 && is_exe_line) { line_attr = exelineno; } else if (bp_val == 0 && is_sel_line) { line_attr = sellineno; } swin_wattron(sview->win, line_attr); swin_wprintw(sview->win, fmt, line + 1); swin_wattroff(sview->win, line_attr); } if (!swin_has_colors()) { /* TODO: swin_wprintw(sview->win, "%.*s\n", sview->cur->file_buf.lines[line].line, sview->cur->file_buf.lines[line].len); */ continue; } /* Print the vertical bar or mark */ { SWIN_CHTYPE vert_bar_char; int vert_bar_attr; int mc; if (showmarks && ((mc = source_get_mark_char(sview, sview->cur, line)) > 0)) { vert_bar_char = mc; vert_bar_attr = mark_attr; } else if (is_exe_line && exe_line_display_is_arrow) { vert_bar_attr = exe_arrow_attr; vert_bar_char = SWIN_SYM_LTEE; } else if (is_sel_line && sel_line_display_is_arrow) { vert_bar_attr = sel_arrow_attr; vert_bar_char = SWIN_SYM_LTEE; } else { vert_bar_attr = focus_attr; vert_bar_char = SWIN_SYM_VLINE; } swin_wattron(sview->win, vert_bar_attr); swin_waddch(sview->win, vert_bar_char); swin_wattroff(sview->win, vert_bar_attr); } /* Print the marker */ if (is_exe_line || is_sel_line) { enum LineDisplayStyle display_style; int arrow_attr, block_attr; struct hl_line_attr *highlight_attr; if (is_exe_line) { display_style = exe_display_style; arrow_attr = exe_arrow_attr; block_attr = exe_block_attr; highlight_attr = exe_highlight_attrs; } else { display_style = sel_display_style; arrow_attr = sel_arrow_attr; block_attr = sel_block_attr; highlight_attr = sel_highlight_attrs; } switch (display_style) { case LINE_DISPLAY_SHORT_ARROW: swin_wattron(sview->win, arrow_attr); swin_waddch(sview->win, '>'); swin_wattroff(sview->win, arrow_attr); break; case LINE_DISPLAY_LONG_ARROW: swin_wattron(sview->win, arrow_attr); column_offset = get_line_leading_ws_count( sline->line, sline->len); column_offset -= (sview->cur->sel_col + 1); if (column_offset < 0) column_offset = 0; /* Now actually draw the arrow */ for (int j = 0; j < column_offset; j++) swin_waddch(sview->win, SWIN_SYM_HLINE); swin_waddch(sview->win, '>'); swin_wattroff(sview->win, arrow_attr); break; case LINE_DISPLAY_HIGHLIGHT: swin_waddch(sview->win, ' '); printline_attrs = highlight_attr; break; case LINE_DISPLAY_BLOCK: column_offset = get_line_leading_ws_count( sline->line, sline->len); column_offset -= (sview->cur->sel_col + 1); if (column_offset < 0) column_offset = 0; /* Now actually draw the space to the block */ for (int j = 0; j < column_offset; j++) swin_waddch(sview->win, ' '); /* Draw the block */ swin_wattron(sview->win, block_attr); swin_waddch(sview->win, ' '); swin_wattroff(sview->win, block_attr); break; } } else { swin_waddch(sview->win, ' '); } /* Print the text */ if (line < 0 || line >= count) { for (int j = 2 + lwidth; j < width; j++) swin_waddch(sview->win, ' '); } else { int x, y; y = swin_getcury(sview->win); x = swin_getcurx(sview->win); hl_printline(sview->win, sline->line, sline->len, printline_attrs, -1, -1, sview->cur->sel_col + column_offset, width - lwidth - 2); if (hlsearch && sview->last_hlregex) { struct hl_line_attr *attrs = hl_regex_highlight( &sview->last_hlregex, sline->line, HLG_SEARCH); if (sbcount(attrs)) { hl_printline_highlight(sview->win, sline->line, sline->len, attrs, x, y, sview->cur->sel_col + column_offset, width - lwidth - 2); sbfree(attrs); } } if (is_sel_line && sview->hlregex) { struct hl_line_attr *attrs = hl_regex_highlight( &sview->hlregex, sline->line, HLG_INCSEARCH); if (sbcount(attrs)) { hl_printline_highlight(sview->win, sline->line, sline->len, attrs, x, y, sview->cur->sel_col + column_offset, width - lwidth - 2); sbfree(attrs); } } } } switch(dorefresh) { case WIN_NO_REFRESH: swin_wnoutrefresh(sview->win); break; case WIN_REFRESH: swin_wrefresh(sview->win); break; } sbfree(sel_highlight_attrs); sbfree(exe_highlight_attrs); return 0; }
/* Updates the status bar */ static void update_status_win(void) { int pos; char filename[FSUTIL_PATH_MAX]; int attr; if (hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR, &attr) == -1) return; /* Update the tty status bar */ if (tty_win_on) { wattron(tty_status_win, attr); for (pos = 0; pos < WIDTH; pos++) mvwprintw(tty_status_win, 0, pos, " "); mvwprintw(tty_status_win, 0, 0, (char *) tgdb_tty_name(tgdb)); wattroff(tty_status_win, attr); } /* Print white background */ wattron(status_win, attr); for (pos = 0; pos < WIDTH; pos++) mvwprintw(status_win, 0, pos, " "); if (tty_win_on) wattron(tty_status_win, attr); /* Show the user which window is focused */ if (focus == GDB) mvwprintw(status_win, 0, WIDTH - 1, "*"); else if (focus == TTY && tty_win_on) mvwprintw(tty_status_win, 0, WIDTH - 1, "*"); else if (focus == CGDB || focus == CGDB_STATUS_BAR) mvwprintw(status_win, 0, WIDTH - 1, " "); wattroff(status_win, attr); if (tty_win_on) wattroff(tty_status_win, attr); /* Print the regex that the user is looking for Forward */ if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX && regex_direction_cur) { if_display_message("/", WIDTH - 1, "%s", ibuf_get(regex_cur)); curs_set(1); } /* Regex backwards */ else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX) { if_display_message("?", WIDTH - 1, "%s", ibuf_get(regex_cur)); curs_set(1); } /* A colon command typed at the status bar */ else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { char *command = ibuf_get(cur_sbc); if (!command) command = ""; if_display_message(":", WIDTH - 1, "%s", command); curs_set(1); } /* Default: Current Filename */ else { /* Print filename */ if (src_win != NULL && source_current_file(src_win, filename) != NULL) if_display_message("", WIDTH - 1, "%s", filename); } wrefresh(status_win); }
void scr_refresh(struct scroller *scr, int focus, enum win_refresh dorefresh) { int length; /* Length of current line */ int nlines; /* Number of lines written so far */ int r; /* Current row in scroller */ int c; /* Current column in row */ int width, height; /* Width and height of window */ int highlight_attr; int hlsearch = cgdbrc_get_int(CGDBRC_HLSEARCH); int rows_to_display = 0; /* Steal line highlight attribute for our scroll mode status */ highlight_attr = hl_groups_get_attr(hl_groups_instance, HLG_SCROLL_MODE_STATUS); /* Sanity check */ height = swin_getmaxy(scr->win); width = swin_getmaxx(scr->win); if (scr->current.c > 0) { if (scr->current.c % width != 0) scr->current.c = (scr->current.c / width) * width; } r = scr->current.r; c = scr->current.c; rows_to_display = number_rows_to_display(scr, height, width); /** * Printing the scroller to the gdb window. * * The gdb window has a certain dimension (height and width). * The scroller has a certain number of rows to print. * * When starting cgdb, or when the user clears the screen with Ctrl-L, * the entire scroller buffer is not displayed in the gdb window. * * The gdb readline input will be displayed just below the last * line of output in the scroller. * * In order to display the scroller buffer, first determine how many * lines should be displayed. Then start drawing from the bottom of * the viewable space and work our way up. */ for (nlines = 1; nlines <= height; nlines++) { /* Empty lines below the scroller prompt should be empty. * When in scroller mode, there should be no empty lines on the * bottom. */ if (!scr->in_scroll_mode && nlines <= height - rows_to_display) { swin_wmove(scr->win, height - nlines, 0); swin_wclrtoeol(scr->win); } /* Print the current line [segment] */ else if (r >= 0) { struct scroller_line *sline = &scr->lines[r]; hl_printline(scr->win, sline->line, sline->line_len, sline->attrs, 0, height - nlines, c, width); /* If we're searching right now or we finished search * and have focus... */ if (hlsearch && scr->last_hlregex && focus) { struct hl_line_attr *attrs = hl_regex_highlight( &scr->last_hlregex, sline->line, HLG_SEARCH); if (sbcount(attrs)) { hl_printline_highlight(scr->win, sline->line, sline->line_len, attrs, 0, height - nlines, c, width); sbfree(attrs); } } if (scr->hlregex && scr->current.r == r) { struct hl_line_attr *attrs = hl_regex_highlight( &scr->hlregex, sline->line, HLG_INCSEARCH); if (sbcount(attrs)) { hl_printline_highlight(scr->win, sline->line, sline->line_len, attrs, 0, height - nlines, c, width); sbfree(attrs); } } /* Update our position */ if (c >= width) c -= width; else { r--; if (r >= 0) { length = scr->lines[r].line_len; if (length > width) c = ((length - 1) / width) * width; } } /* Empty lines above the first line in the scroller should be empty. * Since the scroller starts at the top, this should only occur when * in the scroll mode. */ } else { swin_wmove(scr->win, height - nlines, 0); swin_wclrtoeol(scr->win); } /* If we're in scroll mode and this is the top line, spew status on right */ if (scr->in_scroll_mode && (nlines == height)) { char status[ 64 ]; size_t status_len; snprintf(status, sizeof(status), "[%d/%d]", scr->current.r + 1, sbcount(scr->lines)); status_len = strlen(status); if ( status_len < width ) { swin_wattron(scr->win, highlight_attr); swin_mvwprintw(scr->win, height - nlines, width - status_len, "%s", status); swin_wattroff(scr->win, highlight_attr); } } } length = scr->lines[scr->current.r].line_len - scr->current.c; /* Only show the cursor when * - the scroller is in focus * - on the last line * - when it is within the width of the screen * - when not in scroller mode */ if (focus && scr->current.r == sbcount(scr->lines) - 1 && length <= width && !scr->in_scroll_mode) { swin_curs_set(1); swin_wmove(scr->win, rows_to_display-1, scr->current.pos % width); } else { /* Hide the cursor */ swin_curs_set(0); } switch(dorefresh) { case WIN_NO_REFRESH: swin_wnoutrefresh(scr->win); break; case WIN_REFRESH: swin_wrefresh(scr->win); break; } }
int filedlg_display(struct filedlg *fd) { char fmt[16]; int width, height; int lwidth; int file; int i; int statusbar; int arrow_attr; int count = sbcount(fd->buf->files); int hlsearch = cgdbrc_get_int(CGDBRC_HLSEARCH); static const char label[] = "Select a file or press q to cancel."; int inc_search_attr = hl_groups_get_attr(hl_groups_instance, HLG_INCSEARCH); int search_attr = hl_groups_get_attr(hl_groups_instance, HLG_SEARCH); swin_curs_set(0); statusbar = hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR); arrow_attr = hl_groups_get_attr(hl_groups_instance, HLG_SELECTED_LINE_ARROW); /* Check that a file is loaded */ if (fd == NULL || fd->buf == NULL || fd->buf->files == NULL) { swin_wrefresh(fd->win); return 0; } /* Initialize variables */ height = swin_getmaxy(fd->win); width = swin_getmaxx(fd->win); /* The status bar and display line * Fake the display function to think the height is 2 lines less */ height -= 2; /* Set starting line number (center source file if it's small enough) */ if (count < height) file = (count - height) / 2; else { file = fd->buf->sel_line - height / 2; if (file > count - height) file = count - height; else if (file < 0) file = 0; } /* Print 'height' lines of the file, starting at 'file' */ lwidth = log10_uint(count) + 1; snprintf(fmt, sizeof(fmt), "%%%dd", lwidth); print_in_middle(fd->win, 0, width, label); swin_wmove(fd->win, 0, 0); for (i = 1; i < height + 1; i++, file++) { swin_wmove(fd->win, i, 0); /* Outside of filename, just finish drawing the vertical file */ if (file < 0 || file >= count) { int j; for (j = 1; j < lwidth; j++) swin_waddch(fd->win, ' '); swin_waddch(fd->win, '~'); swin_wattron(fd->win, SWIN_A_BOLD); swin_waddch(fd->win, SWIN_SYM_VLINE); swin_wattroff(fd->win, SWIN_A_BOLD); for (j = 2 + lwidth; j < width; j++) swin_waddch(fd->win, ' '); continue; } int x, y; char *filename = fd->buf->files[file]; /* Mark the current file with an arrow */ if (file == fd->buf->sel_line) { swin_wattron(fd->win, SWIN_A_BOLD); swin_wprintw(fd->win, fmt, file + 1); swin_wattroff(fd->win, SWIN_A_BOLD); swin_wattron(fd->win, arrow_attr); swin_waddch(fd->win, '-'); swin_waddch(fd->win, '>'); swin_wattroff(fd->win, arrow_attr); } else { /* Ordinary file */ swin_wprintw(fd->win, fmt, file + 1); swin_wattron(fd->win, SWIN_A_BOLD); swin_waddch(fd->win, SWIN_SYM_VLINE); swin_wattroff(fd->win, SWIN_A_BOLD); swin_waddch(fd->win, ' '); } y = swin_getcury(fd->win); x = swin_getcurx(fd->win); hl_printline(fd->win, filename, strlen(filename), NULL, -1, -1, fd->buf->sel_col, width - lwidth - 2); if (hlsearch && fd->last_hlregex) { struct hl_line_attr *attrs = hl_regex_highlight( &fd->last_hlregex, filename, search_attr); if (sbcount(attrs)) { hl_printline_highlight(fd->win, filename, strlen(filename), attrs, x, y, fd->buf->sel_col, width - lwidth - 2); sbfree(attrs); } } if (regex_search && file == fd->buf->sel_line) { struct hl_line_attr *attrs = hl_regex_highlight( &fd->hlregex, filename, inc_search_attr); if (sbcount(attrs)) { hl_printline_highlight(fd->win, filename, strlen(filename), attrs, x, y, fd->buf->sel_col, width - lwidth - 2); sbfree(attrs); } } } /* Add the 2 lines back in so the status bar can be drawn */ height += 2; /* Update status bar */ swin_wmove(fd->win, height, 0); /* Print white background */ swin_wattron(fd->win, statusbar); for (i = 0; i < width; i++) swin_mvwprintw(fd->win, height - 1, i, " "); if (regex_search && regex_direction) swin_mvwprintw(fd->win, height - 1, 0, "Search:%s", regex_line); else if (regex_search) swin_mvwprintw(fd->win, height - 1, 0, "RSearch:%s", regex_line); swin_wattroff(fd->win, statusbar); swin_wmove(fd->win, height - (file - fd->buf->sel_line) - 1, lwidth + 2); swin_wrefresh(fd->win); return 0; }
void hl_wprintw(WINDOW * win, const char *line, int width, int offset, int line_highlight_attr) { int length; /* Length of the line passed in */ enum hl_group_kind color; /* Color used to print current char */ int i; /* Loops through the line char by char */ int j; /* General iterator */ int p; /* Count of chars printed to screen */ int pad; /* Used to pad partial tabs */ int attr; /* A temp variable used for attributes */ int highlight_tabstop = cgdbrc_get_int(CGDBRC_TABSTOP); /* Jump ahead to the character at offset (process color commands too) */ length = strlen(line); color = HLG_TEXT; for (i = 0, j = 0; i < length && j < offset; i++) { if (line[i] == HL_CHAR && i + 1 < length) { /* Even though we're not printing anything in this loop, * the color attribute needs to be maintained for when we * start printing in the loop below. This way the text * printed will be done in the correct color. */ color = (enum hl_group_kind) line[++i]; } else if (line[i] == '\t') { /* Tab character, expand to size set by user */ j += highlight_tabstop - (j % highlight_tabstop); } else { /* Normal character, just increment counter by one */ j++; } } pad = j - offset; /* Pad tab spaces if offset is less than the size of a tab */ for (j = 0, p = 0; j < pad && p < width; j++, p++) wprintw(win, " "); /* Set the color - if we were given line_highlight, use that, otherwise load */ if (line_highlight_attr) attr = line_highlight_attr; else hl_groups_get_attr(hl_groups_instance, color, &attr); wattron(win, attr); /* Print string 1 char at a time */ for (; i < length && p < width; i++) { if (line[i] == HL_CHAR) { if (++i < length) { /* If we're highlight entire line, skip the line attributes */ if (!line_highlight_attr) { wattroff(win, attr); color = (enum hl_group_kind) line[i]; hl_groups_get_attr(hl_groups_instance, color, &attr); wattron(win, attr); } } } else { switch (line[i]) { case '\t': do { wprintw(win, " "); p++; } while ((p + offset) % highlight_tabstop > 0 && p < width); break; default: wprintw(win, "%c", line[i]); p++; } } } /* If we're highlighting line, draw spaces with attributes set */ if (!line_highlight_attr) wattroff(win, attr); for (; p < width; p++) wprintw(win, " "); /* Turn off attributes if we didn't earlier */ if (line_highlight_attr) wattroff(win, attr); }
void hl_wprintw(WINDOW *win, const char *line, int width, int offset) { int length; /* Length of the line passed in */ enum hl_group_kind color; /* Color used to print current char */ int i; /* Loops through the line char by char */ int j; /* General iterator */ int p; /* Count of chars printed to screen */ int pad; /* Used to pad partial tabs */ int attr; /* A temp variable used for attributes */ int highlight_tabstop = cgdbrc_get (CGDBRC_TABSTOP)->variant.int_val; /* Jump ahead to the character at offset (process color commands too) */ length = strlen(line); color = HLG_TEXT; for (i = 0, j = 0; i < length && j < offset; i++) { if (line[i] == HL_CHAR && i+1 < length) { /* Even though we're not printing anything in this loop, * the color attribute needs to be maintained for when we * start printing in the loop below. This way the text * printed will be done in the correct color. */ color = (int)line[++i]; } else if (line[i] == '\t') { /* Tab character, expand to size set by user */ j += highlight_tabstop - (j % highlight_tabstop); } else { /* Normal character, just increment counter by one */ j++; } } pad = j - offset; /* Pad tab spaces if offset is less than the size of a tab */ for (j = 0, p = 0; j < pad && p < width; j++, p++) wprintw(win, " "); /* Set the color appropriately */ if (hl_groups_get_attr (hl_groups_instance, color, &attr) == -1) { logger_write_pos ( logger, __FILE__, __LINE__, "hl_groups_get_attr error"); return; } wattron(win, attr); /* Print string 1 char at a time */ for (; i < length && p < width; i++) { if (line[i] == HL_CHAR) { if (++i < length) { wattroff(win, attr); color = (int)line[i]; if (hl_groups_get_attr (hl_groups_instance, color, &attr) == -1) { logger_write_pos ( logger, __FILE__, __LINE__, "hl_groups_get_attr error"); return; } wattron(win, attr); } } else { switch (line[i]) { case '\t': do { wprintw(win, " "); p++; } while ((p+offset) % highlight_tabstop > 0 && p < width); break; default: wprintw(win, "%c", line[i]); p++; } } } /* Shut off color attribute */ wattroff(win, attr); for (; p < width; p++) wprintw(win, " "); }