win_exchange(long Prenum)
{
    frame_T	*frp;
    frame_T	*frp2;
    win_T	*wp;
    win_T	*wp2;
    int		temp;

    if (ERROR_IF_POPUP_WINDOW)
	return;
    if (ONE_WINDOW)	    // just one window
    {
	beep_flush();
	return;
    }

#ifdef FEAT_GUI
    need_mouse_correct = TRUE;
#endif

    /*
     * find window to exchange with
     */
    if (Prenum)
    {
	frp = curwin->w_frame->fr_parent->fr_child;
	while (frp != NULL && --Prenum > 0)
	    frp = frp->fr_next;
    }
    else if (curwin->w_frame->fr_next != NULL)	/* Swap with next */
	frp = curwin->w_frame->fr_next;
    else    /* Swap last window in row/col with previous */
	frp = curwin->w_frame->fr_prev;

    /* We can only exchange a window with another window, not with a frame
     * containing windows. */
    if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin)
	return;
    wp = frp->fr_win;

/*
 * 1. remove curwin from the list. Remember after which window it was in wp2
 * 2. insert curwin before wp in the list
 * if wp != wp2
 *    3. remove wp from the list
 *    4. insert wp after wp2
 * 5. exchange the status line height and vsep width.
 */
    wp2 = curwin->w_prev;
    frp2 = curwin->w_frame->fr_prev;
    if (wp->w_prev != curwin)
    {
	win_remove(curwin, NULL);
	frame_remove(curwin->w_frame);
	win_append(wp->w_prev, curwin);
	frame_insert(frp, curwin->w_frame);
    }
    if (wp != wp2)
    {
	win_remove(wp, NULL);
	frame_remove(wp->w_frame);
	win_append(wp2, wp);
	if (frp2 == NULL)
	    frame_insert(wp->w_frame->fr_parent->fr_child, wp->w_frame);
	else
	    frame_append(frp2, wp->w_frame);
    }
    temp = curwin->w_status_height;
    curwin->w_status_height = wp->w_status_height;
    wp->w_status_height = temp;
    temp = curwin->w_vsep_width;
    curwin->w_vsep_width = wp->w_vsep_width;
    wp->w_vsep_width = temp;

    /* If the windows are not in the same frame, exchange the sizes to avoid
     * messing up the window layout.  Otherwise fix the frame sizes. */
    if (curwin->w_frame->fr_parent != wp->w_frame->fr_parent)
    {
	temp = curwin->w_height;
	curwin->w_height = wp->w_height;
	wp->w_height = temp;
	temp = curwin->w_width;
	curwin->w_width = wp->w_width;
	wp->w_width = temp;
    }
    else
    {
	frame_fix_height(curwin);
	frame_fix_height(wp);
	frame_fix_width(curwin);
	frame_fix_width(wp);
    }

    (void)win_comp_pos();		/* recompute window positions */

    win_enter(wp, TRUE);
    redraw_all_later(NOT_VALID);
}
Unknown