forked from xyproto/wallutils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xinfo.go
72 lines (68 loc) · 1.72 KB
/
xinfo.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
package wallutils
// #cgo LDFLAGS: -lX11
// #include "xinfo.h"
import "C"
import (
"errors"
"strconv"
"strings"
)
func XCanConnect() bool {
return bool(C.X11Running())
}
func XInfo() (string, error) {
if !XCanConnect() {
return "", errors.New("XInfo(): not connected over X11")
}
infoString := C.GoString(C.X11InfoString())
return infoString, nil
}
// Monitor enumerates the monitors and returns a slice of structs,
// including the resolution.
func XMonitors(IDs, widths, heights, wDPIs, hDPIs *[]uint) error {
if !XCanConnect() {
return errors.New("XMonitors(): not connected over X11")
}
info, err := XInfo()
if err != nil {
return err
}
var counter uint
// TODO: Write a C implementation instead of parsing the info string
for _, line := range strings.Split(info, "\n") {
if strings.Contains(line, "dimensions:") {
fields := strings.Fields(line)
if len(fields) > 2 && strings.Contains(fields[1], "x") {
resFields := strings.SplitN(fields[1], "x", 2)
w, err := strconv.Atoi(resFields[0])
if err != nil {
return err
}
h, err := strconv.Atoi(resFields[1])
if err != nil {
return err
}
*IDs = append(*IDs, counter)
*widths = append(*widths, uint(w))
*heights = append(*heights, uint(h))
counter++
}
} else if strings.Contains(line, "resolution:") {
fields := strings.Fields(line)
if len(fields) > 2 && strings.Contains(fields[1], "x") {
dpiFields := strings.SplitN(fields[1], "x", 2)
wDPI, err := strconv.Atoi(dpiFields[0])
if err != nil {
return err
}
hDPI, err := strconv.Atoi(dpiFields[1])
if err != nil {
return err
}
*wDPIs = append(*wDPIs, uint(wDPI))
*hDPIs = append(*hDPIs, uint(hDPI))
}
}
}
return nil
}