1/* 2 * linux/drivers/video/console/fbcon_rotate.c -- Software Rotation 3 * 4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net> 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 for 8 * more details. 9 */ 10 11#include <linux/module.h> 12#include <linux/string.h> 13#include <linux/fb.h> 14#include <linux/vt_kern.h> 15#include <linux/console.h> 16#include <asm/types.h> 17#include "fbcon.h" 18#include "fbcon_rotate.h" 19 20static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) 21{ 22 struct fbcon_ops *ops = info->fbcon_par; 23 int len, err = 0; 24 int s_cellsize, d_cellsize, i; 25 const u8 *src; 26 u8 *dst; 27 28 if (vc->vc_font.data == ops->fontdata && 29 ops->p->con_rotate == ops->cur_rotate) 30 goto finished; 31 32 src = ops->fontdata = vc->vc_font.data; 33 ops->cur_rotate = ops->p->con_rotate; 34 len = (!ops->p->userfont) ? 256 : FNTCHARCNT(src); 35 s_cellsize = ((vc->vc_font.width + 7)/8) * 36 vc->vc_font.height; 37 d_cellsize = s_cellsize; 38 39 if (ops->rotate == FB_ROTATE_CW || 40 ops->rotate == FB_ROTATE_CCW) 41 d_cellsize = ((vc->vc_font.height + 7)/8) * 42 vc->vc_font.width; 43 44 if (info->fbops->fb_sync) 45 info->fbops->fb_sync(info); 46 47 if (ops->fd_size < d_cellsize * len) { 48 dst = kmalloc(d_cellsize * len, GFP_KERNEL); 49 50 if (dst == NULL) { 51 err = -ENOMEM; 52 goto finished; 53 } 54 55 ops->fd_size = d_cellsize * len; 56 kfree(ops->fontbuffer); 57 ops->fontbuffer = dst; 58 } 59 60 dst = ops->fontbuffer; 61 memset(dst, 0, ops->fd_size); 62 63 switch (ops->rotate) { 64 case FB_ROTATE_UD: 65 for (i = len; i--; ) { 66 rotate_ud(src, dst, vc->vc_font.width, 67 vc->vc_font.height); 68 69 src += s_cellsize; 70 dst += d_cellsize; 71 } 72 break; 73 case FB_ROTATE_CW: 74 for (i = len; i--; ) { 75 rotate_cw(src, dst, vc->vc_font.width, 76 vc->vc_font.height); 77 src += s_cellsize; 78 dst += d_cellsize; 79 } 80 break; 81 case FB_ROTATE_CCW: 82 for (i = len; i--; ) { 83 rotate_ccw(src, dst, vc->vc_font.width, 84 vc->vc_font.height); 85 src += s_cellsize; 86 dst += d_cellsize; 87 } 88 break; 89 } 90 91finished: 92 return err; 93} 94 95void fbcon_set_rotate(struct fbcon_ops *ops) 96{ 97 ops->rotate_font = fbcon_rotate_font; 98 99 switch(ops->rotate) { 100 case FB_ROTATE_CW: 101 fbcon_rotate_cw(ops); 102 break; 103 case FB_ROTATE_UD: 104 fbcon_rotate_ud(ops); 105 break; 106 case FB_ROTATE_CCW: 107 fbcon_rotate_ccw(ops); 108 break; 109 } 110} 111EXPORT_SYMBOL(fbcon_set_rotate); 112 113MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); 114MODULE_DESCRIPTION("Console Rotation Support"); 115MODULE_LICENSE("GPL"); 116