View Single Post
Old 03-17-2024, 04:26 PM   #15
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
OSKANSI2 - NEW KEYDEFS, EXTRA LAYOUTS, AUTO DISPLAY SIZE, GRAB INPUT

***


OSKANSI2 - NEW KEYDEFS, EXTRA LAYOUTS, AUTO DISPLAY SIZE, GRAB INPUT


Some new key definitions available:

"DEL","INS","HOME","END"
"F1" - "F10" (though who knows if they work properly)
"EXIT" (kills oskansi - handy if OSK_GRABIN is set.)
"SYM" (Brings up Symbol keyboard layout.)
"S0" - "S99" (Extra symbol layouts can be defined.)
"ALT" (Really just sends an escape character before any normal character, i.e any character with "keyType"= 0. Will switch off after each character, i.e. ALT-a ALT-b requires two ALT key presses.)
"CTL" (Works only on a-z and A-Z. Now switches off after each character , like ALT.)
"TAB" (Now properly changes to SHIFT-TAB when "CAP" active.)
"CAP" (Now can be pressed twice consecutively without needing to press an intervening key.)


Oskansi2 can work with the same keyboard layout JSON files as the original oskansi (keymap1-en_us.json, keymap2-en_us.json), EXCEPT they now must be renamed to:
osk-keymap-LC.json
osk-keymap-UC.json

Plus you can have an optional symbol layout:
osk-keymap-S0.json

You can add additional symbol layouts (S1-S99) if you configure it in a configuration file:
osk-keymap-conf.json

The same configuration file can be used to define fonts and programmable key macros. Otherwise the font defaults to the same as it was for oskansi:
Roboto-Medium.ttf
For those concerned about the security aspect, programmable key macros are disabled in the three main layouts:
osk-keymap-LC.json
osk-keymap-UC.json
osk-keymap-S0.json


Examples of configuration file and symbol layouts are attached.


***

LANDSCAPE and PORTRAIT refer to NickelMenu entries:
# Nickel_Orientation Actions
menu_item : main : Orientation - LANDSCAPE - handle above : nickel_orientation: landscape
menu_item : main : Orientation - PORTRAIT - handle on right : nickel_orientation: portrait


Using with device in LANDSCAPE:

# OSK_XIN=1 OSK_YIN=3 OSK_HEIGHT=1000 OSK_REGEN=1 OSK_GRABIN=1 oskansi2


Back in PORTRAIT:

# oskansi2
Now has offset keyboard because still using the previous png files, so reset the env variables:

# OSK_XIN=4 OSK_YIN=1 OSK_HEIGHT=0 OSK_REGEN=1 OSK_GRABIN=0 oskansi2
The layout png files are regenerated for portrait. Now run without regen:

# oskansi2
Startup is fast without having to regenerate layout png images.



EXPLANATION:

The koboin.go input handler library was modified to handle a few experimental environmental variables, namely:


OSK_XIN, OSK_YIN: Set input orientation for x, y, to one of the following values:

1 -> x
2 -> reverse x
3 -> y
4 -> reverse y

If these variables are left undefined, they will default to the input orientation for the Clara HD in portrait mode, i.e. OSK_XIN=4 and OSK_YIN=1.


OSK_GRABIN: Grab input from /dev/input/event1. Nickel elements on the display no longer respond to touch.


Additional environment variables are handled by main.go:


OSK_WIDTH: Sent to osk.go and koboin.go to set display width.

OSK_HEIGHT: Sent to osk.go and koboin.go to set display height.

You can probably leave OSK_WIDTH and OSK_HEIGHT undefined, since oskansi2 now sets them to values returned by libFBInk (In previous oskansi they were hardcoded values similar to Clara HD size.)
This means oskansi2 could now in theory display properly on any Kobo device - but I don't have devices to test.
However, I can now run it in LANDSCAPE mode (provided I modify the OSK_XIN and OSK_YIN input orientation variables to match, found by trial and error).
That said, it can be helpful to tweak the OSK_HEIGHT value to slightly less than full-height, so as to leave a margin between keyboard and Nickel buttons at the bottom of the display (not too much or the touch alignment is skewed), if not grabbing input.


