some lint fixes
Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
parent
3aba31d655
commit
2024b32082
31
aten.go
31
aten.go
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Aten IKVM message types.
|
||||
const (
|
||||
AteniKVMFrontGroundEventMsgType ServerMessageType = 4
|
||||
AteniKVMKeepAliveEventMsgType ServerMessageType = 22
|
||||
@ -14,18 +15,22 @@ const (
|
||||
AteniKVMGetViewerLangMsgType ServerMessageType = 60
|
||||
)
|
||||
|
||||
// AteniKVMFrontGroundEvent unknown aten ikvm message
|
||||
type AteniKVMFrontGroundEvent struct {
|
||||
_ [20]byte
|
||||
}
|
||||
|
||||
// String return string representation
|
||||
func (msg *AteniKVMFrontGroundEvent) String() string {
|
||||
return fmt.Sprintf("%s", msg.Type())
|
||||
}
|
||||
|
||||
// Type return ServerMessageType
|
||||
func (*AteniKVMFrontGroundEvent) Type() ServerMessageType {
|
||||
return AteniKVMFrontGroundEventMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*AteniKVMFrontGroundEvent) Read(c Conn) (ServerMessage, error) {
|
||||
msg := &AteniKVMFrontGroundEvent{}
|
||||
var pad [20]byte
|
||||
@ -35,6 +40,7 @@ func (*AteniKVMFrontGroundEvent) Read(c Conn) (ServerMessage, error) {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (*AteniKVMFrontGroundEvent) Write(c Conn) error {
|
||||
var pad [20]byte
|
||||
if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
||||
@ -43,18 +49,22 @@ func (*AteniKVMFrontGroundEvent) Write(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AteniKVMKeepAliveEvent unknown aten ikvm message
|
||||
type AteniKVMKeepAliveEvent struct {
|
||||
_ [1]byte
|
||||
}
|
||||
|
||||
// String return string representation
|
||||
func (msg *AteniKVMKeepAliveEvent) String() string {
|
||||
return fmt.Sprintf("%s", msg.Type())
|
||||
}
|
||||
|
||||
// Type return ServerMessageType
|
||||
func (*AteniKVMKeepAliveEvent) Type() ServerMessageType {
|
||||
return AteniKVMKeepAliveEventMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*AteniKVMKeepAliveEvent) Read(c Conn) (ServerMessage, error) {
|
||||
msg := &AteniKVMKeepAliveEvent{}
|
||||
var pad [1]byte
|
||||
@ -64,6 +74,7 @@ func (*AteniKVMKeepAliveEvent) Read(c Conn) (ServerMessage, error) {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (*AteniKVMKeepAliveEvent) Write(c Conn) error {
|
||||
var pad [1]byte
|
||||
if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
||||
@ -72,18 +83,22 @@ func (*AteniKVMKeepAliveEvent) Write(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AteniKVMVideoGetInfo unknown aten ikvm message
|
||||
type AteniKVMVideoGetInfo struct {
|
||||
_ [20]byte
|
||||
}
|
||||
|
||||
// String return string representation
|
||||
func (msg *AteniKVMVideoGetInfo) String() string {
|
||||
return fmt.Sprintf("%s", msg.Type())
|
||||
}
|
||||
|
||||
// Type return ServerMessageType
|
||||
func (*AteniKVMVideoGetInfo) Type() ServerMessageType {
|
||||
return AteniKVMVideoGetInfoMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*AteniKVMVideoGetInfo) Read(c Conn) (ServerMessage, error) {
|
||||
msg := &AteniKVMVideoGetInfo{}
|
||||
var pad [40]byte
|
||||
@ -93,6 +108,7 @@ func (*AteniKVMVideoGetInfo) Read(c Conn) (ServerMessage, error) {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (*AteniKVMVideoGetInfo) Write(c Conn) error {
|
||||
var pad [4]byte
|
||||
if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
||||
@ -101,18 +117,22 @@ func (*AteniKVMVideoGetInfo) Write(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AteniKVMMouseGetInfo unknown aten ikvm message
|
||||
type AteniKVMMouseGetInfo struct {
|
||||
_ [2]byte
|
||||
}
|
||||
|
||||
// String return string representation
|
||||
func (msg *AteniKVMMouseGetInfo) String() string {
|
||||
return fmt.Sprintf("%s", msg.Type())
|
||||
}
|
||||
|
||||
// Type return ServerMessageType
|
||||
func (*AteniKVMMouseGetInfo) Type() ServerMessageType {
|
||||
return AteniKVMMouseGetInfoMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*AteniKVMMouseGetInfo) Read(c Conn) (ServerMessage, error) {
|
||||
msg := &AteniKVMFrontGroundEvent{}
|
||||
var pad [2]byte
|
||||
@ -122,6 +142,7 @@ func (*AteniKVMMouseGetInfo) Read(c Conn) (ServerMessage, error) {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (*AteniKVMMouseGetInfo) Write(c Conn) error {
|
||||
var pad [2]byte
|
||||
if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
||||
@ -130,18 +151,22 @@ func (*AteniKVMMouseGetInfo) Write(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AteniKVMSessionMessage unknown aten ikvm message
|
||||
type AteniKVMSessionMessage struct {
|
||||
_ [264]byte
|
||||
}
|
||||
|
||||
// String return string representation
|
||||
func (msg *AteniKVMSessionMessage) String() string {
|
||||
return fmt.Sprintf("%s", msg.Type())
|
||||
}
|
||||
|
||||
// Type return ServerMessageType
|
||||
func (*AteniKVMSessionMessage) Type() ServerMessageType {
|
||||
return AteniKVMFrontGroundEventMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*AteniKVMSessionMessage) Read(c Conn) (ServerMessage, error) {
|
||||
msg := &AteniKVMSessionMessage{}
|
||||
var pad [264]byte
|
||||
@ -151,6 +176,7 @@ func (*AteniKVMSessionMessage) Read(c Conn) (ServerMessage, error) {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (*AteniKVMSessionMessage) Write(c Conn) error {
|
||||
var pad [264]byte
|
||||
if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
||||
@ -159,18 +185,22 @@ func (*AteniKVMSessionMessage) Write(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AteniKVMGetViewerLang unknown aten ikvm message
|
||||
type AteniKVMGetViewerLang struct {
|
||||
_ [8]byte
|
||||
}
|
||||
|
||||
// String return string representation
|
||||
func (msg *AteniKVMGetViewerLang) String() string {
|
||||
return fmt.Sprintf("%s", msg.Type())
|
||||
}
|
||||
|
||||
// Type return ServerMessageType
|
||||
func (*AteniKVMGetViewerLang) Type() ServerMessageType {
|
||||
return AteniKVMGetViewerLangMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*AteniKVMGetViewerLang) Read(c Conn) (ServerMessage, error) {
|
||||
msg := &AteniKVMGetViewerLang{}
|
||||
var pad [8]byte
|
||||
@ -180,6 +210,7 @@ func (*AteniKVMGetViewerLang) Read(c Conn) (ServerMessage, error) {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (*AteniKVMGetViewerLang) Write(c Conn) error {
|
||||
var pad [8]byte
|
||||
if err := binary.Write(c, binary.BigEndian, pad); err != nil {
|
||||
|
@ -18,6 +18,7 @@ const (
|
||||
BtnNone Button = 0
|
||||
)
|
||||
|
||||
// Mask returns button mask
|
||||
func Mask(button Button) uint8 {
|
||||
return uint8(button)
|
||||
}
|
||||
|
53
client.go
53
client.go
@ -10,7 +10,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultClientHandlers []ClientHandler = []ClientHandler{
|
||||
// DefaultClientHandlers represents default client handlers
|
||||
DefaultClientHandlers = []ClientHandler{
|
||||
&DefaultClientVersionHandler{},
|
||||
&DefaultClientSecurityHandler{},
|
||||
&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) {
|
||||
conn, err := NewClientConn(c, cfg)
|
||||
if err != nil {
|
||||
@ -44,22 +46,27 @@ func Connect(ctx context.Context, c net.Conn, cfg *ClientConfig) (*ClientConn, e
|
||||
|
||||
var _ Conn = (*ClientConn)(nil)
|
||||
|
||||
// Config returns connection config
|
||||
func (c *ClientConn) Config() interface{} {
|
||||
return c.cfg
|
||||
}
|
||||
|
||||
// Wait waiting for connection close
|
||||
func (c *ClientConn) Wait() {
|
||||
<-c.quit
|
||||
}
|
||||
|
||||
// Conn return underlining net.Conn
|
||||
func (c *ClientConn) Conn() net.Conn {
|
||||
return c.c
|
||||
}
|
||||
|
||||
// SetProtoVersion sets proto version
|
||||
func (c *ClientConn) SetProtoVersion(pv string) {
|
||||
c.protocol = pv
|
||||
}
|
||||
|
||||
// SetEncodings write SetEncodings message
|
||||
func (c *ClientConn) SetEncodings(encs []EncodingType) error {
|
||||
|
||||
msg := &SetEncodings{
|
||||
@ -70,10 +77,12 @@ func (c *ClientConn) SetEncodings(encs []EncodingType) error {
|
||||
return msg.Write(c)
|
||||
}
|
||||
|
||||
// Flush flushes data to conn
|
||||
func (c *ClientConn) Flush() error {
|
||||
return c.bw.Flush()
|
||||
}
|
||||
|
||||
// Close closing conn
|
||||
func (c *ClientConn) Close() error {
|
||||
if c.quit != nil {
|
||||
close(c.quit)
|
||||
@ -85,61 +94,85 @@ func (c *ClientConn) Close() error {
|
||||
return c.c.Close()
|
||||
}
|
||||
|
||||
// Read reads data from conn
|
||||
func (c *ClientConn) Read(buf []byte) (int, error) {
|
||||
return c.br.Read(buf)
|
||||
}
|
||||
|
||||
// Write data to conn must be Flushed
|
||||
func (c *ClientConn) Write(buf []byte) (int, error) {
|
||||
return c.bw.Write(buf)
|
||||
}
|
||||
|
||||
// ColorMap returns color map
|
||||
func (c *ClientConn) ColorMap() ColorMap {
|
||||
return c.colorMap
|
||||
}
|
||||
|
||||
// SetColorMap sets color map
|
||||
func (c *ClientConn) SetColorMap(cm ColorMap) {
|
||||
c.colorMap = cm
|
||||
}
|
||||
|
||||
// DesktopName returns connection desktop name
|
||||
func (c *ClientConn) DesktopName() []byte {
|
||||
return c.desktopName
|
||||
}
|
||||
|
||||
// PixelFormat returns connection pixel format
|
||||
func (c *ClientConn) PixelFormat() PixelFormat {
|
||||
return c.pixelFormat
|
||||
}
|
||||
|
||||
// SetDesktopName sets desktop name
|
||||
func (c *ClientConn) SetDesktopName(name []byte) {
|
||||
copy(c.desktopName, name)
|
||||
}
|
||||
|
||||
// SetPixelFormat sets pixel format
|
||||
func (c *ClientConn) SetPixelFormat(pf PixelFormat) error {
|
||||
c.pixelFormat = pf
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encodings returns client encodings
|
||||
func (c *ClientConn) Encodings() []Encoding {
|
||||
return c.encodings
|
||||
}
|
||||
|
||||
// Width returns width
|
||||
func (c *ClientConn) Width() uint16 {
|
||||
return c.fbWidth
|
||||
}
|
||||
|
||||
// Height returns height
|
||||
func (c *ClientConn) Height() uint16 {
|
||||
return c.fbHeight
|
||||
}
|
||||
|
||||
// Protocol returns protocol
|
||||
func (c *ClientConn) Protocol() string {
|
||||
return c.protocol
|
||||
}
|
||||
func (c *ClientConn) SetWidth(w uint16) {
|
||||
c.fbWidth = w
|
||||
}
|
||||
func (c *ClientConn) SetHeight(h uint16) {
|
||||
c.fbHeight = h
|
||||
|
||||
// SetWidth sets width of client conn
|
||||
func (c *ClientConn) SetWidth(width uint16) {
|
||||
c.fbWidth = width
|
||||
}
|
||||
|
||||
// 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 {
|
||||
c net.Conn
|
||||
br *bufio.Reader
|
||||
bw *bufio.Writer
|
||||
cfg *ClientConfig
|
||||
protocol string
|
||||
m sync.Mutex
|
||||
|
||||
// If the pixel format uses a color map, then this is the color
|
||||
// map that is used. This should not be modified directly, since
|
||||
// the data comes from the server.
|
||||
@ -169,6 +202,7 @@ type ClientConn struct {
|
||||
errorCh chan error
|
||||
}
|
||||
|
||||
// NewClientConn creates new client conn using config
|
||||
func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) {
|
||||
if len(cfg.Encodings) == 0 {
|
||||
return nil, fmt.Errorf("client can't handle encodings")
|
||||
@ -186,9 +220,10 @@ func NewClientConn(c net.Conn, cfg *ClientConfig) (*ClientConn, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DefaultClientMessageHandler represents default client message handler
|
||||
type DefaultClientMessageHandler struct{}
|
||||
|
||||
// listens to a VNC server and handles server messages.
|
||||
// Handle handles server messages.
|
||||
func (*DefaultClientMessageHandler) Handle(c Conn) error {
|
||||
cfg := c.Config().(*ClientConfig)
|
||||
var err error
|
||||
|
1
conn.go
1
conn.go
@ -5,6 +5,7 @@ import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// Conn represents vnc conection
|
||||
type Conn interface {
|
||||
io.ReadWriteCloser
|
||||
Conn() net.Conn
|
||||
|
13
encoding.go
13
encoding.go
@ -2,6 +2,7 @@ package vnc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@ -11,8 +12,11 @@ type EncodingType int32
|
||||
//go:generate stringer -type=EncodingType
|
||||
|
||||
const (
|
||||
// EncRaw raw encoding
|
||||
EncRaw EncodingType = 0
|
||||
// EncCopyRect copyrect encoding
|
||||
EncCopyRect EncodingType = 1
|
||||
|
||||
EncRRE EncodingType = 2
|
||||
EncCoRRE EncodingType = 4
|
||||
EncHextile EncodingType = 5
|
||||
@ -74,6 +78,7 @@ var bPool = sync.Pool{
|
||||
},
|
||||
}
|
||||
|
||||
// Encoding represents interface for vnc encoding
|
||||
type Encoding interface {
|
||||
Type() EncodingType
|
||||
Read(Conn, *Rectangle) error
|
||||
@ -99,3 +104,11 @@ func getBit(n uint8, pos uint8) uint8 {
|
||||
n = n & (1 << pos)
|
||||
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
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ func (enc *AtenHermon) Read(c Conn, rect *Rectangle) error {
|
||||
for aten_length > 0 {
|
||||
switch aten_type {
|
||||
case 0: //subrects
|
||||
panic("unknown subrect")
|
||||
var a uint16
|
||||
var b uint16
|
||||
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))
|
||||
panic("subrect!")
|
||||
case 1: //raw
|
||||
fmt.Printf("raw reader %d %s\n", aten_length, rect)
|
||||
encRaw := &RawEncoding{}
|
||||
|
45
encoding_cursor.go
Normal file
45
encoding_cursor.go
Normal 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
|
||||
}
|
25
handlers.go
25
handlers.go
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ClientHandler represents client handler
|
||||
type ClientHandler interface {
|
||||
Handle(Conn) error
|
||||
}
|
||||
@ -17,6 +18,7 @@ type ClientMessage interface {
|
||||
Write(Conn) error
|
||||
}
|
||||
|
||||
// ServerHandler represents server handler
|
||||
type ServerHandler interface {
|
||||
Handle(Conn) error
|
||||
}
|
||||
@ -29,14 +31,19 @@ type ServerMessage interface {
|
||||
Write(Conn) error
|
||||
}
|
||||
|
||||
// ProtoVersionLength protocol version length
|
||||
const ProtoVersionLength = 12
|
||||
|
||||
const (
|
||||
// ProtoVersionUnknown unknown version
|
||||
ProtoVersionUnknown = ""
|
||||
// ProtoVersion33 sets if proto 003.003
|
||||
ProtoVersion33 = "RFB 003.003\n"
|
||||
// ProtoVersion38 sets if proto 003.008
|
||||
ProtoVersion38 = "RFB 003.008\n"
|
||||
)
|
||||
|
||||
// ParseProtoVersion parse protocol version
|
||||
func ParseProtoVersion(pv []byte) (uint, uint, error) {
|
||||
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)
|
||||
if l != 2 {
|
||||
return 0, 0, fmt.Errorf("error parsing ProtocolVersion.")
|
||||
return 0, 0, fmt.Errorf("error parsing protocol version")
|
||||
}
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
@ -55,8 +62,10 @@ func ParseProtoVersion(pv []byte) (uint, uint, error) {
|
||||
return major, minor, nil
|
||||
}
|
||||
|
||||
// DefaultClientVersionHandler represents default handler
|
||||
type DefaultClientVersionHandler struct{}
|
||||
|
||||
// Handle provide version handler for client side
|
||||
func (*DefaultClientVersionHandler) Handle(c Conn) error {
|
||||
var version [ProtoVersionLength]byte
|
||||
|
||||
@ -88,8 +97,10 @@ func (*DefaultClientVersionHandler) Handle(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// DefaultServerVersionHandler represents default server handler
|
||||
type DefaultServerVersionHandler struct{}
|
||||
|
||||
// Handle provide server version handler
|
||||
func (*DefaultServerVersionHandler) Handle(c Conn) error {
|
||||
var version [ProtoVersionLength]byte
|
||||
if err := binary.Write(c, binary.BigEndian, []byte(ProtoVersion38)); err != nil {
|
||||
@ -122,8 +133,10 @@ func (*DefaultServerVersionHandler) Handle(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultClientSecurityHandler used for client security handler
|
||||
type DefaultClientSecurityHandler struct{}
|
||||
|
||||
// Handle provide client side security handler
|
||||
func (*DefaultClientSecurityHandler) Handle(c Conn) error {
|
||||
cfg := c.Config().(*ClientConfig)
|
||||
var numSecurityTypes uint8
|
||||
@ -177,8 +190,10 @@ func (*DefaultClientSecurityHandler) Handle(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultServerSecurityHandler used for server security handler
|
||||
type DefaultServerSecurityHandler struct{}
|
||||
|
||||
// Handle provide server side security handler
|
||||
func (*DefaultServerSecurityHandler) Handle(c Conn) error {
|
||||
cfg := c.Config().(*ServerConfig)
|
||||
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
|
||||
}
|
||||
|
||||
// DefaultClientServerInitHandler default client server init handler
|
||||
type DefaultClientServerInitHandler struct{}
|
||||
|
||||
// Handle provide default server init handler
|
||||
func (*DefaultClientServerInitHandler) Handle(c Conn) error {
|
||||
srvInit := ServerInit{}
|
||||
|
||||
@ -320,8 +337,10 @@ func (*DefaultClientServerInitHandler) Handle(c Conn) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultServerServerInitHandler default server server init handler
|
||||
type DefaultServerServerInitHandler struct{}
|
||||
|
||||
// Handle provide default server server init handler
|
||||
func (*DefaultServerServerInitHandler) Handle(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, c.Width()); err != nil {
|
||||
return err
|
||||
@ -341,8 +360,10 @@ func (*DefaultServerServerInitHandler) Handle(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// DefaultClientClientInitHandler default client client init handler
|
||||
type DefaultClientClientInitHandler struct{}
|
||||
|
||||
// Handle provide default client client init handler
|
||||
func (*DefaultClientClientInitHandler) Handle(c Conn) error {
|
||||
cfg := c.Config().(*ClientConfig)
|
||||
var shared uint8
|
||||
@ -357,8 +378,10 @@ func (*DefaultClientClientInitHandler) Handle(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// DefaultServerClientInitHandler default server client init handler
|
||||
type DefaultServerClientInitHandler struct{}
|
||||
|
||||
// Handle provide default server client init handler
|
||||
func (*DefaultServerClientInitHandler) Handle(c Conn) error {
|
||||
var shared uint8
|
||||
if err := binary.Read(c, binary.BigEndian, &shared); err != nil {
|
||||
|
127
image.go
127
image.go
@ -17,9 +17,10 @@ type Color struct {
|
||||
R, G, B uint16
|
||||
}
|
||||
|
||||
// ColorMap represent color map
|
||||
type ColorMap [256]Color
|
||||
|
||||
// NewColor returns a new Color object.
|
||||
// NewColor returns a new Color object
|
||||
func NewColor(pf *PixelFormat, cm *ColorMap) *Color {
|
||||
return &Color{
|
||||
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 {
|
||||
X, Y uint16
|
||||
Width, Height uint16
|
||||
@ -35,14 +36,17 @@ type Rectangle struct {
|
||||
Enc Encoding
|
||||
}
|
||||
|
||||
// String return string representation
|
||||
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)
|
||||
}
|
||||
|
||||
// NewRectangle returns new rectangle
|
||||
func NewRectangle() *Rectangle {
|
||||
return &Rectangle{}
|
||||
}
|
||||
|
||||
// Write marshal color to conn
|
||||
func (clr *Color) Write(c Conn) error {
|
||||
var err error
|
||||
order := clr.pf.order()
|
||||
@ -65,32 +69,7 @@ func (clr *Color) Write(c Conn) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Marshal implements the Marshaler interface.
|
||||
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
|
||||
}
|
||||
|
||||
// Read unmarshal color from conn
|
||||
func (clr *Color) Read(c Conn) error {
|
||||
order := clr.pf.order()
|
||||
var pixel uint32
|
||||
@ -127,36 +106,6 @@ func (clr *Color) Read(c Conn) error {
|
||||
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 {
|
||||
rect := image.Rect(int(x), int(y), int(x+width), int(y+height))
|
||||
rgba := image.NewRGBA64(rect)
|
||||
@ -174,72 +123,76 @@ func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 {
|
||||
return rgba
|
||||
}
|
||||
|
||||
// Marshal implements the Marshaler interface.
|
||||
func (r *Rectangle) Write(c Conn) error {
|
||||
|
||||
// Write marshal rectangle to conn
|
||||
func (rect *Rectangle) Write(c Conn) 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
|
||||
}
|
||||
if err = binary.Write(c, binary.BigEndian, r.Y); err != nil {
|
||||
if err = binary.Write(c, binary.BigEndian, rect.Y); err != nil {
|
||||
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
|
||||
}
|
||||
if err = binary.Write(c, binary.BigEndian, r.Height); err != nil {
|
||||
if err = binary.Write(c, binary.BigEndian, rect.Height); err != nil {
|
||||
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 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
|
||||
if err = binary.Read(c, binary.BigEndian, &r.X); err != nil {
|
||||
|
||||
if err = binary.Read(c, binary.BigEndian, &rect.X); err != nil {
|
||||
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
|
||||
}
|
||||
if err = binary.Read(c, binary.BigEndian, &r.Width); err != nil {
|
||||
if err = binary.Read(c, binary.BigEndian, &rect.Width); err != nil {
|
||||
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
|
||||
}
|
||||
if err = binary.Read(c, binary.BigEndian, &r.EncType); err != nil {
|
||||
if err = binary.Read(c, binary.BigEndian, &rect.EncType); err != nil {
|
||||
return err
|
||||
}
|
||||
switch r.EncType {
|
||||
|
||||
switch rect.EncType {
|
||||
case EncCopyRect:
|
||||
r.Enc = &CopyRectEncoding{}
|
||||
rect.Enc = &CopyRectEncoding{}
|
||||
case EncTight:
|
||||
r.Enc = &TightEncoding{}
|
||||
rect.Enc = &TightEncoding{}
|
||||
case EncTightPng:
|
||||
r.Enc = &TightPngEncoding{}
|
||||
rect.Enc = &TightPngEncoding{}
|
||||
case EncRaw:
|
||||
if c.Protocol() == "aten" {
|
||||
r.Enc = &AtenHermon{}
|
||||
rect.Enc = &AtenHermon{}
|
||||
} else {
|
||||
r.Enc = &RawEncoding{}
|
||||
rect.Enc = &RawEncoding{}
|
||||
}
|
||||
case EncDesktopSizePseudo:
|
||||
r.Enc = &DesktopSizePseudoEncoding{}
|
||||
rect.Enc = &DesktopSizePseudoEncoding{}
|
||||
case EncDesktopNamePseudo:
|
||||
r.Enc = &DesktopNamePseudoEncoding{}
|
||||
rect.Enc = &DesktopNamePseudoEncoding{}
|
||||
case EncXCursorPseudo:
|
||||
r.Enc = &XCursorPseudoEncoding{}
|
||||
rect.Enc = &XCursorPseudoEncoding{}
|
||||
case EncAtenHermon:
|
||||
r.Enc = &AtenHermon{}
|
||||
rect.Enc = &AtenHermon{}
|
||||
default:
|
||||
return fmt.Errorf("unsupported encoding %s", r.EncType)
|
||||
return fmt.Errorf("unsupported encoding %s", rect.EncType)
|
||||
}
|
||||
return r.Enc.Read(c, r)
|
||||
|
||||
return rect.Enc.Read(c, rect)
|
||||
}
|
||||
|
||||
// Area returns the total area in pixels of the Rectangle.
|
||||
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) }
|
||||
|
121
messages.go
121
messages.go
@ -5,27 +5,43 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var DefaultClientMessages = []ClientMessage{
|
||||
var (
|
||||
// DefaultClientMessages slice of default client messages sent to server
|
||||
DefaultClientMessages = []ClientMessage{
|
||||
&SetPixelFormat{},
|
||||
&SetEncodings{},
|
||||
&FramebufferUpdateRequest{},
|
||||
&KeyEvent{},
|
||||
&PointerEvent{},
|
||||
&ClientCutText{},
|
||||
}
|
||||
}
|
||||
|
||||
type ServerInit struct {
|
||||
FBWidth, FBHeight uint16
|
||||
PixelFormat PixelFormat
|
||||
NameLength uint32
|
||||
NameText []byte
|
||||
}
|
||||
// DefaultServerMessages slice of default server messages sent to client
|
||||
DefaultServerMessages = []ServerMessage{
|
||||
&FramebufferUpdate{},
|
||||
&SetColorMapEntries{},
|
||||
&Bell{},
|
||||
&ServerCutText{},
|
||||
}
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
// ClientMessageType represents a Client-to-Server RFB message type.
|
||||
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
|
||||
|
||||
//go:generate stringer -type=ServerMessageType
|
||||
@ -38,6 +54,19 @@ const (
|
||||
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.
|
||||
type FramebufferUpdate struct {
|
||||
_ [1]byte // pad
|
||||
@ -45,14 +74,17 @@ type FramebufferUpdate struct {
|
||||
Rects []*Rectangle // rectangles
|
||||
}
|
||||
|
||||
// String provide stringer
|
||||
func (msg *FramebufferUpdate) String() string {
|
||||
return fmt.Sprintf("rects %d rectangle[]: { %v }", msg.NumRect, msg.Rects)
|
||||
}
|
||||
|
||||
// Type return ServerMessageType
|
||||
func (*FramebufferUpdate) Type() ServerMessageType {
|
||||
return FramebufferUpdateMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
|
||||
msg := FramebufferUpdate{}
|
||||
var pad [1]byte
|
||||
@ -73,6 +105,7 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshals message to conn
|
||||
func (msg *FramebufferUpdate) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -92,20 +125,24 @@ func (msg *FramebufferUpdate) Write(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// ServerCutText represents server message
|
||||
type ServerCutText struct {
|
||||
_ [1]byte
|
||||
Length uint32
|
||||
Text []byte
|
||||
}
|
||||
|
||||
// String returns string
|
||||
func (msg *ServerCutText) String() string {
|
||||
return fmt.Sprintf("lenght: %d text: %s", msg.Length, msg.Text)
|
||||
}
|
||||
|
||||
// Type returns ServerMessageType
|
||||
func (*ServerCutText) Type() ServerMessageType {
|
||||
return ServerCutTextMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*ServerCutText) Read(c Conn) (ServerMessage, error) {
|
||||
msg := ServerCutText{}
|
||||
|
||||
@ -125,6 +162,7 @@ func (*ServerCutText) Read(c Conn) (ServerMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *ServerCutText) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -147,20 +185,25 @@ func (msg *ServerCutText) Write(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// Bell server message
|
||||
type Bell struct{}
|
||||
|
||||
// String return string
|
||||
func (*Bell) String() string {
|
||||
return fmt.Sprintf("bell")
|
||||
}
|
||||
|
||||
// Type returns ServerMessageType
|
||||
func (*Bell) Type() ServerMessageType {
|
||||
return BellMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*Bell) Read(c Conn) (ServerMessage, error) {
|
||||
return &Bell{}, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *Bell) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -168,6 +211,7 @@ func (msg *Bell) Write(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// SetColorMapEntries server message
|
||||
type SetColorMapEntries struct {
|
||||
_ [1]byte
|
||||
FirstColor uint16
|
||||
@ -175,14 +219,17 @@ type SetColorMapEntries struct {
|
||||
Colors []Color
|
||||
}
|
||||
|
||||
// String returns string
|
||||
func (msg *SetColorMapEntries) String() string {
|
||||
return fmt.Sprintf("first color: %d, numcolors: %d, colors[]: { %v }", msg.FirstColor, msg.ColorsNum, msg.Colors)
|
||||
}
|
||||
|
||||
// Type returns ServerMessageType
|
||||
func (*SetColorMapEntries) Type() ServerMessageType {
|
||||
return SetColorMapEntriesMsgType
|
||||
}
|
||||
|
||||
// Read unmrashal message from conn
|
||||
func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) {
|
||||
msg := SetColorMapEntries{}
|
||||
var pad [1]byte
|
||||
@ -212,6 +259,7 @@ func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *SetColorMapEntries) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -242,43 +290,23 @@ func (msg *SetColorMapEntries) Write(c Conn) error {
|
||||
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.
|
||||
type SetPixelFormat struct {
|
||||
_ [3]byte // padding
|
||||
PF PixelFormat // pixel-format
|
||||
}
|
||||
|
||||
// String returns string
|
||||
func (msg *SetPixelFormat) String() string {
|
||||
return fmt.Sprintf("%s", msg.PF)
|
||||
}
|
||||
|
||||
// Type returns ClientMessageType
|
||||
func (*SetPixelFormat) Type() ClientMessageType {
|
||||
return SetPixelFormatMsgType
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *SetPixelFormat) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -297,6 +325,7 @@ func (msg *SetPixelFormat) Write(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*SetPixelFormat) Read(c Conn) (ClientMessage, error) {
|
||||
msg := SetPixelFormat{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
@ -312,14 +341,17 @@ type SetEncodings struct {
|
||||
Encodings []EncodingType
|
||||
}
|
||||
|
||||
// String return string
|
||||
func (msg *SetEncodings) String() string {
|
||||
return fmt.Sprintf("encnum: %d, encodings[]: { %v }", msg.EncNum, msg.Encodings)
|
||||
}
|
||||
|
||||
// Type returns ClientMessageType
|
||||
func (*SetEncodings) Type() ClientMessageType {
|
||||
return SetEncodingsMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*SetEncodings) Read(c Conn) (ClientMessage, error) {
|
||||
msg := SetEncodings{}
|
||||
var pad [1]byte
|
||||
@ -341,6 +373,7 @@ func (*SetEncodings) Read(c Conn) (ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *SetEncodings) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -372,14 +405,17 @@ type FramebufferUpdateRequest struct {
|
||||
Width, Height uint16 // width, height
|
||||
}
|
||||
|
||||
// String returns 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)
|
||||
}
|
||||
|
||||
// Type returns ClientMessageType
|
||||
func (*FramebufferUpdateRequest) Type() ClientMessageType {
|
||||
return FramebufferUpdateRequestMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*FramebufferUpdateRequest) Read(c Conn) (ClientMessage, error) {
|
||||
msg := FramebufferUpdateRequest{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
@ -388,6 +424,7 @@ func (*FramebufferUpdateRequest) Read(c Conn) (ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *FramebufferUpdateRequest) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -405,14 +442,17 @@ type KeyEvent struct {
|
||||
Key Key // key
|
||||
}
|
||||
|
||||
// String returns string
|
||||
func (msg *KeyEvent) String() string {
|
||||
return fmt.Sprintf("down: %d, key: %v", msg.Down, msg.Key)
|
||||
}
|
||||
|
||||
// Type returns ClientMessageType
|
||||
func (*KeyEvent) Type() ClientMessageType {
|
||||
return KeyEventMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*KeyEvent) Read(c Conn) (ClientMessage, error) {
|
||||
msg := KeyEvent{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
@ -421,6 +461,7 @@ func (*KeyEvent) Read(c Conn) (ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *KeyEvent) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -431,20 +472,23 @@ func (msg *KeyEvent) Write(c Conn) error {
|
||||
return c.Flush()
|
||||
}
|
||||
|
||||
// PointerEventMessage holds the wire format message.
|
||||
// PointerEvent message holds the wire format message
|
||||
type PointerEvent struct {
|
||||
Mask uint8 // button-mask
|
||||
X, Y uint16 // x-, y-position
|
||||
}
|
||||
|
||||
// String returns string
|
||||
func (msg *PointerEvent) String() string {
|
||||
return fmt.Sprintf("mask %d, x: %d, y: %d", msg.Mask, msg.X, msg.Y)
|
||||
}
|
||||
|
||||
// Type returns ClientMessageType
|
||||
func (*PointerEvent) Type() ClientMessageType {
|
||||
return PointerEventMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*PointerEvent) Read(c Conn) (ClientMessage, error) {
|
||||
msg := PointerEvent{}
|
||||
if err := binary.Read(c, binary.BigEndian, &msg); err != nil {
|
||||
@ -453,6 +497,7 @@ func (*PointerEvent) Read(c Conn) (ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *PointerEvent) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
@ -470,14 +515,17 @@ type ClientCutText struct {
|
||||
Text []byte
|
||||
}
|
||||
|
||||
// String returns string
|
||||
func (msg *ClientCutText) String() string {
|
||||
return fmt.Sprintf("length: %d, text: %s", msg.Length, msg.Text)
|
||||
}
|
||||
|
||||
// Type returns ClientMessageType
|
||||
func (*ClientCutText) Type() ClientMessageType {
|
||||
return ClientCutTextMsgType
|
||||
}
|
||||
|
||||
// Read unmarshal message from conn
|
||||
func (*ClientCutText) Read(c Conn) (ClientMessage, error) {
|
||||
msg := ClientCutText{}
|
||||
var pad [3]byte
|
||||
@ -496,6 +544,7 @@ func (*ClientCutText) Read(c Conn) (ClientMessage, error) {
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// Write marshal message to conn
|
||||
func (msg *ClientCutText) Write(c Conn) error {
|
||||
if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil {
|
||||
return err
|
||||
|
@ -10,13 +10,17 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
PixelFormat8bit PixelFormat = NewPixelFormat(8)
|
||||
PixelFormat16bit PixelFormat = NewPixelFormat(16)
|
||||
PixelFormat32bit PixelFormat = NewPixelFormat(32)
|
||||
PixelFormatAten PixelFormat = NewPixelFormatAten()
|
||||
// PixelFormat8bit returns 8 bit pixel format
|
||||
PixelFormat8bit = NewPixelFormat(8)
|
||||
// PixelFormat16bit returns 16 bit pixel format
|
||||
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 {
|
||||
BPP uint8 // bits-per-pixel
|
||||
Depth uint8 // depth
|
||||
@ -27,27 +31,9 @@ type PixelFormat struct {
|
||||
_ [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
|
||||
|
||||
// NewPixelFormat returns a populated PixelFormat structure.
|
||||
// NewPixelFormat returns a populated PixelFormat structure
|
||||
func NewPixelFormat(bpp uint8) PixelFormat {
|
||||
bigEndian := uint8(0)
|
||||
// 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{}}
|
||||
}
|
||||
|
||||
// NewPixelFormatAten returns Aten IKVM pixel format
|
||||
func NewPixelFormatAten() PixelFormat {
|
||||
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) {
|
||||
// Validation checks.
|
||||
switch pf.BPP {
|
||||
case 8, 16, 32:
|
||||
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 {
|
||||
@ -94,7 +81,7 @@ func (pf PixelFormat) Marshal() ([]byte, error) {
|
||||
switch pf.Depth {
|
||||
case 8, 16, 32:
|
||||
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
|
||||
@ -109,7 +96,7 @@ func (pf PixelFormat) Marshal() ([]byte, error) {
|
||||
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 {
|
||||
buf := make([]byte, pixelFormatLen)
|
||||
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)
|
||||
}
|
||||
|
||||
// Unmarshal implements the Unmarshaler interface.
|
||||
// Unmarshal implements the Unmarshaler interface
|
||||
func (pf PixelFormat) Unmarshal(data []byte) error {
|
||||
buf := bPool.Get().(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
@ -135,7 +122,7 @@ func (pf PixelFormat) Unmarshal(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
// String implements the fmt.Stringer interface
|
||||
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)
|
||||
|
43
server.go
43
server.go
@ -11,18 +11,22 @@ import (
|
||||
|
||||
var _ Conn = (*ServerConn)(nil)
|
||||
|
||||
// Config returns config for server conn
|
||||
func (c *ServerConn) Config() interface{} {
|
||||
return c.cfg
|
||||
}
|
||||
|
||||
// Conn returns underlining server net.Conn
|
||||
func (c *ServerConn) Conn() net.Conn {
|
||||
return c.c
|
||||
}
|
||||
|
||||
// Wait waits connection to close
|
||||
func (c *ServerConn) Wait() {
|
||||
<-c.quit
|
||||
}
|
||||
|
||||
// SetEncodings ??? sets server connection encodings
|
||||
func (c *ServerConn) SetEncodings(encs []EncodingType) error {
|
||||
encodings := make(map[EncodingType]Encoding)
|
||||
for _, enc := range c.cfg.Encodings {
|
||||
@ -36,14 +40,17 @@ func (c *ServerConn) SetEncodings(encs []EncodingType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetProtoVersion ??? sets proto version
|
||||
func (c *ServerConn) SetProtoVersion(pv string) {
|
||||
c.protocol = pv
|
||||
}
|
||||
|
||||
// Flush buffered data to server conn
|
||||
func (c *ServerConn) Flush() error {
|
||||
return c.bw.Flush()
|
||||
}
|
||||
|
||||
// Close closing server conn
|
||||
func (c *ServerConn) Close() error {
|
||||
if c.quit != nil {
|
||||
close(c.quit)
|
||||
@ -52,62 +59,86 @@ func (c *ServerConn) Close() error {
|
||||
return c.c.Close()
|
||||
}
|
||||
|
||||
// Read reads data from net.Conn
|
||||
func (c *ServerConn) Read(buf []byte) (int, error) {
|
||||
return c.br.Read(buf)
|
||||
}
|
||||
|
||||
// Write writes data to net.Conn, must be Flashed
|
||||
func (c *ServerConn) Write(buf []byte) (int, error) {
|
||||
return c.bw.Write(buf)
|
||||
}
|
||||
|
||||
// ColorMap returns server connection color map
|
||||
func (c *ServerConn) ColorMap() ColorMap {
|
||||
return c.colorMap
|
||||
}
|
||||
|
||||
// SetColorMap sets connection color map
|
||||
func (c *ServerConn) SetColorMap(cm ColorMap) {
|
||||
c.colorMap = cm
|
||||
}
|
||||
|
||||
// DesktopName returns connection desktop name
|
||||
func (c *ServerConn) DesktopName() []byte {
|
||||
return c.desktopName
|
||||
}
|
||||
|
||||
// PixelFormat return connection pixel format
|
||||
func (c *ServerConn) PixelFormat() PixelFormat {
|
||||
return c.pixelFormat
|
||||
}
|
||||
|
||||
// SetDesktopName sets connection desktop name
|
||||
func (c *ServerConn) SetDesktopName(name []byte) {
|
||||
copy(c.desktopName, name)
|
||||
}
|
||||
|
||||
// SetPixelFormat sets pixel format for server conn
|
||||
func (c *ServerConn) SetPixelFormat(pf PixelFormat) error {
|
||||
c.pixelFormat = pf
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encodings returns connection encodings
|
||||
func (c *ServerConn) Encodings() []Encoding {
|
||||
return c.encodings
|
||||
}
|
||||
|
||||
// Width returns framebuffer width
|
||||
func (c *ServerConn) Width() uint16 {
|
||||
return c.fbWidth
|
||||
}
|
||||
|
||||
// Height returns framebuffer height
|
||||
func (c *ServerConn) Height() uint16 {
|
||||
return c.fbHeight
|
||||
}
|
||||
|
||||
// Protocol returns protocol
|
||||
func (c *ServerConn) Protocol() string {
|
||||
return c.protocol
|
||||
}
|
||||
|
||||
// TODO send desktopsize pseudo encoding
|
||||
// SetWidth sets framebuffer width
|
||||
func (c *ServerConn) SetWidth(w uint16) {
|
||||
// TODO send desktopsize pseudo encoding
|
||||
c.fbWidth = w
|
||||
}
|
||||
|
||||
// SetHeight sets framebuffer height
|
||||
func (c *ServerConn) SetHeight(h uint16) {
|
||||
// TODO send desktopsize pseudo encoding
|
||||
c.fbHeight = h
|
||||
}
|
||||
|
||||
// ServerConn underlining server conn
|
||||
type ServerConn struct {
|
||||
c net.Conn
|
||||
cfg *ServerConfig
|
||||
br *bufio.Reader
|
||||
bw *bufio.Writer
|
||||
protocol string
|
||||
m sync.Mutex
|
||||
// If the pixel format uses a color map, then this is the color
|
||||
// map that is used. This should not be modified directly, since
|
||||
// the data comes from the server.
|
||||
@ -136,7 +167,8 @@ type ServerConn struct {
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultServerHandlers []ServerHandler = []ServerHandler{
|
||||
// DefaultServerHandlers uses default handlers for hanshake
|
||||
DefaultServerHandlers = []ServerHandler{
|
||||
&DefaultServerVersionHandler{},
|
||||
&DefaultServerSecurityHandler{},
|
||||
&DefaultServerClientInitHandler{},
|
||||
@ -145,6 +177,7 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// ServerConfig config struct
|
||||
type ServerConfig struct {
|
||||
Handlers []ServerHandler
|
||||
SecurityHandlers []SecurityHandler
|
||||
@ -160,6 +193,7 @@ type ServerConfig struct {
|
||||
ErrorCh chan error
|
||||
}
|
||||
|
||||
// NewServerConn returns new Server connection fron net.Conn
|
||||
func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
|
||||
return &ServerConn{
|
||||
c: c,
|
||||
@ -175,6 +209,7 @@ func NewServerConn(c net.Conn, cfg *ServerConfig) (*ServerConn, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Serve serves requests from net.Listener using ServerConfig
|
||||
func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error {
|
||||
for {
|
||||
|
||||
@ -204,8 +239,10 @@ func Serve(ctx context.Context, ln net.Listener, cfg *ServerConfig) error {
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultServerMessageHandler default package handler
|
||||
type DefaultServerMessageHandler struct{}
|
||||
|
||||
// Handle handles messages from clients
|
||||
func (*DefaultServerMessageHandler) Handle(c Conn) error {
|
||||
cfg := c.Config().(*ServerConfig)
|
||||
var err error
|
||||
|
Loading…
Reference in New Issue
Block a user