#define _GNU_SOURCE #include #include #include #include #include #include typedef enum LBOOL{ TRUE = 0, FALSE = 1 } LBOOL; typedef enum LOPTYPE{ SET = 0, ADD = 1, SUB = 2 } LOPTYPE; /* Flags */ LBOOL q; /* Quiet, supresses output */ LBOOL c; /* print unprecise current value in percentage */ LBOOL m; /* read max value*/ LBOOL p; /* precision read current value */ int wbright; LOPTYPE ot; LBOOL readint(const char* f, unsigned int *i){ FILE* ff = fopen(f, "r"); if(ff){ fscanf(ff, "%u", i); fclose(ff); return TRUE; }else{ return FALSE; } } LBOOL writeint(const char* f, unsigned int i){ FILE* ff = fopen(f, "w"); if(ff){ fprintf(ff, "%u", i); fclose(ff); return TRUE; }else{ return FALSE; } } LBOOL is_dir(const char* d){ DIR* dd = opendir(d); if(dd){ closedir(dd); return TRUE; }else{ return FALSE; } } LBOOL is_writable(const char* f){ FILE* dd = fopen(f, "w"); if(dd){ fclose(dd); return TRUE; }else{ return FALSE; } } typedef struct { char* name; unsigned int current_brightness; unsigned int max_brightness; char* c_path; /* Controller-path */ char* cb_path; /* Current brightness-path */ char* mb_path; /* Max brightness-path */ char* b_path; /* Brightness-path */ enum LBOOL is_ok; } controller; typedef struct { controller controllers[256]; unsigned int num_controllers; } fetch_result; fetch_result fetch_controllers(const char* ctrldir){ fetch_result returner; struct dirent* ep; DIR* lcdir = opendir(ctrldir); returner.num_controllers = 0; if(!lcdir){ if(q == FALSE) printf("Error: Could not open directory '%s'!\n", ctrldir); }else{ while( ( ep = readdir(lcdir) ) ){ char* currctrldir = ""; char* currctrldir_curr = ""; char* currctrldir_max = ""; char* currctrldir_f = ""; if( ep->d_name[0] != '.'){ returner.controllers[returner.num_controllers].name = ep->d_name; /* Set some default values, in case something fails we dont just get null */ returner.controllers[returner.num_controllers].current_brightness = 0; returner.controllers[returner.num_controllers].max_brightness = 0; returner.controllers[returner.num_controllers].is_ok = TRUE; returner.controllers[returner.num_controllers].c_path = NULL; returner.controllers[returner.num_controllers].cb_path = NULL; returner.controllers[returner.num_controllers].b_path = NULL; returner.controllers[returner.num_controllers].mb_path = NULL; /* Get path to the current controller dir */ asprintf(&currctrldir, "%s/%s", ctrldir, ep->d_name); returner.controllers[returner.num_controllers].c_path = currctrldir; if(is_dir(currctrldir) == FALSE){ if(q == FALSE) printf("Warning: '%s' is not a directory, check your system.\n", currctrldir); returner.controllers[returner.num_controllers].is_ok = FALSE; } /* Get path to current actual_brightness-file */ asprintf(&currctrldir_curr, "%s/%s", currctrldir, "actual_brightness"); returner.controllers[returner.num_controllers].cb_path = currctrldir_curr; if( readint(currctrldir_curr, &returner.controllers[returner.num_controllers].current_brightness) == FALSE ){ if(q == FALSE) printf("Warning: Can't read actual_brightness-file of '%s'. Will ignore this controller.\n", ep->d_name); returner.controllers[returner.num_controllers].is_ok = FALSE; } /* Get path to current max_brightness-file*/ asprintf(&currctrldir_max, "%s/%s", currctrldir, "max_brightness"); returner.controllers[returner.num_controllers].mb_path = currctrldir_max; if( readint(currctrldir_max, &returner.controllers[returner.num_controllers].max_brightness) == FALSE ){ if(q == FALSE) printf("Warning: Can't read max_brightness-file of '%s'. Will ignore this controller.\n", ep->d_name); returner.controllers[returner.num_controllers].is_ok = FALSE; } /* Get path to current brightness-file */ asprintf(&currctrldir_f, "%s/%s", currctrldir, "brightness"); returner.controllers[returner.num_controllers].b_path = currctrldir_f; if( is_writable(currctrldir_f) == FALSE){ if(q == FALSE) printf("Warning: Controllerfile of '%s' is not writable. Will ignore this controller.\n", ep->d_name); returner.controllers[returner.num_controllers].is_ok = FALSE; } returner.num_controllers++; } } closedir(lcdir); } return returner; } controller* get_best_controller(fetch_result* res){ unsigned int it; unsigned int cmax; LBOOL foundokctrl; controller* returner; it = 0; cmax = 0; foundokctrl = FALSE; returner = NULL; while(it < res->num_controllers){ if(res->controllers[it].is_ok == TRUE){ if(foundokctrl != TRUE){ foundokctrl = TRUE; returner = &res->controllers[it]; } if(res->controllers[it].max_brightness > cmax){ cmax = res->controllers[it].max_brightness; returner = &res->controllers[it]; } } it++; } return returner; } void usage(){ printf("Usage: light [-qcas] \n\n\t-q:\t Run quiet, supresses output.\n\t-c:\t Prints the current brightness in percent and exits.(Not precise)\n\t-p:\t Prints the current brightness directly from controller and exits. (Precise)\n\t-m:\t Prints the max brightness directly from controller and exits. (To be used side-by-side with -p)\n\t-a:\t Add the value instead of setting it.\n\t-s:\t Subtract the value instead of setting it.\n\n\t\t Brightness wanted in percent.\n\n"); } int main(int argc, char **argv) { unsigned int argsit; fetch_result res; controller* best_ctrl; unsigned int citr; uid_t uid; unsigned int minlight; LBOOL given; unsigned int real_wbright; unsigned int minlight_nonp; unsigned int curr_bright; unsigned int curr_brightp; /* Get UID */ uid = getuid(); /* Parse arguments */ q=FALSE; c=FALSE; m=FALSE; p=FALSE; ot=SET; wbright=0; argsit = 1; given=FALSE; while(argsit < argc){ char* carg = argv[argsit]; if(carg[0] == '-'){ unsigned int cargit = 1; while(cargit < strlen(carg)){ switch(carg[cargit]){ case 'q': q = TRUE; break; case 'a': ot = ADD; break; case 's': ot = SUB; break; case 'c': c = TRUE; break; case 'p': p = TRUE; break; case 'm': m = TRUE; break; default: break; } cargit++; } }else{ wbright = atoi(carg); given=TRUE; } argsit++; } if(c == TRUE || m == TRUE || p == TRUE){ q = TRUE; } if(given == FALSE && c == FALSE && m == FALSE && p == FALSE){ usage(); return 0; } if(q == FALSE) printf("Light v0.4 - Fredrik Haikarainen\n"); /* Get and check minlight */ if(readint("/etc/light/minlight", &minlight) == FALSE){ minlight = 5; if(q == FALSE) printf("Warning: Couldn't read /etc/light/minlight, using 5 as default.\n"); } /* Fetch controllers */ if(q == FALSE) printf("Fetching controllers..\n"); res = fetch_controllers("/sys/class/backlight"); citr = 0; while(citr < res.num_controllers){ controller* currc = &res.controllers[citr]; if(currc->is_ok == TRUE){ if(q == FALSE) printf("\tFound '%s' (%u/%u)\n", currc->name, currc->current_brightness, currc->max_brightness); }else{ if(q == FALSE) printf("\tFound '%s', but ignoring\n", currc->name); } citr++; } if(q == FALSE) printf("\n"); /* Get the best controller */ best_ctrl = get_best_controller(&res); if(best_ctrl == NULL){ if(uid == 0){ if(q == FALSE) printf("No okay controller found, even though you are root! Check your system.\n"); }else{ if(q == FALSE) printf("No okay controller found, check your permissions or try to run as root.\n"); } return 1; } if(p == TRUE){ printf("%u\n", best_ctrl->current_brightness); return 0; } if(m == TRUE){ printf("%u\n", best_ctrl->max_brightness); return 0; } if(q == FALSE) printf("Using controller '%s' ..\n", best_ctrl->name); if(wbright < 0){ wbright = 0;} if(wbright > 100){wbright=100;} curr_bright = best_ctrl->current_brightness; curr_brightp = (float)((float)curr_bright / (float)best_ctrl->max_brightness) * 100; if(c == TRUE){ printf("%u\n", curr_brightp); return 0; } switch(ot){ case SET: real_wbright = best_ctrl->max_brightness * ( (float)wbright / 100 ); break; case ADD: real_wbright = ( best_ctrl->max_brightness * ( (float)( curr_brightp + wbright +1) / 100 )); break; case SUB: real_wbright = ( best_ctrl->max_brightness * ( (float)( curr_brightp - wbright + 1) / 100 )); break; default: break; } minlight_nonp = best_ctrl->max_brightness * ( (float)minlight / 100); /* FIXME Line below makes sure the value never wraps around and gets higher. Puts a (high) limit on max brightness. Not sure if safe for portabilities sake. */ if(real_wbright > ((UINT_MAX/2) - best_ctrl->max_brightness)){ real_wbright = minlight_nonp; } if(real_wbright > best_ctrl->max_brightness){real_wbright = best_ctrl->max_brightness;} if(real_wbright < minlight_nonp){real_wbright = minlight_nonp;} if(q == FALSE) printf("Writing %u to file '%s'..\n", real_wbright, best_ctrl->b_path); if(writeint(best_ctrl->b_path, real_wbright) == FALSE){ if(q == FALSE){ printf("Error: Could not write to file %s, check your permissions!\n", best_ctrl->b_path); } return 1; } return 0; }