我一直试图将我的BBC Micro连接到我的Raspberry Pi并将其用作串口TTY上的键盘。我找到了一些很棒的code on Github to forward Serial Keypresses to X11,但我似乎无法按照我的希望让它发挥作用。我不擅长C并且有一个去,但遗憾的是没有任何地方。
下面的工作原理是,只有在按下“返回”时才会将按键发送到X11。麻烦的是,如果你键入'ABCDE(RETURN)',它会发送'ABCDE'进入X11会话并点击返回键,你看不到你输入的内容,直到你回来。我想要它做的是当我按下'A'时发送'A',当我按下B等时发送'B'。
我认为它似乎将某些缓冲区(readbuf
?)中的所有内容控制在XFlush(dpy);
以112缓冲字符输入到X11,所以将其移动到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);
}