Skip to content

Commit

Permalink
feat(telnet): React to the current terminal size
Browse files Browse the repository at this point in the history
Ref #35
  • Loading branch information
gabe565 committed Apr 18, 2024
1 parent f613742 commit 56a7c0a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 17 deletions.
28 changes: 24 additions & 4 deletions internal/server/telnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/gabe565/ascii-movie/internal/server/idleconn"
"github.com/gabe565/ascii-movie/internal/server/telnet"
"github.com/gabe565/ascii-movie/internal/util"
"github.com/muesli/termenv"
flag "github.com/spf13/pflag"
)

Expand Down Expand Up @@ -112,13 +113,20 @@ func (s *TelnetServer) Handler(ctx context.Context, conn net.Conn, m *movie.Movi
ctx, cancel := context.WithCancel(ctx)
defer cancel()

termCh := make(chan string)
termCh := make(chan telnet.TermInfo)
go func() {
// Proxy input to program
_ = telnet.Proxy(conn, inW, termCh)
cancel()
}()
profile := util.Profile(<-termCh)

var profile termenv.Profile
select {
case info := <-termCh:
profile = util.Profile(info.Term)
case <-time.After(250 * time.Millisecond):
profile = termenv.ANSI256
}

player := movie.NewPlayer(m, logger, profile)
program := tea.NewProgram(
Expand All @@ -129,8 +137,20 @@ func (s *TelnetServer) Handler(ctx context.Context, conn net.Conn, m *movie.Movi
)

go func() {
<-ctx.Done()
program.Send(movie.Quit())
for {
select {
case info := <-termCh:
if info.Width != 0 && info.Height != 0 {
program.Send(tea.WindowSizeMsg{
Width: int(info.Width),
Height: int(info.Height),
})
}
case <-ctx.Done():
program.Send(movie.Quit())
return
}
}
}()

go func() {
Expand Down
38 changes: 25 additions & 13 deletions internal/server/telnet/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package telnet

import (
"bufio"
"bytes"
"encoding/binary"
"errors"
"io"
"net"
Expand All @@ -11,8 +13,18 @@ import (
log "github.com/sirupsen/logrus"
)

func Proxy(conn net.Conn, proxy io.Writer, termCh chan string) error {
type TermInfo struct {
Term string
WindowSize
}

type WindowSize struct {
Width, Height uint16
}

func Proxy(conn net.Conn, proxy io.Writer, termCh chan TermInfo) error {
reader := bufio.NewReaderSize(conn, 64)
var info TermInfo
var wroteTelnetCommands bool
var wroteTermType bool

Expand All @@ -23,15 +35,6 @@ func Proxy(conn net.Conn, proxy io.Writer, termCh chan string) error {
return err
}

go func() {
time.Sleep(250 * time.Millisecond)
if !wroteTermType {
wroteTermType = true
log.Trace("Did not get terminal type in time")
close(termCh)
}
}()

for {
b, err := reader.ReadByte()
if err != nil {
Expand All @@ -48,6 +51,7 @@ func Proxy(conn net.Conn, proxy io.Writer, termCh chan string) error {
Iac, Will, Echo,
Iac, Will, SuppressGoAhead,
Iac, Do, TerminalType,
Iac, Do, NegotiateAboutWindowSize,
); err != nil {
log.WithError(err).Error("Failed to write Telnet commands")
}
Expand Down Expand Up @@ -77,10 +81,18 @@ func Proxy(conn net.Conn, proxy io.Writer, termCh chan string) error {
case TerminalType:
if len(command) > 5 && !wroteTermType {
wroteTermType = true
term := string(command[2 : len(command)-2])
info.Term = string(command[2 : len(command)-2])
log.Trace("Got terminal type")
termCh <- term
close(termCh)
termCh <- info
}
case NegotiateAboutWindowSize:
if len(command) > 5 {
log.Trace("Got window size")
r := bytes.NewReader(command[1 : len(command)-2])
if err := binary.Read(r, binary.BigEndian, &info.WindowSize); err != nil {
return err
}
termCh <- info
}
}
}
Expand Down

0 comments on commit 56a7c0a

Please sign in to comment.