avicap32 patch

Maarten Lankhorst m.b.lankhorst at gmail.com
Mon Apr 25 12:14:08 CDT 2005


This patch implements capGetDriverDescription, I wrote it so i could use 
it in devenum to implement vfwcapture

it checks for linux/videodev.h and if it's found, it can be used in 
avicap32..

linux/videodev.h also includes videodev2.h if V4L2 is available, and if 
it is, it defines HAVE_V4L2, which I also use in the patch
-------------- next part --------------
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.347
diff -u -p -r1.347 configure.ac
--- configure.ac	20 Apr 2005 19:15:31 -0000	1.347
+++ configure.ac	25 Apr 2005 17:08:11 -0000
@@ -1211,6 +1211,9 @@ AC_CHECK_HEADERS([resolv.h],,,
 
 AC_CHECK_HEADERS(ucontext.h,,,[#include <signal.h>])
 
+dnl **** Check for v4l headers ****
+AC_CHECK_HEADERS(linux/videodev.h,,,[#include <asm/types.h>])
+
 dnl **** Check for IPX headers (currently Linux only) ****
 
 AC_CACHE_CHECK([for GNU style IPX support], ac_cv_c_ipx_gnu,
Index: configure
===================================================================
RCS file: /home/wine/wine/configure,v
retrieving revision 1.643
diff -u -p -r1.643 configure
--- configure	20 Apr 2005 19:15:31 -0000	1.643
+++ configure	25 Apr 2005 17:08:22 -0000
@@ -16809,6 +16809,67 @@ done
 
 
 
+for ac_header in linux/videodev.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <asm/types.h>
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
 echo "$as_me:$LINENO: checking for GNU style IPX support" >&5
 echo $ECHO_N "checking for GNU style IPX support... $ECHO_C" >&6
 if test "${ac_cv_c_ipx_gnu+set}" = set; then
Index: include/config.h.in
===================================================================
RCS file: /home/wine/wine/include/config.h.in,v
retrieving revision 1.214
diff -u -p -r1.214 config.h.in
--- include/config.h.in	4 Mar 2005 12:38:37 -0000	1.214
+++ include/config.h.in	25 Apr 2005 17:08:22 -0000
@@ -335,6 +335,9 @@
 /* Define to 1 if you have the <linux/ucdrom.h> header file. */
 #undef HAVE_LINUX_UCDROM_H
 
+/* Define to 1 if you have the <linux/videodev.h> header file. */
+#undef HAVE_LINUX_VIDEODEV_H
+
 /* Define to 1 if the system has the type `long long'. */
 #undef HAVE_LONG_LONG
 
Index: dlls/avicap32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/avicap32/Makefile.in,v
retrieving revision 1.7
diff -u -p -r1.7 Makefile.in
--- dlls/avicap32/Makefile.in	11 Oct 2003 01:09:21 -0000	1.7
+++ dlls/avicap32/Makefile.in	25 Apr 2005 17:09:02 -0000
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = avicap32.dll
-IMPORTS   = ntdll
+IMPORTS   = ntdll unicows kernel32
 
 C_SRCS = avicap32_main.c
 
Index: dlls/avicap32/avicap32_main.c
===================================================================
RCS file: /home/wine/wine/dlls/avicap32/avicap32_main.c,v
retrieving revision 1.11
diff -u -p -r1.11 avicap32_main.c
--- dlls/avicap32/avicap32_main.c	9 Sep 2003 19:39:32 -0000	1.11
+++ dlls/avicap32/avicap32_main.c	25 Apr 2005 17:09:03 -0000
@@ -17,6 +17,7 @@
  */
 
 #define COM_NO_WINDOWS_H
+#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
@@ -28,6 +29,18 @@
 #include "winternl.h"
 #include "wine/debug.h"
 
+#ifdef HAVE_LINUX_VIDEODEV_H
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <asm/types.h>
+#include <linux/videodev.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "winnls.h"
+#endif
+
 WINE_DEFAULT_DEBUG_CHANNEL(avicap);
 
 
@@ -63,15 +76,102 @@ HWND VFWAPI capCreateCaptureWindowA(LPCS
     return retW;
 }
 
+#ifdef HAVE_LINUX_VIDEODEV_H
+static int xioctl(int fd, int request, void * arg)
+{
+   int r;
+
+   do r = ioctl (fd, request, arg);
+   while (-1 == r && EINTR == errno);
+
+   return r;
+}
+
+static BOOL queryvideodevice(int devnum, char *name, char *version)
+{
+   int fd = -1;
+   char device[16];
+   struct stat st;
+   struct video_capability capa;
+#ifdef HAVE_V4L2
+   struct v4l2_capability caps;
+#endif
+
+   sprintf(device, "/dev/video%i", devnum);
+
+   if (stat (device, &st) == -1) {
+      /* This is probably because the device does not exist */
+      WARN("%s: %s\n", device, strerror(errno));
+      return 0;
+   }
+
+   if (!S_ISCHR (st.st_mode)) {
+      ERR("%s: Not a device\n", device);
+      return 0;
+   }
+
+   fd = open(device, O_RDWR | O_NONBLOCK);
+   if (fd == 0) {
+      ERR("%s: Failed to open: %s\n", device, strerror(errno));
+      return 0;
+   }
+
+#ifdef HAVE_V4L2
+   memset(&caps, 0, sizeof(caps));
+   if (xioctl(fd, VIDIOC_QUERYCAP, &caps) != -1) {
+      strcpy(name, caps.card);
+      name[sizeof(caps.card) - 1] = 0;
+      sprintf(version, "%s v%u.%u.%u", caps.driver, (caps.version >> 16) & 0xFF,
+                             (caps.version >> 8) & 0xFF, caps.version & 0xFF);
+      close(fd);
+      return 1;
+   }
+
+   if (errno != EINVAL && errno != 515)
+      WARN("%s: ioctl failed: %s -- Falling back to V4L\n", device, strerror(errno));
+   else WARN("%s: Not a V4L2 compatible device, trying V4l 1\n", device);
+#endif /* HAVE_V4L2 */
+
+   memset(&capa, 0, sizeof(capa));
+   if (xioctl(fd, VIDIOCGCAP, &capa) == -1) {
+/* errno 515 is used by some webcam drivers for unknown IOICTL command */
+      if (errno != EINVAL && errno != 515)
+         ERR("%s: Querying failed: %s\n", device, strerror(errno));
+      else ERR("%s: Querying failed: Not a V4L compatible device", device);
+      close(fd);
+      return 0;
+   }
+
+   strcpy(name, capa.name);
+   strcpy(version, device);
+   close(fd);
+   return 1;
+}
+
+#else /* HAVE_LINUX_VIDEODEV_H */
+
+static int queryvideodevice(int devnum, char *name, char *version)
+{
+   ERR("Video 4 Linux support not enabled\n");
+   return 0;
+}
+
+#endif /* HAVE_LINUX_VIDEODEV_H */
+
 /***********************************************************************
  *             capGetDriverDescriptionA   (AVICAP32.@)
  */
 BOOL VFWAPI capGetDriverDescriptionA(WORD wDriverIndex, LPSTR lpszName,
 				     INT cbName, LPSTR lpszVer, INT cbVer)
 {
-    FIXME("(%d, %p, %d, %p, %d) stub!\n", wDriverIndex, lpszName, cbName,
-	  lpszVer, cbVer);
-    return FALSE;
+   char devname[32], devver[32];
+
+   if (!queryvideodevice(wDriverIndex, devname, devver)) return FALSE;
+
+   strncpy(lpszName, devname, cbName);
+   strncpy(lpszVer, devver, cbVer);
+   TRACE("Version: %s - Name: %s\n", lpszVer, lpszName);
+   return TRUE;
 }
 
 /***********************************************************************
@@ -80,7 +180,13 @@ BOOL VFWAPI capGetDriverDescriptionA(WOR
 BOOL VFWAPI capGetDriverDescriptionW(WORD wDriverIndex, LPWSTR lpszName,
 				     INT cbName, LPWSTR lpszVer, INT cbVer)
 {
-    FIXME("(%d, %p, %d, %p, %d) stub!\n", wDriverIndex, lpszName, cbName,
-	  lpszVer, cbVer);
-    return FALSE;
+   char devname[32], devver[32];
+
+   if (!queryvideodevice(wDriverIndex, devname, devver)) return FALSE;
+
+   MultiByteToWideChar(CP_UTF8, 0, devname, -1, lpszName, cbName);
+   MultiByteToWideChar(CP_UTF8, 0, devver, -1, lpszVer, cbVer);
+   TRACE("Version: %s - Name: %s\n", debugstr_w(lpszVer), debugstr_w(lpszName));
+   return TRUE;
 }
+


More information about the wine-patches mailing list