From 888eaae74cf43743fa0b25a05c67dc839da44eeb Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 27 Apr 2005 09:46:25 +0000 Subject: [PATCH] Implemented capGetDriverDescription. --- configure | 69 +++++++++++++++++ configure.ac | 11 +++ dlls/avicap32/Makefile.in | 2 +- dlls/avicap32/avicap32_main.c | 137 ++++++++++++++++++++++++++++++++-- include/config.h.in | 6 ++ 5 files changed, 216 insertions(+), 9 deletions(-) diff --git a/configure b/configure index fb45f1713b9..e2c4d8bf952 100755 --- a/configure +++ b/configure @@ -7260,11 +7260,13 @@ done + for ac_header in \ arpa/inet.h \ arpa/nameser.h \ + asm/types.h \ cups/cups.h \ direct.h \ elf.h \ @@ -16809,6 +16811,73 @@ 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. */ +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#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 diff --git a/configure.ac b/configure.ac index 2df8318d0c9..f6d908c8eee 100644 --- a/configure.ac +++ b/configure.ac @@ -167,6 +167,7 @@ dnl **** Check for header files **** AC_CHECK_HEADERS(\ arpa/inet.h \ arpa/nameser.h \ + asm/types.h \ cups/cups.h \ direct.h \ elf.h \ @@ -1211,6 +1212,16 @@ AC_CHECK_HEADERS([resolv.h],,, AC_CHECK_HEADERS(ucontext.h,,,[#include ]) +dnl **** Check for v4l(2) headers **** + +AC_CHECK_HEADERS(linux/videodev.h,,, +[#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_ASM_TYPES_H +#include +#endif]) + dnl **** Check for IPX headers (currently Linux only) **** AC_CACHE_CHECK([for GNU style IPX support], ac_cv_c_ipx_gnu, diff --git a/dlls/avicap32/Makefile.in b/dlls/avicap32/Makefile.in index b118fbbc90b..c025ada2e25 100644 --- a/dlls/avicap32/Makefile.in +++ b/dlls/avicap32/Makefile.in @@ -3,7 +3,7 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = avicap32.dll -IMPORTS = ntdll +IMPORTS = kernel32 ntdll C_SRCS = avicap32_main.c diff --git a/dlls/avicap32/avicap32_main.c b/dlls/avicap32/avicap32_main.c index 781a5e4df17..f0dcef4b8a1 100644 --- a/dlls/avicap32/avicap32_main.c +++ b/dlls/avicap32/avicap32_main.c @@ -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,7 +18,31 @@ */ #define COM_NO_WINDOWS_H +#include "config.h" #include +#include +#include +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_ERRNO_H +# include +#endif +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_ASM_TYPES_H +# include +#endif +#ifdef HAVE_LINUX_VIDEODEV_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif #include "windef.h" #include "winbase.h" @@ -25,9 +50,12 @@ #include "winuser.h" #include "vfw.h" #include "winreg.h" +#include "winnls.h" #include "winternl.h" #include "wine/debug.h" +#define CAP_DESC_MAX 32 + WINE_DEFAULT_DEBUG_CHANNEL(avicap); @@ -63,24 +91,117 @@ HWND VFWAPI capCreateCaptureWindowA(LPCSTR lpszWindowName, DWORD dwStyle, INT x, 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 query_video_device(int devnum, char *name, int namesize, char *version, int versionsize) +{ + int fd; + 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 == -1) { + 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 BOOL query_video_device(int devnum, char *name, int namesize, char *version, int versionsize) +{ + ERR("Video 4 Linux support not enabled\n"); + return FALSE; +} + +#endif /* HAVE_LINUX_VIDEODEV_H */ + /*********************************************************************** * capGetDriverDescriptionA (AVICAP32.@) */ BOOL VFWAPI capGetDriverDescriptionA(WORD wDriverIndex, LPSTR lpszName, - INT cbName, LPSTR lpszVer, INT cbVer) + INT cbName, LPSTR lpszVer, INT cbVer) { - FIXME("(%d, %p, %d, %p, %d) stub!\n", wDriverIndex, lpszName, cbName, - lpszVer, cbVer); - return FALSE; + HRESULT retval; + WCHAR devname[CAP_DESC_MAX], devver[CAP_DESC_MAX]; + TRACE("--> capGetDriverDescriptionW\n"); + retval = capGetDriverDescriptionW(wDriverIndex, devname, CAP_DESC_MAX, devver, CAP_DESC_MAX); + if (retval) { + WideCharToMultiByte(CP_ACP, 0, devname, -1, lpszName, cbName, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, devver, -1, lpszVer, cbVer, NULL, NULL); + } + return retval; } /*********************************************************************** * capGetDriverDescriptionW (AVICAP32.@) */ BOOL VFWAPI capGetDriverDescriptionW(WORD wDriverIndex, LPWSTR lpszName, - INT cbName, LPWSTR lpszVer, INT cbVer) + INT cbName, LPWSTR lpszVer, INT cbVer) { - FIXME("(%d, %p, %d, %p, %d) stub!\n", wDriverIndex, lpszName, cbName, - lpszVer, cbVer); - return FALSE; + char devname[CAP_DESC_MAX], devver[CAP_DESC_MAX]; + + if (!query_video_device(wDriverIndex, devname, CAP_DESC_MAX, devver, CAP_DESC_MAX)) return FALSE; + + MultiByteToWideChar(CP_UNIXCP, 0, devname, -1, lpszName, cbName); + MultiByteToWideChar(CP_UNIXCP, 0, devver, -1, lpszVer, cbVer); + TRACE("Version: %s - Name: %s\n", debugstr_w(lpszVer), debugstr_w(lpszName)); + return TRUE; } diff --git a/include/config.h.in b/include/config.h.in index b26730d2d26..a4470675361 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -38,6 +38,9 @@ /* Define if the assembler keyword .size is accepted */ #undef HAVE_ASM_DOT_SIZE +/* Define to 1 if you have the header file. */ +#undef HAVE_ASM_TYPES_H + /* Define to 1 if you have the