Thread: Greedy XGrabKeyboard

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    2

    Greedy XGrabKeyboard

    Hi there,

    How do I passively capture keyboard input from a terminal program without locking out the system?

    As it stands, my small test program (shown below) locks out all running programs of keyboard input and I've tried a number of variations to try and solve this:
    - tried issuing XAllowEvents after KeyPress and KeyRelease, passing AsyncKeyboard, SyncKeyboard and ReplayKeyboard.
    - tried using GrabKey with AnyKey, AnyModifier on DefaultRootWindow but that triggers an error (x_grabkey BadAccess (attempt to access private resource denied ...))

    Any comments/suggestions would be greatly appreciated!


    Code:
    int main(int argc, char **argv)
    {
       Display *dpy;
       int quit = 0;
    
       if((dpy = XOpenDisplay(NULL)) == NULL) {
          perror(argv[0]);
          exit(1);
       }
    
       XGrabKeyboard(dpy, DefaultRootWindow(dpy),
                     False, GrabModeAsync, GrabModeAsync, CurrentTime);
    
       while(!quit) {
          XEvent ev;
    
          XNextEvent(dpy, &ev);
    
          switch (ev.type) {
          case KeyPress:
            char *s;
            unsigned int kc;
    
            kc = ((XKeyPressedEvent*)&ev)->keycode;
            s = XKeysymToString(XKeycodeToKeysym(dpy, kc, 0));
    
            if(s) printf("KEY: %s\n", s);
            if(!strcmp(s, "q")) quit=~0;
          }
       }
    
       XUngrabKeyboard(dpy, CurrentTime);
    
       if (XCloseDisplay(dpy)) {
          perror(argv[0]);
          exit(1);
       }
    
       return 0;
    }

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by belnac View Post
    Hi there,

    How do I passively capture keyboard input from a terminal program without locking out the system?
    For one thing, don't use Xlib to do it. Is this a program you are writing? If so, use libtermcap or ncurses. If not, hmm, google "keylogger".
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    2
    Quote Originally Posted by MK27
    For one thing, don't use Xlib to do it. Is this a program you are writing? If so, use libtermcap or ncurses. If not, hmm, google "keylogger".
    Thanks for your reply. First off, this isn't a keylogger at all

    This is a program I'm writing as an introduction to Linux programming (my background is in Win32.) Its aim is to:
    - run as a daemon (already done)
    - capture keyboard input
    - produce a sound (from a headerless uncompressed sound file) once a key is pressed via ALSA (already done)

    This is why I thought of interfacing directly with X11 for keyboard capture. Was that a wrong design call?

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by belnac View Post
    This is why I thought of interfacing directly with X11 for keyboard capture. Was that a wrong design call?
    Just to clarify, a daemon is not a terminal app, just like a terminal app is not a GUI.

    So if it is a daemon, this is not a bad idea. I use Xlib in a daemon to flash the keyboard LEDS in different patterns as alerts -- but I've never tried to capture all keyboard input. Unfortunately, as far as I've noticed nobody else around here uses Xlib at all, so you may not get advice on that but you may get some other ideas. You could probably do this from kernel space too, but kernel programming is even more of a b**ch to research than Xlib

    I would look into event handling (with X) instead of this grab keyboard thing, obviously it's very assertive, you want a more passive approach. However, I'm going to guess that events from one window do not propagate to the root.

    Mostly I'd advise you to sign up on an appropriate mailing list and ask there:

    X.Org Wiki - XorgMailingLists

    if anyone can help, it will be those folks.
    Last edited by MK27; 05-18-2010 at 01:02 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. ITERATED GREEDY ALGORITHM. Help!!
    By joan in forum C++ Programming
    Replies: 0
    Last Post: 12-05-2006, 12:45 PM
  2. Is Kazaa being greedy?
    By minesweeper in forum A Brief History of Cprogramming.com
    Replies: 29
    Last Post: 11-05-2002, 04:39 PM