Browse Source

Merge pull request #25 from abdullahibnnadjo/master

Various fixes and improvements
Fredrik Svantesson 7 years ago
parent
commit
1ec60ac183
No account linked to committer's email
6 changed files with 558 additions and 329 deletions
  1. 1
    1
      Makefile
  2. 27
    4
      README.md
  3. 43
    10
      include/helpers.h
  4. 31
    45
      include/light.h
  5. 35
    8
      src/helpers.c
  6. 421
    261
      src/light.c

+ 1
- 1
Makefile View File

@@ -3,7 +3,7 @@ BINDIR=$(PREFIX)/bin
3 3
 MANDIR=$(PREFIX)/share/man/man1
4 4
 
5 5
 CC=gcc
6
-CFLAGS=-std=c89 -O2 -pedantic -Wall -I"./include"
6
+CFLAGS=-std=c89 -O2 -pedantic -Wall -I"./include" -D_XOPEN_SOURCE=500
7 7
 MANFLAGS=-h -h -v -V -N
8 8
 
9 9
 HELP2MAN_VERSION := $(shell help2man --version 2>/dev/null)

+ 27
- 4
README.md View File

@@ -40,7 +40,7 @@ ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chmod g+w /sys/class/backlight
40 40
 
41 41
 ## Usage
42 42
 
43
-This application usually has 4 different criteria on flags to use, which are operation modes, value mode, target and controller mode. Flags from these different modes can never be used in conjunction, but all of them do not always have to be specified (although it is recommended to do so for verbosity).
43
+This application usually has 5 different criteria on flags to use, which are operation modes, value mode, target, field and controller mode. Flags from these different modes can never be used in conjunction, but all of them do not always have to be specified (although it is recommended to do so for verbosity).
44 44
 
45 45
 **Note:** This application will only print errors if you are using it incorrectly. If something goes wrong, and you can't figure out why, try setting the verbosity flag with -v:
46 46
 
@@ -74,12 +74,18 @@ Remember, this is the unit that will be used when you set, get, add or subtract
74 74
 
75 75
 ### Target
76 76
 
77
-As you can not only handle the **brightness** of controllers, you may also specify a target to read/write from/to:
77
+You can choose which target to act on:
78
+
79
+* -l: Act on screen backlight
80
+* -k: Act on keyboard backlight and LEDs
81
+
82
+### Field
83
+
84
+As you can not only handle the **brightness** of controllers, you may also specify a field to read/write from/to:
78 85
 
79 86
 * -b: Current brightness of selected controller
80 87
 * -m: Maximum brightness of selected controller
81 88
 * -c: Minimum brightness (cap) of selected controller
82
-* -k: Set keyboard brightness instead of display brightness
83 89
 
84 90
 The minimum brightness is a feature implemented as some controllers make the screen go pitch black at 0%, if you have a controller like that, it is recommended to set this value (in either percent or in raw mode). These values will be saved in raw mode though, so if you specify it in percent it might not be too accurate depending on your controller.
85 91
 
@@ -93,7 +99,7 @@ Finally, you can either use the built-in controller selection to get the control
93 99
 
94 100
 Get the current brightness in percent
95 101
 
96
-`light -G`
102
+`light -G`, or simply `light`
97 103
 
98 104
 Increase brightness by 5 percent
99 105
 
@@ -103,3 +109,20 @@ Set the minimum cap to 2 in raw value on the acpi_video0 controller:
103 109
 
104 110
 `light -Scrs "acpi_video0" 2`
105 111
 
112
+Try to set the brightness to 0 after that, it will be changed to the minimum 2
113
+
114
+`light -Srs "acpi_video0" 0`
115
+
116
+Find keyboard controllers
117
+
118
+`light -Lk`
119
+
120
+Activate `ScrollLock` LED
121
+
122
+`light -Sks "input15::scrolllock" 100`
123
+
124
+Usually, LEDs only take 0 or 1 in raw value (i.e. for off/on), so you can write
125
+
126
+`light -Skrs "input15::scrolllock" 1`
127
+
128
+Verify this with `light -v3 -mkrs input15::scrolllock`, you should get a max. brightness of 1

+ 43
- 10
include/helpers.h View File

@@ -13,22 +13,46 @@
13 13
  *    x;
14 14
  *  }
15 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");
16
+#define LIGHT_CLAMP(x, y, z) ((x<y) ? (light_logInfClamp(y)) : ((x>z) ? (light_logSupClamp(z)) : x ))
25 17
 
