File: context.go

package info (click to toggle)
golang-github-dkolbly-wl 0.0~git20180220.b06f57e-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 336 kB
  • sloc: makefile: 3
file content (129 lines) | stat: -rw-r--r-- 2,346 bytes parent folder | download
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
126
127
128
129
package wl

import (
	"context"
	"errors"
	"io"
	"log"
	"net"
	"os"
	"sync"
	"time"
)

func init() {
	log.SetFlags(0)
}

type Context struct {
	mu           sync.RWMutex
	conn         *net.UnixConn
	currentId    ProxyId
	objects      map[ProxyId]Proxy
	dispatchChan chan struct{}
	exitChan     chan struct{}
}

func (ctx *Context) Register(proxy Proxy) {
	ctx.mu.Lock()
	defer ctx.mu.Unlock()
	ctx.currentId += 1
	proxy.SetId(ctx.currentId)
	proxy.SetContext(ctx)
	ctx.objects[ctx.currentId] = proxy
}

func (ctx *Context) lookupProxy(id ProxyId) Proxy {
	ctx.mu.RLock()
	defer ctx.mu.RUnlock()
	proxy, ok := ctx.objects[id]
	if !ok {
		return nil
	}
	return proxy
}

func (ctx *Context) unregister(proxy Proxy) {
	ctx.mu.Lock()
	defer ctx.mu.Unlock()
	delete(ctx.objects, proxy.Id())
}

func (c *Context) Close() {
	c.conn.Close()
	c.exitChan <- struct{}{}
	close(c.dispatchChan)

}

func (c *Context) Dispatch() chan<- struct{} {
	return c.dispatchChan
}

func Connect(addr string) (ret *Display, err error) {
	runtime_dir := os.Getenv("XDG_RUNTIME_DIR")
	if runtime_dir == "" {
		return nil, errors.New("XDG_RUNTIME_DIR not set in the environment.")
	}
	if addr == "" {
		addr = os.Getenv("WAYLAND_DISPLAY")
	}
	if addr == "" {
		addr = "wayland-0"
	}
	addr = runtime_dir + "/" + addr
	c := new(Context)
	c.objects = make(map[ProxyId]Proxy)
	c.currentId = 0
	c.dispatchChan = make(chan struct{})
	c.exitChan = make(chan struct{})
	c.conn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: addr, Net: "unix"})
	if err != nil {
		return nil, err
	}
	c.conn.SetReadDeadline(time.Time{})
	//dispatch events in separate gorutine
	go c.run()
	return NewDisplay(c), nil
}

func (c *Context) run() {
	ctx := context.Background()

loop:
	for {
		select {
		case <-c.dispatchChan:
			ev, err := c.readEvent()
			if err != nil {
				if err == io.EOF {
					// connection closed
					break loop

				}

				if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
					log.Print("Timeout Error")
					continue
				}

				log.Fatal(err)
			}

			proxy := c.lookupProxy(ev.pid)
			if proxy != nil {
				if dispatcher, ok := proxy.(Dispatcher); ok {
					dispatcher.Dispatch(ctx, ev)
					bytePool.Give(ev.data)
				} else {
					log.Print("Not dispatched")
				}
			} else {
				log.Print("Proxy NULL")
			}

		case <-c.exitChan:
			break loop
		}
	}
}