avicap32_main.c 5.68 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 132
      lstrcpynA(name, (char *)caps.card, namesize);
      snprintf(version, versionsize, "%s v%u.%u.%u", (char *)caps.driver, (caps.version >> 16) & 0xFF,
133 134 135 136 137 138 139
                             (caps.version >> 8) & 0xFF, caps.version & 0xFF);
      close(fd);
      return TRUE;
   }

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

   close(fd);
144
   return FALSE;
145 146
}

147
#else /* HAVE_LINUX_VIDEODEV2_H */
148 149 150 151 152 153 154

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

155
#endif /* HAVE_LINUX_VIDEODEV2_H */
156

157 158 159
/***********************************************************************
 *             capGetDriverDescriptionA   (AVICAP32.@)
 */
160
BOOL VFWAPI capGetDriverDescriptionA(WORD wDriverIndex, LPSTR lpszName,
161
                                     INT cbName, LPSTR lpszVer, INT cbVer)
162
{
163
   BOOL retval;
164 165 166 167 168 169 170 171
   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;
172 173
}

174 175 176
/***********************************************************************
 *             capGetDriverDescriptionW   (AVICAP32.@)
 */
177
BOOL VFWAPI capGetDriverDescriptionW(WORD wDriverIndex, LPWSTR lpszName,
178
                                     INT cbName, LPWSTR lpszVer, INT cbVer)
179
{
180 181 182 183 184 185 186 187
   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;
188
}