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

📄 qv.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	 */	qvaddr = (struct qvdevice *)tp->t_addr;	if (QVCHAN(unit) == QVKEYBOARD )		qvaddr->qv_csr &= ~QV_INT_ENABLE;	/*	 * If unit is not the mouse channel call the line disc.	 * otherwise clear the state flag, and put the keyboard into down/up.	 */	if (QVCHAN(unit) != QVMOUSECHAN) {		(*linesw[tp->t_line].l_close)(tp, flag);		error = ttyclose(tp);	} else {		mouseon = 0;		qv_init( qvaddr );		error = 0;	}	tp->t_state = 0;	return (error);}qvread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	int unit = minor( dev );	if (QVCHAN(unit) != QVMOUSECHAN) {		tp = &qv_tty[unit];		return ((*linesw[tp->t_line].l_read)(tp, uio));	}	return (ENXIO);}qvwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	int unit = minor( dev );	/*	 * If this is the mouse we simply fake the i/o, otherwise	 * we let the line disp. handle it.	 */	if (QVCHAN(unit) == QVMOUSECHAN) {		uio->uio_offset = uio->uio_resid;		uio->uio_resid = 0;		return 0;	}	tp = &qv_tty[unit];	return ((*linesw[tp->t_line].l_write)(tp, uio));}/* * Mouse activity select routine */qvselect(dev, rw)dev_t dev;{	register int s = spl5();	register struct qv_info *qp = qv_scn;	if( QVCHAN(minor(dev)) == QVMOUSECHAN )		switch(rw) {		case FREAD:			/* if events okay */			if(qp->ihead != qp->itail) {				splx(s);				return(1);			}			qvrsel = u.u_procp;			splx(s);			return(0);		default:			/* can never write */			splx(s);			return(0);		}	else {		splx(s);		return( ttselect(dev, rw) );	}	/*NOTREACHED*/}		/* * QVSS keyboard interrupt. */qvkint(qv)	int qv;{	struct tty *tp;	register c;	struct uba_device *ui;	register int key;	register int i;	ui = qvinfo[qv];	if (ui == 0 || ui->ui_alive == 0)		return;	tp = &qv_tty[qv<<2];	/*	 * Get a character from the keyboard.	 */	key = ((struct qvdevice *)ui->ui_addr)->qv_uartdata & 0xff;	if( mouseon == 0) {		/*		 * Check for various keyboard errors		 */		if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR ||		    key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) {			log(LOG_ERR,			    "qv%d: Keyboard error, code = %x\n",qv,key);			return;		}		if( key < LK_LOWEST ) return;		/*		 * See if its a state change key		 */		switch ( key ) {		case LOCK:			qv_keyboard.lock ^= 0xffff;	/* toggle */			if( qv_keyboard.lock )				qv_key_out( LK_LED_ENABLE );			else				qv_key_out( LK_LED_DISABLE );			qv_key_out( LED_3 );			return;		case SHIFT:			qv_keyboard.shift ^= 0xffff;			return;			case CNTRL:			qv_keyboard.cntrl ^= 0xffff;			return;		case ALLUP:			qv_keyboard.cntrl = qv_keyboard.shift = 0;			return;		case REPEAT:			c = qv_keyboard.last;			break;		default:		/*		 * Test for control characters. If set, see if the character		 * is elligible to become a control character.		 */			if( qv_keyboard.cntrl ) {				c = q_key[ key ];				if( c >= ' ' && c <= '~' )					c &= 0x1f;			} else if( qv_keyboard.lock || qv_keyboard.shift )				c = q_shift_key[ key ];				else				c = q_key[ key ];			break;			}		qv_keyboard.last = c;		/*		 * Check for special function keys		 */		if( c & 0x80 ) {			register char *string;			string = q_special[ c & 0x7f ];			while( *string )			(*linesw[tp->t_line].l_rint)(*string++, tp);		} else			(*linesw[tp->t_line].l_rint)(c, tp);	} else {		/*		 * Mouse channel is open put it into the event queue		 * instead.		 */		register struct qv_info *qp = qv_scn;		register vsEvent *vep;		if ((i = EVROUND(qp->itail+1)) == qp->ihead) 			return;		vep = &qp->ibuff[qp->itail];		vep->vse_direction = VSE_KBTRAW;		vep->vse_type = VSE_BUTTON;		vep->vse_device = VSE_DKB;		vep->vse_x = qp->mouse.x;		vep->vse_y = qp->mouse.y;		vep->vse_time = TOY;		vep->vse_key = key;		qp->itail = i;		if(qvrsel) {			selwakeup(qvrsel,0);			qvrsel = 0;		}	}}/* * Ioctl for QVSS. *//*ARGSUSED*/qvioctl(dev, cmd, data, flag)	dev_t dev;	register caddr_t data;{	register struct tty *tp;	register int unit = minor(dev);	register struct qv_info *qp = qv_scn;	register struct qv_kpcmd *qk;	register unsigned char *cp;	int error; 	/*	 * Check for and process qvss specific ioctl's	 */	switch( cmd ) {	case QIOCGINFO:					/* return screen info */		bcopy((caddr_t)qp, data, sizeof (struct qv_info));		break;	case QIOCSMSTATE:				/* set mouse state */		qp->mouse = *((vsCursor *)data);		qv_pos_cur( qp->mouse.x, qp->mouse.y );		break;	case QIOCINIT:					/* init screen	*/		qv_init( qp->qvaddr );		break;	case QIOCKPCMD:		qk = (struct qv_kpcmd *)data;		if(qk->nbytes == 0) qk->cmd |= 0200;		if(mouseon == 0) qk->cmd |= 1;	/* no mode changes */		qv_key_out(qk->cmd);		cp = &qk->par[0];		while(qk->nbytes-- > 0) {	/* terminate parameters */			if(qk->nbytes <= 0) *cp |= 0200;			qv_key_out(*cp++);		}		break;	case QIOCADDR:					/* get struct addr */		*(struct qv_info **) data = qp;		break;	default:					/* not ours ??  */		tp = &qv_tty[unit];		error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);		if (error >= 0)			return (error);		error = ttioctl(tp, cmd, data, flag);		if (error >= 0) {			return (error);		}		break;	}	return (0);}/* * Initialize the screen and the scanmap */qv_init(qvaddr)struct qvdevice *qvaddr;{	register short *scanline;	register int i;	register short scan;	register char *ptr;	register struct qv_info *qp = qv_scn;	/*	 * Clear the bit map	 */	for( i=0 , ptr = qp->bitmap ; i<240 ; i += 2 , ptr += 2048)		bzero( ptr, 2048 );	/*	 * Reinitialize the scanmap	 */        scan = qvaddr->qv_csr & QV_MEM_BANK;        scanline = qp->scanmap;        for(i = 0 ; i < qp->max_y ; i++ )                *scanline++ = scan++;	/*	 * Home the cursor	 */	qp->row = qp->col = 0;	/*	 * Reset the cursor to the default type.	 */	for( i=0 ; i<16 ; i++ )		qp->cursorbits[i] = q_cursor[i];	qvaddr->qv_csr |= QV_CUR_MODE;	/*	 * Reset keyboard to default state.	 */	qvkbdreset();}qvreset(){}qvkbdreset(){	register int i;	qv_key_out(LK_DEFAULTS);	for( i=1 ; i < 15 ; i++ )		qv_key_out( divdefaults[i] | (i<<3));	for (i = 0; i < KBD_INIT_LENGTH; i++)		qv_key_out(kbdinitstring[i]);}#define abs(x) (((x) > 0) ? (x) : (-(x)))/* * QVSS vertical sync interrupt */qvvint(qv)	int qv;{	extern int selwait;	register struct qvdevice *qvaddr;	struct uba_device *ui;	register struct qv_info *qp = qv_scn;	int unit;	struct tty *tp0;	int i;	register int j;	/*	 * Mouse state info	 */	static ushort omouse = 0, nmouse = 0;	static char omx=0, omy=0, mx=0, my=0, om_switch=0, m_switch=0;	register int dx, dy;	/*	 * Test and set the qv_ipl_lo flag. If the result is not zero then	 * someone else must have already gotten here.	 */	if( --qv_ipl_lo )		return;	(void)spl4();	ui = qvinfo[qv];	unit = qv<<2;	qvaddr = (struct qvdevice *)ui->ui_addr;	tp0 = &qv_tty[QVCHAN(unit) + QVMOUSECHAN];	/*	 * See if the mouse has moved.	 */	if( omouse != (nmouse = qvaddr->qv_mouse) ) {		omouse = nmouse;		mx = nmouse & 0xff;		my = nmouse >> 8;		dy = my - omy; omy = my;		dx = mx - omx; omx = mx;		if( dy < 50 && dy > -50 && dx < 50 && dx > -50 ) {			register vsEvent *vep;			if( qp->mscale < 0 ) {	/* Ray Lanza's original */				if( dy < 0 )					dy = -( dy * dy );				else					dy *= dy;				if( dx < 0 )					dx = -( dx * dx );				else					dx *= dx;			}			else {			/* Vs100 style, see WGA spec */			    int thresh = qp->mthreshold;			    int scale  = qp->mscale;			    if( abs(dx) > thresh ) {				if ( dx < 0 )				    dx = (dx + thresh)*scale - thresh;				else				    dx = (dx - thresh)*scale + thresh;			    }			    if( abs(dy) > thresh ) {				if ( dy < 0 )				    dy = (dy + thresh)*scale - thresh;				else				    dy = (dy - thresh)*scale + thresh;			    }			}			qp->mouse.x += dx;			qp->mouse.y -= dy;			if( qp->mouse.x < 0 )				qp->mouse.x = 0;			if( qp->mouse.y < 0 )				qp->mouse.y = 0;			if( qp->mouse.x > qp->max_cur_x )				qp->mouse.x = qp->max_cur_x;			if( qp->mouse.y > qp->max_cur_y )				qp->mouse.y = qp->max_cur_y;			if( tp0->t_state & TS_ISOPEN )				qv_pos_cur( qp->mouse.x, qp->mouse.y );			if (qp->mouse.y < qp->mbox.bottom &&			    qp->mouse.y >=  qp->mbox.top &&			    qp->mouse.x < qp->mbox.right &&			    qp->mouse.x >=  qp->mbox.left) goto switches;			qp->mbox.bottom = 0;	/* trash box */			if (EVROUND(qp->itail+1) == qp->ihead)				goto switches;			i = EVROUND(qp->itail - 1);			if ((qp->itail != qp->ihead) &&	(i != qp->ihead)) {				vep = & qp->ibuff[i];				if(vep->vse_type == VSE_MMOTION) {					vep->vse_x = qp->mouse.x;					vep->vse_y = qp->mouse.y;					goto switches;				}			}			/* put event into queue and do select */			vep = & qp->ibuff[qp->itail];			vep->vse_type = VSE_MMOTION;			vep->vse_time = TOY;			vep->vse_x = qp->mouse.x;			vep->vse_y = qp->mouse.y;			qp->itail = EVROUND(qp->itail+1);		}	}	/*	 * See if mouse switches have changed.	 */switches:if( om_switch != ( m_switch = (qvaddr->qv_csr & QV_MOUSE_ANY) >> 8 ) ) {		qp->mswitches = ~m_switch & 0x7;		for (j = 0; j < 3; j++) {	/* check each switch */			register vsEvent *vep;			if ( ((om_switch>>j) & 1) == ((m_switch>>j) & 1) )				continue;			/* check for room in the queue */			if ((i = EVROUND(qp->itail+1)) == qp->ihead) return;			/* put event into queue and do select */			vep = &qp->ibuff[qp->itail];			vep->vse_type = VSE_BUTTON;			vep->vse_key = 2 - j;			vep->vse_direction = VSE_KBTDOWN;			if ( (m_switch >> j) & 1)				vep->vse_direction = VSE_KBTUP;			vep->vse_device = VSE_MOUSE;			vep->vse_time = TOY;			vep->vse_x = qp->mouse.x;			vep->vse_y = qp->mouse.y;		}		qp->itail =  i;

⌨️ 快捷键说明

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