/* returns a value between 0-255 range, where higher is brighter */ static uint32_t get_normalized_backlight(struct backlight *backlight) { long brightness, max_brightness; long norm; brightness = backlight_get_brightness(backlight); max_brightness = backlight_get_max_brightness(backlight); /* convert it to a scale of 0 to 255 */ norm = (brightness * 255)/(max_brightness); return (int) norm; }
static void set_backlight(struct udev_device *drm_device, int connector_id, int blight) { int connector_type; long max_brightness, brightness, actual_brightness; struct backlight *backlight; long new_blight; connector_type = get_drm_connector_type(drm_device, connector_id); if (connector_type < 0) return; backlight = backlight_init(drm_device, connector_type); if (!backlight) { printf("backlight adjust failed\n"); return; } max_brightness = backlight_get_max_brightness(backlight); printf("Max backlight: %ld\n", max_brightness); brightness = backlight_get_brightness(backlight); printf("Cached backlight: %ld\n", brightness); actual_brightness = backlight_get_actual_brightness(backlight); printf("Hardware backlight: %ld\n", actual_brightness); printf("normalized current brightness: %d\n", get_normalized_backlight(backlight)); /* denormalized value */ new_blight = (blight * max_brightness) / 255; backlight_set_brightness(backlight, new_blight); printf("Setting brightness to: %ld (norm: %d)\n", new_blight, blight); backlight_destroy(backlight); }
struct backlight *backlight_init(struct udev_device *drm_device, uint32_t connector_type) { const char *syspath = NULL; char *pci_name = NULL; char *chosen_path = NULL; char *path = NULL; DIR *backlights; struct dirent *entry; enum backlight_type type = 0; char buffer[100]; struct backlight *backlight; int ret; if (!drm_device) return NULL; syspath = udev_device_get_syspath(drm_device); if (!syspath) return NULL; if (asprintf(&path, "%s/%s", syspath, "device") < 0) return NULL; ret = readlink(path, buffer, sizeof(buffer)); free(path); if (ret < 0) return NULL; buffer[ret] = '\0'; pci_name = basename(buffer); if (connector_type <= 0) return NULL; backlights = opendir("/sys/class/backlight"); if (!backlights) return NULL; /* Find the "best" backlight for the device. Firmware interfaces are preferred over platform interfaces are preferred over raw interfaces. For raw interfaces we'll check if the device ID in the form of pci match, while for firmware interfaces we require the pci ID to match. It's assumed that platform interfaces always match, since we can't actually associate them with IDs. A further awkwardness is that, while it's theoretically possible for an ACPI interface to include support for changing the backlight of external devices, it's unlikely to ever be done. It's effectively impossible for a platform interface to do so. So if we get asked about anything that isn't LVDS or eDP, we pretty much have to require that the control be supplied via a raw interface */ while ((entry = readdir(backlights))) { char *backlight_path; char *parent; enum backlight_type entry_type; int fd; if (entry->d_name[0] == '.') continue; if (asprintf(&backlight_path, "%s/%s", "/sys/class/backlight", entry->d_name) < 0) return NULL; if (asprintf(&path, "%s/%s", backlight_path, "type") < 0) return NULL; fd = open(path, O_RDONLY); if (fd < 0) goto out; ret = read (fd, &buffer, sizeof(buffer)); close (fd); if (ret < 1) goto out; buffer[ret] = '\0'; if (!strncmp(buffer, "raw\n", sizeof(buffer))) entry_type = BACKLIGHT_RAW; else if (!strncmp(buffer, "platform\n", sizeof(buffer))) entry_type = BACKLIGHT_PLATFORM; else if (!strncmp(buffer, "firmware\n", sizeof(buffer))) entry_type = BACKLIGHT_FIRMWARE; else goto out; if (connector_type != DRM_MODE_CONNECTOR_LVDS && connector_type != DRM_MODE_CONNECTOR_eDP) { /* External displays are assumed to require gpu control at the moment */ if (entry_type != BACKLIGHT_RAW) goto out; } free (path); if (asprintf(&path, "%s/%s", backlight_path, "device") < 0) return NULL; ret = readlink(path, buffer, sizeof(buffer)); if (ret < 0) goto out; buffer[ret] = '\0'; parent = basename(buffer); /* Perform matching for raw and firmware backlights - platform backlights have to be assumed to match */ if (entry_type == BACKLIGHT_RAW || entry_type == BACKLIGHT_FIRMWARE) { if (!(pci_name && !strcmp(pci_name, parent))) goto out; } if (entry_type < type) goto out; type = entry_type; if (chosen_path) free(chosen_path); chosen_path = strdup(backlight_path); out: free(backlight_path); free(path); } if (!chosen_path) return NULL; backlight = malloc(sizeof(struct backlight)); if (!backlight) goto err; backlight->path = chosen_path; backlight->type = type; backlight->max_brightness = backlight_get_max_brightness(backlight); if (backlight->max_brightness < 0) goto err; backlight->brightness = backlight_get_actual_brightness(backlight); if (backlight->brightness < 0) goto err; return backlight; err: if (chosen_path) free(chosen_path); free (backlight); return NULL; }