/* if_draw: Draws the interface on the screen. * -------- */ void if_draw(void) { /* Only redisplay the filedlg if it is up */ if (focus == FILE_DLG) { filedlg_display(fd); return; } update_status_win(); if (get_src_height() != 0 && get_gdb_height() != 0) wrefresh(status_win); if (tty_win_on) wrefresh(tty_status_win); if (get_src_height() > 0) source_display(src_win, focus == CGDB); if (tty_win_on && get_tty_height() > 0) scr_refresh(tty_win, focus == TTY); if (get_gdb_height() > 0) scr_refresh(gdb_win, focus == GDB); /* This check is here so that the cursor goes to the * cgdb window. The cursor would stay in the gdb window * on cygwin */ if (get_src_height() > 0 && focus == CGDB) wrefresh(src_win->win); }
/* if_draw: Draws the interface on the screen. * -------- */ void if_draw(void) { if (!curses_initialized) return; /* Only redisplay the filedlg if it is up */ if (focus == FILE_DLG) { filedlg_display(fd); return; } update_status_win(WIN_NO_REFRESH); if (get_src_height() != 0 && get_gdb_height() != 0) swin_wnoutrefresh(status_win); if (get_src_height() > 0) source_display(src_viewer, focus == CGDB, WIN_NO_REFRESH); separator_display(cur_split_orientation == WSO_VERTICAL); if (get_gdb_height() > 0) scr_refresh(gdb_scroller, focus == GDB, WIN_NO_REFRESH); /* This check is here so that the cursor goes to the * cgdb window. The cursor would stay in the gdb window * on cygwin */ if (get_src_height() > 0 && focus == CGDB) swin_wnoutrefresh(src_viewer->win); swin_doupdate(); }
/* gdb_input: Handles user input to the GDB window. * ---------- * * key: Keystroke received. * * Return Value: 0 if internal key was used, * 1 if input to gdb or ... * -1 : Error resizing terminal -- terminal too small */ static int gdb_input(int key) { /* Handle special keys */ switch (key) { case CGDB_KEY_PPAGE: scr_up(gdb_win, get_gdb_height() - 1); break; case CGDB_KEY_NPAGE: scr_down(gdb_win, get_gdb_height() - 1); break; case CGDB_KEY_F11: scr_home(gdb_win); break; case CGDB_KEY_F12: scr_end(gdb_win); break; #if 0 /* I would like to add better support for control-l in the GDB * window, but this patch didn't make me happy enough to release it. * The problem is, when it clears the screen, it adds a lot of * whitespace in the buffer. If you hit page-up to look back in * the buffer, it's visible. This is really unacceptable. * * The approach I believe I would like to take with this, is to * have the GDB window behave more like the terminal. That is, * have GDB start at the top line, and move down as input * becomes available. Then, when you hit ctrl-l, you just move * the prompt to the top line. */ case CGDB_KEY_CTRL_L: { int height = get_gdb_height(), i; /* Allocate and print enough newlines to clear the gdb buffer. */ char *buf = (char *) cgdb_malloc(sizeof (char *) * height); for (i = 0; i < height - 1; ++i) { buf[i] = '\n'; } buf[i] = '\0'; if_print(buf); free(buf); /* Sneaky return 1 here. Basically, this allows tricks readline to think * that gdb did not handle the Ctrl-l. That way readline will also handle * it. Because readline uses TERM=dumb, that means that it will clear a * single line and put out the prompt. */ return 1; break; } #endif default: return 1; } if_draw(); return 0; }
/* if_layout: Update the layout of the screen based on current terminal size. * ---------- * * Return Value: Zero on success, non-zero on failure. */ static int if_layout() { /* Verify the window size is reasonable */ validate_window_sizes(); /* Initialize the GDB I/O window */ if (gdb_win == NULL) { gdb_win = scr_new(get_gdb_row(), get_gdb_col(), get_gdb_height(), get_gdb_width()); if (gdb_win == NULL) return 2; } else { /* Resize the GDB I/O window */ if (get_gdb_height() > 0) scr_move(gdb_win, get_gdb_row(), get_gdb_col(), get_gdb_height(), get_gdb_width()); } /* Initialize TTY I/O window */ if (tty_win == NULL) { tty_win = scr_new(get_tty_row(), get_tty_col(), get_tty_height(), get_tty_width()); if (tty_win == NULL) return 2; } else { /* Resize the GDB I/O window */ if (get_tty_height() > 0) scr_move(tty_win, get_tty_row(), get_tty_col(), get_tty_height(), get_tty_width()); } /* Initialize the source viewer window */ if (src_win == NULL) { src_win = source_new(get_src_row(), get_src_col(), get_src_height(), get_src_width()); if (src_win == NULL) return 3; } else { /* Resize the source viewer window */ if (get_src_height() > 0) source_move(src_win, get_src_row(), get_src_col(), get_src_height(), get_src_width()); } /* Initialize the status bar window */ status_win = newwin(get_src_status_height(), get_src_status_width(), get_src_status_row(), get_src_status_col()); /* Initialize the tty status bar window */ if (tty_win_on) tty_status_win = newwin(get_tty_status_height(), get_tty_status_width(), get_tty_status_row(), get_tty_status_col()); if_draw(); return 0; }
/* * increase_win_height: Increase size of source or tty window * ____________________ * * Param jump_or_tty - if 0, increase source window by 1 * if 1, if tty window is visible, increase it by 1 * else jump source window to next biggest quarter * */ static void increase_win_height(int jump_or_tty) { int height = (HEIGHT / 2) - ((tty_win_on) ? TTY_WIN_OFFSET + 1 : 0); int old_window_height_shift = window_height_shift; int old_tty_win_height_shift = tty_win_height_shift; if (jump_or_tty) { /* user input: '+' */ if (tty_win_on) { /* tty window is visible */ height = get_gdb_height() + get_tty_height(); if (tty_win_height_shift + TTY_WIN_DEFAULT_HEIGHT < height - interface_winminheight) { /* increase tty window size by 1 */ tty_win_height_shift++; } } else { /* no tty window */ if (cur_win_split == WIN_SPLIT_FREE) { /* cur position is not on mark, find nearest mark */ cur_win_split = (int) (2 * window_height_shift) / height; /* handle rounding on either side of mid-way mark */ if (window_height_shift > 0) { cur_win_split++; } } else { /* increase to next mark */ cur_win_split++; } /* check split bounds */ if (cur_win_split > WIN_SPLIT_TOP_FULL) { cur_win_split = WIN_SPLIT_TOP_FULL; } /* set window height to specified quarter mark */ window_height_shift = (int) (height * (cur_win_split / 2.0)); } } else { /* user input: '=' */ cur_win_split = WIN_SPLIT_FREE; /* cur split is not on a mark */ window_height_shift++; /* increase src window size by 1 */ } /* reduce flicker by avoiding unnecessary redraws */ if (window_height_shift != old_window_height_shift || tty_win_height_shift != old_tty_win_height_shift) { if_layout(); } }
void if_print(const char *buf) { /* Print it to the scroller */ scr_add(gdb_win, buf); if (get_gdb_height() > 0) { scr_refresh(gdb_win, focus == GDB); /* Make sure cursor reappears in source window if focus is there */ if (focus == CGDB) wrefresh(src_win->win); } }
void if_tty_print(const char *buf) { /* If the tty I/O window is not open send output to gdb window */ if (!tty_win_on) if_print(buf); /* Print it to the scroller */ scr_add(tty_win, buf); /* Only need to redraw if tty_win is being displayed */ if (tty_win_on && get_gdb_height() > 0) { scr_refresh(tty_win, focus == TTY); /* Make sure cursor reappears in source window if focus is there */ if (focus == CGDB) wrefresh(src_win->win); } }
static void if_print_internal(const char *buf, enum ScrInputKind kind) { if (!gdb_scroller) { clog_error(CLOG_CGDB, "%s", buf); return; } /* Print it to the scroller */ scr_add(gdb_scroller, buf, kind); if (get_gdb_height() > 0) { scr_refresh(gdb_scroller, focus == GDB, WIN_NO_REFRESH); /* Make sure cursor reappears in source window if focus is there */ if (focus == CGDB) swin_wnoutrefresh(src_viewer->win); swin_doupdate(); } }
/* if_layout: Update the layout of the screen based on current terminal size. * ---------- * * Return Value: Zero on success, -1 on failure. */ static int if_layout() { SWINDOW *gdb_scroller_win = NULL; SWINDOW *src_viewer_win = NULL; if (!curses_initialized) return -1; /* Verify the window size is reasonable */ validate_window_sizes(); /* Resize the source viewer window */ create_swindow(&src_viewer_win, get_src_height(), get_src_width(), get_src_row(), get_src_col()); if (src_viewer) { source_move(src_viewer, src_viewer_win); } else { src_viewer = source_new(src_viewer_win); } /* Resize the GDB I/O window */ create_swindow(&gdb_scroller_win, get_gdb_height(), get_gdb_width(), get_gdb_row(), get_gdb_col()); if (gdb_scroller) { scr_move(gdb_scroller, gdb_scroller_win); } else { gdb_scroller = scr_new(gdb_scroller_win); } /* Initialize the status bar window */ create_swindow(&status_win, get_src_status_height(), get_src_status_width(), get_src_status_row(), get_src_status_col()); /* Redraw the interface */ if_draw(); return 0; }
/** * The goal of this function is to display the tab completion information * to the user in an asychronous and potentially interactive manner. * * It will output to the screen as much as can be until user input is needed. * If user input is needed, then this function must stop, and wait until * that data has been recieved. * * If this function is called a second time with the same completion_ptr * parameter, it will continue outputting the tab completion data from * where it left off. * * \param completion_ptr * The tab completion data to output to the user * * \param key * The key the user wants to pass to the query command that was made. * If -1, then this is assummed to be the first time this function has been * called. * * \return * 0 on success or -1 on error */ static int handle_tab_completion_request(tab_completion_ptr comptr, int key) { int query_items; int gdb_window_size; if (!comptr) return -1; query_items = rline_get_rl_completion_query_items(rline); gdb_window_size = get_gdb_height(); if (comptr->state == TAB_COMPLETION_START) { if_print("\n"); if (query_items > 0 && comptr->num_matches >= query_items) { if_print_message("Display all %d possibilities? (y or n)\n", comptr->num_matches); comptr->state = TAB_COMPLETION_QUERY_POSSIBILITIES; return 0; } comptr->state = TAB_COMPLETION_COMPLETION_DISPLAY; } if (comptr->state == TAB_COMPLETION_QUERY_POSSIBILITIES) { int val = cgdb_get_y_or_n(key, 0); if (val == 1) comptr->state = TAB_COMPLETION_COMPLETION_DISPLAY; else if (val == 0) comptr->state = TAB_COMPLETION_DONE; else return 0; /* stay at the same state */ } if (comptr->state == TAB_COMPLETION_QUERY_PAGER) { int i = cgdb_get_y_or_n(key, 1); if_clear_line(); /* Clear the --More-- */ if (i == 0) comptr->state = TAB_COMPLETION_DONE; else if (i == 2) { comptr->lines--; comptr->state = TAB_COMPLETION_COMPLETION_DISPLAY; } else { comptr->lines = 0; comptr->state = TAB_COMPLETION_COMPLETION_DISPLAY; } } if (comptr->state == TAB_COMPLETION_COMPLETION_DISPLAY) { for (; comptr->total <= comptr->num_matches; comptr->total++) { if_print(comptr->matches[comptr->total]); if_print("\n"); comptr->lines++; if (comptr->lines >= (gdb_window_size - 1) && comptr->total < comptr->num_matches) { if_print("--More--"); comptr->state = TAB_COMPLETION_QUERY_PAGER; comptr->total++; return 0; } } comptr->state = TAB_COMPLETION_DONE; } if (comptr->state == TAB_COMPLETION_DONE) { tab_completion_destroy(completion_ptr); completion_ptr = NULL; is_tab_completing = 0; rline_rl_forced_update_display(rline); } return 0; }
/* gdb_input: Handles user input to the GDB window. * ---------- * * key: Keystroke received. * * Return Value: 0 if internal key was used, * 1 if input to gdb or ... * -1 : Error resizing terminal -- terminal too small */ static int gdb_input(int key, int *last_key) { int result = 0; if (gdb_scroller->in_search_mode) return gdb_input_regex_input(gdb_scroller, key); if (gdb_scroller->in_scroll_mode) { /* Handle setting (mX) and going ('X) to gdb buffer marks */ if (last_key_pressed == 'm' || last_key_pressed == '\'') { int ret = 0; if (last_key_pressed == 'm') ret = scr_set_mark(gdb_scroller, key); else if(last_key_pressed == '\'') ret = scr_goto_mark(gdb_scroller, key); if (ret) { *last_key = 0; if_draw(); } return 0; } /* In scroll mode, all extra characters are not passed to * the active GDB command. result = 0 above ensures that. */ switch (key) { case 'm': case '\'': /* Mark keys - ignore them */ break; case CGDB_KEY_CTRL_U: scr_up(gdb_scroller, get_gdb_height() / 2); break; case CGDB_KEY_PPAGE: scr_up(gdb_scroller, get_gdb_height() - 1); break; case CGDB_KEY_CTRL_D: scr_down(gdb_scroller, get_gdb_height() / 2); break; case CGDB_KEY_NPAGE: scr_down(gdb_scroller, get_gdb_height() - 1); break; case CGDB_KEY_HOME: case CGDB_KEY_F11: scr_home(gdb_scroller); break; case 'G': case CGDB_KEY_END: case CGDB_KEY_F12: scr_end(gdb_scroller); break; case 'k': case CGDB_KEY_UP: case CGDB_KEY_CTRL_P: scr_up(gdb_scroller, 1); break; case 'j': case CGDB_KEY_DOWN: case CGDB_KEY_CTRL_N: scr_down(gdb_scroller, 1); break; case 'g': if (last_key_pressed == 'g') { scr_home(gdb_scroller); } break; case 'q': case 'i': case '\r': case '\n': case CGDB_KEY_CTRL_M: scr_end(gdb_scroller); gdb_scroller->in_scroll_mode = 0; break; case 'n': scr_search_regex(gdb_scroller, ibuf_get(regex_last), 2, regex_direction_last, cgdbrc_get_int(CGDBRC_IGNORECASE)); break; case 'N': scr_search_regex(gdb_scroller, ibuf_get(regex_last), 2, !regex_direction_last, cgdbrc_get_int(CGDBRC_IGNORECASE)); break; case '/': case '?': /* Capturing regular expressions */ regex_cur = ibuf_init(); regex_direction_cur = ('/' == key); orig_line_regex = gdb_scroller->current.r; sbc_kind = SBC_REGEX; scr_search_regex_init(gdb_scroller); break; } } else { switch (key) { case CGDB_KEY_PPAGE: scr_up(gdb_scroller, get_gdb_height() - 1); break; case CGDB_KEY_CTRL_L: scr_clear(gdb_scroller); /* The return 1 tells readline that gdb did not handle the * Ctrl-l. That way readline will handle it. Because * readline uses TERM=dumb, that means that it will clear * a single line and put out the prompt. */ result = 1; break; default: /* This tells the input to go to active GDB command */ result = 1; } } if_draw(); return result; }