fbcon_rotate.c 2.5 KB

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