2017-06-12 14:11:23 +03:00
|
|
|
package vnc
|
|
|
|
|
2017-06-13 01:52:07 +03:00
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
2017-06-12 14:11:23 +03:00
|
|
|
// EncodingType represents a known VNC encoding type.
|
|
|
|
type EncodingType int32
|
|
|
|
|
|
|
|
//go:generate stringer -type=EncodingType
|
|
|
|
|
|
|
|
const (
|
2017-06-13 01:52:07 +03:00
|
|
|
EncRaw EncodingType = 0
|
|
|
|
EncCopyRect EncodingType = 1
|
|
|
|
EncRRE EncodingType = 2
|
|
|
|
EncCoRRE EncodingType = 4
|
|
|
|
EncHextile EncodingType = 5
|
|
|
|
EncZlib EncodingType = 6
|
|
|
|
EncTight EncodingType = 7
|
|
|
|
EncZlibHex EncodingType = 8
|
|
|
|
EncUltra1 EncodingType = 9
|
|
|
|
EncUltra2 EncodingType = 10
|
|
|
|
EncJPEG EncodingType = 21
|
|
|
|
EncJRLE EncodingType = 22
|
|
|
|
//EncRichCursor EncodingType = 0xFFFFFF11
|
|
|
|
//EncPointerPos EncodingType = 0xFFFFFF18
|
|
|
|
//EncLastRec EncodingType = 0xFFFFFF20
|
2017-06-12 14:11:23 +03:00
|
|
|
EncTRLE EncodingType = 15
|
|
|
|
EncZRLE EncodingType = 16
|
|
|
|
EncColorPseudo EncodingType = -239
|
|
|
|
EncDesktopSizePseudo EncodingType = -223
|
2017-06-13 01:52:07 +03:00
|
|
|
EncClientRedirect EncodingType = -311
|
2017-06-12 14:11:23 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type Encoding interface {
|
|
|
|
Type() EncodingType
|
|
|
|
Read(Conn, *Rectangle) error
|
|
|
|
Write(Conn, *Rectangle) error
|
|
|
|
}
|
|
|
|
|
|
|
|
type RawEncoding struct {
|
|
|
|
Colors []Color
|
|
|
|
}
|
|
|
|
|
|
|
|
func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
|
2017-06-13 16:20:35 +03:00
|
|
|
buf := bytes.NewBuffer(nil)
|
|
|
|
defer buf.Reset()
|
|
|
|
n := 0
|
|
|
|
for _, c := range enc.Colors {
|
|
|
|
bytes, err := c.Marshal()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2017-06-12 14:11:23 +03:00
|
|
|
}
|
2017-06-13 16:20:35 +03:00
|
|
|
n += len(bytes)
|
2017-06-12 14:11:23 +03:00
|
|
|
|
2017-06-13 16:20:35 +03:00
|
|
|
if err := binary.Write(buf, binary.BigEndian, bytes); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
if _, err := buf.Write(bytes); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
fmt.Printf("w %d\n", n)
|
|
|
|
//return binary.Write(c, binary.BigEndian, buf.Bytes())
|
|
|
|
fmt.Printf("w %v\n", buf.Bytes())
|
|
|
|
_, err := c.Write(buf.Bytes())
|
|
|
|
return err
|
2017-06-12 14:11:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read implements the Encoding interface.
|
|
|
|
func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
|
2017-06-13 01:52:07 +03:00
|
|
|
buf := bytes.NewBuffer(nil)
|
|
|
|
pf := c.PixelFormat()
|
|
|
|
cm := c.ColorMap()
|
|
|
|
bytesPerPixel := int(pf.BPP / 8)
|
|
|
|
n := rect.Area() * bytesPerPixel
|
|
|
|
data := make([]byte, n)
|
2017-06-13 16:20:35 +03:00
|
|
|
fmt.Printf("r %d\n", n)
|
2017-06-13 01:52:07 +03:00
|
|
|
if err := binary.Read(c, binary.BigEndian, &data); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
buf.Write(data)
|
|
|
|
defer buf.Reset()
|
2017-06-13 16:20:35 +03:00
|
|
|
fmt.Printf("r %v\n", buf.Bytes())
|
2017-06-13 01:52:07 +03:00
|
|
|
colors := make([]Color, rect.Area())
|
|
|
|
for y := uint16(0); y < rect.Height; y++ {
|
|
|
|
for x := uint16(0); x < rect.Width; x++ {
|
|
|
|
color := NewColor(pf, cm)
|
|
|
|
if err := color.Unmarshal(buf.Next(bytesPerPixel)); err != nil {
|
|
|
|
return err
|
2017-06-12 14:11:23 +03:00
|
|
|
}
|
2017-06-13 01:52:07 +03:00
|
|
|
colors[int(y)*int(rect.Width)+int(x)] = *color
|
2017-06-12 14:11:23 +03:00
|
|
|
}
|
2017-06-13 01:52:07 +03:00
|
|
|
}
|
2017-06-12 14:11:23 +03:00
|
|
|
|
2017-06-13 01:52:07 +03:00
|
|
|
enc.Colors = colors
|
2017-06-12 14:11:23 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (*RawEncoding) Type() EncodingType { return EncRaw }
|
|
|
|
|
|
|
|
// DesktopSizePseudoEncoding represents a desktop size message from the server.
|
|
|
|
type DesktopSizePseudoEncoding struct{}
|
|
|
|
|
2017-06-13 16:20:35 +03:00
|
|
|
func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePseudo }
|
|
|
|
|
2017-06-12 14:11:23 +03:00
|
|
|
// Read implements the Encoding interface.
|
|
|
|
func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
|
|
|
c.SetWidth(rect.Width)
|
|
|
|
c.SetHeight(rect.Height)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-13 16:20:35 +03:00
|
|
|
func (enc *DesktopSizePseudoEncoding) Write(c Conn, rect *Rectangle) error {
|
2017-06-12 14:11:23 +03:00
|
|
|
return nil
|
|
|
|
}
|