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