Example #1
0
func connect(c *xgb.Conn, s *xproto.ScreenInfo, rl_execute_atom xproto.Atom, args []string) {
	log.Println("Connecting with args:", args)

	tree, err := xproto.QueryTree(c, s.Root).Reply()
	if err != nil {
		log.Panic("QueryTree failed:", err)
	}

	// Broadcast a property request to every window
	results := make([]xproto.GetPropertyCookie, len(tree.Children))
	for ch, child := range tree.Children {
		results[ch] = xproto.GetProperty(c, false, child,
			rl_execute_atom, xproto.GetPropertyTypeAny, 0, 1024)
	}

	success := false
	// Get the responses, look for windows that can recieve our command
	for i, r := range results {
		reply, err := r.Reply()
		if err != nil {
			log.Panic("GetPropertyRequest failed:", err)
		}
		if reply.Format != 0 {
			data := []byte(strings.Join(args, "\x00"))
			err = xproto.ChangePropertyChecked(c, xproto.PropModeReplace, tree.Children[i],
				rl_execute_atom, xproto.AtomString, 8, uint32(len(data)), data).Check()
			log.Println(" .. sent")
			success = true
		}
	}
	if success != true {
		log.Println(" .. server not running? atom = ", rl_execute_atom)
	}
}
Example #2
0
// currentTime forcefully causes a PropertyNotify event to fire on the root
// window, then scans the event queue and picks up the time.
//
// It is NOT SAFE to call this function in a place other than Wingo's
// initialization. Namely, this function subverts xevent's queue and reads
// events directly from X.
func currentTime(X *xgbutil.XUtil) (xproto.Timestamp, error) {
	wmClassAtom, err := xprop.Atm(X, "WM_CLASS")
	if err != nil {
		return 0, err
	}

	stringAtom, err := xprop.Atm(X, "STRING")
	if err != nil {
		return 0, err
	}

	// Make sure we're listening to PropertyChange events on the root window.
	err = xwindow.New(X, X.RootWin()).Listen(xproto.EventMaskPropertyChange)
	if err != nil {
		return 0, fmt.Errorf(
			"Could not listen to Root window events (PropertyChange): %s", err)
	}

	// Do a zero-length append on a property as suggested by ICCCM 2.1.
	err = xproto.ChangePropertyChecked(
		X.Conn(), xproto.PropModeAppend, X.RootWin(),
		wmClassAtom, stringAtom, 8, 0, nil).Check()
	if err != nil {
		return 0, err
	}

	// Now look for the PropertyNotify generated by that zero-length append
	// and return the timestamp attached to that event.
	// Note that we do this outside of xgbutil/xevent, since ownership
	// is literally the first thing we do after connecting to X.
	// (i.e., we don't have our event handling system initialized yet.)
	timeout := time.After(3 * time.Second)
	for {
		select {
		case <-timeout:
			return 0, fmt.Errorf(
				"Expected a PropertyNotify event to get a valid timestamp, " +
					"but never received one.")
		default:
			ev, err := X.Conn().PollForEvent()
			if err != nil {
				continue
			}
			if propNotify, ok := ev.(xproto.PropertyNotifyEvent); ok {
				X.TimeSet(propNotify.Time) // why not?
				return propNotify.Time, nil
			}
			time.Sleep(100 * time.Millisecond)
		}
	}
	panic("unreachable")
}
Example #3
0
func (a *atomic) ChangeProp(w xproto.Window, format byte, prop, typ string, data []byte) error {
	propAtom, err := a.Atom(prop)
	if err != nil {
		return err
	}

	typAtom, err := a.Atom(typ)
	if err != nil {
		return err
	}

	return xproto.ChangePropertyChecked(a.c, xproto.PropModeReplace, w, propAtom, typAtom, format, uint32(len(data)/(int(format)/8)), data).Check()
}
Example #4
0
func start_server(c *xgb.Conn, s *xproto.ScreenInfo, rl_execute_atom xproto.Atom) {
	win, err := xproto.NewWindowId(c)
	if err != nil {
		panic(err)
	}

	// Make a window which can be communicated with
	err = xproto.CreateWindowChecked(c, s.RootDepth, win, s.Root, 0, 0, 1, 1, 0, 0, 0, 0, nil).Check()
	if err != nil {
		panic(err)
	}

	err = xproto.ChangePropertyChecked(c, xproto.PropModeReplace, win,
		rl_execute_atom, xproto.AtomString, 8, xproto.PropModeReplace,
		[]byte("\x00")).Check()
	if err != nil {
		panic(err)
	}
	err = xproto.ChangeWindowAttributesChecked(c, win, xproto.CwEventMask, []uint32{xproto.EventMaskPropertyChange}).Check()
	if err != nil {
		panic(err)
	}

	get_execute_value := func() string {
		response, err := xproto.GetProperty(c, false, win, rl_execute_atom,
			xproto.GetPropertyTypeAny, 0, 1024).Reply()
		if err != nil {
			panic(err)
		}
		result := string(response.Value)
		return result
	}

	log.Print("Ready and waiting..")
	// Event loop
	for {
		reply, err := c.WaitForEvent()
		if err != nil {
			log.Panic("Error in event loop:", err)
		}

		switch event := reply.(type) {
		case xproto.PropertyNotifyEvent:
			if event.Window == win && event.Atom == rl_execute_atom {
				values := strings.Split(get_execute_value(), "\x00")
				run(values)
			}
		}
	}
}
Example #5
0
func initXSettings() {
	a0 := internAtom("_XSETTINGS_S0")
	if err := xp.SetSelectionOwnerChecked(xConn, desktopXWin, a0,
		xp.TimeCurrentTime).Check(); err != nil {
		log.Printf("could not set xsettings: %v", err)
		return
	}
	a1 := internAtom("_XSETTINGS_SETTINGS")
	encoded := makeEncodedXSettings()
	if err := xp.ChangePropertyChecked(xConn, xp.PropModeReplace, desktopXWin, a1, a1,
		8, uint32(len(encoded)), encoded).Check(); err != nil {
		log.Printf("could not set xsettings: %v", err)
		return
	}
}
Example #6
0
// ChangeProperty abstracts the semi-nastiness of xgb.ChangeProperty.
func ChangeProp(xu *xgbutil.XUtil, win xproto.Window, format byte, prop string,
	typ string, data []byte) error {

	propAtom, err := Atm(xu, prop)
	if err != nil {
		return err
	}

	typAtom, err := Atm(xu, typ)
	if err != nil {
		return err
	}

	return xproto.ChangePropertyChecked(xu.Conn(), xproto.PropModeReplace, win,
		propAtom, typAtom, format,
		uint32(len(data)/(int(format)/8)), data).Check()
}