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