Raspberry Pi Keyboard Interface (Key Remapping?) - linux

I am building a Raspberry Pi wearable computer and as a result am not able to hook up a full sized keyboard to the Pi (I don't have one that is not full sized). Instead I have a numeric keypad USB attachment which functions as a keyboard, but only the numeric keypad part (0-9, a triple 0, +, -, *, - and numlock).
Now my question is: how would one go about writing a script/program to run in the background that will change input keypress(es) to other keypress(es), for example, changing 777 (in rapid succession) to 'c' or 5 to 'x'. This way I hope to be able to type, albeit slowly at first, using only 16 keys. What libraries are a good idea and do you have any sample usage of them.
Ideally this should work both in the startup command prompt (RPi doesn't run X immediately) and in the X environment.

You could use evmapd to catch the keyboard keycodes, and modify its source (I assume you're comfortable with C) to wait for multiple keystrokes before outputting a regular keyboard code. For example, send 67 for 'c' to the keyboard buffer, after receiving 97 (numpad 1) three times in quick succession from the physical device.

Related

Linux program to emulate keystrokes without X

I'm writing a driver for a pda with a goal of converting UART received key numbers to keystrokes.
The way i currently have this system set up is that when a key number is received, i can exec a program. In a config it is defined what command is executed if a certain number is received by my driver. It does this by fork()ing and exec()ing. It runs at boot and immediately parses these key numbers, so i intend to use this instead of a real keyboard.
Is there any program then, with which i could simply do something like
programname KEY_SPACE 1 to press KEY_SPACE
and
programname KEY_SPACE 0 to release KEY_SPACE?
Such a program must work without, as well as with X. I'd also prefer this to be able to do mouse events as well, however if there is a different program to do that, that's fine by me. It can be run as root as well, if need be.
What you need is to use uinput, it allows to emulate input device from userspace. You have documentation here: https://www.kernel.org/doc/html/v5.11/input/uinput.html
It has an example showing how to send a KEY_SPACE press event and then a KEY_SPACE release event.

Is there a reliable way to reconnect a paired ZAGG - Logitech Bluetooth Keyboard upon power-up?

I have a bluetooth keyboard that I use on a regular basis. It has a Logitech logo, but is manufactured by ZAGG and has model number Y-R0023.
I have paired the keyboard with my Ubuntu desktop and it works great.
Upon powering up my computer and keyboard, I can sometimes reconnect without having to pair again, but other times I have to remove the existing pairing and reconnect before Ubuntu can receive keystrokes.
Extra information: Ubuntu displays a bluetooth symbol as a status when it connects (regardless if it is able to receive keystrokes or not). This symbol will appear and disappear roughly every 10 seconds until the two devices are able to successfully negotiate a valid connection.
I notice that I have best success when I press 'delete-delete-enter-enter' after powering the ZAGG keyboard up. (Sometimes, just repeatedly pressing a key every second or so seems to work too.)
I am wondering if the "delete-delete-enter" keystroke combination (or some other that I haven't discovered) is recognized by the Logitech BIOS as a special sequence to help retry a paired re-connection. I'd be interested in finding out if this trick works for devices other than those made by ZAGG. Otherwise, it would help just to know if there is a reliable script I can run that calls bluetoothctl to help improve the re-connection. (I want to avoid having to enter a pairing code on subsequent connections).
ZAGG sites and Logitech ones don't say anything about this key combination. So I don't think it's recognized as a special sequence, only advice they give is to re-pair the device when it's not working.
In summary I'm sure they would include this troubleshooting option in manual and/or troubleshooting guide if it was present.

How to detect xterm resize in-band

I'm looking for a way to get resize events on an xterm as an alternative to the winch signal. I need to get a signal for the xterm resize that is remote compatible, that is, could be used over a serial line/telnet/ssh/whatever. The winch signal is only for local machine tasks.
I know that vi/curses can do this because I have tried ssh and use vi to edit a file, and it responds to resizing of the window.
So after a bit of research, it does seem there is no in-band method for this. I don't think it would be difficult to add. You have two sides to a connection, ssh, serial or whatever, let's say A and B where A is on the host and B is the remote. To get behavior equivalent to a local windowed task, I would say at least two things are essential:
Mouse movement/button messaging.
Window resize messaging.
The second, can be a two step process. If the B task gets an alert that the window size has changed, it can use in band queries to determine what the new size is, using the (perhaps infamous) method of setting the cursor to the end of an impossibly large screen and then reading the actual location of the cursor that results, then restoring the location, all done with standard in-band controls.
Why care about in-band vs. out of band? Well, nobody cares now :-), but serial lines used to be quite popular, and in-band, that is, actual escape sequences sent down the line are going to work, but telnet or ssh "out of band" communication is not.
It would not be difficult to add, a local program that shims the ssh or telnet, or even xterm itself, can get the winch message and change that to an escape alert to the B side. Here the mouse messaging is instructive. The messages consist of two actions:
The B side must enable such messages, so that the A side won't send unknown escapes to it.
The A side must have an escape to signify winch.
Thus a new escape from B to A, and one from A to B.
I'm actually fairly satisfied with winch. What was wanted is to have the same capabilities as vi/curses (based on my observation). This kind of support is already far better than Windows, which (as far as I know) implements none of this remote side support.

My own linux Chorded keyboard driver and interface to my embedded application

I wan to develop my own keypad driver to my own keypad. I have to used GPIO to identify Key Events and used I2c to get scan code.
I am going to develop keypad driver like this.
#include <linux/gpio.h>
#include <linux/interrupt.h>
#define GPIO 1 //gpio PIN
...
if(gpio_request(GPIO, "Description")){
Exception
}
gpio_direction_input(GPIO);
...
int irq = 0;
if((irq = gpio_to_irq(GPIO)) < 0 ){
Exception
}
…
int init_module(){
int result = request_irq(GPIO, handler_func, IRQF_TRIGGER_LOW,"Description", "Device id");
if(result){
Exception
}
}
void handler_func(...){
//get scan code via i2c
}
I need to develop an interface and have to handle following operations
In my keypad, print as "1abc" on the [KEY1] .
1. When press key, display 1st Characters as it is -> "1"
2. Special key combinations are used to input other 3 characters
Eg:
key input operations as follows;
KEY1 (direct press) should display "1"
F1 + KEY1 (simultaneous press) should display "a"
F2 + KEY1 (simultaneous press) should display "b"
F3 + KEY1 (simultaneous press) should display "c"
My problem is how should I develop this interface?
You better follow Analog devices' Keyboard and GPIO Linux Driver. I'm going to link you to some GPIO drivers.
This driver included these features
Configurable keypad size matrix (rows, columns).
Support for switch events.
automatic key repeat.
Lock/Unlock key feature.
ADP5588 Keyboard - GPIO Linux Driver
ADP5589 Keyboard - GPIO Linux Driver
Your question is a bit vague, so I'm going to link you to some pages that describe making such input devices:
Steve Mann's septambic keyer
Building and using a 7 key chording keyboard
What is important for chording is to separate a key press from a key release. These actions send separate scancodes, and most keyboards use them.
If you are specifically interested in the logic, then reading the chorded keyboard wikipedia article may be helpful:
In Engelbart's original mapping, he used five keys: 1,2,4,8,16. The
keys were mapped as follows: a = 1, b = 2, c = 3, d = 4, and so on. If
the user pressed keys 1 + 2 = 3 simultaneously the letter "c"
appeared.
What you need to do is figure out which character is desired by looking at the combination of keys that are pressed down, but only send the character when all keys are released.
So if I pressed keys 1 and 2, then the bits for key 1 and key 2 are set, but the character is only determined and sent when I release all keys, at which point all the key bits are reset.
That is but one way to do it. It's your system, and you can make it arbitrarily complex.
Maybe you want to base it on n-gram frequency and send character phrases instead of single characters. Maybe you want to base it on sequences of letters pressed and released, with arbitrary chord sequence termination, rather than when you release all keys. It's up to you.
If you are using a normal keypad, and not one you built yourself, watch out for problems with key rollover. Basically, most keyboards have limits on which keys can be pressed at the same time.
The answer depends on the kernel version and the architecture that you are using.
If you are using an architecture that is supported in 3.1 or later then you can use the gpio-keys driver to create a keyboard event device file that you can configure in the OpenFirmware device tree and then read from userspace. The advantages of this approach over the approach suggested in the OP are that you do not have to write any new kernel code, and you can write your higher level driver entirely in userspace using a loop that does a blocking read on the device event file. (Now I realize that "not have to write any new kernel code" isn't nearly as cool as writing your own kernel module, so this might not be seen as an advantage by everyone ;-)
Even if you are using an older kernel, you can still use the gpio_keys driver using the older "board file" configuration approach used in the ADP5589 gpio driver suggested as a solution by user3072817. This still gives you the advantage of a device file on which you can do a blocking read from userspace.
To use the newer gpio-key approach you need to add a gpio-keys section to the device tree for your board, which should be located in arch/<your arch>/boot/dts. The syntax for the binding is specified in gpio_keys.txt. You can see an example gpio-keys device tree configuration for the Manga touchscreen on the BeagleBone here. This example also shows a gpio-key userspace driver, written in Python. Remember to compile your kernel with CONFIG_KEYBOARD_GPIO.

How to exit a gw basic program at any time?

I am creating a game and i want that if the user hit F10 or any other function key then they the program should end.
Kinda bad that you haven't had this answered...
Well to start, you will have to find the ASCII value of whatever key you would like to have be the exit.
To do this either make a simple program to figure it out using chr$,asc(),and an input. Or just search it real quick.
What you are going to want to do is in your games area where you are using an inkey$(Which I assume you are, because most games would have movement and that is almost required) and just check for the key being pressed along with every other key.
For Example:
A simple movement game:
10 cls
20 K$=inkey$
30 if K$="a" then REM move left
40 if K$="d" then REM move right
50 if K$= EXITKEY then REM EXIT
60 goto 20
-Also, sorry if this is the incorrect method, but this should work...I'm still a bit rusty on GW
I assume you are in the middle of some kind of BASIC program and you would like to 'get out', exit from this ?
Press ENTER to get to a BLANK space and type system, hit ENTER again and you are out!
For future searchers, this answer provides additional context to inform the design of mechanisms for exiting BASIC programs.
For some simplistically designed BASIC programs, the only method to exit is Control-C or Control-Break. But some emulators (such as DOSBox) do not process Control-C in a manner that will present it to the underlying program.
On some systems, you can press Ctrl-ScrollLock as a workaround:
I have a little trick for those interested: use Ctrl-ScrollLock, it
behaves like Ctrl-Break with many BASIC interpreters running within
DOSBox. It works with GW-BASIC, BASICA (often bundled with compatible
DOSes like Compaq's), QBasic, QuickBasic, and possibly other
development "workbench" interfaces.
The reason this works is a little complicated, so only read on if
you're interested in knowing. DOSBox does not have true Ctrl-Break
handling like real DOS, which is a combination of hardware and
software interrupts and internal flags. However, the DOS Ctrl-Break
handler is only a default handler that all starts with INT 9, the
keyboard hardware interrupt. Many of the program development apps hook
INT 9 and intercept keys before DOS sees them, so they can do their
own processing. After all, the DOS default behavior for Ctrl-Break is
to terminate the app, and that is often not what is wanted. The INT 9
handler code looks for the Control key being depressed by checking the
shift status byte in BIOS data, and then reads scancodes from the
keyboard data port 60h. The scancode for ScrollLock is 46h, and the
scancode for Ctrl-Break is a 2-byte "escaped" sequence of E0h 46h,
where E0h is the escape code. It seems the handler routines are often
not very rigorous in their processing of the escape code, and just
drop it, so Ctrl-ScrollLock ends up working the same as Ctrl-Break.
This code snip exits a program when function key is pressed in Qbasic:
DO
DO
' read keyboard
X$ = INKEY$
IF LEN(X$) THEN
EXIT DO
END IF
LOOP
IF LEN(X$) = 2 THEN
x = ASC(RIGHT$(X$, 1))
' exit program on F1 to F10
IF x >= 59 AND x <= 68 THEN
END
END IF
END IF
LOOP

Resources