Fixes suggested by Ivo, and failure under non-root operation improved. Original patch by Mark Sanderson < mmp AH kiora P ath P cx > (reworked a bit to try to meet out commit policy).

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18693 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
gpoirier 2006-06-13 07:57:06 +00:00
parent 70379a17db
commit 9f72c10255
1 changed files with 46 additions and 30 deletions

View File

@ -39,6 +39,12 @@ static vo_info_t info =
LIBVO_EXTERN(s3fb)
typedef struct vga_type {
int cr38, cr39, cr53;
unsigned char *mmio;
} vga_t;
static vga_t *v = NULL;
static int fd = -1;
static struct fb_fix_screeninfo fb_finfo;
static struct fb_var_screeninfo fb_vinfo;
@ -80,12 +86,7 @@ static void clear_screen();
#define S3V_MMIO_REGSIZE 0x8000 /* 32KB */
#define S3_NEWMMIO_VGABASE (S3_NEWMMIO_REGBASE + 0x8000)
#define OUTREG(mmreg, value) *(unsigned int *)(&v.mmio[mmreg]) = value
typedef struct vga_type {
int cr38, cr39, cr53;
unsigned char *mmio;
} vga_t;
#define OUTREG(mmreg, value) *(unsigned int *)(&v->mmio[mmreg]) = value
int readcrtc(int reg) {
outb(reg, 0x3d4);
@ -97,36 +98,52 @@ void writecrtc(int reg, int value) {
outb(value, 0x3d5);
}
int enable(vga_t *v) {
// enable S3 registers
int enable() {
int fd;
// enable registers
if (iopl(3) != 0)
return 0;
if (v)
return 1;
errno = 0;
v = (vga_t *)malloc(sizeof(vga_t));
if (v) {
if (ioperm(0x3d4, 2, 1) == 0) {
fd = open("/dev/mem", O_RDWR);
if (fd != -1) {
v->mmio = mmap(0, S3_NEWMMIO_REGSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
S3_MEMBASE + S3_NEWMMIO_REGBASE);
close(fd);
if (v->mmio != MAP_FAILED) {
v->cr38 = readcrtc(0x38);
v->cr39 = readcrtc(0x39);
v->cr53 = readcrtc(0x53);
writecrtc(0x38, 0x48);
writecrtc(0x39, 0xa5);
writecrtc(0x53, 0x08);
fd = open("/dev/mem", O_RDWR);
v->mmio = mmap(0, S3_NEWMMIO_REGSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
S3_MEMBASE + S3_NEWMMIO_REGBASE);
close(fd);
return 1;
}
}
iopl(0);
}
free(v);
v = NULL;
}
}
void disable(vga_t *v) {
void disable() {
if (v) {
writecrtc(0x53, v->cr53);
writecrtc(0x39, v->cr39);
writecrtc(0x38, v->cr38);
iopl(0);
ioperm(0x3d4, 2, 0);
munmap(v->mmio, S3_NEWMMIO_REGSIZE);
free(v);
v = NULL;
}
}
int yuv_on(int format, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int crop, int xres, int yres, int line_length, int offset) {
int tmp, pitch, start, src_wc, src_hc, bpp;
vga_t v;
if (format == 0 || format == 7)
bpp = 4;
@ -151,9 +168,6 @@ int yuv_on(int format, int src_w, int src_h, int dst_x, int dst_y, int dst_w, in
// start is the top left viewable scaler input pixel
start = offset + crop * pitch + crop * bpp;
if (!enable(&v))
return 0;
OUTREG(COL_CHROMA_KEY_CONTROL_REG, 0x47000000);
OUTREG(CHROMA_KEY_UPPER_BOUND_REG, 0x0);
OUTREG(BLEND_CONTROL_REG, 0x00000020);
@ -192,18 +206,12 @@ int yuv_on(int format, int src_w, int src_h, int dst_x, int dst_y, int dst_w, in
writecrtc(0x67, readcrtc(0x67) | 0x4);
disable(&v);
return offset;
}
void yuv_off() {
vga_t v;
enable(&v);
writecrtc(0x67, readcrtc(0x67) & ~0xc);
memset(v.mmio + 0x8180, 0, 0x80);
memset(v->mmio + 0x8180, 0, 0x80);
OUTREG(0x81b8, 0x900);
OUTREG(0x81bc, 0x900);
OUTREG(0x81c8, 0x900);
@ -213,7 +221,6 @@ void yuv_off() {
OUTREG(0x81fc, 0x00010001);
writecrtc(0x92, 0);
writecrtc(0x93, 0);
disable(&v);
}
static int preinit(const char *arg)
@ -271,9 +278,17 @@ static int preinit(const char *arg)
return -1;
}
return 0;
if (!enable()) {
mp_msg(MSGT_VO, MSGL_FATAL, "s3fb: Couldn't map S3 registers: %s\n", strerror(errno));
close(fd);
fd = -1;
return -1;
}
return 0; // Success
}
/* And close our mess */
static void uninit(void)
{
if (inpage0) {
@ -282,12 +297,13 @@ static void uninit(void)
inpage0 = NULL;
}
/* And close our mess */
if(smem) {
munmap(smem, fb_finfo.smem_len);
smem = NULL;
}
disable();
if(fd != -1) {
close(fd);
fd = -1;