/
main.go
125 lines (113 loc) · 2.54 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"flag"
"image"
"log"
"math"
"net"
"os"
"runtime/pprof"
"time"
"github.com/patdhlk/rfb"
)
var (
bindAddress = flag.String("bindAddress", ":5900", "listen on [ip]:port")
profile = flag.Bool("profile", false, "write a cpu.prof file when client disconnects")
)
const (
width = 1280
height = 720
)
func main() {
flag.Parse()
ln, err := net.Listen("tcp", *bindAddress)
if err != nil {
log.Fatal(err)
}
s := rfb.NewServer(width, height)
go func() {
err = s.Serve(ln)
log.Fatalf("rfb server failed with: %v", err)
}()
for c := range s.Conns {
handleConn(c)
}
}
func handleConn(c *rfb.Conn) {
if *profile {
f, err := os.Create("cpu.prof")
if err != nil {
log.Fatal(err)
}
err = pprof.StartCPUProfile(f)
if err != nil {
log.Fatal(err)
}
log.Printf("profiling CPU")
defer pprof.StopCPUProfile()
defer log.Printf("stopping profiling CPU")
}
// we need two different images here so the rfb library can compare two consecutive frames (and only send changed sections)
li := &rfb.LockableImage{Img: image.NewRGBA(image.Rect(0, 0, width, height))}
li2 := &rfb.LockableImage{Img: image.NewRGBA(image.Rect(0, 0, width, height))}
closec := make(chan bool)
go func() {
slide := 0
tick := time.NewTicker(time.Second / 2000)
defer tick.Stop()
haveNewFrame := false
for {
feed := c.Feed
if !haveNewFrame {
feed = nil
}
_ = feed
select {
case feed <- li:
haveNewFrame = false
// swap frames
var tmp = li
li = li2
li2 = tmp
case <-closec:
return
case <-tick.C:
slide++
li.Lock()
drawImage(li.Img.(*image.RGBA), slide)
li.Unlock()
haveNewFrame = true
}
}
}()
for e := range c.Event {
log.Printf("got event: %#v", e)
}
close(closec)
log.Printf("Client disconnected")
}
func drawImage(im *image.RGBA, anim int) {
pos := 0
const border = 50
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
var r, g, b uint8
switch {
case x < border*2.5 && x < int((1.1+math.Sin(float64(y+anim*2)/40))*border):
r = 255
case x > width-border*2.5 && x > width-int((1.1+math.Sin(math.Pi+float64(y+anim*2)/40))*border):
g = 255
case y < border*2.5 && y < int((1.1+math.Sin(float64(x+anim*2)/40))*border):
r, g = 255, 255
case y > height-border*2.5 && y > height-int((1.1+math.Sin(math.Pi+float64(x+anim*2)/40))*border):
b = 255
default:
r, g, b = uint8(x+anim), uint8(y+anim), uint8(x+y+anim*3)
}
im.Pix[pos] = r
im.Pix[pos+1] = g
im.Pix[pos+2] = b
pos += 4 // skipping alpha
}
}
}