📄 pcvt_drv.c
字号:
/* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. * * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner. * * Copyright (c) 1993 Charles Hannum. * * All rights reserved. * * Parts of this code regarding the NetBSD interface were written * by Charles Hannum. * * This code is derived from software contributed to Berkeley by * William Jolitz and Don Ahn. * * 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 * Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Scott Turner * and Charles Hannum. * 4. The name authors may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. * * * @(#)pcvt_drv.c, 3.20, Last Edit-Date: [Sun Apr 2 19:09:19 1995] * *//*---------------------------------------------------------------------------* * * pcvt_drv.c VT220 Driver Main Module / OS - Interface * --------------------------------------------------------- * -hm ------------ Release 3.00 -------------- * -hm integrating NetBSD-current patches * -hm adding ttrstrt() proto for NetBSD 0.9 * -hm kernel/console output cursor positioning fixed * -hm kernel/console output switches optional to screen 0 * -hm FreeBSD 1.1 porting * -hm the NetBSD 0.9 compiler detected a nondeclared var which was * NOT detected by neither the NetBSD-current nor FreeBSD 1.x! * -hm including Michael's keyboard fifo code * -hm Joergs patch for FreeBSD tty-malloc code * -hm adjustments for NetBSD-current * -hm FreeBSD bugfix from Joerg re timeout/untimeout casts * -jw including Thomas Gellekum's FreeBSD 1.1.5 patch * -hm adjusting #if's for NetBSD-current * -hm applying Joerg's patch for FreeBSD 2.0 * -hm patch from Onno & Martin for NetBSD-current (post 1.0) * -hm some adjustments for NetBSD 1.0 * -hm NetBSD PR #400: screen size report for new session * -hm patch from Rafael Boni/Lon Willett for NetBSD-current * -hm bell patch from Thomas Eberhardt for NetBSD * -hm multiple X server bugfixes from Lon Willett * -hm patch from joerg - pcdevtotty for FreeBSD pre-2.1 * -hm delay patch from Martin Husemann after port-i386 ml-discussion * -jw add some code to provide more FreeBSD pre-2.1 support * *---------------------------------------------------------------------------*/#include "vt.h"#if NVT > 0#define EXTERN /* allocate mem */#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */#ifdef DEVFS#include <sys/devfsext.h>#if !defined(MAXCONS)#define MAXCONS 16#endifstatic void *pcvt_devfs_token[MAXCONS];#endif /*DEVFS*/#if PCVT_FREEBSD >= 200#include <machine/stdarg.h>#else#include "machine/stdarg.h"#endifextern int getchar __P((void));#if PCVT_NETBSD extern u_short *Crtat;#endif /* PCVT_NETBSD */unsigned __debug = 0; /*0xffe */static __color;static nrow;static void vgapelinit(void); /* read initial VGA DAC palette */#if defined XSERVER && !PCVT_USL_VT_COMPATstatic int pcvt_xmode_set(int on, struct proc *p); /* initialize for X mode */#endif /* XSERVER && !PCVT_USL_VT_COMPAT */static d_open_t pcopen;static d_close_t pcclose;static d_read_t pcread;static d_write_t pcwrite;static d_ioctl_t pcioctl;static d_devtotty_t pcdevtotty;static d_mmap_t pcmmap;#define CDEV_MAJOR 12static struct cdevsw pcdevsw = { pcopen, pcclose, pcread, pcwrite, pcioctl, nullstop, noreset, pcdevtotty, ttselect, pcmmap, nostrategy, "vt", NULL, -1};#if PCVT_FREEBSD > 205struct tty *pcdevtotty(Dev_t dev){ return get_pccons(dev);}#endif /* PCVT_FREEBSD > 205 */#if PCVT_NETBSD > 100 /* NetBSD-current Feb 20 1995 */intpcprobe(struct device *parent, void *match, void *aux)#else#if PCVT_NETBSD > 9intpcprobe(struct device *parent, struct device *self, void *aux)#elseintpcprobe(struct isa_device *dev)#endif /* PCVT_NETBSD > 9 */#endif /* PCVT_NETBSD > 100 */{#ifdef _I386_ISA_KBDIO_H_ kbdc = kbdc_open(IO_KBD); if(kbdc == NULL) { reset_keyboard = 0; return 1; } reset_keyboard = 1; /* it's now safe to do kbd reset */#endif /* _I386_ISA_KBDIO_H_ */ kbd_code_init();#if PCVT_NETBSD > 9 ((struct isa_attach_args *)aux)->ia_iosize = 16; return 1;#else#if PCVT_NETBSD || PCVT_FREEBSD return (16);#else return 1;#endif /* PCVT_NETBSD || PCVT_FREEBSD */#endif /* PCVT_NETBSD > 9 */}#if PCVT_NETBSD > 9voidpcattach(struct device *parent, struct device *self, void *aux){ struct isa_attach_args *ia = aux; static struct intrhand vthand;#elseintpcattach(struct isa_device *dev){#endif /* PCVT_NETBSD > 9 */#ifdef DEVFS int vt;#endif /*DEVFS*/ int i; vt_coldmalloc(); /* allocate memory for screens */#if PCVT_NETBSD || PCVT_FREEBSD#if PCVT_NETBSD > 9 printf(": ");#else printf("vt%d: ", dev->id_unit);#endif /* PCVT_NETBSD > 9 */ switch(adaptor_type) { case MDA_ADAPTOR: printf("mda"); break; case CGA_ADAPTOR: printf("cga"); break; case EGA_ADAPTOR: printf("ega"); break; case VGA_ADAPTOR: printf("%s, ", (char *)vga_string(vga_type)); if(can_do_132col) printf("80/132 col"); else printf("80 col"); vgapelinit(); break; default: printf("unknown"); break; } if(color == 0) printf(", mono"); else printf(", color"); printf(", %d scr, ", totalscreens); switch(keyboard_type) { case KB_AT: printf("at-"); break; case KB_MFII: printf("mf2-"); break; default: printf("unknown "); break; } printf("kbd, [R%s]\n", PCVT_REL);#if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) for(i = 0; i < totalscreens; i++) {#if PCVT_NETBSD pc_tty[i] = ttymalloc(); vs[i].vs_tty = pc_tty[i];#else /* !PCVT_NETBSD */ pccons[i] = ttymalloc(pccons[i]); vs[i].vs_tty = pccons[i];#endif /* PCVT_NETBSD */ }#if PCVT_EMU_MOUSE#if PCVT_NETBSD pc_tty[totalscreens] = ttymalloc(); /* the mouse emulator tty */#else /* !PCVT_NETBSD */ /* the mouse emulator tty */ pc_tty[totalscreens] = ttymalloc(pccons[totalscreens]);#endif /* PCVT_NETBSD */#endif /* PCVT_EMU_MOUSE */#if PCVT_NETBSD pcconsp = pc_tty[0];#else /* !PCVT_NETBSD */ pcconsp = pccons[0];#endif /* PCVT_NETBSD */#endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */#else /* !PCVT_NETBSD && !PCVT_FREEBSD*/ switch(adaptor_type) { case MDA_ADAPTOR: printf(" <mda"); break; case CGA_ADAPTOR: printf(" <cga"); break; case EGA_ADAPTOR: printf(" <ega"); break; case VGA_ADAPTOR: printf(" <%s,", (char *)vga_string(vga_type)); if(can_do_132col) printf("80/132 col"); else printf("80 col"); vgapelinit(); break; default: printf(" <unknown"); break; } if(color == 0) printf(",mono"); else printf(",color"); printf(",%d scr,", totalscreens); switch(keyboard_type) { case KB_AT: printf("at-"); break; case KB_MFII: printf("mf2-"); break; default: printf("unknown "); break; } printf("kbd,[R%s]>", PCVT_REL);#endif /* PCVT_NETBSD || PCVT_FREEBSD */#if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) for(i = 0; i < totalscreens; i++) vs[i].vs_tty = &pccons[i];#endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */ async_update(UPDATE_START); /* start asynchronous updates */#if PCVT_FREEBSD > 205 { dev_t dev = makedev(CDEV_MAJOR, 0); cdevsw_add(&dev, &pcdevsw, NULL); }#ifdef DEVFS for(vt = 0; vt < MAXCONS; vt++) { pcvt_devfs_token[vt] = devfs_add_devswf(&pcdevsw, vt, DV_CHR, 0, 0, 0600, "ttyv%n", vt ); }#endif DEVFS#endif /* PCVT_FREEBSD > 205 */#if PCVT_NETBSD > 9 vthand.ih_fun = pcrint; vthand.ih_arg = 0; vthand.ih_level = IPL_TTY;#if (PCVT_NETBSD > 100) && defined(IST_EDGE) intr_establish(ia->ia_irq, IST_EDGE, &vthand);#else /* PCVT_NETBSD > 100 */ intr_establish(ia->ia_irq, &vthand);#endif /* PCVT_NETBSD > 100 */#else /* PCVT_NETBSD > 9 */ return 1;#endif /* PCVT_NETBSD > 9 */}/* had a look at the friedl driver */#if !PCVT_NETBSDstruct tty *get_pccons(Dev_t dev){ register int i = minor(dev);#if PCVT_EMU_MOUSE if(i == totalscreens)#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) return(&pccons[i]);#else return(pccons[i]);#endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */#endif /* PCVT_EMU_MOUSE */ if(i >= PCVT_NSCREENS) return(NULL);#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) return(&pccons[i]);#else return(pccons[i]);#endif}#elsestruct tty *get_pccons(Dev_t dev){ register int i = minor(dev);#if PCVT_EMU_MOUSE if(i == totalscreens) return(pc_tty[i]);#endif /* PCVT_EMU_MOUSE */ if(i >= PCVT_NSCREENS) return(NULL); return(pc_tty[i]);}#endif /* !PCVT_NETBSD *//*---------------------------------------------------------------------------* * /dev/ttyc0, /dev/ttyc1, etc. *---------------------------------------------------------------------------*/intpcopen(Dev_t dev, int flag, int mode, struct proc *p){ register struct tty *tp; register struct video_state *vsx; int s, retval; int winsz = 0; int i = minor(dev);#if PCVT_EMU_MOUSE if(i == totalscreens) vsx = 0; else#endif /* PCVT_EMU_MOUSE */ vsx = &vs[i]; if((tp = get_pccons(dev)) == NULL) return ENXIO;#if PCVT_EMU_MOUSE if(i == totalscreens) { if(mouse.opened == 0) mouse.buttons = mouse.extendedseen = mouse.breakseen = mouse.lastmove.tv_sec = 0; mouse.minor = i; mouse.opened++; } else#endif /* PCVT_EMU_MOUSE */ vsx->openf++; tp->t_oproc = pcstart; tp->t_param = pcparam; tp->t_dev = dev; if ((tp->t_state & TS_ISOPEN) == 0) {#ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */ tp->t_state |= TS_WOPEN;#endif ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; pcparam(tp, &tp->t_termios); ttsetwater(tp); (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */ winsz = 1; /* set winsize later */ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) return (EBUSY);#if PCVT_NETBSD || (PCVT_FREEBSD >= 200) retval = ((*linesw[tp->t_line].l_open)(dev, tp));#else retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));#endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */ if(winsz == 1) { /* * The line discipline has clobbered t_winsize if TS_ISOPEN * was clear. (NetBSD PR #400 from Bill Sommerfeld) * We have to do this after calling the open routine, because * it does some other things in other/older *BSD releases -hm */ s = spltty(); tp->t_winsize.ws_col = vsx->maxcol; tp->t_winsize.ws_row = vsx->screen_rows; tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056; tp->t_winsize.ws_ypixel = 400; splx(s); } return(retval);}intpcclose(Dev_t dev, int flag, int mode, struct proc *p){ register struct tty *tp; register struct video_state *vsx; int i = minor(dev);#if PCVT_EMU_MOUSE if(i == totalscreens) vsx = 0; else#endif /* PCVT_EMU_MOUSE */ vsx = &vs[i]; if((tp = get_pccons(dev)) == NULL) return ENXIO; (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -