title: Detect running screensaver with xlib
body: <p>I'm trying to detect wether a screensaver is running or not.</p>
  
  <p>Here's the code that I've got so far:</p>
  
  <pre><code>/* LDFLAGS='-L/usr/X11R6/lib/ -lX11 -lXext -lXss' make xidle */
  #include &lt;stdio.h&gt;
  #include &lt;X11/Xlib.h&gt;
  #include &lt;X11/Xutil.h&gt;
  #include &lt;X11/extensions/scrnsaver.h&gt;
  
  int
  main(int argc, char *argv[])
  {
      XScreenSaverInfo info;
      Display *dpy = XOpenDisplay(NULL);
  
      if(NULL == dpy) {
          fprintf(stderr, "failed to open display\n");
          return 1;
      }
  
      int a = 0;
      int b = 0;
      XScreenSaverQueryExtension(dpy, &amp;a, &amp;b);
      printf("%d %d\n", a, b);
  
      XScreenSaverQueryInfo(dpy, RootWindow(dpy, DefaultScreen(dpy)), &amp;info);
      printf("%d %d %d %d\n", info.state, info.til_or_since, info.idle, info.kind);
      return 0;
  }
  </code></pre>
  
  <p>But info.state is always 3 (ScreenSaverDisabled). I've tested this with xscreensaver and gnome-screensaver.</p>
  
  <p>Here is some example output:</p>
  
  <pre><code>92 0
  3 0 9903 0
  </code></pre>
  
  <p>It's the same with a running screensaver or without (except info.idle of course).</p>
  
  <p>Additional info:</p>
  
  <pre><code>$ X -version
  X.Org X Server 1.13.0
  Release Date: 2012-09-05
  X Protocol Version 11, Revision 0
  </code></pre>
  
  <p>Window Manager: i3</p>
  
  <p>Distribution: Arch Linux</p>
  
  <p>EDIT:
  With the help of [this][1] I've created an xcb version, which also doesn't work. To exclude errors in my testing procedure, here it is:
  I have this code running in an endless loop while I have xscreensaver running in the background. And to actually activate the screensaver I use xscreensaver-command --activate</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;xcb/xcb.h&gt;
  #include &lt;xcb/screensaver.h&gt;
  
  static xcb_connection_t * connection;
  static xcb_screen_t * screen;
  
  /**
   * Connects to the X server (via xcb) and gets the screen
   */
  void magic_begin () {
      connection = xcb_connect (NULL, NULL);
      screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
  }
  
  /**
   * Asks X for the time the user has been idle
   * @returns idle time in milliseconds
   */
  unsigned long magic_get_state () {
      xcb_screensaver_query_info_cookie_t cookie;
      xcb_screensaver_query_info_reply_t *info;
  
      cookie = xcb_screensaver_query_info (connection, screen-&gt;root);
      info = xcb_screensaver_query_info_reply (connection, cookie, NULL);
  
      int state = info-&gt;state;
  
      return state;
  }
  
  int main(int arc, char *argv[])
  {
      magic_begin();
      int state = magic_get_state();
      printf("state: %d\n", state);
  }
  
  
  [1]: http://stackoverflow.com/questions/9049087/with-x11-how-can-i-get-the-users-time-away-from-keyboard-while-ignoring-cert
  </code></pre>