| 
			
			 | 
		#1 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
		
		
		 
			
			*** SECURITY REMINDER *** 
		
	
		
		
		
		
		
		
		
		
		
		
		
			You are browsing as root on an outdated kernel that is not likely to see timely security patches. You should at least create a non-root user (e.g. using adduser), but they would need permission to use the framebuffer i.e. FBInk, if they want to use the graphical image viewer feature. To create a user 'fbuser' with framebuffer access you can do the following: adduser fbuser addgroup fbgroup adduser fbuser fbgroup chgrp fbgroup /dev/fb0 But it looks like you have to redo that last chgrp command each session. Furthermore, Kobo seems to have disallowed write access to /mnt/onboard to anyone but root, so other users cannot save bookmarks to .elinks/ but they can at least save downloads to the /tmp directory (of course you then have to copy them as root to a more permanent location). *NOTE* You can edit the "umask 002" line in /etc/init.d/rcS to "umask 000" allow all user write access to the /mnt/onboard partition, but that would defeat the security objective. You can't have fine-grained access permission because it is a vfat format. When you create a user with "adduser bla", a /home/bla directory is created on the root partition, which DOES have fine-grained access controls, as you can see by running "ls -l /home". But the root partition doesn't have much free space, only about 60MB, as you can see by running "df". So you may prefer "adduser bla -d /mnt/onboard/.adds/koreader/home/bla" to put the home directory on the /mnt/onboard partition which has many GB of free space, which the user won't be able to write to, but at least it doesn't use up valuable root partition space. In retrospect I should have crosscompiled using "--prefix=/mnt/onboard/.adds/koreader/templib" on my desktop instead of "--prefix=$HOME/Downloads/mykobossh/templib", so I wouldn't have to use up valuable root partition space with all the certificates, as you will see. The links near the bottom of this post point to an alternative approach using a chroot. Clara HD owners also have the option to pull out the SD card and shrink the /mnt/onboard partition with a disk utility, then creating a new /home partition that is writable by non-root users. But non-Clara owners can still create a /home partition in an image file, as was done here, (but no need to create root file system - just format it and mount it.) **EDIT - Comment #3 has another way to get elinks by copying and may be easier. Otherwise: 1.Back up your SD card. 2.Don't use your Kobo for sensitive info including passwords. 3.Don't browse to unsafe sites. Or just use Firefox on your desktop to save complete webpage with image folder, or print to pdf on your cellphone, these can be webserved to your Kobo for secure graphic browsing using KOReader! As mentioned here *** HOW TO CROSSCOMPILE ELINKS AND WGET FOR THE KOBO CLARA HD (using linux desktop). --- First, follow the instructions here to determine the crosscompile tool for your device. For the Kobo Clara HD, it is gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz. Download this and source packages for openssl, elinks, and wget to $HOME/Downloads/mykobossh/. --- To build OPENSSL: (see also) cd cd Downloads/mykobossh/ tar xJf gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz export PATH=$PWD/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf/bin:$PATH tar zxvf openssl-1.1.1s.tar.gz cd openssl-1.1.1s/ mkdir $HOME/Downloads/mykobossh/templib ./Configure gcc -static -no-shared --prefix=$HOME/Downloads/mykobossh/templib --cross-compile-prefix=arm-linux-gnueabihf- make make install cd .. --- To build ELINKS: (see also) tar zxvf elinks-0.15.1.tar.gz cd elinks-0.15.1/ ./autogen.sh ./configure --help ./configure --host=arm-linux-gnueabihf --enable-own-libc --enable-sm-scripting --disable-nls --disable-xbel --disable-ipv6 --disable-leds --disable-backtrace --with-static --without-zlib --without-bzlib --without-gnutls --with-openssl=$HOME/Downloads/mykobossh/templib CPPFLAGS="-I$HOME/Downloads/mykobossh/templib/include" LDFLAGS="-L$HOME/Downloads/mykobossh/templib/lib" make cp src/elinks ../elinks111s cd .. --- DEVICE: Copy elinks111s to .adds/koreader/scripts directory on Kobo Clara HD. Run KOReader and connect to WIFI on Clara HD. Open Terminal Emulator and you will see elinks111s in working directory (/mnt/onboard/.adds/koreader/scripts). chmod +x elinks111s elinks111s (enter "mobileread.mobi/forums/") (keep pressing return key if get ssl error message) ***EDIT*** It helps to copy certificates to a $HOME/Downloads/mykobossh/templib/ssl/certs directory that you must create on your Kobo, where $HOME is /home/user, or whatever your desktop home directory was. I got certificates from my desktop /usr/share/ca-certificates/mozilla directory, but your case may differ. Also, a heavy page like amazon might stall, but I press q then cancel and it seems to get going again! *Update-wget seems to handle certs differently. A workaround might be to copy the ca-certificates.crt file from your desktop (mine was in /etc/ssl/certs) to the above directory, and let wget know by creating a .wgetrc file in /mnt/onboard/.adds/koreader with the single line: ca_certificate=/home/user/Downloads/mykobossh/templib/ssl/certs/ca-certificates.crt (or wherever you saved it). ** Update-Courtesy of qkqw's post, here is another source of Mozilla CA certificates from the Curl website. *** Press Esc key and down arrow key to get menu and key codes. Use spacebar for pagedown and 'b' for pageup, 'g' followed by '.' to browse local filesystem. Press q (followed by return key) to quit --- NiLuJe's FBInk can be configured as an image viewer for elinks, except the image gets quickly overwritten. But it is there long enough to decide if you want to download it. Turns out I had to not use the FBInk that came with my installed KOReader but to download it separately from here. EDIT elinks.conf FILE IN .elinks/ (TO CONFIGURE fbink AS IMAGE VIEWER): set document.browse.images.display_style = 1 set document.browse.images.filename_maxlen = 50 set document.browse.images.image_link_tagging = 2 set document.browse.images.show_as_links = 1 set mime.extension.jpg="image/jpeg" set mime.extension.jpeg="image/jpeg" set mime.extension.png="image/png" set mime.extension.gif="image/gif" set mime.extension.bmp="image/bmp" set mime.extension.pnm="image/pnm" set mime.handler.image_viewer.unix.ask = 1 set mime.handler.image_viewer.unix-xwin.ask = 0 set mime.handler.image_viewer.unix.block = 1 set mime.handler.image_viewer.unix-xwin.block = 0 set mime.handler.image_viewer.unix.program = "/mnt/onboard/.adds/koreader/scripts/fbink -g file=%" set mime.handler.image_viewer.unix-xwin.program = "/mnt/onboard/.adds/koreader/scripts/fbink -g file=%" set mime.type.image.jpg = "image_viewer" set mime.type.image.jpeg = "image_viewer" set mime.type.image.png = "image_viewer" set mime.type.image.gif = "image_viewer" set mime.type.image.bmp = "image_viewer" set mime.type.image.pnm = "image_viewer" --- *EDIT* Actually "fbink -G -g file=% ;sleep 2" keeps the image longer. I tried appending 2>/dev/null but that only helps outside of elinks. *You need that space between "%" and ";" for some reason. Another option is: "fbink -G -y 30 -g file=% ;sleep 2" Which keeps the image to the lower part of the display, so it doesn't get overwritten. --- To build WGET: (see also) tar zxvf wget-1.21.tar.gz cd wget-1.21/ ./configure --help env CPPFLAGS="-I$HOME/Downloads/mykobossh/templib/include" LDFLAGS="-L$HOME/Downloads/mykobossh/templib/lib" ./configure --with-ssl=openssl --with-libssl-prefix=$HOME/Downloads/mykobossh/templib --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf --disable-nls --disable-ipv6 --without-zlib make CPPFLAGS="-I$HOME/Downloads/mykobossh/templib/include" LDFLAGS="-L/$HOME/Downloads/mykobossh/templib/lib -static" cp src/wget ../wget111s DEVICE: Copy wget111s to .adds/koreader/scripts directory on Kobo Clara HD. Run KOReader and connect to WIFI on Clara HD. Open Terminal Emulator and you will see wget111s in working directory (/mnt/onboard/.adds/koreader/scripts). chmod +x wget111s wget111s google.com ls index.html Here is a more sophisticated use: ***NOTE THE VERY IMPORTANT OPTION '-Q50M' WHICH LIMITS DOWNLOAD TO 50MB !!!*** (this is to keep you from inadvertently "downloading the internet") wget111s --no-check-certificate --no-parent -k -nd -D www.mobileread.mobi -E -r -A jpg,jpeg,png,gif,htm.html -l1 -Q50M -P ./mywgets/ www.mobileread.mobi/forums/ ------ THE NEXT SECTIONS ARE OPTIONAL, IF YOU WANT AN ASCIIVIEW IMAGE VIEWER. *It is for ascii images - not high resolution images, from when I could not get NiLuJe's FBInk to work within elinks. So this is mostly just a fun substitute! Spoiler: 
 Finally, if you have gotten this far and said, whew, that was a lot, then "HOWTO Create your own native development environment on your Kobo!" might be making a lot more sense now! *EDIT:Looks like graphical browser with Xorg is also available via chroot. Extra Clara HD config steps on post #46.. So there you have an almost graphical browser. *Actually, if you use wget (the real one you compiled above, or maybe the cURL binary installed from NiLuJe's kobostuff package - not the stripped-down one that comes with KOReader) you can with a little practice download a page WITH images and that can be opened WITH IMAGES(if they are local, like saved as complete webpage by Firefox) in KOReader for a graphical view! Last edited by elinkser; 09-17-2024 at 03:25 PM. Reason: alt install,mobi link  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#2 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
		
		
		 
			
			***TO DOWNLOAD "COMPLETE" WEB PAGE (Firefox-style)*** 
		
	
		
		
		
		
		
		
		
		
		
		
		
			Follow instructions at this link to add uri passing to our cross-compiled wget111s command from above, except name the entry "wgets", use the command "wget111s --no-check-certificate --show-progress -nd -E -k -p -Q20M %c", and assign keybinding "Ctrl-W". Press ENTER key and save by tabbing to the "SAVE" button and pressing ENTER, then ESC to get back to current page. Now, if you press g, then "g" for google, followed by ENTER, elinks will take you to the google search page. Enter "Ctl-w" and complete web page is saved to current directory. To verify, press g, then "." for current local directory, followed by ENTER, then maybe "Ctrl-r" to refresh cache, and a few down-arrow presses to scroll, and voila, your complete web page with images! Now if you want to browse this page in the luxury of the KOReader environment, turn off networking to be sure you are looking at locally saved files, and browse to your download directory in KOReader to see the "complete" web page with images displayed. *Note-this option was done while running elinks111s as root, so that the change would be written to the elinks.conf file. *LONG INSTRUCTIONS FROM LINK: Spoiler: 
 
		Last edited by elinkser; 01-16-2023 at 01:06 PM. Reason: remove link dependency  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#3 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
		
		
		 
			
			***PLS SEE SECURITY REMINDER ON TOP POST*** 
		
	
		
		
		
		
		
		
		
		
		
		
		
			COPYING ELINKS BINARY TO KOBO CLARA HD WITHOUT COMPILING OR CHROOT: (Some may find this an easier way to get the elinks browser.) You can see dependencies of elinks from here. Depends (6) libbz2 libcrypto3 libexpat libssl3 musl zlib You can get the packages from here. You can get a CA certificate store from here. DOWNLOAD THE REQUIRED PACKAGES: $ wget https://dl-cdn.alpinelinux.org/alpin...-0.15.1-r1.apk $ wget https://dl-cdn.alpinelinux.org/alpin...2-1.0.8-r4.apk $ wget https://dl-cdn.alpinelinux.org/alpin...3-3.0.8-r1.apk $ wget https://dl-cdn.alpinelinux.org/alpin...t-2.5.0-r0.apk $ wget https://dl-cdn.alpinelinux.org/alpin...3-3.0.8-r1.apk $ wget https://dl-cdn.alpinelinux.org/alpin...l-1.2.3-r4.apk $ wget https://dl-cdn.alpinelinux.org/alpin...-1.2.13-r0.apk $ wget https://curl.se/ca/cacert.pem RUN THESE COMMANDS FROM LINUX DESKTOP OR ENVIRONMENT(really just need to unarchive and copy some files, but the tar command fails if you try it on the vfat filesystem /mnt/onboard of the Kobo because of vfat not supporting symlinks. I didn't try on the root filesystem partition e.g. /opt): $ mkdir myalpine $ cd myalpine/ $ tar zxvf elinks-0.15.1-r1.apk $ tar zxvf libbz2-1.0.8-r4.apk $ tar zxvf libcrypto3-3.0.8-r1.apk $ tar zxvf libexpat-2.5.0-r0.apk $ tar zxvf libssl3-3.0.8-r1.apk $ tar zxvf musl-1.2.3-r4.apk $ tar zxvf zlib-1.2.13-r0.apk $ mkdir scripts $ mv usr/bin/elinks scripts/ $ ls -l scripts/ -rwxr-xr-x 923356 elinks $ mkdir libs $ mv usr/lib/libbz2.so.1.0.8 libs/libbz2.so.1 $ mv lib/libcrypto.so.3 libs/ $ mv usr/lib/libexpat.so.1.8.10 libs/libexpat.so.1 $ mv lib/libssl.so.3 libs/ $ cp lib/ld-musl-armhf.so.1 libs/libc.musl-armv7.so.1 $ mv lib/ld-musl-armhf.so.1 libs/ $ mv lib/libz.so.1.2.13 libs/libz.so.1 $ ls -l libs -rwxr-xr-x 525980 ld-musl-armhf.so.1 -rwxr-xr-x 69772 libbz2.so.1 -rwxr-xr-x 525980 libc.musl-armv7.so.1 -rwxr-xr-x 2233828 libcrypto.so.3 -rwxr-xr-x 132444 libexpat.so.1 -rwxr-xr-x 405904 libssl.so.3 -rwxr-xr-x 66856 libz.so.1 $ cp cacert.pem cert.pm $ mkdir certs $ cp cacert.pem certs/ca-certificates.crt NOW CONNECT YOUR KOBO TO YOUR PC: Note the contents of /mnt/onboard/.adds/koreader/scripts/ does not have any elinks binary. Copy your elinks binary from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. Note the contents of /mnt/onboard/.adds/koreader/libs/ already has a libz.so.1 lib. Copy all libs except libz.so.1 from the libs/ folder on the PC to the /mnt/onboard/.adds/koreader/libs/ folder on the kobo. Note that these new libs all have a different date than the default pre-existing libs. Copy your cert.pm and certs/ca-certificates.crt to the /etc/ssl/ directory.(You may notice there is already one in the /mnt/onboard/.adds/koreader/data/ folder anyway.) RUN THESE COMMANDS IN KOREADER TERMINAL, OR FROM A TELNET/SSH CLIENT CONNECTION: ***SECURITY REMINDER*** Telnet sessions are in cleartext INCLUDING LOGIN SESSIONS, so only use on a private network, if at all! If you always have DEVMODE set to ON for whatever reasons , that means Telnet is on by default, unless you toggle it off , e.g. using NickelMenu. You can install KOReader to get the more secure SSH option, and NiLuJe's kobostuff provides a package that includes an SSH binary. You can start the KOReader SSH server via NickelMenu. ********************************** IF RUNNING FROM KOREADER TERMINAL: # elinks IF RUNNING FROM A TELNET/SSH CLIENT CONNECTION: # cd /mnt/onboard/.adds/koreader/ # export LD_LIBRARY_PATH=/mnt/onboard/.adds/koreader/libs/ # echo $LD_LIBRARY_PATH # ./scripts/elinks You then enter '.' to see current working directory, or enter a web address (just keep pressing return if you get SSL errors). Up and Down arrows to traverse the links. Left and Right arrows to follow link or go back. Space and 'b' to page forward and back. '[' and ']' to go left and right. Enter to edit a text field, 'd' to download link. 'a' to add a bookmark, 's' to see them, TAB to move through options. ESC followed by Down arrow and Left/Right arrows to see menus. 'g' to enter a new address, 'q' to quit. ALL THIS WORKED FOR ME, BUT I AM UNSURE IF IT IS BECAUSE OF SOMETHING I INSTALLED PREVIOUSLY! YMMVVVVVVVVVVVVVV..... *** ***ADDENDUM - NANO AND WGET*** The nano editor has only the following dependencies: Depends (2) musl* ncurses-libs And it's not much additional effort to add wget . Depends (6) libcrypto3* libidn2 libssl3* musl* pcre2 zlib* *already got these from elinks install. DOWNLOAD THE REQUIRED PACKAGES: $ wget https://dl-cdn.alpinelinux.org/alpin...ano-7.0-r0.apk $ wget https://dl-cdn.alpinelinux.org/alpin...0221119-r0.apk $ wget https://dl-cdn.alpinelinux.org/alpin...0221119-r0.apk (a dependency of ncurses-libs) $ wget https://dl-cdn.alpinelinux.org/alpin...-1.21.3-r2.apk $ wget https://dl-cdn.alpinelinux.org/alpin...2-2.3.4-r0.apk $ wget https://dl-cdn.alpinelinux.org/alpin...ing-1.1-r0.apk (a dependency of libidn2) $ wget https://dl-cdn.alpinelinux.org/alpin...2-10.42-r0.apk RUN THESE COMMANDS FROM LINUX DESKTOP: $ cd myalpine/ $ tar zxvf nano-7.0-r0.apk $ tar zxvf ncurses-libs-6.3_p20221119-r0.apk $ tar zxvf ncurses-terminfo-base-6.3_p20221119-r0.apk $ tar zxvf wget-1.21.3-r2.apk $ tar zxvf libidn2-2.3.4-r0.apk $ tar zxvf libunistring-1.1-r0.apk $ tar zxvf pcre2-10.42-r0.apk $ mv usr/bin/nano scripts/ $ mv usr/lib/libformw.so.6.3 libs/libformw.so.6 $ mv usr/lib/libmenuw.so.6.3 libs/libmenuw.so.6 $ mv usr/lib/libncursesw.so.6.3 libs/libncursesw.so.6 $ mv usr/lib/libpanelw.so.6.3 libs/libpanelw.so.6 $ mv usr/bin/wget scripts/wgets $ mv usr/lib/libidn2.so.0.3.8 libs/libidn2.so.0 $ mv usr/lib/libunistring.so.5.0.0 libs/libunistring.so.5 $ mv usr/lib/libpcre2-8.so.0.11.2 libs/libpcre2-8.so.0 $ mv usr/lib/libpcre2-posix.so.3.0.4 libs/libpcre2-posix.so.3 NOW CONNECT YOUR KOBO TO YOUR PC: Copy your nano/wgets binaries from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. Copy new libs from the libs/ folder on the PC to the /mnt/onboard/.adds/koreader/libs/ folder on the kobo: libformw.so.6 libmenuw.so.6 libncursesw.so.6 libpanelw.so.6 libidn2.so.0 libunistring.so.5 libpcre2-8.so.0 libpcre2-posix.so.3 Copy your etc/terminfo directory to the /etc/ directory. RUN THESE FROM KOREADER TERMINAL: # nano (Ctrl-x to exit) # /usr/bin/wget BusyBox v1.31.1.kobo (2020-04-22 11:41:43 EDT) multi-call binary. ... # wgets -V GNU Wget 1.21.3 built on linux-musleabihf. ... # wgets -O mr.html https://www.mobileread.com/forums/sh...91&postcount=3 (Ctrl-c if it hangs) # elinks mr.html (q to exit) IF RUNNING FROM A TELNET/SSH CLIENT CONNECTION: CREATE THE FILE "/korenv.sh": #!/bin/sh export PATH=/mnt/onboard/.adds/koreader/scripts:/mnt/onboard/.adds/koreader/plugins/terminal.koplugin/:$PATH export LD_LIBRARY_PATH=/mnt/onboard/.adds/koreader/libs:$LD_LIBRARY_PATH export TERM=xterm export HOME=/mnt/onboard/.adds/koreader/ cd $HOME Run the command " . ./korenv.sh" Then run the commands from above. (You will also be able to run the KOReader file manager as just "shfm", as listed here . *** TRY THE W3M BROWSER AS AN ALTERNATIVE TO ELINKS: The w3m web browser has only the following dependencies: Depends (6) gc libcrypto3* libssl3* musl* ncurses-libs* zlib* *already got these from elinks and nano installs. $ wget https://dl-cdn.alpinelinux.org/alpin...0220429-r3.apk $ wget https://dl-cdn.alpinelinux.org/alpin...c-8.2.2-r0.apk $ wget https://dl-cdn.alpinelinux.org/alpin...0220924-r4.apk (a dependency of gc) $ wget https://dl-cdn.alpinelinux.org/alpin...0220924-r4.apk (a dependency of gc) $ tar zxvf w3m-0.5.3.20220429-r3.apk $ tar zxvf gc-8.2.2-r0.apk $ tar zxvf libgcc-12.2.1_git20220924-r4.apk $ tar zxvf libstdc++-12.2.1_git20220924-r4.apk $ mv usr/bin/w3m scripts/ $ cp -r usr/lib/w3m libs/ $ mv usr/share/w3m/w3mhelp.html libs/w3m/ $ mv usr/lib/libcord.so.1.5.0 libs/libcord.so.1 $ mv usr/lib/libgc.so.1.5.1 libs/libgc.so.1 $ mv usr/lib/libgctba.so.1.5.0 libs/libgctba.so.1 $ mv usr/lib/libgcc_s.so.1 libs/libgcc_s.so.1 $ mv usr/lib/libstdc++.so.6.0.30 libs/libstdc++.so.6 NOW CONNECT YOUR KOBO TO YOUR PC: Copy your w3m binary from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. Copy new libs from the libs/ folder on the PC to the /mnt/onboard/.adds/koreader/libs/ folder on the kobo: w3m/ libcord.so.1 libgc.so.1 libgctba.so.1 libgcc_s.so.1 libstdc++.so.6 RUN THESE FROM KOREADER TERMINAL: # cp -r libs/w3m/ /usr/lib/ # w3m -v ('U' to open link,e.g. http://w3m.sourceforge.net/ or https://github.com/tats/w3m , 'q' to quit) ('o' to get option list Space down to Color Settings->Display with color Tab to No Enter Space down to bottom of options page Tab or Esc-Tab to OK Enter 'q' , 'y' to quit) *** When upgrading to OCP-KOReader-v2023.06 and copying libs from my old KOReader setup, KOReader would crash when opening pdf files. The crash was because of libs installed for the w3m browser. w3m libs not needed: libgcc_s.so.1 libgctba.so.1 * this lib would crash KOReader when opening pdf files * Ironically, if I don't copy those two libs to the new KOReader installation, w3m seems to work fine anyway. *** ABBREVIATED OUTPUT OF "elinks -dump libs/w3m/w3mhelp.html": Spoiler: 
 ***ADD A COUPLE OF GAMES*** The moon-buggy arcade shooting game has only the following dependencies: Depends (2) libncursesw** musl* * Already got it from the Elinks/Nano install above. ** Already got the equivalent from the Nano install above. The ttyper typing test game has only the following dependencies: Depends (2) libgcc** musl* * Already got it from the Elinks/Nano install above. ** Already got it as a gc subdependency from the W3m install above. DOWNLOAD THE REQUIRED PACKAGES: wget https://dl-cdn.alpinelinux.org/alpin...-1.0.51-r1.apk wget https://dl-cdn.alpinelinux.org/alpin...r-1.2.0-r1.apk RUN THESE COMMANDS FROM LINUX DESKTOP: $ cd myalpine/ $ tar zxvf moon-buggy-1.0.51-r1.apk $ mv usr/bin/moon-buggy scripts/ $ tar zxvf ttyper-1.2.0-r1.apk $ mv usr/bin/ttyper scripts/ NOW CONNECT YOUR KOBO TO YOUR PC: Copy your moon-buggy/ttyper binaries from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. RUN THESE FROM KOREADER TERMINAL: # moon-buggy (Space to jump, 'a' to fire, 'q' to quit) # ttyper -w 5 (type any letter followed by backspace to see 5-word list, then type each word followed by a space. Slide up the right scrollbar to see score.) *** ***NOTE*** The links provided were valid at the time, and should be good for a while, especially if they are all from the same branch, i.e. 3.17 in this case. But if you download packages from the edge branch, as was the case for moon-buggy, its dependencies will keep changing as the rolling edge branch keeps updating. So at some point the provided links will be out of date, and you would have to search for the package yourself in the edge branch or the latest branch(e.g. 3.18): https://pkgs.alpinelinux.org/packages?arch=armv7 This would list the up-to-date dependencies. Then download the required binary the from the appropriate repository: https://dl-cdn.alpinelinux.org/alpine/ *** Last edited by elinkser; 09-18-2023 at 07:28 PM. Reason: nano wgets + games + w3m libs not needed + edge note  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#4 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				Fbpad
			 
			
			
			Fbpad and Inkvt 
		
	
		
		
			There was a framebuffer-based terminal emulator that runs on the Clara HD (you have to compile it), which you can control from your phone or PC keyboard: https://www.mobileread.com/forums/sh...d.php?t=298877 These are the build directions if you have a couple of hours to kill (binary attached for your convenience.) *** On a debian PC: koreader/koxtoolchain https://github.com/koreader/koxtoolchain $ git clone https://github.com/koreader/koxtoolchain.git $ cd koxtoolchain/ $ sudo apt-get install build-essential autoconf automake bison flex gawk libtool libtool-bin libncurses-dev curl file git gperf help2man texinfo unzip wget $ ./gen-tc.sh kobo (2 hours build time on an Acer Chromebook 11 converted to an MX Linux workstation) $ cd .. *** $ mkdir fbpad-build $ cd fbpad-build/ JulianDroske/fbpads https://github.com/JulianDroske/fbpads forked from aligrudi/fbpad $ wget https://github.com/JulianDroske/fbpa...ads/master.zip $ unzip fbpads-master.zip $ cd fbpads-master/ $ make $ cd fbpad_mkfn/ $ make $ nano -l gen.sh 5 OP="-h34 -w19" 6 SZ="18h135v135" 7 # OP="-h26 -w14" 8 # SZ="18h100v100" $ ./gen.sh $ cd .. $ cd .. *** NiLuJe/FBInk https://github.com/NiLuJe/FBInk/releases $ wget https://github.com/NiLuJe/FBInk/rele...v1.25.0.tar.xz $ tar xJf FBInk-v1.25.0.tar.xz $ cd FBInk-v1.25.0/ $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare $ make static stripped $ cd .. ddvk / fbpad-eink forked from kisonecat/fbpad-eink https://github.com/ddvk/fbpad-eink $ wget https://github.com/ddvk/fbpad-eink/a...ads/master.zip $ unzip fbpad-eink-master.zip $ cd fbpad-eink-master/ $ cp -r ../FBInk-v1.25.0/Release FBInk/ $ cp ../FBInk-v1.25.0/fbink.h FBInk/ $ cp ../fbpads-master/fbpad_mkfn/ar.tf fonts/ $ cp ../fbpads-master/fbpad_mkfn/ai.tf fonts/ $ cp ../fbpads-master/fbpad_mkfn/ab.tf fonts/ $ nano -l conf.h 17 typedef int fbval_t; ... 20 #define FR "ab.tf" 21 #define FI "ab.tf" 22 #define FB "ab.tf" $ nano -l Makefile 3 CC := arm-kobo-linux-gnueabihf-gcc ... 10 xxd -i fonts/ab.tf > font.h $ nano -l font.c 40 memcpy(&head, fonts_ab_tf, sizeof(head)); ... 46 font->glyphs = (int*)(fonts_ab_tf + sizeof(head)); 47 font->data =(char*) (fonts_ab_tf + sizeof(head) + font->n * sizeof(int)); $ xxd -i fonts/ab.tf > font.h $ make $ file fbpad fbpad: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.33, with debug_info, not stripped $ cd .. *** Copy the fbpad binary to the /mnt/onboard/.adds/koreader/scripts/ directory on your Kobo. On a ssh session to your Kobo (from phone or PC): $ ssh root@192.168.2.2 -p 2222 # . /korenv.sh # fbpad /bin/sh # pwd Works in landscape too. (Try elinks if you have good eyesight.)UPDATE- Fixed font size - now very readable. Hit the lower right corner of the screen and the nickel menu comes up. Ctl-Alt-q to quit If that doesn't work, try "pkill fbpad". *** How about let's change the default elinks keybindings to allow normal use of arrow keys: The hard way (see below for the easier way): In elinks, press 'k' to bring up Keybinding manager. Press Space to expand [+]- Main mapping. Use Right arrow to move focus to Delete tab. Use Down arrow to scroll to and delete the following: [-]- Move to the next frame: Tab [-]- Move to the previous frame: Shift-Tab [-]- Return to the previous document in history: Left [-]- Go forward in history: u [-]- Follow the current link: Right [-]- Follow the current link, forcing reload...: Ctrl-Right [-]- Open a lua Console: , [-]- Move to the next link: Down [-]- Move to the previous link: Up [-]- Move downwards by a page: Ctrl-F [-]- Move upwards by a page: Ctrl-B [-]- Search link text by typing ahead: # [-]- Toggle displaying of links numbers: . Use Right arrow to move focus to Save tab. Save and Close. Press 'k' to bring up Keybinding manager again. Press Space to expand [+]- Main mapping, or Up arrow to scroll to the top if already expanded. Use Left/Right arrow to focus on Add tab. Use Down arrow to scroll to and add the following: [-]- Move to the next frame: Ctrl-f [-]- Move to the previous frame: Ctrl-b [-]- Return to the previous document in history: , [-]- Go forward in history: . [-]- Show information about current link: u [-]- Open a lua Console: Alt-l [-]- Move cursor down: Down [-]- Move cursor left: Left [-]- Move cursor right: Right [-]- Move cursor up: Up [-]- Move to the next link: Tab [-]- Move to the previous link: Shift-Tab [-]- Toggle displaying of links numbers: # Use Right arrow to move focus to Save tab. Save and Close. The easier way: Or you could just append to the end of the config file: $ vi .elinks/elinks.conf Code: 
	################################## # Automatically saved keybindings # bind "main" "Ctrl-F" = "frame-next" bind "main" "Ctrl-B" = "frame-prev" bind "main" "," = "history-move-back" bind "main" "." = "history-move-forward" bind "main" "u" = "link-info" bind "main" "Alt-l" = "lua-console" bind "main" "Down" = "move-cursor-down" bind "main" "Left" = "move-cursor-left" bind "main" "Right" = "move-cursor-right" bind "main" "Up" = "move-cursor-up" bind "main" "Tab" = "move-link-next" bind "main" "Shift-Tab" = "move-link-prev" bind "main" "#" = "toggle-numbered-links" bind "main" "Ctrl-Right" = "none" So the new way of navigating in elinks would be: On startup, enter '.' to see current working directory, or enter a web address. Tab and Shift-Tab to traverse the links. Enter to follow link or '.' and ',' to go forward and back. Space and 'b' to page forward and back. '[' and ']' to go left and right. Enter to edit a text field, 'd' to download link. 'a' to add a bookmark, 's' to see them, TAB to move through options. ESC followed by Down arrow and Left/Right arrows to see menus. 'g' to enter a new address, 'q' to quit. Main difference being now able to move around the page with arrows keys. Old Down/Up link travelling replaced by Tab/Shift-Tab, and old Left/Right history traversing replaced by ','/'.'. *** Also get rid of the colors in the ls command by appending this to the /korenv.sh file: # vi /korenv.sh Code: 
	#!/bin/sh export PATH=$PATH:/mnt/onboard/.adds/koreader/scripts:/mnt/onboard/.adds/koreader/plugins/terminal.k export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/onboard/.adds/koreader/libs export TERM=xterm export HOME=/mnt/onboard/.adds/koreader/ cd $HOME alias ls='ls --color=never' But it seems you have to run it again after running fbpad. *** To get rid of the colors in the w3m browser: In w3m, normally press 'o' to bring up the Option Setting Panel. Scroll down to the second group, Color Settings. Put the cursor on the first entry: Display with color. Tab to the ()NO option and press enter. Scroll to the end of the section, tab to the [OK], and press enter. Or just edit the config file: $ nano -l .w3m/config 38 color 0 But w3m doesn't handle very well fbpad with large font/low number of columns. Or at all, as you can see with the small-font "fbpads" that I reuploaded. Note: the "fbpads" I uploaded means "fbpad with Small font", not because it is the above JulianDroske/fbpads that I exploited earlier in the post for its font setup. Sorry for any confusion. *** Networking note: In Quitting Telnet Habit , I said that I wanted to quit telnet and turn off devmode ( Go to the Discover tab and search the store for "devmodeoff"). meaning I lost the "ForceWifiOn=true" option in [DeveloperSettings] in the /mnt/onboard/.kobo/Kobo/Kobo eReader.conf file. Unfortunately I now find the WiFi connection cutting out. Others have said leaving the Wifi applet dialog open helps, so I am trying that. *** * UPDATE: You do NOT need DEVMODEON to set the "ForceWifiOn=true" option in [DeveloperSettings] in the /mnt/onboard/.kobo/Kobo/Kobo eReader.conf file. I tested it that WiFi shuts off automatically after 1-2 minutes of inactivity, but will stay on if "ForceWifiOn=true" in [DeveloperSettings] in the /mnt/onboard/.kobo/Kobo/Kobo eReader.conf file, EVEN IF DEVMODEOFF. Also, interestingly, "EnableDebugServices=false" stopped telnet and logread from running automatically even if DEVMODEOFF. Unfortunately, that option stopped my oskansi fbpad terminal from working. I will need to investigate that.., *** Here's one with keyboard: NiLuJe/inkvt forked from llandsmeer/inkvt https://github.com/NiLuJe/inkvt $ mkdir inkpad-build $ cd inkpad-build/ $ wget http://http.us.debian.org/debian/poo....1.1-1_all.deb $ sudo dpkg -i libcxxopts-dev_3.1.1-1_all.deb OR $ sudo apt install libcxxopts-dev $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare $ cp ../fbpad-build/FBInk-v1.25.0.tar.xz . $ tar xJf FBInk-v1.25.0.tar.xz $ wget https://github.com/NiLuJe/inkvt/arch...ads/master.zip $ unzip master.zip $ mv master.zip inkvt-master.zip $ cd inkvt-master/ $ mv ../FBInk-v1.25.0/* FBInk/ $ mkdir cxxopts/include $ cp /usr/include/cxxopts.hpp cxxopts/include/ $ make release Extract InkVT-.zip to Kobo. InkVT erminal comes up, elinks working great, until screen froze. Update: Crashed my device, and somehow an update was triggered even though SideloadedMode=true. Note developer's warning on inkVT github page: Warning: this project is very experimental! It might brick your device. Only install this if you know what you are doing. Happy with just fbpad for now. Last edited by elinkser; 11-30-2023 at 06:20 PM. Reason: UPDATE- Fixed font size - fbpad big font, fbpads small, inkvt  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#5 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				Fbpad & USB
			 
			
			
			It seems there is somewhat flaky support for USB keyboard for fbpad on the Kobo, if you have some productive time to fritter away... 
		
	
		
		
		
		
		
		
		
		
		
		
		
			* requires USB host support: https://www.mobileread.com/forums/sh...d.php?t=340418 DOWNLOAD THE AGETTY PACKAGE: $ cd myalpine/ $ wget https://dl-cdn.alpinelinux.org/alpin...-2.38.1-r1.apk RUN THESE COMMANDS FROM LINUX DESKTOP: $ tar zxvf agetty-2.38.1-r1.apk $ mv sbin/agetty scripts/ NOW CONNECT YOUR KOBO TO YOUR PC: Copy your agetty binary from the scripts/ folder on the PC to the sbin/ folder on the kobo. ***UPDATE*** CRITICAL STEP (or agetty won't run): # cp /mnt/onboard/.adds/koreader/libs/ld-musl-armhf.so.1 /lib/ *** Edit system file on your Kobo at your own risk (may blow up your device - just kidding, but type carefully) : EDIT /sbin/kobo_getty.sh Code: 
	#!/bin/sh [ -e /dev/ttymxc0 ] && /sbin/getty -L ttymxc0 115200 vt100 & [ -e /dev/ttyS0 ] && /sbin/getty -L ttyS0 0 vt100 & [ -e /dev/tty1 ] && /sbin/agetty -s 38400 -t 600 tty1 vt100 If I may paraphrase NiLuJe, "Here Be Dragons", where "Dragons" be a metaphor for messing up core system functionality possibly leading to failure to startup or connect, or even mysterious application malfunctions that manifest later on. These system files were put there by folks with comprehensive system level understanding, to be modified by folks who have invested many person-hours code-grokking/reverse engineering to achieve comparable understanding. Since I am neither, what is my excuse? Well on my Clara HD the first two lines are exactly the same except I added the "&" at the end. I then added the third line which I have researched the meaning of. Also I have multiple backups and contingency plans for connecting to and/or re-establishing my Clara. Also, it only cost 99 US$, is not used for work, and contains no important data. So non-expert readers, please make your own risk assessment. Edit NickelMenu config file: EDIT /mnt/onboard/.adds/nm/config.txt Code: 
	menu_item :main :fbpad :cmd_spawn :quiet:/mnt/onboard/.adds/koreader/scripts/fbpad /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpad                           
    chain_failure                      :dbg_toast          :Error                                   
