vt.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,768 行 · 第 1/5 页

C
2,768
字号
	if (currcons == sel_cons)		clear_selection();	sw->con_cursor(vc_cons[currcons].d,CM_ERASE);	hide_softcursor(currcons);}static void set_cursor(int currcons){    if (!IS_FG || console_blanked || vcmode == KD_GRAPHICS)	return;    if (deccm) {	if (currcons == sel_cons)		clear_selection();	add_softcursor(currcons);	if ((cursor_type & 0x0f) != 1)	    sw->con_cursor(vc_cons[currcons].d,CM_DRAW);    } else	hide_cursor(currcons);}static void set_origin(int currcons){	WARN_CONSOLE_UNLOCKED();	if (!IS_VISIBLE ||	    !sw->con_set_origin ||	    !sw->con_set_origin(vc_cons[currcons].d))		origin = (unsigned long) screenbuf;	visible_origin = origin;	scr_end = origin + screenbuf_size;	pos = origin + video_size_row*y + 2*x;}static inline void save_screen(int currcons){	WARN_CONSOLE_UNLOCKED();	if (sw->con_save_screen)		sw->con_save_screen(vc_cons[currcons].d);}/* *	Redrawing of screen */static void clear_buffer_attributes(int currcons){	unsigned short *p = (unsigned short *) origin;	int count = screenbuf_size/2;	int mask = hi_font_mask | 0xff;	for (; count > 0; count--, p++) {		scr_writew((scr_readw(p)&mask) | (video_erase_char&~mask), p);	}}void redraw_screen(int new_console, int is_switch){	int redraw = 1;	int currcons, old_console;	WARN_CONSOLE_UNLOCKED();	if (!vc_cons_allocated(new_console)) {		/* strange ... */		/* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */		return;	}	if (is_switch) {		currcons = fg_console;		hide_cursor(currcons);		if (fg_console != new_console) {			struct vc_data **display = vc_cons[new_console].d->vc_display_fg;			old_console = (*display) ? (*display)->vc_num : fg_console;			*display = vc_cons[new_console].d;			fg_console = new_console;			currcons = old_console;			if (!IS_VISIBLE) {				save_screen(currcons);				set_origin(currcons);			}			currcons = new_console;			if (old_console == new_console)				redraw = 0;		}	} else {		currcons = new_console;		hide_cursor(currcons);	}	if (redraw) {		int update;		int old_was_color = vc_cons[currcons].d->vc_can_do_color;		set_origin(currcons);		update = sw->con_switch(vc_cons[currcons].d);		set_palette(currcons);		/*		 * If console changed from mono<->color, the best we can do		 * is to clear the buffer attributes. As it currently stands,		 * rebuilding new attributes from the old buffer is not doable		 * without overly complex code.		 */		if (old_was_color != vc_cons[currcons].d->vc_can_do_color) {			update_attr(currcons);			clear_buffer_attributes(currcons);		}		if (update && vcmode != KD_GRAPHICS)			do_update_region(currcons, origin, screenbuf_size/2);	}	set_cursor(currcons);	if (is_switch) {		set_leds();		compute_shiftstate();	}}/* *	Allocation, freeing and resizing of VTs. */int vc_cons_allocated(unsigned int i){	return (i < MAX_NR_CONSOLES && vc_cons[i].d);}static void visual_init(int currcons, int init){    /* ++Geert: sw->con_init determines console size */    if (sw)	module_put(sw->owner);    sw = conswitchp;#ifndef VT_SINGLE_DRIVER    if (con_driver_map[currcons])	sw = con_driver_map[currcons];#endif    __module_get(sw->owner);    cons_num = currcons;    display_fg = &master_display_fg;    vc_cons[currcons].d->vc_uni_pagedir_loc = &vc_cons[currcons].d->vc_uni_pagedir;    vc_cons[currcons].d->vc_uni_pagedir = 0;    hi_font_mask = 0;    complement_mask = 0;    can_do_color = 0;    sw->con_init(vc_cons[currcons].d, init);    if (!complement_mask)        complement_mask = can_do_color ? 0x7700 : 0x0800;    s_complement_mask = complement_mask;    video_size_row = video_num_columns<<1;    screenbuf_size = video_num_lines*video_size_row;}int vc_allocate(unsigned int currcons)	/* return 0 on success */{	WARN_CONSOLE_UNLOCKED();	if (currcons >= MAX_NR_CONSOLES)		return -ENXIO;	if (!vc_cons[currcons].d) {	    long p, q;	    /* prevent users from taking too much memory */	    if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))	      return -EPERM;	    /* due to the granularity of kmalloc, we waste some memory here */	    /* the alloc is done in two steps, to optimize the common situation	       of a 25x80 console (structsize=216, screenbuf_size=4000) */	    /* although the numbers above are not valid since long ago, the	       point is still up-to-date and the comment still has its value	       even if only as a historical artifact.  --mj, July 1998 */	    p = (long) kmalloc(structsize, GFP_KERNEL);	    if (!p)		return -ENOMEM;	    memset((void *)p, 0, structsize);	    vc_cons[currcons].d = (struct vc_data *)p;	    vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));	    visual_init(currcons, 1);	    if (!*vc_cons[currcons].d->vc_uni_pagedir_loc)		con_set_default_unimap(currcons);	    q = (long)kmalloc(screenbuf_size, GFP_KERNEL);	    if (!q) {		kfree((char *) p);		vc_cons[currcons].d = NULL;		vt_cons[currcons] = NULL;		return -ENOMEM;	    }	    screenbuf = (unsigned short *) q;	    kmalloced = 1;	    vc_init(currcons, video_num_lines, video_num_columns, 1);	    if (!pm_con) {		    pm_con = pm_register(PM_SYS_DEV,					 PM_SYS_VGA,					 pm_con_request);	    }	}	return 0;}inline int resize_screen(int currcons, int width, int height){	/* Resizes the resolution of the display adapater */	int err = 0;	if (vcmode != KD_GRAPHICS && sw->con_resize)		err = sw->con_resize(vc_cons[currcons].d, width, height);	return err;}/* * Change # of rows and columns (0 means unchanged/the size of fg_console) * [this is to be used together with some user program * like resize that changes the hardware videomode] */int vc_resize(int currcons, unsigned int cols, unsigned int lines){	unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;	unsigned int old_cols, old_rows, old_row_size, old_screen_size;	unsigned int new_cols, new_rows, new_row_size, new_screen_size;	unsigned short *newscreen;	WARN_CONSOLE_UNLOCKED();	if (!vc_cons_allocated(currcons))		return -ENXIO;	new_cols = (cols ? cols : video_num_columns);	new_rows = (lines ? lines : video_num_lines);	new_row_size = new_cols << 1;	new_screen_size = new_row_size * new_rows;	if (new_cols == video_num_columns && new_rows == video_num_lines)		return 0;	newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);	if (!newscreen)		return -ENOMEM;	old_rows = video_num_lines;	old_cols = video_num_columns;	old_row_size = video_size_row;	old_screen_size = screenbuf_size;	err = resize_screen(currcons, new_cols, new_rows);	if (err) {		kfree(newscreen);		return err;	}	video_num_lines = new_rows;	video_num_columns = new_cols;	video_size_row = new_row_size;	screenbuf_size = new_screen_size;	rlth = min(old_row_size, new_row_size);	rrem = new_row_size - rlth;	old_origin = origin;	new_origin = (long) newscreen;	new_scr_end = new_origin + new_screen_size;	if (new_rows < old_rows)		old_origin += (old_rows - new_rows) * old_row_size;	update_attr(currcons);	while (old_origin < scr_end) {		scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth);		if (rrem)			scr_memsetw((void *)(new_origin + rlth), video_erase_char, rrem);		old_origin += old_row_size;		new_origin += new_row_size;	}	if (new_scr_end > new_origin)		scr_memsetw((void *) new_origin, video_erase_char, new_scr_end - new_origin);	if (kmalloced)		kfree(screenbuf);	screenbuf = newscreen;	kmalloced = 1;	screenbuf_size = new_screen_size;	set_origin(currcons);	/* do part of a reset_terminal() */	top = 0;	bottom = video_num_lines;	gotoxy(currcons, x, y);	save_cur(currcons);	if (vc_cons[currcons].d->vc_tty) {		struct winsize ws, *cws = &vc_cons[currcons].d->vc_tty->winsize;		memset(&ws, 0, sizeof(ws));		ws.ws_row = video_num_lines;		ws.ws_col = video_num_columns;		ws.ws_ypixel = video_scan_lines;		if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&		    vc_cons[currcons].d->vc_tty->pgrp > 0)			kill_pg(vc_cons[currcons].d->vc_tty->pgrp, SIGWINCH, 1);		*cws = ws;	}	if (IS_VISIBLE)		update_screen(currcons);	return err;}void vc_disallocate(unsigned int currcons){	WARN_CONSOLE_UNLOCKED();	if (vc_cons_allocated(currcons)) {	    sw->con_deinit(vc_cons[currcons].d);	    if (kmalloced)		kfree(screenbuf);	    if (currcons >= MIN_NR_CONSOLES)		kfree(vc_cons[currcons].d);	    vc_cons[currcons].d = NULL;	}}/* *	VT102 emulator */#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)#define decarm		VC_REPEAT#define decckm		VC_CKMODE#define kbdapplic	VC_APPLIC#define lnm		VC_CRLF/* * this is what the terminal answers to a ESC-Z or csi0c query. */#define VT100ID "\033[?1;2c"#define VT102ID "\033[?6c"unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,				       8,12,10,14, 9,13,11,15 };/* the default colour table, for VGA+ colour systems */int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,    0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,    0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,    0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};/* * gotoxy() must verify all boundaries, because the arguments * might also be negative. If the given position is out of * bounds, the cursor is placed at the nearest margin. */static void gotoxy(int currcons, int new_x, int new_y){	int min_y, max_y;	if (new_x < 0)		x = 0;	else		if (new_x >= video_num_columns)			x = video_num_columns - 1;		else			x = new_x; 	if (decom) {		min_y = top;		max_y = bottom;	} else {		min_y = 0;		max_y = video_num_lines;	}	if (new_y < min_y)		y = min_y;	else if (new_y >= max_y)		y = max_y - 1;	else		y = new_y;	pos = origin + y*video_size_row + (x<<1);	need_wrap = 0;}/* for absolute user moves, when decom is set */static void gotoxay(int currcons, int new_x, int new_y){	gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);}void scrollback(int lines){	int currcons = fg_console;	if (!lines)		lines = video_num_lines/2;	scrolldelta(-lines);}void scrollfront(int lines){	int currcons = fg_console;	if (!lines)		lines = video_num_lines/2;	scrolldelta(lines);}static void lf(int currcons){    	/* don't scroll if above bottom of scrolling region, or	 * if below scrolling region	 */    	if (y+1 == bottom)		scrup(currcons,top,bottom,1);	else if (y < video_num_lines-1) {	    	y++;		pos += video_size_row;	}	need_wrap = 0;}static void ri(int currcons){    	/* don't scroll if below top of scrolling region, or	 * if above scrolling region	 */	if (y == top)		scrdown(currcons,top,bottom,1);	else if (y > 0) {		y--;		pos -= video_size_row;	}	need_wrap = 0;}static inline void cr(int currcons){	pos -= x<<1;	need_wrap = x = 0;}static inline void bs(int currcons){	if (x) {		pos -= 2;		x--;		need_wrap = 0;	}}static inline void del(int currcons){	/* ignored */}static void csi_J(int currcons, int vpar){	unsigned int count;	unsigned short * start;	switch (vpar) {		case 0:	/* erase from cursor to end of display */			count = (scr_end-pos)>>1;			start = (unsigned short *) pos;			if (DO_UPDATE) {				/* do in two stages */				sw->con_clear(vc_cons[currcons].d, y, x, 1,					      video_num_columns-x);				sw->con_clear(vc_cons[currcons].d, y+1, 0,					      video_num_lines-y-1,					      video_num_columns);			}			break;		case 1:	/* erase from start to cursor */			count = ((pos-origin)>>1)+1;			start = (unsigned short *) origin;			if (DO_UPDATE) {				/* do in two stages */				sw->con_clear(vc_cons[currcons].d, 0, 0, y,					      video_num_columns);				sw->con_clear(vc_cons[currcons].d, y, 0, 1,					      x + 1);			}			break;		case 2: /* erase whole display */			count = video_num_columns * video_num_lines;			start = (unsigned short *) origin;			if (DO_UPDATE)				sw->con_clear(vc_cons[currcons].d, 0, 0,					      video_num_lines,					      video_num_columns);			break;		default:			return;	}	scr_memsetw(start, video_erase_char, 2*count);	need_wrap = 0;}static void csi_K(int currcons, int vpar){	unsigned int count;	unsigned short * start;	switch (vpar) {		case 0:	/* erase from cursor to end of line */			count = video_num_columns-x;			start = (unsigned short *) pos;			if (DO_UPDATE)				sw->con_clear(vc_cons[currcons].d, y, x, 1,					      video_num_columns-x);			break;		case 1:	/* erase from start of line to cursor */			start = (unsigned short *) (pos - (x<<1));			count = x+1;			if (DO_UPDATE)				sw->con_clear(vc_cons[currcons].d, y, 0, 1,					      x + 1);			break;		case 2: /* erase whole line */			start = (unsigned short *) (pos - (x<<1));			count = video_num_columns;			if (DO_UPDATE)				sw->con_clear(vc_cons[currcons].d, y, 0, 1,					      video_num_columns);			break;		default:			return;	}	scr_memsetw(start, video_erase_char, 2 * count);	need_wrap = 0;}static void csi_X(int currcons, int vpar) /* erase the following vpar positions */{					  /* not vt100? */	int count;	if (!vpar)		vpar++;	count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;	scr_memsetw((unsigned short *) pos, video_erase_char, 2 * count);	if (DO_UPDATE)		sw->con_clear(vc_cons[currcons].d, y, x, 1, count);	need_wrap = 0;}static void default_attr(int currcons){	intensity = 1;	underline = 0;	reverse = 0;	blink = 0;

⌨️ 快捷键说明

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