瀏覽代碼

added files

Fredrik Haikarainen 11 年之前
父節點
當前提交
ae308c5e34
共有 2 個檔案被更改,包括 389 行新增0 行删除
  1. 10
    0
      Makefile
  2. 379
    0
      main.c

+ 10
- 0
Makefile 查看文件

@@ -0,0 +1,10 @@
1
+CC=gcc
2
+CFLAGS=-std=c89 -pedantic -Wall
3
+
4
+debug:clean
5
+	$(CC) $(CFLAGS) -g -o light main.c
6
+stable:clean
7
+	$(CC) $(CFLAGS) -o light main.c
8
+clean:
9
+	rm -vfr *~ light
10
+	

+ 379
- 0
main.c 查看文件

@@ -0,0 +1,379 @@
1
+#define _GNU_SOURCE
2
+
3
+#include <stdio.h>
4
+#include <stdlib.h>
5
+#include <dirent.h>
6
+#include <string.h>
7
+#include <unistd.h>
8
+#include <limits.h>
9
+
10
+typedef enum LBOOL{
11
+	TRUE = 0,
12
+	FALSE = 1
13
+} LBOOL;
14
+
15
+typedef enum LOPTYPE{
16
+	SET = 0,
17
+	ADD = 1,
18
+	SUB = 2
19
+} LOPTYPE;
20
+
21
+/* Flags */
22
+LBOOL q; /* Quiet, supresses output */
23
+LBOOL c; /* print unprecise current value in percentage */
24
+LBOOL m; /* read max value*/
25
+LBOOL p; /* precision read current value */
26
+int wbright;
27
+LOPTYPE ot;
28
+
29
+LBOOL readint(const char* f, unsigned int *i){
30
+	FILE* ff = fopen(f, "r");
31
+	if(ff){
32
+		fscanf(ff, "%u", i);
33
+		fclose(ff);
34
+		return TRUE;
35
+	}else{
36
+		return FALSE;
37
+	}
38
+}
39
+
40
+LBOOL writeint(const char* f, unsigned int i){
41
+	FILE* ff = fopen(f, "w");
42
+	if(ff){
43
+		fprintf(ff, "%u", i);
44
+		fclose(ff);
45
+		return TRUE;
46
+	}else{
47
+		return FALSE;
48
+	}
49
+}
50
+
51
+
52
+LBOOL is_dir(const char* d){
53
+	DIR* dd = opendir(d);
54
+	if(dd){
55
+		closedir(dd);
56
+		return TRUE;
57
+	}else{
58
+		return FALSE;
59
+	}
60
+}
61
+
62
+LBOOL is_writable(const char* f){
63
+	FILE* dd = fopen(f, "w");
64
+	if(dd){
65
+		fclose(dd);
66
+		return TRUE;
67
+	}else{
68
+		return FALSE;
69
+	}	
70
+}
71
+
72
+typedef struct {
73
+	char*		name;
74
+	unsigned int	current_brightness;
75
+	unsigned int	max_brightness;
76
+	char*		c_path; /* Controller-path */
77
+	char*		cb_path; /* Current brightness-path */
78
+	char*		mb_path; /* Max brightness-path */
79
+	char*		b_path; /* Brightness-path */
80
+	enum LBOOL		is_ok;
81
+} controller;
82
+
83
+typedef struct {
84
+	controller	controllers[256];
85
+	unsigned int	num_controllers;
86
+} fetch_result;
87
+
88
+
89
+fetch_result fetch_controllers(const char* ctrldir){
90
+	fetch_result returner;
91
+	struct dirent* ep;
92
+
93
+	DIR* lcdir = opendir(ctrldir);
94
+	
95
+	returner.num_controllers = 0;
96
+
97
+	if(!lcdir){
98
+		if(q == FALSE)
99
+			printf("Error: Could not open directory '%s'!\n", ctrldir);
100
+	}else{
101
+		while( ( ep = readdir(lcdir) ) ){
102
+			char* currctrldir = "";
103
+			char* currctrldir_curr = "";
104
+			char* currctrldir_max = "";
105
+			char* currctrldir_f = "";
106
+			if( ep->d_name[0] != '.'){
107
+				returner.controllers[returner.num_controllers].name = ep->d_name;
108
+				
109
+				/* Set some default values, in case something fails we dont just get null */
110
+				returner.controllers[returner.num_controllers].current_brightness = 0;
111
+				returner.controllers[returner.num_controllers].max_brightness = 0;
112
+				returner.controllers[returner.num_controllers].is_ok = TRUE;
113
+				returner.controllers[returner.num_controllers].c_path = NULL;
114
+				returner.controllers[returner.num_controllers].cb_path = NULL;
115
+				returner.controllers[returner.num_controllers].b_path = NULL;
116
+				returner.controllers[returner.num_controllers].mb_path = NULL;
117
+				
118
+				/* Get path to the current controller dir */
119
+				asprintf(&currctrldir, "%s/%s", ctrldir, ep->d_name);
120
+				returner.controllers[returner.num_controllers].c_path = currctrldir;
121
+				if(is_dir(currctrldir) == FALSE){
122
+					if(q == FALSE)
123
+						printf("Warning: '%s' is not a directory, check your system.\n", currctrldir);
124
+					returner.controllers[returner.num_controllers].is_ok = FALSE;
125
+				}
126
+				
127
+				/* Get path to current actual_brightness-file */
128
+				asprintf(&currctrldir_curr, "%s/%s", currctrldir, "actual_brightness");
129
+				returner.controllers[returner.num_controllers].cb_path = currctrldir_curr;
130
+				if( readint(currctrldir_curr, &returner.controllers[returner.num_controllers].current_brightness) == FALSE ){
131
+					if(q == FALSE)
132
+						printf("Warning: Can't read actual_brightness-file of '%s'. Will ignore this controller.\n", ep->d_name);
133
+					returner.controllers[returner.num_controllers].is_ok = FALSE;
134
+				}				
135
+				
136
+				/* Get path to current max_brightness-file*/
137
+				asprintf(&currctrldir_max, "%s/%s", currctrldir, "max_brightness");
138
+				returner.controllers[returner.num_controllers].mb_path = currctrldir_max;
139
+				if( readint(currctrldir_max, &returner.controllers[returner.num_controllers].max_brightness) == FALSE ){
140
+					if(q == FALSE)
141
+						printf("Warning: Can't read max_brightness-file of '%s'. Will ignore this controller.\n", ep->d_name);
142
+					returner.controllers[returner.num_controllers].is_ok = FALSE;
143
+				}
144
+				
145
+				/* Get path to current brightness-file */
146
+				asprintf(&currctrldir_f, "%s/%s", currctrldir, "brightness");
147
+				returner.controllers[returner.num_controllers].b_path = currctrldir_f;
148
+				if( is_writable(currctrldir_f) == FALSE){
149
+					if(q == FALSE)
150
+						printf("Warning: Controllerfile of '%s' is not writable. Will ignore this controller.\n", ep->d_name);
151
+					returner.controllers[returner.num_controllers].is_ok = FALSE;
152
+				}
153
+				
154
+				
155
+				returner.num_controllers++;
156
+			}
157
+		}
158
+		closedir(lcdir);	
159
+	}
160
+	return returner;
161
+}
162
+
163
+controller* get_best_controller(fetch_result* res){
164
+	unsigned int it;
165
+	unsigned int cmax;
166
+	LBOOL foundokctrl;
167
+	controller* returner;
168
+	
169
+	
170
+	it = 0;
171
+	cmax = 0;
172
+	foundokctrl = FALSE;
173
+	
174
+	returner = NULL;
175
+	
176
+	while(it < res->num_controllers){
177
+		if(res->controllers[it].is_ok == TRUE){
178
+			if(foundokctrl != TRUE){
179
+				foundokctrl = TRUE;
180
+				returner = &res->controllers[it];
181
+			}
182
+			if(res->controllers[it].max_brightness > cmax){
183
+				cmax = res->controllers[it].max_brightness;
184
+				returner = &res->controllers[it];
185
+			}
186
+		}
187
+		it++;
188
+	}
189
+	
190
+	return returner;
191
+}
192
+
193
+void usage(){
194
+	printf("Usage: light [-qcas] <value>\n\n\t-q:\t Run quiet, supresses output.\n\t-c:\t Prints the current brightness in percent and exits.(Not precise)\n\t-p:\t Prints the current brightness directly from controller and exits. (Precise)\n\t-m:\t Prints the max brightness directly from controller and exits. (To be used side-by-side with -p)\n\t-a:\t Add the value instead of setting it.\n\t-s:\t Subtract the value instead of setting it.\n\n\t<value>\t Brightness wanted in percent.\n\n");
195
+}
196
+
197
+int main(int argc, char **argv) {
198
+	unsigned int argsit;
199
+	
200
+	fetch_result	res;
201
+	controller*	best_ctrl;
202
+	unsigned int	citr;
203
+	uid_t		uid;
204
+	unsigned int	minlight;
205
+	LBOOL		given;
206
+	unsigned int	real_wbright;
207
+	unsigned int	minlight_nonp;
208
+	unsigned int	curr_bright;
209
+	unsigned int	curr_brightp;
210
+	
211
+	
212
+	/* Get UID */
213
+	uid = getuid();
214
+	
215
+	/* Parse arguments */
216
+	q=FALSE;
217
+	c=FALSE;
218
+	m=FALSE;
219
+	p=FALSE;
220
+	ot=SET;
221
+	wbright=0;
222
+	argsit = 1;
223
+	given=FALSE;
224
+	while(argsit < argc){
225
+		char* carg = argv[argsit];
226
+		if(carg[0] == '-'){
227
+			unsigned int cargit = 1;
228
+			while(cargit < strlen(carg)){
229
+				switch(carg[cargit]){
230
+					case 'q':
231
+						q = TRUE;
232
+					break;
233
+					case 'a':
234
+						ot = ADD;
235
+					break;
236
+					case 's':
237
+						ot = SUB;
238
+					break;
239
+					case 'c':
240
+						c = TRUE;
241
+					break;
242
+					case 'p':
243
+						p = TRUE;
244
+					break;
245
+					case 'm':
246
+						m = TRUE;
247
+					break;
248
+					default:
249
+					break;
250
+				}
251
+				cargit++;
252
+			}
253
+		}else{
254
+			wbright = atoi(carg);
255
+			given=TRUE;
256
+		}
257
+		
258
+		argsit++;
259
+	}
260
+	
261
+	if(c == TRUE || m == TRUE || p == TRUE){
262
+		q = TRUE;
263
+	}
264
+	
265
+	if(given == FALSE && c == FALSE && m == FALSE && p == FALSE){
266
+		usage();
267
+		return 0;
268
+	}
269
+	if(q == FALSE)
270
+		printf("Light v0.4 - Fredrik Haikarainen\n");
271
+	
272
+	/* Get and check minlight */
273
+	
274
+	if(readint("/etc/light/minlight", &minlight) == FALSE){
275
+		minlight = 5;
276
+		if(q == FALSE)
277
+			printf("Warning: Couldn't read /etc/light/minlight, using 5 as default.\n");
278
+	}
279
+	
280
+	/* Fetch controllers */
281
+	if(q == FALSE)
282
+		printf("Fetching controllers..\n");
283
+	
284
+	res = fetch_controllers("/sys/class/backlight");
285
+	
286
+	citr = 0;
287
+	while(citr < res.num_controllers){
288
+		controller* currc = &res.controllers[citr];
289
+		if(currc->is_ok == TRUE){
290
+			if(q == FALSE)
291
+				printf("\tFound '%s' (%u/%u)\n", currc->name, currc->current_brightness, currc->max_brightness);
292
+		}else{
293
+			if(q == FALSE)
294
+				printf("\tFound '%s', but ignoring\n", currc->name);
295
+		}
296
+		citr++;
297
+	}
298
+
299
+	if(q == FALSE)
300
+		printf("\n");
301
+	
302
+	/* Get the best controller */
303
+	best_ctrl = get_best_controller(&res);
304
+	
305
+	if(best_ctrl == NULL){
306
+		if(uid == 0){
307
+			if(q == FALSE)
308
+				printf("No okay controller found, even though you are root! Check your system.\n");
309
+		}else{
310
+			if(q == FALSE)
311
+				printf("No okay controller found, check your permissions or try to run as root.\n");
312
+		}
313
+		return 1;
314
+	}
315
+	
316
+	if(p == TRUE){
317
+		printf("%u\n", best_ctrl->current_brightness);
318
+		return 0;
319
+	}
320
+	
321
+	if(m == TRUE){
322
+		printf("%u\n", best_ctrl->max_brightness);
323
+		return 0;
324
+	}
325
+	
326
+	if(q == FALSE)
327
+		printf("Using controller '%s' ..\n", best_ctrl->name);
328
+	
329
+	if(wbright < 0){ wbright = 0;}
330
+	if(wbright > 100){wbright=100;}
331
+	
332
+	curr_bright = best_ctrl->current_brightness;
333
+	curr_brightp = (float)((float)curr_bright / (float)best_ctrl->max_brightness) * 100;
334
+	
335
+	
336
+	if(c == TRUE){
337
+		printf("%u\n", curr_brightp);
338
+		return 0;
339
+	}
340
+	
341
+	switch(ot){
342
+		case SET:
343
+			real_wbright = best_ctrl->max_brightness * ( (float)wbright / 100 );
344
+		break;
345
+		case ADD:
346
+			real_wbright = ( best_ctrl->max_brightness * ( (float)( curr_brightp + wbright +1) / 100 ));
347
+		break;
348
+		case SUB:
349
+			real_wbright = ( best_ctrl->max_brightness * ( (float)( curr_brightp - wbright + 1) / 100 ));
350
+		break;
351
+		default:
352
+		break;
353
+	}
354
+	
355
+	minlight_nonp = best_ctrl->max_brightness * ( (float)minlight / 100);
356
+
357
+	/* FIXME 
358
+		Line below makes sure the value never wraps around and gets higher. Puts a (high) limit on max brightness.
359
+		Not sure if safe for portabilities sake.
360
+	 */
361
+	if(real_wbright > ((UINT_MAX/2) - best_ctrl->max_brightness)){ real_wbright = minlight_nonp; } 
362
+	
363
+	
364
+	
365
+	if(real_wbright > best_ctrl->max_brightness){real_wbright = best_ctrl->max_brightness;}
366
+	if(real_wbright < minlight_nonp){real_wbright = minlight_nonp;}
367
+	
368
+	if(q == FALSE)
369
+		printf("Writing %u to file '%s'..\n", real_wbright, best_ctrl->b_path);
370
+	
371
+	if(writeint(best_ctrl->b_path, real_wbright) == FALSE){
372
+		if(q == FALSE){
373
+			printf("Error: Could not write to file %s, check your permissions!\n", best_ctrl->b_path);
374
+		}
375
+		return 1;
376
+	}
377
+	
378
+	return 0;
379
+}