Browse Source

Full rewrite (0.9)

Fredrik Haikarainen 10 years ago
parent
commit
adf0861847
10 changed files with 1232 additions and 524 deletions
  1. 13
    1
      CHANGELOG
  2. 7
    6
      Makefile
  3. 71
    39
      README
  4. 63
    0
      include/helpers.h
  5. 142
    0
      include/light.h
  6. BIN
      light
  7. 0
    478
      main.c
  8. 207
    0
      src/helpers.c
  9. 703
    0
      src/light.c
  10. 26
    0
      src/main.c

+ 13
- 1
CHANGELOG View File

@@ -1 +1,13 @@
1
-0.7 -- Ported bash script to C.
1
+0.9
2
+  * Complete rewrite of program (Every single byte)
3
+  * Cleaner, safer code
4
+  * Completely new intuitive usage (Sorry, it was needed)
5
+  * Added functionality:
6
+    * Ability to set/get minimum brightness directly from commandline
7
+    * Ability to specify the backlight controller to use directly from commandline
8
+    * Better verbosity
9
+
10
+  * Probably missed some stuff
11
+
12
+0.7
13
+  * Ported bash script to C.

+ 7
- 6
Makefile View File

@@ -1,10 +1,11 @@
1 1
 CC=gcc
2
-CFLAGS=-std=c89 -pedantic -Wall
2
+CFLAGS=-std=c89 -pedantic -Wall -I"./include"
3
+
4
+all:
5
+	$(CC) $(CFLAGS) -g -o light src/helpers.c src/light.c src/main.c
6
+exp:
7
+	$(CC) $(CFLAGS) -E  src/helpers.c src/light.c
3 8
 
4
-debug:clean
5
-	$(CC) $(CFLAGS) -g -o light main.c
6
-stable:clean
7
-	$(CC) $(CFLAGS) -o light main.c
8 9
 clean:
9 10
 	rm -vfr *~ light
10
-	
11
+	

+ 71
- 39
README View File

@@ -1,63 +1,95 @@
1
-Light 0.7
2
----------
1
+Light 0.9
3 2
 
4
-Copyright (C) 2012 - Fredrik Haikarainen
5
-Program is licensed under the GPLv3 (Read LICENSE before contiuing)
3
+Copyright (C) 2012 - 2014, Fredrik Haikarainen
4
+This is free software, see the source for copying conditions.  There is NO
5
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
6 6
 
7
- - Description ---
7
+--------------------------------------------------------------------------
8 8
 
9
-"Light" is a program to control backlight-controllers in GNU/Linux-systems. It is the successor of "LightScript",
10
-which is a bash-script with the same purpose, and tries to maintain the same functionality.
9
+Description:
11 10
 
12
-It features:
11
+"Light"  is  a program  to control backlight controllers  under GNU/Linux,
12
+it is the successor of lightscript, which was a bash script with the  same
13
+purpose, and tries to maintain the same functionality.
13 14
 
14
-	* Works excellent where other software has proven unusable/problematic(xbacklight etc) thanks to how
15
-	  it operates internally, and the fact that it doesn't need X. 
16 15
 
17
-	* Automatically figures out the best controller to use depending on its resolution, making full use
18
-	  of the underlying hardware, if you have a "bad system" the controller to use is overridable by the
19
-	  /etc/light/override-file
16
+Features:
20 17
 
21
-	* Written in ANSI-C89 -- which practically makes it as portable as a program can be, with the exception
22
-	  of the glibc-dependency.
18
+  * Works excellent where other software has been proven to be unusable or
19
+    problematic, thanks to how it operates internally and to the fact that
20
+    it does not rely on xorg.
23 21
 
24
-	* Has a default minimumcap of 5% brightness, easily changeable in /etc/light/minlight. This to prevent
25
-	  screens from turning pitchblack, since some controllers do that on 0 brightness.
22
+  * Can automatically figure out the best controller to use,   making full
23
+    use of underlying hardware.
26 24
 
27
- - Usage ---
25
+  * Possibility to set a minimum brightness value, as some controllers set
26
+    the screen to be pitch black at a vaĺue of 0 (or higher).
28 27
 
29
-Executed without arguments, light prints usage-information that is pretty self-explanatory.
30 28
 
31
-Examples:
29
+Installation:
30
+  
31
+  If you run ArchLinux, there is a package in the AUR called light.
32 32
 
33
-	Set brightness to 40 percent:
34
-	light 40
33
+  1) Install neccessary build tools (gcc, make etc.)
35 34
 
36
-	Increase brightness with 10% and supress output:
37
-	light -aq 10	
35
+  2) Type `make`
38 36
 
39
-	Print the maximum-brightness of the best controller and exit:
40
-	light -m
37
+  3) Run makeexec.sh as root to give regular users the ability to run the
38
+     program with root permissions.
41 39
 
40
+  4) Copy/create a symbolic link to the executable to /usr/bin
42 41
 
43
- - Installation ---
42
+  5) Enjoy!
44 43
 
45
-	1. Install the neccesary buildtools (make, gcc etc)
46 44
 
47
-	2. Type "make stable"
45
+Usage:
48 46
 
49
-	3. Optionally make the light-binary executable by regular users by running makeexec.sh as root
50
-	
51
-	4. Create a symbolic link to /usr/bin
52
-	
53
-	5. Enjoy!
47
+  This application has 4 different operation modes, which are:
54 48
 
55
-	Optional:
56
-	
57
-	6. Create /etc/light/minlight to set a minimumcap (5 is good for highresolution controllers)
49
+    -G:   Get, which reads/gets brightness/data from controllers/files
50
+    -S:   Set, whichs writes/sets brightness/data to controllers/files
51
+    -A:   Add, does like -S but instead adds the value
52
+    -U:   Subtract, does like -S but instead subtracts the value
58 53
 
54
+  When used by themselves   operate on the brightness of a controller that
55
+  is selected automatically. S, A and U needs another argument,   which is
56
+  the value to set/add/subtract.   This can be specified either in percent
57
+  or in raw values,  but remember to specify the value mode if you want to
58
+  write raw values.
59 59
 
60
+  The value modes are set with -p for percent (default), and -r for raw.
60 61
 
61
- - Contact ---
62
+  As you can not only read/write the brightness of controllers,    you may
63
+  also specify a target to read/write from/to:
62 64
 
63
-In case of any feedback(problems/bugs, feature-requests etc) contact me directly on fredrik.haikarainen@gmail.com
65
+    -b:   Current brightness of selected controller
66
+    -m:   Maximum brightness of selected controller
67
+    -c:   Minimum brightness (cap) of selected controller
68
+
69
+  Finally, you can either use the built-in controller selection to get the
70
+  controller with the maximum precision,   or you can specify one manually
71
+  with the -s flag. The -a flag will force automatic mode and is default.
72
+
73
+  NOTE:
74
+  This application will only print errors if you are using it incorrectly.
75
+  If something goes wrong, and you can't figure out why,   try setting the
76
+  verbosity flag:
77
+
78
+    -v 0: No debug output
79
+    -v 1: Errors
80
+    -v 2: Errors, warnings
81
+    -v 3: Errors, warnings, notices
82
+
83
+  Examples:
84
+
85
+    * Get the current brightness in percent
86
+    
87
+      light -G
88
+
89
+    * Increase brightness by 5 percent
90
+
91
+      light -A 5
92
+
93
+    * Set the minimum cap to 2 in raw value on the acpi_video0 controller:
94
+
95
+      light -Scrs "acpi_video0" 2

+ 63
- 0
include/helpers.h View File

