简体   繁体   English

如何知道在 C++ 中使用 X11 的按键?

[英]How to know keypresses using X11 in C++?

My Goal:我的目标:

I'm making C++ programs but something very important is missing,我正在编写C++程序,但缺少一些非常重要的东西,
the program needs to know which key is pressed but I don't know any way to do it.程序需要知道按下了哪个键,但我不知道有什么方法可以做到。

Problems:问题:

After some researches, the most native way of getting key presses seems to be using X11 .经过一些研究,获得按键的最原生方式似乎是使用X11
Everything about keyboard input the Xlib manual were using events, Xlib手册中有关键盘输入的所有内容都使用事件,
but I don't know how to handle events!我不知道如何处理事件!

Is there any way to know key presses without using events?有没有办法在不使用事件的情况下知道按键?
Or how to use X11 events?或者如何使用X11事件?

If any clarification is needed, please add a comment or suggest an edit如果需要任何说明,请添加评论或建议编辑

There is two (and more) ways to achieve it:有两种(和更多)方法可以实现它:

The Not Recommended Hard Way不推荐的硬方式

It does the required features but is not recommended as it is slower and uses more lines of code.它具有所需的功能,但不推荐,因为它速度较慢且使用更多行代码。

uint32_t PressedKeys[8];

bool RefreshPressedKeys() {
  while(XPending(X11Display)) {
    XEvent KeyEvent;
    XNextEvent(X11Display,&KeyEvent);
    if(KeyEvent.type==KeyPress) {
      uint32_t KeyEventCode=KeyEvent.xkey.keycode;
      for(uint8_t i=0;i<8;i++) {
        if(PressedKeys[i]==0) {
          PressedKeys[i]=KeyEventCode;
          break;
        }
      }
    }else if(KeyEvent.type==KeyRelease) {
      uint32_t KeyEventCode=KeyEvent.xkey.keycode;
      for(uint8_t i=0;i<8;i++) {
        if(PressedKeys[i]==KeyEventCode) {
          PressedKeys[i]=0;
          break;
        }
      }
    }
  }
  return true;
}

uint32_t GetAPressedKey() { //Get a pressed key, won't always the last pressed key
  for(uint8_t i=0;i<8;i++) {
    if(PressedKeys[i]!=0) return PressedKeys[i]; //Returns the first pressed key found
  }
  return 0; //Or 0 when no key found
}

bool IsKeyPressed(uint32_t KeyFilter) { //Is Key Pressed?
  for(uint8_t i=0;i<8;i++) {
    if(PressedKeys[i]==KeyFilter) return true; //Returns true if the key is pressed
  }
  return false; //Else false
}

int main() {
  uint8_t Key;
  XSelectInput(X11Display,X11Window,KeyPressMask|KeyReleaseMask); //Enables keyboard input
  while(1) {
    Key = GetPressedKey(); //Gets the pressed key's number
    std::cout << Key << '\n'; //Displays the number
    /* Some code using the Key var */
  }
  return 0;
}

The Recommended Easy Way推荐的简单方法

The program might be more complex to understand at first but it's better since it can theoretically handle an "infinite" number of key pressed at once.该程序一开始可能更难理解,但它更好,因为它理论上可以处理一次按下的“无限”数量的键。

int main() {
  XSelectInput(Pixel.GetX11Display(),Pixel.GetX11Window(),KeyPressMask|KeyReleaseMask);
  while(1) {
    while(XPending(Pixel.GetX11Display())) { //Repeats until all events are computed
      XEvent KeyEvent;
      XNextEvent(Pixel.GetX11Display(),&KeyEvent); //Gets exactly one event
      if(KeyEvent.type==KeyPress) {
        uint32_t KeyEventCode=KeyEvent.xkey.keycode; //Gets the key code, NOT HIS CHAR EQUIVALENT
        std::cout << KeyEventCode << '\n'; //Displays the key code

        /* Code handling a Keypress event */

      } else if(KeyEvent.type==KeyRelease) {
         uint32_t KeyEventCode=KeyEvent.xkey.keycode;
         std::cout << KeyEventCode << '\n'; //Displays the key code

         /* Code handling a KeyRelease event */

      }
    }

    /* General code */

  }
}

Theses two codes were handwritten by me, I may have made an error since I haven't tested it but it should be something similar.这两个代码是我手写的,我可能犯了错误,因为我没有测试过,但应该是类似的。

Theses are copyleft and you don't need to credit me :)论文是 copyleft,你不需要相信我 :)

Please comment or suggest an edit for any error found or for code clarification.请评论或建议对发现的任何错误或代码澄清进行编辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM