📄 qv.c
字号:
tp->t_state = TS_ISOPEN|TS_CARR_ON; tp->t_cflag = tp->t_cflag_ext = B9600; tp->t_iflag_ext = 0; tp->t_oflag_ext = 0; tp->t_lflag_ext = 0; if( unit == 0 ) { /* make sure keyboard is always back to default *//* qvkbdreset();*/ /* * Ultrix defaults to a "COOKED" mode on the first * open, while termio defaults to a "RAW" style. * Base this decision by a flag set in the termio * emulation routine for open, or set by an explicit * ioctl call. */ if ( flag & O_TERMIO ) { /* * Provide a termio style environment. * "RAW" style by default. */ tp->t_flags = RAW; tp->t_iflag = 0; tp->t_oflag = 0; tp->t_cflag |= CS8|CREAD|HUPCL; tp->t_lflag = 0; /* * Change to System V line discipline. */ tp->t_line = TERMIODISC; /* * The following three control chars have * different default values than ULTRIX. */ tp->t_cc[VERASE] = '#'; tp->t_cc[VKILL] = '@'; tp->t_cc[VINTR] = 0177; tp->t_cc[VMIN] = 6; tp->t_cc[VTIME] = 1; } else { /* * Provide a backward compatible ULTRIX * environment. "COOKED" style. */ tp->t_flags = IFLAGS; tp->t_iflag = IFLAG; tp->t_oflag = OFLAG; tp->t_lflag = LFLAG; tp->t_cflag |= CFLAG; } } else { tp->t_flags = RAW; tp->t_iflag = 0; tp->t_oflag = 0; tp->t_cflag |= CS8|CREAD|HUPCL; tp->t_lflag = 0; } if( unit == 1 ) tp->t_iflag |= IXOFF; /* flow control for qconsole */ } qvaddr->qv_csr |= QV_INT_ENABLE; /* * Process line discipline specific open if its not the * mouse channel. For the mouse we init the ring ptr's. */ if( ( unit % 4 ) != QVMOUSECHAN ) return ((*linesw[tp->t_line].l_open)(dev, tp)); else { mouseon = 1; qp->qe.events = (qvEvent *)qp - QVMAXEVQ; qp->qe.eSize = QVMAXEVQ; qp->qe.eHead = qp->qe.eTail = 0; qp->qe.tcs = (qvTimeCoord *)qp->qe.events - MOTION_BUFFER_SIZE; qp->qe.tcSize = MOTION_BUFFER_SIZE; qp->qe.tcNext = 0; return 0; }}/* * Close a QVSS line. *//*ARGSUSED*/qvclose(dev, flag) dev_t dev; int flag;{ register struct tty *tp; register unit; register struct qvdevice *qvaddr; register struct qv_info *qp = qv_scn; unit = minor(dev); tp = &qv_tty[unit]; /* * If this is the keyboard unit (0) shutdown the * interface. */ qvaddr = (struct qvdevice *)tp->t_addr;#ifdef notdef if( unit == 0 ) qvaddr->qv_csr &= ~QV_INT_ENABLE;#endif /* * If unit is not the mouse channel call the line disc. * otherwise clear the state flag, and put the keyboard into down/up. */ if( ( unit % 4 ) != QVMOUSECHAN ){ (*linesw[tp->t_line].l_close)(tp); ttyclose(tp); qv_dev_inuse &= ~CONS_DEV; qv_keyboard.cntrl = qv_keyboard.shift = 0; } else { mouseon = 0; if (qv_open_flag != 1) return(EBUSY); else qv_open_flag = 0; /* mark the graphics device available */ qv_dev_inuse &= ~GRAPHIC_DEV; qv_init( qvaddr ); if (qv_video_off) { qp->qvaddr->qv_csr |= QV_VIDEO_ENA; qv_video_off = 0; } } tp->t_state = 0; /* Remove termio flags that do not map */ tp->t_iflag &= ~TERMIO_ONLY_IFLAG; tp->t_oflag &= ~TERMIO_ONLY_OFLAG; tp->t_cflag &= ~TERMIO_ONLY_CFLAG; tp->t_lflag &= ~TERMIO_ONLY_LFLAG;}qvread(dev, uio) dev_t dev; struct uio *uio;{ register struct tty *tp; int unit = minor( dev ); if( (unit % 4) != 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( (unit % 4) == 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 int unit = minor(dev); register struct qv_info *qp = qv_scn; if( (unit % 4) == QVMOUSECHAN ) switch(rw) { case FREAD: /* if events okay */ if (qp->qe.eHead != qp->qe.eTail) { splx(s); return(1); } rsel = u.u_procp; splx(s); return(0); case FWRITE: /* can never write */ splx(s); return(EACCES); } else return( ttselect(dev, rw) );}/* * QVSS keyboard interrupt. */qvkint(qv) int qv;{ struct tty *tp; register u_short c; struct uba_device *ui; register int key; register int i,j; int k,l; register struct qv_info *qp = qv_scn; struct mouse_report *new_rep, last_rep, current_rep; qvEvent *qep;/* * Mouse state info */ static char temp, old_switch, new_switch; 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) { mprintf("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 (c >= 0xA1 && c <= 0xFE) /* 8-bit chr */ c &= 0x9F; } 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 & 0x100 ) { register char *string; string = q_special[ c & 0x7f ]; while( *string ) (*linesw[tp->t_line].l_rint)(*string++, tp); } else { if (tp->t_iflag & ISTRIP) /* Strip to 7 bits. */ c &= 0177; else { /* Take the full 8-bits */ /* If ISTRIP is not set a valid character of 377 * is read as 0377,0377 to avoid ambiguity with * the PARMARK sequence. */ if ((c == 0377) && (tp->t_line == TERMIODISC) && (tp->t_iflag & PARMRK)) (*linesw[tp->t_line].l_rint)(0377,tp); } (*linesw[tp->t_line].l_rint)(c, tp); } } else { /* * Mouse channel is open put it into the event queue * instead. */ if ((i = EVROUND(qp->qe.eTail+1)) == qp->qe.eHead) return(0); qep = &qp->qe.events[qp->qe.eTail]; qep->direction = QV_KBTRAW; qep->type = QV_BUTTON; qep->device = QV_DKB; qep->x = qp->mouse.x; qep->y = qp->mouse.y; qep->time = TOY; qep->key = key; qp->qe.eTail = i; if((i=EVROUND(qp->qe.eTail+1)) == qp->qe.eHead) return(0); qep = &qp->qe.events[qp->qe.eTail]; if (rsel && (qp->qe.eHead != qp->qe.eTail)) { selwakeup (rsel, 0); rsel = 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) >> 2; register struct qv_info *qp = qv_scn; register struct qv_kpcmd *qk; register unsigned char *cp; struct uba_device *ui = qvinfo[unit]; struct qv_softc *sc = &qv_softc[ui->ui_unit]; struct devget *devget; int error; int minor_dev = minor(dev); int i; u_short *pcurs=(u_short *)data; /* * Check for and process qvss specific ioctl's */ switch( cmd ) { case QIOCGINFO: /* return screen info */ bcopy(qp, data, sizeof (struct qv_info)); break; case QIOCSMSTATE: /* set mouse state */ qp->mouse = *((qvCursor *)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; case QIOWCURSOR: /* Write cursor bit map */ for( i=0 ; i<16 ; i++ ) qp->cursorbits[i] = *pcurs++; qp->qvaddr->qv_csr |= QV_CUR_MODE; break; case QIOVIDEOON: /* turn on the video */ qp->qvaddr->qv_csr |= QV_VIDEO_ENA; qv_video_off = 0; break; case QIOVIDEOOFF: /* turn off the video */ qp->qvaddr->qv_csr &= ~QV_VIDEO_ENA; qv_video_off = 1; break; case DEVIOCGET: /* device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); devget->category = DEV_TERMINAL; devget->bus = DEV_QB; bcopy(DEV_VCB01,devget->interface, strlen(DEV_VCB01)); bcopy(DEV_VR260,devget->device, strlen(DEV_VR260)); /* terminal */ devget->adpt_num = ui->ui_adpt; /* which adapter*/ devget->nexus_num = ui->ui_nexus; /* which nexus */ devget->bus_num = ui->ui_ubanum; /* which QB */ devget->ctlr_num = unit; /* which interf.*/ devget->slave_num = unit; /* which line */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "qv" */ devget->unit_num = unit; /* qv line? */ devget->soft_count = sc->sc_softcnt; /* soft er. cnt.*/ devget->hard_count = sc->sc_hardcnt; /* hard er cnt. */ devget->stat = sc->sc_flags; /* status */ devget->category_stat = sc->sc_category_flags; /* cat. stat. */ break; case QD_KERN_UNLOOP: /* called from inside kernel, but not used */ break; default: /* not ours ?? */ tp = &qv_tty[minor_dev]; 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); } /* if error = -1 then ioctl does not exist */ if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); 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 */#define QVSS_TIME1 100#define QVSS_TIME2 500#define QVSS_MAX_LOOP 10200qvvint(qv) int qv;{ extern int selwait; register struct qvdevice *qvaddr; struct uba_device *ui; register struct qv_info *qp = qv_scn; register int value; 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; qvEvent *qep; /* * 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; qp->qe.timestamp_ms = TOY; spl4(); ui = qvinfo[qv]; unit = qv<<2; qvaddr = (struct qvdevice *)ui->ui_addr; tp0 = &qv_tty[(unit % 4 )+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 ) { 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -