当前位置: 首页 > 面试题库 >

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

唐睿
2023-03-14
问题内容

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

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


问题答案:

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

这是您从键盘上抓取所有东西并再次释放的html" target="_blank">方法:

/* 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之下的争夺。当您不熟悉X时,有时最好启动一个延时过程,该过程将在测试代码时使服务器脱钩,并让它每两分钟坐下来运行并脱钩。它节省了必须杀死服务器或从服务器切换到外部重置状态的麻烦。

在这里,我将留给您决定如何多路复用渲染。阅读XGrabKeyboard文档和XEvent文档以开始使用。如果您在屏幕角落暴露了小窗口,则可以将指针卡在一个角落中以选择控制器。XWarpPointer也可以从代码中将指针推到其中之一。

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



 类似资料:
  • 问题内容: 我想创建一个供个人使用的简单堆叠窗口管理器,主要用于学习和挑战自我。 我浏览了的源代码,它的花样少,但由于它不是基于小部件工具箱的,因此它的级别似乎很低。1使用GTK +之类的工具箱会更好吗?恐怕其中的某些代码和库可能过于陈旧( 编辑: 已弃用),我希望窗口管理器使用相对较新的库。为了理解,我也将对如何从头启动窗口管理器的建议感兴趣-为此目的的教程并不多。 更新: 对于那些考虑类似项目

  • 译注 注意,由于作者对教程做出了更新,之前本节使用的是GLEW库,但现在改为了使用GLAD库,关于GLEW配置的部分现在已经被修改,但我仍决定将这部分教程保留起来,放到一个历史存档中,如果有需要的话可以到这里来查看。 在我们画出出色的效果之前,首先要做的就是创建一个OpenGL上下文(Context)和一个用于显示的窗口。然而,这些操作在每个系统上都是不一样的,OpenGL有目的地从这些操作抽象(

  • 当我尝试创建一个新的数据库(m)在xampp mysql命令窗口然后我得到一个错误消息 错误1044(42000):用户“@'localhost”对数据库“m”的访问被拒绝。 然后我使用phpmyadmin创建了这个数据库,但是当我在mysql命令窗口中输入命令时,它并没有显示出来。有人能告诉我如何才能摆脱这个错误信息,并能成功地创建新的数据库,通过使用mysql命令窗口在xampp?(我使用的是

  • 问题内容: 我正在尝试在具有结构的Django Docker容器中创建createsuperuser。 要在django中创建超级用户,我需要以django交互模式运行它: 并且因为我想使其在结构脚本中运行,所以我发现 此 命令可以避免输入密码 然后,将其与 “ docker exec” 放在一起,以在我的django容器中运行它 问题出在linux管道上,管道(|)在其左侧的所有内容(包括doc

  • 问题内容: 在Linux终端中创建文件的最简单方法是什么? 问题答案: 根据您希望文件包含的内容: 对于一个空文件 用于包含某些命令输出的文件。 或(或) 它可以打开现有文件进行编辑,也可以创建并打开一个空文件以输入(如果不存在)

  • 这是我的代码伙计们: 以下是错误: Traceback(最近一次调用最后一次):文件"C:/用户/Argel/PycharmProjects/day 2/rockpaper.py",第4行,在标签=标签(根,'Hello World')文件"C:\用户\Argel\AppData\本地\程序\Python\Python36-32\lib\tkinter__init__. py",第2760行,在i