Exemple #1
0
static void uninit(void)
{
    if (fb_cmap_changed) {
        if (ioctl(fb_dev_fd, FBIOPUTCMAP, &fb_oldcmap))
            mp_msg(MSGT_VO, MSGL_WARN, "Can't restore original cmap\n");
        fb_cmap_changed = 0;
    }
    if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo))
        mp_msg(MSGT_VO, MSGL_WARN, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));
    fb_orig_vinfo.xoffset = fb_vinfo.xoffset;
    fb_orig_vinfo.yoffset = fb_vinfo.yoffset;
    if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo))
        mp_msg(MSGT_VO, MSGL_WARN, "Can't reset original fb_var_screeninfo: %s\n", strerror(errno));
    if (fb_tty_fd >= 0) {
        if (ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0)
            mp_msg(MSGT_VO, MSGL_WARN, "Can't restore text mode: %s\n", strerror(errno));
    }
    vt_set_textarea(0, fb_orig_vinfo.yres);
    close(fb_tty_fd);
    close(fb_dev_fd);
    if (frame_buffer)
        munmap(frame_buffer, fb_size);
    frame_buffer = NULL;
    fb_preinit(1);
}
Exemple #2
0
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;
}
Exemple #3
0
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_fix_screeninfo fb_finfo;
  uint32_t black = 0x00800080;
  long temp;
  int vt_fd;

  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;

  in_width  = width;
  in_height = height;

  out_width  = (d_width && fs) ? d_width  : width;
  out_height = (d_width && fs) ? d_height : height;

  fb_vinfo.xres_virtual = fb_vinfo.xres;
  fb_vinfo.yres_virtual = fb_vinfo.yres;

  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)) {
    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 = 2;

  if (fs) {
    out_width  = fb_vinfo.xres;
    out_height = fb_vinfo.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;
  }

  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;
  }

  fb_line_len = fb_finfo.line_length;
  fb_size     = fb_finfo.smem_len;

  frame_buffer = (uint8_t *) 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;

  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);

  /* blanking screen */
  for (temp = 0; temp < fb_size; temp += 4)
    memcpy(frame_buffer + temp, (void *) &black, 4);

  if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) {
    mp_msg(MSGT_VO, MSGL_ERR, "can't open /dev/tty: %s\n", strerror(errno));
    vt_doit = 0;
  }
  if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) {
    mp_msg(MSGT_VO, MSGL_ERR, "can't fdopen /dev/tty: %s\n", strerror(errno));
    vt_doit = 0;
  }

  if (vt_doit)
    vt_set_textarea((out_height + in_height) / 2, fb_vinfo.yres);

  return 0;
}