~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/video/fbcmap.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.