Mercurial > backlight
view backlight.c @ 9:bd47bd0c977a
backlight: fix for FreeBSD and pet a warning
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 19 Sep 2019 21:05:00 +0200 |
parents | 45a06b02a61f |
children | 2b12d8bee90d |
line wrap: on
line source
/* * main.c -- adjust laptop backlight using ACPI * * Copyright (c) 2010-2019 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <errno.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> enum action { None, Up, Down }; static void usage(const char *name) { fprintf(stderr, "usage: %s down\n", name); fprintf(stderr, " %s up\n", name); exit(1); } static void die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "abort: "); vfprintf(stderr, fmt, ap); va_end(ap); exit(1); } /* {{{ Support for FreeBSD */ #if defined(__FreeBSD__) #include <sys/types.h> #include <sys/sysctl.h> static int set(enum action type) { int current, next = 0, i; int msg[100]; size_t len, nextlen; /* First, get all values availables */ len = sizeof (msg); if (sysctlbyname("hw.acpi.video.lcd0.levels", msg, &len, NULL, 0) == -1) die("sysctl: %s\n", strerror(errno)); /* Get the current value */ len = sizeof (current); if (sysctlbyname("hw.acpi.video.lcd0.brightness", ¤t, &len, NULL, 0) == -1) die("sysctl: %s\n", strerror(errno)); /* First find the index of 0 */ for (i = 0; msg[i] != 0; ++i) continue; /* Find the current value index in msg */ for (; msg[i] != current; ++i) continue; if (type == Up) { if (msg[i] >= 100) return msg[i]; next = msg[i + 1]; } else { if (msg[i] == 0) return 0; next = msg[i - 1]; } nextlen = sizeof (next); if (sysctlbyname("hw.acpi.video.lcd0.brightness", ¤t, &len, &next, nextlen) == -1) die("sysctl: %s\n", strerror(errno)); return next; } /* }}} */ /* {{{ Support for Linux */ #elif defined(__linux__) #include <sys/types.h> #include <sys/stat.h> static int read_int(const char *path) { FILE *fp; int value = 0; if ((fp = fopen(path, "r")) == NULL) die("open: %s\n", strerror(errno)); if (fscanf(fp, "%d", &value) != 1) die("could not read value from %s\n", path); fclose(fp); return value; } static int write_int(const char *path, int value) { FILE *fp; if ((fp = fopen(path, "w+")) == NULL) die("open: %s\n", strerror(errno)); fprintf(fp, "%d", value); return value; } static const char * find_card(void) { static const char *list[] = { "/sys/class/backlight/acpi_video0", "/sys/class/backlight/intel_backlight", NULL }; struct stat st; for (const char **ptr = list; *ptr != NULL; ++ptr) if (stat(*ptr, &st) >= 0) return *ptr; return NULL; } static int set(int type) { int current, max; char file[BUFSIZ]; const char *card = find_card(); /* Find a card adaptor */ if (!card) die("could not find card adaptor\n"); /* Read actual */ snprintf(file, sizeof (file), "%s/actual_brightness", card); current = read_int(file); /* Read max */ snprintf(file, sizeof (file), "%s/max_brightness", card); max = read_int(file); if (type == Up) { current += max / 100; if (current > max) return max; } else { current -= max / 100; if (current < 0) return 0; } snprintf(file, sizeof (file), "%s/brightness", card); return write_int(file, current); } #else /* Not supported */ static int set(int type) { (void)type; die("backlight is not supported on this system"); } #endif /* }}} */ int main(int argc, char *argv[]) { int st, type = None; if (argc < 2) usage(argv[0]); if (strcmp(argv[1], "up") == 0) type = Up; else if (strcmp(argv[1], "down") == 0) type = Down; else usage(argv[0]); if ((st = set(type)) < 0) return 1; printf("switching to %d\n", st); return 0; }