Access to events from the root window ? (~ mouse / keyboard hook) - Xwindows

This is a discussion on Access to events from the root window ? (~ mouse / keyboard hook) - Xwindows ; Hello, I need to know on Linux when a user press a key or use a button of his mouse even when my app is not in focus (it's for a small "podcasting" software which also grabs/synchronize screenshot(slides) when the ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: Access to events from the root window ? (~ mouse / keyboard hook)

  1. Access to events from the root window ? (~ mouse / keyboard hook)

    Hello,

    I need to know on Linux when a user press a key or use a button of his
    mouse even when my app is not in focus (it's for a small "podcasting"
    software which also grabs/synchronize screenshot(slides) when the user
    do something).

    On windows I've used the PyHook module (Python). Since I didn't find
    anything equivalent on Linux I thought it was a good idea to use the
    Xlib since it's obvious that the X server centralise all the events and
    pass them to clients which request them.

    The problem is that I can have these events only if I make a client
    window which have the focus on it [I use these maks
    XSelectInput(display, win, KeyPressMask |ButtonPressMask); ]

    If I ask directly for the main root window events
    [XSelectInput(display, root_window, KeyPressMask |ButtonPressMask);] I
    have this message:
    ---
    X Error of failed request: BadAccess (attempt to access private
    resource denied)
    Major opcode of failed request: 2 (X_ChangeWindowAttributes)
    Serial number of failed request: 7
    Current serial number in output stream: 7
    ---

    I paste below the little test snippet.

    Is what I'm trying to do feasible with Xlib ?
    If so can you give me a hint ?
    If not what would you advise (I don't necessarily need to know which
    particular button or key is pressed)

    Thanks in advance !

    Test snippet:

    ------
    #include
    #include
    #include
    #include
    void
    main()
    {
    Display* display;
    int screen_num;
    Window win;
    Window root_window; //should be the main Window Manager window ?

    unsigned int display_width, display_height,width, height,win_x,
    win_y,win_border_width;
    char *display_name = getenv("DISPLAY");

    display = XOpenDisplay(display_name);
    screen_num = DefaultScreen(display);

    width = 200;
    height = 100;
    win_x = 0;
    win_y = 0;
    win_border_width = 2;

    win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
    win_x, win_y, width, height,
    win_border_width,
    BlackPixel(display, screen_num),
    WhitePixel(display, screen_num));*/
    root_window= RootWindow(display,screen_num);

    /* make the window actually appear on the screen. */
    XMapWindow(display, win);

    /* subscribe to the given set of event types. */
    //XSelectInput(display, win, KeyPressMask |ButtonPressMask); //works
    fine with win
    XSelectInput(display, root_window, KeyPressMask |ButtonPressMask);

    /* perform an events loop */
    {
    int done = 0;
    XEvent an_event;
    while (!done) {
    XNextEvent(display, &an_event);
    switch (an_event.type) {
    case ButtonPress:
    printf("Button pressed !\n");
    break;
    case KeyPress:
    printf("Key pressed !!!\n");
    break;
    } /* end switch on event type */
    } /* end while events handling */
    }


  2. Re: Access to events from the root window ? (~ mouse / keyboard hook)


    wrote in message
    news:1152698867.110435.151570@i42g2000cwa.googlegr oups.com...
    > Hello,
    >
    > I need to know on Linux when a user press a key or use a button of his
    > mouse even when my app is not in focus (it's for a small "podcasting"
    > software which also grabs/synchronize screenshot(slides) when the user
    > do something).
    >
    > On windows I've used the PyHook module (Python). Since I didn't find
    > anything equivalent on Linux I thought it was a good idea to use the
    > Xlib since it's obvious that the X server centralise all the events and
    > pass them to clients which request them.
    >
    > The problem is that I can have these events only if I make a client
    > window which have the focus on it [I use these maks
    > XSelectInput(display, win, KeyPressMask |ButtonPressMask); ]
    >
    > If I ask directly for the main root window events
    > [XSelectInput(display, root_window, KeyPressMask |ButtonPressMask);] I
    > have this message:
    > ---
    > X Error of failed request: BadAccess (attempt to access private
    > resource denied)
    > Major opcode of failed request: 2 (X_ChangeWindowAttributes)
    > Serial number of failed request: 7
    > Current serial number in output stream: 7
    > ---
    >
    > I paste below the little test snippet.
    >
    > Is what I'm trying to do feasible with Xlib ?
    > If so can you give me a hint ?
    > If not what would you advise (I don't necessarily need to know which
    > particular button or key is pressed)
    >
    > Thanks in advance !
    >
    > Test snippet:
    >
    > ------
    > #include
    > #include
    > #include
    > #include
    > void
    > main()
    > {
    > Display* display;
    > int screen_num;
    > Window win;
    > Window root_window; //should be the main Window Manager window ?
    >
    > unsigned int display_width, display_height,width, height,win_x,
    > win_y,win_border_width;
    > char *display_name = getenv("DISPLAY");
    >
    > display = XOpenDisplay(display_name);
    > screen_num = DefaultScreen(display);
    >
    > width = 200;
    > height = 100;
    > win_x = 0;
    > win_y = 0;
    > win_border_width = 2;
    >
    > win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
    > win_x, win_y, width, height,
    > win_border_width,
    > BlackPixel(display, screen_num),
    > WhitePixel(display, screen_num));*/
    > root_window= RootWindow(display,screen_num);
    >
    > /* make the window actually appear on the screen. */
    > XMapWindow(display, win);
    >
    > /* subscribe to the given set of event types. */
    > //XSelectInput(display, win, KeyPressMask |ButtonPressMask); //works
    > fine with win
    > XSelectInput(display, root_window, KeyPressMask |ButtonPressMask);
    >
    > /* perform an events loop */
    > {
    > int done = 0;
    > XEvent an_event;
    > while (!done) {
    > XNextEvent(display, &an_event);
    > switch (an_event.type) {
    > case ButtonPress:
    > printf("Button pressed !\n");
    > break;
    > case KeyPress:
    > printf("Key pressed !!!\n");
    > break;
    > } /* end switch on event type */
    > } /* end while events handling */
    > }
    >


    You would have to call XSelectInput on all windows, not just the root
    window.
    Note that even then you might not get the input, if that window's
    application has
    implemented a keyboard grab (Otherwise it is easy to write a keystroke
    listener and steal passwords as they are typed in).
    --
    Fred L. Kleinschmidt
    Boeing Associate Technical Fellow
    Technical Architect, Software Reuse Project





+ Reply to Thread