]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/tui/tui-win.c
2004-02-07 Andrew Cagney <cagney@redhat.com>
[thirdparty/binutils-gdb.git] / gdb / tui / tui-win.c
1 /* TUI window generic functions.
2
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4 Foundation, Inc.
5
6 Contributed by Hewlett-Packard Company.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25 /* This module contains procedures for handling tui window functions
26 like resize, scrolling, scrolling, changing focus, etc.
27
28 Author: Susan B. Macchia */
29
30 #include "defs.h"
31 #include "command.h"
32 #include "symtab.h"
33 #include "breakpoint.h"
34 #include "frame.h"
35 #include "cli/cli-cmds.h"
36 #include "top.h"
37 #include "source.h"
38
39 #include "tui/tui.h"
40 #include "tui/tui-data.h"
41 #include "tui/tui-wingeneral.h"
42 #include "tui/tui-stack.h"
43 #include "tui/tui-regs.h"
44 #include "tui/tui-disasm.h"
45 #include "tui/tui-source.h"
46 #include "tui/tui-winsource.h"
47 #include "tui/tui-windata.h"
48
49 #ifdef HAVE_NCURSES_H
50 #include <ncurses.h>
51 #else
52 #ifdef HAVE_CURSES_H
53 #include <curses.h>
54 #endif
55 #endif
56
57 #include <string.h>
58 #include <ctype.h>
59 #include <readline/readline.h>
60
61 /*******************************
62 ** Static Local Decls
63 ********************************/
64 static void _makeVisibleWithNewHeight (struct tui_win_info *);
65 static void _makeInvisibleAndSetNewHeight (struct tui_win_info *, int);
66 static enum tui_status _tuiAdjustWinHeights (struct tui_win_info *, int);
67 static int _newHeightOk (struct tui_win_info *, int);
68 static void _tuiSetTabWidth_command (char *, int);
69 static void _tuiRefreshAll_command (char *, int);
70 static void _tuiSetWinHeight_command (char *, int);
71 static void _tuiXDBsetWinHeight_command (char *, int);
72 static void _tuiAllWindowsInfo (char *, int);
73 static void _tuiSetFocus_command (char *, int);
74 static void _tuiScrollForward_command (char *, int);
75 static void _tuiScrollBackward_command (char *, int);
76 static void _tuiScrollLeft_command (char *, int);
77 static void _tuiScrollRight_command (char *, int);
78 static void _parseScrollingArgs (char *, struct tui_win_info * *, int *);
79
80
81 /***************************************
82 ** DEFINITIONS
83 ***************************************/
84 #define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
85 #define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
86 #define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
87
88 /***************************************
89 ** PUBLIC FUNCTIONS
90 ***************************************/
91
92 #ifndef ACS_LRCORNER
93 # define ACS_LRCORNER '+'
94 #endif
95 #ifndef ACS_LLCORNER
96 # define ACS_LLCORNER '+'
97 #endif
98 #ifndef ACS_ULCORNER
99 # define ACS_ULCORNER '+'
100 #endif
101 #ifndef ACS_URCORNER
102 # define ACS_URCORNER '+'
103 #endif
104 #ifndef ACS_HLINE
105 # define ACS_HLINE '-'
106 #endif
107 #ifndef ACS_VLINE
108 # define ACS_VLINE '|'
109 #endif
110
111 /* Possible values for tui-border-kind variable. */
112 static const char *tui_border_kind_enums[] = {
113 "space",
114 "ascii",
115 "acs",
116 NULL
117 };
118
119 /* Possible values for tui-border-mode and tui-active-border-mode. */
120 static const char *tui_border_mode_enums[] = {
121 "normal",
122 "standout",
123 "reverse",
124 "half",
125 "half-standout",
126 "bold",
127 "bold-standout",
128 NULL
129 };
130
131 struct tui_translate
132 {
133 const char *name;
134 int value;
135 };
136
137 /* Translation table for border-mode variables.
138 The list of values must be terminated by a NULL.
139 After the NULL value, an entry defines the default. */
140 struct tui_translate tui_border_mode_translate[] = {
141 { "normal", A_NORMAL },
142 { "standout", A_STANDOUT },
143 { "reverse", A_REVERSE },
144 { "half", A_DIM },
145 { "half-standout", A_DIM | A_STANDOUT },
146 { "bold", A_BOLD },
147 { "bold-standout", A_BOLD | A_STANDOUT },
148 { 0, 0 },
149 { "normal", A_NORMAL }
150 };
151
152 /* Translation tables for border-kind, one for each border
153 character (see wborder, border curses operations).
154 -1 is used to indicate the ACS because ACS characters
155 are determined at run time by curses (depends on terminal). */
156 struct tui_translate tui_border_kind_translate_vline[] = {
157 { "space", ' ' },
158 { "ascii", '|' },
159 { "acs", -1 },
160 { 0, 0 },
161 { "ascii", '|' }
162 };
163
164 struct tui_translate tui_border_kind_translate_hline[] = {
165 { "space", ' ' },
166 { "ascii", '-' },
167 { "acs", -1 },
168 { 0, 0 },
169 { "ascii", '-' }
170 };
171
172 struct tui_translate tui_border_kind_translate_ulcorner[] = {
173 { "space", ' ' },
174 { "ascii", '+' },
175 { "acs", -1 },
176 { 0, 0 },
177 { "ascii", '+' }
178 };
179
180 struct tui_translate tui_border_kind_translate_urcorner[] = {
181 { "space", ' ' },
182 { "ascii", '+' },
183 { "acs", -1 },
184 { 0, 0 },
185 { "ascii", '+' }
186 };
187
188 struct tui_translate tui_border_kind_translate_llcorner[] = {
189 { "space", ' ' },
190 { "ascii", '+' },
191 { "acs", -1 },
192 { 0, 0 },
193 { "ascii", '+' }
194 };
195
196 struct tui_translate tui_border_kind_translate_lrcorner[] = {
197 { "space", ' ' },
198 { "ascii", '+' },
199 { "acs", -1 },
200 { 0, 0 },
201 { "ascii", '+' }
202 };
203
204
205 /* Tui configuration variables controlled with set/show command. */
206 const char *tui_active_border_mode = "bold-standout";
207 const char *tui_border_mode = "normal";
208 const char *tui_border_kind = "acs";
209
210 /* Tui internal configuration variables. These variables are
211 updated by tui_update_variables to reflect the tui configuration
212 variables. */
213 chtype tui_border_vline;
214 chtype tui_border_hline;
215 chtype tui_border_ulcorner;
216 chtype tui_border_urcorner;
217 chtype tui_border_llcorner;
218 chtype tui_border_lrcorner;
219
220 int tui_border_attrs;
221 int tui_active_border_attrs;
222
223 /* Identify the item in the translation table.
224 When the item is not recognized, use the default entry. */
225 static struct tui_translate *
226 translate (const char *name, struct tui_translate *table)
227 {
228 while (table->name)
229 {
230 if (name && strcmp (table->name, name) == 0)
231 return table;
232 table++;
233 }
234
235 /* Not found, return default entry. */
236 table++;
237 return table;
238 }
239
240 /* Update the tui internal configuration according to gdb settings.
241 Returns 1 if the configuration has changed and the screen should
242 be redrawn. */
243 int
244 tui_update_variables ()
245 {
246 int need_redraw = 0;
247 struct tui_translate *entry;
248
249 entry = translate (tui_border_mode, tui_border_mode_translate);
250 if (tui_border_attrs != entry->value)
251 {
252 tui_border_attrs = entry->value;
253 need_redraw = 1;
254 }
255 entry = translate (tui_active_border_mode, tui_border_mode_translate);
256 if (tui_active_border_attrs != entry->value)
257 {
258 tui_active_border_attrs = entry->value;
259 need_redraw = 1;
260 }
261
262 /* If one corner changes, all characters are changed.
263 Only check the first one. The ACS characters are determined at
264 run time by curses terminal management. */
265 entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner);
266 if (tui_border_lrcorner != (chtype) entry->value)
267 {
268 tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value;
269 need_redraw = 1;
270 }
271 entry = translate (tui_border_kind, tui_border_kind_translate_llcorner);
272 tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value;
273
274 entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner);
275 tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value;
276
277 entry = translate (tui_border_kind, tui_border_kind_translate_urcorner);
278 tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value;
279
280 entry = translate (tui_border_kind, tui_border_kind_translate_hline);
281 tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value;
282
283 entry = translate (tui_border_kind, tui_border_kind_translate_vline);
284 tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value;
285
286 return need_redraw;
287 }
288
289 static void
290 set_tui_cmd (char *args, int from_tty)
291 {
292 }
293
294 static void
295 show_tui_cmd (char *args, int from_tty)
296 {
297 }
298
299 /*
300 ** _initialize_tuiWin().
301 ** Function to initialize gdb commands, for tui window manipulation.
302 */
303 void
304 _initialize_tuiWin (void)
305 {
306 struct cmd_list_element *c;
307 static struct cmd_list_element *tui_setlist;
308 static struct cmd_list_element *tui_showlist;
309
310 /* Define the classes of commands.
311 They will appear in the help list in the reverse of this order. */
312 add_cmd ("tui", class_tui, NULL,
313 "Text User Interface commands.",
314 &cmdlist);
315
316 add_prefix_cmd ("tui", class_tui, set_tui_cmd,
317 "TUI configuration variables",
318 &tui_setlist, "set tui ",
319 0/*allow-unknown*/, &setlist);
320 add_prefix_cmd ("tui", class_tui, show_tui_cmd,
321 "TUI configuration variables",
322 &tui_showlist, "show tui ",
323 0/*allow-unknown*/, &showlist);
324
325 add_com ("refresh", class_tui, _tuiRefreshAll_command,
326 "Refresh the terminal display.\n");
327 if (xdb_commands)
328 add_com_alias ("U", "refresh", class_tui, 0);
329 add_com ("tabset", class_tui, _tuiSetTabWidth_command,
330 "Set the width (in characters) of tab stops.\n\
331 Usage: tabset <n>\n");
332 add_com ("winheight", class_tui, _tuiSetWinHeight_command,
333 "Set the height of a specified window.\n\
334 Usage: winheight <win_name> [+ | -] <#lines>\n\
335 Window names are:\n\
336 src : the source window\n\
337 cmd : the command window\n\
338 asm : the disassembly window\n\
339 regs : the register display\n");
340 add_com_alias ("wh", "winheight", class_tui, 0);
341 add_info ("win", _tuiAllWindowsInfo,
342 "List of all displayed windows.\n");
343 add_com ("focus", class_tui, _tuiSetFocus_command,
344 "Set focus to named window or next/prev window.\n\
345 Usage: focus {<win> | next | prev}\n\
346 Valid Window names are:\n\
347 src : the source window\n\
348 asm : the disassembly window\n\
349 regs : the register display\n\
350 cmd : the command window\n");
351 add_com_alias ("fs", "focus", class_tui, 0);
352 add_com ("+", class_tui, _tuiScrollForward_command,
353 "Scroll window forward.\nUsage: + [win] [n]\n");
354 add_com ("-", class_tui, _tuiScrollBackward_command,
355 "Scroll window backward.\nUsage: - [win] [n]\n");
356 add_com ("<", class_tui, _tuiScrollLeft_command,
357 "Scroll window forward.\nUsage: < [win] [n]\n");
358 add_com (">", class_tui, _tuiScrollRight_command,
359 "Scroll window backward.\nUsage: > [win] [n]\n");
360 if (xdb_commands)
361 add_com ("w", class_xdb, _tuiXDBsetWinHeight_command,
362 "XDB compatibility command for setting the height of a command window.\n\
363 Usage: w <#lines>\n");
364
365 /* Define the tui control variables. */
366 c = add_set_enum_cmd
367 ("border-kind", no_class,
368 tui_border_kind_enums, &tui_border_kind,
369 "Set the kind of border for TUI windows.\n"
370 "This variable controls the border of TUI windows:\n"
371 "space use a white space\n"
372 "ascii use ascii characters + - | for the border\n"
373 "acs use the Alternate Character Set\n",
374 &tui_setlist);
375 add_show_from_set (c, &tui_showlist);
376
377 c = add_set_enum_cmd
378 ("border-mode", no_class,
379 tui_border_mode_enums, &tui_border_mode,
380 "Set the attribute mode to use for the TUI window borders.\n"
381 "This variable controls the attributes to use for the window borders:\n"
382 "normal normal display\n"
383 "standout use highlight mode of terminal\n"
384 "reverse use reverse video mode\n"
385 "half use half bright\n"
386 "half-standout use half bright and standout mode\n"
387 "bold use extra bright or bold\n"
388 "bold-standout use extra bright or bold with standout mode\n",
389 &tui_setlist);
390 add_show_from_set (c, &tui_showlist);
391
392 c = add_set_enum_cmd
393 ("active-border-mode", no_class,
394 tui_border_mode_enums, &tui_active_border_mode,
395 "Set the attribute mode to use for the active TUI window border.\n"
396 "This variable controls the attributes to use for the active window border:\n"
397 "normal normal display\n"
398 "standout use highlight mode of terminal\n"
399 "reverse use reverse video mode\n"
400 "half use half bright\n"
401 "half-standout use half bright and standout mode\n"
402 "bold use extra bright or bold\n"
403 "bold-standout use extra bright or bold with standout mode\n",
404 &tui_setlist);
405 add_show_from_set (c, &tui_showlist);
406 }
407
408 /* Update gdb's knowledge of the terminal size. */
409 void
410 tui_update_gdb_sizes ()
411 {
412 char cmd[50];
413 int screenheight, screenwidth;
414
415 rl_get_screen_size (&screenheight, &screenwidth);
416 /* Set to TUI command window dimension or use readline values. */
417 sprintf (cmd, "set width %d",
418 tui_active ? TUI_CMD_WIN->generic.width : screenwidth);
419 execute_command (cmd, 0);
420 sprintf (cmd, "set height %d",
421 tui_active ? TUI_CMD_WIN->generic.height : screenheight);
422 execute_command (cmd, 0);
423 }
424
425
426 /* Set the logical focus to win_info. */
427 void
428 tui_set_win_focus_to (struct tui_win_info * win_info)
429 {
430 if (win_info != NULL)
431 {
432 struct tui_win_info * winWithFocus = tui_win_with_focus ();
433
434 if (winWithFocus != NULL
435 && winWithFocus->generic.type != CMD_WIN)
436 tui_unhighlight_win (winWithFocus);
437 tui_set_win_with_focus (win_info);
438 if (win_info->generic.type != CMD_WIN)
439 tui_highlight_win (win_info);
440 }
441
442 return;
443 } /* tuiSetWinFocusTo */
444
445
446 void
447 tui_scroll_forward (struct tui_win_info * winToScroll, int numToScroll)
448 {
449 if (winToScroll != TUI_CMD_WIN)
450 {
451 int _numToScroll = numToScroll;
452
453 if (numToScroll == 0)
454 _numToScroll = winToScroll->generic.height - 3;
455 /*
456 ** If we are scrolling the source or disassembly window, do a
457 ** "psuedo" scroll since not all of the source is in memory,
458 ** only what is in the viewport. If winToScroll is the
459 ** command window do nothing since the term should handle it.
460 */
461 if (winToScroll == TUI_SRC_WIN)
462 tui_vertical_source_scroll (FORWARD_SCROLL, _numToScroll);
463 else if (winToScroll == TUI_DISASM_WIN)
464 tui_vertical_disassem_scroll (FORWARD_SCROLL, _numToScroll);
465 else if (winToScroll == TUI_DATA_WIN)
466 tui_vertical_data_scroll (FORWARD_SCROLL, _numToScroll);
467 }
468 }
469
470 void
471 tui_scroll_backward (struct tui_win_info * winToScroll, int numToScroll)
472 {
473 if (winToScroll != TUI_CMD_WIN)
474 {
475 int _numToScroll = numToScroll;
476
477 if (numToScroll == 0)
478 _numToScroll = winToScroll->generic.height - 3;
479 /*
480 ** If we are scrolling the source or disassembly window, do a
481 ** "psuedo" scroll since not all of the source is in memory,
482 ** only what is in the viewport. If winToScroll is the
483 ** command window do nothing since the term should handle it.
484 */
485 if (winToScroll == TUI_SRC_WIN)
486 tui_vertical_source_scroll (BACKWARD_SCROLL, _numToScroll);
487 else if (winToScroll == TUI_DISASM_WIN)
488 tui_vertical_disassem_scroll (BACKWARD_SCROLL, _numToScroll);
489 else if (winToScroll == TUI_DATA_WIN)
490 tui_vertical_data_scroll (BACKWARD_SCROLL, _numToScroll);
491 }
492 }
493
494
495 void
496 tui_scroll_left (struct tui_win_info * winToScroll, int numToScroll)
497 {
498 if (winToScroll != TUI_CMD_WIN)
499 {
500 int _numToScroll = numToScroll;
501
502 if (_numToScroll == 0)
503 _numToScroll = 1;
504 /*
505 ** If we are scrolling the source or disassembly window, do a
506 ** "psuedo" scroll since not all of the source is in memory,
507 ** only what is in the viewport. If winToScroll is the
508 ** command window do nothing since the term should handle it.
509 */
510 if (winToScroll == TUI_SRC_WIN || winToScroll == TUI_DISASM_WIN)
511 tui_horizontal_source_scroll (winToScroll, LEFT_SCROLL, _numToScroll);
512 }
513 }
514
515
516 void
517 tui_scroll_right (struct tui_win_info * winToScroll, int numToScroll)
518 {
519 if (winToScroll != TUI_CMD_WIN)
520 {
521 int _numToScroll = numToScroll;
522
523 if (_numToScroll == 0)
524 _numToScroll = 1;
525 /*
526 ** If we are scrolling the source or disassembly window, do a
527 ** "psuedo" scroll since not all of the source is in memory,
528 ** only what is in the viewport. If winToScroll is the
529 ** command window do nothing since the term should handle it.
530 */
531 if (winToScroll == TUI_SRC_WIN || winToScroll == TUI_DISASM_WIN)
532 tui_horizontal_source_scroll (winToScroll, RIGHT_SCROLL, _numToScroll);
533 }
534 }
535
536
537 /* Scroll a window. Arguments are passed through a va_list. */
538 void
539 tui_scroll (enum tui_scroll_direction direction,
540 struct tui_win_info * winToScroll,
541 int numToScroll)
542 {
543 switch (direction)
544 {
545 case FORWARD_SCROLL:
546 tui_scroll_forward (winToScroll, numToScroll);
547 break;
548 case BACKWARD_SCROLL:
549 tui_scroll_backward (winToScroll, numToScroll);
550 break;
551 case LEFT_SCROLL:
552 tui_scroll_left (winToScroll, numToScroll);
553 break;
554 case RIGHT_SCROLL:
555 tui_scroll_right (winToScroll, numToScroll);
556 break;
557 default:
558 break;
559 }
560 }
561
562
563 void
564 tui_refresh_all_win (void)
565 {
566 enum tui_win_type type;
567
568 clearok (curscr, TRUE);
569 tui_refresh_all (tui_win_list);
570 for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
571 {
572 if (tui_win_list[type] && tui_win_list[type]->generic.is_visible)
573 {
574 switch (type)
575 {
576 case SRC_WIN:
577 case DISASSEM_WIN:
578 tui_show_source_content (tui_win_list[type]);
579 tui_check_and_display_highlight_if_needed (tui_win_list[type]);
580 tui_erase_exec_info_content (tui_win_list[type]);
581 tui_update_exec_info (tui_win_list[type]);
582 break;
583 case DATA_WIN:
584 tui_refresh_data_win ();
585 break;
586 default:
587 break;
588 }
589 }
590 }
591 tui_show_locator_content ();
592 }
593
594
595 /*
596 ** tuiResizeAll().
597 ** Resize all the windows based on the the terminal size. This
598 ** function gets called from within the readline sinwinch handler.
599 */
600 void
601 tuiResizeAll (void)
602 {
603 int heightDiff, widthDiff;
604 int screenheight, screenwidth;
605
606 rl_get_screen_size (&screenheight, &screenwidth);
607 widthDiff = screenwidth - tui_term_width ();
608 heightDiff = screenheight - tui_term_height ();
609 if (heightDiff || widthDiff)
610 {
611 enum tui_layout_type curLayout = tui_current_layout ();
612 struct tui_win_info * winWithFocus = tui_win_with_focus ();
613 struct tui_win_info *firstWin;
614 struct tui_win_info *secondWin;
615 struct tui_gen_win_info * locator = tui_locator_win_info_ptr ();
616 enum tui_win_type winType;
617 int newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
618
619 /* turn keypad off while we resize */
620 if (winWithFocus != TUI_CMD_WIN)
621 keypad (TUI_CMD_WIN->generic.handle, FALSE);
622 tui_update_gdb_sizes ();
623 tui_set_term_height_to (screenheight);
624 tui_set_term_width_to (screenwidth);
625 if (curLayout == SRC_DISASSEM_COMMAND ||
626 curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND)
627 numWinsDisplayed++;
628 splitDiff = heightDiff / numWinsDisplayed;
629 cmdSplitDiff = splitDiff;
630 if (heightDiff % numWinsDisplayed)
631 {
632 if (heightDiff < 0)
633 cmdSplitDiff--;
634 else
635 cmdSplitDiff++;
636 }
637 /* now adjust each window */
638 clear ();
639 refresh ();
640 switch (curLayout)
641 {
642 case SRC_COMMAND:
643 case DISASSEM_COMMAND:
644 firstWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
645 firstWin->generic.width += widthDiff;
646 locator->width += widthDiff;
647 /* check for invalid heights */
648 if (heightDiff == 0)
649 newHeight = firstWin->generic.height;
650 else if ((firstWin->generic.height + splitDiff) >=
651 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
652 newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
653 else if ((firstWin->generic.height + splitDiff) <= 0)
654 newHeight = MIN_WIN_HEIGHT;
655 else
656 newHeight = firstWin->generic.height + splitDiff;
657
658 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
659 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
660 TUI_CMD_WIN->generic.width += widthDiff;
661 newHeight = screenheight - TUI_CMD_WIN->generic.origin.y;
662 _makeInvisibleAndSetNewHeight (TUI_CMD_WIN, newHeight);
663 _makeVisibleWithNewHeight (firstWin);
664 _makeVisibleWithNewHeight (TUI_CMD_WIN);
665 if (firstWin->generic.content_size <= 0)
666 tui_erase_source_content (firstWin, EMPTY_SOURCE_PROMPT);
667 break;
668 default:
669 if (curLayout == SRC_DISASSEM_COMMAND)
670 {
671 firstWin = TUI_SRC_WIN;
672 firstWin->generic.width += widthDiff;
673 secondWin = TUI_DISASM_WIN;
674 secondWin->generic.width += widthDiff;
675 }
676 else
677 {
678 firstWin = TUI_DATA_WIN;
679 firstWin->generic.width += widthDiff;
680 secondWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
681 secondWin->generic.width += widthDiff;
682 }
683 /* Change the first window's height/width */
684 /* check for invalid heights */
685 if (heightDiff == 0)
686 newHeight = firstWin->generic.height;
687 else if ((firstWin->generic.height +
688 secondWin->generic.height + (splitDiff * 2)) >=
689 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
690 newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
691 else if ((firstWin->generic.height + splitDiff) <= 0)
692 newHeight = MIN_WIN_HEIGHT;
693 else
694 newHeight = firstWin->generic.height + splitDiff;
695 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
696
697 if (firstWin == TUI_DATA_WIN && widthDiff != 0)
698 firstWin->detail.data_display_info.regs_column_count =
699 tui_calculate_regs_column_count (
700 firstWin->detail.data_display_info.regs_display_type);
701 locator->width += widthDiff;
702
703 /* Change the second window's height/width */
704 /* check for invalid heights */
705 if (heightDiff == 0)
706 newHeight = secondWin->generic.height;
707 else if ((firstWin->generic.height +
708 secondWin->generic.height + (splitDiff * 2)) >=
709 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
710 {
711 newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
712 if (newHeight % 2)
713 newHeight = (newHeight / 2) + 1;
714 else
715 newHeight /= 2;
716 }
717 else if ((secondWin->generic.height + splitDiff) <= 0)
718 newHeight = MIN_WIN_HEIGHT;
719 else
720 newHeight = secondWin->generic.height + splitDiff;
721 secondWin->generic.origin.y = firstWin->generic.height - 1;
722 _makeInvisibleAndSetNewHeight (secondWin, newHeight);
723
724 /* Change the command window's height/width */
725 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
726 _makeInvisibleAndSetNewHeight (
727 TUI_CMD_WIN, TUI_CMD_WIN->generic.height + cmdSplitDiff);
728 _makeVisibleWithNewHeight (firstWin);
729 _makeVisibleWithNewHeight (secondWin);
730 _makeVisibleWithNewHeight (TUI_CMD_WIN);
731 if (firstWin->generic.content_size <= 0)
732 tui_erase_source_content (firstWin, EMPTY_SOURCE_PROMPT);
733 if (secondWin->generic.content_size <= 0)
734 tui_erase_source_content (secondWin, EMPTY_SOURCE_PROMPT);
735 break;
736 }
737 /*
738 ** Now remove all invisible windows, and their content so that they get
739 ** created again when called for with the new size
740 */
741 for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++)
742 {
743 if (winType != CMD_WIN && (tui_win_list[winType] != NULL)
744 && !tui_win_list[winType]->generic.is_visible)
745 {
746 tui_free_window (tui_win_list[winType]);
747 tui_win_list[winType] = (struct tui_win_info *) NULL;
748 }
749 }
750 tui_set_win_resized_to (TRUE);
751 /* turn keypad back on, unless focus is in the command window */
752 if (winWithFocus != TUI_CMD_WIN)
753 keypad (TUI_CMD_WIN->generic.handle, TRUE);
754 }
755 return;
756 } /* tuiResizeAll */
757
758
759 /*
760 ** tuiSigwinchHandler()
761 ** SIGWINCH signal handler for the tui. This signal handler is
762 ** always called, even when the readline package clears signals
763 ** because it is set as the old_sigwinch() (TUI only)
764 */
765 void
766 tuiSigwinchHandler (int signal)
767 {
768 /*
769 ** Say that a resize was done so that the readline can do it
770 ** later when appropriate.
771 */
772 tui_set_win_resized_to (TRUE);
773
774 return;
775 } /* tuiSigwinchHandler */
776
777
778
779 /*************************
780 ** STATIC LOCAL FUNCTIONS
781 **************************/
782
783
784 /*
785 ** _tuiScrollForward_command().
786 */
787 static void
788 _tuiScrollForward_command (char *arg, int fromTTY)
789 {
790 int numToScroll = 1;
791 struct tui_win_info * winToScroll;
792
793 /* Make sure the curses mode is enabled. */
794 tui_enable ();
795 if (arg == (char *) NULL)
796 _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
797 else
798 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
799 tui_scroll (FORWARD_SCROLL, winToScroll, numToScroll);
800 }
801
802
803 /*
804 ** _tuiScrollBackward_command().
805 */
806 static void
807 _tuiScrollBackward_command (char *arg, int fromTTY)
808 {
809 int numToScroll = 1;
810 struct tui_win_info * winToScroll;
811
812 /* Make sure the curses mode is enabled. */
813 tui_enable ();
814 if (arg == (char *) NULL)
815 _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
816 else
817 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
818 tui_scroll (BACKWARD_SCROLL, winToScroll, numToScroll);
819 }
820
821
822 /*
823 ** _tuiScrollLeft_command().
824 */
825 static void
826 _tuiScrollLeft_command (char *arg, int fromTTY)
827 {
828 int numToScroll;
829 struct tui_win_info * winToScroll;
830
831 /* Make sure the curses mode is enabled. */
832 tui_enable ();
833 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
834 tui_scroll (LEFT_SCROLL, winToScroll, numToScroll);
835 }
836
837
838 /*
839 ** _tuiScrollRight_command().
840 */
841 static void
842 _tuiScrollRight_command (char *arg, int fromTTY)
843 {
844 int numToScroll;
845 struct tui_win_info * winToScroll;
846
847 /* Make sure the curses mode is enabled. */
848 tui_enable ();
849 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
850 tui_scroll (RIGHT_SCROLL, winToScroll, numToScroll);
851 }
852
853
854 /*
855 ** _tuiSetFocus().
856 ** Set focus to the window named by 'arg'
857 */
858 static void
859 _tuiSetFocus (char *arg, int fromTTY)
860 {
861 if (arg != (char *) NULL)
862 {
863 char *bufPtr = (char *) xstrdup (arg);
864 int i;
865 struct tui_win_info * win_info = (struct tui_win_info *) NULL;
866
867 for (i = 0; (i < strlen (bufPtr)); i++)
868 bufPtr[i] = toupper (arg[i]);
869
870 if (subset_compare (bufPtr, "NEXT"))
871 win_info = tui_next_win (tui_win_with_focus ());
872 else if (subset_compare (bufPtr, "PREV"))
873 win_info = tui_prev_win (tui_win_with_focus ());
874 else
875 win_info = tui_partial_win_by_name (bufPtr);
876
877 if (win_info == (struct tui_win_info *) NULL || !win_info->generic.is_visible)
878 warning ("Invalid window specified. \n\
879 The window name specified must be valid and visible.\n");
880 else
881 {
882 tui_set_win_focus_to (win_info);
883 keypad (TUI_CMD_WIN->generic.handle, (win_info != TUI_CMD_WIN));
884 }
885
886 if (TUI_DATA_WIN && TUI_DATA_WIN->generic.is_visible)
887 tui_refresh_data_win ();
888 xfree (bufPtr);
889 printf_filtered ("Focus set to %s window.\n",
890 tui_win_name ((struct tui_gen_win_info *) tui_win_with_focus ()));
891 }
892 else
893 warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE);
894
895 return;
896 } /* _tuiSetFocus */
897
898 /*
899 ** _tuiSetFocus_command()
900 */
901 static void
902 _tuiSetFocus_command (char *arg, int fromTTY)
903 {
904 /* Make sure the curses mode is enabled. */
905 tui_enable ();
906 _tuiSetFocus (arg, fromTTY);
907 }
908
909
910 /*
911 ** _tuiAllWindowsInfo().
912 */
913 static void
914 _tuiAllWindowsInfo (char *arg, int fromTTY)
915 {
916 enum tui_win_type type;
917 struct tui_win_info * winWithFocus = tui_win_with_focus ();
918
919 for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
920 if (tui_win_list[type] && tui_win_list[type]->generic.is_visible)
921 {
922 if (winWithFocus == tui_win_list[type])
923 printf_filtered (" %s\t(%d lines) <has focus>\n",
924 tui_win_name (&tui_win_list[type]->generic),
925 tui_win_list[type]->generic.height);
926 else
927 printf_filtered (" %s\t(%d lines)\n",
928 tui_win_name (&tui_win_list[type]->generic),
929 tui_win_list[type]->generic.height);
930 }
931
932 return;
933 } /* _tuiAllWindowsInfo */
934
935
936 /*
937 ** _tuiRefreshAll_command().
938 */
939 static void
940 _tuiRefreshAll_command (char *arg, int fromTTY)
941 {
942 /* Make sure the curses mode is enabled. */
943 tui_enable ();
944
945 tui_refresh_all_win ();
946 }
947
948
949 /*
950 ** _tuiSetWinTabWidth_command().
951 ** Set the height of the specified window.
952 */
953 static void
954 _tuiSetTabWidth_command (char *arg, int fromTTY)
955 {
956 /* Make sure the curses mode is enabled. */
957 tui_enable ();
958 if (arg != (char *) NULL)
959 {
960 int ts;
961
962 ts = atoi (arg);
963 if (ts > 0)
964 tui_set_default_tab_len (ts);
965 else
966 warning ("Tab widths greater than 0 must be specified.\n");
967 }
968
969 return;
970 } /* _tuiSetTabWidth_command */
971
972
973 /*
974 ** _tuiSetWinHeight().
975 ** Set the height of the specified window.
976 */
977 static void
978 _tuiSetWinHeight (char *arg, int fromTTY)
979 {
980 /* Make sure the curses mode is enabled. */
981 tui_enable ();
982 if (arg != (char *) NULL)
983 {
984 char *buf = xstrdup (arg);
985 char *bufPtr = buf;
986 char *wname = (char *) NULL;
987 int newHeight, i;
988 struct tui_win_info * win_info;
989
990 wname = bufPtr;
991 bufPtr = strchr (bufPtr, ' ');
992 if (bufPtr != (char *) NULL)
993 {
994 *bufPtr = (char) 0;
995
996 /*
997 ** Validate the window name
998 */
999 for (i = 0; i < strlen (wname); i++)
1000 wname[i] = toupper (wname[i]);
1001 win_info = tui_partial_win_by_name (wname);
1002
1003 if (win_info == (struct tui_win_info *) NULL || !win_info->generic.is_visible)
1004 warning ("Invalid window specified. \n\
1005 The window name specified must be valid and visible.\n");
1006 else
1007 {
1008 /* Process the size */
1009 while (*(++bufPtr) == ' ')
1010 ;
1011
1012 if (*bufPtr != (char) 0)
1013 {
1014 int negate = FALSE;
1015 int fixedSize = TRUE;
1016 int inputNo;;
1017
1018 if (*bufPtr == '+' || *bufPtr == '-')
1019 {
1020 if (*bufPtr == '-')
1021 negate = TRUE;
1022 fixedSize = FALSE;
1023 bufPtr++;
1024 }
1025 inputNo = atoi (bufPtr);
1026 if (inputNo > 0)
1027 {
1028 if (negate)
1029 inputNo *= (-1);
1030 if (fixedSize)
1031 newHeight = inputNo;
1032 else
1033 newHeight = win_info->generic.height + inputNo;
1034 /*
1035 ** Now change the window's height, and adjust all
1036 ** other windows around it
1037 */
1038 if (_tuiAdjustWinHeights (win_info,
1039 newHeight) == TUI_FAILURE)
1040 warning ("Invalid window height specified.\n%s",
1041 WIN_HEIGHT_USAGE);
1042 else
1043 tui_update_gdb_sizes ();
1044 }
1045 else
1046 warning ("Invalid window height specified.\n%s",
1047 WIN_HEIGHT_USAGE);
1048 }
1049 }
1050 }
1051 else
1052 printf_filtered (WIN_HEIGHT_USAGE);
1053
1054 if (buf != (char *) NULL)
1055 xfree (buf);
1056 }
1057 else
1058 printf_filtered (WIN_HEIGHT_USAGE);
1059
1060 return;
1061 } /* _tuiSetWinHeight */
1062
1063 /*
1064 ** _tuiSetWinHeight_command().
1065 ** Set the height of the specified window, with va_list.
1066 */
1067 static void
1068 _tuiSetWinHeight_command (char *arg, int fromTTY)
1069 {
1070 /* Make sure the curses mode is enabled. */
1071 tui_enable ();
1072 _tuiSetWinHeight (arg, fromTTY);
1073 }
1074
1075
1076 /*
1077 ** _tuiXDBsetWinHeight().
1078 ** XDB Compatibility command for setting the window height. This will
1079 ** increase or decrease the command window by the specified amount.
1080 */
1081 static void
1082 _tuiXDBsetWinHeight (char *arg, int fromTTY)
1083 {
1084 /* Make sure the curses mode is enabled. */
1085 tui_enable ();
1086 if (arg != (char *) NULL)
1087 {
1088 int inputNo = atoi (arg);
1089
1090 if (inputNo > 0)
1091 { /* Add 1 for the locator */
1092 int newHeight = tui_term_height () - (inputNo + 1);
1093
1094 if (!_newHeightOk (tui_win_list[CMD_WIN], newHeight) ||
1095 _tuiAdjustWinHeights (tui_win_list[CMD_WIN],
1096 newHeight) == TUI_FAILURE)
1097 warning ("Invalid window height specified.\n%s",
1098 XDBWIN_HEIGHT_USAGE);
1099 }
1100 else
1101 warning ("Invalid window height specified.\n%s",
1102 XDBWIN_HEIGHT_USAGE);
1103 }
1104 else
1105 warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE);
1106
1107 return;
1108 } /* _tuiXDBsetWinHeight */
1109
1110 /*
1111 ** _tuiSetWinHeight_command().
1112 ** Set the height of the specified window, with va_list.
1113 */
1114 static void
1115 _tuiXDBsetWinHeight_command (char *arg, int fromTTY)
1116 {
1117 _tuiXDBsetWinHeight (arg, fromTTY);
1118 }
1119
1120
1121 /*
1122 ** _tuiAdjustWinHeights().
1123 ** Function to adjust all window heights around the primary
1124 */
1125 static enum tui_status
1126 _tuiAdjustWinHeights (struct tui_win_info * primaryWinInfo, int newHeight)
1127 {
1128 enum tui_status status = TUI_FAILURE;
1129
1130 if (_newHeightOk (primaryWinInfo, newHeight))
1131 {
1132 status = TUI_SUCCESS;
1133 if (newHeight != primaryWinInfo->generic.height)
1134 {
1135 int diff;
1136 struct tui_win_info * win_info;
1137 struct tui_gen_win_info * locator = tui_locator_win_info_ptr ();
1138 enum tui_layout_type curLayout = tui_current_layout ();
1139
1140 diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1141 if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1142 {
1143 struct tui_win_info * srcWinInfo;
1144
1145 _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight);
1146 if (primaryWinInfo->generic.type == CMD_WIN)
1147 {
1148 win_info = (struct tui_win_info *) (tui_source_windows ())->list[0];
1149 srcWinInfo = win_info;
1150 }
1151 else
1152 {
1153 win_info = tui_win_list[CMD_WIN];
1154 srcWinInfo = primaryWinInfo;
1155 }
1156 _makeInvisibleAndSetNewHeight (win_info,
1157 win_info->generic.height + diff);
1158 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
1159 _makeVisibleWithNewHeight (win_info);
1160 _makeVisibleWithNewHeight (primaryWinInfo);
1161 if (srcWinInfo->generic.content_size <= 0)
1162 tui_erase_source_content (srcWinInfo, EMPTY_SOURCE_PROMPT);
1163 }
1164 else
1165 {
1166 struct tui_win_info *firstWin;
1167 struct tui_win_info *secondWin;
1168
1169 if (curLayout == SRC_DISASSEM_COMMAND)
1170 {
1171 firstWin = TUI_SRC_WIN;
1172 secondWin = TUI_DISASM_WIN;
1173 }
1174 else
1175 {
1176 firstWin = TUI_DATA_WIN;
1177 secondWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
1178 }
1179 if (primaryWinInfo == TUI_CMD_WIN)
1180 { /*
1181 ** Split the change in height accross the 1st & 2nd windows
1182 ** adjusting them as well.
1183 */
1184 int firstSplitDiff = diff / 2; /* subtract the locator */
1185 int secondSplitDiff = firstSplitDiff;
1186
1187 if (diff % 2)
1188 {
1189 if (firstWin->generic.height >
1190 secondWin->generic.height)
1191 if (diff < 0)
1192 firstSplitDiff--;
1193 else
1194 firstSplitDiff++;
1195 else
1196 {
1197 if (diff < 0)
1198 secondSplitDiff--;
1199 else
1200 secondSplitDiff++;
1201 }
1202 }
1203 /* make sure that the minimum hieghts are honored */
1204 while ((firstWin->generic.height + firstSplitDiff) < 3)
1205 {
1206 firstSplitDiff++;
1207 secondSplitDiff--;
1208 }
1209 while ((secondWin->generic.height + secondSplitDiff) < 3)
1210 {
1211 secondSplitDiff++;
1212 firstSplitDiff--;
1213 }
1214 _makeInvisibleAndSetNewHeight (
1215 firstWin,
1216 firstWin->generic.height + firstSplitDiff);
1217 secondWin->generic.origin.y = firstWin->generic.height - 1;
1218 _makeInvisibleAndSetNewHeight (
1219 secondWin, secondWin->generic.height + secondSplitDiff);
1220 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
1221 _makeInvisibleAndSetNewHeight (TUI_CMD_WIN, newHeight);
1222 }
1223 else
1224 {
1225 if ((TUI_CMD_WIN->generic.height + diff) < 1)
1226 { /*
1227 ** If there is no way to increase the command window
1228 ** take real estate from the 1st or 2nd window.
1229 */
1230 if ((TUI_CMD_WIN->generic.height + diff) < 1)
1231 {
1232 int i;
1233 for (i = TUI_CMD_WIN->generic.height + diff;
1234 (i < 1); i++)
1235 if (primaryWinInfo == firstWin)
1236 secondWin->generic.height--;
1237 else
1238 firstWin->generic.height--;
1239 }
1240 }
1241 if (primaryWinInfo == firstWin)
1242 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
1243 else
1244 _makeInvisibleAndSetNewHeight (
1245 firstWin,
1246 firstWin->generic.height);
1247 secondWin->generic.origin.y = firstWin->generic.height - 1;
1248 if (primaryWinInfo == secondWin)
1249 _makeInvisibleAndSetNewHeight (secondWin, newHeight);
1250 else
1251 _makeInvisibleAndSetNewHeight (
1252 secondWin, secondWin->generic.height);
1253 TUI_CMD_WIN->generic.origin.y = locator->origin.y + 1;
1254 if ((TUI_CMD_WIN->generic.height + diff) < 1)
1255 _makeInvisibleAndSetNewHeight (TUI_CMD_WIN, 1);
1256 else
1257 _makeInvisibleAndSetNewHeight (
1258 TUI_CMD_WIN, TUI_CMD_WIN->generic.height + diff);
1259 }
1260 _makeVisibleWithNewHeight (TUI_CMD_WIN);
1261 _makeVisibleWithNewHeight (secondWin);
1262 _makeVisibleWithNewHeight (firstWin);
1263 if (firstWin->generic.content_size <= 0)
1264 tui_erase_source_content (firstWin, EMPTY_SOURCE_PROMPT);
1265 if (secondWin->generic.content_size <= 0)
1266 tui_erase_source_content (secondWin, EMPTY_SOURCE_PROMPT);
1267 }
1268 }
1269 }
1270
1271 return status;
1272 } /* _tuiAdjustWinHeights */
1273
1274
1275 /*
1276 ** _makeInvisibleAndSetNewHeight().
1277 ** Function make the target window (and auxillary windows associated
1278 ** with the targer) invisible, and set the new height and location.
1279 */
1280 static void
1281 _makeInvisibleAndSetNewHeight (struct tui_win_info * win_info, int height)
1282 {
1283 int i;
1284 struct tui_gen_win_info * genWinInfo;
1285
1286 tui_make_invisible (&win_info->generic);
1287 win_info->generic.height = height;
1288 if (height > 1)
1289 win_info->generic.viewport_height = height - 1;
1290 else
1291 win_info->generic.viewport_height = height;
1292 if (win_info != TUI_CMD_WIN)
1293 win_info->generic.viewport_height--;
1294
1295 /* Now deal with the auxillary windows associated with win_info */
1296 switch (win_info->generic.type)
1297 {
1298 case SRC_WIN:
1299 case DISASSEM_WIN:
1300 genWinInfo = win_info->detail.source_info.execution_info;
1301 tui_make_invisible (genWinInfo);
1302 genWinInfo->height = height;
1303 genWinInfo->origin.y = win_info->generic.origin.y;
1304 if (height > 1)
1305 genWinInfo->viewport_height = height - 1;
1306 else
1307 genWinInfo->viewport_height = height;
1308 if (win_info != TUI_CMD_WIN)
1309 genWinInfo->viewport_height--;
1310
1311 if (tui_win_has_locator (win_info))
1312 {
1313 genWinInfo = tui_locator_win_info_ptr ();
1314 tui_make_invisible (genWinInfo);
1315 genWinInfo->origin.y = win_info->generic.origin.y + height;
1316 }
1317 break;
1318 case DATA_WIN:
1319 /* delete all data item windows */
1320 for (i = 0; i < win_info->generic.content_size; i++)
1321 {
1322 genWinInfo = (struct tui_gen_win_info *) & ((struct tui_win_element *)
1323 win_info->generic.content[i])->which_element.data_window;
1324 tui_delete_win (genWinInfo->handle);
1325 genWinInfo->handle = (WINDOW *) NULL;
1326 }
1327 break;
1328 default:
1329 break;
1330 }
1331 }
1332
1333
1334 /*
1335 ** _makeVisibleWithNewHeight().
1336 ** Function to make the windows with new heights visible.
1337 ** This means re-creating the windows' content since the window
1338 ** had to be destroyed to be made invisible.
1339 */
1340 static void
1341 _makeVisibleWithNewHeight (struct tui_win_info * win_info)
1342 {
1343 struct symtab *s;
1344
1345 tui_make_visible (&win_info->generic);
1346 tui_check_and_display_highlight_if_needed (win_info);
1347 switch (win_info->generic.type)
1348 {
1349 case SRC_WIN:
1350 case DISASSEM_WIN:
1351 tui_free_win_content (win_info->detail.source_info.execution_info);
1352 tui_make_visible (win_info->detail.source_info.execution_info);
1353 if (win_info->generic.content != NULL)
1354 {
1355 union tui_line_or_address lineOrAddr;
1356 struct symtab_and_line cursal
1357 = get_current_source_symtab_and_line ();
1358
1359 if (win_info->generic.type == SRC_WIN)
1360 lineOrAddr.line_no =
1361 win_info->detail.source_info.start_line_or_addr.line_no;
1362 else
1363 lineOrAddr.addr =
1364 win_info->detail.source_info.start_line_or_addr.addr;
1365 tui_free_win_content (&win_info->generic);
1366 tui_update_source_window (win_info, cursal.symtab, lineOrAddr, TRUE);
1367 }
1368 else if (deprecated_selected_frame != (struct frame_info *) NULL)
1369 {
1370 union tui_line_or_address line;
1371 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
1372
1373
1374 s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
1375 if (win_info->generic.type == SRC_WIN)
1376 line.line_no = cursal.line;
1377 else
1378 {
1379 find_line_pc (s, cursal.line, &line.addr);
1380 }
1381 tui_update_source_window (win_info, s, line, TRUE);
1382 }
1383 if (tui_win_has_locator (win_info))
1384 {
1385 tui_make_visible (tui_locator_win_info_ptr ());
1386 tui_show_locator_content ();
1387 }
1388 break;
1389 case DATA_WIN:
1390 tui_display_all_data ();
1391 break;
1392 case CMD_WIN:
1393 win_info->detail.command_info.cur_line = 0;
1394 win_info->detail.command_info.curch = 0;
1395 wmove (win_info->generic.handle,
1396 win_info->detail.command_info.cur_line,
1397 win_info->detail.command_info.curch);
1398 break;
1399 default:
1400 break;
1401 }
1402
1403 return;
1404 } /* _makeVisibleWithNewHeight */
1405
1406
1407 static int
1408 _newHeightOk (struct tui_win_info * primaryWinInfo, int newHeight)
1409 {
1410 int ok = (newHeight < tui_term_height ());
1411
1412 if (ok)
1413 {
1414 int diff;
1415 enum tui_layout_type cur_layout = tui_current_layout ();
1416
1417 diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1418 if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND)
1419 {
1420 ok = ((primaryWinInfo->generic.type == CMD_WIN &&
1421 newHeight <= (tui_term_height () - 4) &&
1422 newHeight >= MIN_CMD_WIN_HEIGHT) ||
1423 (primaryWinInfo->generic.type != CMD_WIN &&
1424 newHeight <= (tui_term_height () - 2) &&
1425 newHeight >= MIN_WIN_HEIGHT));
1426 if (ok)
1427 { /* check the total height */
1428 struct tui_win_info * win_info;
1429
1430 if (primaryWinInfo == TUI_CMD_WIN)
1431 win_info = (struct tui_win_info *) (tui_source_windows ())->list[0];
1432 else
1433 win_info = TUI_CMD_WIN;
1434 ok = ((newHeight +
1435 (win_info->generic.height + diff)) <= tui_term_height ());
1436 }
1437 }
1438 else
1439 {
1440 int curTotalHeight, totalHeight, minHeight = 0;
1441 struct tui_win_info *firstWin;
1442 struct tui_win_info *secondWin;
1443
1444 if (cur_layout == SRC_DISASSEM_COMMAND)
1445 {
1446 firstWin = TUI_SRC_WIN;
1447 secondWin = TUI_DISASM_WIN;
1448 }
1449 else
1450 {
1451 firstWin = TUI_DATA_WIN;
1452 secondWin = (struct tui_win_info *) (tui_source_windows ())->list[0];
1453 }
1454 /*
1455 ** We could simply add all the heights to obtain the same result
1456 ** but below is more explicit since we subtract 1 for the
1457 ** line that the first and second windows share, and add one
1458 ** for the locator.
1459 */
1460 totalHeight = curTotalHeight =
1461 (firstWin->generic.height + secondWin->generic.height - 1)
1462 + TUI_CMD_WIN->generic.height + 1 /*locator */ ;
1463 if (primaryWinInfo == TUI_CMD_WIN)
1464 {
1465 /* locator included since first & second win share a line */
1466 ok = ((firstWin->generic.height +
1467 secondWin->generic.height + diff) >=
1468 (MIN_WIN_HEIGHT * 2) &&
1469 newHeight >= MIN_CMD_WIN_HEIGHT);
1470 if (ok)
1471 {
1472 totalHeight = newHeight + (firstWin->generic.height +
1473 secondWin->generic.height + diff);
1474 minHeight = MIN_CMD_WIN_HEIGHT;
1475 }
1476 }
1477 else
1478 {
1479 minHeight = MIN_WIN_HEIGHT;
1480 /*
1481 ** First see if we can increase/decrease the command
1482 ** window. And make sure that the command window is
1483 ** at least 1 line
1484 */
1485 ok = ((TUI_CMD_WIN->generic.height + diff) > 0);
1486 if (!ok)
1487 { /*
1488 ** Looks like we have to increase/decrease one of
1489 ** the other windows
1490 */
1491 if (primaryWinInfo == firstWin)
1492 ok = (secondWin->generic.height + diff) >= minHeight;
1493 else
1494 ok = (firstWin->generic.height + diff) >= minHeight;
1495 }
1496 if (ok)
1497 {
1498 if (primaryWinInfo == firstWin)
1499 totalHeight = newHeight +
1500 secondWin->generic.height +
1501 TUI_CMD_WIN->generic.height + diff;
1502 else
1503 totalHeight = newHeight +
1504 firstWin->generic.height +
1505 TUI_CMD_WIN->generic.height + diff;
1506 }
1507 }
1508 /*
1509 ** Now make sure that the proposed total height doesn't exceed
1510 ** the old total height.
1511 */
1512 if (ok)
1513 ok = (newHeight >= minHeight && totalHeight <= curTotalHeight);
1514 }
1515 }
1516
1517 return ok;
1518 } /* _newHeightOk */
1519
1520
1521 /*
1522 ** _parseScrollingArgs().
1523 */
1524 static void
1525 _parseScrollingArgs (char *arg, struct tui_win_info * * winToScroll, int *numToScroll)
1526 {
1527 if (numToScroll)
1528 *numToScroll = 0;
1529 *winToScroll = tui_win_with_focus ();
1530
1531 /*
1532 ** First set up the default window to scroll, in case there is no
1533 ** window name arg
1534 */
1535 if (arg != (char *) NULL)
1536 {
1537 char *buf, *bufPtr;
1538
1539 /* process the number of lines to scroll */
1540 buf = bufPtr = xstrdup (arg);
1541 if (isdigit (*bufPtr))
1542 {
1543 char *numStr;
1544
1545 numStr = bufPtr;
1546 bufPtr = strchr (bufPtr, ' ');
1547 if (bufPtr != (char *) NULL)
1548 {
1549 *bufPtr = (char) 0;
1550 if (numToScroll)
1551 *numToScroll = atoi (numStr);
1552 bufPtr++;
1553 }
1554 else if (numToScroll)
1555 *numToScroll = atoi (numStr);
1556 }
1557
1558 /* process the window name if one is specified */
1559 if (bufPtr != (char *) NULL)
1560 {
1561 char *wname;
1562 int i;
1563
1564 if (*bufPtr == ' ')
1565 while (*(++bufPtr) == ' ')
1566 ;
1567
1568 if (*bufPtr != (char) 0)
1569 wname = bufPtr;
1570 else
1571 wname = "?";
1572
1573 /* Validate the window name */
1574 for (i = 0; i < strlen (wname); i++)
1575 wname[i] = toupper (wname[i]);
1576 *winToScroll = tui_partial_win_by_name (wname);
1577
1578 if (*winToScroll == (struct tui_win_info *) NULL ||
1579 !(*winToScroll)->generic.is_visible)
1580 warning ("Invalid window specified. \n\
1581 The window name specified must be valid and visible.\n");
1582 else if (*winToScroll == TUI_CMD_WIN)
1583 *winToScroll = (struct tui_win_info *) (tui_source_windows ())->list[0];
1584 }
1585 xfree (buf);
1586 }
1587
1588 return;
1589 } /* _parseScrollingArgs */