162 lines
4.7 KiB
Rust
162 lines
4.7 KiB
Rust
#![allow(dead_code)]
|
|
use std::ffi::CStr;
|
|
|
|
use x11::dpms::{
|
|
DPMSCapable, DPMSDisable, DPMSEnable, DPMSForceLevel, DPMSGetTimeouts,
|
|
DPMSInfo, DPMSQueryExtension,
|
|
};
|
|
use x11::dpms::{DPMSModeOff, DPMSModeOn, DPMSModeStandby, DPMSModeSuspend};
|
|
use x11::xlib::{XCloseDisplay, XDisplayName, XOpenDisplay, _XDisplay};
|
|
use x11::xmd::{BOOL, CARD16};
|
|
|
|
/// Error returned if connecting to the X server fails
|
|
#[derive(Debug)]
|
|
pub struct OpenDisplayError;
|
|
|
|
/// Wrapper for an X display pointer
|
|
pub struct Display {
|
|
display: *mut _XDisplay,
|
|
}
|
|
|
|
impl Display {
|
|
/// Open a connection to the X server
|
|
///
|
|
/// If the connection succeeds, a [`Display`] is returned. Otherwise, an
|
|
/// [`OpenDisplayError`] is returned.
|
|
pub fn open() -> Result<Self, OpenDisplayError> {
|
|
let display = unsafe { XOpenDisplay(std::ptr::null()) };
|
|
if display.is_null() {
|
|
Err(OpenDisplayError)
|
|
} else {
|
|
Ok(Self { display })
|
|
}
|
|
}
|
|
|
|
/// Return the name of the X server display
|
|
///
|
|
/// If the display name cannot be determined, an empty string is returned.
|
|
pub fn name() -> String {
|
|
let name = unsafe { CStr::from_ptr(XDisplayName(std::ptr::null())) };
|
|
let name = name.to_str().unwrap_or("");
|
|
String::from(name)
|
|
}
|
|
}
|
|
|
|
impl Drop for Display {
|
|
fn drop(&mut self) {
|
|
unsafe { XCloseDisplay(self.display) };
|
|
}
|
|
}
|
|
|
|
/// DPMS Power Level
|
|
///
|
|
/// There are four power levels specified by the Video Electronics Standards
|
|
/// Association (VESA) Display Power Management Signaling (DPMS) standard.
|
|
/// These are mapped onto the X DPMS Extension
|
|
#[derive(PartialEq)]
|
|
pub enum DpmsPowerLevel {
|
|
/// In use
|
|
On = DPMSModeOn as isize,
|
|
/// Blanked, low power
|
|
Standby = DPMSModeStandby as isize,
|
|
/// Blanked, lower power
|
|
Suspend = DPMSModeSuspend as isize,
|
|
/// Shut off, awaiting activity
|
|
Off = DPMSModeOff as isize,
|
|
Unknown = -1,
|
|
}
|
|
|
|
impl From<u16> for DpmsPowerLevel {
|
|
fn from(v: u16) -> Self {
|
|
#[allow(non_snake_case)]
|
|
match v {
|
|
x if x == DpmsPowerLevel::On as u16 => Self::On,
|
|
x if x == DpmsPowerLevel::Standby as u16 => Self::Standby,
|
|
x if x == DpmsPowerLevel::Suspend as u16 => Self::Suspend,
|
|
x if x == DpmsPowerLevel::Off as u16 => Self::Off,
|
|
_ => Self::Unknown,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Result from [`get_info`] function (`DPMSInfo`)
|
|
pub struct DpmsInfo {
|
|
/// Current power level
|
|
pub power_level: DpmsPowerLevel,
|
|
/// DPMS enabled/disabled state
|
|
pub state: bool,
|
|
}
|
|
|
|
/// Result from [`get_timeouts`] function (`DPMSGetTimeouts`)
|
|
pub struct DpmsTimeouts {
|
|
/// Amount of time of inactivity in seconds before standby mode is invoked
|
|
pub standby: u16,
|
|
/// Amount of time of inactivity in seconds before the second level of power
|
|
/// savings is invoked
|
|
pub suspend: u16,
|
|
/// Amount of time of inactivity in seconds before the third and final level
|
|
/// of power savings is invoked
|
|
pub off: u16,
|
|
}
|
|
|
|
/// Queries the X server to determine the availability of the DPMS Extension
|
|
pub fn query_extension(display: &Display) -> bool {
|
|
let mut event_base = 0;
|
|
let mut error_base = 0;
|
|
let r = unsafe {
|
|
DPMSQueryExtension(display.display, &mut event_base, &mut error_base)
|
|
};
|
|
r != 0
|
|
}
|
|
|
|
/// Returns the DPMS capability of the X server, either TRUE (capable of DPMS)
|
|
/// or FALSE (incapable of DPMS)
|
|
pub fn dpms_capable(display: &Display) -> bool {
|
|
let r = unsafe { DPMSCapable(display.display) };
|
|
r != 0
|
|
}
|
|
|
|
/// Returns information about the current DPMS state
|
|
pub fn get_info(display: &Display) -> DpmsInfo {
|
|
let mut power_level: CARD16 = 0;
|
|
let mut state: BOOL = 0;
|
|
unsafe { DPMSInfo(display.display, &mut power_level, &mut state) };
|
|
DpmsInfo {
|
|
power_level: power_level.into(),
|
|
state: state != 0,
|
|
}
|
|
}
|
|
|
|
/// Retrieves the timeout values used by the X server for DPMS timings
|
|
pub fn get_timeouts(display: &Display) -> DpmsTimeouts {
|
|
let mut standby: CARD16 = 0;
|
|
let mut suspend: CARD16 = 0;
|
|
let mut off: CARD16 = 0;
|
|
unsafe {
|
|
DPMSGetTimeouts(display.display, &mut standby, &mut suspend, &mut off)
|
|
};
|
|
DpmsTimeouts {
|
|
standby,
|
|
suspend,
|
|
off,
|
|
}
|
|
}
|
|
|
|
/// Forces a DPMS capable display into the specified power level
|
|
pub fn force_level(display: &Display, level: DpmsPowerLevel) -> bool {
|
|
let r = unsafe { DPMSForceLevel(display.display, level as u16) };
|
|
r != 0
|
|
}
|
|
|
|
/// Enables DPMS on the specified display
|
|
pub fn enable(display: &Display) -> bool {
|
|
let r = unsafe { DPMSEnable(display.display) };
|
|
r != 0
|
|
}
|
|
|
|
/// Disables DPMS on the specified display
|
|
pub fn disable(display: &Display) -> bool {
|
|
let r = unsafe { DPMSDisable(display.display) };
|
|
r != 0
|
|
}
|