menu_item :main :Stop fbpad :cmd_spawn :quiet:/usr/bin/pkill fbpad                                
    chain_success                      :dbg_toast          :Stopped fbpad                           
    chain_failure                      :dbg_toast          :Error
Power off your Kobo. When you restart it, set USB host mode, plug in your powered USB connected keyboard, run fbpad from NickelMenu, and type (may stall). ***** CORRECTION FOR MORE STABLE OPERATION: DO NOT EDIT /sbin/kobo_getty.sh. RETURN IT TO ORIGINAL STATE, e.g.: Code: 
	#!/bin/sh [ -e /dev/ttymxc0 ] && /sbin/getty -L ttymxc0 115200 vt100 [ -e /dev/ttyS0 ] && /sbin/getty -L ttyS0 0 vt100 #[ -e /dev/tty1 ] && /sbin/agetty -s 38400 -t 600 tty1 vt100 INSTEAD EDIT /etc/inittab to add the agetty line only: Code: 
	::sysinit:/etc/init.d/rcS ::respawn:/sbin/kobo_getty.sh ::once:/sbin/agetty -s 38400 -t 600 tty1 vt100 ::ctrlaltdel:/sbin/reboot ::shutdown:/etc/init.d/rcK ::restart:/sbin/init ***UPDATE*** See POST #7 for a better way of doing this. Avoids the most system file meddling, but you will have to kill agetty again each time you return to Nickel after exiting KOReader. *** Edit NickelMenu config file to add Stop agetty command: EDIT /mnt/onboard/.adds/nm/config.txt Code: 
	menu_item :main :fbpad :cmd_spawn :quiet:/mnt/onboard/.adds/koreader/scripts/fbpad /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpad                           
    chain_failure                      :dbg_toast          :Error                                   
menu_item :main :Stop fbpad :cmd_spawn :quiet:/usr/bin/pkill fbpad                                
    chain_success                      :dbg_toast          :Stopped fbpad                           
    chain_failure                      :dbg_toast          :Error  
menu_item :main :Stop agetty :cmd_spawn :quiet:/usr/bin/pkill agetty                                
    chain_success                      :dbg_toast          :Stopped agetty                           
    chain_failure                      :dbg_toast          :Error
