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

Generated by cgit