get inputs from OS application even if app is not active


Having some app, made with x11 libs, tested for ubuntu.
It takes simple keyboard inputs and outputs corresponding value.
It works fine if application window (ubuntu terminal) is currently open
I need to get keys from any app within OS (Ubuntu)
How can should I amend the code?

linux-kbhit.h

1
2
3
4
5
6
7
8
9
10
11
#define     ESC     "\033"
#define     UP      "\033[A"
#define     DOWN    "\033[B"
#define     LEFT    "\033[D"
#define     RIGHT   "\033[C"
#define     A   "a"

void term_setup(void (*sighandler)(int));
void term_restore();
bool kbhit();
bool keydown(const char* key);

linux-kbhit.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <poll.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>

static struct termios oldtio;
static struct termios curtio;

void term_setup(void (*sighandler)(int)){
    struct sigaction sa;

    /* Save stdin terminal attributes */
    tcgetattr(0, &oldtio);

    if(sighandler){
    /* Make sure we exit cleanly */
        memset(&sa, 0, sizeof(struct sigaction));
        sa.sa_handler = sighandler;
        sigaction(SIGINT, &sa, NULL);
        sigaction(SIGQUIT, &sa, NULL);
        sigaction(SIGTERM, &sa, NULL);
    }

    /* This is needed to be able to tcsetattr() after a hangup (Ctrl-C)
     * see tcsetattr() on POSIX
     */
    memset(&sa, 0, sizeof(struct sigaction));
    sa.sa_handler = SIG_IGN;
    sigaction(SIGTTOU, &sa, NULL);

    /* Set non-canonical no-echo for stdin */
    tcgetattr(0, &curtio);
    curtio.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(0, TCSANOW, &curtio);
}

void term_restore(){
    /* restore terminal attributes */
    tcsetattr(0, TCSANOW, &oldtio);
}

static char get[4]= {0};
bool kbhit(){
    struct pollfd pfds[1];
    int ret;
    memset(get, 0, sizeof(char) * 4);

    /* See if there is data available */
    pfds[0].fd = 0;
    pfds[0].events = POLLIN;
    ret = poll(pfds, 1, 0);

    /* Consume data */
    if (ret > 0) {
        read(0, get, 3);
        return strlen(get) > 0;
    }
    return false;
}

bool keydown(const char* key){
    return !strcmp(get, key);
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "linux-kbhit.h"
#include "stdio.h"
#include <signal.h>

static sig_atomic_t end = 0;
static void sighandler(int signo)
{
    end = 1;
    printf("good beye!\n");
}

int main()
{
    term_setup(sighandler);

    while (!end) {
        if (kbhit()) {
            if (keydown(ESC))
                printf("This is \"ESC\" button!\n");
            if (keydown(UP))
                printf("This is \"UP\" button!\n");
            if (keydown(DOWN))
                printf("This is \"DOWN\" button!\n");
            if (keydown(LEFT))
                printf("This is \"LEFT\" button!\n");
            if (keydown(RIGHT))
                printf("This is \"RIGHT\" button!\n");
            if (keydown(A))
                printf("This is \"A\" button!\n");
        }
    }

    term_restore();

    return 0;
}

Last edited on
I've googled a lot /dev/input but still not clue, how to get even smaller test case
Please assist

add:
can I use boost asio?
Last edited on
Topic archived. No new replies allowed.