Power off your Kobo. When you restart it, set USB host mode, plug in your powered USB connected keyboard, run Stop agetty, then fbpad from NickelMenu, and type (shouldn't stall). Last edited by elinkser; 10-22-2023 at 01:33 PM. Reason: risk notice, cd, corrected stability,better hack,ld-musl-armhf.so.1  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#6 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				OSCREEN KEYBOARD
			 
			
			
			MAKING AN ONSCREEN KEYBOARD FOR OUR TERMINAL: 
		
	
		
		
			Fbkeyboard is a framebuffer keyboard that we can port to Kobo's fbink library, following the fbpad-eink example. $ mkdir fbkeyboard-build $ cd fbkeyboard-build/ *** First we build fbpad as in the previous post, except we leave some rows empty at the bottom of the screen for the keyboard. Assuming you have already built KOReader's koxtoolchain, NiLuJe's FBInk library, and Aligrudi/Droske's fbpads as before: $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare $ unzip fbpad-eink-master.zip $ cd fbpad-eink-master/ $ cp -r ../FBInk-v1.25.0/Release FBInk/ $ cp ../FBInk-v1.25.0/fbink.h FBInk/ (First make fbpadkbS, the small font version of fbpad for onscreen keyboard.) $ nano -l conf.h Code: 
	17 typedef int fbval_t; Code: 
	3 CC := arm-kobo-linux-gnueabihf-gcc 4 all: fbpadkbS ... 11 fbpadkbS: fbpad.o term.o pad.o draw.o font.o isdw.o scrsnap.o FBInk/Release/libfbink.a ... 15 rm -f *.o fbpadkbS Code: 
	25 rows = fb_rows() * 29 / 51 / fnrows; Copy the fbpadkbS binary to the /mnt/onboard/.adds/koreader/scripts/ folder on your Kobo. (Now make fbpadkb, the large font version of fbpad for onscreen keyboard.) $ cp ../fbpads-master/fbpad_mkfn/ar.tf fonts/ $ cp ../fbpads-master/fbpad_mkfn/ai.tf fonts/ $ cp ../fbpads-master/fbpad_mkfn/ab.tf fonts/ $ nano -l conf.h Code: 
	20 #define FR "ab.tf" 21 #define FI "ab.tf" 22 #define FB "ab.tf" Code: 
	4 all: fbpadkb 10 xxd -i fonts/ab.tf > font.h 11 fbpadkb: fbpad.o term.o pad.o draw.o font.o isdw.o scrsnap.o FBInk/Release/libfbink.a ... 15 rm -f *.o fbpadkb Code: 
	40 memcpy(&head, fonts_ab_tf, sizeof(head)); ... 46 font->glyphs = (int*)(fonts_ab_tf + sizeof(head)); 47 font->data =(char*) (fonts_ab_tf + sizeof(head) + font->n * sizeof(int)); $ nano -l pad.c Code: 
	25 rows = fb_rows() * 25 / 42 / fnrows; Copy the fbpadkb binary to the /mnt/onboard/.adds/koreader/scripts/ folder on your Kobo. $ cd .. Add the following entries to /mnt/onboard/.adds/nm/config.txt: Code: 
	...
menu_item :main :fbpadkb :cmd_spawn :quiet:/mnt/onboard/.adds/koreader/scripts/fbpadkb /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpadkb       
    chain_failure                      :dbg_toast          :Error                                   
menu_item :main :Stop fbpadkb :cmd_spawn :quiet:/usr/bin/pkill fbpadkb 
    chain_success                      :dbg_toast          :Stopped fbpadkb                        
    chain_failure                      :dbg_toast          :Error
...
*** Freetype is a dependency of Fbkeyboard: Freetype https://freetype.org/download.html Download from: https://sourceforge.net/projects/fre...etype2/2.13.1/ $ tar zxvf freetype-2.13.1.tar.gz $ cd freetype-2.13.1/ $ ./configure --host=arm-kobo-linux-gnueabihf $ make $ cd .. *** bakonyiferenc/fbkeyboard forked from julianwi/fbkeyboard https://github.com/bakonyiferenc/fbkeyboard $ wget https://github.com/bakonyiferenc/fbk...ads/master.zip $ mv master.zip fbkeyboard-master.zip $ unzip fbkeyboard-master.zip $ cd fbkeyboard-master/ $ nano -l fbkeyboard.c Code: 
	...
 18 */
 19
 20 #include <stdlib.h>
 21 #include <signal.h>
 22 #include <fcntl.h>
 23 #include <string.h>
 24 #include <unistd.h>
 25 #include <dirent.h>
 26 #include <errno.h>
 27 #include <linux/fb.h>
 28 #include <linux/input.h>
 29 #include <linux/uinput.h>
 30 #include <linux/vt.h>
 31 #include <ft2build.h>
 32 #include FT_FREETYPE_H
 33 #include "conf.h"
 34 #include "draw.h"
 35 volatile sig_atomic_t done = 0;
 36 char *font = "/mnt/onboard/.adds/koreader/fonts/noto/NotoSans-Bold.ttf";
...
 38 char *special[][7] = {
 39         { "Esc", "Tab", "Up ", "Dn ", "Lt ", "Rt ", "PgD" },
...
53 __u16 keys[][26] = {
 54         { KEY_ESC, KEY_TAB, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_PAGEDOWN },
......
 88 FT_Face face;
 89 int advance;    // offset to the next glyph
 90 int fduinput;
 91 struct input_event ie;
 92 int oldrow = 0, oldpressed = 0;
 93 struct timeval oldstamp, newstamp, diffstamp;
 94 int theight;    // of touchscreen
 95 int twidth;     // of touchscreen
 96 int trowh;      // heigth of one keyboard row on touchscreen
 97 
 98 void fill_rect(int x, int y, int w, int h, int color)
...
299 void show_fbkeyboard(int fbfd)
300 {
301         switch (rotate) {
302                 case FB_ROTATE_UR:
303                         lseek(fbfd, fblinelength * (fbheight - height * 6), SEEK_SET);
304                         write(fbfd, buf, buflen);
305                         keyb_refresh(fbfd, fbheight - height * 6, 0, width, fbheight);
306                         break;
307                 case FB_ROTATE_UD:
308                         lseek(fbfd, 0, SEEK_SET);
309                         write(fbfd, buf, buflen);
310                         keyb_refresh(fbfd, 0, 0, width, height * 5);
311                         break;
312                 case FB_ROTATE_CW:
313                         for (int i = 0; i < width; i++) {
314                                 lseek(fbfd, fblinelength * i, SEEK_SET);
315                                 write(fbfd, (int32_t *) (buf + linelength * i), linelength);
316                         }
317                         keyb_refresh(fbfd, 0, 0, height * 5, width);
318                         break;
319                 case FB_ROTATE_CCW:
320                         for (int i = 0; i < width; i++) {
321                                 lseek(fbfd, fblinelength * i + (fbwidth - height * 5) * 4, SEEK_SET);
322                                 write(fbfd, (int32_t *) (buf + linelength * i), linelength);
323                         }
324                         keyb_refresh(fbfd, 0, fbwidth - height * 5, fbwidth, width);
325                         break;
326         }
327 }
328 /*  Waits for a relevant input event. Returns 0 if touched, 1 if released. */
329 int check_input_events(int fdinput, int *x, int *y) 
330 {
331         int released = 0;
332         int key = 1;
333         int absolute_x = -1, absolute_y = -1;
334         while (!done && !released && (absolute_x == -1 || absolute_y == -1))
335                 while (read(fdinput, &ie, sizeof(struct input_event))
336                        && !(ie.type == EV_SYN && ie.code == SYN_REPORT)) {
337                         if (ie.type == EV_ABS) {
338                                 switch (ie.code) {
339                                         case ABS_MT_POSITION_X:
340                                                 absolute_x = ie.value;
341                                                 released = 0;
342                                                 key = 0;
343                                                 break;
344                                         case ABS_MT_POSITION_Y:
345                                                 absolute_y = ie.value;
346                                                 released = 0;
347                                                 key = 0;
348                                                 break;
349                                         case ABS_MT_TRACKING_ID:
350                                                 if (ie.value == -1) {
351                                                         released = 1;
352                                                 }
353                                                 break;
354                                 }
355                         }
...
356                         if (ie.type == EV_SYN && ie.code == SYN_MT_REPORT) {
...
357                                 released = 1;
358                         }
359                 }
360         switch (rotate) {
361                 case FB_ROTATE_UR:
362                         *x = 0x10000 - absolute_y * 0x10000 / theight;
363                         *y = absolute_x * 0x10000 / twidth;
364                         break;
365                 case FB_ROTATE_UD:
366                         *x = 0x10000 - absolute_x * 0x10000 / twidth;
367                         *y = 0x10000 - absolute_y * 0x10000 / theight;
368                         break;
369                 case FB_ROTATE_CW:
370                         *x = absolute_y * 0x10000 / theight;
371                         *y = 0x10000 - absolute_x * 0x10000 / twidth;
372                         break;
373                 case FB_ROTATE_CCW:
374                         *x = 0x10000 - absolute_y * 0x10000 / theight;
375                         *y = absolute_x * 0x10000 / twidth;
376                         break;
377         }
378         oldstamp.tv_sec = newstamp.tv_sec;
379         oldstamp.tv_usec = newstamp.tv_usec;
380         newstamp.tv_sec  = ie.time.tv_sec;
381         newstamp.tv_usec  = ie.time.tv_usec;
382         timersub(&newstamp,&oldstamp,&diffstamp);
383         return released;
384 }
385 /* x, y and trowh are scaled to 2^16 (e.g. min x = 0, max x = 65535) */
386 void identify_touched_key(int x, int y, int *row, int *pressed) 
387 {
388         switch ((0x10000 - y) / trowh) {
389                 case 5:
390                         *row = 0;               // Esc, Tab, F10, etc
391                         *pressed = x * 7 / 0x10000;
392                         break;
393                 case 4:
394                         *row = 1;               // q - p
395                         *pressed = x * 10 / 0x10000;
396                         break;
397                 case 3:
398                         *row = 1;               // a - l
399                         if (x > 0x10000 / 20 && x < 0x10000 * 19 / 20)
400                                 *pressed = 10 + (x * 10 - 0x10000 / 2) / 0x10000;
401                         break;
402                 case 2:
403                         if (x < 0x10000 * 3 / 20) {
404                                 *row = 3;
405                                 *pressed = 0;   // Left Shift
406                         } else if (x < 0x10000 * 17 / 20) {
407                                 *row = 1;       // z - m
408                                 *pressed = 19 + (x * 10 - 0x10000 * 3 / 2) / 0x10000;
409                         } else {
410                                 *row = 3;
411                                 *pressed = 1;   // Bcksp
412                         }
413                         break;
414                 case 1:
415                         *row = 4;
416                         if (x < 0x10000 * 3 / 20)
417                                 *pressed = 99;  // 123!@
418                         else if (x < 0x10000 * 5 / 20)
419                                 *pressed = 0;   // Left Alt
420                         else if (x < 0x10000 * 15 / 20)
421                                 *pressed = 1;   // Space
422                         else if (x < 0x10000 * 17 / 20)
423                                 *pressed = 2;   // Right Ctrl
424                         else
425                                 *pressed = 3;   // Enter
426                         break;
427                 default:
428                         *row = 5;               // cursor, Enter, Home, PgDn, etc
429                         *pressed = 3 * y / (0x10000 - trowh * 6);
430                         *pressed *= 3;
431                         *pressed += 3 * x / 0x10000;
432                         break;
433         }
434 }
435
...
489         } else {
490                 send_key(keys[row][pressed]);
491         }
492         oldrow = row;
493         oldpressed = pressed;
494 }
495 /* return max of rows  */
496 int reset_window_size(int fd)
...
559
560 /*      fdcons = open("/dev/tty1", O_RDWR | O_NOCTTY);
561         if (fdcons < 0) {
562                 perror("Error opening /dev/tty1");
563                 exit(-1);
564         } */
565
...
599
600         if (fb_init(FBDEV)) {
601                 fprintf(stderr, "fbkeyboard: failed to initialize the framebuffer\n");
602                 return 1;
603         }
604         if (sizeof(fbval_t) != FBM_BPP(fb_mode())) {
605                 fprintf(stderr, "fbkeyboard: fbval_t does not match framebuffer depth (%d bytes$
606                 return 1;
607         }
608         
609         timerclear(&oldstamp);
610         timerclear(&newstamp);
611         timerclear(&diffstamp);
612         fbfd = fb_fd();
613         fbwidth = fb_cols();
614         fbheight = fb_rows();
615         fblinelength = fb_length();
616         switch (rotate) {
617                 case FB_ROTATE_UR:
...
724
725         while (!done) {
726         /*      if (!ioctl(fdcons, VT_GETSTATE, &ttyinfo)) {
727                         if (tty != ttyinfo.v_active) {
728                                 tty = ttyinfo.v_active;
729                                 close(fdcons);
730                                 fdcons = open("/dev/tty1", O_RDWR | O_NOCTTY);
731                                 set_window_size(fdcons);
732                                 resized[tty] = 1;
733                         }
734                 } else {
735                         perror("VT_GETSTATE ioctl failed");
736                 } */
737
738                 draw_keyboard(row, pressed);
739                 show_fbkeyboard(fbfd);
740                 released = check_input_events(fdinput, &x, &y);
741
742                 if (released)
743                         identify_touched_key(x, y, &row, &pressed);
744                 if (pressed != -1 && (pressed != oldpressed || (long)diffstamp.tv_usec > 50000))
745                         send_uinput_event(row, pressed);
746                 pressed = -1;
747         }
748
...
760                         reset_window_size(fdcons);
761                 }
762         }
763         fb_free();
764 }
765
...
$ mkdir FBInk $ cp -r ../FBInk-v1.25.0/Release FBInk/ $ cp ../FBInk-v1.25.0/fbink.h FBInk/ $ cp ../fbpad-eink-master/draw.c . $ cp ../fbpad-eink-master/draw.h . $ cp ../fbpad-eink-master/conf.h . $ cp ../freetype-2.13.1/objs/.libs/libfreetype.so* . $ nano -l draw.c Code: 
	...
160
161 int fb_length(void) 
162 { 
163         return finfo.line_length; 
164 }
165
166 void keyb_refresh(int fd, int invalid_top, int invalid_left, int invalid_right, int invalid_bot$
167   fbink_refresh( fb_fd(),
168                  invalid_top,
169                  invalid_left,
170                  invalid_right - invalid_left,
171                  invalid_bottom - invalid_top,
172                  cfg() );
173 /*  invalid_nonempty = 0; */
174   invalid_top = invalid_bottom = invalid_left = invalid_right = 0;
175 }
176
$ nano -l draw.h Code: 
	19 int fb_length(void); 20 void keyb_refresh(int fd, int invalid_top, int invalid_left, int invalid_right, int invalid_bottom); $ arm-kobo-linux-gnueabihf-gcc -o fbkeyboard -I../freetype-2.13.1/include/ fbkeyboard.c draw.c libfreetype.a FBInk/Release/libfbink.a Copy the fbkeyboard binary to the /mnt/onboard/.adds/koreader/scripts/ folder on your Kobo. $ cd .. Add the following entries to /mnt/onboard/.adds/nm/config.txt: Code: 
	...
          
menu_item :main :fbkeyboard :cmd_spawn :quiet:/mnt/onboard/.adds/koreader/scripts/fbkeyboard
    chain_success                      :dbg_toast          :Started fbkeyboard     
    chain_failure                      :dbg_toast          :Error                                   
menu_item :main :Stop fbkeyboard :cmd_spawn :quiet:/usr/bin/pkill fbkeyboard 
    chain_success                      :dbg_toast          :Stopped fbkeyboard                            
    chain_failure                      :dbg_toast          :Error
...
From MyBooks, go to the Activity page on your Kobo (second tab from left at bottom of screen.) ***UPDATE*** If you are not in SideloadedMode=true (in [ApplicationPreferences] in /mnt/onboard/.kobo/Kobo/Kobo eReader.conf) then you go to More (second tab from RIGHT at bottom of screen, then select Activity.) *** From NickelMenu select Stop Agetty, fbpadkb, and fbkeyboard entries. (i.e. requires that you implemented the USB keyboard hack of the previous post.) Edit: Agetty not needed for fbkeyboard, just for fbpad+USB keyboard. Unfortunately too slow for practical use right now. Hopefully something can be tweaked to optimize it. Can exit with Stop fbkeyboard and Stop fbpadkb entries. *** EDIT: Added arrow keys to lines 39, 40 and 54 of fbkeyboard.c: Code: 
	 38 char *special[][7] = {
 39         { "Esc", "Tab", " ^ ", " v ", " < ", " > ", ">>⇓" },
 40         { "Esc", "Tab", " ^ ", " v ", " < ", " > ", ">>⇓" },
 41 }; 
