Example #1
0
func getPrimaryScreenBestResolution() (w uint16, h uint16) {
	// if connect to x failed, just return 1024x768
	w, h = 1024, 768

	XU, err := xgbutil.NewConn()
	if err != nil {
		return
	}
	err = randr.Init(XU.Conn())
	if err != nil {
		return
	}
	_, err = randr.QueryVersion(XU.Conn(), 1, 4).Reply()
	if err != nil {
		return
	}
	Root := xproto.Setup(XU.Conn()).DefaultScreen(XU.Conn()).Root
	resources, err := randr.GetScreenResources(XU.Conn(), Root).Reply()
	if err != nil {
		return
	}

	bestModes := make([]uint32, 0)
	for _, output := range resources.Outputs {
		reply, err := randr.GetOutputInfo(XU.Conn(), output, 0).Reply()
		if err == nil && reply.NumModes > 1 {
			bestModes = append(bestModes, uint32(reply.Modes[0]))
		}
	}

	w, h = 0, 0
	for _, m := range resources.Modes {
		for _, id := range bestModes {
			if id == m.Id {
				bw, bh := m.Width, m.Height
				if w == 0 || h == 0 {
					w, h = bw, bh
				} else if uint32(bw)*uint32(bh) < uint32(w)*uint32(h) {
					w, h = bw, bh
				}
			}
		}
	}

	if w == 0 || h == 0 {
		// get resource failed, use root window's geometry
		rootRect := xwindow.RootGeometry(XU)
		w, h = uint16(rootRect.Width()), uint16(rootRect.Height())
	}

	if w == 0 || h == 0 {
		w, h = 1024, 768 // default value
	}

	logger.Debugf("primary screen's best resolution is %dx%d", w, h)
	return
}
Example #2
0
func GetOutputs(X *xgbutil.XUtil) (outputs []*randr.GetOutputInfoReply) {
	resources, err := randr.GetScreenResources(X.Conn(), X.RootWin()).Reply()
	if err != nil {
		return nil
	}
	for _, output := range resources.Outputs {
		oinfo, err := randr.GetOutputInfo(X.Conn(), output, 0).Reply()
		if err != nil {
			return nil
		}
		outputs = append(outputs, oinfo)
	}
	return outputs
}
Example #3
0
// NewBackground creates an xgraphics.Image which spans the entire screen,
// initialized to black.
func NewBackground(X *xgbutil.XUtil) (*xgraphics.Image, error) {
	res, err := randr.GetScreenResources(X.Conn(), X.RootWin()).Reply()
	if err != nil {
		return nil, err
	}
	var bgRect image.Rectangle
	for _, output := range res.Outputs {
		r, err := util.OutputRect(X, output)
		// NOTE: It doesn't really matter if this returns a Zero Rectangle.
		if err != nil {
			return nil, err
		}
		bgRect = bgRect.Union(r)
	}
	return xgraphics.New(X, bgRect), nil
}
Example #4
0
func (b *brightness) adjust(Xu *xgbutil.XUtil, increase bool) error {
	X := Xu.Conn()
	root := xproto.Setup(X).DefaultScreen(X).Root
	screens, err := randr.GetScreenResources(X, root).Reply()
	if err != nil {
		return fmt.Errorf("getting screen: %v", err)
	}

	for _, output := range screens.Outputs {
		query, err := randr.QueryOutputProperty(X, output, b.prop).Reply()
		if err != nil {
			if _, ok := err.(xproto.NameError); ok {
				// this output has no backlight
				continue
			}
			return fmt.Errorf("query backlight: %v", err)
		}
		if !query.Range {
			return errors.New("backlight brightness range not specified")
		}
		if len(query.ValidValues) != 2 {
			return fmt.Errorf("expected min and max, got: %v", query.ValidValues)
		}
		min, max := query.ValidValues[0], query.ValidValues[1]
		// log.Printf("backlight range: %d .. %d", min, max)

		get, err := randr.GetOutputProperty(X, output, b.prop, xproto.AtomNone, 0, 4, false, false).Reply()
		if err != nil {
			return fmt.Errorf("get backlight property: %v", err)
		}
		if get.Type != xproto.AtomInteger ||
			get.NumItems != 1 ||
			get.Format != 32 {
			return fmt.Errorf("backlight property value looks wrong")
		}
		old := *(*int32)(unsafe.Pointer(&get.Data[0]))
		// log.Printf("backlight data: %d", old)

		bri := delta5(old, min, max, increase)

		data := (*[4]byte)(unsafe.Pointer(&bri))[:]
		if err := randr.ChangeOutputPropertyChecked(X, output, b.prop, xproto.AtomInteger, 32, xproto.PropModeReplace, 1, data).Check(); err != nil {
			return err
		}
	}
	return nil
}
Example #5
0
// GetOutputByName fetches an output by name.
// FIXME: It's really ugly to just throw away the OutputInfo after using it. See
// if there's a better way to do this.
func GetOutputByName(X *xgbutil.XUtil, name string) (randr.Output, error) {
	res, err := randr.GetScreenResources(X.Conn(), X.RootWin()).Reply()
	if err != nil {
		return 0, err
	}
	var (
		oinfo  *randr.GetOutputInfoReply
		output randr.Output
	)
	for _, output = range res.Outputs {
		oinfo, err = randr.GetOutputInfo(X.Conn(), output, 0).Reply()
		if err != nil {
			return 0, err
		}
		// See if we've found the correct output.
		if string(oinfo.Name) == name {
			break
		}
	}
	return output, nil
}
Example #6
0
func main() {
	X, _ := xgb.NewConn()

	// Every extension must be initialized before it can be used.
	err := randr.Init(X)
	if err != nil {
		log.Fatal(err)
	}

	// Get the root window on the default screen.
	root := xproto.Setup(X).DefaultScreen(X).Root

	// Gets the current screen resources. Screen resources contains a list
	// of names, crtcs, outputs and modes, among other things.
	resources, err := randr.GetScreenResources(X, root).Reply()
	if err != nil {
		log.Fatal(err)
	}

	// Iterate through all of the outputs and show some of their info.
	for _, output := range resources.Outputs {
		info, err := randr.GetOutputInfo(X, output, 0).Reply()
		if err != nil {
			log.Fatal(err)
		}

		bestMode := info.Modes[0]
		for _, mode := range resources.Modes {
			if mode.Id == uint32(bestMode) {
				fmt.Printf("Width: %d, Height: %d\n", mode.Width, mode.Height)
			}
		}
	}

	fmt.Println("\n")

	// Iterate through all of the crtcs and show some of their info.
	for _, crtc := range resources.Crtcs {
		info, err := randr.GetCrtcInfo(X, crtc, 0).Reply()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("X: %d, Y: %d, Width: %d, Height: %d\n",
			info.X, info.Y, info.Width, info.Height)
	}

	// Tell RandR to send us events. (I think these are all of them, as of 1.3.)
	err = randr.SelectInputChecked(X, root,
		randr.NotifyMaskScreenChange|
			randr.NotifyMaskCrtcChange|
			randr.NotifyMaskOutputChange|
			randr.NotifyMaskOutputProperty).Check()
	if err != nil {
		log.Fatal(err)
	}

	// Listen to events and just dump them to standard out.
	// A more involved approach will have to read the 'U' field of
	// RandrNotifyEvent, which is a union (really a struct) of type
	// RanrNotifyDataUnion.
	for {
		ev, err := X.WaitForEvent()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(ev)
	}
}
Example #7
0
func (ms Monitors) Update(e *Euclid, x XHandle, mergeOverlapping, removeUnplugged, removeDisabled bool) bool {
	c := x.Conn()

	sres, err := randr.GetScreenResources(c, x.Root()).Reply()
	if err != nil {
		return false
	}

	var r []*randr.GetOutputInfoReply
	for _, o := range sres.Outputs {
		rp, _ := randr.GetOutputInfo(c, o, xproto.TimeCurrentTime).Reply()
		r = append(r, rp)
	}

	for _, m := range ms {
		m.wired = false
	}

	for i, info := range r {
		if info != nil {
			if info.Crtc != 0 {
				ir, _ := randr.GetCrtcInfo(c, info.Crtc, xproto.TimeCurrentTime).Reply()
				if ir != nil {
					rect := xproto.Rectangle{ir.X, ir.Y, ir.Width, ir.Height}
					m := ms.fromId(sres.Outputs[i])
					if m != nil {
						m.rectangle = rect
						m.UpdateRoot()
						for _, d := range m.desktops {
							for _, _ = range d.clients {
								//mm.Translate(mm, n.Client)
							}
						}
						//mm.Arrange()
						m.wired = true
					} else {
						m := ms.Add(e, x, rect)
						m.name = string(info.Name)
						m.id = sres.Outputs[i]
					}
				}
			} else if !removeDisabled && info.Connection != randr.ConnectionDisconnected {
				m := ms.fromId(sres.Outputs[i])
				if m != nil {
					m.wired = true
				}
			}
		}
	}

	gpo, _ := randr.GetOutputPrimary(c, x.Root()).Reply()
	if gpo != nil {
		primary := ms.fromId(gpo.Output)
		if primary != nil {
			primary.primary = true
			if ms.Focused() != primary {
				primary.focused = true
			}
			//ewmh_update_current_desktop();
		}
	}

	if mergeOverlapping {
		ms.mergeOverlapping()
	}

	if removeUnplugged {
		ms.removeUnplugged()
	}

	//update_motion_recorder();

	return ms.Number() > 0
}