3

I found numerous examples that use either X11 or linux/input.h unfortunately I am on Cygwin where linux/input.h does not exist.

I would like a simple example that I can use to detect events such as:

  • Key down
  • Key up

Or

  • Mouse button down
  • Mouse button up

I would like to find a solution that can work on Cygwin/Linux and as optionally on Windows/OSX.

Is it possible?

So far I've found 1 solution that is using X11:

#include <stdio.h>
#include <X11/Xlib.h>

char *key_name[] = {
    "first",
    "second (or middle)",
    "third",
    "fourth",  // :D
    "fivth"    // :|
};

int main(int argc, char **argv)
{
    Display *display;
    XEvent xevent;
    Window window;

    if( (display = XOpenDisplay(NULL)) == NULL )
        return -1;

    window = DefaultRootWindow(display);
    XAllowEvents(display, AsyncBoth, CurrentTime);

    XGrabPointer(display, 
                 window,
                 1, 
                 PointerMotionMask | ButtonPressMask | ButtonReleaseMask , 
                 GrabModeAsync,
                 GrabModeAsync, 
                 None,
                 None,
                 CurrentTime);

    while(1) {
        XNextEvent(display, &xevent);
        switch (xevent.type) {
            case ButtonPress:
                printf("Button pressed  : %s\n", key_name[xevent.xbutton.button - 1]);
                break;
            case ButtonRelease:
                printf("Button released : %s\n", key_name[xevent.xbutton.button - 1]);
                break;
        }
    }

    return 0;
}

Building with

gcc foo.c -lX11

Unfortunately the Xserver has to be launched startxwin& and the mouse pointer has to be inside a X server window. So this is not a good solution.

Another approach was to use ncurses but It seems states key-down, key-up are not possible.

The example below does not work on cygwin because conio.h is not POSIX:

#include <stdio.h>
#include <conio.h>
char ch;
void main(){
    while(1){
        if(kbhit()){ //kbhit is 1 if a key has been pressed
            ch=getch();
            printf("pressed key was: %c", ch);
        }
    }
}

conio.h is a C header file used mostly by MS-DOS compilers to provide console input/output.[1] It is not part of the C standard library or ISO C, nor is it defined by POSIX.

nowox
  • 25,978
  • 39
  • 143
  • 293
  • Have you done [a simple search](https://www.google.fr/search?q=cygwin%20C%20program%20capture%20keydown) to see if [there is an answer already somewhere](http://stackoverflow.com/questions/22166074/is-there-a-way-to-detect-if-a-key-has-been-pressed) ? – Eregrith May 04 '15 at 12:22
  • Good question and the answer is yes. I've tried many examples using `fcntl.h`, `termios.h`, `conio.h` or `linux/input.h` but I still did not succeed... Perhaps this is not an easy task... – nowox May 04 '15 at 12:27
  • You should include in your question what you tried and where it failed, so people could help you with that, instead of plainly asking for a packaged solution to your need. Stack Overflow is not about getting people to code for you :) – Eregrith May 04 '15 at 12:31
  • 1
    Well, this post is going to be very long :) – nowox May 04 '15 at 12:33
  • can you show us how do you compile program ? – Mekap May 04 '15 at 12:36
  • `gcc -lX11 myfile.c -o myprogram` – nowox May 04 '15 at 12:38
  • I just discovered that it's much better to put `-lX11` at the end of gcc like `gcc -static foo.c -o test -lncurses` – nowox May 04 '15 at 12:44
  • Actually I've just edited my question. I tried to X11 example successfully but I have to start a x server and place the mouse pointer inside the X window which is not very convenient. I initially just want to capture the event "Keypress", "Keyreleased". I'm currently trying something with ncurses... – nowox May 04 '15 at 12:54

1 Answers1

2

You seem to want to make a cross-platform program. I doubt you'll be able to resolve this problem with Linux-only libraries. What I suggest is to:

  1. Ditch X in favor of Qt or GTK.
  2. Make a module that listens to key events using facilities from Windows.h, compiled only if user is on Windows. Sooner or later you'll need to do that anyway for other stuff as your project grows.
rr-
  • 14,303
  • 6
  • 45
  • 67