fbcon_rotate.c 2.5 KB

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