I map this to Meta-B since the native one only goes to "brightest" and
there is no other way to adjust it.
This has been used on linux kernels 2.6.22 and 2.6.24.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
//
// can use debian package for libxosd-dev
//
// compile with:
// gcc -Wall -DXOSD `xosd-config --cflags --libs` brightness_lcd.c -o brightness_lcd
//
// set sticky:
// sudo chown root:root brightness_lcd
// sudo chmod u+s brightness_lcd
//
// execute:
// ./brightness_lcd
//
#ifdef XOSD
#include <xosd.h>
#endif //XOSD
#define LEVELS "levels:"
#define CURRENT "current:"
static int lcmp(const void *a, const void *b)
{
long x = *((long *)a), y = *((long *)b);
return (x > y) - (x < y);
}
void help(int argc, char *argv[])
{
// ======= args =========
if (argc>1 && !strcmp(argv[1], "-h")) {
fprintf(stderr,
"By default, move to next brightness level\n"
"Options are device and/or value, e.g.:\n"
"\t%s 37 /proc/acpi/video/VGA/LCD/brightness\n"
"\t%s 37\n",
argv[0], argv[0] );
exit(-1);
}
}
int main(int argc, char *argv[])
{
FILE *fp=NULL;
char *devname = "/proc/acpi/video/VGA/LCD/brightness";
int NS=1024;
char s[NS];
int NL = 256;
long levels[NL], nlevels = 0;
long current = 0;
int i, j, c=0;
struct timespec ts = {0, 1000000*250};
#ifdef XOSD
xosd *osd;
#endif //XOSD
help(argc, argv);
// ======= read =========
if (argc>2)
devname = argv[2];
if ( !(fp = fopen(devname, "r")) ) {
fprintf(stderr,
"Could not open device '%s' for reading.\n",
devname);
return -1;
}
while (fgets(s, NS, fp)) {
if ( !strncmp(LEVELS, s, strlen(LEVELS)) ) {
char *sp, *sp1 = s + strlen(LEVELS);
errno = 0;
do {
sp = sp1;
levels[nlevels++] = strtol(sp, &sp1, 10);
} while (sp!=sp1) ;
nlevels--;
// printf("levels: ... %ld %ld %ld x%ld\n",
// levels[8], levels[9], levels[10], nlevels);
}
else if ( !strncmp(CURRENT, s, strlen(CURRENT)) ) {
char *sp = s + strlen(CURRENT);
current = strtol(sp, &sp, 10);
// printf("current: %ld\n", current);
}
}
if (fp)
fclose(fp);
// ======= sort and remove duplicates =========
qsort(levels, nlevels, sizeof(long), lcmp);
for (i=1; i<nlevels; i++) {
if (levels[i]==levels[i-1]) {
for (j=i+1; j<nlevels; j++) {
levels[j-1] = levels[j];
}
nlevels--;
}
}
// for (i=0; i<nlevels; i++) {
// printf(" level: %ld\n", levels[i]);
// }
// ======= find current, go to next =========
// printf("current: %ld\n", current);
for (i=0; i<nlevels; i++) {
if (current<=levels[i]) {
c = i;
break;
}
}
c++;
c%=nlevels;
// printf("c: %d, level: %ld, x%ld\n", c, levels[c], nlevels);
if (argc>1)
sprintf(s, "%s", argv[1]);
else {
sprintf(s, "%ld", levels[c]);
}
// ======= write =========
printf("Writing '%s' to '%s'\n", s, devname);
if ( !(fp = fopen(devname, "w")) ) {
fprintf(stderr, "Could not open device '%s' for writing.\n", devname);
return -1;
}
fwrite(s, 1, strlen(s), fp);
if (fp)
fclose(fp);
#ifdef XOSD
osd = xosd_create (1);
if (osd == NULL) {
perror ("Could not create \"osd\"");
exit (1);
}
xosd_set_font (osd, "-adobe-helvetica-bold-r-normal-*-*-320-*-*-p-*-iso8859-1");
xosd_set_pos (osd, XOSD_bottom);
xosd_set_align (osd, XOSD_left);
xosd_display (osd, 0, XOSD_string, s);
xosd_set_shadow_offset (osd, 2);
//sleep (1);
nanosleep (&ts, NULL);
xosd_destroy (osd);
#endif //XOSD
return 0;
}
No comments:
Post a Comment