tileblit.c 4.6 KB

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