152 lines
3.2 KiB
Go
152 lines
3.2 KiB
Go
package vnc
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"io"
|
|
)
|
|
|
|
// PixelFormat describes the way a pixel is formatted for a VNC connection.
|
|
//
|
|
// See RFC 6143 Section 7.4 for information on each of the fields.
|
|
type PixelFormat struct {
|
|
BPP uint8
|
|
Depth uint8
|
|
BigEndian bool
|
|
TrueColor bool
|
|
RedMax uint16
|
|
GreenMax uint16
|
|
BlueMax uint16
|
|
RedShift uint8
|
|
GreenShift uint8
|
|
BlueShift uint8
|
|
}
|
|
|
|
func readPixelFormat(r io.Reader, result *PixelFormat) error {
|
|
var rawPixelFormat [16]byte
|
|
if _, err := io.ReadFull(r, rawPixelFormat[:]); err != nil {
|
|
return err
|
|
}
|
|
|
|
var pfBoolByte uint8
|
|
brPF := bytes.NewReader(rawPixelFormat[:])
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.BPP); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.Depth); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &pfBoolByte); err != nil {
|
|
return err
|
|
}
|
|
|
|
if pfBoolByte != 0 {
|
|
// Big endian is true
|
|
result.BigEndian = true
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &pfBoolByte); err != nil {
|
|
return err
|
|
}
|
|
|
|
if pfBoolByte != 0 {
|
|
// True Color is true. So we also have to read all the color max & shifts.
|
|
result.TrueColor = true
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.RedMax); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.GreenMax); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.BlueMax); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.RedShift); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.GreenShift); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := binary.Read(brPF, binary.BigEndian, &result.BlueShift); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func writePixelFormat(format *PixelFormat) ([]byte, error) {
|
|
var buf bytes.Buffer
|
|
|
|
// Byte 1
|
|
if err := binary.Write(&buf, binary.BigEndian, format.BPP); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Byte 2
|
|
if err := binary.Write(&buf, binary.BigEndian, format.Depth); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var boolByte byte
|
|
if format.BigEndian {
|
|
boolByte = 1
|
|
} else {
|
|
boolByte = 0
|
|
}
|
|
|
|
// Byte 3 (BigEndian)
|
|
if err := binary.Write(&buf, binary.BigEndian, boolByte); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if format.TrueColor {
|
|
boolByte = 1
|
|
} else {
|
|
boolByte = 0
|
|
}
|
|
|
|
// Byte 4 (TrueColor)
|
|
if err := binary.Write(&buf, binary.BigEndian, boolByte); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// If we have true color enabled then we have to fill in the rest of the
|
|
// structure with the color values.
|
|
if format.TrueColor {
|
|
if err := binary.Write(&buf, binary.BigEndian, format.RedMax); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := binary.Write(&buf, binary.BigEndian, format.GreenMax); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := binary.Write(&buf, binary.BigEndian, format.BlueMax); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := binary.Write(&buf, binary.BigEndian, format.RedShift); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := binary.Write(&buf, binary.BigEndian, format.GreenShift); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := binary.Write(&buf, binary.BigEndian, format.BlueShift); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return buf.Bytes()[0:16], nil
|
|
}
|