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

📄 fbcon.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  linux/drivers/video/fbcon.c -- Low level frame buffer based console driver * *	Copyright (C) 1995 Geert Uytterhoeven * * *  This file is based on the original Amiga console driver (amicon.c): * *	Copyright (C) 1993 Hamish Macdonald *			   Greg Harp *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk] * *	      with work by William Rucklidge (wjr@cs.cornell.edu) *			   Geert Uytterhoeven *			   Jes Sorensen (jds@kom.auc.dk) *			   Martin Apel * *  and on the original Atari console driver (atacon.c): * *	Copyright (C) 1993 Bjoern Brauel *			   Roman Hodek * *	      with work by Guenther Kelleter *			   Martin Schaller *			   Andreas Schwab * *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org) *  Smart redraw scrolling, arbitrary font width support, 512char font support *  and software scrollback added by  *                         Jakub Jelinek (jj@ultra.linux.cz) * *  Random hacking by Martin Mares <mj@ucw.cz> * *	2001 - Documented with DocBook *	- Brad Douglas <brad@neruo.com> * *  The low level operations for the various display memory organizations are *  now in separate source files. * *  Currently the following organizations are supported: * *    o afb			Amiga bitplanes *    o cfb{2,4,8,16,24,32}	Packed pixels *    o ilbm			Amiga interleaved bitplanes *    o iplan2p[248]		Atari interleaved bitplanes *    o mfb			Monochrome *    o vga			VGA characters/attributes * *  To do: * *    - Implement 16 plane mode (iplan2p16) * * *  This file is subject to the terms and conditions of the GNU General Public *  License.  See the file COPYING in the main directory of this archive for *  more details. */#undef FBCONDEBUG#include <linux/module.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/delay.h>	/* MSch: for IRQ probe */#include <linux/console.h>#include <linux/string.h>#include <linux/kd.h>#include <linux/slab.h>#include <linux/fb.h>#include <linux/vt_kern.h>#include <linux/selection.h>#include <linux/font.h>#include <linux/smp.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/crc32.h> /* For counting font checksums */#include <asm/irq.h>#include <asm/system.h>#include <asm/uaccess.h>#include "fbcon.h"#  define DPRINTK(fmt, args...)enum {	FBCON_LOGO_CANSHOW	= -1,	/* the logo can be shown */	FBCON_LOGO_DRAW		= -2,	/* draw the logo to a console */	FBCON_LOGO_DONTSHOW	= -3	/* do not show the logo */};static struct display fb_display[MAX_NR_CONSOLES];static signed char con2fb_map[MAX_NR_CONSOLES];static signed char con2fb_map_boot[MAX_NR_CONSOLES];static int logo_height;static int logo_lines;/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO   enums.  */static int logo_shown = FBCON_LOGO_CANSHOW;/* Software scrollback */static int fbcon_softback_size = 32768;static unsigned long softback_buf, softback_curr;static unsigned long softback_in;static unsigned long softback_top, softback_end;static int softback_lines;/* console mappings */static int first_fb_vc;static int last_fb_vc = MAX_NR_CONSOLES - 1;static int fbcon_is_default = 1; static int fbcon_has_exited;/* font data */static char fontname[40];/* current fb_info */static int info_idx = -1;/* console rotation */static int rotate;static int fbcon_has_sysfs;static const struct consw fb_con;#define CM_SOFTBACK	(8)#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)static int fbcon_set_origin(struct vc_data *);#define CURSOR_DRAW_DELAY		(1)/* # VBL ints between cursor state changes */#define ATARI_CURSOR_BLINK_RATE		(42)#define MAC_CURSOR_BLINK_RATE		(32)#define DEFAULT_CURSOR_BLINK_RATE	(20)static int vbl_cursor_cnt;#define divides(a, b)	((!(a) || (b)%(a)) ? 0 : 1)/* *  Interface used by the world */static const char *fbcon_startup(void);static void fbcon_init(struct vc_data *vc, int init);static void fbcon_deinit(struct vc_data *vc);static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,			int width);static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos);static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,			int count, int ypos, int xpos);static void fbcon_clear_margins(struct vc_data *vc, int bottom_only);static void fbcon_cursor(struct vc_data *vc, int mode);static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,			int count);static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,			int height, int width);static int fbcon_switch(struct vc_data *vc);static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);static int fbcon_set_palette(struct vc_data *vc, unsigned char *table);static int fbcon_scrolldelta(struct vc_data *vc, int lines);/* *  Internal routines */static __inline__ void ywrap_up(struct vc_data *vc, int count);static __inline__ void ywrap_down(struct vc_data *vc, int count);static __inline__ void ypan_up(struct vc_data *vc, int count);static __inline__ void ypan_down(struct vc_data *vc, int count);static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,			    int dy, int dx, int height, int width, u_int y_break);static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,			   struct vc_data *vc);static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,			      int unit);static void fbcon_redraw_move(struct vc_data *vc, struct display *p,			      int line, int count, int dy);static void fbcon_modechanged(struct fb_info *info);static void fbcon_set_all_vcs(struct fb_info *info);static void fbcon_start(void);static void fbcon_exit(void);static struct class_device *fbcon_class_device;static inline void fbcon_set_rotation(struct fb_info *info){	struct fbcon_ops *ops = info->fbcon_par;	ops->rotate = FB_ROTATE_UR;}static void fbcon_rotate(struct fb_info *info, u32 rotate){	return;}static void fbcon_rotate_all(struct fb_info *info, u32 rotate){	return;}static int fbcon_get_rotate(struct fb_info *info){	struct fbcon_ops *ops = info->fbcon_par;	return (ops) ? ops->rotate : 0;}static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info){	struct fbcon_ops *ops = info->fbcon_par;	return (info->state != FBINFO_STATE_RUNNING ||		vc->vc_mode != KD_TEXT || ops->graphics);}static inline int get_color(struct vc_data *vc, struct fb_info *info,	      u16 c, int is_fg){	int depth = fb_get_color_depth(&info->var, &info->fix);	int color = 0;	if (console_blanked) {		unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;		c = vc->vc_video_erase_char & charmask;	}	if (depth != 1)		color = (is_fg) ? attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8, c)			: attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12, c);	switch (depth) {	case 1:	{		int col = ~(0xfff << (max(info->var.green.length,					  max(info->var.red.length,					      info->var.blue.length)))) & 0xff;		/* 0 or 1 */		int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;		int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;		if (console_blanked)			fg = bg;		color = (is_fg) ? fg : bg;		break;	}	case 2:		/*		 * Scale down 16-colors to 4 colors. Default 4-color palette		 * is grayscale. However, simply dividing the values by 4		 * will not work, as colors 1, 2 and 3 will be scaled-down		 * to zero rendering them invisible.  So empirically convert		 * colors to a sane 4-level grayscale.		 */		switch (color) {		case 0:			color = 0; /* black */			break;		case 1 ... 6:			color = 2; /* white */			break;		case 7 ... 8:			color = 1; /* gray */			break;		default:			color = 3; /* intense white */			break;		}		break;	case 3:		/*		 * Last 8 entries of default 16-color palette is a more intense		 * version of the first 8 (i.e., same chrominance, different		 * luminance).		 */		color &= 7;		break;	}	return color;}static void fbcon_update_softback(struct vc_data *vc){	int l = fbcon_softback_size / vc->vc_size_row;	if (l > 5)		softback_end = softback_buf + l * vc->vc_size_row;	else		/* Smaller scrollback makes no sense, and 0 would screw		   the operation totally */		softback_top = 0;}static void fb_flashcursor(struct work_struct *work){	struct fb_info *info = container_of(work, struct fb_info, queue);	struct fbcon_ops *ops = info->fbcon_par;	struct display *p;	struct vc_data *vc = NULL;	int c;	int mode;	acquire_console_sem();	if (ops && ops->currcon != -1)		vc = vc_cons[ops->currcon].d;	if (!vc || !CON_IS_VISIBLE(vc) || 	    registered_fb[con2fb_map[vc->vc_num]] != info ||	    vc->vc_deccm != 1) {		release_console_sem();		return;	}	p = &fb_display[vc->vc_num];	c = scr_readw((u16 *) vc->vc_pos);	mode = (!ops->cursor_flash || ops->cursor_state.enable) ?		CM_ERASE : CM_DRAW;	ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),		    get_color(vc, info, c, 0));	release_console_sem();}	static void cursor_timer_handler(unsigned long dev_addr){	struct fb_info *info = (struct fb_info *) dev_addr;	struct fbcon_ops *ops = info->fbcon_par;	schedule_work(&info->queue);	mod_timer(&ops->cursor_timer, jiffies + HZ/5);}static void fbcon_add_cursor_timer(struct fb_info *info){	struct fbcon_ops *ops = info->fbcon_par;	if ((!info->queue.func || info->queue.func == fb_flashcursor) &&	    !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) {		if (!info->queue.func)			INIT_WORK(&info->queue, fb_flashcursor);		init_timer(&ops->cursor_timer);		ops->cursor_timer.function = cursor_timer_handler;		ops->cursor_timer.expires = jiffies + HZ / 5;		ops->cursor_timer.data = (unsigned long ) info;		add_timer(&ops->cursor_timer);		ops->flags |= FBCON_FLAGS_CURSOR_TIMER;	}}static void fbcon_del_cursor_timer(struct fb_info *info){	struct fbcon_ops *ops = info->fbcon_par;	if (info->queue.func == fb_flashcursor &&	    ops->flags & FBCON_FLAGS_CURSOR_TIMER) {		del_timer_sync(&ops->cursor_timer);		ops->flags &= ~FBCON_FLAGS_CURSOR_TIMER;	}}static int __init fb_console_setup(char *this_opt){	char *options;	int i, j;	if (!this_opt || !*this_opt)		return 1;	while ((options = strsep(&this_opt, ",")) != NULL) {		if (!strncmp(options, "font:", 5))			strcpy(fontname, options + 5);				if (!strncmp(options, "scrollback:", 11)) {			options += 11;			if (*options) {				fbcon_softback_size = simple_strtoul(options, &options, 0);				if (*options == 'k' || *options == 'K') {					fbcon_softback_size *= 1024;					options++;				}				if (*options != ',')					return 1;				options++;			} else				return 1;		}				if (!strncmp(options, "map:", 4)) {			options += 4;			if (*options)				for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) {					if (!options[j])						j = 0;					con2fb_map_boot[i] =						(options[j++]-'0') % FB_MAX;				}			return 1;		}		if (!strncmp(options, "vc:", 3)) {			options += 3;			if (*options)				first_fb_vc = simple_strtoul(options, &options, 10) - 1;			if (first_fb_vc < 0)				first_fb_vc = 0;			if (*options++ == '-')				last_fb_vc = simple_strtoul(options, &options, 10) - 1;			fbcon_is_default = 0; 		}			if (!strncmp(options, "rotate:", 7)) {			options += 7;			if (*options)				rotate = simple_strtoul(options, &options, 0);			if (rotate > 3)				rotate = 0;		}	}	return 1;}__setup("fbcon=", fb_console_setup);static int search_fb_in_map(int idx){	int i, retval = 0;	for (i = first_fb_vc; i <= last_fb_vc; i++) {		if (con2fb_map[i] == idx)			retval = 1;	}	return retval;}static int search_for_mapped_con(void){	int i, retval = 0;	for (i = first_fb_vc; i <= last_fb_vc; i++) {		if (con2fb_map[i] != -1)			retval = 1;	}	return retval;}static int fbcon_takeover(int show_logo){	int err, i;	if (!num_registered_fb)		return -ENODEV;	if (!show_logo)		logo_shown = FBCON_LOGO_DONTSHOW;	for (i = first_fb_vc; i <= last_fb_vc; i++)		con2fb_map[i] = info_idx;	err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,				fbcon_is_default);	if (err) {		for (i = first_fb_vc; i <= last_fb_vc; i++) {			con2fb_map[i] = -1;		}		info_idx = -1;	}	return err;}static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,			       int cols, int rows, int new_cols, int new_rows){	/* Need to make room for the logo */	struct fbcon_ops *ops = info->fbcon_par;	int cnt, erase = vc->vc_video_erase_char, step;	unsigned short *save = NULL, *r, *q;	if (info->flags & FBINFO_MODULE) {		logo_shown = FBCON_LOGO_DONTSHOW;		return;	}	/*	 * remove underline attribute from erase character	 * if black and white framebuffer.	 */	if (fb_get_color_depth(&info->var, &info->fix) == 1)		erase &= ~0x400;	logo_height = fb_prepare_logo(info, ops->rotate);	logo_lines = (logo_height + vc->vc_font.height - 1) /		vc->vc_font.height;	q = (unsigned short *) (vc->vc_origin +

⌨️ 快捷键说明

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