aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2005-11-09 00:39:10 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:34 -0500
commit9c44e5f6c211a9b7313ded897f3135ef7d9ad3e2 (patch)
treeb4d94144527964a822367e4018693dc4e8a83383
parente4fc27618b75234b721c4a13d0e0d9d07e75e641 (diff)
[PATCH] fbcon: Console Rotation - Add support to rotate the logo
Add support for rotating and positioning of the logo. Rotation and position depends on 'int rotate' parameter added to fb_prepare_logo() and fb_show_logo(). Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/fbmem.c130
-rw-r--r--include/linux/fb.h4
3 files changed, 122 insertions, 17 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index b5d678c73252..26935e231a1d 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -499,6 +499,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
499 int cols, int rows, int new_cols, int new_rows) 499 int cols, int rows, int new_cols, int new_rows)
500{ 500{
501 /* Need to make room for the logo */ 501 /* Need to make room for the logo */
502 struct fbcon_ops *ops = info->fbcon_par;
502 int cnt, erase = vc->vc_video_erase_char, step; 503 int cnt, erase = vc->vc_video_erase_char, step;
503 unsigned short *save = NULL, *r, *q; 504 unsigned short *save = NULL, *r, *q;
504 505
@@ -508,7 +509,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
508 */ 509 */
509 if (fb_get_color_depth(&info->var, &info->fix) == 1) 510 if (fb_get_color_depth(&info->var, &info->fix) == 1)
510 erase &= ~0x400; 511 erase &= ~0x400;
511 logo_height = fb_prepare_logo(info); 512 logo_height = fb_prepare_logo(info, ops->rotate);
512 logo_lines = (logo_height + vc->vc_font.height - 1) / 513 logo_lines = (logo_height + vc->vc_font.height - 1) /
513 vc->vc_font.height; 514 vc->vc_font.height;
514 q = (unsigned short *) (vc->vc_origin + 515 q = (unsigned short *) (vc->vc_origin +
@@ -2073,7 +2074,7 @@ static int fbcon_switch(struct vc_data *vc)
2073 2074
2074 logo_shown = fg_console; 2075 logo_shown = fg_console;
2075 /* This is protected above by initmem_freed */ 2076 /* This is protected above by initmem_freed */
2076 fb_show_logo(info); 2077 fb_show_logo(info, ops->rotate);
2077 update_region(vc, 2078 update_region(vc,
2078 vc->vc_origin + vc->vc_size_row * vc->vc_top, 2079 vc->vc_origin + vc->vc_size_row * vc->vc_top,
2079 vc->vc_size_row * (vc->vc_bottom - 2080 vc->vc_size_row * (vc->vc_bottom -
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e2667ddab3f1..7a2a8fa50b3b 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -323,9 +323,103 @@ static struct logo_data {
323 const struct linux_logo *logo; 323 const struct linux_logo *logo;
324} fb_logo; 324} fb_logo;
325 325
326int fb_prepare_logo(struct fb_info *info) 326static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
327{
328 u32 size = width * height, i;
329
330 out += size - 1;
331
332 for (i = size; i--; )
333 *out-- = *in++;
334}
335
336static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
337{
338 int i, j, w = width - 1;
339
340 for (i = 0; i < height; i++)
341 for (j = 0; j < width; j++)
342 out[height * j + w - i] = *in++;
343}
344
345static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
346{
347 int i, j, w = width - 1;
348
349 for (i = 0; i < height; i++)
350 for (j = 0; j < width; j++)
351 out[height * (w - j) + i] = *in++;
352}
353
354static void fb_rotate_logo(struct fb_info *info, u8 *dst,
355 struct fb_image *image, int rotate)
356{
357 u32 tmp;
358
359 if (rotate == FB_ROTATE_UD) {
360 image->dx = info->var.xres - image->width;
361 image->dy = info->var.yres - image->height;
362 fb_rotate_logo_ud(image->data, dst, image->width,
363 image->height);
364 } else if (rotate == FB_ROTATE_CW) {
365 tmp = image->width;
366 image->width = image->height;
367 image->height = tmp;
368 image->dx = info->var.xres - image->height;
369 fb_rotate_logo_cw(image->data, dst, image->width,
370 image->height);
371 } else if (rotate == FB_ROTATE_CCW) {
372 tmp = image->width;
373 image->width = image->height;
374 image->height = tmp;
375 image->dy = info->var.yres - image->width;
376 fb_rotate_logo_ccw(image->data, dst, image->width,
377 image->height);
378 }
379
380 image->data = dst;
381}
382
383static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
384 int rotate)
385{
386 int x;
387
388 if (rotate == FB_ROTATE_UR) {
389 for (x = 0; x < num_online_cpus() &&
390 x * (fb_logo.logo->width + 8) <=
391 info->var.xres - fb_logo.logo->width; x++) {
392 info->fbops->fb_imageblit(info, image);
393 image->dx += fb_logo.logo->width + 8;
394 }
395 } else if (rotate == FB_ROTATE_UD) {
396 for (x = 0; x < num_online_cpus() &&
397 x * (fb_logo.logo->width + 8) <=
398 info->var.xres - fb_logo.logo->width; x++) {
399 info->fbops->fb_imageblit(info, image);
400 image->dx -= fb_logo.logo->width + 8;
401 }
402 } else if (rotate == FB_ROTATE_CW) {
403 for (x = 0; x < num_online_cpus() &&
404 x * (fb_logo.logo->width + 8) <=
405 info->var.yres - fb_logo.logo->width; x++) {
406 info->fbops->fb_imageblit(info, image);
407 image->dy += fb_logo.logo->width + 8;
408 }
409 } else if (rotate == FB_ROTATE_CCW) {
410 for (x = 0; x < num_online_cpus() &&
411 x * (fb_logo.logo->width + 8) <=
412 info->var.yres - fb_logo.logo->width; x++) {
413 info->fbops->fb_imageblit(info, image);
414 image->dy -= fb_logo.logo->width + 8;
415 }
416 }
417}
418
419int fb_prepare_logo(struct fb_info *info, int rotate)
327{ 420{
328 int depth = fb_get_color_depth(&info->var, &info->fix); 421 int depth = fb_get_color_depth(&info->var, &info->fix);
422 int yres;
329 423
330 memset(&fb_logo, 0, sizeof(struct logo_data)); 424 memset(&fb_logo, 0, sizeof(struct logo_data));
331 425
@@ -358,10 +452,16 @@ int fb_prepare_logo(struct fb_info *info)
358 /* Return if no suitable logo was found */ 452 /* Return if no suitable logo was found */
359 fb_logo.logo = fb_find_logo(depth); 453 fb_logo.logo = fb_find_logo(depth);
360 454
361 if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { 455 if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
456 yres = info->var.yres;
457 else
458 yres = info->var.xres;
459
460 if (fb_logo.logo && fb_logo.logo->height > yres) {
362 fb_logo.logo = NULL; 461 fb_logo.logo = NULL;
363 return 0; 462 return 0;
364 } 463 }
464
365 /* What depth we asked for might be different from what we get */ 465 /* What depth we asked for might be different from what we get */
366 if (fb_logo.logo->type == LINUX_LOGO_CLUT224) 466 if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
367 fb_logo.depth = 8; 467 fb_logo.depth = 8;
@@ -372,12 +472,11 @@ int fb_prepare_logo(struct fb_info *info)
372 return fb_logo.logo->height; 472 return fb_logo.logo->height;
373} 473}
374 474
375int fb_show_logo(struct fb_info *info) 475int fb_show_logo(struct fb_info *info, int rotate)
376{ 476{
377 u32 *palette = NULL, *saved_pseudo_palette = NULL; 477 u32 *palette = NULL, *saved_pseudo_palette = NULL;
378 unsigned char *logo_new = NULL; 478 unsigned char *logo_new = NULL, *logo_rotate = NULL;
379 struct fb_image image; 479 struct fb_image image;
380 int x;
381 480
382 /* Return if the frame buffer is not mapped or suspended */ 481 /* Return if the frame buffer is not mapped or suspended */
383 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) 482 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
@@ -417,25 +516,30 @@ int fb_show_logo(struct fb_info *info)
417 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); 516 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth);
418 } 517 }
419 518
519 image.dx = 0;
520 image.dy = 0;
420 image.width = fb_logo.logo->width; 521 image.width = fb_logo.logo->width;
421 image.height = fb_logo.logo->height; 522 image.height = fb_logo.logo->height;
422 image.dy = 0;
423 523
424 for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && 524 if (rotate) {
425 x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { 525 logo_rotate = kmalloc(fb_logo.logo->width *
426 image.dx = x; 526 fb_logo.logo->height, GFP_KERNEL);
427 info->fbops->fb_imageblit(info, &image); 527 if (logo_rotate)
528 fb_rotate_logo(info, logo_rotate, &image, rotate);
428 } 529 }
429 530
531 fb_do_show_logo(info, &image, rotate);
532
430 kfree(palette); 533 kfree(palette);
431 if (saved_pseudo_palette != NULL) 534 if (saved_pseudo_palette != NULL)
432 info->pseudo_palette = saved_pseudo_palette; 535 info->pseudo_palette = saved_pseudo_palette;
433 kfree(logo_new); 536 kfree(logo_new);
537 kfree(logo_rotate);
434 return fb_logo.logo->height; 538 return fb_logo.logo->height;
435} 539}
436#else 540#else
437int fb_prepare_logo(struct fb_info *info) { return 0; } 541int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
438int fb_show_logo(struct fb_info *info) { return 0; } 542int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
439#endif /* CONFIG_LOGO */ 543#endif /* CONFIG_LOGO */
440 544
441static int fbmem_read_proc(char *buf, char **start, off_t offset, 545static int fbmem_read_proc(char *buf, char **start, off_t offset,
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 51791dc5d4dc..357dd3a0a01e 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -825,8 +825,8 @@ extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
825/* drivers/video/fbmem.c */ 825/* drivers/video/fbmem.c */
826extern int register_framebuffer(struct fb_info *fb_info); 826extern int register_framebuffer(struct fb_info *fb_info);
827extern int unregister_framebuffer(struct fb_info *fb_info); 827extern int unregister_framebuffer(struct fb_info *fb_info);
828extern int fb_prepare_logo(struct fb_info *fb_info); 828extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
829extern int fb_show_logo(struct fb_info *fb_info); 829extern int fb_show_logo(struct fb_info *fb_info, int rotate);
830extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); 830extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
831extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, 831extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
832 u32 height, u32 shift_high, u32 shift_low, u32 mod); 832 u32 height, u32 shift_high, u32 shift_low, u32 mod);