75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
// Fenrir console screen reader.
|
|
// Copyright (c) 2026 Storm Dragon
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify it
|
|
// under the terms of the GNU General Public License as published by the Free
|
|
// Software Foundation, either version 3 of the License, or (at your option)
|
|
// any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
// more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along with
|
|
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
|
|
|
|
//go:build linux && cgo
|
|
|
|
package terminal
|
|
|
|
/*
|
|
#include "native.h"
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"fmt"
|
|
"unsafe"
|
|
|
|
"git.stormux.org/storm/fenrir/internal/clipboard"
|
|
)
|
|
|
|
// Queue_paste belongs to the app loop. The existing nonblocking PTY relay
|
|
// drains it, preserving byte order and the child application's paste mode.
|
|
func (s *Session) Queue_paste(text string) error {
|
|
if err := clipboard.Validate_text(text); err != nil {
|
|
return err
|
|
}
|
|
if !s.active || s.eof || s.closed {
|
|
return fmt.Errorf("clipboard paste: terminal inactive")
|
|
}
|
|
if len(s.pending)+len(text) > clipboard.MaxBytes {
|
|
return fmt.Errorf("clipboard paste queue full")
|
|
}
|
|
if s.pasteEnd > 0 {
|
|
return fmt.Errorf("clipboard paste already queued")
|
|
}
|
|
s.pasteStart = len(s.pending)
|
|
s.pasteGeneration = uint64(C.terminal_generation(s.vt.native))
|
|
var bytes [32]byte
|
|
C.vterm_keyboard_start_paste(s.vt.native)
|
|
n := C.vterm_output_read(s.vt.native, (*C.char)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes)))
|
|
s.pending = append(s.pending, bytes[:int(n)]...)
|
|
s.pending = append(s.pending, text...)
|
|
C.vterm_keyboard_end_paste(s.vt.native)
|
|
n = C.vterm_output_read(s.vt.native, (*C.char)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes)))
|
|
s.pending = append(s.pending, bytes[:int(n)]...)
|
|
s.pasteEnd = len(s.pending)
|
|
s.arm_watch()
|
|
return nil
|
|
}
|
|
|
|
func (s *Session) retire_paste() {
|
|
if s.pasteEnd == 0 {
|
|
return
|
|
}
|
|
if s.active && s.pasteGeneration == uint64(C.terminal_generation(s.vt.native)) {
|
|
return
|
|
}
|
|
copy(s.pending[s.pasteStart:], s.pending[s.pasteEnd:])
|
|
s.pending = s.pending[:len(s.pending)-(s.pasteEnd-s.pasteStart)]
|
|
s.pasteStart, s.pasteEnd = 0, 0
|
|
}
|