📄 qv.c
字号:
*/ 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 + -