...
 53 __u16 keys[][26] = {
 54         { KEY_ESC, KEY_TAB, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_PAGEDOWN },
...
EDIT: Added non-blocking IO to fbkeyboard.c to get faster response: Code: 
	...
334         while (!done && !released && (absolute_x == -1 || absolute_y == -1))
335                 while ((read(fdinput, &ie, sizeof(struct input_event)) > 0)
336                     /*   && !(ie.type == EV_SYN && ie.code == SYN_REPORT) */ ) {
337                         if (ie.type == EV_ABS) {
338                                 switch (ie.code) {
339                                         case ABS_MT_POSITION_X:
340                                                 absolute_x = ie.value;
341                                                 released = 0;
342                                                 key = 0;
343                                                 break;
344                                         case ABS_MT_POSITION_Y:
345                                                 absolute_y = ie.value;
346                                                 released = 0;
347                                                 key = 0;
348                                                 break;
349                                         case ABS_MT_TRACKING_ID:
350                                                 if (ie.value == -1) {
351                                                         released = 1;
352                                                 }
353                                                 break;
354                                 }
355                         }
356                         if (ie.type == EV_SYN && ie.code == SYN_REPORT) {
357                                 released = 1;
358                         }
359                 }
360         switch (rotate) {
'''
659                 while ((dptr = readdir(inputdevs))) {
660                         if ((fdinput =
661                              openat(dirfd(inputdevs), dptr->d_name,
662                                     O_RDONLY | O_NONBLOCK)) != -1
663                             && ioctl(fdinput, EVIOCGBIT(0, sizeof(key)),
664                                      &key) != -1 && key >> EV_ABS & 1)
665                                 break;
...
742                 if (released)
743                         identify_touched_key(x, y, &row, &pressed);
744                 if (pressed != -1 && (pressed != oldpressed || (long)diffstamp.tv_usec > 200000))
745                         send_uinput_event(row, pressed);
746                 pressed = -1;
747                 usleep(50000);
748         }
749         int i;
...
Unicode Character 21d3 (PageDown arrow on line 39) was entered while holding Ctrl-Sh-u. https://en.wikipedia.org/wiki/Arrow_(symbol) *** This code is probably in need of cleanup. Feel free to jump in! *** ***UPDATE*** See POST #7 - Need WiFi ON (or USB networking) to avoid freezing. *** ***UPDATE*** CRITICAL STEP (or agetty won't run): # cp /mnt/onboard/.adds/koreader/libs/ld-musl-armhf.so.1 /lib/ Edit: Agetty not needed for fbkeyboard, just for fbpad+USB keyboard. *** Last edited by elinkser; 12-03-2023 at 07:24 PM. Reason: EDIT: Added arrow keys,nonblock,need wifi on,agetty not needed for fbkeyboard  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#7 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				SAVING SPACE IN NICKELMENU WITH "SUBMENUS" USING NICKELDBUS
			 
			
			
			*** 
		
	
		
		
		
		
		
		
		
		
		
		
		
			SAVING SPACE IN NICKELMENU WITH "SUBMENUS" USING NICKELDBUS Your NickelMenu might be getting crowded if you have added all the following entries: Code: 
	menu_item :main :stop agetty+fbpad+fbkeyboard :cmd_spawn :quiet:/usr/bin/pkill agetty                          
    chain_success                      :cmd_spawn          :quiet :/usr/bin/pkill fbpad
    chain_failure                      :cmd_spawn          :quiet :/usr/bin/pkill fbpad 
    chain_success                      :cmd_spawn          :quiet :/usr/bin/pkill fbkeyboard 
    chain_failure                      :cmd_spawn          :quiet :/usr/bin/pkill fbkeyboard 
menu_item :main    :fbpadkb+fbkeyboard :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbpadkb /bin/sh 0</dev/tty1
    chain_success                      :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbkeyboard
    chain_success                      :dbg_toast          :Started fbpadkb and fbkeyboard
    chain_failure                      :dbg_toast          :Error starting fbpadkb or fbkeyboard
menu_item :main    :fbpadkbS+fbkeyboard :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbpadkbS /bin/sh 0</dev/tty1
    chain_success                      :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbkeyboard
    chain_success                      :dbg_toast          :Started fbpadkbS and fbkeyboard
    chain_failure                      :dbg_toast          :Error starting fbpadkbS or fbkeyboard   
menu_item :main    :fbpad (toggle):cmd_output         :500:quiet :/usr/bin/pkill -f "fbpad"
    chain_success:skip:4
    chain_failure                      :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbpad /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpad
    chain_failure                      :dbg_toast          :Error starting fbpad
    chain_always:skip:-1
    chain_success                      :dbg_toast          :Stopped fbpad
menu_item :main    :fbpadS (toggle):cmd_output         :500:quiet :/usr/bin/pkill -f "fbpadS"
    chain_success:skip:4
    chain_failure                      :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbpadS /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpadS
    chain_failure                      :dbg_toast          :Error starting fbpadS
    chain_always:skip:-1
    chain_success                      :dbg_toast          :Stopped fbpadS
menu_item :main    :fbkeyboard (toggle):cmd_output         :500:quiet :/usr/bin/pkill fbkeyboard
    chain_success:skip:4
    chain_failure                      :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbkeyboard
    chain_success                      :dbg_toast          :Started fbkeyboard
    chain_failure                      :dbg_toast          :Error starting fbkeyboard
    chain_always:skip:-1
    chain_success                      :dbg_toast          :Stopped fbkeyboard
*** But NickelDBus allows us to condense everything to a single NickelMenu entry (i.e. also need NickelDBus installed): Code: 
	menu_item :main :fbmenu :cmd_spawn :quiet:exec /mnt/onboard/.adds/koreader/scripts/fbmenu.sh
    chain_success                      :dbg_toast          :Started fbmenu       
    chain_failure                      :dbg_toast          :Error
Also create script /mnt/onboard/.adds/koreader/scripts/fbmenu.sh: Code: 
	#!/bin/sh                                        
# fbmenu - fbpad and fbkeyboard selection menu
num=0                              
qndb -m dlgConfirmCreate true                                       
qndb -m dlgConfirmSetTitle "1-Stop agetty+fb(all); 2-fbpadkb; 3-fbpadkbS; 4-fbpad; 5-fbpadS; 6-fbkeyboard;    Select option (1-6):"
qndb -m dlgConfirmSetLEPlaceholder "1"
qndb -m dlgConfirmShow                           
result=$(qndb -s dlgConfirmTextInput)            
textIn=$(echo $result | sed 's/dlgConfirmTextInput //')
num=$(echo $textIn | sed 's/[^0-9]//g')
num=${num:-1}
if [ "$num" != "$textIn" ]
then
num=1
fi                                                                                                 
if [ "$num" == "1" ]; then
		qndb -m mwcToast 1000 "You selected 1-Stop agetty+fbpad"
		fbcmd="/usr/bin/pkill agetty"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
		fbcmd="/usr/bin/pkill fbpad"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
		fbcmd="/usr/bin/pkill fbkeyboard"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "2" ]; then
		qndb -m mwcToast 1000 "You selected 2-fbpadkb"
		fbcmd="/mnt/onboard/.adds/koreader/scripts/fbkeyboard"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1) &
		fbcmd="eval /mnt/onboard/.adds/koreader/scripts/fbpadkb /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "3" ]; then	
		qndb -m mwcToast 1000 "You selected 3-fbpadkbS"
		fbcmd="/mnt/onboard/.adds/koreader/scripts/fbkeyboard"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1) &
		fbcmd="eval /mnt/onboard/.adds/koreader/scripts/fbpadkbS /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "4" ]; then
		qndb -m mwcToast 1000 "You selected 4-fbpad"
		fbcmd="eval /mnt/onboard/.adds/koreader/scripts/fbpad /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "5" ]; then
		qndb -m mwcToast 1000 "You selected 5-fbpadS"
		fbcmd="eval /mnt/onboard/.adds/koreader/scripts/fbpadS /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "6" ]; then
		qndb -m mwcToast 1000 "You selected 6-fbkeyboard"
		fbcmd="/mnt/onboard/.adds/koreader/scripts/fbkeyboard"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
else
		qndb -m mwcToast 1000 "You selected an invalid option" 
fi
qndb -m mwcToast 1000 "${fberr:-"Bye!"}"
*** A NEW HACK TO AVOID MESSING WITH SYSTEM FILES LIKE A PRO: * While messing around with an rmkit install, I saw how they avoided messing with system files like we did in POST #5 above: Return your /etc/inittab to to the way it was (i.e. remove the "agetty" line you added). Instead create the following file: /etc/udev/rules.d/90-fbpad.rules Code: 
	# : 90-fbpad.rules 2015-01-10 23:58:00Z NiLuJe $ # Runs early at boot... (onboard *might* be mounted at that point) KERNEL=="loop0", RUN+="/sbin/agetty -s 38400 tty1 vt100" It would be nice if we could also kill agetty automatically with the following file, but I tried it and that one doesn't work: /etc/udev/rules.d/91-fbpad.rules Code: 
	# : 91-fbpad.rules 2015-01-10 23:58:00Z NiLuJe $ # Runs early at boot... (onboard *might* be mounted at that point) KERNEL=="loop0", RUN+="/usr/bin/pkill agetty" *** IMPORTANT NOTE: ON MY KOBO, EITHER USB OR WIFI NETWORKING (WHETHER CONNECTED TO HOTSPOT OR NOT) HAD TO BE ENABLED OR DEVICE FREEZES. WHO KNOWS WHY? SORRY FOR ANY FRUSTRATION - I HAD DONE MANY SUCCESSFUL TESTS NOT REALIZING THAT ENABLING WIFI WAS RELEVANT! **** * NOTE : you have to kill agetty again upon returning to Nickel after exiting KOReader. Last edited by elinkser; 10-28-2023 at 04:16 PM. Reason: NEEDS USB OR WIFI NETWORKING ENABLED!  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#8 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				ADD A CHESS GAME FOR THE TERMINAL
			 
			
			
			***ADD A CHESS GAME FOR THE TERMINAL*** 
		
	
		
		
			Here's a chess app to stress test your fbpadkb, and have a little fun at the same time! The gnuchess game has only the following dependencies: Depends (3) libgcc** libintl musl* * Already got it from the Elinks/Nano install above (POST #3 - also got the /korenv.sh script.) ** Do not install libgcc since it would crash OCP-KOReader-v2023.06 when opening pdf files. Fortunately, gnuchess runs fine without it! RUN THESE COMMANDS FROM LINUX DESKTOP: $ cd myalpine/ DOWNLOAD THE REQUIRED PACKAGES: $ wget https://dl-cdn.alpinelinux.org/alpin...s-6.2.9-r1.apk $ wget https://dl-cdn.alpinelinux.org/alpin...-0.21.1-r1.apk $ tar zxvf gnuchess-6.2.9-r1.apk $ tar zxvf libintl-0.21.1-r1.apk $ mv usr/bin/gnuchess scripts/ $ mv usr/lib/libintl.so.8.3.0 libs/libintl.so.8 NOW CONNECT YOUR KOBO TO YOUR PC: Copy your gnuchess binary from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. Copy new lib from the libs/ folder on the PC to the /mnt/onboard/.adds/koreader/libs/ folder on the kobo: libintl.so.8 Copy the usr/share/gnuchess folder on the PC to the /usr/share/ folder on the kobo: PLAY CHESS FROM fbpadkb TERMINAL: # . /korenv.sh # gnuchess -e GNU Chess 6.2.9 Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. White (1) : ENTER YOUR MOVE, E.G.: White (1) : e2e4 1. e2e4 black KQkq e3 r n b q k b n r p p p p p p p p . . . . . . . . . . . . . . . . . . . . P . . . . . . . . . . . P P P P . P P P R N B Q K B N R Thinking... white KQkq d6 r n b q k b n r p p p . p p p p . . . . . . . . . . . p . . . . . . . . P . . . . . . . . . . . P P P P . P P P R N B Q K B N R My move is : d5 White (2) : ENTER YOUR NEXT MOVE, E.G.: White (2) : e4d5 2. e4d5 black KQkq r n b q k b n r p p p . p p p p . . . . . . . . . . . P . . . . . . . . . . . . . . . . . . . . P P P P . P P P R N B Q K B N R Thinking... white KQkq r n b q k b . r p p p . p p p p . . . . . n . . . . . P . . . . . . . . . . . . . . . . . . . . P P P P . P P P R N B Q K B N R My move is : Nf6 SAVE YOUR GAME AND QUIT: White (3) : pgnsave game1.pgn White (3) : quit # PLAY AGAIN: # gnuchess -e GNU Chess 6.2.9 Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. White (1) : LOAD YOUR GAME AND QUIT: White (1) : pgnload game1.pgn white KQkq r n b q k b . r p p p . p p p p . . . . . n . . . . . P . . . . . . . . . . . . . . . . . . . . P P P P . P P P R N B Q K B N R White (1) : quit # With a little command-line labor you can install a GUI chess app in a graphical chroot, thanks to NiMa et al: https://www.mobileread.com/forums/sh...d.php?t=336210 *Of course there is also Vlasovsoft's app which includes a fine GUI chess program. Updated setup instructions starting from: https://www.mobileread.com/forums/sh...4&postcount=53 Then just: # apk add xboard # xboard TIPS FOR GETTING STARTED WITH GRAPHICAL CHROOT: 1) Start with the simpler non-graphical version of the chroot: https://www.mobileread.com/forums/sh...d.php?t=336175 (You may find a script like the one in section 6 of this comment helpful.): https://www.mobileread.com/forums/sh...1&postcount=46 *** CAUTION: You know how Nickel does all that background work when you connect USB cable to desktop, click "connect", then later unmount? Well, there may be a risk of data corruption if you had a loop mounted file, e.g. Alpine chroot. https://www.mobileread.com/forums/sh...38&postcount=2 So better don't try this. But if you DO connect a USB cable, either exit the chroot and unmount the loop first, OR click "cancel" and use SSH/Telnet networking instead. (I have done this for months.) *** 2) Try this site to get the tldr description of a Linux command e.g. the chroot command: https://html.duckduckgo.com/html/?q=tldr+chroot (You can change the "chroot" to some other command, e.g. "pkill"): https://html.duckduckgo.com/html/?q=tldr+pkill ***ADD NETPBM IMAGE CONVERTER*** Netpbm's pnmscale and pnmtopng help with converting our phone camera images to rmkit's Harmony drawing app png layers. Then you can draw with the photo as a background layer. https://rmkit.dev/apps/harmony You can also run the following script as a GUI app, using rmkit's Simple App Script interpreter: https://www.mobileread.com/forums/sh...59&postcount=9 The netpbm package has the following dependencies: Depends (6) libjpeg-turbo** libpng libx11*** musl* tiff*** zlib** * Already got it from the Elinks/Nano install above (POST #3 - also got the /korenv.sh script.) ** Already have equivalents from base KOReader install. *** Don't need tiff or libx11 for our commands RUN THESE COMMANDS FROM LINUX DESKTOP: $ cd myalpine/ DOWNLOAD THE REQUIRED PACKAGES: $ wget https://dl-cdn.alpinelinux.org/alpin...0.73.41-r1.apk $ wget https://dl-cdn.alpinelinux.org/alpin...-1.6.39-r0.apk $ tar zxvf netpbm-10.73.41-r1.apk $ mv usr/bin/pamscale scripts/pnmscale $ mv usr/bin/pnmtopng scripts/ $ mv usr/lib/libnetpbm.so.11.73 libs/libnetpbm.so.11 $ tar zxvf libpng-1.6.39-r0.apk $ mv usr/lib/libpng16.so.16.39.0 libs/ NOW CONNECT YOUR KOBO TO YOUR PC: Copy the following binaries from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. pnmscale pnmtopng *** * Backup your old libpng16.so.16 from the /mnt/onboard/.adds/koreader/libs/ folder on the kobo. Then delete it from /mnt/onboard/.adds/koreader/libs/ *** Copy libs from the libs/ folder on the PC to the /mnt/onboard/.adds/koreader/libs/ folder on the kobo: libnetpbm.so.11 libpng16.so.16.39.0 *** * Now doublecheck that KOReader can read png files with this new libpng16.so.16.39.0 *** Copy camera image s.jpg from your phone to the /mnt/onboard/.adds/rmkit/data/harmony/ folder on the kobo. TRANSFORM PHOTO S.JPG FROM fbpadkb OR KOReader TERMINAL: From kobo terminal(or SSH session): # . /korenv.sh # cd /mnt/onboard/.adds/rmkit/data/harmony Convert image to grayscale, rotating if necessary: # jpegtran -rotate 90 -grayscale s.jpg > s90.jpg Convert jpg image to pnm: # djpeg -pnm s90.jpg > sg.pnm Scale image to your display(1088x1488 for Clara HD): # pnmscale -width 1088 -height 1488 sg.pnm > bg.pnm Convert pnm image to png: # pnmtopng bg.pnm > bg.png Note: you could have dimmed the image by using itself as an alpha mask: # pnmtopng -alpha bg.pnm bg.pnm > bgs.png Or for a less ghostly effect, use a 50% grayscale mask: # pnmtopng -alpha a50.pgm bg.pnm > bga.png Run harmony from rmkit, and import the bg.png as a layer. Tip: You can wirelessly copy the photo from phone to Kobo, e.g. with KOReader's GUI ftp client: https://www.mobileread.com/forums/sh...25&postcount=6 *** USING SCRIPT AND 50% ALPHA CHANNEL (REQUIRES ATTACHED a50.pgm FILE): Create script jtop.sh (and jtopr.sh for when image needs to be rotated), to convert a jpg image to png while applying 50% alpha transparency. $ nano jtop.sh Code: 
	jpegtran -grayscale $1 | djpeg -pnm | pnmscale -width 1088 -height 1488 | pnmtopng -alpha a50.pgm > $2 Unzip the attached a50.zip file and copy a50.pgm and your phone photo s.jpg to /mnt/onboard/.adds/rmkit/data/harmony. Tip: you can use KOReader's GUI ftp client to download the photo from your phone to your kobo. https://www.mobileread.com/forums/sh...25&postcount=6 Run the script with input parameters s.jpg (the photo image from your phone) and bg.png (the name you chose for the output png file). # jtop.sh s.jpg bg.png You can then input this png image as a layer to harmony. Similarly for landscape photos that you need to rotate to portrait: $ nano jtopr.sh Code: 
	jpegtran -rotate 90 -grayscale $1 | djpeg -pnm | pnmscale -width 1088 -height 1488 | pnmtopng -alpha a50.pgm > $2 * NOTE : you have to kill agetty again upon returning to Nickel after exiting KOReader. *** *UPDATE: Add GIF support From netpbm package above, add also: $ mv usr/bin/pngtopnm scripts/ $ mv usr/bin/pamtogif scripts/ $ mv usr/bin/ppmtogif scripts/ $ mv usr/bin/giftopnm scripts/ Also add gifsicle package: Gifsicle assembles gif images into gif animations. http://www.lcdf.org/gifsicle/ The gifsicle package has the following dependencies: Depends (2) libx11** musl* * Already got it from the Elinks/Nano install above ** Don't need libx11 for our command RUN THESE COMMANDS FROM LINUX DESKTOP: $ cd myalpine/ DOWNLOAD THE REQUIRED PACKAGES: $ wget https://dl-cdn.alpinelinux.org/alpin...le-1.93-r1.apk $ tar zxvf gifsicle-1.93-r1.apk $ mv usr/bin/gifsicle scripts/ NOW CONNECT YOUR KOBO TO YOUR PC: Copy the following binaries from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. pngtopnm pamtogif ppmtogif giftopnm gifsicle FROM SSH SHELL OR ON KOBO: # . /korenv.sh # cd /mnt/onboard/.adds/rmkit/data/harmony Convert png images to gif: # pngtopnm lines.png | ppmtogif > 1.gif # pngtopnm mtn.png | ppmtogif > 2.gif Making a GIF animation with gifsicle: # gifsicle --delay=123 --loop 1.gif 2.gif > anim.gif # gifsicle -I anim.gif * anim.gif 2 images logical screen 1408x1920 global color table [2] background 0 loop forever + image #0 1088x1448 delay 1.23s + image #1 1408x1920 delay 1.23s View animated gif on desktop browser (or luakit browser if you had installed a graphical chroot on your Kobo) via html file: # vi anim.html Code: 
	<html> <img SRC="anim.gif" ALT="anim"> </html> # ls /mnt/onboard/shared/anim.* /mnt/onboard/shared/anim.gif /mnt/onboard/shared/anim.html View animated gif on Kobo via playgif.sh script (requires fbink binary and gifsicle from above): # vi /mnt/onboard/.adds/kordir/scripts/playgif.sh Code: 
	#!/bin/sh # playgif.sh - play animated gifs using gifsicle and fbink export LD_LIBRARY_PATH="/mnt/onboard/.adds/kordir/libs:$LD_LIBRARY_PATH" nframes=`/mnt/onboard/.adds/kordir/scripts/gifsicle -I $1 | sed -n 's/ images//p' | sed 's/\* .*\.gif // '` echo "nframes = $nframes" nframes=$(expr "$nframes" - 1) delays=`/mnt/onboard/.adds/kordir/scripts/gifsicle -I $1 | sed -n 's/.*delay //p' | sed 's/s//'` for i in $(seq 0 1 "$nframes");do /mnt/onboard/.adds/kordir/scripts/gifsicle "$1" "#$i" > /tmp/tmp.gif; /mnt/onboard/.adds/kordir/scripts/fbink -G -g file=/tmp/tmp.gif; j=$(expr "$i" \+ 1) delayfraction=`echo "$delays" | sed -n "$j"' s/.*[0-9][0-9]*\.//p'` delaywhole=`echo "$delays" | sed -n "$j"' s/\.[0-9][0-9]//p'` delay=`echo $(expr "$delayfraction" \* 10000 \+ "$delaywhole" \* 1000000)` echo "delay = $delay" usleep "$delay"; done nframes = 2 delay = 1230000 delay = 1230000 (can comment out : echo "delay = $delay") *** Last edited by elinkser; 03-27-2024 at 05:15 PM. Reason: ADD NETPBM + GIFSICLE + IMPROVED PLAYGIF+REPO  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#9 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				ERRORS SO FAR
			 
			
			
			ERRORS SO FAR 
		
	
		
		
		
		
		
		
		
		
		
		
		
			I think I should dedicate a post to errors since I am so error-prone. * I do not do this on purpose to torture you - sometimes things work only on my Clara that I discover later, e.g. by clean install on new SD card! CRITICAL STEP (or /sbin/agetty won't run): # cp /mnt/onboard/.adds/koreader/libs/ld-musl-armhf.so.1 /lib/ This is the the same loader ld-musl-armhf.so.1 from the elinks install in a previous post. Obviously if I am running binary from /sbin without the library path of /mnt/onboard/.adds/koreader/libs/, then I need to supply the loader in the base /lib/ directory. I did not realize that I had done this on my Clara some months ago. Your fbpad w/USB keyboard won't work without starting and pkilling agetty (or equivalent). IMPORTANT NOTE: ON MY KOBO, EITHER USB OR WIFI NETWORKING (WHETHER CONNECTED TO HOTSPOT OR NOT) HAD TO BE ENABLED OR DEVICE FREEZES (when running fbkeyboard). WHO KNOWS WHY? SORRY FOR ANY FRUSTRATION - I HAD DONE MANY SUCCESSFUL TESTS NOT REALIZING THAT ENABLING WIFI WAS RELEVANT! Somewhere I renamed fbpads in my upload to fbpadS in my NickelMenu entries. That might cause error... Anything else?Hopefully that's it. *** CAUTION: You know how Nickel does all that background work when you connect USB cable to desktop, click "connect", then later unmount? Well, there may be a risk of data corruption if you had a loop mounted file, e.g. Alpine chroot. https://www.mobileread.com/forums/sh...38&postcount=2 So better don't try this. But if you DO connect a USB cable, either exit the chroot and unmount the loop first, OR click "cancel" and use SSH/Telnet networking instead. (I have done this for months.) *** Last edited by elinkser; 12-03-2023 at 04:17 PM. Reason: fbkeyboard not needing agetty  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#10 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				OSK, A FASTER & MORE USER-CONFIGURABLE ONSCREEN KEYBOARD
			 
			
			
			OSK, A FASTER & MORE USER-CONFIGURABLE ONSCREEN KEYBOARD: 
		
	
		
		
			(Found this by accident when looking for something else. It's from 2018, but still works great on my Clara HD.) USBMS Shenanigans... https://www.mobileread.com/forums/sh...0&postcount=14 https://github.com/shermp/go-kobo-input shermp/go-kobo-input $ mkdir osk-build $ cd osk-build/ $ wget https://golang.org/dl/go1.20.2.linux-amd64.tar.gz $ sudo tar -C /usr/local -xzf go1.20.2.linux-amd64.tar.gz $ echo "export PATH=/usr/local/go/bin:${PATH}" | sudo tee -a $HOME/.profile $ source $HOME/.profile $ go version go version go1.20.2 linux/amd64 $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare Note: This refers to the KOReader toolchain from: https://www.mobileread.com/forums/sh...16&postcount=4 You could try a different toolchain if you feel lucky. $ env GO111MODULE=off go get github.com/shermp/go-fbink-v2 $ cd ~/go/src/github.com/shermp/go-fbink-v2/ $ cd gofbink/ $ env GOOS=linux GOARCH=arm CGO_ENABLED=1 CC=arm-kobo-linux-gnueabihf-gcc CXX=arm-kobo-linux-gnueabihf-g++ go build $ cd ../example/ $ env GOOS=linux GOARCH=arm CGO_ENABLED=1 CC=arm-kobo-linux-gnueabihf-gcc CXX=arm-kobo-linux-gnueabihf-g++ go build Copy the /go/src/github.com/shermp/go-fbink-v2/example/example binary to the /mnt/onboard/.adds/koreader/scripts/ folder of your Kobo. Run these commands from an SSH session to the Kobo: # . /korenv.sh # example (Should display some nice text messages on Kobo display.) *** Now for the keyboard: Back on your PC run: $ env GO111MODULE=off go get github.com/fogleman/gg $ env GO111MODULE=off go get github.com/shermp/go-osk //$ env GO111MODULE=off go get github.com/shermp/kobo-sim-usb/simusb $ env GO111MODULE=off go get github.com/shermp/go-kobo-input $ cd ~/go/src/github.com/shermp/go-kobo-input/ $ cd koboin-osk-sample/ $ nano -l main.go Code: 
	 25 //      "fmt"
...
 32 //      "github.com/shermp/kobo-sim-usb/simusb"
...
 57 //      u, err := simusb.New(fb)
 58 //      if err != nil {
 59 //              fmt.Println(err)
 60 //      }
 61 //      err = u.Start(true, true)
 62 //      if err != nil {
 63 //              fmt.Println(err)
 64 //              return
 65 //      }
 66 //      defer u.End(true)
$ env GO111MODULE=off GOOS=linux GOARCH=arm CGO_ENABLED=1 CC=arm-kobo-linux-gnueabihf-gcc CXX=arm-kobo-linux-gnueabihf-g++ go build $ arm-kobo-linux-gnueabihf-strip koboin-osk-sample $ file koboin-osk-sample koboin-osk-sample: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.33, Go Copy the ~/go/src/github.com/shermp/go-kobo-input/koboin-osk-sample/koboin-osk-sample binary to the /mnt/onboard/.adds/koreader/scripts/ folder of your Kobo. Copy the keymap-en_us.json and Roboto-Medium.ttf files from the ~/go/src/github.com/shermp/go-kobo-input/koboin-osk-sample/ folder to the /mnt/onboard/.adds/koreader/ folder of your Kobo. To avoid keyboard taps activating a Nickel function: From More tab (second tab from right at bottom of screen), select Activity. If you are in SideloadedMode=true, then Activity tab is second from left at bottom of screen. Run these commands from an SSH session to the Kobo: # . /korenv.sh # koboin-osk-sample Tap the CAP key for uppercase letters. Tap the RET key to exit. *** To customize our keyboard, we need to: 1. FIX KEY REPEAT ERRORS 2. CHANGE LAYOUT 3. SEND INPUT TO FBPAD *** $ cd ~/go/src/github.com/shermp/go-osk/ $ cd osk/ 1. FIX KEY REPEAT ERRORS: $ nano -l osk.go Code: 
	27 //      "strings"
...
253                                         kc.DrawStringAnchored(string(k.KeyCode), kmx, kmy, 0.5, 0.5)
'''
273                                         if time.Since(v.debounceStartTm) < (200 * time.Millisecond) {
2. CHANGE LAYOUT: $ nano -l osk.go Code: 
	41 KTesc = 7 42 KTtab = 8 43 KTup = 9 44 KTdown = 10 45 KTleft = 11 46 KTright = 12 47 KTpgUp = 13 48 KTpgDn = 14 ... 198 case KTalt: 199 return "ALT" 200 case KTbackspace: 201 return "BKSP" 202 case KTcapsLock: 203 return "CAP" 204 case KTcarriageReturn: 205 return "RET" 206 case KTcontrol: 207 return "CTL" 208 case KTdelete: 209 return "DEL" 210 case KTesc: 211 return "ESC" 212 case KTtab: 213 return "TAB" 214 case KTup: 215 return "^" 216 case KTdown: 217 return "V" 218 case KTleft: 219 return "<" 220 case KTright: 221 return ">" 222 case KTpgUp: 223 return "<<" 224 case KTpgDn: 225 return ">>" $ cd koboin-osk-sample/ $ nano -l keymap-en_us.json Spoiler: 
 $ cp keymap-en_us.json keymap1-en_us.json $ cp keymap-en_us.json keymap2-en_us.json $ nano -l keymap2-en_us.json Spoiler: 
 $ nano -l main.go Spoiler: 
 $ env GO111MODULE=off GOOS=linux GOARCH=arm CGO_ENABLED=1 CC=arm-kobo-linux-gnueabihf-gcc CXX=arm-kobo-linux-gnueabihf-g++ go build $ arm-kobo-linux-gnueabihf-strip koboin-osk-sample Copy the ~/go/src/github.com/shermp/go-kobo-input/koboin-osk-sample/koboin-osk-sample binary to the /mnt/onboard/.adds/koreader/scripts/ folder of your Kobo. Copy the keymap1-en_us.json and keymap2-en_us.json files from the ~/go/src/github.com/shermp/go-kobo-input/koboin-osk-sample/ folder to the /mnt/onboard/.adds/koreader/ folder of your Kobo. To avoid keyboard taps activating a Nickel function: From More tab (second tab from right at bottom of screen), select Activity. If you are in SideloadedMode=true, then Activity tab is second from left at bottom of screen. Run these commands from an SSH session to the Kobo: # . /korenv.sh # koboin-osk-sample Tap the CAP key to change layouts. Tap the RET key to exit. *** 3. SEND INPUT TO FBPAD: To be able to use our keyboard with fbpad terminal, we will send ANSI codes with IOCTL calls instead of simulating input events with uinput. $ cd ~/go/src/github.com/shermp/go-kobo-input/ $ cd koboin-osk-sample/ $ nano -l main.go Spoiler: 
 $ env GO111MODULE=off GOOS=linux GOARCH=arm CGO_ENABLED=1 CC=arm-kobo-linux-gnueabihf-gcc CXX=arm-kobo-linux-gnueabihf-g++ go build -o oskansi $ arm-kobo-linux-gnueabihf-strip oskansi Copy the ~/go/src/github.com/shermp/go-kobo-input/koboin-osk-sample/oskansi binary to the /mnt/onboard/.adds/koreader/scripts/ folder of your Kobo. Note: we have renamed the app "oskansi", meaning on screen keyboard that sends keypresses as ANSI sequences. Now, edit our /mnt/onboard/.adds/koreader/scripts/fbmenu.sh script (from Post #7 above) so we can call our oskansi keyboard app from NickelMenu: # nano -l /mnt/onboard/.adds/koreader/scripts/fbmenu.sh Code: 
	  6 qndb -m dlgConfirmSetTitle "1-Stop agetty; 2-fbpadkb;      3-fbpadkbS;   4-fbpad;          5-fbpadS;        6-oskansi;       7-oskansiS; Select option (1-7):"
...
 18 if [ "$num" == "1" ]; then
 19                 qndb -m mwcToast 500 "You selected 1-Stop agetty+fbpad"
 20                 fbcmd="/usr/bin/pkill agetty"
 21                 qndb -m mwcToast 200 "$fbcmd"
 22                 fberr=$($fbcmd 2>&1)
 23                 fbcmd="/usr/bin/pkill fbpad"
 24                 qndb -m mwcToast 200 "$fbcmd"
 25                 fberr=$($fbcmd 2>&1)
 26                 fbcmd="/usr/bin/pkill fbkeyboard"
 27                 qndb -m mwcToast 200 "$fbcmd"
 28                 fberr=$($fbcmd 2>&1)
 29                 fbcmd="/usr/bin/pkill oskansi"
 30                 qndb -m mwcToast 200 "$fbcmd"
 31                 fberr=$($fbcmd 2>&1)
...
 58 elif [ "$num" == "6" ]; then
 59                 qndb -m mwcToast 1000 "You selected 6-oskansi"
 60                 export HOME="/mnt/onboard/.adds/koreader/"
 61                 cd "$HOME"
 62                 fbcmd="eval /mnt/onboard/.adds/koreader/scripts/fbpadkb /bin/sh 0</dev/tty1"
 63                 qndb -m mwcToast 1000 "$fbcmd"
 64                 fberr=$($fbcmd 2>&1) &
 65                 fbcmd="/mnt/onboard/.adds/koreader/scripts/oskansi"
 66                 qndb -m mwcToast 1000 "$fbcmd"
 67                 fberr=$($fbcmd 2>&1)
 68 elif [ "$num" == "7" ]; then
 69                 qndb -m mwcToast 1000 "You selected 7-oskansiS"
 70                 export HOME="/mnt/onboard/.adds/koreader/"
 71                 cd "$HOME"
 72                 fbcmd="eval /mnt/onboard/.adds/koreader/scripts/fbpadkbS /bin/sh 0</dev/tty1"
 73                 qndb -m mwcToast 1000 "$fbcmd"
 74                 fberr=$($fbcmd 2>&1) &
 75                 fbcmd="/mnt/onboard/.adds/koreader/scripts/oskansi"
 76                 qndb -m mwcToast 1000 "$fbcmd"
 77                 fberr=$($fbcmd 2>&1)
 78 else
 79                 qndb -m mwcToast 1000 "You selected an invalid option" 
 80 fi
 81
 82 qndb -m mwcToast 1000 "${fberr:-"Bye!"}"
*** To avoid keyboard taps activating a Nickel function: From More tab (second tab from right at bottom of screen), select Activity. If you are in SideloadedMode=true, then Activity tab is second from left at bottom of screen. Oskansi keyboard can be started and stopped from NickelMenu and unlike fbkeyboard, doesn't require networking, as well as being much faster, due to sending ANSI codes with IOCTL calls instead of simulating input events with uinput. The biggest issue might be that nothing appears on the fbpad screen due to e.g. oskansi sending codes to /dev/pts/0 but fbpad being on /dev/pts/1, but that shouldn't happen if you start oskansi before any other SSH session. *Also pls see *UPDATE below for NickelMenu entry. *** And don't forget to copy the keymap1-en_us.json, keymap2-en_us.json, and Roboto-Medium.ttf files to the /mnt/onboard/.adds/koreader/ folder of your Kobo. Oskansi binary or fbmenu.sh script should be in /mnt/onboard/.adds/koreader/scripts/ folder. If you're using the fbmenu.sh script above to launch oskansi, you need: 1) NickelDBus installed https://www.mobileread.com/forums/sh...ht=nickel+dbus 2) A NickelMenu config entry like: menu_item :main :fbmenu :cmd_spawn :quiet:exec /mnt/onboard/.adds/koreader/scripts/fbmenu.sh chain_success :dbg_toast :Started fbmenu chain_failure :dbg_toast :Error If you're not using the fbmenu.sh script, you could try NickelMenu config entries like: menu_item :main :fbpadkb :cmd_spawn :quiet :/mnt/onboard/.adds/koreader/scripts/fbpadkb /bin/sh 0</dev/tty1 chain_success :dbg_toast :Started fbpadkb chain_failure :dbg_toast :Error starting fbpadkb menu_item :main : oskansi :cmd_spawn :quiet:exec /mnt/onboard/.adds/koreader/scripts/oskansi chain_success :dbg_toast :Started oskansi chain_failure :dbg_toast :Error *** UPDATE *** * The NickelMenu command (if not using fbmenu.sh) for oskansi should be: menu_item :main : oskansi :cmd_spawn :quiet:export HOME="/mnt/onboard/.adds/koreader/" && cd "$HOME" && /mnt/onboard/.adds/koreader/scripts/oskansi This is because oskansi looks for the font and .json files in the current folder, which would be / by default, so it wouldn't find them if you put them in /mnt/onboard/.adds/koreader/ . *** And grab the fbpadkb.bin binary from Post #6 above and rename it fbpadkb. You need to run this before oskansi. You do not need the agetty hack from Post #7 above, and can comment out the line in /etc/udev/rules.d/90-fbpad.rules unless you are using fbpad with a USB keyboard. Note that the CTL key in oskansi is a toggle so if you forget to retap it you may get funny characters. Though it only works with alphabetic characters. ALT key is a dummy key - maybe someone will want to activate it one day! *** *UPDATE2* Unfortunately, setting "EnableDebugServices=false" in [DeveloperSettings] in the /mnt/onboard/.kobo/Kobo/Kobo eReader.conf file, stopped oskansi keyboard from talking to fbpadkb. Fortunately, you just need to run Dropbear or even telnet from NickelMenu beforehand, and then oskansi works again. https://www.mobileread.com/forums/sh...d.php?t=353810 So it seems that: -fbpad with USB keyboard needs agetty started and stopped in order to not stall. -fbkeyboard needs WiFi on (or USB networking connected), though no hotspot connection needed, in order to not eventually freeze. -oskansi needs either "EnableDebugServices=true" or dropbear/telnet started beforehand via NickelMenu in order to communicate with fbpad. *** * Must rename oskansi.zip to oskansi.xz and extract with xz -d. Last edited by elinkser; 12-04-2023 at 05:59 PM. Reason: NickelMenu entry,EnableDebugServices=false issue  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#11 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				FBPAD2 - WITH USER-CONFIGURABLE FONT AND PERCENTAGE OF DISPLAY
			 
			
			
			*** 
		
	
		
		
			FBPAD2 - WITH USER-CONFIGURABLE FONT AND PERCENTAGE OF DISPLAY One fbpad to do the job of four. fbpad -> fbpad2 fbpadS -> fbpad2 -f RobotoMono-MediumS.tf fbpadkb -> fbpad2 -p 58 fbpadkbS -> fbpad2 -f RobotoMono-MediumS.tf -p 58 * fbpad2 is just a working title - I guess the actual name should be fbpad-eink-rev2 or something. *** From FBInk build of Post #4 above: $ unzip fbpads-master.zip $ cd fbpads-master/ $ cd fbpad_mkfn/ $ make Grab some fonts e.g.: RobotoMono-Medium.ttf GWMonospace.ttf Generate small fonts for fbpadkbS: $ nano -l gen.sh CODE] 5 # OP="-h34 -w19" 6 # SZ="18h135v135" 7 OP="-h26 -w14" 8 SZ="18h100v100" 9 ./mkfn_ft $OP $FP/RobotoMono-Medium.ttf:$SZ >RobotoMono-MediumS.tf 10 ./mkfn_ft $OP $FP/GWMonospace.ttf:$SZ >GWMonospaceS.tf [/CODE] $ ./gen.sh tinyfont[ 875]: height=26 width=14 tinyfont[ 2858]: height=26 width=14 Generate large fonts for fbpadkb: $ nano -l gen.sh CODE] 5 OP="-h34 -w19" 6 SZ="18h135v135" 7 # OP="-h26 -w14" 8 # SZ="18h100v100" 9 ./mkfn_ft $OP $FP/RobotoMono-Medium.ttf:$SZ >RobotoMono-Medium.tf 10 ./mkfn_ft $OP $FP/GWMonospace.ttf:$SZ >GWMonospace.tf [/CODE] $ ./gen.sh tinyfont[ 875]: height=34 width=19 tinyfont[ 2858]: height=34 width=19 $ ls -l *.tf -rw-r--r-- 136976 courr.tf -rw-r--r-- 322024 RobotoMono-MediumS.tf -rw-r--r-- 568774 RobotoMono-Medium.tf -rw-r--r-- 1051768 GWMonospaceS.tf -rw-r--r-- 1857724 GWMonospace.tf $ cd .. $ cd .. $ tar xJf FBInk-v1.25.0.tar.xz $ cd FBInk-v1.25.0/ $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare $ make static $ cd .. $ unzip fbpad-eink-master.zip $ cd fbpad-eink-master/ $ cp -r ../FBInk-v1.25.0/Release FBInk/ $ cp ../FBInk-v1.25.0/fbink.h FBInk/ $ cp ../fbpads-master/fbpad_mkfn/*.tf fonts/ *** $ nano -l Makefile Code: 
	3 CC := arm-kobo-linux-gnueabihf-gcc 4 all: fbpad2 ... 6 %.o: %.c conf.h ... 10 xxd -i fonts/RobotoMono-Medium.tf > font.h 11 fbpad2: fbpad.o term.o pad.o draw.o font.o isdw.o scrsnap.o FBInk/Release/libfbink.a ... 15 rm -f *.o fbpad2 $ rm font.h $ make font.h xxd -i fonts/RobotoMono-MediumS.tf > font.h $ nano -l conf.h Code: 
	17 typedef int fbval_t; ... 20 #define FR "ar.tf" 21 #define FI "ai.tf" 22 #define FB "ab.tf" Code: 
	 37 struct font *embeddefont(){
 38         struct font *font;
 39         struct tinyfont head;
 40     memcpy(&head, fonts_RobotoMono_Medium_tf, sizeof(head));
 41         font = malloc(sizeof(*font));
 42         font->n = head.n;
 43         font->rows = head.rows;
 44         font->cols = head.cols;
 45         font->rows = head.rows;
 46         font->glyphs = (int*)(fonts_RobotoMono_Medium_tf + sizeof(head));
 47         font->data =(char*) (fonts_RobotoMono_Medium_tf + sizeof(head) + font->n * sizeof(int));
 48     printf("n %d\n", font->n);
 49     printf("cols %d\n", font->cols);
 50     printf("rows %d\n", font->rows);
 51         return font;
 52 }
Code: 
	57 int pad_init(char *tinyfont, int percentDisplay); ... 67 struct font *embeddefont(void); Code: 
	335 int main(int argc, char *argv[])
336 {
337         char *hide = "\x1b[2J\x1b[H\x1b[?25l";
338         char *show = "\x1b[?25h";
339         char **args = argv + 1;
340         char *tinyfont = NULL;
341         int percentDisplay = 100;
342         if (fb_init(FBDEV)) {
...
351         int i;
352         int j = 0;
353         for (i = 1; i < argc; i++) {
354                 if (argv[i][0] == '-' && argv[i][1] == 'f') {
355                         tinyfont = argv[++i];
356                         j++;
357                 } else if (argv[i][0] == '-' && argv[i][1] == 'p') {
358                         percentDisplay = atoi(argv[++i]);
359                         if (percentDisplay < 1)
360                                 percentDisplay = 1;
361                         if (percentDisplay > 99)
362                                 percentDisplay = 100;
363                         j++;
364                 } else if (argv[i][0] == '-' && argv[i][1] == 'h') {
365                         printf("usage: %s [options] [command]\npossible options are:\n -h: print this help\n -f: set path to tinyfont\n -p: set percent display\n",argv[0]);
366                         return 1;
367                 }
368         }
369         args = args + 2 * j;
370
371         if (pad_init(tinyfont, percentDisplay)) {
372                 fprintf(stderr, "fbpad: cannot find fonts\n");
373                 return 1;
374         }
Code: 
	 21 int pad_init(char* tinyfont)
 22 {
 23         if (pad_font(tinyfont, FI, FB))
 24                 return 1;
 25         rows = fb_rows() * percentDisplay / 100 / fnrows;
...
219 int pad_font(char *fr, char *fi, char *fb)
220 {
221         struct font *r = font_open(fr);
222         if (!r) {
223                 r = font_open("ar.tf");
224                 if (!r) {
225                         r = embeddefont();
226                         if (!r) 
227                                 return 1;
228                 }
229         }
230         fonts[0] = r;
231         fonts[1] = NULL;
232         fonts[2] = NULL;
233         memset(gc_info, 0, sizeof(gc_info));
234         fnrows = font_rows(fonts[0]);
235         fncols = font_cols(fonts[0]);
236         return 0;
237 }
$ make $ ls -l fbpad2 -rwxr-xr-x 604248 fbpad2 Copy fbpad2 to /mnt/onboard/.adds/koreader/scripts/ folder on your Kobo. Copy the tinyfonts you generated to the /mnt/onboard/.adds/koreader/ folder on your Kobo: courr.tf GWMonospaceS.tf GWMonospace.tf RobotoMono-MediumS.tf RobotoMono-Medium.tf On the kobo, rename whichever tinyfont you want to be the regular font to "ar.tf", e.g.: # cp RobotoMono-MediumS.tf ar.tf From SSH shell run (after first running ". /korenv.sh" as was done in Post #4): # fbpad2 -p 58 /bin/sh n 875 cols 14 rows 26 1072x1448 pixels, so 76x32 characters Input commands from your SSH shell. Now kill fbpad2 (e.g. with fbmenu.sh entry) and retry fbpad2 in the built-in font: For fbpad2 to use the built-in font, there must be no ar.tf, so delete it: # rm ar.tf # fbpad2 -p 58 /bin/sh n 875 cols 19 rows 34 1072x1448 pixels, so 56x24 characters Run a command e.g. "ps" and you see the built-in larger RobotoMono-Medium.tf font. Now kill fbpad2 and retry fbpad2 in a font you specify as a command line parameter: # fbpad2 -f courr.tf -p 58 /bin/sh n 323 cols 15 rows 28 1072x1448 pixels, so 71x29 characters *** You can also crosscompile the mkfn_ft binary to convert ttf fonts to tf right on your Kobo: Grab some fonts e.g.: DejaVuSansMono.ttf $ cd ttf-build $ cd fbpads-master/ $ cd fbpad_mkfn/ $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare Freetype https://freetype.org/download.html Download from: https://sourceforge.net/projects/fre...etype2/2.13.1/ $ tar zxvf freetype-2.13.1.tar.gz $ cd freetype-2.13.1/ $ ./configure --host=arm-kobo-linux-gnueabihf $ make $ cd .. $ nano -l Makefile Code: 
	2 CC = arm-kobo-linux-gnueabihf-gcc ... 4 CFLAGS = -O2 -Wall -I./freetype-2.13.1/include/ ... 11 $(CC) -c $(CFLAGS) mkfn_ft.c 12 $(CC) -o $@ mkfn_ft.o mkfn.o isdw.o $(LDFLAGS) ./freetype-2.13.1/objs/.libs/libfreetype.a $ make $ file mkfn_ft mkfn_ft: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.33, with debug_info, not stripped Generate large fonts for fbpadkb: $ nano -l gen.sh CODE] 5 OP="-h34 -w19" 6 SZ="18h135v135" 7 # OP="-h26 -w14" 8 # SZ="18h100v100" 9 ./mkfn_ft $OP $FP/DejaVuSansMono.ttf:$SZ >DejaVuSansMono.tf 10 [/CODE] Now copy the mkfn_ft binary, the gen.sh script, and the DejaVuSansMono.ttf font to the /mnt/onboard/.adds/koreader/ folder of your Kobo. Now on your Kobo, cd to the /mnt/onboard/.adds/koreader/ folder and run the gen.sh script. # ./gen.sh tinyfont[ 3258]: height=34 width=19 # ls -l *.tf -rw-r--r-- 2117724 DejaVuSansMono.tf Add characters like ¡€£°♜幸☺♫√ꭍ to one of your oskansi keyboard layouts. (They may appear as empty squares on the keyboard if the default oskansi font of Roboto-Medium.ttf does not include their code.) Run fbpad2 using the same font in tinyfont format: # fbpad2 -f DejaVuSansMono.tf -p 58 /bin/sh Now if you run oskansi, the shell still shows Unicode characters as question marks, but if you enter characters into an app like nano, at least some characters are displayed: # . /korenv.sh # nano /mnt/onboard/shared/u.txt Code: 
	¡€£°♜幸☺♫√ꭍ And if you open u.txt on a desktop environment with a font that supports more Unicode characters, you will see they were faithfully transmitted. Moreover, running gnuchess in graphic mode shows the symbols. # gnuchess -e -g White (1) : e2e4 1. e2e4 black KQkq e3 ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖ Thinking... white KQkq ♜ ♞ ♝ ♛ ♚ ♝ ♜ ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♞ ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖ My move is : Nf6 White (2) : quit Not necessarily more legible, but at least it's Unicode, right? *** *UPDATE - START PERCENT DISPLAY COMMANDLINE OPTION: Enable putting fbpad2 at bottom since now you can put fbkeyboard2 at top (see following post): $ nano -l fbpad.h Code: 
	... 57 int pad_init(char *tinyfont, int percentDisplay, int starttDisplay); ... Code: 
	...
350         int percentDisplay = 100;
351         int starttDisplay = 0;
352         if (fb_init(FBDEV)) {
...
374                         startDisplay = atoi(argv[++i]);
375                         if (startDisplay < 0)
376                                 startDisplay = 0;
377                         if (startDisplay > 99)
378                                 startDisplay = 99;
379                         j++;
380                 } else if (argv[i][0] == '-' && argv[i][1] == 'h') {
381                         printf("usage: %s [options] [command]\npossible options are:\n -h: print this help\n -f: set path to tinyfont\n -p: set percent display\n -s: set start percent display\n",argv[0]);
382                         return 1;
383                 }
...
387         if (pad_init(tinyfont, percentDisplay, startDisplay)) {
...
Code: 
	...
 15 static int startRow;
...
 21 int pad_init(char* tinyfont, int percentDisplay, int startDisplay)
 22 {
 23         if (pad_font(tinyfont, FI, FB))
 24                 return 1;
 25         startRow = fb_rows() * startDisplay / 100 / fnrows;
 26         rows = fb_rows() * percentDisplay / 100 / fnrows;
 27         if (rows > (fb_rows() / fnrows - startRow))
 28                 rows = (fb_rows() / fnrows - startRow);
 29         cols = fb_cols() / fncols;
 30         printf("%dx%d pixels, so %dx%d characters\n", fb_cols(), fb_rows(), cols, rows );
 31         return 0;
 32 }
...
149 void pad_put(int ch, int r, int c, int fg, int bg)
150 {
151         r = r + startRow;
...
179 void pad_fill(int sr, int er, int sc, int ec, int c)
180 {
181         sr = sr + startRow;
182         er = er + startRow;
183         int fber = er >= 0 ? er * fnrows : (startRow + rows) * fnrows;
184         int fbec = ec >= 0 ? ec * fncols : fb_cols();
...
$ make Now on kobo try fbpad2 at bottom with fbkeyboard2 at top (see following post): # . /korenv.sh # fbpad2 -p 63 -s 37 /bin/sh 0</dev/tty1 & # fbkeyboard2 -c 99 -g Keyboard is at the top, terminal output at the bottom! *** TRY THE TAGS TERMINAL SWITCHING AND SCROLLING FEATURE OF FBPAD: There is a cool tags system in fbpad you can access if you run "fbpad2" by itself, i.e. without the "/bin/sh" parameter. Then you need to enter ALT-c from keyboard to start a shell, list tags with ALT-p, and switch terminals with ALT-x, where x can be one of the terminals listed in conf.h, i.e. "xnlhtr01uiva-". Run fbpad2 from an SSH session. # fbpad2 -p 63 -s 37 0</dev/tty1 & # fbkeyboard2 -c 99 -g Enter ALT-c and you get the shell prompt on the Kobo display. Enter ALT-p and you get the tags list at the bottom of the screen, e.g.: TAGS: (x) n l h t r 0 1 u i v a - Enter ALT-n then ALT-p, the tags list shows you have switched to terminal (n): TAGS: x (n) l h t r 0 1 u i v a - Enter ALT-c and enter a command e.g. "ls"<RET> Enter ALT-x then ALT-p, the tags list shows you have switched back to terminal (x): TAGS: (x) n l h t r 0 1 u i v a - Enter a command e.g. "lsof"<RET> Enter a command e.g. "ps"<RET> Enter ALT-, and you scroll up. Enter ALT-. and you scroll down. CTRL-ALT-q to end the fbpad session. CTRL-ALT-x to end the fbkeyboard session. Now try fbpad2 with the shell command as a command line argument. # fbpad2 -p 63 -s 37 /bin/sh 0</dev/tty1 & # fbkeyboard2 -c 99 -g Now the terminal appears without needing to enter ALT-c. However the tag commands no longer work and you cannnot use CTRL-ALT-q to end the fbpad session. (However you can still use "pkill fbpad" then CTRL-ALT-x to end the fbkeyboard session.) Binaries fbpad2-shared and fbkeyboard2-shared from Post #12 should work the same way *** Note: Segmentation error message on exit due to introduction of embeddefont() in fbpad-eink corrected here: $ nano -l font.c Code: 
	...
 45 //      font->rows = head.rows;
...
106 void font_free(struct font *font)
107 {
108         struct tinyfont head;
109         if (font->glyphs != (int*)(fonts_RobotoMono_Medium_tf + sizeof(head))) {
110                 if (font->data)
111                         free(font->data);
112                 if (font->glyphs)
113                         free(font->glyphs);
114         }
115         free(font);
116 }
...
MAKE SHARED VERSION OF FBPAD2: $ cd .. $ cd fbpad-eink-master/ $ cp -r ../FBInk-v1.25.0/Release FBInk/ $ nano -l Makefile Code: 
	... 2 LDFLAGS += -lutil -lm -LFBInk/Release/ -lfbink 3 CC := arm-kobo-linux-gnueabihf-gcc 4 all: fbpad2-shared ... 11 fbpad2-shared: fbpad.o term.o pad.o draw.o font.o isdw.o scrsnap.o ... 15 rm -f *.o fbpad2-shared *** $ zip -r fbpad2.zip fbpad2/ *** Last edited by elinkser; 01-26-2024 at 07:11 PM. Reason: korenv.sh,mkfn-kobo,startDisplay,shared,tags,seg on exit  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#12 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				FBKEYBOARD2 - improved key mappings + rotate modes
			 
			
			
			*** 
		
	
		
		
			FBKEYBOARD2 - improved key mappings + rotate modes *** Notice that the Esc key causes the Kobo to go into sleep mode, which is a problem if we want to enter command mode in Vi, or call up the menu in elinks. Until we address Kobo's grabbing of the input in various other ways, we can still get by with: 1) Ctrl-c in Vi can also be used instead of Esc to enter command mode. 2) We can remap the 'm' key instead of Esc in elinks to open the menu. In Post #4 we already remapped some elinks keys by appending to the elinks config file: $ nano -l /mnt/onboard/.adds/koreader/.elinks/elinks.conf Code: 
	################################## # Automatically saved keybindings # bind "main" "Ctrl-F" = "frame-next" bind "main" "Ctrl-B" = "frame-prev" bind "main" "," = "history-move-back" bind "main" "." = "history-move-forward" bind "main" "u" = "link-info" bind "main" "Alt-l" = "lua-console" bind "main" "Down" = "move-cursor-down" bind "main" "Left" = "move-cursor-left" bind "main" "Right" = "move-cursor-right" bind "main" "Up" = "move-cursor-up" bind "main" "Tab" = "move-link-next" bind "main" "Shift-Tab" = "move-link-prev" bind "main" "#" = "toggle-numbered-links" bind "main" "Ctrl-Right" = "none" Up,Down,Left,Right -> move cursor Tab,Shift-Tab -> travel links on a page . -> go forward in history , -> go back in history Some handy default key mappings are: Space -> page down b -> page up [ or { -> scroll left ] or } -> scroll right. Enter to edit a text field, d -> download link a -> add bookmark s -> show bookmarks Esc -> main menu g -> enter new address or '.' for current directory q -> quit T -> open in new tab <,> -> go to previous,next tab c -> close tab W -> wrap text In the numeric layout of fbkeyboard.c, there are some empty key slots after the '/', which if pressed, currently yield "cvbnm". We will assign "aswtc" to them in char *layout[] and in keys[][26] so that in elinks we can access when in the numeric keyboard layout: a -> add bookmark s -> show bookmarks w -> wrap text t -> open in new tab c -> close tab To do this we will further append to the elinks config file as follows: $ nano -l /mnt/onboard/.adds/koreader/.elinks/elinks.conf Code: 
	################################## # Automatically saved keybindings # bind "main" "Ctrl-F" = "frame-next" bind "main" "Ctrl-B" = "frame-prev" bind "main" "," = "history-move-back" bind "main" "." = "history-move-forward" bind "main" "u" = "link-info" bind "main" "Alt-l" = "lua-console" bind "main" "Down" = "move-cursor-down" bind "main" "Left" = "move-cursor-left" bind "main" "Right" = "move-cursor-right" bind "main" "Up" = "move-cursor-up" bind "main" "Tab" = "move-link-next" bind "main" "Shift-Tab" = "move-link-prev" bind "main" "#" = "toggle-numbered-links" bind "main" "Ctrl-Right" = "none" # bind "main" "w" = "toggle-wrap-text" bind "main" "t" = "open-link-in-new-tab" bind "main" "m" = "menu" Also in fbkeyboard2, we will reassign top row keys when in CAPS LOCK mode from Up, Down, Left, Right, and PageDown to accelerated (4 x) direction keys,and PageUp. Also in fbkeyboard2, we will configure rotation modes for the Clara HD. *** $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare Build FBInk and Freetype as in Post #6. $ unzip fbkeyboard-master.zip $ cd fbkeyboard-master/ *** Edit fbkeyboard.c * EXACTLY AS IN POST #6 *, except correct the following error: $ nano -l fbkeyboard.c Code: 
	... 605 fprintf(stderr, "fbkeyboard: fbval_t does not match framebuffer depth (%d bytes)\n", FBM_BPP(fb_mode()) ); ... $ nano -l fbkeyboard.c Code: 
	...
 36 char *font = "./RobotoMono-Bold.ttf";
...
 39         { "Esc", "Tab", " ^ ", " v ", " < ", " > ", ">> " },
 40         { "Esc", "Tab", " 4^", " 4v", " 4<", " 4>", "<< " },
...
 46         "1234567890-=[];\'\\,.`/aswtc",
 47         "!@#$%^&*()_+{}:\"|<>~?aswtc"
...
 60           KEY_GRAVE, KEY_SLASH, KEY_A, KEY_S, KEY_W, KEY_T, KEY_C },
...
102         switch (rotate) {
103                 case FB_ROTATE_UR:
104                 case FB_ROTATE_UD:
105                 case FB_ROTATE_CW:
106                 case FB_ROTATE_CCW:
107                         break;
108 /*              case FB_ROTATE_UD:
...
121                         break; */
...
136         switch (rotate) {
137                 case FB_ROTATE_UR:
138                 case FB_ROTATE_UD:
139                 case FB_ROTATE_CW:
140                 case FB_ROTATE_CCW:
141                         FT_Load_Char(face, c, FT_LOAD_RENDER);
142                         x += face->glyph->bitmap_left;
143                         y += (face->size->metrics.ascender >> 6) - face->glyph->bitmap_top;
144                         advance = face->glyph->advance.x >> 6;
145                         break;
146 /*              case FB_ROTATE_UD:
...
184                         break; */
...
307         switch (rotate) {
308                 case FB_ROTATE_UR:
309                 case FB_ROTATE_UD:
310                 case FB_ROTATE_CW:
311                 case FB_ROTATE_CCW:
312                         lseek(fbfd, fblinelength * (fbheight - height * 6), SEEK_SET);
313                         write(fbfd, buf, buflen);
314                         keyb_refresh(fbfd, fbheight - height * 6, 0, width, fbheight);
315                         break;
316 /*              case FB_ROTATE_UD:
...
334                         break; */
...
369         switch (rotate) {
370                 case FB_ROTATE_UR:
371                         *x = 0x10000 - absolute_y * 0x10000 / theight;
372                         *y = absolute_x * 0x10000 / twidth;
373                         break;
374                 case FB_ROTATE_UD:
375                         *x = 0x10000 - absolute_x * 0x10000 / twidth;
376                         *y = 0x10000 - absolute_y * 0x10000 / theight;
377                         break;
378                 case FB_ROTATE_CW:
379                         *x = absolute_y * 0x10000 / theight;
380                         *y = 0x10000 - absolute_x * 0x10000 / twidth;
381                         break; 
382                 case FB_ROTATE_CCW:
383                         *x = absolute_x * 0x10000 / twidth;
384                         *y = absolute_y * 0x10000 / theight;
385                         break; 
386         }
...
436                 default:
437                         *row = 5;               // cursor, Enter, Home, PgDn, etc
438 /*                      *pressed = 3 * y / (0x10000 - trowh * 5);
439                         *pressed *= 3;
440                         *pressed += 3 * x / 0x10000; */
441                         break;
...
466         if (pressed == 99)      // second page
467                 layoutuse ^= 2;
468         else if (row == 1 && (layoutuse & 1) > 0 && (layoutuse & 2) > 0 && (pressed > 20)) {
469                 ie.type = EV_KEY;
470                 ie.code = KEY_LEFTSHIFT;
471                 ie.value = layoutuse & 0;
472                 if (write(fduinput, &ie, sizeof(ie)) != sizeof(ie))
473                         fprintf(stderr, "error sending uinput event\n");
474                 send_key(keys[row + (layoutuse >> 1)][pressed]);
475                 ie.type = EV_KEY;
476                 ie.code = KEY_LEFTSHIFT;
477                 ie.value = layoutuse & 1;
478                 if (write(fduinput, &ie, sizeof(ie)) != sizeof(ie))
479                         fprintf(stderr, "error sending uinput event\n");
480         } else if (row == 1) {  // normal keys (abc, 123, !@#)
...
510         } else if (row == 0 && (layoutuse & 1) > 0) {
511                 ie.type = EV_KEY;
512                 ie.code = KEY_LEFTSHIFT;
513                 ie.value = layoutuse & 0;
514                 if (write(fduinput, &ie, sizeof(ie)) != sizeof(ie))
515                         fprintf(stderr, "error sending uinput event\n");
516                 if (pressed == 6) { 
517                         send_key(KEY_PAGEUP);
518                 } else if (pressed == 2) {
519                         send_key(KEY_UP);
520                         send_key(KEY_UP);
521                         send_key(KEY_UP);
522                         send_key(KEY_UP);
523                 } else if (pressed == 3) {
524                         send_key(KEY_DOWN);
525                         send_key(KEY_DOWN);
526                         send_key(KEY_DOWN);
527                         send_key(KEY_DOWN);
528                 } else if (pressed == 4) {
529                         send_key(KEY_LEFT);
530                         send_key(KEY_LEFT);
531                         send_key(KEY_LEFT);
532                         send_key(KEY_LEFT);
533                 } else if (pressed == 5) {
534                         send_key(KEY_RIGHT);
535                         send_key(KEY_RIGHT);
536                         send_key(KEY_RIGHT);
537                         send_key(KEY_RIGHT);
538                 } else {
539                         send_key(keys[row][pressed]);
540                 }
541                 ie.type = EV_KEY;
542                 ie.code = KEY_LEFTSHIFT;
543                 ie.value = layoutuse & 1;
544                 if (write(fduinput, &ie, sizeof(ie)) != sizeof(ie))
545                         fprintf(stderr, "error sending uinput event\n");
546         } else {
547                 send_key(keys[row][pressed]);
548         }
...
673         switch (rotate) {
674                 case FB_ROTATE_UR:
675                 case FB_ROTATE_UD: 
676                 case FB_ROTATE_CW:
677                 case FB_ROTATE_CCW:
678                         landscape = fbheight < fbwidth;
679                         width = fbwidth;
680                         height = fbheight / (landscape ? 2 : 3) / 5;    // height of one row
681                         trowh = height * 0x10000 / fbheight;
682                         linelength = fblinelength;
683                         buflen = linelength * (height * 5 + 1);
684                         break;
685 /*              case FB_ROTATE_CW: 
...
693                         break; */
...
$ cp -r ../FBInk-v1.25.0/Release FBInk/ $ cp ../FBInk-v1.25.0/fbink.h FBInk/ $ cp ../fbpad-eink-master/draw.c . $ cp ../fbpad-eink-master/draw.h . $ cp ../fbpad-eink-master/conf.h . Edit draw.c and draw.h, also as in Post #6, but correct the following error: $ nano -l draw.c Code: 
	...
166 void keyb_refresh(int fd, int invalid_top, int invalid_left, int invalid_right, int invalid_bottom) {
...
$ arm-kobo-linux-gnueabihf-gcc -o fbkeyboard2 -I../freetype-2.13.1/include/ fbkeyboard.c draw.c libfreetype.a FBInk/Release/libfbink.a $ ls -l fbkeyboard2 -rwxr-xr-x 588844 fbkeyboard2 Copy the fbkeyboard2 binary to the /mnt/onboard/.adds/koreader/scripts/ folder on your Kobo. Copy the RobotoMono-Bold.ttf font to the /mnt/onboard/.adds/koreader/ folder on your Kobo (although with fbkeyboard you can also specify a font using the -f commandline argument.) Edit /mnt/onboard/.adds/nm/config.txt to add a NickelMenu entry like this: Code: 
	menu_item :main    :fbkeyboard2         :cmd_spawn          :quiet :export HOME="/mnt/onboard/.adds/koreader/" && cd "$HOME" && /mnt/onboard/.adds/koreader/scripts/fbkeyboard2
    chain_success                      :dbg_toast          :Started fbkeyboard2
    chain_failure                      :dbg_toast          :Error starting fbkeyboard2
ROTATION MODES: Your NickelMenu may already have rotation options: Code: 
	# Nickel_Orientation Actions menu_item : main : Orientation - LANDSCAPE - handle above : nickel_orientation: landscape menu_item : main : Orientation - LANDSCAPE - handle below : nickel_orientation: inverted_landscape menu_item : main : Orientation - PORTRAIT - handle on left : nickel_orientation: inverted_portrait menu_item : main : Orientation - PORTRAIT - handle on right : nickel_orientation: portrait You can specify an fbkeyboard2 rotation with the -r commandline argument. On my Clara HD, this is how they map: fbkeyboard2 -r 3 -> LANDSCAPE - handle above fbkeyboard2 -r 2 -> LANDSCAPE - handle below fbkeyboard2 -r 1 -> PORTRAIT - handle on left fbkeyboard2 -r 0 -> PORTRAIT - handle on right If you are in landscape mode, you would want to restrict the percentage of the display that fbpad2 uses, with e.g.: Code: 
	menu_item :main    :fbpad2 -p 42       :cmd_spawn          :quiet :/mnt/onboard/.adds/koreader/scripts/fbpad2 -p 42  /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpad2
    chain_failure                      :dbg_toast          :Error starting fbpad2
*** *UPDATE: COPY AND PASTE IN ELINKS Edit: use 'e' instead of 'm' for opening menu in /mnt/onboard/.adds/koreader/.elinks/elinks.conf. The default use of 'm' followed by a character, e.g. 'a' allows you to save your place in the document, and return to it by entering "'" then your character , e.g. 'a'. bind "main" "e" = "menu" bind "main" "S" = "save-as" bind "main" "Ctrl-o" = "open-os-shell" Use 'E' to open current link under cursor into a text field. (Or 'S' for current URL.) Use "Ctrl-x" to copy link. Use "Ctrl-v" to paste link. *** Using Screen utility for copy-pasting: The screen app has only the following dependencies: Depends (4) libutempter musl* ncurses-libs* utmps-libs *already got these from elinks/nano install in Post #3. RUN THESE COMMANDS FROM LINUX DESKTOP: DOWNLOAD THE REQUIRED PACKAGES: $ cd myalpine/ $ wget https://dl-cdn.alpinelinux.org/alpin...n-4.9.0-r1.apk $ wget https://dl-cdn.alpinelinux.org/alpin...r-1.2.1-r5.apk $ wget https://dl-cdn.alpinelinux.org/alpin....12.0.1-r0.apk $ wget https://dl-cdn.alpinelinux.org/alpin...0.1.2.0-r1.apk $ tar zxvf screen-4.9.0-r1.apk $ tar zxvf libutempter-1.2.1-r5.apk $ tar zxvf skalibs-2.12.0.1-r0.apk $ tar zxvf utmps-libs-0.1.2.0-r1.apk $ mv usr/bin/screen-4.9.0 scripts/screen $ mv usr/lib/libutempter.so.1.2.1 libs/libutempter.so.0 $ mv lib/libskarnet.so.2.12.0.1 libs/libskarnet.so.2.12 $ mv lib/libutmps.so.0.1.2.0 libs/libutmps.so.0.1 NOW CONNECT YOUR KOBO TO YOUR PC: Copy your screen binary from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. Copy new libs from the libs/ folder on the PC to the /mnt/onboard/.adds/koreader/libs/ folder on the kobo: libutempter.so.0 libskarnet.so.2.12 libutmps.so.0.1 Copy the usr/share/screen/ folder on the PC to the /usr/share/ folder on the kobo. Copy the etc/screenrc file on the PC to the /etc/ folder on the kobo. Copy the etc/skel/ folder on the PC to the /etc/ folder on the kobo. RUN THESE FROM FBPAD2/FBKEYBOARD2 TERMINAL: # . /korenv.sh # screen (Press Ret to dismiss message) # elinks . enter 'g' to open new URL enter e.g. "g elinks doc" click on the link, e.g. "http://elinks.or.cz/documentation/index.html" enter 'a' to add to bookmarks enter 's' to show bookmarks Use the arrow keys to move to a link you want, e.g. "Documentation" Use 'E' to open current link under cursor into a text field. (Or just 'S' to open current URL.) Use "Ctrl-x" to copy link. Use "Ctrl-v" to paste link. Cancel to exit the dialog. Enter "Ctrl-a" and then 'c' to open a new screen window. Type the name of a command, e.g. 'echo > try.txt "' followed by "Ctrl-a" and then ']' and '"' and you get the text pasted to the file: # cat try.txt http://elinks.or.cz/documentation/index.html (Was it worth the effort. i.e.you could have just saved as a bookmark, then retrieved the link from /mnt/onboard/.adds/koreader/.elinks/bookmarks!) Move back and forth between screen terminals with "Ctrl-a" and then '0' or '1', or just "Ctrl-a" "Ctrl-a". Enter 'q' to exit elinks. "Ctrl-a" and then '\' to kill all windows and terminate screen. *** Some time later... OK definitely worth it for me anyway. Check this out: On your Kobo: # . /korenv.sh Create a sample html file with a form field: # nano text.html Code: 
	<html> <textarea rows="3" cols="20"> Enter text here... </textarea> </html> # elinks text.hml Enter "Ctrl-a" and then 'c' to open a second screen window. # vi bla.txt Enter 'i' to get into insert mode Type some text in the editor, e.g. Code: 
	blablabla hahahaha wawawa Enter "Ctrl-n" or "Ctrl-p" to get to the start line you want, then Space (no 'Ctrl') to start the copy. Enter "Ctrl-n" or "Ctrl-p" to get to the end line you want, then Space (no 'Ctrl') to complete the copy. Enter "Ctrl-a" then '0' (no 'Ctrl') to return to the first screen window. Press Enter in the text box, then "Ctrl-a" then ']' (no 'Ctrl') to paste the text from the second window. Screen also allow off-screen scrolling in copy mode using the same "Ctrl-n" or "Ctrl-p" keys. Just remember not to press any other key,or it will be aborted.(Maybe "Ctrl-h" is permitted.) (Must stay aware of the 'Ctrl' key toggle state.) In this way I could even run 'ps' and copy offscreen process names like "/usr/local/kfmon/bin/kfmon" to the other window. Enter "Ctrl-a" then 'd' (no 'Ctrl') to detach from the session. Run KOReader. From KOReader Terminal: # screen -r And you are back in! "Ctrl-a" and then 'k' to kill window. *** *UPDATE2 - LOWKEY PROFILES FOR MORE DISPLAY SPACE $ nano -l fbkeyboard.c Code: 
	 76 int lowkey; // low key profile
...
 97 int z;
...
312                         lseek(fbfd, fblinelength * (fbheight - height * (6 + lowkey)), SEEK_SET);
313                         write(fbfd, buf, buflen);
314                         keyb_refresh(fbfd, fbheight - height * (6 + lowkey), 0, width, fbheight);
315                         break;
...
395 void identify_touched_key(int x, int y, int *row, int *pressed)
396 {
397         z = ((0x10000 - y) / trowh);
398                 if (z == (5 + lowkey)) {
399                         *row = 0;               // Esc, Tab, F10, etc
400                         *pressed = x * 7 / 0x10000;
401                 /*      break; */
402                 } else if (z == (4 + lowkey)) {
403                         *row = 1;               // q - p
404                         *pressed = x * 10 / 0x10000;
405                 /*      break; */
406                 } else if (z == (3 + lowkey)) {
407                         *row = 1;               // a - l
408                         if (x > 0x10000 / 20 && x < 0x10000 * 19 / 20)
409                                 *pressed = 10 + (x * 10 - 0x10000 / 2) / 0x10000;
410                 /*      break; */
411                 } else if (z == (2 + lowkey)) {
412                         if (x < 0x10000 * 3 / 20) {
413                                 *row = 3;
414                                 *pressed = 0;   // Left Shift
415                         } else if (x < 0x10000 * 17 / 20) {
416                                 *row = 1;       // z - m
417                                 *pressed = 19 + (x * 10 - 0x10000 * 3 / 2) / 0x10000;
418                         } else {
419                                 *row = 3;
420                                 *pressed = 1;   // Bcksp
421                         }
422                 /*      break; */
423                 } else if (z == (1 + lowkey)) {
424                         *row = 4;
425                         if (x < 0x10000 * 3 / 20)
426                                 *pressed = 99;  // 123!@
427                         else if (x < 0x10000 * 5 / 20)
428                                 *pressed = 0;   // Left Alt
429                         else if (x < 0x10000 * 15 / 20)
430                                 *pressed = 1;   // Space
431                         else if (x < 0x10000 * 17 / 20)
432                                 *pressed = 2;   // Right Ctrl
433                         else
434                                 *pressed = 3;   // Enter
435                 /*      break; */
436                 } else {
437                         *row = 5;               // cursor, Enter, Home, PgDn, etc
438 /*                      *pressed = 3 * y / (0x10000 - trowh * 5);
439                         *pressed *= 3;
440                         *pressed += 3 * x / 0x10000; */
441                 /*      break; */
442                 }
443 }
...
629         while ((c = getopt(argc, argv, "d:f:r:l:h")) != (char) -1) {
...
645                 case 'l':
646                         errno = 0;
647                         lowkey = strtol(optarg, &p, 10) % 3;
648                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
649                                 printf("Invalid numeric value for -l option\n");
650                                 exit(0);
651                         }
652                         break;
...
688                         height = fbheight / (landscape ? (2 + lowkey) : (3 + lowkey)) / 5;      // height of one row
689                         trowh = height * 0x10000 / fbheight;
690                         linelength = fblinelength;
691                         buflen = linelength * (height * 5 + (1 + lowkey));
*** Now you can use the -l commandline argument for lower profile keyboard layouts, to get more display space: # fbkeyboard2 -r 0 -l 0 -> normal width # fbkeyboard2 -r 0 -l 1 -> low key width # fbkeyboard2 -r 0 -l 2 -> extreme "loco" low key width *** *UPDATE3 - ADDITIONAL COMMANDLINE OPTIONS # fbkeyboard2 -h usage: fbkeyboard2 [options] possible options are: -h: print this help -d: set path to input device -f: set path to ttf font file -r: set rotation 0-3 -l: set lowkey profile 0-2 -x: set direction key acceleration factor 1-9 (default 4) -b: set base interval 1-999 (default 100) in uS between any key presses -a: set additional interval 1-999 (default 250) in mS between same key presses -g: set grab input events 0-1 $ nano -l fbkeyboard.c Code: 
	 77 int acceleration = 4; // direction keys acceleration factor
 78 int baseDelay = 100; // base keybounce delay(uS) any key 
 79 int additionalDelay = 250; // additional keybounce delay(mS) same key
 80 int grabInput = 0; // grab input events
...
317                         lseek(fbfd, fblinelength * (fbheight - height * (6 + lowkey - grabInput)), SEEK_SET);
318                         write(fbfd, buf, buflen);
319                         keyb_refresh(fbfd, fbheight - height * (6 + lowkey - grabInput), 0, width, fbheight);
...
403                 if (z == (5 + lowkey - grabInput)) {
404                         *row = 0;               // Esc, Tab, F10, etc
405                         *pressed = x * 7 / 0x10000;
406                 /*      break; */
407                 } else if (z == (4 + lowkey - grabInput)) {
408                         *row = 1;               // q - p
409                         *pressed = x * 10 / 0x10000;
410                 /*      break; */
411                 } else if (z == (3 + lowkey - grabInput)) {
412                         *row = 1;               // a - l
413                         if (x > 0x10000 / 20 && x < 0x10000 * 19 / 20)
414                                 *pressed = 10 + (x * 10 - 0x10000 / 2) / 0x10000;
415                 /*      break; */
416                 } else if (z == (2 + lowkey - grabInput)) {
417                         if (x < 0x10000 * 3 / 20) {
418                                 *row = 3;
419                                 *pressed = 0;   // Left Shift
420                         } else if (x < 0x10000 * 17 / 20) {
421                                 *row = 1;       // z - m
422                                 *pressed = 19 + (x * 10 - 0x10000 * 3 / 2) / 0x10000;
423                         } else {
424                                 *row = 3;
425                                 *pressed = 1;   // Bcksp
426                         }
427                 /*      break; */
428                 } else if (z == (1 + lowkey - grabInput)) {
429                         *row = 4;
...
468 int k;
...
521                 if (pressed == 6) { 
522                         send_key(KEY_PAGEUP);
523                 } else if (pressed == 2) {
524                         for (k = 0; k < acceleration; k++)
525                                 send_key(KEY_UP);
526                 } else if (pressed == 3) {
527                         for (k = 0; k < acceleration; k++)
528                                 send_key(KEY_DOWN);
529                 } else if (pressed == 4) {
530                         for (k = 0; k < acceleration; k++)
531                                 send_key(KEY_LEFT);
532                 } else if (pressed == 5) {
533                         for (k = 0; k < acceleration; k++)
534                                 send_key(KEY_RIGHT);
535                 } else {
...
625         char c;
626         while ((c = getopt(argc, argv, "d:f:r:l:x:b:a:g:h")) != (char) -1) {
627                 switch (c) {
...
650                 case 'x':
651                         errno = 0;
652                         acceleration = strtol(optarg, &p, 10) % 10;
653                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
654                                 printf("Invalid numeric value for -x option\n");
655                                 exit(0);
656                         }
657                         if (acceleration < 1 || acceleration > 9)
658                                 acceleration = 4;
659                         break;
660                 case 'b':
661                         errno = 0;
662                         baseDelay = strtol(optarg, &p, 10) % 1000;
663                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
664                                 printf("Invalid numeric value for -b option\n");
665                                 exit(0);
666                         }
667                         if (baseDelay < 1 || baseDelay > 999)
668                                 baseDelay = 100;
669                         break;
670                 case 'a':
671                         errno = 0;
672                         additionalDelay = strtol(optarg, &p, 10) % 1000;
673                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
674                                 printf("Invalid numeric value for -a option\n");
675                                 exit(0);
676                         }
677                         if (additionalDelay < 1 || additionalDelay > 999)
678                                 additionalDelay = 250;
679                         break;
680                 case 'g':
681                         errno = 0;
682                         grabInput = strtol(optarg, &p, 10) % 2;
683                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
684                                 printf("Invalid numeric value for -g option\n");
685                                 exit(0);
686                         }
687                         break;
688                 case 'h':
689                         printf("usage: %s [options]\npossible options are:\n -h: print this help\n -d: set path to input device\n -f: set path to ttf font file\n -r: set rotation 0-3\n -l: set lowkey profile 0-2\n -x: set direction key acceleration factor 1-9 (default 4)\n -b: set base interval 1-999 (default 100) in uS between any key presses\n -a: set additional interval 1-999 (default 250) in mS between same key presses\n -g: set grab input events 0-1\n",
690                              argv[0]);
691                         exit(0);
692                         break;
...
787         if (grabInput == 1) {
788                 ioctl(fdinput, EVIOCGRAB, (void*)1);
789                 fprintf(stderr,"Grabbing input");
790         }
...
851                 if (pressed != -1 && (pressed != oldpressed &&  (long)diffstamp.tv_usec > baseDelay) || (long)diffstamp.tv_usec > additionalDelay * 1000)
852                         send_uinput_event(row, pressed);
853                 pressed = -1;
...
870         fb_free();
871         if (grabInput == 1) {
872                 ioctl(fdinput, EVIOCGRAB, (void*)0);
873                 fprintf(stderr,"Releasing input");
874         }
So running "fbkeyboard2 -g 1" grabs input, as was discussed in this thread: https://www.mobileread.com/forums/sh...d.php?t=358066 Now you have to exit "fbkeyboard2" by running "pkill fbkeyboard" since you don't have access to the NickelMenu at this point. *** * (MINI)UPDATE4 - EXIT BY "Ctrl-Alt-x" OK, now you can exit fbkeyboard2 by entering "Ctrl-Alt-x": $ nano -l fbkeyboard.c Code: 
	849                 if (released)
850                         identify_touched_key(x, y, &row, &pressed);
851                 if (pressed != -1 && (pressed != oldpressed &&  (long)diffstamp.tv_usec > baseDelay) || (long)diffstamp.tv_usec > additionalDelay * 1000) {
852                         if (layoutuse == 0 && ctrllock == 1 && altlock == 1 && row == 1 && pressed == 20) {
853                                 break;
854                         } else {
855                                 send_uinput_event(row, pressed);
856                         }
857                         pressed = -1;
858                         usleep(50000);
859                 }
*UPDATE5 - USE POLLING TO REDUCE %CPU USAGE, KEYBOARD CLEARANCE COMMANDLINE OPTION, SET GRAB INPUT EVENTS COMMANDLINE OPTION TO NEED ONLY SPECIFY "-g" rather than "-g 1": $ nano -l fbkeyboard.c Code: 
	...
 31 #include <poll.h>
...
 82 int clearance = -1; // keyboard base clearance
...
317                 case FB_ROTATE_CCW:
318                         lseek(fbfd, fblinelength * (fbheight - height * ((clearance >= 0)? clearance + 5 : (6 + lowkey - ((grabInput == 1)? ((lowkey == 2)? 2 : 1) : 0)))), SEEK_SET);
319                         write(fbfd, buf, buflen);
320                         keyb_refresh(fbfd, fbheight - height * ((clearance >= 0)? clearance + 5 : (6 + lowkey - ((grabInput == 1)? ((lowkey == 2)? 2 : 1) : 0))), 0, width, fbheight);
321                         break;
...
404                 if (z == (4 + ((clearance >= 0)? clearance : 1 + lowkey - ((grabInput == 1)? ((lowkey == 2)? 2 : 1) : 0)))) {
...
408                 } else if (z == (3 + ((clearance >= 0)? clearance : 1 + lowkey - ((grabInput == 1)? ((lowkey == 2)? 2 : 1) : 0)))) {
...
412                 } else if (z == (2 + ((clearance >= 0)? clearance : 1 + lowkey - ((grabInput == 1)? ((lowkey == 2)? 2 : 1) : 0)))) {
...
417                 } else if (z == (1 + ((clearance >= 0)? clearance : 1 + lowkey - ((grabInput == 1)? ((lowkey == 2)? 2 : 1) : 0)))) {
...
429                 } else if (z == (0 + ((clearance >= 0)? clearance : 1 + lowkey - ((grabInput == 1)? ((lowkey == 2)? 2 : 1) : 0)))) {
...
603         int fbfd, fdcons;
604         struct pollfd fdinput[1];
605         int timeout_ms = 100000;
...
629         while ((c = getopt(argc, argv, "d:f:r:l:x:b:a:c:gh")) != (char) -1) {
...
683                 case 'c':
684                         errno = 0;
685                         clearance = strtol(optarg, &p, 10) % 100;
686                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
687                                 printf("Invalid numeric value for -c option\n");
688                                 exit(0);
689                         }
690                         if (clearance < 0 || clearance > 99)
691                                 clearance = -1;
692                         break;
693                 case 'g':
694                         grabInput = 1;
695                         break;
696                 case 'h':
697                         printf("usage: %s [options]\npossible options are:\n -h: print this help\n -d: set path to input device\n -f: set path to ttf font file\n -r: set rotation 0-3\n -l: set lowkey profile 0-2\n -x: set direction key acceleration factor 1-9 (default 4)\n -b: set base interval 1-999 (default 100) in uS between any key presses\n -a: set additional interval 1-999 (default 250) in mS between same key presses\n -c: set base keyboard clearance 0-99 \n -g: set grab input events\n",
...
734                         buflen = linelength * (height * 5 + 1);
...
746         if (clearance > (landscape ? (2 + lowkey) * 5 - 5 : (3 + lowkey) * 5 - 5)) clearance = (landscape ? (2 + lowkey) * 5 - 5 : (3 + lowkey) * 5 - 5);
...
760         if (device) {
761                 if ((fdinput[0].fd = open(device, O_RDONLY)) == -1) {
762                         perror("failed to open input device node");
763                         exit(-1);
764                 }
765         } else {
766                 DIR *inputdevs = opendir("/dev/input");
767                 struct dirent *dptr;
768                 fdinput[0].fd = -1;
769                 while ((dptr = readdir(inputdevs))) {
770                         if ((fdinput[0].fd =
771                              openat(dirfd(inputdevs), dptr->d_name,
772                                     O_RDONLY | O_NONBLOCK)) != -1
773                             && ioctl(fdinput[0].fd, EVIOCGBIT(0, sizeof(key)),
774                                      &key) != -1 && key >> EV_ABS & 1)
775                                 break;
776                         if (fdinput[0].fd != -1) {
777                                 close(fdinput[0].fd);
778                                 fdinput[0].fd = -1;
779                         }
780                 }
781                 if (fdinput[0].fd == -1) {
782                         fprintf(stderr,
783                                 "no absolute axes device found in /dev/input\n");
784                         exit(-1);
785                 }
786         }
787         if ((ioctl(fdinput[0].fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_x) == -1) ||
788             (ioctl(fdinput[0].fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_y) == -1)) {
789                 perror("error: getting touchscreen size");
790                 exit(-1);
791         }
...
839         fdinput[0].events = POLLIN;
840         while (!done) {
...
855                 poll(fdinput, 1, timeout_ms);
856                 released = check_input_events(fdinput[0].fd, &x, &y);
...
865                         }
866                         pressed = -1;
867                 }
868         }
869         int i;
...
883         fb_free();
884         if (grabInput == 1) {
885                 ioctl(fdinput[0].fd, EVIOCGRAB, (void*)0);
886                 fprintf(stderr,"Releasing input");
...
Now %cpu usage drops when fbkeyboard2 not in use. (Credit goes to Szybet post for that one,lol) Also you can enter just "-g" (instead of "-g 1") as an option, e.g.: # fbkeyboard2 -r 3 -l 2 -g # fbkeyboard2 -h usage: fbkeyboard2 [options] possible options are: -h: print this help -d: set path to input device -f: set path to ttf font file -r: set rotation 0-3 -l: set lowkey profile 0-2 -x: set direction key acceleration factor 1-9 (default 4) -b: set base interval 1-999 (default 100) in uS between any key presses -a: set additional interval 1-999 (default 250) in mS between same key presses -c: set base keyboard clearance 0-99 -g: set grab input events For example, set keyboard at bottom: # fbkeyboard2 -c 0 -g Or set keyboard at top: # fbkeyboard2 -c 99 -g Set keyboard in middle: # fbkeyboard2 -c 5 -g (Not sure why anyone would want to do that, but who knows?) Now try in combination with updated version of fbpad2 (previous post): # . /korenv.sh # fbpad2 -p 63 -s 37 /bin/sh 0</dev/tty1 & # fbkeyboard2 -c 99 -g Keyboard is at the top, terminal output at the bottom! *** *UPDATE6 - ALLOW USER TO SET INPUT ORIENTATION FOR THEIR OWN DEVICE VIA "-x" AND "-y" COMMANDLINE OPTIONS. (CHANGE DIRECTION KEY ACCELERATION COMMANDLINE OPTION "-x" TO "-m" FOR DIRECTION KEY MULTIPLICATION.): $ nano -l fbkeyboard.c Code: 
	...
 82 int clearance = -1; // keyboard base clearance
 83 int xtouch = -1; // x input touch orientation
 84 int ytouch = -1; // y input touch orientation
 85
...
379         if (xtouch < 0) {
380                 switch (rotate) {
381                         case FB_ROTATE_UR:
382                                 *x = 0x10000 - absolute_y * 0x10000 / theight;
383                         break;
384                 case FB_ROTATE_UD:
385                         *x = 0x10000 - absolute_x * 0x10000 / twidth;
386                         break;
387                 case FB_ROTATE_CW:
388                         *x = absolute_y * 0x10000 / theight;
389                         break; 
390                 case FB_ROTATE_CCW:
391                                 *x = absolute_x * 0x10000 / twidth;
392                         break;
393                 } 
394         } else if (xtouch == 0) {
395                 *x = absolute_x * 0x10000 / twidth;
396         } else if (xtouch == 1) {
397                 *x = 0x10000 - absolute_x * 0x10000 / twidth;
398         } else if (xtouch == 2) {
399                 *x = absolute_y * 0x10000 / theight;
400         } else if (xtouch == 3) {
401                 *x = 0x10000 - absolute_y * 0x10000 / theight;
402         }
403         
404         if (ytouch < 0) {
405                 switch (rotate) {
406                         case FB_ROTATE_UR:
407                                 *y = absolute_x * 0x10000 / twidth;
408                         break;
409                 case FB_ROTATE_UD:
410                         *y = 0x10000 - absolute_y * 0x10000 / theight;
411                         break;
412                 case FB_ROTATE_CW:
413                         *y = 0x10000 - absolute_x * 0x10000 / twidth;
414                         break; 
415                 case FB_ROTATE_CCW:
416                         *y = absolute_y * 0x10000 / theight;
417                         break;
418                 } 
419         } else if (ytouch == 0) {
420                 *y = absolute_x * 0x10000 / twidth;
421         } else if (ytouch == 1) {
422                 *y = 0x10000 - absolute_x * 0x10000 / twidth;
423         } else if (ytouch == 2) {
424                 *y = absolute_y * 0x10000 / theight;
425         } else if (ytouch == 3) {
426                 *y = 0x10000 - absolute_y * 0x10000 / theight;
427         }
428
429         oldstamp.tv_sec = newstamp.tv_sec;
...
558                 if (pressed == 6) { 
559                         send_key(KEY_PAGEUP);
560                 } else if (pressed == 2) {
561                         for (k = 0; k < multidir; k++)
562                                 send_key(KEY_UP);
563                 } else if (pressed == 3) {
564                         for (k = 0; k < multidir; k++)
565                                 send_key(KEY_DOWN);
566                 } else if (pressed == 4) {
567                         for (k = 0; k < multidir; k++)
568                                 send_key(KEY_LEFT);
569                 } else if (pressed == 5) {
570                         for (k = 0; k < multidir; k++)
571                                 send_key(KEY_RIGHT);
572                 } else {
573                         send_key(keys[row][pressed]);
...
665         while ((c = getopt(argc, argv, "d:f:r:l:m:b:a:c:x:y:gh")) != (char) -1) {
...
729                 case 'x':
730                         errno = 0;
731                         xtouch = strtol(optarg, &p, 10) % 4;
732                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
733                                 printf("Invalid numeric value for -x option\n");
734                                 exit(0);
735                         }
736                         break;
737                 case 'y':
738                         errno = 0;
739                         ytouch = strtol(optarg, &p, 10) % 4;
740                         if (errno != 0 || p == optarg || p == NULL || *p != '\0') {
741                                 printf("Invalid numeric value for -y option\n");
742                                 exit(0);
743                         }
744                         break;
745                 case 'g':
746                         grabInput = 1;
747                         break;
748                 case 'h':
749                         printf("usage: %s [options]\npossible options are:\n -h: print this help\n -d: set path to input device\n -f: set path to ttf font file\n -r: set rotation 0-3\n -l: set lowkey profile 0-2\n -m: set direction key multiplication factor 1-9 (default 4)\n -b: set base interval 1-999 (default 100) in uS between any key presses\n -a: set additional interval 1-999 (default 250) in mS between same key presses\n -c: set base keyboard clearance 0-99 \n -x: set x touch orientation 0-3\n -y: set y touch orientation 0-3\n -g: set grab input events\n",
750                              argv[0]);
751                         exit(0);
752                         break;
...
# fbkeyboard2 -h usage: fbkeyboard2 [options] possible options are: -h: print this help -d: set path to input device -f: set path to ttf font file -r: set rotation 0-3 -l: set lowkey profile 0-2 -m: set direction key multiplication factor 1-9 (default 4) -b: set base interval 1-999 (default 100) in uS between any key presses -a: set additional interval 1-999 (default 250) in mS between same key presses -c: set base keyboard clearance 0-99 -x: set x touch orientation 0-3 -y: set y touch orientation 0-3 -g: set grab input events -x and -y commandline options allow user to set input touch orientation for their own device if it differs from that of the Clara HD. (The former -x direction key acceleration factor has been moved to -m direction key multiplication factor.) x/y touch orientation 0: absolute_x * 0x10000 / twidth 1: 0x10000 - absolute_x * 0x10000 / twidth 2: absolute_y * 0x10000 / theight 3: 0x10000 - absolute_y * 0x10000 / theight; default: -x 3 -y 0 # fbkeyboard2 -g -x 3 -y 0 (touch orientation is normal for the Clara HD) # fbkeyboard2 -g -x 2 -y 0 (x-axis touch is reversed for the Clara HD) # fbkeyboard2 -g -x 3 -y 0 (touch orientation is normal for the Clara HD) # fbkeyboard2 -g -x 3 -y 1 (y-axis touch is reversed for the Clara HD) # fbkeyboard2 -g -m 2 (direction key multiplication factor set to 2) *** MAKE SHARED VERSION OF FBKEYBOARD2: $ cd .. $ cd FBInk-v1.25.0/ $ make shared $ cd .. $ cd fbkeyboard-master/ $ cp -r ../FBInk-v1.25.0/Release FBInk/ $ arm-kobo-linux-gnueabihf-gcc -o fbkeyboard2-shared -I../freetype-2.13.1/include/ -LFBInk/Release/ fbkeyboard.c draw.c libfreetype.a -lfbink *** Don't forget that: -fbpad with USB keyboard needs agetty started and stopped in order to not stall. -fbkeyboard needs WiFi on (or USB networking connected), though no hotspot connection needed, in order to not eventually freeze. *** $ zip -r fbkeyboard2.zip fbkeyboard2/ *** Last edited by elinkser; 01-26-2024 at 07:42 PM. Reason: copy, lowkey,screen+exit+poll,clearance+touch,shared update fbpad2  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#13 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				DBSERVER AND VALGRIND (USE AT OWN RISK - SEE WARNING)
			 
			
			
			*** 
		
	
		
		
			GDBSERVER (This is mainly for minimalists - you can get full gdb from NiLuJe kobostuff developer suite.) The GNU Debugger - gdbserver The gdb app has only the following dependencies: Depends (9) gmp libexpat libgcc libstdc++** musl* ncurses-libs python3 readline zlib *already got it from elinks/nano install in Post #3 **gdbserver has this additional dependency RUN THESE COMMANDS FROM LINUX DESKTOP: DOWNLOAD THE REQUIRED PACKAGES: $ cd myalpine/ $ wget https://dl-cdn.alpinelinux.org/alpin...db-12.1-r2.apk $ wget https://dl-cdn.alpinelinux.org/alpin...0220924-r4.apk $ tar zxvf gdb-12.1-r2.apk $ mv usr/bin/gdbserver scripts/ $ tar zxvf libstdc++-12.2.1_git20220924-r4.apk $ mv usr/lib/libstdc++.so.6.0.30 libs/libstdc++.so.6 On your PC recompile fbpad2 with -g option: $ cd fbpad-eink-master/ $ source ~/koxtoolchain/refs/x-compile.sh kobo env bare $ nano -l Makefile Code: 
	1 CFLAGS += -Wall -O2 -g $ file fbpad2 fbpad2: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.33, with debug_info, not stripped NOW CONNECT YOUR KOBO TO YOUR PC: Copy your gdbserver binary from the scripts/ folder on the PC to the /mnt/onboard/.adds/koreader/scripts/ folder on the kobo. Copy fbpad2 to /mnt/onboard/.adds/koreader/scripts/ folder on your Kobo. *** ***Backup the existing libstdc++.so.6 in the /mnt/onboard/.adds/koreader/libs/ folder on the kobo.*** Copy libstdc++.so.6 from the libs/ folder on the PC to the /mnt/onboard/.adds/koreader/libs/ folder on the kobo. Make sure KOReader can still run. If not, restore the original libstdc++.so.6 to the /mnt/onboard/.adds/koreader/libs/ folder. *** $ sudo apt install gdb-multiarch $ sudo ufw allow proto tcp from 192.168.2.1 to 192.168.2.2 port 2345 From SSH shell run (after first running ". /korenv.sh" as was done in Post #4): # gdbserver host:2345 fbpad2 -p 58 0</dev/tty1 & # Process fbpad2 created; pid = 1532 Listening on port 2345 From host desktop run: $ gdb-multiarch fbpad2 GNU gdb (Debian 8.2.1-2+b3) 8.2.1 ... Reading symbols from fbpad2...done. (gdb) Connect to gdbserver: (gdb) target remote 192.168.2.2:2345 Remote debugging using 192.168.2.2:2345 ... Reading symbols from target:/lib/ld-linux-armhf.so.3...(no debugging symbols found)...done. 0x76fcfb00 in ?? () from target:/lib/ld-linux-armhf.so.3 (gdbserver response: Remote debugging from host 192.168.2.1, port 51944) (gdb) b main Breakpoint 1 at 0x10de1 (gdb) continue Continuing. Reading /lib/libarmmem-v7l.so from remote target... Reading /lib/libutil.so.1 from remote target... Reading /lib/libc.so.6 from remote target... Breakpoint 1, 0x00010dec in main () From a second SSH shell to Kobo run: # fbkeyboard2 Enter ALT-c and you get the shell prompt on the Kobo display. (may have to issue "continue" command again from gdb.) Enter ALT-p <Ret> to see tag list. CTRL-ALT-q to end the fbpad session. CTRL-ALT-x to end the fbkeyboard session. *** Do NOT attempt the following on your Kobo. Having valgrind is NOT worth the risk of having to factory wipe your device. I had a replaceable sdcard-based system with multiple backups, previous proof that the substitute build environment was compatible, and an SFTP-capable filemanager running on my desktop with an already loaded SSH server in Kobo memory. Spoiler: 
 *** Last edited by elinkser; 02-08-2024 at 04:31 AM. Reason: warning  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#14 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				Karma: 146236 
				Join Date: Oct 2022 
				
				
				
				Device: Kobo Clara HD 
				
				
				 | 
	
	
	
		
		
			
			 
				
				MIGRATE TO NEW /mnt/onboard/.adds/kordir/ FOLDER
			 
			
			
			*** 
		
	
		
		
		
		
		
		
		
		
		
		
		
			MIGRATE TO NEW /mnt/onboard/.adds/kordir/ FOLDER Originally, the /mnt/onboard/.adds/koreader/scripts/ folder was a handy place to install elinks so we could run it from KOReader terminal. But it has gotten cluttered, and we have added many apps like fbpad that are not even run from KOReader terminal, not to mention some libfile clashes that have come up. So we will move everything to the /mnt/onboard/.adds/kordir/ folder and point the /korenv.sh script there. Note that you would now have to run ". /korenv.sh" from KOReader terminal to set the PATH and LD_LIBRARY_PATH, same as in fbpad, since it is no longer the default KOReader path. # cd /mnt/onboard/.adds/ # mkdir kordir # mkdir kordir/scripts # mkdir kordir/libs POST #3 FILES: # cd /mnt/onboard/.adds/koreader/scripts/ # mv elinks nano wgets w3m moon-buggy ttyper chalpine.sh chalpined.sh fbink /mnt/onboard/.adds/kordir/scripts/ # cd /mnt/onboard/.adds/koreader/libs/ # mv ld-musl-armhf.so.1 libbz2.so.1 libc.musl-armv7.so.1 libcrypto.so.3 libexpat.so.1 libssl.so.3 libformw.so.6 libmenuw.so.6 libncursesw.so.6 libpanelw.so.6 libidn2.so.0 libunistring.so.5 libpcre2-8.so.0 libpcre2-posix.so.3 libcord.so.1 libgc.so.1 libstdc++.so.6 libfbink.so.1 /mnt/onboard/.adds/kordir/libs/ # mv w3m/ /mnt/onboard/.adds/kordir/usr/lib/ Copy your cert.pm and certs/ca-certificates.crt to the /etc/ssl/ directory. Copy your etc/terminfo directory to the /etc/ directory. EDIT /korenv.sh TO POINT TO NEW FOLDER: # vi /korenv.sh Code: 
	#!/bin/sh export PATH=/mnt/onboard/.adds/kordir/scripts:/mnt/onboard/.adds/koreader/plugins/terminal.koplugin/:/mnt/onboard/.adds/koreader/scripts:$PATH export LD_LIBRARY_PATH=/mnt/onboard/.adds/kordir/libs:/mnt/onboard/.adds/koreader/libs:$LD_LIBRARY_PATH export TERM=screen export FBPDF_PERCENT=58 export HOME=/mnt/onboard/.adds/kordir/ cd $HOME alias ls='ls --color=never' Run (". /korenv.sh" and) elinks once, then update the new .elinks/ folder: # vi /mnt/onboard/.adds/kordir/.elinks/bookmarks Code: 
	Kobo Reader - MobileRead Forums https://www.mobileread.com/forums/forumdisplay.php?f=223 0 Code: 
	
    ## protocol.http.user_agent <str>
    set protocol.http.user_agent = "Mozilla/5.0(Android 11; Mobile; rv:89.0) Gecko/89.0 Firefox/89.0"
set mime.extension.jpg="image/jpeg"
set mime.extension.jpeg="image/jpeg"
set mime.extension.png="image/png"
set mime.extension.gif="image/gif"
set mime.extension.bmp="image/bmp"
set mime.extension.pnm="image/pnm"
set mime.handler.image_viewer.unix.ask = 1
set mime.handler.image_viewer.unix-xwin.ask = 0
set mime.handler.image_viewer.unix.block = 1
set mime.handler.image_viewer.unix-xwin.block = 0
set mime.handler.image_viewer.unix.program = "/mnt/onboard/.adds/kordir/scripts/fbink -G -y 30 -g file=% ;sleep 2"
set mime.handler.image_viewer.unix-xwin.program = "/mnt/onboard/.adds/kordir/scripts/fbink -G -y 30 -g file=% ;sleep 2"
set mime.type.image.jpg = "image_viewer"
set mime.type.image.jpeg = "image_viewer"
set mime.type.image.png = "image_viewer"
set mime.type.image.gif = "image_viewer"
set mime.type.image.bmp = "image_viewer"
set mime.type.image.pnm = "image_viewer"
      ## document.uri_passing.wgets.command <str>
      set document.uri_passing.wgets.command = "wgets  -nd -E -k -p -Q20M %c"
      ## document.uri_passing.wgets.foreground [0|1]
      set document.uri_passing.wgets.foreground = 0
bind "main" "Ctrl-W" = "tab-external-command"
bind "main" "Ctrl-F" = "frame-next"
bind "main" "Ctrl-B" = "frame-prev"
bind "main" "u" = "link-info"
bind "main" "Alt-l" = "lua-console"
bind "main" "Down" = "move-cursor-down"
bind "main" "Left" = "move-cursor-left"
bind "main" "Right" = "move-cursor-right"
bind "main" "Up" = "move-cursor-up"
bind "main" "Tab" = "move-link-next"
bind "main" "Shift-Tab" = "move-link-prev"
bind "main" "Ctrl-Right" = "none"
#
bind "main" "w" = "toggle-wrap-text"
bind "main" "t" = "open-link-in-new-tab"
bind "main" "e" = "menu"
bind "main" "S" = "save-as"
bind "main" "Ctrl-o" = "open-os-shell" 
bind "main" "y" = "copy-clipboard"
bind "main" "H" = "history-manager"
bind "main" "h" = "history-move-back"
bind "main" "l" = "history-move-forward"
bind "main" "j" = "move-cursor-down"
bind "main" "k" = "move-cursor-up"
  
bind "main" "Ctrl-a" = "none"
bind "main" "Ctrl-A" = "none"
set document.colors.use_document_colors = 0
POST #7,9,10,11,12 FILES: (Note : fbkeyboard and fbpad variants have been upgraded to fbkeyboard2 and fbpad2 and are no longer needed.) # cd /mnt/onboard/.adds/koreader/scripts/ # mv fbmenu.sh oskansi fbpad2 fbkeyboard2 fbpad2-shared fbkeyboard2-shared screen /mnt/onboard/.adds/kordir/scripts/ # cd /mnt/onboard/.adds/koreader/libs/ # mv libutempter.so.0 libskarnet.so.2.12 libutmps.so.0.1 /mnt/onboard/.adds/kordir/libs/ These should stay the same: *** Copy the usr/share/screen/ folder on the PC to the /usr/share/ folder on the kobo. Copy the etc/screenrc file on the PC to the /etc/ folder on the kobo. Copy the etc/skel/ folder on the PC to the /etc/ folder on the kobo. Copy your agetty binary (needed for running fbpad2 from USB keyboard as in Posts #5,7,9) from the scripts/ folder on the PC to the sbin/ folder on the kobo. # cp /mnt/onboard/.adds/kordir/libs/ld-musl-armhf.so.1 /lib/ # vi /etc/udev/rules.d/90-fbpad.rules Code: 
	# : 90-fbpad.rules 2015-01-10 23:58:00Z NiLuJe $ # Runs early at boot... (onboard *might* be mounted at that point) KERNEL=="loop0", RUN+="/sbin/agetty -s 38400 tty1 vt100" Move fonts required by oskansi,fbkeyboard2, fbpad2. # cd /mnt/onboard/.adds/koreader/ # mv RobotoMono-Medium.tf RobotoMono-MediumS.tf courr.tf gen.sh mkfn_ft DejaVuSansMono.ttf DejaVuSansMono.tf DejaVuSansMonoS.tf /mnt/onboard/.adds/kordir/ # cd /mnt/onboard/.adds/oskansi/ # mv keymap1-en_us.json keymap2-en_us.json osk-keymap-LC.json osk-keymap-UC.json Roboto-Medium.ttf RobotoMono-Regular.ttf RobotoMono-Bold.ttf RobotoMono-Italic.ttf /mnt/onboard/.adds/kordir/ Update fbmenu.sh (from Post #7) to point NickelMenu submenu to new fbpad2,fbkeyboard2 binaries: # vi /mnt/onboard/.adds/kordir/scripts/fbmenu.sh Code: 
	#!/bin/sh                                        
# fbmenu - fbpad and fbkeyboard selection menu
num=0                              
qndb -m dlgConfirmCreate true                                       
qndb -m dlgConfirmSetTitle "1-Stop agetty; 2-fbpadkb;      3-fbpadkbS;   4-fbpad;          5-fbpadS;        6-oskansi;       7-oskansiS;     8-elinks;   Select option (1-8):"
qndb -m dlgConfirmSetLEPlaceholder "1"
qndb -m dlgConfirmShow                           
result=$(qndb -s dlgConfirmTextInput)            
textIn=$(echo $result | sed 's/dlgConfirmTextInput //')
num=$(echo $textIn | sed 's/[^0-9]//g')
num=${num:-1}
if [ "$num" != "$textIn" ]
then
num=1
fi                                                                                                 
if [ "$num" == "1" ]; then
		qndb -m mwcToast 500 "You selected 1-Stop agetty+fbpad"
		fbcmd="/usr/bin/pkill agetty"
		qndb -m mwcToast 200 "$fbcmd"
		fberr=$($fbcmd 2>&1)
		fbcmd="/usr/bin/pkill fbpad"
		qndb -m mwcToast 200 "$fbcmd"
		fberr=$($fbcmd 2>&1)
		fbcmd="/usr/bin/pkill fbkeyboard"
		qndb -m mwcToast 200 "$fbcmd"
		fberr=$($fbcmd 2>&1)
		fbcmd="/usr/bin/pkill oskansi"
		qndb -m mwcToast 200 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "2" ]; then
		qndb -m mwcToast 1000 "You selected 2-fbpadkb"
		export HOME="/mnt/onboard/.adds/kordir/"
		cd "$HOME"
		fbcmd="/mnt/onboard/.adds/kordir/scripts/fbkeyboard2"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1) &
		fbcmd="eval /mnt/onboard/.adds/kordir/scripts/fbpad2 -p 59 /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "3" ]; then	
		qndb -m mwcToast 1000 "You selected 3-fbpadkbS"
		export HOME="/mnt/onboard/.adds/kordir/"
		cd "$HOME"
		fbcmd="/mnt/onboard/.adds/kordir/scripts/fbkeyboard2"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1) &
		fbcmd="eval /mnt/onboard/.adds/kordir/scripts/fbpad2 -f RobotoMono-MediumS.tf -p 59 /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "4" ]; then
		qndb -m mwcToast 1000 "You selected 4-fbpad"
		fbcmd="eval /mnt/onboard/.adds/kordir/scripts/fbpad2 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "5" ]; then
		qndb -m mwcToast 1000 "You selected 5-fbpadS"
		fbcmd="eval /mnt/onboard/.adds/kordir/scripts/fbpad2 -f /mnt/onboard/.adds/kordir/RobotoMono-MediumS.tf 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "6" ]; then
		qndb -m mwcToast 1000 "You selected 6-oskansi"
		export HOME="/mnt/onboard/.adds/kordir/"
		cd "$HOME"
		fbcmd="eval /mnt/onboard/.adds/kordir/scripts/fbpad2 -p 59  /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1) &
		fbcmd="/mnt/onboard/.adds/kordir/scripts/oskansi"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "7" ]; then
		qndb -m mwcToast 1000 "You selected 7-oskansiS"
		export HOME="/mnt/onboard/.adds/kordir/"
		cd "$HOME"
		fbcmd="eval /mnt/onboard/.adds/kordir/scripts/fbpad2 -f /mnt/onboard/.adds/kordir/RobotoMono-MediumS.tf -p 59 /bin/sh 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1) &
		fbcmd="/mnt/onboard/.adds/kordir/scripts/oskansi"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
elif [ "$num" == "8" ]; then
		qndb -m mwcToast 1000 "You selected 8-elinks"
		export PATH="$PATH:/mnt/onboard/.adds/kordir/scripts"
		export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/mnt/onboard/.adds/kordir/libs"
		export TERM="xterm"
		export HOME="/mnt/onboard/.adds/kordir/"
		cd "$HOME"
		fbcmd="eval fbpad2 -p 59 elinks . 0</dev/tty1"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1) &
		cd "/mnt/onboard/.adds/kordir/"
		fbcmd="/mnt/onboard/.adds/kordir/scripts/oskansi"
		qndb -m mwcToast 1000 "$fbcmd"
		fberr=$($fbcmd 2>&1)
else
		qndb -m mwcToast 1000 "You selected an invalid option" 
fi
qndb -m mwcToast 1000 "${fberr:-"Bye!"}"
Add a few more NickelMenu items, if desired: # vi /mnt/onboard/.adds/nm/config.txt Code: 
	
menu_item :main :fbmenu :cmd_spawn :quiet:exec /mnt/onboard/.adds/kordir/scripts/fbmenu.sh
    chain_success                      :dbg_toast          :Started fbmenu       
    chain_failure                      :dbg_toast          :Error                                   
menu_item :main    :fbpad2 -p 59       :cmd_spawn          :quiet :/mnt/onboard/.adds/kordir/scripts/fbpad2 -p 59  /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpad2
    chain_failure                      :dbg_toast          :Error starting fbpad2
#menu_item :main    :fbpad2 -p 42       :cmd_spawn          :quiet :export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && /mnt/onboard/.adds/kordir/scripts/fbpad2 -p 42  /bin/sh 0</dev/tty1
#    chain_success                      :dbg_toast          :Started fbpad2
#    chain_failure                      :dbg_toast          :Error starting fbpad2
menu_item :main    :fbpad2 -p 63 -s 37 :cmd_spawn          :quiet :export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && /mnt/onboard/.adds/kordir/scripts/fbpad2 -p 63 -s 37  0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpad2
    chain_failure                      :dbg_toast          :Error starting fbpad2
menu_item :main    :fbpad2 -p 42  -f RobotoMono-MediumS.tf      :cmd_spawn          :quiet :export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && /mnt/onboard/.adds/kordir/scripts/fbpad2 -p 42  -f RobotoMono-MediumS.tf /bin/sh 0</dev/tty1
    chain_success                      :dbg_toast          :Started fbpad2
    chain_failure                      :dbg_toast          :Error starting fbpad2
#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
menu_item :main    :fbkeyboard2 -g        :cmd_spawn          :quiet :export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && /mnt/onboard/.adds/kordir/scripts/fbkeyboard2 -g
    chain_success                      :dbg_toast          :Started fbkeyboard2
    chain_failure                      :dbg_toast          :Error starting fbkeyboard2
menu_item :main    :fbkeyboard2 -c 99 -g        :cmd_spawn          :quiet :export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && /mnt/onboard/.adds/kordir/scripts/fbkeyboard2 -c 99 -g 
    chain_success                      :dbg_toast          :Started fbkeyboard2
    chain_failure                      :dbg_toast          :Error starting fbkeyboard2
menu_item :main    :fbkeyboard2 -r 3 -l 1 -g       :cmd_spawn          :quiet :export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && /mnt/onboard/.adds/kordir/scripts/fbkeyboard2 -r 3 -l 1 -g
    chain_success                      :dbg_toast          :Started fbkeyboard2
    chain_failure                      :dbg_toast          :Error starting fbkeyboard2
 
menu_item :main :oskansi :cmd_spawn :quiet:export HOME="/mnt/onboard/.adds/kordir/" && cd "$HOME" && /mnt/onboard/.adds/kordir/scripts/oskansi
    chain_success                      :dbg_toast          :Started oskansi       
    chain_failure                      :dbg_toast          :Error                                   
menu_item :main :Stop oskansi :cmd_spawn :quiet:/usr/bin/pkill oskansi 
    chain_success                      :dbg_toast          :Stopped oskansi                       
    chain_failure                      :dbg_toast          :Error
POST #8 FILES: # cd /mnt/onboard/.adds/koreader/scripts/ # mv gnuchess pnmscale pnmtopng jtop.sh jtopr.sh pngtopnm pamtogif ppmtogif giftopnm gifsicle /mnt/onboard/.adds/kordir/scripts/ # cd /mnt/onboard/.adds/koreader/libs/ # mv libintl.so.8 libnetpbm.so.11 libpng16.so.16.39.0 /mnt/onboard/.adds/kordir/libs/ Restore the original libpng16.so.16 to the /mnt/onboard/.adds/koreader/libs/ folder. Redirect rmkit j2p.sh SAS script to new folder: https://www.mobileread.com/forums/sh...59&postcount=9 # nano -l /mnt/onboard/.adds/rmkit/bin/apps/j2p.sh Code: 
	...
40   if (expr "${output}" : ".*Portrait" > /dev/null); then
41     echo "CLICKED Portrait"
42     option="Output to Portrait"
43     cd /mnt/onboard/.adds/rmkit/data/harmony/ && export PATH=$PATH:/mnt/onboard/.adds/kordir/scripts && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/onboard/.adds/kordir/libs && jpegtran -grayscale ${jpgSelected} |  djpeg -pnm | pnmscale -width 1088 -height 1488 | pnmtopng -alpha a50.pgm > ${pngFilename}
44   fi
45   if (expr "${output}" : ".*Landscape" > /dev/null); then
46     echo "CLICKED Landscape"
47     option="Output to Landscape"
48     cd /mnt/onboard/.adds/rmkit/data/harmony/ && export PATH=$PATH:/mnt/onboard/.adds/kordir/scripts && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/onboard/.adds/kordir/libs && jpegtran -rotate 90 -grayscale ${jpgSelected} | djpeg -pnm | pnmscale -width 1088 -height 1488 | pnmtopng -alpha a50.pgm > ${pngFilename}
49   fi
50   sleep 0.1
51 done
...
POST #13 FILES: # cd /mnt/onboard/.adds/koreader/scripts/ # mv gdbserver /mnt/onboard/.adds/kordir/scripts/ # cd /mnt/onboard/.adds/koreader/libs/ # mv libstdc++.so.6.0.30 /mnt/onboard/.adds/kordir/libs/libstdc++.so.6 Restore the original libstdc++.so.6 to the /mnt/onboard/.adds/koreader/libs/ folder. *** Note : the fbink binary and libfbink.so.1 lib may not have already been installed in your KOReader folder, but they are necessary for such things as viewing images in elinks or viewing animated gifs. You can download it from here: FBInk: A small tool/library to print crap on your screen! https://www.mobileread.com/forums/sh...d.php?t=299110 Attached Files : FBInk-v1.25.0.zip On desktop: $ cd myalpine/ $ mkdir FBInk-v1.25.0 $ mv FBInk-v1.25.0.zip FBInk-v1.25.0/ $ cd FBInk-v1.25.0/ $ unzip FBInk-v1.25.0.zip $ tar zxvf KoboRoot.tgz $ cd .. $ mv FBInk-v1.25.0/usr/local/fbink/bin/fbink scripts/ $ mv FBInk-v1.25.0/usr/local/fbink/lib/libfbink.so.1.0.0 libs/libfbink.so.1 Copy your fbink binary from the scripts/ folder on the PC to the /mnt/onboard/.adds/kordir/scripts/ folder on the kobo. Copy new lib from the libs/ folder on the PC to the /mnt/onboard/.adds/kordir/libs/ folder on the kobo: libfbink.so.1 *** *** UPDATE ELINKS.CONF KEY BINDINGS *** Update /mnt/onboard/.adds/kordir/.elinks/elinks.conf to harmonize elinks with new apps fbpdf and sfm: REMOVE: bind "main" "," = "history-move-back" bind "main" "." = "history-move-forward" bind "main" "#" = "toggle-numbered-links" ADD: bind "main" "H" = "history-manager" bind "main" "h" = "history-move-back" bind "main" "l" = "history-move-forward" bind "main" "j" = "move-cursor-down" bind "main" "k" = "move-cursor-up" RESULT: Use H instead of h for history Use h/l instead of ,/. for move forward/back in history Use j/k for for move cursor down/up Use the default . to toggle displaying numbered links on page, so you can go directly to the link by entering the number. *************************************** *** ALSO UPDATE /KORENV.SH *** Update /korenv.sh to better work with new apps fbpdf and sfm: REMOVE: export TERM=xterm ADD: export TERM=screen export FBPDF_PERCENT=58 *************************************** * Edit : add a couple more bindings to elinks.conf to not interfere with screen utility. Code: 
	... bind "main" "Ctrl-a" = "none" bind "main" "Ctrl-A" = "none" set document.colors.use_document_colors = 0 ... Last edited by elinkser; 04-05-2024 at 06:42 PM. Reason: restore original libpng16.so.16,harmonized keydefs,TERM,screen  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#15 | 
| 
			
			
			
			 Addict 
			
			![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 242 
				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. *** Last edited by elinkser; 03-17-2024 at 05:33 PM.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
![]()  | 
            
        
            
            
  | 
    
			 
			Similar Threads
		 | 
	||||
| Thread | Thread Starter | Forum | Replies | Last Post | 
| PW4 Terminal or SSH through experimental browser | SirMassive | Kindle Developer's Corner | 7 | 03-30-2021 09:51 PM | 
| Web Browser and BookWalker web viewer | chronoreverse | Amazon Kindle | 0 | 02-06-2019 02:44 PM | 
| Cannot access Calibre-Web via Kobo web browser | chakattack | Server | 14 | 08-19-2018 08:51 PM | 
| Kindle Fire Web Browser will likely allow for web based games. | sirmaru | Amazon Fire | 10 | 11-15-2011 03:55 PM | 
| merged terminal/launchpad/web server | lrizzo | Kindle Developer's Corner | 46 | 10-21-2011 06:51 PM |