【问题标题】:How to check if Linux console screensaver has blanked screen如何检查 Linux 控制台屏幕保护程序是否有空白屏幕
【发布时间】:2011-04-18 16:03:28
【问题描述】:

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

谢谢和最好的问候,

君特

【问题讨论】:

    标签: linux console screensaver


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      你可以通过设置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
      

      【讨论】:

      • 谢谢,这就行了。不是最优雅的解决方案,但检查“监视器打开|关闭”的输出是可行的。
      • 这很好,但它依赖于可用的 X 服务器。如果你只有一个控制台(诚然,这几天很少见),它就行不通。
      • 就我而言,这很好。我正在运行一个全屏 Gtk-WebKit 浏览器,它会像筛子一样泄漏内存,所以在屏幕关闭一段时间后,我可以安全地杀死并重新启动浏览器;-) 当然最好不要有这些泄漏首先...
      • 我会,但我没有时间和资源来修复 WebKitGTK+...现在,必须做一些肮脏的伎俩。
      【解决方案3】:

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

      #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");
                  }
              }
          }
      }
      

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          我在 Python 中使用 ctypes 对 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
          

          调用示例在my github

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-05-18
            • 1970-01-01
            • 1970-01-01
            • 2012-01-11
            • 1970-01-01
            • 2020-10-01
            • 2013-07-30
            • 2011-03-01
            相关资源
            最近更新 更多