comparison libvo/vo_fbdev.c @ 950:de1e10c4da3c

some little cleanup
author szabii
date Sat, 02 Jun 2001 20:48:16 +0000
parents 83919c1b9924
children d3354ad8aa7b
comparison
equal deleted inserted replaced
949:efc27fd4efed 950:de1e10c4da3c
25 #include "video_out.h" 25 #include "video_out.h"
26 #include "video_out_internal.h" 26 #include "video_out_internal.h"
27 #include "fastmemcpy.h" 27 #include "fastmemcpy.h"
28 #include "sub.h" 28 #include "sub.h"
29 #include "yuv2rgb.h" 29 #include "yuv2rgb.h"
30 extern void rgb15to16_mmx(char *s0, char *d0, int count);
31 30
32 LIBVO_EXTERN(fbdev) 31 LIBVO_EXTERN(fbdev)
33 32
34 static vo_info_t vo_info = { 33 static vo_info_t vo_info = {
35 "Framebuffer Device", 34 "Framebuffer Device",
36 "fbdev", 35 "fbdev",
37 "Szabolcs Berecz <szabi@inf.elte.hu>", 36 "Szabolcs Berecz <szabi@inf.elte.hu>",
38 "" 37 ""
39 }; 38 };
40 39
40 extern void rgb15to16_mmx(char *s0, char *d0, int count);
41 extern int verbose; 41 extern int verbose;
42 42
43 /****************************** 43 /******************************
44 * fb.modes support * 44 * fb.modes support *
45 ******************************/ 45 ******************************/
46
47 /*
48 * read the fb.modes manual page!
49 */
50 46
51 typedef struct { 47 typedef struct {
52 char *name; 48 char *name;
53 uint32_t xres, yres, vxres, vyres, depth; 49 uint32_t xres, yres, vxres, vyres, depth;
54 uint32_t pixclock, left, right, upper, lower, hslen, vslen; 50 uint32_t pixclock, left, right, upper, lower, hslen, vslen;
105 for (i = 0; i < num; i++) { 101 for (i = 0; i < num; i++) {
106 while (isspace(line[line_pos])) 102 while (isspace(line[line_pos]))
107 ++line_pos; 103 ++line_pos;
108 if (line[line_pos] == '\0' || line[line_pos] == '#') { 104 if (line[line_pos] == '\0' || line[line_pos] == '#') {
109 read_nextline = 1; 105 read_nextline = 1;
110 if (i == num)
111 goto out_ok;
112 goto out_eol; 106 goto out_eol;
113 } 107 }
114 token[i] = line + line_pos; 108 token[i] = line + line_pos;
115 c = line[line_pos]; 109 c = line[line_pos];
116 if (c == '"' || c == '\'') { 110 if (c == '"' || c == '\'') {
117 token[i]++; 111 token[i]++;
118 while (line[++line_pos] != c && line[line_pos]) 112 while (line[++line_pos] != c && line[line_pos])
119 /* NOTHING */; 113 /* NOTHING */;
114 if (!line[line_pos])
115 goto out_eol;
116 line[line_pos] = ' ';
120 } else { 117 } else {
121 for (/* NOTHING */; !isspace(line[line_pos]) && 118 for (/* NOTHING */; !isspace(line[line_pos]) &&
122 line[line_pos]; line_pos++) 119 line[line_pos]; line_pos++)
123 /* NOTHING */; 120 /* NOTHING */;
124 } 121 }
126 read_nextline = 1; 123 read_nextline = 1;
127 if (i == num - 1) 124 if (i == num - 1)
128 goto out_ok; 125 goto out_ok;
129 goto out_eol; 126 goto out_eol;
130 } 127 }
131 line[line_pos] = '\0'; 128 line[line_pos++] = '\0';
132 line_pos++;
133 } 129 }
134 out_ok: 130 out_ok:
135 return i; 131 return i;
136 out_eof: 132 out_eof:
137 return RET_EOF; 133 return RET_EOF;
146 { 142 {
147 fb_mode_t *mode = NULL; 143 fb_mode_t *mode = NULL;
148 char *endptr; // strtoul()... 144 char *endptr; // strtoul()...
149 int tmp, i; 145 int tmp, i;
150 146
151 #ifdef DEBUG 147 if (verbose > 0)
152 assert(cfgfile != NULL); 148 printf("Reading %s: ", cfgfile);
153 #endif
154
155 printf("Reading %s: ", cfgfile);
156 149
157 if ((fp = fopen(cfgfile, "r")) == NULL) { 150 if ((fp = fopen(cfgfile, "r")) == NULL) {
158 printf("can't open '%s': %s\n", cfgfile, strerror(errno)); 151 printf("can't open '%s': %s\n", cfgfile, strerror(errno));
159 return -1; 152 return -1;
160 } 153 }
182 if (!validate_mode(mode)) 175 if (!validate_mode(mode))
183 goto err_out_not_valid; 176 goto err_out_not_valid;
184 loop_enter: 177 loop_enter:
185 if (!(fb_modes = (fb_mode_t *) realloc(fb_modes, 178 if (!(fb_modes = (fb_mode_t *) realloc(fb_modes,
186 sizeof(fb_mode_t) * (nr_modes + 1)))) { 179 sizeof(fb_mode_t) * (nr_modes + 1)))) {
187 printf("can't realloc 'fb_modes': %s\n", strerror(errno)); 180 printf("can't realloc 'fb_modes' (nr_modes = %d):"
181 " %s\n", nr_modes, strerror(errno));
188 goto err_out; 182 goto err_out;
189 } 183 }
190 mode=fb_modes + nr_modes; 184 mode=fb_modes + nr_modes;
191 ++nr_modes; 185 ++nr_modes;
192 memset(mode,0,sizeof(fb_mode_t)); 186 memset(mode,0,sizeof(fb_mode_t));
244 goto err_out_parse_error; 238 goto err_out_parse_error;
245 mode->vslen = strtoul(token[6], &endptr, 0); 239 mode->vslen = strtoul(token[6], &endptr, 0);
246 if (*endptr) 240 if (*endptr)
247 goto err_out_parse_error; 241 goto err_out_parse_error;
248 } else if (!strcmp(token[0], "endmode")) { 242 } else if (!strcmp(token[0], "endmode")) {
249 /* NOTHING for now*/ 243 /* FIXME NOTHING for now*/
250 } else if (!strcmp(token[0], "accel")) { 244 } else if (!strcmp(token[0], "accel")) {
251 if (get_token(1) < 0) 245 if (get_token(1) < 0)
252 goto err_out_parse_error; 246 goto err_out_parse_error;
253 /* 247 /*
254 * it's only used for text acceleration 248 * it's only used for text acceleration
312 goto err_out_parse_error; 306 goto err_out_parse_error;
313 } 307 }
314 if (!validate_mode(mode)) 308 if (!validate_mode(mode))
315 goto err_out_not_valid; 309 goto err_out_not_valid;
316 out: 310 out:
317 printf("%d modes\n", nr_modes); 311 if (verbose > 0)
312 printf("%d modes\n", nr_modes);
318 free(line); 313 free(line);
319 fclose(fp); 314 fclose(fp);
320 return nr_modes; 315 return nr_modes;
321 err_out_parse_error: 316 err_out_parse_error:
322 printf("parse error"); 317 printf("parse error");
330 nr_modes = 0; 325 nr_modes = 0;
331 free(line); 326 free(line);
332 free(fp); 327 free(fp);
333 return -2; 328 return -2;
334 err_out_not_valid: 329 err_out_not_valid:
335 printf("mode is not definied correctly"); 330 printf("previous mode is not correct");
336 goto err_out_print_linenum; 331 goto err_out_print_linenum;
337 } 332 }
338 333
339 static fb_mode_t *find_mode_by_name(char *name) 334 static fb_mode_t *find_mode_by_name(char *name)
340 { 335 {
382 int i; 377 int i;
383 fb_mode_t *best = fb_modes; 378 fb_mode_t *best = fb_modes;
384 fb_mode_t *curr; 379 fb_mode_t *curr;
385 380
386 /* find first working mode */ 381 /* find first working mode */
387 for (i = nr_modes - 1; i; i--, best++) { 382 for (i = 0; i < nr_modes; i++, best++)
388 if (in_range(hfreq, hsf(best)) && in_range(vfreq, vsf(best)) && 383 if (in_range(hfreq, hsf(best)) && in_range(vfreq, vsf(best)) &&
389 in_range(dotclock, dcf(best))) 384 in_range(dotclock, dcf(best)))
390 break; 385 break;
391 if (verbose > 1) 386
392 printf(FBDEV "can't set %dx%d\n", best->xres, best->yres); 387 if (i == nr_modes)
393 }
394
395 if (!i)
396 return NULL; 388 return NULL;
397 if (i == 1) 389 if (i == nr_modes - 1)
398 return best; 390 return best;
399 391
400 for (curr = best + 1; i; i--, curr++) { 392 if (verbose > 1)
401 if (!in_range(hfreq, hsf(curr))) 393 printf(FBDEV "%dx%d\n", best->xres, best->yres);
402 continue; 394
403 if (!in_range(vfreq, vsf(curr))) 395 for (curr = best + 1; i < nr_modes; i++, curr++) {
404 continue; 396 if (!in_range(hfreq, hsf(curr)) ||
405 if (!in_range(dotclock, dcf(curr))) 397 !in_range(vfreq, vsf(curr)) ||
398 !in_range(dotclock, dcf(curr)))
406 continue; 399 continue;
407 if (verbose > 1) 400 if (verbose > 1)
408 printf(FBDEV "%dx%d ", curr->xres, curr->yres); 401 printf(FBDEV "%dx%d ", curr->xres, curr->yres);
409 if ((best->xres < xres || best->yres < yres) && 402 if ((best->xres < xres || best->yres < yres) &&
410 (curr->xres > best->xres || 403 (curr->xres > best->xres ||
436 static void set_bpp(struct fb_var_screeninfo *p, int bpp) 429 static void set_bpp(struct fb_var_screeninfo *p, int bpp)
437 { 430 {
438 p->bits_per_pixel = (bpp + 1) & ~1; 431 p->bits_per_pixel = (bpp + 1) & ~1;
439 p->red.msb_right = p->green.msb_right = p->blue.msb_right = 0; 432 p->red.msb_right = p->green.msb_right = p->blue.msb_right = 0;
440 p->transp.offset = p->transp.length = 0; 433 p->transp.offset = p->transp.length = 0;
434 p->blue.offset = 0;
441 switch (bpp) { 435 switch (bpp) {
442 case 32: 436 case 32:
443 p->transp.offset = 24; 437 p->transp.offset = 24;
444 p->transp.length = 8; 438 p->transp.length = 8;
445 case 24: 439 case 24:
446 p->red.offset = 16; 440 p->red.offset = 16;
447 p->red.length = 8; 441 p->red.length = 8;
448 p->green.offset = 8; 442 p->green.offset = 8;
449 p->green.length = 8; 443 p->green.length = 8;
450 p->blue.length = 8; 444 p->blue.length = 8;
451 p->blue.offset = 0;
452 break; 445 break;
453 case 16: 446 case 16:
454 p->red.offset = 11; 447 p->red.offset = 11;
455 p->green.length = 6; 448 p->green.length = 6;
456 p->red.length = 5; 449 p->red.length = 5;
457 p->green.offset = 5; 450 p->green.offset = 5;
458 p->blue.length = 5; 451 p->blue.length = 5;
459 p->blue.offset = 0;
460 break; 452 break;
461 case 15: 453 case 15:
462 p->red.offset = 10; 454 p->red.offset = 10;
463 p->green.length = 5; 455 p->green.length = 5;
464 p->red.length = 5; 456 p->red.length = 5;
465 p->green.offset = 5; 457 p->green.offset = 5;
466 p->blue.length = 5; 458 p->blue.length = 5;
467 p->blue.offset = 0;
468 break; 459 break;
469 } 460 }
470 } 461 }
471 462
472 static void fb_mode2fb_vinfo(fb_mode_t *m, struct fb_var_screeninfo *v) 463 static void fb_mode2fb_vinfo(fb_mode_t *m, struct fb_var_screeninfo *v)
490 static range_t *str2range(char *s) 481 static range_t *str2range(char *s)
491 { 482 {
492 float tmp_min, tmp_max; 483 float tmp_min, tmp_max;
493 char *endptr = s; // to start the loop 484 char *endptr = s; // to start the loop
494 range_t *r = NULL; 485 range_t *r = NULL;
495 int i, j; 486 int i;
496 487
497 if (!s) 488 if (!s)
498 return NULL; 489 return NULL;
499 for (i = 0; *endptr; i++) { 490 for (i = 0; *endptr; i++) {
500 if (*s == ',') 491 if (*s == ',')
526 tmp_max = tmp_min; 517 tmp_max = tmp_min;
527 } else 518 } else
528 goto out_err; 519 goto out_err;
529 r[i].min = tmp_min; 520 r[i].min = tmp_min;
530 r[i].max = tmp_max; 521 r[i].max = tmp_max;
522 if (r[i].min < 0 || r[i].max < 0)
523 goto out_err;
531 s = endptr + 1; 524 s = endptr + 1;
532 } 525 }
533 /* check if we have negative numbers... */
534 for (j = 0; j < i; j++)
535 if (r[j].min < 0 || r[j].max < 0)
536 goto out_err;
537 r[i].min = r[i].max = -1; 526 r[i].min = r[i].max = -1;
538 return r; 527 return r;
539 out_err: 528 out_err:
540 if (r) 529 if (r)
541 free(r); 530 free(r);
558 range_t *monitor_hfreq = NULL; 547 range_t *monitor_hfreq = NULL;
559 range_t *monitor_vfreq = NULL; 548 range_t *monitor_vfreq = NULL;
560 range_t *monitor_dotclock = NULL; 549 range_t *monitor_dotclock = NULL;
561 static fb_mode_t *fb_mode = NULL; 550 static fb_mode_t *fb_mode = NULL;
562 551
552 /* vt related variables */
553 int vt_fd;
554 FILE *vt_fp;
555 int vt_doit = 1;
556
563 /* vo_fbdev related variables */ 557 /* vo_fbdev related variables */
564 static int fb_preinit_done = 0;
565 static int fb_works = 0;
566 static int fb_dev_fd; 558 static int fb_dev_fd;
567 static size_t fb_size; 559 static size_t fb_size;
568 static uint8_t *frame_buffer; 560 static uint8_t *frame_buffer;
569 static uint8_t *L123123875; /* thx .so :) */ 561 static uint8_t *L123123875; /* thx .so :) */
570 static struct fb_fix_screeninfo fb_finfo; 562 static struct fb_fix_screeninfo fb_finfo;
574 static int fb_cmap_changed = 0; 566 static int fb_cmap_changed = 0;
575 static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2 567 static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2
576 static int fb_real_bpp; // 32: 24 24: 24 16: 16 15: 15 568 static int fb_real_bpp; // 32: 24 24: 24 16: 16 15: 15
577 static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15 569 static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15
578 static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15 570 static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15
579 static int fb_screen_width; 571 static int fb_line_len;
572 static int fb_xres;
573 static int fb_yres;
580 static void (*draw_alpha_p)(int w, int h, unsigned char *src, 574 static void (*draw_alpha_p)(int w, int h, unsigned char *src,
581 unsigned char *srca, int stride, unsigned char *dst, 575 unsigned char *srca, int stride, unsigned char *dst,
582 int dstride); 576 int dstride);
583 577
584 static uint8_t *next_frame; 578 static uint8_t *next_frame;
585 static int in_width; 579 static int in_width;
586 static int in_height; 580 static int in_height;
587 static int out_width; 581 static int out_width;
588 static int out_height; 582 static int out_height;
583 static int first_row;
584 static int last_row;
589 static uint32_t pixel_format; 585 static uint32_t pixel_format;
590 static int fs; 586 static int fs;
591 static int flip; 587 static int flip;
592 588
593 /* 589 /*
661 return cmap; 657 return cmap;
662 } 658 }
663 659
664 static int fb_preinit(void) 660 static int fb_preinit(void)
665 { 661 {
662 static int fb_preinit_done = 0;
663 static int fb_works = 0;
664
665 if (fb_preinit_done)
666 return fb_works;
667
666 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) 668 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
667 fb_dev_name = "/dev/fb0"; 669 fb_dev_name = "/dev/fb0";
668 if (verbose > 0) 670 if (verbose > 0)
669 printf(FBDEV "using %s\n", fb_dev_name); 671 printf(FBDEV "using %s\n", fb_dev_name);
670 672
694 fb_bpp = vo_dbpp; 696 fb_bpp = vo_dbpp;
695 } 697 }
696 698
697 fb_preinit_done = 1; 699 fb_preinit_done = 1;
698 fb_works = 1; 700 fb_works = 1;
699 return 0; 701 return 1;
700 err_out_fd: 702 err_out_fd:
701 close(fb_dev_fd); 703 close(fb_dev_fd);
702 fb_dev_fd = -1; 704 fb_dev_fd = -1;
703 err_out: 705 err_out:
704 fb_preinit_done = 1; 706 fb_preinit_done = 1;
705 return 1; 707 fb_works = 0;
708 return 0;
706 } 709 }
707 710
708 static void lots_of_printf(void) 711 static void lots_of_printf(void)
709 { 712 {
710 if (verbose > 0) { 713 if (verbose > 0) {
764 printf(FBDEV "ywrapstep: %u\n", fb_finfo.ywrapstep); 767 printf(FBDEV "ywrapstep: %u\n", fb_finfo.ywrapstep);
765 printf(FBDEV "mmio_start: %p\n", (void *) fb_finfo.mmio_start); 768 printf(FBDEV "mmio_start: %p\n", (void *) fb_finfo.mmio_start);
766 printf(FBDEV "mmio_len: %u bytes\n", fb_finfo.mmio_len); 769 printf(FBDEV "mmio_len: %u bytes\n", fb_finfo.mmio_len);
767 printf(FBDEV "accel: %u\n", fb_finfo.accel); 770 printf(FBDEV "accel: %u\n", fb_finfo.accel);
768 } 771 }
769 } 772 printf(FBDEV "fb_bpp: %d\n", fb_bpp);
773 printf(FBDEV "fb_real_bpp: %d\n", fb_real_bpp);
774 printf(FBDEV "fb_pixel_size: %d bytes\n", fb_pixel_size);
775 printf(FBDEV "other:\n");
776 printf(FBDEV "in_width: %d\n", in_width);
777 printf(FBDEV "in_height: %d\n", in_height);
778 printf(FBDEV "out_width: %d\n", out_width);
779 printf(FBDEV "out_height: %d\n", out_height);
780 printf(FBDEV "first_row: %d\n", first_row);
781 printf(FBDEV "last_row: %d\n", last_row);
782 if (verbose > 1)
783 printf(FBDEV "draw_alpha_p:%dbpp = %p\n", fb_bpp, draw_alpha_p);
784 }
785 }
786
787 static void vt_set_textarea(int u, int l)
788 {
789 /* how can I determine the font height?
790 * just use 16 for now
791 */
792 int urow = ((u + 15) / 16) + 1;
793 int lrow = l / 16;
794
795 if (verbose > 1)
796 printf(FBDEV "vt_set_textarea(%d,%d): %d,%d\n", u, l, urow, lrow);
797 fprintf(vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0);
798 fflush(vt_fp);
770 } 799 }
771 800
772 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, 801 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width,
773 uint32_t d_height, uint32_t fullscreen, char *title, 802 uint32_t d_height, uint32_t fullscreen, char *title,
774 uint32_t format) 803 uint32_t format)
775 { 804 {
776 #define FS (fullscreen & 0x01)
777 #define VM (fullscreen & 0x02)
778 #define ZOOM (fullscreen & 0x04)
779 #define FLIP (fullscreen & 0x08)
780
781 struct fb_cmap *cmap; 805 struct fb_cmap *cmap;
782 806 int vm = fullscreen & 0x02;
783 fs = FS; 807 int zoom = fullscreen & 0x04;
784 if (!fb_preinit_done) 808
785 if (fb_preinit()) 809 fs = fullscreen & 0x01;
786 return 1; 810 flip = fullscreen & 0x08;
787 if (!fb_works) 811
812 if (!fb_preinit())
788 return 1; 813 return 1;
789 814
790 flip = FLIP; 815 if (zoom) {
791
792 if (ZOOM) {
793 printf(FBDEV "-zoom is not supported\n"); 816 printf(FBDEV "-zoom is not supported\n");
794 return 1; 817 return 1;
795 } 818 }
796 if (fb_mode_name && !VM) { 819 if (fb_mode_name && !vm) {
797 printf(FBDEV "-fbmode can be used only with -vm" 820 printf(FBDEV "-fbmode can only be used with -vm\n");
798 " (is it the right behaviour?)\n");
799 return 1; 821 return 1;
800 } 822 }
801 if (VM) 823 if (vm && (parse_fbmode_cfg(fb_mode_cfgfile) < 0))
802 if (parse_fbmode_cfg(fb_mode_cfgfile) < 0)
803 return 1; 824 return 1;
804 if (d_width && (fs || VM)) { 825 if (d_width && (fs || vm)) {
805 out_width = d_width; 826 out_width = d_width;
806 out_height = d_height; 827 out_height = d_height;
807 } else { 828 } else {
808 out_width = width; 829 out_width = width;
809 out_height = height; 830 out_height = height;
816 if (!(fb_mode = find_mode_by_name(fb_mode_name))) { 837 if (!(fb_mode = find_mode_by_name(fb_mode_name))) {
817 printf(FBDEV "can't find requested video mode\n"); 838 printf(FBDEV "can't find requested video mode\n");
818 return 1; 839 return 1;
819 } 840 }
820 fb_mode2fb_vinfo(fb_mode, &fb_vinfo); 841 fb_mode2fb_vinfo(fb_mode, &fb_vinfo);
821 } else if (VM) { 842 } else if (vm) {
822 monitor_hfreq = str2range(monitor_hfreq_str); 843 monitor_hfreq = str2range(monitor_hfreq_str);
823 monitor_vfreq = str2range(monitor_vfreq_str); 844 monitor_vfreq = str2range(monitor_vfreq_str);
824 monitor_dotclock = str2range(monitor_dotclock_str); 845 monitor_dotclock = str2range(monitor_dotclock_str);
825 if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) { 846 if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) {
826 printf(FBDEV "you have to specify the capabilities of" 847 printf(FBDEV "you have to specify the capabilities of"
844 865
845 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { 866 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
846 printf(FBDEV "Can't put VSCREENINFO: %s\n", strerror(errno)); 867 printf(FBDEV "Can't put VSCREENINFO: %s\n", strerror(errno));
847 return 1; 868 return 1;
848 } 869 }
870
871 fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
872 fb_real_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
873 fb_vinfo.blue.length;
874 fb_bpp = (fb_pixel_size == 4) ? 32 : fb_real_bpp;
875 if (fb_bpp_we_want != fb_bpp)
876 printf(FBDEV "requested %d bpp, got %d bpp)!!!\n",
877 fb_bpp_we_want, fb_bpp);
878
879 switch (fb_bpp) {
880 case 32:
881 draw_alpha_p = vo_draw_alpha_rgb32;
882 break;
883 case 24:
884 draw_alpha_p = vo_draw_alpha_rgb24;
885 break;
886 case 16:
887 draw_alpha_p = vo_draw_alpha_rgb16;
888 break;
889 case 15:
890 draw_alpha_p = vo_draw_alpha_rgb15;
891 break;
892 }
893
894 if (flip & ((((pixel_format & 0xff) + 7) / 8) != fb_pixel_size)) {
895 printf(FBDEV "Flipped output with depth conversion is not "
896 "supported\n");
897 return 1;
898 }
899
900 fb_xres = fb_vinfo.xres;
901 fb_yres = fb_vinfo.yres;
902
903 if (vm || fs) {
904 out_width = fb_xres;
905 out_height = fb_yres;
906 }
907 if (out_width < in_width || out_height < in_height) {
908 printf(FBDEV "screensize is smaller than video size\n");
909 return 1;
910 }
911
912 first_row = (out_height - in_height) / 2;
913 last_row = (out_height + in_height) / 2;
914
849 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) { 915 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
850 printf(FBDEV "Can't get FSCREENINFO: %s\n", strerror(errno)); 916 printf(FBDEV "Can't get FSCREENINFO: %s\n", strerror(errno));
851 return 1; 917 return 1;
852 } 918 }
853 919
886 printf(FBDEV "visual: %d not yet supported\n", 952 printf(FBDEV "visual: %d not yet supported\n",
887 fb_finfo.visual); 953 fb_finfo.visual);
888 return 1; 954 return 1;
889 } 955 }
890 956
891 if (VM || fs) { 957 fb_line_len = fb_finfo.line_length;
892 out_width = fb_vinfo.xres;
893 out_height = fb_vinfo.yres;
894 }
895 if (out_width < in_width || out_height < in_height) {
896 printf(FBDEV "screensize is smaller than video size\n");
897 return 1;
898 }
899
900 fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
901 fb_real_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
902 fb_vinfo.blue.length;
903 fb_bpp = (fb_pixel_size == 4) ? 32 : fb_real_bpp;
904 if (fb_bpp_we_want != fb_bpp)
905 printf(FBDEV "requested %d bpp, got %d bpp)!!!\n",
906 fb_bpp_we_want, fb_bpp);
907 fb_screen_width = fb_finfo.line_length;
908 fb_size = fb_finfo.smem_len; 958 fb_size = fb_finfo.smem_len;
909 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, 959 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE,
910 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { 960 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) {
911 printf(FBDEV "Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); 961 printf(FBDEV "Can't mmap %s: %s\n", fb_dev_name, strerror(errno));
912 return 1; 962 return 1;
913 } 963 }
914 L123123875 = frame_buffer + (out_width - in_width) * fb_pixel_size / 964 L123123875 = frame_buffer + (out_width - in_width) * fb_pixel_size /
915 2 + (out_height - in_height) * fb_screen_width / 2; 965 2 + (out_height - in_height) * fb_line_len / 2;
916 966
917 if (verbose > 0) { 967 if (verbose > 0) {
918 printf(FBDEV "other:\n");
919 if (verbose > 1) { 968 if (verbose > 1) {
920 printf(FBDEV "frame_buffer @ %p\n", frame_buffer); 969 printf(FBDEV "frame_buffer @ %p\n", frame_buffer);
921 printf(FBDEV "L123123875 @ %p\n", L123123875); 970 printf(FBDEV "L123123875 @ %p\n", L123123875);
922 } 971 }
923 printf(FBDEV "fb_bpp: %d\n", fb_bpp); 972 printf(FBDEV "pixel per line: %d\n", fb_line_len / fb_pixel_size);
924 printf(FBDEV "fb_real_bpp: %d\n", fb_real_bpp); 973 }
925 printf(FBDEV "fb_pixel_size: %d bytes\n", fb_pixel_size);
926 printf(FBDEV "pixel per line: %d\n", fb_screen_width / fb_pixel_size);
927 }
928
929 switch (fb_bpp) {
930 case 32:
931 draw_alpha_p = vo_draw_alpha_rgb32;
932 break;
933 case 24:
934 draw_alpha_p = vo_draw_alpha_rgb24;
935 break;
936 case 16:
937 draw_alpha_p = vo_draw_alpha_rgb16;
938 break;
939 case 15:
940 draw_alpha_p = vo_draw_alpha_rgb15;
941 break;
942 }
943 if (verbose > 1)
944 printf(FBDEV "draw_alpha_p:%dbpp = %p\n", fb_bpp, draw_alpha_p);
945 974
946 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * fb_pixel_size))) { 975 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * fb_pixel_size))) {
947 printf(FBDEV "Can't malloc next_frame: %s\n", strerror(errno)); 976 printf(FBDEV "Can't malloc next_frame: %s\n", strerror(errno));
948 return 1; 977 return 1;
949 } 978 }
950 979
951 if (flip & (((pixel_format & 0xff) + 7) / 8) != fb_pixel_size) { 980 if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) {
952 printf(FBDEV "Flipped output with depth conversion is not " 981 printf(FBDEV "can't open /dev/tty: %s\n", strerror(errno));
953 "supported\n"); 982 vt_doit = 0;
954 return 1; 983 }
955 } 984 if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) {
985 printf(FBDEV "can't fdopen /dev/tty: %s\n", strerror(errno));
986 vt_doit = 0;
987 }
988
989 if (vt_doit)
990 vt_set_textarea(last_row, fb_yres);
991
992 if (fs || vm)
993 memset(frame_buffer, '\0', fb_line_len * fb_yres);
994
956 if (format == IMGFMT_YV12) 995 if (format == IMGFMT_YV12)
957 yuv2rgb_init(fb_bpp, MODE_RGB); 996 yuv2rgb_init(fb_bpp, MODE_RGB);
997
958 return 0; 998 return 0;
959 } 999 }
960 1000
961 static uint32_t query_format(uint32_t format) 1001 static uint32_t query_format(uint32_t format)
962 { 1002 {
963 int ret = 0x4; /* osd/sub is supported on every bpp */ 1003 int ret = 0x4; /* osd/sub is supported on every bpp */
964 1004
965 if (!fb_preinit_done) 1005 if (!fb_preinit())
966 if (fb_preinit())
967 return 0;
968 if (!fb_works)
969 return 0; 1006 return 0;
970 1007
971 if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { 1008 if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
972 int bpp = format & 0xff; 1009 int bpp = format & 0xff;
973 1010
1057 int i, out_offset = 0, in_offset = 0; 1094 int i, out_offset = 0, in_offset = 0;
1058 1095
1059 for (i = 0; i < in_height; i++) { 1096 for (i = 0; i < in_height; i++) {
1060 memcpy(L123123875 + out_offset, next_frame + in_offset, 1097 memcpy(L123123875 + out_offset, next_frame + in_offset,
1061 in_width * fb_pixel_size); 1098 in_width * fb_pixel_size);
1062 out_offset += fb_screen_width; 1099 out_offset += fb_line_len;
1063 in_offset += in_width * fb_pixel_size; 1100 in_offset += in_width * fb_pixel_size;
1064 } 1101 }
1065 } 1102 }
1066 1103
1067 static void flip_page(void) 1104 static void flip_page(void)
1085 printf(FBDEV "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); 1122 printf(FBDEV "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));
1086 fb_orig_vinfo.xoffset = fb_vinfo.xoffset; 1123 fb_orig_vinfo.xoffset = fb_vinfo.xoffset;
1087 fb_orig_vinfo.yoffset = fb_vinfo.yoffset; 1124 fb_orig_vinfo.yoffset = fb_vinfo.yoffset;
1088 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo)) 1125 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo))
1089 printf(FBDEV "Can't reset original fb_var_screeninfo: %s\n", strerror(errno)); 1126 printf(FBDEV "Can't reset original fb_var_screeninfo: %s\n", strerror(errno));
1127 if (vt_doit)
1128 vt_set_textarea(0, fb_orig_vinfo.yres);
1090 close(fb_dev_fd); 1129 close(fb_dev_fd);
1091 munmap(frame_buffer, fb_size); 1130 munmap(frame_buffer, fb_size);
1092 } 1131 }