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

📄 window.c

📁 使用BorlandC++4.5编译的一个MUD客户端程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	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;
}

/* input_fdel - delete character under cursor
 *
 * This also updates text to the end of the line.
 *
 * Parameters:
 *   num - number of chars to delete.  must be >= 0, < kpos
 */
void input_fdel(num)
	int num;
{
	int n;
        assert(num >= 0 /* count may not be negative */);
        assert(num <= (Klen - kpos) /* Delete past end of string */);

	if (!echo_mode)
		return;
	n = min(Klen - kpos - num, Margin - icol);
	IBwriteal(&Kptr[kpos + num], n);
	Iclear_end;
	Imove_left(n, icol);
	IBflush;
}

/* input_clear - clears the input edit line */
void input_clear()
{
	if (!echo_mode)
		return;
	if (kpos <= Isize * Margin) /* fills entire window? */
        {
		input_cmove(0);
		IBwritea(s_clreol);
                icol = Oplen % Margin;
	}
        else
        {
		Iclear_space(Itop, 1);
		draw_prompt();      /* sets icol */
	}
	IBflush;
}

/* input_draw - draws the input edit line (no prompt)
 *
 * Sets icol.
 *
 * Note:
 *  This is not easy to get right, so be careful
 *  to step through every inch of code after modification.
 */
void input_draw()
{
    int pos = 0;                /* offset in kbuf */
    int n, col;

    if (!echo_mode)
        return;
    
    col = Oplen % Margin;       /* initial location */
    if (Klen > 0)
    {
        while (1)                   /* Loop to write input line */
        {
            n = min(Klen - pos, Margin - col);
            assert(n >= 0);         /* Logic error */
            IBwriteal(&Kptr[pos], n);
            pos += n;               /* printed n chars */
            assert(pos <= Klen);    /* off end of array? */
            
            if (pos > kpos || pos >= Klen)         /* Cursor on line? */
                break;
            else                    /* not done, scroll forward */
                Iscr_fwd;
            
            col = 0;                /* beginning of row now */
        };
        if (n == (Margin - col)) /* write ended at last line on screen? */
            Iscr_fwd;
    };
    icol = (Oplen + kpos) % Margin;
    assert(icol >= 0 && icol < cols); /* off screen? */
        
    Iclear_end;
    Icmove(icol, 1);
    IBflush;
}

void input_newline()
{
	input_cmove(Klen);
	Iscr_fwd;
	icol = 0;
	if (plen && !vtc_mode) {
		Discardstring(prompt);
		prompt = vtstrdup("");
		plen = 0;
	}
	IBflush;
}

/* change_prompt - set a new prompt with length l
 *
 * Nonprintable characters are ignored.
 */
void change_prompt(new, l)
	char *new;
	int l;
{
	char *p, *q;
	Discardstring(prompt);
	for (p = new; *p; p++) {       /* Get new prompt length */
		if (!isprint(*p))
			l--;
	}
	q = prompt = Newarray(char, l + 1); /* copy prompt string */
	for (p = new; *p; p++) {
		if (isprint(*p))
			*q++ = *p;
	}
	*q = 0;

        /* clear and redraw input window */
        
	if (!vtc_mode) {                
		curs_input();
		clear_input_window();
	}
	plen = l;                       
	if (!vtc_mode) {                 
		draw_prompt();
		input_draw();
	}
}

void update_echo_mode()
{
	int new_mode;
	
	if(0 != ign_echo_mode)
		return;

	new_mode = (active_win->Wrmt) ? active_win->Wrmt->Recho : 1;

	if (echo_mode != new_mode) {
		echo_mode = 1;
		curs_input();
		if (new_mode)
			input_draw();
		else
			input_clear();
		echo_mode = new_mode;
	}
}

/* Output routines */

void output(win, text)
	Unode *win;
	char *text;
{
	int norm, n;

	if (!win) {
		win = active_win;
		if (win->Wnl)
			output(win, "[background] ");
	}
	curs_window(win);
	if (win->Wnl) {
		BputEOLN();
		win->Wnl = 0;
	}
	while (1) {
		norm = strcspn(text, "\n\b\f\v\t\r");
		n = cols - win->Wcol;
		for (; norm >= n; text += n, norm -= n, n = cols) {
			BputEOLN();
			cmove(win->Wcol, win->Wbot - 1);
			Bwriteal(text, n);
			cmove(0, win->Wbot);
			win->Wcol = 0;
		}
		Bwriteal(text, norm);
		win->Wcol = (win->Wcol + norm) % cols;
		text += norm;
		switch(*text++) {
		    case '\0':
			Bflush;
			return;
		    case '\n':
		    case '\v':
			if (*text)
				BputEOLN();
			else
				win->Wnl = 1;
			win->Wcol = 0;
		    Case '\b':
			if (win->Wcol) {
				Bputch('\b');
				win->Wcol--;
			}
		    Case '\f':
			clear_space(win->Wtop, win->Wbot);
			win->Wcol = 0;
			curs_window(win);
		    Case '\t':
			if (win->Wcol == cols - 1) {
				BputEOLN();
				win->Wcol = 0;
			} else {
				do {
					Bputch(' ');
					win->Wcol++;
				} while (win->Wcol % 8 && 
					 win->Wcol < cols - 1);
			}
		    Case '\r':
			Bputch('\r');
			win->Wcol = 0;
		}
	}
}

#ifdef USE_STDARG
void outputf(char *fmt, ...)
#else
void outputf(va_alist)
	va_dcl
#endif
{
	va_list ap;
	char *ptr, *sval, *intstr;
	String *buf = &wbufs[1];
	int width = 0;
#ifdef USE_STDARG
	va_start(ap, fmt);
#else
	char *fmt;
	va_start(ap);
	fmt = va_arg(ap, char *);
#endif

	s_term(buf, 0);
	ptr = strchr(fmt, '%');
	while (ptr) {
		s_cat(buf, cstr_sl(fmt, ptr - fmt));
		if (isdigit(*++ptr)) {
			width = atoi(ptr);
			while (isdigit(*++ptr));
		}
		if (*ptr == 'd') {
			intstr = ITOA(va_arg(ap, int));
			for (width -= strlen(intstr); width > 0; width--)
				s_fadd(buf, ' ');
			s_acat(buf, intstr);
		} else if (*ptr == 's') {
			sval = va_arg(ap, char *);
			for (width -= strlen(sval); width > 0; width--)
				s_fadd(buf, ' ');
			s_acat(buf, sval);
		} else
			s_fadd(buf, *ptr);
		fmt = ptr + 1;
		ptr = strchr(fmt, '%');
	}
	s_acat(buf, fmt);
	output(Cur_win, buf->c.s);
	va_end(ap);
}

void operror(s, rmt)
	char *s;
	Unode *rmt;
{
	char errbuf[128];
	Unode *win = rmt ? rmt->Rwin : Cur_win;

	strcpy(errbuf, s);
	strcat(errbuf, ": ");
	strcat(errbuf, sys_errlist[errno]);
	strcat(errbuf, "\n");
	output(win, errbuf);
}

⌨️ 快捷键说明

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