int main(int argc, char* argv[]) { parse_options(argc, argv); // Daemonize, unless we're passed -d if(daemonize) { pid_t pid = fork(); if(pid < 0) { fprintf(stderr, "Fork failed with %d\n", pid); } else if(pid > 0) { return EXIT_SUCCESS; // child has forked off correctly, we terminate immediately. } } // we will be sent a USR1 by acpid when the power adapter is plugged/unplugged. at that point we reread its state. // this approach saves us from having to poll that every few seconds to see if it's changed // (one of the few places where it's practical to avoid polling) signal(SIGUSR1, refresh_adapter_state); XScreenSaverInfo* info = XScreenSaverAllocInfo(); info->idle = 0; // ensure this is initialised since we'll calculate on it shortly Display* display = XOpenDisplay(0); if(display == NULL) { fprintf(stderr, "Couldn't connect to X display\n"); return EXIT_FAILURE; } // do some initial updates to make sure everything's been read at first // this will set the initial brightness values for us as well refresh_adapter_state(); update_light_sensor(); // NB. ideally we would use select() or something to wait for the applesmc sysfs entry // to change, but it doesn't seem to work. Not sure that's possible on this kind of hardware sensor? while(1) { // we've just gone idle. wait in 2 second chunks to keep checking the light sensor int i; for(i = 0; i < time_before_dim * 1000 - info->idle; i += 2000) { sleep(2); update_light_sensor(); dprintf("Time until dimming planned to begin: %ld\n", time_before_dim - info->idle/1000 - i/1000); } // now check the idle time again XScreenSaverQueryInfo(display, DefaultRootWindow(display), info); if(info->idle < time_before_dim*1000) { // we must have been woken in between. go back to waiting. continue; } // here we have waited the requisite amount of time. dim the display. dprintf("Dimming display\n"); if(!continuous_dim_backlight(display, info)) { wait_for_event(display, info); } // once we get here, we are undimming because something's happened is_dimmed = 0; adjust_brightness(1.0); } }
void property_update(void *inContext) { int num = 0; app_context_t * app_context = (app_context_t*)inContext; while(1) { mico_thread_sleep(1); if(!app_context->appStatus.arrayentStatus.isCloudConnected){ continue; } switch(num) { case 0: update_dht11_sensor(); break; case 1: update_light_sensor(); break; case 2: update_infrared_sensor(); break; } num++; if(num == 3)num = 0; } }
void update_property(void *inContext){ int num = 0; while(1) { switch(num) { case 0: update_dht11_sensor(); break; case 1: update_light_sensor(); break; case 2: update_infrared_sensor(); break; } num++; if(num == 3)num = 0; } }
// Waits until the user moves mouse or presses a key void wait_for_event(Display* display, XScreenSaverInfo* info) { // waiting until something happens // currently just doing polling, not sure how possible it is to get notified of this event by X // it's not hard to get mouse/keyboard events for your window but I don't think you can get *any* such event // TODO: is there a different approach? could we hook into devices in /dev or something? may not be worth going down that rabbit hole though... struct timespec tm_remaining = { 0, 0 }; struct timespec half_second = { 0, 500000000 }; // this is about the longest period that still feels reasonably responsive when undimming the screen unsigned long last_idle; int locked_screen = 0; do { last_idle = info->idle; nanosleep(&half_second, &tm_remaining); XScreenSaverQueryInfo(display, DefaultRootWindow(display), info); update_light_sensor(); // now lock screen if we've gone over the threshold - but obviously only the first time // slimlock checks itself if it's already running, but we don't want to spawn new slimlock // processes every second if they're not going to do anything! if(!locked_screen && info->idle >= lock_delay_ms) { lock_screen(); locked_screen = 1; } } while(info->idle >= last_idle); }