[gnome-settings-daemon] power: Use the kernel-supplied backlight type rather than a whitelist



commit fff09fe17eecb9314962d119a5c5b4e865f2570d
Author: Richard Hughes <richard hughsie com>
Date:   Thu Feb 2 16:30:42 2012 +0000

    power: Use the kernel-supplied backlight type rather than a whitelist
    
    For a long time we have shipped a whitelist that mixes a list of devices we
    should use, and the order we should attempt to do them. Since kernel 2.6.37 we
    have a 'type' attribute which specifies if the device is a firmware device,
    platform or raw device. According to mjg59, we should attempt to connect to
    devices in this order only and nuke the whitelist.
    
    This ensures the whitelist stays up to date as new backlight device names appear
    upstream in the kernel.

 plugins/power/gsd-backlight-helper.c |  136 +++++++++++++++++++++++-----------
 1 files changed, 94 insertions(+), 42 deletions(-)
---
diff --git a/plugins/power/gsd-backlight-helper.c b/plugins/power/gsd-backlight-helper.c
index ea5b5b7..005f240 100644
--- a/plugins/power/gsd-backlight-helper.c
+++ b/plugins/power/gsd-backlight-helper.c
@@ -36,65 +36,117 @@
 
 #define GSD_BACKLIGHT_HELPER_SYSFS_LOCATION			"/sys/class/backlight"
 
-static gchar *
-gsd_backlight_helper_get_best_backlight ()
+typedef enum {
+	GS_BACKLIGHT_TYPE_UNKNOWN,
+	GS_BACKLIGHT_TYPE_FIRMWARE,
+	GS_BACKLIGHT_TYPE_PLATFORM,
+	GS_BACKLIGHT_TYPE_RAW
+} GsdBacklightType;
+
+static GsdBacklightType
+gsd_backlight_helper_get_type (const gchar *sysfs_path)
 {
-	gchar *filename;
-	guint i;
 	gboolean ret;
-	GDir *dir = NULL;
+	gchar *filename = NULL;
 	GError *error = NULL;
-	const gchar *first_device;
-
-	/* available kernel interfaces in priority order */
-	static const gchar *backlight_interfaces[] = {
-		"nv_backlight",
-		"asus_laptop",
-		"toshiba",
-		"eeepc-wmi",
-		"eeepc",
-		"thinkpad_screen",
-		"dell_backlight",
-		"acpi_video1",
-		"mbp_backlight",
-		"acpi_video0",
-		"fujitsu-laptop",
-		"sony",
-		"samsung",
-		NULL,
-	};
+	gchar *type_tmp = NULL;
+	GsdBacklightType type = GS_BACKLIGHT_TYPE_UNKNOWN;
 
-	/* search each one */
-	for (i=0; backlight_interfaces[i] != NULL; i++) {
-		filename = g_build_filename (GSD_BACKLIGHT_HELPER_SYSFS_LOCATION,
-					     backlight_interfaces[i], NULL);
-		ret = g_file_test (filename, G_FILE_TEST_EXISTS);
-		if (ret)
-			goto out;
-		g_free (filename);
+	filename = g_build_filename (sysfs_path,
+				     "type", NULL);
+	ret = g_file_get_contents (filename,
+				   &type_tmp,
+				   NULL, &error);
+	if (!ret) {
+		g_warning ("failed to get type: %s", error->message);
+		g_error_free (error);
+		goto out;
 	}
+	if (g_str_has_prefix (type_tmp, "platform")) {
+		type = GS_BACKLIGHT_TYPE_PLATFORM;
+		goto out;
+	}
+	if (g_str_has_prefix (type_tmp, "firmware")) {
+		type = GS_BACKLIGHT_TYPE_FIRMWARE;
+		goto out;
+	}
+	if (g_str_has_prefix (type_tmp, "raw")) {
+		type = GS_BACKLIGHT_TYPE_RAW;
+		goto out;
+	}
+out:
+	g_free (filename);
+	g_free (type_tmp);
+	return type;
+}
 
-	/* nothing found in the ordered list */
-	filename = NULL;
+static gchar *
+gsd_backlight_helper_get_best_backlight ()
+{
+	const gchar *device_name;
+	const gchar *filename_tmp;
+	gchar *best_device = NULL;
+	gchar *filename = NULL;
+	GDir *dir = NULL;
+	GError *error = NULL;
+	GPtrArray *sysfs_paths = NULL;
+	GsdBacklightType *backlight_types = NULL;
+	guint i;
 
-	/* find any random ones */
+	/* search the backlight devices and prefer the types:
+	 * firmware -> platform -> raw */
 	dir = g_dir_open (GSD_BACKLIGHT_HELPER_SYSFS_LOCATION, 0, &error);
 	if (dir == NULL) {
 		g_warning ("failed to find any devices: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
-
-	/* get first device if any */
-	first_device = g_dir_read_name (dir);
-	if (first_device != NULL) {
+	sysfs_paths = g_ptr_array_new_with_free_func (g_free);
+	device_name = g_dir_read_name (dir);
+	while (device_name != NULL) {
 		filename = g_build_filename (GSD_BACKLIGHT_HELPER_SYSFS_LOCATION,
-					     first_device, NULL);
+					     device_name, NULL);
+		g_ptr_array_add (sysfs_paths, filename);
+		device_name = g_dir_read_name (dir);
+	}
+
+	/* no backlights */
+	if (sysfs_paths->len == 0)
+		goto out;
+
+	/* find out the type of each backlight */
+	backlight_types = g_new0 (GsdBacklightType, sysfs_paths->len);
+	for (i = 0; i < sysfs_paths->len; i++) {
+		filename_tmp = g_ptr_array_index (sysfs_paths, i);
+		backlight_types[i] = gsd_backlight_helper_get_type (filename_tmp);
+	}
+
+	/* any devices of type firmware -> platform -> raw? */
+	for (i = 0; i < sysfs_paths->len; i++) {
+		if (backlight_types[i] == GS_BACKLIGHT_TYPE_FIRMWARE) {
+			best_device = g_strdup (g_ptr_array_index (sysfs_paths, i));
+			goto out;
+		}
+	}
+	for (i = 0; i < sysfs_paths->len; i++) {
+		if (backlight_types[i] == GS_BACKLIGHT_TYPE_PLATFORM) {
+			best_device = g_strdup (g_ptr_array_index (sysfs_paths, i));
+			goto out;
+		}
+	}
+	for (i = 0; i < sysfs_paths->len; i++) {
+		if (backlight_types[i] == GS_BACKLIGHT_TYPE_RAW) {
+			best_device = g_strdup (g_ptr_array_index (sysfs_paths, i));
+			goto out;
+		}
 	}
 out:
+	g_free (backlight_types);
+	if (sysfs_paths != NULL)
+		g_ptr_array_unref (sysfs_paths);
 	if (dir != NULL)
 		g_dir_close (dir);
-	return filename;
+	return best_device;
 }
 
 static gboolean



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]