// PhyiscalHeads returns the list of heads in a physical ordering. // Namely, left to right then top to bottom. (Defined by (X, Y).) // Xinerama must have been initialized, otherwise the xinerama.QueryScreens // request will panic. // PhysicalHeads also checks to make sure each rectangle has a unique (x, y) // tuple, so as not to return the geometry of cloned displays. // (At present moment, xgbutil initializes Xinerama automatically during // initial connection.) func PhysicalHeads(xu *xgbutil.XUtil) (Heads, error) { xinfo, err := xinerama.QueryScreens(xu.Conn()).Reply() if err != nil { return nil, err } hds := make(Heads, 0) for _, info := range xinfo.ScreenInfo { head := xrect.New(int(info.XOrg), int(info.YOrg), int(info.Width), int(info.Height)) // Maybe Xinerama is enabled, but we have cloned displays... unique := true for _, h := range hds { if h.X() == head.X() && h.Y() == head.Y() { unique = false break } } if unique { hds = append(hds, head) } } sort.Sort(hds) return hds, nil }
func (ms Monitors) Init(e *Euclid, x XHandle) (bool, bool) { var rr, xn bool c := x.Conn() err := randr.Init(c) if err == nil && ms.Update(e, x, false, false, false) { rr = true randr.SelectInputChecked(c, x.Root(), randr.NotifyMaskScreenChange) } else { rr = false err = xinerama.Init(c) if err == nil { xia, err := xinerama.IsActive(c).Reply() if xia != nil && err == nil { xn = true xsq, _ := xinerama.QueryScreens(c).Reply() xsi := xsq.ScreenInfo for i := 0; i < len(xsi); i++ { info := xsi[i] rect := xproto.Rectangle{info.XOrg, info.YOrg, info.Width, info.Height} ms.Add(e, x, rect) } } else { s := x.Screen() rect := xproto.Rectangle{0, 0, s.WidthInPixels, s.HeightInPixels} ms.Add(e, x, rect) } } } return rr, xn }
func initScreens() { xine, err := xinerama.QueryScreens(xConn).Reply() if err != nil { log.Fatal(err) } if len(xine.ScreenInfo) > 0 { screens = make([]*screen, len(xine.ScreenInfo)) for i, si := range xine.ScreenInfo { screens[i] = &screen{ rect: xp.Rectangle{ X: si.XOrg, Y: si.YOrg, Width: si.Width - 1, Height: si.Height - 1, }, } } } else { screens = make([]*screen, 1) screens[0] = &screen{ rect: xp.Rectangle{ X: 0, Y: 0, Width: desktopWidth - 1, Height: desktopHeight - 1, }, } } for _, s := range screens { k := newWorkspace(s.rect, dummyWorkspace.link[prev]) s.workspace, k.screen = k, s } }
func main() { X, err := xgb.NewConn() if err != nil { log.Fatal(err) } // Initialize the Xinerama extension. // The appropriate 'Init' function must be run for *every* // extension before any of its requests can be used. err = xinerama.Init(X) if err != nil { log.Fatal(err) } // Issue a request to get the screen information. reply, err := xinerama.QueryScreens(X).Reply() if err != nil { log.Fatal(err) } // reply.Number is the number of active heads, while reply.ScreenInfo // is a slice of XineramaScreenInfo containing the rectangle geometry // of each head. fmt.Printf("Number of heads: %d\n", reply.Number) for i, screen := range reply.ScreenInfo { fmt.Printf("%d :: X: %d, Y: %d, Width: %d, Height: %d\n", i, screen.XOrg, screen.YOrg, screen.Width, screen.Height) } }
func Load(c *xgb.Conn) error { err := xinerama.Init(c) if err != nil { return err } reply, err := xinerama.QueryScreens(c).Reply() if err != nil { return err } count = reply.Number for _, scr := range reply.ScreenInfo { sizes = append(sizes, types.Geometry{int32(scr.XOrg), int32(scr.YOrg), int32(scr.Width), int32(scr.Height)}) } return nil }