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

9

有没有一种方式可以通过编程(通过ioctl()等)或通过读取/sys、/proc或/dev中的文件来检查Linux控制台屏幕保护程序是否已经使屏幕变黑?

谢谢,祝好!

Günter

5个回答

10

好的,我检查了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");
            }
        }
    }
}

以防其他人需要,;-)


7
您可以使用设置了DISPLAYxset 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

谢谢,这个方法可以解决问题。虽然不是最优雅的解决方案,但检查输出中是否包含“显示器已开启|关闭”是有效的。 - Günter Obiltschnig
1
这很好,但它依赖于 X 服务器的可用性。如果你只有一个控制台(尽管这在今天很少见),它将无法工作。 - Gabe
在我的情况下还好。我正在运行一个全屏的Gtk-WebKit浏览器,它像漏斗一样泄漏内存,所以当屏幕关闭一段时间后,我可以安全地杀死并重新启动浏览器;-) 当然,如果一开始就没有这些泄漏,那就太好了... - Günter Obiltschnig
我想修复WebKitGTK+,但现在没有时间和资源...暂时只能使用一些不太正规的方法。 - Günter Obiltschnig

1

我使用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上。


0
我正在使用这个脚本来读取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}'");
?>

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接