summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorgpoirier <gpoirier@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-06-13 07:57:06 +0000
committergpoirier <gpoirier@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-06-13 07:57:06 +0000
commit9f72c10255c1874b0fe7229f170f86ea3e1f6d91 (patch)
treebed02ed51f6be6a3487feecd61a6e46f064bf403 /libvo
parent70379a17db3eb870e2a69968bcbcf07550a2c5c6 (diff)
downloadmpv-9f72c10255c1874b0fe7229f170f86ea3e1f6d91.tar.bz2
mpv-9f72c10255c1874b0fe7229f170f86ea3e1f6d91.tar.xz
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
Diffstat (limited to 'libvo')
-rw-r--r--libvo/vo_s3fb.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/libvo/vo_s3fb.c b/libvo/vo_s3fb.c
index 8f9c7ceef7..8a07ae0764 100644
--- a/libvo/vo_s3fb.c
+++ b/libvo/vo_s3fb.c
@@ -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;