Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > 0cae4b9408b3937361a5692e4e266ef5 > files > 1

libwebcam-0.2.0-1.20100322svn.fc13.src.rpm

From f8a73b2399c5266edc8487eac90755da6396e081 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 16 May 2010 11:17:22 +0200
Subject: [PATCH 1/6] Support mapping button controls

---
 libwebcam/dynctrl.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libwebcam/dynctrl.c b/libwebcam/dynctrl.c
index 8c90c87..20a4894 100644
--- a/libwebcam/dynctrl.c
+++ b/libwebcam/dynctrl.c
@@ -423,6 +423,9 @@ static enum v4l2_ctrl_type get_v4l2_ctrl_type_by_name (const xmlChar *name)
 	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_BOOLEAN"))) {
 		type = V4L2_CTRL_TYPE_BOOLEAN;
 	}
+	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_BUTTON"))) {
+		type = V4L2_CTRL_TYPE_BUTTON;
+	}
 #ifdef ENABLE_RAW_CONTROLS
 	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_STRING"))) {
 		type = V4L2_CTRL_TYPE_STRING;
@@ -432,9 +435,6 @@ static enum v4l2_ctrl_type get_v4l2_ctrl_type_by_name (const xmlChar *name)
 	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_MENU"))) {
 		type = V4L2_CTRL_TYPE_MENU;
 	}
-	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_BUTTON"))) {
-		type = V4L2_CTRL_TYPE_BUTTON;
-	}
 	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_INTEGER64"))) {
 		type = V4L2_CTRL_TYPE_INTEGER64;
 	}
-- 
1.7.0.1

From 96940902cfc0d71909df83a9e6e85eea008e704b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 16 May 2010 11:18:48 +0200
Subject: [PATCH 2/6] Change Pan / Tilt reset mappings to be of the button type

Note for this to work properly applications should specify a value
of 1 (3 for V4L2_CID_PANTILT_RESET, but see the next patch). I've a
kernel (uvcvideo) patch removing the need for this as this is not
in accordance with the v4l2 spec.
---
 uvcdynctrl/data/046d/logitech.xml |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/uvcdynctrl/data/046d/logitech.xml b/uvcdynctrl/data/046d/logitech.xml
index 590a223..2de441e 100644
--- a/uvcdynctrl/data/046d/logitech.xml
+++ b/uvcdynctrl/data/046d/logitech.xml
@@ -357,7 +357,7 @@
 			</uvc>
 			<v4l2>
 				<id>V4L2_CID_PAN_RESET</id>
-				<v4l2_type>V4L2_CTRL_TYPE_INTEGER</v4l2_type>
+				<v4l2_type>V4L2_CTRL_TYPE_BUTTON</v4l2_type>
 			</v4l2>
 		</mapping>
 		
@@ -371,7 +371,7 @@
 			</uvc>
 			<v4l2>
 				<id>V4L2_CID_TILT_RESET</id>
-				<v4l2_type>V4L2_CTRL_TYPE_INTEGER</v4l2_type>
+				<v4l2_type>V4L2_CTRL_TYPE_BUTTON</v4l2_type>
 			</v4l2>
 		</mapping>
 		
@@ -385,7 +385,7 @@
 			</uvc>
 			<v4l2>
 				<id>V4L2_CID_PANTILT_RESET</id>
-				<v4l2_type>V4L2_CTRL_TYPE_INTEGER</v4l2_type>
+				<v4l2_type>V4L2_CTRL_TYPE_BUTTON</v4l2_type>
 			</v4l2>
 		</mapping>
 		
-- 
1.7.0.1

From d802ac143d53fb791e86246b85b8a2ced66cd277 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 16 May 2010 12:19:14 +0200
Subject: [PATCH 3/6] Remove V4L2_CID_PANTILT_RESET mapping

There is no V4L2_CID_PANTILT_RESET in the official videodev2.h, if
an application wants to change 2 controls at the same time (trigger
2 button actions at the same time in this case) it should use the
extended controls API.
---
 common/include/dynctrl-logitech.h |    4 ----
 uvcdynctrl/data/046d/logitech.xml |   20 +-------------------
 2 files changed, 1 insertions(+), 23 deletions(-)

diff --git a/common/include/dynctrl-logitech.h b/common/include/dynctrl-logitech.h
index 6cf68a7..944e6f3 100644
--- a/common/include/dynctrl-logitech.h
+++ b/common/include/dynctrl-logitech.h
@@ -72,10 +72,6 @@
 #define V4L2_CID_TILT_RELATIVE 0x009A0905
 #endif
 
-#ifndef V4L2_CID_PANTILT_RESET
-#define V4L2_CID_PANTILT_RESET 0x0A046D03
-#endif
-
 #ifndef V4L2_CID_PAN_RESET
 #define V4L2_CID_PAN_RESET 0x009A0906
 #endif
diff --git a/uvcdynctrl/data/046d/logitech.xml b/uvcdynctrl/data/046d/logitech.xml
index 2de441e..9657b16 100644
--- a/uvcdynctrl/data/046d/logitech.xml
+++ b/uvcdynctrl/data/046d/logitech.xml
@@ -93,10 +93,6 @@
 			<value>0x009A0905</value><!-- V4L2_CID_CAMERA_CLASS_BASE + 5 -->
 		</constant>
 		<constant type="integer">
-			<id>V4L2_CID_PANTILT_RESET</id>
-			<value>0x0A046D03</value>
-		</constant>
-		<constant type="integer">
 			<id>V4L2_CID_PAN_RESET</id>
 			<value>0x009A0906</value><!-- V4L2_CID_CAMERA_CLASS_BASE + 6 -->
 		</constant>
@@ -374,21 +370,7 @@
 				<v4l2_type>V4L2_CTRL_TYPE_BUTTON</v4l2_type>
 			</v4l2>
 		</mapping>
-		
-		<mapping>
-			<name>Pan/tilt Reset</name>
-			<uvc>
-				<control_ref idref="logitech_motor_pantilt_reset"/>
-				<size>8</size>
-				<offset>0</offset>
-				<uvc_type>UVC_CTRL_DATA_TYPE_UNSIGNED</uvc_type>
-			</uvc>
-			<v4l2>
-				<id>V4L2_CID_PANTILT_RESET</id>
-				<v4l2_type>V4L2_CTRL_TYPE_BUTTON</v4l2_type>
-			</v4l2>
-		</mapping>
-		
+
 		<mapping>
 			<name>Focus</name>
 			<uvc>
-- 
1.7.0.1

From 1cfec4c49503da8bb8d7e4715e9d764fab610d3f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 16 May 2010 14:03:42 +0200
Subject: [PATCH 4/6] Add support for menu controls

This requires the latest uvcvideo.h with the menu support patch
applied.
---
 libwebcam/dynctrl.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/libwebcam/dynctrl.c b/libwebcam/dynctrl.c
index 20a4894..52d91ab 100644
--- a/libwebcam/dynctrl.c
+++ b/libwebcam/dynctrl.c
@@ -426,15 +426,15 @@ static enum v4l2_ctrl_type get_v4l2_ctrl_type_by_name (const xmlChar *name)
 	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_BUTTON"))) {
 		type = V4L2_CTRL_TYPE_BUTTON;
 	}
+	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_MENU"))) {
+		type = V4L2_CTRL_TYPE_MENU;
+	}
 #ifdef ENABLE_RAW_CONTROLS
 	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_STRING"))) {
 		type = V4L2_CTRL_TYPE_STRING;
 	}
 #endif
 	/*
-	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_MENU"))) {
-		type = V4L2_CTRL_TYPE_MENU;
-	}
 	else if(xmlStrEqual(name, BAD_CAST("V4L2_CTRL_TYPE_INTEGER64"))) {
 		type = V4L2_CTRL_TYPE_INTEGER64;
 	}
@@ -1090,6 +1090,66 @@ static CResult process_mapping (const xmlNode *node_mapping, ParseContext *ctx)
 	}
 	mapping_info.data_type = uvc_type;
 
+	if(v4l2_type == V4L2_CTRL_TYPE_MENU) {
+		xmlNode *node_menu = xml_get_first_child_by_name(node_v4l2, "menu_entry");
+		if(!node_menu) {
+			add_error_at_node(ctx, node_v4l2,
+				"<menu_entry> is mandatory for mappings with a v4l2_type of V4L2_CTRL_TYPE_MENU");
+			return C_PARSE_ERROR;
+		}
+
+		mapping_info.menu_count = 1;
+		while ((node_menu = xml_get_next_sibling_by_name(node_menu, "menu_entry")))
+			mapping_info.menu_count++;
+
+		mapping_info.menu_info =
+			malloc(mapping_info.menu_count * sizeof(struct uvc_menu_info));
+		if(!mapping_info.menu_info)
+			return C_NO_MEMORY;
+
+		int i;
+		node_menu = xml_get_first_child_by_name(node_v4l2, "menu_entry");
+		for (i = 0; i < mapping_info.menu_count; i++) {
+			xmlChar *menu_name_uni = xmlGetProp(node_menu, BAD_CAST("name"));
+			char *menu_name_asc = UNICODE_TO_NORM_ASCII(menu_name_uni);
+			if(!menu_name_asc) {
+				add_error_at_node(ctx, node_menu,
+					"Invalid menu_entry. 'name' attribute is mandatory.");
+				free(mapping_info.menu_info);
+				return C_PARSE_ERROR;
+			}
+
+			xmlChar *menu_value = xmlGetProp(node_menu, BAD_CAST("value"));
+			if(!menu_value) {
+				add_error_at_node(ctx, node_menu,
+					"Invalid menu_entry. 'value' attribute is mandatory.");
+				xmlFree(menu_name_uni);
+				free(menu_name_asc);
+				free(mapping_info.menu_info);
+				return C_PARSE_ERROR;
+			}
+
+			snprintf((char *)mapping_info.menu_info[i].name,
+				 sizeof(mapping_info.menu_info[i].name),
+				 "%s", menu_name_asc);
+			ret = lookup_or_convert_to_integer(menu_value,
+				(int *)&mapping_info.menu_info[i].value,
+				ctx);
+			if(ret)
+				add_error_at_node(ctx, node_menu,
+					"<menu_entry> value contains invalid number or references unknown constant: '%s'",
+					menu_value);
+			xmlFree(menu_value);
+			xmlFree(menu_name_uni);
+			free(menu_name_asc);
+			if(ret) {
+				free(mapping_info.menu_info);
+				return C_PARSE_ERROR;
+			}
+			node_menu = xml_get_next_sibling_by_name(node_menu, "menu_entry");
+		}
+	}
+
 	// Add the control to the UVC driver's control list
 	/*
 	printf(
@@ -1114,6 +1174,7 @@ static CResult process_mapping (const xmlNode *node_mapping, ParseContext *ctx)
 	);
 	*/
 	int v4l2_ret = ioctl(ctx->v4l2_handle, UVCIOC_CTRL_MAP, &mapping_info);
+	free(mapping_info.menu_info);
 	if(v4l2_ret != 0
 #ifdef DYNCTRL_IGNORE_EEXIST_AFTER_PASS1
 			&& (ctx->pass == 1 || errno != EEXIST)
-- 
1.7.0.1

From 9a43ebe963341103482b34aedb66200e247922e5 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 16 May 2010 14:15:52 +0200
Subject: [PATCH 5/6] Change LED mode control to a menu

---
 uvcdynctrl/data/046d/logitech.xml |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/uvcdynctrl/data/046d/logitech.xml b/uvcdynctrl/data/046d/logitech.xml
index 9657b16..3cd6767 100644
--- a/uvcdynctrl/data/046d/logitech.xml
+++ b/uvcdynctrl/data/046d/logitech.xml
@@ -395,7 +395,11 @@
 			</uvc>
 			<v4l2>
 				<id>V4L2_CID_LED1_MODE</id>
-				<v4l2_type>V4L2_CTRL_TYPE_INTEGER</v4l2_type>
+				<v4l2_type>V4L2_CTRL_TYPE_MENU</v4l2_type>
+				<menu_entry name="Off" value="0"/>
+				<menu_entry name="On" value="1"/>
+				<menu_entry name="Blinking" value="2"/>
+				<menu_entry name="Auto" value="3"/>
 			</v4l2>
 		</mapping>
 		
-- 
1.7.0.1

From 9f1f9521b8dbbb9d33f5723bf91c5d006a394eba Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 16 May 2010 14:50:51 +0200
Subject: [PATCH 6/6] Make control mapping work with older kernels

With the addition of the capability of adding menu control mappings
the id of the UVCIOC_CTRL_MAP ioctl changed as the size of the
uvc_xu_control_mapping struct changed. The old ioctl id is still available
as UVCIOC_CTRL_MAP_OLD. The main reason for the availability of the old
ioctl id is for use by the driver, so that newer kernels will stay
working with older versions of uvcdynctrl. But we can use it the otherway
around too, to make uvcdynctrl compiled with the new uvcvideo.h also
work with older kernels.
---
 libwebcam/dynctrl.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/libwebcam/dynctrl.c b/libwebcam/dynctrl.c
index 52d91ab..d3ad3e4 100644
--- a/libwebcam/dynctrl.c
+++ b/libwebcam/dynctrl.c
@@ -1174,6 +1174,24 @@ static CResult process_mapping (const xmlNode *node_mapping, ParseContext *ctx)
 	);
 	*/
 	int v4l2_ret = ioctl(ctx->v4l2_handle, UVCIOC_CTRL_MAP, &mapping_info);
+	if(v4l2_ret != 0 && errno == EINVAL) {
+		/* EINVAL can indicate:
+		   1) wrong v4l2_type, we never cause this
+		   2) wrong id, a wrong entry in the xml file could cause this
+		   3) an older kernel which needs UVCIOC_CTRL_MAP_OLD
+		   We assume 3 is the cause, if 2 is the cause we will get
+		   the same error with UVCIOC_CTRL_MAP_OLD/ */
+
+		/* If this is a menu type control change it to an integer
+		   control, menu controls are not supported with older
+		   kernels, and worse they make the driver oops (NULL ptr
+		   deref). */
+		if (mapping_info.v4l2_type == V4L2_CTRL_TYPE_MENU)
+			mapping_info.v4l2_type = V4L2_CTRL_TYPE_INTEGER;
+
+		v4l2_ret = ioctl(ctx->v4l2_handle, UVCIOC_CTRL_MAP_OLD,
+				 &mapping_info);
+	}
 	free(mapping_info.menu_info);
 	if(v4l2_ret != 0
 #ifdef DYNCTRL_IGNORE_EEXIST_AFTER_PASS1
-- 
1.7.0.1