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