4
4
* Public domain, do as you wish.
5
5
*/
6
6
7
- #include <X11/Xatom.h>
8
- #include <X11/Xlib.h>
9
- #include <X11/Xproto.h>
10
- #include <X11/extensions/Xrandr.h>
11
-
12
- #include <stdio.h>
13
- #include <stdlib.h>
14
- #include <string.h>
15
- #include <math.h>
7
+ #include "xsct.h"
16
8
17
9
static void usage (char * pname )
18
10
{
19
- printf ("Xsct (1.8 )\n"
20
- "Usage: %s [options] [temperature]\n"
11
+ printf ("Xsct (%s )\n"
12
+ "Usage: %s [options] [temperature] [brightness] \n"
21
13
"\tIf the argument is 0, xsct resets the display to the default temperature (6500K)\n"
22
- "\tIf no arguments are passed, xsct estimates the current display temperature\n"
14
+ "\tIf no arguments are passed, xsct estimates the current display temperature and brightness \n"
23
15
"Options:\n"
24
16
"\t-h, --help \t xsct will display this usage information\n"
25
17
"\t-v, --verbose \t xsct will display debugging information\n"
26
18
"\t-d, --delta\t xsct will shift temperature by the temperature value\n"
27
19
"\t-s, --screen N\t xsct will only select screen specified by given zero-based index\n"
28
- "\t-c, --crtc N\t xsct will only select CRTC specified by given zero-based index\n" , pname );
20
+ "\t-c, --crtc N\t xsct will only select CRTC specified by given zero-based index\n" , XSCT_VERSION , pname );
29
21
}
30
22
31
- #define TEMPERATURE_NORM 6500
32
- #define TEMPERATURE_ZERO 700
33
- #define GAMMA_MULT 65535.0
34
- // Approximation of the `redshift` table from
35
- // https://github.com/jonls/redshift/blob/04760afe31bff5b26cf18fe51606e7bdeac15504/src/colorramp.c#L30-L273
36
- // without limits:
37
- // GAMMA = K0 + K1 * ln(T - T0)
38
- // Red range (T0 = TEMPERATURE_ZERO)
39
- // Green color
40
- #define GAMMA_K0GR -1.47751309139817
41
- #define GAMMA_K1GR 0.28590164772055
42
- // Blue color
43
- #define GAMMA_K0BR -4.38321650114872
44
- #define GAMMA_K1BR 0.6212158769447
45
- // Blue range (T0 = TEMPERATURE_NORM - TEMPERATURE_ZERO)
46
- // Red color
47
- #define GAMMA_K0RB 1.75390204039018
48
- #define GAMMA_K1RB -0.1150805671482
49
- // Green color
50
- #define GAMMA_K0GB 1.49221604915144
51
- #define GAMMA_K1GB -0.07513509588921
52
-
53
23
static double DoubleTrim (double x , double a , double b )
54
24
{
55
25
double buff [3 ] = {a , x , b };
56
26
return buff [ (int )(x > a ) + (int )(x > b ) ];
57
27
}
58
28
59
- static int get_sct_for_screen (Display * dpy , int screen , int icrtc , int fdebug )
29
+ static struct temp_status get_sct_for_screen (Display * dpy , int screen , int icrtc , int fdebug )
60
30
{
61
31
Window root = RootWindow (dpy , screen );
62
32
XRRScreenResources * res = XRRGetScreenResourcesCurrent (dpy , root );
63
33
64
- int temp = 0 , n , c ;
34
+ int n , c ;
65
35
double t = 0.0 ;
66
- double gammar = 0.0 , gammag = 0.0 , gammab = 0.0 , gammam = 1.0 , gammad = 0.0 ;
36
+ double gammar = 0.0 , gammag = 0.0 , gammab = 0.0 , gammad = 0.0 ;
37
+ struct temp_status temp ;
38
+ temp .temp = 0 ;
39
+ temp .brightness = 1.0 ;
67
40
68
41
n = res -> ncrtc ;
69
- int icrtc_specified = icrtc >= 0 && icrtc < n ;
70
- for (c = icrtc_specified ? icrtc : 0 ; c < (icrtc_specified ? icrtc + 1 : n ); c ++ )
42
+ if ((icrtc >= 0 ) && (icrtc < n ))
43
+ n = 1 ;
44
+ else
45
+ icrtc = 0 ;
46
+ for (c = icrtc ; c < (icrtc + n ); c ++ )
71
47
{
72
48
RRCrtc crtcxid ;
73
49
int size ;
@@ -82,14 +58,17 @@ static int get_sct_for_screen(Display *dpy, int screen, int icrtc, int fdebug)
82
58
XRRFreeGamma (crtc_gamma );
83
59
}
84
60
XFree (res );
85
- gammam = (gammar > gammag ) ? gammar : gammag ;
86
- gammam = (gammab > gammam ) ? gammab : gammam ;
87
- if (gammam > 0.0 )
61
+ temp . brightness = (gammar > gammag ) ? gammar : gammag ;
62
+ temp . brightness = (gammab > temp . brightness ) ? gammab : temp . brightness ;
63
+ if (temp . brightness > 0.0 && n > 0 )
88
64
{
89
- gammar /= gammam ;
90
- gammag /= gammam ;
91
- gammab /= gammam ;
92
- if (fdebug > 0 ) fprintf (stderr , "DEBUG: Gamma: %f, %f, %f\n" , gammar , gammag , gammab );
65
+ gammar /= temp .brightness ;
66
+ gammag /= temp .brightness ;
67
+ gammab /= temp .brightness ;
68
+ temp .brightness /= n ;
69
+ temp .brightness /= BRIGHTHESS_DIV ;
70
+ temp .brightness = DoubleTrim (temp .brightness , 0.0 , 1.0 );
71
+ if (fdebug > 0 ) fprintf (stderr , "DEBUG: Gamma: %f, %f, %f, brightness: %f\n" , gammar , gammag , gammab , temp .brightness );
93
72
gammad = gammab - gammar ;
94
73
if (gammad < 0.0 )
95
74
{
@@ -107,34 +86,37 @@ static int get_sct_for_screen(Display *dpy, int screen, int icrtc, int fdebug)
107
86
t = exp ((gammag + 1.0 - gammad - (GAMMA_K0GB + GAMMA_K0RB )) / (GAMMA_K1GB + GAMMA_K1RB )) + (TEMPERATURE_NORM - TEMPERATURE_ZERO );
108
87
}
109
88
}
89
+ else
90
+ temp .brightness = DoubleTrim (temp .brightness , 0.0 , 1.0 );
110
91
111
- temp = (int )(t + 0.5 );
92
+ temp . temp = (int )(t + 0.5 );
112
93
113
94
return temp ;
114
95
}
115
96
116
- static void sct_for_screen (Display * dpy , int screen , int icrtc , int temp , int fdebug )
97
+ static void sct_for_screen (Display * dpy , int screen , int icrtc , struct temp_status temp , int fdebug )
117
98
{
118
- double t = 0.0 , g = 0.0 , gammar , gammag , gammab ;
99
+ double t = 0.0 , b = 1.0 , g = 0.0 , gammar , gammag , gammab ;
119
100
int n , c ;
120
101
Window root = RootWindow (dpy , screen );
121
102
XRRScreenResources * res = XRRGetScreenResourcesCurrent (dpy , root );
122
103
123
- t = (double )temp ;
124
- if (temp < TEMPERATURE_NORM )
104
+ t = (double )temp .temp ;
105
+ b = DoubleTrim (temp .brightness , 0.0 , 1.0 );
106
+ if (temp .temp < TEMPERATURE_NORM )
125
107
{
126
108
gammar = 1.0 ;
127
- if (temp < TEMPERATURE_ZERO )
128
- {
129
- gammag = 0.0 ;
130
- gammab = 0.0 ;
131
- }
132
- else
109
+ if (temp .temp > TEMPERATURE_ZERO )
133
110
{
134
111
g = log (t - TEMPERATURE_ZERO );
135
112
gammag = DoubleTrim (GAMMA_K0GR + GAMMA_K1GR * g , 0.0 , 1.0 );
136
113
gammab = DoubleTrim (GAMMA_K0BR + GAMMA_K1BR * g , 0.0 , 1.0 );
137
114
}
115
+ else
116
+ {
117
+ gammag = 0.0 ;
118
+ gammab = 0.0 ;
119
+ }
138
120
}
139
121
else
140
122
{
@@ -143,10 +125,13 @@ static void sct_for_screen(Display *dpy, int screen, int icrtc, int temp, int fd
143
125
gammag = DoubleTrim (GAMMA_K0GB + GAMMA_K1GB * g , 0.0 , 1.0 );
144
126
gammab = 1.0 ;
145
127
}
146
- if (fdebug > 0 ) fprintf (stderr , "DEBUG: Gamma: %f, %f, %f\n" , gammar , gammag , gammab );
128
+ if (fdebug > 0 ) fprintf (stderr , "DEBUG: Gamma: %f, %f, %f, brightness: %f \n" , gammar , gammag , gammab , b );
147
129
n = res -> ncrtc ;
148
- int icrtc_specified = icrtc >= 0 && icrtc < n ;
149
- for (c = icrtc_specified ? icrtc : 0 ; c < (icrtc_specified ? icrtc + 1 : n ); c ++ )
130
+ if ((icrtc >= 0 ) && (icrtc < n ))
131
+ n = 1 ;
132
+ else
133
+ icrtc = 0 ;
134
+ for (c = icrtc ; c < (icrtc + n ); c ++ )
150
135
{
151
136
int size , i ;
152
137
RRCrtc crtcxid ;
@@ -158,7 +143,7 @@ static void sct_for_screen(Display *dpy, int screen, int icrtc, int temp, int fd
158
143
159
144
for (i = 0 ; i < size ; i ++ )
160
145
{
161
- g = GAMMA_MULT * (double )i / (double )size ;
146
+ g = GAMMA_MULT * b * (double )i / (double )size ;
162
147
crtc_gamma -> red [i ] = (unsigned short int )(g * gammar + 0.5 );
163
148
crtc_gamma -> green [i ] = (unsigned short int )(g * gammag + 0.5 );
164
149
crtc_gamma -> blue [i ] = (unsigned short int )(g * gammab + 0.5 );
@@ -173,8 +158,9 @@ static void sct_for_screen(Display *dpy, int screen, int icrtc, int temp, int fd
173
158
174
159
int main (int argc , char * * argv )
175
160
{
176
- int i , screen , screens , temp ;
161
+ int i , screen , screens ;
177
162
int screen_specified , screen_first , screen_last , crtc_specified ;
163
+ struct temp_status temp ;
178
164
int fdebug = 0 , fdelta = 0 , fhelp = 0 ;
179
165
Display * dpy = XOpenDisplay (NULL );
180
166
@@ -187,9 +173,10 @@ int main(int argc, char **argv)
187
173
screens = XScreenCount (dpy );
188
174
screen_first = 0 ;
189
175
screen_last = screens - 1 ;
190
- temp = -1 ;
191
176
screen_specified = -1 ;
192
177
crtc_specified = -1 ;
178
+ temp .temp = DELTA_MIN ;
179
+ temp .brightness = -1.0 ;
193
180
for (i = 1 ; i < argc ; i ++ )
194
181
{
195
182
if ((strcmp (argv [i ],"-h" ) == 0 ) || (strcmp (argv [i ],"--help" ) == 0 )) fhelp = 1 ;
@@ -217,7 +204,8 @@ int main(int argc, char **argv)
217
204
fhelp = 1 ;
218
205
}
219
206
}
220
- else if (temp == -1 ) temp = atoi (argv [i ]);
207
+ else if (temp .temp == DELTA_MIN ) temp .temp = atoi (argv [i ]);
208
+ else if (temp .brightness < 0.0 ) temp .brightness = atof (argv [i ]);
221
209
else
222
210
{
223
211
fprintf (stderr , "ERROR! Unknown parameter: %s\n!" , argv [i ]);
@@ -235,33 +223,34 @@ int main(int argc, char **argv)
235
223
}
236
224
else
237
225
{
226
+ if (temp .brightness < 0.0 ) temp .brightness = 1.0 ;
238
227
if (screen_specified >= 0 )
239
228
{
240
229
screen_first = screen_specified ;
241
230
screen_last = screen_specified ;
242
231
}
243
- if ((temp < 0 ) && (fdelta == 0 ))
232
+ if ((temp . temp < 0 ) && (fdelta == 0 ))
244
233
{
245
234
// No arguments, so print estimated temperature for each screen
246
235
for (screen = screen_first ; screen <= screen_last ; screen ++ )
247
236
{
248
237
temp = get_sct_for_screen (dpy , screen , crtc_specified , fdebug );
249
- printf ("Screen %d: temperature ~ %d\n" , screen , temp );
238
+ printf ("Screen %d: temperature ~ %d %f \n" , screen , temp . temp , temp . brightness );
250
239
}
251
240
}
252
241
else
253
242
{
254
243
if (fdelta == 0 )
255
244
{
256
245
// Set temperature to given value or default for a value of 0
257
- if (temp == 0 )
246
+ if (temp . temp == 0 )
258
247
{
259
- temp = TEMPERATURE_NORM ;
248
+ temp . temp = TEMPERATURE_NORM ;
260
249
}
261
- else if (temp < TEMPERATURE_ZERO )
250
+ else if (temp . temp < TEMPERATURE_ZERO )
262
251
{
263
252
fprintf (stderr , "WARNING! Temperatures below %d cannot be displayed.\n" , TEMPERATURE_ZERO );
264
- temp = TEMPERATURE_ZERO ;
253
+ temp . temp = TEMPERATURE_ZERO ;
265
254
}
266
255
for (screen = screen_first ; screen <= screen_last ; screen ++ )
267
256
{
@@ -273,11 +262,12 @@ int main(int argc, char **argv)
273
262
// Delta mode: Shift temperature of each screen by given value
274
263
for (screen = screen_first ; screen <= screen_last ; screen ++ )
275
264
{
276
- int tempd = temp + get_sct_for_screen (dpy , screen , crtc_specified , fdebug );
277
- if (tempd < TEMPERATURE_ZERO )
265
+ struct temp_status tempd = get_sct_for_screen (dpy , screen , crtc_specified , fdebug );
266
+ tempd .temp += temp .temp ;
267
+ if (tempd .temp < TEMPERATURE_ZERO )
278
268
{
279
269
fprintf (stderr , "WARNING! Temperatures below %d cannot be displayed.\n" , TEMPERATURE_ZERO );
280
- tempd = TEMPERATURE_ZERO ;
270
+ tempd . temp = TEMPERATURE_ZERO ;
281
271
}
282
272
sct_for_screen (dpy , screen , crtc_specified , tempd , fdebug );
283
273
}
0 commit comments