From c101f493676126e2a4cec2002b6dd55cfc055ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Tue, 31 Dec 2024 18:03:17 -0500 Subject: [PATCH] In X11 mode, support arbitrary character entry. You still cannot enter a NUL. Holding down ALT and entering an 8-bit decimal number on the keypad starting with a digit from 1-9 will pass that byte to the input buffer as entered. If you prefix the decimal number with the keypad zero, you can enter a Unicode codepoint to be translated and sent (if it translates). --- src/conio/x_cio.c | 4 ++ src/conio/x_events.c | 87 +++++++++++++++++++++++++++++++++++++++++++- src/conio/x_events.h | 1 + 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/conio/x_cio.c b/src/conio/x_cio.c index 51a8daabd5..fd37e0fda8 100644 --- a/src/conio/x_cio.c +++ b/src/conio/x_cio.c @@ -514,6 +514,10 @@ int x_initciolib(int mode) xp_dlclose(dl); return(-1); } + if((x11.XLookupKeysym=xp_dlsym(dl,XLookupKeysym))==NULL) { + xp_dlclose(dl); + return(-1); + } #ifdef WITH_XRENDER xrender_found = true; if ((dl2 = xp_dlopen(libnames2,RTLD_LAZY,1)) == NULL) diff --git a/src/conio/x_events.c b/src/conio/x_events.c index 8cd43e6198..21535d4c23 100644 --- a/src/conio/x_events.c +++ b/src/conio/x_events.c @@ -1106,7 +1106,7 @@ static int init_window() gcv.graphics_exposures = False; gc=x11.XCreateGC(dpy, win, GCFunction | GCForeground | GCBackground | GCGraphicsExposures, &gcv); - x11.XSelectInput(dpy, win, KeyReleaseMask | KeyPressMask + x11.XSelectInput(dpy, win, KeyReleaseMask | KeyPressMask | KeyReleaseMask | ExposureMask | ButtonPressMask | PropertyChangeMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | FocusChangeMask); @@ -1651,9 +1651,42 @@ handle_configuration(int w, int h, bool map, bool se) got_first_resize = true; } +static void +handle_bios_key(uint32_t *bios_key, bool *bios_key_parsing, bool *zero_first) +{ + uint8_t ch; + + if (*bios_key > 0 && *bios_key_parsing) { + if (*zero_first) { + // Unicode character + ch = cpchar_from_unicode_cpoint(getcodepage(), *bios_key, 0); + if (ch == 0) + x11.XBell(dpy, 100); + else { + write(key_pipe[1], &ch, 1); + if (ch == 0xe0) + write(key_pipe[1], &ch, 1); + } + } + else { + // Codepage character + ch = *bios_key; + write(key_pipe[1], &ch, 1); + if (ch == 0xe0) + write(key_pipe[1], &ch, 1); + } + } + *bios_key = 0; + *bios_key_parsing = false; + *zero_first = false; +} + static void x11_event(XEvent *ev) { + static uint32_t bios_key = 0; + static bool bios_key_parsing = false; + static bool zero_first = false; bool resize; int x, y, w, h; @@ -1959,6 +1992,18 @@ x11_event(XEvent *ev) break; /* Keyboard Events */ + case KeyRelease: + { + if (bios_key_parsing) { + KeySym ks = x11.XLookupKeysym((XKeyEvent *)ev, 0); + // If Mod1 (ie: ALT) is released, *and* the only bytes were KP numbers, do the BIOS thing. + if (ks == XK_Alt_L || ks == XK_Alt_R) { + handle_bios_key(&bios_key, &bios_key_parsing, &zero_first); + } + } + } + break; + case KeyPress: { static char buf[128]; @@ -1970,6 +2015,7 @@ x11_event(XEvent *ev) int cnt; int i; uint8_t ch; + bool terminate_bios = false; if (ic) cnt = x11.XwcLookupString(ic, (XKeyPressedEvent *)ev, wbuf, sizeof(wbuf)/sizeof(wbuf[0]), &ks, &lus); @@ -1978,6 +2024,45 @@ x11_event(XEvent *ev) lus = XLookupKeySym; } + if (bios_key_parsing) { + if (ks >= XK_KP_0 && ks <= XK_KP_9) { + if (bios_key == 0 && ks == XK_KP_0) + zero_first = true; + else { + if (zero_first) { + if (bios_key >= 429496730 || + (bios_key == 429496729 && ks > XK_KP_5)) { + terminate_bios = true; + } + } + else { + if (bios_key >= 26 || + (bios_key == 25 && ks > XK_KP_5)) { + terminate_bios = true; + } + } + if (terminate_bios) { + handle_bios_key(&bios_key, &bios_key_parsing, &zero_first); + } + else { + bios_key *= 10; + bios_key += (ks - XK_KP_0); + break; + } + } + } + else { + handle_bios_key(&bios_key, &bios_key_parsing, &zero_first); + } + } + + if (ks == XK_Alt_L || ks == XK_Alt_R) { + bios_key = 0; + bios_key_parsing = true; + zero_first = false; + break; + } + switch(lus) { case XLookupNone: ks = 0xffff; diff --git a/src/conio/x_events.h b/src/conio/x_events.h index 51b5b3cd22..6e4c6b8bed 100644 --- a/src/conio/x_events.h +++ b/src/conio/x_events.h @@ -119,6 +119,7 @@ struct x11 { int (*XMoveWindow)(Display *, Window, int, int); Status (*XGetWMNormalHints)(Display*, Window, XSizeHints*, long*); int (*XMoveResizeWindow)(Display*, Window, int, int, unsigned int, unsigned int); + KeySym (*XLookupKeysym)(XKeyEvent *, int); #ifndef DefaultDepth int (*DefaultDepth)(Display *, int); #endif -- GitLab