diff --git a/.idea/libraries/GOPATH__vncproxy_.xml b/.idea/libraries/GOPATH__vncproxy_.xml
index 60c50f4..d56667c 100644
--- a/.idea/libraries/GOPATH__vncproxy_.xml
+++ b/.idea/libraries/GOPATH__vncproxy_.xml
@@ -3,23 +3,37 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index aeb2b94..009d106 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 6564d52..94a25f7 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index b708980..93de0cb 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,7 +1,39 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -18,63 +50,46 @@
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
-
-
+
+
-
-
+
+
@@ -90,11 +105,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -103,18 +160,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -122,6 +169,19 @@
+
+
+ Read
+ .Read
+ .read
+ server
+ uint8
+ TightMinToCompress
+
+
+
+
+
-
-
-
-
+
+
+
+
+
@@ -163,13 +228,120 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -232,51 +404,24 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
@@ -534,7 +679,7 @@
-
+
@@ -735,9 +880,9 @@
-
-
-
+
+
+
@@ -784,11 +929,16 @@
+
+
+
+
+
-
+
@@ -800,38 +950,38 @@
-
-
+
-
-
+
-
+
-
+
+
-
+
+
@@ -855,53 +1005,45 @@
file://$PROJECT_DIR$/main.go
11
-
file://$PROJECT_DIR$/vnc/enc-tight.go
76
-
file://$PROJECT_DIR$/vnc/enc-tight.go
98
-
file://$PROJECT_DIR$/vnc/enc-tight.go
103
-
file://$PROJECT_DIR$/vnc/enc-tight.go
- 155
-
+ 156
file://$PROJECT_DIR$/vnc/enc-tight.go
- 172
-
+ 173
file://$PROJECT_DIR$/vnc/enc-tight.go
- 177
-
+ 178
file://$PROJECT_DIR$/vnc/server_messages.go
78
-
-
+
@@ -910,16 +1052,54 @@
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -933,7 +1113,7 @@
-
+
@@ -946,16 +1126,7 @@
-
-
-
-
-
-
-
-
-
-
+
@@ -969,7 +1140,7 @@
-
+
@@ -982,16 +1153,7 @@
-
-
-
-
-
-
-
-
-
-
+
@@ -1013,21 +1175,12 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -1036,16 +1189,7 @@
-
-
-
-
-
-
-
-
-
-
+
@@ -1067,31 +1211,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -1113,21 +1239,12 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -1136,42 +1253,92 @@
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1188,42 +1355,38 @@
-
+
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
diff --git a/vnc/Logger.go b/common/Logger.go
similarity index 95%
rename from vnc/Logger.go
rename to common/Logger.go
index 389ee0b..069f906 100644
--- a/vnc/Logger.go
+++ b/common/Logger.go
@@ -1,4 +1,4 @@
-package vnc
+package common
type Logger interface {
Debug(v ...interface{})
diff --git a/common/encoding.go b/common/encoding.go
new file mode 100644
index 0000000..baab23c
--- /dev/null
+++ b/common/encoding.go
@@ -0,0 +1,28 @@
+package common
+
+import (
+ "io"
+)
+
+// An Encoding implements a method for encoding pixel data that is
+// sent by the server to the client.
+type Encoding interface {
+ // The number that uniquely identifies this encoding type.
+ Type() int32
+
+ // Read reads the contents of the encoded pixel data from the reader.
+ // This should return a new Encoding implementation that contains
+ // the proper data.
+ Read(*PixelFormat, *Rectangle, io.Reader) (Encoding, error)
+}
+
+const (
+ EncodingRaw = 0
+ EncodingCopyRect = 1
+ EncodingRRE = 2
+ EncodingCoRRE = 4
+ EncodingHextile = 5
+ EncodingZlib = 6
+ EncodingTight = 7
+ EncodingZRLE = 16
+)
diff --git a/common/readers.go b/common/readers.go
new file mode 100644
index 0000000..0f2212d
--- /dev/null
+++ b/common/readers.go
@@ -0,0 +1,111 @@
+// Package vnc implements a VNC client.
+//
+// References:
+// [PROTOCOL]: http://tools.ietf.org/html/rfc6143
+package common
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "io"
+)
+
+// type DataSource struct {
+// conn io.Reader
+// output io.Writer
+// passThrough bool
+// PixelFormat PixelFormat
+// }Color
+type RfbReader struct {
+ reader io.Reader
+ saveBytes bool
+ savedBuff bytes.Buffer
+}
+
+func (r *RfbReader) Read(p []byte) (n int, err error) {
+ readLen, err := r.reader.Read(p)
+ r.savedBuff.Write(p)
+ return readLen, err
+}
+func (r *RfbReader) SavedBuff() bytes.Buffer {
+ return r.savedBuff
+}
+
+type RfbReadHelper struct {
+ io.Reader
+}
+
+func (d *RfbReadHelper) ReadBytes(count int) ([]byte, error) {
+ buff := make([]byte, count)
+
+ _, err := io.ReadFull(d.Reader, buff)
+ if err != nil {
+ //if err := binary.Read(d.conn, binary.BigEndian, &buff); err != nil {
+ return nil, err
+ }
+ return buff, nil
+}
+
+func (d *RfbReadHelper) ReadUint8() (uint8, error) {
+ var myUint uint8
+ if err := binary.Read(d.Reader, binary.BigEndian, &myUint); err != nil {
+ return 0, err
+ }
+ //fmt.Printf("myUint=%d", myUint)
+ return myUint, nil
+}
+func (d *RfbReadHelper) ReadUint16() (uint16, error) {
+ var myUint uint16
+ if err := binary.Read(d.Reader, binary.BigEndian, &myUint); err != nil {
+ return 0, err
+ }
+ //fmt.Printf("myUint=%d", myUint)
+ return myUint, nil
+}
+func (d *RfbReadHelper) ReadUint32() (uint32, error) {
+ var myUint uint32
+ if err := binary.Read(d.Reader, binary.BigEndian, &myUint); err != nil {
+ return 0, err
+ }
+ //fmt.Printf("myUint=%d", myUint)
+ return myUint, nil
+}
+func (d *RfbReadHelper) ReadCompactLen() (int, error) {
+ var err error
+ part, err := d.ReadUint8()
+ //byteCount := 1
+ len := uint32(part & 0x7F)
+ if (part & 0x80) != 0 {
+ part, err = d.ReadUint8()
+ //byteCount++
+ len |= uint32(part&0x7F) << 7
+ if (part & 0x80) != 0 {
+ part, err = d.ReadUint8()
+ //byteCount++
+ len |= uint32(part&0xFF) << 14
+ }
+ }
+
+ // for i := 0; i < byteCount; i++{
+ // rec.writeByte(portion[i]);
+ // }
+
+ return int(len), err
+}
+
+var TightMinToCompress int = 12
+
+func (r *RfbReadHelper) ReadTightData(dataSize int) ([]byte, error) {
+ if int(dataSize) < TightMinToCompress {
+ return r.ReadBytes(int(dataSize))
+ }
+ zlibDataLen, err := r.ReadCompactLen()
+ fmt.Printf("compactlen=%d\n", zlibDataLen)
+ if err != nil {
+ return nil, err
+ }
+ //byte[] zlibData = new byte[zlibDataLen];
+ //rfb.readFully(zlibData);
+ return r.ReadBytes(zlibDataLen)
+}
diff --git a/vnc/rectangle.go b/common/rectangle.go
similarity index 73%
rename from vnc/rectangle.go
rename to common/rectangle.go
index 3211635..8125823 100644
--- a/vnc/rectangle.go
+++ b/common/rectangle.go
@@ -1,26 +1,34 @@
-package vnc
-
-// Rectangle represents a rectangle of pixel data.
-type Rectangle struct {
- X uint16
- Y uint16
- Width uint16
- Height uint16
- Enc Encoding
-}
-
-// PixelFormat describes the way a pixel is formatted for a VNC connection.
-//
-// See RFC 6143 Section 7.4 for information on each of the fields.
-type PixelFormat struct {
- BPP uint8
- Depth uint8
- BigEndian bool
- TrueColor bool
- RedMax uint16
- GreenMax uint16
- BlueMax uint16
- RedShift uint8
- GreenShift uint8
- BlueShift uint8
-}
+package common
+
+import (
+ "fmt"
+)
+
+// Rectangle represents a rectangle of pixel data.
+type Rectangle struct {
+ X uint16
+ Y uint16
+ Width uint16
+ Height uint16
+ Enc Encoding
+}
+
+func (r *Rectangle) String() string {
+ return fmt.Sprintf("(%d,%d) (width: %d, height: %d), Enc= %d", r.X, r.Y, r.Width, r.Height, r.Enc.Type())
+}
+
+// PixelFormat describes the way a pixel is formatted for a VNC connection.
+//
+// See RFC 6143 Section 7.4 for information on each of the fields.
+type PixelFormat struct {
+ BPP uint8
+ Depth uint8
+ BigEndian bool
+ TrueColor bool
+ RedMax uint16
+ GreenMax uint16
+ BlueMax uint16
+ RedShift uint8
+ GreenShift uint8
+ BlueShift uint8
+}
diff --git a/encodings/enc-copy-rect.go b/encodings/enc-copy-rect.go
new file mode 100644
index 0000000..4cef62f
--- /dev/null
+++ b/encodings/enc-copy-rect.go
@@ -0,0 +1,26 @@
+package encodings
+
+import (
+ "io"
+ "vncproxy/common"
+)
+
+type CopyRectEncoding struct {
+ //Colors []Color
+ copyRectSrcX uint16
+ copyRectSrcY uint16
+}
+
+func (z *CopyRectEncoding) Type() int32 {
+ return 1
+}
+func (z *CopyRectEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, r io.Reader) (common.Encoding, error) {
+ conn := common.RfbReadHelper{r}
+ //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
+ //bytesPerPixel := c.PixelFormat.BPP / 8
+ z.copyRectSrcX, _ = conn.ReadUint16()
+ z.copyRectSrcY, _ = conn.ReadUint16()
+ return z, nil
+}
+
+//////////
diff --git a/encodings/enc-corre.go b/encodings/enc-corre.go
new file mode 100644
index 0000000..6731691
--- /dev/null
+++ b/encodings/enc-corre.go
@@ -0,0 +1,48 @@
+package encodings
+
+import (
+ "io"
+ "vncproxy/common"
+)
+
+type CoRREEncoding struct {
+ //Colors []Color
+}
+
+func (z *CoRREEncoding) Type() int32 {
+ return 4
+}
+
+func (z *CoRREEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, r io.Reader) (common.Encoding, error) {
+ conn := common.RfbReadHelper{r}
+ bytesPerPixel := int(pixelFmt.BPP / 8)
+ numOfSubrectangles, _ := conn.ReadUint32()
+
+ //read whole rect background color
+ conn.ReadBytes(bytesPerPixel)
+
+ //read all individual rects (color=BPP + x=16b + y=16b + w=16b + h=16b)
+ _, err := conn.ReadBytes(int(numOfSubrectangles) * (bytesPerPixel + 4))
+
+ if err != nil {
+ return nil, err
+ }
+ return z, nil
+
+ //int nSubrects = rfb.readU32();
+
+ //byte[] bg_buf = new byte[bytesPerPixel];
+ //rfb.readFully(bytesPerPixel);
+ //Color pixel;
+ // if (bytesPixel == 1) {
+ // pixel = colors[bg_buf[0] & 0xFF];
+ // } else {
+ // pixel = new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF);
+ // }
+ // memGraphics.setColor(pixel);
+ // memGraphics.fillRect(x, y, w, h);
+
+ // byte[] buf = new byte[nSubrects * (bytesPixel + 4)];
+ // rfb.readFully(buf);
+
+}
diff --git a/vnc/enc-hextile.go b/encodings/enc-hextile.go
similarity index 77%
rename from vnc/enc-hextile.go
rename to encodings/enc-hextile.go
index b545126..9bb8d6c 100644
--- a/vnc/enc-hextile.go
+++ b/encodings/enc-hextile.go
@@ -1,81 +1,85 @@
-package vnc
-
-import "io"
-
-const (
- HextileRaw = 1
- HextileBackgroundSpecified = 2
- HextileForegroundSpecified = 4
- HextileAnySubrects = 8
- HextileSubrectsColoured = 16
-)
-
-type HextileEncoding struct {
- Colors []Color
-}
-
-func (z *HextileEncoding) Type() int32 {
- return 5
-}
-func (z *HextileEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encoding, error) {
- //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
- bytesPerPixel := int(conn.PixelFormat.BPP) / 8
- //buf := make([]byte, bytesPerPixel)
- for ty := rect.Y; ty < rect.Y+rect.Height; ty += 16 {
- th := 16
- if rect.Y+rect.Height-ty < 16 {
- th = int(rect.Y) + int(rect.Height) - int(ty)
- }
-
- for tx := rect.X; tx < rect.X+rect.Width; tx += 16 {
- tw := 16
- if rect.X+rect.Width-tx < 16 {
- tw = int(rect.X) + int(rect.Width) - int(tx)
- }
-
- //handle Hextile Subrect(tx, ty, tw, th):
- subencoding, err := conn.readUint8()
- //fmt.Printf("hextile reader tile: (%d,%d) subenc=%d\n", ty, tx, subencoding)
- if err != nil {
- //fmt.Printf("error in hextile reader: %v\n", err)
- return nil, err
- }
-
- if (subencoding & HextileRaw) != 0 {
- //ReadRawRect(c, rect, r)
- conn.readBytes(tw * th * bytesPerPixel)
- //fmt.Printf("hextile reader: HextileRaw\n")
- continue
- }
- if (subencoding & HextileBackgroundSpecified) != 0 {
- conn.readBytes(int(bytesPerPixel))
- }
- if (subencoding & HextileForegroundSpecified) != 0 {
- conn.readBytes(int(bytesPerPixel))
- }
- if (subencoding & HextileAnySubrects) == 0 {
- //fmt.Printf("hextile reader: no Subrects\n")
- continue
- }
- //fmt.Printf("hextile reader: handling Subrects\n")
- nSubrects, err := conn.readUint8()
- if err != nil {
- return nil, err
- }
- bufsize := int(nSubrects) * 2
- if (subencoding & HextileSubrectsColoured) != 0 {
- bufsize += int(nSubrects) * int(bytesPerPixel)
- }
- //byte[] buf = new byte[bufsize];
- conn.readBytes(bufsize)
- }
- }
-
- // len, _ := readUint32(c.c)
- // _, err := readBytes(c.c, int(len))
-
- // if err != nil {
- // return nil, err
- // }
- return z, nil
-}
+package encodings
+
+import (
+ "io"
+ "vncproxy/common"
+)
+
+const (
+ HextileRaw = 1
+ HextileBackgroundSpecified = 2
+ HextileForegroundSpecified = 4
+ HextileAnySubrects = 8
+ HextileSubrectsColoured = 16
+)
+
+type HextileEncoding struct {
+ //Colors []Color
+}
+
+func (z *HextileEncoding) Type() int32 {
+ return 5
+}
+func (z *HextileEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, r io.Reader) (common.Encoding, error) {
+ conn := common.RfbReadHelper{r}
+ //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
+ bytesPerPixel := int(pixelFmt.BPP) / 8
+ //buf := make([]byte, bytesPerPixel)
+ for ty := rect.Y; ty < rect.Y+rect.Height; ty += 16 {
+ th := 16
+ if rect.Y+rect.Height-ty < 16 {
+ th = int(rect.Y) + int(rect.Height) - int(ty)
+ }
+
+ for tx := rect.X; tx < rect.X+rect.Width; tx += 16 {
+ tw := 16
+ if rect.X+rect.Width-tx < 16 {
+ tw = int(rect.X) + int(rect.Width) - int(tx)
+ }
+
+ //handle Hextile Subrect(tx, ty, tw, th):
+ subencoding, err := conn.ReadUint8()
+ //fmt.Printf("hextile reader tile: (%d,%d) subenc=%d\n", ty, tx, subencoding)
+ if err != nil {
+ //fmt.Printf("error in hextile reader: %v\n", err)
+ return nil, err
+ }
+
+ if (subencoding & HextileRaw) != 0 {
+ //ReadRawRect(c, rect, r)
+ conn.ReadBytes(tw * th * bytesPerPixel)
+ //fmt.Printf("hextile reader: HextileRaw\n")
+ continue
+ }
+ if (subencoding & HextileBackgroundSpecified) != 0 {
+ conn.ReadBytes(int(bytesPerPixel))
+ }
+ if (subencoding & HextileForegroundSpecified) != 0 {
+ conn.ReadBytes(int(bytesPerPixel))
+ }
+ if (subencoding & HextileAnySubrects) == 0 {
+ //fmt.Printf("hextile reader: no Subrects\n")
+ continue
+ }
+ //fmt.Printf("hextile reader: handling Subrects\n")
+ nSubrects, err := conn.ReadUint8()
+ if err != nil {
+ return nil, err
+ }
+ bufsize := int(nSubrects) * 2
+ if (subencoding & HextileSubrectsColoured) != 0 {
+ bufsize += int(nSubrects) * int(bytesPerPixel)
+ }
+ //byte[] buf = new byte[bufsize];
+ conn.ReadBytes(bufsize)
+ }
+ }
+
+ // len, _ := readUint32(c.c)
+ // _, err := readBytes(c.c, int(len))
+
+ // if err != nil {
+ // return nil, err
+ // }
+ return z, nil
+}
diff --git a/vnc/enc-raw.go b/encodings/enc-raw.go
similarity index 75%
rename from vnc/enc-raw.go
rename to encodings/enc-raw.go
index dc67e8a..e810c28 100644
--- a/vnc/enc-raw.go
+++ b/encodings/enc-raw.go
@@ -1,24 +1,25 @@
-package vnc
+package encodings
-import "io"
+import (
+ "io"
+ "vncproxy/common"
+)
// RawEncoding is raw pixel data sent by the server.
//
// See RFC 6143 Section 7.7.1
type RawEncoding struct {
- Colors []Color
+ //Colors []Color
}
func (*RawEncoding) Type() int32 {
return 0
}
-
-
-func (*RawEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encoding, error) {
+func (*RawEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, r io.Reader) (common.Encoding, error) {
//conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
-
- bytesPerPixel := int(conn.PixelFormat.BPP / 8)
+ conn := common.RfbReadHelper{r}
+ bytesPerPixel := int(pixelFmt.BPP / 8)
//pixelBytes := make([]uint8, bytesPerPixel)
// var byteOrder binary.ByteOrder = binary.LittleEndian
@@ -26,11 +27,11 @@ func (*RawEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encodi
// byteOrder = binary.BigEndian
// }
- colors := make([]Color, int(rect.Height)*int(rect.Width))
+ //colors := make([]vnc.Color, int(rect.Height)*int(rect.Width))
for y := uint16(0); y < rect.Height; y++ {
for x := uint16(0); x < rect.Width; x++ {
- if _, err := conn.readBytes(bytesPerPixel); err != nil {
+ if _, err := conn.ReadBytes(bytesPerPixel); err != nil {
return nil, err
}
@@ -54,5 +55,5 @@ func (*RawEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encodi
}
}
- return &RawEncoding{colors}, nil
+ return &RawEncoding{}, nil
}
diff --git a/encodings/enc-rre.go b/encodings/enc-rre.go
new file mode 100644
index 0000000..7c501d5
--- /dev/null
+++ b/encodings/enc-rre.go
@@ -0,0 +1,28 @@
+package encodings
+
+import "io"
+import "vncproxy/common"
+
+type RREEncoding struct {
+ //Colors []Color
+}
+
+func (z *RREEncoding) Type() int32 {
+ return 2
+}
+func (z *RREEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, r io.Reader) (common.Encoding, error) {
+ conn := common.RfbReadHelper{r}
+ bytesPerPixel := int(pixelFmt.BPP / 8)
+ numOfSubrectangles, _ := conn.ReadUint32()
+
+ //read whole rect background color
+ conn.ReadBytes(bytesPerPixel)
+
+ //read all individual rects (color=BPP + x=16b + y=16b + w=16b + h=16b)
+ _, err := conn.ReadBytes(int(numOfSubrectangles) * (bytesPerPixel + 8))
+
+ if err != nil {
+ return nil, err
+ }
+ return z, nil
+}
diff --git a/vnc/enc-tight.go b/encodings/enc-tight.go
similarity index 85%
rename from vnc/enc-tight.go
rename to encodings/enc-tight.go
index d9346b1..4d43bdf 100644
--- a/vnc/enc-tight.go
+++ b/encodings/enc-tight.go
@@ -1,346 +1,334 @@
-package vnc
-
-import (
- "errors"
- "fmt"
- "io"
-)
-
-var TightMinToCompress int = 12
-
-const (
- TightExplicitFilter = 0x04
- TightFill = 0x08
- TightJpeg = 0x09
- TightMaxSubencoding = 0x09
- TightFilterCopy = 0x00
- TightFilterPalette = 0x01
- TightFilterGradient = 0x02
-)
-
-type TightEncoding struct {
- output io.Writer
- logger Logger
-}
-
-func (t *TightEncoding) SetOutput(output io.Writer) {
- t.output = output
-}
-
-func (*TightEncoding) Type() int32 {
- return 7
-}
-
-// func ReadAndRecBytes(conn io.Reader, rec io.Writer, count int) ([]byte, error) {
-// buf, err := readBytes(conn, count)
-// rec.Write(buf)
-// return buf, err
-// }
-// func ReadAndRecUint8(conn io.Reader, rec io.Writer) (uint8, error) {
-// myUint, err := readUint8(conn)
-// buf := make([]byte, 1)
-// buf[0] = byte(myUint) // cast int8 to byte
-// rec.Write(buf)
-// return myUint, err
-// }
-
-// func ReadAndRecUint16(conn io.Reader, rec io.Writer) (uint16, error) {
-// myUint, err := readUint16(conn)
-// buf := make([]byte, 2)
-// //buf[0] = byte(myUint) // cast int8 to byte
-// //var i int16 = 41
-// //b := make([]byte, 2)
-// binary.LittleEndian.PutUint16(buf, uint16(myUint))
-
-// rec.Write(buf)
-// return myUint, err
-// }
-
-func calcTightBytePerPixel(pf PixelFormat) int {
- bytesPerPixel := int(pf.BPP / 8)
-
- var bytesPerPixelTight int
- if 24 == pf.Depth && 32 == pf.BPP {
- bytesPerPixelTight = 3
- } else {
- bytesPerPixelTight = bytesPerPixel
- }
- return bytesPerPixelTight
-}
-
-func (t *TightEncoding) Read(conn *ClientConn, rect *Rectangle, reader io.Reader) (Encoding, error) {
- bytesPixel := calcTightBytePerPixel(conn.PixelFormat)
-
- //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
-
- //var subencoding uint8
- subencoding, err := conn.readUint8()
- if err != nil {
- fmt.Printf("error in handling tight encoding: %v\n", err)
- return nil, err
- }
- fmt.Printf("bytesPixel= %d, subencoding= %d\n", bytesPixel, subencoding)
- // if err := binary.Read(conn.c, binary.BigEndian, &subencoding); err != nil {
- // return t, err
- // }
-
- //move it to position (remove zlib flush commands)
- compType := subencoding >> 4 & 0x0F
- // for stream_id := 0; stream_id < 4; stream_id++ {
- // // if ((comp_ctl & 1) != 0 && tightInflaters[stream_id] != null) {
- // // tightInflaters[stream_id] = null;
- // // }
- // subencoding >>= 1
- // }
-
- fmt.Printf("afterSHL:%d\n", compType)
- switch compType {
- case TightFill:
- fmt.Printf("reading fill size=%d\n", bytesPixel)
- //read color
- conn.readBytes(int(bytesPixel))
- return t, nil
- case TightJpeg:
- if conn.PixelFormat.BPP == 8 {
- return nil, errors.New("Tight encoding: JPEG is not supported in 8 bpp mode")
- }
-
- len, err := conn.readCompactLen()
- if err != nil {
- return nil, err
- }
- fmt.Printf("reading jpeg size=%d\n", len)
- conn.readBytes(len)
- return t, nil
- default:
-
- if compType > TightJpeg {
- fmt.Println("Compression control byte is incorrect!")
- }
-
- handleTightFilters(subencoding, conn, rect, reader)
- return t, nil
- }
-}
-
-func handleTightFilters(subencoding uint8, conn *ClientConn, rect *Rectangle, reader io.Reader) {
- var FILTER_ID_MASK uint8 = 0x40
- //var STREAM_ID_MASK uint8 = 0x30
-
- //decoderId := (subencoding & STREAM_ID_MASK) >> 4
- var filterid uint8
- var err error
-
- if (subencoding & FILTER_ID_MASK) > 0 { // filter byte presence
- filterid, err = conn.readUint8()
- if err != nil {
- fmt.Printf("error in handling tight encoding, reading filterid: %v\n", err)
- return
- }
- fmt.Printf("read filter: %d\n", filterid)
- }
-
- //var numColors uint8
- bytesPixel := calcTightBytePerPixel(conn.PixelFormat)
-
- fmt.Printf("filter: %d\n", filterid)
- // if rfb.rec != null {
- // rfb.rec.writeByte(filter_id)
- // }
- lengthCurrentbpp := int(bytesPixel) * int(rect.Width) * int(rect.Height)
-
- switch filterid {
- case TightFilterPalette: //PALETTE_FILTER
-
- colorCount, err := conn.readUint8()
- paletteSize := colorCount + 1 // add one more
- fmt.Printf("----PALETTE_FILTER: paletteSize=%d bytesPixel=%d\n", paletteSize, bytesPixel)
- //complete palette
- conn.readBytes(int(paletteSize) * bytesPixel)
-
- var dataLength int
- if paletteSize == 2 {
- dataLength = int(rect.Height) * ((int(rect.Width) + 7) / 8)
- } else {
- dataLength = int(rect.Width * rect.Height)
- }
- _, err = readTightData(conn, dataLength)
- if err != nil {
- fmt.Printf("error in handling tight encoding, Reading Palette: %v\n", err)
- return
- }
- case TightFilterGradient: //GRADIENT_FILTER
- fmt.Printf("----GRADIENT_FILTER: bytesPixel=%d\n", bytesPixel)
- //useGradient = true
- fmt.Printf("usegrad: %d\n", filterid)
- readTightData(conn, lengthCurrentbpp)
- case TightFilterCopy: //BASIC_FILTER
- fmt.Printf("----BASIC_FILTER: bytesPixel=%d\n", bytesPixel)
- readTightData(conn, lengthCurrentbpp)
- default:
- fmt.Printf("Bad tight filter id: %d\n", filterid)
- return
- }
-
- ////////////
-
- // if numColors == 0 && bytesPixel == 4 {
- // rowSize1 *= 3
- // }
- // rowSize := (int(rect.Width)*bitsPixel + 7) / 8
- // dataSize := int(rect.Height) * rowSize
-
- // dataSize1 := rect.Height * rowSize1
- // fmt.Printf("datasize: %d, origDatasize: %d", dataSize, dataSize1)
- // // Read, optionally uncompress and decode data.
- // if int(dataSize1) < TightMinToCompress {
- // // Data size is small - not compressed with zlib.
- // if numColors != 0 {
- // // Indexed colors.
- // //indexedData := make([]byte, dataSize)
- // readBytes(conn.c, int(dataSize1))
- // //readFully(indexedData);
- // // if (rfb.rec != null) {
- // // rfb.rec.write(indexedData);
- // // }
- // // if (numColors == 2) {
- // // // Two colors.
- // // if (bytesPixel == 1) {
- // // decodeMonoData(x, y, w, h, indexedData, palette8);
- // // } else {
- // // decodeMonoData(x, y, w, h, indexedData, palette24);
- // // }
- // // } else {
- // // // 3..255 colors (assuming bytesPixel == 4).
- // // int i = 0;
- // // for (int dy = y; dy < y + h; dy++) {
- // // for (int dx = x; dx < x + w; dx++) {
- // // pixels24[dy * rfb.framebufferWidth + dx] = palette24[indexedData[i++] & 0xFF];
- // // }
- // // }
- // // }
- // } else if useGradient {
- // // "Gradient"-processed data
- // //buf := make ( []byte,w * h * 3);
- // dataByteCount := int(3) * int(rect.Width) * int(rect.Height)
- // readBytes(conn.c, dataByteCount)
- // // rfb.readFully(buf);
- // // if (rfb.rec != null) {
- // // rfb.rec.write(buf);
- // // }
- // // decodeGradientData(x, y, w, h, buf);
- // } else {
- // // Raw truecolor data.
- // dataByteCount := int(bytesPixel) * int(rect.Width) * int(rect.Height)
- // readBytes(conn.c, dataByteCount)
-
- // // if (bytesPixel == 1) {
- // // for (int dy = y; dy < y + h; dy++) {
-
- // // rfb.readFully(pixels8, dy * rfb.framebufferWidth + x, w);
- // // if (rfb.rec != null) {
- // // rfb.rec.write(pixels8, dy * rfb.framebufferWidth + x, w);
- // // }
- // // }
- // // } else {
- // // byte[] buf = new byte[w * 3];
- // // int i, offset;
- // // for (int dy = y; dy < y + h; dy++) {
- // // rfb.readFully(buf);
- // // if (rfb.rec != null) {
- // // rfb.rec.write(buf);
- // // }
- // // offset = dy * rfb.framebufferWidth + x;
- // // for (i = 0; i < w; i++) {
- // // pixels24[offset + i] = (buf[i * 3] & 0xFF) << 16 | (buf[i * 3 + 1] & 0xFF) << 8 | (buf[i * 3 + 2] & 0xFF);
- // // }
- // // }
- // // }
- // }
- // } else {
- // // Data was compressed with zlib.
- // zlibDataLen, err := readCompactLen(conn.c)
- // fmt.Printf("compactlen=%d\n", zlibDataLen)
- // if err != nil {
- // return nil, err
- // }
- // //byte[] zlibData = new byte[zlibDataLen];
- // //rfb.readFully(zlibData);
- // readBytes(conn.c, zlibDataLen)
-
- // // if (rfb.rec != null) {
- // // rfb.rec.write(zlibData);
- // // }
- // // int stream_id = comp_ctl & 0x03;
- // // if (tightInflaters[stream_id] == null) {
- // // tightInflaters[stream_id] = new Inflater();
- // // }
- // // Inflater myInflater = tightInflaters[stream_id];
- // // myInflater.setInput(zlibData);
- // // byte[] buf = new byte[dataSize];
- // // myInflater.inflate(buf);
- // // if (rfb.rec != null && !rfb.recordFromBeginning) {
- // // rfb.recordCompressedData(buf);
- // // }
-
- // // if (numColors != 0) {
- // // // Indexed colors.
- // // if (numColors == 2) {
- // // // Two colors.
- // // if (bytesPixel == 1) {
- // // decodeMonoData(x, y, w, h, buf, palette8);
- // // } else {
- // // decodeMonoData(x, y, w, h, buf, palette24);
- // // }
- // // } else {
- // // // More than two colors (assuming bytesPixel == 4).
- // // int i = 0;
- // // for (int dy = y; dy < y + h; dy++) {
- // // for (int dx = x; dx < x + w; dx++) {
- // // pixels24[dy * rfb.framebufferWidth + dx] = palette24[buf[i++] & 0xFF];
- // // }
- // // }
- // // }
- // // } else if (useGradient) {
- // // // Compressed "Gradient"-filtered data (assuming bytesPixel == 4).
- // // decodeGradientData(x, y, w, h, buf);
- // // } else {
- // // // Compressed truecolor data.
- // // if (bytesPixel == 1) {
- // // int destOffset = y * rfb.framebufferWidth + x;
- // // for (int dy = 0; dy < h; dy++) {
- // // System.arraycopy(buf, dy * w, pixels8, destOffset, w);
- // // destOffset += rfb.framebufferWidth;
- // // }
- // // } else {
- // // int srcOffset = 0;
- // // int destOffset, i;
- // // for (int dy = 0; dy < h; dy++) {
- // // myInflater.inflate(buf);
- // // destOffset = (y + dy) * rfb.framebufferWidth + x;
- // // for (i = 0; i < w; i++) {
- // // pixels24[destOffset + i] = (buf[srcOffset] & 0xFF) << 16 | (buf[srcOffset + 1] & 0xFF) << 8
- // // | (buf[srcOffset + 2] & 0xFF);
- // // srcOffset += 3;
- // // }
- // // }
- // // }
- // // }
- // }
-
- return
-}
-
-func readTightData(conn *ClientConn, dataSize int) ([]byte, error) {
- if int(dataSize) < TightMinToCompress {
- return conn.readBytes(int(dataSize))
- }
- zlibDataLen, err := conn.readCompactLen()
- fmt.Printf("compactlen=%d\n", zlibDataLen)
- if err != nil {
- return nil, err
- }
- //byte[] zlibData = new byte[zlibDataLen];
- //rfb.readFully(zlibData);
- return conn.readBytes(zlibDataLen)
-}
+package encodings
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "vncproxy/common"
+)
+
+var TightMinToCompress int = 12
+
+const (
+ TightExplicitFilter = 0x04
+ TightFill = 0x08
+ TightJpeg = 0x09
+ TightMaxSubencoding = 0x09
+ TightFilterCopy = 0x00
+ TightFilterPalette = 0x01
+ TightFilterGradient = 0x02
+)
+
+type TightEncoding struct {
+ output io.Writer
+ logger common.Logger
+}
+
+func (t *TightEncoding) SetOutput(output io.Writer) {
+ t.output = output
+}
+
+func (*TightEncoding) Type() int32 {
+ return 7
+}
+
+// func ReadAndRecBytes(conn io.Reader, rec io.Writer, count int) ([]byte, error) {
+// buf, err := readBytes(conn, count)
+// rec.Write(buf)
+// return buf, err
+// }
+// func ReadAndRecUint8(conn io.Reader, rec io.Writer) (uint8, error) {
+// myUint, err := readUint8(conn)
+// buf := make([]byte, 1)
+// buf[0] = byte(myUint) // cast int8 to byte
+// rec.Write(buf)
+// return myUint, err
+// }
+
+// func ReadAndRecUint16(conn io.Reader, rec io.Writer) (uint16, error) {
+// myUint, err := readUint16(conn)
+// buf := make([]byte, 2)
+// //buf[0] = byte(myUint) // cast int8 to byte
+// //var i int16 = 41
+// //b := make([]byte, 2)
+// binary.LittleEndian.PutUint16(buf, uint16(myUint))
+
+// rec.Write(buf)
+// return myUint, err
+// }
+
+func calcTightBytePerPixel(pf *common.PixelFormat) int {
+ bytesPerPixel := int(pf.BPP / 8)
+
+ var bytesPerPixelTight int
+ if 24 == pf.Depth && 32 == pf.BPP {
+ bytesPerPixelTight = 3
+ } else {
+ bytesPerPixelTight = bytesPerPixel
+ }
+ return bytesPerPixelTight
+}
+
+func (t *TightEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, reader io.Reader) (common.Encoding, error) {
+ bytesPixel := calcTightBytePerPixel(pixelFmt)
+ conn := common.RfbReadHelper{reader}
+ //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
+
+ //var subencoding uint8
+ subencoding, err := conn.ReadUint8()
+ if err != nil {
+ fmt.Printf("error in handling tight encoding: %v\n", err)
+ return nil, err
+ }
+ fmt.Printf("bytesPixel= %d, subencoding= %d\n", bytesPixel, subencoding)
+ // if err := binary.Read(conn.c, binary.BigEndian, &subencoding); err != nil {
+ // return t, err
+ // }
+
+ //move it to position (remove zlib flush commands)
+ compType := subencoding >> 4 & 0x0F
+ // for stream_id := 0; stream_id < 4; stream_id++ {
+ // // if ((comp_ctl & 1) != 0 && tightInflaters[stream_id] != null) {
+ // // tightInflaters[stream_id] = null;
+ // // }
+ // subencoding >>= 1
+ // }
+
+ fmt.Printf("afterSHL:%d\n", compType)
+ switch compType {
+ case TightFill:
+ fmt.Printf("reading fill size=%d\n", bytesPixel)
+ //read color
+ conn.ReadBytes(int(bytesPixel))
+ return t, nil
+ case TightJpeg:
+ if pixelFmt.BPP == 8 {
+ return nil, errors.New("Tight encoding: JPEG is not supported in 8 bpp mode")
+ }
+
+ len, err := conn.ReadCompactLen()
+ if err != nil {
+ return nil, err
+ }
+ fmt.Printf("reading jpeg size=%d\n", len)
+ conn.ReadBytes(len)
+ return t, nil
+ default:
+
+ if compType > TightJpeg {
+ fmt.Println("Compression control byte is incorrect!")
+ }
+
+ handleTightFilters(subencoding, pixelFmt, rect, reader)
+ return t, nil
+ }
+}
+
+func handleTightFilters(subencoding uint8, pixelFmt *common.PixelFormat, rect *common.Rectangle, reader io.Reader) {
+ conn := common.RfbReadHelper{reader}
+ var FILTER_ID_MASK uint8 = 0x40
+ //var STREAM_ID_MASK uint8 = 0x30
+
+ //decoderId := (subencoding & STREAM_ID_MASK) >> 4
+ var filterid uint8
+ var err error
+
+ if (subencoding & FILTER_ID_MASK) > 0 { // filter byte presence
+ filterid, err = conn.ReadUint8()
+ if err != nil {
+ fmt.Printf("error in handling tight encoding, reading filterid: %v\n", err)
+ return
+ }
+ fmt.Printf("read filter: %d\n", filterid)
+ }
+
+ //var numColors uint8
+ bytesPixel := calcTightBytePerPixel(pixelFmt)
+
+ fmt.Printf("filter: %d\n", filterid)
+ // if rfb.rec != null {
+ // rfb.rec.writeByte(filter_id)
+ // }
+ lengthCurrentbpp := int(bytesPixel) * int(rect.Width) * int(rect.Height)
+
+ switch filterid {
+ case TightFilterPalette: //PALETTE_FILTER
+
+ colorCount, err := conn.ReadUint8()
+ paletteSize := colorCount + 1 // add one more
+ fmt.Printf("----PALETTE_FILTER: paletteSize=%d bytesPixel=%d\n", paletteSize, bytesPixel)
+ //complete palette
+ conn.ReadBytes(int(paletteSize) * bytesPixel)
+
+ var dataLength int
+ if paletteSize == 2 {
+ dataLength = int(rect.Height) * ((int(rect.Width) + 7) / 8)
+ } else {
+ dataLength = int(rect.Width * rect.Height)
+ }
+ _, err = conn.ReadTightData(dataLength)
+ if err != nil {
+ fmt.Printf("error in handling tight encoding, Reading Palette: %v\n", err)
+ return
+ }
+ case TightFilterGradient: //GRADIENT_FILTER
+ fmt.Printf("----GRADIENT_FILTER: bytesPixel=%d\n", bytesPixel)
+ //useGradient = true
+ fmt.Printf("usegrad: %d\n", filterid)
+ conn.ReadTightData(lengthCurrentbpp)
+ case TightFilterCopy: //BASIC_FILTER
+ fmt.Printf("----BASIC_FILTER: bytesPixel=%d\n", bytesPixel)
+ conn.ReadTightData(lengthCurrentbpp)
+ default:
+ fmt.Printf("Bad tight filter id: %d\n", filterid)
+ return
+ }
+
+ ////////////
+
+ // if numColors == 0 && bytesPixel == 4 {
+ // rowSize1 *= 3
+ // }
+ // rowSize := (int(rect.Width)*bitsPixel + 7) / 8
+ // dataSize := int(rect.Height) * rowSize
+
+ // dataSize1 := rect.Height * rowSize1
+ // fmt.Printf("datasize: %d, origDatasize: %d", dataSize, dataSize1)
+ // // Read, optionally uncompress and decode data.
+ // if int(dataSize1) < TightMinToCompress {
+ // // Data size is small - not compressed with zlib.
+ // if numColors != 0 {
+ // // Indexed colors.
+ // //indexedData := make([]byte, dataSize)
+ // readBytes(conn.c, int(dataSize1))
+ // //readFully(indexedData);
+ // // if (rfb.rec != null) {
+ // // rfb.rec.write(indexedData);
+ // // }
+ // // if (numColors == 2) {
+ // // // Two colors.
+ // // if (bytesPixel == 1) {
+ // // decodeMonoData(x, y, w, h, indexedData, palette8);
+ // // } else {
+ // // decodeMonoData(x, y, w, h, indexedData, palette24);
+ // // }
+ // // } else {
+ // // // 3..255 colors (assuming bytesPixel == 4).
+ // // int i = 0;
+ // // for (int dy = y; dy < y + h; dy++) {
+ // // for (int dx = x; dx < x + w; dx++) {
+ // // pixels24[dy * rfb.framebufferWidth + dx] = palette24[indexedData[i++] & 0xFF];
+ // // }
+ // // }
+ // // }
+ // } else if useGradient {
+ // // "Gradient"-processed data
+ // //buf := make ( []byte,w * h * 3);
+ // dataByteCount := int(3) * int(rect.Width) * int(rect.Height)
+ // readBytes(conn.c, dataByteCount)
+ // // rfb.readFully(buf);
+ // // if (rfb.rec != null) {
+ // // rfb.rec.write(buf);
+ // // }
+ // // decodeGradientData(x, y, w, h, buf);
+ // } else {
+ // // Raw truecolor data.
+ // dataByteCount := int(bytesPixel) * int(rect.Width) * int(rect.Height)
+ // readBytes(conn.c, dataByteCount)
+
+ // // if (bytesPixel == 1) {
+ // // for (int dy = y; dy < y + h; dy++) {
+
+ // // rfb.readFully(pixels8, dy * rfb.framebufferWidth + x, w);
+ // // if (rfb.rec != null) {
+ // // rfb.rec.write(pixels8, dy * rfb.framebufferWidth + x, w);
+ // // }
+ // // }
+ // // } else {
+ // // byte[] buf = new byte[w * 3];
+ // // int i, offset;
+ // // for (int dy = y; dy < y + h; dy++) {
+ // // rfb.readFully(buf);
+ // // if (rfb.rec != null) {
+ // // rfb.rec.write(buf);
+ // // }
+ // // offset = dy * rfb.framebufferWidth + x;
+ // // for (i = 0; i < w; i++) {
+ // // pixels24[offset + i] = (buf[i * 3] & 0xFF) << 16 | (buf[i * 3 + 1] & 0xFF) << 8 | (buf[i * 3 + 2] & 0xFF);
+ // // }
+ // // }
+ // // }
+ // }
+ // } else {
+ // // Data was compressed with zlib.
+ // zlibDataLen, err := readCompactLen(conn.c)
+ // fmt.Printf("compactlen=%d\n", zlibDataLen)
+ // if err != nil {
+ // return nil, err
+ // }
+ // //byte[] zlibData = new byte[zlibDataLen];
+ // //rfb.readFully(zlibData);
+ // readBytes(conn.c, zlibDataLen)
+
+ // // if (rfb.rec != null) {
+ // // rfb.rec.write(zlibData);
+ // // }
+ // // int stream_id = comp_ctl & 0x03;
+ // // if (tightInflaters[stream_id] == null) {
+ // // tightInflaters[stream_id] = new Inflater();
+ // // }
+ // // Inflater myInflater = tightInflaters[stream_id];
+ // // myInflater.setInput(zlibData);
+ // // byte[] buf = new byte[dataSize];
+ // // myInflater.inflate(buf);
+ // // if (rfb.rec != null && !rfb.recordFromBeginning) {
+ // // rfb.recordCompressedData(buf);
+ // // }
+
+ // // if (numColors != 0) {
+ // // // Indexed colors.
+ // // if (numColors == 2) {
+ // // // Two colors.
+ // // if (bytesPixel == 1) {
+ // // decodeMonoData(x, y, w, h, buf, palette8);
+ // // } else {
+ // // decodeMonoData(x, y, w, h, buf, palette24);
+ // // }
+ // // } else {
+ // // // More than two colors (assuming bytesPixel == 4).
+ // // int i = 0;
+ // // for (int dy = y; dy < y + h; dy++) {
+ // // for (int dx = x; dx < x + w; dx++) {
+ // // pixels24[dy * rfb.framebufferWidth + dx] = palette24[buf[i++] & 0xFF];
+ // // }
+ // // }
+ // // }
+ // // } else if (useGradient) {
+ // // // Compressed "Gradient"-filtered data (assuming bytesPixel == 4).
+ // // decodeGradientData(x, y, w, h, buf);
+ // // } else {
+ // // // Compressed truecolor data.
+ // // if (bytesPixel == 1) {
+ // // int destOffset = y * rfb.framebufferWidth + x;
+ // // for (int dy = 0; dy < h; dy++) {
+ // // System.arraycopy(buf, dy * w, pixels8, destOffset, w);
+ // // destOffset += rfb.framebufferWidth;
+ // // }
+ // // } else {
+ // // int srcOffset = 0;
+ // // int destOffset, i;
+ // // for (int dy = 0; dy < h; dy++) {
+ // // myInflater.inflate(buf);
+ // // destOffset = (y + dy) * rfb.framebufferWidth + x;
+ // // for (i = 0; i < w; i++) {
+ // // pixels24[destOffset + i] = (buf[srcOffset] & 0xFF) << 16 | (buf[srcOffset + 1] & 0xFF) << 8
+ // // | (buf[srcOffset + 2] & 0xFF);
+ // // srcOffset += 3;
+ // // }
+ // // }
+ // // }
+ // // }
+ // }
+
+ return
+}
diff --git a/encodings/enc-zlib.go b/encodings/enc-zlib.go
new file mode 100644
index 0000000..3da39d1
--- /dev/null
+++ b/encodings/enc-zlib.go
@@ -0,0 +1,24 @@
+package encodings
+
+import "io"
+import "vncproxy/common"
+
+type ZLibEncoding struct {
+ //Colors []Color
+}
+
+func (z *ZLibEncoding) Type() int32 {
+ return 6
+}
+func (z *ZLibEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, r io.Reader) (common.Encoding, error) {
+ conn := common.RfbReadHelper{r}
+ //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
+ //bytesPerPixel := c.PixelFormat.BPP / 8
+ len, _ := conn.ReadUint32()
+ _, err := conn.ReadBytes(int(len))
+
+ if err != nil {
+ return nil, err
+ }
+ return z, nil
+}
diff --git a/encodings/enc-zrle.go b/encodings/enc-zrle.go
new file mode 100644
index 0000000..5059b7e
--- /dev/null
+++ b/encodings/enc-zrle.go
@@ -0,0 +1,24 @@
+package encodings
+
+import "io"
+import "vncproxy/common"
+
+type ZRLEEncoding struct {
+ //Colors []Color
+}
+
+func (z *ZRLEEncoding) Type() int32 {
+ return 16
+}
+func (z *ZRLEEncoding) Read(pixelFmt *common.PixelFormat, rect *common.Rectangle, r io.Reader) (common.Encoding, error) {
+ conn := common.RfbReadHelper{r}
+ //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
+ //bytesPerPixel := c.PixelFormat.BPP / 8
+ len, _ := conn.ReadUint32()
+ _, err := conn.ReadBytes(int(len))
+
+ if err != nil {
+ return nil, err
+ }
+ return z, nil
+}
diff --git a/main.go b/main.go
index 2340df1..c151fe9 100644
--- a/main.go
+++ b/main.go
@@ -5,11 +5,13 @@ import (
"net"
"os"
"time"
+ "vncproxy/common"
+ "vncproxy/encodings"
"vncproxy/vnc"
)
func main() {
- fmt.Println("")
+ //fmt.Println("")
//nc, err := net.Dial("tcp", "192.168.1.101:5903")
nc, err := net.Dial("tcp", "localhost:5903")
@@ -29,17 +31,18 @@ func main() {
// fmt.Printf("error requesting fb update: %s\n", err)
// }
- tight := vnc.TightEncoding{}
- //rre := vnc.RREEncoding{}
- //zlib := vnc.ZLibEncoding{}
- //zrle := vnc.ZRLEEncoding{}
- cpyRect := vnc.CopyRectEncoding{}
- //hextile := vnc.HextileEncoding{}
+ tight := encodings.TightEncoding{}
+ //rre := encodings.RREEncoding{}
+ //zlib := encodings.ZLibEncoding{}
+ //zrle := encodings.ZRLEEncoding{}
+ cpyRect := encodings.CopyRectEncoding{}
+ //coRRE := encodings.CoRREEncoding{}
+ //hextile := encodings.HextileEncoding{}
file, _ := os.OpenFile("stam.bin", os.O_CREATE|os.O_RDWR, 0755)
defer file.Close()
tight.SetOutput(file)
- clientConn.SetEncodings([]vnc.Encoding{&cpyRect, &tight})
+ clientConn.SetEncodings([]common.Encoding{&cpyRect, &tight})
go func() {
for {
diff --git a/vnc/client-conn.go b/vnc/client-conn.go
index 6fc55a8..5710e0d 100644
--- a/vnc/client-conn.go
+++ b/vnc/client-conn.go
@@ -7,6 +7,7 @@ import (
"io"
"net"
"unicode"
+ "vncproxy/common"
)
// A ServerMessage implements a message sent from the server to the client.
@@ -32,9 +33,7 @@ type ClientAuth interface {
}
type ClientConn struct {
- conn net.Conn
- output io.Writer
- passThrough bool
+ conn net.Conn
//c net.Conn
config *ClientConfig
@@ -46,7 +45,7 @@ type ClientConn struct {
// Encodings supported by the client. This should not be modified
// directly. Instead, SetEncodings should be used.
- Encs []Encoding
+ Encs []common.Encoding
// Width of the frame buffer in pixels, sent from the server.
FrameBufferWidth uint16
@@ -60,7 +59,7 @@ type ClientConn struct {
// The pixel format associated with the connection. This shouldn't
// be modified. If you wish to set a new pixel format, use the
// SetPixelFormat method.
- PixelFormat PixelFormat
+ PixelFormat common.PixelFormat
}
// A ClientConfig structure is used to configure a ClientConn. After
@@ -246,7 +245,7 @@ func (c *ClientConn) PointerEvent(mask ButtonMask, x, y uint16) error {
// given should not be modified.
//
// See RFC 6143 Section 7.5.2
-func (c *ClientConn) SetEncodings(encs []Encoding) error {
+func (c *ClientConn) SetEncodings(encs []common.Encoding) error {
data := make([]interface{}, 3+len(encs))
data[0] = uint8(2)
data[1] = uint8(0)
@@ -277,7 +276,7 @@ func (c *ClientConn) SetEncodings(encs []Encoding) error {
// in FramebufferUpdate messages from the server.
//
// See RFC 6143 Section 7.5.1
-func (c *ClientConn) SetPixelFormat(format *PixelFormat) error {
+func (c *ClientConn) SetPixelFormat(format *common.PixelFormat) error {
var keyEvent [20]byte
keyEvent[0] = 0
diff --git a/vnc/client.go b/vnc/client.go
deleted file mode 100644
index e46d86c..0000000
--- a/vnc/client.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Package vnc implements a VNC client.
-//
-// References:
-// [PROTOCOL]: http://tools.ietf.org/html/rfc6143
-package vnc
-
-import (
- "encoding/binary"
- "io"
-)
-
-// type DataSource struct {
-// conn io.Reader
-// output io.Writer
-// passThrough bool
-// PixelFormat PixelFormat
-// }Color
-
-func (d *ClientConn) readBytes(count int) ([]byte, error) {
- buff := make([]byte, count)
-
- _, err := io.ReadFull(d.conn, buff)
- if err != nil {
- //if err := binary.Read(d.conn, binary.BigEndian, &buff); err != nil {
- return nil, err
- }
- return buff, nil
-}
-
-func (d *ClientConn) readUint8() (uint8, error) {
- var myUint uint8
- if err := binary.Read(d.conn, binary.BigEndian, &myUint); err != nil {
- return 0, err
- }
- //fmt.Printf("myUint=%d", myUint)
- return myUint, nil
-}
-func (d *ClientConn) readUint16() (uint16, error) {
- var myUint uint16
- if err := binary.Read(d.conn, binary.BigEndian, &myUint); err != nil {
- return 0, err
- }
- //fmt.Printf("myUint=%d", myUint)
- return myUint, nil
-}
-func (d *ClientConn) readUint32() (uint32, error) {
- var myUint uint32
- if err := binary.Read(d.conn, binary.BigEndian, &myUint); err != nil {
- return 0, err
- }
- //fmt.Printf("myUint=%d", myUint)
- return myUint, nil
-}
-func (d *ClientConn) readCompactLen() (int, error) {
- var err error
- part, err := d.readUint8()
- //byteCount := 1
- len := uint32(part & 0x7F)
- if (part & 0x80) != 0 {
- part, err = d.readUint8()
- //byteCount++
- len |= uint32(part&0x7F) << 7
- if (part & 0x80) != 0 {
- part, err = d.readUint8()
- //byteCount++
- len |= uint32(part&0xFF) << 14
- }
- }
-
- // for i := 0; i < byteCount; i++{
- // rec.writeByte(portion[i]);
- // }
-
- return int(len), err
-}
diff --git a/vnc/enc-rre.go b/vnc/enc-rre.go
deleted file mode 100644
index 2b58811..0000000
--- a/vnc/enc-rre.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package vnc
-
-import "io"
-
-type RREEncoding struct {
- Colors []Color
-}
-
-func (z *RREEncoding) Type() int32 {
- return 2
-}
-func (z *RREEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encoding, error) {
-
- bytesPerPixel := int(conn.PixelFormat.BPP / 8)
- numOfSubrectangles, _ := conn.readUint32()
-
- //read whole rect background color
- conn.readBytes(bytesPerPixel)
-
- //read all individual rects (color=BPP + x=16b + y=16b + w=16b + h=16b)
- _, err := conn.readBytes(int(numOfSubrectangles) * (bytesPerPixel + 8))
-
- if err != nil {
- return nil, err
- }
- return z, nil
-}
-
-type CoRREEncoding struct {
- Colors []Color
-}
-
-func (z *CoRREEncoding) Type() int32 {
- return 4
-}
-
-func (z *CoRREEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encoding, error) {
-
- bytesPerPixel := int(conn.PixelFormat.BPP / 8)
- numOfSubrectangles, _ := conn.readUint32()
-
- //read whole rect background color
- conn.readBytes(bytesPerPixel)
-
- //read all individual rects (color=BPP + x=16b + y=16b + w=16b + h=16b)
- _, err := conn.readBytes(int(numOfSubrectangles) * (bytesPerPixel + 4))
-
- if err != nil {
- return nil, err
- }
- return z, nil
-
- //int nSubrects = rfb.readU32();
-
- //byte[] bg_buf = new byte[bytesPerPixel];
- //rfb.readFully(bytesPerPixel);
- //Color pixel;
- // if (bytesPixel == 1) {
- // pixel = colors[bg_buf[0] & 0xFF];
- // } else {
- // pixel = new Color(bg_buf[2] & 0xFF, bg_buf[1] & 0xFF, bg_buf[0] & 0xFF);
- // }
- // memGraphics.setColor(pixel);
- // memGraphics.fillRect(x, y, w, h);
-
- // byte[] buf = new byte[nSubrects * (bytesPixel + 4)];
- // rfb.readFully(buf);
-
-}
diff --git a/vnc/enc-zlib.go b/vnc/enc-zlib.go
deleted file mode 100644
index f28b023..0000000
--- a/vnc/enc-zlib.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package vnc
-
-import "io"
-
-type ZLibEncoding struct {
- Colors []Color
-}
-
-func (z *ZLibEncoding) Type() int32 {
- return 6
-}
-func (z *ZLibEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encoding, error) {
- //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
- //bytesPerPixel := c.PixelFormat.BPP / 8
- len, _ := conn.readUint32()
- _, err := conn.readBytes(int(len))
-
- if err != nil {
- return nil, err
- }
- return z, nil
-}
diff --git a/vnc/enc-zrle.go b/vnc/enc-zrle.go
deleted file mode 100644
index 7731a8a..0000000
--- a/vnc/enc-zrle.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package vnc
-
-import "io"
-
-type ZRLEEncoding struct {
- Colors []Color
-}
-
-func (z *ZRLEEncoding) Type() int32 {
- return 16
-}
-func (z *ZRLEEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encoding, error) {
- //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
- //bytesPerPixel := c.PixelFormat.BPP / 8
- len, _ := conn.readUint32()
- _, err := conn.readBytes(int(len))
-
- if err != nil {
- return nil, err
- }
- return z, nil
-}
diff --git a/vnc/encoding.go b/vnc/encoding.go
deleted file mode 100644
index 9c7b09e..0000000
--- a/vnc/encoding.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package vnc
-
-import "io"
-
-// An Encoding implements a method for encoding pixel data that is
-// sent by the server to the client.
-type Encoding interface {
- // The number that uniquely identifies this encoding type.
- Type() int32
-
- // Read reads the contents of the encoded pixel data from the reader.
- // This should return a new Encoding implementation that contains
- // the proper data.
- Read(*ClientConn, *Rectangle, io.Reader) (Encoding, error)
-}
-
-const (
- EncodingRaw = 0
- EncodingCopyRect = 1
- EncodingRRE = 2
- EncodingCoRRE = 4
- EncodingHextile = 5
- EncodingZlib = 6
- EncodingTight = 7
- EncodingZRLE = 16
-)
-
-type CopyRectEncoding struct {
- Colors []Color
- copyRectSrcX uint16
- copyRectSrcY uint16
-}
-
-func (z *CopyRectEncoding) Type() int32 {
- return 1
-}
-func (z *CopyRectEncoding) Read(conn *ClientConn, rect *Rectangle, r io.Reader) (Encoding, error) {
- //conn := &DataSource{conn: conn.c, PixelFormat: conn.PixelFormat}
- //bytesPerPixel := c.PixelFormat.BPP / 8
- z.copyRectSrcX, _ = conn.readUint16()
- z.copyRectSrcY, _ = conn.readUint16()
- return z, nil
-}
-
-//////////
diff --git a/vnc/pixel_format.go b/vnc/pixel_format.go
index c951298..e25af24 100644
--- a/vnc/pixel_format.go
+++ b/vnc/pixel_format.go
@@ -4,9 +4,10 @@ import (
"bytes"
"encoding/binary"
"io"
+ "vncproxy/common"
)
-func readPixelFormat(r io.Reader, result *PixelFormat) error {
+func readPixelFormat(r io.Reader, result *common.PixelFormat) error {
var rawPixelFormat [16]byte
if _, err := io.ReadFull(r, rawPixelFormat[:]); err != nil {
return err
@@ -67,7 +68,7 @@ func readPixelFormat(r io.Reader, result *PixelFormat) error {
return nil
}
-func writePixelFormat(format *PixelFormat) ([]byte, error) {
+func writePixelFormat(format *common.PixelFormat) ([]byte, error) {
var buf bytes.Buffer
// Byte 1
diff --git a/vnc/recorder.go b/vnc/recorder.go
index a9aad24..83b900d 100644
--- a/vnc/recorder.go
+++ b/vnc/recorder.go
@@ -2,15 +2,16 @@ package vnc
import (
"os"
+ "vncproxy/common"
)
type Recorder struct {
RBSFileName string
fileHandle *os.File
- logger Logger
+ logger common.Logger
}
-func NewRecorder(saveFilePath string, logger Logger) *Recorder {
+func NewRecorder(saveFilePath string, logger common.Logger) *Recorder {
rec := Recorder{RBSFileName: saveFilePath}
var err error
rec.fileHandle, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0755)
diff --git a/vnc/server_messages.go b/vnc/server_messages.go
index 8f6de43..fb1ad2e 100644
--- a/vnc/server_messages.go
+++ b/vnc/server_messages.go
@@ -5,18 +5,14 @@ import (
"encoding/json"
"fmt"
"io"
+ "vncproxy/common"
+ "vncproxy/encodings"
)
-
// FramebufferUpdateMessage consists of a sequence of rectangles of
// pixel data that the client should put into its framebuffer.
type FramebufferUpdateMessage struct {
- Rectangles []Rectangle
-}
-
-
-func (r *Rectangle) String() string {
- return fmt.Sprintf("(%d,%d) (width: %d, height: %d), Enc= %d", r.X, r.Y, r.Width, r.Height, r.Enc.Type())
+ Rectangles []common.Rectangle
}
func (m *FramebufferUpdateMessage) String() string {
@@ -44,17 +40,17 @@ func (*FramebufferUpdateMessage) Read(c *ClientConn, r io.Reader) (ServerMessage
}
// Build the map of encodings supported
- encMap := make(map[int32]Encoding)
+ encMap := make(map[int32]common.Encoding)
for _, enc := range c.Encs {
encMap[enc.Type()] = enc
}
// We must always support the raw encoding
- rawEnc := new(RawEncoding)
+ rawEnc := new(encodings.RawEncoding)
encMap[rawEnc.Type()] = rawEnc
fmt.Printf("numrects= %d\n", numRects)
- rects := make([]Rectangle, numRects)
+ rects := make([]common.Rectangle, numRects)
for i := uint16(0); i < numRects; i++ {
fmt.Printf("###############rect################: %d\n", i)
var encodingType int32
@@ -84,7 +80,7 @@ func (*FramebufferUpdateMessage) Read(c *ClientConn, r io.Reader) (ServerMessage
}
var err error
- rect.Enc, err = enc.Read(c, rect, r)
+ rect.Enc, err = enc.Read(&c.PixelFormat, rect, r)
if err != nil {
return nil, err
}
@@ -184,7 +180,7 @@ func (*ServerCutTextMessage) Type() uint8 {
return 3
}
-func (*ServerCutTextMessage) Read(c *ClientConn, r io.Reader) (ServerMessage, error) {
+func (*ServerCutTextMessage) Read(conn *ClientConn, r io.Reader) (ServerMessage, error) {
// Read off the padding
var padding [1]byte
if _, err := io.ReadFull(r, padding[:]); err != nil {