-
Notifications
You must be signed in to change notification settings - Fork 1
/
brownout.c
119 lines (98 loc) · 2.46 KB
/
brownout.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* public domain */
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xrandr.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include "config.h"
#ifndef VERSION
#define VERSION "unknown"
#endif
Display *dpy;
Window root_window;
Atom brown_atom;
static void
die(const char *errstr, ...)
{
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
static int
getbrownvalue(char *arg)
{
int permille = atoi(arg);
if (arg[0] == '+' || arg[0] == '-') {
int format;
unsigned long n = 0, extra = 0;
unsigned int *p = NULL;
Atom atom;
if(XGetWindowProperty(dpy, root_window, brown_atom, 0L, 1L, False, XA_CARDINAL,
&atom, &format, &n, &extra, (unsigned char **)&p) == Success && n > 0) {
permille += *p;
XFree(p);
}
}
if (permille < 0) return 0;
if (permille > 1000) return 1000;
return permille;
}
static void
setbrownvalue(int value)
{
XChangeProperty(dpy, root_window, brown_atom, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*)&value, 1);
}
static void
brownoutscreen(int screen, float gr, float gg, float gb)
{
XRRScreenResources *res = XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, screen));
for (int c = 0; c < res->ncrtc; c++) {
int crtcxid = res->crtcs[c];
int size = XRRGetCrtcGammaSize(dpy, crtcxid);
XRRCrtcGamma *crtc_gamma = XRRAllocGamma(size);
for (int i = 0; i < size; i++) {
float g = 1.0 * USHRT_MAX * i / (size-1);
crtc_gamma->red[i] = g * gr;
crtc_gamma->green[i] = g * gg;
crtc_gamma->blue[i] = g * gb;
}
XRRSetCrtcGamma(dpy, crtcxid, crtc_gamma);
XFree(crtc_gamma);
}
}
static void
brownallscreens(int percent)
{
int screen, nscreens = ScreenCount(dpy);
float gr = gammar(percent);
float gg = gammag(percent);
float gb = gammab(percent);
for (screen = 0; screen < nscreens; screen++) {
brownoutscreen(screen, gr, gg, gb);
}
}
int
main(int argc, char **argv)
{
int permille = 0;
if (argc < 2)
die("usage: %s [+|-]PERCENT brownscreen to[by] PERCENT\n", argv[0]);
if (!strcmp("-v", argv[1]))
die("brownout-"VERSION", public domain software\n");
if (!(dpy = XOpenDisplay(NULL)))
die("Cannot open display\n");
root_window = RootWindow(dpy, DefaultScreen(dpy));
brown_atom = XInternAtom(dpy, "_BROWN_PERCENT", False);
permille = getbrownvalue(argv[1]);
brownallscreens(permille);
setbrownvalue(permille);
printf("%d\n", permille);
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}