1 /* TUI data manipulation routines.
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
6 Contributed by Hewlett-Packard Company.
8 This file is part of GDB.
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.
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.
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. */
28 #include "tui/tui-data.h"
29 #include "tui/tui-wingeneral.h"
31 #include "gdb_string.h"
41 /****************************
42 ** GLOBAL DECLARATIONS
43 ****************************/
44 struct tui_win_info
*(tui_win_list
[MAX_MAJOR_WINDOWS
]);
46 /***************************
48 ****************************/
49 static enum tui_layout_type _currentLayout
= UNDEFINED_LAYOUT
;
50 static int _termHeight
, _termWidth
;
51 static struct tui_gen_win_info _locator
;
52 static struct tui_gen_win_info _execInfo
[2];
53 static struct tui_win_info
* _srcWinList
[2];
54 static struct tui_list _sourceWindows
= {(void **) _srcWinList
, 0};
55 static int _defaultTabLen
= DEFAULT_TAB_LEN
;
56 static struct tui_win_info
* _winWithFocus
= (struct tui_win_info
*) NULL
;
57 static struct tui_layout_def _layoutDef
=
58 {SRC_WIN
, /* displayMode */
60 TUI_UNDEFINED_REGS
, /* regsDisplayType */
61 TUI_SFLOAT_REGS
}; /* floatRegsDisplayType */
62 static int _winResized
= FALSE
;
65 /*********************************
66 ** Static function forward decls
67 **********************************/
68 static void freeContent (tui_win_content
, int, enum tui_win_type
);
69 static void freeContentElements (tui_win_content
, int, enum tui_win_type
);
73 /*********************************
75 **********************************/
78 tui_win_is_source_type (enum tui_win_type win_type
)
80 return (win_type
== SRC_WIN
|| win_type
== DISASSEM_WIN
);
84 tui_win_is_auxillary (enum tui_win_type win_type
)
86 return (win_type
> MAX_MAJOR_WINDOWS
);
90 tui_win_has_locator (struct tui_win_info
*win_info
)
92 return (win_info
!= NULL \
93 && win_info
->detail
.source_info
.has_locator
);
97 tui_set_win_highlight (struct tui_win_info
*win_info
, int highlight
)
100 win_info
->is_highlighted
= highlight
;
103 /******************************************
104 ** ACCESSORS & MUTATORS FOR PRIVATE DATA
105 ******************************************/
107 /* Answer a whether the terminal window has been resized or not. */
109 tui_win_resized (void)
115 /* Set a whether the terminal window has been resized or not. */
117 tui_set_win_resized_to (int resized
)
119 _winResized
= resized
;
123 /* Answer a pointer to the current layout definition. */
124 struct tui_layout_def
*
125 tui_layout_def (void)
131 /* Answer the window with the logical focus. */
132 struct tui_win_info
*
133 tui_win_with_focus (void)
135 return _winWithFocus
;
139 /* Set the window that has the logical focus. */
141 tui_set_win_with_focus (struct tui_win_info
* win_info
)
143 _winWithFocus
= win_info
;
147 /* Answer the length in chars, of tabs. */
149 tui_default_tab_len (void)
151 return _defaultTabLen
;
155 /* Set the length in chars, of tabs. */
157 tui_set_default_tab_len (int len
)
159 _defaultTabLen
= len
;
164 ** currentSourceWin()
165 ** Accessor for the current source window. Usually there is only
166 ** one source window (either source or disassembly), but both can
167 ** be displayed at the same time.
170 tui_source_windows (void)
172 return &_sourceWindows
;
176 /* Clear the list of source windows. Usually there is only one source
177 window (either source or disassembly), but both can be displayed at
180 tui_clear_source_windows (void)
182 _sourceWindows
.list
[0] = NULL
;
183 _sourceWindows
.list
[1] = NULL
;
184 _sourceWindows
.count
= 0;
188 /* Clear the pertinant detail in the source windows. */
190 tui_clear_source_windows_detail (void)
194 for (i
= 0; i
< (tui_source_windows ())->count
; i
++)
195 tui_clear_win_detail ((struct tui_win_info
*) (tui_source_windows ())->list
[i
]);
199 /* Add a window to the list of source windows. Usually there is only
200 one source window (either source or disassembly), but both can be
201 displayed at the same time. */
203 tui_add_to_source_windows (struct tui_win_info
* win_info
)
205 if (_sourceWindows
.count
< 2)
206 _sourceWindows
.list
[_sourceWindows
.count
++] = (void *) win_info
;
210 /* Clear the pertinant detail in the windows. */
212 tui_clear_win_detail (struct tui_win_info
* win_info
)
214 if (win_info
!= NULL
)
216 switch (win_info
->generic
.type
)
220 win_info
->detail
.source_info
.start_line_or_addr
.addr
= 0;
221 win_info
->detail
.source_info
.horizontal_offset
= 0;
224 win_info
->detail
.command_info
.cur_line
=
225 win_info
->detail
.command_info
.curch
= 0;
228 win_info
->detail
.data_display_info
.data_content
=
229 (tui_win_content
) NULL
;
230 win_info
->detail
.data_display_info
.data_content_count
= 0;
231 win_info
->detail
.data_display_info
.regs_content
=
232 (tui_win_content
) NULL
;
233 win_info
->detail
.data_display_info
.regs_content_count
= 0;
234 win_info
->detail
.data_display_info
.regs_display_type
=
236 win_info
->detail
.data_display_info
.regs_column_count
= 1;
237 win_info
->detail
.data_display_info
.display_regs
= FALSE
;
245 } /* clearWinDetail */
249 ** sourceExecInfoPtr().
250 ** Accessor for the source execution info ptr.
252 struct tui_gen_win_info
*
253 tui_source_exec_info_win_ptr (void)
255 return &_execInfo
[0];
256 } /* sourceExecInfoWinPtr */
260 ** disassemExecInfoPtr().
261 ** Accessor for the disassem execution info ptr.
263 struct tui_gen_win_info
*
264 tui_disassem_exec_info_win_ptr (void)
266 return &_execInfo
[1];
267 } /* disassemExecInfoWinPtr */
270 /* Accessor for the locator win info. Answers a pointer to the static
271 locator win info struct. */
272 struct tui_gen_win_info
*
273 tui_locator_win_info_ptr (void)
279 /* Accessor for the termHeight. */
281 tui_term_height (void)
287 /* Mutator for the term height. */
289 tui_set_term_height_to (int h
)
295 /* Accessor for the termWidth. */
297 tui_term_width (void)
303 /* Mutator for the termWidth. */
305 tui_set_term_width_to (int w
)
311 /* Accessor for the current layout. */
313 tui_current_layout (void)
315 return _currentLayout
;
319 /* Mutator for the current layout. */
321 tui_set_current_layout_to (enum tui_layout_type newLayout
)
323 _currentLayout
= newLayout
;
328 ** setGenWinOrigin().
329 ** Set the origin of the window
332 setGenWinOrigin (struct tui_gen_win_info
* win_info
, int x
, int y
)
334 win_info
->origin
.x
= x
;
335 win_info
->origin
.y
= y
;
338 } /* setGenWinOrigin */
341 /*****************************
342 ** OTHER PUBLIC FUNCTIONS
343 *****************************/
346 /* Answer the next window in the list, cycling back to the top if
348 struct tui_win_info
*
349 tui_next_win (struct tui_win_info
* curWin
)
351 enum tui_win_type type
= curWin
->generic
.type
;
352 struct tui_win_info
* nextWin
= (struct tui_win_info
*) NULL
;
354 if (curWin
->generic
.type
== CMD_WIN
)
357 type
= curWin
->generic
.type
+ 1;
358 while (type
!= curWin
->generic
.type
&& (nextWin
== NULL
))
360 if (tui_win_list
[type
] && tui_win_list
[type
]->generic
.is_visible
)
361 nextWin
= tui_win_list
[type
];
375 /* Answer the prev window in the list, cycling back to the bottom if
377 struct tui_win_info
*
378 tui_prev_win (struct tui_win_info
* curWin
)
380 enum tui_win_type type
= curWin
->generic
.type
;
381 struct tui_win_info
* prev
= (struct tui_win_info
*) NULL
;
383 if (curWin
->generic
.type
== SRC_WIN
)
386 type
= curWin
->generic
.type
- 1;
387 while (type
!= curWin
->generic
.type
&& (prev
== NULL
))
389 if (tui_win_list
[type
]->generic
.is_visible
)
390 prev
= tui_win_list
[type
];
404 /* Answer the window represented by name. */
405 struct tui_win_info
*
406 tui_partial_win_by_name (char *name
)
408 struct tui_win_info
* win_info
= (struct tui_win_info
*) NULL
;
410 if (name
!= (char *) NULL
)
414 while (i
< MAX_MAJOR_WINDOWS
&& win_info
== NULL
)
416 if (tui_win_list
[i
] != 0)
418 char *curName
= tui_win_name (&tui_win_list
[i
]->generic
);
419 if (strlen (name
) <= strlen (curName
) &&
420 strncmp (name
, curName
, strlen (name
)) == 0)
421 win_info
= tui_win_list
[i
];
428 } /* partialWinByName */
433 ** Answer the name of the window
436 tui_win_name (struct tui_gen_win_info
* win_info
)
438 char *name
= (char *) NULL
;
440 switch (win_info
->type
)
449 name
= DISASSEM_NAME
;
464 tui_initialize_static_data (void)
466 tui_init_generic_part (tui_source_exec_info_win_ptr ());
467 tui_init_generic_part (tui_disassem_exec_info_win_ptr ());
468 tui_init_generic_part (tui_locator_win_info_ptr ());
472 struct tui_gen_win_info
*
473 tui_alloc_generic_win_info (void)
475 struct tui_gen_win_info
* win
;
477 if ((win
= (struct tui_gen_win_info
*) xmalloc (
478 sizeof (struct tui_gen_win_info
*))) != (struct tui_gen_win_info
*) NULL
)
479 tui_init_generic_part (win
);
482 } /* allocGenericWinInfo */
486 ** initGenericPart().
489 tui_init_generic_part (struct tui_gen_win_info
* win
)
495 win
->viewport_height
=
497 win
->last_visible_line
= 0;
498 win
->handle
= (WINDOW
*) NULL
;
500 win
->content_in_use
=
501 win
->is_visible
= FALSE
;
507 ** initContentElement().
510 initContentElement (struct tui_win_element
* element
, enum tui_win_type type
)
512 element
->highlight
= FALSE
;
517 element
->which_element
.source
.line
= (char *) NULL
;
518 element
->which_element
.source
.line_or_addr
.line_no
= 0;
519 element
->which_element
.source
.is_exec_point
= FALSE
;
520 element
->which_element
.source
.has_break
= FALSE
;
523 tui_init_generic_part (&element
->which_element
.data_window
);
524 element
->which_element
.data_window
.type
= DATA_ITEM_WIN
;
525 ((struct tui_gen_win_info
*) & element
->which_element
.data_window
)->content
=
526 (void **) tui_alloc_content (1, DATA_ITEM_WIN
);
527 ((struct tui_gen_win_info
*)
528 & element
->which_element
.data_window
)->content_size
= 1;
531 element
->which_element
.command
.line
= (char *) NULL
;
534 element
->which_element
.data
.name
= (char *) NULL
;
535 element
->which_element
.data
.type
= TUI_REGISTER
;
536 element
->which_element
.data
.item_no
= UNDEFINED_ITEM
;
537 element
->which_element
.data
.value
= NULL
;
538 element
->which_element
.data
.highlight
= FALSE
;
541 element
->which_element
.locator
.file_name
[0] =
542 element
->which_element
.locator
.proc_name
[0] = (char) 0;
543 element
->which_element
.locator
.line_no
= 0;
544 element
->which_element
.locator
.addr
= 0;
547 memset(element
->which_element
.simple_string
, ' ',
548 sizeof(element
->which_element
.simple_string
));
554 } /* initContentElement */
560 initWinInfo (struct tui_win_info
* win_info
)
562 tui_init_generic_part (&win_info
->generic
);
563 win_info
->can_highlight
=
564 win_info
->is_highlighted
= FALSE
;
565 switch (win_info
->generic
.type
)
569 win_info
->detail
.source_info
.execution_info
= (struct tui_gen_win_info
*) NULL
;
570 win_info
->detail
.source_info
.has_locator
= FALSE
;
571 win_info
->detail
.source_info
.horizontal_offset
= 0;
572 win_info
->detail
.source_info
.start_line_or_addr
.addr
= 0;
573 win_info
->detail
.source_info
.filename
= 0;
576 win_info
->detail
.data_display_info
.data_content
= (tui_win_content
) NULL
;
577 win_info
->detail
.data_display_info
.data_content_count
= 0;
578 win_info
->detail
.data_display_info
.regs_content
= (tui_win_content
) NULL
;
579 win_info
->detail
.data_display_info
.regs_content_count
= 0;
580 win_info
->detail
.data_display_info
.regs_display_type
=
582 win_info
->detail
.data_display_info
.regs_column_count
= 1;
583 win_info
->detail
.data_display_info
.display_regs
= FALSE
;
586 win_info
->detail
.command_info
.cur_line
= 0;
587 win_info
->detail
.command_info
.curch
= 0;
590 win_info
->detail
.opaque
= NULL
;
598 struct tui_win_info
*
599 tui_alloc_win_info (enum tui_win_type type
)
601 struct tui_win_info
* win_info
= (struct tui_win_info
*) NULL
;
603 win_info
= (struct tui_win_info
*) xmalloc (sizeof (struct tui_win_info
));
604 if ((win_info
!= NULL
))
606 win_info
->generic
.type
= type
;
607 initWinInfo (win_info
);
616 ** Allocates the content and elements in a block.
619 tui_alloc_content (int numElements
, enum tui_win_type type
)
621 tui_win_content content
= (tui_win_content
) NULL
;
622 char *elementBlockPtr
= (char *) NULL
;
625 if ((content
= (tui_win_content
)
626 xmalloc (sizeof (struct tui_win_element
*) * numElements
)) != (tui_win_content
) NULL
)
628 ** All windows, except the data window, can allocate the elements
629 ** in a chunk. The data window cannot because items can be
630 ** added/removed from the data display by the user at any time.
632 if (type
!= DATA_WIN
)
634 if ((elementBlockPtr
= (char *)
635 xmalloc (sizeof (struct tui_win_element
) * numElements
)) != (char *) NULL
)
637 for (i
= 0; i
< numElements
; i
++)
639 content
[i
] = (struct tui_win_element
*) elementBlockPtr
;
640 initContentElement (content
[i
], type
);
641 elementBlockPtr
+= sizeof (struct tui_win_element
);
647 content
= (tui_win_content
) NULL
;
656 /* Adds the input number of elements to the windows's content. If no
657 content has been allocated yet, allocContent() is called to do
658 this. The index of the first element added is returned, unless
659 there is a memory allocation error, in which case, (-1) is
662 tui_add_content_elements (struct tui_gen_win_info
* win_info
, int numElements
)
664 struct tui_win_element
* elementPtr
;
667 if (win_info
->content
== NULL
)
669 win_info
->content
= (void **) tui_alloc_content (numElements
, win_info
->type
);
673 indexStart
= win_info
->content_size
;
674 if (win_info
->content
!= NULL
)
676 for (i
= indexStart
; (i
< numElements
+ indexStart
); i
++)
678 if ((elementPtr
= (struct tui_win_element
*)
679 xmalloc (sizeof (struct tui_win_element
))) != (struct tui_win_element
*) NULL
)
681 win_info
->content
[i
] = (void *) elementPtr
;
682 initContentElement (elementPtr
, win_info
->type
);
683 win_info
->content_size
++;
685 else /* things must be really hosed now! We ran out of memory!? */
691 } /* addContentElements */
694 /* Delete all curses windows associated with win_info, leaving everything
697 tuiDelWindow (struct tui_win_info
* win_info
)
699 struct tui_gen_win_info
* genericWin
;
701 switch (win_info
->generic
.type
)
705 genericWin
= tui_locator_win_info_ptr ();
706 if (genericWin
!= (struct tui_gen_win_info
*) NULL
)
708 tui_delete_win (genericWin
->handle
);
709 genericWin
->handle
= (WINDOW
*) NULL
;
710 genericWin
->is_visible
= FALSE
;
712 if (win_info
->detail
.source_info
.filename
)
714 xfree (win_info
->detail
.source_info
.filename
);
715 win_info
->detail
.source_info
.filename
= 0;
717 genericWin
= win_info
->detail
.source_info
.execution_info
;
718 if (genericWin
!= (struct tui_gen_win_info
*) NULL
)
720 tui_delete_win (genericWin
->handle
);
721 genericWin
->handle
= (WINDOW
*) NULL
;
722 genericWin
->is_visible
= FALSE
;
726 if (win_info
->generic
.content
!= NULL
)
728 tui_del_data_windows (win_info
->detail
.data_display_info
.regs_content
,
729 win_info
->detail
.data_display_info
.regs_content_count
);
730 tui_del_data_windows (win_info
->detail
.data_display_info
.data_content
,
731 win_info
->detail
.data_display_info
.data_content_count
);
737 if (win_info
->generic
.handle
!= (WINDOW
*) NULL
)
739 tui_delete_win (win_info
->generic
.handle
);
740 win_info
->generic
.handle
= (WINDOW
*) NULL
;
741 win_info
->generic
.is_visible
= FALSE
;
747 tui_free_window (struct tui_win_info
* win_info
)
749 struct tui_gen_win_info
* genericWin
;
751 switch (win_info
->generic
.type
)
755 genericWin
= tui_locator_win_info_ptr ();
756 if (genericWin
!= (struct tui_gen_win_info
*) NULL
)
758 tui_delete_win (genericWin
->handle
);
759 genericWin
->handle
= (WINDOW
*) NULL
;
761 tui_free_win_content (genericWin
);
762 if (win_info
->detail
.source_info
.filename
)
764 xfree (win_info
->detail
.source_info
.filename
);
765 win_info
->detail
.source_info
.filename
= 0;
767 genericWin
= win_info
->detail
.source_info
.execution_info
;
768 if (genericWin
!= (struct tui_gen_win_info
*) NULL
)
770 tui_delete_win (genericWin
->handle
);
771 genericWin
->handle
= (WINDOW
*) NULL
;
772 tui_free_win_content (genericWin
);
776 if (win_info
->generic
.content
!= NULL
)
778 tui_free_data_content (win_info
->detail
.data_display_info
.regs_content
,
779 win_info
->detail
.data_display_info
.regs_content_count
);
780 win_info
->detail
.data_display_info
.regs_content
=
781 (tui_win_content
) NULL
;
782 win_info
->detail
.data_display_info
.regs_content_count
= 0;
783 tui_free_data_content (win_info
->detail
.data_display_info
.data_content
,
784 win_info
->detail
.data_display_info
.data_content_count
);
785 win_info
->detail
.data_display_info
.data_content
=
786 (tui_win_content
) NULL
;
787 win_info
->detail
.data_display_info
.data_content_count
= 0;
788 win_info
->detail
.data_display_info
.regs_display_type
=
790 win_info
->detail
.data_display_info
.regs_column_count
= 1;
791 win_info
->detail
.data_display_info
.display_regs
= FALSE
;
792 win_info
->generic
.content
= NULL
;
793 win_info
->generic
.content_size
= 0;
799 if (win_info
->generic
.handle
!= (WINDOW
*) NULL
)
801 tui_delete_win (win_info
->generic
.handle
);
802 win_info
->generic
.handle
= (WINDOW
*) NULL
;
803 tui_free_win_content (&win_info
->generic
);
805 if (win_info
->generic
.title
)
806 xfree (win_info
->generic
.title
);
812 tui_free_all_source_wins_content (void)
816 for (i
= 0; i
< (tui_source_windows ())->count
; i
++)
818 struct tui_win_info
* win_info
= (struct tui_win_info
*) (tui_source_windows ())->list
[i
];
820 if (win_info
!= NULL
)
822 tui_free_win_content (&(win_info
->generic
));
823 tui_free_win_content (win_info
->detail
.source_info
.execution_info
);
830 tui_free_win_content (struct tui_gen_win_info
* win_info
)
832 if (win_info
->content
!= NULL
)
834 freeContent ((tui_win_content
) win_info
->content
,
835 win_info
->content_size
,
837 win_info
->content
= NULL
;
839 win_info
->content_size
= 0;
842 } /* freeWinContent */
846 tui_del_data_windows (tui_win_content content
, int contentSize
)
851 ** Remember that data window content elements are of type struct tui_gen_win_info *,
852 ** each of which whose single element is a data element.
854 for (i
= 0; i
< contentSize
; i
++)
856 struct tui_gen_win_info
* genericWin
= &content
[i
]->which_element
.data_window
;
858 if (genericWin
!= (struct tui_gen_win_info
*) NULL
)
860 tui_delete_win (genericWin
->handle
);
861 genericWin
->handle
= (WINDOW
*) NULL
;
862 genericWin
->is_visible
= FALSE
;
869 tui_free_data_content (tui_win_content content
, int contentSize
)
874 ** Remember that data window content elements are of type struct tui_gen_win_info *,
875 ** each of which whose single element is a data element.
877 for (i
= 0; i
< contentSize
; i
++)
879 struct tui_gen_win_info
* genericWin
= &content
[i
]->which_element
.data_window
;
881 if (genericWin
!= (struct tui_gen_win_info
*) NULL
)
883 tui_delete_win (genericWin
->handle
);
884 genericWin
->handle
= (WINDOW
*) NULL
;
885 tui_free_win_content (genericWin
);
888 freeContent (content
,
893 } /* freeDataContent */
896 /**********************************
897 ** LOCAL STATIC FUNCTIONS **
898 **********************************/
905 freeContent (tui_win_content content
, int contentSize
, enum tui_win_type winType
)
907 if (content
!= (tui_win_content
) NULL
)
909 freeContentElements (content
, contentSize
, winType
);
918 ** freeContentElements().
921 freeContentElements (tui_win_content content
, int contentSize
, enum tui_win_type type
)
923 if (content
!= (tui_win_content
) NULL
)
927 if (type
== SRC_WIN
|| type
== DISASSEM_WIN
)
929 /* free whole source block */
930 xfree (content
[0]->which_element
.source
.line
);
934 for (i
= 0; i
< contentSize
; i
++)
936 struct tui_win_element
* element
;
938 element
= content
[i
];
939 if (element
!= (struct tui_win_element
*) NULL
)
948 ** Note that data elements are not allocated
949 ** in a single block, but individually, as needed.
951 if (element
->which_element
.data
.type
!= TUI_REGISTER
)
952 xfree ((void *)element
->which_element
.data
.name
);
953 xfree (element
->which_element
.data
.value
);
957 xfree (element
->which_element
.command
.line
);
965 if (type
!= DATA_WIN
&& type
!= DATA_ITEM_WIN
)
966 xfree (content
[0]); /* free the element block */
970 } /* freeContentElements */