/* * Driver for Hauppage TV board * * Control commands: * * init * window %d %d %d %d * colorkey %d %d %d %d %d %d * capture %d %d %d %d * capbrightness %d * capcontrast %d * capsaturation %d * caphue %d * capbw %d * brightness %d * contrast %d * saturation %d * source %d * svideo %d * format %d * channel %d %d * signal * volume %d [ %d ] * bass %d * treble %d * freeze %d */#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "../port/error.h"#include "tv.h" #include <draw.h> enum { MemSize= 1, MemAddr= 0xB8000, CompressReg= -14, /* smart lock registers */ SLReg1= -2, SLReg2= -1, /* the Bt812 registers */ Bt812Index= -5, Bt812Data= -6, Bt2VideoPresent= 0x40, Bt4ColorBars= 0x40, Bt5YCFormat= 0x80, Bt7TriState= 0x0C, /* VxP 500 registers */ Vxp500Index= 0, Vxp500Data= 1, /* video controller registers */ MemoryWindowBaseAddrA= 0x14, MemoryWindowBaseAddrB= 0x15, MemoryPageReg= 0x16, MemoryConfReg= 0x18, ISAControl= 0x30, I2CControl= 0x34, InputVideoConfA= 0x38, InputVideoConfB= 0x39, ISASourceWindowWidthA= 0x3A, ISASourceWindowWidthB= 0x3B, ISASourceWindowHeightA= 0x3C, ISASourceWindowHeightB= 0x3D, InputHorzCropLeftA= 0x40, InputHorzCropLeftB= 0x41, InputHorzCropRightA= 0x44, InputHorzCropRightB= 0x45, InputHorzCropTopA= 0x48, InputHorzCropTopB= 0x49, InputHorzCropBottomA= 0x4C, InputHorzCropBottomB= 0x4D, InputHorzFilter= 0x50, InputHorzScaleControlA= 0x54, InputHorzScaleControlB= 0x55, InputVertInterpolControl= 0x58, InputVertScaleControlA= 0x5C, InputVertScaleControlB= 0x5D, InputFieldPixelBufStatus= 0x64, VideoInputFrameBufDepthA= 0x68, VideoInputFrameBufDepthB= 0x69, AcquisitionControl= 0x6C, AcquisitionAddrA= 0x70, AcquisitionAddrB= 0x71, AcquisitionAddrC= 0x72, VideoBufferLayoutControl= 0x73, CaptureControl= 0x80, CaptureViewPortAddrA= 0x81, CaptureViewPortAddrB= 0x82, CaptureViewPortAddrC= 0x83, CaptureViewPortWidthA= 0x84, CaptureViewPortWidthB= 0x85, CaptureViewPortHeightA= 0x86, CaptureViewPortHeightB= 0x87, CapturePixelBufLow= 0x88, CapturePixelBufHigh= 0x89, CaptureMultiBufDepthA= 0x8A, CaptureMultiBufDepthB= 0x8B, DisplayControl= 0x92, VGAControl= 0x94, OutputProcControlA= 0x96, OutputProcControlB= 0x97, DisplayViewPortStartAddrA= 0xA0, DisplayViewPortStartAddrB= 0xA1, DisplayViewPortStartAddrC= 0xA2, DisplayViewPortWidthA= 0xA4, DisplayViewPortWidthB= 0xA5, DisplayViewPortHeightA= 0xA6, DisplayViewPortHeightB= 0xA7, DisplayViewPortOrigTopA= 0xA8, DisplayViewPortOrigTopB= 0xA9, DisplayViewPortOrigLeftA= 0xAA, DisplayViewPortOrigLeftB= 0xAB, DisplayWindowLeftA= 0xB0, DisplayWindowLeftB= 0xB1, DisplayWindowRightA= 0xB4, DisplayWindowRightB= 0xB5, DisplayWindowTopA= 0xB8, DisplayWindowTopB= 0xB9, DisplayWindowBottomA= 0xBC, DisplayWindowBottomB= 0xBD, OutputVertZoomControlA= 0xC0, OutputVertZoomControlB= 0xC1, OutputHorzZoomControlA= 0xC4, OutputHorzZoomControlB= 0xC5, BrightnessControl= 0xC8, ContrastControl= 0xC9, SaturationControl= 0xCA, VideoOutIntrStatus= 0xD3, /* smart lock bits */ PixelClk= 0x03, SmartLock= 0x00, FeatureConnector= 0x01, Divider= 0x02, Window= 0x08, KeyWindow= 0x0C, HSyncLow= 0x20, VSyncLow= 0x40, ClkBit= 0x01, DataBit= 0x02, HoldBit= 0x04, SelBit= 0x08, DivControl= 0x40, /* i2c bus control bits */ I2C_Clock= 0x02, I2C_Data= 0x08, I2C_RdClock= 0x10, I2C_RdData= 0x20, I2C_RdData_D= 0x40, /* I2C bus addresses */ Adr5249= 0x22, /* teletext decoder */ Adr8444= 0x48, /* 6-bit DAC (TDA 8444) */ Adr6300= 0x80, /* sound fader (TEA 6300) */ Adr6320= 0x80, /* sound fader (TEA 6320T) */ AdrTuner= 0xC0, /* Philips audio chips */ TEA6300= 0, TEA6320T= 1, /* input formats */ NTSC_M = 0, NTSC_443 = 1, External = 2, NTSCCropLeft= 36, /* NTSC 3.6 usec */ NTSCCropRight= 558, /* NTSC 55.8 usec */ /* color control indices */ Vxp500Brightness= 1, Vxp500Contrast= 2, Vxp500Saturation= 3, Bt812Brightness= 4, Bt812Contrast= 5, Bt812Saturation= 6, Bt812Hue= 7, Bt812BW= 8, /* board revision numbers */ RevisionPP= 0, RevisionA= 1, HighQ= 2, /* VGA controller registers */ VGAMiscOut= 0x3CC, VGAIndex= 0x3D4, VGAData= 0x3D5, VGAHorzTotal= 0x00,}; enum { Qdir, Qdata, Qctl,}; staticDirtab tvtab[]={ ".", {Qdir, 0, QTDIR}, 0, 0555, "tv", {Qdata, 0}, 0, 0666, "tvctl", {Qctl, 0}, 0, 0666,}; staticint ports[] = { /* board addresses */ 0x51C, 0x53C, 0x55C, 0x57C, 0x59C, 0x5BC, 0x5DC, 0x5FC}; /* * Default settings, settings between 0..100 */staticint defaults[] = { Vxp500Brightness, 0, Vxp500Contrast, 54, Vxp500Saturation, 54, Bt812Brightness, 13, Bt812Contrast, 57, Bt812Saturation, 51, Bt812Hue, 0, Bt812BW, 0,}; static int port;static int soundchip;static int boardrev;static int left, right;static int vsync, hsync;static ulong xtalfreq;static ushort cropleft, cropright;static ushort cropbottom, croptop;static Rectangle window, capwindow; static void setreg(int, int);static void setbt812reg(int, int);static void videoinit(void);static void createwindow(Rectangle);static void setcontrols(int, uchar);static void setcolorkey(int, int, int, int, int, int);static void soundinit(void);static void setvolume(int, int);static void setbass(int);static void settreble(int);static void setsoundsource(int);static void tunerinit(void);static void settuner(int, int);static void setvideosource(int);static int waitvideosignal(void);static void freeze(int);static void setsvideo(int);static void setinputformat(int);static void enablevideo(void);static void *saveframe(int *); static intmin(int a, int b){ return a < b ? a : b;} static intmax(int a, int b){ return a < b ? b : a;} static intpresent(int port){ outb(port+Vxp500Index, 0xAA); if (inb(port+Vxp500Index) != 0xAA) return 0; outb(port+Vxp500Index, 0x55); outb(port+Vxp500Data, 0xAA); if (inb(port+Vxp500Index) != 0x55) return 0; if (inb(port+Vxp500Data) != 0xAA) return 0; outb(port+Vxp500Data, 0x55); if (inb(port+Vxp500Index) != 0x55) return 0; if (inb(port+Vxp500Data) != 0x55) return 0; return 1;} static intgetvsync(void){ int vslow, vshigh, s; ushort timo; s = splhi(); outb(port+Vxp500Index, VideoOutIntrStatus); /* wait for VSync to go high then low */ for (timo = ~0; timo; timo--) if (inb(port+Vxp500Data) & 2) break; for (timo = ~0; timo; timo--) if ((inb(port+Vxp500Data) & 2) == 0) break; /* count how long it stays low and how long it stays high */ for (vslow = 0, timo = ~0; timo; timo--, vslow++) if (inb(port+Vxp500Data) & 2) break; for (vshigh = 0, timo = ~0; timo; timo--, vshigh++) if ((inb(port+Vxp500Data) & 2) == 0) break; splx(s); return vslow < vshigh;} static intgethsync(void){ int hslow, hshigh, s; ushort timo; s = splhi(); outb(port+Vxp500Index, VideoOutIntrStatus); /* wait for HSync to go high then low */ for (timo = ~0; timo; timo--) if (inb(port+Vxp500Data) & 1) break; for (timo = ~0; timo; timo--) if ((inb(port+Vxp500Data) & 1) == 0) break; /* count how long it stays low and how long it stays high */ for (hslow = 0, timo = ~0; timo; timo--, hslow++) if (inb(port+Vxp500Data) & 1) break; for (hshigh = 0, timo = ~0; timo; timo--, hshigh++) if ((inb(port+Vxp500Data) & 1) == 0) break; splx(s); return hslow < hshigh;} static voidtvinit(void){ int i; for (i = 0, port = 0; i < nelem(ports); i++) { if (present(ports[i])) { port = ports[i]; break; } } if (i == nelem(ports)) return; /* * the following routines are the prefered way to * find out the sync polarities. Unfortunately, it * doesn't always work. */#ifndef VSync vsync = getvsync(); hsync = gethsync();#else vsync = VSync; hsync = HSync;#endif left = right = 80; soundinit(); tunerinit(); videoinit();} static Chan*tvattach(char *spec){ if (port == 0) error(Enonexist); return devattach('V', spec);} static Walkqid*tvwalk(Chan *c, Chan *nc, char **name, int nname){ return devwalk(c, nc, name, nname, tvtab, nelem(tvtab), devgen);} static inttvstat(Chan *c, uchar *db, int n){ return devstat(c, db, n, tvtab, nelem(tvtab), devgen);} static Chan*tvopen(Chan *c, int omode){ return devopen(c, omode, tvtab, nelem(tvtab), devgen);} static voidtvclose(Chan *){} static longtvread(Chan *c, void *a, long n, vlong offset){ static void *frame; static int size; USED(offset); switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, tvtab, nelem(tvtab), devgen); case Qdata: if (eqrect(capwindow, Rect(0, 0, 0, 0))) error(Ebadarg); if (offset == 0) frame = saveframe(&size); if (frame) { if (n > size - offset) n = size - offset; memmove(a, (char *)frame + offset, n); } else error(Enovmem); break; default: n=0; break; } return n;} static longtvwrite(Chan *c, void *vp, long n, vlong offset){ char buf[128], *field[10], *a; int i, nf, source; static Rectangle win; static int hsize, size = 0; static void *frame; USED(offset); a = vp; switch((ulong)c->qid.path){ case Qctl: if (n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = '\0'; nf = getfields(buf, field, nelem(field), 1, " \t"); if (nf < 1) error(Ebadarg); if (strcmp(field[0], "init") == 0) { window = Rect(0, 0, 0, 0); capwindow = Rect(0, 0, 0, 0); source = 0; /* video 0 input */ setvideosource(source); left = right = 80; setsoundsource(source); for (i = 0; i < nelem(defaults); i += 2) setcontrols(defaults[i], defaults[i+1]); } else if (strcmp(field[0], "colorkey") == 0) { if (nf < 7) error(Ebadarg); setcolorkey(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0), strtoul(field[3], 0, 0), strtoul(field[4], 0, 0), strtoul(field[5], 0, 0), strtoul(field[6], 0, 0)); } else if (strcmp(field[0], "window") == 0) { if (nf < 5) error(Ebadarg); createwindow(Rect(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0), strtoul(field[3], 0, 0), strtoul(field[4], 0, 0))); setvolume(left, right); } else if (strcmp(field[0], "capture") == 0) { if (nf < 5) error(Ebadarg); capwindow = Rect(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0), strtoul(field[3], 0, 0), strtoul(field[4], 0, 0)); } else if (strcmp(field[0], "freeze") == 0) { if (nf < 2) error(Ebadarg); freeze(strtoul(field[1], 0, 0)); } else if (strcmp(field[0], "capbrightness") == 0) { if (nf < 2) error(Ebadarg); setcontrols(Bt812Brightness, strtoul(field[1], 0, 0)); } else if (strcmp(field[0], "capcontrast") == 0) { if (nf < 2) error(Ebadarg); setcontrols(Bt812Contrast, strtoul(field[1], 0, 0)); } else if (strcmp(field[0], "capsaturation") == 0) {Lines 1–500 of 1826. Load more
/* * Driver for Hauppage TV board * * Control commands: * * init * window %d %d %d %d * colorkey %d %d %d %d %d %d * capture %d %d %d %d * capbrightness %d * capcontrast %d * capsaturation %d * caphue %d * capbw %d * brightness %d * contrast %d * saturation %d * source %d * svideo %d * format %d * channel %d %d * signal * volume %d [ %d ] * bass %d * treble %d * freeze %d */ #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "tv.h" #include <draw.h> enum { MemSize= 1, MemAddr= 0xB8000, CompressReg= -14, /* smart lock registers */ SLReg1= -2, SLReg2= -1, /* the Bt812 registers */ Bt812Index= -5, Bt812Data= -6, Bt2VideoPresent= 0x40, Bt4ColorBars= 0x40, Bt5YCFormat= 0x80, Bt7TriState= 0x0C, /* VxP 500 registers */ Vxp500Index= 0, Vxp500Data= 1, /* video controller registers */ MemoryWindowBaseAddrA= 0x14, MemoryWindowBaseAddrB= 0x15, MemoryPageReg= 0x16, MemoryConfReg= 0x18, ISAControl= 0x30, I2CControl= 0x34, InputVideoConfA= 0x38, InputVideoConfB= 0x39, ISASourceWindowWidthA= 0x3A, ISASourceWindowWidthB= 0x3B, ISASourceWindowHeightA= 0x3C, ISASourceWindowHeightB= 0x3D, InputHorzCropLeftA= 0x40, InputHorzCropLeftB= 0x41, InputHorzCropRightA= 0x44, InputHorzCropRightB= 0x45, InputHorzCropTopA= 0x48, InputHorzCropTopB= 0x49, InputHorzCropBottomA= 0x4C, InputHorzCropBottomB= 0x4D, InputHorzFilter= 0x50, InputHorzScaleControlA= 0x54, InputHorzScaleControlB= 0x55, InputVertInterpolControl= 0x58, InputVertScaleControlA= 0x5C, InputVertScaleControlB= 0x5D, InputFieldPixelBufStatus= 0x64, VideoInputFrameBufDepthA= 0x68, VideoInputFrameBufDepthB= 0x69, AcquisitionControl= 0x6C, AcquisitionAddrA= 0x70, AcquisitionAddrB= 0x71, AcquisitionAddrC= 0x72, VideoBufferLayoutControl= 0x73, CaptureControl= 0x80, CaptureViewPortAddrA= 0x81, CaptureViewPortAddrB= 0x82, CaptureViewPortAddrC= 0x83, CaptureViewPortWidthA= 0x84, CaptureViewPortWidthB= 0x85, CaptureViewPortHeightA= 0x86, CaptureViewPortHeightB= 0x87, CapturePixelBufLow= 0x88, CapturePixelBufHigh= 0x89, CaptureMultiBufDepthA= 0x8A, CaptureMultiBufDepthB= 0x8B, DisplayControl= 0x92, VGAControl= 0x94, OutputProcControlA= 0x96, OutputProcControlB= 0x97, DisplayViewPortStartAddrA= 0xA0, DisplayViewPortStartAddrB= 0xA1, DisplayViewPortStartAddrC= 0xA2, DisplayViewPortWidthA= 0xA4, DisplayViewPortWidthB= 0xA5, DisplayViewPortHeightA= 0xA6, DisplayViewPortHeightB= 0xA7, DisplayViewPortOrigTopA= 0xA8, DisplayViewPortOrigTopB= 0xA9, DisplayViewPortOrigLeftA= 0xAA, DisplayViewPortOrigLeftB= 0xAB, DisplayWindowLeftA= 0xB0, DisplayWindowLeftB= 0xB1, DisplayWindowRightA= 0xB4, DisplayWindowRightB= 0xB5, DisplayWindowTopA= 0xB8, DisplayWindowTopB= 0xB9, DisplayWindowBottomA= 0xBC, DisplayWindowBottomB= 0xBD, OutputVertZoomControlA= 0xC0, OutputVertZoomControlB= 0xC1, OutputHorzZoomControlA= 0xC4, OutputHorzZoomControlB= 0xC5, BrightnessControl= 0xC8, ContrastControl= 0xC9, SaturationControl= 0xCA, VideoOutIntrStatus= 0xD3, /* smart lock bits */ PixelClk= 0x03, SmartLock= 0x00, FeatureConnector= 0x01, Divider= 0x02, Window= 0x08, KeyWindow= 0x0C, HSyncLow= 0x20, VSyncLow= 0x40, ClkBit= 0x01, DataBit= 0x02, HoldBit= 0x04, SelBit= 0x08, DivControl= 0x40, /* i2c bus control bits */ I2C_Clock= 0x02, I2C_Data= 0x08, I2C_RdClock= 0x10, I2C_RdData= 0x20, I2C_RdData_D= 0x40, /* I2C bus addresses */ Adr5249= 0x22, /* teletext decoder */ Adr8444= 0x48, /* 6-bit DAC (TDA 8444) */ Adr6300= 0x80, /* sound fader (TEA 6300) */ Adr6320= 0x80, /* sound fader (TEA 6320T) */ AdrTuner= 0xC0, /* Philips audio chips */ TEA6300= 0, TEA6320T= 1, /* input formats */ NTSC_M = 0, NTSC_443 = 1, External = 2, NTSCCropLeft= 36, /* NTSC 3.6 usec */ NTSCCropRight= 558, /* NTSC 55.8 usec */ /* color control indices */ Vxp500Brightness= 1, Vxp500Contrast= 2, Vxp500Saturation= 3, Bt812Brightness= 4, Bt812Contrast= 5, Bt812Saturation= 6, Bt812Hue= 7, Bt812BW= 8, /* board revision numbers */ RevisionPP= 0, RevisionA= 1, HighQ= 2, /* VGA controller registers */ VGAMiscOut= 0x3CC, VGAIndex= 0x3D4, VGAData= 0x3D5, VGAHorzTotal= 0x00, }; enum { Qdir, Qdata, Qctl, }; static Dirtab tvtab[]={ ".", {Qdir, 0, QTDIR}, 0, 0555, "tv", {Qdata, 0}, 0, 0666, "tvctl", {Qctl, 0}, 0, 0666, }; static int ports[] = { /* board addresses */ 0x51C, 0x53C, 0x55C, 0x57C, 0x59C, 0x5BC, 0x5DC, 0x5FC }; /* * Default settings, settings between 0..100 */ static int defaults[] = { Vxp500Brightness, 0, Vxp500Contrast, 54, Vxp500Saturation, 54, Bt812Brightness, 13, Bt812Contrast, 57, Bt812Saturation, 51, Bt812Hue, 0, Bt812BW, 0, }; static int port; static int soundchip; static int boardrev; static int left, right; static int vsync, hsync; static ulong xtalfreq; static ushort cropleft, cropright; static ushort cropbottom, croptop; static Rectangle window, capwindow; static void setreg(int, int); static void setbt812reg(int, int); static void videoinit(void); static void createwindow(Rectangle); static void setcontrols(int, uchar); static void setcolorkey(int, int, int, int, int, int); static void soundinit(void); static void setvolume(int, int); static void setbass(int); static void settreble(int); static void setsoundsource(int); static void tunerinit(void); static void settuner(int, int); static void setvideosource(int); static int waitvideosignal(void); static void freeze(int); static void setsvideo(int); static void setinputformat(int); static void enablevideo(void); static void *saveframe(int *); static int min(int a, int b) { return a < b ? a : b; } static int max(int a, int b) { return a < b ? b : a; } static int present(int port) { outb(port+Vxp500Index, 0xAA); if (inb(port+Vxp500Index) != 0xAA) return 0; outb(port+Vxp500Index, 0x55); outb(port+Vxp500Data, 0xAA); if (inb(port+Vxp500Index) != 0x55) return 0; if (inb(port+Vxp500Data) != 0xAA) return 0; outb(port+Vxp500Data, 0x55); if (inb(port+Vxp500Index) != 0x55) return 0; if (inb(port+Vxp500Data) != 0x55) return 0; return 1; } static int getvsync(void) { int vslow, vshigh, s; ushort timo; s = splhi(); outb(port+Vxp500Index, VideoOutIntrStatus); /* wait for VSync to go high then low */ for (timo = ~0; timo; timo--) if (inb(port+Vxp500Data) & 2) break; for (timo = ~0; timo; timo--) if ((inb(port+Vxp500Data) & 2) == 0) break; /* count how long it stays low and how long it stays high */ for (vslow = 0, timo = ~0; timo; timo--, vslow++) if (inb(port+Vxp500Data) & 2) break; for (vshigh = 0, timo = ~0; timo; timo--, vshigh++) if ((inb(port+Vxp500Data) & 2) == 0) break; splx(s); return vslow < vshigh; } static int gethsync(void) { int hslow, hshigh, s; ushort timo; s = splhi(); outb(port+Vxp500Index, VideoOutIntrStatus); /* wait for HSync to go high then low */ for (timo = ~0; timo; timo--) if (inb(port+Vxp500Data) & 1) break; for (timo = ~0; timo; timo--) if ((inb(port+Vxp500Data) & 1) == 0) break; /* count how long it stays low and how long it stays high */ for (hslow = 0, timo = ~0; timo; timo--, hslow++) if (inb(port+Vxp500Data) & 1) break; for (hshigh = 0, timo = ~0; timo; timo--, hshigh++) if ((inb(port+Vxp500Data) & 1) == 0) break; splx(s); return hslow < hshigh; } static void tvinit(void) { int i; for (i = 0, port = 0; i < nelem(ports); i++) { if (present(ports[i])) { port = ports[i]; break; } } if (i == nelem(ports)) return; /* * the following routines are the prefered way to * find out the sync polarities. Unfortunately, it * doesn't always work. */ #ifndef VSync vsync = getvsync(); hsync = gethsync(); #else vsync = VSync; hsync = HSync; #endif left = right = 80; soundinit(); tunerinit(); videoinit(); } static Chan* tvattach(char *spec) { if (port == 0) error(Enonexist); return devattach('V', spec); } static Walkqid* tvwalk(Chan *c, Chan *nc, char **name, int nname) { return devwalk(c, nc, name, nname, tvtab, nelem(tvtab), devgen); } static int tvstat(Chan *c, uchar *db, int n) { return devstat(c, db, n, tvtab, nelem(tvtab), devgen); } static Chan* tvopen(Chan *c, int omode) { return devopen(c, omode, tvtab, nelem(tvtab), devgen); } static void tvclose(Chan *) { } static long tvread(Chan *c, void *a, long n, vlong offset) { static void *frame; static int size; USED(offset); switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, tvtab, nelem(tvtab), devgen); case Qdata: if (eqrect(capwindow, Rect(0, 0, 0, 0))) error(Ebadarg); if (offset == 0) frame = saveframe(&size); if (frame) { if (n > size - offset) n = size - offset; memmove(a, (char *)frame + offset, n); } else error(Enovmem); break; default: n=0; break; } return n; } static long tvwrite(Chan *c, void *vp, long n, vlong offset) { char buf[128], *field[10], *a; int i, nf, source; static Rectangle win; static int hsize, size = 0; static void *frame; USED(offset); a = vp; switch((ulong)c->qid.path){ case Qctl: if (n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = '\0'; nf = getfields(buf, field, nelem(field), 1, " \t"); if (nf < 1) error(Ebadarg); if (strcmp(field[0], "init") == 0) { window = Rect(0, 0, 0, 0); capwindow = Rect(0, 0, 0, 0); source = 0; /* video 0 input */ setvideosource(source); left = right = 80; setsoundsource(source); for (i = 0; i < nelem(defaults); i += 2) setcontrols(defaults[i], defaults[i+1]); } else if (strcmp(field[0], "colorkey") == 0) { if (nf < 7) error(Ebadarg); setcolorkey(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0), strtoul(field[3], 0, 0), strtoul(field[4], 0, 0), strtoul(field[5], 0, 0), strtoul(field[6], 0, 0)); } else if (strcmp(field[0], "window") == 0) { if (nf < 5) error(Ebadarg); createwindow(Rect(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0), strtoul(field[3], 0, 0), strtoul(field[4], 0, 0))); setvolume(left, right); } else if (strcmp(field[0], "capture") == 0) { if (nf < 5) error(Ebadarg); capwindow = Rect(strtoul(field[1], 0, 0), strtoul(field[2], 0, 0), strtoul(field[3], 0, 0), strtoul(field[4], 0, 0)); } else if (strcmp(field[0], "freeze") == 0) { if (nf < 2) error(Ebadarg); freeze(strtoul(field[1], 0, 0)); } else if (strcmp(field[0], "capbrightness") == 0) { if (nf < 2) error(Ebadarg); setcontrols(Bt812Brightness, strtoul(field[1], 0, 0)); } else if (strcmp(field[0], "capcontrast") == 0) { if (nf < 2) error(Ebadarg); setcontrols(Bt812Contrast, strtoul(field[1], 0, 0)); } else if (strcmp(field[0], "capsaturation") == 0) {