Example #1
0
func newHeads(X *xgb.Conn) heads {
	var primaryHead *head
	var primaryOutput randr.Output

	root := xproto.Setup(X).DefaultScreen(X).Root
	resources, err := randr.GetScreenResourcesCurrent(X, root).Reply()
	if err != nil {
		log.Fatalf("Could not get screen resources: %s.", err)
	}

	primaryOutputReply, _ := randr.GetOutputPrimary(X, root).Reply()
	if primaryOutputReply != nil {
		primaryOutput = primaryOutputReply.Output
	}

	hds := make([]head, 0, len(resources.Outputs))
	off := make([]string, 0)
	disconnected := make([]string, 0)
	for i, output := range resources.Outputs {
		oinfo, err := randr.GetOutputInfo(X, output, 0).Reply()
		if err != nil {
			log.Fatalf("Could not get output info for screen %d: %s.", i, err)
		}
		outputName := string(oinfo.Name)

		if oinfo.Connection != randr.ConnectionConnected {
			disconnected = append(disconnected, outputName)
			continue
		}
		if oinfo.Crtc == 0 {
			off = append(off, outputName)
			continue
		}

		crtcinfo, err := randr.GetCrtcInfo(X, oinfo.Crtc, 0).Reply()
		if err != nil {
			log.Fatalf("Could not get crtc info for screen (%d, %s): %s.",
				i, outputName, err)
		}

		head := newHead(output, outputName, crtcinfo)
		if output == primaryOutput {
			primaryHead = &head
		}
		hds = append(hds, head)
	}
	if primaryHead == nil && len(hds) > 0 {
		tmp := hds[0]
		primaryHead = &tmp
	}

	hdsPrim := heads{
		primary:      primaryHead,
		heads:        hds,
		off:          off,
		disconnected: disconnected,
	}
	sort.Sort(hdsPrim)
	return hdsPrim
}
Example #2
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 #3
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 #4
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 #5
0
// OutputRect creates a Rectangle fitting the active CRTC of the given output.
// Returns the Zero Rectangle and an error if anything goes wrong. If the output
// is disabled, the ZR will be returned.
func OutputRect(X *xgbutil.XUtil, output randr.Output) (image.Rectangle, error) {
	oinfo, err := randr.GetOutputInfo(X.Conn(), output, 0).Reply()
	if err != nil {
		return image.ZR, err
	}
	if oinfo.Crtc == 0 {
		// this output is disabled
		return image.ZR, nil
	}
	crtc, err := randr.GetCrtcInfo(X.Conn(), oinfo.Crtc, 0).Reply()
	if err != nil {
		return image.ZR, err
	}

	x, y := int(crtc.X), int(crtc.Y)
	w, h := int(crtc.Width), int(crtc.Height)
	return image.Rectangle{
		image.Point{x, y},
		image.Point{x + w, y + h},
	}, 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
}