11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/drivers/video/console/bitblit.c -- BitBlitting Operation 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Originally from the 'accel_*' routines in drivers/video/console/fbcon.c 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004 Antonino Daplas <adaplas @pol.net> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License. See the file COPYING in the main directory of this archive for 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * more details. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 145a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fb.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/vt_kern.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/console.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/types.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "fbcon.h" 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Accelerated handlers. 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2526c5be3c750df6f8a9193d478905627ec75f7f41Denys Vlasenkostatic void update_attr(u8 *dst, u8 *src, int attribute, 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct vc_data *vc) 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, offset = (vc->vc_font.height < 10) ? 1 : 2; 299a4a83d2ed83da0c4b45289ca72f10205aa96589Jiri Slaby int width = DIV_ROUND_UP(vc->vc_font.width, 8); 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cellsize = vc->vc_font.height * width; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 c; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offset = cellsize - (offset * width); 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < cellsize; i++) { 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = src[i]; 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i >= offset) 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = 0xff; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (attribute & FBCON_ATTRIBUTE_BOLD) 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c |= c >> 1; 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (attribute & FBCON_ATTRIBUTE_REVERSE) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = ~c; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst[i] = c; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy, 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sx, int dy, int dx, int height, int width) 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_copyarea area; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds area.sx = sx * vc->vc_font.width; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds area.sy = sy * vc->vc_font.height; 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds area.dx = dx * vc->vc_font.width; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds area.dy = dy * vc->vc_font.height; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds area.height = height * vc->vc_font.height; 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds area.width = width * vc->vc_font.width; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info->fbops->fb_copyarea(info, &area); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bit_clear(struct vc_data *vc, struct fb_info *info, int sy, 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sx, int height, int width) 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_fillrect region; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6791c4313206e4409871e2ddd13c29508afe1c8834Thomas Pfaff region.color = attr_bgcol_ec(bgshift, vc, info); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.dx = sx * vc->vc_font.width; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.dy = sy * vc->vc_font.height; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.width = width * vc->vc_font.width; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.height = height * vc->vc_font.height; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.rop = ROP_COPY; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info->fbops->fb_fillrect(info, ®ion); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 77829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplasstatic inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info, 78829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas const u16 *s, u32 attr, u32 cnt, 79829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 d_pitch, u32 s_pitch, u32 cellsize, 80829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas struct fb_image *image, u8 *buf, u8 *dst) 81829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas{ 82829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 83829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 idx = vc->vc_font.width >> 3; 84829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u8 *src; 85829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 86829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas while (cnt--) { 87829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas src = vc->vc_font.data + (scr_readw(s++)& 88829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas charmask)*cellsize; 89829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 90829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas if (attr) { 91829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas update_attr(buf, src, attr, vc); 92829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas src = buf; 93829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas } 94829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 95829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas if (likely(idx == 1)) 96829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas __fb_pad_aligned_buffer(dst, d_pitch, src, idx, 97829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas image->height); 98829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas else 99829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas fb_pad_aligned_buffer(dst, d_pitch, src, idx, 100829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas image->height); 101829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 102829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas dst += s_pitch; 103829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas } 104829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 105829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas info->fbops->fb_imageblit(info, image); 106829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas} 107829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 108829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplasstatic inline void bit_putcs_unaligned(struct vc_data *vc, 109829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas struct fb_info *info, const u16 *s, 110829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 attr, u32 cnt, u32 d_pitch, 111829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 s_pitch, u32 cellsize, 112829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas struct fb_image *image, u8 *buf, 113829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u8 *dst) 114829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas{ 115829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 116829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 shift_low = 0, mod = vc->vc_font.width % 8; 117829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 shift_high = 8; 118829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 idx = vc->vc_font.width >> 3; 119829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u8 *src; 120829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 121829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas while (cnt--) { 122829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas src = vc->vc_font.data + (scr_readw(s++)& 123829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas charmask)*cellsize; 124829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 125829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas if (attr) { 126829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas update_attr(buf, src, attr, vc); 127829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas src = buf; 128829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas } 129829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 130829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas fb_pad_unaligned_buffer(dst, d_pitch, src, idx, 131829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas image->height, shift_high, 132829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas shift_low, mod); 133829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas shift_low += mod; 134829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas dst += (shift_low >= 8) ? s_pitch : s_pitch - 1; 135829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas shift_low &= 7; 136829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas shift_high = 8 - shift_low; 137829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas } 138829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 139829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas info->fbops->fb_imageblit(info, image); 140829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 141829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas} 142829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bit_putcs(struct vc_data *vc, struct fb_info *info, 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned short *s, int count, int yy, int xx, 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fg, int bg) 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_image image; 1489a4a83d2ed83da0c4b45289ca72f10205aa96589Jiri Slaby u32 width = DIV_ROUND_UP(vc->vc_font.width, 8); 149829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 cellsize = width * vc->vc_font.height; 150829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 maxcnt = info->pixmap.size/cellsize; 151829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 scan_align = info->pixmap.scan_align - 1; 152829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 buf_align = info->pixmap.buf_align - 1; 153829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 mod = vc->vc_font.width % 8, cnt, pitch, size; 154829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u32 attribute = get_attribute(info, scr_readw(s)); 155829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas u8 *dst, *buf = NULL; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.fg_color = fg; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.bg_color = bg; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.dx = xx * vc->vc_font.width; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.dy = yy * vc->vc_font.height; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.height = vc->vc_font.height; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.depth = 1; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 164829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas if (attribute) { 165829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas buf = kmalloc(cellsize, GFP_KERNEL); 166829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas if (!buf) 167829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas return; 168829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas } 169829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (count) { 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count > maxcnt) 172829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas cnt = maxcnt; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 174829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas cnt = count; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.width = vc->vc_font.width * cnt; 1779a4a83d2ed83da0c4b45289ca72f10205aa96589Jiri Slaby pitch = DIV_ROUND_UP(image.width, 8) + scan_align; 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pitch &= ~scan_align; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = pitch * image.height + buf_align; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size &= ~buf_align; 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = fb_get_buffer_offset(info, &info->pixmap, size); 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.data = dst; 183829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 184829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas if (!mod) 185829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas bit_putcs_aligned(vc, info, s, attribute, cnt, pitch, 186829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas width, cellsize, &image, buf, dst); 187829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas else 188829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas bit_putcs_unaligned(vc, info, s, attribute, cnt, 189829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas pitch, width, cellsize, &image, 190829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas buf, dst); 191829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds image.dx += cnt * vc->vc_font.width; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= cnt; 194829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas s += cnt; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* buf is always NULL except when in monochrome mode, so in this case 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it's a gain to check buf against NULL even though kfree() handles 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL pointers just fine */ 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (unlikely(buf)) 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buf); 202829e79b680210c4f4de435af6e1f90451922fc7dAntonino A. Daplas 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bit_clear_margins(struct vc_data *vc, struct fb_info *info, 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int bottom_only) 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cw = vc->vc_font.width; 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int ch = vc->vc_font.height; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int rw = info->var.xres - (vc->vc_cols*cw); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int bh = info->var.yres - (vc->vc_rows*ch); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int rs = info->var.xres - rw; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int bs = info->var.yres - bh; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_fillrect region; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21791c4313206e4409871e2ddd13c29508afe1c8834Thomas Pfaff region.color = attr_bgcol_ec(bgshift, vc, info); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.rop = ROP_COPY; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rw && !bottom_only) { 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.dx = info->var.xoffset + rs; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.dy = 0; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.width = rw; 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.height = info->var.yres_virtual; 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info->fbops->fb_fillrect(info, ®ion); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bh) { 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.dx = info->var.xoffset; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.dy = info->var.yoffset + bs; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.width = rs; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region.height = bh; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info->fbops->fb_fillrect(info, ®ion); 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 237b73deed32d08740bdbf5f4aab43d988e4d135d95Antonino A. Daplasstatic void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, 238b73deed32d08740bdbf5f4aab43d988e4d135d95Antonino A. Daplas int softback_lines, int fg, int bg) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_cursor cursor; 241b73deed32d08740bdbf5f4aab43d988e4d135d95Antonino A. Daplas struct fbcon_ops *ops = info->fbcon_par; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 2439a4a83d2ed83da0c4b45289ca72f10205aa96589Jiri Slaby int w = DIV_ROUND_UP(vc->vc_font.width, 8), c; 244b73deed32d08740bdbf5f4aab43d988e4d135d95Antonino A. Daplas int y = real_y(ops->p, vc->vc_y); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int attribute, use_sw = (vc->vc_cursor_type & 0x10); 246c465e05a03209651078b95686158648fd7ed84c5Antonino A. Daplas int err = 1; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *src; 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.set = 0; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (softback_lines) { 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (y + softback_lines >= vc->vc_rows) { 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = CM_ERASE; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_flash = 0; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y += softback_lines; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = scr_readw((u16 *) vc->vc_pos); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attribute = get_attribute(info, c); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height)); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ops->cursor_state.image.data != src || 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_reset) { 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.data = src; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.set |= FB_CUR_SETIMAGE; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (attribute) { 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *dst; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dst) 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ops->cursor_data); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_data = dst; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds update_attr(dst, src, attribute, vc); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src = dst; 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ops->cursor_state.image.fg_color != fg || 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.bg_color != bg || 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_reset) { 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.fg_color = fg; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.bg_color = bg; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.set |= FB_CUR_SETCMAP; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->vc_x)) || 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (ops->cursor_state.image.dy != (vc->vc_font.height * y)) || 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_reset) { 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.dx = vc->vc_font.width * vc->vc_x; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.dy = vc->vc_font.height * y; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.set |= FB_CUR_SETPOS; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ops->cursor_state.image.height != vc->vc_font.height || 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.width != vc->vc_font.width || 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_reset) { 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.height = vc->vc_font.height; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.image.width = vc->vc_font.width; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.set |= FB_CUR_SETSIZE; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ops->cursor_state.hot.x || ops->cursor_state.hot.y || 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_reset) { 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.hot.x = cursor.hot.y = 0; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.set |= FB_CUR_SETHOT; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cursor.set & FB_CUR_SETSIZE || 313b73deed32d08740bdbf5f4aab43d988e4d135d95Antonino A. Daplas vc->vc_cursor_type != ops->p->cursor_shape || 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.mask == NULL || 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_reset) { 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cur_height, size, i = 0; 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 msk = 0xff; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mask) 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ops->cursor_state.mask); 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.mask = mask; 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 326b73deed32d08740bdbf5f4aab43d988e4d135d95Antonino A. Daplas ops->p->cursor_shape = vc->vc_cursor_type; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.set |= FB_CUR_SETSHAPE; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 329b73deed32d08740bdbf5f4aab43d988e4d135d95Antonino A. Daplas switch (ops->p->cursor_shape & CUR_HWMASK) { 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_NONE: 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cur_height = 0; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_UNDERLINE: 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cur_height = (vc->vc_font.height < 10) ? 1 : 2; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_LOWER_THIRD: 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cur_height = vc->vc_font.height/3; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_LOWER_HALF: 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cur_height = vc->vc_font.height >> 1; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_TWO_THIRDS: 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cur_height = (vc->vc_font.height << 1)/3; 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CUR_BLOCK: 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cur_height = vc->vc_font.height; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = (vc->vc_font.height - cur_height) * w; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (size--) 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask[i++] = ~msk; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = cur_height * w; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (size--) 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask[i++] = msk; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (mode) { 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CM_ERASE: 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.enable = 0; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CM_DRAW: 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CM_MOVE: 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_state.enable = (use_sw) ? 0 : 1; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.data = src; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.fg_color = ops->cursor_state.image.fg_color; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.bg_color = ops->cursor_state.image.bg_color; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.dx = ops->cursor_state.image.dx; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.dy = ops->cursor_state.image.dy; 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.height = ops->cursor_state.image.height; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.width = ops->cursor_state.image.width; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.hot.x = ops->cursor_state.hot.x; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.hot.y = ops->cursor_state.hot.y; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.mask = ops->cursor_state.mask; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.enable = ops->cursor_state.enable; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.image.depth = 1; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cursor.rop = ROP_XOR; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 383c465e05a03209651078b95686158648fd7ed84c5Antonino A. Daplas if (info->fbops->fb_cursor) 384c465e05a03209651078b95686158648fd7ed84c5Antonino A. Daplas err = info->fbops->fb_cursor(info, &cursor); 385c465e05a03209651078b95686158648fd7ed84c5Antonino A. Daplas 386c465e05a03209651078b95686158648fd7ed84c5Antonino A. Daplas if (err) 387c465e05a03209651078b95686158648fd7ed84c5Antonino A. Daplas soft_cursor(info, &cursor); 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor_reset = 0; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 392e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplasstatic int bit_update_start(struct fb_info *info) 393e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas{ 394e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas struct fbcon_ops *ops = info->fbcon_par; 395e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas int err; 396e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas 397e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas err = fb_pan_display(info, &ops->var); 398e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas ops->var.xoffset = info->var.xoffset; 399e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas ops->var.yoffset = info->var.yoffset; 400e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas ops->var.vmode = info->var.vmode; 401e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas return err; 402e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas} 403e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid fbcon_set_bitops(struct fbcon_ops *ops) 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->bmove = bit_bmove; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->clear = bit_clear; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->putcs = bit_putcs; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->clear_margins = bit_clear_margins; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ops->cursor = bit_cursor; 411e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas ops->update_start = bit_update_start; 412e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas ops->rotate_font = NULL; 413e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas 414e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas if (ops->rotate) 415e4fc27618b75234b721c4a13d0e0d9d07e75e641Antonino A. Daplas fbcon_set_rotate(ops); 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(fbcon_set_bitops); 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Bit Blitting Operation"); 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 424