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