Rev 468 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
468 | giacomo | 1 | /* |
2 | * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices |
||
3 | * |
||
4 | * Created 14 Nov 2002 by James Simmons |
||
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 |
||
8 | * for more details. |
||
9 | */ |
||
10 | |||
11 | #include <linuxcomp.h> |
||
12 | |||
13 | #include <linux/module.h> |
||
14 | #include <linux/string.h> |
||
15 | #include <linux/tty.h> |
||
16 | #include <linux/fb.h> |
||
17 | #include <linux/slab.h> |
||
18 | |||
19 | #include <asm/uaccess.h> |
||
20 | #include <asm/io.h> |
||
21 | |||
22 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) |
||
23 | { |
||
24 | unsigned int scan_align = info->pixmap.scan_align - 1; |
||
25 | unsigned int buf_align = info->pixmap.buf_align - 1; |
||
26 | unsigned int i, size, dsize, s_pitch, d_pitch; |
||
27 | u8 *dst, src[64]; |
||
28 | |||
29 | if (cursor->set & FB_CUR_SETSIZE) { |
||
30 | info->cursor.image.height = cursor->image.height; |
||
31 | info->cursor.image.width = cursor->image.width; |
||
32 | } |
||
33 | |||
34 | if (cursor->set & FB_CUR_SETPOS) { |
||
35 | info->cursor.image.dx = cursor->image.dx; |
||
36 | info->cursor.image.dy = cursor->image.dy; |
||
37 | } |
||
38 | |||
39 | if (cursor->set & FB_CUR_SETHOT) |
||
40 | info->cursor.hot = cursor->hot; |
||
41 | |||
42 | if (cursor->set & FB_CUR_SETCMAP) { |
||
43 | if (cursor->image.depth == 1) { |
||
44 | info->cursor.image.bg_color = cursor->image.bg_color; |
||
45 | info->cursor.image.fg_color = cursor->image.fg_color; |
||
46 | } else { |
||
47 | if (cursor->image.cmap.len) |
||
48 | fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0); |
||
49 | } |
||
50 | info->cursor.image.depth = cursor->image.depth; |
||
51 | } |
||
52 | |||
53 | s_pitch = (info->cursor.image.width + 7) >> 3; |
||
54 | dsize = s_pitch * info->cursor.image.height; |
||
55 | d_pitch = (s_pitch + scan_align) & ~scan_align; |
||
56 | size = d_pitch * info->cursor.image.height + buf_align; |
||
57 | size &= ~buf_align; |
||
58 | dst = info->pixmap.addr + fb_get_buffer_offset(info, size); |
||
59 | |||
60 | if (info->cursor.enable) { |
||
61 | switch (info->cursor.rop) { |
||
62 | case ROP_XOR: |
||
63 | for (i = 0; i < dsize; i++) |
||
64 | src[i] = cursor->image.data[i] ^ info->cursor.mask[i]; |
||
65 | break; |
||
66 | case ROP_COPY: |
||
67 | default: |
||
68 | for (i = 0; i < dsize; i++) |
||
69 | src[i] = cursor->image.data[i] & info->cursor.mask[i]; |
||
70 | break; |
||
71 | } |
||
72 | } else |
||
73 | memcpy(src, cursor->image.data, dsize); |
||
74 | |||
75 | move_buf_aligned(info, dst, src, d_pitch, s_pitch, info->cursor.image.height); |
||
76 | info->cursor.image.data = dst; |
||
77 | |||
78 | info->fbops->fb_imageblit(info, &info->cursor.image); |
||
79 | atomic_dec(&info->pixmap.count); |
||
80 | smp_mb__after_atomic_dec(); |
||
81 | return 0; |
||
82 | } |
||
83 | |||
84 | EXPORT_SYMBOL(soft_cursor); |
||
85 | |||
86 | MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>"); |
||
87 | MODULE_DESCRIPTION("Generic software cursor"); |
||
88 | MODULE_LICENSE("GPL"); |