Files

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
}