1 /* 2 * linux/drivers/video/console/tileblit.c -- Tile Blitting Operation 3 * 4 * Copyright (C) 2004 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 19 static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy, 20 int sx, int dy, int dx, int height, int width) 21 { 22 struct fb_tilearea area; 23 24 area.sx = sx; 25 area.sy = sy; 26 area.dx = dx; 27 area.dy = dy; 28 area.height = height; 29 area.width = width; 30 31 info->tileops->fb_tilecopy(info, &area); 32 } 33 34 static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy, 35 int sx, int height, int width, int fg, int bg) 36 { 37 struct fb_tilerect rect; 38 39 rect.index = vc->vc_video_erase_char & 40 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); 41 rect.fg = fg; 42 rect.bg = bg; 43 rect.sx = sx; 44 rect.sy = sy; 45 rect.width = width; 46 rect.height = height; 47 rect.rop = ROP_COPY; 48 49 info->tileops->fb_tilefill(info, &rect); 50 } 51 52 static void tile_putcs(struct vc_data *vc, struct fb_info *info, 53 const unsigned short *s, int count, int yy, int xx, 54 int fg, int bg) 55 { 56 struct fb_tileblit blit; 57 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 58 int size = sizeof(u32) * count, i; 59 60 blit.sx = xx; 61 blit.sy = yy; 62 blit.width = count; 63 blit.height = 1; 64 blit.fg = fg; 65 blit.bg = bg; 66 blit.length = count; 67 blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size); 68 for (i = 0; i < count; i++) 69 blit.indices[i] = (u32)(scr_readw(s++) & charmask); 70 71 info->tileops->fb_tileblit(info, &blit); 72 } 73 74 static void tile_clear_margins(struct vc_data *vc, struct fb_info *info, 75 int color, int bottom_only) 76 { 77 unsigned int cw = vc->vc_font.width; 78 unsigned int ch = vc->vc_font.height; 79 unsigned int rw = info->var.xres - (vc->vc_cols*cw); 80 unsigned int bh = info->var.yres - (vc->vc_rows*ch); 81 unsigned int rs = info->var.xres - rw; 82 unsigned int bs = info->var.yres - bh; 83 unsigned int vwt = info->var.xres_virtual / cw; 84 unsigned int vht = info->var.yres_virtual / ch; 85 struct fb_tilerect rect; 86 87 rect.index = vc->vc_video_erase_char & 88 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); 89 rect.fg = color; 90 rect.bg = color; 91 92 if ((int) rw > 0 && !bottom_only) { 93 rect.sx = (info->var.xoffset + rs + cw - 1) / cw; 94 rect.sy = 0; 95 rect.width = (rw + cw - 1) / cw; 96 rect.height = vht; 97 if (rect.width + rect.sx > vwt) 98 rect.width = vwt - rect.sx; 99 if (rect.sx < vwt) 100 info->tileops->fb_tilefill(info, &rect); 101 } 102 103 if ((int) bh > 0) { 104 rect.sx = info->var.xoffset / cw; 105 rect.sy = (info->var.yoffset + bs) / ch; 106 rect.width = rs / cw; 107 rect.height = (bh + ch - 1) / ch; 108 if (rect.height + rect.sy > vht) 109 rect.height = vht - rect.sy; 110 if (rect.sy < vht) 111 info->tileops->fb_tilefill(info, &rect); 112 } 113 } 114 115 static void tile_cursor(struct vc_data *vc, struct fb_info *info, bool enable, 116 int fg, int bg) 117 { 118 struct fb_tilecursor cursor; 119 int use_sw = vc->vc_cursor_type & CUR_SW; 120 121 cursor.sx = vc->state.x; 122 cursor.sy = vc->state.y; 123 cursor.mode = enable && !use_sw; 124 cursor.fg = fg; 125 cursor.bg = bg; 126 127 switch (vc->vc_cursor_type & 0x0f) { 128 case CUR_NONE: 129 cursor.shape = FB_TILE_CURSOR_NONE; 130 break; 131 case CUR_UNDERLINE: 132 cursor.shape = FB_TILE_CURSOR_UNDERLINE; 133 break; 134 case CUR_LOWER_THIRD: 135 cursor.shape = FB_TILE_CURSOR_LOWER_THIRD; 136 break; 137 case CUR_LOWER_HALF: 138 cursor.shape = FB_TILE_CURSOR_LOWER_HALF; 139 break; 140 case CUR_TWO_THIRDS: 141 cursor.shape = FB_TILE_CURSOR_TWO_THIRDS; 142 break; 143 case CUR_BLOCK: 144 default: 145 cursor.shape = FB_TILE_CURSOR_BLOCK; 146 break; 147 } 148 149 info->tileops->fb_tilecursor(info, &cursor); 150 } 151 152 static int tile_update_start(struct fb_info *info) 153 { 154 struct fbcon_ops *ops = info->fbcon_par; 155 int err; 156 157 err = fb_pan_display(info, &ops->var); 158 ops->var.xoffset = info->var.xoffset; 159 ops->var.yoffset = info->var.yoffset; 160 ops->var.vmode = info->var.vmode; 161 return err; 162 } 163 164 void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info) 165 { 166 struct fb_tilemap map; 167 struct fbcon_ops *ops = info->fbcon_par; 168 169 ops->bmove = tile_bmove; 170 ops->clear = tile_clear; 171 ops->putcs = tile_putcs; 172 ops->clear_margins = tile_clear_margins; 173 ops->cursor = tile_cursor; 174 ops->update_start = tile_update_start; 175 176 if (ops->p) { 177 map.width = vc->vc_font.width; 178 map.height = vc->vc_font.height; 179 map.depth = 1; 180 map.length = vc->vc_font.charcount; 181 map.data = ops->p->fontdata; 182 info->tileops->fb_settile(info, &map); 183 } 184 } 185