212 lines
4.6 KiB
Go
212 lines
4.6 KiB
Go
package vnc
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
)
|
|
|
|
const (
|
|
EncAtenHermonSubrect EncodingType = 0
|
|
EncAtenHermonRaw EncodingType = 1
|
|
)
|
|
|
|
type AtenHermon struct {
|
|
_ [4]byte
|
|
AtenLength uint32
|
|
AtenType uint8
|
|
_ [1]byte
|
|
AtenSubrects uint32
|
|
AtenRawLength uint32
|
|
Encodings []Encoding
|
|
}
|
|
|
|
type AtenHermonSubrect struct {
|
|
A uint16
|
|
B uint16
|
|
Y uint8
|
|
X uint8
|
|
Data []byte
|
|
}
|
|
|
|
func (*AtenHermon) Supported(Conn) bool {
|
|
return false
|
|
}
|
|
|
|
func (*AtenHermon) Type() EncodingType { return EncAtenHermon }
|
|
|
|
func (enc *AtenHermon) Read(c Conn, rect *Rectangle) error {
|
|
var pad4 [4]byte
|
|
|
|
if err := binary.Read(c, binary.BigEndian, &pad4); err != nil {
|
|
return err
|
|
}
|
|
|
|
var aten_length uint32
|
|
if err := binary.Read(c, binary.BigEndian, &aten_length); err != nil {
|
|
return err
|
|
}
|
|
enc.AtenLength = aten_length
|
|
|
|
if rect.Width == 64896 && rect.Height == 65056 {
|
|
if aten_length != 10 && aten_length != 0 {
|
|
return fmt.Errorf("screen is off and length is invalid")
|
|
}
|
|
aten_length = 0
|
|
}
|
|
|
|
if c.Width() != rect.Width && c.Height() != rect.Height {
|
|
c.SetWidth(rect.Width)
|
|
c.SetHeight(rect.Height)
|
|
}
|
|
|
|
var aten_type uint8
|
|
if err := binary.Read(c, binary.BigEndian, &aten_type); err != nil {
|
|
return err
|
|
}
|
|
enc.AtenType = aten_type
|
|
|
|
var pad1 [1]byte
|
|
if err := binary.Read(c, binary.BigEndian, &pad1); err != nil {
|
|
return err
|
|
}
|
|
|
|
var subrects uint32
|
|
if err := binary.Read(c, binary.BigEndian, &subrects); err != nil {
|
|
return err
|
|
}
|
|
enc.AtenSubrects = subrects
|
|
|
|
var raw_length uint32
|
|
if err := binary.Read(c, binary.BigEndian, &raw_length); err != nil {
|
|
return err
|
|
}
|
|
enc.AtenRawLength = raw_length
|
|
|
|
if aten_length != raw_length {
|
|
return fmt.Errorf("aten_length != raw_length, %d != %d", aten_length, raw_length)
|
|
}
|
|
|
|
aten_length -= 10 // skip
|
|
|
|
for aten_length > 0 {
|
|
switch EncodingType(aten_type) {
|
|
case EncAtenHermonSubrect:
|
|
encSR := &AtenHermonSubrect{}
|
|
if err := encSR.Read(c, rect); err != nil {
|
|
return err
|
|
}
|
|
enc.Encodings = append(enc.Encodings, encSR)
|
|
aten_length -= 6 + (16 * 16 * uint32(c.PixelFormat().BPP/8))
|
|
case EncAtenHermonRaw:
|
|
encRaw := &RawEncoding{}
|
|
if err := encRaw.Read(c, rect); err != nil {
|
|
return err
|
|
}
|
|
enc.Encodings = append(enc.Encodings, encRaw)
|
|
aten_length -= uint32(rect.Area()) * uint32(c.PixelFormat().BPP/8)
|
|
default:
|
|
return fmt.Errorf("unknown aten hermon type %d", aten_type)
|
|
|
|
}
|
|
}
|
|
|
|
if aten_length < 0 {
|
|
return fmt.Errorf("aten_len dropped below zero")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (enc *AtenHermon) Write(c Conn, rect *Rectangle) error {
|
|
if !enc.Supported(c) {
|
|
for _, ew := range enc.Encodings {
|
|
if err := ew.Write(c, rect); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
var pad4 [4]byte
|
|
|
|
if err := binary.Write(c, binary.BigEndian, pad4); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Write(c, binary.BigEndian, enc.AtenLength); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Write(c, binary.BigEndian, enc.AtenType); err != nil {
|
|
return err
|
|
}
|
|
|
|
var pad1 [1]byte
|
|
if err := binary.Write(c, binary.BigEndian, pad1); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Write(c, binary.BigEndian, enc.AtenSubrects); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Write(c, binary.BigEndian, enc.AtenRawLength); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, ew := range enc.Encodings {
|
|
if err := ew.Write(c, rect); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (*AtenHermonSubrect) Supported(Conn) bool {
|
|
return false
|
|
}
|
|
|
|
func (enc *AtenHermonSubrect) Type() EncodingType {
|
|
return EncAtenHermonSubrect
|
|
}
|
|
|
|
func (enc *AtenHermonSubrect) Read(c Conn, rect *Rectangle) error {
|
|
if err := binary.Read(c, binary.BigEndian, &enc.A); err != nil {
|
|
return err
|
|
}
|
|
if err := binary.Read(c, binary.BigEndian, &enc.B); err != nil {
|
|
return err
|
|
}
|
|
if err := binary.Read(c, binary.BigEndian, &enc.Y); err != nil {
|
|
return err
|
|
}
|
|
if err := binary.Read(c, binary.BigEndian, &enc.X); err != nil {
|
|
return err
|
|
}
|
|
enc.Data = make([]byte, 16*16*uint32(c.PixelFormat().BPP/8))
|
|
if err := binary.Read(c, binary.BigEndian, &enc.Data); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (enc *AtenHermonSubrect) Write(c Conn, rect *Rectangle) error {
|
|
if !enc.Supported(c) {
|
|
return nil
|
|
}
|
|
if err := binary.Write(c, binary.BigEndian, enc.A); err != nil {
|
|
return err
|
|
}
|
|
if err := binary.Write(c, binary.BigEndian, enc.B); err != nil {
|
|
return err
|
|
}
|
|
if err := binary.Write(c, binary.BigEndian, enc.Y); err != nil {
|
|
return err
|
|
}
|
|
if err := binary.Write(c, binary.BigEndian, enc.X); err != nil {
|
|
return err
|
|
}
|
|
if err := binary.Write(c, binary.BigEndian, enc.Data); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|