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

📄 console.c

📁 powerpc内核mpc8241linux系统下char驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
			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;	}}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;	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;	}	if (from_user) {		/* just to make sure that noone lurks at places he shouldn't see. */		if (verify_area(VERIFY_READ, buf, count))			return 0; /* ?? are error codes legal here ?? */	}	himask = hi_font_mask;	charmask = himask ? 0x1ff : 0xff;	/* undraw cursor first */	if (IS_FG)		hide_cursor(currcons);	disable_bh(CONSOLE_BH);	while (!tty->stopped && count) {		enable_bh(CONSOLE_BH);		if (from_user)			__get_user(c, buf);		else			c = *buf;		buf++; n++; count--;		disable_bh(CONSOLE_BH);		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	enable_bh(CONSOLE_BH);	return n;#undef FLUSH}/* * This is the console switching bottom half handler. * * Doing console switching in a bottom half handler allows * us to do the switches asynchronously (needed when we want * to switch due to a keyboard interrupt), while still giving * us the option to easily disable it to avoid races when we * need to write to the console. */static void console_bh(void){	run_task_queue(&con_task_queue);	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;	}}#ifdef CONFIG_VT_CONSOLE/* *	Console on virtual terminal * * NOTE NOTE NOTE! This code can do no global locking. In particular, * we can't disable interrupts or bottom half handlers globally, because * we can be called from contexts that hold critical spinlocks, and * trying do get a global lock at this point will lead to deadlocks. */void vt_console_print(struct console *co, const char * b, unsigned count){	int currcons = fg_console;	unsigned char c;	static unsigned long printing = 0;	const ushort *start;	ushort cnt = 0;	ushort myx = x;	/* console busy or not yet initialized */	if (!printable || test_and_set_bit(0, &printing))		return;	if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))		currcons = kmsg_redirect - 1;	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);	poke_blanked_console();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 = {	"tty",	vt_console_print,	NULL,	vt_console_device,	keyboard_wait_for_keypress,	unblank_screen,	NULL,	CON_PRINTBUFFER,	-1,	0,	NULL};#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;			return __put_user(data, (char *) arg);		case 7:			data = mouse_reporting();			return __put_user(data, (char *) arg);		case 10:			set_vesa_blanking(arg);			return 0;		case 11:	/* set kmsg redirect */			if (!suser())				return -EPERM;			if (get_user(data, (char *)arg+1))					return -EFAULT;			kmsg_redirect = data;			return 0;		case 12:	/* get fg_console */			return fg_console;	}	return -EINVAL;}/* *	/dev/ttyN handling */static int con_write(struct tty_struct * tty, int from_user,		     const unsigned char *buf, int count){	int	retval;	retval = do_con_write(tty, from_user, buf, count);	con_flush_chars(tty);	return retval;}static void con_put_char(struct tty_struct *tty, unsigned char ch){	do_con_write(tty, 0, &ch, 1);}static int con_write_room(struct tty_struct *tty){	if (tty->stopped)		return 0;	return 4096;		/* No limit, really; we're not buffering */}static int con_chars_in_buffer(struct tty_struct *tty){	return 0;		/* we're not buffering */}/* * con_throttle and con_unthrottle are only used for * paste_selection(), which has to stuff in a large number of * characters... */static void con_throttle(struct tty_struct *tty){}static void con_unthrottle(struct tty_struct *tty){	struct vt_struct *vt = (struct vt_struct *) tty->driver_data;	wake_up_interruptible(&vt->paste_wait);}/* * Turn the Scroll-Lock LED on when the tty is stopped */static void con_stop(struct tty_struct *tty){	int console_num;	if (!tty)		return;	console_num = MINOR(tty->device) - (tty->driver.minor_start);	if (!vc_cons_allocated(console_num))		return;	set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);

⌨️ 快捷键说明

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