1 /* TUI data manipulation routines. 2 3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 4 2009, 2010, 2011 Free Software Foundation, 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 3 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, see <http://www.gnu.org/licenses/>. */ 22 23 #include "defs.h" 24 #include "symtab.h" 25 #include "tui/tui.h" 26 #include "tui/tui-data.h" 27 #include "tui/tui-wingeneral.h" 28 29 #include "gdb_string.h" 30 #include "gdb_curses.h" 31 32 /**************************** 33 ** GLOBAL DECLARATIONS 34 ****************************/ 35 struct tui_win_info *(tui_win_list[MAX_MAJOR_WINDOWS]); 36 37 /*************************** 38 ** Private data 39 ****************************/ 40 static enum tui_layout_type current_layout = UNDEFINED_LAYOUT; 41 static int term_height, term_width; 42 static struct tui_gen_win_info _locator; 43 static struct tui_gen_win_info exec_info[2]; 44 static struct tui_win_info *src_win_list[2]; 45 static struct tui_list source_windows = {src_win_list, 0}; 46 static int default_tab_len = DEFAULT_TAB_LEN; 47 static struct tui_win_info *win_with_focus = (struct tui_win_info *) NULL; 48 static struct tui_layout_def layout_def = { 49 SRC_WIN, /* DISPLAY_MODE */ 50 FALSE, /* SPLIT */ 51 TUI_UNDEFINED_REGS, /* REGS_DISPLAY_TYPE */ 52 TUI_SFLOAT_REGS}; /* FLOAT_REGS_DISPLAY_TYPE */ 53 54 static int win_resized = FALSE; 55 56 57 /********************************* 58 ** Static function forward decls 59 **********************************/ 60 static void free_content (tui_win_content, 61 int, 62 enum tui_win_type); 63 static void free_content_elements (tui_win_content, 64 int, 65 enum tui_win_type); 66 67 68 69 /********************************* 70 ** PUBLIC FUNCTIONS 71 **********************************/ 72 73 int 74 tui_win_is_source_type (enum tui_win_type win_type) 75 { 76 return (win_type == SRC_WIN || win_type == DISASSEM_WIN); 77 } 78 79 int 80 tui_win_is_auxillary (enum tui_win_type win_type) 81 { 82 return (win_type > MAX_MAJOR_WINDOWS); 83 } 84 85 int 86 tui_win_has_locator (struct tui_win_info *win_info) 87 { 88 return (win_info != NULL 89 && win_info->detail.source_info.has_locator); 90 } 91 92 void 93 tui_set_win_highlight (struct tui_win_info *win_info, 94 int highlight) 95 { 96 if (win_info != NULL) 97 win_info->is_highlighted = highlight; 98 } 99 100 /****************************************** 101 ** ACCESSORS & MUTATORS FOR PRIVATE DATA 102 ******************************************/ 103 104 /* Answer a whether the terminal window has been resized or not. */ 105 int 106 tui_win_resized (void) 107 { 108 return win_resized; 109 } 110 111 112 /* Set a whether the terminal window has been resized or not. */ 113 void 114 tui_set_win_resized_to (int resized) 115 { 116 win_resized = resized; 117 } 118 119 120 /* Answer a pointer to the current layout definition. */ 121 struct tui_layout_def * 122 tui_layout_def (void) 123 { 124 return &layout_def; 125 } 126 127 128 /* Answer the window with the logical focus. */ 129 struct tui_win_info * 130 tui_win_with_focus (void) 131 { 132 return win_with_focus; 133 } 134 135 136 /* Set the window that has the logical focus. */ 137 void 138 tui_set_win_with_focus (struct tui_win_info *win_info) 139 { 140 win_with_focus = win_info; 141 } 142 143 144 /* Answer the length in chars, of tabs. */ 145 int 146 tui_default_tab_len (void) 147 { 148 return default_tab_len; 149 } 150 151 152 /* Set the length in chars, of tabs. */ 153 void 154 tui_set_default_tab_len (int len) 155 { 156 default_tab_len = len; 157 } 158 159 160 /* Accessor for the current source window. Usually there is only one 161 source window (either source or disassembly), but both can be 162 displayed at the same time. */ 163 struct tui_list * 164 tui_source_windows (void) 165 { 166 return &source_windows; 167 } 168 169 170 /* Clear the list of source windows. Usually there is only one source 171 window (either source or disassembly), but both can be displayed at 172 the same time. */ 173 void 174 tui_clear_source_windows (void) 175 { 176 source_windows.list[0] = NULL; 177 source_windows.list[1] = NULL; 178 source_windows.count = 0; 179 } 180 181 182 /* Clear the pertinant detail in the source windows. */ 183 void 184 tui_clear_source_windows_detail (void) 185 { 186 int i; 187 188 for (i = 0; i < (tui_source_windows ())->count; i++) 189 tui_clear_win_detail ((tui_source_windows ())->list[i]); 190 } 191 192 193 /* Add a window to the list of source windows. Usually there is only 194 one source window (either source or disassembly), but both can be 195 displayed at the same time. */ 196 void 197 tui_add_to_source_windows (struct tui_win_info *win_info) 198 { 199 if (source_windows.count < 2) 200 source_windows.list[source_windows.count++] = (void *) win_info; 201 } 202 203 204 /* Clear the pertinant detail in the windows. */ 205 void 206 tui_clear_win_detail (struct tui_win_info *win_info) 207 { 208 if (win_info != NULL) 209 { 210 switch (win_info->generic.type) 211 { 212 case SRC_WIN: 213 case DISASSEM_WIN: 214 win_info->detail.source_info.gdbarch = NULL; 215 win_info->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS; 216 win_info->detail.source_info.start_line_or_addr.u.addr = 0; 217 win_info->detail.source_info.horizontal_offset = 0; 218 break; 219 case CMD_WIN: 220 win_info->detail.command_info.cur_line = 221 win_info->detail.command_info.curch = 0; 222 break; 223 case DATA_WIN: 224 win_info->detail.data_display_info.data_content = 225 (tui_win_content) NULL; 226 win_info->detail.data_display_info.data_content_count = 0; 227 win_info->detail.data_display_info.regs_content = 228 (tui_win_content) NULL; 229 win_info->detail.data_display_info.regs_content_count = 0; 230 win_info->detail.data_display_info.regs_display_type = 231 TUI_UNDEFINED_REGS; 232 win_info->detail.data_display_info.regs_column_count = 1; 233 win_info->detail.data_display_info.display_regs = FALSE; 234 break; 235 default: 236 break; 237 } 238 } 239 } 240 241 242 /* Accessor for the source execution info ptr. */ 243 struct tui_gen_win_info * 244 tui_source_exec_info_win_ptr (void) 245 { 246 return &exec_info[0]; 247 } 248 249 250 /* Accessor for the disassem execution info ptr. */ 251 struct tui_gen_win_info * 252 tui_disassem_exec_info_win_ptr (void) 253 { 254 return &exec_info[1]; 255 } 256 257 258 /* Accessor for the locator win info. Answers a pointer to the static 259 locator win info struct. */ 260 struct tui_gen_win_info * 261 tui_locator_win_info_ptr (void) 262 { 263 return &_locator; 264 } 265 266 267 /* Accessor for the term_height. */ 268 int 269 tui_term_height (void) 270 { 271 return term_height; 272 } 273 274 275 /* Mutator for the term height. */ 276 void 277 tui_set_term_height_to (int h) 278 { 279 term_height = h; 280 } 281 282 283 /* Accessor for the term_width. */ 284 int 285 tui_term_width (void) 286 { 287 return term_width; 288 } 289 290 291 /* Mutator for the term_width. */ 292 void 293 tui_set_term_width_to (int w) 294 { 295 term_width = w; 296 } 297 298 299 /* Accessor for the current layout. */ 300 enum tui_layout_type 301 tui_current_layout (void) 302 { 303 return current_layout; 304 } 305 306 307 /* Mutator for the current layout. */ 308 void 309 tui_set_current_layout_to (enum tui_layout_type new_layout) 310 { 311 current_layout = new_layout; 312 } 313 314 315 /* Set the origin of the window. */ 316 void 317 set_gen_win_origin (struct tui_gen_win_info *win_info, 318 int x, int y) 319 { 320 win_info->origin.x = x; 321 win_info->origin.y = y; 322 } 323 324 325 /***************************** 326 ** OTHER PUBLIC FUNCTIONS 327 *****************************/ 328 329 330 /* Answer the next window in the list, cycling back to the top if 331 necessary. */ 332 struct tui_win_info * 333 tui_next_win (struct tui_win_info *cur_win) 334 { 335 enum tui_win_type type = cur_win->generic.type; 336 struct tui_win_info *next_win = (struct tui_win_info *) NULL; 337 338 if (cur_win->generic.type == CMD_WIN) 339 type = SRC_WIN; 340 else 341 type = cur_win->generic.type + 1; 342 while (type != cur_win->generic.type && (next_win == NULL)) 343 { 344 if (tui_win_list[type] 345 && tui_win_list[type]->generic.is_visible) 346 next_win = tui_win_list[type]; 347 else 348 { 349 if (type == CMD_WIN) 350 type = SRC_WIN; 351 else 352 type++; 353 } 354 } 355 356 return next_win; 357 } 358 359 360 /* Answer the prev window in the list, cycling back to the bottom if 361 necessary. */ 362 struct tui_win_info * 363 tui_prev_win (struct tui_win_info *cur_win) 364 { 365 enum tui_win_type type = cur_win->generic.type; 366 struct tui_win_info *prev = (struct tui_win_info *) NULL; 367 368 if (cur_win->generic.type == SRC_WIN) 369 type = CMD_WIN; 370 else 371 type = cur_win->generic.type - 1; 372 while (type != cur_win->generic.type && (prev == NULL)) 373 { 374 if (tui_win_list[type] 375 && tui_win_list[type]->generic.is_visible) 376 prev = tui_win_list[type]; 377 else 378 { 379 if (type == SRC_WIN) 380 type = CMD_WIN; 381 else 382 type--; 383 } 384 } 385 386 return prev; 387 } 388 389 390 /* Answer the window represented by name. */ 391 struct tui_win_info * 392 tui_partial_win_by_name (char *name) 393 { 394 struct tui_win_info *win_info = (struct tui_win_info *) NULL; 395 396 if (name != (char *) NULL) 397 { 398 int i = 0; 399 400 while (i < MAX_MAJOR_WINDOWS && win_info == NULL) 401 { 402 if (tui_win_list[i] != 0) 403 { 404 char *cur_name = tui_win_name (&tui_win_list[i]->generic); 405 406 if (strlen (name) <= strlen (cur_name) 407 && strncmp (name, cur_name, strlen (name)) == 0) 408 win_info = tui_win_list[i]; 409 } 410 i++; 411 } 412 } 413 414 return win_info; 415 } 416 417 418 /* Answer the name of the window. */ 419 char * 420 tui_win_name (struct tui_gen_win_info *win_info) 421 { 422 char *name = (char *) NULL; 423 424 switch (win_info->type) 425 { 426 case SRC_WIN: 427 name = SRC_NAME; 428 break; 429 case CMD_WIN: 430 name = CMD_NAME; 431 break; 432 case DISASSEM_WIN: 433 name = DISASSEM_NAME; 434 break; 435 case DATA_WIN: 436 name = DATA_NAME; 437 break; 438 default: 439 name = ""; 440 break; 441 } 442 443 return name; 444 } 445 446 447 void 448 tui_initialize_static_data (void) 449 { 450 tui_init_generic_part (tui_source_exec_info_win_ptr ()); 451 tui_init_generic_part (tui_disassem_exec_info_win_ptr ()); 452 tui_init_generic_part (tui_locator_win_info_ptr ()); 453 } 454 455 456 struct tui_gen_win_info * 457 tui_alloc_generic_win_info (void) 458 { 459 struct tui_gen_win_info *win; 460 461 if ((win = XMALLOC (struct tui_gen_win_info)) != NULL) 462 tui_init_generic_part (win); 463 464 return win; 465 } 466 467 468 void 469 tui_init_generic_part (struct tui_gen_win_info *win) 470 { 471 win->width = 472 win->height = 473 win->origin.x = 474 win->origin.y = 475 win->viewport_height = 476 win->content_size = 477 win->last_visible_line = 0; 478 win->handle = (WINDOW *) NULL; 479 win->content = NULL; 480 win->content_in_use = 481 win->is_visible = FALSE; 482 win->title = 0; 483 } 484 485 486 /* init_content_element(). 487 */ 488 static void 489 init_content_element (struct tui_win_element *element, 490 enum tui_win_type type) 491 { 492 element->highlight = FALSE; 493 switch (type) 494 { 495 case SRC_WIN: 496 case DISASSEM_WIN: 497 element->which_element.source.line = (char *) NULL; 498 element->which_element.source.line_or_addr.loa = LOA_LINE; 499 element->which_element.source.line_or_addr.u.line_no = 0; 500 element->which_element.source.is_exec_point = FALSE; 501 element->which_element.source.has_break = FALSE; 502 break; 503 case DATA_WIN: 504 tui_init_generic_part (&element->which_element.data_window); 505 element->which_element.data_window.type = DATA_ITEM_WIN; 506 ((struct tui_gen_win_info *) 507 &element->which_element.data_window)->content = 508 (void **) tui_alloc_content (1, DATA_ITEM_WIN); 509 ((struct tui_gen_win_info *) 510 & element->which_element.data_window)->content_size = 1; 511 break; 512 case CMD_WIN: 513 element->which_element.command.line = (char *) NULL; 514 break; 515 case DATA_ITEM_WIN: 516 element->which_element.data.name = (char *) NULL; 517 element->which_element.data.type = TUI_REGISTER; 518 element->which_element.data.item_no = UNDEFINED_ITEM; 519 element->which_element.data.value = NULL; 520 element->which_element.data.highlight = FALSE; 521 element->which_element.data.content = (char*) NULL; 522 break; 523 case LOCATOR_WIN: 524 element->which_element.locator.file_name[0] = 525 element->which_element.locator.proc_name[0] = (char) 0; 526 element->which_element.locator.line_no = 0; 527 element->which_element.locator.addr = 0; 528 break; 529 case EXEC_INFO_WIN: 530 memset(element->which_element.simple_string, ' ', 531 sizeof(element->which_element.simple_string)); 532 break; 533 default: 534 break; 535 } 536 } 537 538 static void 539 init_win_info (struct tui_win_info *win_info) 540 { 541 tui_init_generic_part (&win_info->generic); 542 win_info->can_highlight = 543 win_info->is_highlighted = FALSE; 544 switch (win_info->generic.type) 545 { 546 case SRC_WIN: 547 case DISASSEM_WIN: 548 win_info->detail.source_info.execution_info 549 = (struct tui_gen_win_info *) NULL; 550 win_info->detail.source_info.has_locator = FALSE; 551 win_info->detail.source_info.horizontal_offset = 0; 552 win_info->detail.source_info.gdbarch = NULL; 553 win_info->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS; 554 win_info->detail.source_info.start_line_or_addr.u.addr = 0; 555 win_info->detail.source_info.filename = 0; 556 break; 557 case DATA_WIN: 558 win_info->detail.data_display_info.data_content = (tui_win_content) NULL; 559 win_info->detail.data_display_info.data_content_count = 0; 560 win_info->detail.data_display_info.regs_content = (tui_win_content) NULL; 561 win_info->detail.data_display_info.regs_content_count = 0; 562 win_info->detail.data_display_info.regs_display_type = 563 TUI_UNDEFINED_REGS; 564 win_info->detail.data_display_info.regs_column_count = 1; 565 win_info->detail.data_display_info.display_regs = FALSE; 566 win_info->detail.data_display_info.current_group = 0; 567 break; 568 case CMD_WIN: 569 win_info->detail.command_info.cur_line = 0; 570 win_info->detail.command_info.curch = 0; 571 break; 572 default: 573 win_info->detail.opaque = NULL; 574 break; 575 } 576 } 577 578 579 struct tui_win_info * 580 tui_alloc_win_info (enum tui_win_type type) 581 { 582 struct tui_win_info *win_info; 583 584 win_info = XMALLOC (struct tui_win_info); 585 if (win_info != NULL) 586 { 587 win_info->generic.type = type; 588 init_win_info (win_info); 589 } 590 591 return win_info; 592 } 593 594 595 /* Allocates the content and elements in a block. */ 596 tui_win_content 597 tui_alloc_content (int num_elements, enum tui_win_type type) 598 { 599 tui_win_content content; 600 char *element_block_ptr; 601 int i; 602 603 content = xmalloc (sizeof (struct tui_win_element *) *num_elements); 604 if (content != NULL) 605 { 606 /* 607 * All windows, except the data window, can allocate the 608 * elements in a chunk. The data window cannot because items 609 * can be added/removed from the data display by the user at any 610 * time. 611 */ 612 if (type != DATA_WIN) 613 { 614 element_block_ptr = 615 xmalloc (sizeof (struct tui_win_element) * num_elements); 616 if (element_block_ptr != NULL) 617 { 618 for (i = 0; i < num_elements; i++) 619 { 620 content[i] = (struct tui_win_element *) element_block_ptr; 621 init_content_element (content[i], type); 622 element_block_ptr += sizeof (struct tui_win_element); 623 } 624 } 625 else 626 { 627 xfree (content); 628 content = (tui_win_content) NULL; 629 } 630 } 631 } 632 633 return content; 634 } 635 636 637 /* Adds the input number of elements to the windows's content. If no 638 content has been allocated yet, alloc_content() is called to do 639 this. The index of the first element added is returned, unless 640 there is a memory allocation error, in which case, (-1) is 641 returned. */ 642 int 643 tui_add_content_elements (struct tui_gen_win_info *win_info, 644 int num_elements) 645 { 646 struct tui_win_element *element_ptr; 647 int i, index_start; 648 649 if (win_info->content == NULL) 650 { 651 win_info->content = (void **) tui_alloc_content (num_elements, 652 win_info->type); 653 index_start = 0; 654 } 655 else 656 index_start = win_info->content_size; 657 if (win_info->content != NULL) 658 { 659 for (i = index_start; (i < num_elements + index_start); i++) 660 { 661 if ((element_ptr = XMALLOC (struct tui_win_element)) != NULL) 662 { 663 win_info->content[i] = (void *) element_ptr; 664 init_content_element (element_ptr, win_info->type); 665 win_info->content_size++; 666 } 667 else /* Things must be really hosed now! We ran out of 668 memory!? */ 669 return (-1); 670 } 671 } 672 673 return index_start; 674 } 675 676 677 /* Delete all curses windows associated with win_info, leaving 678 everything else intact. */ 679 void 680 tui_del_window (struct tui_win_info *win_info) 681 { 682 struct tui_gen_win_info *generic_win; 683 684 switch (win_info->generic.type) 685 { 686 case SRC_WIN: 687 case DISASSEM_WIN: 688 generic_win = tui_locator_win_info_ptr (); 689 if (generic_win != (struct tui_gen_win_info *) NULL) 690 { 691 tui_delete_win (generic_win->handle); 692 generic_win->handle = (WINDOW *) NULL; 693 generic_win->is_visible = FALSE; 694 } 695 if (win_info->detail.source_info.filename) 696 { 697 xfree (win_info->detail.source_info.filename); 698 win_info->detail.source_info.filename = 0; 699 } 700 generic_win = win_info->detail.source_info.execution_info; 701 if (generic_win != (struct tui_gen_win_info *) NULL) 702 { 703 tui_delete_win (generic_win->handle); 704 generic_win->handle = (WINDOW *) NULL; 705 generic_win->is_visible = FALSE; 706 } 707 break; 708 case DATA_WIN: 709 if (win_info->generic.content != NULL) 710 { 711 tui_del_data_windows (win_info->detail.data_display_info.regs_content, 712 win_info->detail.data_display_info.regs_content_count); 713 tui_del_data_windows (win_info->detail.data_display_info.data_content, 714 win_info->detail.data_display_info.data_content_count); 715 } 716 break; 717 default: 718 break; 719 } 720 if (win_info->generic.handle != (WINDOW *) NULL) 721 { 722 tui_delete_win (win_info->generic.handle); 723 win_info->generic.handle = (WINDOW *) NULL; 724 win_info->generic.is_visible = FALSE; 725 } 726 } 727 728 729 void 730 tui_free_window (struct tui_win_info *win_info) 731 { 732 struct tui_gen_win_info *generic_win; 733 734 switch (win_info->generic.type) 735 { 736 case SRC_WIN: 737 case DISASSEM_WIN: 738 generic_win = tui_locator_win_info_ptr (); 739 if (generic_win != (struct tui_gen_win_info *) NULL) 740 { 741 tui_delete_win (generic_win->handle); 742 generic_win->handle = (WINDOW *) NULL; 743 } 744 tui_free_win_content (generic_win); 745 if (win_info->detail.source_info.filename) 746 { 747 xfree (win_info->detail.source_info.filename); 748 win_info->detail.source_info.filename = 0; 749 } 750 generic_win = win_info->detail.source_info.execution_info; 751 if (generic_win != (struct tui_gen_win_info *) NULL) 752 { 753 tui_delete_win (generic_win->handle); 754 generic_win->handle = (WINDOW *) NULL; 755 tui_free_win_content (generic_win); 756 } 757 break; 758 case DATA_WIN: 759 if (win_info->generic.content != NULL) 760 { 761 tui_free_data_content (win_info->detail.data_display_info.regs_content, 762 win_info->detail.data_display_info.regs_content_count); 763 win_info->detail.data_display_info.regs_content = 764 (tui_win_content) NULL; 765 win_info->detail.data_display_info.regs_content_count = 0; 766 tui_free_data_content (win_info->detail.data_display_info.data_content, 767 win_info->detail.data_display_info.data_content_count); 768 win_info->detail.data_display_info.data_content = 769 (tui_win_content) NULL; 770 win_info->detail.data_display_info.data_content_count = 0; 771 win_info->detail.data_display_info.regs_display_type = 772 TUI_UNDEFINED_REGS; 773 win_info->detail.data_display_info.regs_column_count = 1; 774 win_info->detail.data_display_info.display_regs = FALSE; 775 win_info->generic.content = NULL; 776 win_info->generic.content_size = 0; 777 } 778 break; 779 default: 780 break; 781 } 782 if (win_info->generic.handle != (WINDOW *) NULL) 783 { 784 tui_delete_win (win_info->generic.handle); 785 win_info->generic.handle = (WINDOW *) NULL; 786 tui_free_win_content (&win_info->generic); 787 } 788 if (win_info->generic.title) 789 xfree (win_info->generic.title); 790 xfree (win_info); 791 } 792 793 794 void 795 tui_free_all_source_wins_content (void) 796 { 797 int i; 798 799 for (i = 0; i < (tui_source_windows ())->count; i++) 800 { 801 struct tui_win_info *win_info = (tui_source_windows ())->list[i]; 802 803 if (win_info != NULL) 804 { 805 tui_free_win_content (&(win_info->generic)); 806 tui_free_win_content (win_info->detail.source_info.execution_info); 807 } 808 } 809 } 810 811 812 void 813 tui_free_win_content (struct tui_gen_win_info *win_info) 814 { 815 if (win_info->content != NULL) 816 { 817 free_content ((tui_win_content) win_info->content, 818 win_info->content_size, 819 win_info->type); 820 win_info->content = NULL; 821 } 822 win_info->content_size = 0; 823 } 824 825 826 void 827 tui_del_data_windows (tui_win_content content, 828 int content_size) 829 { 830 int i; 831 832 /* Remember that data window content elements are of type struct 833 tui_gen_win_info *, each of which whose single element is a data 834 element. */ 835 for (i = 0; i < content_size; i++) 836 { 837 struct tui_gen_win_info *generic_win 838 = &content[i]->which_element.data_window; 839 840 if (generic_win != (struct tui_gen_win_info *) NULL) 841 { 842 tui_delete_win (generic_win->handle); 843 generic_win->handle = (WINDOW *) NULL; 844 generic_win->is_visible = FALSE; 845 } 846 } 847 } 848 849 850 void 851 tui_free_data_content (tui_win_content content, 852 int content_size) 853 { 854 int i; 855 856 /* Remember that data window content elements are of type struct 857 tui_gen_win_info *, each of which whose single element is a data 858 element. */ 859 for (i = 0; i < content_size; i++) 860 { 861 struct tui_gen_win_info *generic_win 862 = &content[i]->which_element.data_window; 863 864 if (generic_win != (struct tui_gen_win_info *) NULL) 865 { 866 tui_delete_win (generic_win->handle); 867 generic_win->handle = (WINDOW *) NULL; 868 tui_free_win_content (generic_win); 869 } 870 } 871 free_content (content, 872 content_size, 873 DATA_WIN); 874 } 875 876 877 /********************************** 878 ** LOCAL STATIC FUNCTIONS ** 879 **********************************/ 880 881 882 static void 883 free_content (tui_win_content content, 884 int content_size, 885 enum tui_win_type win_type) 886 { 887 if (content != (tui_win_content) NULL) 888 { 889 free_content_elements (content, content_size, win_type); 890 xfree (content); 891 } 892 } 893 894 895 /* free_content_elements(). 896 */ 897 static void 898 free_content_elements (tui_win_content content, 899 int content_size, 900 enum tui_win_type type) 901 { 902 if (content != (tui_win_content) NULL) 903 { 904 int i; 905 906 if (type == SRC_WIN || type == DISASSEM_WIN) 907 { 908 /* Free whole source block. */ 909 xfree (content[0]->which_element.source.line); 910 } 911 else 912 { 913 for (i = 0; i < content_size; i++) 914 { 915 struct tui_win_element *element; 916 917 element = content[i]; 918 if (element != (struct tui_win_element *) NULL) 919 { 920 switch (type) 921 { 922 case DATA_WIN: 923 xfree (element); 924 break; 925 case DATA_ITEM_WIN: 926 /* Note that data elements are not allocated in 927 a single block, but individually, as 928 needed. */ 929 if (element->which_element.data.type != TUI_REGISTER) 930 xfree ((void *)element->which_element.data.name); 931 xfree (element->which_element.data.value); 932 xfree (element->which_element.data.content); 933 xfree (element); 934 break; 935 case CMD_WIN: 936 xfree (element->which_element.command.line); 937 break; 938 default: 939 break; 940 } 941 } 942 } 943 } 944 if (type != DATA_WIN && type != DATA_ITEM_WIN) 945 xfree (content[0]); /* Free the element block. */ 946 } 947 } 948