我一直在尝试将我的 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);
}