2005-04-17 02:20:36 +04:00
/*
2007-05-09 09:51:49 +04:00
* linux / drivers / video / console / softcursor . c
2006-12-08 13:40:48 +03:00
*
* Generic software cursor for frame buffer devices
2005-04-17 02:20:36 +04:00
*
2005-11-07 12:00:35 +03:00
* Created 14 Nov 2002 by James Simmons
2005-04-17 02:20:36 +04:00
*
2006-12-08 13:40:48 +03:00
* This file is subject to the terms and conditions of the GNU General
* Public License . See the file COPYING in the main directory of this
* archive for more details .
2005-04-17 02:20:36 +04:00
*/
# include <linux/module.h>
# include <linux/string.h>
# include <linux/fb.h>
# include <linux/slab.h>
# include <asm/io.h>
2006-01-10 07:54:04 +03:00
# include "fbcon.h"
2005-04-17 02:20:36 +04:00
int soft_cursor ( struct fb_info * info , struct fb_cursor * cursor )
{
2006-10-03 12:14:47 +04:00
struct fbcon_ops * ops = info - > fbcon_par ;
2005-04-17 02:20:36 +04:00
unsigned int scan_align = info - > pixmap . scan_align - 1 ;
unsigned int buf_align = info - > pixmap . buf_align - 1 ;
unsigned int i , size , dsize , s_pitch , d_pitch ;
struct fb_image * image ;
2006-12-08 13:40:48 +03:00
u8 * src , * dst ;
2005-04-17 02:20:36 +04:00
if ( info - > state ! = FBINFO_STATE_RUNNING )
return 0 ;
s_pitch = ( cursor - > image . width + 7 ) > > 3 ;
dsize = s_pitch * cursor - > image . height ;
2006-10-03 12:14:47 +04:00
if ( dsize + sizeof ( struct fb_image ) ! = ops - > cursor_size ) {
if ( ops - > cursor_src ! = NULL )
kfree ( ops - > cursor_src ) ;
ops - > cursor_size = dsize + sizeof ( struct fb_image ) ;
2005-04-17 02:20:36 +04:00
2006-10-03 12:14:47 +04:00
ops - > cursor_src = kmalloc ( ops - > cursor_size , GFP_ATOMIC ) ;
if ( ! ops - > cursor_src ) {
ops - > cursor_size = 0 ;
return - ENOMEM ;
}
}
2006-12-08 13:40:48 +03:00
src = ops - > cursor_src + sizeof ( struct fb_image ) ;
image = ( struct fb_image * ) ops - > cursor_src ;
2005-04-17 02:20:36 +04:00
* image = cursor - > image ;
d_pitch = ( s_pitch + scan_align ) & ~ scan_align ;
size = d_pitch * image - > height + buf_align ;
size & = ~ buf_align ;
dst = fb_get_buffer_offset ( info , & info - > pixmap , size ) ;
if ( cursor - > enable ) {
switch ( cursor - > rop ) {
case ROP_XOR :
for ( i = 0 ; i < dsize ; i + + )
2006-12-08 13:40:48 +03:00
src [ i ] = image - > data [ i ] ^ cursor - > mask [ i ] ;
2005-04-17 02:20:36 +04:00
break ;
case ROP_COPY :
default :
for ( i = 0 ; i < dsize ; i + + )
2006-12-08 13:40:48 +03:00
src [ i ] = image - > data [ i ] & cursor - > mask [ i ] ;
2005-04-17 02:20:36 +04:00
break ;
}
2005-11-07 12:00:35 +03:00
} else
2006-12-08 13:40:48 +03:00
memcpy ( src , image - > data , dsize ) ;
2005-11-07 12:00:35 +03:00
2006-12-08 13:40:48 +03:00
fb_pad_aligned_buffer ( dst , d_pitch , src , s_pitch , image - > height ) ;
2005-04-17 02:20:36 +04:00
image - > data = dst ;
info - > fbops - > fb_imageblit ( info , image ) ;
return 0 ;
}
EXPORT_SYMBOL ( soft_cursor ) ;
2005-11-07 12:00:35 +03:00
2005-04-17 02:20:36 +04:00
MODULE_AUTHOR ( " James Simmons <jsimmons@users.sf.net> " ) ;
MODULE_DESCRIPTION ( " Generic software cursor " ) ;
MODULE_LICENSE ( " GPL " ) ;