Browse Source

Add untested and very experimental razer support #57

Fredrik Svantesson 5 years ago
parent
commit
55ad3be529
6 changed files with 154 additions and 4 deletions
  1. 1
    1
      src/Makefile.am
  2. 6
    0
      src/helpers.c
  3. 1
    0
      src/helpers.h
  4. 120
    0
      src/impl/razer.c
  5. 24
    1
      src/impl/razer.h
  6. 2
    2
      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 impl/sysfs.c impl/sysfs.h impl/util.h impl/util.c
2
+light_SOURCES  = main.c light.c light.h helpers.c helpers.h impl/sysfs.c impl/sysfs.h impl/util.h impl/util.c impl/razer.h impl/razer.c
3 3
 light_CPPFLAGS = -I../include -D_GNU_SOURCE
4 4
 light_CFLAGS   = -W -Wall -Wextra -std=gnu18 -Wno-type-limits -Wno-format-truncation -Wno-unused-parameter
5 5
 

+ 6
- 0
src/helpers.c View File

@@ -3,6 +3,7 @@
3 3
 #include <stdio.h>
4 4
 #include <stdlib.h>
5 5
 #include <string.h>
6
+#include <unistd.h> // access
6 7
 #include <sys/types.h>
7 8
 #include <dirent.h>
8 9
 #include <errno.h> // errno
@@ -56,6 +57,11 @@ bool light_file_write_uint64(char const *filename, uint64_t val)
56 57
     return true;
57 58
 }
58 59
 
60
+bool light_file_exists (char const *filename)
61
+{
62
+    return access( filename, F_OK ) != -1;
63
+}
64
+
59 65
 /* Returns true if file is writable, false otherwise */
60 66
 bool light_file_is_writable(char const *filename)
