Detecting If a Screen is Turned off in Linux


I occasionally write utilities for my computer that make my life a bit easier. This morning I was looking for a way to detect whether the monitor was turned off on my Linux laptop. The best advice I came across was using xset -q and parsing the following section:

DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Enabled
  Monitor is On

Wait, what? After diving into some C code, it turns out that this can be very simply done with a bit of dotnet core code:

namespace Laptop {
    class Display {
        [DllImport("libX11")]
        private static extern IntPtr XOpenDisplay(string displayName);

        [DllImport("libX11")]
        private static extern void XCloseDisplay(IntPtr display);

        [DllImport("libXext.so.6")]
        private static extern bool DPMSQueryExtension(IntPtr display, out string dummy1, out string dummy2);

        [DllImport("libXext.so.6")]
        private static extern bool DPMSCapable(IntPtr display);

        [DllImport("libXext.so.6")]
        private static extern void DPMSInfo(IntPtr display, out State state, out bool onOff);

        public State IsOn(string displayAddress = ":0")
        {
            // get a handle to the display, but don't forget to close it!
            var display = XOpenDisplay(displayAddress);
            if (display == IntPtr.Zero)
            {
                return State.Fail; // return 
            }

            var reading = State.Fail;
             
            // attempt to read the state from the display
            if (DPMSQueryExtension(display, out var dummy1, out var dummy2))
                if (DPMSCapable(display))
                {
                    DPMSInfo(display, out var state, out var onOff);

                    if (onOff) reading = state;
                }

            // close our handle to the display
            XCloseDisplay(display);
            return reading;
        }

        public enum State
        {
            Fail = -1,
            On = 0,
            Standby = 1,
            Suspend = 2,
            Off = 3,
        }
    }
}

And bam, we can get the display state with Display.IsOn().


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.