package xrandr import ( "encoding/json" "errors" "regexp" "strings" "git.milar.in/milarin/bufr" ) var ( displayConfig = regexp.MustCompile(`^(.*?-\d) (disconnected|connected)( primary)?(?: (\d*?)x(\d*?)\+(\d*?)\+(\d*?) )?(normal|inverted|left|right)?\s*?(X axis|Y axis|X and Y axis)?\s*?\(((?:normal |left |inverted |right |x axis |y axis )*(?:normal|left|inverted|right|x axis|y axis))\)(?: (\d*)mm x (\d*)mm)?$`) ) type DisplayConfig struct { Port string `json:"port"` Connected bool `json:"connected"` Primary bool `json:"primary"` Resolution *Resolution `json:"resolution"` Position *Position `json:"position"` Rotation Rotation `json:"rotation"` Reflection Reflection `json:"reflection"` RecommendedMode *DisplayMode ActiveMode *DisplayMode Modes []DisplayMode `json:"modes"` DimensionsMillimeter *Resolution `json:"-"` } func parseDisplayConfig(r *bufr.Reader) (*DisplayConfig, error) { // bufcontent := reflect.ValueOf(r).Elem().FieldByName("buf").Elem().FieldByName("values") // bufcontent = reflect.NewAt(bufcontent.Type(), unsafe.Pointer(bufcontent.UnsafeAddr())).Elem() // fmt.Printf("%#v\n", string(bufcontent.Interface().([]rune))) line, err := r.StringUntil(isNewLine) if err != nil { return nil, err } matches := displayConfig.FindStringSubmatch(line) if matches == nil { return nil, errors.New("no data") } active, recommended, modes, err := parseDisplayModes(r) if err != nil { return nil, err } return &DisplayConfig{ Port: matches[1], Connected: strings.TrimSpace(matches[2]) == "connected", Primary: strings.TrimSpace(matches[3]) == "primary", Resolution: NewResolutionFromString(matches[4], matches[5]), Position: NewPositionFromString(matches[6], matches[7]), Rotation: makeRotation(matches[8]), Reflection: MakeReflection(matches[9]), DimensionsMillimeter: NewResolutionFromString(matches[11], matches[12]), ActiveMode: active, RecommendedMode: recommended, Modes: modes, }, nil } func (c DisplayConfig) String() string { data, _ := json.MarshalIndent(c, "", "\t") return string(data) }