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

📄 console.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
			return;		case 'D':			if (!par[0]) par[0]++;			gotoxy(currcons,x-par[0],y);			return;		case 'E':			if (!par[0]) par[0]++;			gotoxy(currcons,0,y+par[0]);			return;		case 'F':			if (!par[0]) par[0]++;			gotoxy(currcons,0,y-par[0]);			return;		case 'd':			if (par[0]) par[0]--;			gotoxay(currcons,x,par[0]);			return;		case 'H': case 'f':			if (par[0]) par[0]--;			if (par[1]) par[1]--;			gotoxay(currcons,par[1],par[0]);			return;		case 'J':			csi_J(currcons,par[0]);			return;		case 'K':			csi_K(currcons,par[0]);			return;		case 'L':			csi_L(currcons,par[0]);			return;		case 'M':			csi_M(currcons,par[0]);			return;		case 'P':			csi_P(currcons,par[0]);			return;		case 'c':			if (!par[0])				respond_ID(tty);			return;		case 'g':			if (!par[0])				tab_stop[x >> 5] &= ~(1 << (x & 31));			else if (par[0] == 3) {				tab_stop[0] =					tab_stop[1] =					tab_stop[2] =					tab_stop[3] =					tab_stop[4] = 0;			}			return;		case 'm':			csi_m(currcons);			return;		case 'q': /* DECLL - but only 3 leds */			/* map 0,1,2,3 to 0,1,2,4 */			if (par[0] < 4)				setledstate(kbd_table + currcons,					    (par[0] < 3) ? par[0] : 4);			return;		case 'r':			if (!par[0])				par[0]++;			if (!par[1])				par[1] = video_num_lines;			/* Minimum allowed region is 2 lines */			if (par[0] < par[1] &&			    par[1] <= video_num_lines) {				top=par[0]-1;				bottom=par[1];				gotoxay(currcons,0,0);			}			return;		case 's':			save_cur(currcons);			return;		case 'u':			restore_cur(currcons);			return;		case 'X':			csi_X(currcons, par[0]);			return;		case '@':			csi_at(currcons,par[0]);			return;		case ']': /* setterm functions */			setterm_command(currcons);			return;		}		return;	case ESpercent:		vc_state = ESnormal;		switch (c) {		case '@':  /* defined in ISO 2022 */			utf = 0;			return;		case 'G':  /* prelim official escape code */		case '8':  /* retained for compatibility */			utf = 1;			return;		}		return;	case ESfunckey:		vc_state = ESnormal;		return;	case EShash:		vc_state = ESnormal;		if (c == '8') {			/* DEC screen alignment test. kludge :-) */			video_erase_char =				(video_erase_char & 0xff00) | 'E';			csi_J(currcons, 2);			video_erase_char =				(video_erase_char & 0xff00) | ' ';			do_update_region(currcons, origin, screenbuf_size/2);		}		return;	case ESsetG0:		if (c == '0')			G0_charset = GRAF_MAP;		else if (c == 'B')			G0_charset = LAT1_MAP;		else if (c == 'U')			G0_charset = IBMPC_MAP;		else if (c == 'K')			G0_charset = USER_MAP;		if (charset == 0)			translate = set_translate(G0_charset,currcons);		vc_state = ESnormal;		return;	case ESsetG1:		if (c == '0')			G1_charset = GRAF_MAP;		else if (c == 'B')			G1_charset = LAT1_MAP;		else if (c == 'U')			G1_charset = IBMPC_MAP;		else if (c == 'K')			G1_charset = USER_MAP;		if (charset == 1)			translate = set_translate(G1_charset,currcons);		vc_state = ESnormal;		return;	default:		vc_state = ESnormal;	}}/* This is a temporary buffer used to prepare a tty console write * so that we can easily avoid touching user space while holding the * console spinlock.  It is allocated in con_init and is shared by * this code and the vc_screen read/write tty calls. * * We have to allocate this statically in the kernel data section * since console_init (and thus con_init) are called before any * kernel memory allocation is available. */char con_buf[PAGE_SIZE];#define CON_BUF_SIZE	PAGE_SIZEDECLARE_MUTEX(con_buf_sem);static int do_con_write(struct tty_struct * tty, int from_user,			const unsigned char *buf, int count){#ifdef VT_BUF_VRAM_ONLY#define FLUSH do { } while(0);#else#define FLUSH if (draw_x >= 0) { \	sw->con_putcs(vc_cons[currcons].d, (u16 *)draw_from, (u16 *)draw_to-(u16 *)draw_from, y, draw_x); \	draw_x = -1; \	}#endif	int c, tc, ok, n = 0, draw_x = -1;	unsigned int currcons;	unsigned long draw_from = 0, draw_to = 0;	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;	u16 himask, charmask;	const unsigned char *orig_buf = NULL;	int orig_count;	currcons = vt->vc_num;	if (!vc_cons_allocated(currcons)) {	    /* could this happen? */	    static int error = 0;	    if (!error) {		error = 1;		printk("con_write: tty %d not allocated\n", currcons+1);	    }	    return 0;	}	orig_buf = buf;	orig_count = count;	if (from_user) {		down(&con_buf_sem);again:		if (count > CON_BUF_SIZE)			count = CON_BUF_SIZE;		if (copy_from_user(con_buf, buf, count)) {			n = 0; /* ?? are error codes legal here ?? */			goto out;		}		buf = con_buf;	}	/* At this point 'buf' is guarenteed to be a kernel buffer	 * and therefore no access to userspace (and therefore sleeping)	 * will be needed.  The con_buf_sem serializes all tty based	 * console rendering and vcs write/read operations.  We hold	 * the console spinlock during the entire write.	 */	spin_lock_irq(&console_lock);	himask = hi_font_mask;	charmask = himask ? 0x1ff : 0xff;	/* undraw cursor first */	if (IS_FG)		hide_cursor(currcons);	while (!tty->stopped && count) {		c = *buf;		buf++;		n++;		count--;		if (utf) {		    /* Combine UTF-8 into Unicode */		    /* Incomplete characters silently ignored */		    if(c > 0x7f) {			if (utf_count > 0 && (c & 0xc0) == 0x80) {				utf_char = (utf_char << 6) | (c & 0x3f);				utf_count--;				if (utf_count == 0)				    tc = c = utf_char;				else continue;			} else {				if ((c & 0xe0) == 0xc0) {				    utf_count = 1;				    utf_char = (c & 0x1f);				} else if ((c & 0xf0) == 0xe0) {				    utf_count = 2;				    utf_char = (c & 0x0f);				} else if ((c & 0xf8) == 0xf0) {				    utf_count = 3;				    utf_char = (c & 0x07);				} else if ((c & 0xfc) == 0xf8) {				    utf_count = 4;				    utf_char = (c & 0x03);				} else if ((c & 0xfe) == 0xfc) {				    utf_count = 5;				    utf_char = (c & 0x01);				} else				    utf_count = 0;				continue;			      }		    } else {		      tc = c;		      utf_count = 0;		    }		} else {	/* no utf */		  tc = translate[toggle_meta ? (c|0x80) : c];		}                /* If the original code was a control character we                 * only allow a glyph to be displayed if the code is                 * not normally used (such as for cursor movement) or                 * if the disp_ctrl mode has been explicitly enabled.                 * Certain characters (as given by the CTRL_ALWAYS                 * bitmap) are always displayed as control characters,                 * as the console would be pretty useless without                 * them; to display an arbitrary font position use the                 * direct-to-font zone in UTF-8 mode.                 */                ok = tc && (c >= 32 ||                            (!utf && !(((disp_ctrl ? CTRL_ALWAYS                                         : CTRL_ACTION) >> c) & 1)))                        && (c != 127 || disp_ctrl)			&& (c != 128+27);		if (vc_state == ESnormal && ok) {			/* Now try to find out how to display it */			tc = conv_uni_to_pc(vc_cons[currcons].d, tc);			if ( tc == -4 ) {                                /* If we got -4 (not found) then see if we have                                   defined a replacement character (U+FFFD) */                                tc = conv_uni_to_pc(vc_cons[currcons].d, 0xfffd);				/* One reason for the -4 can be that we just				   did a clear_unimap();				   try at least to show something. */				if (tc == -4)				     tc = c;                        } else if ( tc == -3 ) {                                /* Bad hash table -- hope for the best */                                tc = c;                        }			if (tc & ~charmask)                                continue; /* Conversion failed */			if (need_wrap || decim)				FLUSH			if (need_wrap) {				cr(currcons);				lf(currcons);			}			if (decim)				insert_char(currcons, 1);			scr_writew(himask ?				     ((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :				     (attr << 8) + tc,				   (u16 *) pos);			if (DO_UPDATE && draw_x < 0) {				draw_x = x;				draw_from = pos;			}			if (x == video_num_columns - 1) {				need_wrap = decawm;				draw_to = pos+2;			} else {				x++;				draw_to = (pos+=2);			}			continue;		}		FLUSH		do_con_trol(tty, currcons, c);	}	FLUSH	spin_unlock_irq(&console_lock);out:	if (from_user) {		/* If the user requested something larger than		 * the CON_BUF_SIZE, and the tty is not stopped,		 * keep going.		 */		if ((orig_count > CON_BUF_SIZE) && !tty->stopped) {			orig_count -= CON_BUF_SIZE;			orig_buf += CON_BUF_SIZE;			count = orig_count;			buf = orig_buf;			goto again;		}		up(&con_buf_sem);	}	return n;#undef FLUSH}/* * This is the console switching tasklet. * * Doing console switching in a tasklet allows * us to do the switches asynchronously (needed when we want * to switch due to a keyboard interrupt).  Synchronization * with other console code and prevention of re-entrancy is * ensured with console_lock. */static void console_softint(unsigned long ignored){	/* Runs the task queue outside of the console lock.  These	 * callbacks can come back into the console code and thus	 * will perform their own locking.	 */	run_task_queue(&con_task_queue);	spin_lock_irq(&console_lock);	if (want_console >= 0) {		if (want_console != fg_console && vc_cons_allocated(want_console)) {			hide_cursor(fg_console);			change_console(want_console);			/* we only changed when the console had already			   been allocated - a new console is not created			   in an interrupt routine */		}		want_console = -1;	}	if (do_poke_blanked_console) { /* do not unblank for a LED change */		do_poke_blanked_console = 0;		poke_blanked_console();	}	if (scrollback_delta) {		int currcons = fg_console;		clear_selection();		if (vcmode == KD_TEXT)			sw->con_scrolldelta(vc_cons[currcons].d, scrollback_delta);		scrollback_delta = 0;	}	spin_unlock_irq(&console_lock);}#ifdef CONFIG_VT_CONSOLE/* *	Console on virtual terminal * * The console_lock must be held when we get here. */void vt_console_print(struct console *co, const char * b, unsigned count){	int currcons = fg_console;	unsigned char c;	static unsigned long printing;	const ushort *start;	ushort cnt = 0;	ushort myx;	/* console busy or not yet initialized */	if (!printable || test_and_set_bit(0, &printing))		return;	pm_access(pm_con);	if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))		currcons = kmsg_redirect - 1;	/* read `x' only after setting currecons properly (otherwise	   the `x' macro will read the x of the foreground console). */	myx = x;	if (!vc_cons_allocated(currcons)) {		/* impossible */		/* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */		goto quit;	}	if (vcmode != KD_TEXT)		goto quit;	/* undraw cursor first */	if (IS_FG)		hide_cursor(currcons);	start = (ushort *)pos;	/* Contrived structure to try to emulate original need_wrap behaviour	 * Problems caused when we have need_wrap set on '\n' character */	while (count--) {		c = *b++;		if (c == 10 || c == 13 || c == 8 || need_wrap) {			if (cnt > 0) {				if (IS_VISIBLE)					sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x);				x += cnt;				if (need_wrap)					x--;				cnt = 0;			}			if (c == 8) {		/* backspace */				bs(currcons);				start = (ushort *)pos;				myx = x;				continue;			}			if (c != 13)				lf(currcons);			cr(currcons);			start = (ushort *)pos;			myx = x;			if (c == 10 || c == 13)				continue;		}		scr_writew((attr << 8) + c, (unsigned short *) pos);		cnt++;		if (myx == video_num_columns - 1) {			need_wrap = 1;			continue;		}		pos+=2;		myx++;	}	if (cnt > 0) {		if (IS_VISIBLE)			sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x);		x += cnt;		if (x == video_num_columns) {			x--;			need_wrap = 1;		}	}	set_cursor(currcons);quit:	clear_bit(0, &printing);}static kdev_t vt_console_device(struct console *c){	return MKDEV(TTY_MAJOR, c->index ? c->index : fg_console + 1);}struct console vt_console_driver = {	name:		"tty",	write:		vt_console_print,	device:		vt_console_device,	wait_key:	keyboard_wait_for_keypress,	unblank:	unblank_screen,	flags:		CON_PRINTBUFFER,	index:		-1,};#endif/* *	Handling of Linux-specific VC ioctls */int tioclinux(struct tty_struct *tty, unsigned long arg){	char type, data;	if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)		return -EINVAL;	if (current->tty != tty && !suser())		return -EPERM;	if (get_user(type, (char *)arg))		return -EFAULT;	switch (type)	{		case 2:			return set_selection(arg, tty, 1);		case 3:			return paste_selection(tty);		case 4:			unblank_screen();			return 0;		case 5:			return sel_loadlut(arg);		case 6:				/*	 * Make it possible to react to Shift+Mousebutton.	 * Note that 'shift_state' is an undocumented	 * kernel-internal variable; programs not closely	 * related to the kernel should not use this.	 */	 		data = shift_state;

⌨️ 快捷键说明

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