#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
+#include "verbs.h"
#define PCI_CLASS_GRAPHICS_CARD 0x30000
return 1; /* Found. */
}
-static int run(int argc, char *argv[]) {
+static int verb_load(int argc, char *argv[], void *userdata) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
- unsigned max_brightness, brightness;
+ unsigned max_brightness, brightness, percent;
+ bool clamp;
int r;
- log_setup();
+ assert(argc == 2);
- if (argv_looks_like_help(argc, argv))
- return help();
-
- if (argc != 3)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires two arguments.");
-
- if (!STR_IN_SET(argv[1], "load", "save"))
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", argv[1]);
-
- umask(0022);
+ if (!shall_restore_state())
+ return 0;
- r = device_new_from_arg(argv[2], &device);
+ r = device_new_from_arg(argv[1], &device);
if (r <= 0)
return r;
if (r <= 0)
return r;
- /* If there are multiple conflicting backlight devices, then their probing at boot-time might
- * happen in any order. This means the validity checking of the device then is not reliable,
- * since it might not see other devices conflicting with a specific backlight. To deal with
- * this, we will actively delete backlight state files at shutdown (where device probing should
- * be complete), so that the validity check at boot time doesn't have to be reliable. */
+ /* Ignore any errors in validation, and use the device as is. */
+ if (validate_device(device) == 0)
+ return 0;
- if (streq(argv[1], "load")) {
- unsigned percent;
- bool clamp;
+ clamp = shall_clamp(device, &percent);
- if (!shall_restore_state())
+ r = read_saved_brightness(device, &brightness);
+ if (r < 0) {
+ /* Fallback to clamping current brightness or exit early if clamping is not
+ * supported/enabled. */
+ if (!clamp)
return 0;
- if (validate_device(device) == 0)
- return 0;
+ r = read_brightness(device, max_brightness, &brightness);
+ if (r < 0)
+ return log_device_error_errno(device, r, "Failed to read current brightness: %m");
- clamp = shall_clamp(device, &percent);
+ (void) clamp_brightness(device, percent, /* saved = */ false, max_brightness, &brightness);
+ } else if (clamp)
+ (void) clamp_brightness(device, percent, /* saved = */ true, max_brightness, &brightness);
- if (read_saved_brightness(device, &brightness) < 0) {
- /* Fallback to clamping current brightness or exit early if clamping is not
- * supported/enabled. */
- if (!clamp)
- return 0;
+ r = sd_device_set_sysattr_valuef(device, "brightness", "%u", brightness);
+ if (r < 0)
+ return log_device_error_errno(device, r, "Failed to write system 'brightness' attribute: %m");
- r = read_brightness(device, max_brightness, &brightness);
- if (r < 0)
- return log_device_error_errno(device, r, "Failed to read current brightness: %m");
+ return 0;
+}
- (void) clamp_brightness(device, percent, /* saved = */ false, max_brightness, &brightness);
- } else if (clamp)
- (void) clamp_brightness(device, percent, /* saved = */ true, max_brightness, &brightness);
+static int verb_save(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_device_unrefp) sd_device *device = NULL;
+ _cleanup_free_ char *path = NULL;
+ unsigned max_brightness, brightness;
+ int r;
- r = sd_device_set_sysattr_valuef(device, "brightness", "%u", brightness);
- if (r < 0)
- return log_device_error_errno(device, r, "Failed to write system 'brightness' attribute: %m");
+ assert(argc == 2);
- } else if (streq(argv[1], "save")) {
- _cleanup_free_ char *saved = NULL;
+ r = device_new_from_arg(argv[1], &device);
+ if (r <= 0)
+ return r;
- r = build_save_file_path(device, &saved);
- if (r < 0)
- return r;
+ r = read_max_brightness(device, &max_brightness);
+ if (r <= 0)
+ return r;
- if (validate_device(device) == 0) {
- (void) unlink(saved);
- return 0;
- }
+ r = build_save_file_path(device, &path);
+ if (r < 0)
+ return r;
- r = read_brightness(device, max_brightness, &brightness);
- if (r < 0)
- return log_device_error_errno(device, r, "Failed to read current brightness: %m");
+ /* If there are multiple conflicting backlight devices, then their probing at boot-time might
+ * happen in any order. This means the validity checking of the device then is not reliable,
+ * since it might not see other devices conflicting with a specific backlight. To deal with
+ * this, we will actively delete backlight state files at shutdown (where device probing should
+ * be complete), so that the validity check at boot time doesn't have to be reliable. */
+ if (validate_device(device) == 0) {
+ (void) unlink(path);
+ return 0;
+ }
- r = write_string_filef(saved, WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_MKDIR_0755, "%u", brightness);
- if (r < 0)
- return log_device_error_errno(device, r, "Failed to write %s: %m", saved);
+ r = read_brightness(device, max_brightness, &brightness);
+ if (r < 0)
+ return log_device_error_errno(device, r, "Failed to read current brightness: %m");
- } else
- assert_not_reached();
+ r = write_string_filef(path, WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_MKDIR_0755, "%u", brightness);
+ if (r < 0)
+ return log_device_error_errno(device, r, "Failed to write %s: %m", path);
return 0;
}
+static int run(int argc, char *argv[]) {
+ static const Verb verbs[] = {
+ { "load", 2, 2, VERB_ONLINE_ONLY, verb_load },
+ { "save", 2, 2, VERB_ONLINE_ONLY, verb_save },
+ {}
+ };
+
+ log_setup();
+
+ if (argv_looks_like_help(argc, argv))
+ return help();
+
+ umask(0022);
+
+ return dispatch_verb(argc, argv, verbs, NULL);
+}
+
DEFINE_MAIN_FUNCTION(run);