refactoring, start developing OSK
This commit is contained in:
parent
1023aa1bc2
commit
6229d5092a
62
main.go
62
main.go
|
@ -5,15 +5,13 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
// "fmt"
|
||||||
"git.sr.ht/~adnano/go-gemini"
|
"git.sr.ht/~adnano/go-gemini"
|
||||||
"git.sr.ht/~adnano/go-gemini/tofu"
|
"git.sr.ht/~adnano/go-gemini/tofu"
|
||||||
"github.com/fogleman/gg"
|
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
"github.com/shermp/go-fbink-v2/gofbink"
|
"github.com/shermp/go-fbink-v2/gofbink"
|
||||||
"github.com/shermp/go-kobo-input/koboin"
|
"github.com/shermp/go-kobo-input/koboin"
|
||||||
"golang.org/x/image/font"
|
"golang.org/x/image/font"
|
||||||
"image"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -28,37 +26,17 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Visual options
|
// Visual options
|
||||||
const (
|
const (
|
||||||
width int = 1080
|
width int = 1080
|
||||||
height int = 1440 // TODO get from device instead of hardcoding
|
height int = 1440 // TODO get from device instead of hardcoding
|
||||||
linewidth float64 = 10
|
linewidth float64 = 5
|
||||||
|
oskpadding float64 = 20
|
||||||
|
keyspacing float64 = 5 // spacing between keys
|
||||||
)
|
)
|
||||||
|
|
||||||
var f *truetype.Font
|
var f *truetype.Font
|
||||||
var face font.Face
|
var face font.Face
|
||||||
|
|
||||||
// drawErrorBox prints the given error on screen, and only proceeds after touch input.
|
|
||||||
func drawErrorBox(e error, fb *gofbink.FBInk, t *koboin.TouchDevice, opts *gofbink.FBInkConfig) {
|
|
||||||
boxheight := height / 4
|
|
||||||
boxwidth := width / 2
|
|
||||||
i := image.NewRGBA(image.Rect(0, 0, boxwidth, boxheight))
|
|
||||||
dc := gg.NewContextForRGBA(i)
|
|
||||||
if face != nil {
|
|
||||||
dc.SetFontFace(face)
|
|
||||||
}
|
|
||||||
dc.SetLineWidth(linewidth)
|
|
||||||
dc.DrawRectangle(0, 0, float64(boxwidth), float64(boxheight))
|
|
||||||
dc.SetRGB(1, 1, 1)
|
|
||||||
dc.FillPreserve()
|
|
||||||
dc.SetRGB(0, 0, 0)
|
|
||||||
dc.Stroke()
|
|
||||||
dc.SetRGB(0, 0, 0)
|
|
||||||
dc.DrawStringWrapped("Error:\n"+e.Error(), float64(boxwidth/2), float64(boxheight/2), 0.5, 0.5, float64(boxwidth), 1.0, gg.AlignCenter)
|
|
||||||
dc.Fill()
|
|
||||||
fb.PrintRBGA(int16(width/2-(boxwidth/2)), int16(height/2-(boxheight/2)), i, opts)
|
|
||||||
t.GetInput()
|
|
||||||
}
|
|
||||||
|
|
||||||
func trustCertificate(hostname string, cert *x509.Certificate) error {
|
func trustCertificate(hostname string, cert *x509.Certificate) error {
|
||||||
host := tofu.NewHost(hostname, cert.Raw, cert.NotAfter)
|
host := tofu.NewHost(hostname, cert.Raw, cert.NotAfter)
|
||||||
knownHost, ok := hosts.Lookup(hostname)
|
knownHost, ok := hosts.Lookup(hostname)
|
||||||
|
@ -136,11 +114,13 @@ func main() {
|
||||||
// Logging setup
|
// Logging setup
|
||||||
var logFile, err = os.Create("/mnt/onboard/gemini.log")
|
var logFile, err = os.Create("/mnt/onboard/gemini.log")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
drawErrorBox(err, fb, t, &fbinkOpts)
|
drawErrorBox(err, fb, t, &fbinkOpts, &face)
|
||||||
}
|
}
|
||||||
var logger *log.Logger = log.New(logFile, "gemini", log.LstdFlags)
|
var logger *log.Logger = log.New(logFile, "gemini", log.LstdFlags)
|
||||||
defer logFile.Close()
|
defer logFile.Close()
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
path := "/mnt/onboard/.adds/gemini/known-hosts" // TODO don't hardcode
|
path := "/mnt/onboard/.adds/gemini/known-hosts" // TODO don't hardcode
|
||||||
|
|
||||||
// Reload or create known hosts file
|
// Reload or create known hosts file
|
||||||
|
@ -149,7 +129,7 @@ func main() {
|
||||||
}
|
}
|
||||||
err = hosts.Load(path)
|
err = hosts.Load(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
drawErrorBox(err, fb, t, &fbinkOpts)
|
drawErrorBox(err, fb, t, &fbinkOpts, &face)
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +137,7 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fb.Println(err)
|
fb.Println(err)
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Load Fonts, Create font face
|
// Load Fonts, Create font face
|
||||||
b, err := ioutil.ReadFile("/mnt/onboard/.adds/gemini/NotoSerif.ttf")
|
b, err := ioutil.ReadFile("/mnt/onboard/.adds/gemini/NotoSerif.ttf")
|
||||||
|
@ -172,15 +152,22 @@ func main() {
|
||||||
}
|
}
|
||||||
face = truetype.NewFace(f, &truetype.Options{Size: 32})
|
face = truetype.NewFace(f, &truetype.Options{Size: 32})
|
||||||
|
|
||||||
|
err = drawOSK(fb, &fbinkOpts, &face)
|
||||||
|
if err != nil {
|
||||||
|
fb.Println("Error: ")
|
||||||
|
logger.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
url := "gemini://gemini.circumlunar.space"
|
url := "gemini://gemini.circumlunar.space"
|
||||||
req, err := gemini.NewRequest(url)
|
req, err := gemini.NewRequest(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
drawErrorBox(err, fb, t, &fbinkOpts)
|
drawErrorBox(err, fb, t, &fbinkOpts, &face)
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
resp, err := do(req, nil)
|
resp, err := do(req, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
drawErrorBox(err, fb, t, &fbinkOpts)
|
drawErrorBox(err, fb, t, &fbinkOpts, &face)
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
@ -189,13 +176,14 @@ func main() {
|
||||||
if resp.Status.Class() == gemini.StatusClassSuccess {
|
if resp.Status.Class() == gemini.StatusClassSuccess {
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
drawErrorBox(err, fb, t, &fbinkOpts)
|
drawErrorBox(err, fb, t, &fbinkOpts, &face)
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
fb.Println(string(body))
|
fb.Println(string(body))
|
||||||
} else {
|
} else {
|
||||||
fb.Println(fmt.Sprintf("%d %s\n", resp.Status, resp.Meta))
|
fb.Println(fmt.Sprintf("%d %s\n", resp.Status, resp.Meta))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
for {
|
for {
|
||||||
x, y, err := t.GetInput()
|
x, y, err := t.GetInput()
|
||||||
|
@ -206,7 +194,7 @@ func main() {
|
||||||
fb.Println("Exiting...")
|
fb.Println("Exiting...")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hostsfile.Close()
|
// hostsfile.Close()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/fogleman/gg"
|
||||||
|
"github.com/shermp/go-fbink-v2/gofbink"
|
||||||
|
"github.com/shermp/go-kobo-input/koboin"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"image"
|
||||||
|
)
|
||||||
|
|
||||||
|
var keyboard [][]string = [][]string{
|
||||||
|
{"1","2","3","4","5","6","7","8","9","10"},
|
||||||
|
{"q","w","e","r","t","y","u","i","o","p","BKSP"},
|
||||||
|
{"a","s","d","f","g","h","j","k","l",";","ENTER"},
|
||||||
|
{"z","x","c","v","b","n","m",".","/",":","SHIFT"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyLocation encodes a keyboard key and where it is on the screen, so input can be scanned.
|
||||||
|
type KeyLocation struct {
|
||||||
|
X,Y,W,H int
|
||||||
|
Label string
|
||||||
|
Keycode string
|
||||||
|
}
|
||||||
|
|
||||||
|
// drawOSK draws an on-screen keyboard.
|
||||||
|
func drawOSK(fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *font.Face) error {
|
||||||
|
var keysw int // Keys wide
|
||||||
|
keysh := len(keyboard) // Keys high
|
||||||
|
for _, r := range keyboard {
|
||||||
|
if len(r) > keysw {
|
||||||
|
keysw = len(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oskheight := height/3
|
||||||
|
i := image.NewRGBA(image.Rect(0, 0, width, oskheight))
|
||||||
|
dc := gg.NewContextForRGBA(i)
|
||||||
|
if *f != nil {
|
||||||
|
dc.SetFontFace(*f)
|
||||||
|
}
|
||||||
|
dc.SetLineWidth(linewidth)
|
||||||
|
dc.DrawRectangle(0,0,float64(width),float64(oskheight))
|
||||||
|
dc.SetRGB(1,1,1)
|
||||||
|
dc.FillPreserve()
|
||||||
|
dc.SetRGB(0,0,0)
|
||||||
|
dc.Stroke()
|
||||||
|
boardwidth := float64(width) - oskpadding*2
|
||||||
|
boardheight := float64(height/3) - oskpadding*2
|
||||||
|
keywidth := boardwidth / float64(keysw)
|
||||||
|
keyheight := boardheight / float64(keysh)
|
||||||
|
ypos := oskpadding
|
||||||
|
for _, r := range keyboard {
|
||||||
|
xpos := oskpadding // padding
|
||||||
|
for _, k := range r {
|
||||||
|
// dc.DrawRectangle(xpos, ypos, xpos+keywidth-keyspacing, ypos+keyheight-keyspacing)
|
||||||
|
// dc.Stroke()
|
||||||
|
dc.DrawStringAnchored(k, xpos+keywidth/2, ypos+keyheight/2, 0.5, 0.5)
|
||||||
|
dc.Fill()
|
||||||
|
xpos += keywidth
|
||||||
|
}
|
||||||
|
ypos += keyheight
|
||||||
|
}
|
||||||
|
|
||||||
|
err := fb.PrintRBGA(0, int16(height-oskheight), i, opts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// drawErrorBox prints the given error on screen, and only proceeds after touch input.
|
||||||
|
func drawErrorBox(e error, fb *gofbink.FBInk, t *koboin.TouchDevice, opts *gofbink.FBInkConfig, f *font.Face) {
|
||||||
|
boxheight := height / 4
|
||||||
|
boxwidth := width / 2
|
||||||
|
i := image.NewRGBA(image.Rect(0, 0, boxwidth, boxheight))
|
||||||
|
dc := gg.NewContextForRGBA(i)
|
||||||
|
if *f != nil {
|
||||||
|
dc.SetFontFace(*f)
|
||||||
|
}
|
||||||
|
dc.SetLineWidth(linewidth)
|
||||||
|
dc.DrawRectangle(0, 0, float64(boxwidth), float64(boxheight))
|
||||||
|
dc.SetRGB(1, 1, 1)
|
||||||
|
dc.FillPreserve()
|
||||||
|
dc.SetRGB(0, 0, 0)
|
||||||
|
dc.Stroke()
|
||||||
|
dc.SetRGB(0, 0, 0)
|
||||||
|
dc.DrawStringWrapped("Error:\n"+e.Error(), float64(boxwidth/2), float64(boxheight/2), 0.5, 0.5, float64(boxwidth), 1.0, gg.AlignCenter)
|
||||||
|
dc.Fill()
|
||||||
|
fb.PrintRBGA(int16(width/2-(boxwidth/2)), int16(height/2-(boxheight/2)), i, opts)
|
||||||
|
t.GetInput()
|
||||||
|
}
|
Reference in New Issue