2 * Copyright 2002 Dmitry Timoshkov for CodeWeavers
3 * Copyright 2005 Maarten Lankhorst
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * 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
32 #include <sys/ioctl.h>
33 #ifdef HAVE_LINUX_VIDEODEV2_H
34 # include <linux/videodev2.h>
38 #define WIN32_NO_STATUS
41 #include "wine/debug.h"
45 #ifdef HAVE_LINUX_VIDEODEV2_H
47 WINE_DEFAULT_DEBUG_CHANNEL(avicap
);
49 static int xioctl(int fd
, int request
, void *arg
)
54 ret
= ioctl(fd
, request
, arg
);
55 while (ret
< 0 && errno
== EINTR
);
60 static void v4l_umbstowcs(const char *src
, DWORD srclen
, WCHAR
*dst
, DWORD dstlen
)
62 DWORD ret
= ntdll_umbstowcs(src
, srclen
, dst
, dstlen
- 1);
67 static NTSTATUS
get_device_desc(void *args
)
69 struct get_device_desc_params
*params
= args
;
70 struct v4l2_capability caps
= {{0}};
75 snprintf(device
, sizeof(device
), "/dev/video%u", params
->index
);
77 if (stat(device
, &st
) < 0)
79 /* This is probably because the device does not exist */
80 WARN("Failed to stat %s: %s\n", device
, strerror(errno
));
81 return STATUS_OBJECT_NAME_NOT_FOUND
;
84 if (!S_ISCHR(st
.st_mode
))
86 ERR("%s is not a character device.\n", device
);
87 return STATUS_OBJECT_TYPE_MISMATCH
;
90 if ((fd
= open(device
, O_RDWR
| O_NONBLOCK
)) < 0)
92 ERR("%s: Failed to open: %s\n", device
, strerror(errno
));
93 return STATUS_UNSUCCESSFUL
;
96 if (!xioctl(fd
, VIDIOC_QUERYCAP
, &caps
))
98 BOOL is_capture_device
;
99 #ifdef V4L2_CAP_DEVICE_CAPS
100 if (caps
.capabilities
& V4L2_CAP_DEVICE_CAPS
)
101 is_capture_device
= caps
.device_caps
& V4L2_CAP_VIDEO_CAPTURE
;
104 is_capture_device
= caps
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
;
105 if (is_capture_device
)
107 char version
[CAP_DESC_MAX
];
110 v4l_umbstowcs((char *)caps
.card
, strlen((char *)caps
.card
),
111 params
->name
, ARRAY_SIZE(params
->name
));
113 ret
= snprintf(version
, ARRAY_SIZE(version
), "%s v%u.%u.%u", (char *)caps
.driver
,
114 (caps
.version
>> 16) & 0xff, (caps
.version
>> 8) & 0xff, caps
.version
& 0xff);
115 v4l_umbstowcs(version
, ret
, params
->version
, ARRAY_SIZE(params
->version
));
118 return is_capture_device
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
;
121 /* errno 515 is used by some webcam drivers for unknown IOCTL commands. */
122 ERR("Failed to get capabilities for %s: %s\n", device
, strerror(errno
));
125 return STATUS_UNSUCCESSFUL
;
128 const unixlib_entry_t __wine_unix_call_funcs
[] =
135 const unixlib_entry_t __wine_unix_call_wow64_funcs
[] =
142 #endif /* HAVE_LINUX_VIDEODEV2_H */