summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorszabii <szabii@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-04-11 20:52:56 +0000
committerszabii <szabii@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-04-11 20:52:56 +0000
commite4c07a314f6caada981582c3d43f886ba4ee3152 (patch)
treef99b384165b93a7ab25146367ac4d83266bfdc57 /libvo
parentfeb552b3de7f7c2e19ef30424f3b4d5d625a6115 (diff)
downloadmpv-e4c07a314f6caada981582c3d43f886ba4ee3152.tar.bz2
mpv-e4c07a314f6caada981582c3d43f886ba4ee3152.tar.xz
video mode change supported
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@360 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libvo')
-rw-r--r--libvo/vo_fbdev.c566
1 files changed, 443 insertions, 123 deletions
diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c
index cd241585ee..6549c85fd9 100644
--- a/libvo/vo_fbdev.c
+++ b/libvo/vo_fbdev.c
@@ -1,6 +1,7 @@
/*
* Video driver for Framebuffer device
* by Szabolcs Berecz <szabi@inf.elte.hu>
+ * (C) 2001
*
* Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27
*/
@@ -11,6 +12,8 @@
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
+#include <ctype.h>
+#include <assert.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
@@ -35,33 +38,334 @@ static vo_info_t vo_info = {
""
};
-static int vt_active = -1;
-static int vt_fd;
+/******************************
+* fb.modes parser *
+******************************/
+/*
+ * read the fb.modes manual page!
+ */
+
+typedef struct {
+ char *name;
+ uint32_t xres, yres, vxres, vyres, depth;
+ uint32_t pixclock, left, right, upper, lower, hslen, vslen;
+ uint32_t sync;
+ uint32_t vmode;
+} fb_mode_t;
+
+#define PRINT_LINENUM printf(" at line %d\n", line_num)
+
+#define MAX_NR_TOKEN 16
+
+#define MAX_LINE_LEN 1000
+
+#define RET_EOF -1
+#define RET_EOL -2
+
+static int validate_mode(fb_mode_t *m)
+{
+ if (!m->xres) {
+ printf("needs geometry ");
+ return 0;
+ }
+ if (!m->pixclock) {
+ printf("needs timings ");
+ return 0;
+ }
+ return 1;
+}
+
+static FILE *fp;
+static int line_num = 0;
+static char *line;
+static char *token[MAX_NR_TOKEN];
+
+static int get_token(int num)
+{
+ static int read_nextline = 1;
+ static int line_pos;
+ int i;
+ char c;
+
+ if (num >= MAX_NR_TOKEN) {
+ printf("get_token(): max >= MAX_NR_TOKEN!");
+ goto out_eof;
+ }
+
+ if (read_nextline) {
+ if (!fgets(line, MAX_LINE_LEN, fp))
+ goto out_eof;
+ line_pos = 0;
+ ++line_num;
+ read_nextline = 0;
+ }
+ for (i = 0; i < num; i++) {
+ while (isspace(line[line_pos]))
+ ++line_pos;
+ if (line[line_pos] == '\0' || line[line_pos] == '#') {
+ read_nextline = 1;
+ if (i == num)
+ goto out_ok;
+ goto out_eol;
+ }
+ token[i] = line + line_pos;
+ c = line[line_pos];
+ if (c == '"' || c == '\'') {
+ token[i]++;
+ while (line[++line_pos] != c && line[line_pos])
+ /* NOTHING */;
+ } else {
+ for (/* NOTHING */; !isspace(line[line_pos]) &&
+ line[line_pos]; line_pos++)
+ /* NOTHING */;
+ }
+ if (!line[line_pos]) {
+ read_nextline = 1;
+ if (i == num - 1)
+ goto out_ok;
+ goto out_eol;
+ }
+ line[line_pos] = '\0';
+ line_pos++;
+ }
+out_ok:
+ return i;
+out_eof:
+ return RET_EOF;
+out_eol:
+ return RET_EOL;
+}
+
+static fb_mode_t *fb_modes = NULL;
+static int nr_modes = 0;
+
+static int parse_fbmode_cfg(char *cfgfile)
+{
+ fb_mode_t *mode = NULL;
+ char *endptr; // strtoul()...
+ int tmp, i;
+
+#ifdef DEBUG
+ assert(cfgfile != NULL);
+#endif
+
+ printf("Reading %s: ", cfgfile);
+
+ if ((fp = fopen(cfgfile, "r")) == NULL) {
+ printf("can't open '%s': %s\n", cfgfile, strerror(errno));
+ return -1;
+ }
+
+ if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) {
+ printf("can't get memory for 'line': %s\n", strerror(errno));
+ return -2;
+ }
+
+ /*
+ * check if the cfgfile starts with 'mode'
+ */
+ while ((tmp = get_token(1)) == RET_EOL)
+ /* NOTHING */;
+ if (tmp == RET_EOF)
+ goto out;
+ if (!strcmp(token[0], "mode"))
+ goto loop_enter;
+ goto err_out_parse_error;
+
+ while ((tmp = get_token(1)) != RET_EOF) {
+ if (tmp == RET_EOL)
+ continue;
+ if (!strcmp(token[0], "mode")) {
+ if (!validate_mode(mode))
+ goto err_out_not_valid;
+ loop_enter:
+ if (!(fb_modes = (fb_mode_t *) realloc(fb_modes,
+ sizeof(fb_mode_t) * (nr_modes + 1)))) {
+ printf("can't realloc 'fb_modes': %s\n", strerror(errno));
+ goto err_out;
+ }
+ mode=fb_modes + nr_modes;
+ ++nr_modes;
+ memset(mode,0,sizeof(fb_mode_t));
+
+ if (get_token(1) < 0)
+ goto err_out_parse_error;
+ for (i = 0; i < nr_modes - 1; i++) {
+ if (!strcmp(token[0], fb_modes[i].name)) {
+ printf("mode name '%s' isn't unique", token[0]);
+ goto err_out_print_linenum;
+ }
+ }
+ if (!(mode->name = strdup(token[0]))) {
+ printf("can't strdup -> 'name': %s\n", strerror(errno));
+ goto err_out;
+ }
+ } else if (!strcmp(token[0], "geometry")) {
+ if (get_token(5) < 0)
+ goto err_out_parse_error;
+ mode->xres = strtoul(token[0], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->yres = strtoul(token[1], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->vxres = strtoul(token[2], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->vyres = strtoul(token[3], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->depth = strtoul(token[4], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ } else if (!strcmp(token[0], "timings")) {
+ if (get_token(7) < 0)
+ goto err_out_parse_error;
+ mode->pixclock = strtoul(token[0], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->left = strtoul(token[1], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->right = strtoul(token[2], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->upper = strtoul(token[3], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->lower = strtoul(token[4], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->hslen = strtoul(token[5], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ mode->vslen = strtoul(token[6], &endptr, 0);
+ if (*endptr)
+ goto err_out_parse_error;
+ } else if (!strcmp(token[0], "endmode")) {
+ /* NOTHING for now*/
+ } else if (!strcmp(token[0], "hsync")) {
+ if (get_token(1) < 0)
+ goto err_out_parse_error;
+ if (!strcmp(token[0], "low"))
+ mode->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+ else if(!strcmp(token[0], "high"))
+ mode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ else
+ goto err_out_parse_error;
+ } else if (!strcmp(token[0], "vsync")) {
+ if (get_token(1) < 0)
+ goto err_out_parse_error;
+ if (!strcmp(token[0], "low"))
+ mode->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+ else if(!strcmp(token[0], "high"))
+ mode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ else
+ goto err_out_parse_error;
+ } else if (!strcmp(token[0], "csync")) {
+ if (get_token(1) < 0)
+ goto err_out_parse_error;
+ if (!strcmp(token[0], "low"))
+ mode->sync &= ~FB_SYNC_COMP_HIGH_ACT;
+ else if(!strcmp(token[0], "high"))
+ mode->sync |= FB_SYNC_COMP_HIGH_ACT;
+ else
+ goto err_out_parse_error;
+ } else if (!strcmp(token[0], "extsync")) {
+ if (get_token(1) < 0)
+ goto err_out_parse_error;
+ if (!strcmp(token[0], "false"))
+ mode->sync &= ~FB_SYNC_EXT;
+ else if(!strcmp(token[0], "true"))
+ mode->sync |= FB_SYNC_EXT;
+ else
+ goto err_out_parse_error;
+ } else if (!strcmp(token[0], "laced")) {
+ if (get_token(1) < 0)
+ goto err_out_parse_error;
+ if (!strcmp(token[0], "false"))
+ mode->vmode = FB_VMODE_NONINTERLACED;
+ else if (!strcmp(token[0], "true"))
+ mode->vmode = FB_VMODE_INTERLACED;
+ else
+ goto err_out_parse_error;
+ } else if (!strcmp(token[0], "dblscan")) {
+ if (get_token(1) < 0)
+ goto err_out_parse_error;
+ if (!strcmp(token[0], "false"))
+ ;
+ else if (!strcmp(token[0], "true"))
+ mode->vmode = FB_VMODE_DOUBLE;
+ else
+ goto err_out_parse_error;
+ } else
+ goto err_out_parse_error;
+ }
+ if (!validate_mode(mode))
+ goto err_out_not_valid;
+out:
+ printf("%d modes\n", nr_modes);
+ free(line);
+ fclose(fp);
+ return nr_modes;
+err_out_parse_error:
+ printf("parse error");
+err_out_print_linenum:
+ PRINT_LINENUM;
+err_out:
+ if (fb_modes)
+ free(fb_modes);
+ free(line);
+ free(fp);
+ return -2;
+err_out_not_valid:
+ printf("mode is not definied correctly");
+ goto err_out_print_linenum;
+}
+
+static fb_mode_t *find_mode_by_name(char *name)
+{
+ int i;
+
+ for (i = 0; i < nr_modes; i++) {
+ if (!strcmp(name, fb_modes[i].name))
+ return fb_modes + i;
+ }
+ return NULL;
+}
+
+/******************************
+* vo_fbdev *
+******************************/
+
+static int fb_init_done = 0;
+static int fb_works = 0;
char *fb_dev_name = NULL;
static int fb_dev_fd;
static size_t fb_size;
static uint8_t *frame_buffer;
-static int fb_pixel_size;
-static int fb_bpp;
-static int fb_bpp_on_screen;
-struct fb_fix_screeninfo fb_fix_info;
-struct fb_var_screeninfo fb_var_info;
-static uint32_t fb_xres_virtual;
-static uint32_t fb_yres_virtual;
-static struct fb_cmap *oldcmap = NULL;
+static struct fb_fix_screeninfo fb_finfo;
+static struct fb_var_screeninfo fb_orig_vinfo;
+static struct fb_var_screeninfo fb_vinfo;
+static struct fb_cmap *fb_oldcmap = NULL;
+static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2
+static int fb_real_bpp; // 32: 24 24: 24 16: 16 15: 15
+static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15
+static int fb_screen_width;
+
+char *fb_mode_cfgfile = "/etc/fb.modes";
+char *fb_mode_name = NULL;
+static fb_mode_t *fb_mode = NULL;
+static int fb_switch_mode = 0;
+static uint8_t *next_frame;
static int in_width;
static int in_height;
static int out_width;
static int out_height;
-static uint8_t *next_frame;
-static int screen_width;
static uint32_t pixel_format;
-static int fb_init_done = 0;
-static int fb_works = 0;
-
/*
* Note: this function is completely cut'n'pasted from
* Chris Lawrence's code.
@@ -138,6 +442,16 @@ static int fb_init(void)
int fd;
struct fb_cmap *cmap;
+ if (fb_mode_name) {
+ if (parse_fbmode_cfg(fb_mode_cfgfile) < 0)
+ return 1;
+ if (!(fb_mode = find_mode_by_name(fb_mode_name))) {
+ printf("fb_init: can't find requested video mode\n");
+ return 1;
+ }
+ fb_switch_mode = 1;
+ }
+
if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
fb_dev_name = "/dev/fb0";
printf("fb_init: using %s\n", fb_dev_name);
@@ -147,28 +461,75 @@ static int fb_init(void)
goto err_out;
}
- if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_var_info)) {
+ if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno));
goto err_out_fd;
}
- /* disable scrolling */
- fb_xres_virtual = fb_var_info.xres_virtual;
- fb_yres_virtual = fb_var_info.yres_virtual;
- fb_var_info.xres_virtual = fb_var_info.xres;
- fb_var_info.yres_virtual = fb_var_info.yres;
+ fb_orig_vinfo = fb_vinfo;
+ if (fb_switch_mode) {
+ fb_vinfo.xres = fb_mode->xres;
+ fb_vinfo.yres = fb_mode->yres;
+ fb_vinfo.xres_virtual = fb_mode->vxres;
+ fb_vinfo.yres_virtual = fb_mode->vyres;
+ fb_vinfo.bits_per_pixel = fb_mode->depth;
+ switch (fb_mode->depth) {
+ case 32:
+ case 24:
+ fb_vinfo.red.offset = 16;
+ fb_vinfo.red.length = 8;
+ fb_vinfo.red.msb_right = 0;
+ fb_vinfo.green.offset = 8;
+ fb_vinfo.green.length = 8;
+ fb_vinfo.green.msb_right = 0;
+ fb_vinfo.blue.offset = 0;
+ fb_vinfo.blue.length = 8;
+ fb_vinfo.blue.msb_right = 0;
+ case 16:
+ fb_vinfo.red.offset = 11;
+ fb_vinfo.red.length = 5;
+ fb_vinfo.red.msb_right = 0;
+ fb_vinfo.green.offset = 5;
+ fb_vinfo.green.length = 6;
+ fb_vinfo.green.msb_right = 0;
+ fb_vinfo.blue.offset = 0;
+ fb_vinfo.blue.length = 5;
+ fb_vinfo.blue.msb_right = 0;
+ case 15:
+ fb_vinfo.red.offset = 10;
+ fb_vinfo.red.length = 5;
+ fb_vinfo.red.msb_right = 0;
+ fb_vinfo.green.offset = 5;
+ fb_vinfo.green.length = 5;
+ fb_vinfo.green.msb_right = 0;
+ fb_vinfo.blue.offset = 0;
+ fb_vinfo.blue.length = 5;
+ fb_vinfo.blue.msb_right = 0;
+ }
+ fb_vinfo.pixclock = fb_mode->pixclock;
+ fb_vinfo.left_margin = fb_mode->left;
+ fb_vinfo.right_margin = fb_mode->right;
+ fb_vinfo.upper_margin = fb_mode->upper;
+ fb_vinfo.lower_margin = fb_mode->lower;
+ fb_vinfo.hsync_len = fb_mode->hslen;
+ fb_vinfo.vsync_len = fb_mode->vslen;
+ fb_vinfo.sync = fb_mode->sync;
+ fb_vinfo.vmode = fb_mode->vmode;
+ }
+ fb_vinfo.xres_virtual = fb_vinfo.xres;
+ fb_vinfo.yres_virtual = fb_vinfo.yres;
- if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) {
+ if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
printf("fb_init: Can't put VSCREENINFO: %s\n", strerror(errno));
goto err_out_fd;
}
- if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_fix_info)) {
+ if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno));
goto err_out_fd;
return 1;
}
- switch (fb_fix_info.type) {
+ switch (fb_finfo.type) {
case FB_TYPE_VGA_PLANES:
printf("fb_init: FB_TYPE_VGA_PLANES not supported.\n");
goto err_out_fd;
@@ -192,17 +553,17 @@ static int fb_init(void)
printf("fb_init: FB_TYPE_PACKED_PIXELS: OK\n");
break;
default:
- printf("fb_init: unknown FB_TYPE: %d\n", fb_fix_info.type);
+ printf("fb_init: unknown FB_TYPE: %d\n", fb_finfo.type);
goto err_out_fd;
}
- if (fb_fix_info.visual == FB_VISUAL_DIRECTCOLOR) {
+ if (fb_finfo.visual == FB_VISUAL_DIRECTCOLOR) {
printf("fb_init: creating cmap for directcolor\n");
- if (ioctl(fb_dev_fd, FBIOGETCMAP, oldcmap)) {
+ if (ioctl(fb_dev_fd, FBIOGETCMAP, fb_oldcmap)) {
printf("fb_init: can't get cmap: %s\n",
strerror(errno));
goto err_out_fd;
}
- if (!(cmap = make_directcolor_cmap(&fb_var_info)))
+ if (!(cmap = make_directcolor_cmap(&fb_vinfo)))
goto err_out_fd;
if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) {
printf("fb_init: can't put cmap: %s\n",
@@ -213,18 +574,18 @@ static int fb_init(void)
free(cmap->green);
free(cmap->blue);
free(cmap);
- } else if (fb_fix_info.visual != FB_VISUAL_TRUECOLOR) {
+ } else if (fb_finfo.visual != FB_VISUAL_TRUECOLOR) {
printf("fb_init: visual: %d not yet supported\n",
- fb_fix_info.visual);
+ fb_finfo.visual);
goto err_out_fd;
}
- fb_pixel_size = fb_var_info.bits_per_pixel / 8;
- fb_bpp = fb_var_info.red.length + fb_var_info.green.length +
- fb_var_info.blue.length;
- fb_bpp_on_screen = (fb_pixel_size == 4) ? 32 : fb_bpp;
- screen_width = fb_fix_info.line_length;
- fb_size = fb_fix_info.smem_len;
+ fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
+ fb_real_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
+ fb_vinfo.blue.length;
+ fb_bpp = (fb_pixel_size == 4) ? 32 : fb_real_bpp;
+ fb_screen_width = fb_finfo.line_length;
+ fb_size = fb_finfo.smem_len;
if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) {
printf("fb_init: Can't mmap %s: %s\n", fb_dev_name, strerror(errno));
@@ -234,16 +595,16 @@ static int fb_init(void)
printf("fb_init: framebuffer @ %p\n", frame_buffer);
printf("fb_init: framebuffer size: %d bytes\n", fb_size);
printf("fb_init: bpp: %d\n", fb_bpp);
- printf("fb_init: bpp on screen: %d\n", fb_bpp_on_screen);
- printf("fb_init: pixel size: %d\n", fb_pixel_size);
- printf("fb_init: pixel per line: %d\n", screen_width / fb_pixel_size);
- printf("fb_init: visual: %d\n", fb_fix_info.visual);
- printf("fb_init: red: %d %d %d\n", fb_var_info.red.offset,
- fb_var_info.red.length, fb_var_info.red.msb_right);
- printf("fb_init: green: %d %d %d\n", fb_var_info.green.offset,
- fb_var_info.green.length, fb_var_info.green.msb_right);
- printf("fb_init: blue: %d %d %d\n", fb_var_info.blue.offset,
- fb_var_info.blue.length, fb_var_info.blue.msb_right);
+ printf("fb_init: real bpp: %d\n", fb_real_bpp);
+ printf("fb_init: pixel size: %d bytes\n", fb_pixel_size);
+ printf("fb_init: pixel per line: %d\n", fb_screen_width / fb_pixel_size);
+ printf("fb_init: visual: %d\n", fb_finfo.visual);
+ printf("fb_init: red: %d %d %d\n", fb_vinfo.red.offset,
+ fb_vinfo.red.length, fb_vinfo.red.msb_right);
+ printf("fb_init: green: %d %d %d\n", fb_vinfo.green.offset,
+ fb_vinfo.green.length, fb_vinfo.green.msb_right);
+ printf("fb_init: blue: %d %d %d\n", fb_vinfo.blue.offset,
+ fb_vinfo.blue.length, fb_vinfo.blue.msb_right);
fb_init_done = 1;
fb_works = 1;
@@ -277,8 +638,7 @@ static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width,
}
if (format == IMGFMT_YV12)
-// yuv2rgb_init(fb_pixel_size * 8, MODE_RGB);
- yuv2rgb_init(fb_bpp_on_screen, MODE_RGB);
+ yuv2rgb_init(fb_bpp, MODE_RGB);
return 0;
}
@@ -292,65 +652,16 @@ static uint32_t query_format(uint32_t format)
if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
int bpp = format & 0xff;
- if (bpp == fb_bpp_on_screen)
+ if (bpp == fb_bpp)
return 1;
- else if (bpp == 15 && fb_bpp_on_screen == 16)
+ else if (bpp == 15 && fb_bpp == 16)
return 1;
- else if (bpp == 24 && fb_bpp_on_screen == 32)
+ else if (bpp == 24 && fb_bpp == 32)
return 1;
}
if (format == IMGFMT_YV12)
return 1;
return 0;
-/*
- printf("vo_fbdev: query_format(%#x(%.4s)): ", format, &format);
- if (format & IMGFMT_BGR_MASK == IMGFMT_BGR)
- goto not_supported;
- switch (format) {
- case IMGFMT_YV12:
- goto supported;
-
- case IMGFMT_RGB32:
- if (fb_bpp == 32)
- goto supported;
- break;
- case IMGFMT_RGB24:
- if (fb_bpp == 24)
- goto supported;
- break;
- case IMGFMT_RGB16:
- if (fb_bpp == 16)
- goto supported;
- break;
- case IMGFMT_RGB15:
- if (fb_bpp == 15)
- goto supported;
- break;
-
- case IMGFMT_BGR|32:
- if (fb_bpp == 24 && fb_pixel_size == 4)
- goto supported;
- break;
- case IMGFMT_BGR|24:
- if (fb_bpp == 24 && fb_pixel_size == 3)
- goto supported;
- break;
- case IMGFMT_BGR|16:
- if (fb_bpp == 16)
- goto supported;
- break;
- case IMGFMT_BGR|15:
- if (fb_bpp == 15)
- goto supported;
- break;
- }
-not_supported:
- printf("not_supported\n");
- return 0;
-supported:
- printf("supported\n");
- return 1;
-*/
}
static const vo_info_t *get_info(void)
@@ -361,6 +672,24 @@ static const vo_info_t *get_info(void)
static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
unsigned char *srca, int stride)
{
+ uint8_t *dst = next_frame + (in_width * y0 + x0) * fb_pixel_size;
+ int dstride = in_width * fb_pixel_size;
+
+ switch (fb_real_bpp) {
+ case 24:
+ vo_draw_alpha_rgb24(w, h, src, srca, stride, dst, dstride);
+ break;
+ case 32:
+ vo_draw_alpha_rgb32(w, h, src, srca, stride, dst, dstride);
+ break;
+ case 15:
+ vo_draw_alpha_rgb15(w, h, src, srca, stride, dst, dstride);
+ break;
+ case 16:
+ vo_draw_alpha_rgb16(w, h, src, srca, stride, dst, dstride);
+ break;
+ }
+#if 0
int x, y;
uint8_t *dst;
@@ -379,6 +708,7 @@ static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
srca += stride;
}
// }
+#endif
}
static uint32_t draw_frame(uint8_t *src[])
@@ -392,7 +722,7 @@ static uint32_t draw_frame(uint8_t *src[])
char *d = next_frame;
char *s = src[0];
if (sbpp == fb_pixel_size) {
- if (fb_bpp == 16 && pixel_format == (IMGFMT_BGR|15)) {
+ if (fb_real_bpp == 16 && pixel_format == (IMGFMT_BGR|15)) {
#ifdef HAVE_MMX
rgb15to16_mmx(s, d, 2 * in_width * in_height);
#else
@@ -408,16 +738,6 @@ static uint32_t draw_frame(uint8_t *src[])
memcpy(d, s, sbpp * in_width * in_height);
}
}
-/*
- } else if ((pixel_format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
- if (pixel_format == fb_bpp_on_screen)
- memcpy(next_frame, src[0],
- in_width * in_height * fb_pixel_size);
- else {
-
- }
- }
-*/
return 0;
}
@@ -443,7 +763,7 @@ static void put_frame(void)
for (i = 0; i < in_height; i++) {
memcpy(frame_buffer + out_offset, next_frame + in_offset,
in_width * fb_pixel_size);
- out_offset += screen_width;
+ out_offset += fb_screen_width;
in_offset += in_width * fb_pixel_size;
}
}
@@ -458,22 +778,22 @@ static void flip_page(void)
static void uninit(void)
{
printf("vo_fbdev: uninit\n");
- if (oldcmap) {
- if (ioctl(fb_dev_fd, FBIOPUTCMAP, oldcmap))
+ if (fb_oldcmap) {
+ if (ioctl(fb_dev_fd, FBIOPUTCMAP, fb_oldcmap))
printf("vo_fbdev: Can't restore original cmap\n");
- oldcmap = NULL;
+ fb_oldcmap = NULL;
}
- fb_var_info.xres_virtual = fb_xres_virtual;
- fb_var_info.yres_virtual = fb_yres_virtual;
- if (fb_dev_fd != -1) {
- if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info))
- printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno));
- close(fb_dev_fd);
+ if (fb_switch_mode)
+ fb_vinfo = fb_orig_vinfo;
+ else {
+ fb_vinfo.xres_virtual = fb_orig_vinfo.xres_virtual;
+ fb_vinfo.yres_virtual = fb_orig_vinfo.yres_virtual;
}
+ if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo))
+ printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno));
+ close(fb_dev_fd);
memset(next_frame, '\0', in_height * in_width * fb_pixel_size);
put_frame();
- if (vt_active >= 0)
- ioctl(vt_fd, VT_ACTIVATE, vt_active);
free(next_frame);
munmap(frame_buffer, fb_size);
}