18
+#define LIGHT_LOG_FMT_BUF_SIZE 1024
26 19
 /* Verbosity levels: 
27 20
  * 0 - No output
28 21
  * 1 - Errors
29 22
  * 2 - Errors, warnings 
30 23
  * 3 - Errors, warnings, notices */
31
-int    light_verbosity;
24
+typedef enum LIGHT_LOG_LEVEL {
25
+  LIGHT_ERROR_LEVEL = 1,
26
+  LIGHT_WARN_LEVEL,
27
+  LIGHT_NOTE_LEVEL
28
+} LIGHT_LOG_LEVEL;
29
+
30
+LIGHT_LOG_LEVEL light_verbosity;
31
+char light_log_buffer[LIGHT_LOG_FMT_BUF_SIZE];
32
+
33
+#define LIGHT_LOG(lvl,f,t,x)if(light_verbosity >= lvl){fprintf(f,t": \"%s\", in \"%s\" on line %u.\n", x, __FILE__, __LINE__);}
34
+
35
+#define LIGHT_NOTE(x)LIGHT_LOG(LIGHT_NOTE_LEVEL,stdout,"notice",x)
36
+
37
+#define LIGHT_WARN(x)LIGHT_LOG(LIGHT_WARN_LEVEL,stderr,"warning",x)
38
+
39
+#define LIGHT_ERR(x)LIGHT_LOG(LIGHT_ERROR_LEVEL,stderr,"error",x)
40
+
41
+#define LIGHT_LOG_FMT(x,s,f)if(snprintf(light_log_buffer, LIGHT_LOG_FMT_BUF_SIZE,x,s) > 0){f(light_log_buffer);}
42
+
43
+#define LIGHT_NOTE_FMT(x,s)LIGHT_LOG_FMT(x,s,LIGHT_NOTE);
44
+
45
+#define LIGHT_WARN_FMT(x,s)LIGHT_LOG_FMT(x,s,LIGHT_WARN);
46
+
47
+#define LIGHT_ERR_FMT(x,s)LIGHT_LOG_FMT(x,s,LIGHT_ERR);
48
+
49
+#define LIGHT_MEMERR() LIGHT_ERR("memory error");
50
+
51
+#define LIGHT_PERMLOG(x,f)f##_FMT("could not open '%s' for "x,filename); f("check if this file exists or if you have the right permissions");
52
+
53
+#define LIGHT_PERMERR(x) LIGHT_PERMLOG(x,LIGHT_ERR)
54
+
55
+#define LIGHT_PERMWARN(x) LIGHT_PERMLOG(x,LIGHT_WARN)
32 56
 
33 57
 /* Typedef for boolean values */
