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