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

📄 promcon.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
字号:
/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $ * Console driver utilizing PROM sun terminal emulation * * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be) * Copyright (C) 1998  Jakub Jelinek  (jj@ultra.linux.cz) */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/console.h>#include <linux/console_struct.h>#include <linux/vt_kern.h>#include <linux/selection.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/kd.h>#include <asm/oplib.h>#include <asm/uaccess.h>static short pw = 80 - 1, ph = 34 - 1;static short px, py;static unsigned long promcon_uni_pagedir[2];extern u8 promfont_unicount[];extern u16 promfont_unitable[];#define PROMCON_COLOR 0#if PROMCON_COLOR#define inverted(s)	((((s) & 0x7700) == 0x0700) ? 0 : 1)#else#define inverted(s)	(((s) & 0x0800) ? 1 : 0)#endifstatic __inline__ voidpromcon_puts(char *buf, int cnt){	prom_printf("%*.*s", cnt, cnt, buf);}static intpromcon_start(struct vc_data *conp, char *b){	unsigned short *s = (unsigned short *)			(conp->vc_origin + py * conp->vc_size_row + (px << 1));	u16 cs;	cs = scr_readw(s);	if (px == pw) {		unsigned short *t = s - 1;		u16 ct = scr_readw(t);		if (inverted(cs) && inverted(ct))			return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,				       ct);		else if (inverted(cs))			return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,				       ct);		else if (inverted(ct))			return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,				       ct);		else			return sprintf(b, "\b%c\b\033[@%c", cs, ct);	}	if (inverted(cs))		return sprintf(b, "\033[7m%c\033[m\b", cs);	else		return sprintf(b, "%c\b", cs);}static intpromcon_end(struct vc_data *conp, char *b){	unsigned short *s = (unsigned short *)			(conp->vc_origin + py * conp->vc_size_row + (px << 1));	char *p = b;	u16 cs;	b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);	cs = scr_readw(s);	if (px == pw) {		unsigned short *t = s - 1;		u16 ct = scr_readw(t);		if (inverted(cs) && inverted(ct))			b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);		else if (inverted(cs))			b += sprintf(b, "\b%c\b\033[@%c", cs, ct);		else if (inverted(ct))			b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);		else			b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);		return b - p;	}	if (inverted(cs))		b += sprintf(b, "%c\b", cs);	else		b += sprintf(b, "\033[7m%c\033[m\b", cs);	return b - p;}const char __init *promcon_startup(void){	const char *display_desc = "PROM";	int node;	char buf[40];		node = prom_getchild(prom_root_node);	node = prom_searchsiblings(node, "options");	if (prom_getproperty(node,  "screen-#columns", buf, 40) != -1) {		pw = simple_strtoul(buf, NULL, 0);		if (pw < 10 || pw > 256)			pw = 80;		pw--;	}	if (prom_getproperty(node,  "screen-#rows", buf, 40) != -1) {		ph = simple_strtoul(buf, NULL, 0);		if (ph < 10 || ph > 256)			ph = 34;		ph--;	}	promcon_puts("\033[H\033[J", 6);	return display_desc;}static void __init promcon_init_unimap(struct vc_data *conp){	mm_segment_t old_fs = get_fs();	struct unipair *p, *p1;	u16 *q;	int i, j, k;		p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);	if (!p) return;		q = promfont_unitable;	p1 = p;	k = 0;	for (i = 0; i < 256; i++)		for (j = promfont_unicount[i]; j; j--) {			p1->unicode = *q++;			p1->fontpos = i;			p1++;			k++;		}	set_fs(KERNEL_DS);	con_clear_unimap(conp->vc_num, NULL);	con_set_unimap(conp->vc_num, k, p);	con_protect_unimap(conp->vc_num, 1);	set_fs(old_fs);	kfree(p);}static voidpromcon_init(struct vc_data *conp, int init){	unsigned long p;		conp->vc_can_do_color = PROMCON_COLOR;	if (init) {		conp->vc_cols = pw + 1;		conp->vc_rows = ph + 1;	}	p = *conp->vc_uni_pagedir_loc;	if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||	    !--conp->vc_uni_pagedir_loc[1])		con_free_unimap(conp->vc_num);	conp->vc_uni_pagedir_loc = promcon_uni_pagedir;	promcon_uni_pagedir[1]++;	if (!promcon_uni_pagedir[0] && p) {		promcon_init_unimap(conp);	}	if (!init) {		if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)			vc_resize_con(ph + 1, pw + 1, conp->vc_num);	}}static voidpromcon_deinit(struct vc_data *conp){	/* When closing the last console, reset video origin */	if (!--promcon_uni_pagedir[1])		con_free_unimap(conp->vc_num);	conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;	con_set_default_unimap(conp->vc_num);}static intpromcon_switch(struct vc_data *conp){	return 1;}static unsigned short *promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp){	int cnt = pw + 1;	int attr = -1;	unsigned char *b = *bp;	while (cnt--) {		u16 c = scr_readw(s);		if (attr != inverted(c)) {			attr = inverted(c);			if (attr) {				strcpy (b, "\033[7m");				b += 4;			} else {				strcpy (b, "\033[m");				b += 3;			}		}		*b++ = c;		s++;		if (b - buf >= 224) {			promcon_puts(buf, b - buf);			b = buf;		}	}	*bp = b;	return s;}static voidpromcon_putcs(struct vc_data *conp, const unsigned short *s,	      int count, int y, int x){	unsigned char buf[256], *b = buf;	unsigned short attr = scr_readw(s);	unsigned char save;	int i, last = 0;	if (console_blanked)		return;		if (count <= 0)		return;	b += promcon_start(conp, b);	if (x + count >= pw + 1) {		if (count == 1) {			x -= 1;			save = scr_readw((unsigned short *)(conp->vc_origin						   + y * conp->vc_size_row						   + (x << 1)));			if (px != x || py != y) {				b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);				px = x;				py = y;			}			if (inverted(attr))				b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));			else				b += sprintf(b, "%c", scr_readw(s++));			strcpy(b, "\b\033[@");			b += 4;			if (inverted(save))				b += sprintf(b, "\033[7m%c\033[m", save);			else				b += sprintf(b, "%c", save);			px++;			b += promcon_end(conp, b);			promcon_puts(buf, b - buf);			return;		} else {			last = 1;			count = pw - x - 1;		}	}	if (inverted(attr)) {		strcpy(b, "\033[7m");		b += 4;	}	if (px != x || py != y) {		b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);		px = x;		py = y;	}	for (i = 0; i < count; i++) {		if (b - buf >= 224) {			promcon_puts(buf, b - buf);			b = buf;		}		*b++ = scr_readw(s++);	}	px += count;	if (last) {		save = scr_readw(s++);		b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);		px++;	}	if (inverted(attr)) {		strcpy(b, "\033[m");		b += 3;	}	b += promcon_end(conp, b);	promcon_puts(buf, b - buf);}static voidpromcon_putc(struct vc_data *conp, int c, int y, int x){	unsigned short s;	if (console_blanked)		return;		scr_writew(c, &s);	promcon_putcs(conp, &s, 1, y, x);}static voidpromcon_clear(struct vc_data *conp, int sy, int sx, int height, int width){	unsigned char buf[256], *b = buf;	int i, j;	if (console_blanked)		return;		b += promcon_start(conp, b);	if (!sx && width == pw + 1) {		if (!sy && height == ph + 1) {			strcpy(b, "\033[H\033[J");			b += 6;			b += promcon_end(conp, b);			promcon_puts(buf, b - buf);			return;		} else if (sy + height == ph + 1) {			b += sprintf(b, "\033[%dH\033[J", sy + 1);			b += promcon_end(conp, b);			promcon_puts(buf, b - buf);			return;		}		b += sprintf(b, "\033[%dH", sy + 1);		for (i = 1; i < height; i++) {			strcpy(b, "\033[K\n");			b += 4;		}		strcpy(b, "\033[K");		b += 3;		b += promcon_end(conp, b);		promcon_puts(buf, b - buf);		return;	} else if (sx + width == pw + 1) {		b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);		for (i = 1; i < height; i++) {			strcpy(b, "\033[K\n");			b += 4;		}		strcpy(b, "\033[K");		b += 3;		b += promcon_end(conp, b);		promcon_puts(buf, b - buf);		return;	}	for (i = sy + 1; i <= sy + height; i++) {		b += sprintf(b, "\033[%d;%dH", i, sx + 1);		for (j = 0; j < width; j++)			*b++ = ' ';		if (b - buf + width >= 224) {			promcon_puts(buf, b - buf);			b = buf;		}	}	b += promcon_end(conp, b);	promcon_puts(buf, b - buf);}                        static voidpromcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,	      int height, int width){	char buf[256], *b = buf;	if (console_blanked)		return;		b += promcon_start(conp, b);	if (sy == dy && height == 1) {		if (dx > sx && dx + width == conp->vc_cols)			b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",				     sy + 1, sx + 1, dx - sx, py + 1, px + 1);		else if (dx < sx && sx + width == conp->vc_cols)			b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",				     dy + 1, dx + 1, sx - dx, py + 1, px + 1);		b += promcon_end(conp, b);		promcon_puts(buf, b - buf);		return;	}	/*	 * FIXME: What to do here???	 * Current console.c should not call it like that ever.	 */	prom_printf("\033[7mFIXME: bmove not handled\033[m\n");}static voidpromcon_cursor(struct vc_data *conp, int mode){	char buf[32], *b = buf;	switch (mode) {	case CM_ERASE:		break;	case CM_MOVE:	case CM_DRAW:		b += promcon_start(conp, b);		if (px != conp->vc_x || py != conp->vc_y) {			px = conp->vc_x;			py = conp->vc_y;			b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);		}		promcon_puts(buf, b - buf);		break;	}}static intpromcon_font_op(struct vc_data *conp, struct console_font_op *op){	return -ENOSYS;}        static intpromcon_blank(struct vc_data *conp, int blank){	if (blank) {		promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);		return 0;	} else {		/* Let console.c redraw */		return 1;	}}static intpromcon_scroll(struct vc_data *conp, int t, int b, int dir, int count){	unsigned char buf[256], *p = buf;	unsigned short *s;	int i;	if (console_blanked)		return 0;		p += promcon_start(conp, p);	switch (dir) {	case SM_UP:		if (b == ph + 1) {			p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);			px = 0;			py = t;			p += promcon_end(conp, p);			promcon_puts(buf, p - buf);			break;		}		s = (unsigned short *)(conp->vc_origin				       + (t + count) * conp->vc_size_row);		p += sprintf(p, "\033[%dH", t + 1);		for (i = t; i < b - count; i++)			s = promcon_repaint_line(s, buf, &p);		for (; i < b - 1; i++) {			strcpy(p, "\033[K\n");			p += 4;			if (p - buf >= 224) {				promcon_puts(buf, p - buf);				p = buf;			}		}		strcpy(p, "\033[K");		p += 3;		p += promcon_end(conp, p);		promcon_puts(buf, p - buf);		break;	case SM_DOWN:		if (b == ph + 1) {			p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);			px = 0;			py = t;			p += promcon_end(conp, p);			promcon_puts(buf, p - buf);			break;		}		s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);		p += sprintf(p, "\033[%dH", t + 1);		for (i = t; i < t + count; i++) {			strcpy(p, "\033[K\n");			p += 4;			if (p - buf >= 224) {				promcon_puts(buf, p - buf);				p = buf;			}		}		for (; i < b; i++)			s = promcon_repaint_line(s, buf, &p);		p += promcon_end(conp, p);		promcon_puts(buf, p - buf);		break;	}	return 0;}#if !(PROMCON_COLOR)static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse){	return (_reverse) ? 0xf : 0x7;}#endif/* *  The console 'switch' structure for the VGA based console */static int promcon_dummy(void){        return 0;}#define DUMMY (void *) promcon_dummyconst struct consw prom_con = {	con_startup:		promcon_startup,	con_init:		promcon_init,	con_deinit:		promcon_deinit,	con_clear:		promcon_clear,	con_putc:		promcon_putc,	con_putcs:		promcon_putcs,	con_cursor:		promcon_cursor,	con_scroll:		promcon_scroll,	con_bmove:		promcon_bmove,	con_switch:		promcon_switch,	con_blank:		promcon_blank,	con_font_op:		promcon_font_op,	con_set_palette:	DUMMY,	con_scrolldelta:	DUMMY,#if !(PROMCON_COLOR)	con_build_attr:		promcon_build_attr,#endif};void __init prom_con_init(void){#ifdef CONFIG_DUMMY_CONSOLE	if (conswitchp == &dummy_con)		take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);	else#endif	if (conswitchp == &prom_con)		promcon_init_unimap(vc_cons[fg_console].d);}

⌨️ 快捷键说明

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