diff --git a/client.go b/client.go index 097357d..2013cc8 100644 --- a/client.go +++ b/client.go @@ -100,23 +100,23 @@ func (c *ClientConn) Write(buf []byte) (int, error) { return c.bw.Write(buf) } -func (c *ClientConn) ColorMap() *ColorMap { +func (c *ClientConn) ColorMap() ColorMap { return c.colorMap } -func (c *ClientConn) SetColorMap(cm *ColorMap) { +func (c *ClientConn) SetColorMap(cm ColorMap) { c.colorMap = cm } func (c *ClientConn) DesktopName() []byte { return c.desktopName } -func (c *ClientConn) PixelFormat() *PixelFormat { +func (c *ClientConn) PixelFormat() PixelFormat { return c.pixelFormat } func (c *ClientConn) SetDesktopName(name []byte) { copy(c.desktopName, name) } -func (c *ClientConn) SetPixelFormat(pf *PixelFormat) error { +func (c *ClientConn) SetPixelFormat(pf PixelFormat) error { c.pixelFormat = pf return nil } @@ -151,7 +151,7 @@ type ClientConn struct { // map that is used. This should not be modified directly, since // the data comes from the server. // Definition in §5 - Representation of Pixel Data. - colorMap *ColorMap + colorMap ColorMap // Name associated with the desktop, sent from the server. desktopName []byte @@ -169,7 +169,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 PixelFormat quitCh chan struct{} quit chan struct{} @@ -215,6 +215,10 @@ type SetPixelFormat struct { PF PixelFormat // pixel-format } +func (msg *SetPixelFormat) String() string { + return fmt.Sprintf("%s", msg.PF) +} + func (*SetPixelFormat) Type() ClientMessageType { return SetPixelFormatMsgType } @@ -231,7 +235,7 @@ func (msg *SetPixelFormat) Write(c Conn) error { pf := c.PixelFormat() // Invalidate the color map. if pf.TrueColor != 1 { - c.SetColorMap(&ColorMap{}) + c.SetColorMap(ColorMap{}) } return c.Flush() @@ -252,6 +256,10 @@ type SetEncodings struct { Encodings []EncodingType } +func (msg *SetEncodings) String() string { + return fmt.Sprintf("encnum: %d, encodings[]: { %v }", msg.EncNum, msg.Encodings) +} + func (*SetEncodings) Type() ClientMessageType { return SetEncodingsMsgType } @@ -308,6 +316,10 @@ type FramebufferUpdateRequest struct { Width, Height uint16 // width, height } +func (msg *FramebufferUpdateRequest) String() string { + return fmt.Sprintf("incremental: %d, x: %d, y: %d, width: %d, height: %d", msg.Inc, msg.X, msg.Y, msg.Width, msg.Height) +} + func (*FramebufferUpdateRequest) Type() ClientMessageType { return FramebufferUpdateRequestMsgType } @@ -337,6 +349,10 @@ type KeyEvent struct { Key Key // key } +func (msg *KeyEvent) String() string { + return fmt.Sprintf("down: %d, key: %v", msg.Down, msg.Key) +} + func (*KeyEvent) Type() ClientMessageType { return KeyEventMsgType } @@ -365,6 +381,10 @@ type PointerEvent struct { X, Y uint16 // x-, y-position } +func (msg *PointerEvent) String() string { + return fmt.Sprintf("mask %d, x: %d, y: %d", msg.Mask, msg.X, msg.Y) +} + func (*PointerEvent) Type() ClientMessageType { return PointerEventMsgType } @@ -394,6 +414,10 @@ type ClientCutText struct { Text []byte } +func (msg *ClientCutText) String() string { + return fmt.Sprintf("length: %d, text: %s", msg.Length, msg.Text) +} + func (*ClientCutText) Type() ClientMessageType { return ClientCutTextMsgType } @@ -509,8 +533,8 @@ type ClientConfig struct { Handlers []ClientHandler SecurityHandlers []SecurityHandler Encodings []Encoding - PixelFormat *PixelFormat - ColorMap *ColorMap + PixelFormat PixelFormat + ColorMap ColorMap ClientMessageCh chan ClientMessage ServerMessageCh chan ServerMessage Exclusive bool diff --git a/conn.go b/conn.go index 84cea2f..797c79b 100644 --- a/conn.go +++ b/conn.go @@ -10,10 +10,10 @@ type Conn interface { Conn() net.Conn Config() interface{} Protocol() string - PixelFormat() *PixelFormat - SetPixelFormat(*PixelFormat) error - ColorMap() *ColorMap - SetColorMap(*ColorMap) + PixelFormat() PixelFormat + SetPixelFormat(PixelFormat) error + ColorMap() ColorMap + SetColorMap(ColorMap) Encodings() []Encoding SetEncodings([]EncodingType) error Width() uint16 diff --git a/encoding.go b/encoding.go index df3c1b0..c22dae9 100644 --- a/encoding.go +++ b/encoding.go @@ -25,6 +25,11 @@ const ( EncJRLE EncodingType = 22 EncTRLE EncodingType = 15 EncZRLE EncodingType = 16 + EncAtenAST2100 EncodingType = 0x57 + EncAtenASTJPEG EncodingType = 0x58 + EncAtenHermon EncodingType = 0x59 + EncAtenYarkon EncodingType = 0x60 + EncAtenPilot3 EncodingType = 0x61 EncJPEGQualityLevelPseudo10 EncodingType = -23 EncJPEGQualityLevelPseudo9 EncodingType = -24 EncJPEGQualityLevelPseudo8 EncodingType = -25 @@ -35,7 +40,7 @@ const ( EncJPEGQualityLevelPseudo3 EncodingType = -30 EncJPEGQualityLevelPseudo2 EncodingType = -31 EncJPEGQualityLevelPseudo1 EncodingType = -32 - EncColorPseudo EncodingType = -239 + EncCursorPseudo EncodingType = -239 EncXCursorPseudo EncodingType = -240 EncDesktopSizePseudo EncodingType = -223 EncLastRectPseudo EncodingType = -224 @@ -55,9 +60,9 @@ const ( EncDesktopNamePseudo EncodingType = -307 EncExtendedDesktopSizePseudo EncodingType = -308 EncXvpPseudo EncodingType = -309 + EncClientRedirect EncodingType = -311 EncFencePseudo EncodingType = -312 EncContinuousUpdatesPseudo EncodingType = -313 - EncClientRedirect EncodingType = -311 ) var bPool = sync.Pool{ diff --git a/encoding_raw.go b/encoding_raw.go index 78b2a84..dd415bc 100644 --- a/encoding_raw.go +++ b/encoding_raw.go @@ -23,7 +23,7 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error { Loop: for y := uint16(0); y < rect.Height; y++ { for x := uint16(0); x < rect.Width; x++ { - color := NewColor(pf, cm) + color := NewColor(&pf, &cm) if err = color.Read(c); err != nil { break Loop } diff --git a/encodingtype_string.go b/encodingtype_string.go index 3c997f0..b21a196 100644 --- a/encodingtype_string.go +++ b/encodingtype_string.go @@ -4,7 +4,7 @@ package vnc import "fmt" -const _EncodingType_name = "EncContinuousUpdatesPseudoEncFencePseudoEncClientRedirectEncXvpPseudoEncExtendedDesktopSizePseudoEncDesktopNamePseudoEncTightPngEncQEMUExtendedKeyEventPseudoEncQEMUPointerMotionChangePseudoEncCompressionLevel1EncCompressionLevel2EncCompressionLevel3EncCompressionLevel4EncCompressionLevel5EncCompressionLevel6EncCompressionLevel7EncCompressionLevel8EncCompressionLevel9EncCompressionLevel10EncXCursorPseudoEncColorPseudoEncLastRectPseudoEncDesktopSizePseudoEncJPEGQualityLevelPseudo1EncJPEGQualityLevelPseudo2EncJPEGQualityLevelPseudo3EncJPEGQualityLevelPseudo4EncJPEGQualityLevelPseudo5EncJPEGQualityLevelPseudo6EncJPEGQualityLevelPseudo7EncJPEGQualityLevelPseudo8EncJPEGQualityLevelPseudo9EncJPEGQualityLevelPseudo10EncRawEncCopyRectEncRREEncCoRREEncHextileEncZlibEncTightEncZlibHexEncUltra1EncUltra2EncTRLEEncZRLEEncJPEGEncJRLE" +const _EncodingType_name = "EncContinuousUpdatesPseudoEncFencePseudoEncClientRedirectEncXvpPseudoEncExtendedDesktopSizePseudoEncDesktopNamePseudoEncTightPngEncQEMUExtendedKeyEventPseudoEncQEMUPointerMotionChangePseudoEncCompressionLevel1EncCompressionLevel2EncCompressionLevel3EncCompressionLevel4EncCompressionLevel5EncCompressionLevel6EncCompressionLevel7EncCompressionLevel8EncCompressionLevel9EncCompressionLevel10EncXCursorPseudoEncCursorPseudoEncLastRectPseudoEncDesktopSizePseudoEncJPEGQualityLevelPseudo1EncJPEGQualityLevelPseudo2EncJPEGQualityLevelPseudo3EncJPEGQualityLevelPseudo4EncJPEGQualityLevelPseudo5EncJPEGQualityLevelPseudo6EncJPEGQualityLevelPseudo7EncJPEGQualityLevelPseudo8EncJPEGQualityLevelPseudo9EncJPEGQualityLevelPseudo10EncRawEncCopyRectEncRREEncCoRREEncHextileEncZlibEncTightEncZlibHexEncUltra1EncUltra2EncTRLEEncZRLEEncJPEGEncJRLEEncAtenAST2100EncAtenASTJPEGEncAtenHermonEncAtenYarkonEncAtenPilot3" var _EncodingType_map = map[EncodingType]string{ -313: _EncodingType_name[0:26], @@ -27,33 +27,38 @@ var _EncodingType_map = map[EncodingType]string{ -248: _EncodingType_name[349:369], -247: _EncodingType_name[369:390], -240: _EncodingType_name[390:406], - -239: _EncodingType_name[406:420], - -224: _EncodingType_name[420:437], - -223: _EncodingType_name[437:457], - -32: _EncodingType_name[457:483], - -31: _EncodingType_name[483:509], - -30: _EncodingType_name[509:535], - -29: _EncodingType_name[535:561], - -28: _EncodingType_name[561:587], - -27: _EncodingType_name[587:613], - -26: _EncodingType_name[613:639], - -25: _EncodingType_name[639:665], - -24: _EncodingType_name[665:691], - -23: _EncodingType_name[691:718], - 0: _EncodingType_name[718:724], - 1: _EncodingType_name[724:735], - 2: _EncodingType_name[735:741], - 4: _EncodingType_name[741:749], - 5: _EncodingType_name[749:759], - 6: _EncodingType_name[759:766], - 7: _EncodingType_name[766:774], - 8: _EncodingType_name[774:784], - 9: _EncodingType_name[784:793], - 10: _EncodingType_name[793:802], - 15: _EncodingType_name[802:809], - 16: _EncodingType_name[809:816], - 21: _EncodingType_name[816:823], - 22: _EncodingType_name[823:830], + -239: _EncodingType_name[406:421], + -224: _EncodingType_name[421:438], + -223: _EncodingType_name[438:458], + -32: _EncodingType_name[458:484], + -31: _EncodingType_name[484:510], + -30: _EncodingType_name[510:536], + -29: _EncodingType_name[536:562], + -28: _EncodingType_name[562:588], + -27: _EncodingType_name[588:614], + -26: _EncodingType_name[614:640], + -25: _EncodingType_name[640:666], + -24: _EncodingType_name[666:692], + -23: _EncodingType_name[692:719], + 0: _EncodingType_name[719:725], + 1: _EncodingType_name[725:736], + 2: _EncodingType_name[736:742], + 4: _EncodingType_name[742:750], + 5: _EncodingType_name[750:760], + 6: _EncodingType_name[760:767], + 7: _EncodingType_name[767:775], + 8: _EncodingType_name[775:785], + 9: _EncodingType_name[785:794], + 10: _EncodingType_name[794:803], + 15: _EncodingType_name[803:810], + 16: _EncodingType_name[810:817], + 21: _EncodingType_name[817:824], + 22: _EncodingType_name[824:831], + 87: _EncodingType_name[831:845], + 88: _EncodingType_name[845:859], + 89: _EncodingType_name[859:872], + 96: _EncodingType_name[872:885], + 97: _EncodingType_name[885:898], } func (i EncodingType) String() string { diff --git a/handlers.go b/handlers.go index 2808fc1..f0aed68 100644 --- a/handlers.go +++ b/handlers.go @@ -7,6 +7,7 @@ import ( // ClientMessage is the interface type ClientMessage interface { + String() string Type() ClientMessageType Read(Conn) (ClientMessage, error) Write(Conn) error @@ -14,6 +15,7 @@ type ClientMessage interface { // ServerMessage is the interface type ServerMessage interface { + String() string Type() ServerMessageType Read(Conn) (ServerMessage, error) Write(Conn) error @@ -253,7 +255,7 @@ func (*DefaultClientServerInitHandler) Handle(c Conn) error { c.SetDesktopName(srvInit.NameText) c.SetWidth(srvInit.FBWidth) c.SetHeight(srvInit.FBHeight) - c.SetPixelFormat(&srvInit.PixelFormat) + c.SetPixelFormat(srvInit.PixelFormat) if c.Protocol() == "aten" { ikvm := struct { diff --git a/pixel_format.go b/pixel_format.go index 2e669a1..1e926dc 100644 --- a/pixel_format.go +++ b/pixel_format.go @@ -10,9 +10,9 @@ import ( ) var ( - PixelFormat8bit *PixelFormat = NewPixelFormat(8) - PixelFormat16bit *PixelFormat = NewPixelFormat(16) - PixelFormat32bit *PixelFormat = NewPixelFormat(32) + PixelFormat8bit PixelFormat = NewPixelFormat(8) + PixelFormat16bit PixelFormat = NewPixelFormat(16) + PixelFormat32bit PixelFormat = NewPixelFormat(32) ) // PixelFormat describes the way a pixel is formatted for a VNC connection. @@ -47,7 +47,7 @@ qemu: const pixelFormatLen = 16 // NewPixelFormat returns a populated PixelFormat structure. -func NewPixelFormat(bpp uint8) *PixelFormat { +func NewPixelFormat(bpp uint8) PixelFormat { bigEndian := uint8(0) // rgbMax := uint16(math.Exp2(float64(bpp))) - 1 rMax := uint16(255) @@ -71,11 +71,11 @@ func NewPixelFormat(bpp uint8) *PixelFormat { // rs, gs, bs = 0, 8, 16 rs, gs, bs = 16, 8, 0 } - return &PixelFormat{bpp, depth, bigEndian, tc, rMax, gMax, bMax, rs, gs, bs, [3]byte{}} + return PixelFormat{bpp, depth, bigEndian, tc, rMax, gMax, bMax, rs, gs, bs, [3]byte{}} } // Marshal implements the Marshaler interface. -func (pf *PixelFormat) Marshal() ([]byte, error) { +func (pf PixelFormat) Marshal() ([]byte, error) { // Validation checks. switch pf.BPP { case 8, 16, 32: @@ -105,7 +105,7 @@ func (pf *PixelFormat) Marshal() ([]byte, error) { } // Read reads from an io.Reader, and populates the PixelFormat. -func (pf *PixelFormat) Read(r io.Reader) error { +func (pf PixelFormat) Read(r io.Reader) error { buf := make([]byte, pixelFormatLen) if _, err := io.ReadAtLeast(r, buf, pixelFormatLen); err != nil { return err @@ -114,7 +114,7 @@ func (pf *PixelFormat) Read(r io.Reader) error { } // Unmarshal implements the Unmarshaler interface. -func (pf *PixelFormat) Unmarshal(data []byte) error { +func (pf PixelFormat) Unmarshal(data []byte) error { buf := bPool.Get().(*bytes.Buffer) buf.Reset() defer bPool.Put(buf) @@ -123,22 +123,20 @@ func (pf *PixelFormat) Unmarshal(data []byte) error { return err } - var msg PixelFormat - if err := binary.Read(buf, binary.BigEndian, &msg); err != nil { + if err := binary.Read(buf, binary.BigEndian, &pf); err != nil { return err } - *pf = msg return nil } // String implements the fmt.Stringer interface. -func (pf *PixelFormat) String() string { +func (pf PixelFormat) String() string { return fmt.Sprintf("{ bpp: %d depth: %d big-endian: %d true-color: %d red-max: %d green-max: %d blue-max: %d red-shift: %d green-shift: %d blue-shift: %d }", pf.BPP, pf.Depth, pf.BigEndian, pf.TrueColor, pf.RedMax, pf.GreenMax, pf.BlueMax, pf.RedShift, pf.GreenShift, pf.BlueShift) } -func (pf *PixelFormat) order() binary.ByteOrder { +func (pf PixelFormat) order() binary.ByteOrder { if pf.BigEndian == 1 { return binary.BigEndian } diff --git a/server.go b/server.go index bdb244b..a5e86a1 100644 --- a/server.go +++ b/server.go @@ -80,23 +80,23 @@ func (c *ServerConn) Write(buf []byte) (int, error) { return c.bw.Write(buf) } -func (c *ServerConn) ColorMap() *ColorMap { +func (c *ServerConn) ColorMap() ColorMap { return c.colorMap } -func (c *ServerConn) SetColorMap(cm *ColorMap) { +func (c *ServerConn) SetColorMap(cm ColorMap) { c.colorMap = cm } func (c *ServerConn) DesktopName() []byte { return c.desktopName } -func (c *ServerConn) PixelFormat() *PixelFormat { +func (c *ServerConn) PixelFormat() PixelFormat { return c.pixelFormat } func (c *ServerConn) SetDesktopName(name []byte) { copy(c.desktopName, name) } -func (c *ServerConn) SetPixelFormat(pf *PixelFormat) error { +func (c *ServerConn) SetPixelFormat(pf PixelFormat) error { c.pixelFormat = pf return nil } @@ -141,6 +141,10 @@ type FramebufferUpdate struct { Rects []*Rectangle // rectangles } +func (msg *FramebufferUpdate) String() string { + return fmt.Sprintf("rects %d rectangle[]: { %v }", msg.NumRect, msg.Rects) +} + func (*FramebufferUpdate) Type() ServerMessageType { return FramebufferUpdateMsgType } @@ -195,7 +199,7 @@ type ServerConn struct { // map that is used. This should not be modified directly, since // the data comes from the server. // Definition in §5 - Representation of Pixel Data. - colorMap *ColorMap + colorMap ColorMap // Name associated with the desktop, sent from the server. desktopName []byte @@ -213,7 +217,7 @@ type ServerConn 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 PixelFormat quit chan struct{} } @@ -236,15 +240,15 @@ type ServerConfig struct { Handlers []ServerHandler SecurityHandlers []SecurityHandler Encodings []Encoding - PixelFormat *PixelFormat - ColorMap *ColorMap + PixelFormat PixelFormat + ColorMap ColorMap ClientMessageCh chan ClientMessage ServerMessageCh chan ServerMessage ClientMessages []ClientMessage DesktopName []byte Height uint16 Width uint16 - errorCh chan error + ErrorCh chan error } func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) { @@ -272,16 +276,20 @@ func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error { conn, err := NewServerConn(c, cfg) if err != nil { + cfg.ErrorCh <- err continue } + if len(cfg.Handlers) == 0 { cfg.Handlers = DefaultServerHandlers } + handlerLoop: for _, h := range cfg.Handlers { if err := h.Handle(conn); err != nil { + cfg.ErrorCh <- err conn.Close() - break + break handlerLoop } } } @@ -312,7 +320,7 @@ func (*DefaultServerMessageHandler) Handle(c Conn) error { return case msg := <-cfg.ServerMessageCh: if err = msg.Write(c); err != nil { - cfg.errorCh <- err + cfg.ErrorCh <- err if quit != nil { close(quit) quit = nil @@ -333,7 +341,7 @@ func (*DefaultServerMessageHandler) Handle(c Conn) error { default: var messageType ClientMessageType if err := binary.Read(c, binary.BigEndian, &messageType); err != nil { - cfg.errorCh <- err + cfg.ErrorCh <- err if quit != nil { close(quit) quit = nil @@ -342,13 +350,13 @@ func (*DefaultServerMessageHandler) Handle(c Conn) error { } msg, ok := clientMessages[messageType] if !ok { - cfg.errorCh <- fmt.Errorf("unsupported message-type: %v", messageType) + cfg.ErrorCh <- fmt.Errorf("unsupported message-type: %v", messageType) close(quit) return } parsedMsg, err := msg.Read(c) if err != nil { - cfg.errorCh <- err + cfg.ErrorCh <- err if quit != nil { close(quit) quit = nil @@ -370,6 +378,10 @@ type ServerCutText struct { Text []byte } +func (msg *ServerCutText) String() string { + return fmt.Sprintf("lenght: %d text: %s", msg.Length, msg.Text) +} + func (*ServerCutText) Type() ServerMessageType { return ServerCutTextMsgType } @@ -417,6 +429,10 @@ func (msg *ServerCutText) Write(c Conn) error { type Bell struct{} +func (*Bell) String() string { + return fmt.Sprintf("bell") +} + func (*Bell) Type() ServerMessageType { return BellMsgType } @@ -439,6 +455,10 @@ type SetColorMapEntries struct { Colors []Color } +func (msg *SetColorMapEntries) String() string { + return fmt.Sprintf("first color: %d, numcolors: %d, colors[]: { %v }", msg.FirstColor, msg.ColorsNum, msg.Colors) +} + func (*SetColorMapEntries) Type() ServerMessageType { return SetColorMapEntriesMsgType }