view main.c @ 1:4402b74acda0

misc: happy new year!
author David Demelier <markand@malikania.fr>
date Mon, 02 Jan 2017 16:34:05 +0100
parents 73a371432d36
children a81001c9e45a
line wrap: on
line source

/*
 * main.c -- adjust laptop backlight using ACPI
 *
 * Copyright (c) 2010-2017 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

enum {
    Up,
    Down
};

static void
usage(const char *name)
{
    fprintf(stderr, "usage: %s down\n", name);
    fprintf(stderr, "       %s up\n", name);
    exit(1);
}

/* {{{ Support for FreeBSD */

#ifdef __FreeBSD__
#  include <sys/types.h>
#  include <sys/sysctl.h>

static int
set(int type)
{
    int current, next, 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) {
        perror("sysctl");
        return -1;
    }

    /* Get the current value */
    len = sizeof (current);

    if (sysctlbyname("hw.acpi.video.lcd0.brightness", &current, &len, NULL, 0) == -1) {
        perror("sysctl");
        return -1;
    }

    /* 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", &current, &len, &next, nextlen) == -1) {
        perror("sysctl");
        return -1;
    }

    return next;
}

#endif

/* }}} */

/* {{{ Support for Linux */

#ifdef __linux__

static int
read_int(const char *path)
{
    FILE *fp;
    int value;

    if ((fp = fopen(path, "r")) == NULL) {
        perror("open");
        return -1;
    }

    if (fscanf(fp, "%d", &value) != 1)
        value = -1;
    fclose(fp);

    return value;
}

static int
write_int(const char *path, int value)
{
    FILE *fp;

    if ((fp = fopen(path, "w+")) == NULL) {
        perror("open");
        return -1;
    }

    fprintf(fp, "%d", value);

    return value;
}

static int
set(int type)
{
    int current, max, next;

    /* Read actual */
    current = read_int("/sys/class/backlight/acpi_video0/actual_brightness");
    if (current < 0)
        return -1;

    /* Read max */
    max = read_int("/sys/class/backlight/acpi_video0/max_brightness");
    if (max < 0)
        return -1;

    if (type == Up) {
        next = ++ current;

        if (next > max)
            return max;
    } else {
        next = -- current;

        if (next < 0)
            return 0;
    }

    return write_int("/sys/class/backlight/acpi_video0/brightness", next);
}

#else

#include <errno.h>

/* Not supported */
static int
set(int type)
{
    (void)type;

    fprintf(stderr, "backlight is not supported on this system");
    exit(1);
}

#endif

/* }}} */

int
main(int argc, char *argv[])
{
    int st, type;

    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) {
        printf("failed to set brightness to %d\n", st);
        return 1;
    }

    printf("switching to %d\n", st);

    return 0;
}