home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lxapi32.zip / Lib32 / lxvideodev.c < prev    next >
C/C++ Source or Header  |  2002-04-26  |  7KB  |  315 lines

  1. /* $Id: lxvideodev.c,v 1.2 2002/04/26 23:09:25 smilcke Exp $ */
  2.  
  3. /*
  4.  * videodev.c
  5.  * Autor:               Stefan Milcke
  6.  * Erstellt am:         15.11.2001
  7.  * Letzte Aenderung am: 11.02.2002
  8.  *
  9. */
  10. #define INCL_NOPMAPI
  11. #define INCL_DOSERRORS           // for ERROR_INVALID_FUNCTION
  12. #include <os2.h>
  13.  
  14. #include <linux/config.h>
  15. #include <linux/version.h>
  16. #include <linux/module.h>
  17. #include <linux/types.h>
  18. #include <linux/kernel.h>
  19. #include <linux/sched.h>
  20. //#include <linux/smp_lock.h>
  21. #include <linux/mm.h>
  22. #include <linux/string.h>
  23. #include <linux/errno.h>
  24. #include <linux/videodev.h>
  25. #include <linux/init.h>
  26. #include <linux/ioctl.h>
  27.  
  28. #include <asm/uaccess.h>
  29. //#include <asm/system.h>
  30. #include <asm/semaphor.h>
  31.  
  32. #include <linux/kmod.h>
  33.  
  34. #include <lxapios2.h>
  35. #include <lxapilib.h>
  36.  
  37. #define VIDEO_NUM_DEVICES  256
  38.  
  39. static struct video_device *video_device[VIDEO_NUM_DEVICES]={0};
  40.  
  41. static struct video_init video_init_list[]={
  42.  {"end", NULL}
  43. };
  44. struct semaphore videodev_register_lock;
  45.  
  46. //--------------------------- video_register_device ----------------------------
  47. int video_register_device(struct video_device *vfd,int type,int nr)
  48. {
  49.  int i=0;
  50.  int base;
  51.  int err;
  52.  int end;
  53.  char *name_base;
  54.  char name[16];
  55.  switch(type)
  56.  {
  57.   case VFL_TYPE_GRABBER:
  58.    base=0;
  59.    end=64;
  60.    name_base="video";
  61.    break;
  62.   case VFL_TYPE_VTX:
  63.    base=192;
  64.    end=224;
  65.    name_base="vtx";
  66.    break;
  67.   case VFL_TYPE_VBI:
  68.    base=224;
  69.    end=240;
  70.    name_base="vbi";
  71.    break;
  72.   case VFL_TYPE_RADIO:
  73.    base=64;
  74.    end=128;
  75.    name_base="radio";
  76.    break;
  77.   default:
  78.    return -1;
  79.  }
  80.  // pick a minor number
  81.  down(&videodev_register_lock);
  82.  if(-1==nr)
  83.  { // use first free
  84.   for(i=base;i<end;i++)
  85.    if(NULL==video_device[i])
  86.     break;
  87.   if(i==end)
  88.   {
  89.    up(&videodev_register_lock);
  90.    return -ENFILE;
  91.   }
  92.  }
  93.  else
  94.  { // use the one the driver asked for
  95.   i=base+nr;
  96.   if(NULL!=video_device[i])
  97.   {
  98.    up(&videodev_register_lock);
  99.    return -ENFILE;
  100.   }
  101.  }
  102.  video_device[i]=vfd;
  103.  vfd->minor=i;
  104.  up(&videodev_register_lock);
  105.  // The init call may sleep so we book the slot out then call
  106.  MOD_INC_USE_COUNT;
  107.  if(vfd->initialize)
  108.  {
  109.   err=vfd->initialize(vfd);
  110.   if(err<0)
  111.   {
  112.    video_device[i]=NULL;
  113.    MOD_DEC_USE_COUNT;
  114.    return err;
  115.   }
  116.  }
  117.  sprintf(name,"v4l:%s%d",name_base,i-base);
  118. #ifdef TARGET_OS2
  119.  strcpy(vfd->devname,name);
  120. #endif
  121.  return 0;
  122. }
  123.  
  124. //-------------------------- video_unregister_device ---------------------------
  125. void video_unregister_device(struct video_device *vfd)
  126. {
  127.  if(video_device[vfd->minor]!=vfd)
  128.   return;
  129.  video_device[vfd->minor]=NULL;
  130.  MOD_DEC_USE_COUNT;
  131. }
  132.  
  133. //------------------------------- videodev_init --------------------------------
  134. int __init videodev_init(void)
  135. {
  136.  struct video_init *vfli=video_init_list;
  137.  CPK(printk(KERN_INFO "Linux video capture interface: v1.00\n"));
  138.  while(vfli->init!=NULL)
  139.  {
  140.   vfli->init(vfli);
  141.   vfli++;
  142.  }
  143.  return 0;
  144. }
  145.  
  146. //------------------------------- videodev_exit --------------------------------
  147. void __exit videodev_exit(void)
  148. {
  149. }
  150.  
  151.  
  152. /******************************************************************************/
  153. /* OS2 functions                                                              */
  154. /******************************************************************************/
  155. #define MAX_OPENED_VIDEO_DEVICES 10
  156.  
  157. static struct video_device *opened_video_devices[MAX_OPENED_VIDEO_DEVICES]={0};
  158.  
  159. //-------------------------- OS2_v4lx_get_num_devices --------------------------
  160. unsigned long OS2_v4lx_get_num_devices(void)
  161. {
  162.  unsigned long c=0,i;
  163.  for(i=0;i<VIDEO_NUM_DEVICES;i++)
  164.   if(video_device[i])
  165.    c++;
  166.  return c;
  167. }
  168.  
  169. //--------------------------- OS2_v4lx_enum_devices ----------------------------
  170. int OS2_v4lx_enum_devices(void *buffer,unsigned long buffer_len)
  171. {
  172.  int c=0,i;
  173.  struct os2_enum_video_device *pd=(struct os2_enum_video_device *)buffer;
  174.  for(i=0
  175.      ;i<VIDEO_NUM_DEVICES && buffer_len>=sizeof(struct os2_enum_video_device)
  176.      ;i++)
  177.  {
  178.   if(video_device[i])
  179.   {
  180.    memcpy(pd->name,&video_device[i]->name,32);
  181.    memcpy(pd->devname,&video_device[i]->devname,16);
  182.    pd->type=video_device[i]->type;
  183.    pd->hardware=video_device[i]->hardware;
  184.    pd++;
  185.    c++;
  186.    if(buffer_len>=sizeof(struct os2_enum_video_device))
  187.     buffer_len-=sizeof(struct os2_enum_video_device);
  188.    else
  189.     buffer_len=0;
  190.   }
  191.  }
  192.  return c;
  193. }
  194.  
  195. //------------------------- OS2_v4lx_get_opened_device -------------------------
  196. struct video_device *OS2_v4lx_get_opened_device(int handle)
  197. {
  198.  if(handle>0 && handle<=MAX_OPENED_VIDEO_DEVICES)
  199.   return opened_video_devices[handle-1];
  200.  return NULL;
  201. }
  202.  
  203. //---------------------------- OS2_v4lx_open_device ----------------------------
  204. int OS2_v4lx_open_device(char *devname)
  205. {
  206.  int i,retval=-ENXIO;
  207.  int c=-1;
  208.  struct video_device *v=NULL;
  209.  // first check, if device is already open. If so, return -EBUSY
  210.  for(i=0;i<MAX_OPENED_VIDEO_DEVICES;i++)
  211.  {
  212.   v=opened_video_devices[i];
  213.   if(v && !strncmp(v->devname,devname,32))
  214.    return -EBUSY;
  215.   // Empty slot ? So remember it for storage
  216.   if(-1==c && NULL==v)
  217.    c=i;
  218.  }
  219.  if(-1==c)
  220.   return -EBUSY;
  221.  // now walk through the registered devices and find matching name
  222.  for(i=0;i<VIDEO_NUM_DEVICES;i++)
  223.  {
  224.   if(video_device[i])
  225.   {
  226.    v=video_device[i];
  227.    if(NULL!=v && 0==strncmp(v->devname,devname,32))
  228.    {
  229.     if(!v->open)
  230.      return -ENOSYS;
  231.     if((retval=v->open(v,0)))
  232.      return retval;
  233.     opened_video_devices[c]=v;
  234.     return c+1;
  235.    }
  236.   }
  237.  }
  238.  return -ENXIO;
  239. }
  240.  
  241. //--------------------- OS2_v4lx_close_all_opened_devices ----------------------
  242. void OS2_v4lx_close_all_opened_devices(void)
  243. {
  244.  int i;
  245.  struct vide_device *v=NULL;
  246.  for(i=0;i<MAX_OPENED_VIDEO_DEVICES;i++)
  247.   if(OS2_v4lx_get_opened_device(i+1))
  248.    OS2_v4lx_close_device(i+1);
  249. }
  250.  
  251. //--------------------------- OS2_v4lx_close_device ----------------------------
  252. int OS2_v4lx_close_device(int handle)
  253. {
  254.  struct video_device *v=OS2_v4lx_get_opened_device(handle);
  255.  if(v)
  256.  {
  257.   if(!v->close)
  258.    return -ENOSYS;
  259.   v->close(v);
  260.   opened_video_devices[handle-1]=NULL;
  261.   return 0;
  262.  }
  263.  return -ENXIO;
  264. }
  265.  
  266. int ioctlmap[]=
  267. {
  268.  VIDIOCGCAP,
  269.  VIDIOCGCHAN,
  270.  VIDIOCSCHAN,
  271.  VIDIOCGTUNER,
  272.  VIDIOCSTUNER,
  273.  VIDIOCGPICT,
  274.  VIDIOCSPICT,
  275.  VIDIOCCAPTURE,
  276.  VIDIOCGWIN,
  277.  VIDIOCSWIN,
  278.  VIDIOCGFBUF,
  279.  VIDIOCSFBUF,
  280.  VIDIOCKEY,
  281.  VIDIOCGFREQ,
  282.  VIDIOCSFREQ,
  283.  VIDIOCGAUDIO,
  284.  VIDIOCSAUDIO,
  285.  VIDIOCSYNC,
  286.  VIDIOCMCAPTURE,
  287.  VIDIOCGMBUF,
  288.  VIDIOCGUNIT,
  289.  VIDIOCGCAPTURE,
  290.  VIDIOCSCAPTURE,
  291.  VIDIOCSPLAYMODE,
  292.  VIDIOCSWRITEMODE,
  293.  VIDIOCGPLAYINFO,
  294.  VIDIOCSMICROCODE,
  295.  VIDIOCGVBIFMT,
  296.  VIDIOCSVBIFMT,
  297.  0,
  298.  0,
  299.  0,
  300.  VIDIOCSFREQSTEP
  301. };
  302. int numioctls=sizeof(ioctlmap)/sizeof(int);
  303.  
  304. //------------------------------- OS2_v4lx_ioctl -------------------------------
  305. int OS2_v4lx_ioctl(int handle,int ioctlfn,void *userData)
  306. {
  307.  struct video_device *v=OS2_v4lx_get_opened_device(handle);
  308.  if(!v)
  309.   return -ENXIO;
  310.  if(!v->ioctl)
  311.   return -ENOSYS;
  312.  if(ioctlfn<1 || ioctlfn>numioctls)
  313.   return -EINVAL;
  314.  return v->ioctl(v,ioctlmap[ioctlfn-1],userData);
  315. }