esc-printer-driver: async device file

This commit is contained in:
Emery Hemingway 2024-06-06 10:46:27 +03:00
parent 8452d5811e
commit 6718a3b040
1 changed files with 24 additions and 5 deletions

View File

@ -4,12 +4,15 @@
## ESC/P printer control actor.
import
std/[cmdline, oserrors, posix, sets],
std/[cmdline, oserrors, posix, sequtils, sets],
pkg/sys/[files, ioqueue],
preserves, preserves/sugar,
syndicate, syndicate/relays,
syndicate/protocols/[gatekeeper, sturdy],
./private/esc_p
from pkg/sys/handles import FD
proc echo(args: varargs[string, `$`]) {.used.} =
stderr.writeLine(args)
@ -17,12 +20,26 @@ type
HandleSet = HashSet[Handle]
Printer = ref object of Entity
device: cint
device: AsyncFile
boldHandles, italicHandles, superscriptHandles, subscriptHandles: HandleSet
buffer: seq[byte]
isBusy: bool
proc flush(printer: Printer) {.asyncio.} =
printer.isBusy = true
while printer.buffer.len > 0:
let n = printer.device.write(printer.buffer)
if n > 0:
printer.buffer.delete(0, n)
elif n < 0:
osLastError().osErrorMsg().quit()
printer.isBusy = false
proc write(printer: Printer; s: string) {.inline.} =
if posix.write(printer.device, s[0].addr, s.len) < 0:
osLastError().osErrorMsg().quit()
printer.buffer.add cast[seq[byte]](s)
if not printer.isBusy:
discard trampoline:
whelp printer.flush()
proc writeLine(printer: Printer; s: string) {.inline.} =
printer.write(s)
@ -73,7 +90,9 @@ let devicePath = paramStr(1)
proc openPrinter(turn: Turn): Printer =
new result
result.facet = turn.facet
result.device = posix.open(devicePath, O_WRONLY, 0)
let fd = posix.open(devicePath, O_WRONLY or O_NONBLOCK, 0)
if fd < 0: osLastError().osErrorMsg().quit()
result.device = newAsyncFile(FD fd)
result.write(InitializePrinter)
runActor(devicePath) do (turn: Turn):