131 lines
2.5 KiB
C
131 lines
2.5 KiB
C
/*
|
|
* Based on xorg-xset
|
|
* https://github.com/freedesktop/xorg-xset/blob/master/xset.c
|
|
*/
|
|
|
|
#include "dpms.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/extensions/dpms.h>
|
|
|
|
|
|
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;
|
|
}
|