Example #1
0
// WM_HINTS get
func WmHintsGet(xu *xgbutil.XUtil,
	win xproto.Window) (hints *Hints, err error) {

	lenExpect := 9
	raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_HINTS"))
	if err != nil {
		return nil, err
	}
	if len(raw) != lenExpect {
		return nil,
			fmt.Errorf("WmHints: There are %d fields in "+
				"WM_HINTS, but xgbutil expects %d.", len(raw), lenExpect)
	}

	hints = &Hints{}
	hints.Flags = raw[0]
	hints.Input = raw[1]
	hints.InitialState = raw[2]
	hints.IconPixmap = xproto.Pixmap(raw[3])
	hints.IconWindow = xproto.Window(raw[4])
	hints.IconX = int(raw[5])
	hints.IconY = int(raw[6])
	hints.IconMask = xproto.Pixmap(raw[7])
	hints.WindowGroup = xproto.Window(raw[8])

	return hints, nil
}
Example #2
0
func main() {
	X, err := xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Get the window id of the root window.
	setup := xproto.Setup(X)
	root := setup.DefaultScreen(X).Root

	// Get the atom id (i.e., intern an atom) of "_NET_ACTIVE_WINDOW".
	aname := "_NET_ACTIVE_WINDOW"
	query1, buf := xproto.InternAtom(X, nil, true, uint16(len(aname)), aname)

	activeAtom, err := query1.Reply()
	if err != nil {
		log.Fatal(err)
	}

	// Get the atom id (i.e., intern an atom) of "_NET_WM_NAME".
	aname = "_NET_WM_NAME"
	query2, buf := xproto.InternAtom(X, buf, true, uint16(len(aname)),
		aname)
	nameAtom, err := query2.Reply()
	if err != nil {
		log.Fatal(err)
	}

	// Get the actual value of _NET_ACTIVE_WINDOW.
	// Note that 'reply.Value' is just a slice of bytes, so we use an
	// XGB helper function, 'Get32', to pull an unsigned 32-bit integer out
	// of the byte slice. We then convert it to an X resource id so it can
	// be used to get the name of the window in the next GetProperty request.
	query3, buf := xproto.GetProperty(X, buf, false, root, activeAtom.Atom,
		xproto.GetPropertyTypeAny, 0, (1<<32)-1)
	reply, err := query3.Reply()
	if err != nil {
		log.Fatal(err)
	}
	windowId := xproto.Window(xgb.Get32(reply.Value))
	fmt.Printf("Active window id: %X\n", windowId)

	// Now get the value of _NET_WM_NAME for the active window.
	// Note that this time, we simply convert the resulting byte slice,
	// reply.Value, to a string.
	query4, buf := xproto.GetProperty(X, buf, false, windowId, nameAtom.Atom,
		xproto.GetPropertyTypeAny, 0, (1<<32)-1)
	reply, err = query4.Reply()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Active window name: %s\n", string(reply.Value))
}
Example #3
0
// PropValWindow transforms a GetPropertyReply struct into an X resource
// window identifier.
// The property reply must be in 32 bit format.
func PropValWindow(reply *xproto.GetPropertyReply,
	err error) (xproto.Window, error) {

	if err != nil {
		return 0, err
	}
	if reply.Format != 32 {
		return 0, fmt.Errorf("PropValId: Expected format 32 but got %d",
			reply.Format)
	}
	return xproto.Window(xgb.Get32(reply.Value)), nil
}
Example #4
0
// WM_STATE get
func WmStateGet(xu *xgbutil.XUtil, win xproto.Window) (*WmState, error) {
	raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_STATE"))
	if err != nil {
		return nil, err
	}
	if len(raw) != 2 {
		return nil,
			fmt.Errorf("WmState: Expected two integers in WM_STATE property "+
				"but xgbutil found %d in '%v'.", len(raw), raw)
	}

	return &WmState{
		State: raw[0],
		Icon:  xproto.Window(raw[1]),
	}, nil
}
Example #5
0
// getOverlayWindowReply reads a byte slice into a GetOverlayWindowReply value.
func getOverlayWindowReply(buf []byte) *GetOverlayWindowReply {
	v := new(GetOverlayWindowReply)
	b := 1 // skip reply determinant

	b += 1 // padding

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.Length = xgb.Get32(buf[b:]) // 4-byte units
	b += 4

	v.OverlayWin = xproto.Window(xgb.Get32(buf[b:]))
	b += 4

	b += 20 // padding

	return v
}
Example #6
0
// PropValWindows is the same as PropValWindow, except that it returns a slice
// of identifiers. Also must be 32 bit format.
func PropValWindows(reply *xproto.GetPropertyReply,
	err error) ([]xproto.Window, error) {

	if err != nil {
		return nil, err
	}
	if reply.Format != 32 {
		return nil, fmt.Errorf("PropValIds: Expected format 32 but got %d",
			reply.Format)
	}

	ids := make([]xproto.Window, reply.ValueLen)
	vals := reply.Value
	for i := 0; len(vals) >= 4; i++ {
		ids[i] = xproto.Window(xgb.Get32(vals))
		vals = vals[4:]
	}
	return ids, nil
}
Example #7
0
// NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice.
func NotifyEventNew(buf []byte) xgb.Event {
	v := NotifyEvent{}
	b := 1 // don't read event number

	v.ShapeKind = Kind(buf[b])
	b += 1

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.AffectedWindow = xproto.Window(xgb.Get32(buf[b:]))
	b += 4

	v.ExtentsX = int16(xgb.Get16(buf[b:]))
	b += 2

	v.ExtentsY = int16(xgb.Get16(buf[b:]))
	b += 2

	v.ExtentsWidth = xgb.Get16(buf[b:])
	b += 2

	v.ExtentsHeight = xgb.Get16(buf[b:])
	b += 2

	v.ServerTime = xproto.Timestamp(xgb.Get32(buf[b:]))
	b += 4

	if buf[b] == 1 {
		v.Shaped = true
	} else {
		v.Shaped = false
	}
	b += 1

	b += 11 // padding

	return v
}
Example #8
0
// processEventQueue processes every item in the event/error queue.
func processEventQueue(xu *xgbutil.XUtil, pingBefore, pingAfter chan struct{}) {
	for !Empty(xu) {
		if Quitting(xu) {
			return
		}

		// We send the ping *before* the next event is dequeued.
		// This is so the queue doesn't present a misrepresentation of which
		// events haven't been processed yet.
		if pingBefore != nil && pingAfter != nil {
			pingBefore <- struct{}{}
		}
		ev, err := Dequeue(xu)

		// If we gobbled up an error, send it to the error event handler
		// and move on the next event/error.
		if err != nil {
			ErrorHandlerGet(xu)(err)
			if pingBefore != nil && pingAfter != nil {
				pingAfter <- struct{}{}
			}
			continue
		}

		// We know there isn't an error. If there isn't an event either,
		// then there's a bug somewhere.
		if ev == nil {
			xgbutil.Logger.Fatal("BUG: Expected an event but got nil.")
		}

		switch event := ev.(type) {
		case xproto.KeyPressEvent:
			e := KeyPressEvent{&event}

			// If we're redirecting key events, this is the place to do it!
			if wid := RedirectKeyGet(xu); wid > 0 {
				e.Event = wid
			}

			xu.TimeSet(e.Time)
			runCallbacks(xu, e, KeyPress, e.Event)
		case xproto.KeyReleaseEvent:
			e := KeyReleaseEvent{&event}

			// If we're redirecting key events, this is the place to do it!
			if wid := RedirectKeyGet(xu); wid > 0 {
				e.Event = wid
			}

			xu.TimeSet(e.Time)
			runCallbacks(xu, e, KeyRelease, e.Event)
		case xproto.ButtonPressEvent:
			e := ButtonPressEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, ButtonPress, e.Event)
		case xproto.ButtonReleaseEvent:
			e := ButtonReleaseEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, ButtonRelease, e.Event)
		case xproto.MotionNotifyEvent:
			e := MotionNotifyEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, MotionNotify, e.Event)
		case xproto.EnterNotifyEvent:
			e := EnterNotifyEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, EnterNotify, e.Event)
		case xproto.LeaveNotifyEvent:
			e := LeaveNotifyEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, LeaveNotify, e.Event)
		case xproto.FocusInEvent:
			e := FocusInEvent{&event}
			runCallbacks(xu, e, FocusIn, e.Event)
		case xproto.FocusOutEvent:
			e := FocusOutEvent{&event}
			runCallbacks(xu, e, FocusOut, e.Event)
		case xproto.KeymapNotifyEvent:
			e := KeymapNotifyEvent{&event}
			runCallbacks(xu, e, KeymapNotify, NoWindow)
		case xproto.ExposeEvent:
			e := ExposeEvent{&event}
			runCallbacks(xu, e, Expose, e.Window)
		case xproto.GraphicsExposureEvent:
			e := GraphicsExposureEvent{&event}
			runCallbacks(xu, e, GraphicsExposure, xproto.Window(e.Drawable))
		case xproto.NoExposureEvent:
			e := NoExposureEvent{&event}
			runCallbacks(xu, e, NoExposure, xproto.Window(e.Drawable))
		case xproto.VisibilityNotifyEvent:
			e := VisibilityNotifyEvent{&event}
			runCallbacks(xu, e, VisibilityNotify, e.Window)
		case xproto.CreateNotifyEvent:
			e := CreateNotifyEvent{&event}
			runCallbacks(xu, e, CreateNotify, e.Parent)
		case xproto.DestroyNotifyEvent:
			e := DestroyNotifyEvent{&event}
			runCallbacks(xu, e, DestroyNotify, e.Window)
		case xproto.UnmapNotifyEvent:
			e := UnmapNotifyEvent{&event}
			runCallbacks(xu, e, UnmapNotify, e.Window)
		case xproto.MapNotifyEvent:
			e := MapNotifyEvent{&event}
			runCallbacks(xu, e, MapNotify, e.Event)
		case xproto.MapRequestEvent:
			e := MapRequestEvent{&event}
			runCallbacks(xu, e, MapRequest, e.Window)
			runCallbacks(xu, e, MapRequest, e.Parent)
		case xproto.ReparentNotifyEvent:
			e := ReparentNotifyEvent{&event}
			runCallbacks(xu, e, ReparentNotify, e.Window)
		case xproto.ConfigureNotifyEvent:
			e := ConfigureNotifyEvent{&event}
			runCallbacks(xu, e, ConfigureNotify, e.Window)
		case xproto.ConfigureRequestEvent:
			e := ConfigureRequestEvent{&event}
			runCallbacks(xu, e, ConfigureRequest, e.Window)
			runCallbacks(xu, e, ConfigureRequest, e.Parent)
		case xproto.GravityNotifyEvent:
			e := GravityNotifyEvent{&event}
			runCallbacks(xu, e, GravityNotify, e.Window)
		case xproto.ResizeRequestEvent:
			e := ResizeRequestEvent{&event}
			runCallbacks(xu, e, ResizeRequest, e.Window)
		case xproto.CirculateNotifyEvent:
			e := CirculateNotifyEvent{&event}
			runCallbacks(xu, e, CirculateNotify, e.Window)
		case xproto.CirculateRequestEvent:
			e := CirculateRequestEvent{&event}
			runCallbacks(xu, e, CirculateRequest, e.Window)
		case xproto.PropertyNotifyEvent:
			e := PropertyNotifyEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, PropertyNotify, e.Window)
		case xproto.SelectionClearEvent:
			e := SelectionClearEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, SelectionClear, e.Owner)
		case xproto.SelectionRequestEvent:
			e := SelectionRequestEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, SelectionRequest, e.Requestor)
		case xproto.SelectionNotifyEvent:
			e := SelectionNotifyEvent{&event}
			xu.TimeSet(e.Time)
			runCallbacks(xu, e, SelectionNotify, e.Requestor)
		case xproto.ColormapNotifyEvent:
			e := ColormapNotifyEvent{&event}
			runCallbacks(xu, e, ColormapNotify, e.Window)
		case xproto.ClientMessageEvent:
			e := ClientMessageEvent{&event}
			runCallbacks(xu, e, ClientMessage, e.Window)
		case xproto.MappingNotifyEvent:
			e := MappingNotifyEvent{&event}
			runCallbacks(xu, e, MappingNotify, NoWindow)
		case shape.NotifyEvent:
			e := ShapeNotifyEvent{&event}
			runCallbacks(xu, e, ShapeNotify, e.AffectedWindow)
		default:
			if event != nil {
				xgbutil.Logger.Printf("ERROR: UNSUPPORTED EVENT TYPE: %T",
					event)
			}
		}

		if pingBefore != nil && pingAfter != nil {
			pingAfter <- struct{}{}
		}
	}
}