diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
commit | 230e5ab6a084ed50470f101934782dbf54b0d06b (patch) | |
tree | 5dd821c8d33f450470588e7a543f74bf74306e9e /drivers/video/fbcon-cfb16.c | |
parent | c9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff) |
Merge with Linux 2.1.67.
Diffstat (limited to 'drivers/video/fbcon-cfb16.c')
-rw-r--r-- | drivers/video/fbcon-cfb16.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/drivers/video/fbcon-cfb16.c b/drivers/video/fbcon-cfb16.c new file mode 100644 index 000000000..817322d4a --- /dev/null +++ b/drivers/video/fbcon-cfb16.c @@ -0,0 +1,233 @@ +/* + * linux/drivers/video/cfb16.c -- Low level frame buffer operations for 16 bpp + * packed pixels + * + * Created 5 Apr 1997 by Geert Uytterhoeven + * + * 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. + */ + +#include <linux/module.h> +#include <linux/tty.h> +#include <linux/console.h> +#include <linux/string.h> +#include <linux/config.h> +#include <linux/fb.h> + +#include "fbcon.h" + + + /* + * Prototypes + */ + +static int open_cfb16(struct display *p); +static void release_cfb16(void); +static void bmove_cfb16(struct display *p, int sy, int sx, int dy, int dx, + int height, int width); +static void clear_cfb16(struct vc_data *conp, struct display *p, int sy, + int sx, int height, int width); +static void putc_cfb16(struct vc_data *conp, struct display *p, int c, + int yy, int xx); +static void putcs_cfb16(struct vc_data *conp, struct display *p, + const char *s, int count, int yy, int xx); +static void rev_char_cfb16(struct display *p, int xx, int yy); + + + /* + * `switch' for the low level operations + */ + +static struct display_switch dispsw_cfb16 = { + open_cfb16, release_cfb16, bmove_cfb16, clear_cfb16, putc_cfb16, + putcs_cfb16, rev_char_cfb16 +}; + + + /* + * 16 bpp packed pixels + */ + +u_short packed16_cmap[16]; + +static u_long tab_cfb16[] = { + 0x00000000,0x0000ffff,0xffff0000,0xffffffff +}; + +static int open_cfb16(struct display *p) +{ + if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 16) + return -EINVAL; + + p->next_line = p->var.xres_virtual<<1; + p->next_plane = 0; + MOD_INC_USE_COUNT; + return 0; +} + +static void release_cfb16(void) +{ + MOD_DEC_USE_COUNT; +} + +static void bmove_cfb16(struct display *p, int sy, int sx, int dy, int dx, + int height, int width) +{ + int bytes = p->next_line, linesize = bytes * p->fontheight, rows; + u_char *src,*dst; + + if (sx == 0 && dx == 0 && width * 16 == bytes) + mymemmove(p->screen_base + dy * linesize, + p->screen_base + sy * linesize, + height * linesize); + else if (dy < sy || (dy == sy && dx < sx)) { + src = p->screen_base + sy * linesize + sx * 16; + dst = p->screen_base + dy * linesize + dx * 16; + for (rows = height * p->fontheight ; rows-- ;) { + mymemmove(dst, src, width * 16); + src += bytes; + dst += bytes; + } + } else { + src = p->screen_base + (sy+height) * linesize + sx * 16 - bytes; + dst = p->screen_base + (dy+height) * linesize + dx * 16 - bytes; + for (rows = height * p->fontheight ; rows-- ;) { + mymemmove(dst, src, width * 16); + src -= bytes; + dst -= bytes; + } + } +} + +static void clear_cfb16(struct vc_data *conp, struct display *p, int sy, + int sx, int height, int width) +{ + u_char *dest0,*dest; + int bytes=p->next_line,lines=height * p->fontheight, rows, i; + u_long bgx; + + dest = p->screen_base + sy * p->fontheight * bytes + sx * 16; + + bgx = attr_bgcol_ec(p,conp); + bgx = packed16_cmap[bgx]; + bgx |= (bgx << 16); + + if (sx == 0 && width * 16 == bytes) + for (i = 0 ; i < lines * width ; i++) { + ((u_long *)dest)[0]=bgx; + ((u_long *)dest)[1]=bgx; + ((u_long *)dest)[2]=bgx; + ((u_long *)dest)[3]=bgx; + dest+=16; + } + else { + dest0=dest; + for (rows = lines; rows-- ; dest0 += bytes) { + dest=dest0; + for (i = 0 ; i < width ; i++) { + ((u_long *)dest)[0]=bgx; + ((u_long *)dest)[1]=bgx; + ((u_long *)dest)[2]=bgx; + ((u_long *)dest)[3]=bgx; + dest+=16; + } + } + } +} + +static void putc_cfb16(struct vc_data *conp, struct display *p, int c, int yy, + int xx) +{ + u_char *dest,*cdat; + int bytes=p->next_line,rows; + ulong eorx,fgx,bgx; + + c &= 0xff; + + dest = p->screen_base + yy * p->fontheight * bytes + xx * 16; + cdat = p->fontdata + c * p->fontheight; + + fgx = attr_fgcol(p,conp); + fgx = packed16_cmap[fgx]; + bgx = attr_bgcol(p,conp); + bgx = packed16_cmap[bgx]; + fgx |= (fgx << 16); + bgx |= (bgx << 16); + eorx = fgx ^ bgx; + + for (rows = p->fontheight ; rows-- ; dest += bytes) { + ((u_long *)dest)[0]= (tab_cfb16[*cdat >> 6] & eorx) ^ bgx; + ((u_long *)dest)[1]= (tab_cfb16[*cdat >> 4 & 0x3] & eorx) ^ bgx; + ((u_long *)dest)[2]= (tab_cfb16[*cdat >> 2 & 0x3] & eorx) ^ bgx; + ((u_long *)dest)[3]= (tab_cfb16[*cdat++ & 0x3] & eorx) ^ bgx; + } +} + +static void putcs_cfb16(struct vc_data *conp, struct display *p, const char *s, + int count, int yy, int xx) +{ + u_char *cdat, c, *dest, *dest0; + int rows,bytes=p->next_line; + u_long eorx, fgx, bgx; + + dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 16; + fgx = attr_fgcol(p,conp); + fgx = packed16_cmap[fgx]; + bgx = attr_bgcol(p,conp); + bgx = packed16_cmap[bgx]; + fgx |= (fgx << 16); + bgx |= (bgx << 16); + eorx = fgx ^ bgx; + while (count--) { + c = *s++; + cdat = p->fontdata + c * p->fontheight; + + for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) { + ((u_long *)dest)[0]= (tab_cfb16[*cdat >> 6] & eorx) ^ bgx; + ((u_long *)dest)[1]= (tab_cfb16[*cdat >> 4 & 0x3] & eorx) ^ bgx; + ((u_long *)dest)[2]= (tab_cfb16[*cdat >> 2 & 0x3] & eorx) ^ bgx; + ((u_long *)dest)[3]= (tab_cfb16[*cdat++ & 0x3] & eorx) ^ bgx; + } + dest0+=16; + } +} + +static void rev_char_cfb16(struct display *p, int xx, int yy) +{ + u_char *dest; + int bytes=p->next_line, rows; + + dest = p->screen_base + yy * p->fontheight * bytes + xx * 16; + for (rows = p->fontheight ; rows-- ; dest += bytes) { + ((u_long *)dest)[0] ^= 0xffffffff; + ((u_long *)dest)[1] ^= 0xffffffff; + ((u_long *)dest)[2] ^= 0xffffffff; + ((u_long *)dest)[3] ^= 0xffffffff; + } +} + + +#ifdef MODULE +int init_module(void) +#else +int fbcon_init_cfb16(void) +#endif +{ + return(fbcon_register_driver(&dispsw_cfb16, 0)); +} + +#ifdef MODULE +void cleanup_module(void) +{ + fbcon_unregister_driver(&dispsw_cfb16); +} +#endif /* MODULE */ + + + /* + * Visible symbols for modules + */ + +EXPORT_SYMBOL(packed16_cmap); |