如何检查 Linux 控制台屏幕保护程序是否黑屏

发布于 2024-09-25 12:03:19 字数 119 浏览 5 评论 0原文

有没有办法以编程方式(通过 ioctl() 等)或通过读取 /sys、/proc 或 /dev 中的文件)检查屏幕是否已被 Linux 控制台屏幕保护程序清空?

谢谢并致以最诚挚的问候,

冈特

is there a way to check programmatically (via ioctl(), etc.) or by reading a file in /sys, /proc or /dev) whether the screen has been blanked by the Linux console screensaver?

Thanks and best regards,

Günter

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

玻璃人 2024-10-02 12:03:19

好的,检查了 xset 源代码。相关的代码部分是

#include <X11/extensions/dpms.h>
...
Display* dpy = XOpenDisplay(NULL);
...
int dummy;
CARD16 standby, suspend, off;
BOOL onoff;
CARD16 state;

printf("DPMS (Energy Star):\n");
if (DPMSQueryExtension(dpy, &dummy, &dummy)) 
{
    if (DPMSCapable(dpy)) 
    {
        DPMSGetTimeouts(dpy, &standby, &suspend, &off);
        printf ("  Standby: %d    Suspend: %d    Off: %d\n",
                standby, suspend, off);
        DPMSInfo(dpy, &state, &onoff);
        if (onoff) 
        {
            printf("  DPMS is Enabled\n");
            switch (state) 
            {
            case DPMSModeOn:
                printf("  Monitor is On\n");
                break;
            case DPMSModeStandby:
                printf("  Monitor is in Standby\n");
                break;
            case DPMSModeSuspend:
                printf("  Monitor is in Suspend\n");
                break;
            case DPMSModeOff:
                printf("  Monitor is Off\n");
                break;
            default:
                printf("  Unrecognized response from server\n");
            }
        }
    }
}

为了以防万一其他人需要这个;-)

Okay, checked the xset source code. The relevant code parts are

#include <X11/extensions/dpms.h>
...
Display* dpy = XOpenDisplay(NULL);
...
int dummy;
CARD16 standby, suspend, off;
BOOL onoff;
CARD16 state;

printf("DPMS (Energy Star):\n");
if (DPMSQueryExtension(dpy, &dummy, &dummy)) 
{
    if (DPMSCapable(dpy)) 
    {
        DPMSGetTimeouts(dpy, &standby, &suspend, &off);
        printf ("  Standby: %d    Suspend: %d    Off: %d\n",
                standby, suspend, off);
        DPMSInfo(dpy, &state, &onoff);
        if (onoff) 
        {
            printf("  DPMS is Enabled\n");
            switch (state) 
            {
            case DPMSModeOn:
                printf("  Monitor is On\n");
                break;
            case DPMSModeStandby:
                printf("  Monitor is in Standby\n");
                break;
            case DPMSModeSuspend:
                printf("  Monitor is in Suspend\n");
                break;
            case DPMSModeOff:
                printf("  Monitor is Off\n");
                break;
            default:
                printf("  Unrecognized response from server\n");
            }
        }
    }
}

Just in case anyone else needs this ;-)

宣告ˉ结束 2024-10-02 12:03:19

您可以使用 DISPLAY 设置来解析 xset q 的输出,但这并不漂亮。

$ xset q
Keyboard Control:
  auto repeat:  on    key click percent:  0    LED mask:  00000000
  XKB indicators:
    00: Caps Lock:   off    01: Num Lock:    off    02: Scroll Lock: off
    03: Compose:     off    04: Kana:        off    05: Sleep:       off
    06: Suspend:     off    07: Mute:        off    08: Misc:        off
    09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
    12: Group 2:     off    13: Mouse Keys:  off
  auto repeat delay:  250    repeat rate:  30
  auto repeating keys:  00ffffffdffffbbf
                        fadfffefffedffff
                        9fffffffffffffff
                        fff7ffffffffffff
  bell percent:  50    bell pitch:  400    bell duration:  100
