Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  linux/drivers/video/console/fbcon_rotate.c -- Software Rotation
0003  *
0004  *      Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
0005  *
0006  *  This file is subject to the terms and conditions of the GNU General Public
0007  *  License.  See the file COPYING in the main directory of this archive for
0008  *  more details.
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 #include <linux/string.h>
0014 #include <linux/fb.h>
0015 #include <linux/vt_kern.h>
0016 #include <linux/console.h>
0017 #include <asm/types.h>
0018 #include "fbcon.h"
0019 #include "fbcon_rotate.h"
0020 
0021 static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
0022 {
0023     struct fbcon_ops *ops = info->fbcon_par;
0024     int len, err = 0;
0025     int s_cellsize, d_cellsize, i;
0026     const u8 *src;
0027     u8 *dst;
0028 
0029     if (vc->vc_font.data == ops->fontdata &&
0030         ops->p->con_rotate == ops->cur_rotate)
0031         goto finished;
0032 
0033     src = ops->fontdata = vc->vc_font.data;
0034     ops->cur_rotate = ops->p->con_rotate;
0035     len = vc->vc_font.charcount;
0036     s_cellsize = ((vc->vc_font.width + 7)/8) *
0037         vc->vc_font.height;
0038     d_cellsize = s_cellsize;
0039 
0040     if (ops->rotate == FB_ROTATE_CW ||
0041         ops->rotate == FB_ROTATE_CCW)
0042         d_cellsize = ((vc->vc_font.height + 7)/8) *
0043             vc->vc_font.width;
0044 
0045     if (info->fbops->fb_sync)
0046         info->fbops->fb_sync(info);
0047 
0048     if (ops->fd_size < d_cellsize * len) {
0049         dst = kmalloc_array(len, d_cellsize, GFP_KERNEL);
0050 
0051         if (dst == NULL) {
0052             err = -ENOMEM;
0053             goto finished;
0054         }
0055 
0056         ops->fd_size = d_cellsize * len;
0057         kfree(ops->fontbuffer);
0058         ops->fontbuffer = dst;
0059     }
0060 
0061     dst = ops->fontbuffer;
0062     memset(dst, 0, ops->fd_size);
0063 
0064     switch (ops->rotate) {
0065     case FB_ROTATE_UD:
0066         for (i = len; i--; ) {
0067             rotate_ud(src, dst, vc->vc_font.width,
0068                   vc->vc_font.height);
0069 
0070             src += s_cellsize;
0071             dst += d_cellsize;
0072         }
0073         break;
0074     case FB_ROTATE_CW:
0075         for (i = len; i--; ) {
0076             rotate_cw(src, dst, vc->vc_font.width,
0077                   vc->vc_font.height);
0078             src += s_cellsize;
0079             dst += d_cellsize;
0080         }
0081         break;
0082     case FB_ROTATE_CCW:
0083         for (i = len; i--; ) {
0084             rotate_ccw(src, dst, vc->vc_font.width,
0085                    vc->vc_font.height);
0086             src += s_cellsize;
0087             dst += d_cellsize;
0088         }
0089         break;
0090     }
0091 
0092 finished:
0093     return err;
0094 }
0095 
0096 void fbcon_set_rotate(struct fbcon_ops *ops)
0097 {
0098     ops->rotate_font = fbcon_rotate_font;
0099 
0100     switch(ops->rotate) {
0101     case FB_ROTATE_CW:
0102         fbcon_rotate_cw(ops);
0103         break;
0104     case FB_ROTATE_UD:
0105         fbcon_rotate_ud(ops);
0106         break;
0107     case FB_ROTATE_CCW:
0108         fbcon_rotate_ccw(ops);
0109         break;
0110     }
0111 }