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

📄 ite.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1988 University of Utah. * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: Utah $Hdr: ite.c 1.28 92/12/20$ * *	@(#)ite.c	8.2 (Berkeley) 1/12/94 *//* * Bit-mapped display terminal emulator machine independent code. * This is a very rudimentary.  Much more can be abstracted out of * the hardware dependent routines. */#include "ite.h"#if NITE > 0#include "grf.h"#undef NITE#define NITE	NGRF#include <sys/param.h>#include <sys/conf.h>#include <sys/proc.h>#include <sys/ioctl.h>#include <sys/tty.h>#include <sys/systm.h>#include <sys/malloc.h>#include <hp/dev/grfioctl.h>#include <hp/dev/grfvar.h>#include <hp/dev/itevar.h>#include <hp/dev/kbdmap.h>#define set_attr(ip, attr)	((ip)->attribute |= (attr))#define clr_attr(ip, attr)	((ip)->attribute &= ~(attr))/* * No need to raise SPL above the HIL (the only thing that can * affect our state. */#include <hp/dev/hilreg.h>#define splite()		splhil()/* * # of chars are output in a single itestart() call. * If this is too big, user processes will be blocked out for * long periods of time while we are emptying the queue in itestart(). * If it is too small, console output will be very ragged. */int	iteburst = 64;int	nite = NITE;struct  tty *kbd_tty = NULL;struct	tty ite_tty[NITE];struct  ite_softc ite_softc[NITE];void	itestart(), iterestart();extern	struct tty *constty;/* * Primary attribute buffer to be used by the first bitmapped console * found. Secondary displays alloc the attribute buffer as needed. * Size is based on a 68x128 display, which is currently our largest. */u_char  console_attributes[0x2200];#define ite_erasecursor(ip, sp)	{ \	if ((ip)->flags & ITE_CURSORON) \		(*(sp)->ite_cursor)((ip), ERASE_CURSOR); \}#define ite_drawcursor(ip, sp) { \	if ((ip)->flags & ITE_CURSORON) \		(*(sp)->ite_cursor)((ip), DRAW_CURSOR); \}#define ite_movecursor(ip, sp) { \	if ((ip)->flags & ITE_CURSORON) \		(*(sp)->ite_cursor)((ip), MOVE_CURSOR); \}/* * Perform functions necessary to setup device as a terminal emulator. */iteon(dev, flag)	dev_t dev;	int flag;{	int unit = UNIT(dev);	struct tty *tp = &ite_tty[unit];	struct ite_softc *ip = &ite_softc[unit];	if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)		return(ENXIO);	/* force ite active, overriding graphics mode */	if (flag & 1) {		ip->flags |= ITE_ACTIVE;		ip->flags &= ~(ITE_INGRF|ITE_INITED);	}	/* leave graphics mode */	if (flag & 2) {		ip->flags &= ~ITE_INGRF;		if ((ip->flags & ITE_ACTIVE) == 0)			return(0);	}	ip->flags |= ITE_ACTIVE;	if (ip->flags & ITE_INGRF)		return(0);	if (kbd_tty == NULL || kbd_tty == tp) {		kbd_tty = tp;		kbdenable(unit);	}	iteinit(dev);	return(0);}iteinit(dev)     dev_t dev;{	int unit = UNIT(dev);	struct ite_softc *ip = &ite_softc[unit];	if (ip->flags & ITE_INITED)		return;		ip->curx = 0;	ip->cury = 0;	ip->cursorx = 0;	ip->cursory = 0;	(*ip->isw->ite_init)(ip);	ip->flags |= ITE_CURSORON;	ite_drawcursor(ip, ip->isw);	ip->attribute = 0;	if (ip->attrbuf == NULL)		ip->attrbuf = (u_char *)			malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);	bzero(ip->attrbuf, (ip->rows * ip->cols));	ip->imode = 0;	ip->flags |= ITE_INITED;}/* * "Shut down" device as terminal emulator. * Note that we do not deinit the console device unless forced. * Deinit'ing the console every time leads to a very active * screen when processing /etc/rc. */iteoff(dev, flag)	dev_t dev;	int flag;{	register struct ite_softc *ip = &ite_softc[UNIT(dev)];	if (flag & 2) {		ip->flags |= ITE_INGRF;		ip->flags &= ~ITE_CURSORON;	}	if ((ip->flags & ITE_ACTIVE) == 0)		return;	if ((flag & 1) ||	    (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)		(*ip->isw->ite_deinit)(ip);	if ((flag & 2) == 0)		ip->flags &= ~ITE_ACTIVE;}/* ARGSUSED */#ifdef __STDC__iteopen(dev_t dev, int mode, int devtype, struct proc *p)#elseiteopen(dev, mode, devtype, p)	dev_t dev;	int mode, devtype;	struct proc *p;#endif{	int unit = UNIT(dev);	register struct tty *tp = &ite_tty[unit];	register struct ite_softc *ip = &ite_softc[unit];	register int error;	int first = 0;	if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)	    && p->p_ucred->cr_uid != 0)		return (EBUSY);	if ((ip->flags & ITE_ACTIVE) == 0) {		error = iteon(dev, 0);		if (error)			return (error);		first = 1;	}	tp->t_oproc = itestart;	tp->t_param = NULL;	tp->t_dev = dev;	if ((tp->t_state&TS_ISOPEN) == 0) {		ttychars(tp);		tp->t_iflag = TTYDEF_IFLAG;		tp->t_oflag = TTYDEF_OFLAG;		tp->t_cflag = CS8|CREAD;		tp->t_lflag = TTYDEF_LFLAG;		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;		tp->t_state = TS_ISOPEN|TS_CARR_ON;		ttsetwater(tp);	}	error = (*linesw[tp->t_line].l_open)(dev, tp);	if (error == 0) {		tp->t_winsize.ws_row = ip->rows;		tp->t_winsize.ws_col = ip->cols;	} else if (first)		iteoff(dev, 0);	return (error);}/*ARGSUSED*/iteclose(dev, flag, mode, p)	dev_t dev;	int flag, mode;	struct proc *p;{	register struct tty *tp = &ite_tty[UNIT(dev)];	(*linesw[tp->t_line].l_close)(tp, flag);	ttyclose(tp);	iteoff(dev, 0);	return(0);}iteread(dev, uio, flag)	dev_t dev;	struct uio *uio;	int flag;{	register struct tty *tp = &ite_tty[UNIT(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));}itewrite(dev, uio, flag)	dev_t dev;	struct uio *uio;	int flag;{	int unit = UNIT(dev);	register struct tty *tp = &ite_tty[unit];	if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&	    (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))		tp = constty;	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));}iteioctl(dev, cmd, addr, flag, p)	dev_t dev;	int cmd;	caddr_t addr;	int flag;	struct proc *p;{	register struct tty *tp = &ite_tty[UNIT(dev)];	int error;	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag, p);	if (error >= 0)		return (error);	error = ttioctl(tp, cmd, addr, flag);	if (error >= 0)		return (error);	return (ENOTTY);}voiditerestart(tp)	register struct tty *tp;{	register int s = splite();	tp->t_state &= ~TS_TIMEOUT;	itestart(tp);	splx(s);}voiditestart(tp)	register struct tty *tp;{	register int cc, s;	int hiwat = 0, hadcursor = 0;	struct ite_softc *ip;	/*	 * (Potentially) lower priority.  We only need to protect ourselves	 * from keyboard interrupts since that is all that can affect the	 * state of our tty (kernel printf doesn't go through this routine).	 */	s = splite();	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {		splx(s);		return;	}	tp->t_state |= TS_BUSY;	cc = tp->t_outq.c_cc;	if (cc <= tp->t_lowat) {		if (tp->t_state & TS_ASLEEP) {			tp->t_state &= ~TS_ASLEEP;			wakeup((caddr_t)&tp->t_outq);		}		selwakeup(&tp->t_wsel);	}	/*	 * Handle common (?) case	 */	if (cc == 1) {		iteputchar(getc(&tp->t_outq), tp->t_dev);	} else if (cc) {		/*		 * Limit the amount of output we do in one burst		 * to prevent hogging the CPU.		 */		if (cc > iteburst) {			hiwat++;			cc = iteburst;		}		/*		 * Turn off cursor while we output multiple characters.		 * Saves a lot of expensive window move operations.		 */		ip = &ite_softc[UNIT(tp->t_dev)];		if (ip->flags & ITE_CURSORON) {			ite_erasecursor(ip, ip->isw);			ip->flags &= ~ITE_CURSORON;			hadcursor = 1;		}		while (--cc >= 0)			iteputchar(getc(&tp->t_outq), tp->t_dev);		if (hadcursor) {			ip->flags |= ITE_CURSORON;			ite_drawcursor(ip, ip->isw);		}		if (hiwat) {			tp->t_state |= TS_TIMEOUT;			timeout(iterestart, tp, 1);		}	}	tp->t_state &= ~TS_BUSY;	splx(s);}itefilter(stat, c)	register char stat, c;{	static int capsmode = 0;	static int metamode = 0;  	register char code, *str;	if (kbd_tty == NULL)		return;	switch (c & 0xFF) {	case KBD_CAPSLOCK:		capsmode = !capsmode;		return;	case KBD_EXT_LEFT_DOWN:	case KBD_EXT_RIGHT_DOWN:		metamode = 1;		return;			case KBD_EXT_LEFT_UP:	case KBD_EXT_RIGHT_UP:		metamode = 0;		return;	}	c &= KBD_CHARMASK;	switch ((stat>>KBD_SSHIFT) & KBD_SMASK) {	case KBD_KEY:	        if (!capsmode) {			code = kbd_keymap[c];			break;		}		/* FALLTHROUGH */	case KBD_SHIFT:		code = kbd_shiftmap[c];		break;	case KBD_CTRL:		code = kbd_ctrlmap[c];		break;			case KBD_CTRLSHIFT:			code = kbd_ctrlshiftmap[c];		break;        }	if (code == NULL && (str = kbd_stringmap[c]) != NULL) {		while (*str)			(*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);	} else {		if (metamode)			code |= 0x80;		(*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);	}}iteputchar(c, dev)	register int c;	dev_t dev;  {	int unit = UNIT(dev);	register struct ite_softc *ip = &ite_softc[unit];	register struct itesw *sp = ip->isw;	register int n;	if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)	  	return;	if (ip->escape) {doesc:		switch (ip->escape) {		case '&':			/* Next can be a,d, or s */			if (ip->fpd++) {				ip->escape = c;				ip->fpd = 0;			}			return;		case 'a':				/* cursor change */			switch (c) {			case 'Y':			/* Only y coord. */

⌨️ 快捷键说明

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