avicap32_main.c 5.99 KB
Newer Older
1
/*
2
 * Copyright 2002 Dmitry Timoshkov for CodeWeavers
3
 * Copyright 2005 Maarten Lankhorst
4 5 6 7 8 9 10 11 12 13 14 15 16
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 19
 */

20
#include "config.h"
21 22
#include "wine/port.h"

23
#include <stdarg.h>
24 25 26 27 28 29 30 31
#include <stdio.h>
#include <fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
32
#include <errno.h>
33 34 35 36 37 38
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_ASM_TYPES_H
# include <asm/types.h>
#endif
39 40
#ifdef HAVE_LINUX_VIDEODEV2_H
# include <linux/videodev2.h>
41 42 43 44
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
45 46 47 48

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
49
#include "winuser.h"
50
#include "vfw.h"
51
#include "winnls.h"
52
#include "winternl.h"
53 54
#include "wine/debug.h"

55 56
#define CAP_DESC_MAX 32

57 58
WINE_DEFAULT_DEBUG_CHANNEL(avicap);

59 60 61 62 63 64 65 66

/***********************************************************************
 *             capCreateCaptureWindowW   (AVICAP32.@)
 */
HWND VFWAPI capCreateCaptureWindowW(LPCWSTR lpszWindowName, DWORD dwStyle, INT x,
                                    INT y, INT nWidth, INT nHeight, HWND hWnd,
                                    INT nID)
{
67 68
    FIXME("(%s, %08x, %08x, %08x, %08x, %08x, %p, %08x): stub\n",
           debugstr_w(lpszWindowName), dwStyle, x, y, nWidth, nHeight, hWnd, nID);
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
    return 0;
}

/***********************************************************************
 *             capCreateCaptureWindowA   (AVICAP32.@)
 */
HWND VFWAPI capCreateCaptureWindowA(LPCSTR lpszWindowName, DWORD dwStyle, INT x,
                                    INT y, INT nWidth, INT nHeight, HWND hWnd,
                                    INT nID)
{   UNICODE_STRING nameW;
    HWND retW;

    if (lpszWindowName) RtlCreateUnicodeStringFromAsciiz(&nameW, lpszWindowName);
    else nameW.Buffer = NULL;

    retW = capCreateCaptureWindowW(nameW.Buffer, dwStyle, x, y, nWidth, nHeight,
                                   hWnd, nID);
    RtlFreeUnicodeString(&nameW);

    return retW;
}

91
#ifdef HAVE_LINUX_VIDEODEV2_H
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

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 v4l2_capability caps;

   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;
   }

   memset(&caps, 0, sizeof(caps));
   if (xioctl(fd, VIDIOC_QUERYCAP, &caps) != -1) {
131
      BOOL isCaptureDevice;
132
#ifdef V4L2_CAP_DEVICE_CAPS
133 134 135
      if (caps.capabilities & V4L2_CAP_DEVICE_CAPS)
         isCaptureDevice = caps.device_caps & V4L2_CAP_VIDEO_CAPTURE;
      else
136
#endif
137 138 139 140
         isCaptureDevice = caps.capabilities & V4L2_CAP_VIDEO_CAPTURE;
      if (isCaptureDevice) {
         lstrcpynA(name, (char *)caps.card, namesize);
         snprintf(version, versionsize, "%s v%u.%u.%u", (char *)caps.driver, (caps.version >> 16) & 0xFF,
141
                             (caps.version >> 8) & 0xFF, caps.version & 0xFF);
142
      }
143
      close(fd);
144
      return isCaptureDevice;
145 146 147 148
   }

   if (errno != EINVAL && errno != 515)
/* errno 515 is used by some webcam drivers for unknown IOICTL command */
149 150
      ERR("%s: Querying failed: %s\n", device, strerror(errno));
   else ERR("%s: Querying failed: Not a V4L compatible device\n", device);
151 152

   close(fd);
153
   return FALSE;
154 155
}

156
#else /* HAVE_LINUX_VIDEODEV2_H */
157 158 159 160 161 162 163

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;
}

164
#endif /* HAVE_LINUX_VIDEODEV2_H */
165

166 167 168
/***********************************************************************
 *             capGetDriverDescriptionA   (AVICAP32.@)
 */
169
BOOL VFWAPI capGetDriverDescriptionA(WORD wDriverIndex, LPSTR lpszName,
170
                                     INT cbName, LPSTR lpszVer, INT cbVer)
171
{
172
   BOOL retval;
173 174 175 176 177 178 179 180
   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;
181 182
}

183 184 185
/***********************************************************************
 *             capGetDriverDescriptionW   (AVICAP32.@)
 */
186
BOOL VFWAPI capGetDriverDescriptionW(WORD wDriverIndex, LPWSTR lpszName,
187
                                     INT cbName, LPWSTR lpszVer, INT cbVer)
188
{
189 190 191 192 193 194 195 196
   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;
197
}