Browse Source

Rewrite codebase, add device-system

Fredrik Svantesson 5 years ago
parent
commit
7a3f49a395
11 changed files with 1286 additions and 949 deletions
  1. 1
    1
      configure.ac
  2. 1
    1
      src/Makefile.am
  3. 44
    14
      src/helpers.c
  4. 14
    10
      src/helpers.h
  5. 1
    0
      src/impl/razer.c
  6. 1
    0
      src/impl/razer.h
  7. 255
    0
      src/impl/sysfs.c
  8. 21
    0
      src/impl/sysfs.h
  9. 780
    819
      src/light.c
  10. 160
    99
      src/light.h
  11. 8
    5
      src/main.c

+ 1
- 1
configure.ac View File

@@ -1,5 +1,5 @@
1 1
 AC_INIT([light], [1.2-dev], [https://github.com/haikarainen/light/issues])
2
-AM_INIT_AUTOMAKE([1.11 foreign])
2
+AM_INIT_AUTOMAKE([1.11 foreign subdir-objects])
3 3
 AM_SILENT_RULES([yes])
4 4
 
5 5
 AC_CONFIG_SRCDIR([src/light.c])

+ 1
- 1
src/Makefile.am View File

@@ -1,5 +1,5 @@
1 1
 bin_PROGRAMS   = light
2
-light_SOURCES  = main.c light.c light.h helpers.c helpers.h
2
+light_SOURCES  = main.c light.c light.h helpers.c helpers.h impl/sysfs.c impl/sysfs.h
3 3
 light_CPPFLAGS = -I../include -D_GNU_SOURCE
4 4
 light_CFLAGS   = -W -Wall -Wextra -std=gnu99 -Wno-type-limits
5 5
 

+ 44
- 14
src/helpers.c View File

@@ -5,20 +5,25 @@
5 5
 #include <string.h>
6 6
 #include <sys/types.h>
7 7
 #include <dirent.h>
8
+#include <errno.h> // errno
9
+#include <libgen.h> // dirname 
8 10
 
9
-bool light_file_read_val(char const *filename, unsigned long *val)
11
+
12
+bool light_file_read_uint64(char const *filename, uint64_t *val)
10 13
 {
11 14
 	FILE *fp;
12
-	unsigned long data;
15
+	uint64_t data;
13 16
 
14 17
 	fp = fopen(filename, "r");
15
-	if (!fp) {
18
+	if (!fp)
19
+	{
16 20
 		LIGHT_PERMERR("reading");
17 21
 		return false;
18 22
 	}
19 23
 
20
-	if (fscanf(fp, "%lu", &data) != 1) {
21
-		LIGHT_ERR("Couldn't parse a positive integer number from '%s'", filename);
24
+	if (fscanf(fp, "%lu", &data) != 1)
25
+	{
26
+		LIGHT_ERR("Couldn't parse an unsigned integer from '%s'", filename);
22 27
 		fclose(fp);
23 28
 		return false;
24 29
 	}
@@ -29,17 +34,19 @@ bool light_file_read_val(char const *filename, unsigned long *val)
29 34
 	return true;
30 35
 }
31 36
 
32
-bool light_file_write_val(char const *filename, unsigned long val)
37
+bool light_file_write_uint64(char const *filename, uint64_t val)
33 38
 {
34 39
 	FILE *fp;
35 40
 
36 41
 	fp = fopen(filename, "w");
37
-	if (!fp) {
42
+	if (!fp)
43
+	{
38 44
 		LIGHT_PERMERR("writing");
39 45
 		return false;
40 46
 	}
41 47
 
42
-	if (fprintf(fp, "%lu", val) < 0) {
48
+	if (fprintf(fp, "%lu", val) < 0)
49
+	{
43 50
 		LIGHT_ERR("fprintf failed");
44 51
 		fclose(fp);
45 52
 		return false;
@@ -55,7 +62,8 @@ bool light_file_is_writable(char const *filename)
55 62
 	FILE *fp;
56 63
 
57 64
 	fp = fopen(filename, "r+");
58
-	if (!fp) {
65
+	if (!fp)
66
+	{
59 67
 		LIGHT_PERMWARN("writing");
60 68
 		return false;
61 69
 	}
@@ -70,7 +78,8 @@ bool light_file_is_readable(char const *filename)
70 78
 	FILE *fp;
71 79
 
72 80
 	fp = fopen(filename, "r");
73
-	if (!fp) {
81
+	if (!fp)
82
+	{
74 83
 		LIGHT_PERMWARN("reading");
75 84
 		return false;
76 85
 	}
@@ -80,14 +89,14 @@ bool light_file_is_readable(char const *filename)
80 89
 }
81 90
 
82 91
 /* Prints a notice about a value which was below `x` and was adjusted to it */
83
-unsigned long light_log_clamp_min(unsigned long min)
92
+uint64_t light_log_clamp_min(uint64_t min)
84 93
 {
85 94
 	LIGHT_NOTE("too small value, adjusting to mininum %lu (raw)", min);
86 95
 	return min;
87 96
 }
88 97
 
89 98
 /* Prints a notice about a value which was above `x` and was adjusted to it */
90
-unsigned long light_log_clamp_max(unsigned long max)
99
+uint64_t light_log_clamp_max(uint64_t max)
91 100
 {
92 101
 	LIGHT_NOTE("too large value, adjusting to mavalimum %lu (raw)", max);
93 102
 	return max;
@@ -96,15 +105,36 @@ unsigned long light_log_clamp_max(unsigned long max)
96 105
 /* Clamps the `percent` value between 0% and 100% */
97 106
 double light_percent_clamp(double val)
98 107
 {
99
-	if (val < 0.0) {
108
+	if (val < 0.0)
109
+	{
100 110
 		LIGHT_WARN("specified value %g%% is not valid, adjusting it to 0%%", val);
101 111
 		return 0.0;
102 112
 	}
103 113
 
104
-	if (val > 100.0) {
114
+	if (val > 100.0)
115
+	{
105 116
 		LIGHT_WARN("specified value %g%% is not valid, adjusting it to 100%%", val);
106 117
 		return 100.0;
107 118
 	}
108 119
 
109 120
 	return val;
110 121
 }
122
+
123
+int light_mkpath(char *dir, mode_t mode)
124
+{
125
+	struct stat sb;
126
+
127
+	if (!dir)
128
+	{
129
+		errno = EINVAL;
130
+		return -1;
131
+	}
132
+
133
+	if (!stat(dir, &sb))
134
+		return 0;
135
+
136
+	light_mkpath(dirname(strdupa(dir)), mode);
137
+
138
+	return mkdir(dir, mode);
139
+}
140
+

+ 14
- 10
src/helpers.h View File

@@ -1,7 +1,10 @@
1
-#ifndef LIGHT_HELPERS_H
2
-#define LIGHT_HELPERS_H
1
+
2
+#pragma once
3 3
 
4 4
 #include <stdbool.h>
5
+#include <stdint.h>
6
+#include <sys/stat.h>
7
+#include <stdio.h>
5 8
 
6 9
 /* Clamps x(value) between y(min) and z(max) in a nested ternary operation */
7 10
 #define LIGHT_CLAMP(val, min, max)					\
@@ -29,9 +32,9 @@ light_loglevel_t light_loglevel;
29 32
 	if (light_loglevel >= lvl)					\
30 33
 		fprintf(fp, "%s:%d:" fmt "\n", __FILE__, __LINE__, ##args)
31 34
 
32
-#define LIGHT_NOTE(fmt, args...) LIGHT_LOG(LIGHT_NOTE_LEVEL,  stdout, "NOTE:" fmt, ##args)
33
-#define LIGHT_WARN(fmt, args...) LIGHT_LOG(LIGHT_WARN_LEVEL,  stderr, "WARN:" fmt, ##args)
34
-#define LIGHT_ERR(fmt, args...)  LIGHT_LOG(LIGHT_ERROR_LEVEL, stderr, "!ERR:" fmt, ##args)
35
+#define LIGHT_NOTE(fmt, args...) LIGHT_LOG(LIGHT_NOTE_LEVEL,  stdout, " Notice: " fmt, ##args)
36
+#define LIGHT_WARN(fmt, args...) LIGHT_LOG(LIGHT_WARN_LEVEL,  stderr, " Warning: " fmt, ##args)
37
+#define LIGHT_ERR(fmt, args...)  LIGHT_LOG(LIGHT_ERROR_LEVEL, stderr, " Error: " fmt, ##args)
35 38
 #define LIGHT_MEMERR()           LIGHT_ERR("memory error");
36 39
 #define LIGHT_PERMLOG(act, log)						\
37 40
 	do {								\
@@ -41,15 +44,16 @@ light_loglevel_t light_loglevel;
41 44
 #define LIGHT_PERMERR(x)         LIGHT_PERMLOG(x, LIGHT_ERR)
42 45
 #define LIGHT_PERMWARN(x)        LIGHT_PERMLOG(x, LIGHT_WARN)
43 46
 
44
-bool light_file_write_val   (char const *filename, unsigned long val);
45
-bool light_file_read_val    (char const *filename, unsigned long *val);
47
+bool light_file_write_uint64   (char const *filename, uint64_t val);
48
+bool light_file_read_uint64    (char const *filename, uint64_t *val);
46 49
 
47 50
 bool light_file_is_writable (char const *filename);
48 51
 bool light_file_is_readable (char const *filename);
49 52
 
50
-unsigned long light_log_clamp_min(unsigned long min);
51
-unsigned long light_log_clamp_max(unsigned long max);
53
+uint64_t light_log_clamp_min(uint64_t min);
54
+uint64_t light_log_clamp_max(uint64_t max);
52 55
 
53 56
 double light_percent_clamp(double percent);
54 57
 
55
-#endif /* LIGHT_HELPERS_H */
58
+int light_mkpath(char *dir, mode_t mode);
59
+

+ 1
- 0
src/impl/razer.c View File

@@ -0,0 +1 @@
1
+ 

+ 1
- 0
src/impl/razer.h View File

@@ -0,0 +1 @@
1
+ 

+ 255
- 0
src/impl/sysfs.c View File

@@ -0,0 +1,255 @@
1
+
2
+#include "impl/sysfs.h"
3
+#include "light.h"
4
+#include "helpers.h"
5
+
6
+#include <stdio.h> //snprintf
7
+#include <stdlib.h> // malloc, free
8
+#include <dirent.h> // opendir, readdir
9
+
10
+static bool _impl_sysfs_init_leds(light_device_enumerator_t *enumerator)
11
+{
12
+	// Create a new backlight device
13
+	light_device_t *leds_device = malloc(sizeof(light_device_t));
14
+	snprintf(leds_device->name, sizeof(leds_device->name), "%s", "leds");
15
+	
16
+	// Add it to the enumerator 
17
+	light_add_enumerator_device(enumerator, leds_device);
18
+	
19
+	// Iterate through the led controllers and create a device_target for each controller 
20
+	DIR *leds_dir;
21
+	struct dirent *curr_entry;
22
+	
23
+	if((leds_dir = opendir("/sys/class/leds")) == NULL)
24
+	{
25
+		LIGHT_ERR("failed to open leds controller directory for reading");
26
+		return false;
27
+	}
28
+	
29
+	while((curr_entry = readdir(leds_dir)) != NULL)
30
+	{
31
+		// Skip dot entries
32
+		if(curr_entry->d_name[0] == '.')
33
+		{
34
+			continue;
35
+		}
36
+		
37
+		// Create a new device target for the controller 
38
+		light_device_target_t *led_controller = malloc(sizeof(light_device_target_t));
39
+		snprintf(led_controller->name, sizeof(led_controller->name), "%s", curr_entry->d_name);
40
+		
41
+		// Setup the function bindings
42
+		led_controller->set_value = impl_sysfs_set;
43
+		led_controller->get_value = impl_sysfs_get;
44
+		led_controller->get_max_value = impl_sysfs_getmax;
45
+		led_controller->custom_command = impl_sysfs_command;
46
+		
47
+		// Setup the target data 
48
+		impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
49
+		led_controller->device_target_data = dev_data;
50
+		snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/leds/%s/brightness", curr_entry->d_name);
51
+		snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/leds/%s/max_brightness", curr_entry->d_name);
52
+		
53
+		// Add it to the device
54
+		light_add_device_target(leds_device, led_controller);
55
+	}
56
+	
57
+	return true;
58
+}
59
+
60
+static bool _impl_sysfs_init_backlight(light_device_enumerator_t *enumerator)
61
+{
62
+	// Create a new backlight device
63
+	light_device_t *backlight_device = malloc(sizeof(light_device_t));
64
+	snprintf(backlight_device->name, sizeof(backlight_device->name), "%s", "backlight");
65
+	
66
+	// Add it to the enumerator 
67
+	light_add_enumerator_device(enumerator, backlight_device);
68
+	
69
+	// Iterate through the backlight controllers and create a device_target for each controller 
70
+	DIR *backlight_dir;
71
+	struct dirent *curr_entry;
72
+	
73
+	// Keep track of the best controller, and create an autodevice from that
74
+	char best_controller[NAME_MAX];
75
+	uint64_t best_value = 0;
76
+	
77
+	if((backlight_dir = opendir("/sys/class/backlight")) == NULL)
78
+	{
79
+		LIGHT_ERR("failed to open backlight controller directory for reading");
80
+		return false;
81
+	}
82
+	
83
+	while((curr_entry = readdir(backlight_dir)) != NULL)
84
+	{
85
+		// Skip dot entries
86
+		if(curr_entry->d_name[0] == '.')
87
+		{
88
+			continue;
89
+		}
90
+		
91
+		// Create a new device target for the controller 
92
+		light_device_target_t *backlight_controller = malloc(sizeof(light_device_target_t));
93
+		snprintf(backlight_controller->name, sizeof(backlight_controller->name), "%s", curr_entry->d_name);
94
+		
95
+		// Setup the function bindings
96
+		backlight_controller->set_value = impl_sysfs_set;
97
+		backlight_controller->get_value = impl_sysfs_get;
98
+		backlight_controller->get_max_value = impl_sysfs_getmax;
99
+		backlight_controller->custom_command = impl_sysfs_command;
100
+		
101
+		// Setup the target data 
102
+		impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
103
+		backlight_controller->device_target_data = dev_data;
104
+		snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/backlight/%s/brightness", curr_entry->d_name);
105
+		snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/backlight/%s/max_brightness", curr_entry->d_name);
106
+		
107
+		// Read the max brightness to get the best one
108
+		uint64_t curr_value = 0;
109
+		if(light_file_read_uint64(dev_data->max_brightness, &curr_value))
110
+		{
111
+			if(curr_value > best_value)
112
+			{
113
+				best_value = curr_value;
114
+				snprintf(best_controller, sizeof(best_controller), "%s", backlight_controller->name);
115
+			}
116
+		}
117
+		
118
+		// Add it to the device
119
+		light_add_device_target(backlight_device, backlight_controller);
120
+	}
121
+	
122
+	// Create an auto controller 
123
+	light_device_target_t *auto_controller = malloc(sizeof(light_device_target_t));
124
+	snprintf(auto_controller->name, sizeof(auto_controller->name), "%s", "auto");
125
+	
126
+	// Setup the function bindings
127
+	auto_controller->set_value = impl_sysfs_set;
128
+	auto_controller->get_value = impl_sysfs_get;
129
+	auto_controller->get_max_value = impl_sysfs_getmax;
130
+	auto_controller->custom_command = impl_sysfs_command;
131
+	
132
+	// Setup the target data 
133
+	impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
134
+	auto_controller->device_target_data = dev_data;
135
+	snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/backlight/%s/brightness", best_controller);
136
+	snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/backlight/%s/max_brightness", best_controller);
137
+	
138
+	// Add it to the device
139
+	light_add_device_target(backlight_device, auto_controller);
140
+	
141
+	return true;
142
+}
143
+
144
+bool impl_sysfs_init(light_device_enumerator_t *enumerator)
145
+{
146
+	// Create a device for the backlight 
147
+	_impl_sysfs_init_backlight(enumerator);
148
+	
149
+	// Create devices for the leds
150
+	 _impl_sysfs_init_leds(enumerator);
151
+	
152
+	return true;
153
+}
154
+
155
+bool impl_sysfs_free(light_device_enumerator_t *enumerator)
156
+{
157
+	// Iterate through the devices in the enumerator
158
+	for(uint64_t d = 0; d < enumerator->num_devices; d++)
159
+	{
160
+		light_device_t *curr_device = enumerator->devices[d];
161
+		
162
+		// If the given device points to NULL, we can safely skip it
163
+		if(curr_device == NULL)
164
+		{
165
+			continue;
166
+		}
167
+		
168
+		// If the given device has a targets array that isnt NULL, iterate through it to free the targets, then free the array
169
+		if(curr_device->targets != NULL)
170
+		{
171
+			for(uint64_t t = 0; t < curr_device->num_targets; t++)
172
+			{
173
+				light_device_target_t *curr_target = curr_device->targets[t];
174
+				
175
+				if(curr_target == NULL)
176
+				{
177
+					continue;
178
+				}
179
+				
180
+				if(curr_target->device_target_data != NULL)
181
+				{
182
+					free(curr_target->device_target_data);
183
+				}
184
+				
185
+				free(curr_target);
186
+			}
187
+			
188
+			free(curr_device->targets);
189
+		}
190
+		
191
+		// If the given device has any device_data, free it
192
+		if(curr_device->device_data != NULL)
193
+		{
194
+			free(curr_device->device_data);
195
+		}
196
+		
197
+		// Free the device
198
+		free(curr_device);
199
+	}
200
+	
201
+	// Free the devices array
202
+	free(enumerator->devices);
203
+	enumerator->devices = NULL;
204
+	enumerator->num_devices = 0;
205
+	
206
+	return true;
207
+}
208
+
209
+bool impl_sysfs_set(light_device_target_t *target, uint64_t in_value)
210
+{
211
+	impl_sysfs_data_t *data = (impl_sysfs_data_t*)target->device_target_data;
212
+
213
+	if(!light_file_write_uint64(data->brightness, in_value))
214
+	{
215
+		LIGHT_ERR("failed to write to sysfs device");
216
+		return false;
217
+	}
218
+	
219
+	return true;
220
+}
221
+
222
+bool impl_sysfs_get(light_device_target_t *target, uint64_t *out_value)
223
+{
224
+	impl_sysfs_data_t *data = (impl_sysfs_data_t*)target->device_target_data;
225
+
226
+	if(!light_file_read_uint64(data->brightness, out_value))
227
+	{
228
+		LIGHT_ERR("failed to read from sysfs device");
229
+		return false;
230
+	}
231
+	
232
+	return true;
233
+}
234
+
235
+bool impl_sysfs_getmax(light_device_target_t *target, uint64_t *out_value)
236
+{
237
+	impl_sysfs_data_t *data = (impl_sysfs_data_t*)target->device_target_data;
238
+
239
+	if(!light_file_read_uint64(data->max_brightness, out_value))
240
+	{
241
+		LIGHT_ERR("failed to read from sysfs device");
242
+		return false;
243
+	}
244
+	
245
+	return true;
246
+}
247
+
248
+bool impl_sysfs_command(light_device_target_t *target, char const *command_string)
249
+{
250
+	// No current need for custom commands in sysfs enumerator
251
+	// To implement support, simply parse the command string to your liking, and return false on invalid input or results!
252
+	return true;
253
+}
254
+
255
+

+ 21
- 0
src/impl/sysfs.h View File

@@ -0,0 +1,21 @@
1
+
2
+#pragma once 
3
+
4
+#include "light.h"
5
+
6
+// Implementation of the sysfs enumerator
7
+// Enumerates devices for backlights and leds
8
+
9
+// Device target data 
10
+typedef struct {
11
+	char brightness[NAME_MAX];
12
+	char max_brightness[NAME_MAX];
13
+} impl_sysfs_data_t;
14
+
15
+bool impl_sysfs_init(light_device_enumerator_t *enumerator);
16
+bool impl_sysfs_free(light_device_enumerator_t *enumerator);
17
+
18
+bool impl_sysfs_set(light_device_target_t *target, uint64_t in_value);
19
+bool impl_sysfs_get(light_device_target_t *target, uint64_t *out_value);
20
+bool impl_sysfs_getmax(light_device_target_t *target, uint64_t *out_value);
21
+bool impl_sysfs_command(light_device_target_t *target, char const *command_string);

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


+ 160
- 99
src/light.h View File

@@ -1,105 +1,166 @@
1
-#ifndef LIGHT_H_
2
-#define LIGHT_H_
3 1
 
4
-#include "config.h"
5
-#include "helpers.h"
2
+#pragma once
6 3
 
4
+#include <stdint.h>
7 5
 #include <stdbool.h>
8
-#include <sys/types.h>
9
-#include <dirent.h>
10
-#include <linux/limits.h>
6
+#include <limits.h> // NAME_MAX
7
+#include <stddef.h> // NULL
8
+
9
+#include "config.h"
11 10
 
12
-#define LIGHT_YEAR   "2012-2018"
11
+#define LIGHT_YEAR   "2012 - 2018"
13 12
 #define LIGHT_AUTHOR "Fredrik Haikarainen"
14 13
 
15
-#define ASSERT_SET(t, v)						\
16
-	if (v) {							\
17
-		fprintf(stderr, t " cannot be used more than once.\n"); \
18
-		return false;						\
19
-	}								\
20
-	v = true;
21
-
22
-#define ASSERT_CMDSET()    ASSERT_SET("Commands", cmd_set)
23
-#define ASSERT_TARGETSET() ASSERT_SET("Targets", target_set)
24
-#define ASSERT_FIELDSET()  ASSERT_SET("Fields", field_set)
25
-#define ASSERT_CTRLSET()   ASSERT_SET("Controllers", ctrl_set)
26
-#define ASSERT_VALSET()    ASSERT_SET("Values", val_set)
27
-
28
-typedef enum {
29
-	LIGHT_BRIGHTNESS = 0,
30
-	LIGHT_MAX_BRIGHTNESS,
31
-	LIGHT_MIN_CAP,
32
-	LIGHT_SAVERESTORE
33
-} light_field_t;
34
-
35
-typedef enum {
36
-	LIGHT_BACKLIGHT = 0,
37
-	LIGHT_KEYBOARD
38
-} light_target_t;
39
-
40
-typedef enum {
41
-	LIGHT_AUTO = 0,
42
-	LIGHT_SPECIFY
43
-} light_ctrl_mode_t;
44
-
45
-typedef enum {
46
-	LIGHT_GET = 0,
47
-	LIGHT_SET,
48
-	LIGHT_ADD,
49
-	LIGHT_SUB,
50
-	LIGHT_PRINT_HELP,	/* Prints help and exits  */
51
-	LIGHT_PRINT_VERSION,	/* Prints version info and exits */
52
-	LIGHT_LIST_CTRL,
53
-	LIGHT_RESTORE,
54
-	LIGHT_SAVE
55
-} light_cmd_t;
56
-
57
-typedef enum {
58
-	LIGHT_RAW = 0,
59
-	LIGHT_PERCENT
60
-} light_val_mode_t;
61
-
62
-typedef struct {
63
-	/* Cache file prefix */
64
-	char               prefix[NAME_MAX];
65
-
66
-	/* Which controller to use */
67
-	light_ctrl_mode_t  ctrl;
68
-	char               ctrl_name[NAME_MAX + 1];
69
-
70
-	/* What to do with the controller */
71
-	light_cmd_t        cmd;
72
-	light_val_mode_t   val_mode;
73
-	unsigned long      val_raw;	/* The specified value in raw mode */
74
-	double             val_percent;	/* The specified value in percent */
75
-
76
-	light_target_t     target;
77
-	light_field_t      field;
78
-
79
-	/* Cache data */
80
-	bool               has_cached_brightness_max;
81
-	unsigned long      cached_brightness_max;
82
-} light_ctx_t;
83
-
84
-/* -- Global variable holding the settings for the current run -- */
85
-light_ctx_t ctx;
86
-
87
-bool light_initialize              (int argc, char **argv);
88
-bool light_execute                 (void);
89
-void light_free                    (void);
90
-
91
-bool light_ctrl_list               (void);
92
-bool light_ctrl_probe              (char *controller, size_t len);
93
-bool light_ctrl_exist              (char const *controller);
94
-
95
-bool light_ctrl_get_brightness     (char const *controller, unsigned long *v);
96
-bool light_ctrl_set_brightness     (char const *controller, unsigned long v);
97
-bool light_ctrl_get_brightness_max (char const *controller, unsigned long *v);
98
-
99
-bool light_ctrl_get_cap_min        (char const *controller, bool *hasMinCap, unsigned long *minCap);
100
-bool light_ctrl_set_cap_min        (char const *controller, unsigned long val);
101
-
102
-bool light_ctrl_save_brightness    (char const *controller, unsigned long val);
103
-bool light_ctrl_restore_brightness (char const *controller);
104
-
105
-#endif /* LIGHT_H_ */
14
+struct _light_device_target_t;
15
+typedef struct _light_device_target_t light_device_target_t;
16
+
17
+struct _light_device_t;
18
+typedef struct _light_device_t light_device_t;
19
+
20
+struct _light_device_enumerator_t;
21
+typedef struct _light_device_enumerator_t light_device_enumerator_t;
22
+
23
+/* Function pointers that implementations have to set for device targets */
24
+typedef bool (*LFUNCVALSET)(light_device_target_t*, uint64_t);
25
+typedef bool (*LFUNCVALGET)(light_device_target_t*, uint64_t*);
26
+typedef bool (*LFUNCMAXVALGET)(light_device_target_t*, uint64_t*);
27
+typedef bool (*LFUNCCUSTOMCMD)(light_device_target_t*, char const *);
28
+
29
+/* Describes a target within a device (for example a led on a keyboard, or a controller for a backlight) */
30
+struct _light_device_target_t
31
+{
32
+	char           name[256];
33
+	LFUNCVALSET    set_value;
34
+	LFUNCVALGET    get_value;
35
+	LFUNCMAXVALGET get_max_value;
36
+	LFUNCCUSTOMCMD custom_command;
37
+	void           *device_target_data;
38
+	light_device_t *device;
39
+};
40
+
41
+
42
+/* Describes a device (a backlight, a keyboard, a led-strip) */
43
+struct _light_device_t
44
+{
45
+	char                  name[256];
46
+	light_device_target_t **targets;
47
+	uint64_t              num_targets;
48
+	void                  *device_data;
49
+	light_device_enumerator_t *enumerator;
50
+};
51
+
52
+
53
+typedef bool (*LFUNCENUMINIT)(light_device_enumerator_t*);
54
+typedef bool (*LFUNCENUMFREE)(light_device_enumerator_t*);
55
+
56
+/* An enumerator that is responsible for creating and freeing devices as well as their targets */
57
+struct _light_device_enumerator_t
58
+{
59
+	char          name[256];
60
+	LFUNCENUMINIT init;
61
+	LFUNCENUMFREE free;
62
+
63
+	light_device_t **devices;
64
+	uint64_t num_devices;
65
+};
66
+
67
+typedef struct _light_context_t light_context_t;
68
+
69
+// A command that can be run (set, get, add, subtract, print help, print version, list devices etc.)
70
+typedef bool (*LFUNCCOMMAND)(light_context_t *);
71
+
72
+
73
+/*
74
+	Options
75
+	v		Specify verbosity, defaults to o
76
+	s		Specify target, defaults to sysfs/backlight/auto
77
+	r		Use raw values instead of percentage
78
+	
79
+	Operations
80
+	H,h 	Print help and exit
81
+	V		Print version and exit
82
+	L		List devices
83
+	
84
+	G		Get brigthness 
85
+	M		Get max brightness
86
+	N		Set minimum cap
87
+	P		Get minimum cap
88
+	S		Set brigthness
89
+	
90
+	A		Increase brightness
91
+	U		Decrease brightness
92
+	O		Save brightness
93
+	I		Restore brightness
94
+ */
95
+
96
+// The different available commands
97
+bool light_cmd_print_help(light_context_t *ctx); // H,h 
98
+bool light_cmd_print_version(light_context_t *ctx); // V
99
+bool light_cmd_list_devices(light_context_t *ctx); // L
100
+bool light_cmd_set_brightness(light_context_t *ctx); // S
101
+bool light_cmd_get_brightness(light_context_t *ctx); // G
102
+bool light_cmd_get_max_brightness(light_context_t *ctx); // M
103
+bool light_cmd_set_min_brightness(light_context_t *ctx); // N
104
+bool light_cmd_get_min_brightness(light_context_t *ctx); // P
105
+bool light_cmd_add_brightness(light_context_t *ctx); // A
106
+bool light_cmd_sub_brightness(light_context_t *ctx); // U
107
+bool light_cmd_save_brightness(light_context_t *ctx); // O
108
+bool light_cmd_restore_brightness(light_context_t *ctx); // I
109
+
110
+
111
+// CONFDIR/targets/<enumerator>/<device>/<target>/ minimum|saved
112
+
113
+struct _light_context_t
114
+{
115
+	struct 
116
+	{
117
+		LFUNCCOMMAND			command; // What command was issued 
118
+		uint64_t				value; // The input value, in raw mode
119
+		bool					raw_mode; // Whether or not we use raw or percentage mode
120
+		light_device_target_t	*device_target; // The device target to act on
121
+	} run_params;
122
+
123
+	struct
124
+	{
125
+		char					conf_dir[NAME_MAX]; // The path to the application cache directory 
126
+	} sys_params;
127
+	
128
+	light_device_enumerator_t **enumerators;
129
+	uint64_t num_enumerators;
130
+
131
+};
132
+
133
+/* Initializes the application, given the command-line. Returns a context. */
134
+light_context_t* light_initialize(int argc, char **argv);
135
+
136
+/* Executes the given context. Returns true on success, false on failure. */
137
+bool light_execute(light_context_t*);
138
+
139
+/* Frees the given context */
140
+void light_free(light_context_t*);
141
+
142
+/* Create a device enumerator in the given context */
143
+light_device_enumerator_t * light_create_enumerator(light_context_t *ctx, char const * name, LFUNCENUMINIT, LFUNCENUMFREE);
144
+
145
+/* Initializes all the device enumerators (and its devices, targets) */
146
+bool light_init_enumerators(light_context_t *ctx);
147
+
148
+/* Frees all the device enumerators (and its devices, targets) */
149
+bool light_free_enumerators(light_context_t *ctx);
150
+
151
+void light_add_enumerator_device(light_device_enumerator_t *enumerator, light_device_t *new_device);
152
+
153
+void light_add_device_target(light_device_t *device, light_device_target_t *new_target);
154
+
155
+typedef struct _light_target_path_t light_target_path_t;
156
+struct _light_target_path_t 
157
+{
158
+	char enumerator[NAME_MAX];
159
+	char device[NAME_MAX];
160
+	char target[NAME_MAX];
161
+};
162
+
163
+bool light_split_target_path(char const * in_path, light_target_path_t *out_path);
164
+
165
+/* Returns the found device target, or null. Name should be enumerator/device/target */
166
+light_device_target_t* light_find_device_target(light_context_t *ctx, char const * name);

+ 8
- 5
src/main.c View File

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