fbcmap.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/video/fbcmap.c -- Colormap handling for frame buffer devices
  3.  *
  4.  * Created 15 Jun 1997 by Geert Uytterhoeven
  5.  *
  6.  * 2001 - Documented with DocBook
  7.  * - Brad Douglas <brad@neruo.com>
  8.  *
  9.  *  This file is subject to the terms and conditions of the GNU General Public
  10.  *  License.  See the file COPYING in the main directory of this archive for
  11.  *  more details.
  12.  */
  13. #include <linux/string.h>
  14. #include <linux/module.h>
  15. #include <linux/tty.h>
  16. #include <linux/fb.h>
  17. #include <linux/slab.h>
  18. #include <asm/uaccess.h>
  19. static u16 red2[] = {
  20.     0x0000, 0xaaaa
  21. };
  22. static u16 green2[] = {
  23.     0x0000, 0xaaaa
  24. };
  25. static u16 blue2[] = {
  26.     0x0000, 0xaaaa
  27. };
  28. static u16 red4[] = {
  29.     0x0000, 0xaaaa, 0x5555, 0xffff
  30. };
  31. static u16 green4[] = {
  32.     0x0000, 0xaaaa, 0x5555, 0xffff
  33. };
  34. static u16 blue4[] = {
  35.     0x0000, 0xaaaa, 0x5555, 0xffff
  36. };
  37. static u16 red8[] = {
  38.     0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa
  39. };
  40. static u16 green8[] = {
  41.     0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa
  42. };
  43. static u16 blue8[] = {
  44.     0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa
  45. };
  46. static u16 red16[] = {
  47.     0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
  48.     0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
  49. };
  50. static u16 green16[] = {
  51.     0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
  52.     0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
  53. };
  54. static u16 blue16[] = {
  55.     0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
  56.     0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
  57. };
  58. static struct fb_cmap default_2_colors = {
  59.     0, 2, red2, green2, blue2, NULL
  60. };
  61. static struct fb_cmap default_8_colors = {
  62.     0, 8, red8, green8, blue8, NULL
  63. };
  64. static struct fb_cmap default_4_colors = {
  65.     0, 4, red4, green4, blue4, NULL
  66. };
  67. static struct fb_cmap default_16_colors = {
  68.     0, 16, red16, green16, blue16, NULL
  69. };
  70. /**
  71.  * fb_alloc_cmap - allocate a colormap
  72.  * @cmap: frame buffer colormap structure
  73.  * @len: length of @cmap
  74.  * @transp: boolean, 1 if there is transparency, 0 otherwise
  75.  *
  76.  * Allocates memory for a colormap @cmap.  @len is the
  77.  * number of entries in the palette.
  78.  *
  79.  * Returns -1 errno on error, or zero on success.
  80.  *
  81.  */
  82. int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
  83. {
  84.     int size = len*sizeof(u16);
  85.     if (cmap->len != len) {
  86. if (cmap->red)
  87.     kfree(cmap->red);
  88. if (cmap->green)
  89.     kfree(cmap->green);
  90. if (cmap->blue)
  91.     kfree(cmap->blue);
  92. if (cmap->transp)
  93.     kfree(cmap->transp);
  94. cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
  95. cmap->len = 0;
  96. if (!len)
  97.     return 0;
  98. if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
  99.     return -1;
  100. if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
  101.     return -1;
  102. if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
  103.     return -1;
  104. if (transp) {
  105.     if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
  106. return -1;
  107. } else
  108.     cmap->transp = NULL;
  109.     }
  110.     cmap->start = 0;
  111.     cmap->len = len;
  112.     fb_copy_cmap(fb_default_cmap(len), cmap, 0);
  113.     return 0;
  114. }
  115. /**
  116.  * fb_copy_cmap - copy a colormap
  117.  * @from: frame buffer colormap structure
  118.  * @to: frame buffer colormap structure
  119.  * @fsfromto: determine copy method
  120.  *
  121.  * Copy contents of colormap from @from to @to.
  122.  *
  123.  * @fsfromto accepts the following integer parameters:
  124.  * 0: memcpy function
  125.  * 1: copy_from_user() function to copy from userspace
  126.  * 2: copy_to_user() function to copy to userspace
  127.  *
  128.  */
  129. void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
  130. {
  131.     int size;
  132.     int tooff = 0, fromoff = 0;
  133.     if (to->start > from->start)
  134. fromoff = to->start-from->start;
  135.     else
  136. tooff = from->start-to->start;
  137.     size = to->len-tooff;
  138.     if (size > from->len-fromoff)
  139. size = from->len-fromoff;
  140.     if (size < 0)
  141. return;
  142.     size *= sizeof(u16);
  143.     
  144.     switch (fsfromto) {
  145.     case 0:
  146. memcpy(to->red+tooff, from->red+fromoff, size);
  147. memcpy(to->green+tooff, from->green+fromoff, size);
  148. memcpy(to->blue+tooff, from->blue+fromoff, size);
  149. if (from->transp && to->transp)
  150.     memcpy(to->transp+tooff, from->transp+fromoff, size);
  151.         break;
  152.     case 1:
  153. copy_from_user(to->red+tooff, from->red+fromoff, size);
  154. copy_from_user(to->green+tooff, from->green+fromoff, size);
  155. copy_from_user(to->blue+tooff, from->blue+fromoff, size);
  156. if (from->transp && to->transp)
  157.             copy_from_user(to->transp+tooff, from->transp+fromoff, size);
  158. break;
  159.     case 2:
  160. copy_to_user(to->red+tooff, from->red+fromoff, size);
  161. copy_to_user(to->green+tooff, from->green+fromoff, size);
  162. copy_to_user(to->blue+tooff, from->blue+fromoff, size);
  163. if (from->transp && to->transp)
  164.     copy_to_user(to->transp+tooff, from->transp+fromoff, size);
  165. break;
  166.     }
  167. }
  168. /**
  169.  * fb_get_cmap - get a colormap
  170.  * @cmap: frame buffer colormap
  171.  * @kspc: boolean, 0 copy local, 1 put_user() function
  172.  * @getcolreg: pointer to a function to get a color register
  173.  * @info: frame buffer info structure
  174.  *
  175.  * Get a colormap @cmap for a screen of device @info.
  176.  *
  177.  * Returns negative errno on error, or zero on success.
  178.  *
  179.  */
  180. int fb_get_cmap(struct fb_cmap *cmap, int kspc,
  181.           int (*getcolreg)(u_int, u_int *, u_int *, u_int *, u_int *,
  182.  struct fb_info *),
  183. struct fb_info *info)
  184. {
  185.     int i, start;
  186.     u16 *red, *green, *blue, *transp;
  187.     u_int hred, hgreen, hblue, htransp;
  188.     red = cmap->red;
  189.     green = cmap->green;
  190.     blue = cmap->blue;
  191.     transp = cmap->transp;
  192.     start = cmap->start;
  193.     if (start < 0)
  194. return -EINVAL;
  195.     for (i = 0; i < cmap->len; i++) {
  196. if (getcolreg(start++, &hred, &hgreen, &hblue, &htransp, info))
  197.     return 0;
  198. if (kspc) {
  199.     *red = hred;
  200.     *green = hgreen;
  201.     *blue = hblue;
  202.     if (transp)
  203. *transp = htransp;
  204. } else {
  205.     put_user(hred, red);
  206.     put_user(hgreen, green);
  207.     put_user(hblue, blue);
  208.     if (transp)
  209. put_user(htransp, transp);
  210. }
  211. red++;
  212. green++;
  213. blue++;
  214. if (transp)
  215.     transp++;
  216.     }
  217.     return 0;
  218. }
  219. /**
  220.  * fb_set_cmap - set the colormap
  221.  * @cmap: frame buffer colormap structure
  222.  * @kspc: boolean, 0 copy local, 1 get_user() function
  223.  * @info: frame buffer info structure
  224.  *
  225.  * Sets the colormap @cmap for a screen of device @info.
  226.  *
  227.  * Returns negative errno on error, or zero on success.
  228.  *
  229.  */
  230. int fb_set_cmap(struct fb_cmap *cmap, int kspc,
  231.           int (*setcolreg)(u_int, u_int, u_int, u_int, u_int,
  232.  struct fb_info *),
  233. struct fb_info *info)
  234. {
  235.     int i, start;
  236.     u16 *red, *green, *blue, *transp;
  237.     u_int hred, hgreen, hblue, htransp;
  238.     red = cmap->red;
  239.     green = cmap->green;
  240.     blue = cmap->blue;
  241.     transp = cmap->transp;
  242.     start = cmap->start;
  243.     if (start < 0)
  244. return -EINVAL;
  245.     for (i = 0; i < cmap->len; i++) {
  246. if (kspc) {
  247.     hred = *red;
  248.     hgreen = *green;
  249.     hblue = *blue;
  250.     htransp = transp ? *transp : 0;
  251. } else {
  252.     get_user(hred, red);
  253.     get_user(hgreen, green);
  254.     get_user(hblue, blue);
  255.     if (transp)
  256. get_user(htransp, transp);
  257.     else
  258. htransp = 0;
  259. }
  260. red++;
  261. green++;
  262. blue++;
  263. if (transp)
  264.     transp++;
  265. if (setcolreg(start++, hred, hgreen, hblue, htransp, info))
  266.     return 0;
  267.     }
  268.     return 0;
  269. }
  270. /**
  271.  * fb_default_cmap - get default colormap
  272.  * @len: size of palette for a depth
  273.  *
  274.  * Gets the default colormap for a specific screen depth.  @len
  275.  * is the size of the palette for a particular screen depth.
  276.  *
  277.  * Returns pointer to a frame buffer colormap structure.
  278.  *
  279.  */
  280. struct fb_cmap *fb_default_cmap(int len)
  281. {
  282.     if (len <= 2)
  283. return &default_2_colors;
  284.     if (len <= 4)
  285. return &default_4_colors;
  286.     if (len <= 8)
  287. return &default_8_colors;
  288.     return &default_16_colors;
  289. }
  290. /**
  291.  * fb_invert_cmaps - invert all defaults colormaps
  292.  *
  293.  * Invert all default colormaps.
  294.  *
  295.  */
  296. void fb_invert_cmaps(void)
  297. {
  298.     u_int i;
  299.     for (i = 0; i < 2; i++) {
  300. red2[i] = ~red2[i];
  301. green2[i] = ~green2[i];
  302. blue2[i] = ~blue2[i];
  303.     }
  304.     for (i = 0; i < 4; i++) {
  305. red4[i] = ~red4[i];
  306. green4[i] = ~green4[i];
  307. blue4[i] = ~blue4[i];
  308.     }
  309.     for (i = 0; i < 8; i++) {
  310. red8[i] = ~red8[i];
  311. green8[i] = ~green8[i];
  312. blue8[i] = ~blue8[i];
  313.     }
  314.     for (i = 0; i < 16; i++) {
  315. red16[i] = ~red16[i];
  316. green16[i] = ~green16[i];
  317. blue16[i] = ~blue16[i];
  318.     }
  319. }
  320.     /*
  321.      *  Visible symbols for modules
  322.      */
  323. EXPORT_SYMBOL(fb_alloc_cmap);
  324. EXPORT_SYMBOL(fb_copy_cmap);
  325. EXPORT_SYMBOL(fb_get_cmap);
  326. EXPORT_SYMBOL(fb_set_cmap);
  327. EXPORT_SYMBOL(fb_default_cmap);
  328. EXPORT_SYMBOL(fb_invert_cmaps);