$NetBSD: patch-ab,v 1.9 2009/05/21 16:11:25 wiz Exp $ http://bugzilla.gnome.org/show_bug.cgi?id=583469 --- src/cheese-webcam.c.orig 2009-05-18 20:46:03.000000000 +0000 +++ src/cheese-webcam.c @@ -31,13 +31,26 @@ #include #include #include + +#if HAVE_HAL #include +#endif -/* for ioctl query */ +#include #include #include -#include + +#if USE_SYS_VIDEOIO_H > 0 +#include +#include +#elif defined(__sun) +#include +#include +#elif defined(__linux__) #include +#else +#define NO_VIDEO_SUPPORT +#endif #include "cheese-webcam.h" @@ -241,6 +254,7 @@ cheese_webcam_bus_message_cb (GstBus *bu } } +#if HAVE_HAL static void cheese_webcam_get_video_devices_from_hal (CheeseWebcam *webcam) { @@ -302,8 +316,12 @@ cheese_webcam_get_video_devices_from_hal char *parent_udi = NULL; char *subsystem = NULL; char *gstreamer_src, *product_name; +#ifndef NO_VIDEO_SUPPORT struct v4l2_capability v2cap; +#endif +#ifdef VIDIOCGCAP struct video_capability v1cap; +#endif gint vendor_id = 0; gint product_id = 0; gchar *property_name = NULL; @@ -317,15 +335,17 @@ cheese_webcam_get_video_devices_from_hal if (parent_udi != NULL) { subsystem = libhal_device_get_property_string (hal_ctx, parent_udi, "info.subsystem", NULL); - if (subsystem == NULL) continue; - property_name = g_strjoin (".", subsystem, "vendor_id", NULL); - vendor_id = libhal_device_get_property_int (hal_ctx, parent_udi, property_name , &error); - if (dbus_error_is_set (&error)) { - g_warning ("error getting vendor id: %s: %s", error.name, error.message); - dbus_error_free (&error); + if (subsystem == NULL) { + vendor_id = g_strdup("{No vendor ID}"); + } else { + property_name = g_strjoin (".", subsystem, "vendor_id", NULL); + vendor_id = libhal_device_get_property_int (hal_ctx, parent_udi, property_name , &error); + if (dbus_error_is_set (&error)) { + g_warning ("error getting vendor id: %s: %s", error.name, error.message); + dbus_error_free (&error); + } + g_free (property_name); } - g_free (property_name); - property_name = g_strjoin (".", subsystem, "product_id", NULL); product_id = libhal_device_get_property_int (hal_ctx, parent_udi, property_name, &error); if (dbus_error_is_set (&error)) { @@ -362,9 +382,14 @@ cheese_webcam_get_video_devices_from_hal libhal_free_string (device); continue; } +#ifdef VIDIOC_QUERYCAP ok = ioctl (fd, VIDIOC_QUERYCAP, &v2cap); +#else + ok = -1; +#endif if (ok < 0) { +#ifdef VIDIOCGCAP ok = ioctl (fd, VIDIOCGCAP, &v1cap); if (ok < 0) { @@ -378,14 +403,22 @@ cheese_webcam_get_video_devices_from_hal g_print ("Device type: %d\n", v1cap.type); gstreamer_src = "v4lsrc"; product_name = v1cap.name; +#else + g_error ("Error while probing v4l2 capabilities for %s: %s\n", + device, strerror (errno)); + libhal_free_string (device); + close (fd); + continue; +#endif } else { +#ifndef NO_VIDEO_SUPPORT guint cap = v2cap.capabilities; g_print ("Detected v4l2 device: %s\n", v2cap.card); g_print ("Driver: %s, version: %d\n", v2cap.driver, v2cap.version); /* g_print ("Bus info: %s\n", v2cap.bus_info); */ /* Doesn't seem anything useful */ - g_print ("Capabilities: 0x%08X\n", v2cap.capabilities); + g_print ("Capabilities: 0x%08X\n", v2cap.capabilities); if (!(cap & V4L2_CAP_VIDEO_CAPTURE)) { g_print ("Device %s seems to not have the capture capability, (radio tuner?)\n" @@ -396,6 +429,10 @@ cheese_webcam_get_video_devices_from_hal } gstreamer_src = "v4l2src"; product_name = (char *) v2cap.card; +#else /* NO_VIDEO_SUPPORT */ + gstreamer_src = "v4l2src"; + product_name = "Webcam"; +#endif } g_print ("\n"); @@ -431,6 +468,55 @@ fallback: priv->webcam_devices[0].hal_udi = g_strdup ("cheese_fake_videodevice"); } } +#else +static void +cheese_webcam_get_video_devices_from_probe (CheeseWebcam *webcam) +{ + CheeseWebcamPrivate* priv = CHEESE_WEBCAM_GET_PRIVATE (webcam); + struct v4l2_capability caps; + gchar videodev[] = "/dev/video?"; + guint16 cammask = 0; + int i, ncams = 0, fd, ret, cur = 0; + + for (i = 0; i < 9; i++) + { + videodev[strlen(videodev) - 1] = '0' + i; + fd = open(videodev, O_RDONLY); + if (fd == -1) + continue; + ret = ioctl(fd, VIDIOC_QUERYCAP, &caps); + close(fd); + if (ret) + { + continue; + } + g_message("Found video device: %s\n", caps.card); + cammask |= (1 << i); + ++ncams; + } + + priv->num_webcam_devices = ncams; + if (ncams == 0) + return; + priv->webcam_devices = g_new0 (CheeseWebcamDevice, ncams); + for (i = 0; i < ncams; i++) + { + priv->webcam_devices[i].num_video_formats = 0; + priv->webcam_devices[i].video_formats = g_array_new (FALSE, FALSE, sizeof (CheeseVideoFormat)); + } + + for (i = 0; i < 9; i++) + { + if (cammask & (1 << i)) + { + videodev[strlen(videodev) - 1] = '0' + i; + priv->webcam_devices[i].video_device = g_strdup (videodev); + ++cur; + } + } +} +#endif /* !HAVE_HAL */ + static void cheese_webcam_get_supported_framerates (CheeseVideoFormat *video_format, GstStructure *structure) @@ -736,7 +822,11 @@ cheese_webcam_detect_webcam_devices (Che int i; +#if HAVE_HAL cheese_webcam_get_video_devices_from_hal (webcam); +#else + cheese_webcam_get_video_devices_from_probe (webcam); +#endif g_print ("Probing supported video formats...\n"); for (i = 0; i < priv->num_webcam_devices; i++)