complete tight png
Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
parent
49c704bc67
commit
1413d28267
292
encoding.go
292
encoding.go
@ -4,6 +4,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
"image/png"
|
||||||
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EncodingType represents a known VNC encoding type.
|
// EncodingType represents a known VNC encoding type.
|
||||||
@ -24,26 +29,292 @@ const (
|
|||||||
EncUltra2 EncodingType = 10
|
EncUltra2 EncodingType = 10
|
||||||
EncJPEG EncodingType = 21
|
EncJPEG EncodingType = 21
|
||||||
EncJRLE EncodingType = 22
|
EncJRLE EncodingType = 22
|
||||||
//EncRichCursor EncodingType = 0xFFFFFF11
|
|
||||||
//EncPointerPos EncodingType = 0xFFFFFF18
|
|
||||||
//EncLastRec EncodingType = 0xFFFFFF20
|
|
||||||
EncTRLE EncodingType = 15
|
EncTRLE EncodingType = 15
|
||||||
EncZRLE EncodingType = 16
|
EncZRLE EncodingType = 16
|
||||||
|
EncJPEGQualityLevelPseudo10 EncodingType = -23
|
||||||
|
EncJPEGQualityLevelPseudo9 EncodingType = -24
|
||||||
|
EncJPEGQualityLevelPseudo8 EncodingType = -25
|
||||||
|
EncJPEGQualityLevelPseudo7 EncodingType = -26
|
||||||
|
EncJPEGQualityLevelPseudo6 EncodingType = -27
|
||||||
|
EncJPEGQualityLevelPseudo5 EncodingType = -28
|
||||||
|
EncJPEGQualityLevelPseudo4 EncodingType = -29
|
||||||
|
EncJPEGQualityLevelPseudo3 EncodingType = -30
|
||||||
|
EncJPEGQualityLevelPseudo2 EncodingType = -31
|
||||||
|
EncJPEGQualityLevelPseudo1 EncodingType = -32
|
||||||
EncColorPseudo EncodingType = -239
|
EncColorPseudo EncodingType = -239
|
||||||
EncDesktopSizePseudo EncodingType = -223
|
EncDesktopSizePseudo EncodingType = -223
|
||||||
|
EncLastRectPseudo EncodingType = -224
|
||||||
|
EncCompressionLevel10 EncodingType = -247
|
||||||
|
EncCompressionLevel9 EncodingType = -248
|
||||||
|
EncCompressionLevel8 EncodingType = -249
|
||||||
|
EncCompressionLevel7 EncodingType = -250
|
||||||
|
EncCompressionLevel6 EncodingType = -251
|
||||||
|
EncCompressionLevel5 EncodingType = -252
|
||||||
|
EncCompressionLevel4 EncodingType = -253
|
||||||
|
EncCompressionLevel3 EncodingType = -254
|
||||||
|
EncCompressionLevel2 EncodingType = -255
|
||||||
|
EncCompressionLevel1 EncodingType = -256
|
||||||
|
EncQEMUPointerMotionChangePseudo EncodingType = -257
|
||||||
|
EncQEMUExtendedKeyEventPseudo EncodingType = -258
|
||||||
|
EncTightPng EncodingType = -260
|
||||||
|
EncExtendedDesktopSizePseudo EncodingType = -308
|
||||||
|
EncXvpPseudo EncodingType = -309
|
||||||
|
EncFencePseudo EncodingType = -312
|
||||||
|
EncContinuousUpdatesPseudo EncodingType = -313
|
||||||
EncClientRedirect EncodingType = -311
|
EncClientRedirect EncodingType = -311
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:generate stringer -type=TightCompression
|
||||||
|
|
||||||
|
type TightCompression uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
TightCompressionBasic TightCompression = 0
|
||||||
|
TightCompressionFill TightCompression = 8
|
||||||
|
TightCompressionJPEG TightCompression = 9
|
||||||
|
TightCompressionPNG TightCompression = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate stringer -type=TightFilter
|
||||||
|
|
||||||
|
type TightFilter uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
TightFilterCopy TightFilter = 0
|
||||||
|
TightFilterPalette TightFilter = 1
|
||||||
|
TightFilterGradient TightFilter = 2
|
||||||
|
)
|
||||||
|
|
||||||
type Encoding interface {
|
type Encoding interface {
|
||||||
Type() EncodingType
|
Type() EncodingType
|
||||||
Read(Conn, *Rectangle) error
|
Read(Conn, *Rectangle) error
|
||||||
Write(Conn, *Rectangle) error
|
Write(Conn, *Rectangle) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CopyRectEncoding struct {
|
||||||
|
SX, SY uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (CopyRectEncoding) Type() EncodingType { return EncCopyRect }
|
||||||
|
|
||||||
|
func (enc *CopyRectEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &enc.SX); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &enc.SY); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *CopyRectEncoding) Write(c Conn, rect *Rectangle) error {
|
||||||
|
if err := binary.Write(c, binary.BigEndian, enc.SX); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := binary.Write(c, binary.BigEndian, enc.SY); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type RawEncoding struct {
|
type RawEncoding struct {
|
||||||
Colors []Color
|
Colors []Color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TightEncoding struct{}
|
||||||
|
|
||||||
|
func (*TightEncoding) Type() EncodingType { return EncTight }
|
||||||
|
|
||||||
|
func (enc *TightEncoding) Write(c Conn, rect *Rectangle) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *TightEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TightCC struct {
|
||||||
|
Compression TightCompression
|
||||||
|
Filter TightFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTightCC(c Conn) (*TightCC, error) {
|
||||||
|
var ccb uint8 // compression control byte
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &ccb); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cmp := TightCompression(ccb >> 4)
|
||||||
|
switch cmp {
|
||||||
|
case TightCompressionBasic:
|
||||||
|
return &TightCC{TightCompressionBasic, TightFilterCopy}, nil
|
||||||
|
case TightCompressionFill:
|
||||||
|
return &TightCC{TightCompressionFill, TightFilterCopy}, nil
|
||||||
|
case TightCompressionPNG:
|
||||||
|
return &TightCC{TightCompressionPNG, TightFilterCopy}, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unknown tight compression %d", cmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setBit(n uint8, pos uint8) uint8 {
|
||||||
|
n |= (1 << pos)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func clrBit(n uint8, pos uint8) uint8 {
|
||||||
|
n = n &^ (1 << pos)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasBit(n uint8, pos uint8) bool {
|
||||||
|
v := n & (1 << pos)
|
||||||
|
return (v > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBit(n uint8, pos uint8) uint8 {
|
||||||
|
n = n & (1 << pos)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeTightCC(c Conn, tcc *TightCC) error {
|
||||||
|
var ccb uint8 // compression control byte
|
||||||
|
switch tcc.Compression {
|
||||||
|
case TightCompressionFill:
|
||||||
|
ccb = setBit(ccb, 7)
|
||||||
|
case TightCompressionJPEG:
|
||||||
|
ccb = setBit(ccb, 7)
|
||||||
|
ccb = setBit(ccb, 4)
|
||||||
|
case TightCompressionPNG:
|
||||||
|
ccb = setBit(ccb, 7)
|
||||||
|
ccb = setBit(ccb, 5)
|
||||||
|
}
|
||||||
|
return binary.Write(c, binary.BigEndian, ccb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *TightPngEncoding) Write(c Conn, rect *Rectangle) error {
|
||||||
|
if err := writeTightCC(c, enc.TightCC); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmp := enc.TightCC.Compression
|
||||||
|
switch cmp {
|
||||||
|
case TightCompressionPNG:
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
if err := png.Encode(buf, enc.Image); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := writeTightLength(c, buf.Len()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := io.Copy(c, buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case TightCompressionFill:
|
||||||
|
var tpx TightPixel
|
||||||
|
r, g, b, _ := enc.Image.At(0, 0).RGBA()
|
||||||
|
tpx.R = uint8(r)
|
||||||
|
tpx.G = uint8(g)
|
||||||
|
tpx.B = uint8(b)
|
||||||
|
if err := binary.Write(c, binary.BigEndian, tpx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown tight compression %d", cmp)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TightPixel struct {
|
||||||
|
R uint8
|
||||||
|
G uint8
|
||||||
|
B uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type TightPngEncoding struct {
|
||||||
|
TightCC *TightCC
|
||||||
|
Image image.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*TightPngEncoding) Type() EncodingType { return EncTightPng }
|
||||||
|
|
||||||
|
func (enc *TightPngEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
|
tcc, err := readTightCC(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
enc.TightCC = tcc
|
||||||
|
cmp := enc.TightCC.Compression
|
||||||
|
switch cmp {
|
||||||
|
case TightCompressionPNG:
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
l, err := readTightLength(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.CopyN(buf, c, int64(l))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
enc.Image, err = png.Decode(buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case TightCompressionFill:
|
||||||
|
var tpx TightPixel
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &tpx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
enc.Image = image.NewRGBA(image.Rect(0, 0, 1, 1))
|
||||||
|
enc.Image.(draw.Image).Set(0, 0, color.RGBA{R: tpx.R, G: tpx.G, B: tpx.B, A: 1})
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown compression %d", cmp)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeTightLength(c Conn, l int) error {
|
||||||
|
var buf []uint8
|
||||||
|
|
||||||
|
buf = append(buf, uint8(l&0x7F))
|
||||||
|
if l > 0x7F {
|
||||||
|
buf[0] |= 0x80
|
||||||
|
buf = append(buf, uint8((l>>7)&0x7F))
|
||||||
|
if l > 0x3FFF {
|
||||||
|
buf[1] |= 0x80
|
||||||
|
buf = append(buf, uint8((l>>14)&0xFF))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return binary.Write(c, binary.BigEndian, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTightLength(c Conn) (int, error) {
|
||||||
|
var length int
|
||||||
|
var err error
|
||||||
|
var b uint8
|
||||||
|
|
||||||
|
if err = binary.Read(c, binary.BigEndian, &b); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
length = int(b) & 0x7F
|
||||||
|
if (b & 0x80) == 0 {
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = binary.Read(c, binary.BigEndian, &b); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
length |= (int(b) & 0x7F) << 7
|
||||||
|
if (b & 0x80) == 0 {
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = binary.Read(c, binary.BigEndian, &b); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
length |= (int(b) & 0xFF) << 14
|
||||||
|
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
|
func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
defer buf.Reset()
|
defer buf.Reset()
|
||||||
@ -58,16 +329,7 @@ func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
|
|||||||
if err := binary.Write(buf, binary.BigEndian, bytes); err != nil {
|
if err := binary.Write(buf, binary.BigEndian, bytes); err != nil {
|
||||||
return err
|
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())
|
_, err := c.Write(buf.Bytes())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -80,13 +342,11 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
bytesPerPixel := int(pf.BPP / 8)
|
bytesPerPixel := int(pf.BPP / 8)
|
||||||
n := rect.Area() * bytesPerPixel
|
n := rect.Area() * bytesPerPixel
|
||||||
data := make([]byte, n)
|
data := make([]byte, n)
|
||||||
fmt.Printf("r %d\n", n)
|
|
||||||
if err := binary.Read(c, binary.BigEndian, &data); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buf.Write(data)
|
buf.Write(data)
|
||||||
defer buf.Reset()
|
defer buf.Reset()
|
||||||
fmt.Printf("r %v\n", buf.Bytes())
|
|
||||||
colors := make([]Color, rect.Area())
|
colors := make([]Color, rect.Area())
|
||||||
for y := uint16(0); y < rect.Height; y++ {
|
for y := uint16(0); y < rect.Height; y++ {
|
||||||
for x := uint16(0); x < rect.Width; x++ {
|
for x := uint16(0); x < rect.Width; x++ {
|
||||||
@ -105,7 +365,8 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
func (*RawEncoding) Type() EncodingType { return EncRaw }
|
func (*RawEncoding) Type() EncodingType { return EncRaw }
|
||||||
|
|
||||||
// DesktopSizePseudoEncoding represents a desktop size message from the server.
|
// DesktopSizePseudoEncoding represents a desktop size message from the server.
|
||||||
type DesktopSizePseudoEncoding struct{}
|
type DesktopSizePseudoEncoding struct {
|
||||||
|
}
|
||||||
|
|
||||||
func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePseudo }
|
func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePseudo }
|
||||||
|
|
||||||
@ -113,7 +374,6 @@ func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePse
|
|||||||
func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
c.SetWidth(rect.Width)
|
c.SetWidth(rect.Width)
|
||||||
c.SetHeight(rect.Height)
|
c.SetHeight(rect.Height)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,46 +4,59 @@ package vnc
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const (
|
const _EncodingType_name = "EncContinuousUpdatesPseudoEncFencePseudoEncClientRedirectEncXvpPseudoEncExtendedDesktopSizePseudoEncTightPngEncQEMUExtendedKeyEventPseudoEncQEMUPointerMotionChangePseudoEncCompressionLevel1EncCompressionLevel2EncCompressionLevel3EncCompressionLevel4EncCompressionLevel5EncCompressionLevel6EncCompressionLevel7EncCompressionLevel8EncCompressionLevel9EncCompressionLevel10EncColorPseudoEncLastRectPseudoEncDesktopSizePseudoEncJPEGQualityLevelPseudo1EncJPEGQualityLevelPseudo2EncJPEGQualityLevelPseudo3EncJPEGQualityLevelPseudo4EncJPEGQualityLevelPseudo5EncJPEGQualityLevelPseudo6EncJPEGQualityLevelPseudo7EncJPEGQualityLevelPseudo8EncJPEGQualityLevelPseudo9EncJPEGQualityLevelPseudo10EncRawEncCopyRectEncRREEncCoRREEncHextileEncZlibEncTightEncZlibHexEncUltra1EncUltra2EncTRLEEncZRLEEncJPEGEncJRLE"
|
||||||
_EncodingType_name_0 = "EncClientRedirect"
|
|
||||||
_EncodingType_name_1 = "EncColorPseudo"
|
|
||||||
_EncodingType_name_2 = "EncDesktopSizePseudo"
|
|
||||||
_EncodingType_name_3 = "EncRawEncCopyRectEncRRE"
|
|
||||||
_EncodingType_name_4 = "EncCoRREEncHextileEncZlibEncTightEncZlibHexEncUltra1EncUltra2"
|
|
||||||
_EncodingType_name_5 = "EncTRLEEncZRLE"
|
|
||||||
_EncodingType_name_6 = "EncJPEGEncJRLE"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var _EncodingType_map = map[EncodingType]string{
|
||||||
_EncodingType_index_0 = [...]uint8{0, 17}
|
-313: _EncodingType_name[0:26],
|
||||||
_EncodingType_index_1 = [...]uint8{0, 14}
|
-312: _EncodingType_name[26:40],
|
||||||
_EncodingType_index_2 = [...]uint8{0, 20}
|
-311: _EncodingType_name[40:57],
|
||||||
_EncodingType_index_3 = [...]uint8{0, 6, 17, 23}
|
-309: _EncodingType_name[57:69],
|
||||||
_EncodingType_index_4 = [...]uint8{0, 8, 18, 25, 33, 43, 52, 61}
|
-308: _EncodingType_name[69:97],
|
||||||
_EncodingType_index_5 = [...]uint8{0, 7, 14}
|
-260: _EncodingType_name[97:108],
|
||||||
_EncodingType_index_6 = [...]uint8{0, 7, 14}
|
-258: _EncodingType_name[108:137],
|
||||||
)
|
-257: _EncodingType_name[137:169],
|
||||||
|
-256: _EncodingType_name[169:189],
|
||||||
|
-255: _EncodingType_name[189:209],
|
||||||
|
-254: _EncodingType_name[209:229],
|
||||||
|
-253: _EncodingType_name[229:249],
|
||||||
|
-252: _EncodingType_name[249:269],
|
||||||
|
-251: _EncodingType_name[269:289],
|
||||||
|
-250: _EncodingType_name[289:309],
|
||||||
|
-249: _EncodingType_name[309:329],
|
||||||
|
-248: _EncodingType_name[329:349],
|
||||||
|
-247: _EncodingType_name[349:370],
|
||||||
|
-239: _EncodingType_name[370:384],
|
||||||
|
-224: _EncodingType_name[384:401],
|
||||||
|
-223: _EncodingType_name[401:421],
|
||||||
|
-32: _EncodingType_name[421:447],
|
||||||
|
-31: _EncodingType_name[447:473],
|
||||||
|
-30: _EncodingType_name[473:499],
|
||||||
|
-29: _EncodingType_name[499:525],
|
||||||
|
-28: _EncodingType_name[525:551],
|
||||||
|
-27: _EncodingType_name[551:577],
|
||||||
|
-26: _EncodingType_name[577:603],
|
||||||
|
-25: _EncodingType_name[603:629],
|
||||||
|
-24: _EncodingType_name[629:655],
|
||||||
|
-23: _EncodingType_name[655:682],
|
||||||
|
0: _EncodingType_name[682:688],
|
||||||
|
1: _EncodingType_name[688:699],
|
||||||
|
2: _EncodingType_name[699:705],
|
||||||
|
4: _EncodingType_name[705:713],
|
||||||
|
5: _EncodingType_name[713:723],
|
||||||
|
6: _EncodingType_name[723:730],
|
||||||
|
7: _EncodingType_name[730:738],
|
||||||
|
8: _EncodingType_name[738:748],
|
||||||
|
9: _EncodingType_name[748:757],
|
||||||
|
10: _EncodingType_name[757:766],
|
||||||
|
15: _EncodingType_name[766:773],
|
||||||
|
16: _EncodingType_name[773:780],
|
||||||
|
21: _EncodingType_name[780:787],
|
||||||
|
22: _EncodingType_name[787:794],
|
||||||
|
}
|
||||||
|
|
||||||
func (i EncodingType) String() string {
|
func (i EncodingType) String() string {
|
||||||
switch {
|
if str, ok := _EncodingType_map[i]; ok {
|
||||||
case i == -311:
|
return str
|
||||||
return _EncodingType_name_0
|
|
||||||
case i == -239:
|
|
||||||
return _EncodingType_name_1
|
|
||||||
case i == -223:
|
|
||||||
return _EncodingType_name_2
|
|
||||||
case 0 <= i && i <= 2:
|
|
||||||
return _EncodingType_name_3[_EncodingType_index_3[i]:_EncodingType_index_3[i+1]]
|
|
||||||
case 4 <= i && i <= 10:
|
|
||||||
i -= 4
|
|
||||||
return _EncodingType_name_4[_EncodingType_index_4[i]:_EncodingType_index_4[i+1]]
|
|
||||||
case 15 <= i && i <= 16:
|
|
||||||
i -= 15
|
|
||||||
return _EncodingType_name_5[_EncodingType_index_5[i]:_EncodingType_index_5[i+1]]
|
|
||||||
case 21 <= i && i <= 22:
|
|
||||||
i -= 21
|
|
||||||
return _EncodingType_name_6[_EncodingType_index_6[i]:_EncodingType_index_6[i+1]]
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("EncodingType(%d)", i)
|
|
||||||
}
|
}
|
||||||
|
return fmt.Sprintf("EncodingType(%d)", i)
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,17 @@ func main() {
|
|||||||
Height: 600,
|
Height: 600,
|
||||||
VersionHandler: vnc.ServerVersionHandler,
|
VersionHandler: vnc.ServerVersionHandler,
|
||||||
SecurityHandler: vnc.ServerSecurityHandler,
|
SecurityHandler: vnc.ServerSecurityHandler,
|
||||||
SecurityHandlers: []vnc.SecurityHandler{&vnc.ClientAuthNone{}},
|
SecurityHandlers: []vnc.SecurityHandler{
|
||||||
|
&vnc.ClientAuthVeNCrypt02Plain{Username: []byte("test"), Password: []byte("test")},
|
||||||
|
&vnc.ClientAuthNone{},
|
||||||
|
},
|
||||||
ClientInitHandler: vnc.ServerClientInitHandler,
|
ClientInitHandler: vnc.ServerClientInitHandler,
|
||||||
ServerInitHandler: vnc.ServerServerInitHandler,
|
ServerInitHandler: vnc.ServerServerInitHandler,
|
||||||
Encodings: []vnc.Encoding{&vnc.RawEncoding{}},
|
Encodings: []vnc.Encoding{
|
||||||
|
&vnc.TightPngEncoding{},
|
||||||
|
&vnc.CopyRectEncoding{},
|
||||||
|
&vnc.RawEncoding{},
|
||||||
|
},
|
||||||
PixelFormat: vnc.PixelFormat32bit,
|
PixelFormat: vnc.PixelFormat32bit,
|
||||||
ClientMessageCh: schClient,
|
ClientMessageCh: schClient,
|
||||||
ServerMessageCh: schServer,
|
ServerMessageCh: schServer,
|
||||||
@ -57,9 +64,9 @@ func main() {
|
|||||||
log.Fatalf("Error dial. %v", err)
|
log.Fatalf("Error dial. %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
scfg.Width = cc.Width()
|
// scfg.Width = cc.Width()
|
||||||
scfg.Height = cc.Height()
|
// scfg.Height = cc.Height()
|
||||||
scfg.PixelFormat = cc.PixelFormat()
|
// scfg.PixelFormat = cc.PixelFormat()
|
||||||
go vnc.Serve(context.Background(), ln, scfg)
|
go vnc.Serve(context.Background(), ln, scfg)
|
||||||
|
|
||||||
defer cc.Close()
|
defer cc.Close()
|
||||||
@ -75,28 +82,28 @@ func main() {
|
|||||||
case msg := <-schClient:
|
case msg := <-schClient:
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
case vnc.SetEncodingsMsgType:
|
case vnc.SetEncodingsMsgType:
|
||||||
msg0 := &vnc.SetPixelFormat{
|
var encTypes []vnc.EncodingType
|
||||||
PF: *vnc.PixelFormat32bit,
|
for _, enc := range scfg.Encodings {
|
||||||
|
encTypes = append(encTypes, enc.Type())
|
||||||
|
}
|
||||||
|
msg0 := &vnc.SetEncodings{
|
||||||
|
Encodings: encTypes,
|
||||||
}
|
}
|
||||||
cchClient <- msg0
|
cchClient <- msg0
|
||||||
|
|
||||||
encRaw := &vnc.RawEncoding{}
|
|
||||||
msg1 := &vnc.SetEncodings{
|
|
||||||
Encodings: []vnc.EncodingType{encRaw.Type()},
|
|
||||||
}
|
|
||||||
cchClient <- msg1
|
|
||||||
/*
|
/*
|
||||||
msg2 := &vnc.FramebufferUpdateRequest{
|
if scfg.Width != cc.Width() || scfg.Height != cc.Height() {
|
||||||
Inc: 0,
|
msg1 := &vnc.FramebufferUpdate{
|
||||||
X: 0,
|
Rects: []*vnc.Rectangle{&vnc.Rectangle{
|
||||||
Y: 0,
|
|
||||||
Width: cc.Width(),
|
Width: cc.Width(),
|
||||||
Height: cc.Height(),
|
Height: cc.Height(),
|
||||||
|
EncType: vnc.EncDesktopSizePseudo,
|
||||||
|
Enc: &vnc.DesktopSizePseudoEncoding{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
schServer <- msg1
|
||||||
}
|
}
|
||||||
cchClient <- msg2
|
|
||||||
*/
|
*/
|
||||||
case vnc.SetPixelFormatMsgType:
|
|
||||||
cchClient <- msg
|
|
||||||
default:
|
default:
|
||||||
cchClient <- msg
|
cchClient <- msg
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,9 @@ func ServerSecurityHandler(cfg *ServerConfig, c Conn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil {
|
if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := c.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return authErr
|
return authErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
image.go
10
image.go
@ -115,7 +115,6 @@ func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 {
|
|||||||
// Marshal implements the Marshaler interface.
|
// Marshal implements the Marshaler interface.
|
||||||
func (r *Rectangle) Write(c Conn) error {
|
func (r *Rectangle) Write(c Conn) error {
|
||||||
var err error
|
var err error
|
||||||
fmt.Printf("w rect %#+v\n", r)
|
|
||||||
if err = binary.Write(c, binary.BigEndian, r.X); err != nil {
|
if err = binary.Write(c, binary.BigEndian, r.X); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -157,10 +156,17 @@ func (r *Rectangle) Read(c Conn) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
switch r.EncType {
|
switch r.EncType {
|
||||||
|
case EncCopyRect:
|
||||||
|
r.Enc = &CopyRectEncoding{}
|
||||||
|
case EncTight:
|
||||||
|
r.Enc = &TightEncoding{}
|
||||||
|
case EncTightPng:
|
||||||
|
r.Enc = &TightPngEncoding{}
|
||||||
case EncRaw:
|
case EncRaw:
|
||||||
r.Enc = &RawEncoding{}
|
r.Enc = &RawEncoding{}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported encoding %s", r.EncType)
|
||||||
}
|
}
|
||||||
fmt.Printf("r rect %#+v\n", r)
|
|
||||||
return r.Enc.Read(c, r)
|
return r.Enc.Read(c, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
73
security.go
73
security.go
@ -1,6 +1,7 @@
|
|||||||
package vnc
|
package vnc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/des"
|
"crypto/des"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -74,6 +75,10 @@ func (*ServerAuthNone) Auth(c Conn) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ClientAuthVeNCrypt02Plain) Type() SecurityType {
|
||||||
|
return SecTypeVeNCrypt
|
||||||
|
}
|
||||||
|
|
||||||
func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType {
|
func (*ClientAuthVeNCrypt02Plain) SubType() SecuritySubType {
|
||||||
return SecSubTypeVeNCrypt02Plain
|
return SecSubTypeVeNCrypt02Plain
|
||||||
}
|
}
|
||||||
@ -85,10 +90,52 @@ type ClientAuthVeNCrypt02Plain struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (auth *ClientAuthVeNCrypt02Plain) Auth(c Conn) error {
|
func (auth *ClientAuthVeNCrypt02Plain) Auth(c Conn) error {
|
||||||
|
if err := binary.Write(c, binary.BigEndian, []uint8{0, 2}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := c.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
major, minor uint8
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &major); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &minor); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res := uint8(1)
|
||||||
|
if major == 0 && minor == 2 {
|
||||||
|
res = uint8(0)
|
||||||
|
}
|
||||||
|
if err := binary.Write(c, binary.BigEndian, res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.Flush()
|
||||||
|
if err := binary.Write(c, binary.BigEndian, uint8(1)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := binary.Write(c, binary.BigEndian, auth.SubType()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := c.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var secType SecuritySubType
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &secType); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if secType != auth.SubType() {
|
||||||
|
binary.Write(c, binary.BigEndian, uint8(1))
|
||||||
|
c.Flush()
|
||||||
|
return fmt.Errorf("invalid sectype")
|
||||||
|
}
|
||||||
if len(auth.Password) == 0 || len(auth.Username) == 0 {
|
if len(auth.Password) == 0 || len(auth.Username) == 0 {
|
||||||
return fmt.Errorf("Security Handshake failed; no username and/or password provided for VeNCryptAuth.")
|
return fmt.Errorf("Security Handshake failed; no username and/or password provided for VeNCryptAuth.")
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Username))); err != nil {
|
if err := binary.Write(c, binary.BigEndian, uint32(len(auth.Username))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -104,8 +151,30 @@ func (auth *ClientAuthVeNCrypt02Plain) Auth(c Conn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, auth.Password); err != nil {
|
if err := binary.Write(c, binary.BigEndian, auth.Password); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
var (
|
||||||
|
uLength, pLength uint32
|
||||||
|
)
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &uLength); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &pLength); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return c.Flush()
|
username := make([]byte, uLength)
|
||||||
|
password := make([]byte, pLength)
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &username); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := binary.Read(c, binary.BigEndian, &password); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !bytes.Equal(auth.Username, username) || !bytes.Equal(auth.Password, password) {
|
||||||
|
return fmt.Errorf("invalid username/password")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerAuthVNC is the standard password authentication. See 7.2.2.
|
// ServerAuthVNC is the standard password authentication. See 7.2.2.
|
||||||
|
@ -156,7 +156,6 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
|
|||||||
if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fmt.Printf("%#+v\n", msg)
|
|
||||||
for i := uint16(0); i < msg.NumRect; i++ {
|
for i := uint16(0); i < msg.NumRect; i++ {
|
||||||
rect := &Rectangle{}
|
rect := &Rectangle{}
|
||||||
if err := rect.Read(c); err != nil {
|
if err := rect.Read(c); err != nil {
|
||||||
@ -164,15 +163,10 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
|
|||||||
}
|
}
|
||||||
msg.Rects = append(msg.Rects, rect)
|
msg.Rects = append(msg.Rects, rect)
|
||||||
}
|
}
|
||||||
fmt.Printf("r fb %d %d %v\n", msg.NumRect, uint16(len(msg.Rects)), msg.Rects)
|
|
||||||
if msg.NumRect != uint16(len(msg.Rects)) {
|
|
||||||
panic("rects not equal")
|
|
||||||
}
|
|
||||||
return &msg, nil
|
return &msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *FramebufferUpdate) Write(c Conn) error {
|
func (msg *FramebufferUpdate) Write(c Conn) error {
|
||||||
fmt.Printf("w fb %d %d %v\n", msg.NumRect, uint16(len(msg.Rects)), msg.Rects)
|
|
||||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -341,14 +335,12 @@ func (c *ServerConn) Handle() error {
|
|||||||
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &messageType); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("srv r %s\n", messageType)
|
|
||||||
msg, ok := clientMessages[messageType]
|
msg, ok := clientMessages[messageType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unsupported message-type: %v", messageType)
|
return fmt.Errorf("unsupported message-type: %v", messageType)
|
||||||
|
|
||||||
}
|
}
|
||||||
parsedMsg, err := msg.Read(c)
|
parsedMsg, err := msg.Read(c)
|
||||||
fmt.Printf("srv r %#+v\n", parsedMsg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("srv err %s\n", err.Error())
|
fmt.Printf("srv err %s\n", err.Error())
|
||||||
return err
|
return err
|
||||||
|
27
tightcompression_string.go
Normal file
27
tightcompression_string.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Code generated by "stringer -type=TightCompression"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package vnc
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const (
|
||||||
|
_TightCompression_name_0 = "TightCompressionBasic"
|
||||||
|
_TightCompression_name_1 = "TightCompressionFillTightCompressionJPEGTightCompressionPNG"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_TightCompression_index_0 = [...]uint8{0, 21}
|
||||||
|
_TightCompression_index_1 = [...]uint8{0, 20, 40, 59}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i TightCompression) String() string {
|
||||||
|
switch {
|
||||||
|
case i == 0:
|
||||||
|
return _TightCompression_name_0
|
||||||
|
case 8 <= i && i <= 10:
|
||||||
|
i -= 8
|
||||||
|
return _TightCompression_name_1[_TightCompression_index_1[i]:_TightCompression_index_1[i+1]]
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("TightCompression(%d)", i)
|
||||||
|
}
|
||||||
|
}
|
16
tightfilter_string.go
Normal file
16
tightfilter_string.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Code generated by "stringer -type=TightFilter"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package vnc
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _TightFilter_name = "TightFilterCopyTightFilterPaletteTightFilterGradient"
|
||||||
|
|
||||||
|
var _TightFilter_index = [...]uint8{0, 15, 33, 52}
|
||||||
|
|
||||||
|
func (i TightFilter) String() string {
|
||||||
|
if i >= TightFilter(len(_TightFilter_index)-1) {
|
||||||
|
return fmt.Sprintf("TightFilter(%d)", i)
|
||||||
|
}
|
||||||
|
return _TightFilter_name[_TightFilter_index[i]:_TightFilter_index[i+1]]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user