fbcon-cfb8.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/video/cfb8.c -- Low level frame buffer operations for 8 bpp
  3.  *   packed pixels
  4.  *
  5.  * Created 5 Apr 1997 by Geert Uytterhoeven
  6.  *
  7.  *  This file is subject to the terms and conditions of the GNU General Public
  8.  *  License.  See the file COPYING in the main directory of this archive for
  9.  *  more details.
  10.  */
  11. #include <linux/module.h>
  12. #include <linux/tty.h>
  13. #include <linux/console.h>
  14. #include <linux/string.h>
  15. #include <linux/fb.h>
  16. #include <video/fbcon.h>
  17. #include <video/fbcon-cfb8.h>
  18.     /*
  19.      *  8 bpp packed pixels
  20.      */
  21. static u32 nibbletab_cfb8[] = {
  22. #if defined(__BIG_ENDIAN)
  23.     0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
  24.     0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
  25.     0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
  26.     0xffff0000,0xffff00ff,0xffffff00,0xffffffff
  27. #elif defined(__LITTLE_ENDIAN)
  28.     0x00000000,0xff000000,0x00ff0000,0xffff0000,
  29.     0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
  30.     0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
  31.     0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
  32. #else
  33. #error FIXME: No endianness??
  34. #endif
  35. };
  36. void fbcon_cfb8_setup(struct display *p)
  37. {
  38.     p->next_line = p->line_length ? p->line_length : p->var.xres_virtual;
  39.     p->next_plane = 0;
  40. }
  41. void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
  42.       int height, int width)
  43. {
  44.     int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
  45.     u8 *src,*dst;
  46.     if (sx == 0 && dx == 0 && width * fontwidth(p) == bytes) {
  47. fb_memmove(p->screen_base + dy * linesize,
  48.   p->screen_base + sy * linesize,
  49.   height * linesize);
  50. return;
  51.     }
  52.     if (fontwidthlog(p)) {
  53.      sx <<= fontwidthlog(p); dx <<= fontwidthlog(p); width <<= fontwidthlog(p);
  54.     } else {
  55.      sx *= fontwidth(p); dx *= fontwidth(p); width *= fontwidth(p);
  56.     }
  57.     if (dy < sy || (dy == sy && dx < sx)) {
  58. src = p->screen_base + sy * linesize + sx;
  59. dst = p->screen_base + dy * linesize + dx;
  60. for (rows = height * fontheight(p) ; rows-- ;) {
  61.     fb_memmove(dst, src, width);
  62.     src += bytes;
  63.     dst += bytes;
  64. }
  65.     } else {
  66. src = p->screen_base + (sy+height) * linesize + sx - bytes;
  67. dst = p->screen_base + (dy+height) * linesize + dx - bytes;
  68. for (rows = height * fontheight(p) ; rows-- ;) {
  69.     fb_memmove(dst, src, width);
  70.     src -= bytes;
  71.     dst -= bytes;
  72. }
  73.     }
  74. }
  75. static inline void rectfill(u8 *dest, int width, int height, u8 data,
  76.     int linesize)
  77. {
  78.     while (height-- > 0) {
  79. fb_memset(dest, data, width);
  80. dest += linesize;
  81.     }
  82. }
  83. void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx,
  84.       int height, int width)
  85. {
  86.     u8 *dest;
  87.     int bytes=p->next_line,lines=height * fontheight(p);
  88.     u8 bgx;
  89.     dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p);
  90.     bgx=attr_bgcol_ec(p,conp);
  91.     width *= fontwidth(p);
  92.     if (width == bytes)
  93. rectfill(dest, lines * width, 1, bgx, bytes);
  94.     else
  95. rectfill(dest, width, lines, bgx, bytes);
  96. }
  97. void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy,
  98.      int xx)
  99. {
  100.     u8 *dest,*cdat;
  101.     int bytes=p->next_line,rows;
  102.     u32 eorx,fgx,bgx;
  103.     dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
  104.     if (fontwidth(p) <= 8)
  105. cdat = p->fontdata + (c & p->charmask) * fontheight(p);
  106.     else
  107. cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
  108.     fgx=attr_fgcol(p,c);
  109.     bgx=attr_bgcol(p,c);
  110.     fgx |= (fgx << 8);
  111.     fgx |= (fgx << 16);
  112.     bgx |= (bgx << 8);
  113.     bgx |= (bgx << 16);
  114.     eorx = fgx ^ bgx;
  115.     switch (fontwidth(p)) {
  116.     case 4:
  117. for (rows = fontheight(p) ; rows-- ; dest += bytes)
  118.     fb_writel((nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx, dest);
  119.         break;
  120.     case 8:
  121. for (rows = fontheight(p) ; rows-- ; dest += bytes) {
  122.     fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
  123.     fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
  124.         }
  125.         break;
  126.     case 12:
  127.     case 16:
  128. for (rows = fontheight(p) ; rows-- ; dest += bytes) {
  129.     fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
  130.     fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
  131.     fb_writel((nibbletab_cfb8[(*cdat >> 4) & 0xf] & eorx) ^ bgx, dest+8);
  132.     if (fontwidth(p) == 16)
  133. fb_writel((nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx, dest+12);
  134.     cdat++;
  135.         }
  136.         break;
  137.     }
  138. }
  139. void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p, 
  140.       const unsigned short *s, int count, int yy, int xx)
  141. {
  142.     u8 *cdat, *dest, *dest0;
  143.     u16 c;
  144.     int rows,bytes=p->next_line;
  145.     u32 eorx, fgx, bgx;
  146.     dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
  147.     c = scr_readw(s);
  148.     fgx = attr_fgcol(p, c);
  149.     bgx = attr_bgcol(p, c);
  150.     fgx |= (fgx << 8);
  151.     fgx |= (fgx << 16);
  152.     bgx |= (bgx << 8);
  153.     bgx |= (bgx << 16);
  154.     eorx = fgx ^ bgx;
  155.     switch (fontwidth(p)) {
  156.     case 4:
  157. while (count--) {
  158.     c = scr_readw(s++) & p->charmask;
  159.     cdat = p->fontdata + c * fontheight(p);
  160.     for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes)
  161. fb_writel((nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx, dest);
  162.     dest0+=4;
  163.         }
  164.         break;
  165.     case 8:
  166. while (count--) {
  167.     c = scr_readw(s++) & p->charmask;
  168.     cdat = p->fontdata + c * fontheight(p);
  169.     for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
  170. fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
  171. fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
  172.     }
  173.     dest0+=8;
  174.         }
  175.         break;
  176.     case 12:
  177.     case 16:
  178. while (count--) {
  179.     c = scr_readw(s++) & p->charmask;
  180.     cdat = p->fontdata + (c * fontheight(p) << 1);
  181.     for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
  182. fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
  183. fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
  184. fb_writel((nibbletab_cfb8[(*cdat >> 4) & 0xf] & eorx) ^ bgx, dest+8);
  185. if (fontwidth(p) == 16)
  186.    fb_writel((nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx, dest+12);
  187. cdat++;
  188.     }
  189.     dest0+=fontwidth(p);
  190.         }
  191.         break;
  192.     }
  193. }
  194. void fbcon_cfb8_revc(struct display *p, int xx, int yy)
  195. {
  196.     u8 *dest;
  197.     int bytes=p->next_line, rows;
  198.     dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
  199.     for (rows = fontheight(p) ; rows-- ; dest += bytes) {
  200.      switch (fontwidth(p)) {
  201.      case 16: fb_writel(fb_readl(dest+12) ^ 0x0f0f0f0f, dest+12); /* fall thru */
  202.      case 12: fb_writel(fb_readl(dest+8) ^ 0x0f0f0f0f, dest+8); /* fall thru */
  203.      case 8: fb_writel(fb_readl(dest+4) ^ 0x0f0f0f0f, dest+4); /* fall thru */
  204.      case 4: fb_writel(fb_readl(dest) ^ 0x0f0f0f0f, dest); /* fall thru */
  205.      default: break;
  206.      }
  207.     }
  208. }
  209. void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p,
  210.       int bottom_only)
  211. {
  212.     int bytes=p->next_line;
  213.     u8 bgx;
  214.     unsigned int right_start = conp->vc_cols*fontwidth(p);
  215.     unsigned int bottom_start = conp->vc_rows*fontheight(p);
  216.     unsigned int right_width, bottom_width;
  217.     bgx=attr_bgcol_ec(p,conp);
  218.     if (!bottom_only && (right_width = p->var.xres-right_start))
  219. rectfill(p->screen_base+right_start, right_width, p->var.yres_virtual,
  220.  bgx, bytes);
  221.     if ((bottom_width = p->var.yres-bottom_start))
  222. rectfill(p->screen_base+(p->var.yoffset+bottom_start)*bytes,
  223.  right_start, bottom_width, bgx, bytes);
  224. }
  225.     /*
  226.      *  `switch' for the low level operations
  227.      */
  228. struct display_switch fbcon_cfb8 = {
  229.     setup: fbcon_cfb8_setup,
  230.     bmove: fbcon_cfb8_bmove,
  231.     clear: fbcon_cfb8_clear,
  232.     putc: fbcon_cfb8_putc,
  233.     putcs: fbcon_cfb8_putcs,
  234.     revc: fbcon_cfb8_revc,
  235.     clear_margins: fbcon_cfb8_clear_margins,
  236.     fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
  237. };
  238. #ifdef MODULE
  239. MODULE_LICENSE("GPL");
  240. int init_module(void)
  241. {
  242.     return 0;
  243. }
  244. void cleanup_module(void)
  245. {}
  246. #endif /* MODULE */
  247.     /*
  248.      *  Visible symbols for modules
  249.      */
  250. EXPORT_SYMBOL(fbcon_cfb8);
  251. EXPORT_SYMBOL(fbcon_cfb8_setup);
  252. EXPORT_SYMBOL(fbcon_cfb8_bmove);
  253. EXPORT_SYMBOL(fbcon_cfb8_clear);
  254. EXPORT_SYMBOL(fbcon_cfb8_putc);
  255. EXPORT_SYMBOL(fbcon_cfb8_putcs);
  256. EXPORT_SYMBOL(fbcon_cfb8_revc);
  257. EXPORT_SYMBOL(fbcon_cfb8_clear_margins);