OSK_REGEN: Recreate all keyboard layout png images from JSON files. This is important if you have made changes to all the JSON files (or changed between PORTRAIT/LANDSCAPE orientation.) Otherwise oskansi2 will continue to use the existing png file and not reflect your changes.
However, if you have 98 layouts and only change the 99th JSON file, it makes more sense to just delete the png file #99 instead of using OSK_REGEN to recreate all 99 png files.


OSK_TTY: Set input tty to arbitrary input device, i.e. /dev/tty1.
This is helpful when fbpad is not running in the default (originally /dev/pts/0) tty expected by oskansi, usually because an ssh session had been run before.
Actually, oskansi2 has now been modified to look for $OSK_TTY first, then /dev/tty1., and then /dev/pts/0, so you can probably leave OSK_TTY undefined.


OSK_FONTMAIN: Override default font of Roboto-Medium.ttf


OSK_VERBOSE: Sends messages to fb, in addition to console.


The relevant changes to ~/go/src/github.com/shermp/go-kobo-input/koboin/koboin.go:
Code:
...
	"os"
	"strconv"
//	#include <linux/input.h>
	"C"
	"syscall"
	"unsafe"
)

const (
	EVIOCGRAB = C.EVIOCGRAB
)
var envstr string
var xin int
var yin int
...
// New creates a new TouchDevice struct and returns it to the caller
func New(inputPath string, vWidth, vHeight int) *TouchDevice {
	t := &TouchDevice{}
	f, err := os.OpenFile(inputPath, os.O_RDONLY, os.ModeDevice)
	if err != nil {
		fmt.Println("Could not open device for reading")
		return nil
	}
	t.devFile = f
	
	// Grab input if OSK_GRABIN set from env
	envstr = os.Getenv("OSK_GRABIN")
	fmt.Println("OSK_GRABIN is: ", envstr)
	var grabin, _ = strconv.Atoi(envstr)
	if (grabin > 0) {
		grabin = 1
	} else {
	 	grabin = 0
	}	
	if (grabin > 0) {
		grab1 := int(1)
		_, _, eno := syscall.Syscall(syscall.SYS_IOCTL,f.Fd(),uintptr(EVIOCGRAB) ,uintptr(unsafe.Pointer(&grab1)),)
		if eno != 0 {
			fmt.Println("OSK_GRABIN error: ", eno)
		}
	} 
			
	// Read input orientation from env
	envstr = os.Getenv("OSK_XIN")
	xin, _ = strconv.Atoi(envstr)	
	envstr = os.Getenv("OSK_YIN")
	yin, _ = strconv.Atoi(envstr)	
	t.viewWidth = vWidth
	t.viewHeight = vHeight
	return t
}
...
// GetInput returns the rotated x, y coordinates of where the user touches
func (t *TouchDevice) GetInput() (rx, ry int, err error) {
...
	/*
		Coordinate rotation needs to happen.
		For reference, from FBInk, a clockwise rotation is as follows:

		rx = y
		ry = width - x - 1

		But we need to rotate counter-clockwise...
	*/
	
	ry = x
	if (yin > 0 && yin < 5) {
		if (yin == 1) {
			ry = x
		} else if (yin == 2) {
			ry = t.viewHeight - x + 1
		} else if (yin == 3) {
			ry = y
		} else if (yin == 4) {
			ry = t.viewWidth - y + 1
		}
	}
				
	rx = t.viewWidth - y + 1
	if (xin > 0 && xin < 5) {
		if (xin == 1) {
			rx = x
		} else if (xin == 2) {
			rx = t.viewHeight - x + 1
		} else if (xin == 3) {
			rx = y
		} else if (xin == 4) {
			rx = t.viewWidth - y + 1
		}
	}

	return rx, ry, nil
}

Other coding changes were made to:
~/go/src/github.com/shermp/go-osk/osk/osk.go
~/go/src/github.com/shermp/go-kobo-input/koboin-osk-sample/main.go
(see attached source files)


***

USAGE:

Assuming you had moved everything to the /mnt/onboard/.adds/kordir/ folder as in previous post #14:

Copy and decompress the attached oskansi2 binary to the /mnt/onboard/.adds/kordir/scripts/ folder.

Copy and decompress the following to the /mnt/onboard/.adds/kordir/ folder:
Roboto-Medium.ttf
keymap1-en_us.json
keymap2-en_us.json

Set the path and move to /mnt/onboard/.adds/kordir/ folder:
# . /korenv.sh

You can run oskansi2 with these oskansi json files, but you have to rename them:
# cp keymap1-en_us.json osk-keymap-LC.json
# cp keymap2-en_us.json osk-keymap-UC.json

First run fbpad2:
# fbpad2 -p 58 /bin/sh 0</dev/tty1 &

Now run oskansi2 with OSK_REGEN to build the png images:
# OSK_REGEN=1 oskansi2
(Ctl-C to exit, or try the new EXIT key.)

To try the new symbol layout, copy and decompress the following to the /mnt/onboard/.adds/kordir/ folder:
osk-keymap-LC.json
osk-keymap-UC.json
osk-keymap-S0.json

Now run oskansi2 with OSK_REGEN to build the png images:
# OSK_REGEN=1 oskansi2
(Ctl-C to exit, or try the new EXIT key.)

To try the extra symbol layouts and programmable key macros, copy and decompress the following to the /mnt/onboard/.adds/kordir/ folder:
RobotoMono-Medium.ttf
osk-keymap-S1.json
osk-keymap-S2.json
osk-keymap-conf.json

Now run oskansi2 with OSK_REGEN to build the png images:
# OSK_REGEN=1 oskansi2
(Ctl-C to exit, or try the new EXIT key.)
* Note that the S2 layout is only 2 rows high, but you can press the SYM key to get back to the regular layout.


It's a good idea to have a separate directory for running oskansi2 in LANDSCAPE mode, so as not to have to regenerate the png image files each invocation.

# mkdir landscape
# cd landscape/

Copy all the above files to /mnt/onboard/.adds/kordir/landscape/, put device in LANDSCAPE and restart fbpad2:

# OSK_XIN=1 OSK_YIN=3 OSK_REGEN=1 OSK_GRABIN=1 oskansi2


You can do all this from NickelMenu with entries like:

menu_item :main :fbpad2 -p 58 :cmd_spawn :quiet :/mnt/onboard/.adds/kordir/scripts/fbpad2 -p 58 0</dev/tty1
chain_success :dbg_toast :Started fbpad2
chain_failure :dbg_toast :Error starting fbpad2

menu_item :main : oskansi2 :cmd_spawn :quiet:export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && OSK_GRABIN=1 /mnt/onboard/.adds/kordir/scripts/oskansi2
chain_success :dbg_toast :Started oskansi2
chain_failure :dbg_toast :Error

LANDSCAPE and PORTRAIT refer to NickelMenu entries:
# Nickel_Orientation Actions
menu_item : main : Orientation - LANDSCAPE - handle above : nickel_orientation: landscape
menu_item : main : Orientation - PORTRAIT - handle on right : nickel_orientation: portrait

menu_item :main : oskansi2 landscape :cmd_spawn :quiet:export HOME="/mnt/onboard/.adds/kordir/" && cd /mnt/onboard/.adds/kordir/landscape/ && OSK_XIN=1 OSK_YIN=3 OSK_GRABIN=1 /mnt/onboard/.adds/kordir/scripts/oskansi2
chain_success :dbg_toast :Started oskansi2
chain_failure :dbg_toast :Error

menu_item :main :fbpad2 -p 80 elinks :cmd_spawn :quiet :export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && export PATH="$PATH:/mnt/onboard/.adds/kordir/scripts" && export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/mnt/onboard/.adds/kordir/libs" && fbpad2 -p 80 elinks . 0</dev/tty1
chain_success :dbg_toast :Started fbpad2
chain_failure :dbg_toast :Error starting fbpad2


Note that if you run "fbpad2 -p 58 0</dev/tty1" like in the above entry, as opposed to "fbpad2 -p 58 /bin/sh 0</dev/tty1" (with the "/bin/sh"), you have to enter ALT-c from the keyboard to activate the shell. Maybe even repeat and press RET.

Unsure if the same kind of issues crop up like in UPDATE2 at the end of Post #10...

* Must rename oskansi2.zip to oskansi2.xz and extract with xz -d.


***
Attached Files
File Type: zip oskansi2-src.zip (176.3 KB, 77 views)
File Type: zip oskansi2.zip (1.05 MB, 35 views)

Last edited by elinkser; 03-17-2024 at 04:33 PM.
elinkser is offline   Reply With Quote