Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
58862699 | 2 | * linux/drivers/video/console/softcursor.c |
024cd7e0 FBH |
3 | * |
4 | * Generic software cursor for frame buffer devices | |
1da177e4 | 5 | * |
c465e05a | 6 | * Created 14 Nov 2002 by James Simmons |
1da177e4 | 7 | * |
024cd7e0 FBH |
8 | * This file is subject to the terms and conditions of the GNU General |
9 | * Public License. See the file COPYING in the main directory of this | |
10 | * archive for more details. | |
1da177e4 LT |
11 | */ |
12 | ||
13 | #include <linux/module.h> | |
14 | #include <linux/string.h> | |
1da177e4 LT |
15 | #include <linux/fb.h> |
16 | #include <linux/slab.h> | |
17 | ||
1da177e4 LT |
18 | #include <asm/io.h> |
19 | ||
a0aa7d06 AB |
20 | #include "fbcon.h" |
21 | ||
1da177e4 LT |
22 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) |
23 | { | |
e299dd4d | 24 | struct fbcon_ops *ops = info->fbcon_par; |
1da177e4 LT |
25 | unsigned int scan_align = info->pixmap.scan_align - 1; |
26 | unsigned int buf_align = info->pixmap.buf_align - 1; | |
27 | unsigned int i, size, dsize, s_pitch, d_pitch; | |
28 | struct fb_image *image; | |
024cd7e0 | 29 | u8 *src, *dst; |
1da177e4 LT |
30 | |
31 | if (info->state != FBINFO_STATE_RUNNING) | |
32 | return 0; | |
33 | ||
34 | s_pitch = (cursor->image.width + 7) >> 3; | |
35 | dsize = s_pitch * cursor->image.height; | |
36 | ||
e299dd4d | 37 | if (dsize + sizeof(struct fb_image) != ops->cursor_size) { |
a240af2e | 38 | kfree(ops->cursor_src); |
e299dd4d | 39 | ops->cursor_size = dsize + sizeof(struct fb_image); |
1da177e4 | 40 | |
e299dd4d DJ |
41 | ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); |
42 | if (!ops->cursor_src) { | |
43 | ops->cursor_size = 0; | |
44 | return -ENOMEM; | |
45 | } | |
46 | } | |
47 | ||
024cd7e0 FBH |
48 | src = ops->cursor_src + sizeof(struct fb_image); |
49 | image = (struct fb_image *)ops->cursor_src; | |
1da177e4 LT |
50 | *image = cursor->image; |
51 | d_pitch = (s_pitch + scan_align) & ~scan_align; | |
52 | ||
53 | size = d_pitch * image->height + buf_align; | |
54 | size &= ~buf_align; | |
55 | dst = fb_get_buffer_offset(info, &info->pixmap, size); | |
56 | ||
57 | if (cursor->enable) { | |
58 | switch (cursor->rop) { | |
59 | case ROP_XOR: | |
60 | for (i = 0; i < dsize; i++) | |
024cd7e0 | 61 | src[i] = image->data[i] ^ cursor->mask[i]; |
1da177e4 LT |
62 | break; |
63 | case ROP_COPY: | |
64 | default: | |
65 | for (i = 0; i < dsize; i++) | |
024cd7e0 | 66 | src[i] = image->data[i] & cursor->mask[i]; |
1da177e4 LT |
67 | break; |
68 | } | |
c465e05a | 69 | } else |
024cd7e0 | 70 | memcpy(src, image->data, dsize); |
c465e05a | 71 | |
024cd7e0 | 72 | fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); |
1da177e4 LT |
73 | image->data = dst; |
74 | info->fbops->fb_imageblit(info, image); | |
1da177e4 LT |
75 | return 0; |
76 | } | |
77 | ||
78 | EXPORT_SYMBOL(soft_cursor); | |
c465e05a | 79 | |
1da177e4 LT |
80 | MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>"); |
81 | MODULE_DESCRIPTION("Generic software cursor"); | |
82 | MODULE_LICENSE("GPL"); |