summaryrefslogtreecommitdiff
path: root/src/main.c
blob: be7bd2938ce41b74c1afc9ef85f4960e9087e784 (plain)
    1 /**
    2  * Copyright (C) 2017 Aaron Ball <nullspoon@oper.io>
    3  *
    4  * Luminous is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 3 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * Luminous is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with noteless.  If not, see <http://www.gnu.org/licenses/>.
   16  */
   17 #include <stdio.h>
   18 #include <stdlib.h>
   19 #include <string.h>
   20 #include <time.h>
   21 #include <errno.h>
   22 
   23 
   24 struct props {
   25   int lvl;
   26   int step;
   27   int rate;
   28   int max;
   29   int cur;
   30   char filebrightness[512];
   31   char filemax_bright[512];
   32 };
   33 
   34 
   35 /**
   36  * fgeti:
   37  * @path
   38  *
   39  * Reads integer from the specified file. If the file does not contain only an
   40  * integer, returns -1.
   41  *
   42  * returns: Integer read from file, otherwise -1.
   43  */
   44 int fgeti(char* path) {
   45   FILE* fd;
   46   char buf[64];
   47 
   48   fd = fopen(path, "r");
   49   if(! fd)
   50     return -1;
   51 
   52   fgets(buf, 64, fd);
   53   fclose(fd);
   54   return atoi(buf);
   55 }
   56 
   57 
   58 /**
   59  * fadeup:
   60  * @props Props struct containing runtime parameters
   61  *
   62  * Fades brightness down, incremented by props->step every props->rate
   63  * milliseconds
   64  *
   65  * returns: Success (0) or failure (-1)
   66  */
   67 int fadeup(struct props* props) {
   68   struct timespec tim, tim2;
   69   int sec;  // Number of seconds to sleep
   70   int msec; // Number of milliseconds to sleep (less than 1 second)
   71 
   72   sec = props->rate / 1000;
   73   msec = props->rate - (sec * 1000);
   74 
   75   tim.tv_sec = sec;
   76   tim.tv_nsec = 1000000 * msec;
   77 
   78   while(props->cur < props->lvl) {
   79     nanosleep(&tim, &tim2);
   80 
   81     FILE* fd = fopen(props->filebrightness, "w");
   82     if(! fd) {
   83       if(errno == EACCES) {
   84         fprintf(stderr, "Permission denied: %s\n", props->filebrightness);
   85       } else {
   86         fprintf(stderr, "Could not open file %s\n", props->filebrightness);
   87       }
   88       return -1;
   89     }
   90 
   91     // Write the new brightness to the brightness file
   92     fprintf(fd, "%d\n", props->cur);
   93     fclose(fd);
   94 
   95     if(props->cur >= props->max)
   96       break;
   97     props->cur += props->step;
   98   }
   99   return 0;
  100 }
  101 
  102 
  103 /**
  104  * fadedown:
  105  * @props Props struct containing runtime parameters
  106  *
  107  * Fades brightness down, decremented by props->step every props->rate
  108  * milliseconds
  109  *
  110  * returns: Success (0) or failure (-1)
  111  */
  112 int fadedown(struct props* props) {
  113   struct timespec tim, tim2;
  114   int sec;  // Number of seconds to sleep
  115   int msec; // Number of milliseconds to sleep (less than 1 second)
  116 
  117   sec = props->rate / 1000;
  118   msec = props->rate - (sec * 1000);
  119 
  120   tim.tv_sec = sec;
  121   tim.tv_nsec = 1000000 * msec;
  122 
  123   while(props->cur > props->lvl) {
  124     nanosleep(&tim, &tim2);
  125 
  126     FILE* fd = fopen(props->filebrightness, "w");
  127     if(! fd) {
  128       if(errno == EACCES) {
  129         fprintf(stderr, "Permission denied: %s\n", props->filebrightness);
  130       } else {
  131         fprintf(stderr, "Could not open file %s\n", props->filebrightness);
  132       }
  133       return -1;
  134     }
  135 
  136     // Write the new brightness to the brightness file
  137     fprintf(fd, "%d\n", props->cur);
  138     fclose(fd);
  139 
  140     if(props->cur <= 0)
  141       break;
  142     props->cur -= props->step;
  143   }
  144   return 0;
  145 }
  146 
  147 
  148 /**
  149  * usage:
  150  *
  151  * Nothing to see here. Just the help text printer.
  152  */
  153 void usage() {
  154   printf(
  155 "Luminous is a backlight manager that supports fading the backlight at\n"
  156 "varying rates and steps. It manages backlight via the kenerl interfaces\n"
  157 "provided in /sys to adjust screen backlight levels. Consequently, it\n"
  158 "requires write access to the brightness property in \n"
  159 "/sys/class/backlight/<device>/brightness.\n"
  160 "\n"
  161 "Usage:\n"
  162 "  luminous --rate 10 --step 8 --level [+-]400\n"
  163 "\n"
  164 "Arguments:\n"
  165 "  -h,--help  Print this helptext\n"
  166 "  -s,--step  Fade step (default: 6)\n"
  167 "  -r,--rate  Time in milliseconds between fade steps (default: 10)\n"
  168 "  -l,--level Brightness level to change to. Supports absolute values and\n"
  169 "             relative values prefixed with + and -."
  170 "\n\n"
  171 );
  172 }
  173 
  174 
  175 /**
  176  * parseargs:
  177  * @out   Output properties struct
  178  * @argc  Number of arguments passed
  179  * @argv  Arguments char array
  180  *
  181  * Parses command line arguments into a props struct.
  182  *
  183  * returns: Success (0), failure (-1), or incomplete (-2)
  184  */
  185 int parseargs(struct props* out, int argc, char* argv[]) {
  186   int i = 0;
  187   
  188   strcpy(out->filebrightness,
  189          "/sys/class/backlight/intel_backlight/brightness");
  190   strcpy(out->filemax_bright,
  191          "/sys/class/backlight/intel_backlight/max_brightness");
  192 
  193   // Read the system values for current and maximum brightness
  194   out->cur = fgeti(out->filebrightness);
  195   out->max = fgeti(out->filemax_bright);
  196 
  197   // Some defaults
  198   out->rate = 10;
  199   out->step = 8;
  200 
  201   for(;i < argc; i++) {
  202     if(strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--rate") == 0) {
  203       i++;
  204       out->rate = atoi(argv[i]);
  205     } else if(strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--step") == 0) {
  206       i++;
  207       out->step = atoi(argv[i]);
  208     } else if(strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--level") == 0) {
  209       i++;
  210       // Account for relative and absolute increments and decrements
  211       if(argv[i][0] == '+') {
  212         out->lvl = out->cur + atoi(&argv[i][1]);
  213       } else if(argv[i][0] == '-') {
  214         out->lvl = out->cur - atoi(&argv[i][1]);
  215       } else {
  216         out->lvl = atoi(argv[i]);
  217       }
  218     } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
  219       usage();
  220       return -2;
  221     }
  222   }
  223 
  224   // Ensure min and max thresholds are respected
  225   if(out->lvl > out->max) {
  226     out->lvl = out->max;
  227   } else if(out->lvl < 0) {
  228     out->lvl = 0;
  229   }
  230   return 0;
  231 }
  232 
  233 
  234 /**
  235  * Ye olde main
  236  */
  237 int main(int argc, char* argv[]) {
  238   int r = 0;
  239   struct props p;
  240 
  241   if(parseargs(&p, argc, argv) != 0)
  242     return 1;
  243 
  244   if(argc == 1) {
  245     printf("%d\n", p.cur);
  246     return 0;
  247   }
  248 
  249   // Determine if we should fade up or fade down
  250   if(p.lvl > p.cur) {
  251     r = fadeup(&p);
  252   } else if (p.lvl < p.cur) {
  253     r = fadedown(&p);
  254   }
  255 
  256   if(r < 0) {
  257     fprintf(stderr, "ERROR: Could not open brightness file\n");
  258     return 1;
  259   }
  260   return 0;
  261 }

Generated by cgit