Skip to content

Commit 4818f33

Browse files
committed
Initial import.
0 parents  commit 4818f33

File tree

6 files changed

+735
-0
lines changed

6 files changed

+735
-0
lines changed

SConstruct

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
sources = ['redshift.c', 'solar.c', 'colortemp.c']
3+
4+
env = Environment()
5+
env.ParseConfig('pkg-config --cflags --libs xcb xcb-randr')
6+
env.Program('redshift', sources,
7+
CFLAGS='-std=c99 -D_BSD_SOURCE',
8+
LINKFLAGS='-lm')

colortemp.c

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/* colortemp.c */
2+
/* Copyright (c) 2009, Jon Lund Steffensen <jonlst@gmail.com> */
3+
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <stdint.h>
7+
#include <math.h>
8+
9+
#include <xcb/xcb.h>
10+
#include <xcb/randr.h>
11+
12+
13+
/* Source: http://www.vendian.org/mncharity/dir3/blackbody/
14+
Rescaled to make exactly 6500K equal to full intensity in all channels. */
15+
static const float blackbody_color[] = {
16+
1.0000, 0.0425, 0.0000, /* 1000K */
17+
1.0000, 0.0668, 0.0000, /* 1100K */
18+
1.0000, 0.0911, 0.0000, /* 1200K */
19+
1.0000, 0.1149, 0.0000, /* ... */
20+
1.0000, 0.1380, 0.0000,
21+
1.0000, 0.1604, 0.0000,
22+
1.0000, 0.1819, 0.0000,
23+
1.0000, 0.2024, 0.0000,
24+
1.0000, 0.2220, 0.0000,
25+
1.0000, 0.2406, 0.0000,
26+
1.0000, 0.2630, 0.0062,
27+
1.0000, 0.2868, 0.0155,
28+
1.0000, 0.3102, 0.0261,
29+
1.0000, 0.3334, 0.0379,
30+
1.0000, 0.3562, 0.0508,
31+
1.0000, 0.3787, 0.0650,
32+
1.0000, 0.4008, 0.0802,
33+
1.0000, 0.4227, 0.0964,
34+
1.0000, 0.4442, 0.1136,
35+
1.0000, 0.4652, 0.1316,
36+
1.0000, 0.4859, 0.1505,
37+
1.0000, 0.5062, 0.1702,
38+
1.0000, 0.5262, 0.1907,
39+
1.0000, 0.5458, 0.2118,
40+
1.0000, 0.5650, 0.2335,
41+
1.0000, 0.5839, 0.2558,
42+
1.0000, 0.6023, 0.2786,
43+
1.0000, 0.6204, 0.3018,
44+
1.0000, 0.6382, 0.3255,
45+
1.0000, 0.6557, 0.3495,
46+
1.0000, 0.6727, 0.3739,
47+
1.0000, 0.6894, 0.3986,
48+
1.0000, 0.7058, 0.4234,
49+
1.0000, 0.7218, 0.4485,
50+
1.0000, 0.7375, 0.4738,
51+
1.0000, 0.7529, 0.4992,
52+
1.0000, 0.7679, 0.5247,
53+
1.0000, 0.7826, 0.5503,
54+
1.0000, 0.7970, 0.5760,
55+
1.0000, 0.8111, 0.6016,
56+
1.0000, 0.8250, 0.6272,
57+
1.0000, 0.8384, 0.6529,
58+
1.0000, 0.8517, 0.6785,
59+
1.0000, 0.8647, 0.7040,
60+
1.0000, 0.8773, 0.7294,
61+
1.0000, 0.8897, 0.7548,
62+
1.0000, 0.9019, 0.7801,
63+
1.0000, 0.9137, 0.8051,
64+
1.0000, 0.9254, 0.8301,
65+
1.0000, 0.9367, 0.8550,
66+
1.0000, 0.9478, 0.8795,
67+
1.0000, 0.9587, 0.9040,
68+
1.0000, 0.9694, 0.9283,
69+
1.0000, 0.9798, 0.9524,
70+
1.0000, 0.9900, 0.9763,
71+
1.0000, 1.0000, 1.0000, /* 6500K */
72+
0.9917, 1.0014, 1.0149,
73+
0.9696, 0.9885, 1.0149,
74+
0.9488, 0.9761, 1.0149,
75+
0.9290, 0.9642, 1.0149,
76+
0.9102, 0.9529, 1.0149,
77+
0.8923, 0.9420, 1.0149,
78+
0.8753, 0.9316, 1.0149,
79+
0.8591, 0.9215, 1.0149,
80+
0.8437, 0.9120, 1.0149,
81+
0.8289, 0.9028, 1.0149,
82+
0.8149, 0.8939, 1.0149,
83+
0.8014, 0.8854, 1.0149,
84+
0.7885, 0.8772, 1.0149,
85+
0.7762, 0.8693, 1.0149,
86+
0.7644, 0.8617, 1.0149,
87+
0.7531, 0.8543, 1.0149,
88+
0.7423, 0.8472, 1.0149,
89+
0.7319, 0.8404, 1.0149,
90+
0.7219, 0.8338, 1.0149,
91+
0.7123, 0.8274, 1.0149,
92+
0.7030, 0.8213, 1.0149,
93+
0.6941, 0.8152, 1.0149,
94+
0.6856, 0.8094, 1.0149,
95+
0.6773, 0.8039, 1.0149,
96+
0.6693, 0.7984, 1.0149,
97+
0.6617, 0.7932, 1.0149,
98+
0.6543, 0.7881, 1.0149,
99+
0.6471, 0.7832, 1.0149,
100+
0.6402, 0.7784, 1.0149,
101+
0.6335, 0.7737, 1.0149,
102+
0.6271, 0.7692, 1.0149,
103+
0.6208, 0.7648, 1.0149,
104+
0.6148, 0.7605, 1.0149,
105+
0.6089, 0.7564, 1.0149,
106+
0.6033, 0.7524, 1.0149 /* 10000K */
107+
};
108+
109+
110+
static void
111+
interpolate_color(float a, const float *c1, const float *c2, float *c)
112+
{
113+
c[0] = (1.0-a)*c1[0] + a*c2[0];
114+
c[1] = (1.0-a)*c1[1] + a*c2[1];
115+
c[2] = (1.0-a)*c1[2] + a*c2[2];
116+
}
117+
118+
int
119+
colortemp_check_extension()
120+
{
121+
xcb_generic_error_t *error;
122+
123+
/* Open X server connection */
124+
xcb_connection_t *conn = xcb_connect(NULL, NULL);
125+
126+
/* Query RandR version */
127+
xcb_randr_query_version_cookie_t ver_cookie =
128+
xcb_randr_query_version(conn, 1, 3);
129+
xcb_randr_query_version_reply_t *ver_reply =
130+
xcb_randr_query_version_reply(conn, ver_cookie, &error);
131+
132+
if (error) {
133+
fprintf(stderr, "RANDR Query Version, error: %d\n",
134+
error->error_code);
135+
xcb_disconnect(conn);
136+
return -1;
137+
}
138+
139+
if (ver_reply->major_version < 1 || ver_reply->minor_version < 3) {
140+
fprintf(stderr, "Unsupported RANDR version (%u.%u)\n",
141+
ver_reply->major_version, ver_reply->minor_version);
142+
free(ver_reply);
143+
xcb_disconnect(conn);
144+
return -1;
145+
}
146+
147+
free(ver_reply);
148+
149+
/* Close connection */
150+
xcb_disconnect(conn);
151+
152+
return 0;
153+
}
154+
155+
int
156+
colortemp_set_temperature(int temp, float gamma)
157+
{
158+
xcb_generic_error_t *error;
159+
160+
/* Open X server connection */
161+
xcb_connection_t *conn = xcb_connect(NULL, NULL);
162+
163+
/* Get first screen */
164+
const xcb_setup_t *setup = xcb_get_setup(conn);
165+
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
166+
xcb_screen_t *screen = iter.data;
167+
168+
/* Get list of CRTCs for the screen */
169+
xcb_randr_get_screen_resources_current_cookie_t res_cookie =
170+
xcb_randr_get_screen_resources_current(conn, screen->root);
171+
xcb_randr_get_screen_resources_current_reply_t *res_reply =
172+
xcb_randr_get_screen_resources_current_reply(conn, res_cookie,
173+
&error);
174+
175+
if (error) {
176+
fprintf(stderr, "RANDR Get Screen Resources Current,"
177+
" error: %d\n", error->error_code);
178+
xcb_disconnect(conn);
179+
return -1;
180+
}
181+
182+
xcb_randr_crtc_t *crtcs =
183+
xcb_randr_get_screen_resources_current_crtcs(res_reply);
184+
xcb_randr_crtc_t crtc = crtcs[0];
185+
186+
free(res_reply);
187+
188+
/* Request size of gamma ramps */
189+
xcb_randr_get_crtc_gamma_size_cookie_t gamma_size_cookie =
190+
xcb_randr_get_crtc_gamma_size(conn, crtc);
191+
xcb_randr_get_crtc_gamma_size_reply_t *gamma_size_reply =
192+
xcb_randr_get_crtc_gamma_size_reply(conn, gamma_size_cookie,
193+
&error);
194+
195+
if (error) {
196+
fprintf(stderr, "RANDR Get CRTC Gamma Size, error: %d\n",
197+
error->error_code);
198+
xcb_disconnect(conn);
199+
return -1;
200+
}
201+
202+
int gamma_ramp_size = gamma_size_reply->size;
203+
204+
free(gamma_size_reply);
205+
206+
if (gamma_ramp_size == 0) {
207+
fprintf(stderr, "Error: Gamma ramp size too small, %i\n",
208+
gamma_ramp_size);
209+
xcb_disconnect(conn);
210+
return -1;
211+
}
212+
213+
/* Calculate white point */
214+
float white_point[3];
215+
float alpha = (temp % 100) / 100.0;
216+
int temp_index = ((temp - 1000) / 100)*3;
217+
interpolate_color(alpha, &blackbody_color[temp_index],
218+
&blackbody_color[temp_index+3], white_point);
219+
220+
printf("White point: %f, %f, %f\n",
221+
white_point[0], white_point[1], white_point[2]);
222+
223+
/* Create new gamma ramps */
224+
uint16_t *gamma_ramps = malloc(3*gamma_ramp_size*sizeof(uint16_t));
225+
if (gamma_ramps == NULL) abort();
226+
227+
uint16_t *gamma_r = &gamma_ramps[0*gamma_ramp_size];
228+
uint16_t *gamma_g = &gamma_ramps[1*gamma_ramp_size];
229+
uint16_t *gamma_b = &gamma_ramps[2*gamma_ramp_size];
230+
231+
for (int i = 0; i < gamma_ramp_size; i++) {
232+
gamma_r[i] = pow((float)i/gamma_ramp_size, 1.0/gamma) *
233+
UINT16_MAX * white_point[0];
234+
gamma_g[i] = pow((float)i/gamma_ramp_size, 1.0/gamma) *
235+
UINT16_MAX * white_point[1];
236+
gamma_b[i] = pow((float)i/gamma_ramp_size, 1.0/gamma) *
237+
UINT16_MAX * white_point[2];
238+
}
239+
240+
/* Set new gamma ramps */
241+
xcb_void_cookie_t gamma_set_cookie =
242+
xcb_randr_set_crtc_gamma_checked(conn, crtc, gamma_ramp_size,
243+
gamma_r, gamma_g, gamma_b);
244+
error = xcb_request_check(conn, gamma_set_cookie);
245+
246+
if (error) {
247+
fprintf(stderr, "RANDR Set CRTC Gamma, error: %d\n",
248+
error->error_code);
249+
free(gamma_ramps);
250+
xcb_disconnect(conn);
251+
return -1;
252+
}
253+
254+
free(gamma_ramps);
255+
256+
/* Close connection */
257+
xcb_disconnect(conn);
258+
259+
return 0;
260+
}

colortemp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* colortemp.h */
2+
3+
#ifndef _COLORTEMP_H
4+
#define _COLORTEMP_H
5+
6+
int colortemp_check_extension();
7+
int colortemp_set_temperature(int temp, float gamma);
8+
9+
#endif /* ! _COLORTEMP_H */

0 commit comments

Comments
 (0)