Compare commits

...

2 Commits

Author SHA1 Message Date
Nico 00692961d4 implement gemini status 10 2021-02-11 22:07:07 +00:00
Nico 67d5488061 make framebuffer and touchscreen global 2021-02-11 18:42:57 +00:00
2 changed files with 34 additions and 31 deletions

35
main.go
View File

@ -36,6 +36,9 @@ const (
var f *truetype.Font var f *truetype.Font
var face font.Face var face font.Face
var fb *gofbink.FBInk
var fbinkOpts gofbink.FBInkConfig
var t *koboin.TouchDevice
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)
@ -64,14 +67,14 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
} }
switch resp.Status.Class() { switch resp.Status.Class() {
case gemini.StatusClassInput: // TODO implement input case gemini.StatusClassInput: // TODO sensitive input
/* input, ok := getInput(resp.Meta, resp.Status == gemini.StatusSensitiveInput) input, err := GetInput(&face, resp.Meta + ":")
if !ok { if err != nil {
break break
} }
req.URL.ForceQuery = true req.URL.ForceQuery = true
req.URL.RawQuery = gemini.QueryEscape(input) req.URL.RawQuery = gemini.QueryEscape(input)
return do(req, via) */ return do(req, via)
case gemini.StatusClassRedirect: case gemini.StatusClassRedirect:
via = append(via, req) via = append(via, req)
@ -94,9 +97,9 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
func main() { func main() {
// Framebuffer setup // Framebuffer setup
fbinkOpts := gofbink.FBInkConfig{} fbinkOpts = gofbink.FBInkConfig{}
rOpts := gofbink.RestrictedConfig{} rOpts := gofbink.RestrictedConfig{}
fb := gofbink.New(&fbinkOpts, &rOpts) fb = gofbink.New(&fbinkOpts, &rOpts)
fb.Open() fb.Open()
defer fb.Close() defer fb.Close()
fb.Init(&fbinkOpts) fb.Init(&fbinkOpts)
@ -105,16 +108,13 @@ func main() {
// Touchscreen setup // Touchscreen setup
touchPath := "/dev/input/event1" touchPath := "/dev/input/event1"
t := koboin.New(touchPath, width, height) t = koboin.New(touchPath, width, height)
if t == nil {
return
}
defer t.Close() defer t.Close()
// 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, &face) drawErrorBox(err, &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()
@ -128,7 +128,7 @@ func main() {
} }
err = hosts.Load(path) err = hosts.Load(path)
if err != nil { if err != nil {
drawErrorBox(err, fb, t, &fbinkOpts, &face) drawErrorBox(err, &face)
logger.Fatal(err) logger.Fatal(err)
} }
@ -151,7 +151,7 @@ func main() {
} }
face = truetype.NewFace(f, &truetype.Options{Size: 32}) face = truetype.NewFace(f, &truetype.Options{Size: 32})
str, err := GetInput(fb, &fbinkOpts, &face, t, "Test:") str, err := GetInput(&face, "Test:")
if err != nil { if err != nil {
fb.Println("Error: ") fb.Println("Error: ")
logger.Fatal(err) logger.Fatal(err)
@ -159,7 +159,7 @@ func main() {
u, err := url.Parse(str) u, err := url.Parse(str)
if err != nil { if err != nil {
drawErrorBox(err, fb, t, &fbinkOpts, &face) drawErrorBox(err, &face)
logger.Println(err) logger.Println(err)
} }
if u.Scheme == "" { if u.Scheme == "" {
@ -169,12 +169,12 @@ func main() {
req, err := gemini.NewRequest(u.String()) req, err := gemini.NewRequest(u.String())
if err != nil { if err != nil {
drawErrorBox(err, fb, t, &fbinkOpts, &face) drawErrorBox(err, &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, &face) drawErrorBox(err, &face)
logger.Fatal(err) logger.Fatal(err)
} }
defer resp.Body.Close() defer resp.Body.Close()
@ -183,9 +183,10 @@ 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, &face) drawErrorBox(err, &face)
logger.Fatal(err) logger.Fatal(err)
} }
fb.ClearScreen(&fbinkOpts)
fb.Println(string(body)) fb.Println(string(body))
fmt.Println(string(body)) fmt.Println(string(body))
} else { } else {

30
ui.go
View File

@ -2,8 +2,8 @@ package main
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"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" "image"
"fmt" "fmt"
@ -13,15 +13,17 @@ import (
var keyboardLowercase [][]string = [][]string{ var keyboardLowercase [][]string = [][]string{
{"1","2","3","4","5","6","7","8","9","10","BKSP"}, {"1","2","3","4","5","6","7","8","9","10","BKSP"},
{"q","w","e","r","t","y","u","i","o","p","ENTER"}, {"q","w","e","r","t","y","u","i","o","p","ENTER"},
{"a","s","d","f","g","h","j","k","l",";","SHIFT"}, {"a","s","d","f","g","h","j","k","l","~","SHIFT"},
{"z","x","c","v","b","n","m",".","/",":","SPACE"}, {"z","x","c","v","b","n","m",".","/",":","SPACE"},
} }
/*
var keyboardUppercase [][]string = [][]string{ var keyboardUppercase [][]string = [][]string{
{"!","\"","£","$","%","^","&","*","(",")","BKSP"}, {"!","\"","£","$","%","^","&","*","(",")","BKSP"},
{"Q","W","E","R","T","Y","U","I","O","P","ENTER"}, {"Q","W","E","R","T","Y","U","I","O","P","ENTER"},
{"A","S","D","F","G","H","J","K","L","?","SHIFT"}, {"A","S","D","F","G","H","J","K","L","?","SHIFT"},
{"Z","X","C","V","B","N","M",",","<",">","SPACE"}, {"Z","X","C","V","B","N","M",",","<",">","SPACE"},
} }
*/
// KeyLocation encodes a keyboard key and where it is on the screen, so input can be scanned. // KeyLocation encodes a keyboard key and where it is on the screen, so input can be scanned.
type KeyLocation struct { type KeyLocation struct {
@ -39,7 +41,7 @@ func touchingKey(x, y int, k KeyLocation) bool {
} }
// Draws a simple dialog box // Draws a simple dialog box
func drawDialog(text string, fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *font.Face) { func drawDialog(text string, f *font.Face) {
boxheight := height / 4 boxheight := height / 4
boxwidth := width / 2 boxwidth := width / 2
i := image.NewRGBA(image.Rect(0, 0, boxwidth, boxheight)) i := image.NewRGBA(image.Rect(0, 0, boxwidth, boxheight))
@ -56,21 +58,21 @@ func drawDialog(text string, fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *fo
dc.SetRGB(0, 0, 0) dc.SetRGB(0, 0, 0)
dc.DrawStringWrapped(text, float64(boxwidth/2), float64(boxheight/2), 0.5, 0.5, float64(boxwidth), 1.0, gg.AlignCenter) dc.DrawStringWrapped(text, float64(boxwidth/2), float64(boxheight/2), 0.5, 0.5, float64(boxwidth), 1.0, gg.AlignCenter)
dc.Fill() dc.Fill()
fb.PrintRBGA(int16(width/2-(boxwidth/2)), int16(height/2-(boxheight/2)), i, opts) fb.PrintRBGA(int16(width/2-(boxwidth/2)), int16(height/2-(boxheight/2)), i, &fbinkOpts)
} }
// GetInput draws an OSK and dialog then gets input from the user. It returns the inputted string and a potential error. // GetInput draws an OSK and dialog then gets input from the user. It returns the inputted string and a potential error.
// TODO: more feedback to the user // TODO: more feedback to the user
func GetInput(fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *font.Face, t *koboin.TouchDevice, prompt string) (string, error) { func GetInput(f *font.Face, prompt string) (string, error) {
var s string var s string
shifted := false shifted := false
// Draw onscreen keyboard // Draw onscreen keyboard
board, err := drawOSK(fb, opts, f, keyboardLowercase) board, err := drawOSK(f, keyboardLowercase)
if err != nil { if err != nil {
return "", err return "", err
} }
drawDialog(prompt + "\n ", fb, opts, f) drawDialog(prompt + "\n ", f)
// Handle input // Handle input
for { for {
@ -105,14 +107,14 @@ func GetInput(fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *font.Face, t *kob
s = s + key.Keycode s = s + key.Keycode
} }
} }
drawDialog(prompt + "\n" + s, fb, opts, f) drawDialog(prompt + "\n" + s, f)
} }
} }
} }
} }
// drawOSK draws an on-screen keyboard. // drawOSK draws an on-screen keyboard.
func drawOSK(fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *font.Face, keyboard [][]string) ([]KeyLocation, error) { func drawOSK(f *font.Face, keyboard [][]string) ([]KeyLocation, error) {
var board []KeyLocation var board []KeyLocation
var keysw int // Keys wide var keysw int // Keys wide
keysh := len(keyboard) // Keys high keysh := len(keyboard) // Keys high
@ -149,7 +151,7 @@ func drawOSK(fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *font.Face, keyboar
ypos += keyheight ypos += keyheight
} }
err := fb.PrintRBGA(0, int16(height-oskheight), i, opts) err := fb.PrintRBGA(0, int16(height-oskheight), i, &fbinkOpts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -157,7 +159,7 @@ func drawOSK(fb *gofbink.FBInk, opts *gofbink.FBInkConfig, f *font.Face, keyboar
} }
// drawErrorBox prints the given error on screen, and only proceeds after touch input. // 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) { func drawErrorBox(e error, f *font.Face) {
drawDialog("Error:\n"+e.Error(), fb, opts, f) drawDialog("Error:\n"+e.Error(), f)
t.GetInput() t.GetInput()
} }