📄 pcvt_sup.c
字号:
/* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. * * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner. * * Copyright (C) 1992, 1993 Soeren Schmidt. * * All rights reserved. * * For the sake of compatibility, portions of this code regarding the * X server interface are taken from Soeren Schmidt's syscons driver. * * 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 Soeren Schmidt. * 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_sup.c, 3.20, Last Edit-Date: [Thu Apr 6 10:49:44 1995] * *//*---------------------------------------------------------------------------* * * pcvt_sup.c VT220 Driver Support Routines * --------------------------------------------- * -hm ------------ Release 3.00 -------------- * -hm integrating NetBSD-current patches * -hm removed paranoid delay()/DELAY() from vga_test() * -hm removing vgapage() protection if PCVT_KBD_FIFO * -hm some new CONF_ - values * -hm Joerg's patches for FreeBSD ttymalloc * -hm applying Joerg's patches for FreeBSD 2.0 * -hm applying Lon Willet's patches for NetBSD * -hm NetBSD PR #400: patch to short-circuit TIOCSWINSZ * -hm getting PCVT_BURST reported correctly for FreeBSD 2.0 * -hm applying patch from Joerg fixing Crtat bug * -hm moving ega/vga coldinit support code to mda2egaorvga() * -hm patch from Thomas Eberhardt fixing force 24 lines fkey update * *---------------------------------------------------------------------------*/#include "vt.h"#if NVT > 0#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */static void vid_cursor ( struct cursorshape *data );static void vgasetfontattr ( struct vgafontattr *data );static void vgagetfontattr ( struct vgafontattr *data );static void vgaloadchar ( struct vgaloadchar *data );static void vid_getscreen ( struct screeninfo *data, Dev_t dev );static void vid_setscreen ( struct screeninfo *data, Dev_t dev );static void setchargen ( void );static void setchargen3 ( void );static void resetchargen ( void );static void vgareadpel ( struct vgapel *data, Dev_t dev );static void vgawritepel ( struct vgapel *data, Dev_t dev );static void vgapcvtid ( struct pcvtid *data );static void vgapcvtinfo ( struct pcvtinfo *data );#ifdef XSERVERstatic unsigned char * compute_charset_base ( unsigned fontset );#endif /* XSERVER */#if PCVT_SCREENSAVERstatic void scrnsv_timedout ( void *arg );static u_short *savedscreen = (u_short *)0; /* ptr to screen contents */static size_t scrnsv_size = (size_t)-1; /* size of saved image */#ifndef XSERVERstatic unsigned scrnsv_timeout = 0; /* initially off */static void pcvt_set_scrnsv_tmo ( int timeout );/* else declared global */#endif /* XSERVER */#if PCVT_PRETTYSCRNSstatic u_short *scrnsv_current = (u_short *)0; /* attention char ptr */static void scrnsv_blink ( void * );static u_short getrand ( void );#endif /* PCVT_PRETTYSCRNS */#endif /* PCVT_SCREENSAVER *//*---------------------------------------------------------------------------* * execute vga ioctls *---------------------------------------------------------------------------*/intvgaioctl(Dev_t dev, int cmd, caddr_t data, int flag){ if(minor(dev) >= PCVT_NSCREENS) return -1;/* * Some of the commands are not applicable if the vt in question, or the * current vt is in graphics mode (i.e., the X server acts on it); they * will cause an EAGAIN (resource temporarily unavailable) to be returned. */#ifdef XSERVER#if PCVT_USL_VT_COMPAT#define is_dev_grafx vs[minor(dev)].vt_status & VT_GRAFX#define is_current_grafx vsp->vt_status & VT_GRAFX#else /* old X interface */#define is_dev_grafx pcvt_xmode#define is_current_grafx pcvt_xmode#endif /* PCVT_USL_VT_COMPAT */#else /* !XSERVER */#define is_dev_grafx 0 /* not applicable */#define is_current_grafx 0#endif /* XSERVER */ switch(cmd) { case VGACURSOR: if(is_current_grafx) return EAGAIN; vid_cursor((struct cursorshape *)data); break; case VGALOADCHAR: if((adaptor_type != VGA_ADAPTOR) && (adaptor_type != EGA_ADAPTOR)) return -1; if(is_current_grafx) return EAGAIN; vgaloadchar((struct vgaloadchar *)data); break; case VGASETFONTATTR: if((adaptor_type != VGA_ADAPTOR) && (adaptor_type != EGA_ADAPTOR)) return -1;#if PCVT_SCREENSAVER pcvt_scrnsv_reset();#endif /* PCVT_SCREENSAVER */ vgasetfontattr((struct vgafontattr *)data); break; case VGAGETFONTATTR: if((adaptor_type != VGA_ADAPTOR) && (adaptor_type != EGA_ADAPTOR)) return -1; vgagetfontattr((struct vgafontattr *)data); break; case VGASETSCREEN:#if defined XSERVER && !PCVT_USL_VT_COMPAT /* avoid screen switch if using old X mode */ if(is_dev_grafx) return EAGAIN;#endif /* XSERVER && !PCVT_USL_VT_COMPAT */#if PCVT_SCREENSAVER pcvt_scrnsv_reset();#endif /* PCVT_SCREENSAVER */ vid_setscreen((struct screeninfo *)data, dev); break; case VGAGETSCREEN: vid_getscreen((struct screeninfo *)data, dev); break; case VGAREADPEL: if(adaptor_type != VGA_ADAPTOR) return -1; if(is_dev_grafx) return EAGAIN; vgareadpel((struct vgapel *)data, dev); break; case VGAWRITEPEL: if(adaptor_type != VGA_ADAPTOR) return -1; if(is_dev_grafx) return EAGAIN; vgawritepel((struct vgapel *)data, dev); break;#if PCVT_SCREENSAVER case VGASCREENSAVER: if(is_current_grafx) return EAGAIN; pcvt_set_scrnsv_tmo(*(int *)data); pcvt_scrnsv_reset(); break;#endif /* PCVT_SCREENSAVER */ case VGAPCVTID: vgapcvtid((struct pcvtid *)data); break; case VGAPCVTINFO: vgapcvtinfo((struct pcvtinfo *)data); break; case VGASETCOLMS: if(is_dev_grafx) return EAGAIN; if(*(int *)data == 80) (void)vt_col(&vs[minor(dev)], SCR_COL80); else if(*(int *)data == 132) { if(vt_col(&vs[minor(dev)], SCR_COL132) == 0) return EINVAL; /* not a VGA */ } else return EINVAL; break; case TIOCSWINSZ: /* do nothing here */ break; default: return -1; } return 0;#undef is_dev_grafx#undef is_current_grafx}/*---------------------------------------------------------------------------* * video ioctl - return driver id *---------------------------------------------------------------------------*/static voidvgapcvtid(struct pcvtid *data){ strcpy(data->name, PCVTIDNAME); data->rmajor = PCVTIDMAJOR; data->rminor = PCVTIDMINOR;}/*---------------------------------------------------------------------------* * video ioctl - return driver compile time options data *---------------------------------------------------------------------------*/static voidvgapcvtinfo(struct pcvtinfo *data){#if PCVT_NETBSD data->opsys = CONF_NETBSD; data->opsysrel = PCVT_NETBSD;#elif PCVT_FREEBSD data->opsys = CONF_FREEBSD; data->opsysrel = PCVT_FREEBSD;#else data->opsys = CONF_UNKNOWNOPSYS; data->opsysrel = 0;#endif data->nscreens = PCVT_NSCREENS; data->scanset = PCVT_SCANSET; data->updatefast= PCVT_UPDATEFAST; data->updateslow= PCVT_UPDATESLOW; data->sysbeepf = PCVT_SYSBEEPF;#if PCVT_NETBSD || PCVT_FREEBSD >= 200 data->pcburst = PCVT_PCBURST;#else data->pcburst = 1;#endif#if PCVT_KBD_FIFO data->kbd_fifo_sz = PCVT_KBD_FIFO_SZ;#else data->kbd_fifo_sz = 0;#endif data->compile_opts = (0#if PCVT_VT220KEYB | CONF_VT220KEYB#endif#if PCVT_SCREENSAVER | CONF_SCREENSAVER#endif#if PCVT_PRETTYSCRNS | CONF_PRETTYSCRNS#endif#if PCVT_CTRL_ALT_DEL | CONF_CTRL_ALT_DEL#endif#if PCVT_USEKBDSEC | CONF_USEKBDSEC#endif#if PCVT_24LINESDEF | CONF_24LINESDEF#endif#if PCVT_EMU_MOUSE | CONF_EMU_MOUSE#endif#if PCVT_SHOWKEYS | CONF_SHOWKEYS#endif#if PCVT_KEYBDID | CONF_KEYBDID#endif#if PCVT_SIGWINCH | CONF_SIGWINCH#endif#if PCVT_NULLCHARS | CONF_NULLCHARS#endif#if PCVT_BACKUP_FONTS | CONF_BACKUP_FONTS#endif#if PCVT_SW0CNOUTP /* was FORCE8BIT */ | CONF_SW0CNOUTP#endif#if PCVT_SETCOLOR | CONF_SETCOLOR#endif#if PCVT_132GENERIC | CONF_132GENERIC#endif#if PCVT_PALFLICKER | CONF_PALFLICKER#endif#if PCVT_WAITRETRACE | CONF_WAITRETRACE#endif#ifdef XSERVER | CONF_XSERVER#endif#if PCVT_USL_VT_COMPAT | CONF_USL_VT_COMPAT#endif#if PCVT_PORTIO_DELAY | CONF_PORTIO_DELAY#endif#if PCVT_INHIBIT_NUMLOCK | CONF_INHIBIT_NUMLOCK#endif#if PCVT_META_ESC | CONF_META_ESC#endif#if PCVT_KBD_FIFO | CONF_KBD_FIFO#endif#if PCVT_NOFASTSCROLL | CONF_NOFASTSCROLL#endif#if PCVT_SLOW_INTERRUPT | CONF_SLOW_INTERRUPT#endif#if PCVT_NO_LED_UPDATE | CONF_NO_LED_UPDATE#endif );}/*---------------------------------------------------------------------------* * video ioctl - set cursor appearence *---------------------------------------------------------------------------*/static voidvid_cursor(struct cursorshape *data){ int screen; int start; int end; int line_height; int character_set; /* for which virtual screen, -1 for current */ screen = data->screen_no; if(screen == -1) /* current ? */ screen = current_video_screen; else if(screen > totalscreens - 1) screen = totalscreens - 1; else if(screen < 0) screen = 0; if(adaptor_type == VGA_ADAPTOR || adaptor_type == EGA_ADAPTOR) { character_set = vs[screen].vga_charset; character_set = (character_set < 0) ? 0 : ((character_set < totalfonts) ? character_set : totalfonts-1); line_height = vgacs[character_set].char_scanlines & 0x1F; } else if(adaptor_type == MDA_ADAPTOR) { line_height = 14; } else { line_height = 8; /* CGA */ } start = (data->start < 0) ? 0 : ((data->start > line_height) ? line_height : data->start); if((vga_family == VGA_F_TRI) && (start == 0)) start = 1; end = (data->end < 0) ? 0 : ((data->end > line_height) ? line_height : data->end); vs[screen].cursor_start = start; vs[screen].cursor_end = end; if(screen == current_video_screen) { outb(addr_6845,CRTC_CURSTART); /* cursor start reg */ outb(addr_6845+1, start); outb(addr_6845,CRTC_CUREND); /* cursor end reg */ outb(addr_6845+1, end); }}/*---------------------------------------------------------------------------* * ega/vga ioctl - set font attributes *---------------------------------------------------------------------------*/static voidvgasetfontattr(struct vgafontattr *data){ register int i; int vga_character_set; int lines_per_character; int totscanlines; int size; vga_character_set = data->character_set; vga_character_set = (vga_character_set < 0) ? 0 : ((vga_character_set < totalfonts) ? vga_character_set : totalfonts-1); vgacs[vga_character_set].loaded = data->font_loaded; /* Limit Characters to 32 scanlines doubled */ vgacs[vga_character_set].char_scanlines = (data->character_scanlines & 0x1F) | 0x40; /* always set bit 9 of line cmp reg */ if(adaptor_type == EGA_ADAPTOR) /* ...and screen height to scan 350 lines */ vgacs[vga_character_set].scr_scanlines = (data->screen_scanlines > 0x5d) ? 0x5d : data->screen_scanlines; else /* ...and screen height to scan 480 lines */ vgacs[vga_character_set].scr_scanlines = (data->screen_scanlines > 0xdF) ? 0xdF : data->screen_scanlines; lines_per_character = (int)(0x1F & vgacs[vga_character_set].char_scanlines)+1; totscanlines = 0x101 + (int)vgacs[vga_character_set].scr_scanlines; size = data->screen_size; if(adaptor_type == EGA_ADAPTOR) { switch(size) { case SIZ_25ROWS: /* This case is always OK */ break; case SIZ_35ROWS: if(totscanlines/lines_per_character >= 35) size = SIZ_35ROWS; else size = SIZ_25ROWS; break; case SIZ_43ROWS: default: if(totscanlines/lines_per_character >= 43) size = SIZ_43ROWS; else if(totscanlines/lines_per_character >= 35) size = SIZ_35ROWS; else size = SIZ_25ROWS; break; } } else { switch(size) { case SIZ_25ROWS: /* This case is always OK */ break; case SIZ_28ROWS: if(totscanlines/lines_per_character >= 28) size = SIZ_28ROWS; else size = SIZ_25ROWS; break; case SIZ_40ROWS: if(totscanlines/lines_per_character >= 40) size = SIZ_40ROWS; else if(totscanlines/lines_per_character >= 28) size = SIZ_28ROWS; else size = SIZ_25ROWS; break; case SIZ_50ROWS: default: if(totscanlines/lines_per_character >= 50) size = SIZ_50ROWS; else if(totscanlines/lines_per_character >= 40) size = SIZ_40ROWS; else if(totscanlines/lines_per_character >= 28) size = SIZ_28ROWS; else size = SIZ_25ROWS; break; } } vgacs[vga_character_set].screen_size = size; for (i = 0;i < PCVT_NSCREENS;i++) { if(vga_character_set == vs[i].vga_charset) set_charset(&(vs[i]),vga_character_set); }#if !PCVT_USL_VT_COMPAT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -