⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window.c

📁 使用BorlandC++4.5编译的一个MUD客户端程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	cmove(0, scr_bot);
	while (num--)
		BputEOLN();
}

/* Scroll the current scroll area backwards num lines */
void scr_rev(num)
	int num;
{
	cmove(0, scr_top);
	while (num--)
		cap_normal(s_scr_rev, scr_bot - scr_top + 1);
}

/* Slightly higher-level termcap routines */

/* clear_end - clear to end of line
 *
 * Optimization is dangerous.  Putting a space/backspace combo can
 * cause scrolling on the last line of the screen
 */
static void clear_end()
{
    Bwritea(s_clreol);
}


/* Clear horizontally a range of rows  */
static void clear_space(top, bottom)
	int top, bottom;
{
	int i;

	scroll(0, rows - 1);
	cmove(0, top);
	Bwritea(s_clreol);
	for (i = top; i < bottom; i++) {
		BputEOLN();
		Bwritea(s_clreol);
	}
	Bflush;
}

static void move_left(n, new)
	int n, new;
{
	if (n < 7)
		chrpt('\010', n);
	else
		cmove(new, rows - 1);
}

/* Windowing routines */

/* Ensure that cursor and scroll area are in window */
void curs_window(win)
	Unode *win;
{
	if (curs_loc == CURS_WINDOW && curs_win == win)
		return;
	scroll(win->Wtop, win->Wbot);
	cmove(win->Wcol, win->Wbot);
	Bflush;
	curs_loc = CURS_WINDOW;
	curs_win = win;
}

/* Ensure that cursor is in input window */
void curs_input()
{
	if (curs_loc == CURS_INPUT)
		return;
	cmove(icol, rows - 1);
	Bflush;
	curs_loc = CURS_INPUT;
}

static void init_window(win, top, bottom)
	Unode *win;
	int top, bottom;
{
	win->Wtop = top;
	win->Wbot = bottom;
	win->Wcol = win->Wnl = 0;
	win->Wrmt = NULL;
	win->Wtermread = NULL;
	win->Wobj = NULL;
	win->Wghstack = NULL;
	win->Wglstack = NULL;
	win->Wrstack = NULL;
}

void draw_Divider(win)
	Unode *win;
{
	scroll(0, rows - 1);
	cmove(0, win->Wbot + 1);
	Bputch((win == active_win) ? '*' : '_');
	chrpt('_', win->next->dummy ? cols - 6 : cols - 1);
	if (win->next->dummy)
		Bwritea(vtc_mode ? "VTC__" : "Text_");
	Bflush;
	curs_loc = CURS_ELSEWHERE;
}

void toggle_imode()
{
        scroll(0, rows - 1);
	vtc_mode = !vtc_mode;
	cmove(cols - 5, Divider);
	Bwritea(vtc_mode ? "VTC__" : "Text_");
	curs_loc = CURS_ELSEWHERE;
	if (plen) {
		clear_input_window();
		draw_prompt();
		input_draw();
	}
}

static void mark(win, value)
	Unode *win;
	int value;
{
	cmove(0, win->Wbot + 1);
	Bputch(value ? '*' : '_');
	Bflush;
	curs_loc = CURS_ELSEWHERE;
}

void init_screen()
{
	Unode *first_win;
	int w_bottom; /* bottom of initial window */
        w_bottom = rows - 5;

	first_win = unalloc();
	init_window(first_win, 0, w_bottom);
	win_ring.next = win_ring.prev = first_win;
	win_ring.dummy = 1;
	first_win->next = first_win->prev = &win_ring;
	active_win = first_win;
	Bwritea(s_clrscr);
	draw_Divider(first_win);
}

void redraw_screen()
{
	Unode *wp;

	Bwritea(s_clrscr);
	for (wp = win_ring.next; !wp->dummy; wp = wp->next)
		draw_Divider(wp);
	cmove(0, rows - 1);
	draw_prompt();
	input_draw();
}

void auto_redraw()
{
	Func *func;

	func = find_func("redraw_hook");
	if (func && func->cmd)
		run_prog(func->cmd);
	else
		redraw_screen();
}

Unode *split_window(win, loc)
	Unode *win;
	int loc;
{
	Unode *new;

	new = unalloc();
	init_window(new, win->Wtop, loc - 1);
	win->Wtop = loc + 1;
	new->prev = win->prev;
	new->next = win;
	win->prev = win->prev->next = new;
	clear_space(new->Wtop, new->Wbot);
	draw_Divider(new);
	return new;
}