61 67
 {

+ 1
- 0
src/helpers.h View File

@@ -43,6 +43,7 @@ light_loglevel_t light_loglevel;
43 43
 bool light_file_write_uint64   (char const *filename, uint64_t val);
44 44
 bool light_file_read_uint64    (char const *filename, uint64_t *val);
45 45
 
46
+bool light_file_exists (char const *filename);
46 47
 bool light_file_is_writable (char const *filename);
47 48
 bool light_file_is_readable (char const *filename);
48 49
 

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

@@ -1 +1,121 @@
1
+
2
+#include "impl/razer.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 void _impl_razer_add_target(light_device_t *device, char const *name, char const *filename, uint64_t max_brightness)
11
+{
12
+    impl_razer_data_t *target_data = malloc(sizeof(impl_razer_data_t));
13
+    snprintf(target_data->brightness, sizeof(target_data->brightness), "/sys/bus/hid/drivers/razerkbd/%s/%s", device->name, filename);
14
+    target_data->max_brightness = max_brightness;
15
+    
16
+    // Only add targets that actually exist, as we aren't fully sure exactly what targets exist for a given device
17
+    if(light_file_exists(target_data->brightness))
18
+    {
19
+        light_create_device_target(device, name, impl_razer_set, impl_razer_get, impl_razer_getmax, impl_razer_command, target_data);
20
+    }
21
+    else 
22
+    {
23
+        LIGHT_WARN("razer: couldn't add target %s to device %s, the file %s doesn't exist", name, device->name, filename);
24
+        // target_data will not be freed automatically if we dont add a device target with it as userdata, so free it here
25
+        free(target_data);
26
+    }
27
+}
28
+
29
+static void _impl_razer_add_device(light_device_enumerator_t *enumerator, char const *device_id)
30
+{
31
+    // Create a new razer device
32
+    light_device_t *new_device = light_create_device(enumerator, device_id, NULL);
33
+
34
+    // Setup a target to backlight
35
+    _impl_razer_add_target(new_device, "backlight", "matrix_brightness", 255);
36
+    
37
+    // Setup targets to different possible leds
38
+    _impl_razer_add_target(new_device, "game_led", "game_led_state", 1);
39
+    _impl_razer_add_target(new_device, "macro_led", "macro_led_state", 1);
40
+    _impl_razer_add_target(new_device, "logo_led", "logo_led_state", 1);
41
+    _impl_razer_add_target(new_device, "profile_led_r", "profile_led_red", 1);
42
+    _impl_razer_add_target(new_device, "profile_led_g", "profile_led_green", 1);
43
+    _impl_razer_add_target(new_device, "profile_led_b", "profile_led_blue", 1);
44
+}
45
+
46
+bool impl_razer_init(light_device_enumerator_t *enumerator)
47
+{
48
+    // Iterate through the led controllers and create a device_target for each controller 
49
+    DIR *razer_dir;
50
+    struct dirent *curr_entry;
51
+    
52
+    if((razer_dir = opendir("/sys/bus/hid/drivers/razerkbd/")) == NULL)
53
+    {
54
+        // Razer driver isnt properly installed, so we cant add devices in this enumerator 
55
+        return true;
56
+    }
57
+    
58
+    while((curr_entry = readdir(razer_dir)) != NULL)
59
+    {
60
+        // Skip dot entries
61
+        if(curr_entry->d_name[0] == '.')
62
+        {
63
+            continue;
64
+        }
1 65
  
66
+        _impl_razer_add_device(enumerator, curr_entry->d_name);
67
+    }
68
+    
69
+    closedir(razer_dir);
70
+    
71
+    return true;
72
+}
73
+
74
+bool impl_razer_free(light_device_enumerator_t *enumerator)
75
+{
76
+    return true;
77
+}
78
+
79
+bool impl_razer_set(light_device_target_t *target, uint64_t in_value)
80
+{
81
+    impl_razer_data_t *data = (impl_razer_data_t*)target->device_target_data;
82
+
83
+    if(!light_file_write_uint64(data->brightness, in_value))
84
+    {
85
+        LIGHT_ERR("failed to write to razer device");
86
+        return false;
87
+    }
88
+    
89
+    return true;
90
+}
91
+
92
+bool impl_razer_get(light_device_target_t *target, uint64_t *out_value)
93
+{
94
+    impl_razer_data_t *data = (impl_razer_data_t*)target->device_target_data;
95
+
96
+    if(!light_file_read_uint64(data->brightness, out_value))
97
+    {
98
+        LIGHT_ERR("failed to read from razer device");
99
+        return false;
100
+    }
101
+    
102
+    return true;
103
+}
104
+
105
+bool impl_razer_getmax(light_device_target_t *target, uint64_t *out_value)
106
+{
107
+    impl_razer_data_t *data = (impl_razer_data_t*)target->device_target_data;
108
+
109
+    *out_value = data->max_brightness;
110
+    
111
+    return true;
112
+}
113
+
114
+bool impl_razer_command(light_device_target_t *target, char const *command_string)
115
+{
116
+    // No current need for custom commands in sysfs enumerator
117
+    // To implement support, simply parse the command string to your liking, and return false on invalid input or results!
118
+    return true;
119
+}
120
+
121
+

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

@@ -1 +1,24 @@
1
- 
1
+
2
+#pragma once 
3
+
4
+#include "light.h"
5
+
6
+// Implementation of the razer enumerator
7
+// Enumerates devices for the openrazer driver https://github.com/openrazer/openrazer
8
+
9
+// Device target data 
10
+struct _impl_razer_data_t
11
+{
12
+    char brightness[NAME_MAX];
13
+    uint64_t max_brightness;
14
+};
15
+
16
+typedef struct _impl_razer_data_t impl_razer_data_t;
17
+
18
+bool impl_razer_init(light_device_enumerator_t *enumerator);
19
+bool impl_razer_free(light_device_enumerator_t *enumerator);
20
+
21
+bool impl_razer_set(light_device_target_t *target, uint64_t in_value);
22
+bool impl_razer_get(light_device_target_t *target, uint64_t *out_value);
23
+bool impl_razer_getmax(light_device_target_t *target, uint64_t *out_value);
24
+bool impl_razer_command(light_device_target_t *target, char const *command_string);

+ 2
- 2
src/light.c View File

@@ -5,7 +5,7 @@
5 5
 // The different device implementations
6 6
 #include "impl/sysfs.h"
7 7
 #include "impl/util.h"
8
-//#include "impl/razer.h"
8
+#include "impl/razer.h"
9 9
 
10 10
 #include <stdlib.h> // malloc, free
11 11
 #include <string.h> // strstr
@@ -433,7 +433,7 @@ light_context_t* light_initialize(int argc, char **argv)
433 433
     // Create the built-in enumerators
434 434
     light_create_enumerator(new_ctx, "sysfs", &impl_sysfs_init, &impl_sysfs_free);
435 435
     light_create_enumerator(new_ctx, "util", &impl_util_init, &impl_util_free);
436
-    //light_create_enumerator(new_ctx, "razer", &impl_razer_init, &impl_razer_free);
436
+    light_create_enumerator(new_ctx, "razer", &impl_razer_init, &impl_razer_free);
437 437
 
438 438
     // This is where we would create enumerators from plugins as well
439 439
     // 1. Run the plugins get_name() function to get its name