home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
lxapi32.zip
/
Lib32
/
lxvideodev.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-04-26
|
7KB
|
315 lines
/* $Id: lxvideodev.c,v 1.2 2002/04/26 23:09:25 smilcke Exp $ */
/*
* videodev.c
* Autor: Stefan Milcke
* Erstellt am: 15.11.2001
* Letzte Aenderung am: 11.02.2002
*
*/
#define INCL_NOPMAPI
#define INCL_DOSERRORS // for ERROR_INVALID_FUNCTION
#include <os2.h>
#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
//#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/videodev.h>
#include <linux/init.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
//#include <asm/system.h>
#include <asm/semaphor.h>
#include <linux/kmod.h>
#include <lxapios2.h>
#include <lxapilib.h>
#define VIDEO_NUM_DEVICES 256
static struct video_device *video_device[VIDEO_NUM_DEVICES]={0};
static struct video_init video_init_list[]={
{"end", NULL}
};
struct semaphore videodev_register_lock;
//--------------------------- video_register_device ----------------------------
int video_register_device(struct video_device *vfd,int type,int nr)
{
int i=0;
int base;
int err;
int end;
char *name_base;
char name[16];
switch(type)
{
case VFL_TYPE_GRABBER:
base=0;
end=64;
name_base="video";
break;
case VFL_TYPE_VTX:
base=192;
end=224;
name_base="vtx";
break;
case VFL_TYPE_VBI:
base=224;
end=240;
name_base="vbi";
break;
case VFL_TYPE_RADIO:
base=64;
end=128;
name_base="radio";
break;
default:
return -1;
}
// pick a minor number
down(&videodev_register_lock);
if(-1==nr)
{ // use first free
for(i=base;i<end;i++)
if(NULL==video_device[i])
break;
if(i==end)
{
up(&videodev_register_lock);
return -ENFILE;
}
}
else
{ // use the one the driver asked for
i=base+nr;
if(NULL!=video_device[i])
{
up(&videodev_register_lock);
return -ENFILE;
}
}
video_device[i]=vfd;
vfd->minor=i;
up(&videodev_register_lock);
// The init call may sleep so we book the slot out then call
MOD_INC_USE_COUNT;
if(vfd->initialize)
{
err=vfd->initialize(vfd);
if(err<0)
{
video_device[i]=NULL;
MOD_DEC_USE_COUNT;
return err;
}
}
sprintf(name,"v4l:%s%d",name_base,i-base);
#ifdef TARGET_OS2
strcpy(vfd->devname,name);
#endif
return 0;
}
//-------------------------- video_unregister_device ---------------------------
void video_unregister_device(struct video_device *vfd)
{
if(video_device[vfd->minor]!=vfd)
return;
video_device[vfd->minor]=NULL;
MOD_DEC_USE_COUNT;
}
//------------------------------- videodev_init --------------------------------
int __init videodev_init(void)
{
struct video_init *vfli=video_init_list;
CPK(printk(KERN_INFO "Linux video capture interface: v1.00\n"));
while(vfli->init!=NULL)
{
vfli->init(vfli);
vfli++;
}
return 0;
}
//------------------------------- videodev_exit --------------------------------
void __exit videodev_exit(void)
{
}
/******************************************************************************/
/* OS2 functions */
/******************************************************************************/
#define MAX_OPENED_VIDEO_DEVICES 10
static struct video_device *opened_video_devices[MAX_OPENED_VIDEO_DEVICES]={0};
//-------------------------- OS2_v4lx_get_num_devices --------------------------
unsigned long OS2_v4lx_get_num_devices(void)
{
unsigned long c=0,i;
for(i=0;i<VIDEO_NUM_DEVICES;i++)
if(video_device[i])
c++;
return c;
}
//--------------------------- OS2_v4lx_enum_devices ----------------------------
int OS2_v4lx_enum_devices(void *buffer,unsigned long buffer_len)
{
int c=0,i;
struct os2_enum_video_device *pd=(struct os2_enum_video_device *)buffer;
for(i=0
;i<VIDEO_NUM_DEVICES && buffer_len>=sizeof(struct os2_enum_video_device)
;i++)
{
if(video_device[i])
{
memcpy(pd->name,&video_device[i]->name,32);
memcpy(pd->devname,&video_device[i]->devname,16);
pd->type=video_device[i]->type;
pd->hardware=video_device[i]->hardware;
pd++;
c++;
if(buffer_len>=sizeof(struct os2_enum_video_device))
buffer_len-=sizeof(struct os2_enum_video_device);
else
buffer_len=0;
}
}
return c;
}
//------------------------- OS2_v4lx_get_opened_device -------------------------
struct video_device *OS2_v4lx_get_opened_device(int handle)
{
if(handle>0 && handle<=MAX_OPENED_VIDEO_DEVICES)
return opened_video_devices[handle-1];
return NULL;
}
//---------------------------- OS2_v4lx_open_device ----------------------------
int OS2_v4lx_open_device(char *devname)
{
int i,retval=-ENXIO;
int c=-1;
struct video_device *v=NULL;
// first check, if device is already open. If so, return -EBUSY
for(i=0;i<MAX_OPENED_VIDEO_DEVICES;i++)
{
v=opened_video_devices[i];
if(v && !strncmp(v->devname,devname,32))
return -EBUSY;
// Empty slot ? So remember it for storage
if(-1==c && NULL==v)
c=i;
}
if(-1==c)
return -EBUSY;
// now walk through the registered devices and find matching name
for(i=0;i<VIDEO_NUM_DEVICES;i++)
{
if(video_device[i])
{
v=video_device[i];
if(NULL!=v && 0==strncmp(v->devname,devname,32))
{
if(!v->open)
return -ENOSYS;
if((retval=v->open(v,0)))
return retval;
opened_video_devices[c]=v;
return c+1;
}
}
}
return -ENXIO;
}
//--------------------- OS2_v4lx_close_all_opened_devices ----------------------
void OS2_v4lx_close_all_opened_devices(void)
{
int i;
struct vide_device *v=NULL;
for(i=0;i<MAX_OPENED_VIDEO_DEVICES;i++)
if(OS2_v4lx_get_opened_device(i+1))
OS2_v4lx_close_device(i+1);
}
//--------------------------- OS2_v4lx_close_device ----------------------------
int OS2_v4lx_close_device(int handle)
{
struct video_device *v=OS2_v4lx_get_opened_device(handle);
if(v)
{
if(!v->close)
return -ENOSYS;
v->close(v);
opened_video_devices[handle-1]=NULL;
return 0;
}
return -ENXIO;
}
int ioctlmap[]=
{
VIDIOCGCAP,
VIDIOCGCHAN,
VIDIOCSCHAN,
VIDIOCGTUNER,
VIDIOCSTUNER,
VIDIOCGPICT,
VIDIOCSPICT,
VIDIOCCAPTURE,
VIDIOCGWIN,
VIDIOCSWIN,
VIDIOCGFBUF,
VIDIOCSFBUF,
VIDIOCKEY,
VIDIOCGFREQ,
VIDIOCSFREQ,
VIDIOCGAUDIO,
VIDIOCSAUDIO,
VIDIOCSYNC,
VIDIOCMCAPTURE,
VIDIOCGMBUF,
VIDIOCGUNIT,
VIDIOCGCAPTURE,
VIDIOCSCAPTURE,
VIDIOCSPLAYMODE,
VIDIOCSWRITEMODE,
VIDIOCGPLAYINFO,
VIDIOCSMICROCODE,
VIDIOCGVBIFMT,
VIDIOCSVBIFMT,
0,
0,
0,
VIDIOCSFREQSTEP
};
int numioctls=sizeof(ioctlmap)/sizeof(int);
//------------------------------- OS2_v4lx_ioctl -------------------------------
int OS2_v4lx_ioctl(int handle,int ioctlfn,void *userData)
{
struct video_device *v=OS2_v4lx_get_opened_device(handle);
if(!v)
return -ENXIO;
if(!v->ioctl)
return -ENOSYS;
if(ioctlfn<1 || ioctlfn>numioctls)
return -EINVAL;
return v->ioctl(v,ioctlmap[ioctlfn-1],userData);
}