extensions are working! extensions are working!
This commit is contained in:
parent
b6715f376f
commit
369ad0d33e
|
@ -10,7 +10,8 @@ import (
|
||||||
"strings"
|
"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").
|
// If 'display' is empty it will be taken from os.Getenv("DISPLAY").
|
||||||
// Note that you should read and understand the "Connection Setup" of the
|
// Note that you should read and understand the "Connection Setup" of the
|
||||||
// X Protocol Reference Manual before changing this function:
|
// X Protocol Reference Manual before changing this function:
|
||||||
|
@ -87,6 +88,7 @@ func (c *Conn) connect(display string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dial initializes the actual net connection with X.
|
||||||
func (c *Conn) dial(display string) error {
|
func (c *Conn) dial(display string) error {
|
||||||
if len(display) == 0 {
|
if len(display) == 0 {
|
||||||
display = os.Getenv("DISPLAY")
|
display = os.Getenv("DISPLAY")
|
||||||
|
|
|
@ -4,16 +4,28 @@ import (
|
||||||
"errors"
|
"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 {
|
type cookie struct {
|
||||||
|
conn *Conn
|
||||||
Sequence uint16
|
Sequence uint16
|
||||||
replyChan chan []byte
|
replyChan chan []byte
|
||||||
errorChan chan error
|
errorChan chan error
|
||||||
pingChan chan bool
|
pingChan chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) newCookie(checked, reply bool) cookie {
|
// newCookie creates a new cookie with the correct channels initialized
|
||||||
cookie := cookie{
|
// depending upon the values of 'checked' and 'reply'. Together, there are
|
||||||
Sequence: c.newSequenceId(),
|
// 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,
|
replyChan: nil,
|
||||||
errorChan: nil,
|
errorChan: nil,
|
||||||
pingChan: nil,
|
pingChan: nil,
|
||||||
|
@ -48,6 +60,8 @@ func (c *Conn) newCookie(checked, reply bool) cookie {
|
||||||
return 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) {
|
func (c cookie) reply() ([]byte, error) {
|
||||||
// checked
|
// checked
|
||||||
if c.errorChan != nil {
|
if c.errorChan != nil {
|
||||||
|
@ -56,6 +70,10 @@ func (c cookie) reply() ([]byte, error) {
|
||||||
return c.replyUnchecked()
|
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) {
|
func (c cookie) replyChecked() ([]byte, error) {
|
||||||
if c.replyChan == nil {
|
if c.replyChan == nil {
|
||||||
return nil, errors.New("Cannot call 'replyChecked' on a cookie that " +
|
return nil, errors.New("Cannot call 'replyChecked' on a cookie that " +
|
||||||
|
@ -75,6 +93,12 @@ func (c cookie) replyChecked() ([]byte, error) {
|
||||||
panic("unreachable")
|
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) {
|
func (c cookie) replyUnchecked() ([]byte, error) {
|
||||||
if c.replyChan == nil {
|
if c.replyChan == nil {
|
||||||
return nil, errors.New("Cannot call 'replyUnchecked' on a cookie " +
|
return nil, errors.New("Cannot call 'replyUnchecked' on a cookie " +
|
||||||
|
@ -90,7 +114,15 @@ func (c cookie) replyUnchecked() ([]byte, error) {
|
||||||
panic("unreachable")
|
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 {
|
if c.replyChan != nil {
|
||||||
return errors.New("Cannot call 'Check' on a cookie that is " +
|
return errors.New("Cannot call 'Check' on a cookie that is " +
|
||||||
"expecting a *reply*. Use 'Reply' instead.")
|
"expecting a *reply*. Use 'Reply' instead.")
|
||||||
|
@ -100,6 +132,17 @@ func (c cookie) Check() error {
|
||||||
"not expecting a possible *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 {
|
select {
|
||||||
case err := <-c.errorChan:
|
case err := <-c.errorChan:
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -18,7 +18,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
aname := "_NET_ACTIVE_WINDOW"
|
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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,15 @@ func main() {
|
||||||
root := X.DefaultScreen().Root
|
root := X.DefaultScreen().Root
|
||||||
|
|
||||||
aname := "_NET_ACTIVE_WINDOW"
|
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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := X.GetProperty(false, root, atom.Atom, xgb.GetPropertyTypeAny,
|
reply, err := X.GetProperty(false, root, atom.Atom,
|
||||||
0, (1<<32)-1)
|
xgb.GetPropertyTypeAny, 0, (1<<32)-1).Reply()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
log.Printf("%X", get32(reply.Value))
|
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 (
|
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
|
readBuffer = 100
|
||||||
writeBuffer = 100
|
writeBuffer = 100
|
||||||
)
|
)
|
||||||
|
@ -32,7 +37,7 @@ type Conn struct {
|
||||||
extensions map[string]byte
|
extensions map[string]byte
|
||||||
|
|
||||||
eventChan chan eventOrError
|
eventChan chan eventOrError
|
||||||
cookieChan chan cookie
|
cookieChan chan *cookie
|
||||||
xidChan chan xid
|
xidChan chan xid
|
||||||
seqChan chan uint16
|
seqChan chan uint16
|
||||||
reqChan chan *request
|
reqChan chan *request
|
||||||
|
@ -68,7 +73,7 @@ func NewConnDisplay(display string) (*Conn, error) {
|
||||||
|
|
||||||
conn.extensions = make(map[string]byte)
|
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.xidChan = make(chan xid, 5)
|
||||||
conn.seqChan = make(chan uint16, 20)
|
conn.seqChan = make(chan uint16, 20)
|
||||||
conn.reqChan = make(chan *request, 100)
|
conn.reqChan = make(chan *request, 100)
|
||||||
|
@ -87,6 +92,12 @@ func (c *Conn) Close() {
|
||||||
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.
|
// Id is used for all X identifiers, such as windows, pixmaps, and GCs.
|
||||||
type Id uint32
|
type Id uint32
|
||||||
|
|
||||||
|
@ -95,6 +106,7 @@ type Id uint32
|
||||||
type Event interface {
|
type Event interface {
|
||||||
ImplementsEvent()
|
ImplementsEvent()
|
||||||
Bytes() []byte
|
Bytes() []byte
|
||||||
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newEventFuncs is a map from event numbers to functions that create
|
// 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.
|
// to match up replies with requests.
|
||||||
// Since sequence ids can only be 16 bit integers we start over at zero when it
|
// Since sequence ids can only be 16 bit integers we start over at zero when it
|
||||||
// comes time to wrap.
|
// 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() {
|
func (c *Conn) generateSeqIds() {
|
||||||
seqid := uint16(1)
|
seqid := uint16(1)
|
||||||
for {
|
for {
|
||||||
|
@ -206,13 +219,14 @@ func (c *Conn) generateSeqIds() {
|
||||||
// The cookie is used to match up the reply/error.
|
// The cookie is used to match up the reply/error.
|
||||||
type request struct {
|
type request struct {
|
||||||
buf []byte
|
buf []byte
|
||||||
cookie cookie
|
cookie *cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRequest takes the bytes an a cookie, constructs a request type,
|
// newRequest takes the bytes an a cookie, constructs a request type,
|
||||||
// and sends it over the Conn.reqChan channel. It then returns the cookie
|
// and sends it over the Conn.reqChan channel.
|
||||||
// (for convenience).
|
// Note that the sequence number is added to the cookie after it is sent
|
||||||
func (c *Conn) newRequest(buf []byte, cookie cookie) {
|
// over the request channel.
|
||||||
|
func (c *Conn) newRequest(buf []byte, cookie *cookie) {
|
||||||
c.reqChan <- &request{buf: buf, 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.
|
// the bytes to the wire and adds the cookie to the cookie queue.
|
||||||
func (c *Conn) sendRequests() {
|
func (c *Conn) sendRequests() {
|
||||||
for req := range c.reqChan {
|
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
|
c.cookieChan <- req.cookie
|
||||||
if _, err := c.conn.Write(req.buf); err != nil {
|
if !c.writeBuffer(req.buf) {
|
||||||
fmt.Fprintf(os.Stderr, "x protocol write error: %s\n", err)
|
|
||||||
close(c.reqChan)
|
|
||||||
return
|
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
|
// readResponses is a goroutine that reads events, errors and
|
||||||
// replies off the wire.
|
// replies off the wire.
|
||||||
// When an event is read, it is always added to the event channel.
|
// 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
|
case 0: // This is an error
|
||||||
// Use the constructor function for this error (that is auto
|
// Use the constructor function for this error (that is auto
|
||||||
// generated) by looking it up by the error number.
|
// 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()
|
seq = err.SequenceId()
|
||||||
|
|
||||||
// This error is either sent to the event channel or a specific
|
// 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
|
// 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
|
// the most significant bit (which is set when it was sent from
|
||||||
// a SendEvent request).
|
// a SendEvent request).
|
||||||
event = newEventFuncs[int(buf[0] & 127)](buf)
|
evNum := int(buf[0] & 127)
|
||||||
// seq = event.SequenceId() // 0 for KeymapNotify
|
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.
|
// Put the event into the queue.
|
||||||
c.eventChan <- event
|
c.eventChan <- event
|
||||||
|
|
||||||
// No more processing for events.
|
// No more processing for events.
|
||||||
continue
|
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
|
// At this point, we have a sequence number and we're either
|
||||||
|
@ -326,12 +372,17 @@ func (c *Conn) readResponses() {
|
||||||
cookie.errorChan <- err
|
cookie.errorChan <- err
|
||||||
} else { // asynchronous processing
|
} else { // asynchronous processing
|
||||||
c.eventChan <- err
|
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
|
} else { // this is a reply
|
||||||
if cookie.replyChan == nil {
|
if cookie.replyChan == nil {
|
||||||
fmt.Fprintf(os.Stderr,
|
fmt.Fprintf(os.Stderr,
|
||||||
"Reply with sequence id %d does not have a " +
|
"Reply with sequence id %d does not have a " +
|
||||||
"cookie with a valid reply channel.\n", seq)
|
"cookie with a valid reply channel.\n", seq)
|
||||||
|
continue
|
||||||
} else {
|
} else {
|
||||||
cookie.replyChan <- replyBytes
|
cookie.replyChan <- replyBytes
|
||||||
}
|
}
|
||||||
|
@ -344,10 +395,14 @@ func (c *Conn) readResponses() {
|
||||||
case cookie.replyChan != nil && cookie.errorChan != nil:
|
case cookie.replyChan != nil && cookie.errorChan != nil:
|
||||||
fmt.Fprintf(os.Stderr,
|
fmt.Fprintf(os.Stderr,
|
||||||
"Found cookie with sequence id %d that is expecting a " +
|
"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
|
// Unchecked requests with replies
|
||||||
case cookie.replyChan != nil && cookie.pingChan != nil:
|
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
|
// Checked requests without replies
|
||||||
case cookie.pingChan != nil && cookie.errorChan != nil:
|
case cookie.pingChan != nil && cookie.errorChan != nil:
|
||||||
cookie.pingChan <- true
|
cookie.pingChan <- true
|
||||||
|
@ -368,6 +423,7 @@ func processEventOrError(everr eventOrError) (Event, Error) {
|
||||||
return nil, ee
|
return nil, ee
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "Invalid event/error type: %T\n", everr)
|
fmt.Fprintf(os.Stderr, "Invalid event/error type: %T\n", everr)
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,20 +5,6 @@ import (
|
||||||
"strings"
|
"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
|
// stringsJoin is an alias to strings.Join. It allows us to avoid having to
|
||||||
// import 'strings' in each of the generated Go files.
|
// import 'strings' in each of the generated Go files.
|
||||||
func stringsJoin(ss []string, sep string) string {
|
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.
|
// Pad a length to align on 4 bytes.
|
||||||
func pad(n int) int { return (n + 3) & ^3 }
|
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 Put32(buf []byte, v uint32) {
|
// popCount counts the number of bits set in a value list mask.
|
||||||
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.
|
|
||||||
func popCount(mask0 int) int {
|
func popCount(mask0 int) int {
|
||||||
mask := uint32(mask0)
|
mask := uint32(mask0)
|
||||||
n := 0
|
n := 0
|
||||||
|
@ -94,6 +33,57 @@ func popCount(mask0 int) int {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultScreen returns the Screen info for the default screen, which is
|
// Put16 takes a 16 bit integer and copies it into a byte slice.
|
||||||
// 0 or the one given in the display argument to Dial.
|
func Put16(buf []byte, v uint16) {
|
||||||
func (c *Conn) DefaultScreen() *ScreenInfo { return &c.Setup.Roots[c.defaultScreen] }
|
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