summaryrefslogtreecommitdiffstats
path: root/libvo/vo_fbdev.c
diff options
context:
space:
mode:
authorwm4 <wm4@mplayer2.org>2012-07-28 20:20:17 +0200
committerwm4 <wm4@mplayer2.org>2012-07-28 20:44:59 +0200
commit16145ff43fd92947cb8fe301ebce46e7be52a9fb (patch)
tree5a5ade633d922f416d3b1c7c68e8aff878da9a8f /libvo/vo_fbdev.c
parentf03eed6469e34a5bff975ed43292016a621296ea (diff)
downloadmpv-16145ff43fd92947cb8fe301ebce46e7be52a9fb.tar.bz2
mpv-16145ff43fd92947cb8fe301ebce46e7be52a9fb.tar.xz
libvo, libao: remove useless video and audio output drivers
Some of these have only limited use, and some of these have no use at all. Remove them. They make maintainance harder and nobody needs them. It's possible that many of the removed drivers were very useful a dozen of years ago, but now it's 2012. Note that some of these could be added back, in case they were more useful than I thought. But right now, they are just a burden. Reason for removal for each module: vo_3dfx, vo_dfbmga, vo_dxr3, vo_ivtv, vo_mga, vo_s3fb, vo_tdfxfb, vo_xmga, vo_tdfx_vid: All of these are for very specific and outdated hardware. Some of them require non-standard kernel drivers or do direct HW access. vo_dga: the most crappy and ancient way to get fast output on X. vo_aa: there's vo_caca for the same purpose. vo_ggi: this never lived, and is entirely useless. vo_mpegpes: for DVB cards, I can't test this and it's crappy. vo_fbdev, vo_fbdev2: there's vo_directfb2 vo_bl: what is this even? But it's neither important, nor alive. vo_svga, vo_vesa: you want to use this? You can't be serious. vo_wii: I can't test this, and who the hell uses this? vo_xvr100: some Sun thing. vo_xover: only useful in connection with xvr100. ao_nas: still alive, but I doubt it has any meaning today. ao_sun: Sun. ao_win32: use ao_dsound or ao_portaudio instead. ao_ivtv: removed along vo_ivtv. Also get rid of anything SDL related. SDL 1.x is total crap for video output, and will be replaced with SDL 2.x soon (perhaps), so if you want to use SDL, write output drivers for SDL 2.x. Additionally, I accidentally damaged Sun support, which made me completely remove Sun/Solaris support. Nobody cares about this anyway. Some left overs from previous commits removing modules were cleaned up.
Diffstat (limited to 'libvo/vo_fbdev.c')
-rw-r--r--libvo/vo_fbdev.c1091
1 files changed, 0 insertions, 1091 deletions
diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c
deleted file mode 100644
index 6d70cca0fe..0000000000
--- a/libvo/vo_fbdev.c
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*
- * video driver for framebuffer device
- * copyright (C) 2001 Szabolcs Berecz <szabi@inf.elte.hu>
- *
- * Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27
- * Some fixes and small improvements by Joey Parrish <joey@nicewarrior.org>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/kd.h>
-#include <linux/fb.h>
-#include <libavutil/common.h>
-
-#include "config.h"
-#include "video_out.h"
-#include "video_out_internal.h"
-#include "fastmemcpy.h"
-#include "sub/sub.h"
-#include "geometry.h"
-#include "aspect.h"
-#include "mp_msg.h"
-
-static const vo_info_t info = {
- "Framebuffer Device",
- "fbdev",
- "Szabolcs Berecz <szabi@inf.elte.hu>",
- ""
-};
-
-LIBVO_EXTERN(fbdev)
-
-static signed int pre_init_err = -2;
-/******************************
- * fb.modes support *
- ******************************/
-
-static range_t *monitor_hfreq = NULL;
-static range_t *monitor_vfreq = NULL;
-static range_t *monitor_dotclock = NULL;
-
-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 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) {
- mp_msg(MSGT_VO, MSGL_V, "needs geometry ");
- return 0;
- }
- if (!m->pixclock) {
- mp_msg(MSGT_VO, MSGL_V, "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) {
- mp_msg(MSGT_VO, MSGL_V, "get_token(): max >= MAX_NR_TOKEN!\n");
- 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;
- 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 */;
- if (!line[line_pos])
- goto out_eol;
- line[line_pos] = ' ';
- } 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';
- }
-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)
-{
-#define CHECK_IN_MODE_DEF\
- if (!in_mode_def) {\
- mp_msg(MSGT_VO, MSGL_V, "'needs 'mode' first");\
- goto err_out_print_linenum;\
- }
- fb_mode_t *mode = NULL;
- char *endptr; // strtoul()...
- int in_mode_def = 0;
- int tmp, i;
-
- /* If called more than once, reuse parsed data */
- if (nr_modes)
- return nr_modes;
-
- mp_msg(MSGT_VO, MSGL_V, "Reading %s: ", cfgfile);
-
- if ((fp = fopen(cfgfile, "r")) == NULL) {
- mp_msg(MSGT_VO, MSGL_V, "can't open '%s': %s\n", cfgfile, strerror(errno));
- return -1;
- }
-
- if ((line = malloc(MAX_LINE_LEN + 1)) == NULL) {
- mp_msg(MSGT_VO, MSGL_V, "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 (in_mode_def) {
- mp_msg(MSGT_VO, MSGL_V, "'endmode' required");
- goto err_out_print_linenum;
- }
- if (!validate_mode(mode))
- goto err_out_not_valid;
- loop_enter:
- if (!(fb_modes =
- realloc(fb_modes, sizeof(fb_mode_t) * (nr_modes + 1)))) {
- mp_msg(MSGT_VO, MSGL_V, "can't realloc 'fb_modes' (nr_modes = %d):"
- " %s\n", nr_modes, 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)) {
- mp_msg(MSGT_VO, MSGL_V, "mode name '%s' isn't unique", token[0]);
- goto err_out_print_linenum;
- }
- }
- if (!(mode->name = strdup(token[0]))) {
- mp_msg(MSGT_VO, MSGL_V, "can't strdup -> 'name': %s\n", strerror(errno));
- goto err_out;
- }
- in_mode_def = 1;
- } else if (!strcmp(token[0], "geometry")) {
- CHECK_IN_MODE_DEF;
- 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")) {
- CHECK_IN_MODE_DEF;
- 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")) {
- CHECK_IN_MODE_DEF;
- in_mode_def = 0;
- } else if (!strcmp(token[0], "accel")) {
- CHECK_IN_MODE_DEF;
- if (get_token(1) < 0)
- goto err_out_parse_error;
- /*
- * it's only used for text acceleration
- * so we just ignore it.
- */
- } else if (!strcmp(token[0], "hsync")) {
- CHECK_IN_MODE_DEF;
- 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")) {
- CHECK_IN_MODE_DEF;
- 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")) {
- CHECK_IN_MODE_DEF;
- 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")) {
- CHECK_IN_MODE_DEF;
- 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")) {
- CHECK_IN_MODE_DEF;
- 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], "double")) {
- CHECK_IN_MODE_DEF;
- 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:
- mp_msg(MSGT_VO, MSGL_V, "%d modes\n", nr_modes);
- free(line);
- fclose(fp);
- return nr_modes;
-err_out_parse_error:
- mp_msg(MSGT_VO, MSGL_V, "parse error");
-err_out_print_linenum:
- mp_msg(MSGT_VO, MSGL_V, " at line %d\n", line_num);
-err_out:
- free(fb_modes);
- fb_modes = NULL;
- nr_modes = 0;
- free(line);
- free(fp);
- return -2;
-err_out_not_valid:
- mp_msg(MSGT_VO, MSGL_V, "previous mode is not correct");
- 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;
-}
-
-static float dcf(fb_mode_t *m) //driving clock frequency
-{
- return 1e12f / m->pixclock;
-}
-
-static float hsf(fb_mode_t *m) //horizontal scan frequency
-{
- int htotal = m->left + m->xres + m->right + m->hslen;
- return dcf(m) / htotal;
-}
-
-static float vsf(fb_mode_t *m) //vertical scan frequency
-{
- int vtotal = m->upper + m->yres + m->lower + m->vslen;
- return hsf(m) / vtotal;
-}
-
-
-static int mode_works(fb_mode_t *m, range_t *hfreq, range_t *vfreq,
- range_t *dotclock)
-{
- float h = hsf(m);
- float v = vsf(m);
- float d = dcf(m);
- int ret = 1;
-
- mp_msg(MSGT_VO, MSGL_DBG2, "mode %dx%d:", m->xres, m->yres);
- if (!in_range(hfreq, h)) {
- ret = 0;
- mp_msg(MSGT_VO, MSGL_DBG2, " hsync out of range.");
- }
- if (!in_range(vfreq, v)) {
- ret = 0;
- mp_msg(MSGT_VO, MSGL_DBG2, " vsync out of range.");
- }
- if (!in_range(dotclock, d)) {
- ret = 0;
- mp_msg(MSGT_VO, MSGL_DBG2, " dotclock out of range.");
- }
- if (ret)
- mp_msg(MSGT_VO, MSGL_DBG2, " hsync, vsync, dotclock ok.\n");
- else
- mp_msg(MSGT_VO, MSGL_DBG2, "\n");
-
- return ret;
-}
-
-static fb_mode_t *find_best_mode(int xres, int yres, range_t *hfreq,
- range_t *vfreq, range_t *dotclock)
-{
- int i;
- fb_mode_t *best = fb_modes;
- fb_mode_t *curr;
-
- mp_msg(MSGT_VO, MSGL_DBG2, "Searching for first working mode\n");
-
- for (i = 0; i < nr_modes; i++, best++)
- if (mode_works(best, hfreq, vfreq, dotclock))
- break;
-
- if (i == nr_modes)
- return NULL;
- if (i == nr_modes - 1)
- return best;
-
- mp_msg(MSGT_VO, MSGL_DBG2, "First working mode: %dx%d\n", best->xres, best->yres);
- mp_msg(MSGT_VO, MSGL_DBG2, "Searching for better modes\n");
-
- for (curr = best + 1; i < nr_modes - 1; i++, curr++) {
- if (!mode_works(curr, hfreq, vfreq, dotclock))
- continue;
-
- if (best->xres < xres || best->yres < yres) {
- if (curr->xres > best->xres || curr->yres > best->yres) {
- mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too small.\n",
- best->xres, best->yres);
- best = curr;
- } else
- mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n");
- } else if (curr->xres == best->xres && curr->yres == best->yres &&
- vsf(curr) > vsf(best)) {
- mp_msg(MSGT_VO, MSGL_DBG2, "faster screen refresh.\n");
- best = curr;
- } else if ((curr->xres <= best->xres && curr->yres <= best->yres) &&
- (curr->xres >= xres && curr->yres >= yres)) {
- mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too large.\n",
- best->xres, best->yres);
- best = curr;
- } else {
- if (curr->xres < xres || curr->yres < yres)
- mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n");
- else if (curr->xres > best->xres || curr->yres > best->yres)
- mp_msg(MSGT_VO, MSGL_DBG2, "too large.\n");
- else
- mp_msg(MSGT_VO, MSGL_DBG2, "it's worse, don't know why.\n");
- }
- }
-
- return best;
-}
-
-static void set_bpp(struct fb_var_screeninfo *p, int bpp, int rgb)
-{
- p->bits_per_pixel = FFALIGN(bpp, 2);
- p->red.msb_right = p->green.msb_right = p->blue.msb_right = p->transp.msb_right = 0;
- p->transp.offset = p->transp.length = 0;
- p->blue.offset = 0;
- switch (bpp) {
- case 32:
- p->transp.offset = 24;
- p->transp.length = 8;
- case 24:
- p->red.offset = 16;
- p->red.length = 8;
- p->green.offset = 8;
- p->green.length = 8;
- p->blue.length = 8;
- break;
- case 16:
- p->red.offset = 11;
- p->green.length = 6;
- p->red.length = 5;
- p->green.offset = 5;
- p->blue.length = 5;
- break;
- case 15:
- p->red.offset = 10;
- p->green.length = 5;
- p->red.length = 5;
- p->green.offset = 5;
- p->blue.length = 5;
- break;
- case 12:
- p->red.offset = 8;
- p->green.length = 4;
- p->red.length = 4;
- p->green.offset = 4;
- p->blue.length = 4;
- break;
- }
- if (rgb) {
- p->blue.offset = p->red.offset;
- p->red.offset = 0;
- }
-}
-
-static void fb_mode2fb_vinfo(fb_mode_t *m, struct fb_var_screeninfo *v, int rgb)
-{
- v->xres = m->xres;
- v->yres = m->yres;
- v->xres_virtual = m->vxres;
- v->yres_virtual = m->vyres;
- set_bpp(v, m->depth, rgb);
- v->pixclock = m->pixclock;
- v->left_margin = m->left;
- v->right_margin = m->right;
- v->upper_margin = m->upper;
- v->lower_margin = m->lower;
- v->hsync_len = m->hslen;
- v->vsync_len = m->vslen;
- v->sync = m->sync;
- v->vmode = m->vmode;
-}
-
-
-/******************************
-* vo_fbdev *
-******************************/
-
-/* command line/config file options */
-static char *fb_dev_name = NULL;
-char *fb_mode_cfgfile = NULL;
-char *fb_mode_name = NULL;
-
-static fb_mode_t *fb_mode = NULL;
-
-/* vo_fbdev related variables */
-static int fb_dev_fd;
-static int fb_tty_fd = -1;
-static size_t fb_size;
-static uint8_t *frame_buffer;
-static uint8_t *center;
-static struct fb_fix_screeninfo fb_finfo;
-static struct fb_var_screeninfo fb_orig_vinfo;
-static struct fb_var_screeninfo fb_vinfo;
-static unsigned short fb_ored[256], fb_ogreen[256], fb_oblue[256];
-static struct fb_cmap fb_oldcmap = { 0, 256, fb_ored, fb_ogreen, fb_oblue };
-static int fb_cmap_changed = 0;
-static int fb_rgb;
-static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2
-static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15
-static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15
-static int fb_line_len;
-static int fb_xres;
-static int fb_yres;
-static int fb_page;
-static void (*draw_alpha_p)(int w, int h, unsigned char *src,
- unsigned char *srca, int stride,
- unsigned char *dst, int dstride);
-
-static int in_width;
-static int in_height;
-static int out_width;
-static int out_height;
-static int first_row;
-static int last_row;
-static uint32_t pixel_format;
-static int fs;
-
-/*
- * Note: this function is completely cut'n'pasted from
- * Chris Lawrence's code.
- * (modified a bit to fit in my code...)
- */
-static struct fb_cmap *make_directcolor_cmap(struct fb_var_screeninfo *var)
-{
- /* Hopefully any DIRECTCOLOR device will have a big enough palette
- * to handle mapping the full color depth.
- * e.g. 8 bpp -> 256 entry palette
- *
- * We could handle some sort of gamma here
- */
- int i, cols, rcols, gcols, bcols;
- uint16_t *red, *green, *blue;
- struct fb_cmap *cmap;
-
- rcols = 1 << var->red.length;
- gcols = 1 << var->green.length;
- bcols = 1 << var->blue.length;
-
- /* Make our palette the length of the deepest color */
- cols = FFMAX3(rcols, gcols, bcols);
-
- red = malloc(cols * sizeof(red[0]));
- if (!red) {
- mp_msg(MSGT_VO, MSGL_V, "Can't allocate red palette with %d entries.\n", cols);
- return NULL;
- }
- for (i = 0; i < rcols; i++)
- red[i] = (65535 / (rcols - 1)) * i;
-
- green = malloc(cols * sizeof(green[0]));
- if (!green) {
- mp_msg(MSGT_VO, MSGL_V, "Can't allocate green palette with %d entries.\n", cols);
- free(red);
- return NULL;
- }
- for (i = 0; i < gcols; i++)
- green[i] = (65535 / (gcols - 1)) * i;
-
- blue = malloc(cols * sizeof(blue[0]));
- if (!blue) {
- mp_msg(MSGT_VO, MSGL_V, "Can't allocate blue palette with %d entries.\n", cols);
- free(red);
- free(green);
- return NULL;
- }
- for (i = 0; i < bcols; i++)
- blue[i] = (65535 / (bcols - 1)) * i;
-
- cmap = malloc(sizeof(struct fb_cmap));
- if (!cmap) {
- mp_msg(MSGT_VO, MSGL_V, "Can't allocate color map\n");
- free(red);
- free(green);
- free(blue);
- return NULL;
- }
- cmap->start = 0;
- cmap->transp = 0;
- cmap->len = cols;
- cmap->red = red;
- cmap->blue = blue;
- cmap->green = green;
- cmap->transp = NULL;
-
- return cmap;
-}
-
-
-static int fb_preinit(int reset)
-{
- static int fb_preinit_done = 0;
- static int fb_works = 0;
-
- if (reset) {
- fb_preinit_done = 0;
- return 0;
- }
-
- if (fb_preinit_done)
- return fb_works;
-
- fb_dev_fd = fb_tty_fd = -1;
-
- if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
- fb_dev_name = strdup("/dev/fb0");
- mp_msg(MSGT_VO, MSGL_V, "using %s\n", fb_dev_name);
-
- if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) {
- mp_msg(MSGT_VO, MSGL_ERR, "Can't open %s: %s\n", fb_dev_name, strerror(errno));
- goto err_out;
- }
- if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
- mp_msg(MSGT_VO, MSGL_ERR, "Can't get VSCREENINFO: %s\n", strerror(errno));
- goto err_out;
- }
- fb_orig_vinfo = fb_vinfo;
-
- if ((fb_tty_fd = open("/dev/tty", O_RDWR)) < 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "notice: Can't open /dev/tty: %s\n", strerror(errno));
- }
-
- fb_rgb = !fb_vinfo.red.offset;
- fb_bpp = fb_vinfo.bits_per_pixel;
- if (fb_bpp == 16)
- fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + fb_vinfo.blue.length;
-
- if (fb_bpp == 8 && !vo_dbpp) {
- mp_msg(MSGT_VO, MSGL_ERR, "8 bpp output is not supported.\n");
- goto err_out;
- }
-
- if (vo_dbpp) {
- if (vo_dbpp != 12 && vo_dbpp != 15 && vo_dbpp != 16
- && vo_dbpp != 24 && vo_dbpp != 32) {
- mp_msg(MSGT_VO, MSGL_ERR, "can't switch to %d bpp\n", vo_dbpp);
- goto err_out;
- }
- fb_bpp = vo_dbpp;
- }
-
- if (!fb_mode_cfgfile)
- fb_mode_cfgfile = strdup("/etc/fb.modes");
-
- fb_preinit_done = 1;
- fb_works = 1;
- return 1;
-err_out:
- if (fb_tty_fd != -1)
- close(fb_tty_fd);
- fb_tty_fd = -1;
- if (fb_dev_fd != -1)
- close(fb_dev_fd);
- fb_dev_fd = -1;
- fb_preinit_done = 1;
- fb_works = 0;
- return 0;
-}
-
-static void vt_set_textarea(int u, int l)
-{
- /* how can I determine the font height?
- * just use 16 for now
- */
- int urow = ((u + 15) / 16) + 1;
- int lrow = l / 16;
-
- mp_msg(MSGT_VO, MSGL_DBG2, "vt_set_textarea(%d,%d): %d,%d\n", u, l, urow, lrow);
- if (fb_tty_fd >= 0) {
- char modestring[100];
- snprintf(modestring, sizeof(modestring), "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0);
- write(fb_tty_fd, modestring, strlen(modestring));
- fsync(fb_tty_fd);
- }
-}
-
-static int config(uint32_t width, uint32_t height, uint32_t d_width,
- uint32_t d_height, uint32_t flags, char *title,
- uint32_t format)
-{
- struct fb_cmap *cmap;
- int vm = flags & VOFLAG_MODESWITCHING;
-
- fs = flags & VOFLAG_FULLSCREEN;
-
- if (pre_init_err == -2) {
- mp_msg(MSGT_VO, MSGL_ERR, "Internal fatal error: config() was called before preinit()\n");
- return -1;
- }
-
- if (pre_init_err)
- return 1;
-
- if (fb_mode_name && !vm) {
- mp_msg(MSGT_VO, MSGL_ERR, "-fbmode can only be used with -vm\n");
- return 1;
- }
- if (vm && parse_fbmode_cfg(fb_mode_cfgfile) < 0)
- return 1;
- if (d_width && (fs || vm)) {
- out_width = d_width;
- out_height = d_height;
- } else {
- out_width = width;
- out_height = height;
- }
- in_width = width;
- in_height = height;
- pixel_format = format;
-
- if (fb_mode_name) {
- if (!(fb_mode = find_mode_by_name(fb_mode_name))) {
- mp_msg(MSGT_VO, MSGL_ERR, "can't find requested video mode\n");
- return 1;
- }
- fb_mode2fb_vinfo(fb_mode, &fb_vinfo, fb_rgb);
- } else if (vm) {
- monitor_hfreq = str2range(monitor_hfreq_str);
- monitor_vfreq = str2range(monitor_vfreq_str);
- monitor_dotclock = str2range(monitor_dotclock_str);
- if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) {
- mp_msg(MSGT_VO, MSGL_ERR, "you have to specify the capabilities of"
- " the monitor.\n");
- return 1;
- }
- if (!(fb_mode = find_best_mode(out_width, out_height, monitor_hfreq,
- monitor_vfreq, monitor_dotclock))) {
- mp_msg(MSGT_VO, MSGL_ERR, "can't find best video mode\n");
- return 1;
- }
- mp_msg(MSGT_VO, MSGL_V, "using mode %dx%d @ %.1fHz\n", fb_mode->xres,
- fb_mode->yres, vsf(fb_mode));
- fb_mode2fb_vinfo(fb_mode, &fb_vinfo, fb_rgb);
- }
- fb_bpp_we_want = fb_bpp;
- set_bpp(&fb_vinfo, fb_bpp, fb_rgb);
- fb_vinfo.xres_virtual = fb_vinfo.xres;
- fb_vinfo.yres_virtual = fb_vinfo.yres;
- fb_page = 0;
- if (vo_doublebuffering) {
- fb_vinfo.yres_virtual <<= 1;
- fb_vinfo.yoffset = 0;
- fb_page = 1; // start writing into the page we don't display
- }
-
- if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) {
- mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno));
- close(fb_tty_fd);
- fb_tty_fd = -1;
- }
-
- if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo))
- // Intel drivers fail if we request a transparency channel
- fb_vinfo.transp.length = fb_vinfo.transp.offset = 0;
- if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
- mp_msg(MSGT_VO, MSGL_ERR, "Can't put VSCREENINFO: %s\n", strerror(errno));
- if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "Can't restore text mode: %s\n", strerror(errno));
- }
- return 1;
- }
-
- fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
- fb_bpp = fb_vinfo.bits_per_pixel;
- if (fb_bpp == 16)
- fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + fb_vinfo.blue.length;
- if (fb_bpp_we_want != fb_bpp)
- mp_msg(MSGT_VO, MSGL_WARN, "requested %d bpp, got %d bpp!!!\n",
- fb_bpp_we_want, fb_bpp);
-
- switch (fb_bpp) {
- case 32:
- draw_alpha_p = vo_draw_alpha_rgb32;
- break;
- case 24:
- draw_alpha_p = vo_draw_alpha_rgb24;
- break;
- case 16:
- draw_alpha_p = vo_draw_alpha_rgb16;
- break;
- case 15:
- draw_alpha_p = vo_draw_alpha_rgb15;
- break;
- case 12:
- draw_alpha_p = vo_draw_alpha_rgb12;
- break;
- default:
- return 1;
- }
-
- fb_xres = fb_vinfo.xres;
- fb_yres = fb_vinfo.yres;
-
- if (vm || fs) {
- out_width = fb_xres;
- out_height = fb_yres;
- }
- if (out_width < in_width || out_height < in_height) {
- mp_msg(MSGT_VO, MSGL_ERR, "screensize is smaller than video size\n");
- return 1;
- }
-
- first_row = (out_height - in_height) / 2;
- last_row = (out_height + in_height) / 2;
-
- if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
- mp_msg(MSGT_VO, MSGL_ERR, "Can't get FSCREENINFO: %s\n", strerror(errno));
- return 1;
- }
-
- if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) {
- mp_msg(MSGT_VO, MSGL_ERR, "type %d not supported\n", fb_finfo.type);
- return 1;
- }
-
- switch (fb_finfo.visual) {
- case FB_VISUAL_TRUECOLOR:
- break;
- case FB_VISUAL_DIRECTCOLOR:
- mp_msg(MSGT_VO, MSGL_V, "creating cmap for directcolor\n");
- if (ioctl(fb_dev_fd, FBIOGETCMAP, &fb_oldcmap)) {
- mp_msg(MSGT_VO, MSGL_ERR, "can't get cmap: %s\n",
- strerror(errno));
- return 1;
- }
- if (!(cmap = make_directcolor_cmap(&fb_vinfo)))
- return 1;
- if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) {
- mp_msg(MSGT_VO, MSGL_ERR, "can't put cmap: %s\n",
- strerror(errno));
- return 1;
- }
- fb_cmap_changed = 1;
- free(cmap->red);
- free(cmap->green);
- free(cmap->blue);
- free(cmap);
- break;
- default:
- mp_msg(MSGT_VO, MSGL_ERR, "visual: %d not yet supported\n",
- fb_finfo.visual);
- return 1;
- }
-
- fb_line_len = fb_finfo.line_length;
- fb_size = fb_finfo.smem_len;
- if (vo_doublebuffering && fb_size < 2 * fb_yres * fb_line_len)
- {
- mp_msg(MSGT_VO, MSGL_WARN, "framebuffer too small for double-buffering, disabling\n");
- vo_doublebuffering = 0;
- fb_page = 0;
- }
-
- {
- int x_offset = 0, y_offset = 0;
- geometry(&x_offset, &y_offset, &out_width, &out_height, fb_xres, fb_yres);
-
- frame_buffer = mmap(0, fb_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fb_dev_fd, 0);
- if (frame_buffer == (uint8_t *) -1) {
- mp_msg(MSGT_VO, MSGL_ERR, "Can't mmap %s: %s\n", fb_dev_name, strerror(errno));
- return 1;
- }
-
- center = frame_buffer +
- ( (out_width - in_width) / 2 ) * fb_pixel_size +
- ( (out_height - in_height) / 2 ) * fb_line_len +
- x_offset * fb_pixel_size + y_offset * fb_line_len +
- fb_page * fb_yres * fb_line_len;
-
- mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer);
- mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center);
- mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size);
-
- if (fs || vm) {
- int clear_size = fb_line_len * fb_yres;
- if (vo_doublebuffering)
- clear_size <<= 1;
- memset(frame_buffer, 0, clear_size);
- }
- }
-
- vt_set_textarea(last_row, fb_yres);
-
- return 0;
-}
-
-static int query_format(uint32_t format)
-{
- if (!fb_preinit(0))
- return 0;
- if ((format & IMGFMT_BGR_MASK) == (fb_rgb ? IMGFMT_RGB : IMGFMT_BGR)) {
- int bpp = format & 0xff;
-
- if (bpp == fb_bpp)
- return VFCAP_ACCEPT_STRIDE | VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
- }
- return 0;
-}
-
-static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
- unsigned char *srca, int stride)
-{
- unsigned char *dst;
-
- dst = center + fb_line_len * y0 + fb_pixel_size * x0;
-
- (*draw_alpha_p)(w, h, src, srca, stride, dst, fb_line_len);
-}
-
-static int draw_frame(uint8_t *src[])
-{
- return 1;
-}
-
-static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
-{
- uint8_t *d;
-
- d = center + fb_line_len * y + fb_pixel_size * x;
-
- memcpy_pic2(d, src[0], w * fb_pixel_size, h, fb_line_len, stride[0], 1);
-
- return 0;
-}
-
-static void check_events(void)
-{
-}
-
-static void flip_page(void)
-{
- int next_page = !fb_page;
- int page_delta = next_page - fb_page;
- if (!vo_doublebuffering)
- return;
-
- fb_vinfo.yoffset = fb_page * fb_yres;
- ioctl(fb_dev_fd, FBIOPAN_DISPLAY, &fb_vinfo);
-
- center += page_delta * fb_yres * fb_line_len;
- fb_page = next_page;
-}
-
-static void dr