jpeg_mem_term (j_common_ptr cinfo) { /* Microsoft C, at least in v6.00A, will not successfully reclaim freed * blocks of size > 32Kbytes unless we give it a kick in the rear, like so: */ #ifdef NEED_FHEAPMIN _fheapmin(); #endif }
/* * Name: finish * Purpose: To remove the current window and terminate the program if no * more windows are left. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Order of deciding which window becomes current window: * 1) If any invisible window with same top and bottom line, * and start_col and end_col, then first invisible one becomes * current window. * 2) window above if it exists becomes current window * 3) window below if it exists becomes current window * 4) window right if it exists becomes current window * 5) window left if it exists becomes current window * 6) first available invisible window becomes current window. * When I added vertical windows, this routine became a LOT * more complicated. To keep things reasonably sane, let's * only close windows that have three common edges, eg. * * ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿ * ³ ³ no ³ * ³ ÃÄÄÄÄÄÂÄÄÄÄ´ * ³ ³yes1 ³yes1³ * ³ no ÃÄÄÄÄÄÁÄÄÄÄ´ * ³ ³ yes2 ³ * ³ ÃÄÄÄÄÄÄÄÄÄÄ´ * ³ ³ yes2 ³ * ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ * * Windows with 'no' cannot be closed. Windows with 'yes' can * be combined with windows that have the same yes number. */ void finish( WINDOW *window ) { register WINDOW *wp; /* for scanning other windows */ register WINDOW *win; /* register pointer for window */ file_infos *file, *fp; /* for scanning other files */ int poof; int cline; int top; int bottom; int start_col; int end_col; int max_letter; int file_change = FALSE; line_list_ptr ll; line_list_ptr temp_ll; win = window; entab_linebuff( ); if (un_copy_line( win->ll, win, TRUE ) == ERROR) return; file = win->file_info; /* * remove all hidden windows that point to same file */ file = win->file_info; for (wp=g_status.window_list; wp != NULL; wp=wp->next) { if (wp->file_info == file) { if (!wp->visible) { if (wp->prev == NULL) { if (wp->next == NULL) g_status.stop = TRUE; else g_status.window_list = wp->next; } else wp->prev->next = wp->next; if (wp->next) wp->next->prev = wp->prev; --wp->file_info->ref_count; free( wp ); --g_status.window_count; } } } if (win->prev == NULL && win->next == NULL) g_status.stop = TRUE; poof = FALSE; if (g_status.stop != TRUE) { /* * see if there are any invisible windows with same top and bottom, * lines, and start_col and end_col as this window. start looking at * end of window list. */ top = win->top_line; bottom = win->bottom_line; start_col = win->start_col; end_col = win->end_col; wp = g_status.window_list; if (wp != NULL) { while (wp->next != NULL) wp = wp->next; } while (wp != NULL && poof == FALSE) { if (wp->top_line == top && wp->bottom_line == bottom && wp->start_col == start_col && wp->end_col == end_col && !wp->visible) poof = TRUE; else wp = wp->prev; } if (poof == FALSE) { /* * see if there are any windows above */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->bottom_line+2 == win->top_line && wp->start_col == win->start_col && wp->end_col == win->end_col && wp->visible) { poof = TRUE; top = wp->top_line; } else wp = wp->next; } if (poof == FALSE) { /* * see if there are any windows below */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->top_line-2 == win->bottom_line && wp->start_col == win->start_col && wp->end_col == win->end_col && wp->visible) { poof = TRUE; bottom = wp->bottom_line; } else wp = wp->next; } } if (poof == FALSE) { /* * see if there are any windows right */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->top_line == win->top_line && wp->bottom_line == win->bottom_line && wp->start_col-2 == win->end_col && wp->visible) { poof = TRUE; end_col = wp->end_col; } else wp = wp->next; } } if (poof == FALSE) { /* * see if there are any windows left */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->top_line == win->top_line && wp->bottom_line == win->bottom_line && wp->end_col+2 == win->start_col && wp->visible) { poof = TRUE; start_col = wp->start_col; } else wp = wp->next; } } if (poof == FALSE) { /* * see if there are any other invisible windows. start looking * at the end of the window list. */ wp = g_status.window_list; if (wp != NULL) { while (wp->next != NULL) wp = wp->next; } while (wp != NULL && poof == FALSE) { if (!wp->visible) poof = TRUE; else wp = wp->prev; } } } if (poof) { wp->visible = TRUE; cline = wp->cline - (wp->top_line+wp->ruler); wp->top_line = top; wp->bottom_line = bottom; wp->cline = (wp->top_line+wp->ruler) + cline; if (wp->cline > wp->bottom_line) wp->cline = wp->top_line+wp->ruler; wp->start_col = start_col; wp->end_col = end_col; if (start_col == 0 && end_col == g_display.ncols - 1) wp->vertical = FALSE; else wp->vertical = TRUE; check_virtual_col( wp, wp->rcol, wp->ccol ); setup_window( wp ); show_window_header( wp ); if (wp->vertical) show_vertical_separator( wp ); /* * The window above, below, or previously invisible becomes the new * current window. */ g_status.current_window = wp; } } if (!poof && g_status.stop != TRUE) /* * cannot close current window */ error( WARNING, win->bottom_line, win7 ); else { /* * free unused file memory if necessary */ if (--file->ref_count == 0) { /* * if a block is marked, unmark it */ if (file == g_status.marked_file) { g_status.marked = FALSE; g_status.marked_file = NULL; } for (fp=g_status.file_list; fp != NULL; fp=fp->next) { if (fp->file_no > file->file_no) fp->file_no--; } file_change = file->file_no; /* * no window now refers to this file, so remove file from the list */ if (file->prev == NULL) g_status.file_list = file->next; else file->prev->next = file->next; if (file->next) file->next->prev = file->prev; /* * free the line pointers, linked list of line pointers, and * file struc. */ ll = file->undo_top; while (ll != NULL) { temp_ll = ll->next; if (ll->line != NULL) my_free( ll->line ); my_free( ll ); ll = temp_ll; } ll = file->line_list; while (ll != NULL) { temp_ll = ll->next; if (ll->line != NULL) my_free( ll->line ); my_free( ll ); ll = temp_ll; } #if defined( __MSC__ ) _fheapmin( ); #endif free( file ); if (--g_status.file_count) { show_file_count( g_status.file_count ); show_avail_mem( ); } } /* * remove the current window from the window list */ if (win->prev == NULL) g_status.window_list = win->next; else win->prev->next = win->next; if (win->next) win->next->prev = win->prev; if (diff.defined && (diff.w1 == win || diff.w2 == win)) diff.defined = FALSE; /* * free the memory taken by the window structure */ free( win ); --g_status.window_count; if (g_status.stop == FALSE) { g_status.current_file = wp->file_info; wp->file_info->dirty = LOCAL; make_ruler( wp ); show_ruler( wp ); show_window_count( g_status.window_count ); if (file_change) { for (wp=g_status.window_list; wp!=NULL; wp=wp->next) if (wp->visible) show_window_number_letter( wp ); } else { max_letter = 'a'; for (wp=g_status.window_list; wp!=NULL; wp=wp->next) { if (wp->file_info == file && wp->letter > max_letter) max_letter = wp->letter; } if (max_letter < file->next_letter - 1) file->next_letter = max_letter + 1; } } } if (g_status.stop == TRUE) { if (g_status.sas_defined && g_status.sas_arg < g_status.sas_argc) { show_avail_mem( ); for (bottom=0; bottom <= g_display.nlines; bottom++) eol_clear( 0, bottom, g_display.text_color ); bottom = g_display.nlines; set_prompt( win18, bottom ); top = getkey( ); top = getfunc( top ); eol_clear( 0, bottom, g_display.text_color ); if (top == RepeatGrep) { g_status.command = RepeatGrep; g_status.window_list = g_status.current_window = NULL; if (search_and_seize( g_status.window_list ) != ERROR) g_status.stop = FALSE; } } } }
/* * Name: initialize_window * Purpose: To open a new window * Date: June 5, 1991 * Returns: OK if window opened successfully * ERROR if anything went wrong * Notes: If this is first window, then set up as normal displayed window; * otherwise, make the present window invisible and open a new * window in the same screen location as the old one. */ int initialize_window( void ) { int top; int bottom; int start_col; int end_col; WINDOW *wp; /* used for scanning windows */ WINDOW *window; register file_infos *fp; /* used for scanning files */ register int rc; line_list_ptr ll; line_list_ptr temp_ll; rc = OK; window = g_status.current_window; fp = g_status.current_file; if (window == NULL) { /* * special case if this is the first window on screen. */ top = start_col = 0; bottom = g_display.nlines; end_col = g_display.ncols - 1; } else { /* * else put the new window in same place as current window. * make current window invisible. new window becomes current window. */ top = window->top_line - 1; bottom = window->bottom_line; start_col = window->start_col; end_col = window->end_col; } assert( top < bottom ); assert( start_col < end_col ); assert( fp != NULL ); if (create_window( &wp, top, bottom, start_col, end_col, fp ) == ERROR) { /* * out of memory */ error( WARNING, bottom, main4 ); /* * This is a real nuisance. We had room for the file and the * file structure, but not enough for the window as well. * Now we must free all the memory that has already been * allocated. */ if (fp->ref_count == 0) { /* * remove fp from file pointer list. */ if (fp->prev != NULL) fp->prev->next = fp->next; else g_status.file_list = fp->next; if (fp->next != NULL) fp->next->prev = fp->prev; /* * free the undo stack, line pointers, and linked list. */ ll = fp->undo_top; while (ll != NULL) { temp_ll = ll->next; if (ll->line != NULL) my_free( ll->line ); my_free( ll ); ll = temp_ll; } ll = fp->line_list; while (ll != NULL) { temp_ll = ll->next; if (ll->line != NULL) my_free( ll->line ); my_free( ll ); ll = temp_ll; } #if defined( __MSC__ ) _fheapmin( ); #endif free( fp ); wp = g_status.current_window; if (wp != NULL && wp->visible) g_status.current_file = wp->file_info; else g_status.stop = TRUE; } rc = ERROR; } if (rc != ERROR) { /* * set up the new cursor position as appropriate */ wp->ccol = wp->start_col; wp->rcol = wp->bcol = 0; wp->rline = 1L; wp->ll = fp->line_list; wp->visible = TRUE; wp->letter = fp->next_letter++; if (window != NULL) window->visible = FALSE; /* * the new window becomes the current window. */ g_status.current_window = wp; } return( rc ); }