Search code examples
clinuxxlibscreensaver

Detect running screensaver with xlib


I'm trying to detect wether a screensaver is running or not.

Here's the code that I've got so far:

/* LDFLAGS='-L/usr/X11R6/lib/ -lX11 -lXext -lXss' make xidle */
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/scrnsaver.h>

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, &a, &b);
    printf("%d %d\n", a, b);

    XScreenSaverQueryInfo(dpy, RootWindow(dpy, DefaultScreen(dpy)), &info);
    printf("%d %d %d %d\n", info.state, info.til_or_since, info.idle, info.kind);
    return 0;
}

But info.state is always 3 (ScreenSaverDisabled). I've tested this with xscreensaver and gnome-screensaver.

Here is some example output:

92 0
3 0 9903 0

It's the same with a running screensaver or without (except info.idle of course).

Additional info:

$ X -version
X.Org X Server 1.13.0
Release Date: 2012-09-05
X Protocol Version 11, Revision 0

Window Manager: i3

Distribution: Arch Linux

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

#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
#include <xcb/screensaver.h>

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->root);
    info = xcb_screensaver_query_info_reply (connection, cookie, NULL);

    int state = info->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

Solution

  • I went to the xorg irc channel and was told that at least xscreensaver doesn't use the extension I use.