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