mirror of
				https://github.com/pion/mediadevices.git
				synced 2025-11-01 04:12:45 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			193 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package vnc
 | |
| 
 | |
| import (
 | |
| 	"encoding/binary"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| )
 | |
| 
 | |
| // A ServerMessage implements a message sent from the server to the client.
 | |
| type ServerMessage interface {
 | |
| 	// The type of the message that is sent down on the wire.
 | |
| 	Type() uint8
 | |
| 
 | |
| 	// Read reads the contents of the message from the reader. At the point
 | |
| 	// this is called, the message type has already been read from the reader.
 | |
| 	// This should return a new ServerMessage that is the appropriate type.
 | |
| 	Read(*ClientConn, io.Reader) (ServerMessage, error)
 | |
| }
 | |
| 
 | |
| // FramebufferUpdateMessage consists of a sequence of rectangles of
 | |
| // pixel data that the client should put into its framebuffer.
 | |
| type FramebufferUpdateMessage struct {
 | |
| 	Rectangles []Rectangle
 | |
| }
 | |
| 
 | |
| // Rectangle represents a rectangle of pixel data.
 | |
| type Rectangle struct {
 | |
| 	X      uint16
 | |
| 	Y      uint16
 | |
| 	Width  uint16
 | |
| 	Height uint16
 | |
| 	Enc    Encoding
 | |
| }
 | |
| 
 | |
| func (*FramebufferUpdateMessage) Type() uint8 {
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| func (*FramebufferUpdateMessage) Read(c *ClientConn, r io.Reader) (ServerMessage, error) {
 | |
| 	// Read off the padding
 | |
| 	var padding [1]byte
 | |
| 	if _, err := io.ReadFull(r, padding[:]); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	var numRects uint16
 | |
| 	if err := binary.Read(r, binary.BigEndian, &numRects); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	// Build the map of encodings supported
 | |
| 	encMap := make(map[int32]Encoding)
 | |
| 	for _, enc := range c.Encs {
 | |
| 		encMap[enc.Type()] = enc
 | |
| 	}
 | |
| 
 | |
| 	// We must always support the raw encoding
 | |
| 	rawEnc := new(RawEncoding)
 | |
| 	encMap[rawEnc.Type()] = rawEnc
 | |
| 
 | |
| 	rects := make([]Rectangle, numRects)
 | |
| 	for i := uint16(0); i < numRects; i++ {
 | |
| 		var encodingType int32
 | |
| 
 | |
| 		rect := &rects[i]
 | |
| 		data := []any{
 | |
| 			&rect.X,
 | |
| 			&rect.Y,
 | |
| 			&rect.Width,
 | |
| 			&rect.Height,
 | |
| 			&encodingType,
 | |
| 		}
 | |
| 
 | |
| 		for _, val := range data {
 | |
| 			if err := binary.Read(r, binary.BigEndian, val); err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		enc, ok := encMap[encodingType]
 | |
| 		if !ok {
 | |
| 			return nil, fmt.Errorf("unsupported encoding type: %d", encodingType)
 | |
| 		}
 | |
| 
 | |
| 		var err error
 | |
| 		rect.Enc, err = enc.Read(c, rect, r)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return &FramebufferUpdateMessage{rects}, nil
 | |
| }
 | |
| 
 | |
| // SetColorMapEntriesMessage is sent by the server to set values into
 | |
| // the color map. This message will automatically update the color map
 | |
| // for the associated connection, but contains the color change data
 | |
| // if the consumer wants to read it.
 | |
| //
 | |
| // See RFC 6143 Section 7.6.2
 | |
| type SetColorMapEntriesMessage struct {
 | |
| 	FirstColor uint16
 | |
| 	Colors     []Color
 | |
| }
 | |
| 
 | |
| func (*SetColorMapEntriesMessage) Type() uint8 {
 | |
| 	return 1
 | |
| }
 | |
| 
 | |
| func (*SetColorMapEntriesMessage) Read(c *ClientConn, r io.Reader) (ServerMessage, error) {
 | |
| 	// Read off the padding
 | |
| 	var padding [1]byte
 | |
| 	if _, err := io.ReadFull(r, padding[:]); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	var result SetColorMapEntriesMessage
 | |
| 	if err := binary.Read(r, binary.BigEndian, &result.FirstColor); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	var numColors uint16
 | |
| 	if err := binary.Read(r, binary.BigEndian, &numColors); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	result.Colors = make([]Color, numColors)
 | |
| 	for i := uint16(0); i < numColors; i++ {
 | |
| 
 | |
| 		color := &result.Colors[i]
 | |
| 		data := []any{
 | |
| 			&color.R,
 | |
| 			&color.G,
 | |
| 			&color.B,
 | |
| 		}
 | |
| 
 | |
| 		for _, val := range data {
 | |
| 			if err := binary.Read(r, binary.BigEndian, val); err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Update the connection's color map
 | |
| 		c.ColorMap[result.FirstColor+i] = *color
 | |
| 	}
 | |
| 
 | |
| 	return &result, nil
 | |
| }
 | |
| 
 | |
| // Bell signals that an audible bell should be made on the client.
 | |
| //
 | |
| // See RFC 6143 Section 7.6.3
 | |
| type BellMessage byte
 | |
| 
 | |
| func (*BellMessage) Type() uint8 {
 | |
| 	return 2
 | |
| }
 | |
| 
 | |
| func (*BellMessage) Read(*ClientConn, io.Reader) (ServerMessage, error) {
 | |
| 	return new(BellMessage), nil
 | |
| }
 | |
| 
 | |
| // ServerCutTextMessage indicates the server has new text in the cut buffer.
 | |
| //
 | |
| // See RFC 6143 Section 7.6.4
 | |
| type ServerCutTextMessage struct {
 | |
| 	Text string
 | |
| }
 | |
| 
 | |
| func (*ServerCutTextMessage) Type() uint8 {
 | |
| 	return 3
 | |
| }
 | |
| 
 | |
| func (*ServerCutTextMessage) Read(c *ClientConn, r io.Reader) (ServerMessage, error) {
 | |
| 	// Read off the padding
 | |
| 	var padding [3]byte
 | |
| 	if _, err := io.ReadFull(r, padding[:]); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	var textLength uint32
 | |
| 	if err := binary.Read(r, binary.BigEndian, &textLength); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	textBytes := make([]uint8, textLength)
 | |
| 	if err := binary.Read(r, binary.BigEndian, &textBytes); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return &ServerCutTextMessage{string(textBytes)}, nil
 | |
| }
 | 
