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

📄 pcvt_ext.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if(color)			inb(GN_INPSTAT1C);		else			inb(GN_INPSTAT1M);		/* ATC Mode control */		outb(ATC_INDEX, ATC_MODE | ATC_ACCESS);		outb(ATC_DATAW, *sp++);		if(color)			inb(GN_INPSTAT1C);		else			inb(GN_INPSTAT1M);		/* ATC Horizontal Pixel Panning */		outb(ATC_INDEX, ATC_HORPIXPAN | ATC_ACCESS);		outb(ATC_DATAW, *sp++);		/* VCLK2 Numerator Register */		outb(TS_INDEX, 0xd);		outb(TS_DATA, *sp++);		/* VCLK2 Denominator and Post-Scalar Value Register */		outb(TS_INDEX, 0x1d);		outb(TS_DATA, *sp++);		outb(GN_MISCOUTW, *sp++);	/* Misc output register */	}	/* disable access to cirrus extension registers */	outb(TS_INDEX, 6);	outb(TS_DATA, 0);	/* disable access to first 7 CRTC registers */	outb(addr_6845, CRTC_VSYNCE);	outb(addr_6845+1, byte);	vga_screen_on();	return(1);}#if PCVT_USL_VT_COMPAT/*---------------------------------------------------------------------------* *	switch screen from text mode to X-mode and vice versa *---------------------------------------------------------------------------*/voidswitch_screen(int n, int oldgrafx, int newgrafx){#if PCVT_SCREENSAVER	static unsigned saved_scrnsv_tmo = 0;#endif	/* PCVT_SCREENSAVER */#if !PCVT_KBD_FIFO	int x;#endif	/* !PCVT_KBD_FIFO */	int cols = vsp->maxcol;		/* get current col val */	if(n < 0 || n >= totalscreens)		return;#if !PCVT_KBD_FIFO	x = spltty();			/* protect us */#endif	/* !PCVT_KBD_FIFO */	if(!oldgrafx && newgrafx)	{		/* switch from text to graphics */#if PCVT_SCREENSAVER		if((saved_scrnsv_tmo = scrnsv_timeout))			pcvt_set_scrnsv_tmo(0);	/* screensaver off */#endif /* PCVT_SCREENSAVER */		async_update(UPDATE_STOP);	/* status display off */	}	if(!oldgrafx)	{		/* switch from text mode */		/* video board memory -> kernel memory */		bcopy(vsp->Crtat, vsp->Memory,		      vsp->screen_rows * vsp->maxcol * CHR);		vsp->Crtat = vsp->Memory;	/* operate in memory now */	}	/* update global screen pointers/variables */	current_video_screen = n;	/* current screen no */#if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)	pcconsp = &pccons[n];		/* current tty */#elif PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200	pcconsp = pccons[n];		/* current tty */#else	pcconsp = pc_tty[n];		/* current tty */#endif	vsp = &vs[n];			/* current video state ptr */	if(oldgrafx && !newgrafx)	{		/* switch from graphics to text mode */		unsigned i;		/* restore fonts */		for(i = 0; i < totalfonts; i++)			if(saved_charsets[i])				vga_move_charset(i, 0, 0);#if PCVT_SCREENSAVER		/* activate screen saver */		if(saved_scrnsv_tmo)			pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);#endif /* PCVT_SCREENSAVER */		/* re-initialize lost MDA information */		if(adaptor_type == MDA_ADAPTOR)		{		    /*		     * Due to the fact that HGC registers are write-only,		     * the Xserver can only make guesses about the state		     * the HGC adaptor has been before turning on X mode.		     * Thus, the display must be re-enabled now, and the		     * cursor shape and location restored.		     */		    outb(GN_DMCNTLM, 0x28); /* enable display, text mode */		    outb(addr_6845, CRTC_CURSORH); /* select high register */		    outb(addr_6845+1,			 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);		    outb(addr_6845, CRTC_CURSORL); /* select low register */		    outb(addr_6845+1,			 ((vsp->Crtat + vsp->cur_offset) - Crtat));		    outb(addr_6845, CRTC_CURSTART); /* select high register */		    outb(addr_6845+1, vsp->cursor_start);		    outb(addr_6845, CRTC_CUREND); /* select low register */		    outb(addr_6845+1, vsp->cursor_end);		}		/* make status display happy */		async_update(UPDATE_START);	}	if(!newgrafx)	{		/* to text mode */		/* kernel memory -> video board memory */		bcopy(vsp->Crtat, Crtat,		      vsp->screen_rows * vsp->maxcol * CHR);		vsp->Crtat = Crtat;		/* operate on screen now */		outb(addr_6845, CRTC_STARTADRH);		outb(addr_6845+1, 0);		outb(addr_6845, CRTC_STARTADRL);		outb(addr_6845+1, 0);	}#if !PCVT_KBD_FIFO	splx(x);#endif	/* !PCVT_KBD_FIFO */	select_vga_charset(vsp->vga_charset);	if(vsp->maxcol != cols)		vga_col(vsp, vsp->maxcol);	/* select 80/132 columns */ 	outb(addr_6845, CRTC_CURSORH);	/* select high register */	outb(addr_6845+1, vsp->cur_offset >> 8);	outb(addr_6845, CRTC_CURSORL);	/* select low register */	outb(addr_6845+1, vsp->cur_offset);	if(vsp->cursor_on)	{		outb(addr_6845, CRTC_CURSTART);	/* select high register */		outb(addr_6845+1, vsp->cursor_start);		outb(addr_6845, CRTC_CUREND);	/* select low register */		outb(addr_6845+1, vsp->cursor_end);	}	else	{		sw_cursor(0);	}	if(adaptor_type == VGA_ADAPTOR)	{		unsigned i;		/* switch VGA DAC palette entries */		for(i = 0; i < NVGAPEL; i++)			vgapaletteio(i, &vsp->palette[i], 1);	}	if(!newgrafx)	{		update_led();	/* update led's */		update_hp(vsp);	/* update fkey labels, if present */		/* if we switch to a vt with force 24 lines mode and	*/		/* pure VT emulation and 25 rows charset, then we have	*/		/* to clear the last line on display ...		*/		if(vsp->force24 && (vsp->vt_pure_mode == M_PUREVT) &&			(vgacs[vsp->vga_charset].screen_size == SIZ_25ROWS))		{			fillw(' ', vsp->Crtat + vsp->screen_rows * vsp->maxcol,				vsp->maxcol);		}	}}/*---------------------------------------------------------------------------* *	Change specified vt to VT_AUTO mode *	xxx Maybe this should also reset VT_GRAFX mode; since switching and *	graphics modes are not going to work without VT_PROCESS mode. *---------------------------------------------------------------------------*/static voidset_auto_mode (struct video_state *vsx){	unsigned ostatus = vsx->vt_status;	vsx->smode.mode = VT_AUTO;	vsx->proc = NULL;	vsx->pid = 0;	vsx->vt_status &= ~(VT_WAIT_REL|VT_WAIT_ACK);	if (ostatus & VT_WAIT_ACK) {#if 0		assert (!(ostatus&VT_WAIT_REL));		assert (vsp == vsx &&			vt_switch_pending == current_video_screen + 1);		vt_switch_pending = 0;#else		if (vsp == vsx &&		    vt_switch_pending == current_video_screen + 1)			vt_switch_pending = 0;#endif	}	if (ostatus&VT_WAIT_REL) {		int new_screen = vt_switch_pending - 1;#if 0		assert(vsp == vsx && vt_switch_pending);		vt_switch_pending = 0;		vgapage (new_screen);#else		if (vsp == vsx && vt_switch_pending) {			vt_switch_pending = 0;			vgapage (new_screen);		}#endif	}}/*---------------------------------------------------------------------------* *	Exported function; to be called when a vt is closed down. * *	Ideally, we would like to be able to recover from an X server crash; *	but in reality, if the server crashes hard while in control of the *	vga board, then you're not likely to be able to use pcvt ttys *	without rebooting. *---------------------------------------------------------------------------*/voidreset_usl_modes (struct video_state *vsx){	/* Clear graphics mode */	if (vsx->vt_status & VT_GRAFX) {	    vsx->vt_status &= ~VT_GRAFX;	    if (vsp == vsx)		switch_screen(current_video_screen, 1, 0);	}	/* Take kbd out of raw mode */	if (pcvt_kbd_raw && vsp == vsx) {#if PCVT_SCANSET > 1		kbd_emulate_pc(0);#endif /* PCVT_SCANSET > 1 */		pcvt_kbd_raw = 0;	}	/* Clear process controlled mode */	set_auto_mode (vsx);}/*---------------------------------------------------------------------------* *	switch to virtual screen n (0 ... PCVT_NSCREENS-1), VT_USL version *	(the name vgapage() stands for historical reasons) *---------------------------------------------------------------------------*/intvgapage(int new_screen){	int x;	if(new_screen < 0 || new_screen >= totalscreens)		return EINVAL;	/* fallback to VT_AUTO if controlling processes died */	if(vsp->proc && vsp->proc != pfind(vsp->pid))		set_auto_mode(vsp);	if(vs[new_screen].proc	   && vs[new_screen].proc != pfind(vs[new_screen].pid))		set_auto_mode(&vs[new_screen]);	if (!vt_switch_pending && new_screen == current_video_screen)		return 0;	if(vt_switch_pending && vt_switch_pending != new_screen + 1) {		/* Try resignaling uncooperative X-window servers */		if (vsp->smode.mode == VT_PROCESS) {			if (vsp->vt_status & VT_WAIT_REL) {				if(vsp->smode.relsig)					psignal(vsp->proc, vsp->smode.relsig);			} else if (vsp->vt_status & VT_WAIT_ACK) {				if(vsp->smode.acqsig)					psignal(vsp->proc, vsp->smode.acqsig);			}		}		return EAGAIN;	}	vt_switch_pending = new_screen + 1;	if(vsp->smode.mode == VT_PROCESS)	{		/* we cannot switch immediately here */		vsp->vt_status |= VT_WAIT_REL;		if(vsp->smode.relsig)			psignal(vsp->proc, vsp->smode.relsig);	}	else	{		struct video_state *old_vsp = vsp;		switch_screen(new_screen,			      vsp->vt_status & VT_GRAFX,			      vs[new_screen].vt_status & VT_GRAFX);		x = spltty();		if(old_vsp->vt_status & VT_WAIT_ACT)		{			old_vsp->vt_status &= ~VT_WAIT_ACT;			wakeup((caddr_t)&old_vsp->smode);		}		if(vsp->vt_status & VT_WAIT_ACT)		{			vsp->vt_status &= ~VT_WAIT_ACT;			wakeup((caddr_t)&vsp->smode);		}		splx(x);		if(vsp->smode.mode == VT_PROCESS)		{			/* if _new_ vt is under process control... */			vsp->vt_status |= VT_WAIT_ACK;			if(vsp->smode.acqsig)				psignal(vsp->proc, vsp->smode.acqsig);		}		else		{			/* we are committed */			vt_switch_pending = 0;#if PCVT_FREEBSD > 206			/*			 * XXX: If pcvt is acting as the systems console,			 * avoid panics going to the debugger while we are in			 * process mode.			 */			if(pcvt_is_console)				cons_unavail = 0;#endif		}	}	return 0;}/*---------------------------------------------------------------------------* *	ioctl handling for VT_USL mode *---------------------------------------------------------------------------*/intusl_vt_ioctl(Dev_t dev, int cmd, caddr_t data, int flag, struct proc *p){	int i, j, error, opri;	struct vt_mode newmode;	switch(cmd)	{	case VT_SETMODE:		newmode = *(struct vt_mode *)data;		opri = spltty();		if (newmode.mode != VT_PROCESS) {			struct video_state *vsx = &vs[minor(dev)];			if (vsx->smode.mode == VT_PROCESS) {				if (vsx->proc != p) {					splx(opri);					return EPERM;				}				set_auto_mode(vsx);			}			splx(opri);			return 0;		}		/*		 * NB: XFree86-3.1.1 does the following:		 *		VT_ACTIVATE (vtnum)		 *		VT_WAITACTIVE (vtnum)		 *		VT_SETMODE (VT_PROCESS)		 * So it is possible that the screen was switched		 * between the WAITACTIVE and the SETMODE (here).  This		 * can actually happen quite frequently, and it was		 * leading to dire consequences. Now it is detected by		 * requiring that minor(dev) match current_video_screen.		 * An alternative would be to operate on vs[minor(dev)]		 * instead of *vsp, but that would leave the server		 * confused, because it would believe that its vt was		 * currently activated.		 */		if (minor(dev) != current_video_screen) {			splx(opri);			return EPERM;		}		/* Check for server died */		if(vsp->proc && vsp->proc != pfind(vsp->pid))			set_auto_mode(vsp);		/* Check for server already running */		if (vsp->smode.mode == VT_PROCESS && vsp->proc != p)		{			splx(opri);			return EBUSY; /* already in use on this VT */		}		if (!ISSIGVALID(newmode.relsig) || !ISSIGVALID(newmode.acqsig)		    || !ISSIGVALID(newmode.frsig))		{			splx(opri);			return EINVAL;		}		vsp->smode = newmode;		vsp->proc = p;		vsp->pid = p->p_pid;#if PCVT_FREEBSD > 206		/*		 * XXX: If pcvt is acting as the systems console,		 * avoid panics going to the debugger while we are in		 * process mode.		 */		if(pcvt_is_console)			cons_unavail = (newmode.mode == VT_PROCESS);#endif		splx(opri);		return 0;	case VT_GETMODE:		*(struct vt_mode *)data = vsp->smode;		return 0;	case VT_RELDISP:		if (minor(dev) != current_video_screen)			return EPERM;		if (vsp->smode.mode != VT_PROCESS)			return EINVAL;		if (vsp->proc != p)			return EPERM;		switch(*(int *)data) {		case VT_FALSE:			/* process refuses to release screen; abort */			if(vt_switch_pending			   && (vsp->vt_status & VT_WAIT_REL)) {				vsp->vt_status &= ~VT_WAIT_REL;				vt_switch_pending = 0;				return 0;			}			break;		case VT_TRUE:			/* process releases its VT */			if(vt_switch_pending			   && (vsp->vt_status & VT_WAIT_REL)) {				int new_screen = vt_switch_pending - 1;				struct video_state *old_vsp = vsp;				vsp->vt_status &= ~VT_WAIT_REL;				switch_screen(new_screen,					      vsp->vt_status & VT_GRAFX,					      vs[new_screen].vt_status					      & VT_GRAFX);				opri = spltty();				if(old_vsp->vt_status & VT_WAIT_ACT)				{					old_vsp->vt_status &= ~VT_WAIT_ACT;					wakeup((caddr_t)&old_vsp->smode);				}				if(vsp->vt_status & VT_WAIT_ACT)				{					vsp->vt_status &= ~VT_WAIT_ACT;					wakeup((caddr_t)&vsp->smode);				}				splx(opri);				if(vsp->smode.mode == VT_PROCESS) {					/*					 * if the new vt is also in process					 * mode, we have to wait until its					 * controlling process acknowledged					 * the swit

⌨️ 快捷键说明

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