1

我一直在尝试将我的 BBC Micro 连接到我的 Raspberry Pi 并将其用作串行 TTY 上的键盘。我在 Github 上找到了一些很棒的代码,可以将 Serial Keypresses 转发到 X11,但我似乎无法让它像我希望的那样工作。我在 C 方面并不出色,我尝试过,但遗憾的是,我一无所获。

以下内容仅在您按“返回”时将按键发送到 X11。问题是,如果您输入“ABCDE(RETURN)”,它会将“ABCDE”发送到 X11 会话并按回车键,在您按回车之前您看不到您输入的内容。我想要它做的是当我按下'A'时发送'A',当我按下B时发送'B'等。

我认为它似乎将所有内容都保存在某种缓冲区(readbuf?)中,以某种方式由XFlush(dpy);X11 的 112 刷新字符输入控制,因此将其移至 104(不起作用),在 53 和 155 尝试它希望会做的伎俩。

任何帮助将不胜感激!

static int serialPort;
static Display *dpy;

static void xtest_key_press(unsigned char letter) {
  unsigned int shiftcode = XKeysymToKeycode(dpy, XStringToKeysym("Shift_L"));
  int upper = 0;
  int skip_lookup = 0;
  char s[2];
  s[0] = letter;
  s[1] = 0;
  KeySym sym = XStringToKeysym(s);
  KeyCode keycode;



  if (sym == 0) {
    sym = letter;
  }


  if (sym == '\n') {
    sym = XK_Return;
    skip_lookup = 1;

  } else if (sym == '\t') {
    sym = XK_Tab;
    skip_lookup = 1;
  }

  keycode = XKeysymToKeycode(dpy, sym);
  if (keycode == 0) {
    sym = 0xff00 | letter;
    keycode = XKeysymToKeycode(dpy, sym);

  }

  if (!skip_lookup) {
    // Here we try to determine if a keysym
    // needs a modifier key (shift), such as a
    // shifted letter or symbol.
    // The second keysym should be the shifted char
    KeySym *syms;
    int keysyms_per_keycode;
    syms = XGetKeyboardMapping(dpy, keycode, 1, &keysyms_per_keycode);
    int i = 0;
    for (i = 0; i <= keysyms_per_keycode; i++) {
      if (syms[i] == 0)
        break;

      if (i == 0 && syms[i] != letter)
        upper = 1;


    }
  }

  if (upper)
    XTestFakeKeyEvent(dpy, shiftcode, True, 0); 


  XTestFakeKeyEvent(dpy, keycode, True, 0); 
  XTestFakeKeyEvent(dpy, keycode, False, 0);

  if (upper)
    XTestFakeKeyEvent(dpy, shiftcode, False, 0);  



}

static void press_keys(char* string) {
  int len = strlen(string);
  int i = 0;
  for (i = 0; i < len; i++) {
    xtest_key_press(string[i]);
  }
  XFlush(dpy);
}


int sw_open_serial(const char *port) {
  serialPort = open(port, O_RDONLY);
  if (serialPort < 0) {
    fprintf(stderr, "Can't open serial port: %s\n", port);
    exit(-1);
  }

  return 0;
}

void sw_init() {

  int xtest_major_version = 0;
  int xtest_minor_version = 0;
  int dummy;


  /*
   * Open the display using the $DISPLAY environment variable to locate
   * the X server.  See Section 2.1.
   */
  if ((dpy = XOpenDisplay(NULL)) == NULL) {
    fprintf(stderr, "%s: can't open %s\en", "softwedge", XDisplayName(NULL));
    exit(1);
  }

  Bool success = XTestQueryExtension(dpy, &dummy, &dummy,
                     &xtest_major_version, &xtest_minor_version);
  if(success == False || xtest_major_version < 2 ||
     (xtest_major_version <= 2 && xtest_minor_version < 2))
  {
    fprintf(stderr,"XTEST extension not supported. Can't continue\n");
    exit(1);
  }

}


void sw_read_loop() {

  char readbuf[2];
  readbuf[1] = 0;

  while(read(serialPort, readbuf, 1) > 0) {
    if (readbuf[0] == 0x02 || readbuf[0] == 0x03) 
      continue;
    press_keys(readbuf);
  }
  // We're done now
  close(serialPort);
}
4

0 回答 0