Pointer Control:
  acceleration:  20/10    threshold:  4
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  0    cycle:  600
Colors:
  default colormap:  0x20    BlackPixel:  0    WhitePixel:  16777215
Font Path:
  /usr/share/fonts/misc,/usr/share/fonts/100dpi:unscaled,/usr/share/fonts/75dpi:unscaled,/usr/share/fonts/TTF,/usr/share/fonts/Type1,/usr/share/fonts/misc/,/usr/share/fonts/TTF/,/usr/share/fonts/Type1/,/usr/share/fonts/100dpi/,/usr/share/fonts/75dpi/,built-ins
DPMS (Energy Star):
  Standby: 1200    Suspend: 1800    Off: 0
  DPMS is Enabled
  Monitor is On
Font cache:
  Server does not have the FontCache Extension

You can parse the output of xset q with DISPLAY set, but it's not pretty.

$ xset q
Keyboard Control:
  auto repeat:  on    key click percent:  0    LED mask:  00000000
  XKB indicators:
    00: Caps Lock:   off    01: Num Lock:    off    02: Scroll Lock: off
    03: Compose:     off    04: Kana:        off    05: Sleep:       off
    06: Suspend:     off    07: Mute:        off    08: Misc:        off
    09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
    12: Group 2:     off    13: Mouse Keys:  off
  auto repeat delay:  250    repeat rate:  30
  auto repeating keys:  00ffffffdffffbbf
                        fadfffefffedffff
                        9fffffffffffffff
                        fff7ffffffffffff
  bell percent:  50    bell pitch:  400    bell duration:  100
Pointer Control:
  acceleration:  20/10    threshold:  4
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  0    cycle:  600
Colors:
  default colormap:  0x20    BlackPixel:  0    WhitePixel:  16777215
Font Path:
  /usr/share/fonts/misc,/usr/share/fonts/100dpi:unscaled,/usr/share/fonts/75dpi:unscaled,/usr/share/fonts/TTF,/usr/share/fonts/Type1,/usr/share/fonts/misc/,/usr/share/fonts/TTF/,/usr/share/fonts/Type1/,/usr/share/fonts/100dpi/,/usr/share/fonts/75dpi/,built-ins
DPMS (Energy Star):
  Standby: 1200    Suspend: 1800    Off: 0
  DPMS is Enabled
  Monitor is On
Font cache:
  Server does not have the FontCache Extension
绮筵 2024-10-02 12:03:19

我使用 ctypes 在 Python 中对 Günter 的代码进行了等效实现。

import ctypes
import struct

ctypes.cdll.LoadLibrary('libXext.so')
libXext = ctypes.CDLL('libXext.so')

DPMSFAIL = -1
DPMSModeOn = 0
DPMSModeStandby = 1
DPMSModeSuspend = 2
DPMSModeOff = 3


def get_DPMS_state(display_name_in_byte_string=b':0'):
    state = DPMSFAIL
    if not isinstance(display_name_in_byte_string, bytes):
        raise TypeError
    display_name = ctypes.c_char_p()
    display_name.value = display_name_in_byte_string
    libXext.XOpenDisplay.restype = ctypes.c_void_p
    display = ctypes.c_void_p(libXext.XOpenDisplay(display_name))
    dummy1_i_p = ctypes.create_string_buffer(8)
    dummy2_i_p = ctypes.create_string_buffer(8)
    if display.value:
        if libXext.DPMSQueryExtension(display, dummy1_i_p, dummy2_i_p)\
           and libXext.DPMSCapable(display):
            onoff_p = ctypes.create_string_buffer(1)
            state_p = ctypes.create_string_buffer(2)
            if libXext.DPMSInfo(display, state_p, onoff_p):
                onoff = struct.unpack('B', onoff_p.raw)[0]
                if onoff:
                    state = struct.unpack('H', state_p.raw)[0]
        libXext.XCloseDisplay(display)
    return state

调用示例位于我的github上。

I made an equivalent implementation of Günter's code in Python with ctypes.

import ctypes
import struct

ctypes.cdll.LoadLibrary('libXext.so')
libXext = ctypes.CDLL('libXext.so')

