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