void close_window(win, dir)
	Unode *win;
	int dir;
{
	Unode *into;

	if (dir < 0) {
		into = win->prev;
		scroll(into->Wtop, win->Wbot + 1);
		scr_rev(win->Wbot - into->Wbot);
		into->Wbot = win->Wbot;
		if (win->next->dummy) {
			cmove(cols - 5, Divider);
			Bwritea(vtc_mode ? "VTC__" : "Text_");
		}
		Bflush;
	} else {
		into = win->next;
		clear_space(win->Wtop, win->Wbot + 1);
		into->Wtop = win->Wtop;
	}
	if (win->Wrmt)
		win->Wrmt->Rwin = NULL;
	if (active_win == win) {
		active_win = into;
		mark(into, 1);
	}
	if (cur_win == win)
		cur_win = NULL;
	win->prev->next = win->next;
	win->next->prev = win->prev;
	destroy_pointers(win->frefs);
	break_pipe(win->Wghstack);
	break_pipe(win->Wglstack);
	break_pipe(win->Wrstack);
	discard_unode(win);
	curs_loc = CURS_ELSEWHERE;
}

void resize_window(win, row)
	Unode *win;
	int row;
{
	if (row - 1 > win->Wbot) {
		scroll(win->Wtop, row);
		scr_rev(row - win->Wbot - 1);
	} else if (row - 1 < win->Wbot) {
		scroll(win->Wtop, win->Wbot + 1);
		scr_fwd(win->Wbot - row + 1);
	}
	Bflush;
	win->next->Wtop = row + 1;
	win->Wbot = row - 1;
	curs_loc = CURS_ELSEWHERE;
}

void new_active_win(win)
	Unode *win;
{
	if (win == active_win)
		return;
	mark(active_win, 0);
	mark(win, 1);
	active_win = win;
	curs_loc = CURS_ELSEWHERE;
	update_echo_mode();
}

void resize_screen(new_rows, new_cols)
	int new_rows, new_cols;
{
	int new_Isize, new_ospace, old_ospace, pos = 0, used = 0, overrun;
	int num_wins = 0, size, decr = 0;
	Unode *w;

	if (new_rows < 4 || new_cols < 15)
		vtdie("Screen size too small");
	for (w = win_ring.next; !w->dummy; w = w->next, num_wins++);
	old_ospace = rows - Isize - num_wins;
	while (num_wins > (new_rows - 1) / 3) {
		w = win_ring.prev;
		if (w->Wrmt)
			w->Wrmt->Rwin = NULL;
		if (active_win == w)
			active_win = w->prev;
		if (cur_win == w)
		    cur_win = NULL;
		w->prev->next = &win_ring;
		win_ring.prev = w->prev;
		destroy_pointers(w->frefs);
		destroy_pipe(w->Wghstack);
		destroy_pipe(w->Wglstack);
		destroy_pipe(w->Wrstack);
		discard_unode(w);
		num_wins--;
	}
	new_Isize = min(Isize, new_rows - num_wins * 3);
	new_ospace = new_rows - new_Isize - num_wins;
	for (w = win_ring.next; !w->dummy; w = w->next) {
		size = ((w->Wbot - w->Wtop + 1) * new_ospace
		       + old_ospace / 2) / old_ospace;
		size = max(size, 2);
		w->Wtop = pos;
		w->Wbot = pos + size - 1;
		pos += size + 1;
		used += size;
	}
	overrun = used - new_ospace;
	for (w = win_ring.next; !w->dummy; w = w->next) {
		w->Wtop -= decr;
		w->Wbot -= decr;
		if (overrun > 0 && w->Wbot - w->Wtop > 1) {
			w->Wbot--;
			decr++;
			overrun--;
		}
	}
	rows = new_rows;
	cols = new_cols;
	auto_redraw();
}

/* input routines */

/* draw_prompt - assumes current cursor location is 0. */
static void draw_prompt()
{
    int pos = 0;
    
    if (vtc_mode)               /* No prompt? */
        icol = 0;
    else
    {
        while (pos < plen)
        {
            IBwritem(&prompt[pos], plen - pos, Margin);
            pos += Margin;
            if (pos <= plen)
                Iscr_fwd;
        };
        icol = plen % Margin;
        IBflush;
    };
}