DPMSFAIL = -1
DPMSModeOn = 0
DPMSModeStandby = 1
DPMSModeSuspend = 2
DPMSModeOff = 3


def get_DPMS_state(display_name_in_byte_string=b':0'):
    state = DPMSFAIL
    if not isinstance(display_name_in_byte_string, bytes):
        raise TypeError
    display_name = ctypes.c_char_p()
    display_name.value = display_name_in_byte_string
    libXext.XOpenDisplay.restype = ctypes.c_void_p
    display = ctypes.c_void_p(libXext.XOpenDisplay(display_name))
    dummy1_i_p = ctypes.create_string_buffer(8)
    dummy2_i_p = ctypes.create_string_buffer(8)
    if display.value:
        if libXext.DPMSQueryExtension(display, dummy1_i_p, dummy2_i_p)\
           and libXext.DPMSCapable(display):
            onoff_p = ctypes.create_string_buffer(1)
            state_p = ctypes.create_string_buffer(2)
            if libXext.DPMSInfo(display, state_p, onoff_p):
                onoff = struct.unpack('B', onoff_p.raw)[0]
                if onoff:
                    state = struct.unpack('H', state_p.raw)[0]
        libXext.XCloseDisplay(display)
    return state

Calling sample is on my github.

一身骄傲 2024-10-02 12:03:19

我已经很久没有做过任何桌面开发了,但记忆告诉我,大多数 Linux 屏幕保护程序都是由 xscreensaver 执行的 - 可能会检查进程是否正在运行,或者检查其源代码以查看是否设置了任何系统状态,或者在项目邮件列表上询问会产生一些结果。
当然,KDE 和 Gnome 现在可能有单独的屏幕保护程序实现 - 不幸的是,Linux GUI 几乎没有统一性......

I haven't done any desktop development in ages, but memory tells me that most linux screensavers were being executed by xscreensaver - maybe checking whether the process is running, or going through its source-code to see for any system-state being set, or asking on the project maillist would yield some results.
Of course KDE and Gnome might have separate screensaver implementations by now - there is very little uniformity when it comes to linux GUIs, unfortunately...

筱果果 2024-10-02 12:03:19

我正在使用此脚本来读取 DPMS 信息。效果很好!它是用 PHP 编写的,但您可以看到它是如何工作的。

<?php
if ( !$pid = exec('pidof X') )
    return !trigger_error(E_USER_WARNING,'Could not find pid of X');

if ( !$data = file_get_contents("/proc/$pid/cmdline") )
    return !trigger_error(E_USER_WARNING,"Cound not read pid info (/proc/$pid/cmdline)");

$data = explode(chr(0),$data);
foreach($data as $key => $line) {
    if ( $line == "-auth" ) {
        $auth = $data[$key+1];
        break;
    }
}

if ( !isset($auth) )
    return !trigger_error(E_USER_WARNING,'Could not find XAUTHORITY in xinit process environment');

echo exec("export DISPLAY=:0; export XAUTHORITY={$auth}; export PATH=\${PATH}:/usr/X11R6/bin; xset -q | grep \"Monitor is\" | awk '{print $3}'");
?>

I'm using this script to read DPMS info. It works great! Its written in PHP, but you can see the idea how it works.

<?php
if ( !$pid = exec('pidof X') )
    return !trigger_error(E_USER_WARNING,'Could not find pid of X');

if ( !$data = file_get_contents("/proc/$pid/cmdline") )
    return !trigger_error(E_USER_WARNING,"Cound not read pid info (/proc/$pid/cmdline)");

$data = explode(chr(0),$data);
foreach($data as $key => $line) {
    if ( $line == "-auth" ) {
        $auth = $data[$key+1];
        break;
    }
}

if ( !isset($auth) )
    return !trigger_error(E_USER_WARNING,'Could not find XAUTHORITY in xinit process environment');

echo exec("export DISPLAY=:0; export XAUTHORITY={$auth}; export PATH=\${PATH}:/usr/X11R6/bin; xset -q | grep \"Monitor is\" | awk '{print $3}'");
?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文