/* * Based on xorg-xset * https://github.com/freedesktop/xorg-xset/blob/master/xset.c */ #include "dpms.h" #include #include #include #include #include #include #include int check_dpms_extension(Display* disp) { int err = 0; int dummy; if (DPMSQueryExtension(disp, &dummy, &dummy)) { if (!DPMSCapable(disp)) err = NOTDPMSCAPABLE; } else err = NODPMSEXTENSION; return err; } /* * status->state can result in: * - DPMSModeOn * - DPMSModeStandby * - DPMSModeSuspend * - DPMSModeOff * * anything else means unknown state */ int check_dpms_status(Display* disp, CARD16* state) { BOOL dpmsEnabled; int error = check_dpms_extension(disp); if (!error) { DPMSInfo(disp, state, &dpmsEnabled); if (!dpmsEnabled) return DPMSDISABLED; } else return error; return 0; } int is_display_on(const char* xDisplayName, bool* isOn) { Display* disp = XOpenDisplay(xDisplayName); if (disp == NULL) return BADDISPLAY; CARD16 state; int returnError = 0; int error = check_dpms_status(disp, &state); if (!error) { switch (state) { case DPMSModeOn: *isOn = true; break; case DPMSModeStandby: case DPMSModeSuspend: case DPMSModeOff: *isOn = false; break; default: returnError = UNKNOWNDPMSMODE; break; } } else if (error == DPMSDISABLED) *isOn = true; else if (error) returnError = error; XCloseDisplay(disp); return returnError; } /* * Citing the original xorg-xset: * * The calls to usleep below are necessary to * delay the actual DPMS mode setting briefly. * Without them, it's likely that the mode will be * set between the Down and Up key transitions, in * which case the Up transition may immediately * turn the display back on. */ int dpms_force_off(Display* disp) { int error = check_dpms_extension(disp); if (!error) { DPMSEnable(disp); usleep(100000); DPMSForceLevel(disp, DPMSModeOff); } return error; } int turn_display_off(const char* xDisplayName) { Display* disp = XOpenDisplay(xDisplayName); if (disp == NULL) return BADDISPLAY; int returnError = 0; int error = dpms_force_off(disp); if (error) returnError = error; XCloseDisplay(disp); return returnError; }