Get transmission medium detection working
This commit is contained in:
parent
2d1a2c30bf
commit
ea756db544
@ -3,6 +3,7 @@
|
|||||||
package icat
|
package icat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ import (
|
|||||||
"kitty/tools/tui/graphics"
|
"kitty/tools/tui/graphics"
|
||||||
"kitty/tools/tui/loop"
|
"kitty/tools/tui/loop"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
|
"kitty/tools/utils/shm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
@ -29,8 +31,11 @@ const (
|
|||||||
var transfer_by_file, transfer_by_memory, transfer_by_stream transfer_mode
|
var transfer_by_file, transfer_by_memory, transfer_by_stream transfer_mode
|
||||||
|
|
||||||
var temp_files_to_delete []string
|
var temp_files_to_delete []string
|
||||||
|
var shm_files_to_delete []shm.MMap
|
||||||
var direct_query_id, file_query_id, memory_query_id uint32
|
var direct_query_id, file_query_id, memory_query_id uint32
|
||||||
var stderr_is_tty bool
|
var stderr_is_tty bool
|
||||||
|
var query_in_flight bool
|
||||||
|
var stream_response string
|
||||||
|
|
||||||
func print_error(format string, args ...any) {
|
func print_error(format string, args ...any) {
|
||||||
if lp == nil || !stderr_is_tty {
|
if lp == nil || !stderr_is_tty {
|
||||||
@ -44,10 +49,12 @@ func print_error(format string, args ...any) {
|
|||||||
|
|
||||||
func on_initialize() (string, error) {
|
func on_initialize() (string, error) {
|
||||||
var iid uint32
|
var iid uint32
|
||||||
|
query_in_flight = true
|
||||||
g := func(t graphics.GRT_t, payload string) uint32 {
|
g := func(t graphics.GRT_t, payload string) uint32 {
|
||||||
iid += 1
|
iid += 1
|
||||||
g1 := &graphics.GraphicsCommand{}
|
g1 := &graphics.GraphicsCommand{}
|
||||||
g1.SetTransmission(t).SetAction(graphics.GRT_action_query).SetImageId(iid).SetDataWidth(1).SetDataHeight(1).SetFormat(graphics.GRT_format_rgb)
|
g1.SetTransmission(t).SetAction(graphics.GRT_action_query).SetImageId(iid).SetDataWidth(1).SetDataHeight(1).SetFormat(
|
||||||
|
graphics.GRT_format_rgb).SetDataSize(uint64(len(payload)))
|
||||||
g1.WriteWithPayloadToLoop(lp, utils.UnsafeStringToBytes(payload))
|
g1.WriteWithPayloadToLoop(lp, utils.UnsafeStringToBytes(payload))
|
||||||
return iid
|
return iid
|
||||||
}
|
}
|
||||||
@ -69,16 +76,90 @@ func on_initialize() (string, error) {
|
|||||||
transfer_by_file = unsupported
|
transfer_by_file = unsupported
|
||||||
print_error("Failed to create temporary file for data transfer, file based transfer is disabled. Error: %v", err)
|
print_error("Failed to create temporary file for data transfer, file based transfer is disabled. Error: %v", err)
|
||||||
}
|
}
|
||||||
|
sf, err := shm.CreateTemp("icat-", 3)
|
||||||
|
if err == nil {
|
||||||
|
memory_query_id = g(graphics.GRT_transmission_sharedmem, sf.Name())
|
||||||
|
shm_files_to_delete = append(shm_files_to_delete, sf)
|
||||||
|
copy(sf.Slice(), []byte{1, 2, 3})
|
||||||
|
sf.Close()
|
||||||
|
} else {
|
||||||
|
transfer_by_memory = unsupported
|
||||||
|
var ens *shm.ErrNotSupported
|
||||||
|
if !errors.As(err, &ens) {
|
||||||
|
print_error("Failed to create SHM for data transfer, memory based transfer is disabled. Error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lp.QueueWriteString("\x1b[c")
|
||||||
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func on_query_finished() (err error) {
|
||||||
|
query_in_flight = false
|
||||||
|
if transfer_by_stream != supported {
|
||||||
|
return fmt.Errorf("This terminal emulator does not support the graphics protocol, use a terminal emulator such as kitty that does support it")
|
||||||
|
}
|
||||||
|
if opts.DetectSupport {
|
||||||
|
switch {
|
||||||
|
case transfer_by_memory == supported:
|
||||||
|
print_error("memory")
|
||||||
|
case transfer_by_file == supported:
|
||||||
|
print_error("file")
|
||||||
|
default:
|
||||||
|
print_error("stream")
|
||||||
|
}
|
||||||
|
lp.Quit(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func on_query_response(g *graphics.GraphicsCommand) (err error) {
|
||||||
|
var tm *transfer_mode
|
||||||
|
switch g.ImageId() {
|
||||||
|
case direct_query_id:
|
||||||
|
tm = &transfer_by_stream
|
||||||
|
case file_query_id:
|
||||||
|
tm = &transfer_by_file
|
||||||
|
case memory_query_id:
|
||||||
|
tm = &transfer_by_memory
|
||||||
|
}
|
||||||
|
if g.ResponseMessage() == "OK" {
|
||||||
|
*tm = supported
|
||||||
|
} else {
|
||||||
|
*tm = unsupported
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func on_escape_code(etype loop.EscapeCodeType, payload []byte) (err error) {
|
||||||
|
switch etype {
|
||||||
|
case loop.CSI:
|
||||||
|
if len(payload) > 3 && payload[0] == '?' && payload[len(payload)-1] == 'c' {
|
||||||
|
return on_query_finished()
|
||||||
|
}
|
||||||
|
case loop.APC:
|
||||||
|
g := graphics.GraphicsCommandFromAPC(payload)
|
||||||
|
if g != nil {
|
||||||
|
if query_in_flight {
|
||||||
|
return on_query_response(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func on_finalize() string {
|
func on_finalize() string {
|
||||||
if len(temp_files_to_delete) > 0 {
|
if len(temp_files_to_delete) > 0 && transfer_by_file != supported {
|
||||||
for _, name := range temp_files_to_delete {
|
for _, name := range temp_files_to_delete {
|
||||||
os.Remove(name)
|
os.Remove(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(shm_files_to_delete) > 0 && transfer_by_memory != supported {
|
||||||
|
for _, name := range shm_files_to_delete {
|
||||||
|
name.Unlink()
|
||||||
|
}
|
||||||
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,13 +179,25 @@ func main(cmd *cli.Command, o *Options, args []string) (rc int, err error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
temp_files_to_delete = make([]string, 0, 8)
|
temp_files_to_delete = make([]string, 0, 8)
|
||||||
|
shm_files_to_delete = make([]shm.MMap, 0, 8)
|
||||||
lp, err = loop.New(loop.NoAlternateScreen, loop.NoRestoreColors, loop.NoMouseTracking)
|
lp, err = loop.New(loop.NoAlternateScreen, loop.NoRestoreColors, loop.NoMouseTracking)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lp.OnInitialize = on_initialize
|
lp.OnInitialize = on_initialize
|
||||||
lp.OnFinalize = on_finalize
|
lp.OnFinalize = on_finalize
|
||||||
|
lp.OnEscapeCode = on_escape_code
|
||||||
|
|
||||||
|
err = lp.Run()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ds := lp.DeathSignalName()
|
||||||
|
if ds != "" {
|
||||||
|
fmt.Println("Killed by signal: ", ds)
|
||||||
|
lp.KillIfSignalled()
|
||||||
|
return
|
||||||
|
}
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user