diff --git a/cgdb/cgdbrc.c b/cgdb/cgdbrc.c index 8a01b5b0..6f0722a2 100644 --- a/cgdb/cgdbrc.c +++ b/cgdb/cgdbrc.c @@ -47,6 +47,7 @@ enum ConfigType { static int command_set_arrowstyle(const char *value); static int command_set_cgdb_mode_key(const char *value); static int command_set_winsplit(const char *value); +static int command_set_splitorientation(const char *value); static int command_set_timeout(int value); static int command_set_timeoutlen(int value); static int command_set_ttimeout(int value); @@ -74,6 +75,7 @@ static struct cgdbrc_config_option cgdbrc_config_options[CGDBRC_WRAPSCAN + 1] = {CGDBRC_TTIMEOUT_LEN, {100}}, {CGDBRC_WINMINHEIGHT, {0}}, {CGDBRC_WINSPLIT, {WIN_SPLIT_EVEN}}, + {CGDBRC_SPLITORIENTATION, {SPLIT_HORIZONTAL}}, {CGDBRC_WRAPSCAN, {1}} }; @@ -136,6 +138,10 @@ static struct ConfigVariable { /* winsplit */ { "winsplit", "winsplit", CONFIG_TYPE_FUNC_STRING, command_set_winsplit}, + /* splitorientation */ + { + "splitorientation", "so", CONFIG_TYPE_FUNC_STRING, + command_set_splitorientation}, /* wrapscan */ { "wrapscan", "ws", CONFIG_TYPE_BOOL, @@ -334,6 +340,26 @@ int command_set_winsplit(const char *value) return 0; } +int command_set_splitorientation(const char *value) +{ + struct cgdbrc_config_option option; + SPLIT_ORIENTATION_TYPE orientation = SPLIT_HORIZONTAL; + + option.option_kind = CGDBRC_SPLITORIENTATION; + + if (strcasecmp(value, "horizontal") == 0) + orientation = SPLIT_HORIZONTAL; + else if (strcasecmp(value, "vertical") == 0) + orientation = SPLIT_VERTICAL; + + option.variant.win_orientation_val = orientation; + if (cgdbrc_set_val(option)) + return 1; + if_set_splitorientation(orientation); + + return 0; +} + static int command_set_winminheight(int value) { struct cgdbrc_config_option option; diff --git a/cgdb/cgdbrc.h b/cgdb/cgdbrc.h index bac90bba..6c98743e 100644 --- a/cgdb/cgdbrc.h +++ b/cgdb/cgdbrc.h @@ -99,6 +99,16 @@ typedef enum { WIN_SPLIT_FREE = -3, /* split point not on quarter mark */ WIN_SPLIT_TOP_FULL = 2 /* src window is 100% of screen */ } WIN_SPLIT_TYPE; +/** window split orientation type enumeration + * + * SPLIT_VERTICAL and SPLIT_HORIZONTAL refer to the orientation + * of the split between the source and GDB windows. + */ +typedef enum { + SPLIT_HORIZONTAL = 0, /* source above and GDB below (default) */ + SPLIT_VERTICAL = 1 /* source left and GDB right */ +} SPLIT_ORIENTATION_TYPE; + /** All of the different configuration options */ enum cgdbrc_option_kind { CGDBRC_ARROWSTYLE, @@ -114,6 +124,7 @@ enum cgdbrc_option_kind { CGDBRC_TTIMEOUT_LEN, CGDBRC_WINMINHEIGHT, CGDBRC_WINSPLIT, + CGDBRC_SPLITORIENTATION, CGDBRC_WRAPSCAN }; @@ -139,6 +150,8 @@ struct cgdbrc_config_option { enum tokenizer_language_support language_support_val; /* option_kind == CGDBRC_WINSPLIT */ WIN_SPLIT_TYPE win_split_val; + /* option_kind == CGDBRC_WINORIENTATION */ + SPLIT_ORIENTATION_TYPE win_orientation_val; } variant; }; diff --git a/cgdb/interface.c b/cgdb/interface.c index d0f37acc..0838a87a 100644 --- a/cgdb/interface.c +++ b/cgdb/interface.c @@ -82,7 +82,7 @@ extern struct tgdb *tgdb; static int interface_winminheight = 0; /* The offset that determines allows gdb/sources window to grow or shrink */ -static int window_height_shift; +static int window_shift; /* This is for the tty I/O window */ #define TTY_WIN_DEFAULT_HEIGHT ((interface_winminheight>4)?interface_winminheight:4) @@ -96,6 +96,7 @@ static int tty_win_height_shift = 0; /* Current window split state */ WIN_SPLIT_TYPE cur_win_split = WIN_SPLIT_EVEN; +SPLIT_ORIENTATION_TYPE cur_split_orientation = SPLIT_HORIZONTAL; /* --------------- */ /* Local Variables */ @@ -187,13 +188,19 @@ static int get_src_col(void) return 0; } +static int get_src_status_height(void); + static int get_src_height(void) { - return ((int) (((screen_size.ws_row + 0.5) / 2) + window_height_shift)); + if (cur_split_orientation == SPLIT_HORIZONTAL) + return ((int) (((screen_size.ws_row + 0.5) / 2) + window_shift)); + return (screen_size.ws_row) - get_src_status_height(); } static int get_src_width(void) { + if (cur_split_orientation == SPLIT_VERTICAL) + return ((int) (((screen_size.ws_col + 0.5) / 2) + window_shift)); return (screen_size.ws_col); } @@ -207,7 +214,7 @@ static int get_src_status_row(void) static int get_src_status_col(void) { - return 0; + return get_src_col();; } static int get_src_status_height(void) @@ -217,17 +224,42 @@ static int get_src_status_height(void) static int get_src_status_width(void) { - return (screen_size.ws_col); + return get_src_width(); +} + +/* These are for the separator line in horizontal split mode */ +static int get_sep_row(void) +{ + return 0; +} + +static int get_sep_col(void) +{ + return get_src_col() + get_src_width(); +} + +static int get_sep_height(void) +{ + return (screen_size.ws_row); +} + +static int get_sep_width(void) +{ + return 1; } /* This is for the tty I/O window */ static int get_tty_row(void) { - return get_src_status_row() + get_src_status_height(); + if (cur_split_orientation == SPLIT_HORIZONTAL) + return get_src_status_row() + get_src_status_height(); + return 0; } static int get_tty_col(void) { + if (cur_split_orientation == SPLIT_VERTICAL) + return get_sep_col() + get_sep_width(); return 0; } @@ -236,8 +268,12 @@ static int get_tty_height(void) return TTY_WIN_OFFSET; } +static int get_gdb_width(void); + static int get_tty_width(void) { + if (cur_split_orientation == SPLIT_VERTICAL) + return get_gdb_width(); return (screen_size.ws_col); } @@ -249,7 +285,7 @@ static int get_tty_status_row(void) static int get_tty_status_col(void) { - return 0; + return get_tty_col(); } static int get_tty_status_height(void) @@ -259,7 +295,7 @@ static int get_tty_status_height(void) static int get_tty_status_width(void) { - return (screen_size.ws_col); + return get_tty_width(); } /* This is for the debugger window */ @@ -268,30 +304,59 @@ static int get_gdb_row(void) if (tty_win_on) return get_tty_status_row() + get_tty_status_height(); - return get_src_status_row() + get_src_status_height(); + if (cur_split_orientation == SPLIT_HORIZONTAL) + return get_src_status_row() + get_src_status_height(); + + return 0; } static int get_gdb_col(void) { + if (cur_split_orientation == SPLIT_VERTICAL) + return get_sep_col() + get_sep_width(); return 0; } int get_gdb_height(void) { - int window_size = ((screen_size.ws_row / 2) - window_height_shift - 1); - int odd_screen_size = (screen_size.ws_row % 2); + if (cur_split_orientation == SPLIT_HORIZONTAL) { + int window_size = ((screen_size.ws_row / 2) - window_shift - 1); + int odd_screen_size = (screen_size.ws_row % 2); - if (tty_win_on) - return window_size - TTY_WIN_OFFSET + odd_screen_size - 1; + if (tty_win_on) + return window_size - TTY_WIN_OFFSET + odd_screen_size - 1; - return window_size + odd_screen_size; + return window_size + odd_screen_size; + } + + return (screen_size.ws_row) - (tty_win_on ? TTY_WIN_OFFSET + 1 : 0); } static int get_gdb_width(void) { + if (cur_split_orientation == SPLIT_VERTICAL) { + int window_size = ((screen_size.ws_col / 2) - window_shift - 1); + int odd_screen_size = (screen_size.ws_col % 2); + + return window_size + odd_screen_size; + } + return (screen_size.ws_col); } +static void separator_display() +{ + int col = get_sep_col(); + int row = get_sep_row(); + int last_row = row + get_sep_height(); + + for (; row < last_row; ++row) { + wmove(stdscr, row, col); + waddch(stdscr, VERT_LINE); + wrefresh(stdscr); + } +} + /* --------------------------------------- * Below is the core body of the interface * --------------------------------------- */ @@ -431,6 +496,9 @@ void if_draw(void) if (get_src_height() > 0) source_display(src_win, focus == CGDB); + if (cur_split_orientation == SPLIT_VERTICAL) + separator_display(); + if (tty_win_on && get_tty_height() > 0) scr_refresh(tty_win, focus == TTY); @@ -454,22 +522,25 @@ void if_draw(void) */ static void validate_window_sizes(void) { - int tty_window_offset = (tty_win_on) ? TTY_WIN_OFFSET + 1 : 0; - int odd_height = (HEIGHT + 1) % 2; - int max_window_height_shift = (HEIGHT / 2) - tty_window_offset - odd_height; - int min_window_height_shift = -(HEIGHT / 2); + int h_or_w = cur_split_orientation == SPLIT_HORIZONTAL ? HEIGHT : WIDTH; + int tty_window_offset = (tty_win_on + && cur_split_orientation == SPLIT_HORIZONTAL) + ? TTY_WIN_OFFSET + 1 : 0; + int odd_size = (h_or_w + 1) % 2; + int max_window_size_shift = (h_or_w / 2) - tty_window_offset - odd_size; + int min_window_size_shift = -(h_or_w / 2); /* update max and min based off of users winminheight request */ - min_window_height_shift += interface_winminheight; - max_window_height_shift -= interface_winminheight; + min_window_size_shift += interface_winminheight; + max_window_size_shift -= interface_winminheight; /* Make sure that the windows offset is within its bounds: * This checks the window offset. * */ - if (window_height_shift > max_window_height_shift) - window_height_shift = max_window_height_shift; - else if (window_height_shift < min_window_height_shift) - window_height_shift = min_window_height_shift; + if (window_shift > max_window_size_shift) + window_shift = max_window_size_shift; + else if (window_shift < min_window_size_shift) + window_shift = min_window_size_shift; } /* if_layout: Update the layout of the screen based on current terminal size. @@ -588,7 +659,7 @@ int if_resize_term(void) 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_window_height_shift = window_shift; int old_tty_win_height_shift = tty_win_height_shift; if (jump_or_tty) { @@ -606,10 +677,10 @@ static void increase_win_height(int jump_or_tty) /* 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; + cur_win_split = (int) (2 * window_shift) / height; /* handle rounding on either side of mid-way mark */ - if (window_height_shift > 0) { + if (window_shift > 0) { cur_win_split++; } } else { @@ -623,17 +694,17 @@ static void increase_win_height(int jump_or_tty) } /* set window height to specified quarter mark */ - window_height_shift = (int) (height * (cur_win_split / 2.0)); + window_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 */ + window_shift++; /* increase src window size by 1 */ } /* reduce flicker by avoiding unnecessary redraws */ - if (window_height_shift != old_window_height_shift || + if (window_shift != old_window_height_shift || tty_win_height_shift != old_tty_win_height_shift) { if_layout(); } @@ -651,7 +722,7 @@ static void increase_win_height(int jump_or_tty) static void decrease_win_height(int jump_or_tty) { int height = HEIGHT / 2; - int old_window_height_shift = window_height_shift; + int old_window_height_shift = window_shift; int old_tty_win_height_shift = tty_win_height_shift; if (jump_or_tty) { @@ -667,10 +738,10 @@ static void decrease_win_height(int jump_or_tty) /* 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; + cur_win_split = (int) (2 * window_shift) / height; /* handle rounding on either side of mid-way mark */ - if (window_height_shift < 0) { + if (window_shift < 0) { cur_win_split--; } } else { @@ -684,17 +755,17 @@ static void decrease_win_height(int jump_or_tty) } /* set window height to specified quarter mark */ - window_height_shift = (int) (height * (cur_win_split / 2.0)); + window_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--; /* decrease src window size by 1 */ + window_shift--; /* decrease src window size by 1 */ } /* reduce flicker by avoiding unnecessary redraws */ - if (window_height_shift != old_window_height_shift || + if (window_shift != old_window_height_shift || tty_win_height_shift != old_tty_win_height_shift) { if_layout(); } @@ -1054,7 +1125,7 @@ static void source_input(struct sviewer *sview, int key) case CGDB_KEY_CTRL_F: /* VI-style page down */ source_vscroll(sview, get_src_height() - 1); break; - case 'g': /* beggining of file */ + case 'g': /* beginning of file */ if (last_key_pressed == 'g') source_set_sel_line(sview, 1); break; @@ -1180,7 +1251,7 @@ int if_init(void) return 5; /* Set up window layout */ - window_height_shift = (int) ((HEIGHT / 2) * (cur_win_split / 2.0)); + window_shift = (int) ((HEIGHT / 2) * (cur_win_split / 2.0)); switch (if_layout()) { case 2: return 4; @@ -1284,6 +1355,15 @@ int internal_if_input(int key) if_layout(); } + break; + case CGDB_KEY_CTRL_W: + if (cur_split_orientation == SPLIT_HORIZONTAL) + cur_split_orientation = SPLIT_VERTICAL; + else + cur_split_orientation = SPLIT_HORIZONTAL; + + if_layout(); + break; case CGDB_KEY_F1: if_display_help(); @@ -1535,11 +1615,24 @@ Focus if_get_focus(void) return focus; } +void reset_window_shift(void) +{ + int h_or_w = cur_split_orientation == SPLIT_HORIZONTAL ? HEIGHT : WIDTH; + + window_shift = (int) ((h_or_w / 2) * (cur_win_split / 2.0)); + if_layout(); +} + +void if_set_splitorientation(SPLIT_ORIENTATION_TYPE new_orientation) +{ + cur_split_orientation = new_orientation; + reset_window_shift(); +} + void if_set_winsplit(WIN_SPLIT_TYPE new_split) { cur_win_split = new_split; - window_height_shift = (int) ((HEIGHT / 2) * (cur_win_split / 2.0)); - if_layout(); + reset_window_shift(); } void if_highlight_sviewer(enum tokenizer_language_support l) diff --git a/cgdb/interface.h b/cgdb/interface.h index 3a6903b3..4de71f0a 100644 --- a/cgdb/interface.h +++ b/cgdb/interface.h @@ -163,6 +163,11 @@ void if_tty_toggle(void); */ void if_draw(void); + /* if_set_winorientation: + * ________________ + */ +void if_set_splitorientation(SPLIT_ORIENTATION_TYPE newOrientation); + /* if_set_winsplit: * ________________ */ diff --git a/doc/cgdb.texinfo b/doc/cgdb.texinfo index d4160d03..33ec71b6 100644 --- a/doc/cgdb.texinfo +++ b/doc/cgdb.texinfo @@ -351,6 +351,9 @@ Opens a window to give input to the debugged program. @item Ctrl-T Opens a new tty for the debugged program. +@item Ctrl-W +Toggle the window orientation (horizontal <-> vertical). + @item k @itemx up arrow Move up a line. @@ -409,10 +412,10 @@ Sets a breakpoint at the current line number. Sets a temporary breakpoint at the current line number. @item - -Shrink source window 1 line. +Shrink source window 1 line or column (depending on split orientation). @item = -Grow source window 1 line. +Grow source window 1 line or column (depending on split orientation). @item _ Shrink source window 25% (or, shrink tty window 1 line, if visible). @@ -678,6 +681,13 @@ as an init setting in your @file{cgdbrc} file. @xref{Configuring CGDB}. The possible values for @var{style} are @samp{top_full}, @samp{top_big}, @samp{even}, @samp{bottom_big}, and @samp{bottom_full}. +@item :set so=@var{style} +@itemx :set splitorientation=@var{style} +Sets the window split orientation to either @samp{horizontal} (which places the +source window above and the GDB window below), or @samp{vertical} (which places the +source window on the left and the GDB window on the right). +@xref{Configuring CGDB}. + @item :set ws @itemx :set wrapscan Searches wrap around the end of file. The default is on.