package server import ( "encoding/binary" "io" "github.com/amitbet/vncproxy/common" ) // Key represents a VNC key press. type Key uint32 //go:generate stringer -type=Key // Keys is a slice of Key values. type Keys []Key // MsgSetPixelFormat holds the wire format message. type MsgSetPixelFormat struct { _ [3]byte // padding PF common.PixelFormat // pixel-format _ [3]byte // padding after pixel format } func (*MsgSetPixelFormat) Type() common.ClientMessageType { return common.SetPixelFormatMsgType } func (msg *MsgSetPixelFormat) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } //pf := c.CurrentPixelFormat() // Invalidate the color map. // if pf.TrueColor { // c.SetColorMap(&common.ColorMap{}) // } return nil } func (*MsgSetPixelFormat) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgSetPixelFormat{} if err := binary.Read(c, binary.BigEndian, &msg); err != nil { return nil, err } return &msg, nil } // MsgSetEncodings holds the wire format message, sans encoding-type field. type MsgSetEncodings struct { _ [1]byte // padding EncNum uint16 // number-of-encodings Encodings []common.EncodingType } func (*MsgSetEncodings) Type() common.ClientMessageType { return common.SetEncodingsMsgType } func (*MsgSetEncodings) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgSetEncodings{} var pad [1]byte if err := binary.Read(c, binary.BigEndian, &pad); err != nil { return nil, err } if err := binary.Read(c, binary.BigEndian, &msg.EncNum); err != nil { return nil, err } var enc common.EncodingType for i := uint16(0); i < msg.EncNum; i++ { if err := binary.Read(c, binary.BigEndian, &enc); err != nil { return nil, err } msg.Encodings = append(msg.Encodings, enc) } c.(common.IServerConn).SetEncodings(msg.Encodings) return &msg, nil } func (msg *MsgSetEncodings) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } var pad [1]byte if err := binary.Write(c, binary.BigEndian, pad); err != nil { return err } if uint16(len(msg.Encodings)) > msg.EncNum { msg.EncNum = uint16(len(msg.Encodings)) } if err := binary.Write(c, binary.BigEndian, msg.EncNum); err != nil { return err } for _, enc := range msg.Encodings { if err := binary.Write(c, binary.BigEndian, enc); err != nil { return err } } return nil } // MsgFramebufferUpdateRequest holds the wire format message. type MsgFramebufferUpdateRequest struct { Inc uint8 // incremental X, Y uint16 // x-, y-position Width, Height uint16 // width, height } func (*MsgFramebufferUpdateRequest) Type() common.ClientMessageType { return common.FramebufferUpdateRequestMsgType } func (*MsgFramebufferUpdateRequest) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgFramebufferUpdateRequest{} if err := binary.Read(c, binary.BigEndian, &msg); err != nil { return nil, err } return &msg, nil } func (msg *MsgFramebufferUpdateRequest) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } return nil } // MsgKeyEvent holds the wire format message. type MsgKeyEvent struct { Down uint8 // down-flag _ [2]byte // padding Key Key // key } func (*MsgKeyEvent) Type() common.ClientMessageType { return common.KeyEventMsgType } func (*MsgKeyEvent) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgKeyEvent{} if err := binary.Read(c, binary.BigEndian, &msg); err != nil { return nil, err } return &msg, nil } func (msg *MsgKeyEvent) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } return nil } // MsgKeyEvent holds the wire format message. type MsgQEMUExtKeyEvent struct { SubmessageType uint8 // submessage type DownFlag uint16 // down-flag KeySym Key // key symbol KeyCode uint32 // scan code } func (*MsgQEMUExtKeyEvent) Type() common.ClientMessageType { return common.QEMUExtendedKeyEventMsgType } func (*MsgQEMUExtKeyEvent) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgKeyEvent{} if err := binary.Read(c, binary.BigEndian, &msg); err != nil { return nil, err } return &msg, nil } func (msg *MsgQEMUExtKeyEvent) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } return nil } // PointerEventMessage holds the wire format message. type MsgPointerEvent struct { Mask uint8 // button-mask X, Y uint16 // x-, y-position } func (*MsgPointerEvent) Type() common.ClientMessageType { return common.PointerEventMsgType } func (*MsgPointerEvent) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgPointerEvent{} if err := binary.Read(c, binary.BigEndian, &msg); err != nil { return nil, err } return &msg, nil } func (msg *MsgPointerEvent) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } return nil } type MsgClientFence struct { } func (*MsgClientFence) Type() common.ClientMessageType { return common.ClientFenceMsgType } func (cf *MsgClientFence) Read(c io.Reader) (common.ClientMessage, error) { bytes := make([]byte, 3) c.Read(bytes) if _, err := c.Read(bytes); err != nil { return nil, err } var flags uint32 if err := binary.Read(c, binary.BigEndian, &flags); err != nil { return nil, err } var length uint8 if err := binary.Read(c, binary.BigEndian, &length); err != nil { return nil, err } bytes = make([]byte, length) if _, err := c.Read(bytes); err != nil { return nil, err } return cf, nil } func (msg *MsgClientFence) Write(c io.Writer) error { panic("not implemented!") } // MsgClientCutText holds the wire format message, sans the text field. type MsgClientCutText struct { _ [3]byte // padding Length uint32 // length Text []byte } func (*MsgClientCutText) Type() common.ClientMessageType { return common.ClientCutTextMsgType } func (*MsgClientCutText) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgClientCutText{} var pad [3]byte if err := binary.Read(c, binary.BigEndian, &pad); err != nil { return nil, err } if err := binary.Read(c, binary.BigEndian, &msg.Length); err != nil { return nil, err } msg.Text = make([]byte, msg.Length) if err := binary.Read(c, binary.BigEndian, &msg.Text); err != nil { return nil, err } return &msg, nil } func (msg *MsgClientCutText) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } var pad [3]byte if err := binary.Write(c, binary.BigEndian, &pad); err != nil { return err } if uint32(len(msg.Text)) > msg.Length { msg.Length = uint32(len(msg.Text)) } if err := binary.Write(c, binary.BigEndian, msg.Length); err != nil { return err } if err := binary.Write(c, binary.BigEndian, msg.Text); err != nil { return err } return nil } // MsgClientQemuExtendedKey holds the wire format message, for qemu keys type MsgClientQemuExtendedKey struct { SubType uint8 // sub type IsDown uint16 // button down indicator KeySym uint32 // key symbol KeyCode uint32 // key code } func (*MsgClientQemuExtendedKey) Type() common.ClientMessageType { return common.QEMUExtendedKeyEventMsgType } func (*MsgClientQemuExtendedKey) Read(c io.Reader) (common.ClientMessage, error) { msg := MsgClientQemuExtendedKey{} if err := binary.Read(c, binary.BigEndian, &msg); err != nil { return nil, err } return &msg, nil } func (msg *MsgClientQemuExtendedKey) Write(c io.Writer) error { if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } return nil }