Linux / X11输入库,无需创建窗口

时间:2020-03-05 18:49:30  来源:igfitidea点击:

是否有一个好的库可用于从鼠标/键盘/操纵杆收集Linux中的用户输入,而不会强迫我们创建可见的窗口呢? SDL可让我们以合理的方式获取用户输入,但似乎会迫使我们创建一个窗口,如果我们已抽象了控件,那么这将很麻烦,因此控制计算机不必与渲染计算机相同。但是,如果控制机器和渲染机器相同,则会导致显示器顶部的SDL窗口很小。

编辑以澄清:
渲染器有一个输出窗口,在正常情况下,该窗口是全屏的,除非它们都在同一台计算机上运行,​​所以可以给控制器以焦点。实际上可能有多个渲染器在全部由同一控制器控制的不同计算机上显示相同数据的不同视图,因此输入与输出完全脱钩(充分利用内置的X11客户端/服务器内容来减少显示次数)另外,一个渲染器也可以有多个控制器应用程序。控制器和渲染器之间的通信是通过套接字进行的。

解决方案

回答

对于鼠标,我们可以使用GPM。

我不确定键盘或者操纵杆在头顶上的位置。

如果需要的话,直接读取那里的/ dev文件可能还不错。

希望能帮助到你

回答

好的,如果我们使用的是X11,并且想要获取kbd,则需要进行抓取。
如果我们不是,那么我唯一的好答案是从终端获取ncurses。

这是我们从键盘上抓取所有东西并再次释放的方法:

/* Demo code, needs more error checking, compile
 * with "gcc nameofthisfile.c -lX11".

/* weird formatting for markdown follows.  argh! */

#include <X11 / Xlib.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);
   }

   /*
    * You might want to warp the pointer to somewhere that you know
    * is not associated with anything that will drain events.
    *  (void)XWarpPointer(dpy, None, DefaultRootWindow(dpy), 0, 0, 0, 0, x, y);
    */

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

   printf("KEYBOARD GRABBED!  Hit 'q' to quit!\n"
          "If this job is killed or you get stuck, use Ctrl-Alt-F1\n"
          "to switch to a console (if possible) and run something that\n"
          "ungrabs the keyboard.\n");

   /* A very simple event loop: start at "man XEvent" for more info. */
   /* Also see "apropos XGrab" for various ways to lock down access to
    * certain types of info. coming out of or going into the server */
   for (;!quit;) {
      XNextEvent(dpy, &ev);
      switch (ev.type) {
         case KeyPress:
            kc = ((XKeyPressedEvent*)&ev)->keycode;
            s = XKeysymToString(XKeycodeToKeysym(dpy, kc, 0));
            /* s is NULL or a static no-touchy return string. */
            if (s) printf("KEY:%s\n", s);
            if (!strcmp(s, "q")) quit=~0;
            break;
         case Expose:
               /* Often, it's a good idea to drain residual exposes to
                * avoid visiting Blinky's Fun Club. */
               while (XCheckTypedEvent(dpy, Expose, &ev)) /* empty body */ ;
            break;
         case ButtonPress:
         case ButtonRelease:
         case KeyRelease:
         case MotionNotify:
         case ConfigureNotify:
         default:
            break;
      }
   }

   XUngrabKeyboard(dpy, CurrentTime);

   if (XCloseDisplay(dpy)) {
      perror(argv[0]);
      exit(1);
   }

   return 0;
}

从终端运行此命令,所有kbd事件都应命中它。我正在Xorg下测试
但它使用了古老而稳定的Xlib机制。

希望这可以帮助。

谨慎对待X下的抢夺。当我们不熟悉它们时,有时候这是一个好习惯
启动一个延时过程的想法,这将在我们处于忙碌状态时取消服务器
测试代码,让它每两分钟就可以坐着运行并取消锁定。
它节省了必须杀死服务器或者从服务器切换到外部重置状态的麻烦。

在这里,我将留给我们决定如何多路复用渲染。读
XGrabKeyboard文档和XEvent文档入门。
如果我们在屏幕角落暴露了小窗户,则可能会造成卡纸
将指针放到一个角以选择一个控制器。 XWarpPointer可以
从代码中也将指针推向其中之一。

还有一点:我们也可以获取指针和其他资源。如果我们坐在前面的盒子上运行着一个控制器,则可以使用键盘和鼠标输入在具有不同渲染器的开放式插座之间切换。使用这种方法,我们不再需要将输出窗口的大小调整为小于全屏大小。通过做更多的工作,我们实际上可以使用SHAPE和COMPOSITE扩展名将Alpha混合的叠加放置在顶部,以响应用户输入获得不错的叠加功能(这可能算作百合花的烫金)。