* tuiStack.c: Add missing includes.
[deliverable/binutils-gdb.git] / gdb / tui / tuiWin.c
1 /* TUI window generic functions.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* This module contains procedures for handling tui window functions
23 like resize, scrolling, scrolling, changing focus, etc.
24
25 Author: Susan B. Macchia */
26
27 #include <string.h>
28 #include "defs.h"
29 #include "command.h"
30 #include "symtab.h"
31 #include "breakpoint.h"
32 #include "frame.h"
33
34 #include "tui.h"
35 #include "tuiData.h"
36 #include "tuiGeneralWin.h"
37 #include "tuiStack.h"
38 #include "tuiSourceWin.h"
39 #include "tuiDataWin.h"
40
41 /*******************************
42 ** External Declarations
43 ********************************/
44 extern void init_page_info ();
45
46 /*******************************
47 ** Static Local Decls
48 ********************************/
49 static void _makeVisibleWithNewHeight (TuiWinInfoPtr);
50 static void _makeInvisibleAndSetNewHeight (TuiWinInfoPtr, int);
51 static TuiStatus _tuiAdjustWinHeights (TuiWinInfoPtr, int);
52 static int _newHeightOk (TuiWinInfoPtr, int);
53 static void _tuiSetTabWidth_command (char *, int);
54 static void _tuiRefreshAll_command (char *, int);
55 static void _tuiSetWinHeight_command (char *, int);
56 static void _tuiXDBsetWinHeight_command (char *, int);
57 static void _tuiAllWindowsInfo (char *, int);
58 static void _tuiSetFocus_command (char *, int);
59 static void _tuiScrollForward_command (char *, int);
60 static void _tuiScrollBackward_command (char *, int);
61 static void _tuiScrollLeft_command (char *, int);
62 static void _tuiScrollRight_command (char *, int);
63 static void _parseScrollingArgs (char *, TuiWinInfoPtr *, int *);
64
65
66 /***************************************
67 ** DEFINITIONS
68 ***************************************/
69 #define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
70 #define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
71 #define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
72
73 /***************************************
74 ** PUBLIC FUNCTIONS
75 ***************************************/
76
77 /*
78 ** _initialize_tuiWin().
79 ** Function to initialize gdb commands, for tui window manipulation.
80 */
81 void
82 _initialize_tuiWin (void)
83 {
84 if (tui_version)
85 {
86 add_com ("refresh", class_tui, _tuiRefreshAll_command,
87 "Refresh the terminal display.\n");
88 if (xdb_commands)
89 add_com_alias ("U", "refresh", class_tui, 0);
90 add_com ("tabset", class_tui, _tuiSetTabWidth_command,
91 "Set the width (in characters) of tab stops.\n\
92 Usage: tabset <n>\n");
93 add_com ("winheight", class_tui, _tuiSetWinHeight_command,
94 "Set the height of a specified window.\n\
95 Usage: winheight <win_name> [+ | -] <#lines>\n\
96 Window names are:\n\
97 src : the source window\n\
98 cmd : the command window\n\
99 asm : the disassembly window\n\
100 regs : the register display\n");
101 add_com_alias ("wh", "winheight", class_tui, 0);
102 add_info ("win", _tuiAllWindowsInfo,
103 "List of all displayed windows.\n");
104 add_com ("focus", class_tui, _tuiSetFocus_command,
105 "Set focus to named window or next/prev window.\n\
106 Usage: focus {<win> | next | prev}\n\
107 Valid Window names are:\n\
108 src : the source window\n\
109 asm : the disassembly window\n\
110 regs : the register display\n\
111 cmd : the command window\n");
112 add_com_alias ("fs", "focus", class_tui, 0);
113 add_com ("+", class_tui, _tuiScrollForward_command,
114 "Scroll window forward.\nUsage: + [win] [n]\n");
115 add_com ("-", class_tui, _tuiScrollBackward_command,
116 "Scroll window backward.\nUsage: - [win] [n]\n");
117 add_com ("<", class_tui, _tuiScrollLeft_command,
118 "Scroll window forward.\nUsage: < [win] [n]\n");
119 add_com (">", class_tui, _tuiScrollRight_command,
120 "Scroll window backward.\nUsage: > [win] [n]\n");
121 if (xdb_commands)
122 add_com ("w", class_xdb, _tuiXDBsetWinHeight_command,
123 "XDB compatibility command for setting the height of a command window.\n\
124 Usage: w <#lines>\n");
125 }
126
127 return;
128 } /* _intialize_tuiWin */
129
130
131 /*
132 ** tuiClearWinFocusFrom
133 ** Clear the logical focus from winInfo
134 */
135 void
136 tuiClearWinFocusFrom (TuiWinInfoPtr winInfo)
137 {
138 if (m_winPtrNotNull (winInfo))
139 {
140 if (winInfo->generic.type != CMD_WIN)
141 unhighlightWin (winInfo);
142 tuiSetWinWithFocus ((TuiWinInfoPtr) NULL);
143 }
144
145 return;
146 } /* tuiClearWinFocusFrom */
147
148
149 /*
150 ** tuiClearWinFocus().
151 ** Clear the window that has focus.
152 */
153 void
154 tuiClearWinFocus (void)
155 {
156 tuiClearWinFocusFrom (tuiWinWithFocus ());
157
158 return;
159 } /* tuiClearWinFocus */
160
161
162 /*
163 ** tuiSetWinFocusTo
164 ** Set the logical focus to winInfo
165 */
166 void
167 tuiSetWinFocusTo (TuiWinInfoPtr winInfo)
168 {
169 if (m_winPtrNotNull (winInfo))
170 {
171 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
172
173 if (m_winPtrNotNull (winWithFocus) &&
174 winWithFocus->generic.type != CMD_WIN)
175 unhighlightWin (winWithFocus);
176 tuiSetWinWithFocus (winInfo);
177 if (winInfo->generic.type != CMD_WIN)
178 highlightWin (winInfo);
179 }
180
181 return;
182 } /* tuiSetWinFocusTo */
183
184
185 char *
186 tuiStrDup (char *str)
187 {
188 char *newStr = (char *) NULL;
189
190 if (str != (char *) NULL)
191 {
192 newStr = (char *) xmalloc (strlen (str) + 1);
193 strcpy (newStr, str);
194 }
195
196 return newStr;
197 } /* tuiStrDup */
198
199
200 /*
201 ** tuiScrollForward().
202 */
203 void
204 tuiScrollForward (TuiWinInfoPtr winToScroll, int numToScroll)
205 {
206 if (winToScroll != cmdWin)
207 {
208 int _numToScroll = numToScroll;
209
210 if (numToScroll == 0)
211 _numToScroll = winToScroll->generic.height - 3;
212 /*
213 ** If we are scrolling the source or disassembly window, do a
214 ** "psuedo" scroll since not all of the source is in memory,
215 ** only what is in the viewport. If winToScroll is the
216 ** command window do nothing since the term should handle it.
217 */
218 if (winToScroll == srcWin)
219 tuiVerticalSourceScroll (FORWARD_SCROLL, _numToScroll);
220 else if (winToScroll == disassemWin)
221 tuiVerticalDisassemScroll (FORWARD_SCROLL, _numToScroll);
222 else if (winToScroll == dataWin)
223 tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll);
224 }
225
226 return;
227 } /* tuiScrollForward */
228
229
230 /*
231 ** tuiScrollBackward().
232 */
233 void
234 tuiScrollBackward (TuiWinInfoPtr winToScroll, int numToScroll)
235 {
236 if (winToScroll != cmdWin)
237 {
238 int _numToScroll = numToScroll;
239
240 if (numToScroll == 0)
241 _numToScroll = winToScroll->generic.height - 3;
242 /*
243 ** If we are scrolling the source or disassembly window, do a
244 ** "psuedo" scroll since not all of the source is in memory,
245 ** only what is in the viewport. If winToScroll is the
246 ** command window do nothing since the term should handle it.
247 */
248 if (winToScroll == srcWin)
249 tuiVerticalSourceScroll (BACKWARD_SCROLL, _numToScroll);
250 else if (winToScroll == disassemWin)
251 tuiVerticalDisassemScroll (BACKWARD_SCROLL, _numToScroll);
252 else if (winToScroll == dataWin)
253 tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll);
254 }
255 return;
256 } /* tuiScrollBackward */
257
258
259 /*
260 ** tuiScrollLeft().
261 */
262 void
263 tuiScrollLeft (TuiWinInfoPtr winToScroll, int numToScroll)
264 {
265 if (winToScroll != cmdWin)
266 {
267 int _numToScroll = numToScroll;
268
269 if (_numToScroll == 0)
270 _numToScroll = 1;
271 /*
272 ** If we are scrolling the source or disassembly window, do a
273 ** "psuedo" scroll since not all of the source is in memory,
274 ** only what is in the viewport. If winToScroll is the
275 ** command window do nothing since the term should handle it.
276 */
277 if (winToScroll == srcWin || winToScroll == disassemWin)
278 tuiHorizontalSourceScroll (winToScroll, LEFT_SCROLL, _numToScroll);
279 }
280 return;
281 } /* tuiScrollLeft */
282
283
284 /*
285 ** tuiScrollRight().
286 */
287 void
288 tuiScrollRight (TuiWinInfoPtr winToScroll, int numToScroll)
289 {
290 if (winToScroll != cmdWin)
291 {
292 int _numToScroll = numToScroll;
293
294 if (_numToScroll == 0)
295 _numToScroll = 1;
296 /*
297 ** If we are scrolling the source or disassembly window, do a
298 ** "psuedo" scroll since not all of the source is in memory,
299 ** only what is in the viewport. If winToScroll is the
300 ** command window do nothing since the term should handle it.
301 */
302 if (winToScroll == srcWin || winToScroll == disassemWin)
303 tuiHorizontalSourceScroll (winToScroll, RIGHT_SCROLL, _numToScroll);
304 }
305 return;
306 } /* tuiScrollRight */
307
308
309 /*
310 ** tui_vScroll().
311 ** Scroll a window. Arguments are passed through a va_list.
312 */
313 void
314 tui_vScroll (va_list args)
315 {
316 TuiScrollDirection direction = va_arg (args, TuiScrollDirection);
317 TuiWinInfoPtr winToScroll = va_arg (args, TuiWinInfoPtr);
318 int numToScroll = va_arg (args, int);
319
320 switch (direction)
321 {
322 case FORWARD_SCROLL:
323 tuiScrollForward (winToScroll, numToScroll);
324 break;
325 case BACKWARD_SCROLL:
326 tuiScrollBackward (winToScroll, numToScroll);
327 break;
328 case LEFT_SCROLL:
329 tuiScrollLeft (winToScroll, numToScroll);
330 break;
331 case RIGHT_SCROLL:
332 tuiScrollRight (winToScroll, numToScroll);
333 break;
334 default:
335 break;
336 }
337
338 return;
339 } /* tui_vScroll */
340
341
342 /*
343 ** tuiRefreshAll().
344 */
345 void
346 tuiRefreshAll (void)
347 {
348 TuiWinType type;
349
350 refreshAll (winList);
351 for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
352 {
353 if (winList[type] && winList[type]->generic.isVisible)
354 {
355 switch (type)
356 {
357 case SRC_WIN:
358 case DISASSEM_WIN:
359 tuiClearWin (&winList[type]->generic);
360 if (winList[type]->detail.sourceInfo.hasLocator)
361 tuiClearLocatorDisplay ();
362 tuiShowSourceContent (winList[type]);
363 checkAndDisplayHighlightIfNeeded (winList[type]);
364 tuiEraseExecInfoContent (winList[type]);
365 tuiUpdateExecInfo (winList[type]);
366 break;
367 case DATA_WIN:
368 tuiRefreshDataWin ();
369 break;
370 default:
371 break;
372 }
373 }
374 }
375 tuiClearLocatorDisplay ();
376 tuiShowLocatorContent ();
377
378 return;
379 } /* tuiRefreshAll */
380
381
382 /*
383 ** tuiResizeAll().
384 ** Resize all the windows based on the the terminal size. This
385 ** function gets called from within the readline sinwinch handler.
386 */
387 void
388 tuiResizeAll (void)
389 {
390 int heightDiff, widthDiff;
391 extern int screenheight, screenwidth; /* in readline */
392
393 widthDiff = screenwidth - termWidth ();
394 heightDiff = screenheight - termHeight ();
395 if (heightDiff || widthDiff)
396 {
397 TuiLayoutType curLayout = currentLayout ();
398 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
399 TuiWinInfoPtr firstWin, secondWin;
400 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
401 TuiWinType winType;
402 int i, newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
403
404 /* turn keypad off while we resize */
405 if (winWithFocus != cmdWin)
406 keypad (cmdWin->generic.handle, FALSE);
407 init_page_info ();
408 setTermHeightTo (screenheight);
409 setTermWidthTo (screenwidth);
410 if (curLayout == SRC_DISASSEM_COMMAND ||
411 curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND)
412 numWinsDisplayed++;
413 splitDiff = heightDiff / numWinsDisplayed;
414 cmdSplitDiff = splitDiff;
415 if (heightDiff % numWinsDisplayed)
416 {
417 if (heightDiff < 0)
418 cmdSplitDiff--;
419 else
420 cmdSplitDiff++;
421 }
422 /* now adjust each window */
423 clear ();
424 refresh ();
425 switch (curLayout)
426 {
427 case SRC_COMMAND:
428 case DISASSEM_COMMAND:
429 firstWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
430 firstWin->generic.width += widthDiff;
431 locator->width += widthDiff;
432 /* check for invalid heights */
433 if (heightDiff == 0)
434 newHeight = firstWin->generic.height;
435 else if ((firstWin->generic.height + splitDiff) >=
436 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
437 newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
438 else if ((firstWin->generic.height + splitDiff) <= 0)
439 newHeight = MIN_WIN_HEIGHT;
440 else
441 newHeight = firstWin->generic.height + splitDiff;
442
443 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
444 cmdWin->generic.origin.y = locator->origin.y + 1;
445 cmdWin->generic.width += widthDiff;
446 newHeight = screenheight - cmdWin->generic.origin.y;
447 _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
448 _makeVisibleWithNewHeight (firstWin);
449 _makeVisibleWithNewHeight (cmdWin);
450 if (firstWin->generic.contentSize <= 0)
451 tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
452 break;
453 default:
454 if (curLayout == SRC_DISASSEM_COMMAND)
455 {
456 firstWin = srcWin;
457 firstWin->generic.width += widthDiff;
458 secondWin = disassemWin;
459 secondWin->generic.width += widthDiff;
460 }
461 else
462 {
463 firstWin = dataWin;
464 firstWin->generic.width += widthDiff;
465 secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
466 secondWin->generic.width += widthDiff;
467 }
468 /* Change the first window's height/width */
469 /* check for invalid heights */
470 if (heightDiff == 0)
471 newHeight = firstWin->generic.height;
472 else if ((firstWin->generic.height +
473 secondWin->generic.height + (splitDiff * 2)) >=
474 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
475 newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
476 else if ((firstWin->generic.height + splitDiff) <= 0)
477 newHeight = MIN_WIN_HEIGHT;
478 else
479 newHeight = firstWin->generic.height + splitDiff;
480 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
481
482 if (firstWin == dataWin && widthDiff != 0)
483 firstWin->detail.dataDisplayInfo.regsColumnCount =
484 tuiCalculateRegsColumnCount (
485 firstWin->detail.dataDisplayInfo.regsDisplayType);
486 locator->width += widthDiff;
487
488 /* Change the second window's height/width */
489 /* check for invalid heights */
490 if (heightDiff == 0)
491 newHeight = secondWin->generic.height;
492 else if ((firstWin->generic.height +
493 secondWin->generic.height + (splitDiff * 2)) >=
494 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
495 {
496 newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
497 if (newHeight % 2)
498 newHeight = (newHeight / 2) + 1;
499 else
500 newHeight /= 2;
501 }
502 else if ((secondWin->generic.height + splitDiff) <= 0)
503 newHeight = MIN_WIN_HEIGHT;
504 else
505 newHeight = secondWin->generic.height + splitDiff;
506 secondWin->generic.origin.y = firstWin->generic.height - 1;
507 _makeInvisibleAndSetNewHeight (secondWin, newHeight);
508
509 /* Change the command window's height/width */
510 cmdWin->generic.origin.y = locator->origin.y + 1;
511 _makeInvisibleAndSetNewHeight (
512 cmdWin, cmdWin->generic.height + cmdSplitDiff);
513 _makeVisibleWithNewHeight (firstWin);
514 _makeVisibleWithNewHeight (secondWin);
515 _makeVisibleWithNewHeight (cmdWin);
516 if (firstWin->generic.contentSize <= 0)
517 tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
518 if (secondWin->generic.contentSize <= 0)
519 tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
520 break;
521 }
522 /*
523 ** Now remove all invisible windows, and their content so that they get
524 ** created again when called for with the new size
525 */
526 for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++)
527 {
528 if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) &&
529 !winList[winType]->generic.isVisible)
530 {
531 freeWindow (winList[winType]);
532 winList[winType] = (TuiWinInfoPtr) NULL;
533 }
534 }
535 tuiSetWinResizedTo (TRUE);
536 /* turn keypad back on, unless focus is in the command window */
537 if (winWithFocus != cmdWin)
538 keypad (cmdWin->generic.handle, TRUE);
539 }
540 return;
541 } /* tuiResizeAll */
542
543
544 /*
545 ** tuiSigwinchHandler()
546 ** SIGWINCH signal handler for the tui. This signal handler is
547 ** always called, even when the readline package clears signals
548 ** because it is set as the old_sigwinch() (TUI only)
549 */
550 void
551 tuiSigwinchHandler (int signal)
552 {
553 /*
554 ** Say that a resize was done so that the readline can do it
555 ** later when appropriate.
556 */
557 tuiSetWinResizedTo (TRUE);
558
559 return;
560 } /* tuiSigwinchHandler */
561
562
563
564 /*************************
565 ** STATIC LOCAL FUNCTIONS
566 **************************/
567
568
569 /*
570 ** _tuiScrollForward_command().
571 */
572 static void
573 _tuiScrollForward_command (char *arg, int fromTTY)
574 {
575 int numToScroll = 1;
576 TuiWinInfoPtr winToScroll;
577
578 if (arg == (char *) NULL)
579 _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
580 else
581 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
582 tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
583 FORWARD_SCROLL,
584 winToScroll,
585 numToScroll);
586
587 return;
588 } /* _tuiScrollForward_command */
589
590
591 /*
592 ** _tuiScrollBackward_command().
593 */
594 static void
595 _tuiScrollBackward_command (char *arg, int fromTTY)
596 {
597 int numToScroll = 1;
598 TuiWinInfoPtr winToScroll;
599
600 if (arg == (char *) NULL)
601 _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
602 else
603 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
604 tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
605 BACKWARD_SCROLL,
606 winToScroll,
607 numToScroll);
608
609 return;
610 } /* _tuiScrollBackward_command */
611
612
613 /*
614 ** _tuiScrollLeft_command().
615 */
616 static void
617 _tuiScrollLeft_command (char *arg, int fromTTY)
618 {
619 int numToScroll;
620 TuiWinInfoPtr winToScroll;
621
622 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
623 tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
624 LEFT_SCROLL,
625 winToScroll,
626 numToScroll);
627
628 return;
629 } /* _tuiScrollLeft_command */
630
631
632 /*
633 ** _tuiScrollRight_command().
634 */
635 static void
636 _tuiScrollRight_command (char *arg, int fromTTY)
637 {
638 int numToScroll;
639 TuiWinInfoPtr winToScroll;
640
641 _parseScrollingArgs (arg, &winToScroll, &numToScroll);
642 tuiDo ((TuiOpaqueFuncPtr) tui_vScroll,
643 RIGHT_SCROLL,
644 winToScroll,
645 numToScroll);
646
647 return;
648 } /* _tuiScrollRight_command */
649
650
651 /*
652 ** _tuiSetFocus().
653 ** Set focus to the window named by 'arg'
654 */
655 static void
656 _tuiSetFocus (char *arg, int fromTTY)
657 {
658 if (arg != (char *) NULL)
659 {
660 char *bufPtr = (char *) tuiStrDup (arg);
661 int i;
662 TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
663
664 for (i = 0; (i < strlen (bufPtr)); i++)
665 bufPtr[i] = toupper (arg[i]);
666
667 if (subsetCompare (bufPtr, "NEXT"))
668 winInfo = tuiNextWin (tuiWinWithFocus ());
669 else if (subsetCompare (bufPtr, "PREV"))
670 winInfo = tuiPrevWin (tuiWinWithFocus ());
671 else
672 winInfo = partialWinByName (bufPtr);
673
674 if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
675 warning ("Invalid window specified. \n\
676 The window name specified must be valid and visible.\n");
677 else
678 {
679 tuiSetWinFocusTo (winInfo);
680 keypad (cmdWin->generic.handle, (winInfo != cmdWin));
681 }
682
683 if (dataWin && dataWin->generic.isVisible)
684 tuiRefreshDataWin ();
685 tuiFree (bufPtr);
686 printf_filtered ("Focus set to %s window.\n",
687 winName ((TuiGenWinInfoPtr) tuiWinWithFocus ()));
688 }
689 else
690 warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE);
691
692 return;
693 } /* _tuiSetFocus */
694
695
696 /*
697 ** _tui_vSetFocus()
698 */
699 static void
700 _tui_vSetFocus (va_list args)
701 {
702 char *arg = va_arg (args, char *);
703 int fromTTY = va_arg (args, int);
704
705 _tuiSetFocus (arg, fromTTY);
706
707 return;
708 } /* tui_vSetFocus */
709
710
711 /*
712 ** _tuiSetFocus_command()
713 */
714 static void
715 _tuiSetFocus_command (char *arg, int fromTTY)
716 {
717 tuiDo ((TuiOpaqueFuncPtr) _tui_vSetFocus, arg, fromTTY);
718
719 return;
720 } /* tui_SetFocus */
721
722
723 /*
724 ** _tuiAllWindowsInfo().
725 */
726 static void
727 _tuiAllWindowsInfo (char *arg, int fromTTY)
728 {
729 TuiWinType type;
730 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
731
732 for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
733 if (winList[type]->generic.isVisible)
734 {
735 if (winWithFocus == winList[type])
736 printf_filtered (" %s\t(%d lines) <has focus>\n",
737 winName (&winList[type]->generic),
738 winList[type]->generic.height);
739 else
740 printf_filtered (" %s\t(%d lines)\n",
741 winName (&winList[type]->generic),
742 winList[type]->generic.height);
743 }
744
745 return;
746 } /* _tuiAllWindowsInfo */
747
748
749 /*
750 ** _tuiRefreshAll_command().
751 */
752 static void
753 _tuiRefreshAll_command (char *arg, int fromTTY)
754 {
755 tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll);
756 }
757
758
759 /*
760 ** _tuiSetWinTabWidth_command().
761 ** Set the height of the specified window.
762 */
763 static void
764 _tuiSetTabWidth_command (char *arg, int fromTTY)
765 {
766 if (arg != (char *) NULL)
767 {
768 int ts;
769
770 ts = atoi (arg);
771 if (ts > 0)
772 tuiSetDefaultTabLen (ts);
773 else
774 warning ("Tab widths greater than 0 must be specified.\n");
775 }
776
777 return;
778 } /* _tuiSetTabWidth_command */
779
780
781 /*
782 ** _tuiSetWinHeight().
783 ** Set the height of the specified window.
784 */
785 static void
786 _tuiSetWinHeight (char *arg, int fromTTY)
787 {
788 if (arg != (char *) NULL)
789 {
790 char *buf = tuiStrDup (arg);
791 char *bufPtr = buf;
792 char *wname = (char *) NULL;
793 int newHeight, i;
794 TuiWinInfoPtr winInfo;
795
796 wname = bufPtr;
797 bufPtr = strchr (bufPtr, ' ');
798 if (bufPtr != (char *) NULL)
799 {
800 *bufPtr = (char) 0;
801
802 /*
803 ** Validate the window name
804 */
805 for (i = 0; i < strlen (wname); i++)
806 wname[i] = toupper (wname[i]);
807 winInfo = partialWinByName (wname);
808
809 if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
810 warning ("Invalid window specified. \n\
811 The window name specified must be valid and visible.\n");
812 else
813 {
814 /* Process the size */
815 while (*(++bufPtr) == ' ')
816 ;
817
818 if (*bufPtr != (char) 0)
819 {
820 int negate = FALSE;
821 int fixedSize = TRUE;
822 int inputNo;;
823
824 if (*bufPtr == '+' || *bufPtr == '-')
825 {
826 if (*bufPtr == '-')
827 negate = TRUE;
828 fixedSize = FALSE;
829 bufPtr++;
830 }
831 inputNo = atoi (bufPtr);
832 if (inputNo > 0)
833 {
834 if (negate)
835 inputNo *= (-1);
836 if (fixedSize)
837 newHeight = inputNo;
838 else
839 newHeight = winInfo->generic.height + inputNo;
840 /*
841 ** Now change the window's height, and adjust all
842 ** other windows around it
843 */
844 if (_tuiAdjustWinHeights (winInfo,
845 newHeight) == TUI_FAILURE)
846 warning ("Invalid window height specified.\n%s",
847 WIN_HEIGHT_USAGE);
848 else
849 init_page_info ();
850 }
851 else
852 warning ("Invalid window height specified.\n%s",
853 WIN_HEIGHT_USAGE);
854 }
855 }
856 }
857 else
858 printf_filtered (WIN_HEIGHT_USAGE);
859
860 if (buf != (char *) NULL)
861 tuiFree (buf);
862 }
863 else
864 printf_filtered (WIN_HEIGHT_USAGE);
865
866 return;
867 } /* _tuiSetWinHeight */
868
869
870 /*
871 ** _tui_vSetWinHeight().
872 ** Set the height of the specified window, with va_list.
873 */
874 static void
875 _tui_vSetWinHeight (va_list args)
876 {
877 char *arg = va_arg (args, char *);
878 int fromTTY = va_arg (args, int);
879
880 _tuiSetWinHeight (arg, fromTTY);
881
882 return;
883 } /* _tui_vSetWinHeight */
884
885
886 /*
887 ** _tuiSetWinHeight_command().
888 ** Set the height of the specified window, with va_list.
889 */
890 static void
891 _tuiSetWinHeight_command (char *arg, int fromTTY)
892 {
893 tuiDo ((TuiOpaqueFuncPtr) _tui_vSetWinHeight, arg, fromTTY);
894
895 return;
896 } /* _tuiSetWinHeight_command */
897
898
899 /*
900 ** _tuiXDBsetWinHeight().
901 ** XDB Compatibility command for setting the window height. This will
902 ** increase or decrease the command window by the specified amount.
903 */
904 static void
905 _tuiXDBsetWinHeight (char *arg, int fromTTY)
906 {
907 if (arg != (char *) NULL)
908 {
909 int inputNo = atoi (arg);
910
911 if (inputNo > 0)
912 { /* Add 1 for the locator */
913 int newHeight = termHeight () - (inputNo + 1);
914
915 if (!_newHeightOk (winList[CMD_WIN], newHeight) ||
916 _tuiAdjustWinHeights (winList[CMD_WIN],
917 newHeight) == TUI_FAILURE)
918 warning ("Invalid window height specified.\n%s",
919 XDBWIN_HEIGHT_USAGE);
920 }
921 else
922 warning ("Invalid window height specified.\n%s",
923 XDBWIN_HEIGHT_USAGE);
924 }
925 else
926 warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE);
927
928 return;
929 } /* _tuiXDBsetWinHeight */
930
931
932 /*
933 ** _tui_vXDBsetWinHeight().
934 ** Set the height of the specified window, with va_list.
935 */
936 static void
937 _tui_vXDBsetWinHeight (va_list args)
938 {
939 char *arg = va_arg (args, char *);
940 int fromTTY = va_arg (args, int);
941
942 _tuiXDBsetWinHeight (arg, fromTTY);
943
944 return;
945 } /* _tui_vXDBsetWinHeight */
946
947
948 /*
949 ** _tuiSetWinHeight_command().
950 ** Set the height of the specified window, with va_list.
951 */
952 static void
953 _tuiXDBsetWinHeight_command (char *arg, int fromTTY)
954 {
955 tuiDo ((TuiOpaqueFuncPtr) _tui_vXDBsetWinHeight, arg, fromTTY);
956
957 return;
958 } /* _tuiXDBsetWinHeight_command */
959
960
961 /*
962 ** _tuiAdjustWinHeights().
963 ** Function to adjust all window heights around the primary
964 */
965 static TuiStatus
966 _tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo, int newHeight)
967 {
968 TuiStatus status = TUI_FAILURE;
969
970 if (_newHeightOk (primaryWinInfo, newHeight))
971 {
972 status = TUI_SUCCESS;
973 if (newHeight != primaryWinInfo->generic.height)
974 {
975 int i, diff;
976 TuiWinInfoPtr winInfo;
977 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
978 TuiLayoutType curLayout = currentLayout ();
979
980 diff = (newHeight - primaryWinInfo->generic.height) * (-1);
981 if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
982 {
983 TuiWinInfoPtr srcWinInfo;
984
985 _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight);
986 if (primaryWinInfo->generic.type == CMD_WIN)
987 {
988 winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
989 srcWinInfo = winInfo;
990 }
991 else
992 {
993 winInfo = winList[CMD_WIN];
994 srcWinInfo = primaryWinInfo;
995 }
996 _makeInvisibleAndSetNewHeight (winInfo,
997 winInfo->generic.height + diff);
998 cmdWin->generic.origin.y = locator->origin.y + 1;
999 _makeVisibleWithNewHeight (winInfo);
1000 _makeVisibleWithNewHeight (primaryWinInfo);
1001 if (srcWinInfo->generic.contentSize <= 0)
1002 tuiEraseSourceContent (srcWinInfo, EMPTY_SOURCE_PROMPT);
1003 }
1004 else
1005 {
1006 TuiWinInfoPtr firstWin, secondWin;
1007
1008 if (curLayout == SRC_DISASSEM_COMMAND)
1009 {
1010 firstWin = srcWin;
1011 secondWin = disassemWin;
1012 }
1013 else
1014 {
1015 firstWin = dataWin;
1016 secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1017 }
1018 if (primaryWinInfo == cmdWin)
1019 { /*
1020 ** Split the change in height accross the 1st & 2nd windows
1021 ** adjusting them as well.
1022 */
1023 int firstSplitDiff = diff / 2; /* subtract the locator */
1024 int secondSplitDiff = firstSplitDiff;
1025
1026 if (diff % 2)
1027 {
1028 if (firstWin->generic.height >
1029 secondWin->generic.height)
1030 if (diff < 0)
1031 firstSplitDiff--;
1032 else
1033 firstSplitDiff++;
1034 else
1035 {
1036 if (diff < 0)
1037 secondSplitDiff--;
1038 else
1039 secondSplitDiff++;
1040 }
1041 }
1042 /* make sure that the minimum hieghts are honored */
1043 while ((firstWin->generic.height + firstSplitDiff) < 3)
1044 {
1045 firstSplitDiff++;
1046 secondSplitDiff--;
1047 }
1048 while ((secondWin->generic.height + secondSplitDiff) < 3)
1049 {
1050 secondSplitDiff++;
1051 firstSplitDiff--;
1052 }
1053 _makeInvisibleAndSetNewHeight (
1054 firstWin,
1055 firstWin->generic.height + firstSplitDiff);
1056 secondWin->generic.origin.y = firstWin->generic.height - 1;
1057 _makeInvisibleAndSetNewHeight (
1058 secondWin, secondWin->generic.height + secondSplitDiff);
1059 cmdWin->generic.origin.y = locator->origin.y + 1;
1060 _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
1061 }
1062 else
1063 {
1064 if ((cmdWin->generic.height + diff) < 1)
1065 { /*
1066 ** If there is no way to increase the command window
1067 ** take real estate from the 1st or 2nd window.
1068 */
1069 if ((cmdWin->generic.height + diff) < 1)
1070 {
1071 int i;
1072 for (i = cmdWin->generic.height + diff;
1073 (i < 1); i++)
1074 if (primaryWinInfo == firstWin)
1075 secondWin->generic.height--;
1076 else
1077 firstWin->generic.height--;
1078 }
1079 }
1080 if (primaryWinInfo == firstWin)
1081 _makeInvisibleAndSetNewHeight (firstWin, newHeight);
1082 else
1083 _makeInvisibleAndSetNewHeight (
1084 firstWin,
1085 firstWin->generic.height);
1086 secondWin->generic.origin.y = firstWin->generic.height - 1;
1087 if (primaryWinInfo == secondWin)
1088 _makeInvisibleAndSetNewHeight (secondWin, newHeight);
1089 else
1090 _makeInvisibleAndSetNewHeight (
1091 secondWin, secondWin->generic.height);
1092 cmdWin->generic.origin.y = locator->origin.y + 1;
1093 if ((cmdWin->generic.height + diff) < 1)
1094 _makeInvisibleAndSetNewHeight (cmdWin, 1);
1095 else
1096 _makeInvisibleAndSetNewHeight (
1097 cmdWin, cmdWin->generic.height + diff);
1098 }
1099 _makeVisibleWithNewHeight (cmdWin);
1100 _makeVisibleWithNewHeight (secondWin);
1101 _makeVisibleWithNewHeight (firstWin);
1102 if (firstWin->generic.contentSize <= 0)
1103 tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
1104 if (secondWin->generic.contentSize <= 0)
1105 tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
1106 }
1107 }
1108 }
1109
1110 return status;
1111 } /* _tuiAdjustWinHeights */
1112
1113
1114 /*
1115 ** _makeInvisibleAndSetNewHeight().
1116 ** Function make the target window (and auxillary windows associated
1117 ** with the targer) invisible, and set the new height and location.
1118 */
1119 static void
1120 _makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height)
1121 {
1122 int i;
1123 struct symtab *s;
1124 TuiGenWinInfoPtr genWinInfo;
1125
1126
1127 m_beInvisible (&winInfo->generic);
1128 winInfo->generic.height = height;
1129 if (height > 1)
1130 winInfo->generic.viewportHeight = height - 1;
1131 else
1132 winInfo->generic.viewportHeight = height;
1133 if (winInfo != cmdWin)
1134 winInfo->generic.viewportHeight--;
1135
1136 /* Now deal with the auxillary windows associated with winInfo */
1137 switch (winInfo->generic.type)
1138 {
1139 case SRC_WIN:
1140 case DISASSEM_WIN:
1141 genWinInfo = winInfo->detail.sourceInfo.executionInfo;
1142 m_beInvisible (genWinInfo);
1143 genWinInfo->height = height;
1144 genWinInfo->origin.y = winInfo->generic.origin.y;
1145 if (height > 1)
1146 genWinInfo->viewportHeight = height - 1;
1147 else
1148 genWinInfo->viewportHeight = height;
1149 if (winInfo != cmdWin)
1150 genWinInfo->viewportHeight--;
1151
1152 if (m_hasLocator (winInfo))
1153 {
1154 genWinInfo = locatorWinInfoPtr ();
1155 m_beInvisible (genWinInfo);
1156 genWinInfo->origin.y = winInfo->generic.origin.y + height;
1157 }
1158 break;
1159 case DATA_WIN:
1160 /* delete all data item windows */
1161 for (i = 0; i < winInfo->generic.contentSize; i++)
1162 {
1163 genWinInfo = (TuiGenWinInfoPtr) & ((TuiWinElementPtr)
1164 winInfo->generic.content[i])->whichElement.dataWindow;
1165 tuiDelwin (genWinInfo->handle);
1166 genWinInfo->handle = (WINDOW *) NULL;
1167 }
1168 break;
1169 default:
1170 break;
1171 }
1172
1173 return;
1174 } /* _makeInvisibleAndSetNewHeight */
1175
1176
1177 /*
1178 ** _makeVisibleWithNewHeight().
1179 ** Function to make the windows with new heights visible.
1180 ** This means re-creating the windows' content since the window
1181 ** had to be destroyed to be made invisible.
1182 */
1183 static void
1184 _makeVisibleWithNewHeight (TuiWinInfoPtr winInfo)
1185 {
1186 int i;
1187 struct symtab *s;
1188
1189 m_beVisible (&winInfo->generic);
1190 checkAndDisplayHighlightIfNeeded (winInfo);
1191 switch (winInfo->generic.type)
1192 {
1193 case SRC_WIN:
1194 case DISASSEM_WIN:
1195 freeWinContent (winInfo->detail.sourceInfo.executionInfo);
1196 m_beVisible (winInfo->detail.sourceInfo.executionInfo);
1197 if (winInfo->generic.content != (OpaquePtr) NULL)
1198 {
1199 TuiLineOrAddress lineOrAddr;
1200
1201 if (winInfo->generic.type == SRC_WIN)
1202 lineOrAddr.lineNo =
1203 winInfo->detail.sourceInfo.startLineOrAddr.lineNo;
1204 else
1205 lineOrAddr.addr =
1206 winInfo->detail.sourceInfo.startLineOrAddr.addr;
1207 freeWinContent (&winInfo->generic);
1208 tuiUpdateSourceWindow (winInfo,
1209 current_source_symtab,
1210 ((winInfo->generic.type == SRC_WIN) ?
1211 (Opaque) lineOrAddr.lineNo :
1212 lineOrAddr.addr),
1213 TRUE);
1214 }
1215 else if (selected_frame != (struct frame_info *) NULL)
1216 {
1217 Opaque line = 0;
1218 extern int current_source_line;
1219
1220 s = find_pc_symtab (selected_frame->pc);
1221 if (winInfo->generic.type == SRC_WIN)
1222 line = (Opaque) current_source_line;
1223 else
1224 line = (Opaque) find_line_pc (s, current_source_line);
1225 tuiUpdateSourceWindow (winInfo, s, line, TRUE);
1226 }
1227 if (m_hasLocator (winInfo))
1228 {
1229 m_beVisible (locatorWinInfoPtr ());
1230 tuiClearLocatorDisplay ();
1231 tuiShowLocatorContent ();
1232 }
1233 break;
1234 case DATA_WIN:
1235 tuiDisplayAllData ();
1236 break;
1237 case CMD_WIN:
1238 winInfo->detail.commandInfo.curLine = 0;
1239 winInfo->detail.commandInfo.curch = 0;
1240 wmove (winInfo->generic.handle,
1241 winInfo->detail.commandInfo.curLine,
1242 winInfo->detail.commandInfo.curch);
1243 break;
1244 default:
1245 break;
1246 }
1247
1248 return;
1249 } /* _makeVisibleWithNewHeight */
1250
1251
1252 static int
1253 _newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight)
1254 {
1255 int ok = (newHeight < termHeight ());
1256
1257 if (ok)
1258 {
1259 int diff, curHeight;
1260 TuiLayoutType curLayout = currentLayout ();
1261
1262 diff = (newHeight - primaryWinInfo->generic.height) * (-1);
1263 if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
1264 {
1265 ok = ((primaryWinInfo->generic.type == CMD_WIN &&
1266 newHeight <= (termHeight () - 4) &&
1267 newHeight >= MIN_CMD_WIN_HEIGHT) ||
1268 (primaryWinInfo->generic.type != CMD_WIN &&
1269 newHeight <= (termHeight () - 2) &&
1270 newHeight >= MIN_WIN_HEIGHT));
1271 if (ok)
1272 { /* check the total height */
1273 TuiWinInfoPtr winInfo;
1274
1275 if (primaryWinInfo == cmdWin)
1276 winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1277 else
1278 winInfo = cmdWin;
1279 ok = ((newHeight +
1280 (winInfo->generic.height + diff)) <= termHeight ());
1281 }
1282 }
1283 else
1284 {
1285 int curTotalHeight, totalHeight, minHeight;
1286 TuiWinInfoPtr firstWin, secondWin;
1287
1288 if (curLayout == SRC_DISASSEM_COMMAND)
1289 {
1290 firstWin = srcWin;
1291 secondWin = disassemWin;
1292 }
1293 else
1294 {
1295 firstWin = dataWin;
1296 secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1297 }
1298 /*
1299 ** We could simply add all the heights to obtain the same result
1300 ** but below is more explicit since we subtract 1 for the
1301 ** line that the first and second windows share, and add one
1302 ** for the locator.
1303 */
1304 curTotalHeight =
1305 (firstWin->generic.height + secondWin->generic.height - 1)
1306 + cmdWin->generic.height + 1 /*locator */ ;
1307 if (primaryWinInfo == cmdWin)
1308 {
1309 /* locator included since first & second win share a line */
1310 ok = ((firstWin->generic.height +
1311 secondWin->generic.height + diff) >=
1312 (MIN_WIN_HEIGHT * 2) &&
1313 newHeight >= MIN_CMD_WIN_HEIGHT);
1314 if (ok)
1315 {
1316 totalHeight = newHeight + (firstWin->generic.height +
1317 secondWin->generic.height + diff);
1318 minHeight = MIN_CMD_WIN_HEIGHT;
1319 }
1320 }
1321 else
1322 {
1323 minHeight = MIN_WIN_HEIGHT;
1324 /*
1325 ** First see if we can increase/decrease the command
1326 ** window. And make sure that the command window is
1327 ** at least 1 line
1328 */
1329 ok = ((cmdWin->generic.height + diff) > 0);
1330 if (!ok)
1331 { /*
1332 ** Looks like we have to increase/decrease one of
1333 ** the other windows
1334 */
1335 if (primaryWinInfo == firstWin)
1336 ok = (secondWin->generic.height + diff) >= minHeight;
1337 else
1338 ok = (firstWin->generic.height + diff) >= minHeight;
1339 }
1340 if (ok)
1341 {
1342 if (primaryWinInfo == firstWin)
1343 totalHeight = newHeight +
1344 secondWin->generic.height +
1345 cmdWin->generic.height + diff;
1346 else
1347 totalHeight = newHeight +
1348 firstWin->generic.height +
1349 cmdWin->generic.height + diff;
1350 }
1351 }
1352 /*
1353 ** Now make sure that the proposed total height doesn't exceed
1354 ** the old total height.
1355 */
1356 if (ok)
1357 ok = (newHeight >= minHeight && totalHeight <= curTotalHeight);
1358 }
1359 }
1360
1361 return ok;
1362 } /* _newHeightOk */
1363
1364
1365 /*
1366 ** _parseScrollingArgs().
1367 */
1368 static void
1369 _parseScrollingArgs (char *arg, TuiWinInfoPtr * winToScroll, int *numToScroll)
1370 {
1371 if (numToScroll)
1372 *numToScroll = 0;
1373 *winToScroll = tuiWinWithFocus ();
1374
1375 /*
1376 ** First set up the default window to scroll, in case there is no
1377 ** window name arg
1378 */
1379 if (arg != (char *) NULL)
1380 {
1381 char *buf, *bufPtr;
1382
1383 /* process the number of lines to scroll */
1384 buf = bufPtr = tuiStrDup (arg);
1385 if (isdigit (*bufPtr))
1386 {
1387 char *numStr;
1388
1389 numStr = bufPtr;
1390 bufPtr = strchr (bufPtr, ' ');
1391 if (bufPtr != (char *) NULL)
1392 {
1393 *bufPtr = (char) 0;
1394 if (numToScroll)
1395 *numToScroll = atoi (numStr);
1396 bufPtr++;
1397 }
1398 else if (numToScroll)
1399 *numToScroll = atoi (numStr);
1400 }
1401
1402 /* process the window name if one is specified */
1403 if (bufPtr != (char *) NULL)
1404 {
1405 char *wname;
1406 int i;
1407
1408 if (*bufPtr == ' ')
1409 while (*(++bufPtr) == ' ')
1410 ;
1411
1412 if (*bufPtr != (char) 0)
1413 wname = bufPtr;
1414
1415 /* Validate the window name */
1416 for (i = 0; i < strlen (wname); i++)
1417 wname[i] = toupper (wname[i]);
1418 *winToScroll = partialWinByName (wname);
1419
1420 if (*winToScroll == (TuiWinInfoPtr) NULL ||
1421 !(*winToScroll)->generic.isVisible)
1422 warning ("Invalid window specified. \n\
1423 The window name specified must be valid and visible.\n");
1424 else if (*winToScroll == cmdWin)
1425 *winToScroll = (TuiWinInfoPtr) (sourceWindows ())->list[0];
1426 }
1427 tuiFree (buf);
1428 }
1429
1430 return;
1431 } /* _parseScrollingArgs */
This page took 0.072441 seconds and 5 git commands to generate.