d703e1f195eae895b6852dd7152bc3871237bf80 — Drew DeVault 2 months ago
Initial commit (written on a line printer!)
5 files changed, 95 insertions(+), 0 deletions(-)

A .gitignore
A go.mod
A go.sum
A lpsh.go
A todo
A  => .gitignore +1 -0
@@ 1,1 @@
+lpsh

A  => go.mod +5 -0
@@ 1,5 @@
+module git.sr.ht/~sircmpwn/lpshell
+
+go 1.13
+
+require git.sr.ht/~sircmpwn/pty v0.0.0-20190330154901-3a43678975a9

A  => go.sum +2 -0
@@ 1,2 @@
+git.sr.ht/~sircmpwn/pty v0.0.0-20190330154901-3a43678975a9 h1:WWPN5lf6KzXp3xWRrPQZ4MLR3yrFEI4Ysz7HSQ1G/yo=
+git.sr.ht/~sircmpwn/pty v0.0.0-20190330154901-3a43678975a9/go.mod h1:8Jmcax8M9nYoEwBhVBhv2ixLRCoUqlbQPE95VpPu43I=

A  => lpsh.go +84 -0
@@ 1,84 @@
+package main
+
+import (
+	"os"
+	"os/exec"
+	"time"
+
+	"git.sr.ht/~sircmpwn/pty"
+)
+
+// TODO: Talk directly to CUPS/the printer?
+func lpr(data []byte) {
+	lpr := exec.Command("/usr/bin/lpr", "-l")
+	pipe, err := lpr.StdinPipe()
+	if err != nil {
+		panic(err)
+	}
+	go func() {
+		defer pipe.Close()
+		pipe.Write(data)
+	}()
+	lpr.Run()
+}
+
+func lprmgr(out chan ([]byte)) {
+	lpr([]byte("\n\n\n\r"))
+	feed := false
+
+	for {
+		select {
+		case data := <-out:
+			if feed {
+				lpr([]byte("\x1Bj\xD8\x1Bj\xD8\x1Bj\x6C"))
+				feed = false
+			}
+			lpr(data)
+		case <-time.After(250 * time.Millisecond):
+			if !feed {
+				feed = true
+				lpr([]byte("\x1BJ\xD8\x1BJ\xD8\x1BJ\x6C"))
+			}
+		}
+	}
+}
+
+func main() {
+	winsize := pty.Winsize{
+		Cols: 160,
+		Rows: 24,
+	}
+	cmd := exec.Command("/bin/sh")
+	cmd.Env = append(os.Environ(), "TERM=lp")
+	tty, err := pty.StartWithSize(cmd, &winsize)
+	if err != nil {
+		panic(err)
+	}
+
+	exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
+
+	lprch := make(chan ([]byte))
+	go lprmgr(lprch)
+
+	inbuf := make([]byte, 4096)
+	go func() {
+		for {
+			n, err := os.Stdin.Read(inbuf)
+			if err != nil {
+				panic(err)
+			}
+			tty.Write(inbuf[:n])
+		}
+	}()
+
+	outbuf := make([]byte, 4096)
+	for {
+		n, err := tty.Read(outbuf)
+		if err != nil {
+			panic(err)
+		}
+		b := make([]byte, n)
+		copy(b, outbuf[:n])
+		lprch <- b
+	}
+}

A  => todo +3 -0
@@ 1,3 @@
+- Write directly to printer
+- Rig into libinput and skip stdin from a parent session
+- Make input timings work more effectively