some lint fixes

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
Василий Толстов 2017-07-04 01:36:10 +03:00
parent 3aba31d655
commit 2024b32082
12 changed files with 352 additions and 177 deletions

31
aten.go
View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
) )
// Aten IKVM message types.
const ( const (
AteniKVMFrontGroundEventMsgType ServerMessageType = 4 AteniKVMFrontGroundEventMsgType ServerMessageType = 4
AteniKVMKeepAliveEventMsgType ServerMessageType = 22 AteniKVMKeepAliveEventMsgType ServerMessageType = 22
@ -14,18 +15,22 @@ const (
AteniKVMGetViewerLangMsgType ServerMessageType = 60 AteniKVMGetViewerLangMsgType ServerMessageType = 60
) )
// AteniKVMFrontGroundEvent unknown aten ikvm message
type AteniKVMFrontGroundEvent struct { type AteniKVMFrontGroundEvent struct {
_ [20]byte _ [20]byte
} }
// String return string representation
func (msg *AteniKVMFrontGroundEvent) String() string { func (msg *AteniKVMFrontGroundEvent) String() string {
return fmt.Sprintf("%s", msg.Type()) return fmt.Sprintf("%s", msg.Type())
} }
// Type return ServerMessageType
func (*AteniKVMFrontGroundEvent) Type() ServerMessageType { func (*AteniKVMFrontGroundEvent) Type() ServerMessageType {
return AteniKVMFrontGroundEventMsgType return AteniKVMFrontGroundEventMsgType
} }
// Read unmarshal message from conn
func (*AteniKVMFrontGroundEvent) Read(c Conn) (ServerMessage, error) { func (*AteniKVMFrontGroundEvent) Read(c Conn) (ServerMessage, error) {
msg := &AteniKVMFrontGroundEvent{} msg := &AteniKVMFrontGroundEvent{}
var pad [20]byte var pad [20]byte
@ -35,6 +40,7 @@ func (*AteniKVMFrontGroundEvent) Read(c Conn) (ServerMessage, error) {
return msg, nil return msg, nil
} }
// Write marshal message to conn
func (*AteniKVMFrontGroundEvent) Write(c Conn) error { func (*AteniKVMFrontGroundEvent) Write(c Conn) error {
var pad [20]byte var pad [20]byte
if err := binary.Write(c, binary.BigEndian, pad); err != nil { if err := binary.Write(c, binary.BigEndian, pad); err != nil {
@ -43,18 +49,22 @@ func (*AteniKVMFrontGroundEvent) Write(c Conn) error {
return nil return nil
} }
// AteniKVMKeepAliveEvent unknown aten ikvm message
type AteniKVMKeepAliveEvent struct { type AteniKVMKeepAliveEvent struct {
_ [1]byte _ [1]byte
} }
// String return string representation
func (msg *AteniKVMKeepAliveEvent) String() string { func (msg *AteniKVMKeepAliveEvent) String() string {
return fmt.Sprintf("%s", msg.Type()) return fmt.Sprintf("%s", msg.Type())
} }
// Type return ServerMessageType
func (*AteniKVMKeepAliveEvent) Type() ServerMessageType { func (*AteniKVMKeepAliveEvent) Type() ServerMessageType {
return AteniKVMKeepAliveEventMsgType return AteniKVMKeepAliveEventMsgType
} }
// Read unmarshal message from conn
func (*AteniKVMKeepAliveEvent) Read(c Conn) (ServerMessage, error) { func (*AteniKVMKeepAliveEvent) Read(c Conn) (ServerMessage, error) {
msg := &AteniKVMKeepAliveEvent{} msg := &AteniKVMKeepAliveEvent{}
var pad [1]byte var pad [1]byte
@ -64,6 +74,7 @@ func (*AteniKVMKeepAliveEvent) Read(c Conn) (ServerMessage, error) {
return msg, nil return msg, nil
} }
// Write marshal message to conn
func (*AteniKVMKeepAliveEvent) Write(c Conn) error { func (*AteniKVMKeepAliveEvent) Write(c Conn) error {
var pad [1]byte var pad [1]byte
if err := binary.Write(c, binary.BigEndian, pad); err != nil { if err := binary.Write(c, binary.BigEndian, pad); err != nil {
@ -72,18 +83,22 @@ func (*AteniKVMKeepAliveEvent) Write(c Conn) error {
return nil return nil
} }
// AteniKVMVideoGetInfo unknown aten ikvm message
type AteniKVMVideoGetInfo struct { type AteniKVMVideoGetInfo struct {
_ [20]byte _ [20]byte
} }
// String return string representation
func (msg *AteniKVMVideoGetInfo) String() string { func (msg *AteniKVMVideoGetInfo) String() string {
return fmt.Sprintf("%s", msg.Type()) return fmt.Sprintf("%s", msg.Type())
} }
// Type return ServerMessageType
func (*AteniKVMVideoGetInfo) Type() ServerMessageType { func (*AteniKVMVideoGetInfo) Type() ServerMessageType {
return AteniKVMVideoGetInfoMsgType return AteniKVMVideoGetInfoMsgType
} }
// Read unmarshal message from conn
func (*AteniKVMVideoGetInfo) Read(c Conn) (ServerMessage, error) { func (*AteniKVMVideoGetInfo) Read(c Conn) (ServerMessage, error) {
msg := &AteniKVMVideoGetInfo{} msg := &AteniKVMVideoGetInfo{}
var pad [40]byte var pad [40]byte
@ -93,6 +108,7 @@ func (*AteniKVMVideoGetInfo) Read(c Conn) (ServerMessage, error) {
return msg, nil return msg, nil
} }
// Write marshal message to conn
func (*AteniKVMVideoGetInfo) Write(c Conn) error { func (*AteniKVMVideoGetInfo) Write(c Conn) error {
var pad [4]byte var pad [4]byte
if err := binary.Write(c, binary.BigEndian, pad); err != nil { if err := binary.Write(c, binary.BigEndian, pad); err != nil {
@ -101,18 +117,22 @@ func (*AteniKVMVideoGetInfo) Write(c Conn) error {
return nil return nil
} }
// AteniKVMMouseGetInfo unknown aten ikvm message
type AteniKVMMouseGetInfo struct { type AteniKVMMouseGetInfo struct {
_ [2]byte _ [2]byte
} }
// String return string representation
func (msg *AteniKVMMouseGetInfo) String() string { func (msg *AteniKVMMouseGetInfo) String() string {
return fmt.Sprintf("%s", msg.Type()) return fmt.Sprintf("%s", msg.Type())
} }
// Type return ServerMessageType
func (*AteniKVMMouseGetInfo) Type() ServerMessageType { func (*AteniKVMMouseGetInfo) Type() ServerMessageType {
return AteniKVMMouseGetInfoMsgType return AteniKVMMouseGetInfoMsgType
} }
// Read unmarshal message from conn
func (*AteniKVMMouseGetInfo) Read(c Conn) (ServerMessage, error) { func (*AteniKVMMouseGetInfo) Read(c Conn) (ServerMessage, error) {
msg := &AteniKVMFrontGroundEvent{} msg := &AteniKVMFrontGroundEvent{}
var pad [2]byte var pad [2]byte
@ -122,6 +142,7 @@ func (*AteniKVMMouseGetInfo) Read(c Conn) (ServerMessage, error) {
return msg, nil return msg, nil
} }
// Write marshal message to conn
func (*AteniKVMMouseGetInfo) Write(c Conn) error { func (*AteniKVMMouseGetInfo) Write(c Conn) error {
var pad [2]byte var pad [2]byte
if err := binary.Write(c, binary.BigEndian, pad); err != nil { if err := binary.Write(c, binary.BigEndian, pad); err != nil {
@ -130,18 +151,22 @@ func (*AteniKVMMouseGetInfo) Write(c Conn) error {
return nil return nil
} }
// AteniKVMSessionMessage unknown aten ikvm message
type AteniKVMSessionMessage struct { type AteniKVMSessionMessage struct {
_ [264]byte _ [264]byte
} }
// String return string representation
func (msg *AteniKVMSessionMessage) String() string { func (msg *AteniKVMSessionMessage) String() string {
return fmt.Sprintf("%s", msg.Type()) return fmt.Sprintf("%s", msg.Type())
} }
// Type return ServerMessageType
func (*AteniKVMSessionMessage) Type() ServerMessageType { func (*AteniKVMSessionMessage) Type() ServerMessageType {
return AteniKVMFrontGroundEventMsgType return AteniKVMFrontGroundEventMsgType
} }
// Read unmarshal message from conn
func (*AteniKVMSessionMessage) Read(c Conn) (ServerMessage, error) { func (*AteniKVMSessionMessage) Read(c Conn) (ServerMessage, error) {
msg := &AteniKVMSessionMessage{} msg := &AteniKVMSessionMessage{}
var pad [264]byte var pad [264]byte
@ -151,6 +176,7 @@ func (*AteniKVMSessionMessage) Read(c Conn) (ServerMessage, error) {
return msg, nil return msg, nil
} }
// Write marshal message to conn
func (*AteniKVMSessionMessage) Write(c Conn) error { func (*AteniKVMSessionMessage) Write(c Conn) error {
var pad [264]byte var pad [264]byte
if err := binary.Write(c, binary.BigEndian, pad); err != nil { if err := binary.Write(c, binary.BigEndian, pad); err != nil {
@ -159,18 +185,22 @@ func (*AteniKVMSessionMessage) Write(c Conn) error {
return nil return nil
} }
// AteniKVMGetViewerLang unknown aten ikvm message
type AteniKVMGetViewerLang struct { type AteniKVMGetViewerLang struct {
_ [8]byte _ [8]byte
} }
// String return string representation
func (msg *AteniKVMGetViewerLang) String() string { func (msg *AteniKVMGetViewerLang) String() string {
return fmt.Sprintf("%s", msg.Type()) return fmt.Sprintf("%s", msg.Type())
} }
// Type return ServerMessageType
func (*AteniKVMGetViewerLang) Type() ServerMessageType { func (*AteniKVMGetViewerLang) Type() ServerMessageType {
return AteniKVMGetViewerLangMsgType return AteniKVMGetViewerLangMsgType
} }
// Read unmarshal message from conn
func (*AteniKVMGetViewerLang) Read(c Conn) (ServerMessage, error) { func (*AteniKVMGetViewerLang) Read(c Conn) (ServerMessage, error) {
msg := &AteniKVMGetViewerLang{} msg := &AteniKVMGetViewerLang{}
var pad [8]byte var pad [8]byte
@ -180,6 +210,7 @@ func (*AteniKVMGetViewerLang) Read(c Conn) (ServerMessage, error) {
return msg, nil return msg, nil
} }
// Write marshal message to conn
func (*AteniKVMGetViewerLang) Write(c Conn) error { func (*AteniKVMGetViewerLang) Write(c Conn) error {
var pad [8]byte var pad [8]byte
if err := binary.Write(c, binary.BigEndian, pad); err != nil { if err := binary.Write(c, binary.BigEndian, pad); err != nil {

View File

@ -18,6 +18,7 @@ const (
BtnNone Button = 0 BtnNone Button = 0
) )
// Mask returns button mask
func Mask(button Button) uint8 { func Mask(button Button) uint8 {
return uint8(button) return uint8(button)
} }

View File

@ -10,7 +10,8 @@ import (
) )
var ( var (
DefaultClientHandlers []ClientHandler = []ClientHandler{ // DefaultClientHandlers represents default client handlers
DefaultClientHandlers = []ClientHandler{
&DefaultClientVersionHandler{}, &DefaultClientVersionHandler{},
&DefaultClientSecurityHandler{}, &DefaultClientSecurityHandler{},
&DefaultClientClientInitHandler{}, &DefaultClientClientInitHandler{},
@ -19,6 +20,7 @@ var (
} }
) )
// Connect handshake with remote server using underlining net.Conn
func Connect(ctx context.Context, c net.Conn, cfg *ClientConfig) (*ClientConn, error) { func Connect(ctx context.Context, c net.Conn, cfg *ClientConfig) (*ClientConn, error) {
conn, err := NewClientConn(c, cfg) conn, err := NewClientConn(c, cfg)
if err != nil { if err != nil {
@ -44,22 +46,27 @@ func Connect(ctx context.Context, c net.Conn, cfg *ClientConfig) (*ClientConn, e
var _ Conn = (*ClientConn)(nil) var _ Conn = (*ClientConn)(nil)
// Config returns connection config
func (c *ClientConn) Config() interface{} { func (c *ClientConn) Config() interface{} {
return c.cfg return c.cfg
} }
// Wait waiting for connection close
func (c *ClientConn) Wait() { func (c *ClientConn) Wait() {
<-c.quit <-c.quit
} }
// Conn return underlining net.Conn
func (c *ClientConn) Conn() net.Conn { func (c *ClientConn) Conn() net.Conn {
return c.c return c.c
} }
// SetProtoVersion sets proto version
func (c *ClientConn) SetProtoVersion(pv string) { func (c *ClientConn) SetProtoVersion(pv string) {
c.protocol = pv c.protocol = pv
} }
// SetEncodings write SetEncodings message
func (c *ClientConn) SetEncodings(encs []EncodingType) error { func (c *ClientConn) SetEncodings(encs []EncodingType) error {
msg := &SetEncodings{ msg := &SetEncodings{
@ -70,10 +77,12 @@ func (c *ClientConn) SetEncodings(encs []EncodingType) error {
return msg.Write(c) return msg.Write(c)
} }
// Flush flushes data to conn
func (c *ClientConn) Flush() error { func (c *ClientConn) Flush() error {
return c.bw.Flush() return c.bw.Flush()
} }
// Close closing conn
func (c *ClientConn) Close() error { func (c *ClientConn) Close() error {
if c.quit != nil { if c.quit != nil {
close(c.quit) close(c.quit)
@ -85,61 +94,85 @@ func (c *ClientConn) Close() error {
return c.c.Close() return c.c.Close()
} }
// Read reads data from conn
func (c *ClientConn) Read(buf []byte) (int, error) { func (c *ClientConn) Read(buf []byte) (int, error) {
return c.br.Read(buf) return c.br.Read(buf)
} }
// Write data to conn must be Flushed
func (c *ClientConn) Write(buf []byte) (int, error) { func (c *ClientConn) Write(buf []byte) (int, error) {
return c.bw.Write(buf) return c.bw.Write(buf)
} }
// ColorMap returns color map
func (c *ClientConn) ColorMap() ColorMap { func (c *ClientConn) ColorMap() ColorMap {
return c.colorMap return c.colorMap
} }
// SetColorMap sets color map
func (c *ClientConn) SetColorMap(cm ColorMap) { func (c *ClientConn) SetColorMap(cm ColorMap) {
c.colorMap = cm c.colorMap = cm
} }
// DesktopName returns connection desktop name
func (c *ClientConn) DesktopName() []byte { func (c *ClientConn) DesktopName() []byte {
return c.desktopName return c.desktopName
} }
// PixelFormat returns connection pixel format
func (c *ClientConn) PixelFormat() PixelFormat { func (c *ClientConn) PixelFormat() PixelFormat {
return c.pixelFormat return c.pixelFormat
} }
// SetDesktopName sets desktop name
func (c *ClientConn) SetDesktopName(name []byte) { func (c *ClientConn) SetDesktopName(name []byte) {
copy(c.desktopName, name) copy(c.desktopName, name)
} }
// SetPixelFormat sets pixel format
func (c *ClientConn) SetPixelFormat(pf PixelFormat) error { func (c *ClientConn) SetPixelFormat(pf PixelFormat) error {
c.pixelFormat = pf c.pixelFormat = pf
return nil return nil
} }
// Encodings returns client encodings
func (c *ClientConn) Encodings() []Encoding { func (c *ClientConn) Encodings() []Encoding {
return c.encodings return c.encodings
} }
// Width returns width
func (c *ClientConn) Width() uint16 { func (c *ClientConn) Width() uint16 {
return c.fbWidth return c.fbWidth
} }
// Height returns height
func (c *ClientConn) Height() uint16 { func (c *ClientConn) Height() uint16 {
return c.fbHeight return c.fbHeight
} }
// Protocol returns protocol
func (c *ClientConn) Protocol() string { func (c *ClientConn) Protocol() string {
return c.protocol return c.protocol
} }
func (c *ClientConn) SetWidth(w uint16) {
c.fbWidth = w // SetWidth sets width of client conn
} func (c *ClientConn) SetWidth(width uint16) {
func (c *ClientConn) SetHeight(h uint16) { c.fbWidth = width
c.fbHeight = h
} }
// The ClientConn type holds client connection information. // SetHeight sets height of client conn
func (c *ClientConn) SetHeight(height uint16) {
c.fbHeight = height
}
// The ClientConn type holds client connection information
type ClientConn struct { type ClientConn struct {
c net.Conn c net.Conn
br *bufio.Reader br *bufio.Reader
bw *bufio.Writer bw *bufio.Writer
cfg *ClientConfig cfg *ClientConfig
protocol string protocol string
m sync.Mutex
// If the pixel format uses a color map, then this is the color // If the pixel format uses a color map, then this is the color
// map that is used. This should not be modified directly, since // map that is used. This should not be modified directly, since
// the data comes from the server. // the data comes from the server.
@ -169,6 +202,7 @@ type ClientConn struct {
errorCh chan error errorCh chan error
} }
// NewClientConn creates new client conn using config
func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) { func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) {
if len(cfg.Encodings) == 0 { if len(cfg.Encodings) == 0 {
return nil, fmt.Errorf("client can't handle encodings") return nil, fmt.Errorf("client can't handle encodings")
@ -186,9 +220,10 @@ func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) {
}, nil }, nil
} }
// DefaultClientMessageHandler represents default client message handler
type DefaultClientMessageHandler struct{} type DefaultClientMessageHandler struct{}
// listens to a VNC server and handles server messages. // Handle handles server messages.
func (*DefaultClientMessageHandler) Handle(c Conn) error { func (*DefaultClientMessageHandler) Handle(c Conn) error {
cfg := c.Config().(*ClientConfig) cfg := c.Config().(*ClientConfig)
var err error var err error

View File

@ -5,6 +5,7 @@ import (
"net" "net"
) )
// Conn represents vnc conection
type Conn interface { type Conn interface {
io.ReadWriteCloser io.ReadWriteCloser
Conn() net.Conn Conn() net.Conn

View File

@ -2,6 +2,7 @@ package vnc
import ( import (
"bytes" "bytes"
"image"
"sync" "sync"
) )
@ -11,8 +12,11 @@ type EncodingType int32
//go:generate stringer -type=EncodingType //go:generate stringer -type=EncodingType
const ( const (
// EncRaw raw encoding
EncRaw EncodingType = 0 EncRaw EncodingType = 0
// EncCopyRect copyrect encoding
EncCopyRect EncodingType = 1 EncCopyRect EncodingType = 1
EncRRE EncodingType = 2 EncRRE EncodingType = 2
EncCoRRE EncodingType = 4 EncCoRRE EncodingType = 4
EncHextile EncodingType = 5 EncHextile EncodingType = 5
@ -74,6 +78,7 @@ var bPool = sync.Pool{
}, },
} }
// Encoding represents interface for vnc encoding
type Encoding interface { type Encoding interface {
Type() EncodingType Type() EncodingType
Read(Conn, *Rectangle) error Read(Conn, *Rectangle) error
@ -99,3 +104,11 @@ func getBit(n uint8, pos uint8) uint8 {
n = n & (1 << pos) n = n & (1 << pos)
return n return n
} }
func newRGBAImage(rgba []byte, rect *Rectangle) image.Image {
img := &image.RGBA{Stride: 4 * int(rect.Width)}
img.Pix = rgba
img.Rect.Max.X = int(rect.Width)
img.Rect.Max.Y = int(rect.Height)
return img
}

View File

@ -74,7 +74,6 @@ func (enc *AtenHermon) Read(c Conn, rect *Rectangle) error {
for aten_length > 0 { for aten_length > 0 {
switch aten_type { switch aten_type {
case 0: //subrects case 0: //subrects
panic("unknown subrect")
var a uint16 var a uint16
var b uint16 var b uint16
var x uint8 var x uint8
@ -97,6 +96,7 @@ func (enc *AtenHermon) Read(c Conn, rect *Rectangle) error {
} }
aten_length -= 6 + (16 * 16 * uint32(c.PixelFormat().BPP)) aten_length -= 6 + (16 * 16 * uint32(c.PixelFormat().BPP))
panic("subrect!")
case 1: //raw case 1: //raw
fmt.Printf("raw reader %d %s\n", aten_length, rect) fmt.Printf("raw reader %d %s\n", aten_length, rect)
encRaw := &RawEncoding{} encRaw := &RawEncoding{}

45
encoding_cursor.go Normal file
View File

@ -0,0 +1,45 @@
package vnc
import "encoding/binary"
type CursorPseudoEncoding struct {
Colors []Color
BitMask []byte
}
func (*CursorPseudoEncoding) Type() EncodingType { return EncCursorPseudo }
func (enc *CursorPseudoEncoding) Read(c Conn, rect *Rectangle) error {
rgba := make([]byte, int(rect.Height)*int(rect.Width)*int(c.PixelFormat().BPP/8))
if err := binary.Read(c, binary.BigEndian, &rgba); err != nil {
return err
}
bitmask := make([]byte, int((rect.Width+7)/8*rect.Height))
if err := binary.Read(c, binary.BigEndian, &bitmask); err != nil {
return err
}
/*
rectStride := 4 * rect.Width
for i := uint16(0); i < rect.Height; i++ {
for j := uint16(0); j < rect.Width; j += 8 {
for idx, k := j/8, 7; k >= 0; k-- {
if (bitmask[idx] & (1 << uint(k))) == 0 {
pIdx := j*4 + i*rectStride
rgbaBuffer[pIdx] = 0
rgbaBuffer[pIdx+1] = 0
rgbaBuffer[pIdx+2] = 0
rgbaBuffer[pIdx+3] = 0
}
}
}
}
*/
return nil
}
func (enc *CursorPseudoEncoding) Write(c Conn, rect *Rectangle) error {
return nil
}

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
) )
// ClientHandler represents client handler
type ClientHandler interface { type ClientHandler interface {
Handle(Conn) error Handle(Conn) error
} }
@ -17,6 +18,7 @@ type ClientMessage interface {
Write(Conn) error Write(Conn) error
} }
// ServerHandler represents server handler
type ServerHandler interface { type ServerHandler interface {
Handle(Conn) error Handle(Conn) error
} }
@ -29,14 +31,19 @@ type ServerMessage interface {
Write(Conn) error Write(Conn) error
} }
// ProtoVersionLength protocol version length
const ProtoVersionLength = 12 const ProtoVersionLength = 12
const ( const (
// ProtoVersionUnknown unknown version
ProtoVersionUnknown = "" ProtoVersionUnknown = ""
// ProtoVersion33 sets if proto 003.003
ProtoVersion33 = "RFB 003.003\n" ProtoVersion33 = "RFB 003.003\n"
// ProtoVersion38 sets if proto 003.008
ProtoVersion38 = "RFB 003.008\n" ProtoVersion38 = "RFB 003.008\n"
) )
// ParseProtoVersion parse protocol version
func ParseProtoVersion(pv []byte) (uint, uint, error) { func ParseProtoVersion(pv []byte) (uint, uint, error) {
var major, minor uint var major, minor uint
@ -46,7 +53,7 @@ func ParseProtoVersion(pv []byte) (uint, uint, error) {
l, err := fmt.Sscanf(string(pv), "RFB %d.%d\n", &major, &minor) l, err := fmt.Sscanf(string(pv), "RFB %d.%d\n", &major, &minor)
if l != 2 { if l != 2 {
return 0, 0, fmt.Errorf("error parsing ProtocolVersion.") return 0, 0, fmt.Errorf("error parsing protocol version")
} }
if err != nil { if err != nil {
return 0, 0, err return 0, 0, err
@ -55,8 +62,10 @@ func ParseProtoVersion(pv []byte) (uint, uint, error) {
return major, minor, nil return major, minor, nil
} }
// DefaultClientVersionHandler represents default handler
type DefaultClientVersionHandler struct{} type DefaultClientVersionHandler struct{}
// Handle provide version handler for client side
func (*DefaultClientVersionHandler) Handle(c Conn) error { func (*DefaultClientVersionHandler) Handle(c Conn) error {
var version [ProtoVersionLength]byte var version [ProtoVersionLength]byte
@ -88,8 +97,10 @@ func (*DefaultClientVersionHandler) Handle(c Conn) error {
return c.Flush() return c.Flush()
} }
// DefaultServerVersionHandler represents default server handler
type DefaultServerVersionHandler struct{} type DefaultServerVersionHandler struct{}
// Handle provide server version handler
func (*DefaultServerVersionHandler) Handle(c Conn) error { func (*DefaultServerVersionHandler) Handle(c Conn) error {
var version [ProtoVersionLength]byte var version [ProtoVersionLength]byte
if err := binary.Write(c, binary.BigEndian, []byte(ProtoVersion38)); err != nil { if err := binary.Write(c, binary.BigEndian, []byte(ProtoVersion38)); err != nil {
@ -122,8 +133,10 @@ func (*DefaultServerVersionHandler) Handle(c Conn) error {
return nil return nil
} }
// DefaultClientSecurityHandler used for client security handler
type DefaultClientSecurityHandler struct{} type DefaultClientSecurityHandler struct{}
// Handle provide client side security handler
func (*DefaultClientSecurityHandler) Handle(c Conn) error { func (*DefaultClientSecurityHandler) Handle(c Conn) error {
cfg := c.Config().(*ClientConfig) cfg := c.Config().(*ClientConfig)
var numSecurityTypes uint8 var numSecurityTypes uint8
@ -177,8 +190,10 @@ func (*DefaultClientSecurityHandler) Handle(c Conn) error {
return nil return nil
} }
// DefaultServerSecurityHandler used for server security handler
type DefaultServerSecurityHandler struct{} type DefaultServerSecurityHandler struct{}
// Handle provide server side security handler
func (*DefaultServerSecurityHandler) Handle(c Conn) error { func (*DefaultServerSecurityHandler) Handle(c Conn) error {
cfg := c.Config().(*ServerConfig) cfg := c.Config().(*ServerConfig)
if err := binary.Write(c, binary.BigEndian, uint8(len(cfg.SecurityHandlers))); err != nil { if err := binary.Write(c, binary.BigEndian, uint8(len(cfg.SecurityHandlers))); err != nil {
@ -236,8 +251,10 @@ func (*DefaultServerSecurityHandler) Handle(c Conn) error {
return nil return nil
} }
// DefaultClientServerInitHandler default client server init handler
type DefaultClientServerInitHandler struct{} type DefaultClientServerInitHandler struct{}
// Handle provide default server init handler
func (*DefaultClientServerInitHandler) Handle(c Conn) error { func (*DefaultClientServerInitHandler) Handle(c Conn) error {
srvInit := ServerInit{} srvInit := ServerInit{}
@ -320,8 +337,10 @@ func (*DefaultClientServerInitHandler) Handle(c Conn) error {
return nil return nil
} }
// DefaultServerServerInitHandler default server server init handler
type DefaultServerServerInitHandler struct{} type DefaultServerServerInitHandler struct{}
// Handle provide default server server init handler
func (*DefaultServerServerInitHandler) Handle(c Conn) error { func (*DefaultServerServerInitHandler) Handle(c Conn) error {
if err := binary.Write(c, binary.BigEndian, c.Width()); err != nil { if err := binary.Write(c, binary.BigEndian, c.Width()); err != nil {
return err return err
@ -341,8 +360,10 @@ func (*DefaultServerServerInitHandler) Handle(c Conn) error {
return c.Flush() return c.Flush()
} }
// DefaultClientClientInitHandler default client client init handler
type DefaultClientClientInitHandler struct{} type DefaultClientClientInitHandler struct{}
// Handle provide default client client init handler
func (*DefaultClientClientInitHandler) Handle(c Conn) error { func (*DefaultClientClientInitHandler) Handle(c Conn) error {
cfg := c.Config().(*ClientConfig) cfg := c.Config().(*ClientConfig)
var shared uint8 var shared uint8
@ -357,8 +378,10 @@ func (*DefaultClientClientInitHandler) Handle(c Conn) error {
return c.Flush() return c.Flush()
} }
// DefaultServerClientInitHandler default server client init handler
type DefaultServerClientInitHandler struct{} type DefaultServerClientInitHandler struct{}
// Handle provide default server client init handler
func (*DefaultServerClientInitHandler) Handle(c Conn) error { func (*DefaultServerClientInitHandler) Handle(c Conn) error {
var shared uint8 var shared uint8
if err := binary.Read(c, binary.BigEndian, &shared); err != nil { if err := binary.Read(c, binary.BigEndian, &shared); err != nil {

129
image.go
View File

@ -17,9 +17,10 @@ type Color struct {
R, G, B uint16 R, G, B uint16
} }
// ColorMap represent color map
type ColorMap [256]Color type ColorMap [256]Color
// NewColor returns a new Color object. // NewColor returns a new Color object
func NewColor(pf *PixelFormat, cm *ColorMap) *Color { func NewColor(pf *PixelFormat, cm *ColorMap) *Color {
return &Color{ return &Color{
pf: pf, pf: pf,
@ -27,7 +28,7 @@ func NewColor(pf *PixelFormat, cm *ColorMap) *Color {
} }
} }
// Rectangle represents a rectangle of pixel data. // Rectangle represents a rectangle of pixel data
type Rectangle struct { type Rectangle struct {
X, Y uint16 X, Y uint16
Width, Height uint16 Width, Height uint16
@ -35,14 +36,17 @@ type Rectangle struct {
Enc Encoding Enc Encoding
} }
// String return string representation
func (rect *Rectangle) String() string { func (rect *Rectangle) String() string {
return fmt.Sprintf("rect x: %d, y: %d, width: %d, height: %d, enc: %s", rect.X, rect.Y, rect.Width, rect.Height, rect.EncType) return fmt.Sprintf("rect x: %d, y: %d, width: %d, height: %d, enc: %s", rect.X, rect.Y, rect.Width, rect.Height, rect.EncType)
} }
// NewRectangle returns new rectangle
func NewRectangle() *Rectangle { func NewRectangle() *Rectangle {
return &Rectangle{} return &Rectangle{}
} }
// Write marshal color to conn
func (clr *Color) Write(c Conn) error { func (clr *Color) Write(c Conn) error {
var err error var err error
order := clr.pf.order() order := clr.pf.order()
@ -65,32 +69,7 @@ func (clr *Color) Write(c Conn) error {
return err return err
} }
// Marshal implements the Marshaler interface. // Read unmarshal color from conn
func (c *Color) Marshal() ([]byte, error) {
order := c.pf.order()
pixel := c.cmIndex
if c.pf.TrueColor == 1 {
pixel = uint32(c.R) << c.pf.RedShift
pixel |= uint32(c.G) << c.pf.GreenShift
pixel |= uint32(c.B) << c.pf.BlueShift
}
var bytes []byte
switch c.pf.BPP {
case 8:
bytes = make([]byte, 1)
bytes[0] = byte(pixel)
case 16:
bytes = make([]byte, 2)
order.PutUint16(bytes, uint16(pixel))
case 32:
bytes = make([]byte, 4)
order.PutUint32(bytes, pixel)
}
return bytes, nil
}
func (clr *Color) Read(c Conn) error { func (clr *Color) Read(c Conn) error {
order := clr.pf.order() order := clr.pf.order()
var pixel uint32 var pixel uint32
@ -127,36 +106,6 @@ func (clr *Color) Read(c Conn) error {
return nil return nil
} }
// Unmarshal implements the Unmarshaler interface.
func (c *Color) Unmarshal(data []byte) error {
if len(data) == 0 {
return nil
}
order := c.pf.order()
var pixel uint32
switch c.pf.BPP {
case 8:
pixel = uint32(data[0])
case 16:
pixel = uint32(order.Uint16(data))
case 32:
pixel = order.Uint32(data)
}
if c.pf.TrueColor == 1 {
c.R = uint16((pixel >> c.pf.RedShift) & uint32(c.pf.RedMax))
c.G = uint16((pixel >> c.pf.GreenShift) & uint32(c.pf.GreenMax))
c.B = uint16((pixel >> c.pf.BlueShift) & uint32(c.pf.BlueMax))
} else {
*c = c.cm[pixel]
c.cmIndex = pixel
}
return nil
}
func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 { func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 {
rect := image.Rect(int(x), int(y), int(x+width), int(y+height)) rect := image.Rect(int(x), int(y), int(x+width), int(y+height))
rgba := image.NewRGBA64(rect) rgba := image.NewRGBA64(rect)
@ -174,72 +123,76 @@ func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 {
return rgba return rgba
} }
// Marshal implements the Marshaler interface. // Write marshal rectangle to conn
func (r *Rectangle) Write(c Conn) error { func (rect *Rectangle) Write(c Conn) error {
var err error var err error
if err = binary.Write(c, binary.BigEndian, r.X); err != nil {
if err = binary.Write(c, binary.BigEndian, rect.X); err != nil {
return err return err
} }
if err = binary.Write(c, binary.BigEndian, r.Y); err != nil { if err = binary.Write(c, binary.BigEndian, rect.Y); err != nil {
return err return err
} }
if err = binary.Write(c, binary.BigEndian, r.Width); err != nil { if err = binary.Write(c, binary.BigEndian, rect.Width); err != nil {
return err return err
} }
if err = binary.Write(c, binary.BigEndian, r.Height); err != nil { if err = binary.Write(c, binary.BigEndian, rect.Height); err != nil {
return err return err
} }
if err = binary.Write(c, binary.BigEndian, r.EncType); err != nil { if err = binary.Write(c, binary.BigEndian, rect.EncType); err != nil {
return err return err
} }
return r.Enc.Write(c, r) return rect.Enc.Write(c, rect)
} }
func (r *Rectangle) Read(c Conn) error { // Read unmarshal rectangle from conn
func (rect *Rectangle) Read(c Conn) error {
var err error var err error
if err = binary.Read(c, binary.BigEndian, &r.X); err != nil {
if err = binary.Read(c, binary.BigEndian, &rect.X); err != nil {
return err return err
} }
if err = binary.Read(c, binary.BigEndian, &r.Y); err != nil { if err = binary.Read(c, binary.BigEndian, &rect.Y); err != nil {
return err return err
} }
if err = binary.Read(c, binary.BigEndian, &r.Width); err != nil { if err = binary.Read(c, binary.BigEndian, &rect.Width); err != nil {
return err return err
} }
if err = binary.Read(c, binary.BigEndian, &r.Height); err != nil { if err = binary.Read(c, binary.BigEndian, &rect.Height); err != nil {
return err return err
} }
if err = binary.Read(c, binary.BigEndian, &r.EncType); err != nil { if err = binary.Read(c, binary.BigEndian, &rect.EncType); err != nil {
return err return err
} }
switch r.EncType {
switch rect.EncType {
case EncCopyRect: case EncCopyRect:
r.Enc = &CopyRectEncoding{} rect.Enc = &CopyRectEncoding{}
case EncTight: case EncTight:
r.Enc = &TightEncoding{} rect.Enc = &TightEncoding{}
case EncTightPng: case EncTightPng:
r.Enc = &TightPngEncoding{} rect.Enc = &TightPngEncoding{}
case EncRaw: case EncRaw:
if c.Protocol() == "aten" { if c.Protocol() == "aten" {
r.Enc = &AtenHermon{} rect.Enc = &AtenHermon{}
} else { } else {
r.Enc = &RawEncoding{} rect.Enc = &RawEncoding{}
} }
case EncDesktopSizePseudo: case EncDesktopSizePseudo:
r.Enc = &DesktopSizePseudoEncoding{} rect.Enc = &DesktopSizePseudoEncoding{}
case EncDesktopNamePseudo: case EncDesktopNamePseudo:
r.Enc = &DesktopNamePseudoEncoding{} rect.Enc = &DesktopNamePseudoEncoding{}
case EncXCursorPseudo: case EncXCursorPseudo:
r.Enc = &XCursorPseudoEncoding{} rect.Enc = &XCursorPseudoEncoding{}
case EncAtenHermon: case EncAtenHermon:
r.Enc = &AtenHermon{} rect.Enc = &AtenHermon{}
default: default:
return fmt.Errorf("unsupported encoding %s", r.EncType) return fmt.Errorf("unsupported encoding %s", rect.EncType)
}
return r.Enc.Read(c, r)
} }
// Area returns the total area in pixels of the Rectangle. return rect.Enc.Read(c, rect)
func (r *Rectangle) Area() int { return int(r.Width) * int(r.Height) } }
// Area returns the total area in pixels of the Rectangle
func (rect *Rectangle) Area() int { return int(rect.Width) * int(rect.Height) }

View File

@ -5,7 +5,9 @@ import (
"fmt" "fmt"
) )
var DefaultClientMessages = []ClientMessage{ var (
// DefaultClientMessages slice of default client messages sent to server
DefaultClientMessages = []ClientMessage{
&SetPixelFormat{}, &SetPixelFormat{},
&SetEncodings{}, &SetEncodings{},
&FramebufferUpdateRequest{}, &FramebufferUpdateRequest{},
@ -14,18 +16,32 @@ var DefaultClientMessages = []ClientMessage{
&ClientCutText{}, &ClientCutText{},
} }
type ServerInit struct { // DefaultServerMessages slice of default server messages sent to client
FBWidth, FBHeight uint16 DefaultServerMessages = []ServerMessage{
PixelFormat PixelFormat &FramebufferUpdate{},
NameLength uint32 &SetColorMapEntries{},
NameText []byte &Bell{},
&ServerCutText{},
} }
)
func (srvInit ServerInit) String() string { // ClientMessageType represents a Client-to-Server RFB message type.
return fmt.Sprintf("Width: %d, Height: %d, PixelFormat: %s, NameLength: %d, MameText: %s", srvInit.FBWidth, srvInit.FBHeight, srvInit.PixelFormat, srvInit.NameLength, srvInit.NameText) type ClientMessageType uint8
}
// ServerMessage represents a Client-to-Server RFB message type. //go:generate stringer -type=ClientMessageType
// Client-to-Server message types.
const (
SetPixelFormatMsgType ClientMessageType = iota
_
SetEncodingsMsgType
FramebufferUpdateRequestMsgType
KeyEventMsgType
PointerEventMsgType
ClientCutTextMsgType
)
// ServerMessageType represents a Client-to-Server RFB message type.
type ServerMessageType uint8 type ServerMessageType uint8
//go:generate stringer -type=ServerMessageType //go:generate stringer -type=ServerMessageType
@ -38,6 +54,19 @@ const (
ServerCutTextMsgType ServerCutTextMsgType
) )
// ServerInit struct used in server init handshake
type ServerInit struct {
FBWidth, FBHeight uint16
PixelFormat PixelFormat
NameLength uint32
NameText []byte
}
// String provide stringer
func (srvInit ServerInit) String() string {
return fmt.Sprintf("Width: %d, Height: %d, PixelFormat: %s, NameLength: %d, MameText: %s", srvInit.FBWidth, srvInit.FBHeight, srvInit.PixelFormat, srvInit.NameLength, srvInit.NameText)
}
// FramebufferUpdate holds a FramebufferUpdate wire format message. // FramebufferUpdate holds a FramebufferUpdate wire format message.
type FramebufferUpdate struct { type FramebufferUpdate struct {
_ [1]byte // pad _ [1]byte // pad
@ -45,14 +74,17 @@ type FramebufferUpdate struct {
Rects []*Rectangle // rectangles Rects []*Rectangle // rectangles
} }
// String provide stringer
func (msg *FramebufferUpdate) String() string { func (msg *FramebufferUpdate) String() string {
return fmt.Sprintf("rects %d rectangle[]: { %v }", msg.NumRect, msg.Rects) return fmt.Sprintf("rects %d rectangle[]: { %v }", msg.NumRect, msg.Rects)
} }
// Type return ServerMessageType
func (*FramebufferUpdate) Type() ServerMessageType { func (*FramebufferUpdate) Type() ServerMessageType {
return FramebufferUpdateMsgType return FramebufferUpdateMsgType
} }
// Read unmarshal message from conn
func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) { func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
msg := FramebufferUpdate{} msg := FramebufferUpdate{}
var pad [1]byte var pad [1]byte
@ -73,6 +105,7 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshals message to conn
func (msg *FramebufferUpdate) Write(c Conn) error { func (msg *FramebufferUpdate) Write(c Conn) error {
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
@ -92,20 +125,24 @@ func (msg *FramebufferUpdate) Write(c Conn) error {
return c.Flush() return c.Flush()
} }
// ServerCutText represents server message
type ServerCutText struct { type ServerCutText struct {
_ [1]byte _ [1]byte
Length uint32 Length uint32
Text []byte Text []byte
} }
// String returns string
func (msg *ServerCutText) String() string { func (msg *ServerCutText) String() string {
return fmt.Sprintf("lenght: %d text: %s", msg.Length, msg.Text) return fmt.Sprintf("lenght: %d text: %s", msg.Length, msg.Text)
} }
// Type returns ServerMessageType
func (*ServerCutText) Type() ServerMessageType { func (*ServerCutText) Type() ServerMessageType {
return ServerCutTextMsgType return ServerCutTextMsgType
} }
// Read unmarshal message from conn
func (*ServerCutText) Read(c Conn) (ServerMessage, error) { func (*ServerCutText) Read(c Conn) (ServerMessage, error) {
msg := ServerCutText{} msg := ServerCutText{}
@ -125,6 +162,7 @@ func (*ServerCutText) Read(c Conn) (ServerMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshal message to conn
func (msg *ServerCutText) Write(c Conn) error { func (msg *ServerCutText) Write(c Conn) error {
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
@ -147,20 +185,25 @@ func (msg *ServerCutText) Write(c Conn) error {
return c.Flush() return c.Flush()
} }
// Bell server message
type Bell struct{} type Bell struct{}
// String return string
func (*Bell) String() string { func (*Bell) String() string {
return fmt.Sprintf("bell") return fmt.Sprintf("bell")
} }
// Type returns ServerMessageType
func (*Bell) Type() ServerMessageType { func (*Bell) Type() ServerMessageType {
return BellMsgType return BellMsgType
} }
// Read unmarshal message from conn
func (*Bell) Read(c Conn) (ServerMessage, error) { func (*Bell) Read(c Conn) (ServerMessage, error) {
return &Bell{}, nil return &Bell{}, nil
} }
// Write marshal message to conn
func (msg *Bell) Write(c Conn) error { func (msg *Bell) Write(c Conn) error {
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
@ -168,6 +211,7 @@ func (msg *Bell) Write(c Conn) error {
return c.Flush() return c.Flush()
} }
// SetColorMapEntries server message
type SetColorMapEntries struct { type SetColorMapEntries struct {
_ [1]byte _ [1]byte
FirstColor uint16 FirstColor uint16
@ -175,14 +219,17 @@ type SetColorMapEntries struct {
Colors []Color Colors []Color
} }
// String returns string
func (msg *SetColorMapEntries) String() string { func (msg *SetColorMapEntries) String() string {
return fmt.Sprintf("first color: %d, numcolors: %d, colors[]: { %v }", msg.FirstColor, msg.ColorsNum, msg.Colors) return fmt.Sprintf("first color: %d, numcolors: %d, colors[]: { %v }", msg.FirstColor, msg.ColorsNum, msg.Colors)
} }
// Type returns ServerMessageType
func (*SetColorMapEntries) Type() ServerMessageType { func (*SetColorMapEntries) Type() ServerMessageType {
return SetColorMapEntriesMsgType return SetColorMapEntriesMsgType
} }
// Read unmrashal message from conn
func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) { func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) {
msg := SetColorMapEntries{} msg := SetColorMapEntries{}
var pad [1]byte var pad [1]byte
@ -212,6 +259,7 @@ func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshal message to conn
func (msg *SetColorMapEntries) Write(c Conn) error { func (msg *SetColorMapEntries) Write(c Conn) error {
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
@ -242,43 +290,23 @@ func (msg *SetColorMapEntries) Write(c Conn) error {
return c.Flush() return c.Flush()
} }
var DefaultServerMessages = []ServerMessage{
&FramebufferUpdate{},
&SetColorMapEntries{},
&Bell{},
&ServerCutText{},
}
// ClientMessage represents a Client-to-Server RFB message type.
type ClientMessageType uint8
//go:generate stringer -type=ClientMessageType
// Client-to-Server message types.
const (
SetPixelFormatMsgType ClientMessageType = iota
_
SetEncodingsMsgType
FramebufferUpdateRequestMsgType
KeyEventMsgType
PointerEventMsgType
ClientCutTextMsgType
)
// SetPixelFormat holds the wire format message. // SetPixelFormat holds the wire format message.
type SetPixelFormat struct { type SetPixelFormat struct {
_ [3]byte // padding _ [3]byte // padding
PF PixelFormat // pixel-format PF PixelFormat // pixel-format
} }
// String returns string
func (msg *SetPixelFormat) String() string { func (msg *SetPixelFormat) String() string {
return fmt.Sprintf("%s", msg.PF) return fmt.Sprintf("%s", msg.PF)
} }
// Type returns ClientMessageType
func (*SetPixelFormat) Type() ClientMessageType { func (*SetPixelFormat) Type() ClientMessageType {
return SetPixelFormatMsgType return SetPixelFormatMsgType
} }
// Write marshal message to conn
func (msg *SetPixelFormat) Write(c Conn) error { func (msg *SetPixelFormat) Write(c Conn) error {
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
@ -297,6 +325,7 @@ func (msg *SetPixelFormat) Write(c Conn) error {
return c.Flush() return c.Flush()
} }
// Read unmarshal message from conn
func (*SetPixelFormat) Read(c Conn) (ClientMessage, error) { func (*SetPixelFormat) Read(c Conn) (ClientMessage, error) {
msg := SetPixelFormat{} msg := SetPixelFormat{}
if err := binary.Read(c, binary.BigEndian, &msg); err != nil { if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
@ -312,14 +341,17 @@ type SetEncodings struct {
Encodings []EncodingType Encodings []EncodingType
} }
// String return string
func (msg *SetEncodings) String() string { func (msg *SetEncodings) String() string {
return fmt.Sprintf("encnum: %d, encodings[]: { %v }", msg.EncNum, msg.Encodings) return fmt.Sprintf("encnum: %d, encodings[]: { %v }", msg.EncNum, msg.Encodings)
} }
// Type returns ClientMessageType
func (*SetEncodings) Type() ClientMessageType { func (*SetEncodings) Type() ClientMessageType {
return SetEncodingsMsgType return SetEncodingsMsgType
} }
// Read unmarshal message from conn
func (*SetEncodings) Read(c Conn) (ClientMessage, error) { func (*SetEncodings) Read(c Conn) (ClientMessage, error) {
msg := SetEncodings{} msg := SetEncodings{}
var pad [1]byte var pad [1]byte
@ -341,6 +373,7 @@ func (*SetEncodings) Read(c Conn) (ClientMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshal message to conn
func (msg *SetEncodings) Write(c Conn) error { func (msg *SetEncodings) Write(c Conn) error {
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
@ -372,14 +405,17 @@ type FramebufferUpdateRequest struct {
Width, Height uint16 // width, height Width, Height uint16 // width, height
} }
// String returns string
func (msg *FramebufferUpdateRequest) String() string { 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) return fmt.Sprintf("incremental: %d, x: %d, y: %d, width: %d, height: %d", msg.Inc, msg.X, msg.Y, msg.Width, msg.Height)
} }
// Type returns ClientMessageType
func (*FramebufferUpdateRequest) Type() ClientMessageType { func (*FramebufferUpdateRequest) Type() ClientMessageType {
return FramebufferUpdateRequestMsgType return FramebufferUpdateRequestMsgType
} }
// Read unmarshal message from conn
func (*FramebufferUpdateRequest) Read(c Conn) (ClientMessage, error) { func (*FramebufferUpdateRequest) Read(c Conn) (ClientMessage, error) {
msg := FramebufferUpdateRequest{} msg := FramebufferUpdateRequest{}
if err := binary.Read(c, binary.BigEndian, &msg); err != nil { if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
@ -388,6 +424,7 @@ func (*FramebufferUpdateRequest) Read(c Conn) (ClientMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshal message to conn
func (msg *FramebufferUpdateRequest) Write(c Conn) error { func (msg *FramebufferUpdateRequest) Write(c Conn) error {
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
@ -405,14 +442,17 @@ type KeyEvent struct {
Key Key // key Key Key // key
} }
// String returns string
func (msg *KeyEvent) String() string { func (msg *KeyEvent) String() string {
return fmt.Sprintf("down: %d, key: %v", msg.Down, msg.Key) return fmt.Sprintf("down: %d, key: %v", msg.Down, msg.Key)
} }
// Type returns ClientMessageType
func (*KeyEvent) Type() ClientMessageType { func (*KeyEvent) Type() ClientMessageType {
return KeyEventMsgType return KeyEventMsgType
} }
// Read unmarshal message from conn
func (*KeyEvent) Read(c Conn) (ClientMessage, error) { func (*KeyEvent) Read(c Conn) (ClientMessage, error) {
msg := KeyEvent{} msg := KeyEvent{}
if err := binary.Read(c, binary.BigEndian, &msg); err != nil { if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
@ -421,6 +461,7 @@ func (*KeyEvent) Read(c Conn) (ClientMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshal message to conn
func (msg *KeyEvent) Write(c Conn) error { func (msg *KeyEvent) Write(c Conn) error {
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
@ -431,20 +472,23 @@ func (msg *KeyEvent) Write(c Conn) error {
return c.Flush() return c.Flush()
} }
// PointerEventMessage holds the wire format message. // PointerEvent message holds the wire format message
type PointerEvent struct { type PointerEvent struct {
Mask uint8 // button-mask Mask uint8 // button-mask
X, Y uint16 // x-, y-position X, Y uint16 // x-, y-position
} }
// String returns string
func (msg *PointerEvent) String() string { func (msg *PointerEvent) String() string {
return fmt.Sprintf("mask %d, x: %d, y: %d", msg.Mask, msg.X, msg.Y) return fmt.Sprintf("mask %d, x: %d, y: %d", msg.Mask, msg.X, msg.Y)
} }
// Type returns ClientMessageType
func (*PointerEvent) Type() ClientMessageType { func (*PointerEvent) Type() ClientMessageType {
return PointerEventMsgType return PointerEventMsgType
} }
// Read unmarshal message from conn
func (*PointerEvent) Read(c Conn) (ClientMessage, error) { func (*PointerEvent) Read(c Conn) (ClientMessage, error) {
msg := PointerEvent{} msg := PointerEvent{}
if err := binary.Read(c, binary.BigEndian, &msg); err != nil { if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
@ -453,6 +497,7 @@ func (*PointerEvent) Read(c Conn) (ClientMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshal message to conn
func (msg *PointerEvent) Write(c Conn) error { func (msg *PointerEvent) Write(c Conn) error {
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
@ -470,14 +515,17 @@ type ClientCutText struct {
Text []byte Text []byte
} }
// String returns string
func (msg *ClientCutText) String() string { func (msg *ClientCutText) String() string {
return fmt.Sprintf("length: %d, text: %s", msg.Length, msg.Text) return fmt.Sprintf("length: %d, text: %s", msg.Length, msg.Text)
} }
// Type returns ClientMessageType
func (*ClientCutText) Type() ClientMessageType { func (*ClientCutText) Type() ClientMessageType {
return ClientCutTextMsgType return ClientCutTextMsgType
} }
// Read unmarshal message from conn
func (*ClientCutText) Read(c Conn) (ClientMessage, error) { func (*ClientCutText) Read(c Conn) (ClientMessage, error) {
msg := ClientCutText{} msg := ClientCutText{}
var pad [3]byte var pad [3]byte
@ -496,6 +544,7 @@ func (*ClientCutText) Read(c Conn) (ClientMessage, error) {
return &msg, nil return &msg, nil
} }
// Write marshal message to conn
func (msg *ClientCutText) Write(c Conn) error { func (msg *ClientCutText) Write(c Conn) error {
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

View File

@ -10,13 +10,17 @@ import (
) )
var ( var (
PixelFormat8bit PixelFormat = NewPixelFormat(8) // PixelFormat8bit returns 8 bit pixel format
PixelFormat16bit PixelFormat = NewPixelFormat(16) PixelFormat8bit = NewPixelFormat(8)
PixelFormat32bit PixelFormat = NewPixelFormat(32) // PixelFormat16bit returns 16 bit pixel format
PixelFormatAten PixelFormat = NewPixelFormatAten() PixelFormat16bit = NewPixelFormat(16)
// PixelFormat32bit returns 32 bit pixel format
PixelFormat32bit = NewPixelFormat(32)
// PixelFormatAten returns pixel format used in Aten IKVM
PixelFormatAten = NewPixelFormatAten()
) )
// PixelFormat describes the way a pixel is formatted for a VNC connection. // PixelFormat describes the way a pixel is formatted for a VNC connection
type PixelFormat struct { type PixelFormat struct {
BPP uint8 // bits-per-pixel BPP uint8 // bits-per-pixel
Depth uint8 // depth Depth uint8 // depth
@ -27,27 +31,9 @@ type PixelFormat struct {
_ [3]byte // padding _ [3]byte // padding
} }
/*
qemu:
<field name="vnc.server_red_max" showname="Red maximum: 255" size="2" pos="76" show="255" value="00ff"/>
<field name="vnc.server_green_max" showname="Green maximum: 255" size="2" pos="78" show="255" value="00ff"/>
<field name="vnc.server_blue_max" showname="Blue maximum: 255" size="2" pos="80" show="255" value="00ff"/>
<field name="vnc.server_red_shift" showname="Red shift: 16" size="1" pos="82" show="16" value="10"/>
<field name="vnc.server_green_shift" showname="Green shift: 8" size="1" pos="83" show="8" value="08"/>
<field name="vnc.server_blue_shift" showname="Blue shift: 0" size="1" pos="84" show="0" value="00"/>
*/
/*
<field name="vnc.server_red_max" showname="Red maximum: 65535" size="2" pos="76" show="65535" value="ffff"/>
<field name="vnc.server_green_max" showname="Green maximum: 65535" size="2" pos="78" show="65535" value="ffff"/>
<field name="vnc.server_blue_max" showname="Blue maximum: 65535" size="2" pos="80" show="65535" value="ffff"/>
<field name="vnc.server_red_shift" showname="Red shift: 0" size="1" pos="82" show="0" value="00"/>
<field name="vnc.server_green_shift" showname="Green shift: 8" size="1" pos="83" show="8" value="08"/>
<field name="vnc.server_blue_shift" showname="Blue shift: 16" size="1" pos="84" show="16" value="10"/>
*/
const pixelFormatLen = 16 const pixelFormatLen = 16
// NewPixelFormat returns a populated PixelFormat structure. // NewPixelFormat returns a populated PixelFormat structure
func NewPixelFormat(bpp uint8) PixelFormat { func NewPixelFormat(bpp uint8) PixelFormat {
bigEndian := uint8(0) bigEndian := uint8(0)
// rgbMax := uint16(math.Exp2(float64(bpp))) - 1 // rgbMax := uint16(math.Exp2(float64(bpp))) - 1
@ -75,17 +61,18 @@ func NewPixelFormat(bpp uint8) PixelFormat {
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{}}
} }
// NewPixelFormatAten returns Aten IKVM pixel format
func NewPixelFormatAten() PixelFormat { func NewPixelFormatAten() PixelFormat {
return PixelFormat{16, 15, 0, 1, (1 << 5) - 1, (1 << 5) - 1, (1 << 5) - 1, 10, 5, 0, [3]byte{}} return PixelFormat{16, 15, 0, 1, (1 << 5) - 1, (1 << 5) - 1, (1 << 5) - 1, 10, 5, 0, [3]byte{}}
} }
// Marshal implements the Marshaler interface. // Marshal implements the Marshaler interface
func (pf PixelFormat) Marshal() ([]byte, error) { func (pf PixelFormat) Marshal() ([]byte, error) {
// Validation checks. // Validation checks.
switch pf.BPP { switch pf.BPP {
case 8, 16, 32: case 8, 16, 32:
default: default:
return nil, fmt.Errorf("Invalid BPP value %v; must be 8, 16, or 32.", pf.BPP) return nil, fmt.Errorf("Invalid BPP value %v; must be 8, 16, or 32", pf.BPP)
} }
if pf.Depth < pf.BPP { if pf.Depth < pf.BPP {
@ -94,7 +81,7 @@ func (pf PixelFormat) Marshal() ([]byte, error) {
switch pf.Depth { switch pf.Depth {
case 8, 16, 32: case 8, 16, 32:
default: default:
return nil, fmt.Errorf("Invalid Depth value %v; must be 8, 16, or 32.", pf.Depth) return nil, fmt.Errorf("Invalid Depth value %v; must be 8, 16, or 32", pf.Depth)
} }
// Create the slice of bytes // Create the slice of bytes
@ -109,7 +96,7 @@ func (pf PixelFormat) Marshal() ([]byte, error) {
return buf.Bytes(), nil return buf.Bytes(), nil
} }
// Read reads from an io.Reader, and populates the PixelFormat. // 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) buf := make([]byte, pixelFormatLen)
if _, err := io.ReadAtLeast(r, buf, pixelFormatLen); err != nil { if _, err := io.ReadAtLeast(r, buf, pixelFormatLen); err != nil {
@ -118,7 +105,7 @@ func (pf PixelFormat) Read(r io.Reader) error {
return pf.Unmarshal(buf) return pf.Unmarshal(buf)
} }
// Unmarshal implements the Unmarshaler interface. // 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 := bPool.Get().(*bytes.Buffer)
buf.Reset() buf.Reset()
@ -135,7 +122,7 @@ func (pf PixelFormat) Unmarshal(data []byte) error {
return nil return nil
} }
// String implements the fmt.Stringer interface. // 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 }", 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) pf.BPP, pf.Depth, pf.BigEndian, pf.TrueColor, pf.RedMax, pf.GreenMax, pf.BlueMax, pf.RedShift, pf.GreenShift, pf.BlueShift)

View File

@ -11,18 +11,22 @@ import (
var _ Conn = (*ServerConn)(nil) var _ Conn = (*ServerConn)(nil)
// Config returns config for server conn
func (c *ServerConn) Config() interface{} { func (c *ServerConn) Config() interface{} {
return c.cfg return c.cfg
} }
// Conn returns underlining server net.Conn
func (c *ServerConn) Conn() net.Conn { func (c *ServerConn) Conn() net.Conn {
return c.c return c.c
} }
// Wait waits connection to close
func (c *ServerConn) Wait() { func (c *ServerConn) Wait() {
<-c.quit <-c.quit
} }
// SetEncodings ??? sets server connection encodings
func (c *ServerConn) SetEncodings(encs []EncodingType) error { func (c *ServerConn) SetEncodings(encs []EncodingType) error {
encodings := make(map[EncodingType]Encoding) encodings := make(map[EncodingType]Encoding)
for _, enc := range c.cfg.Encodings { for _, enc := range c.cfg.Encodings {
@ -36,14 +40,17 @@ func (c *ServerConn) SetEncodings(encs []EncodingType) error {
return nil return nil
} }
// SetProtoVersion ??? sets proto version
func (c *ServerConn) SetProtoVersion(pv string) { func (c *ServerConn) SetProtoVersion(pv string) {
c.protocol = pv c.protocol = pv
} }
// Flush buffered data to server conn
func (c *ServerConn) Flush() error { func (c *ServerConn) Flush() error {
return c.bw.Flush() return c.bw.Flush()
} }
// Close closing server conn
func (c *ServerConn) Close() error { func (c *ServerConn) Close() error {
if c.quit != nil { if c.quit != nil {
close(c.quit) close(c.quit)
@ -52,62 +59,86 @@ func (c *ServerConn) Close() error {
return c.c.Close() return c.c.Close()
} }
// Read reads data from net.Conn
func (c *ServerConn) Read(buf []byte) (int, error) { func (c *ServerConn) Read(buf []byte) (int, error) {
return c.br.Read(buf) return c.br.Read(buf)
} }
// Write writes data to net.Conn, must be Flashed
func (c *ServerConn) Write(buf []byte) (int, error) { func (c *ServerConn) Write(buf []byte) (int, error) {
return c.bw.Write(buf) return c.bw.Write(buf)
} }
// ColorMap returns server connection color map
func (c *ServerConn) ColorMap() ColorMap { func (c *ServerConn) ColorMap() ColorMap {
return c.colorMap return c.colorMap
} }
// SetColorMap sets connection color map
func (c *ServerConn) SetColorMap(cm ColorMap) { func (c *ServerConn) SetColorMap(cm ColorMap) {
c.colorMap = cm c.colorMap = cm
} }
// DesktopName returns connection desktop name
func (c *ServerConn) DesktopName() []byte { func (c *ServerConn) DesktopName() []byte {
return c.desktopName return c.desktopName
} }
// PixelFormat return connection pixel format
func (c *ServerConn) PixelFormat() PixelFormat { func (c *ServerConn) PixelFormat() PixelFormat {
return c.pixelFormat return c.pixelFormat
} }
// SetDesktopName sets connection desktop name
func (c *ServerConn) SetDesktopName(name []byte) { func (c *ServerConn) SetDesktopName(name []byte) {
copy(c.desktopName, name) copy(c.desktopName, name)
} }
// SetPixelFormat sets pixel format for server conn
func (c *ServerConn) SetPixelFormat(pf PixelFormat) error { func (c *ServerConn) SetPixelFormat(pf PixelFormat) error {
c.pixelFormat = pf c.pixelFormat = pf
return nil return nil
} }
// Encodings returns connection encodings
func (c *ServerConn) Encodings() []Encoding { func (c *ServerConn) Encodings() []Encoding {
return c.encodings return c.encodings
} }
// Width returns framebuffer width
func (c *ServerConn) Width() uint16 { func (c *ServerConn) Width() uint16 {
return c.fbWidth return c.fbWidth
} }
// Height returns framebuffer height
func (c *ServerConn) Height() uint16 { func (c *ServerConn) Height() uint16 {
return c.fbHeight return c.fbHeight
} }
// Protocol returns protocol
func (c *ServerConn) Protocol() string { func (c *ServerConn) Protocol() string {
return c.protocol return c.protocol
} }
// TODO send desktopsize pseudo encoding // SetWidth sets framebuffer width
func (c *ServerConn) SetWidth(w uint16) { func (c *ServerConn) SetWidth(w uint16) {
// TODO send desktopsize pseudo encoding
c.fbWidth = w c.fbWidth = w
} }
// SetHeight sets framebuffer height
func (c *ServerConn) SetHeight(h uint16) { func (c *ServerConn) SetHeight(h uint16) {
// TODO send desktopsize pseudo encoding
c.fbHeight = h c.fbHeight = h
} }
// ServerConn underlining server conn
type ServerConn struct { type ServerConn struct {
c net.Conn c net.Conn
cfg *ServerConfig cfg *ServerConfig
br *bufio.Reader br *bufio.Reader
bw *bufio.Writer bw *bufio.Writer
protocol string protocol string
m sync.Mutex
// If the pixel format uses a color map, then this is the color // If the pixel format uses a color map, then this is the color
// map that is used. This should not be modified directly, since // map that is used. This should not be modified directly, since
// the data comes from the server. // the data comes from the server.
@ -136,7 +167,8 @@ type ServerConn struct {
} }
var ( var (
DefaultServerHandlers []ServerHandler = []ServerHandler{ // DefaultServerHandlers uses default handlers for hanshake
DefaultServerHandlers = []ServerHandler{
&DefaultServerVersionHandler{}, &DefaultServerVersionHandler{},
&DefaultServerSecurityHandler{}, &DefaultServerSecurityHandler{},
&DefaultServerClientInitHandler{}, &DefaultServerClientInitHandler{},
@ -145,6 +177,7 @@ var (
} }
) )
// ServerConfig config struct
type ServerConfig struct { type ServerConfig struct {
Handlers []ServerHandler Handlers []ServerHandler
SecurityHandlers []SecurityHandler SecurityHandlers []SecurityHandler
@ -160,6 +193,7 @@ type ServerConfig struct {
ErrorCh chan error ErrorCh chan error
} }
// NewServerConn returns new Server connection fron net.Conn
func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) { func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
return &ServerConn{ return &ServerConn{
c: c, c: c,
@ -175,6 +209,7 @@ func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
}, nil }, nil
} }
// Serve serves requests from net.Listener using ServerConfig
func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error { func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error {
for { for {
@ -204,8 +239,10 @@ func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error {
} }
} }
// DefaultServerMessageHandler default package handler
type DefaultServerMessageHandler struct{} type DefaultServerMessageHandler struct{}
// Handle handles messages from clients
func (*DefaultServerMessageHandler) Handle(c Conn) error { func (*DefaultServerMessageHandler) Handle(c Conn) error {
cfg := c.Config().(*ServerConfig) cfg := c.Config().(*ServerConfig)
var err error var err error