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