Initial commit
This commit is contained in:
103
vendor/github.com/BurntSushi/xgbutil/xprop/atom.go
generated
vendored
Normal file
103
vendor/github.com/BurntSushi/xgbutil/xprop/atom.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
package xprop
|
||||
|
||||
/*
|
||||
xprop/atom.go contains functions related to interning atoms and retrieving
|
||||
atom names from an atom identifier.
|
||||
|
||||
It also manages an atom cache so that once an atom is interned from the X
|
||||
server, all future atom interns use that value. (So that one and only one
|
||||
request is sent for interning each atom.)
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/BurntSushi/xgb/xproto"
|
||||
|
||||
"github.com/BurntSushi/xgbutil"
|
||||
)
|
||||
|
||||
// Atm is a short alias for Atom in the common case of interning an atom.
|
||||
// Namely, interning the atom always succeeds. (If the atom does not already
|
||||
// exist, a new one is created.)
|
||||
func Atm(xu *xgbutil.XUtil, name string) (xproto.Atom, error) {
|
||||
aid, err := Atom(xu, name, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if aid == 0 {
|
||||
return 0, fmt.Errorf("Atm: '%s' returned an identifier of 0.", name)
|
||||
}
|
||||
|
||||
return aid, err
|
||||
}
|
||||
|
||||
// Atom interns an atom and panics if there is any error.
|
||||
func Atom(xu *xgbutil.XUtil, name string,
|
||||
onlyIfExists bool) (xproto.Atom, error) {
|
||||
|
||||
// Check the cache first
|
||||
if aid, ok := atomGet(xu, name); ok {
|
||||
return aid, nil
|
||||
}
|
||||
|
||||
reply, err := xproto.InternAtom(xu.Conn(), onlyIfExists,
|
||||
uint16(len(name)), name).Reply()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("Atom: Error interning atom '%s': %s", name, err)
|
||||
}
|
||||
|
||||
// If we're here, it means we didn't have this atom cached. So cache it!
|
||||
cacheAtom(xu, name, reply.Atom)
|
||||
|
||||
return reply.Atom, nil
|
||||
}
|
||||
|
||||
// AtomName fetches a string representation of an ATOM given its integer id.
|
||||
func AtomName(xu *xgbutil.XUtil, aid xproto.Atom) (string, error) {
|
||||
// Check the cache first
|
||||
if atomName, ok := atomNameGet(xu, aid); ok {
|
||||
return string(atomName), nil
|
||||
}
|
||||
|
||||
reply, err := xproto.GetAtomName(xu.Conn(), aid).Reply()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("AtomName: Error fetching name for ATOM "+
|
||||
"id '%d': %s", aid, err)
|
||||
}
|
||||
|
||||
// If we're here, it means we didn't have ths ATOM id cached. So cache it.
|
||||
atomName := string(reply.Name)
|
||||
cacheAtom(xu, atomName, aid)
|
||||
|
||||
return atomName, nil
|
||||
}
|
||||
|
||||
// atomGet retrieves an atom identifier from a cache if it exists.
|
||||
func atomGet(xu *xgbutil.XUtil, name string) (xproto.Atom, bool) {
|
||||
xu.AtomsLck.RLock()
|
||||
defer xu.AtomsLck.RUnlock()
|
||||
|
||||
aid, ok := xu.Atoms[name]
|
||||
return aid, ok
|
||||
}
|
||||
|
||||
// atomNameGet retrieves an atom name from a cache if it exists.
|
||||
func atomNameGet(xu *xgbutil.XUtil, aid xproto.Atom) (string, bool) {
|
||||
xu.AtomNamesLck.RLock()
|
||||
defer xu.AtomNamesLck.RUnlock()
|
||||
|
||||
name, ok := xu.AtomNames[aid]
|
||||
return name, ok
|
||||
}
|
||||
|
||||
// cacheAtom puts an atom into the cache.
|
||||
func cacheAtom(xu *xgbutil.XUtil, name string, aid xproto.Atom) {
|
||||
xu.AtomsLck.Lock()
|
||||
xu.AtomNamesLck.Lock()
|
||||
defer xu.AtomsLck.Unlock()
|
||||
defer xu.AtomNamesLck.Unlock()
|
||||
|
||||
xu.Atoms[name] = aid
|
||||
xu.AtomNames[aid] = name
|
||||
}
|
||||
40
vendor/github.com/BurntSushi/xgbutil/xprop/doc.go
generated
vendored
Normal file
40
vendor/github.com/BurntSushi/xgbutil/xprop/doc.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Package xprop provides a cache for interning atoms and helper functions for
|
||||
dealing with GetProperty and ChangeProperty X requests.
|
||||
|
||||
Atoms
|
||||
|
||||
Atoms in X are interned, meaning that strings are assigned unique integer
|
||||
identifiers. This minimizes the amount of data transmitted over an X connection.
|
||||
|
||||
Once atoms have been interned, they are never changed while the X server is
|
||||
running. xgbutil takes advantage of this invariant and will only issue an
|
||||
intern atom request once and cache the result.
|
||||
|
||||
To use the xprop package to intern an atom, use Atom:
|
||||
|
||||
atom, err := xprop.Atom(XUtilValue, "THE_ATOM_NAME", false)
|
||||
if err == nil {
|
||||
println("The atom number: ", atom.Atom)
|
||||
}
|
||||
|
||||
The 'false' parameter corresponds to the 'only_if_exists' parameter of the
|
||||
X InternAtom request. When it's false, the atom being interned always returns
|
||||
a non-zero atom number---even if the string being interned hasn't been interned
|
||||
before. If 'only_if_exists' is true, the atom being interned will return a 0
|
||||
atom number if it hasn't already been interned.
|
||||
|
||||
The typical case is to set 'only_if_exists' to false. To this end, xprop.Atm is
|
||||
an alias that always sets this value to false.
|
||||
|
||||
The reverse can also be done: getting an atom string if you have an atom
|
||||
number. This can be done with the xprop.AtomName function.
|
||||
|
||||
Properties
|
||||
|
||||
The other facility of xprop is to help with the use of GetProperty and
|
||||
ChangeProperty. Please see the source code of the ewmh package for plenty of
|
||||
examples.
|
||||
|
||||
*/
|
||||
package xprop
|
||||
270
vendor/github.com/BurntSushi/xgbutil/xprop/xprop.go
generated
vendored
Normal file
270
vendor/github.com/BurntSushi/xgbutil/xprop/xprop.go
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
package xprop
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/BurntSushi/xgb"
|
||||
"github.com/BurntSushi/xgb/xproto"
|
||||
|
||||
"github.com/BurntSushi/xgbutil"
|
||||
)
|
||||
|
||||
// GetProperty abstracts the messiness of calling xgb.GetProperty.
|
||||
func GetProperty(xu *xgbutil.XUtil, win xproto.Window, atom string) (
|
||||
*xproto.GetPropertyReply, error) {
|
||||
|
||||
atomId, err := Atm(xu, atom)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reply, err := xproto.GetProperty(xu.Conn(), false, win, atomId,
|
||||
xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetProperty: Error retrieving property '%s' "+
|
||||
"on window %x: %s", atom, win, err)
|
||||
}
|
||||
|
||||
if reply.Format == 0 {
|
||||
return nil, fmt.Errorf("GetProperty: No such property '%s' on "+
|
||||
"window %x.", atom, win)
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
||||
|
||||
// ChangeProperty32 makes changing 32 bit formatted properties easier
|
||||
// by constructing the raw X data for you.
|
||||
func ChangeProp32(xu *xgbutil.XUtil, win xproto.Window, prop string, typ string,
|
||||
data ...uint) error {
|
||||
|
||||
buf := make([]byte, len(data)*4)
|
||||
for i, datum := range data {
|
||||
xgb.Put32(buf[(i*4):], uint32(datum))
|
||||
}
|
||||
|
||||
return ChangeProp(xu, win, 32, prop, typ, buf)
|
||||
}
|
||||
|
||||
// WindowToUint is a covenience function for converting []xproto.Window
|
||||
// to []uint.
|
||||
func WindowToInt(ids []xproto.Window) []uint {
|
||||
ids32 := make([]uint, len(ids))
|
||||
for i, v := range ids {
|
||||
ids32[i] = uint(v)
|
||||
}
|
||||
return ids32
|
||||
}
|
||||
|
||||
// AtomToInt is a covenience function for converting []xproto.Atom
|
||||
// to []uint.
|
||||
func AtomToUint(ids []xproto.Atom) []uint {
|
||||
ids32 := make([]uint, len(ids))
|
||||
for i, v := range ids {
|
||||
ids32[i] = uint(v)
|
||||
}
|
||||
return ids32
|
||||
}
|
||||
|
||||
// StrToAtoms is a convenience function for converting
|
||||
// []string to []uint32 atoms.
|
||||
// NOTE: If an atom name in the list doesn't exist, it will be created.
|
||||
func StrToAtoms(xu *xgbutil.XUtil, atomNames []string) ([]uint, error) {
|
||||
var err error
|
||||
atoms := make([]uint, len(atomNames))
|
||||
for i, atomName := range atomNames {
|
||||
a, err := Atom(xu, atomName, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
atoms[i] = uint(a)
|
||||
}
|
||||
return atoms, err
|
||||
}
|
||||
|
||||
// PropValAtom transforms a GetPropertyReply struct into an ATOM name.
|
||||
// The property reply must be in 32 bit format.
|
||||
func PropValAtom(xu *xgbutil.XUtil, reply *xproto.GetPropertyReply,
|
||||
err error) (string, error) {
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if reply.Format != 32 {
|
||||
return "", fmt.Errorf("PropValAtom: Expected format 32 but got %d",
|
||||
reply.Format)
|
||||
}
|
||||
|
||||
return AtomName(xu, xproto.Atom(xgb.Get32(reply.Value)))
|
||||
}
|
||||
|
||||
// PropValAtoms is the same as PropValAtom, except that it returns a slice
|
||||
// of atom names. Also must be 32 bit format.
|
||||
// This is a method of an XUtil struct, unlike the other 'PropVal...' functions.
|
||||
func PropValAtoms(xu *xgbutil.XUtil, reply *xproto.GetPropertyReply,
|
||||
err error) ([]string, error) {
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reply.Format != 32 {
|
||||
return nil, fmt.Errorf("PropValAtoms: Expected format 32 but got %d",
|
||||
reply.Format)
|
||||
}
|
||||
|
||||
ids := make([]string, reply.ValueLen)
|
||||
vals := reply.Value
|
||||
for i := 0; len(vals) >= 4; i++ {
|
||||
ids[i], err = AtomName(xu, xproto.Atom(xgb.Get32(vals)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vals = vals[4:]
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// PropValNum transforms a GetPropertyReply struct into an unsigned
|
||||
// integer. Useful when the property value is a single integer.
|
||||
func PropValNum(reply *xproto.GetPropertyReply, err error) (uint, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if reply.Format != 32 {
|
||||
return 0, fmt.Errorf("PropValNum: Expected format 32 but got %d",
|
||||
reply.Format)
|
||||
}
|
||||
return uint(xgb.Get32(reply.Value)), nil
|
||||
}
|
||||
|
||||
// PropValNums is the same as PropValNum, except that it returns a slice
|
||||
// of integers. Also must be 32 bit format.
|
||||
func PropValNums(reply *xproto.GetPropertyReply, err error) ([]uint, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reply.Format != 32 {
|
||||
return nil, fmt.Errorf("PropValIds: Expected format 32 but got %d",
|
||||
reply.Format)
|
||||
}
|
||||
|
||||
nums := make([]uint, reply.ValueLen)
|
||||
vals := reply.Value
|
||||
for i := 0; len(vals) >= 4; i++ {
|
||||
nums[i] = uint(xgb.Get32(vals))
|
||||
vals = vals[4:]
|
||||
}
|
||||
return nums, nil
|
||||
}
|
||||
|
||||
// PropValNum64 transforms a GetPropertyReply struct into a 64 bit
|
||||
// integer. Useful when the property value is a single integer.
|
||||
func PropValNum64(reply *xproto.GetPropertyReply, err error) (int64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if reply.Format != 32 {
|
||||
return 0, fmt.Errorf("PropValNum: Expected format 32 but got %d",
|
||||
reply.Format)
|
||||
}
|
||||
return int64(xgb.Get32(reply.Value)), nil
|
||||
}
|
||||
|
||||
// PropValStr transforms a GetPropertyReply struct into a string.
|
||||
// Useful when the property value is a null terminated string represented
|
||||
// by integers. Also must be 8 bit format.
|
||||
func PropValStr(reply *xproto.GetPropertyReply, err error) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if reply.Format != 8 {
|
||||
return "", fmt.Errorf("PropValStr: Expected format 8 but got %d",
|
||||
reply.Format)
|
||||
}
|
||||
return string(reply.Value), nil
|
||||
}
|
||||
|
||||
// PropValStrs is the same as PropValStr, except that it returns a slice
|
||||
// of strings. The raw byte string is a sequence of null terminated strings,
|
||||
// which is translated into a slice of strings.
|
||||
func PropValStrs(reply *xproto.GetPropertyReply, err error) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reply.Format != 8 {
|
||||
return nil, fmt.Errorf("PropValStrs: Expected format 8 but got %d",
|
||||
reply.Format)
|
||||
}
|
||||
|
||||
var strs []string
|
||||
sstart := 0
|
||||
for i, c := range reply.Value {
|
||||
if c == 0 {
|
||||
strs = append(strs, string(reply.Value[sstart:i]))
|
||||
sstart = i + 1
|
||||
}
|
||||
}
|
||||
if sstart < int(reply.ValueLen) {
|
||||
strs = append(strs, string(reply.Value[sstart:]))
|
||||
}
|
||||
return strs, nil
|
||||
}
|
||||
Reference in New Issue
Block a user