Parcourir la source

Add light_context_mode enum and '-e' option for exponential light changing.

Alexander Lutsai il y a 4 ans
Parent
révision
07a62b97b8
2 fichiers modifiés avec 94 ajouts et 38 suppressions
  1. 84
    37
      src/light.c
  2. 10
    1
      src/light.h

+ 84
- 37
src/light.c Voir le fichier

@@ -16,7 +16,7 @@
16 16
 #include <inttypes.h> // PRIu64
17 17
 
18 18
 /* Static helper functions for this file only, prefix with _ */
19
-
19
+#include <math.h>
20 20
 
21 21
 static void _light_add_enumerator_device(light_device_enumerator_t *enumerator, light_device_t *new_device)
22 22
 {
@@ -146,8 +146,9 @@ static light_device_target_t* _light_find_target(light_device_t * dev, char cons
146 146
     return NULL;
147 147
 }
148 148
 
149
-static bool _light_raw_to_percent(light_device_target_t *target, uint64_t inraw, double *outpercent)
149
+static bool _light_raw_to_percent(light_context_t *ctx, uint64_t inraw, double *outpercent)
150 150
 {
151
+        light_device_target_t *target = ctx->run_params.device_target;
151 152
         double inraw_d = (double)inraw;
152 153
         uint64_t max_value = 0;
153 154
         if(!target->get_max_value(target, &max_value))
@@ -156,14 +157,20 @@ static bool _light_raw_to_percent(light_device_target_t *target, uint64_t inraw,
156 157
             return false;
157 158
         }
158 159
         double max_value_d = (double)max_value;
159
-        double percent = light_percent_clamp((inraw_d / max_value_d) * 100.0);
160
-        *outpercent = percent;
160
+        double percent = 0;
161
+        if(ctx->run_params.mode == LC_MODE_EXPONENTIAL)
162
+            percent = pow((inraw_d / max_value_d), 1.0 / LIGHT_EXPONENT) * 100.0;
163
+        else
164
+            percent = (inraw_d / max_value_d) * 100.0;
165
+        
166
+        *outpercent = light_percent_clamp(percent);
161 167
         
162 168
         return true;
163 169
 }
164 170
 
165
-static bool _light_percent_to_raw(light_device_target_t *target, double inpercent, uint64_t *outraw)
171
+static bool _light_percent_to_raw(light_context_t *ctx, double inpercent, uint64_t *outraw)
166 172
 {
173
+    light_device_target_t *target = ctx->run_params.device_target;
167 174
     uint64_t max_value = 0;
168 175
     if(!target->get_max_value(target, &max_value))
169 176
     {
@@ -172,7 +179,11 @@ static bool _light_percent_to_raw(light_device_target_t *target, double inpercen
172 179
     }
173 180
 
174 181
     double max_value_d = (double)max_value;
175
-    double target_value_d = max_value_d * (light_percent_clamp(inpercent) / 100.0);
182
+    double target_value_d = 0;
183
+    if(ctx->run_params.mode == LC_MODE_EXPONENTIAL)
184
+        target_value_d = max_value_d * pow(light_percent_clamp(inpercent) / 100.0, LIGHT_EXPONENT);
185
+    else
186
+        target_value_d = max_value_d * (light_percent_clamp(inpercent) / 100.0);
176 187
     uint64_t target_value = LIGHT_CLAMP((uint64_t)target_value_d, 0, max_value);
177 188
     *outraw = target_value;
178 189
     
@@ -203,6 +214,7 @@ static void _light_print_usage()
203 214
         "\n"
204 215
         "Options:\n"
205 216
         "  -r          Interpret input and output values in raw mode (ignored for -T)\n"
217
+        "  -e          Interpret input and output values in exponential mode (ignored for -r and -T)\n"
206 218
         "  -s          Specify device target path to use, use -L to list available\n"
207 219
         "  -v          Specify the verbosity level (default 0)\n"
208 220
         "                 0: Values only\n"
@@ -240,8 +252,8 @@ static bool _light_parse_arguments(light_context_t *ctx, int argc, char** argv)
240 252
     bool need_target = true; // default cmd is get brightness
241 253
     bool specified_target = false;
242 254
     snprintf(ctrl_name, sizeof(ctrl_name), "%s", "sysfs/backlight/auto");
243
-    
244
-    while((curr_arg = getopt(argc, argv, "HhVGSLMNPAUTOIv:s:r")) != -1)
255
+
256
+    while((curr_arg = getopt(argc, argv, "HhVGSLMNPAUTOIv:s:re")) != -1)
245 257
     {
246 258
         switch(curr_arg)
247 259
         {
@@ -269,7 +281,10 @@ static bool _light_parse_arguments(light_context_t *ctx, int argc, char** argv)
269 281
                 specified_target = true;
270 282
                 break;
271 283
             case 'r':
272
-                ctx->run_params.raw_mode = true;
284
+                ctx->run_params.mode = LC_MODE_RAW;
285
+                break;
286
+            case 'e':
287
+                ctx->run_params.mode = LC_MODE_EXPONENTIAL;
273 288
                 break;
274 289
             
275 290
             // Commands
@@ -317,6 +332,7 @@ static bool _light_parse_arguments(light_context_t *ctx, int argc, char** argv)
317 332
                 break;
318 333
             case 'T':
319 334
                 _light_set_context_command(ctx, light_cmd_mul_brightness);
335
+                ctx->run_params.mode = LC_MODE_PERCENTAGE;
320 336
                 need_target = true;
321 337
                 need_float_value = true;
322 338
                 break;
@@ -368,7 +384,7 @@ static bool _light_parse_arguments(light_context_t *ctx, int argc, char** argv)
368 384
 
369 385
     if(need_value)
370 386
     {
371
-        if(ctx->run_params.raw_mode)
387
+        if(ctx->run_params.mode == LC_MODE_RAW)
372 388
         {
373 389
             if(sscanf(argv[optind], "%lu", &ctx->run_params.value) != 1)
374 390
             {
@@ -387,16 +403,8 @@ static bool _light_parse_arguments(light_context_t *ctx, int argc, char** argv)
387 403
                 return false;
388 404
             }
389 405
             
390
-            percent_value = light_percent_clamp(percent_value);
391
-            
392
-            uint64_t raw_value = 0;
393
-            if(!_light_percent_to_raw(ctx->run_params.device_target, percent_value, &raw_value))
394
-            {
395
-                LIGHT_ERR("failed to convert from percent to raw for device target");
396
-                return false;
397
-            }
398
-            
399
-            ctx->run_params.value = raw_value;
406
+            percent_value = light_percent_clamp(percent_value);                        
407
+            need_float_value = true;
400 408
         }
401 409
     }
402 410
 
@@ -429,7 +437,7 @@ light_context_t* light_initialize(int argc, char **argv)
429 437
     new_ctx->run_params.command = NULL;
430 438
     new_ctx->run_params.device_target = NULL;
431 439
     new_ctx->run_params.value = 0;
432
-    new_ctx->run_params.raw_mode = false;
440
+    new_ctx->run_params.mode = LC_MODE_PERCENTAGE;
433 441
 
434 442
     uid_t uid = getuid();
435 443
     uid_t euid = geteuid();
@@ -754,14 +762,14 @@ bool light_cmd_get_brightness(light_context_t *ctx)
754 762
         return false;
755 763
     }
756 764
     
757
-    if(ctx->run_params.raw_mode)
765
+    if(ctx->run_params.mode == LC_MODE_RAW)
758 766
     {
759 767
         printf("%" PRIu64 "\n", value);
760 768
     }
761 769
     else 
762 770
     {
763 771
         double percent = 0.0;
764
-        if(!_light_raw_to_percent(target, value, &percent))
772
+        if(!_light_raw_to_percent(ctx, value, &percent))
765 773
         {
766 774
             LIGHT_ERR("failed to convert from raw to percent from device target");
767 775
             return false;
@@ -781,7 +789,8 @@ bool light_cmd_get_max_brightness(light_context_t *ctx)
781 789
         return false;
782 790
     }
783 791
     
784
-    if(!ctx->run_params.raw_mode)
792
+    if(ctx->run_params.mode == LC_MODE_PERCENTAGE ||
793
+       ctx->run_params.mode == LC_MODE_EXPONENTIAL)
785 794
     {
786 795
         printf("100.0\n");
787 796
         return true;
@@ -831,7 +840,7 @@ bool light_cmd_get_min_brightness(light_context_t *ctx)
831 840
     uint64_t minimum_value = 0;
832 841
     if(!light_file_read_uint64(target_path, &minimum_value))
833 842
     {
834
-        if(ctx->run_params.raw_mode)
843
+        if(ctx->run_params.mode == LC_MODE_RAW)
835 844
         {
836 845
             printf("0\n");
837 846
         }
@@ -843,14 +852,14 @@ bool light_cmd_get_min_brightness(light_context_t *ctx)
843 852
         return true;
844 853
     }
845 854
     
846
-    if(ctx->run_params.raw_mode)
855
+    if(ctx->run_params.mode == LC_MODE_RAW)
847 856
     {
848 857
         printf("%" PRIu64 "\n", minimum_value);
849 858
     }
850 859
     else 
851 860
     {
852 861
         double minimum_d = 0.0;
853
-        if(!_light_raw_to_percent(ctx->run_params.device_target, minimum_value, &minimum_d))
862
+        if(!_light_raw_to_percent(ctx, minimum_value, &minimum_d))
854 863
         {
855 864
             LIGHT_ERR("failed to convert value from raw to percent for device target");
856 865
             return false;
@@ -884,16 +893,35 @@ bool light_cmd_add_brightness(light_context_t *ctx)
884 893
         LIGHT_ERR("failed to read from target");
885 894
         return false;
886 895
     }
896
+
897
+    double percent = 0.0;
887 898
     
888
-    value += ctx->run_params.value;
899
+    switch(ctx->run_params.mode)
900
+    {
901
+    case LC_MODE_RAW:    
902
+        value += ctx->run_params.value;
903
+        break;
904
+    case LC_MODE_PERCENTAGE:
905
+    case LC_MODE_EXPONENTIAL:
906
+        if(!_light_raw_to_percent(ctx, value, &percent))
907
+        {
908
+            LIGHT_ERR("failed to convert value from raw to percent for device target");
909
+            return false;
910
+        }
911
+        percent += ctx->run_params.float_value;
912
+        if(!_light_percent_to_raw(ctx, percent, &value))
913
+        {
914
+            LIGHT_ERR("failed to convert value from percent to raw for device target");
915
+            return false;
916
+        }        
917
+        break;
918
+    }
889 919
     
890 920
     uint64_t mincap = _light_get_min_cap(ctx);
891 921
     if(mincap > value)
892 922
     {
893 923
         value = mincap;
894 924
     }
895
-    
896
-    
897 925
     if(value > max_value)
898 926
     {
899 927
         value = max_value;
@@ -904,7 +932,6 @@ bool light_cmd_add_brightness(light_context_t *ctx)
904 932
         LIGHT_ERR("failed to write to target");
905 933
         return false;
906 934
     }
907
-    
908 935
     return true;
909 936
 }
910 937
 
@@ -923,14 +950,34 @@ bool light_cmd_sub_brightness(light_context_t *ctx)
923 950
         LIGHT_ERR("failed to read from target");
924 951
         return false;
925 952
     }
953
+
954
+    double percent = 0.0;
926 955
     
927
-    if(value > ctx->run_params.value)
928
-    {
929
-        value -= ctx->run_params.value;
930
-    }
931
-    else 
956
+    switch(ctx->run_params.mode)
932 957
     {
933
-        value = 0;
958
+    case LC_MODE_RAW:
959
+        if(value > ctx->run_params.value)
960
+            value -= ctx->run_params.value;
961
+        else 
962
+            value = 0;
963
+        break;
964
+    case LC_MODE_PERCENTAGE:
965
+    case LC_MODE_EXPONENTIAL:
966
+        if(!_light_raw_to_percent(ctx, value, &percent))
967
+        {
968
+            LIGHT_ERR("failed to convert value from raw to percent for device target");
969
+            return false;
970
+        }
971
+        if(percent > ctx->run_params.float_value)
972
+            percent -= ctx->run_params.float_value;
973
+        else
974
+            percent = 0;
975
+        if(!_light_percent_to_raw(ctx, percent, &value))
976
+        {
977
+            LIGHT_ERR("failed to convert value from percent to raw for device target");
978
+            return false;
979
+        }        
980
+        break;
934 981
     }
935 982
     
936 983
     uint64_t mincap = _light_get_min_cap(ctx);

+ 10
- 1
src/light.h Voir le fichier

@@ -26,6 +26,9 @@ typedef bool (*LFUNCVALGET)(light_device_target_t*, uint64_t*);
26 26
 typedef bool (*LFUNCMAXVALGET)(light_device_target_t*, uint64_t*);
27 27
 typedef bool (*LFUNCCUSTOMCMD)(light_device_target_t*, char const *);
28 28
 
29
+/* Constant for exponential mode */
30
+#define LIGHT_EXPONENT 4.0
31
+
29 32
 /* Describes a target within a device (for example a led on a keyboard, or a controller for a backlight) */
30 33
 struct _light_device_target_t
31 34
 {
@@ -68,6 +71,12 @@ typedef struct _light_context_t light_context_t;
68 71
 // A command that can be run (set, get, add, subtract, print help, print version, list devices etc.)
69 72
 typedef bool (*LFUNCCOMMAND)(light_context_t *);
70 73
 
74
+typedef enum _light_context_mode {
75
+    LC_MODE_PERCENTAGE,
76
+    LC_MODE_RAW,
77
+    LC_MODE_EXPONENTIAL
78
+} light_context_mode;
79
+
71 80
 struct _light_context_t
72 81
 {
73 82
     struct 
@@ -76,7 +85,7 @@ struct _light_context_t
76 85
         // Only one of value and raw_value is populated; which one depends on the command
77 86
         uint64_t                value; // The input value, in raw mode
78 87
         float                   float_value; // The input value as a float
79
-        bool                    raw_mode; // Whether or not we use raw or percentage mode
88
+        light_context_mode      mode; // Whether or not we use raw, exponential or percentage mode
80 89
         light_device_target_t   *device_target; // The device target to act on
81 90
     } run_params;
82 91