34 58
 typedef enum LIGHT_BOOL {
@@ -60,4 +84,13 @@ LIGHT_BOOL light_isWritable(char const * filename);
60 84
 /* Returns TRUE if file is readable, FALSE otherwise */
61 85
 LIGHT_BOOL light_isReadable(char const * filename);
62 86
 
87
+/* Clamps the `percent` value between 0% and 100% */
88
+double light_clampPercent(double percent);
89
+
90
+/* Prints a notice about a value which was below `x` and was adjusted to it */
91
+unsigned long light_logInfClamp(unsigned long x);
92
+
93
+/* Prints a notice about a value which was above `x` and was adjusted to it */
94
+unsigned long light_logSupClamp(unsigned long x);
95
+
63 96
 #endif /* LIGHT_HELPERS_H */

+ 31
- 45
include/light.h View File

@@ -5,53 +5,38 @@
5 5
 
6 6
 #include <sys/types.h>
7 7
 #include <dirent.h>
8
+#include <linux/limits.h>
8 9
 
9 10
 #define LIGHT_VER_MAJOR 0
10
-#define LIGHT_VER_MINOR 9
11
+#define LIGHT_VER_MINOR 10
11 12
 #define LIGHT_VER_TYPE "beta"
12 13
 #define LIGHT_YEAR 2014
13 14
 #define LIGHT_AUTHOR "Fredrik Haikarainen"
14 15
 
15
-#define ASSERT_OPSET() \
16
-  if(opSet)\
16
+#define ASSERT_SET(t,v) \
17
+  if(v)\
17 18
   {\
18
-    printf("Operation arguments can not be used in conjunction.\n");\
19
+    fprintf(stderr, t" arguments can not be used in conjunction.\n");\
19 20
     return FALSE;\
20 21
   }\
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;
22
+  v = TRUE;
46 23
 
24
+#define ASSERT_OPSET() ASSERT_SET("Operation", opSet)
25
+#define ASSERT_TARGETSET() ASSERT_SET("Target", targetSet)
26
+#define ASSERT_FIELDSET() ASSERT_SET("Field", fieldSet)
27
+#define ASSERT_CTRLSET() ASSERT_SET("Controller", ctrlSet)
28
+#define ASSERT_VALSET() ASSERT_SET("Value", valSet)
47 29
 
48
-typedef enum LIGHT_TARGET {
30
+typedef enum LIGHT_FIELD {
49 31
   LIGHT_BRIGHTNESS = 0,
50 32
   LIGHT_MAX_BRIGHTNESS,
51 33
   LIGHT_MIN_CAP,
52
-  LIGHT_SAVERESTORE,
53
-  LIGHT_KEYBOARD,
54
-  LIGHT_KEYBOARD_MAX_BRIGHTNESS
34
+  LIGHT_SAVERESTORE
35
+} LIGHT_FIELD;
36
+
37
+typedef enum LIGHT_TARGET {
38
+  LIGHT_BACKLIGHT = 0,
39
+  LIGHT_KEYBOARD
55 40
 } LIGHT_TARGET;
56 41
 
57 42
 typedef enum LIGHT_CTRL_MODE {
@@ -80,7 +65,7 @@ typedef enum LIGHT_VAL_MODE {
80 65
 typedef struct light_runtimeArguments_s {
81 66
   /* Which controller to use */
82 67
   LIGHT_CTRL_MODE controllerMode;
83
-  char            specifiedController[256];
68
+  char            specifiedController[NAME_MAX + 1];
84 69
 
85 70
   /* What to do with the controller */
86 71
   LIGHT_OP_MODE   operationMode;
@@ -88,13 +73,14 @@ typedef struct light_runtimeArguments_s {
88 73
   unsigned long   specifiedValueRaw; /* The specified value in raw mode */
89 74
   double          specifiedValuePercent; /* The specified value in percent */
90 75
 
91
-  LIGHT_TARGET    target;
92
-} light_runtimeArguments, *light_runtimeArguments_p;
76
+  LIGHT_TARGET   target;
77
+  LIGHT_FIELD    field;
78
+
79
+  /* Cache data */
80
+  LIGHT_BOOL      hasCachedMaxBrightness;
81
+  unsigned long   cachedMaxBrightness;
93 82
 
94
-/* -- Global variables that handles iterating controllers -- */
95
-struct dirent *light_iterator;
96
-DIR           *light_iteratorDir;
97
-char          light_currentController[256];
83
+} light_runtimeArguments, *light_runtimeArguments_p;
98 84
 
99 85
 /* -- Global variable holding the settings for the current run -- */
100 86
 light_runtimeArguments light_Configuration;
@@ -126,8 +112,10 @@ void light_free();
126 112
 /* SECTION: Controller functionality */
127 113
 
128 114
 /* WARNING: `buffer` HAS to be freed by the user if not null once returned!
129
- * Size is always 256 */
130
-LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET type, char **buffer);
115
+ * Size is always NAME_MAX + 1 */
116
+LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET target, LIGHT_FIELD type, char **buffer);
117
+
118
+LIGHT_BOOL light_validControllerName(char const *controller);
131 119
 
132 120
 LIGHT_BOOL light_getBrightness(char const *controller, unsigned long *v);
133 121
 
@@ -137,9 +125,7 @@ LIGHT_BOOL light_setBrightness(char const *controller, unsigned long v);
137 125
 
138 126
 LIGHT_BOOL light_controllerAccessible(char const *controller);
139 127
 
140
-LIGHT_BOOL light_iterateControllers(void);
141
-
142
-/* WARNING: `controller` HAS to be at least 256 bytes */
128
+/* WARNING: `controller` HAS to be at most NAME_MAX, otherwise fails */
143 129
 LIGHT_BOOL light_getBestController(char *controller);
144 130
 
145 131
 LIGHT_BOOL light_getMinCap(char const *controller, LIGHT_BOOL *hasMinCap, unsigned long *minCap);

+ 35
- 8
src/helpers.c View File

@@ -15,13 +15,13 @@ LIGHT_BOOL light_readUInt(char const * filename, unsigned int *i)
15 15
 
16 16
   if(!fileHandle)
17 17
   {
18
-    LIGHT_ERR("could not open file for reading");
18
+    LIGHT_PERMERR("reading");
19 19
     return FALSE;
20 20
   }
21 21
 
22 22
   if(fscanf(fileHandle, "%u", &iCopy) != 1)
23 23
   {
24
-    LIGHT_ERR("file contents are corrupt");
24
+    LIGHT_ERR_FMT("Couldn't parse a positive integer number from '%s'", filename);
25 25
     fclose(fileHandle);
26 26
     return FALSE;
27 27
   }
@@ -40,7 +40,7 @@ LIGHT_BOOL light_writeUInt(char const * filename, unsigned int i)
40 40
 
41 41
   if(!fileHandle)
42 42
   {
43
-    LIGHT_ERR("could not open file for writing");
43
+    LIGHT_PERMERR("writing");
44 44
     return FALSE;
45 45
   }
46 46
 
@@ -65,13 +65,13 @@ LIGHT_BOOL light_readULong(char const * filename, unsigned long *i)
65 65
 
66 66
   if(!fileHandle)
67 67
   {
68
-    LIGHT_ERR("could not open file for reading");
68
+    LIGHT_PERMERR("reading");
69 69
     return FALSE;
70 70
   }
71 71
 
72 72
   if(fscanf(fileHandle, "%lu", &iCopy) != 1)
73 73
   {
74
-    LIGHT_ERR("file contents are corrupt");
74
+    LIGHT_ERR_FMT("Couldn't parse a positive integer number from '%s'", filename);
75 75
     fclose(fileHandle);
76 76
     return FALSE;
77 77
   }
@@ -90,7 +90,7 @@ LIGHT_BOOL light_writeULong(char const * filename, unsigned long i)
90 90
 
91 91
   if(!fileHandle)
92 92
   {
93
-    LIGHT_ERR("could not open file for writing");
93
+    LIGHT_PERMERR("writing");
94 94
     return FALSE;
95 95
   }
96 96
 
@@ -125,7 +125,7 @@ LIGHT_BOOL light_readString(char const * filename, char *buffer, long* size)
125 125
 
126 126
   if(!fileHandle)
127 127
   {
128
-    LIGHT_ERR("could not open file for reading");
128
+    LIGHT_PERMERR("reading");
129 129
     return FALSE;
130 130
   }
131 131
 
@@ -182,10 +182,11 @@ LIGHT_BOOL light_isDir(char const * path)
182 182
 
183 183
 LIGHT_BOOL light_isWritable(char const * filename)
184 184
 {
185
-  FILE* fileHandle = fopen(filename, "w");
185
+  FILE* fileHandle = fopen(filename, "r+");
186 186
 
187 187
   if(!fileHandle)
188 188
   {
189
+    LIGHT_PERMWARN("writing");
189 190
     return FALSE;
190 191
   }
191 192
 
@@ -199,9 +200,35 @@ LIGHT_BOOL light_isReadable(char const * filename)
199 200
 
200 201
   if(!fileHandle)
201 202
   {
203
+    LIGHT_PERMWARN("reading");
202 204
     return FALSE;
203 205
   }
204 206
 
205 207
   fclose(fileHandle);
206 208
   return TRUE;
207 209
 }
210
+
211
+unsigned long light_logInfClamp(unsigned long x)
212
+{
213
+  LIGHT_NOTE_FMT("specified value is inferior to %lu (raw), so adjusting it to this mininum value", x);
214
+  return x;
215
+}
216
+
217
+unsigned long light_logSupClamp(unsigned long x)
218
+{
219
+  LIGHT_NOTE_FMT("specified value is superior to %lu (raw), so adjusting it to this maximum value", x);
220
+  return x;
221
+}
222
+
223
+double light_clampPercent(double p)
224
+{
225
+  if(p < 0.0)
226
+  {
227
+    LIGHT_WARN_FMT("specified value %g%% is not valid, adjusting it to 0%%", p);
228
+    return 0.0;
229
+  }else if(p > 100.0){
230
+    LIGHT_WARN_FMT("specified value %g%% is not valid, adjusting it to 100%%", p);
231
+    return 100.0;
232
+  }
233
+  return p;
234
+}

+ 421
- 261
src/light.c
File diff suppressed because it is too large
View File