/* clear_input_window - clear input window */
static void clear_input_window()
{
    int len = Oplen;              /* copy of plen */
    if (kpos + Oplen <= Isize * Margin) 
    {
        input_cmove(0);          /* Move to start of edit line */
        while (len > Margin) {   /* Scroll back to first line of prompt */
            Iscr_rev;
            len -= Margin;
        }
        icol = 0;
        Icmove(0, 1);            /* clear line */
        IBwritea(s_clreol);
        IBflush;
    } else                       /* this line fills the window */
        Iclear_space(Itop, 1);
}

/* input_puts - puts a string to the input window
 *
 * Called when the interpreter sends output (usually due to keyboard
 * input).  This apparently does not modify kbuf.  Any input is
 * assumed to be an insertion.
 */
void input_puts(cstr)
	Cstr cstr;
{
	int n;

	if (!echo_mode)
		return;

	while (cstr.l)
        {
		n = min(cstr.l, Margin - icol);
		IBwriteal(cstr.s, n);
                icol = (icol + n) % Margin;
		if (0 == icol)
			Iscr_fwd;
		cstr = cstr_sl(cstr.s + n, cstr.l - n);
	}
        /* Print everything from current pos to eoln */
	n = min(Klen - kpos, Margin - icol);
	IBwriteal(&Kptr[kpos], n);
	Imove_left(n, icol);
	IBflush;
}

/* Move cursor to the new column, updating the screen wrap if necessary
 *
 * Assumes the current value of icol is valid.
 */
void input_cmove(new)
	int new;
{
    int offset = new - kpos, pos, n;
    assert(new >= 0);    /* array bounds error? */
    assert(new <= Klen); /* array bounds error? */

    if (new == kpos || !echo_mode)
        return;
    if (new == kpos - 1 && icol) {
        Imove_left(1, new);
        icol--;
    } else if (new == kpos + 1 && icol < Margin - 1) {
        IBputch(Kptr[kpos]);
        icol++;
    }
    else if (offset > 0)                   /* cursor forward? */
    {
        /* print remainder of this line */
        IBwritem(&Kptr[kpos], Margin - icol, Klen - kpos);
        
        n = (icol + offset) / Margin;      /* Number of times to scroll */
        pos = kpos + Margin - icol;        /* beginning of next line */
        icol = (icol + offset) % Margin;   /* Get future cursor pos */
        while (n --)
        {
            assert(pos <= Klen);            /* my mistake */
            Iscr_fwd;
            if (pos + Margin > Klen)        /* Partial line? */
                IBwriteal(&Kptr[pos], (Klen + Oplen) % Margin); 
            else
                IBwriteal(&Kptr[pos], Margin); /* fill entire line */
            
            pos += Margin;
        };
        Icmove(icol, 1);
    }
    else                                   /* cursor backward. */
    {
        /* Calculate offset into the prompt array corresponding to the first
         * char in the input window.
         */
        pos = (kpos + plen - icol);        /* start of this line */
        pos -= (Isize * Margin);           /* start of first line */
        icol += offset;
        while (icol < 0)                   /* loop to scroll back */
        {
            Iscr_rev;                      /* scroll back */

            if (pos >= 0)                  /* Exposed a line? */
            {
                cmove(0, Itop);
                if (pos < plen)            /* Not past end of prompt? */
                {
                    if (plen - pos < Margin) /* Prompt does not fill line? */
                    {
                        IBwriteal(&prompt[pos], plen - pos);
                        IBwriteal(&Kptr[0], Margin - (plen - pos));
                    }
                    else
                        IBwriteal(&prompt[pos], Margin);
                }
                else                       /* No prompt showing */
                {
                    n = pos - plen;        /* Index into kbuf now */
                    assert(n <= Klen);     /* off end of kbuf array? */
                    IBwritem(&Kptr[n], Klen - n, Margin);
                };
            }
            else                           
                clear_space(Itop, Itop);   /* clear first line */

            pos -= Margin;
            icol += Margin;
        };
        Icmove(icol, 1);
    }
    IBflush;
}

/* input_bdel - Delete previous character
 *
 * Parameters:
 *   num - number of characters to delete.  Must be >= kpos.
 */
void input_bdel(num)
	int num;
{
	int n;
        assert(num <= kpos /* deleting too far */);
        
	if (!num || !echo_mode)
		return;
	input_cmove(kpos - num);
	n = min(Klen - kpos, Margin - icol);
	IBwriteal(&Kptr[kpos], n);
	Iclear_end;
	Imove_left(n, icol);
	IBflush;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -