extensions are working! extensions are working!
This commit is contained in:
parent
b6715f376f
commit
369ad0d33e
|
@ -10,7 +10,8 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// connect connects to the X server given in the 'display' string.
|
||||
// connect connects to the X server given in the 'display' string,
|
||||
// and does all the necessary setup handshaking.
|
||||
// If 'display' is empty it will be taken from os.Getenv("DISPLAY").
|
||||
// Note that you should read and understand the "Connection Setup" of the
|
||||
// X Protocol Reference Manual before changing this function:
|
||||
|
@ -87,6 +88,7 @@ func (c *Conn) connect(display string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// dial initializes the actual net connection with X.
|
||||
func (c *Conn) dial(display string) error {
|
||||
if len(display) == 0 {
|
||||
display = os.Getenv("DISPLAY")
|
||||
|
|
|
@ -4,16 +4,28 @@ import (
|
|||
"errors"
|
||||
)
|
||||
|
||||
// cookie is the internal representation of a cookie, where one is generated
|
||||
// for *every* request sent by XGB.
|
||||
// 'cookie' is most frequently used by embedding it into a more specific
|
||||
// kind of cookie, i.e., 'GetInputFocusCookie'.
|
||||
type cookie struct {
|
||||
conn *Conn
|
||||
Sequence uint16
|
||||
replyChan chan []byte
|
||||
errorChan chan error
|
||||
pingChan chan bool
|
||||
}
|
||||
|
||||
func (c *Conn) newCookie(checked, reply bool) cookie {
|
||||
cookie := cookie{
|
||||
Sequence: c.newSequenceId(),
|
||||
// newCookie creates a new cookie with the correct channels initialized
|
||||
// depending upon the values of 'checked' and 'reply'. Together, there are
|
||||
// four different kinds of cookies. (See more detailed comments in the
|
||||
// function for more info on those.)
|
||||
// Note that a sequence number is not set until just before the request
|
||||
// corresponding to this cookie is sent over the wire.
|
||||
func (c *Conn) newCookie(checked, reply bool) *cookie {
|
||||
cookie := &cookie{
|
||||
conn: c,
|
||||
Sequence: 0, // we add the sequence id just before sending a request
|
||||
replyChan: nil,
|
||||
errorChan: nil,
|
||||
pingChan: nil,
|
||||
|
@ -48,6 +60,8 @@ func (c *Conn) newCookie(checked, reply bool) cookie {
|
|||
return cookie
|
||||
}
|
||||
|
||||
// reply detects whether this is a checked or unchecked cookie, and calls
|
||||
// 'replyChecked' or 'replyUnchecked' appropriately.
|
||||
func (c cookie) reply() ([]byte, error) {
|
||||
// checked
|
||||
if c.errorChan != nil {
|
||||
|
@ -56,6 +70,10 @@ func (c cookie) reply() ([]byte, error) {
|
|||
return c.replyUnchecked()
|
||||
}
|
||||
|
||||
// replyChecked waits for a response on either the replyChan or errorChan
|
||||
// channels. If the former arrives, the bytes are returned with a nil error.
|
||||
// If the latter arrives, no bytes are returned (nil) and the error received
|
||||
// is returned.
|
||||
func (c cookie) replyChecked() ([]byte, error) {
|
||||
if c.replyChan == nil {
|
||||
return nil, errors.New("Cannot call 'replyChecked' on a cookie that " +
|
||||
|
@ -75,6 +93,12 @@ func (c cookie) replyChecked() ([]byte, error) {
|
|||
panic("unreachable")
|
||||
}
|
||||
|
||||
// replyChecked waits for a response on either the replyChan or pingChan
|
||||
// channels. If the former arrives, the bytes are returned with a nil error.
|
||||
// If the latter arrives, no bytes are returned (nil) and a nil error
|
||||
// is returned. (In the latter case, the corresponding error can be retrieved
|
||||
// from (Wait|Poll)ForEvent asynchronously.)
|
||||
// In all honesty, you *probably* don't want to use this method.
|
||||
func (c cookie) replyUnchecked() ([]byte, error) {
|
||||
if c.replyChan == nil {
|
||||
return nil, errors.New("Cannot call 'replyUnchecked' on a cookie " +
|
||||
|
@ -90,7 +114,15 @@ func (c cookie) replyUnchecked() ([]byte, error) {
|
|||
panic("unreachable")
|
||||
}
|
||||
|
||||
func (c cookie) Check() error {
|
||||
// check is used for checked requests that have no replies. It is a mechanism
|
||||
// by which to report "success" or "error" in a synchronous fashion. (Therefore,
|
||||
// unchecked requests without replies cannot use this method.)
|
||||
// If the request causes an error, it is sent to this cookie's errorChan.
|
||||
// If the request was successful, there is no response from the server.
|
||||
// Thus, pingChan is sent a value when the *next* reply is read.
|
||||
// If no more replies are being processed, we force a round trip request with
|
||||
// GetInputFocus.
|
||||
func (c cookie) check() error {
|
||||
if c.replyChan != nil {
|
||||
return errors.New("Cannot call 'Check' on a cookie that is " +
|
||||
"expecting a *reply*. Use 'Reply' instead.")
|
||||
|
@ -100,6 +132,17 @@ func (c cookie) Check() error {
|
|||
"not expecting a possible *error*.")
|
||||
}
|
||||
|
||||
// First do a quick non-blocking check to see if we've been pinged.
|
||||
select {
|
||||
case err := <-c.errorChan:
|
||||
return err
|
||||
case <-c.pingChan:
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
|
||||
// Now force a round trip and try again, but block this time.
|
||||
c.conn.GetInputFocus().Reply()
|
||||
select {
|
||||
case err := <-c.errorChan:
|
||||
return err
|
||||
|
|
|
@ -18,7 +18,7 @@ func main() {
|
|||
}
|
||||
|
||||
aname := "_NET_ACTIVE_WINDOW"
|
||||
atom, err := X.InternAtom(true, uint16(len(aname)), aname)
|
||||
atom, err := X.InternAtom(true, uint16(len(aname)), aname).Reply()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -27,13 +27,15 @@ func main() {
|
|||
root := X.DefaultScreen().Root
|
||||
|
||||
aname := "_NET_ACTIVE_WINDOW"
|
||||
atom, err := X.InternAtom(true, uint16(len(aname)), aname)
|
||||
atom, err := X.InternAtom(true, uint16(len(aname)), aname).Reply()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
reply, err := X.GetProperty(false, root, atom.Atom, xgb.GetPropertyTypeAny,
|
||||
0, (1<<32)-1)
|
||||
reply, err := X.GetProperty(false, root, atom.Atom,
|
||||
xgb.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("%X", get32(reply.Value))
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
102
nexgb/xgb.go
102
nexgb/xgb.go
|
@ -17,6 +17,11 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// cookieBuffer represents the queue size of cookies existing at any
|
||||
// point in time. The size of the buffer is really only important when
|
||||
// there are many requests without replies made in sequence. Once the
|
||||
// buffer fills, a round trip request is made to clear the buffer.
|
||||
cookieBuffer = 1000
|
||||
readBuffer = 100
|
||||
writeBuffer = 100
|
||||
)
|
||||
|
@ -32,7 +37,7 @@ type Conn struct {
|
|||
extensions map[string]byte
|
||||
|
||||
eventChan chan eventOrError
|
||||
cookieChan chan cookie
|
||||
cookieChan chan *cookie
|
||||
xidChan chan xid
|
||||
seqChan chan uint16
|
||||
reqChan chan *request
|
||||
|
@ -68,7 +73,7 @@ func NewConnDisplay(display string) (*Conn, error) {
|
|||
|
||||
conn.extensions = make(map[string]byte)
|
||||
|
||||
conn.cookieChan = make(chan cookie, 100)
|
||||
conn.cookieChan = make(chan *cookie, cookieBuffer)
|
||||
conn.xidChan = make(chan xid, 5)
|
||||
conn.seqChan = make(chan uint16, 20)
|
||||
conn.reqChan = make(chan *request, 100)
|
||||
|
@ -87,6 +92,12 @@ func (c *Conn) Close() {
|
|||
c.conn.Close()
|
||||
}
|
||||
|
||||
// DefaultScreen returns the Screen info for the default screen, which is
|
||||
// 0 or the one given in the display argument to Dial.
|
||||
func (c *Conn) DefaultScreen() *ScreenInfo {
|
||||
return &c.Setup.Roots[c.defaultScreen]
|
||||
}
|
||||
|
||||
// Id is used for all X identifiers, such as windows, pixmaps, and GCs.
|
||||
type Id uint32
|
||||
|
||||
|
@ -95,6 +106,7 @@ type Id uint32
|
|||
type Event interface {
|
||||
ImplementsEvent()
|
||||
Bytes() []byte
|
||||
String() string
|
||||
}
|
||||
|
||||
// newEventFuncs is a map from event numbers to functions that create
|
||||
|
@ -188,7 +200,8 @@ func (c *Conn) newSequenceId() uint16 {
|
|||
// to match up replies with requests.
|
||||
// Since sequence ids can only be 16 bit integers we start over at zero when it
|
||||
// comes time to wrap.
|
||||
// FIXME: 65,536 requests without replies cannot be made in a single sequence.
|
||||
// N.B. As long as the cookie buffer is less than 2^16, there are no limitations
|
||||
// on the number (or kind) of requests made in sequence.
|
||||
func (c *Conn) generateSeqIds() {
|
||||
seqid := uint16(1)
|
||||
for {
|
||||
|
@ -206,13 +219,14 @@ func (c *Conn) generateSeqIds() {
|
|||
// The cookie is used to match up the reply/error.
|
||||
type request struct {
|
||||
buf []byte
|
||||
cookie cookie
|
||||
cookie *cookie
|
||||
}
|
||||
|
||||
// newRequest takes the bytes an a cookie, constructs a request type,
|
||||
// and sends it over the Conn.reqChan channel. It then returns the cookie
|
||||
// (for convenience).
|
||||
func (c *Conn) newRequest(buf []byte, cookie cookie) {
|
||||
// and sends it over the Conn.reqChan channel.
|
||||
// Note that the sequence number is added to the cookie after it is sent
|
||||
// over the request channel.
|
||||
func (c *Conn) newRequest(buf []byte, cookie *cookie) {
|
||||
c.reqChan <- &request{buf: buf, cookie: cookie}
|
||||
}
|
||||
|
||||
|
@ -220,15 +234,38 @@ func (c *Conn) newRequest(buf []byte, cookie cookie) {
|
|||
// the bytes to the wire and adds the cookie to the cookie queue.
|
||||
func (c *Conn) sendRequests() {
|
||||
for req := range c.reqChan {
|
||||
// ho there! if the cookie channel is nearly full, force a round
|
||||
// trip to clear out the cookie buffer.
|
||||
// Note that we circumvent the request channel, because we're *in*
|
||||
// the request channel.
|
||||
if len(c.cookieChan) == cookieBuffer - 1 {
|
||||
cookie := c.newCookie(true, true)
|
||||
cookie.Sequence = c.newSequenceId()
|
||||
c.cookieChan <- cookie
|
||||
if !c.writeBuffer(c.getInputFocusRequest()) {
|
||||
return
|
||||
}
|
||||
GetInputFocusCookie{cookie}.Reply() // wait for the buffer to clear
|
||||
}
|
||||
|
||||
req.cookie.Sequence = c.newSequenceId()
|
||||
c.cookieChan <- req.cookie
|
||||
if _, err := c.conn.Write(req.buf); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "x protocol write error: %s\n", err)
|
||||
close(c.reqChan)
|
||||
if !c.writeBuffer(req.buf) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// writeBuffer is a convenience function for writing a byte slice to the wire.
|
||||
func (c *Conn) writeBuffer(buf []byte) bool {
|
||||
if _, err := c.conn.Write(buf); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "x protocol write error: %s\n", err)
|
||||
close(c.reqChan)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// readResponses is a goroutine that reads events, errors and
|
||||
// replies off the wire.
|
||||
// When an event is read, it is always added to the event channel.
|
||||
|
@ -260,7 +297,15 @@ func (c *Conn) readResponses() {
|
|||
case 0: // This is an error
|
||||
// Use the constructor function for this error (that is auto
|
||||
// generated) by looking it up by the error number.
|
||||
err = newErrorFuncs[int(buf[1])](buf)
|
||||
newErrFun, ok := newErrorFuncs[int(buf[1])]
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"BUG: " +
|
||||
"Could not find error constructor function for error " +
|
||||
"with number %d.", buf[1])
|
||||
continue
|
||||
}
|
||||
err = newErrFun(buf)
|
||||
seq = err.SequenceId()
|
||||
|
||||
// This error is either sent to the event channel or a specific
|
||||
|
@ -291,22 +336,23 @@ func (c *Conn) readResponses() {
|
|||
// Note that we AND the event number with 127 so that we ignore
|
||||
// the most significant bit (which is set when it was sent from
|
||||
// a SendEvent request).
|
||||
event = newEventFuncs[int(buf[0] & 127)](buf)
|
||||
// seq = event.SequenceId() // 0 for KeymapNotify
|
||||
evNum := int(buf[0] & 127)
|
||||
newEventFun, ok := newEventFuncs[evNum]
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"BUG: " +
|
||||
"Could not find event constructor function for event " +
|
||||
"with number %d.", evNum)
|
||||
continue
|
||||
}
|
||||
|
||||
event = newEventFun(buf)
|
||||
|
||||
// Put the event into the queue.
|
||||
c.eventChan <- event
|
||||
|
||||
// No more processing for events.
|
||||
continue
|
||||
|
||||
// If this was a KeymapNotify event, then we don't do any more
|
||||
// processing since we don't have any sequence id.
|
||||
// if event != nil {
|
||||
// if _, ok := event.(KeymapNotifyEvent); ok {
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// At this point, we have a sequence number and we're either
|
||||
|
@ -326,12 +372,17 @@ func (c *Conn) readResponses() {
|
|||
cookie.errorChan <- err
|
||||
} else { // asynchronous processing
|
||||
c.eventChan <- err
|
||||
// if this is an unchecked reply, ping the cookie too
|
||||
if cookie.pingChan != nil {
|
||||
cookie.pingChan <- true
|
||||
}
|
||||
}
|
||||
} else { // this is a reply
|
||||
if cookie.replyChan == nil {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"Reply with sequence id %d does not have a " +
|
||||
"cookie with a valid reply channel.\n", seq)
|
||||
continue
|
||||
} else {
|
||||
cookie.replyChan <- replyBytes
|
||||
}
|
||||
|
@ -344,10 +395,14 @@ func (c *Conn) readResponses() {
|
|||
case cookie.replyChan != nil && cookie.errorChan != nil:
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"Found cookie with sequence id %d that is expecting a " +
|
||||
"reply but will never get it.\n", cookie.Sequence)
|
||||
"reply but will never get it. Currently on sequence " +
|
||||
"number %d\n", cookie.Sequence, seq)
|
||||
// Unchecked requests with replies
|
||||
case cookie.replyChan != nil && cookie.pingChan != nil:
|
||||
cookie.pingChan <- true
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"Found cookie with sequence id %d that is expecting a " +
|
||||
"reply (and not an error) but will never get it. " +
|
||||
"Currently on sequence number %d\n", cookie.Sequence, seq)
|
||||
// Checked requests without replies
|
||||
case cookie.pingChan != nil && cookie.errorChan != nil:
|
||||
cookie.pingChan <- true
|
||||
|
@ -368,6 +423,7 @@ func processEventOrError(everr eventOrError) (Event, Error) {
|
|||
return nil, ee
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Invalid event/error type: %T\n", everr)
|
||||
return nil, nil
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
|
|
@ -5,20 +5,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// getExtensionOpcode retrieves the extension opcode from the extensions map.
|
||||
// If one doesn't exist, just return 0. An X error will likely result.
|
||||
func (c *Conn) getExtensionOpcode(name string) byte {
|
||||
return c.extensions[name]
|
||||
}
|
||||
|
||||
func (c *Conn) bytesPadding(buf []byte) []byte {
|
||||
return append(buf, make([]byte, pad(len(buf))-len(buf))...)
|
||||
}
|
||||
|
||||
func (c *Conn) bytesString(str string) []byte {
|
||||
return c.bytesPadding([]byte(str))
|
||||
}
|
||||
|
||||
// stringsJoin is an alias to strings.Join. It allows us to avoid having to
|
||||
// import 'strings' in each of the generated Go files.
|
||||
func stringsJoin(ss []string, sep string) string {
|
||||
|
@ -31,58 +17,11 @@ func sprintf(format string, v ...interface{}) string {
|
|||
}
|
||||
|
||||
// Pad a length to align on 4 bytes.
|
||||
func pad(n int) int { return (n + 3) & ^3 }
|
||||
|
||||
func Put16(buf []byte, v uint16) {
|
||||
buf[0] = byte(v)
|
||||
buf[1] = byte(v >> 8)
|
||||
func pad(n int) int {
|
||||
return (n + 3) & ^3
|
||||
}
|
||||
|
||||
func Put32(buf []byte, v uint32) {
|
||||
buf[0] = byte(v)
|
||||
buf[1] = byte(v >> 8)
|
||||
buf[2] = byte(v >> 16)
|
||||
buf[3] = byte(v >> 24)
|
||||
}
|
||||
|
||||
func Put64(buf []byte, v uint64) {
|
||||
buf[0] = byte(v)
|
||||
buf[1] = byte(v >> 8)
|
||||
buf[2] = byte(v >> 16)
|
||||
buf[3] = byte(v >> 24)
|
||||
buf[4] = byte(v >> 32)
|
||||
buf[5] = byte(v >> 40)
|
||||
buf[6] = byte(v >> 48)
|
||||
buf[7] = byte(v >> 56)
|
||||
}
|
||||
|
||||
func Get16(buf []byte) uint16 {
|
||||
v := uint16(buf[0])
|
||||
v |= uint16(buf[1]) << 8
|
||||
return v
|
||||
}
|
||||
|
||||
func Get32(buf []byte) uint32 {
|
||||
v := uint32(buf[0])
|
||||
v |= uint32(buf[1]) << 8
|
||||
v |= uint32(buf[2]) << 16
|
||||
v |= uint32(buf[3]) << 24
|
||||
return v
|
||||
}
|
||||
|
||||
func Get64(buf []byte) uint64 {
|
||||
v := uint64(buf[0])
|
||||
v |= uint64(buf[1]) << 8
|
||||
v |= uint64(buf[2]) << 16
|
||||
v |= uint64(buf[3]) << 24
|
||||
v |= uint64(buf[4]) << 32
|
||||
v |= uint64(buf[5]) << 40
|
||||
v |= uint64(buf[6]) << 48
|
||||
v |= uint64(buf[7]) << 56
|
||||
return v
|
||||
}
|
||||
|
||||
// Voodoo to count the number of bits set in a value list mask.
|
||||
// popCount counts the number of bits set in a value list mask.
|
||||
func popCount(mask0 int) int {
|
||||
mask := uint32(mask0)
|
||||
n := 0
|
||||
|
@ -94,6 +33,57 @@ func popCount(mask0 int) int {
|
|||
return n
|
||||
}
|
||||
|
||||
// DefaultScreen returns the Screen info for the default screen, which is
|
||||
// 0 or the one given in the display argument to Dial.
|
||||
func (c *Conn) DefaultScreen() *ScreenInfo { return &c.Setup.Roots[c.defaultScreen] }
|
||||
// Put16 takes a 16 bit integer and copies it into a byte slice.
|
||||
func Put16(buf []byte, v uint16) {
|
||||
buf[0] = byte(v)
|
||||
buf[1] = byte(v >> 8)
|
||||
}
|
||||
|
||||
// Put32 takes a 32 bit integer and copies it into a byte slice.
|
||||
func Put32(buf []byte, v uint32) {
|
||||
buf[0] = byte(v)
|
||||
buf[1] = byte(v >> 8)
|
||||
buf[2] = byte(v >> 16)
|
||||
buf[3] = byte(v >> 24)
|
||||
}
|
||||
|
||||
// Put64 takes a 64 bit integer and copies it into a byte slice.
|
||||
func Put64(buf []byte, v uint64) {
|
||||
buf[0] = byte(v)
|
||||
buf[1] = byte(v >> 8)
|
||||
buf[2] = byte(v >> 16)
|
||||
buf[3] = byte(v >> 24)
|
||||
buf[4] = byte(v >> 32)
|
||||
buf[5] = byte(v >> 40)
|
||||
buf[6] = byte(v >> 48)
|
||||
buf[7] = byte(v >> 56)
|
||||
}
|
||||
|
||||
// Get16 constructs a 16 bit integer from the beginning of a byte slice.
|
||||
func Get16(buf []byte) uint16 {
|
||||
v := uint16(buf[0])
|
||||
v |= uint16(buf[1]) << 8
|
||||
return v
|
||||
}
|
||||
|
||||
// Get32 constructs a 32 bit integer from the beginning of a byte slice.
|
||||
func Get32(buf []byte) uint32 {
|
||||
v := uint32(buf[0])
|
||||
v |= uint32(buf[1]) << 8
|
||||
v |= uint32(buf[2]) << 16
|
||||
v |= uint32(buf[3]) << 24
|
||||
return v
|
||||
}
|
||||
|
||||
// Get64 constructs a 64 bit integer from the beginning of a byte slice.
|
||||
func Get64(buf []byte) uint64 {
|
||||
v := uint64(buf[0])
|
||||
v |= uint64(buf[1]) << 8
|
||||
v |= uint64(buf[2]) << 16
|
||||
v |= uint64(buf[3]) << 24
|
||||
v |= uint64(buf[4]) << 32
|
||||
v |= uint64(buf[5]) << 40
|
||||
v |= uint64(buf[6]) << 48
|
||||
v |= uint64(buf[7]) << 56
|
||||
return v
|
||||
}
|
||||
|
|
|
@ -0,0 +1,629 @@
|
|||
package xgb
|
||||
|
||||
/*
|
||||
This file was generated by xinerama.xml on May 5 2012 5:56:52pm EDT.
|
||||
This file is automatically generated. Edit at your peril!
|
||||
*/
|
||||
|
||||
// Imports are not necessary for XGB because everything is
|
||||
// in one package. They are still listed here for reference.
|
||||
// import "xproto"
|
||||
|
||||
// Skipping definition for base type 'Void'
|
||||
|
||||
// Skipping definition for base type 'Byte'
|
||||
|
||||
// Skipping definition for base type 'Int8'
|
||||
|
||||
// Skipping definition for base type 'Card16'
|
||||
|
||||
// Skipping definition for base type 'Char'
|
||||
|
||||
// Skipping definition for base type 'Card32'
|
||||
|
||||
// Skipping definition for base type 'Double'
|
||||
|
||||
// Skipping definition for base type 'Bool'
|
||||
|
||||
// Skipping definition for base type 'Float'
|
||||
|
||||
// Skipping definition for base type 'Id'
|
||||
|
||||
// Skipping definition for base type 'Card8'
|
||||
|
||||
// Skipping definition for base type 'Int16'
|
||||
|
||||
// Skipping definition for base type 'Int32'
|
||||
|
||||
// 'XineramaScreenInfo' struct definition
|
||||
// Size: 8
|
||||
type XineramaScreenInfo struct {
|
||||
XOrg int16
|
||||
YOrg int16
|
||||
Width uint16
|
||||
Height uint16
|
||||
}
|
||||
|
||||
// Struct read XineramaScreenInfo
|
||||
func ReadXineramaScreenInfo(buf []byte, v *XineramaScreenInfo) int {
|
||||
b := 0
|
||||
|
||||
v.XOrg = int16(Get16(buf[b:]))
|
||||
b += 2
|
||||
|
||||
v.YOrg = int16(Get16(buf[b:]))
|
||||
b += 2
|
||||
|
||||
v.Width = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Height = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Struct list read XineramaScreenInfo
|
||||
func ReadXineramaScreenInfoList(buf []byte, dest []XineramaScreenInfo) int {
|
||||
b := 0
|
||||
for i := 0; i < len(dest); i++ {
|
||||
dest[i] = XineramaScreenInfo{}
|
||||
b += ReadXineramaScreenInfo(buf[b:], &dest[i])
|
||||
}
|
||||
return pad(b)
|
||||
}
|
||||
|
||||
// Struct write XineramaScreenInfo
|
||||
func (v XineramaScreenInfo) Bytes() []byte {
|
||||
buf := make([]byte, 8)
|
||||
b := 0
|
||||
|
||||
Put16(buf[b:], uint16(v.XOrg))
|
||||
b += 2
|
||||
|
||||
Put16(buf[b:], uint16(v.YOrg))
|
||||
b += 2
|
||||
|
||||
Put16(buf[b:], v.Width)
|
||||
b += 2
|
||||
|
||||
Put16(buf[b:], v.Height)
|
||||
b += 2
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Write struct list XineramaScreenInfo
|
||||
func XineramaScreenInfoListBytes(buf []byte, list []XineramaScreenInfo) int {
|
||||
b := 0
|
||||
var structBytes []byte
|
||||
for _, item := range list {
|
||||
structBytes = item.Bytes()
|
||||
copy(buf[b:], structBytes)
|
||||
b += pad(len(structBytes))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Request XineramaQueryVersion
|
||||
// size: 8
|
||||
type XineramaQueryVersionCookie struct {
|
||||
*cookie
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaQueryVersion(Major byte, Minor byte) XineramaQueryVersionCookie {
|
||||
cookie := c.newCookie(true, true)
|
||||
c.newRequest(c.xineramaQueryVersionRequest(Major, Minor), cookie)
|
||||
return XineramaQueryVersionCookie{cookie}
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaQueryVersionUnchecked(Major byte, Minor byte) XineramaQueryVersionCookie {
|
||||
cookie := c.newCookie(false, true)
|
||||
c.newRequest(c.xineramaQueryVersionRequest(Major, Minor), cookie)
|
||||
return XineramaQueryVersionCookie{cookie}
|
||||
}
|
||||
|
||||
// Request reply for XineramaQueryVersion
|
||||
// size: 12
|
||||
type XineramaQueryVersionReply struct {
|
||||
Sequence uint16
|
||||
Length uint32
|
||||
// padding: 1 bytes
|
||||
Major uint16
|
||||
Minor uint16
|
||||
}
|
||||
|
||||
// Waits and reads reply data from request XineramaQueryVersion
|
||||
func (cook XineramaQueryVersionCookie) Reply() (*XineramaQueryVersionReply, error) {
|
||||
buf, err := cook.reply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return xineramaQueryVersionReply(buf), nil
|
||||
}
|
||||
|
||||
// Read reply into structure from buffer for XineramaQueryVersion
|
||||
func xineramaQueryVersionReply(buf []byte) *XineramaQueryVersionReply {
|
||||
v := new(XineramaQueryVersionReply)
|
||||
b := 1 // skip reply determinant
|
||||
|
||||
b += 1 // padding
|
||||
|
||||
v.Sequence = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Length = Get32(buf[b:]) // 4-byte units
|
||||
b += 4
|
||||
|
||||
v.Major = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Minor = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (cook XineramaQueryVersionCookie) Check() error {
|
||||
return cook.check()
|
||||
}
|
||||
|
||||
// Write request to wire for XineramaQueryVersion
|
||||
func (c *Conn) xineramaQueryVersionRequest(Major byte, Minor byte) []byte {
|
||||
size := 8
|
||||
b := 0
|
||||
buf := make([]byte, size)
|
||||
|
||||
buf[b] = c.extensions["XINERAMA"]
|
||||
b += 1
|
||||
|
||||
buf[b] = 0 // request opcode
|
||||
b += 1
|
||||
|
||||
buf[b] = Major
|
||||
b += 1
|
||||
|
||||
Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
|
||||
b += 2
|
||||
|
||||
buf[b] = Minor
|
||||
b += 1
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Request XineramaGetState
|
||||
// size: 8
|
||||
type XineramaGetStateCookie struct {
|
||||
*cookie
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaGetState(Window Id) XineramaGetStateCookie {
|
||||
cookie := c.newCookie(true, true)
|
||||
c.newRequest(c.xineramaGetStateRequest(Window), cookie)
|
||||
return XineramaGetStateCookie{cookie}
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaGetStateUnchecked(Window Id) XineramaGetStateCookie {
|
||||
cookie := c.newCookie(false, true)
|
||||
c.newRequest(c.xineramaGetStateRequest(Window), cookie)
|
||||
return XineramaGetStateCookie{cookie}
|
||||
}
|
||||
|
||||
// Request reply for XineramaGetState
|
||||
// size: 12
|
||||
type XineramaGetStateReply struct {
|
||||
Sequence uint16
|
||||
Length uint32
|
||||
State byte
|
||||
Window Id
|
||||
}
|
||||
|
||||
// Waits and reads reply data from request XineramaGetState
|
||||
func (cook XineramaGetStateCookie) Reply() (*XineramaGetStateReply, error) {
|
||||
buf, err := cook.reply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return xineramaGetStateReply(buf), nil
|
||||
}
|
||||
|
||||
// Read reply into structure from buffer for XineramaGetState
|
||||
func xineramaGetStateReply(buf []byte) *XineramaGetStateReply {
|
||||
v := new(XineramaGetStateReply)
|
||||
b := 1 // skip reply determinant
|
||||
|
||||
v.State = buf[b]
|
||||
b += 1
|
||||
|
||||
v.Sequence = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Length = Get32(buf[b:]) // 4-byte units
|
||||
b += 4
|
||||
|
||||
v.Window = Id(Get32(buf[b:]))
|
||||
b += 4
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (cook XineramaGetStateCookie) Check() error {
|
||||
return cook.check()
|
||||
}
|
||||
|
||||
// Write request to wire for XineramaGetState
|
||||
func (c *Conn) xineramaGetStateRequest(Window Id) []byte {
|
||||
size := 8
|
||||
b := 0
|
||||
buf := make([]byte, size)
|
||||
|
||||
buf[b] = c.extensions["XINERAMA"]
|
||||
b += 1
|
||||
|
||||
buf[b] = 1 // request opcode
|
||||
b += 1
|
||||
|
||||
Put32(buf[b:], uint32(Window))
|
||||
b += 4
|
||||
|
||||
Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
|
||||
b += 2
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Request XineramaGetScreenCount
|
||||
// size: 8
|
||||
type XineramaGetScreenCountCookie struct {
|
||||
*cookie
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaGetScreenCount(Window Id) XineramaGetScreenCountCookie {
|
||||
cookie := c.newCookie(true, true)
|
||||
c.newRequest(c.xineramaGetScreenCountRequest(Window), cookie)
|
||||
return XineramaGetScreenCountCookie{cookie}
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaGetScreenCountUnchecked(Window Id) XineramaGetScreenCountCookie {
|
||||
cookie := c.newCookie(false, true)
|
||||
c.newRequest(c.xineramaGetScreenCountRequest(Window), cookie)
|
||||
return XineramaGetScreenCountCookie{cookie}
|
||||
}
|
||||
|
||||
// Request reply for XineramaGetScreenCount
|
||||
// size: 12
|
||||
type XineramaGetScreenCountReply struct {
|
||||
Sequence uint16
|
||||
Length uint32
|
||||
ScreenCount byte
|
||||
Window Id
|
||||
}
|
||||
|
||||
// Waits and reads reply data from request XineramaGetScreenCount
|
||||
func (cook XineramaGetScreenCountCookie) Reply() (*XineramaGetScreenCountReply, error) {
|
||||
buf, err := cook.reply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return xineramaGetScreenCountReply(buf), nil
|
||||
}
|
||||
|
||||
// Read reply into structure from buffer for XineramaGetScreenCount
|
||||
func xineramaGetScreenCountReply(buf []byte) *XineramaGetScreenCountReply {
|
||||
v := new(XineramaGetScreenCountReply)
|
||||
b := 1 // skip reply determinant
|
||||
|
||||
v.ScreenCount = buf[b]
|
||||
b += 1
|
||||
|
||||
v.Sequence = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Length = Get32(buf[b:]) // 4-byte units
|
||||
b += 4
|
||||
|
||||
v.Window = Id(Get32(buf[b:]))
|
||||
b += 4
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (cook XineramaGetScreenCountCookie) Check() error {
|
||||
return cook.check()
|
||||
}
|
||||
|
||||
// Write request to wire for XineramaGetScreenCount
|
||||
func (c *Conn) xineramaGetScreenCountRequest(Window Id) []byte {
|
||||
size := 8
|
||||
b := 0
|
||||
buf := make([]byte, size)
|
||||
|
||||
buf[b] = c.extensions["XINERAMA"]
|
||||
b += 1
|
||||
|
||||
buf[b] = 2 // request opcode
|
||||
b += 1
|
||||
|
||||
Put32(buf[b:], uint32(Window))
|
||||
b += 4
|
||||
|
||||
Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
|
||||
b += 2
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Request XineramaGetScreenSize
|
||||
// size: 12
|
||||
type XineramaGetScreenSizeCookie struct {
|
||||
*cookie
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaGetScreenSize(Window Id, Screen uint32) XineramaGetScreenSizeCookie {
|
||||
cookie := c.newCookie(true, true)
|
||||
c.newRequest(c.xineramaGetScreenSizeRequest(Window, Screen), cookie)
|
||||
return XineramaGetScreenSizeCookie{cookie}
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaGetScreenSizeUnchecked(Window Id, Screen uint32) XineramaGetScreenSizeCookie {
|
||||
cookie := c.newCookie(false, true)
|
||||
c.newRequest(c.xineramaGetScreenSizeRequest(Window, Screen), cookie)
|
||||
return XineramaGetScreenSizeCookie{cookie}
|
||||
}
|
||||
|
||||
// Request reply for XineramaGetScreenSize
|
||||
// size: 24
|
||||
type XineramaGetScreenSizeReply struct {
|
||||
Sequence uint16
|
||||
Length uint32
|
||||
// padding: 1 bytes
|
||||
Width uint32
|
||||
Height uint32
|
||||
Window Id
|
||||
Screen uint32
|
||||
}
|
||||
|
||||
// Waits and reads reply data from request XineramaGetScreenSize
|
||||
func (cook XineramaGetScreenSizeCookie) Reply() (*XineramaGetScreenSizeReply, error) {
|
||||
buf, err := cook.reply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return xineramaGetScreenSizeReply(buf), nil
|
||||
}
|
||||
|
||||
// Read reply into structure from buffer for XineramaGetScreenSize
|
||||
func xineramaGetScreenSizeReply(buf []byte) *XineramaGetScreenSizeReply {
|
||||
v := new(XineramaGetScreenSizeReply)
|
||||
b := 1 // skip reply determinant
|
||||
|
||||
b += 1 // padding
|
||||
|
||||
v.Sequence = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Length = Get32(buf[b:]) // 4-byte units
|
||||
b += 4
|
||||
|
||||
v.Width = Get32(buf[b:])
|
||||
b += 4
|
||||
|
||||
v.Height = Get32(buf[b:])
|
||||
b += 4
|
||||
|
||||
v.Window = Id(Get32(buf[b:]))
|
||||
b += 4
|
||||
|
||||
v.Screen = Get32(buf[b:])
|
||||
b += 4
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (cook XineramaGetScreenSizeCookie) Check() error {
|
||||
return cook.check()
|
||||
}
|
||||
|
||||
// Write request to wire for XineramaGetScreenSize
|
||||
func (c *Conn) xineramaGetScreenSizeRequest(Window Id, Screen uint32) []byte {
|
||||
size := 12
|
||||
b := 0
|
||||
buf := make([]byte, size)
|
||||
|
||||
buf[b] = c.extensions["XINERAMA"]
|
||||
b += 1
|
||||
|
||||
buf[b] = 3 // request opcode
|
||||
b += 1
|
||||
|
||||
Put32(buf[b:], uint32(Window))
|
||||
b += 4
|
||||
|
||||
Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
|
||||
b += 2
|
||||
|
||||
Put32(buf[b:], Screen)
|
||||
b += 4
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Request XineramaIsActive
|
||||
// size: 4
|
||||
type XineramaIsActiveCookie struct {
|
||||
*cookie
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaIsActive() XineramaIsActiveCookie {
|
||||
cookie := c.newCookie(true, true)
|
||||
c.newRequest(c.xineramaIsActiveRequest(), cookie)
|
||||
return XineramaIsActiveCookie{cookie}
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaIsActiveUnchecked() XineramaIsActiveCookie {
|
||||
cookie := c.newCookie(false, true)
|
||||
c.newRequest(c.xineramaIsActiveRequest(), cookie)
|
||||
return XineramaIsActiveCookie{cookie}
|
||||
}
|
||||
|
||||
// Request reply for XineramaIsActive
|
||||
// size: 12
|
||||
type XineramaIsActiveReply struct {
|
||||
Sequence uint16
|
||||
Length uint32
|
||||
// padding: 1 bytes
|
||||
State uint32
|
||||
}
|
||||
|
||||
// Waits and reads reply data from request XineramaIsActive
|
||||
func (cook XineramaIsActiveCookie) Reply() (*XineramaIsActiveReply, error) {
|
||||
buf, err := cook.reply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return xineramaIsActiveReply(buf), nil
|
||||
}
|
||||
|
||||
// Read reply into structure from buffer for XineramaIsActive
|
||||
func xineramaIsActiveReply(buf []byte) *XineramaIsActiveReply {
|
||||
v := new(XineramaIsActiveReply)
|
||||
b := 1 // skip reply determinant
|
||||
|
||||
b += 1 // padding
|
||||
|
||||
v.Sequence = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Length = Get32(buf[b:]) // 4-byte units
|
||||
b += 4
|
||||
|
||||
v.State = Get32(buf[b:])
|
||||
b += 4
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (cook XineramaIsActiveCookie) Check() error {
|
||||
return cook.check()
|
||||
}
|
||||
|
||||
// Write request to wire for XineramaIsActive
|
||||
func (c *Conn) xineramaIsActiveRequest() []byte {
|
||||
size := 4
|
||||
b := 0
|
||||
buf := make([]byte, size)
|
||||
|
||||
buf[b] = c.extensions["XINERAMA"]
|
||||
b += 1
|
||||
|
||||
buf[b] = 4 // request opcode
|
||||
b += 1
|
||||
|
||||
Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
|
||||
b += 2
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Request XineramaQueryScreens
|
||||
// size: 4
|
||||
type XineramaQueryScreensCookie struct {
|
||||
*cookie
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaQueryScreens() XineramaQueryScreensCookie {
|
||||
cookie := c.newCookie(true, true)
|
||||
c.newRequest(c.xineramaQueryScreensRequest(), cookie)
|
||||
return XineramaQueryScreensCookie{cookie}
|
||||
}
|
||||
|
||||
func (c *Conn) XineramaQueryScreensUnchecked() XineramaQueryScreensCookie {
|
||||
cookie := c.newCookie(false, true)
|
||||
c.newRequest(c.xineramaQueryScreensRequest(), cookie)
|
||||
return XineramaQueryScreensCookie{cookie}
|
||||
}
|
||||
|
||||
// Request reply for XineramaQueryScreens
|
||||
// size: (32 + pad((int(Number) * 8)))
|
||||
type XineramaQueryScreensReply struct {
|
||||
Sequence uint16
|
||||
Length uint32
|
||||
// padding: 1 bytes
|
||||
Number uint32
|
||||
// padding: 20 bytes
|
||||
ScreenInfo []XineramaScreenInfo // size: pad((int(Number) * 8))
|
||||
}
|
||||
|
||||
// Waits and reads reply data from request XineramaQueryScreens
|
||||
func (cook XineramaQueryScreensCookie) Reply() (*XineramaQueryScreensReply, error) {
|
||||
buf, err := cook.reply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return xineramaQueryScreensReply(buf), nil
|
||||
}
|
||||
|
||||
// Read reply into structure from buffer for XineramaQueryScreens
|
||||
func xineramaQueryScreensReply(buf []byte) *XineramaQueryScreensReply {
|
||||
v := new(XineramaQueryScreensReply)
|
||||
b := 1 // skip reply determinant
|
||||
|
||||
b += 1 // padding
|
||||
|
||||
v.Sequence = Get16(buf[b:])
|
||||
b += 2
|
||||
|
||||
v.Length = Get32(buf[b:]) // 4-byte units
|
||||
b += 4
|
||||
|
||||
v.Number = Get32(buf[b:])
|
||||
b += 4
|
||||
|
||||
b += 20 // padding
|
||||
|
||||
v.ScreenInfo = make([]XineramaScreenInfo, v.Number)
|
||||
b += ReadXineramaScreenInfoList(buf[b:], v.ScreenInfo)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (cook XineramaQueryScreensCookie) Check() error {
|
||||
return cook.check()
|
||||
}
|
||||
|
||||
// Write request to wire for XineramaQueryScreens
|
||||
func (c *Conn) xineramaQueryScreensRequest() []byte {
|
||||
size := 4
|
||||
b := 0
|
||||
buf := make([]byte, size)
|
||||
|
||||
buf[b] = c.extensions["XINERAMA"]
|
||||
b += 1
|
||||
|
||||
buf[b] = 5 // request opcode
|
||||
b += 1
|
||||
|
||||
Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
|
||||
b += 2
|
||||
|
||||
return buf
|
||||
}
|
2847
nexgb/xproto.go
2847
nexgb/xproto.go
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue