91 int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
92 {
93 int size = len*sizeof(u16);
94
95 if (cmap->len != len) {
96 fb_dealloc_cmap(cmap);
97 if (!len)
98 return 0;
99 if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
100 goto fail;
101 if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
102 goto fail;
103 if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
104 goto fail;
105 if (transp) {
106 if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
107 goto fail;
108 } else
109 cmap->transp = NULL;
110 }
111 cmap->start = 0;
112 cmap->len = len;
113 fb_copy_cmap(fb_default_cmap(len), cmap);
114 return 0;
115
116 fail:
117 fb_dealloc_cmap(cmap);
118 return -ENOMEM;
119 }
分配colormap, len是颜色分量的number
113使用缺省的colormap初始化颜色分量
149 int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
150 {
151 int tooff = 0, fromoff = 0;
152 int size;
153
154 if (to->start > from->start)
155 fromoff = to->start - from->start;
156 else
157 tooff = from->start - to->start;
158 size = to->len - tooff;
159 if (size > (int) (from->len - fromoff))
160 size = from->len - fromoff;
161 if (size <= 0)
162 return -EINVAL;
163 size *= sizeof(u16);
164
165 memcpy(to->red+tooff, from->red+fromoff, size);
166 memcpy(to->green+tooff, from->green+fromoff, size);
167 memcpy(to->blue+tooff, from->blue+fromoff, size);
168 if (from->transp && to->transp)
169 memcpy(to->transp+tooff, from->transp+fromoff, size);
170 return 0;
171 }
copy colormap @from 到@to
249 int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
250 {
251 int rc, size = cmap->len * sizeof(u16);
252 struct fb_cmap umap;
253
254 memset(&umap, 0, sizeof(struct fb_cmap));
255 rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
256 if (rc)
257 return rc;
258 if (copy_from_user(umap.red, cmap->red, size) ||
259 copy_from_user(umap.green, cmap->green, size) ||
260 copy_from_user(umap.blue, cmap->blue, size) ||
261 (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
262 rc = -EFAULT;
263 goto out;
264 }
265 umap.start = cmap->start;
266 if (!lock_fb_info(info)) {
267 rc = -ENODEV;
268 goto out;
269 }
270 if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
271 !info->fbops->fb_setcmap)) {
272 rc = -EINVAL;
273 goto out1;
274 }
275 rc = fb_set_cmap(&umap, info);
276 out1:
277 unlock_fb_info(info);
278 out:
279 fb_dealloc_cmap(&umap);
280 return rc;
281 }
先把fb_cmap_user类型的cmap内容复制到fb_cmap中,然后再调用fb_set_cmap
294 const struct fb_cmap *fb_default_cmap(int len)
295 {
296 if (len <= 2)
297 return &default_2_colors;
298 if (len <= 4)
299 return &default_4_colors;
300 if (len <= 8)
301 return &default_8_colors;
302 return &default_16_colors;
303 }
根据len,返回缺省的cmap
313 void fb_invert_cmaps(void)
314 {
315 u_int i;
316
317 for (i = 0; i < ARRAY_SIZE(red2); i++) {
318 red2[i] = ~red2[i];
319 green2[i] = ~green2[i];
320 blue2[i] = ~blue2[i];
321 }
322 for (i = 0; i < ARRAY_SIZE(red4); i++) {
323 red4[i] = ~red4[i];
324 green4[i] = ~green4[i];
325 blue4[i] = ~blue4[i];
326 }
327 for (i = 0; i < ARRAY_SIZE(red8); i++) {
328 red8[i] = ~red8[i];
329 green8[i] = ~green8[i];
330 blue8[i] = ~blue8[i];
331 }
332 for (i = 0; i < ARRAY_SIZE(red16); i++) {
333 red16[i] = ~red16[i];
334 green16[i] = ~green16[i];
335 blue16[i] = ~blue16[i];
336 }
337 }
invert cmap的颜色分量