]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/tui/tui-win.c
2004-01-28 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 (TuiWinInfoPtr);
65 static void _makeInvisibleAndSetNewHeight (TuiWinInfoPtr, int);
66 static TuiStatus _tuiAdjustWinHeights (TuiWinInfoPtr, int);
67 static int _newHeightOk (TuiWinInfoPtr, 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 *, TuiWinInfoPtr *, 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 ? cmdWin->generic.width : screenwidth);
419 execute_command (cmd, 0);
420 sprintf (cmd, "set height %d",
421 tui_active ? cmdWin->generic.height : screenheight);
422 execute_command (cmd, 0);
423 }
424
425
426 /*
427 ** tuiSetWinFocusTo
428 ** Set the logical focus to winInfo
429 */
430 void
431 tuiSetWinFocusTo (TuiWinInfoPtr winInfo)
432 {
433 if (m_winPtrNotNull (winInfo))
434 {
435 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
436
437 if (m_winPtrNotNull (winWithFocus) &&
438 winWithFocus->generic.type != CMD_WIN)
439 unhighlightWin (winWithFocus);
440 tuiSetWinWithFocus (winInfo);
441 if (winInfo->generic.type != CMD_WIN)
442 highlightWin (winInfo);
443 }
444
445 return;
446 } /* tuiSetWinFocusTo */
447
448
449 /*
450 ** tuiScrollForward().
451 */
452 void
453 tuiScrollForward (TuiWinInfoPtr winToScroll, int numToScroll)
454 {
455 if (winToScroll != cmdWin)
456 {
457 int _numToScroll = numToScroll;
458
459 if (numToScroll == 0)
460 _numToScroll = winToScroll->generic.height - 3;
461 /*
462 ** If we are scrolling the source or disassembly window, do a
463 ** "psuedo" scroll since not all of the source is in memory,
464 ** only what is in the viewport. If winToScroll is the
465 ** command window do nothing since the term should handle it.
466 */
467 if (winToScroll == srcWin)
468 tuiVerticalSourceScroll (FORWARD_SCROLL, _numToScroll);
469 else if (winToScroll == disassemWin)
470 tui_vertical_disassem_scroll (FORWARD_SCROLL, _numToScroll);
471 else if (winToScroll == dataWin)
472 tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll);
473 }
474
475 return;
476 } /* tuiScrollForward */
477
478
479 /*
480 ** tuiScrollBackward().
481 */
482 void
483 tuiScrollBackward (TuiWinInfoPtr winToScroll, int numToScroll)
484 {
485 if (winToScroll != cmdWin)
486 {
487 int _numToScroll = numToScroll;
488
489 if (numToScroll == 0)
490 _numToScroll = winToScroll->generic.height - 3;
491 /*
492 ** If we are scrolling the source or disassembly window, do a
493 ** "psuedo" scroll since not all of the source is in memory,
494 ** only what is in the viewport. If winToScroll is the
495 ** command window do nothing since the term should handle it.
496 */
497 if (winToScroll == srcWin)
498 tuiVerticalSourceScroll (BACKWARD_SCROLL, _numToScroll);
499 else if (winToScroll == disassemWin)
500 tui_vertical_disassem_scroll (BACKWARD_SCROLL, _numToScroll);
501 else if (winToScroll == dataWin)
502 tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll);
503 }
504 return;
505 } /* tuiScrollBackward */
506
507
508 /*
509 ** tuiScrollLeft().
510 */
511 void
512 tuiScrollLeft (TuiWinInfoPtr winToScroll, int numToScroll)
513 {
514 if (winToScroll != cmdWin)
515 {
516 int _numToScroll = numToScroll;
517
518 if (_numToScroll == 0)
519 _numToScroll = 1;
520 /*
521 ** If we are scrolling the source or disassembly window, do a
522 ** "psuedo" scroll since not all of the source is in memory,
523 ** only what is in the viewport. If winToScroll is the
524 ** command window do nothing since the term should handle it.
525 */
526 if (winToScroll == srcWin || winToScroll == disassemWin)
527 tuiHorizontalSourceScroll (winToScroll, LEFT_SCROLL, _numToScroll);
528 }
529 return;
530 } /* tuiScrollLeft */
531
532
533 /*
534 ** tuiScrollRight().
535 */
536 void
537 tuiScrollRight (TuiWinInfoPtr winToScroll, int numToScroll)
538 {
539 if (winToScroll != cmdWin)
540 {
541 int _numToScroll = numToScroll;
542
543 if (_numToScroll == 0)
544 _numToScroll = 1;
545 /*
546 ** If we are scrolling the source or disassembly window, do a
547 ** "psuedo" scroll since not all of the source is in memory,
548 ** only what is in the viewport. If winToScroll is the
549 ** command window do nothing since the term should handle it.
550 */
551 if (winToScroll == srcWin || winToScroll == disassemWin)
552 tuiHorizontalSourceScroll (winToScroll, RIGHT_SCROLL, _numToScroll);
553 }
554 return;
555 } /* tuiScrollRight */
556
557
558 /*
559 ** tui_scroll().
560 ** Scroll a window. Arguments are passed through a va_list.
561 */
562 void
563 tui_scroll (TuiScrollDirection direction,
564 TuiWinInfoPtr winToScroll,
565 int numToScroll)
566 {
567 switch (direction)
568 {
569 case FORWARD_SCROLL:
570 tuiScrollForward (winToScroll, numToScroll);
571 break;
572 case BACKWARD_SCROLL:
573 tuiScrollBackward (winToScroll, numToScroll);
574 break;
575 case LEFT_SCROLL:
576 tuiScrollLeft (winToScroll, numToScroll);
577 break;
578 case RIGHT_SCROLL:
579 tuiScrollRight (winToScroll, numToScroll);
580 break;
581 default:
582 break;
583 }
584 }
585
586
587 /*
588 ** tuiRefreshAll().
589 */
590 void
591 tuiRefreshAll (void)
592 {
593 TuiWinType type;
594
595 clearok (curscr, TRUE);
596 refreshAll (winList);
597 for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
598 {
599 if (winList[type] && winList[type]->generic.isVisible)
600 {
601 switch (type)
602 {
603 case SRC_WIN:
604 case DISASSEM_WIN:
605 tuiShowSourceContent (winList[type]);
606 checkAndDisplayHighlightIfNeeded (winList[type]);
607 tuiEraseExecInfoContent (winList[type]);
608 tuiUpdateExecInfo (winList[type]);
609 break;
610 case DATA_WIN:
611 tuiRefreshDataWin ();
612 break;
613 default:
614 break;
615 }
616 }
617 }
618 tui_show_locator_content ();
619 }
620
621
622 /*
623 ** tuiResizeAll().
624 ** Resize all the windows based on the the terminal size. This
625 ** function gets called from within the readline sinwinch handler.
626 */
627 void
628 tuiResizeAll (void)
629 {
630 int heightDiff, widthDiff;
631 int screenheight, screenwidth;
632
633 rl_get_screen_size (&screenheight, &screenwidth);
634 widthDiff = screenwidth - termWidth ();
635 heightDiff = screenheight - termHeight ();
636 if (heightDiff || widthDiff)
637 {
638 TuiLayoutType curLayout = currentLayout ();
639 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
640 TuiWinInfoPtr firstWin, secondWin;
641 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
642 TuiWinType winType;
643 int newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
644
645 /* turn keypad off while we resize */
646 if (winWithFocus != cmdWin)
647 keypad (cmdWin->generic.handle, FALSE);
648 tui_update_gdb_sizes ();
649 setTermHeightTo (screenheight);
650 setTermWidthTo (screenwidth);
651 if (curLayout == SRC_DISASSEM_COMMAND ||
652 curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND)
653 numWinsDisplayed++;
654 splitDiff = heightDiff / numWinsDisplayed;
655 cmdSplitDiff = splitDiff;
656 if (heightDiff % numWinsDisplayed)
657 {
658 if (heightDiff < 0)
659 cmdSplitDiff--;
660 else
661 cmdSplitDiff++;
662 }
663 /* now adjust each window */
664 clear ();
665 refresh ();
666 switch (curLayout)
667 {
668 case SRC_COMMAND:
669 case DISASSEM_COMMAND:
670 firstWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
671 firstWin->generic.width += widthDiff;
672 locator->width += widthDiff;
673 /* check for invalid heights */
674 if (heightDiff == 0)
675 newHeight = firstWin->generic.height;
676 else if ((firstWin->generic.height + splitDiff) >=
677 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
678 newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
679 else if ((firstWin->generic.height + splitDiff) <= 0)
680 newHeight = MIN_WIN_HEIGHT;
681 else
682 newHeight = firstWin->generic.height + splitDiff;
683
684 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
685 cmdWin->generic.origin.y = locator->origin.y + 1;
686 cmdWin->generic.width += widthDiff;
687 newHeight = screenheight - cmdWin->generic.origin.y;
688 _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
689 _makeVisibleWithNewHeight (firstWin);
690 _makeVisibleWithNewHeight (cmdWin);
691 if (firstWin->generic.contentSize <= 0)
692 tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
693 break;
694 default:
695 if (curLayout == SRC_DISASSEM_COMMAND)
696 {
697 firstWin = srcWin;
698 firstWin->generic.width += widthDiff;
699 secondWin = disassemWin;
700 secondWin->generic.width += widthDiff;
701 }
702 else
703 {
704 firstWin = dataWin;
705 firstWin->generic.width += widthDiff;
706 secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
707 secondWin->generic.width += widthDiff;
708 }
709 /* Change the first window's height/width */
710 /* check for invalid heights */
711 if (heightDiff == 0)
712 newHeight = firstWin->generic.height;
713 else if ((firstWin->generic.height +
714 secondWin->generic.height + (splitDiff * 2)) >=
715 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
716 newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
717 else if ((firstWin->generic.height + splitDiff) <= 0)
718 newHeight = MIN_WIN_HEIGHT;
719 else
720 newHeight = firstWin->generic.height + splitDiff;
721 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
722
723 if (firstWin == dataWin && widthDiff != 0)
724 firstWin->detail.dataDisplayInfo.regsColumnCount =
725 tui_calculate_regs_column_count (
726 firstWin->detail.dataDisplayInfo.regsDisplayType);
727 locator->width += widthDiff;
728
729 /* Change the second window's height/width */
730 /* check for invalid heights */
731 if (heightDiff == 0)
732 newHeight = secondWin->generic.height;
733 else if ((firstWin->generic.height +
734 secondWin->generic.height + (splitDiff * 2)) >=
735 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
736 {
737 newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
738 if (newHeight % 2)
739 newHeight = (newHeight / 2) + 1;
740 else
741 newHeight /= 2;
742 }
743 else if ((secondWin->generic.height + splitDiff) <= 0)
744 newHeight = MIN_WIN_HEIGHT;
745 else
746 newHeight = secondWin->generic.height + splitDiff;
747 secondWin->generic.origin.y = firstWin->generic.height - 1;
748 _makeInvisibleAndSetNewHeight (secondWin, newHeight);
749
750 /* Change the command window's height/width */
751 cmdWin->generic.origin.y = locator->origin.y + 1;
752 _makeInvisibleAndSetNewHeight (
753 cmdWin, cmdWin->generic.height + cmdSplitDiff);
754 _makeVisibleWithNewHeight (firstWin);
755 _makeVisibleWithNewHeight (secondWin);
756 _makeVisibleWithNewHeight (cmdWin);
757 if (firstWin->generic.contentSize <= 0)
758 tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
759 if (secondWin->generic.contentSize <= 0)
760 tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
761 break;
762 }
763 /*
764 ** Now remove all invisible windows, and their content so that they get
765 ** created again when called for with the new size
766 */
767 for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++)
768 {
769 if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) &&
770 !winList[winType]->generic.isVisible)
771 {
772 freeWindow (winList[winType]);
773 winList[winType] = (TuiWinInfoPtr) NULL;
774 }
775 }
776 tuiSetWinResizedTo (TRUE);
777 /* turn keypad back on, unless focus is in the command window */
778 if (winWithFocus != cmdWin)
779 keypad (cmdWin->generic.handle, TRUE);
780 }
781 return;
782 } /* tuiResizeAll */
783
784
785 /*
786 ** tuiSigwinchHandler()
787 ** SIGWINCH signal handler for the tui. This signal handler is
788 ** always called, even when the readline package clears signals
789 ** because it is set as the old_sigwinch() (TUI only)
790 */
791 void
792 tuiSigwinchHandler (int signal)
793 {
794 /*
795 ** Say that a resize was done so that the readline can do it
796 ** later when appropriate.
797 */
798 tuiSetWinResizedTo (TRUE);
799
800 return;
801 } /* tuiSigwinchHandler */
802
803
804
805 /*************************
806 ** STATIC LOCAL FUNCTIONS
807 **************************/
808
809
810 /*
811 ** _tuiScrollForward_command().
812 */
813 static void
814 _tuiScrollForward_command (char *arg, int fromTTY)
815 {
816 int numToScroll = 1;
817 TuiWinInfoPtr winToScroll;
818
819 /* Make sure the curses mode is enabled. */
820 tui_enable ();
821 if (arg == (char *) NULL)
822 _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
823 else
824 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
825 tui_scroll (FORWARD_SCROLL, winToScroll, numToScroll);
826 }
827
828
829 /*
830 ** _tuiScrollBackward_command().
831 */
832 static void
833 _tuiScrollBackward_command (char *arg, int fromTTY)
834 {
835 int numToScroll = 1;
836 TuiWinInfoPtr winToScroll;
837
838 /* Make sure the curses mode is enabled. */
839 tui_enable ();
840 if (arg == (char *) NULL)
841 _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
842 else
843 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
844 tui_scroll (BACKWARD_SCROLL, winToScroll, numToScroll);
845 }
846
847
848 /*
849 ** _tuiScrollLeft_command().
850 */
851 static void
852 _tuiScrollLeft_command (char *arg, int fromTTY)
853 {
854 int numToScroll;
855 TuiWinInfoPtr winToScroll;
856
857 /* Make sure the curses mode is enabled. */
858 tui_enable ();
859 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
860 tui_scroll (LEFT_SCROLL, winToScroll, numToScroll);
861 }
862
863
864 /*
865 ** _tuiScrollRight_command().
866 */
867 static void
868 _tuiScrollRight_command (char *arg, int fromTTY)
869 {
870 int numToScroll;
871 TuiWinInfoPtr winToScroll;
872
873 /* Make sure the curses mode is enabled. */
874 tui_enable ();
875 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
876 tui_scroll (RIGHT_SCROLL, winToScroll, numToScroll);
877 }
878
879
880 /*
881 ** _tuiSetFocus().
882 ** Set focus to the window named by 'arg'
883 */
884 static void
885 _tuiSetFocus (char *arg, int fromTTY)
886 {
887 if (arg != (char *) NULL)
888 {
889 char *bufPtr = (char *) xstrdup (arg);
890 int i;
891 TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
892
893 for (i = 0; (i < strlen (bufPtr)); i++)
894 bufPtr[i] = toupper (arg[i]);
895
896 if (subset_compare (bufPtr, "NEXT"))
897 winInfo = tuiNextWin (tuiWinWithFocus ());
898 else if (subset_compare (bufPtr, "PREV"))
899 winInfo = tuiPrevWin (tuiWinWithFocus ());
900 else
901 winInfo = partialWinByName (bufPtr);
902
903 if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
904 warning ("Invalid window specified. \n\
905 The window name specified must be valid and visible.\n");
906 else
907 {
908 tuiSetWinFocusTo (winInfo);
909 keypad (cmdWin->generic.handle, (winInfo != cmdWin));
910 }
911
912 if (dataWin && dataWin->generic.isVisible)
913 tuiRefreshDataWin ();
914 tuiFree (bufPtr);
915 printf_filtered ("Focus set to %s window.\n",
916 winName ((TuiGenWinInfoPtr) tuiWinWithFocus ()));
917 }
918 else
919 warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE);
920
921 return;
922 } /* _tuiSetFocus */
923
924 /*
925 ** _tuiSetFocus_command()
926 */
927 static void
928 _tuiSetFocus_command (char *arg, int fromTTY)
929 {
930 /* Make sure the curses mode is enabled. */
931 tui_enable ();
932 _tuiSetFocus (arg, fromTTY);
933 }
934
935
936 /*
937 ** _tuiAllWindowsInfo().
938 */
939 static void
940 _tuiAllWindowsInfo (char *arg, int fromTTY)
941 {
942 TuiWinType type;
943 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
944
945 for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
946 if (winList[type] && winList[type]->generic.isVisible)
947 {
948 if (winWithFocus == winList[type])
949 printf_filtered (" %s\t(%d lines) <has focus>\n",
950 winName (&winList[type]->generic),
951 winList[type]->generic.height);
952 else
953 printf_filtered (" %s\t(%d lines)\n",
954 winName (&winList[type]->generic),
955 winList[type]->generic.height);
956 }
957
958 return;
959 } /* _tuiAllWindowsInfo */
960
961
962 /*
963 ** _tuiRefreshAll_command().
964 */
965 static void
966 _tuiRefreshAll_command (char *arg, int fromTTY)
967 {
968 /* Make sure the curses mode is enabled. */
969 tui_enable ();
970
971 tuiRefreshAll ();
972 }
973
974
975 /*
976 ** _tuiSetWinTabWidth_command().
977 ** Set the height of the specified window.
978 */
979 static void
980 _tuiSetTabWidth_command (char *arg, int fromTTY)
981 {
982 /* Make sure the curses mode is enabled. */
983 tui_enable ();
984 if (arg != (char *) NULL)
985 {
986 int ts;
987
988 ts = atoi (arg);
989 if (ts > 0)
990 tuiSetDefaultTabLen (ts);
991 else
992 warning ("Tab widths greater than 0 must be specified.\n");
993 }
994
995 return;
996 } /* _tuiSetTabWidth_command */
997
998
999 /*
1000 ** _tuiSetWinHeight().
1001 ** Set the height of the specified window.
1002 */
1003 static void
1004 _tuiSetWinHeight (char *arg, int fromTTY)
1005 {
1006 /* Make sure the curses mode is enabled. */
1007 tui_enable ();
1008 if (arg != (char *) NULL)
1009 {
1010 char *buf = xstrdup (arg);
1011 char *bufPtr = buf;
1012 char *wname = (char *) NULL;
1013 int newHeight, i;
1014 TuiWinInfoPtr winInfo;
1015
1016 wname = bufPtr;
1017 bufPtr = strchr (bufPtr, ' ');
1018 if (bufPtr != (char *) NULL)
1019 {
1020 *bufPtr = (char) 0;
1021
1022 /*
1023 ** Validate the window name
1024 */
1025 for (i = 0; i < strlen (wname); i++)
1026 wname[i] = toupper (wname[i]);
1027 winInfo = partialWinByName (wname);
1028
1029 if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
1030 warning ("Invalid window specified. \n\
1031 The window name specified must be valid and visible.\n");
1032 else
1033 {
1034 /* Process the size */
1035 while (*(++bufPtr) == ' ')
1036 ;
1037
1038 if (*bufPtr != (char) 0)
1039 {
1040 int negate = FALSE;
1041 int fixedSize = TRUE;
1042 int inputNo;;
1043
1044 if (*bufPtr == '+' || *bufPtr == '-')
1045 {
1046 if (*bufPtr == '-')
1047 negate = TRUE;
1048 fixedSize = FALSE;
1049 bufPtr++;
1050 }
1051 inputNo = atoi (bufPtr);
1052 if (inputNo > 0)
1053 {
1054 if (negate)
1055 inputNo *= (-1);
1056 if (fixedSize)
1057 newHeight = inputNo;
1058 else
1059 newHeight = winInfo->generic.height + inputNo;
1060 /*
1061 ** Now change the window's height, and adjust all
1062 ** other windows around it
1063 */
1064 if (_tuiAdjustWinHeights (winInfo,
1065 newHeight) == TUI_FAILURE)
1066 warning ("Invalid window height specified.\n%s",
1067 WIN_HEIGHT_USAGE);
1068 else
1069 tui_update_gdb_sizes ();
1070 }
1071 else
1072 warning ("Invalid window height specified.\n%s",
1073 WIN_HEIGHT_USAGE);
1074 }
1075 }
1076 }
1077 else
1078 printf_filtered (WIN_HEIGHT_USAGE);
1079
1080 if (buf != (char *) NULL)
1081 tuiFree (buf);
1082 }
1083 else
1084 printf_filtered (WIN_HEIGHT_USAGE);
1085
1086 return;
1087 } /* _tuiSetWinHeight */
1088
1089 /*
1090 ** _tuiSetWinHeight_command().
1091 ** Set the height of the specified window, with va_list.
1092 */
1093 static void
1094 _tuiSetWinHeight_command (char *arg, int fromTTY)
1095 {
1096 /* Make sure the curses mode is enabled. */
1097 tui_enable ();
1098 _tuiSetWinHeight (arg, fromTTY);
1099 }
1100
1101
1102 /*
1103 ** _tuiXDBsetWinHeight().
1104 ** XDB Compatibility command for setting the window height. This will
1105 ** increase or decrease the command window by the specified amount.
1106 */
1107 static void
1108 _tuiXDBsetWinHeight (char *arg, int fromTTY)
1109 {
1110 /* Make sure the curses mode is enabled. */
1111 tui_enable ();
1112 if (arg != (char *) NULL)
1113 {
1114 int inputNo = atoi (arg);
1115
1116 if (inputNo > 0)
1117 { /* Add 1 for the locator */
1118 int newHeight = termHeight () - (inputNo + 1);
1119
1120 if (!_newHeightOk (winList[CMD_WIN], newHeight) ||
1121 _tuiAdjustWinHeights (winList[CMD_WIN],
1122 newHeight) == TUI_FAILURE)
1123 warning ("Invalid window height specified.\n%s",
1124 XDBWIN_HEIGHT_USAGE);
1125 }
1126 else
1127 warning ("Invalid window height specified.\n%s",
1128 XDBWIN_HEIGHT_USAGE);
1129 }
1130 else
1131 warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE);
1132
1133 return;
1134 } /* _tuiXDBsetWinHeight */
1135
1136 /*
1137 ** _tuiSetWinHeight_command().
1138 ** Set the height of the specified window, with va_list.
1139 */
1140 static void
1141 _tuiXDBsetWinHeight_command (char *arg, int fromTTY)
1142 {
1143 _tuiXDBsetWinHeight (arg, fromTTY);
1144 }
1145
1146
1147 /*
1148 ** _tuiAdjustWinHeights().
1149 ** Function to adjust all window heights around the primary
1150 */
1151 static TuiStatus
1152 _tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo, int newHeight)
1153 {
1154 TuiStatus status = TUI_FAILURE;
1155
1156 if (_newHeightOk (primaryWinInfo, newHeight))
1157 {
1158 status = TUI_SUCCESS;
1159 if (newHeight != primaryWinInfo->generic.height)
1160 {
1161 int diff;
1162 TuiWinInfoPtr winInfo;
1163 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
1164 TuiLayoutType curLayout = currentLayout ();
1165
1166 diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1167 if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1168 {
1169 TuiWinInfoPtr srcWinInfo;
1170
1171 _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight);
1172 if (primaryWinInfo->generic.type == CMD_WIN)
1173 {
1174 winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1175 srcWinInfo = winInfo;
1176 }
1177 else
1178 {
1179 winInfo = winList[CMD_WIN];
1180 srcWinInfo = primaryWinInfo;
1181 }
1182 _makeInvisibleAndSetNewHeight (winInfo,
1183 winInfo->generic.height + diff);
1184 cmdWin->generic.origin.y = locator->origin.y + 1;
1185 _makeVisibleWithNewHeight (winInfo);
1186 _makeVisibleWithNewHeight (primaryWinInfo);
1187 if (srcWinInfo->generic.contentSize <= 0)
1188 tuiEraseSourceContent (srcWinInfo, EMPTY_SOURCE_PROMPT);
1189 }
1190 else
1191 {
1192 TuiWinInfoPtr firstWin, secondWin;
1193
1194 if (curLayout == SRC_DISASSEM_COMMAND)
1195 {
1196 firstWin = srcWin;
1197 secondWin = disassemWin;
1198 }
1199 else
1200 {
1201 firstWin = dataWin;
1202 secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1203 }
1204 if (primaryWinInfo == cmdWin)
1205 { /*
1206 ** Split the change in height accross the 1st & 2nd windows
1207 ** adjusting them as well.
1208 */
1209 int firstSplitDiff = diff / 2; /* subtract the locator */
1210 int secondSplitDiff = firstSplitDiff;
1211
1212 if (diff % 2)
1213 {
1214 if (firstWin->generic.height >
1215 secondWin->generic.height)
1216 if (diff < 0)
1217 firstSplitDiff--;
1218 else
1219 firstSplitDiff++;
1220 else
1221 {
1222 if (diff < 0)
1223 secondSplitDiff--;
1224 else
1225 secondSplitDiff++;
1226 }
1227 }
1228 /* make sure that the minimum hieghts are honored */
1229 while ((firstWin->generic.height + firstSplitDiff) < 3)
1230 {
1231 firstSplitDiff++;
1232 secondSplitDiff--;
1233 }
1234 while ((secondWin->generic.height + secondSplitDiff) < 3)
1235 {
1236 secondSplitDiff++;
1237 firstSplitDiff--;
1238 }
1239 _makeInvisibleAndSetNewHeight (
1240 firstWin,
1241 firstWin->generic.height + firstSplitDiff);
1242 secondWin->generic.origin.y = firstWin->generic.height - 1;
1243 _makeInvisibleAndSetNewHeight (
1244 secondWin, secondWin->generic.height + secondSplitDiff);
1245 cmdWin->generic.origin.y = locator->origin.y + 1;
1246 _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
1247 }
1248 else
1249 {
1250 if ((cmdWin->generic.height + diff) < 1)
1251 { /*
1252 ** If there is no way to increase the command window
1253 ** take real estate from the 1st or 2nd window.
1254 */
1255 if ((cmdWin->generic.height + diff) < 1)
1256 {
1257 int i;
1258 for (i = cmdWin->generic.height + diff;
1259 (i < 1); i++)
1260 if (primaryWinInfo == firstWin)
1261 secondWin->generic.height--;
1262 else
1263 firstWin->generic.height--;
1264 }
1265 }
1266 if (primaryWinInfo == firstWin)
1267 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
1268 else
1269 _makeInvisibleAndSetNewHeight (
1270 firstWin,
1271 firstWin->generic.height);
1272 secondWin->generic.origin.y = firstWin->generic.height - 1;
1273 if (primaryWinInfo == secondWin)
1274 _makeInvisibleAndSetNewHeight (secondWin, newHeight);
1275 else
1276 _makeInvisibleAndSetNewHeight (
1277 secondWin, secondWin->generic.height);
1278 cmdWin->generic.origin.y = locator->origin.y + 1;
1279 if ((cmdWin->generic.height + diff) < 1)
1280 _makeInvisibleAndSetNewHeight (cmdWin, 1);
1281 else
1282 _makeInvisibleAndSetNewHeight (
1283 cmdWin, cmdWin->generic.height + diff);
1284 }
1285 _makeVisibleWithNewHeight (cmdWin);
1286 _makeVisibleWithNewHeight (secondWin);
1287 _makeVisibleWithNewHeight (firstWin);
1288 if (firstWin->generic.contentSize <= 0)
1289 tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
1290 if (secondWin->generic.contentSize <= 0)
1291 tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
1292 }
1293 }
1294 }
1295
1296 return status;
1297 } /* _tuiAdjustWinHeights */
1298
1299
1300 /*
1301 ** _makeInvisibleAndSetNewHeight().
1302 ** Function make the target window (and auxillary windows associated
1303 ** with the targer) invisible, and set the new height and location.
1304 */
1305 static void
1306 _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height)
1307 {
1308 int i;
1309 TuiGenWinInfoPtr genWinInfo;
1310
1311
1312 m_beInvisible (&winInfo->generic);
1313 winInfo->generic.height = height;
1314 if (height > 1)
1315 winInfo->generic.viewportHeight = height - 1;
1316 else
1317 winInfo->generic.viewportHeight = height;
1318 if (winInfo != cmdWin)
1319 winInfo->generic.viewportHeight--;
1320
1321 /* Now deal with the auxillary windows associated with winInfo */
1322 switch (winInfo->generic.type)
1323 {
1324 case SRC_WIN:
1325 case DISASSEM_WIN:
1326 genWinInfo = winInfo->detail.sourceInfo.executionInfo;
1327 m_beInvisible (genWinInfo);
1328 genWinInfo->height = height;
1329 genWinInfo->origin.y = winInfo->generic.origin.y;
1330 if (height > 1)
1331 genWinInfo->viewportHeight = height - 1;
1332 else
1333 genWinInfo->viewportHeight = height;
1334 if (winInfo != cmdWin)
1335 genWinInfo->viewportHeight--;
1336
1337 if (m_hasLocator (winInfo))
1338 {
1339 genWinInfo = locatorWinInfoPtr ();
1340 m_beInvisible (genWinInfo);
1341 genWinInfo->origin.y = winInfo->generic.origin.y + height;
1342 }
1343 break;
1344 case DATA_WIN:
1345 /* delete all data item windows */
1346 for (i = 0; i < winInfo->generic.contentSize; i++)
1347 {
1348 genWinInfo = (TuiGenWinInfoPtr) & ((TuiWinElementPtr)
1349 winInfo->generic.content[i])->whichElement.dataWindow;
1350 tuiDelwin (genWinInfo->handle);
1351 genWinInfo->handle = (WINDOW *) NULL;
1352 }
1353 break;
1354 default:
1355 break;
1356 }
1357 }
1358
1359
1360 /*
1361 ** _makeVisibleWithNewHeight().
1362 ** Function to make the windows with new heights visible.
1363 ** This means re-creating the windows' content since the window
1364 ** had to be destroyed to be made invisible.
1365 */
1366 static void
1367 _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo)
1368 {
1369 struct symtab *s;
1370
1371 m_beVisible (&winInfo->generic);
1372 checkAndDisplayHighlightIfNeeded (winInfo);
1373 switch (winInfo->generic.type)
1374 {
1375 case SRC_WIN:
1376 case DISASSEM_WIN:
1377 freeWinContent (winInfo->detail.sourceInfo.executionInfo);
1378 m_beVisible (winInfo->detail.sourceInfo.executionInfo);
1379 if (winInfo->generic.content != (OpaquePtr) NULL)
1380 {
1381 TuiLineOrAddress lineOrAddr;
1382 struct symtab_and_line cursal
1383 = get_current_source_symtab_and_line ();
1384
1385 if (winInfo->generic.type == SRC_WIN)
1386 lineOrAddr.lineNo =
1387 winInfo->detail.sourceInfo.startLineOrAddr.lineNo;
1388 else
1389 lineOrAddr.addr =
1390 winInfo->detail.sourceInfo.startLineOrAddr.addr;
1391 freeWinContent (&winInfo->generic);
1392 tuiUpdateSourceWindow (winInfo,
1393 cursal.symtab, lineOrAddr, TRUE);
1394 }
1395 else if (deprecated_selected_frame != (struct frame_info *) NULL)
1396 {
1397 TuiLineOrAddress line;
1398 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
1399
1400
1401 s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
1402 if (winInfo->generic.type == SRC_WIN)
1403 line.lineNo = cursal.line;
1404 else
1405 {
1406 find_line_pc (s, cursal.line, &line.addr);
1407 }
1408 tuiUpdateSourceWindow (winInfo, s, line, TRUE);
1409 }
1410 if (m_hasLocator (winInfo))
1411 {
1412 m_beVisible (locatorWinInfoPtr ());
1413 tui_show_locator_content ();
1414 }
1415 break;
1416 case DATA_WIN:
1417 tuiDisplayAllData ();
1418 break;
1419 case CMD_WIN:
1420 winInfo->detail.commandInfo.curLine = 0;
1421 winInfo->detail.commandInfo.curch = 0;
1422 wmove (winInfo->generic.handle,
1423 winInfo->detail.commandInfo.curLine,
1424 winInfo->detail.commandInfo.curch);
1425 break;
1426 default:
1427 break;
1428 }
1429
1430 return;
1431 } /* _makeVisibleWithNewHeight */
1432
1433
1434 static int
1435 _newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight)
1436 {
1437 int ok = (newHeight < termHeight ());
1438
1439 if (ok)
1440 {
1441 int diff;
1442 TuiLayoutType curLayout = currentLayout ();
1443
1444 diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1445 if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1446 {
1447 ok = ((primaryWinInfo->generic.type == CMD_WIN &&
1448 newHeight <= (termHeight () - 4) &&
1449 newHeight >= MIN_CMD_WIN_HEIGHT) ||
1450 (primaryWinInfo->generic.type != CMD_WIN &&
1451 newHeight <= (termHeight () - 2) &&
1452 newHeight >= MIN_WIN_HEIGHT));
1453 if (ok)
1454 { /* check the total height */
1455 TuiWinInfoPtr winInfo;
1456
1457 if (primaryWinInfo == cmdWin)
1458 winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1459 else
1460 winInfo = cmdWin;
1461 ok = ((newHeight +
1462 (winInfo->generic.height + diff)) <= termHeight ());
1463 }
1464 }
1465 else
1466 {
1467 int curTotalHeight, totalHeight, minHeight = 0;
1468 TuiWinInfoPtr firstWin, secondWin;
1469
1470 if (curLayout == SRC_DISASSEM_COMMAND)
1471 {
1472 firstWin = srcWin;
1473 secondWin = disassemWin;
1474 }
1475 else
1476 {
1477 firstWin = dataWin;
1478 secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1479 }
1480 /*
1481 ** We could simply add all the heights to obtain the same result
1482 ** but below is more explicit since we subtract 1 for the
1483 ** line that the first and second windows share, and add one
1484 ** for the locator.
1485 */
1486 totalHeight = curTotalHeight =
1487 (firstWin->generic.height + secondWin->generic.height - 1)
1488 + cmdWin->generic.height + 1 /*locator */ ;
1489 if (primaryWinInfo == cmdWin)
1490 {
1491 /* locator included since first & second win share a line */
1492 ok = ((firstWin->generic.height +
1493 secondWin->generic.height + diff) >=
1494 (MIN_WIN_HEIGHT * 2) &&
1495 newHeight >= MIN_CMD_WIN_HEIGHT);
1496 if (ok)
1497 {
1498 totalHeight = newHeight + (firstWin->generic.height +
1499 secondWin->generic.height + diff);
1500 minHeight = MIN_CMD_WIN_HEIGHT;
1501 }
1502 }
1503 else
1504 {
1505 minHeight = MIN_WIN_HEIGHT;
1506 /*
1507 ** First see if we can increase/decrease the command
1508 ** window. And make sure that the command window is
1509 ** at least 1 line
1510 */
1511 ok = ((cmdWin->generic.height + diff) > 0);
1512 if (!ok)
1513 { /*
1514 ** Looks like we have to increase/decrease one of
1515 ** the other windows
1516 */
1517 if (primaryWinInfo == firstWin)
1518 ok = (secondWin->generic.height + diff) >= minHeight;
1519 else
1520 ok = (firstWin->generic.height + diff) >= minHeight;
1521 }
1522 if (ok)
1523 {
1524 if (primaryWinInfo == firstWin)
1525 totalHeight = newHeight +
1526 secondWin->generic.height +
1527 cmdWin->generic.height + diff;
1528 else
1529 totalHeight = newHeight +
1530 firstWin->generic.height +
1531 cmdWin->generic.height + diff;
1532 }
1533 }
1534 /*
1535 ** Now make sure that the proposed total height doesn't exceed
1536 ** the old total height.
1537 */
1538 if (ok)
1539 ok = (newHeight >= minHeight && totalHeight <= curTotalHeight);
1540 }
1541 }
1542
1543 return ok;
1544 } /* _newHeightOk */
1545
1546
1547 /*
1548 ** _parseScrollingArgs().
1549 */
1550 static void
1551 _parseScrollingArgs (char *arg, TuiWinInfoPtr * winToScroll, int *numToScroll)
1552 {
1553 if (numToScroll)
1554 *numToScroll = 0;
1555 *winToScroll = tuiWinWithFocus ();
1556
1557 /*
1558 ** First set up the default window to scroll, in case there is no
1559 ** window name arg
1560 */
1561 if (arg != (char *) NULL)
1562 {
1563 char *buf, *bufPtr;
1564
1565 /* process the number of lines to scroll */
1566 buf = bufPtr = xstrdup (arg);
1567 if (isdigit (*bufPtr))
1568 {
1569 char *numStr;
1570
1571 numStr = bufPtr;
1572 bufPtr = strchr (bufPtr, ' ');
1573 if (bufPtr != (char *) NULL)
1574 {
1575 *bufPtr = (char) 0;
1576 if (numToScroll)
1577 *numToScroll = atoi (numStr);
1578 bufPtr++;
1579 }
1580 else if (numToScroll)
1581 *numToScroll = atoi (numStr);
1582 }
1583
1584 /* process the window name if one is specified */
1585 if (bufPtr != (char *) NULL)
1586 {
1587 char *wname;
1588 int i;
1589
1590 if (*bufPtr == ' ')
1591 while (*(++bufPtr) == ' ')
1592 ;
1593
1594 if (*bufPtr != (char) 0)
1595 wname = bufPtr;
1596 else
1597 wname = "?";
1598
1599 /* Validate the window name */
1600 for (i = 0; i < strlen (wname); i++)
1601 wname[i] = toupper (wname[i]);
1602 *winToScroll = partialWinByName (wname);
1603
1604 if (*winToScroll == (TuiWinInfoPtr) NULL ||
1605 !(*winToScroll)->generic.isVisible)
1606 warning ("Invalid window specified. \n\
1607 The window name specified must be valid and visible.\n");
1608 else if (*winToScroll == cmdWin)
1609 *winToScroll = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1610 }
1611 tuiFree (buf);
1612 }
1613
1614 return;
1615 } /* _parseScrollingArgs */