Почему XGrabKeyboard() не регистрирует некоторые вводы с клавиатуры?

Я новичок в программировании на C++ и в течение двух недель пишу сценарий для игры в космический шутер для двух игроков на одной клавиатуре.

Для отображения игры я использую NCURSES, а для ввода с клавиатуры я использую X11. Для начала, у меня есть постоянная проблема с вводом с клавиатуры.

С другом мы написали эту функцию:

//earlier in the script :

Display *dpy; 

if (NULL==(dpy=XOpenDisplay(NULL))) {

    perror("Connexion problem");
    exit(1);

}

XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime);


//the function (keysPressed is just an array to store keyboard inputs) :

void getKBinput(bool (&keysPressed)[128], Display* dpy){

    XEvent ev;
    int kc;

    if (XPending(dpy)){

        XNextEvent(dpy, &ev);

        switch (ev.type) {

            case KeyPress:

                kc = ((XKeyPressedEvent*)&ev)->keycode;
                keysPressed[kc] = true;
                break;

            case KeyRelease:

                kc = ((XKeyReleasedEvent*)&ev)->keycode;
                keysPressed[kc] = false;
                break;

            case Expose:

                while (XCheckTypedEvent(dpy, Expose, &ev));
                break;

            case ButtonPress:

            case ButtonRelease:

            case MotionNotify:

            case ConfigureNotify:

            default:

                break;

            }
        }
    }
}


//later in the script :

XUngrabKeyboard(dpy, CurrentTime);

if (XCloseDisplay(dpy)) {

    perror("You can't deconnect to the server");
    exit(1);

}

Я использую эту функцию внутри цикла, чтобы перемещать каждый космический корабль в зависимости от того, какие игроки нажимают на каждый кадр.

Однако, когда я использую определенные сочетания клавиш, программа не заботится о некоторых ключах (поэтому он не регистрирует их в логическом массиве keysPressed).

Например, когда игрок 1 нажимает клавишу "D" и клавишу "C" одновременно, игрок 2 не может использовать клавишу "вверх" или клавишу "!" (но игрок 2 может использовать клавишу "влево" и клавишу "вниз" одновременно без проблем).

Чтобы лучше понять, что делает этот скрипт, я переписал эту часть во внешний файл для печати нажатых клавиш и отпущенных клавиш:

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

int main(int argc, char **argv){

    Display *dpy;
    XEvent ev;
    char * s;
    unsigned int kc;
    int quit = 0;

    if (NULL==(dpy=XOpenDisplay(NULL))) {
        perror(argv[0]);
        exit(1);
    }

    XAutoRepeatOff(dpy);

    XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime);

    for (;!quit;) {

        XNextEvent(dpy, &ev);

        switch (ev.type) {

        case KeyPress:

             kc = ((XKeyPressedEvent*)&ev)->keycode;
             s = XKeysymToString(XKeycodeToKeysym(dpy, kc, 0));

             if (s) printf("KEY PRESS:%s\n", s);

             if (!strcmp(s, "q")) quit=~0;

             break;

        case KeyRelease:

             kc = ((XKeyReleasedEvent*)&ev)->keycode;
             s = XKeysymToString(XKeycodeToKeysym(dpy, kc, 0));

             if (s) printf("KEY RELEASE:%s\n", s);

        case Expose:

             while (XCheckTypedEvent(dpy, Expose, &ev));
             break;

        case ButtonPress:

        case ButtonRelease:

        case MotionNotify:

        case ConfigureNotify:

        default:

            break;

        }
    }

    XUngrabKeyboard(dpy, CurrentTime);

    XAutoRepeatOn(dpy);

    if (XCloseDisplay(dpy)) {

        perror(argv[0]);
        exit(1);

    }

    return 0;
}

Это подтвердило мою проблему. Поскольку мой компьютер старый (и некоторые ключи работают ужасно), я протестировал этот скрипт на других компьютерах, чтобы получить те же результаты.

Я искал в документации x11 (может быть, не правильно?) Функцию разблокировки всех миксов между клавишами или другой способ обойти это ограничение. Я ничего не нашел. Должен ли я использовать другую библиотеку для ввода с клавиатуры?

Извините за мой плохой английский (и потенциальные ошибки), я сделал все возможное, чтобы быть понятным. Спасибо за ваше чтение.

0 ответов

Другие вопросы по тегам