@@ -0,0 +1,63 @@
1
+#ifndef LIGHT_HELPERS_H
2
+#define LIGHT_HELPERS_H
3
+
4
+/* Clamps x(value) between y(min) and z(max) in a nested ternary operation. 
5
+ * if(x < y)
6
+ * {
7
+ *  y;
8
+ * }else{
9
+ *  if(x>z)
10
+ *  {
11
+ *    z;
12
+ *  }else{
13
+ *    x;
14
+ *  }
15
+ * }*/
16
+#define LIGHT_CLAMP(x, y, z) ((x<y) ? y : ((x>z) ? z : x ));
17
+
18
+#define LIGHT_NOTE(x) if(light_verbosity > 2){printf("%s.\n", x);}
19
+
20
+#define LIGHT_WARN(x) if(light_verbosity > 1){printf("warning: \"%s\", in \"%s\" on line %u.\n", x, __FILE__, __LINE__);}
21
+
22
+#define LIGHT_ERR(x) if(light_verbosity > 0){printf("error: \"%s\", in \"%s\" on line %u.\n", x, __FILE__, __LINE__);}
23
+
24
+#define LIGHT_MEMERR() LIGHT_ERR("memory error");
25
+
26
+/* Verbosity levels: 
27
+ * 0 - No output
28
+ * 1 - Errors
29
+ * 2 - Errors, warnings 
30
+ * 3 - Errors, warnings, notices */
31
+int    light_verbosity;
32
+
33
+/* Typedef for boolean values */
34
+typedef enum LIGHT_BOOL {
35
+  FALSE = 0,
36
+  TRUE
37
+} LIGHT_BOOL;
38
+
39
+/* Reads an unsigned integer from a file into `i` if able, otherwise returns FALSE and leaves `i` untouched */
40
+LIGHT_BOOL light_readUInt(char const *filename, unsigned int *v);
41
+
42
+/* Writes an unsigned integer `i` into file `filename` if able, otherwise returns FALSE */
43
+LIGHT_BOOL light_writeUInt(char const *filename, unsigned int v);
44
+
45
+LIGHT_BOOL light_writeULong(char const *filename, unsigned long v);
46
+LIGHT_BOOL light_readULong(char const *filename, unsigned long *v);
47
+
48
+/* Reads a file into null-terminated `buffer` if able, otherwise returns FALSE
49
+ * If `size` isn't NULL, it will be set to the read size.
50
+ *
51
+ * WARNING: `buffer` HAS to be freed by the user, also make sure it is NULL before passed */
52
+LIGHT_BOOL light_readString(char const * filename, char * buffer, long * size);
53
+
54
+/* Returns TRUE if `path` is a valid directory, FALSE otherwise */
55
+LIGHT_BOOL light_isDir(char const * path);
56
+
57
+/* Returns TRUE if file is writable, FALSE otherwise */
58
+LIGHT_BOOL light_isWritable(char const * filename);
59
+
60
+/* Returns TRUE if file is readable, FALSE otherwise */
61
+LIGHT_BOOL light_isReadable(char const * filename);
62
+
63
+#endif /* LIGHT_HELPERS_H */

+ 142
- 0
include/light.h View File

@@ -0,0 +1,142 @@
1
+#ifndef LIGHT_H
2
+#define LIGHT_H
3
+
4
+#include "helpers.h"
5
+
6
+#include <sys/types.h>
7
+#include <dirent.h>
8
+
9
+#define LIGHT_VER_MAJOR 0
10
+#define LIGHT_VER_MINOR 9
11
+#define LIGHT_VER_TYPE "beta"
12
+#define LIGHT_YEAR 2014
13
+#define LIGHT_AUTHOR "Fredrik Haikarainen"
14
+
15
+#define ASSERT_OPSET() \
16
+  if(opSet)\
17
+  {\
18
+    printf("Operation arguments can not be used in conjunction.\n");\
19
+    return FALSE;\
20
+  }\
21
+  opSet = TRUE;
22
+
23
+#define ASSERT_TARGETSET() \
24
+  if(targetSet)\
25
+  {\
26
+    printf("Target arguments can not be used in conjunction.\n");\
27
+    return FALSE;\
28
+  }\
29
+  targetSet = TRUE;
30
+
31
+#define ASSERT_CTRLSET()\
32
+  if(ctrlSet)\
33
+  {\
34
+    printf("Controller arguments can not be used in conjunction.\n");\
35
+    return FALSE;\
36
+  }\
37
+  ctrlSet = TRUE;
38
+
39
+#define ASSERT_VALSET()\
40
+  if(valSet)\
41
+  {\
42
+    printf("Value arguments can not be used in conjunction.\n");\
43
+    return FALSE;\
44
+  }\
45
+  valSet = TRUE;
46
+
47
+
48
+typedef enum LIGHT_TARGET {
49
+  LIGHT_BRIGHTNESS = 0,
50
+  LIGHT_MAX_BRIGHTNESS,
51
+  LIGHT_MIN_CAP
52
+} LIGHT_TARGET;
53
+
54
+typedef enum LIGHT_CTRL_MODE {
55
+  LIGHT_AUTO = 0,
56
+  LIGHT_SPECIFY
57
+} LIGHT_CTRL_MODE;
58
+
59
+typedef enum LIGHT_OP_MODE {
60
+  LIGHT_GET = 0,
61
+  LIGHT_SET,
62
+  LIGHT_ADD,
63
+  LIGHT_SUB,
64
+  LIGHT_PRINT_HELP,   /* Prints help and exits  */
65
+  LIGHT_PRINT_VERSION /* Prints version info and exits */
66
+} LIGHT_OP_MODE;
67
+
68
+typedef enum LIGHT_VAL_MODE {
69
+  LIGHT_RAW = 0,
70
+  LIGHT_PERCENT
71
+} LIGHT_VAL_MODE;
72
+
73
+typedef struct light_runtimeArguments_s {
74
+  /* Which controller to use */
75
+  LIGHT_CTRL_MODE controllerMode;
76
+  char            specifiedController[256];
77
+
78
+  /* What to do with the controller */
79
+  LIGHT_OP_MODE   operationMode;
80
+  LIGHT_VAL_MODE  valueMode;
81
+  unsigned long   specifiedValueRaw; /* The specified value in raw mode */
82
+  double          specifiedValuePercent; /* The specified value in percent */
83
+  
84
+  LIGHT_TARGET    target;
85
+} light_runtimeArguments, *light_runtimeArguments_p;
86
+
87
+/* -- Global variables that handles iterating controllers -- */
88
+struct dirent *light_iterator;
89
+DIR           *light_iteratorDir;
90
+char          light_currentController[256];
91
+
92
+/* -- Global variable holding the settings for the current run -- */
93
+light_runtimeArguments light_Configuration;
94
+
95
+/* Sets default values for the configuration */
96
+void light_defaultConfig();
97
+
98
+
99
+/* Parses the program arguments and sets the configuration accordingly (unsanitized) */
100
+LIGHT_BOOL light_parseArguments(int argc, char** argv);
101
+
102
+/* Prints a header if verbosity level > 0 */
103
+void light_printVersion(void);
104
+
105
+/* Prints help regardless of verbosity level */
106
+void light_printHelp(void);
107
+
108
+/* -- SECTION: Main code -- */
109
+
110
+/* Initializes the application */
111
+LIGHT_BOOL light_initialize(int argc, char** argv);
112
+
113
+/* Does the work */
114
+LIGHT_BOOL light_execute(void);
115
+
116
+/* Frees up resources */
117
+void light_free();
118
+
119
+/* SECTION: Controller functionality */
120
+
121
+/* WARNING: `buffer` HAS to be freed by the user if not null once returned!
122
+ * Size is always 256 */
123
+LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET type, char **buffer);
124
+
125
+LIGHT_BOOL light_getBrightness(char const *controller, unsigned long *v);
126
+
127
+LIGHT_BOOL light_getMaxBrightness(char const *controller, unsigned long *v);
128
+
129
+LIGHT_BOOL light_setBrightness(char const *controller, unsigned long v);
130
+
131
+LIGHT_BOOL light_controllerAccessible(char const *controller);
132
+
133
+LIGHT_BOOL light_iterateControllers(void);
134
+
135
+/* WARNING: `controller` HAS to be at least 256 bytes */
136
+LIGHT_BOOL light_getBestController(char *controller);
137
+
138
+LIGHT_BOOL light_getMinCap(char const *controller, LIGHT_BOOL *hasMinCap, unsigned long *minCap);
139
+
140
+LIGHT_BOOL light_setMinCap(char const *controller, unsigned long v);
141
+
142
+#endif /* LIGHT_H */

BIN
light View File


+ 0
- 478
main.c View File

