fbcon_rotate.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. #include <linux/config.h>
  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. static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
  20. struct display *p)
  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. if (vc->vc_font.data == ops->fontdata &&
  28. p->con_rotate == ops->cur_rotate)
  29. goto finished;
  30. src = ops->fontdata = vc->vc_font.data;
  31. ops->cur_rotate = p->con_rotate;
  32. len = (!p->userfont) ? 256 : FNTCHARCNT(src);
  33. s_cellsize = ((vc->vc_font.width + 7)/8) *
  34. vc->vc_font.height;
  35. d_cellsize = s_cellsize;
  36. if (ops->rotate == FB_ROTATE_CW ||
  37. ops->rotate == FB_ROTATE_CCW)
  38. d_cellsize = ((vc->vc_font.height + 7)/8) *
  39. vc->vc_font.width;
  40. if (info->fbops->fb_sync)
  41. info->fbops->fb_sync(info);
  42. if (ops->fd_size < d_cellsize * len) {
  43. dst = kmalloc(d_cellsize * len, GFP_KERNEL);
  44. if (dst == NULL) {
  45. err = -ENOMEM;
  46. goto finished;
  47. }
  48. ops->fd_size = d_cellsize * len;
  49. kfree(ops->fontbuffer);
  50. ops->fontbuffer = dst;
  51. }
  52. dst = ops->fontbuffer;
  53. memset(dst, 0, ops->fd_size);
  54. switch (ops->rotate) {
  55. case FB_ROTATE_UD:
  56. for (i = len; i--; ) {
  57. rotate_ud(src, dst, vc->vc_font.width,
  58. vc->vc_font.height);
  59. src += s_cellsize;
  60. dst += d_cellsize;
  61. }
  62. break;
  63. case FB_ROTATE_CW:
  64. for (i = len; i--; ) {
  65. rotate_cw(src, dst, vc->vc_font.width,
  66. vc->vc_font.height);
  67. src += s_cellsize;
  68. dst += d_cellsize;
  69. }
  70. break;
  71. case FB_ROTATE_CCW:
  72. for (i = len; i--; ) {
  73. rotate_ccw(src, dst, vc->vc_font.width,
  74. vc->vc_font.height);
  75. src += s_cellsize;
  76. dst += d_cellsize;
  77. }
  78. break;
  79. }
  80. finished:
  81. return err;
  82. }
  83. void fbcon_set_rotate(struct fbcon_ops *ops)
  84. {
  85. ops->rotate_font = fbcon_rotate_font;
  86. switch(ops->rotate) {
  87. case FB_ROTATE_CW:
  88. fbcon_rotate_cw(ops);
  89. break;
  90. }
  91. }
  92. EXPORT_SYMBOL(fbcon_set_rotate);
  93. MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
  94. MODULE_DESCRIPTION("Console Rotation Support");
  95. MODULE_LICENSE("GPL");