Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * linux/drivers/video/console/softcursor.c
0003  *
0004  * Generic software cursor for frame buffer devices
0005  *
0006  *  Created 14 Nov 2002 by James Simmons
0007  *
0008  * This file is subject to the terms and conditions of the GNU General
0009  * Public License.  See the file COPYING in the main directory of this
0010  * archive for more details.
0011  */
0012 
0013 #include <linux/module.h>
0014 #include <linux/string.h>
0015 #include <linux/fb.h>
0016 #include <linux/slab.h>
0017 
0018 #include <asm/io.h>
0019 
0020 #include "fbcon.h"
0021 
0022 int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
0023 {
0024     struct fbcon_ops *ops = info->fbcon_par;
0025     unsigned int scan_align = info->pixmap.scan_align - 1;
0026     unsigned int buf_align = info->pixmap.buf_align - 1;
0027     unsigned int i, size, dsize, s_pitch, d_pitch;
0028     struct fb_image *image;
0029     u8 *src, *dst;
0030 
0031     if (info->state != FBINFO_STATE_RUNNING)
0032         return 0;
0033 
0034     s_pitch = (cursor->image.width + 7) >> 3;
0035     dsize = s_pitch * cursor->image.height;
0036 
0037     if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
0038         kfree(ops->cursor_src);
0039         ops->cursor_size = dsize + sizeof(struct fb_image);
0040 
0041         ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
0042         if (!ops->cursor_src) {
0043             ops->cursor_size = 0;
0044             return -ENOMEM;
0045         }
0046     }
0047 
0048     src = ops->cursor_src + sizeof(struct fb_image);
0049     image = (struct fb_image *)ops->cursor_src;
0050     *image = cursor->image;
0051     d_pitch = (s_pitch + scan_align) & ~scan_align;
0052 
0053     size = d_pitch * image->height + buf_align;
0054     size &= ~buf_align;
0055     dst = fb_get_buffer_offset(info, &info->pixmap, size);
0056 
0057     if (cursor->enable) {
0058         switch (cursor->rop) {
0059         case ROP_XOR:
0060             for (i = 0; i < dsize; i++)
0061                 src[i] = image->data[i] ^ cursor->mask[i];
0062             break;
0063         case ROP_COPY:
0064         default:
0065             for (i = 0; i < dsize; i++)
0066                 src[i] = image->data[i] & cursor->mask[i];
0067             break;
0068         }
0069     } else
0070         memcpy(src, image->data, dsize);
0071 
0072     fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
0073     image->data = dst;
0074     info->fbops->fb_imageblit(info, image);
0075     return 0;
0076 }