Linux/X11输入库,无需创建窗口 [英] Linux/X11 input library without creating a window

查看:220
本文介绍了Linux/X11输入库,无需创建窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there a good library to use for gathering user input in Linux from the mouse/keyboard/joystick that doesn't force you to create a visible window to do so? SDL lets you get user input in a reasonable way, but seems to force you to create a window, which is troublesome if you have abstracted control so the control machine doesn't have to be the same as the render machine. However, if the control and render machines are the same, this results in an ugly little SDL window on top of your display.

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

Edit To Clarify:
The renderer has an output window, in its normal use case, that window is full screen, except when they are both running on the same computer, just so it is possible to give the controller focus. There can actually be multiple renderers displaying a different view of the same data on different computers all controlled by the same controller, hence the total decoupling of the input from the output (Making taking advantage of the built in X11 client/server stuff for display less useable) Also, multiple controller applications for one renderer is also possible. Communication between the controllers and renderers is via sockets.

推荐答案

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

OK, if you're under X11 and you want to get the kbd, you need to do a grab. If you're not, my only good answer is ncurses from a terminal.

以下是您从键盘上抓取所有东西并再次释放的方法:

Here's how you grab everything from the keyboard and release again:


/* 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机制.

Run this from a terminal and all kbd events should hit it. I'm testing it under Xorg but it uses venerable, stable Xlib mechanisms.

希望这会有所帮助.

请谨慎对待X下的抓斗.当您不熟悉它们时,有时会很不错 启动一个延时过程的想法,该过程将使您在忙碌的时候取消服务器的工作 测试代码,让它每两分钟就可以坐着运行并取消锁定. 它省去了将服务器杀死或从服务器切换到外部重置状态的麻烦.

BE CAREFUL with grabs under X. When you're new to them, sometimes it's a good idea to start a time delay process that will ungrab the server when you're testing code and let it sit and run and ungrab every couple of minutes. It saves having to kill or switch away from the server to externally reset state.

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

From here, I'll leave it to you to decide how to multiplex renderes. Read the XGrabKeyboard docs and XEvent docs to get started. If you have small windows exposed at the screen corners, you could jam the pointer into one corner to select a controller. XWarpPointer can shove the pointer to one of them as well from code.

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

One more point: you can grab the pointer as well, and other resources. If you had one controller running on the box in front of which you sit, you could use keyboard and mouse input to switch it between open sockets with different renderers. You shouldn't need to resize the output window to less than full screen anymore with this approach, ever. With more work, you could actually drop alpha-blended overlays on top using the SHAPE and COMPOSITE extensions to get a nice overlay feature in response to user input (which might count as gilding the lily).

这篇关于Linux/X11输入库,无需创建窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