@@ -1,478 +0,0 @@
1
-/*	
2
- * 	Licensed under the GNU Public License version 3.
3
- *	Read attached LICENSE
4
- * 	Copyright (C) 2012 - Fredrik Haikarainen
5
- * 	Fredrik.haikarainen@gmail.com
6
- */
7
-
8
-#define _GNU_SOURCE
9
-
10
-#include <stdio.h>
11
-#include <stdlib.h>
12
-#include <dirent.h>
13
-#include <string.h>
14
-#include <unistd.h>
15
-#include <limits.h>
16
-
17
-typedef enum LBOOL{
18
-	TRUE = 0,
19
-	FALSE = 1
20
-} LBOOL;
21
-
22
-typedef enum LOPTYPE{
23
-	SET = 0,
24
-	ADD = 1,
25
-	SUB = 2
26
-} LOPTYPE;
27
-
28
-/* Flags */
29
-LBOOL q; /* Quiet, supresses output */
30
-LBOOL c; /* print unprecise current value in percentage */
31
-LBOOL m; /* read max value*/
32
-LBOOL p; /* precision read current value */
33
-int wbright;
34
-LOPTYPE ot;
35
-
36
-LBOOL readint(const char* f, unsigned int *i){
37
-	FILE* ff = fopen(f, "r");
38
-	if(ff){
39
-		fscanf(ff, "%u", i);
40
-		fclose(ff);
41
-		return TRUE;
42
-	}else{
43
-		return FALSE;
44
-	}
45
-}
46
-
47
-LBOOL readchar(const char* f, char *c){
48
-	
49
-	FILE* ff = fopen(f, "r");
50
-
51
-	/*c = malloc(sz+1);*/
52
-	if(ff){
53
-		unsigned int sz;
54
-		fseek(ff, 0L, SEEK_END);
55
-		sz = ftell(ff);
56
-		fseek(ff, 0L, SEEK_SET);
57
-		fgets(c,sz,ff);
58
-		fclose(ff);
59
-		return TRUE;
60
-	}else{
61
-		return FALSE;
62
-	}
63
-}
64
-
65
-LBOOL writeint(const char* f, unsigned int i){
66
-	FILE* ff = fopen(f, "w");
67
-	if(ff){
68
-		fprintf(ff, "%u", i);
69
-		fclose(ff);
70
-		return TRUE;
71
-	}else{
72
-		return FALSE;
73
-	}
74
-}
75
-
76
-
77
-LBOOL is_dir(const char* d){
78
-	DIR* dd = opendir(d);
79
-	if(dd){
80
-		closedir(dd);
81
-		return TRUE;
82
-	}else{
83
-		return FALSE;
84
-	}
85
-}
86
-
87
-LBOOL is_writable(const char* f){
88
-	FILE* dd = fopen(f, "w");
89
-	if(dd){
90
-		fclose(dd);
91
-		return TRUE;
92
-	}else{
93
-		return FALSE;
94
-	}	
95
-}
96
-
97
-typedef struct {
98
-	char		name[256];
99
-	unsigned int	current_brightness;
100
-	unsigned int	max_brightness;
101
-	char		c_path[256]; /* Controller-path */
102
-	char		cb_path[256]; /* Current brightness-path */
103
-	char		mb_path[256]; /* Max brightness-path */
104
-	char		b_path[256]; /* Brightness-path */
105
-	enum LBOOL	is_ok;
106
-	unsigned int	guide_id;
107
-} controller;
108
-
109
-typedef struct {
110
-	controller	controllers[256];
111
-	unsigned int	num_controllers;
112
-} fetch_result;
113
-
114
-
115
-fetch_result fetch_controllers(const char* ctrldir){
116
-	fetch_result returner;
117
-	struct dirent* ep;
118
-
119
-	DIR* lcdir = opendir(ctrldir);
120
-	
121
-	returner.num_controllers = 0;
122
-
123
-	if(!lcdir){
124
-		if(q == FALSE)
125
-			printf("Error: Could not open directory '%s'!\n", ctrldir);
126
-	}else{
127
-		while( ( ep = readdir(lcdir) ) ){
128
-			char* currctrldir = "";
129
-			char* currctrldir_curr = "";
130
-			char* currctrldir_max = "";
131
-			char* currctrldir_f = "";
132
-			if( ep->d_name[0] != '.'){
133
-				strncpy(returner.controllers[returner.num_controllers].name, ep->d_name, sizeof(returner.controllers[returner.num_controllers].name));
134
-				
135
-				/* Set some default values, in case something fails we dont just get null */
136
-				returner.controllers[returner.num_controllers].current_brightness = 0;
137
-				returner.controllers[returner.num_controllers].max_brightness = 0;
138
-				returner.controllers[returner.num_controllers].is_ok = TRUE;
139
-				/*
140
-				returner.controllers[returner.num_controllers].c_path = NULL;
141
-				returner.controllers[returner.num_controllers].cb_path = NULL;
142
-				returner.controllers[returner.num_controllers].b_path = NULL;
143
-				returner.controllers[returner.num_controllers].mb_path = NULL;
144
-				*/
145
-				/* Get path to the current controller dir */
146
-				asprintf(&currctrldir, "%s/%s", ctrldir, ep->d_name);
147
-				
148
-				strncpy(returner.controllers[returner.num_controllers].c_path, currctrldir, sizeof(returner.controllers[returner.num_controllers].c_path));
149
-				
150
-				if(is_dir(currctrldir) == FALSE){
151
-					if(q == FALSE)
152
-						printf("Warning: '%s' is not a directory, check your system.\n", currctrldir);
153
-					returner.controllers[returner.num_controllers].is_ok = FALSE;
154
-				}
155
-				
156
-				/* Get path to current actual_brightness-file */
157
-				asprintf(&currctrldir_curr, "%s/%s", currctrldir, "actual_brightness");
158
-				strncpy(returner.controllers[returner.num_controllers].cb_path, currctrldir_curr, sizeof(returner.controllers[returner.num_controllers].cb_path));
159
-				if( readint(currctrldir_curr, &returner.controllers[returner.num_controllers].current_brightness) == FALSE ){
160
-					if(q == FALSE)
161
-						printf("Warning: Can't read actual_brightness-file of '%s'. Will ignore this controller.\n", ep->d_name);
162
-					returner.controllers[returner.num_controllers].is_ok = FALSE;
163
-				}				
164
-				
165
-				/* Get path to current max_brightness-file*/
166
-				asprintf(&currctrldir_max, "%s/%s", currctrldir, "max_brightness");
167
-				strncpy(returner.controllers[returner.num_controllers].mb_path, currctrldir_max, sizeof(returner.controllers[returner.num_controllers].mb_path));
168
-				
169
-				if( readint(currctrldir_max, &returner.controllers[returner.num_controllers].max_brightness) == FALSE ){
170
-					if(q == FALSE)
171
-						printf("Warning: Can't read max_brightness-file of '%s'. Will ignore this controller.\n", ep->d_name);
172
-					returner.controllers[returner.num_controllers].is_ok = FALSE;
173
-				}
174
-				
175
-				/* Get path to current brightness-file */
176
-				asprintf(&currctrldir_f, "%s/%s", currctrldir, "brightness");
177
-				strncpy(returner.controllers[returner.num_controllers].b_path, currctrldir_f, sizeof(returner.controllers[returner.num_controllers].b_path));
178
-				if( is_writable(currctrldir_f) == FALSE){
179
-					if(q == FALSE)
180
-						printf("Warning: Controllerfile of '%s' is not writable. Will ignore this controller.\n", ep->d_name);
181
-					returner.controllers[returner.num_controllers].is_ok = FALSE;
182
-				}
183
-				
184
-				
185
-				returner.num_controllers++;
186
-			}
187
-		}
188
-		closedir(lcdir);	
189
-	}
190
-	return returner;
191
-}
192
-
193
-controller* get_best_controller(fetch_result* res){
194
-	unsigned int it;
195
-	unsigned int cmax;
196
-	LBOOL foundokctrl;
197
-	controller* returner;
198
-	
199
-	
200
-	it = 0;
201
-	cmax = 0;
202
-	foundokctrl = FALSE;
203
-	
204
-	returner = NULL;
205
-	
206
-	while(it < res->num_controllers){
207
-		if(res->controllers[it].is_ok == TRUE){
208
-			if(foundokctrl != TRUE){
209
-				foundokctrl = TRUE;
210
-				returner = &res->controllers[it];
211
-			}
212
-			if(res->controllers[it].max_brightness > cmax){
213
-				cmax = res->controllers[it].max_brightness;
214
-				returner = &res->controllers[it];
215
-			}
216
-		}
217
-		it++;
218
-	}
219
-	
220
-	return returner;
221
-}
222
-
223
-controller* get_controller_by_name(fetch_result* res, const char* name){
224
-	unsigned int it;
225
-	controller* returner;
226
-	
227
-	it = 0;
228
-	returner = NULL;
229
-	
230
-	while(it < res->num_controllers){
231
-		if(strcmp(res->controllers[it].name, name) == 0){
232
-			returner = &res->controllers[it];
233
-		}
234
-		it++;
235
-	}
236
-	
237
-	return returner;
238
-		
239
-}
240
-
241
-void usage(){
242
-	printf("Usage: light [-qcaspmfh] [--options] <value>\n\n\tFlags:\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. \n\t-a:\t Add the value instead of setting it.\n\t-s:\t Subtract the value instead of setting it.\n\t-h:\t Shows this help and exits.\n");
243
-	printf("\n\tOptions:\n\t--help:\t Shows this help and exits.\n\n\t<value>\t Brightness wanted in percent.\n\n");
244
-}
245
-
246
-int main(int argc, char **argv) {
247
-	unsigned int argsit;
248
-	
249
-	fetch_result	res;
250
-	controller*	best_ctrl;
251
-	unsigned int	citr;
252
-	uid_t		uid;
253
-	unsigned int	minlight;
254
-	LBOOL		given;
255
-	unsigned int	real_wbright;
256
-	unsigned int	minlight_nonp;
257
-	unsigned int	curr_bright;
258
-	unsigned int	curr_brightp;
259
-	LBOOL		useforce;
260
-	char*		useforce_name;
261
-	
262
-	/* Get UID */
263
-	uid = getuid();
264
-	
265
-	useforce = FALSE;
266
-	useforce_name = malloc(256*sizeof(char));
267
-	
268
-	/* Parse arguments */
269
-	q=FALSE;
270
-	c=FALSE;
271
-	m=FALSE;
272
-	p=FALSE;
273
-	ot=SET;
274
-	wbright=0;
275
-	argsit = 1;
276
-	given=FALSE;
277
-	while(argsit < argc){
278
-		char* carg = argv[argsit];
279
-		if(carg[0] == '-'){
280
-			LBOOL argdone;
281
-			argdone = FALSE;
282
-			if(strlen(carg) > 2){
283
-				if(carg[1] == '-'){
284
-					int longargs = strlen(carg) -2;
285
-					char *longarg = (char*) malloc(longargs);
286
-					strncpy(longarg, carg+2, longargs);
287
-					
288
-					if(strcmp(longarg, "help") == 0){
289
-						usage();
290
-						return 0;
291
-					}else{
292
-						printf("Unknown option: \"%s\".\n", longarg);
293
-						return 0;
294
-					}
295
-					argdone = TRUE;
296
-				}
297
-			}
298
-			
299
-			if(argdone == FALSE){
300
-				unsigned int cargit = 1;
301
-				while(cargit < strlen(carg)){
302
-					switch(carg[cargit]){
303
-						case 'q':
304
-							q = TRUE;
305
-						break;
306
-						case 'a':
307
-							ot = ADD;
308
-						break;
309
-						case 's':
310
-							ot = SUB;
311
-						break;
312
-						case 'c':
313
-							c = TRUE;
314
-						break;
315
-						case 'p':
316
-							p = TRUE;
317
-						break;
318
-						case 'm':
319
-							m = TRUE;
320
-						break;
321
-						case 'h':
322
-							usage();
323
-							return 0;
324
-						break;
325
-						default:
326
-							printf("Unknown flag: %c\n", carg[cargit]);
327
-							return 1;
328
-						break;
329
-					}
330
-					cargit++;
331
-				}
332
-			}
333
-		}else{
334
-			wbright = atoi(carg);
335
-			given=TRUE;
336
-		}
337
-		
338
-		argsit++;
339
-	}
340
-	
341
-	
342
-	if(c == TRUE || m == TRUE || p == TRUE){
343
-		q = TRUE;
344
-	}
345
-	
346
-	if(given == FALSE && c == FALSE && m == FALSE && p == FALSE){
347
-		usage();
348
-		return 0;
349
-	}
350
-	if(q == FALSE)
351
-		printf("Light 0.7 - Fredrik Haikarainen\n");
352
-	
353
-	/* Get and check minlight */
354
-	
355
-	if(readint("/etc/light/minlight", &minlight) == FALSE){
356
-		minlight = 5;
357
-		if(q == FALSE)
358
-			printf("Warning: Couldn't read /etc/light/minlight, using 5 as default.\n");
359
-	}
360
-	
361
-	/* Fetch controllers */
362
-	if(q == FALSE)
363
-		printf("Fetching controllers..\n");
364
-	
365
-	res = fetch_controllers("/sys/class/backlight");
366
-	citr = 0;
367
-	while(citr < res.num_controllers){
368
-		controller* currc = &res.controllers[citr];
369
-		if(currc->is_ok == TRUE){
370
-			if(q == FALSE)
371
-				printf("\tFound '%s' (%u/%u)\n", currc->name, currc->current_brightness, currc->max_brightness);
372
-		}else{
373
-			if(q == FALSE)
374
-				printf("\tFound '%s', but ignoring\n", currc->name);
375
-		}
376
-		citr++;
377
-	}
378
-
379
-	if(q == FALSE)
380
-		printf("\n");
381
-	/* Read override-file if exists*/
382
-	if(readchar("/etc/light/override",useforce_name) == TRUE){
383
-		printf("Overriding controller '%s' !\n", useforce_name);
384
-		useforce=TRUE;
385
-	}
386
-	if(useforce == TRUE){
387
-		best_ctrl = get_controller_by_name(&res, useforce_name);
388
-		if(best_ctrl == NULL){
389
-			if(q == FALSE)
390
-				printf("Can't override, no such controller. Check/remove your override-file!\n");
391
-			return 1;	
392
-		}
393
-	}else{
394
-		/* Get the best controller */
395
-		best_ctrl = get_best_controller(&res);
396
-		
397
-		if(best_ctrl == NULL){
398
-			if(uid == 0){
399
-				if(q == FALSE)
400
-					printf("No okay controller found, even though you are root! Check your system.\n");
401
-			}else{
402
-				if(q == FALSE)
403
-					printf("No okay controller found, check your permissions or try to run as root.\n");
404
-			}
405
-			return 1;
406
-		}
407
-	}
408
-	
409
-	if(p == TRUE){
410
-		printf("%u\n", best_ctrl->current_brightness);
411
-		return 0;
412
-	}
413
-	
414
-	if(m == TRUE){
415
-		printf("%u\n", best_ctrl->max_brightness);
416
-		return 0;
417
-	}
418
-	
419
-	if(q == FALSE)
420
-		printf("Using controller '%s' ..\n", best_ctrl->name);
421
-	
422
-	if(wbright < 0){ wbright = 0;}
423
-	if(wbright > 100){wbright=100;}
424
-	
425
-	curr_bright = best_ctrl->current_brightness;
426
-	curr_brightp = (float)((float)curr_bright / (float)best_ctrl->max_brightness) * 100;
427
-	
428
-	
429
-	if(c == TRUE){
430
-		printf("%u\n", curr_brightp);
431
-		return 0;
432
-	}
433
-	
434
-	minlight_nonp = best_ctrl->max_brightness * ( (float)minlight / 100) + 1;
435
-	
436
-	switch(ot){
437
-		case SET:
438
-			real_wbright = best_ctrl->max_brightness * ( (float)wbright / 100 );
439
-		break;
440
-		case ADD:
441
-			real_wbright = ( best_ctrl->max_brightness * ( (float)( curr_brightp + wbright +1) / 100 ));
442
-		break;
443
-		case SUB:
444
-			if(curr_brightp <= wbright){
445
-				real_wbright = minlight_nonp;
446
-			}else{
447
-				real_wbright = ( best_ctrl->max_brightness * ( (float)( curr_brightp - wbright + 1) / 100 ));
448
-			}
449
-		break;
450
-		default:
451
-		break;
452
-	}
453
-	
454
-
455
-
456
-	/* FIXME<- SHOULD BE FIXED NOW, LETS STAY HERE ANYWAY JUST IN CASE 
457
-		Line below makes sure the value never wraps around and gets higher. Puts a (high) limit on max brightness.
458
-		Not sure if safe for portabilities sake.
459
-	 
460
-	if(real_wbright > ((UINT_MAX/2) - best_ctrl->max_brightness)){ real_wbright = minlight_nonp; } 
461
-	*/
462
-	
463
-	
464
-	if(real_wbright > best_ctrl->max_brightness){real_wbright = best_ctrl->max_brightness;}
465
-	if(real_wbright < minlight_nonp){real_wbright = minlight_nonp;}
466
-	
467
-	if(q == FALSE)
468
-		printf("Writing %u to file '%s'..\n", real_wbright, best_ctrl->b_path);
469
-	
470
-	if(writeint(best_ctrl->b_path, real_wbright) == FALSE){
471
-		if(q == FALSE){
472
-			printf("Error: Could not write to file %s, check your permissions!\n", best_ctrl->b_path);
473
-		}
474
-		return 1;
475
-	}
476
-	
477
-	return 0;
478
-}

