Mercurial > mplayer.hg
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); |