diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2021-10-03 11:14:45 +0200 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2021-10-03 13:16:30 +0200 | 
| commit | 83b4d96b153632aa7d5e59c2f0b4c3bcbc43ade2 (patch) | |
| tree | 3889d6b637fbb101dd5edcf6ef7c313ae91768c3 | |
| parent | 7dcad3424d8a0c668b97169511d5ae727c363061 (diff) | |
| download | desktop-tools-83b4d96b153632aa7d5e59c2f0b4c3bcbc43ade2.tar.gz desktop-tools-83b4d96b153632aa7d5e59c2f0b4c3bcbc43ade2.tar.xz desktop-tools-83b4d96b153632aa7d5e59c2f0b4c3bcbc43ade2.zip | |
wmstatus: rework battery reporting
Report "USB" and USB devices as well (SpaceMouse, Intuos),
make use of the "capacity" field everywhere.
Present read errors to the user, rather than spam the log.
| -rw-r--r-- | wmstatus.c | 87 | 
1 files changed, 56 insertions, 31 deletions
| @@ -1022,13 +1022,14 @@ read_value (int dir, const char *filename, struct error **e)  		return NULL;  	} +	errno = 0;  	struct str s = str_make (); -	bool success = read_line (fp, &s); +	bool success = read_line (fp, &s) && !ferror (fp);  	fclose (fp);  	if (!success)  	{ -		error_set (e, "%s: %s", filename, "read failed"); +		error_set (e, "%s: %s", filename, errno ? strerror (errno) : "EOF");  		return NULL;  	}  	return str_steal (&s); @@ -1043,42 +1044,61 @@ read_number (int dir, const char *filename, struct error **e)  	unsigned long number = 0;  	if (!xstrtoul (&number, value, 10)) -		error_set (e, "%s: %s", filename, "doesn't contain an unsigned number"); +		error_set (e, "%s: %s", filename, "doesn't contain a valid number");  	free (value);  	return number;  }  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +static int +read_battery_charge (int dir) +{ +	struct error *error = NULL; +	double capacity, now, full; +	if ((capacity = read_number (dir, "capacity",    &error), !error)) +		return capacity; + +	error_free (error); +	if ((now      = read_number (dir, "charge_now",  &error), !error) +	 && (full     = read_number (dir, "charge_full", &error), !error)) +		return now / full * 100 + 0.5; + +	error_free (error); +	return -1; +} +  static char * -read_battery_status (int dir, struct error **e) +read_battery_status (int dir, char **type)  { -	char *result = NULL; +	// We present errors to the user, don't fill up the session's log.  	struct error *error = NULL; +	struct str s = str_make (); -	char *status; -	double charge_now; -	double charge_full; +	// Dell is being unreasonable and seems to set charge_now +	// to charge_full_design when the battery is fully charged +	int charge = read_battery_charge (dir); +	if (charge >= 0 && charge <= 100) +		str_append_printf (&s, "%u%%", charge); -	if ((status      = read_value  (dir, "status",      &error), error) -	 || (charge_now  = read_number (dir, "charge_now",  &error), error) -	 || (charge_full = read_number (dir, "charge_full", &error), error)) -		error_propagate (e, error); +	char *status = NULL; +	char *model_name = read_value (dir, "model_name", NULL); +	if (model_name) +	{ +		model_name[strcspn (model_name, " ")] = 0; +		cstr_set (type, model_name); +	} +	else if ((status = read_value (dir, "status", &error), !error)) +	{ +		str_append_printf (&s, " (%s)", status); +		free (status); +	}  	else  	{ -		struct str s = str_make (); -		str_append (&s, status); - -		// Dell is being unreasonable and seems to set charge_now -		// to charge_full_design when the battery is fully charged -		unsigned percentage = charge_now / charge_full * 100 + 0.5; -		if (percentage < 100) -			str_append_printf (&s, " (%u%%)", percentage); -		result = str_steal (&s); +		str_append_printf (&s, " (%s)", strerror (errno)); +		error_free (error);  	} - -	free (status); -	return result; +	return str_steal (&s);  }  static char * @@ -1094,14 +1114,13 @@ try_power_supply (int dir, struct error **e)  	bool is_relevant =  		!strcmp (type, "Battery") || +		!strcmp (type, "USB") ||  		!strcmp (type, "UPS");  	char *result = NULL;  	if (is_relevant)  	{ -		char *status = read_battery_status (dir, &error); -		if (error) -			error_propagate (e, error); +		char *status = read_battery_status (dir, &type);  		if (status)  			result = xstrdup_printf ("%s %s", type, status);  		free (status); @@ -1122,8 +1141,8 @@ make_battery_status (void)  	}  	struct dirent *entry; -	char *status = NULL; -	while (!status && (entry = readdir (power_supply))) +	struct strv batteries = strv_make (); +	while ((entry = readdir (power_supply)))  	{  		const char *device_name = entry->d_name;  		if (device_name[0] == '.') @@ -1137,8 +1156,11 @@ make_battery_status (void)  		}  		struct error *error = NULL; -		status = try_power_supply (dir, &error); +		char *status = try_power_supply (dir, &error);  		close (dir); + +		if (status) +			strv_append_owned (&batteries, status);  		if (error)  		{  			print_error ("%s: %s", device_name, error->message); @@ -1146,7 +1168,10 @@ make_battery_status (void)  		}  	}  	closedir (power_supply); -	return status; + +	char *result = batteries.len ? strv_join (&batteries, " ") : NULL; +	strv_free (&batteries); +	return result;  }  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