+ 207
- 0
src/helpers.c View File

@@ -0,0 +1,207 @@
1
+#include "helpers.h"
2
+
3
+#include <stdio.h>
4
+#include <stdlib.h>
5
+#include <string.h>
6
+#include <sys/types.h>
7
+#include <dirent.h>
8
+
9
+LIGHT_BOOL light_readUInt(char const * filename, unsigned int *i)
10
+{
11
+  FILE* fileHandle;
12
+  unsigned int iCopy;
13
+
14
+  fileHandle = fopen(filename, "r");
15
+
16
+  if(!fileHandle)
17
+  {
18
+    LIGHT_ERR("could not open file for reading");
19
+    return FALSE;
20
+  }
21
+
22
+  if(fscanf(fileHandle, "%u", &iCopy) != 1)
23
+  {
24
+    LIGHT_ERR("file contents are corrupt");
25
+    fclose(fileHandle);
26
+    return FALSE;
27
+  }
28
+  
29
+  *i = iCopy;
30
+
31
+  fclose(fileHandle);
32
+  return TRUE;
33
+}
34
+
35
+LIGHT_BOOL light_writeUInt(char const * filename, unsigned int i)
36
+{
37
+  FILE* fileHandle;
38
+
39
+  fileHandle = fopen(filename, "w");
40
+
41
+  if(!fileHandle)
42
+  {
43
+    LIGHT_ERR("could not open file for writing");
44
+    return FALSE;
45
+  }
46
+
47
+  if(fprintf(fileHandle, "%u", i) < 0)
48
+  {
49
+    LIGHT_ERR("fprintf failed");
50
+    fclose(fileHandle);
51
+    return FALSE;
52
+  }
53
+
54
+  fclose(fileHandle);
55
+  return TRUE;
56
+}
57
+
58
+
59
+LIGHT_BOOL light_readULong(char const * filename, unsigned long *i)
60
+{
61
+  FILE* fileHandle;
62
+  unsigned long iCopy;;
63
+
64
+  fileHandle = fopen(filename, "r");
65
+
66
+  if(!fileHandle)
67
+  {
68
+    LIGHT_ERR("could not open file for reading");
69
+    return FALSE;
70
+  }
71
+
72
+  if(fscanf(fileHandle, "%lu", &iCopy) != 1)
73
+  {
74
+    LIGHT_ERR("file contents are corrupt");
75
+    fclose(fileHandle);
76
+    return FALSE;
77
+  }
78
+  
79
+  *i = iCopy;
80
+
81
+  fclose(fileHandle);
82
+  return TRUE;
83
+}
84
+
85
+LIGHT_BOOL light_writeULong(char const * filename, unsigned long i)
86
+{
87
+  FILE* fileHandle;
88
+
89
+  fileHandle = fopen(filename, "w");
90
+
91
+  if(!fileHandle)
92
+  {
93
+    LIGHT_ERR("could not open file for writing");
94
+    return FALSE;
95
+  }
96
+
97
+  if(fprintf(fileHandle, "%lu", i) < 0)
98
+  {
99
+    LIGHT_ERR("fprintf failed");
100
+    fclose(fileHandle);
101
+    return FALSE;
102
+  }
103
+
104
+  fclose(fileHandle);
105
+  return TRUE;
106
+}
107
+
108
+
109
+
110
+LIGHT_BOOL light_readString(char const * filename, char *buffer, long* size)
111
+{
112
+  FILE *fileHandle;
113
+  long fileSize;
114
+  long readSize;
115
+
116
+  /* Make sure buffer pointer is null */
117
+  if(buffer != NULL)
118
+  {
119
+    LIGHT_ERR("buffer passed to function isn't NULL");
120
+    return FALSE;
121
+  }
122
+
123
+  /* Open file */
124
+  fileHandle = fopen(filename, "r");
125
+
126
+  if(!fileHandle)
127
+  {
128
+    LIGHT_ERR("could not open file for reading");
129
+    return FALSE;
130
+  }
131
+
132
+  /* Get the file size */
133
+  fseek(fileHandle, 0L, SEEK_END);
134
+  fileSize = ftell(fileHandle);
135
+  rewind(fileHandle);
136
+
137
+  /* Allocate the string and null-terminate it */
138
+  buffer = (char*) malloc(sizeof(char)*(fileSize+1));
139
+  memset(buffer, '\0', fileSize);
140
+
141
+  if(buffer == NULL)
142
+  {
143
+    LIGHT_MEMERR();
144
+    fclose(fileHandle);
145
+    return FALSE;
146
+  }
147
+
148
+  /* Read the file */
149
+  readSize = fread(buffer, sizeof(char), fileSize, fileHandle);
150
+
151
+  if(readSize != fileSize)
152
+  {
153
+    LIGHT_ERR("read error");
154
+    free(buffer);
155
+    fclose(fileHandle);
156
+    return FALSE;
157
+  }
158
+  
159
+  /* Set the size */
160
+  if(size != NULL)
161
+  {
162
+    *size = readSize;
163
+  }
164
+
165
+  /* All well, close handle and return TRUE */
166
+  fclose(fileHandle);
167
+  return TRUE;
168
+}
169
+
170
+LIGHT_BOOL light_isDir(char const * path)
171
+{
172
+  DIR *dirHandle = opendir(path);
173
+
174
+  if(!dirHandle)
175
+  {
176
+    return FALSE;
177
+  }
178
+
179
+  closedir(dirHandle);
180
+  return TRUE;
181
+}
182
+
183
+LIGHT_BOOL light_isWritable(char const * filename)
184
+{
185
+  FILE* fileHandle = fopen(filename, "w");
186
+
187
+  if(!fileHandle)
188
+  {
189
+    return FALSE;
190
+  }
191
+
192
+  fclose(fileHandle);
193
+  return TRUE;
194
+}
195
+
196
+LIGHT_BOOL light_isReadable(char const * filename)
197
+{
198
+  FILE* fileHandle = fopen(filename, "r");
199
+
200
+  if(!fileHandle)
201
+  {
202
+    return FALSE;
203
+  }
204
+
205
+  fclose(fileHandle);
206
+  return TRUE;
207
+}

