mirror of https://github.com/liamg/aminal.git
Merge pull request #13 from jumptrading/set-console-mode
Sixel VT sequence Step 1. Allow pass-through on Windows
This commit is contained in:
commit
657e43742e
|
@ -68,7 +68,7 @@ package platform
|
||||||
// return 0;
|
// return 0;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// DWORD createGuestProcHelper( uintptr_t hpc, LPCWSTR imagePath, uintptr_t * hProcess )
|
// DWORD createGuestProcHelper( uintptr_t hpc, LPCWSTR imagePath, uintptr_t * hProcess, DWORD * dwProcessID )
|
||||||
// {
|
// {
|
||||||
// STARTUPINFOEXW_copy si;
|
// STARTUPINFOEXW_copy si;
|
||||||
// ZeroMemory( &si, sizeof(si) );
|
// ZeroMemory( &si, sizeof(si) );
|
||||||
|
@ -132,6 +132,7 @@ package platform
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// *hProcess = (uintptr_t) pi.hProcess;
|
// *hProcess = (uintptr_t) pi.hProcess;
|
||||||
|
// *dwProcessID = pi.dwProcessId;
|
||||||
//
|
//
|
||||||
// HeapFree(GetProcessHeap(), 0, si.lpAttributeList);
|
// HeapFree(GetProcessHeap(), 0, si.lpAttributeList);
|
||||||
// HeapFree(GetProcessHeap(), 0, cmdLineMutable);
|
// HeapFree(GetProcessHeap(), 0, cmdLineMutable);
|
||||||
|
@ -154,10 +155,11 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type winProcess struct {
|
type winProcess struct {
|
||||||
hproc uintptr
|
hproc uintptr
|
||||||
|
processID uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func createPtyChildProcess(imagePath string, hcon uintptr) (Process, error) {
|
func createPtyChildProcess(imagePath string, hcon uintptr) (*winProcess, error) {
|
||||||
path16 := utf16.Encode([]rune(imagePath))
|
path16 := utf16.Encode([]rune(imagePath))
|
||||||
|
|
||||||
cpath16 := C.calloc(C.size_t(len(path16)+1), 2)
|
cpath16 := C.calloc(C.size_t(len(path16)+1), 2)
|
||||||
|
@ -165,8 +167,9 @@ func createPtyChildProcess(imagePath string, hcon uintptr) (Process, error) {
|
||||||
copy(pp[:], path16)
|
copy(pp[:], path16)
|
||||||
|
|
||||||
hproc := C.uintptr_t(0)
|
hproc := C.uintptr_t(0)
|
||||||
|
dwProcessID := C.DWORD(0)
|
||||||
|
|
||||||
hr := C.createGuestProcHelper(C.uintptr_t(hcon), (C.LPCWSTR)(cpath16), &hproc)
|
hr := C.createGuestProcHelper(C.uintptr_t(hcon), (C.LPCWSTR)(cpath16), &hproc, &dwProcessID)
|
||||||
|
|
||||||
C.free(cpath16)
|
C.free(cpath16)
|
||||||
|
|
||||||
|
@ -175,7 +178,8 @@ func createPtyChildProcess(imagePath string, hcon uintptr) (Process, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &winProcess{
|
return &winProcess{
|
||||||
hproc: uintptr(hproc),
|
hproc: uintptr(hproc),
|
||||||
|
processID: uint32(dwProcessID),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ package platform
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/MaxRis/w32"
|
"github.com/MaxRis/w32"
|
||||||
)
|
)
|
||||||
|
@ -132,7 +133,42 @@ func (pty *winConPty) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pty *winConPty) CreateGuestProcess(imagePath string) (Process, error) {
|
func (pty *winConPty) CreateGuestProcess(imagePath string) (Process, error) {
|
||||||
return createPtyChildProcess(imagePath, pty.hcon)
|
process, err := createPtyChildProcess(imagePath, pty.hcon)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
setupChildConsole(C.DWORD(process.processID), C.STD_OUTPUT_HANDLE, C.ENABLE_PROCESSED_OUTPUT|C.ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||||
|
}
|
||||||
|
|
||||||
|
return process, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupChildConsole(processID C.DWORD, nStdHandle C.DWORD, mode uint) bool {
|
||||||
|
C.FreeConsole()
|
||||||
|
defer C.AttachConsole(^C.DWORD(0)) // attach to parent process console
|
||||||
|
|
||||||
|
// process may not be ready so we'll do retries
|
||||||
|
const maxWaitMilliSeconds = 5000
|
||||||
|
const waitStepMilliSeconds = 200
|
||||||
|
count := maxWaitMilliSeconds / waitStepMilliSeconds
|
||||||
|
|
||||||
|
for {
|
||||||
|
if r := C.AttachConsole(processID); r != 0 {
|
||||||
|
break // success
|
||||||
|
}
|
||||||
|
lastError := C.GetLastError()
|
||||||
|
if lastError != C.ERROR_GEN_FAILURE || count <= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(waitStepMilliSeconds))
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
|
||||||
|
h := C.GetStdHandle(nStdHandle)
|
||||||
|
C.SetConsoleMode(h, C.DWORD(mode))
|
||||||
|
C.FreeConsole()
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pty *winConPty) Resize(x, y int) error {
|
func (pty *winConPty) Resize(x, y int) error {
|
||||||
|
|
|
@ -17,7 +17,10 @@ func sixelHandler(pty chan rune, terminal *Terminal) error {
|
||||||
for {
|
for {
|
||||||
b := <-pty
|
b := <-pty
|
||||||
if b == 0x1b { // terminated by ESC bell or ESC \
|
if b == 0x1b { // terminated by ESC bell or ESC \
|
||||||
_ = <-pty // swallow \ or bell
|
t := <-pty
|
||||||
|
if t != 0x07 && t != 0x5c {
|
||||||
|
return fmt.Errorf("Incorrect terminator in sixel sequence: 0x%02X [%c]", t, t)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if b >= 33 {
|
if b >= 33 {
|
||||||
|
|
Loading…
Reference in New Issue