kde-lockscreen-suspend-display/xdg/display/dpms.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;
}