Avicap32 (Attempt 2)

Maarten Lankhorst m.b.lankhorst at gmail.com
Mon Apr 25 16:05:38 CDT 2005


This time it works! else I'm gonna bite julliards leg off!
-------------- next part --------------
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 20:56:11 -0000
@@ -16809,6 +16809,68 @@ 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 <sys/time.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: 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 20:56:12 -0000
@@ -1211,6 +1211,11 @@ AC_CHECK_HEADERS([resolv.h],,,
 
 AC_CHECK_HEADERS(ucontext.h,,,[#include <signal.h>])
 
+dnl **** Check for v4l(2) headers ****
+AC_CHECK_HEADERS(linux/videodev.h,,,
+    [#include <sys/time.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: 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 20:56:12 -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 20:56:12 -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 20:56:12 -0000
@@ -1,5 +1,6 @@
 /*
  * Copyright 2002 Dmitry Timoshkov for CodeWeavers
+ * Copyright 2005 Maarten Lankhorst
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,6 +18,7 @@
  */
 
 #define COM_NO_WINDOWS_H
+#include "config.h"
 #include <stdarg.h>
 
 #include "windef.h"
@@ -25,9 +27,22 @@
 #include "winuser.h"
 #include "vfw.h"
 #include "winreg.h"
+#include "winnls.h"
 #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 <sys/time.h>
+#include <asm/types.h>
+#include <linux/videodev.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+
 WINE_DEFAULT_DEBUG_CHANNEL(avicap);
 
 
@@ -63,15 +78,97 @@ 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 namesize, int versionsize)
+{
+   int fd = -1;
+   char device[16];
+   struct stat st;
+   struct video_capability capa;
+#ifdef HAVE_V4L2
+   struct v4l2_capability caps;
+#endif
+
+   snprintf(device, sizeof(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 FALSE;
+   }
+
+   if (!S_ISCHR (st.st_mode)) {
+      ERR("%s: Not a device\n", device);
+      return FALSE;
+   }
+
+   fd = open(device, O_RDWR | O_NONBLOCK);
+   if (fd == 0) {
+      ERR("%s: Failed to open: %s\n", device, strerror(errno));
+      return FALSE;
+   }
+
+#ifdef HAVE_V4L2
+   memset(&caps, 0, sizeof(caps));
+   if (xioctl(fd, VIDIOC_QUERYCAP, &caps) != -1) {
+      lstrcpynA(name, caps.card, namesize);
+      snprintf(version, versionsize, "%s v%u.%u.%u", caps.driver, (caps.version >> 16) & 0xFF,
+                             (caps.version >> 8) & 0xFF, caps.version & 0xFF);
+      close(fd);
+      return TRUE;
+   }
+
+   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 FALSE;
+   }
+
+   lstrcpynA(name, capa.name, namesize);
+   lstrcpynA(version, device, versionsize);
+   close(fd);
+   return TRUE;
+}
+
+#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;
+   if (!queryvideodevice(wDriverIndex, lpszName, lpszVer, cbName, cbVer)) return FALSE;
+
+   TRACE("Version: %s - Name: %s\n", lpszVer, lpszName);
+   return TRUE;
 }
 
 /***********************************************************************
@@ -80,7 +177,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, sizeof(devname), sizeof(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