comparison libvo/vo_fbdev.c @ 393:e847396dc49f

some changes...
author szabii
date Fri, 13 Apr 2001 20:34:11 +0000
parents 086c66d570d8
children d75c826a8ab9
comparison
equal deleted inserted replaced
392:50214d6c1826 393:e847396dc49f
3 * by Szabolcs Berecz <szabi@inf.elte.hu> 3 * by Szabolcs Berecz <szabi@inf.elte.hu>
4 * (C) 2001 4 * (C) 2001
5 * 5 *
6 * Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27 6 * Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27
7 */ 7 */
8
9 #define FBDEV "fbdev: "
8 10
9 #include <stdio.h> 11 #include <stdio.h>
10 #include <stdlib.h> 12 #include <stdlib.h>
11 #include <string.h> 13 #include <string.h>
12 #include <fcntl.h> 14 #include <fcntl.h>
39 }; 41 };
40 42
41 extern int verbose; 43 extern int verbose;
42 44
43 /****************************** 45 /******************************
44 * fb.modes parser * 46 * fb.modes support *
45 ******************************/ 47 ******************************/
46 48
47 /* 49 /*
48 * read the fb.modes manual page! 50 * read the fb.modes manual page!
49 */ 51 */
248 } else if (!strcmp(token[0], "endmode")) { 250 } else if (!strcmp(token[0], "endmode")) {
249 /* NOTHING for now*/ 251 /* NOTHING for now*/
250 } else if (!strcmp(token[0], "accel")) { 252 } else if (!strcmp(token[0], "accel")) {
251 if (get_token(1) < 0) 253 if (get_token(1) < 0)
252 goto err_out_parse_error; 254 goto err_out_parse_error;
253 /* NOTHING for now*/ 255 /*
256 * it's only used for text acceleration
257 * so we just ignore it.
258 */
254 } else if (!strcmp(token[0], "hsync")) { 259 } else if (!strcmp(token[0], "hsync")) {
255 if (get_token(1) < 0) 260 if (get_token(1) < 0)
256 goto err_out_parse_error; 261 goto err_out_parse_error;
257 if (!strcmp(token[0], "low")) 262 if (!strcmp(token[0], "low"))
258 mode->sync &= ~FB_SYNC_HOR_HIGH_ACT; 263 mode->sync &= ~FB_SYNC_HOR_HIGH_ACT;
318 err_out_parse_error: 323 err_out_parse_error:
319 printf("parse error"); 324 printf("parse error");
320 err_out_print_linenum: 325 err_out_print_linenum:
321 PRINT_LINENUM; 326 PRINT_LINENUM;
322 err_out: 327 err_out:
323 if (fb_modes) 328 if (fb_modes) {
324 free(fb_modes); 329 free(fb_modes);
330 fb_modes = NULL;
331 }
332 nr_modes = 0;
325 free(line); 333 free(line);
326 free(fp); 334 free(fp);
327 return -2; 335 return -2;
328 err_out_not_valid: 336 err_out_not_valid:
329 printf("mode is not definied correctly"); 337 printf("mode is not definied correctly");
339 return fb_modes + i; 347 return fb_modes + i;
340 } 348 }
341 return NULL; 349 return NULL;
342 } 350 }
343 351
352 static float dcf(fb_mode_t *m) //driving clock frequency
353 {
354 return 1000000.0f / m->pixclock;
355 }
356
357 static float hsf(fb_mode_t *m) //horizontal scan frequency
358 {
359 int htotal = m->left + m->xres + m->right + m->hslen;
360 return dcf(m) / htotal;
361 }
362
363 static float vsf(fb_mode_t *m) //vertical scan frequency
364 {
365 int vtotal = m->upper + m->yres + m->lower + m->vslen;
366 return hsf(m) / vtotal;
367 }
368
369 typedef struct {
370 float min;
371 float max;
372 } range;
373
374 static int in_range(range *r, float f)
375 {
376 for (/* NOTHING */; r; r++) {
377 if (f >= r->min && f <= r->max)
378 return 1;
379 }
380 return 0;
381 }
382
383 static fb_mode_t *find_best_mode(int xres, int yres, range *hfreq,
384 range *vfreq, range *dotclock)
385 {
386 int i;
387 fb_mode_t *best = fb_modes;
388 fb_mode_t *curr = fb_modes + 1;
389
390 for (i = nr_modes - 1; i; i--, curr++) {
391 if (curr->xres >= xres && curr->yres >= yres) {
392 if (curr->xres < best->xres && curr->yres < best->yres) {
393 if (!in_range(hfreq, hsf(curr)))
394 continue;
395 if (!in_range(vfreq, vsf(curr)))
396 continue;
397 if (!in_range(dotclock, dcf(curr)))
398 continue;
399 best = curr;
400 }
401 }
402 }
403 if ((best->xres < xres || best->yres < yres) ||
404 !in_range(hfreq, hsf(best)) ||
405 !in_range(vfreq, vsf(best)) ||
406 !in_range(dotclock, dcf(curr)))
407 return NULL;
408 return best;
409 }
410
344 /****************************** 411 /******************************
345 * vo_fbdev * 412 * vo_fbdev *
346 ******************************/ 413 ******************************/
347 414
348 static int fb_init_done = 0; 415 /*
416 * command line/config file options
417 */
418 char *fb_dev_name = NULL;
419 char *fb_mode_cfgfile = "/etc/fb.modes";
420 char *fb_mode_name = NULL;
421 int fb_mode_depth = 0;
422 int fb_mode_auto = 0;
423 char *monitor_hfreq = NULL;
424 char *monitor_vfreq = NULL;
425 char *monitor_dotclock = NULL;
426
427 static int fb_preinit_done = 0;
349 static int fb_works = 0; 428 static int fb_works = 0;
350 static int fb_dev_fd; 429 static int fb_dev_fd;
351 static size_t fb_size; 430 static size_t fb_size;
352 static uint8_t *frame_buffer; 431 static uint8_t *frame_buffer;
353 static struct fb_fix_screeninfo fb_finfo; 432 static struct fb_fix_screeninfo fb_finfo;
355 static struct fb_var_screeninfo fb_vinfo; 434 static struct fb_var_screeninfo fb_vinfo;
356 static struct fb_cmap *fb_oldcmap = NULL; 435 static struct fb_cmap *fb_oldcmap = NULL;
357 static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2 436 static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2
358 static int fb_real_bpp; // 32: 24 24: 24 16: 16 15: 15 437 static int fb_real_bpp; // 32: 24 24: 24 16: 16 15: 15
359 static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15 438 static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15
439 static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15
360 static int fb_screen_width; 440 static int fb_screen_width;
361
362 char *fb_dev_name = NULL;
363 char *fb_mode_cfgfile = "/etc/fb.modes";
364 char *fb_mode_name = NULL;
365 int fb_mode_depth = 0;
366 static fb_mode_t *fb_mode = NULL; 441 static fb_mode_t *fb_mode = NULL;
367 static int fb_switch_mode = 0;
368 442
369 static uint8_t *next_frame; 443 static uint8_t *next_frame;
370 static int in_width; 444 static int in_width;
371 static int in_height; 445 static int in_height;
372 static int out_width; 446 static int out_width;
442 cmap->transp = NULL; 516 cmap->transp = NULL;
443 517
444 return cmap; 518 return cmap;
445 } 519 }
446 520
447 static void set_rgb_fields(struct fb_var_screeninfo *p, int depth) 521 static void set_bpp(struct fb_var_screeninfo *p, int bpp)
448 { 522 {
449 switch (depth) { 523 p->bits_per_pixel = (bpp == 15) ? 16 : bpp;
524 p->red.msb_right = p->green.msb_right = p->blue.msb_right = 0;
525 switch (bpp) {
450 case 32: 526 case 32:
451 case 24: 527 case 24:
452 p->red.offset = 16; 528 p->red.offset = 16;
453 p->red.length = 8; 529 p->red.length = 8;
454 p->red.msb_right = 0;
455 p->green.offset = 8; 530 p->green.offset = 8;
456 p->green.length = 8; 531 p->green.length = 8;
457 p->green.msb_right = 0;
458 p->blue.offset = 0; 532 p->blue.offset = 0;
459 p->blue.length = 8; 533 p->blue.length = 8;
460 p->blue.msb_right = 0;
461 break; 534 break;
462 case 16: 535 case 16:
463 p->red.offset = 11; 536 p->red.offset = 11;
464 p->red.length = 5; 537 p->red.length = 5;
465 p->red.msb_right = 0;
466 p->green.offset = 5; 538 p->green.offset = 5;
467 p->green.length = 6; 539 p->green.length = 6;
468 p->green.msb_right = 0;
469 p->blue.offset = 0; 540 p->blue.offset = 0;
470 p->blue.length = 5; 541 p->blue.length = 5;
471 p->blue.msb_right = 0;
472 break; 542 break;
473 case 15: 543 case 15:
474 p->red.offset = 10; 544 p->red.offset = 10;
475 p->red.length = 5; 545 p->red.length = 5;
476 p->red.msb_right = 0;
477 p->green.offset = 5; 546 p->green.offset = 5;
478 p->green.length = 5; 547 p->green.length = 5;
479 p->green.msb_right = 0;
480 p->blue.offset = 0; 548 p->blue.offset = 0;
481 p->blue.length = 5; 549 p->blue.length = 5;
482 p->blue.msb_right = 0;
483 break; 550 break;
484 } 551 }
485 } 552 }
486 553
487 static int fb_init(void) 554 static int fb_preinit(void)
488 { 555 {
489 int fd; 556 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
490 struct fb_cmap *cmap; 557 fb_dev_name = "/dev/fb0";
491 558 if (verbose > 0)
492 if (fb_mode_name) { 559 printf(FBDEV "using %s\n", fb_dev_name);
560
561 if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) {
562 printf(FBDEV "Can't open %s: %s\n", fb_dev_name, strerror(errno));
563 goto err_out;
564 }
565 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
566 printf(FBDEV "Can't get VSCREENINFO: %s\n", strerror(errno));
567 goto err_out_fd;
568 }
569
570 fb_bpp = (fb_vinfo.bits_per_pixel == 32) ? 32 :
571 (fb_vinfo.red.length + fb_vinfo.green.length +
572 fb_vinfo.blue.length);
573
574 if ((!!fb_mode_name + !!fb_mode_depth + !!fb_mode_auto) > 1) {
575 printf(FBDEV "Use can use only one of the following parameters:"
576 "-fbmode, -fbdepth, -fbauto\n");
577 goto err_out;
578 }
579 if (fb_mode_name || fb_mode_auto)
493 if (parse_fbmode_cfg(fb_mode_cfgfile) < 0) 580 if (parse_fbmode_cfg(fb_mode_cfgfile) < 0)
494 goto err_out; 581 goto err_out;
582
583 if (fb_mode_name) {
495 if (!(fb_mode = find_mode_by_name(fb_mode_name))) { 584 if (!(fb_mode = find_mode_by_name(fb_mode_name))) {
496 printf("fb: can't find requested video mode\n"); 585 printf(FBDEV "can't find requested video mode\n");
497 goto err_out; 586 goto err_out;
498 } 587 }
499 fb_switch_mode = 1; 588 fb_bpp = fb_mode->depth;
500 } else if (fb_mode_depth) { 589 } else if (fb_mode_depth) {
501 printf("fb: Do _not_ use the 'fbdepth' parameter! " 590 printf(FBDEV "Do _not_ use the 'fbdepth' parameter! "
502 "this parameter will be removed\n"); 591 "this parameter will be removed\n");
503 if (fb_mode_depth != 15 && fb_mode_depth != 16 && 592 if (fb_mode_depth != 15 && fb_mode_depth != 16 &&
504 fb_mode_depth != 24 && fb_mode_depth != 32) { 593 fb_mode_depth != 24 && fb_mode_depth != 32) {
505 printf("fb: can't switch to %d bpp\n", fb_mode_depth); 594 printf(FBDEV "can't switch to %d bpp\n", fb_mode_depth);
506 goto err_out; 595 goto err_out;
507 } 596 }
508 } 597 fb_bpp = fb_mode_depth;
509 598 } else if (fb_mode_auto) {
510 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) 599 printf(FBDEV "Not implemented. try later... :)\n");
511 fb_dev_name = "/dev/fb0";
512 if (verbose > 0)
513 printf("fb: using %s\n", fb_dev_name);
514
515 if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) {
516 printf("fb: Can't open %s: %s\n", fb_dev_name, strerror(errno));
517 goto err_out; 600 goto err_out;
518 } 601 fb_bpp = fb_mode->depth;
519 602 }
520 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) { 603 fb_bpp_we_want = fb_bpp;
521 printf("fb: Can't get VSCREENINFO: %s\n", strerror(errno)); 604
522 goto err_out_fd; 605 fb_preinit_done = 1;
523 } 606 fb_works = 1;
607 return 0;
608 err_out_fd:
609 close(fb_dev_fd);
610 fb_dev_fd = -1;
611 err_out:
612 fb_preinit_done = 1;
613 return 1;
614 }
615
616 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width,
617 uint32_t d_height, uint32_t fullscreen, char *title,
618 uint32_t format)
619 {
620 struct fb_cmap *cmap;
621
622 if (!fb_preinit_done)
623 if (fb_preinit())
624 return 1;
625 if (!fb_works)
626 return 1;
524 627
525 fb_orig_vinfo = fb_vinfo; 628 fb_orig_vinfo = fb_vinfo;
526 if (fb_switch_mode) { 629 if (fb_mode_name) {
527 fb_vinfo.xres = fb_mode->xres; 630 fb_vinfo.xres = fb_mode->xres;
528 fb_vinfo.yres = fb_mode->yres; 631 fb_vinfo.yres = fb_mode->yres;
529 fb_vinfo.xres_virtual = fb_mode->vxres; 632 fb_vinfo.xres_virtual = fb_mode->vxres;
530 fb_vinfo.yres_virtual = fb_mode->vyres; 633 fb_vinfo.yres_virtual = fb_mode->vyres;
531 fb_vinfo.bits_per_pixel = fb_mode->depth; 634 set_bpp(&fb_vinfo, fb_mode->depth);
532 set_rgb_fields(&fb_vinfo, fb_mode->depth);
533 fb_vinfo.pixclock = fb_mode->pixclock; 635 fb_vinfo.pixclock = fb_mode->pixclock;
534 fb_vinfo.left_margin = fb_mode->left; 636 fb_vinfo.left_margin = fb_mode->left;
535 fb_vinfo.right_margin = fb_mode->right; 637 fb_vinfo.right_margin = fb_mode->right;
536 fb_vinfo.upper_margin = fb_mode->upper; 638 fb_vinfo.upper_margin = fb_mode->upper;
537 fb_vinfo.lower_margin = fb_mode->lower; 639 fb_vinfo.lower_margin = fb_mode->lower;
538 fb_vinfo.hsync_len = fb_mode->hslen; 640 fb_vinfo.hsync_len = fb_mode->hslen;
539 fb_vinfo.vsync_len = fb_mode->vslen; 641 fb_vinfo.vsync_len = fb_mode->vslen;
540 fb_vinfo.sync = fb_mode->sync; 642 fb_vinfo.sync = fb_mode->sync;
541 fb_vinfo.vmode = fb_mode->vmode; 643 fb_vinfo.vmode = fb_mode->vmode;
542 } else if (fb_mode_depth) { 644 } else if (fb_mode_depth) {
543 fb_vinfo.bits_per_pixel = fb_mode_depth; 645 set_bpp(&fb_vinfo, fb_mode_depth);
544 set_rgb_fields(&fb_vinfo, fb_mode_depth);
545 } 646 }
546 fb_vinfo.xres_virtual = fb_vinfo.xres; 647 fb_vinfo.xres_virtual = fb_vinfo.xres;
547 fb_vinfo.yres_virtual = fb_vinfo.yres; 648 fb_vinfo.yres_virtual = fb_vinfo.yres;
548 649
549 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { 650 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
550 printf("fb: Can't put VSCREENINFO: %s\n", strerror(errno)); 651 printf(FBDEV "Can't put VSCREENINFO: %s\n", strerror(errno));
551 goto err_out_fd; 652 return 1;
552 } 653 }
553 654 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
655 printf(FBDEV "Can't get VSCREENINFO: %s\n", strerror(errno));
656 return 1;
657 }
658
659 if (verbose > 0) {
660 printf(FBDEV "var info:\n");
661 printf(FBDEV "xres: %ul\n", fb_vinfo.xres);
662 printf(FBDEV "yres: %ul\n", fb_vinfo.yres);
663 printf(FBDEV "xres_virtual: %ul\n", fb_vinfo.xres_virtual);
664 printf(FBDEV "yres_virtual: %ul\n", fb_vinfo.yres_virtual);
665 printf(FBDEV "xoffset: %ul\n", fb_vinfo.xoffset);
666 printf(FBDEV "yoffset: %ul\n", fb_vinfo.yoffset);
667 printf(FBDEV "bits_per_pixel: %ul\n", fb_vinfo.bits_per_pixel);
668 printf(FBDEV "grayscale: %ul\n", fb_vinfo.grayscale);
669 printf(FBDEV "red: %lu %lu %lu\n",
670 (unsigned long) fb_vinfo.red.offset,
671 (unsigned long) fb_vinfo.red.length,
672 (unsigned long) fb_vinfo.red.msb_right);
673 printf(FBDEV "green: %lu %lu %lu\n",
674 (unsigned long) fb_vinfo.green.offset,
675 (unsigned long) fb_vinfo.green.length,
676 (unsigned long) fb_vinfo.green.msb_right);
677 printf(FBDEV "blue: %lu %lu %lu\n",
678 (unsigned long) fb_vinfo.blue.offset,
679 (unsigned long) fb_vinfo.blue.length,
680 (unsigned long) fb_vinfo.blue.msb_right);
681 printf(FBDEV "transp: %lu %lu %lu\n",
682 (unsigned long) fb_vinfo.transp.offset,
683 (unsigned long) fb_vinfo.transp.length,
684 (unsigned long) fb_vinfo.transp.msb_right);
685 printf(FBDEV "nonstd: %ul\n", fb_vinfo.nonstd);
686 if (verbose > 1) {
687 printf(FBDEV "activate: %ul\n", fb_vinfo.activate);
688 printf(FBDEV "height: %ul\n", fb_vinfo.height);
689 printf(FBDEV "width: %ul\n", fb_vinfo.width);
690 printf(FBDEV "accel_flags: %ul\n", fb_vinfo.accel_flags);
691 printf(FBDEV "timing:\n");
692 printf(FBDEV "pixclock: %ul\n", fb_vinfo.pixclock);
693 printf(FBDEV "left_margin: %ul\n", fb_vinfo.left_margin);
694 printf(FBDEV "right_margin: %ul\n", fb_vinfo.right_margin);
695 printf(FBDEV "upper_margin: %ul\n", fb_vinfo.upper_margin);
696 printf(FBDEV "lower_margin: %ul\n", fb_vinfo.lower_margin);
697 printf(FBDEV "hsync_len: %ul\n", fb_vinfo.hsync_len);
698 printf(FBDEV "vsync_len: %ul\n", fb_vinfo.vsync_len);
699 printf(FBDEV "sync: %ul\n", fb_vinfo.sync);
700 printf(FBDEV "vmode: %ul\n", fb_vinfo.vmode);
701 }
702 }
554 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) { 703 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
555 printf("fb: Can't get VSCREENINFO: %s\n", strerror(errno)); 704 printf(FBDEV "Can't get FSCREENINFO: %s\n", strerror(errno));
556 goto err_out_fd;
557 return 1; 705 return 1;
706 }
707 if (verbose > 0) {
708 printf(FBDEV "fix info:\n");
709 if (verbose > 1) {
710 printf(FBDEV "id: %.16s\n", fb_finfo.id);
711 printf(FBDEV "smem_start: %p\n", (void *) fb_finfo.smem_start);
712 }
713 printf(FBDEV "framebuffer size: %d bytes\n", fb_size);
714 printf(FBDEV "type: %lu\n", (unsigned long) fb_finfo.type);
715 printf(FBDEV "type_aux: %lu\n", (unsigned long) fb_finfo.type_aux);
716 printf(FBDEV "visual: %lu\n", (unsigned long) fb_finfo.visual);
717 if (verbose > 1) {
718 printf(FBDEV "xpanstep: %u\n", fb_finfo.xpanstep);
719 printf(FBDEV "ypanstep: %u\n", fb_finfo.ypanstep);
720 printf(FBDEV "ywrapstep: %u\n", fb_finfo.ywrapstep);
721 }
722 printf(FBDEV "line_length: %lu bytes\n", (unsigned long) fb_finfo.line_length);
723 if (verbose > 1) {
724 printf(FBDEV "mmio_start: %p\n", (void *) fb_finfo.mmio_start);
725 printf(FBDEV "mmio_len: %ul bytes\n", fb_finfo.mmio_len);
726 printf(FBDEV "accel: %ul\n", fb_finfo.accel);
727 }
558 } 728 }
559 switch (fb_finfo.type) { 729 switch (fb_finfo.type) {
560 case FB_TYPE_VGA_PLANES: 730 case FB_TYPE_VGA_PLANES:
561 printf("fb: FB_TYPE_VGA_PLANES not supported.\n"); 731 printf(FBDEV "FB_TYPE_VGA_PLANES not supported.\n");
562 goto err_out_fd; 732 return 1;
563 break;
564 case FB_TYPE_PLANES: 733 case FB_TYPE_PLANES:
565 printf("fb: FB_TYPE_PLANES not supported.\n"); 734 printf(FBDEV "FB_TYPE_PLANES not supported.\n");
566 goto err_out_fd; 735 return 1;
567 break;
568 case FB_TYPE_INTERLEAVED_PLANES: 736 case FB_TYPE_INTERLEAVED_PLANES:
569 printf("fb: FB_TYPE_INTERLEAVED_PLANES not supported.\n"); 737 printf(FBDEV "FB_TYPE_INTERLEAVED_PLANES not supported.\n");
570 goto err_out_fd; 738 return 1;
571 break;
572 #ifdef FB_TYPE_TEXT 739 #ifdef FB_TYPE_TEXT
573 case FB_TYPE_TEXT: 740 case FB_TYPE_TEXT:
574 printf("fb: FB_TYPE_TEXT not supported.\n"); 741 printf(FBDEV "FB_TYPE_TEXT not supported.\n");
575 goto err_out_fd; 742 return 1;
576 break;
577 #endif 743 #endif
578 case FB_TYPE_PACKED_PIXELS: 744 case FB_TYPE_PACKED_PIXELS:
579 /* OK */ 745 /* OK */
580 if (verbose > 0) 746 if (verbose > 0)
581 printf("fb: FB_TYPE_PACKED_PIXELS: OK\n"); 747 printf(FBDEV "FB_TYPE_PACKED_PIXELS: OK\n");
582 break; 748 break;
583 default: 749 default:
584 printf("fb: unknown FB_TYPE: %d\n", fb_finfo.type); 750 printf(FBDEV "unknown FB_TYPE: %d\n", fb_finfo.type);
585 goto err_out_fd; 751 return 1;
586 } 752 }
587 switch (fb_finfo.visual) { 753 switch (fb_finfo.visual) {
588 case FB_VISUAL_TRUECOLOR: 754 case FB_VISUAL_TRUECOLOR:
589 break; 755 break;
590 case FB_VISUAL_DIRECTCOLOR: 756 case FB_VISUAL_DIRECTCOLOR:
591 if (verbose > 0) 757 if (verbose > 0)
592 printf("fb: creating cmap for directcolor\n"); 758 printf(FBDEV "creating cmap for directcolor\n");
593 if (ioctl(fb_dev_fd, FBIOGETCMAP, fb_oldcmap)) { 759 if (ioctl(fb_dev_fd, FBIOGETCMAP, fb_oldcmap)) {
594 printf("fb: can't get cmap: %s\n", 760 printf(FBDEV "can't get cmap: %s\n",
595 strerror(errno)); 761 strerror(errno));
596 goto err_out_fd; 762 return 1;
597 } 763 }
598 if (!(cmap = make_directcolor_cmap(&fb_vinfo))) 764 if (!(cmap = make_directcolor_cmap(&fb_vinfo)))
599 goto err_out_fd; 765 return 1;
600 if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) { 766 if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) {
601 printf("fb: can't put cmap: %s\n", 767 printf(FBDEV "can't put cmap: %s\n",
602 strerror(errno)); 768 strerror(errno));
603 goto err_out_fd; 769 return 1;
604 } 770 }
605 free(cmap->red); 771 free(cmap->red);
606 free(cmap->green); 772 free(cmap->green);
607 free(cmap->blue); 773 free(cmap->blue);
608 free(cmap); 774 free(cmap);
609 break; 775 break;
610 case FB_VISUAL_PSEUDOCOLOR: 776 case FB_VISUAL_PSEUDOCOLOR:
611 printf("fb: visual is FB_VISUAL_PSEUDOCOLOR. it's not tested!\n"); 777 printf(FBDEV "visual is FB_VISUAL_PSEUDOCOLOR."
612 break; 778 "it's not tested!\n");
613 default: 779 break;
614 printf("fb: visual: %d not yet supported\n", 780 default:
615 fb_finfo.visual); 781 printf(FBDEV "visual: %d not yet supported\n",
616 goto err_out_fd; 782 fb_finfo.visual);
783 return 1;
617 } 784 }
618 785
619 fb_pixel_size = fb_vinfo.bits_per_pixel / 8; 786 fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
620 fb_real_bpp = fb_vinfo.red.length + fb_vinfo.green.length + 787 fb_real_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
621 fb_vinfo.blue.length; 788 fb_vinfo.blue.length;
622 fb_bpp = (fb_pixel_size == 4) ? 32 : fb_real_bpp; 789 fb_bpp = (fb_pixel_size == 4) ? 32 : fb_real_bpp;
790 if (fb_bpp_we_want != fb_bpp)
791 printf(FBDEV "can't set bpp (requested %d, got %d bpp)!!!\n",
792 fb_bpp_we_want, fb_bpp);
623 fb_screen_width = fb_finfo.line_length; 793 fb_screen_width = fb_finfo.line_length;
624 fb_size = fb_finfo.smem_len; 794 fb_size = fb_finfo.smem_len;
625 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, 795 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE,
626 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { 796 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) {
627 printf("fb: Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); 797 printf(FBDEV "Can't mmap %s: %s\n", fb_dev_name, strerror(errno));
628 goto err_out_fd;
629 }
630
631 if (verbose > 0 && verbose < 4)
632 printf("fb: use verbose level >= 4 to get some info (you will get _lots_ of info)\n");
633 if (verbose >= 4) {
634 printf("fb: fix info:\n");
635 printf("fb: id: %.16s\n", fb_finfo.id);
636 printf("fb: smem_start: %p\n", fb_finfo.smem_start);
637 printf("fb: framebuffer size: %d bytes\n", fb_size);
638 printf("fb: type: %lu\n", fb_finfo.type);
639 printf("fb: type_aux: %lu\n", fb_finfo.type_aux);
640 printf("fb: visual: %lu\n", fb_finfo.visual);
641 printf("fb: xpanstep: %u\n", fb_finfo.xpanstep);
642 printf("fb: ypanstep: %u\n", fb_finfo.ypanstep);
643 printf("fb: ywrapstep: %u\n", fb_finfo.ywrapstep);
644 printf("fb: line_length: %lu bytes\n", fb_finfo.line_length);
645 printf("fb: mmio_start: %p\n", fb_finfo.mmio_start);
646 printf("fb: mmio_len: %ul bytes\n", fb_finfo.mmio_len);
647 printf("fb: accel: %ul\n", fb_finfo.accel);
648 printf("fb: var info:\n");
649 printf("fb: xres: %ul\n", fb_vinfo.xres);
650 printf("fb: yres: %ul\n", fb_vinfo.yres);
651 printf("fb: xres_virtual: %ul\n", fb_vinfo.xres_virtual);
652 printf("fb: yres_virtual: %ul\n", fb_vinfo.yres_virtual);
653 printf("fb: xoffset: %ul\n", fb_vinfo.xoffset);
654 printf("fb: yoffset: %ul\n", fb_vinfo.yoffset);
655 printf("fb: bits_per_pixel: %ul\n", fb_vinfo.bits_per_pixel);
656 printf("fb: grayscale: %ul\n", fb_vinfo.grayscale);
657 printf("fb: red: %lu %lu %lu\n", fb_vinfo.red.offset,
658 fb_vinfo.red.length, fb_vinfo.red.msb_right);
659 printf("fb: green: %lu %lu %lu\n", fb_vinfo.green.offset,
660 fb_vinfo.green.length, fb_vinfo.green.msb_right);
661 printf("fb: blue: %lu %lu %lu\n", fb_vinfo.blue.offset,
662 fb_vinfo.blue.length, fb_vinfo.blue.msb_right);
663 printf("fb: transp: %lu %lu %lu\n", fb_vinfo.transp.offset,
664 fb_vinfo.transp.length, fb_vinfo.transp.msb_right);
665 printf("fb: nonstd: %ul\n", fb_vinfo.nonstd);
666 printf("fb: activate: %ul\n", fb_vinfo.activate);
667 printf("fb: height: %ul\n", fb_vinfo.height);
668 printf("fb: width: %ul\n", fb_vinfo.width);
669 printf("fb: accel_flags: %ul\n", fb_vinfo.accel_flags);
670 printf("fb: timing:\n");
671 printf("fb: pixclock: %ul\n", fb_vinfo.pixclock);
672 printf("fb: left_margin: %ul\n", fb_vinfo.left_margin);
673 printf("fb: right_margin: %ul\n", fb_vinfo.right_margin);
674 printf("fb: upper_margin: %ul\n", fb_vinfo.upper_margin);
675 printf("fb: lower_margin: %ul\n", fb_vinfo.lower_margin);
676 printf("fb: hsync_len: %ul\n", fb_vinfo.hsync_len);
677 printf("fb: vsync_len: %ul\n", fb_vinfo.vsync_len);
678 printf("fb: sync: %ul\n", fb_vinfo.sync);
679 printf("fb: vmode: %ul\n", fb_vinfo.vmode);
680 printf("fb: other:\n");
681 printf("fb: frame_buffer @ %p\n", frame_buffer);
682 printf("fb: fb_bpp: %d\n", fb_bpp);
683 printf("fb: fb_real_bpp: %d\n", fb_real_bpp);
684 printf("fb: fb_pixel_size: %d bytes\n", fb_pixel_size);
685 printf("fb: pixel per line: %d\n", fb_screen_width / fb_pixel_size);
686 }
687
688 fb_init_done = 1;
689 fb_works = 1;
690 return 0;
691 err_out_fd:
692 close(fb_dev_fd);
693 fb_dev_fd = -1;
694 err_out:
695 fb_init_done = 1;
696 return 1;
697 }
698
699 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width,
700 uint32_t d_height, uint32_t fullscreen, char *title,
701 uint32_t format)
702 {
703 if (!fb_init_done)
704 if (fb_init())
705 return 1;
706 if (!fb_works)
707 return 1; 798 return 1;
799 }
800
801 if (verbose > 0) {
802 printf(FBDEV "other:\n");
803 if (verbose > 1)
804 printf(FBDEV "frame_buffer @ %p\n", frame_buffer);
805 printf(FBDEV "fb_bpp: %d\n", fb_bpp);
806 printf(FBDEV "fb_real_bpp: %d\n", fb_real_bpp);
807 printf(FBDEV "fb_pixel_size: %d bytes\n", fb_pixel_size);
808 printf(FBDEV "pixel per line: %d\n", fb_screen_width / fb_pixel_size);
809 }
708 810
709 in_width = width; 811 in_width = width;
710 in_height = height; 812 in_height = height;
711 out_width = width; 813 out_width = width;
712 out_height = height; 814 out_height = height;
713 pixel_format = format; 815 pixel_format = format;
714 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * fb_pixel_size))) { 816 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * fb_pixel_size))) {
715 printf("Can't malloc next_frame: %s\n", strerror(errno)); 817 printf(FBDEV "Can't malloc next_frame: %s\n", strerror(errno));
716 return 1; 818 return 1;
717 } 819 }
718 820
719 if (format == IMGFMT_YV12) 821 if (format == IMGFMT_YV12)
720 yuv2rgb_init(fb_bpp, MODE_RGB); 822 yuv2rgb_init(fb_bpp, MODE_RGB);
721 return 0; 823 return 0;
722 } 824 }
723 825
724 static uint32_t query_format(uint32_t format) 826 static uint32_t query_format(uint32_t format)
725 { 827 {
726 if (!fb_init_done) 828 if (!fb_preinit_done)
727 if (fb_init()) 829 if (fb_preinit())
728 return 0; 830 return 0;
729 if (!fb_works) 831 if (!fb_works)
730 return 0; 832 return 0;
731 833
732 if (verbose > 0) 834 if (verbose > 0)
733 printf("fb: query_format(%#lx(%.4s))\n", format, &format); 835 printf(FBDEV "query_format(%#lx(%.4s))\n",(unsigned long) format,
836 (char *) &format);
734 if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { 837 if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
735 int bpp = format & 0xff; 838 int bpp = format & 0xff;
736 if (bpp == fb_bpp) 839 if (bpp == fb_bpp)
737 return 1; 840 return 1;
738 else if (bpp == 15 && fb_bpp == 16) 841 else if (bpp == 15 && fb_bpp == 16)
747 850
748 static const vo_info_t *get_info(void) 851 static const vo_info_t *get_info(void)
749 { 852 {
750 return &vo_info; 853 return &vo_info;
751 } 854 }
855
856 extern void vo_draw_alpha_rgb32(int w, int h, unsigned char* src,
857 unsigned char *srca, int srcstride, unsigned char* dstbase,
858 int dststride);
859 extern void vo_draw_alpha_rgb24(int w, int h, unsigned char* src,
860 unsigned char *srca, int srcstride, unsigned char* dstbase,
861 int dststride);
862 extern void vo_draw_alpha_rgb16(int w, int h, unsigned char* src,
863 unsigned char *srca, int srcstride, unsigned char* dstbase,
864 int dststride);
865 extern void vo_draw_alpha_rgb15(int w, int h, unsigned char* src,
866 unsigned char *srca, int srcstride, unsigned char* dstbase,
867 int dststride);
752 868
753 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, 869 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
754 unsigned char *srca, int stride) 870 unsigned char *srca, int stride)
755 { 871 {
756 uint8_t *dst = next_frame + (in_width * y0 + x0) * fb_pixel_size; 872 uint8_t *dst = next_frame + (in_width * y0 + x0) * fb_pixel_size;
827 out_offset += fb_screen_width; 943 out_offset += fb_screen_width;
828 in_offset += in_width * fb_pixel_size; 944 in_offset += in_width * fb_pixel_size;
829 } 945 }
830 } 946 }
831 947
948 extern void vo_draw_text(int dxs, int dys, void (*draw_alpha)(int x0, int y0,
949 int w, int h, unsigned char *src, unsigned char *srca,
950 int stride));
951
832 static void flip_page(void) 952 static void flip_page(void)
833 { 953 {
834 vo_draw_text(in_width, in_height, draw_alpha); 954 vo_draw_text(in_width, in_height, draw_alpha);
835 check_events(); 955 check_events();
836 put_frame(); 956 put_frame();
837 } 957 }
838 958
839 static void uninit(void) 959 static void uninit(void)
840 { 960 {
841 if (verbose > 0) 961 if (verbose > 0)
842 printf("fbdev: uninit\n"); 962 printf(FBDEV "uninit\n");
843 if (fb_oldcmap) { 963 if (fb_oldcmap) {
844 if (ioctl(fb_dev_fd, FBIOPUTCMAP, fb_oldcmap)) 964 if (ioctl(fb_dev_fd, FBIOPUTCMAP, fb_oldcmap))
845 printf("fbdev: Can't restore original cmap\n"); 965 printf(FBDEV "Can't restore original cmap\n");
846 fb_oldcmap = NULL; 966 fb_oldcmap = NULL;
847 } 967 }
848 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo)) 968 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo))
849 printf("fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno)); 969 printf(FBDEV "Can't set virtual screensize to original value: %s\n", strerror(errno));
850 close(fb_dev_fd); 970 close(fb_dev_fd);
851 memset(next_frame, '\0', in_height * in_width * fb_pixel_size); 971 memset(next_frame, '\0', in_height * in_width * fb_pixel_size);
852 put_frame(); 972 put_frame();
853 free(next_frame); 973 free(next_frame);
854 munmap(frame_buffer, fb_size); 974 munmap(frame_buffer, fb_size);