+ 703
- 0
src/light.c View File

@@ -0,0 +1,703 @@
1
+#include "light.h"
2
+
3
+#include <stdlib.h>
4
+#include <stdio.h>
5
+#include <string.h>
6
+#include <unistd.h>
7
+#include <getopt.h>
8
+
9
+void light_defaultConfig()
10
+{
11
+  light_Configuration.controllerMode         = LIGHT_AUTO;
12
+  memset(&light_Configuration.specifiedController, '\0', 256);
13
+  light_Configuration.operationMode          = LIGHT_GET;
14
+  light_Configuration.valueMode              = LIGHT_PERCENT;
15
+  light_Configuration.specifiedValueRaw      = 0;
16
+  light_Configuration.specifiedValuePercent  = 0.0;
17
+  light_Configuration.target                 = LIGHT_BRIGHTNESS;
18
+  light_verbosity                            = 0;
19
+}
20
+
21
+LIGHT_BOOL light_parseArguments(int argc, char** argv)
22
+{
23
+  int currFlag;
24
+
25
+  LIGHT_BOOL opSet = FALSE;
26
+  LIGHT_BOOL targetSet = FALSE;
27
+  LIGHT_BOOL ctrlSet = FALSE;
28
+  LIGHT_BOOL valSet = FALSE;
29
+
30
+  unsigned long specLen = 0;
31
+
32
+  while((currFlag = getopt(argc, argv, "HhVGSAUbmcas:prv:")) != -1)
33
+  {
34
+    switch(currFlag)
35
+    {
36
+      /* -- Operations -- */
37
+      case 'H':
38
+      case 'h':
39
+        ASSERT_OPSET();
40
+        light_Configuration.operationMode = LIGHT_PRINT_HELP;
41
+        break;
42
+      case 'V':
43
+        ASSERT_OPSET();
44
+        light_Configuration.operationMode = LIGHT_PRINT_VERSION;
45
+        break;
46
+      case 'G':
47
+        ASSERT_OPSET();
48
+        light_Configuration.operationMode = LIGHT_GET;
49
+        break;
50
+      case 'S':
51
+        ASSERT_OPSET();
52
+        light_Configuration.operationMode = LIGHT_SET;
53
+        break;
54
+      case 'A':
55
+        ASSERT_OPSET();
56
+        light_Configuration.operationMode = LIGHT_ADD;
57
+        break;
58
+      case 'U':
59
+        ASSERT_OPSET();
60
+        light_Configuration.operationMode = LIGHT_SUB;
61
+        break;
62
+
63
+      /* -- Targets -- */
64
+      case 'b':
65
+        ASSERT_TARGETSET();
66
+        light_Configuration.target = LIGHT_BRIGHTNESS;
67
+        break;
68
+      case 'm':
69
+        ASSERT_TARGETSET();
70
+        light_Configuration.target = LIGHT_MAX_BRIGHTNESS;
71
+        break;
72
+      case 'c':
73
+        ASSERT_TARGETSET();
74
+        light_Configuration.target = LIGHT_MIN_CAP;
75
+        break;
76
+
77
+      /* -- Controller selection -- */
78
+      case 'a':
79
+        ASSERT_CTRLSET();
80
+        light_Configuration.controllerMode = LIGHT_AUTO;
81
+        break;;
82
+      case 's':
83
+        ASSERT_CTRLSET();
84
+        light_Configuration.controllerMode = LIGHT_SPECIFY;
85
+        if(optarg == NULL)
86
+        {
87
+          printf("-s NEEDS an argument.\n\n");
88
+          light_printHelp();
89
+        }
90
+
91
+        specLen = strlen(optarg);
92
+        if(specLen > 255)
93
+        {
94
+          specLen = 255;
95
+        }
96
+
97
+        strncpy(light_Configuration.specifiedController, optarg, specLen);
98
+
99
+        light_Configuration.specifiedController[255] = '\0';
100
+        break;
101
+      /* -- Value modes -- */
102
+      case 'p':
103
+        ASSERT_VALSET();
104
+        light_Configuration.valueMode = LIGHT_PERCENT;
105
+        break;
106
+      case 'r':
107
+        ASSERT_VALSET();
108
+        light_Configuration.valueMode = LIGHT_RAW;
109
+        break;
110
+
111
+      /* -- Other -- */
112
+      case 'v':
113
+        if(optarg == NULL)
114
+        {
115
+          printf("-v NEEDS an argument.\n\n");
116
+          light_printHelp();
117
+          return FALSE;
118
+        }
119
+        if(sscanf(optarg, "%i", &light_verbosity) != 1)
120
+        {
121
+          printf("-v Verbosity is not specified in a recognizable format.\n\n");
122
+          light_printHelp();
123
+          return FALSE;
124
+        }
125
+        if(light_verbosity < 0 || light_verbosity > 3)
126
+        {
127
+          printf("-v Verbosity has to be between 0 and 3.\n\n");
128
+          light_printHelp();
129
+          return FALSE;
130
+        }
131
+        break;
132
+    }
133
+  }
134
+
135
+  /* If we need a <value> (for writing), make sure we have it! */
136
+  if(light_Configuration.operationMode == LIGHT_SET ||
137
+     light_Configuration.operationMode == LIGHT_ADD ||
138
+     light_Configuration.operationMode == LIGHT_SUB)
139
+  {
140
+    if(argc - optind != 1)
141
+    {
142
+      printf("Light needs an argument for <value>.\n\n");
143
+      light_printHelp();
144
+      return FALSE;
145
+    }
146
+
147
+    if(light_Configuration.valueMode == LIGHT_PERCENT)
148
+    {
149
+      if(sscanf(argv[optind], "%lf", &light_Configuration.specifiedValuePercent) != 1){
150
+        printf("<value> is not specified in a recognizable format.\n\n");
151
+        light_printHelp();
152
+        return FALSE;
153
+      }
154
+      light_Configuration.specifiedValuePercent = LIGHT_CLAMP(light_Configuration.specifiedValuePercent, 0.00, 100.00);
155
+    }else{
156
+      if(sscanf(argv[optind], "%lu", &light_Configuration.specifiedValueRaw) != 1){
157
+        printf("<value> is not specified in a recognizable format.\n\n");
158
+        light_printHelp();
159
+        return FALSE;
160
+      }
161
+    }
162
+
163
+  }
164
+
165
+  return TRUE;
166
+}
167
+
168
+void light_printVersion(){
169
+  printf("Light %u.%u (%s)\n", LIGHT_VER_MAJOR, LIGHT_VER_MINOR, LIGHT_VER_TYPE);
170
+  printf("Copyright (C) %u %s\n", LIGHT_YEAR, LIGHT_AUTHOR);
171
+  printf("This is free software, see the source for copying conditions.  There is NO\n");
172
+  printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE\n\n");
173
+}
174
+
175
+void light_printHelp(){
176
+  printf("Usage: light <options> <value>\n");
177
+  printf("<value> has to be either integral(raw mode) or decimal(percent mode) depending on the specified value mode.\n");
178
+  printf("<options> can be any of the following:\n\n");
179
+
180
+  printf("Operations (can not be used in conjunction):\n");
181
+  printf("  -H -h:\tPrints this help and exits\n");
182
+  printf("  -V:\t\tPrints version info and exits\n");
183
+  printf("  -G:\t\tGet value (default)\n");
184
+  printf("  -S:\t\tSet value\n");
185
+  printf("  -A:\t\tAdd value\n");
186
+  printf("  -U:\t\tSubtract value\n\n");
187
+  
188
+  printf("Targets (can not be used in conjunction):\n");
189
+  printf("  -b:\t\tBrightness (default)\n  \t\tUsed with [GSAU]\n\n");
190
+  printf("  -m:\t\tMaximum brightness\n  \t\tUsed with [G]\n\n");
191
+  printf("  -c:\t\tMinimum cap\n  \t\tUsed with [GS]\n");
192
+  printf("  \t\tG returns null if no minimum cap is set.\n\n");
193
+
194
+  printf("Controller selection (can not be used in conjunction):\n");
195
+  printf("  -a:\t\tSelects controller automatically (default).\n");
196
+  printf("  -s:\t\tSpecify controller to use. (needs argument)\n\n");
197
+
198
+  printf("Value modes (can not be used in conjunction):\n");
199
+  printf("  -p:\t\tInterpret <value> as, and output values in, percent. (default)\n");
200
+  printf("  -r:\t\tInterpret <value> as, and output values in, raw mode.\n\n");
201
+  
202
+  printf("Other:\n");
203
+  printf("  -v:\t\tSets the verbosity level, (needs argument).\n  \t\t0: Only outputs read values.\n  \t\t1: Read values, Errors.\n  \t\t2: Read values, Errors, Warnings.\n  \t\t3: Read values, Errors, Warnings, Notices.\n\n");
204
+}
205
+
206
+LIGHT_BOOL light_initialize(int argc, char** argv)
207
+{
208
+  light_defaultConfig();
209
+  if(!light_parseArguments(argc, argv))
210
+  {
211
+    LIGHT_ERR("could not parse arguments");
212
+    return FALSE;
213
+  }
214
+
215
+  if(light_Configuration.operationMode == LIGHT_PRINT_HELP || light_Configuration.operationMode == LIGHT_PRINT_VERSION)
216
+  {
217
+      return TRUE;
218
+  }
219
+  
220
+  /* Make sure we have a valid controller before we proceed */
221
+  if(light_Configuration.controllerMode == LIGHT_AUTO)
222
+  {
223
+    LIGHT_NOTE("Automatic mode -- finding best controller");
224
+    if(!light_getBestController(light_Configuration.specifiedController))
225
+    {
226
+      LIGHT_ERR("could not find suitable controller");
227
+      return FALSE;
228
+    }
229
+  }
230
+
231
+  if(!light_controllerAccessible(light_Configuration.specifiedController))
232
+  {
233
+    LIGHT_ERR("selected controller is not valid, make sure this application is run as root.");
234
+    return FALSE;
235
+  }
236
+  
237
+
238
+  return TRUE;
239
+}
240
+
241
+LIGHT_BOOL light_execute()
242
+{
243
+  unsigned long rawCurr; /* The current brightness, in raw mode */
244
+  double    percentCurr; /* The current brightness, in percent  */
245
+  unsigned long  rawMax; /* The max brightness, in percent      */
246
+  
247
+  unsigned long  rawSetP; /* The final value to be set, in raw mode, when setting with percent */
248
+  unsigned long  rawAddP; /* The final value to be set, in raw mode, when adding with percent */
249
+  unsigned long  rawSubP; /* The final value to be set, in raw mode, when subtracting with percent */
250
+
251
+  unsigned long  rawSetR; /* The final value to be set, in raw mode, when setting with raw values */
252
+  unsigned long  rawAddR; /* The final value to be set, in raw mode, when adding with raw values */
253
+  unsigned long  rawSubR; /* The final value to be set, in raw mode, when subtracting with raw values */
254
+
255
+  unsigned long   minCap; /* The minimum cap, in raw mode */
256
+  double   percentMinCap; /* The minimum cap, in percent */
257
+  LIGHT_BOOL   hasMinCap; /* If we have a minimum cap     */
258
+  unsigned long  minCapP; /* The final value to be set, in raw mode, when setting with percent (This is uncapped and used for minimum cap setting) */
259
+  unsigned long  minCapR; /* The final value to be set, in raw mode, when setting with raw values (This is uncapped and used for minimum cap setting) */
260
+
261
+  unsigned long  *writeVal; /* The actual value used for writing */
262
+
263
+  /* Print help and version info */
264
+  if(light_Configuration.operationMode == LIGHT_PRINT_HELP)
265
+  {
266
+    light_printHelp();
267
+    return TRUE;
268
+  }
269
+
270
+  if(light_Configuration.operationMode == LIGHT_PRINT_VERSION)
271
+  {
272
+    light_printVersion();
273
+    return TRUE;
274
+  }
275
+
276
+  /* Prepare variables */
277
+
278
+  /* -- First, get the current, min and max values directly from controller/configuration (raw values) */
279
+  if(!light_getBrightness(light_Configuration.specifiedController, &rawCurr))
280
+  {
281
+    LIGHT_ERR("could not get brightness");
282
+    return FALSE;
283
+  }
284
+
285
+  if(!light_getMaxBrightness(light_Configuration.specifiedController, &rawMax))
286
+  {
287
+    LIGHT_ERR("could not get max brightness");
288
+    return FALSE;
289
+  }
290
+
291
+  if(!light_getMinCap(light_Configuration.specifiedController, &hasMinCap, &minCap))
292
+  {
293
+    LIGHT_ERR("could not get min brightness");
294
+    return FALSE;
295
+  }
296
+
297
+  if( hasMinCap && ( minCap < 0 || minCap > rawMax ) )
298
+  {
299
+    LIGHT_WARN("invalid minimum cap for controller, ignoring and using 0");
300
+    minCap = 0;
301
+  }
302
+
303
+  /* -- Secondly, calculate the rest of the values (Clamp them here as well!) */
304
+  percentCurr = LIGHT_CLAMP( ((double)rawCurr) /  ((double)rawMax) * 100 , 0.00, 100.00 );
305
+  percentMinCap = LIGHT_CLAMP( ((double)minCap) / ((double)rawMax) * 100 , 0.00, 100.00 );  
306
+
307
+  rawSetP     = LIGHT_CLAMP( ((unsigned long) (light_Configuration.specifiedValuePercent * ((double)rawMax) ) / 100) , minCap, rawMax );
308
+  rawAddP     = LIGHT_CLAMP( ((unsigned long) ( (percentCurr + light_Configuration.specifiedValuePercent) * ((double)rawMax)) / 100) , minCap, rawMax );
309
+  rawSubP     = LIGHT_CLAMP( ((unsigned long) ( (percentCurr - light_Configuration.specifiedValuePercent) * ((double)rawMax)) / 100) , minCap, rawMax );
310
+
311
+  rawSetR     = LIGHT_CLAMP( light_Configuration.specifiedValueRaw , minCap, rawMax );
312
+  rawAddR     = LIGHT_CLAMP( rawCurr + light_Configuration.specifiedValueRaw , minCap, rawMax );
313
+  rawSubR     = LIGHT_CLAMP( rawCurr - light_Configuration.specifiedValueRaw , minCap, rawMax );
314
+
315
+  minCapP     = LIGHT_CLAMP(((unsigned long) (light_Configuration.specifiedValuePercent * ((double)rawMax) ) / 100), 0, rawMax);
316
+  minCapR     = LIGHT_CLAMP( light_Configuration.specifiedValueRaw, 0, rawMax );
317
+  
318
+  /* Handle get operations */
319
+  if(light_Configuration.operationMode == LIGHT_GET)
320
+  {
321
+    switch(light_Configuration.target){
322
+      case LIGHT_BRIGHTNESS:
323
+        (light_Configuration.valueMode == LIGHT_RAW) ? printf("%lu\n", rawCurr) : printf("%.2f\n", percentCurr);
324
+        break;
325
+      case LIGHT_MAX_BRIGHTNESS:
326
+        (light_Configuration.valueMode == LIGHT_RAW) ? printf("%lu\n", rawMax) : printf("100.00\n"); /* <- I know how stupid it is but it might just make someones life easier */
327
+        break;
328
+      case LIGHT_MIN_CAP:
329
+        (light_Configuration.valueMode == LIGHT_RAW) ? printf("%lu\n", minCap) : printf("%.2f\n", percentMinCap);
330
+        break;
331
+    }
332
+
333
+    return TRUE;
334
+  }
335
+
336
+  /* Handle set/add/sub operations */
337
+  if(light_Configuration.operationMode == LIGHT_SET ||
338
+     light_Configuration.operationMode == LIGHT_ADD || 
339
+     light_Configuration.operationMode == LIGHT_SUB)
340
+  {
341
+
342
+    /* Set the pointer we will use for write to a fallback (that shouldn't change anything) */
343
+    writeVal = &rawCurr;
344
+
345
+    if(light_Configuration.target == LIGHT_MIN_CAP)
346
+    {
347
+      /* Handle minimum cap files */
348
+
349
+      /* If we are not attempting to set, fail! */
350
+      if(light_Configuration.operationMode != LIGHT_SET)
351
+      {
352
+        printf("Minimum cap can only be used with get/set operations.\n");
353
+        return FALSE;
354
+      }
355
+
356
+      /* Point our writevalue and attempt to write*/
357
+      writeVal = (light_Configuration.valueMode == LIGHT_RAW) ? &minCapR : &minCapP;
358
+      if(!light_setMinCap(light_Configuration.specifiedController, *writeVal))
359
+      {
360
+        LIGHT_ERR("could not set minimum cap");
361
+        return FALSE;
362
+      }
363
+
364
+      /* All good? Return true. */
365
+      return TRUE;
366
+
367
+    }else if(light_Configuration.target == LIGHT_BRIGHTNESS){
368
+      /* Handle brightness writing */
369
+
370
+      /* Point our writevalue according to configuration */
371
+      switch(light_Configuration.operationMode)
372
+      {
373
+        case LIGHT_SET:
374
+          writeVal = (light_Configuration.valueMode == LIGHT_RAW) ? &rawSetR : &rawSetP;
375
+          break;
376
+        case LIGHT_ADD:
377
+          writeVal = (light_Configuration.valueMode == LIGHT_RAW) ? &rawAddR : &rawAddP;
378
+          break;
379
+        case LIGHT_SUB:
380
+          writeVal = (light_Configuration.valueMode == LIGHT_RAW) ? &rawSubR : &rawSubP;
381
+          break;
382
+        case LIGHT_GET:
383
+        case LIGHT_PRINT_HELP:
384
+        case LIGHT_PRINT_VERSION:
385
+          break;
386
+      }
387
+
388
+      /* Attempt to write */
389
+      if(!light_setBrightness(light_Configuration.specifiedController, *writeVal))
390
+      {
391
+        LIGHT_ERR("could not set brightness");
392
+        return FALSE;
393
+      }
394
+
395
+      /* All good? return true. */
396
+      return TRUE;
397
+
398
+    }else{
399
+      /* If we didn't provide a valid target for write operations, fail. */
400
+      printf("set/add/subtract operations are only available for brightness and minimum cap files.\n");
401
+      return FALSE;
402
+    }
403
+  }
404
+
405
+  printf("Controller: %s\nValueRaw: %lu\nValuePercent: %.2f\nOpMode: %u\nValMode: %u\nTarget: %u\n\n", light_Configuration.specifiedController, light_Configuration.specifiedValueRaw, light_Configuration.specifiedValuePercent, light_Configuration.operationMode, light_Configuration.valueMode, light_Configuration.target);
406
+
407
+  printf("You did not specify a valid combination of commandline arguments. Have some help: \n");
408
+  light_printHelp();
409
+  return FALSE;
410
+}
411
+
412
+void light_free()
413
+{
414
+
415
+}
416
+
417
+LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET type, char **buffer)
418
+{
419
+  char* returner = (char*)malloc(256);
420
+  int spfVal = -1;
421
+
422
+  if(returner == NULL)
423
+  {
424
+    LIGHT_MEMERR();
425
+    buffer = NULL;
426
+    return FALSE;
427
+  }
428
+
429
+  memset(returner, '\0', 256);
430
+  
431
+  switch(type)
432
+  {
433
+    case LIGHT_BRIGHTNESS:
434
+      spfVal = sprintf(returner, "/sys/class/backlight/%s/brightness", controller);
435
+      break;
436
+    case LIGHT_MAX_BRIGHTNESS:
437
+      spfVal = sprintf(returner, "/sys/class/backlight/%s/max_brightness", controller);
438
+      break;
439
+    case LIGHT_MIN_CAP:
440
+      spfVal = sprintf(returner, "/etc/light/mincap/%s", controller);
441
+      break;
442
+  }
443
+
444
+  if(spfVal < 0)
445
+  {
446
+    LIGHT_ERR("sprintf failed");
447
+    free(returner);
448
+    buffer = NULL;
449
+    return FALSE;
450
+  }
451
+
452
+  *buffer = returner;
453
+
454
+  return TRUE;
455
+}
456
+
457
+LIGHT_BOOL light_getBrightness(char const *controller, unsigned long *v)
458
+{
459
+  char *brightnessPath = NULL;
460
+  LIGHT_BOOL readVal = FALSE;
461
+
462
+  if(!light_genPath(controller, LIGHT_BRIGHTNESS, &brightnessPath))
463
+  {
464
+    LIGHT_ERR("could not generate path to brightness file");
465
+    return FALSE;
466
+  }
467
+
468
+  readVal = light_readULong( brightnessPath , v);
469
+  free(brightnessPath);
470
+
471
+  if(!readVal)
472
+  {
473
+    LIGHT_ERR("could not read value from brightness file");
474
+    return FALSE;
475
+  }
476
+
477
+  return TRUE;
478
+}
479
+
480
+LIGHT_BOOL light_getMaxBrightness(char const *controller, unsigned long *v)
481
+{
482
+  char *maxPath;
483
+  LIGHT_BOOL readVal = FALSE;
484
+
485
+  if(!light_genPath(controller, LIGHT_MAX_BRIGHTNESS, &maxPath))
486
+  {
487
+    LIGHT_ERR("could not generate path to maximum brightness file");
488
+    return FALSE;
489
+  }
490
+
491
+  readVal = light_readULong(maxPath , v);
492
+  free(maxPath);
493
+
494
+  if(!readVal)
495
+  {
496
+    LIGHT_ERR("could not read value from max brightness file");
497
+    return FALSE;
498
+  }
499
+
500
+  if(*v == 0)
501
+  {
502
+    LIGHT_ERR("max brightness is 0, so controller is not valid");
503
+    return FALSE;
504
+  }
505
+
506
+  return TRUE;
507
+}
508
+
509
+LIGHT_BOOL light_setBrightness(char const *controller, unsigned long v)
510
+{
511
+  char *brightnessPath = NULL;
512
+  LIGHT_BOOL writeVal = FALSE;
513
+
514
+  if(!light_genPath(controller, LIGHT_BRIGHTNESS, &brightnessPath))
515
+  {
516
+    LIGHT_ERR("could not generate path to brightness file");
517
+    return FALSE;
518
+  }
519
+
520
+  writeVal = light_writeULong(brightnessPath, v);
521
+
522
+  if(!writeVal)
523
+  {
524
+    LIGHT_ERR("could not write value to brightness file");
525
+  }
526
+
527
+  free(brightnessPath);
528
+  return writeVal;
529
+}
530
+
531
+LIGHT_BOOL light_controllerAccessible(char const *controller)
532
+{
533
+  char *brightnessPath = NULL;
534
+  unsigned long dummy;
535
+
536
+  if(!light_getBrightness(controller, &dummy))
537
+  {
538
+    LIGHT_WARN("could not read controllers brightness file, so controller is not accessible")
539
+    return FALSE;
540
+  }
541
+
542
+  if(!light_getMaxBrightness(controller, &dummy))
543
+  {
544
+    LIGHT_WARN("could not read controller max brightness file, so controller is not accessible")
545
+    return FALSE;
546
+  }
547
+
548
+  if(!light_genPath(controller, LIGHT_BRIGHTNESS, &brightnessPath))
549
+  {
550
+    LIGHT_ERR("could not generate path to brightness file");
551
+    return FALSE;
552
+  }
553
+
554
+  if(!light_isWritable(brightnessPath))
555
+  {
556
+    LIGHT_WARN("could not open controller brightness file for writing, so controller is not accessible");
557
+    free(brightnessPath);
558
+    return FALSE;
559
+  }
560
+
561
+  free(brightnessPath);
562
+  return TRUE;
563
+}
564
+
565
+LIGHT_BOOL light_iterateControllers()
566
+{
567
+  LIGHT_BOOL dotsKilled = FALSE;
568
+
569
+  if(light_iteratorDir == NULL)
570
+  {
571
+    light_iteratorDir = opendir("/sys/class/backlight");
572
+    if(light_iteratorDir == NULL)
573
+    {
574
+      LIGHT_ERR("could not open /sys/class/backlight directory");
575
+      return FALSE;
576
+    }
577
+  }
578
+
579
+  while(!dotsKilled)
580
+  {
581
+    light_iterator = readdir(light_iteratorDir);
582
+    if(light_iterator == NULL)
583
+    {
584
+      if(light_iteratorDir != NULL)
585
+      {
586
+        closedir(light_iteratorDir);
587
+        light_iteratorDir = NULL;
588
+      }
589
+      return FALSE;
590
+    }
591
+
592
+    if(light_iterator->d_name[0] != '.')
593
+    {
594
+      dotsKilled = TRUE;
595
+    }
596
+  }
597
+
598
+  strcpy(light_currentController, light_iterator->d_name);
599
+
600
+  return TRUE;
601
+}
602
+
603
+LIGHT_BOOL light_getBestController(char *controller)
604
+{
605
+  char bestYet[256];
606
+  unsigned long bestValYet = 0;
607
+  LIGHT_BOOL foundOkController = FALSE;
608
+
609
+  memset(bestYet, '\0', 256);
610
+
611
+  while(light_iterateControllers())
612
+  {
613
+    unsigned long currVal = 0;
614
+
615
+    if(light_getMaxBrightness(light_currentController, &currVal))
616
+    {
617
+      
618
+      if(light_controllerAccessible(light_currentController))
619
+      {
620
+        if(currVal > bestValYet)
621
+        {
622
+        foundOkController = TRUE;
623
+        bestValYet = currVal;
624
+        memset(bestYet, '\0', 256);
625
+        strcpy(bestYet, light_currentController);
626
+        }else{
627
+          LIGHT_NOTE("ignoring controller as better one already found");
628
+        }
629
+      }else{
630
+        LIGHT_WARN("controller not accessible");
631
+      }
632
+    }else{
633
+      LIGHT_WARN("could not read max brightness from file");
634
+    }
635
+  }
636
+
637
+  if(!foundOkController)
638
+  {
639
+    LIGHT_ERR("could not find an accessible controller");
640
+    return FALSE;
641
+  }
642
+
643
+  if(bestValYet == 0)
644
+  {
645
+    LIGHT_ERR("found accessible controller but it's useless/corrupt");
646
+    return FALSE;
647
+  }
648
+
649
+  memset(controller, '\0', 256);
650
+  strcpy(controller, bestYet);
651
+
652
+  return TRUE;
653
+}
654
+
655
+LIGHT_BOOL light_getMinCap(char const * controller, LIGHT_BOOL * hasMinCap, unsigned long * minCap)
656
+{
657
+ char * mincapPath = NULL;
658
+ 
659
+ if(!light_genPath(controller, LIGHT_MIN_CAP, &mincapPath))
660
+ {
661
+    LIGHT_ERR("could not generate path to minimum cap file");
662
+    return FALSE;
663
+ }
664
+
665
+  if(!light_isReadable(mincapPath)){
666
+    *hasMinCap = FALSE;
667
+    *minCap = 0;
668
+    free(mincapPath);
669
+    return TRUE;
670
+  }
671
+
672
+  if(!light_readULong(mincapPath, minCap))
673
+  {
674
+    LIGHT_ERR("could not read minimum cap from file");
675
+    free(mincapPath);
676
+    return FALSE;
677
+  }
678
+
679
+  *hasMinCap = TRUE;
680
+
681
+  free(mincapPath);
682
+  return TRUE;
683
+}
684
+
685
+LIGHT_BOOL light_setMinCap(char const * controller, unsigned long v)
686
+{
687
+  char * mincapPath = NULL;
688
+  if(!light_genPath(controller, LIGHT_MIN_CAP, &mincapPath))
689
+  {
690
+    LIGHT_ERR("could not generate path to minimum cap file");
691
+    return FALSE;
692
+  }
693
+
694
+  if(!light_writeULong(mincapPath, v))
695
+  {
696
+    LIGHT_ERR("could not write to minimum cap file");
697
+    free(mincapPath);
698
+    return FALSE;
699
+  }
700
+
701
+  free(mincapPath);
702
+  return TRUE;
703
+}

+ 26
- 0
src/main.c View File

@@ -0,0 +1,26 @@
1
+#include "light.h"
2
+
3
+#include <stdio.h>
4
+
5
+#define LIGHT_RETURNVAL_INITFAIL  -2
6
+#define LIGHT_RETURNVAL_EXECFAIL  -1
7
+#define LIGHT_RETURNVAL_SUCCESS   0
8
+
9
+int main(int argc, char** argv)
10
+{
11
+  if(!light_initialize(argc, argv))
12
+  {
13
+    LIGHT_ERR("Initialization failed");
14
+    return LIGHT_RETURNVAL_INITFAIL;
15
+  }
16
+
17
+  if(!light_execute())
18
+  {
19
+    LIGHT_ERR("Execution failed");
20
+    light_free();
21
+    return LIGHT_RETURNVAL_EXECFAIL;
22
+  }
23
+
24
+  light_free();
25
+  return LIGHT_RETURNVAL_SUCCESS;
26
+}