Пример #1
0
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
}
Пример #2
0
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)
	}
}
Пример #3
0
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
}
Пример #4
0
// NewConnXgb use the specific xgb.Conn to create a new XUtil.
//
//  NewConn, NewConnDisplay are wrapper of this function.
func NewConnXgb(c *xgb.Conn) (*XUtil, error) {
	setup := xproto.Setup(c)
	screen := setup.DefaultScreen(c)

	// Initialize our central struct that stores everything.
	xu := &XUtil{
		conn:             c,
		Quit:             false,
		Evqueue:          make([]EventOrError, 0, 1000),
		EvqueueLck:       &sync.RWMutex{},
		setup:            setup,
		screen:           screen,
		root:             screen.Root,
		eventTime:        xproto.Timestamp(0), // last event time
		Atoms:            make(map[string]xproto.Atom, 50),
		AtomsLck:         &sync.RWMutex{},
		AtomNames:        make(map[xproto.Atom]string, 50),
		AtomNamesLck:     &sync.RWMutex{},
		Callbacks:        make(map[int]map[xproto.Window][]Callback, 33),
		CallbacksLck:     &sync.RWMutex{},
		Hooks:            make([]CallbackHook, 0),
		HooksLck:         &sync.RWMutex{},
		Keymap:           nil, // we don't have anything yet
		Modmap:           nil,
		KeyRedirect:      0,
		Keybinds:         make(map[KeyKey][]CallbackKey, 10),
		KeybindsLck:      &sync.RWMutex{},
		Keygrabs:         make(map[KeyKey]int, 10),
		Keystrings:       make([]KeyString, 0, 10),
		Mousebinds:       make(map[MouseKey][]CallbackMouse, 10),
		MousebindsLck:    &sync.RWMutex{},
		Mousegrabs:       make(map[MouseKey]int, 10),
		InMouseDrag:      false,
		MouseDragStepFun: nil,
		MouseDragEndFun:  nil,
		ErrorHandler:     func(err xgb.Error) { Logger.Println(err) },
	}

	var err error = nil
	// Create a general purpose graphics context
	xu.gc, err = xproto.NewGcontextId(xu.conn)
	if err != nil {
		return nil, err
	}
	xproto.CreateGC(xu.conn, xu.gc, xproto.Drawable(xu.root),
		xproto.GcForeground, []uint32{xu.screen.WhitePixel})

	// Create a dummy window
	xu.dummy, err = xproto.NewWindowId(xu.conn)
	if err != nil {
		return nil, err
	}
	xproto.CreateWindow(xu.conn, xu.Screen().RootDepth, xu.dummy, xu.RootWin(),
		-1000, -1000, 1, 1, 0,
		xproto.WindowClassInputOutput, xu.Screen().RootVisual,
		xproto.CwEventMask|xproto.CwOverrideRedirect,
		[]uint32{1, xproto.EventMaskPropertyChange})
	xproto.MapWindow(xu.conn, xu.dummy)

	// Register the Xinerama extension... because it doesn't cost much.
	err = xinerama.Init(xu.conn)

	// If we can't register Xinerama, that's okay. Output something
	// and move on.
	if err != nil {
		Logger.Printf("WARNING: %s\n", err)
		Logger.Printf("MESSAGE: The 'xinerama' package cannot be used " +
			"because the XINERAMA extension could not be loaded.")
	}

	return xu, nil
}
Пример #5
0
func main() {
	var err error
	xConn, err = xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	if err = xinerama.Init(xConn); err != nil {
		log.Fatal(err)
	}
	xSetup := xp.Setup(xConn)
	if len(xSetup.Roots) != 1 {
		log.Fatalf("X setup has unsupported number of roots: %d", len(xSetup.Roots))
	}
	rootXWin = xSetup.Roots[0].Root

	becomeTheWM()
	initAtoms()
	initDesktop(&xSetup.Roots[0])
	initKeyboardMapping()
	initScreens()

	// Manage any existing windows.
	if tree, err := xp.QueryTree(xConn, rootXWin).Reply(); err != nil {
		log.Fatal(err)
	} else if tree != nil {
		for _, c := range tree.Children {
			if c == desktopXWin {
				continue
			}
			attrs, err := xp.GetWindowAttributes(xConn, c).Reply()
			if attrs == nil || err != nil {
				continue
			}
			if attrs.OverrideRedirect || attrs.MapState == xp.MapStateUnmapped {
				continue
			}
			manage(c, false)
		}
	}

	// Process X events.
	eeChan := make(chan xEventOrError)
	go func() {
		for {
			e, err := xConn.WaitForEvent()
			eeChan <- xEventOrError{e, err}
		}
	}()
	for {
		for i, c := range checkers {
			if err := c.Check(); err != nil {
				log.Println(err)
			}
			checkers[i] = nil
		}
		checkers = checkers[:0]

		select {
		case f := <-proactiveChan:
			f()
		case ee := <-eeChan:
			if ee.error != nil {
				log.Println(ee.error)
				continue
			}
			switch e := ee.event.(type) {
			case xp.ButtonPressEvent:
				eventTime = e.Time
				handleButtonPress(e)
			case xp.ButtonReleaseEvent:
				eventTime = e.Time
			case xp.ClientMessageEvent:
				// No-op.
			case xp.ConfigureNotifyEvent:
				// No-op.
			case xp.ConfigureRequestEvent:
				handleConfigureRequest(e)
			case xp.DestroyNotifyEvent:
				// No-op.
			case xp.EnterNotifyEvent:
				eventTime = e.Time
				handleEnterNotify(e)
			case xp.ExposeEvent:
				handleExpose(e)
			case xp.KeyPressEvent:
				eventTime, keyRootX, keyRootY, keyState = e.Time, e.RootX, e.RootY, e.State
				handleKeyPress(e)
			case xp.KeyReleaseEvent:
				eventTime, keyRootX, keyRootY, keyState = e.Time, 0, 0, 0
			case xp.MapNotifyEvent:
				// No-op.
			case xp.MappingNotifyEvent:
				// No-op.
			case xp.MapRequestEvent:
				manage(e.Window, true)
			case xp.MotionNotifyEvent:
				eventTime = e.Time
				handleMotionNotify(e)
			case xp.UnmapNotifyEvent:
				unmanage(e.Window)
			default:
				log.Printf("unhandled event: %v", ee.event)
			}
		}
	}
}