diff options
| author | jEzEk <[email protected]> | 2022-11-05 21:22:59 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-11-05 21:22:59 +0100 |
| commit | a57abb570aeba12f867c58afe22ce49ac5db4872 (patch) | |
| tree | 41f7f8fdc1ec903272515c18a0751041702da69e | |
| parent | 7effddcf465f2b8e142c828c90951614922d9b32 (diff) | |
| parent | ba0b8dd42f220cde96737bbd61d87f1bc136824e (diff) | |
Merge pull request #10 from gen2brain/masterv1.1.0
Support for xcb-proto version 1.15.2, #issue 9
| -rw-r--r-- | glx/glx.go | 133 | ||||
| -rw-r--r-- | randr/randr.go | 839 | ||||
| -rw-r--r-- | record/record.go | 20 | ||||
| -rw-r--r-- | render/render.go | 150 | ||||
| -rw-r--r-- | res/res.go | 12 | ||||
| -rw-r--r-- | screensaver/screensaver.go | 19 | ||||
| -rw-r--r-- | xf86dri/xf86dri.go | 5 | ||||
| -rw-r--r-- | xf86vidmode/xf86vidmode.go | 27 | ||||
| -rw-r--r-- | xfixes/xfixes.go | 177 | ||||
| -rw-r--r-- | xgbgen/aligngap.go | 120 | ||||
| -rw-r--r-- | xgbgen/context.go | 19 | ||||
| -rw-r--r-- | xgbgen/expression.go | 54 | ||||
| -rw-r--r-- | xgbgen/field.go | 79 | ||||
| -rw-r--r-- | xgbgen/go.go | 27 | ||||
| -rw-r--r-- | xgbgen/go_request_reply.go | 14 | ||||
| -rw-r--r-- | xgbgen/request_reply.go | 12 | ||||
| -rw-r--r-- | xgbgen/translation.go | 6 | ||||
| -rw-r--r-- | xgbgen/xml_fields.go | 1 | ||||
| -rw-r--r-- | xprint/xprint.go | 87 | ||||
| -rw-r--r-- | xproto/xproto.go | 106 | ||||
| -rw-r--r-- | xselinux/xselinux.go | 16 | ||||
| -rw-r--r-- | xv/xv.go | 44 |
22 files changed, 1456 insertions, 511 deletions
@@ -3165,14 +3165,14 @@ func getClipPlaneReply(buf []byte) *GetClipPlaneReply { v := new(GetClipPlaneReply) b := 1 // skip reply determinant - b += 1 // padding - v.Sequence = xgb.Get16(buf[b:]) b += 2 v.Length = xgb.Get32(buf[b:]) // 4-byte units b += 4 + b += 1 // padding + b += 24 // padding v.Data = make([]Float64, (int(v.Length) / 2)) @@ -4096,14 +4096,14 @@ func getDoublevReply(buf []byte) *GetDoublevReply { v := new(GetDoublevReply) b := 1 // skip reply determinant - b += 1 // padding - v.Sequence = xgb.Get16(buf[b:]) b += 2 v.Length = xgb.Get32(buf[b:]) // 4-byte units b += 4 + b += 1 // padding + b += 4 // padding v.N = xgb.Get32(buf[b:]) @@ -5340,14 +5340,14 @@ func getMapdvReply(buf []byte) *GetMapdvReply { v := new(GetMapdvReply) b := 1 // skip reply determinant - b += 1 // padding - v.Sequence = xgb.Get16(buf[b:]) b += 2 v.Length = xgb.Get32(buf[b:]) // 4-byte units b += 4 + b += 1 // padding + b += 4 // padding v.N = xgb.Get32(buf[b:]) @@ -7548,14 +7548,14 @@ func getTexGendvReply(buf []byte) *GetTexGendvReply { v := new(GetTexGendvReply) b := 1 // skip reply determinant - b += 1 // padding - v.Sequence = xgb.Get16(buf[b:]) b += 2 v.Length = xgb.Get32(buf[b:]) // 4-byte units b += 4 + b += 1 // padding + b += 4 // padding v.N = xgb.Get32(buf[b:]) @@ -8654,6 +8654,103 @@ func isDirectRequest(c *xgb.Conn, Context Context) []byte { return buf } +// IsEnabledCookie is a cookie used only for IsEnabled requests. +type IsEnabledCookie struct { + *xgb.Cookie +} + +// IsEnabled sends a checked request. +// If an error occurs, it will be returned with the reply by calling IsEnabledCookie.Reply() +func IsEnabled(c *xgb.Conn, ContextTag ContextTag, Capability uint32) IsEnabledCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsEnabled' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(isEnabledRequest(c, ContextTag, Capability), cookie) + return IsEnabledCookie{cookie} +} + +// IsEnabledUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func IsEnabledUnchecked(c *xgb.Conn, ContextTag ContextTag, Capability uint32) IsEnabledCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["GLX"]; !ok { + panic("Cannot issue request 'IsEnabled' using the uninitialized extension 'GLX'. glx.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(isEnabledRequest(c, ContextTag, Capability), cookie) + return IsEnabledCookie{cookie} +} + +// IsEnabledReply represents the data returned from a IsEnabled request. +type IsEnabledReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + RetVal Bool32 +} + +// Reply blocks and returns the reply data for a IsEnabled request. +func (cook IsEnabledCookie) Reply() (*IsEnabledReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return isEnabledReply(buf), nil +} + +// isEnabledReply reads a byte slice into a IsEnabledReply value. +func isEnabledReply(buf []byte) *IsEnabledReply { + v := new(IsEnabledReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.RetVal = Bool32(xgb.Get32(buf[b:])) + b += 4 + + return v +} + +// Write request to wire for IsEnabled +// isEnabledRequest writes a IsEnabled request to a byte slice. +func isEnabledRequest(c *xgb.Conn, ContextTag ContextTag, Capability uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["GLX"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 140 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(ContextTag)) + b += 4 + + xgb.Put32(buf[b:], Capability) + b += 4 + + return buf +} + // IsListCookie is a cookie used only for IsList requests. type IsListCookie struct { *xgb.Cookie @@ -10260,7 +10357,7 @@ func (cook SetClientInfo2ARBCookie) Check() error { // Write request to wire for SetClientInfo2ARB // setClientInfo2ARBRequest writes a SetClientInfo2ARB request to a byte slice. func setClientInfo2ARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) []byte { - size := xgb.Pad((((24 + xgb.Pad(((int(NumVersions) * 3) * 4))) + xgb.Pad((int(GlStrLen) * 1))) + xgb.Pad((int(GlxStrLen) * 1)))) + size := xgb.Pad(((((24 + xgb.Pad(((int(NumVersions) * 3) * 4))) + xgb.Pad((int(GlStrLen) * 1))) + 4) + xgb.Pad((int(GlxStrLen) * 1)))) b := 0 buf := make([]byte, size) @@ -10272,7 +10369,7 @@ func setClientInfo2ARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uin buf[b] = 35 // request opcode b += 1 - xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + blen := b b += 2 xgb.Put32(buf[b:], MajorVersion) @@ -10298,10 +10395,14 @@ func setClientInfo2ARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uin copy(buf[b:], GlExtensionString[:GlStrLen]) b += int(GlStrLen) + b = (b + 3) & ^3 // alignment gap + copy(buf[b:], GlxExtensionString[:GlxStrLen]) b += int(GlxStrLen) - return buf + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] } // SetClientInfoARBCookie is a cookie used only for SetClientInfoARB requests. @@ -10344,7 +10445,7 @@ func (cook SetClientInfoARBCookie) Check() error { // Write request to wire for SetClientInfoARB // setClientInfoARBRequest writes a SetClientInfoARB request to a byte slice. func setClientInfoARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32, NumVersions uint32, GlStrLen uint32, GlxStrLen uint32, GlVersions []uint32, GlExtensionString string, GlxExtensionString string) []byte { - size := xgb.Pad((((24 + xgb.Pad(((int(NumVersions) * 2) * 4))) + xgb.Pad((int(GlStrLen) * 1))) + xgb.Pad((int(GlxStrLen) * 1)))) + size := xgb.Pad(((((24 + xgb.Pad(((int(NumVersions) * 2) * 4))) + xgb.Pad((int(GlStrLen) * 1))) + 4) + xgb.Pad((int(GlxStrLen) * 1)))) b := 0 buf := make([]byte, size) @@ -10356,7 +10457,7 @@ func setClientInfoARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint buf[b] = 33 // request opcode b += 1 - xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + blen := b b += 2 xgb.Put32(buf[b:], MajorVersion) @@ -10382,10 +10483,14 @@ func setClientInfoARBRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint copy(buf[b:], GlExtensionString[:GlStrLen]) b += int(GlStrLen) + b = (b + 3) & ^3 // alignment gap + copy(buf[b:], GlxExtensionString[:GlxStrLen]) b += int(GlxStrLen) - return buf + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] } // SwapBuffersCookie is a cookie used only for SwapBuffers requests. diff --git a/randr/randr.go b/randr/randr.go index bc62d73..2944f68 100644 --- a/randr/randr.go +++ b/randr/randr.go @@ -345,6 +345,89 @@ func CrtcChangeListBytes(buf []byte, list []CrtcChange) int { return xgb.Pad(b) } +type Lease uint32 + +func NewLeaseId(c *xgb.Conn) (Lease, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Lease(id), nil +} + +type LeaseNotify struct { + Timestamp xproto.Timestamp + Window xproto.Window + Lease Lease + Created byte + // padding: 15 bytes +} + +// LeaseNotifyRead reads a byte slice into a LeaseNotify value. +func LeaseNotifyRead(buf []byte, v *LeaseNotify) int { + b := 0 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Lease = Lease(xgb.Get32(buf[b:])) + b += 4 + + v.Created = buf[b] + b += 1 + + b += 15 // padding + + return b +} + +// LeaseNotifyReadList reads a byte slice into a list of LeaseNotify values. +func LeaseNotifyReadList(buf []byte, dest []LeaseNotify) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a LeaseNotify value to a byte slice. +func (v LeaseNotify) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Lease)) + b += 4 + + buf[b] = v.Created + b += 1 + + b += 15 // padding + + return buf[:b] +} + +// LeaseNotifyListBytes writes a list of LeaseNotify values to a byte slice. +func LeaseNotifyListBytes(buf []byte, list []LeaseNotify) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + type Mode uint32 func NewModeId(c *xgb.Conn) (Mode, error) { @@ -503,6 +586,153 @@ func ModeInfoListBytes(buf []byte, list []ModeInfo) int { return xgb.Pad(b) } +type MonitorInfo struct { + Name xproto.Atom + Primary bool + Automatic bool + NOutput uint16 + X int16 + Y int16 + Width uint16 + Height uint16 + WidthInMillimeters uint32 + HeightInMillimeters uint32 + Outputs []Output // size: xgb.Pad((int(NOutput) * 4)) +} + +// MonitorInfoRead reads a byte slice into a MonitorInfo value. +func MonitorInfoRead(buf []byte, v *MonitorInfo) int { + b := 0 + + v.Name = xproto.Atom(xgb.Get32(buf[b:])) + b += 4 + + if buf[b] == 1 { + v.Primary = true + } else { + v.Primary = false + } + b += 1 + + if buf[b] == 1 { + v.Automatic = true + } else { + v.Automatic = false + } + b += 1 + + v.NOutput = xgb.Get16(buf[b:]) + b += 2 + + v.X = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Y = int16(xgb.Get16(buf[b:])) + b += 2 + + v.Width = xgb.Get16(buf[b:]) + b += 2 + + v.Height = xgb.Get16(buf[b:]) + b += 2 + + v.WidthInMillimeters = xgb.Get32(buf[b:]) + b += 4 + + v.HeightInMillimeters = xgb.Get32(buf[b:]) + b += 4 + + v.Outputs = make([]Output, v.NOutput) + for i := 0; i < int(v.NOutput); i++ { + v.Outputs[i] = Output(xgb.Get32(buf[b:])) + b += 4 + } + + return b +} + +// MonitorInfoReadList reads a byte slice into a list of MonitorInfo values. +func MonitorInfoReadList(buf []byte, dest []MonitorInfo) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = MonitorInfo{} + b += MonitorInfoRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a MonitorInfo value to a byte slice. +func (v MonitorInfo) Bytes() []byte { + buf := make([]byte, (24 + xgb.Pad((int(v.NOutput) * 4)))) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Name)) + b += 4 + + if v.Primary { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + if v.Automatic { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + xgb.Put16(buf[b:], v.NOutput) + b += 2 + + xgb.Put16(buf[b:], uint16(v.X)) + b += 2 + + xgb.Put16(buf[b:], uint16(v.Y)) + b += 2 + + xgb.Put16(buf[b:], v.Width) + b += 2 + + xgb.Put16(buf[b:], v.Height) + b += 2 + + xgb.Put32(buf[b:], v.WidthInMillimeters) + b += 4 + + xgb.Put32(buf[b:], v.HeightInMillimeters) + b += 4 + + for i := 0; i < int(v.NOutput); i++ { + xgb.Put32(buf[b:], uint32(v.Outputs[i])) + b += 4 + } + + return buf[:b] +} + +// MonitorInfoListBytes writes a list of MonitorInfo values to a byte slice. +func MonitorInfoListBytes(buf []byte, list []MonitorInfo) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + +// MonitorInfoListSize computes the size (bytes) of a list of MonitorInfo values. +func MonitorInfoListSize(list []MonitorInfo) int { + size := 0 + for _, item := range list { + size += (24 + xgb.Pad((int(item.NOutput) * 4))) + } + return size +} + const ( NotifyCrtcChange = 0 NotifyOutputChange = 1 @@ -510,6 +740,7 @@ const ( NotifyProviderChange = 3 NotifyProviderProperty = 4 NotifyResourceChange = 5 + NotifyLease = 6 ) // Notify is the event number for a NotifyEvent. @@ -584,12 +815,14 @@ func init() { // Note that to *create* a Union, you should *never* create // this struct directly (unless you know what you're doing). // Instead use one of the following constructors for 'NotifyDataUnion': -// NotifyDataUnionCcNew(Cc CrtcChange) NotifyDataUnion -// NotifyDataUnionOcNew(Oc OutputChange) NotifyDataUnion -// NotifyDataUnionOpNew(Op OutputProperty) NotifyDataUnion -// NotifyDataUnionPcNew(Pc ProviderChange) NotifyDataUnion -// NotifyDataUnionPpNew(Pp ProviderProperty) NotifyDataUnion -// NotifyDataUnionRcNew(Rc ResourceChange) NotifyDataUnion +// +// NotifyDataUnionCcNew(Cc CrtcChange) NotifyDataUnion +// NotifyDataUnionOcNew(Oc OutputChange) NotifyDataUnion +// NotifyDataUnionOpNew(Op OutputProperty) NotifyDataUnion +// NotifyDataUnionPcNew(Pc ProviderChange) NotifyDataUnion +// NotifyDataUnionPpNew(Pp ProviderProperty) NotifyDataUnion +// NotifyDataUnionRcNew(Rc ResourceChange) NotifyDataUnion +// NotifyDataUnionLcNew(Lc LeaseNotify) NotifyDataUnion type NotifyDataUnion struct { Cc CrtcChange Oc OutputChange @@ -597,6 +830,7 @@ type NotifyDataUnion struct { Pc ProviderChange Pp ProviderProperty Rc ResourceChange + Lc LeaseNotify } // NotifyDataUnionCcNew constructs a new NotifyDataUnion union type with the Cc field. @@ -639,6 +873,10 @@ func NotifyDataUnionCcNew(Cc CrtcChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -682,6 +920,10 @@ func NotifyDataUnionOcNew(Oc OutputChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -725,6 +967,10 @@ func NotifyDataUnionOpNew(Op OutputProperty) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -768,6 +1014,10 @@ func NotifyDataUnionPcNew(Pc ProviderChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -811,6 +1061,10 @@ func NotifyDataUnionPpNew(Pp ProviderProperty) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -854,6 +1108,57 @@ func NotifyDataUnionRcNew(Rc ResourceChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionLcNew constructs a new NotifyDataUnion union type with the Lc field. +func NotifyDataUnionLcNew(Lc LeaseNotify) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Lc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -885,6 +1190,10 @@ func NotifyDataUnionRead(buf []byte, v *NotifyDataUnion) int { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // re-read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return 28 } @@ -933,6 +1242,7 @@ const ( NotifyMaskProviderChange = 16 NotifyMaskProviderProperty = 32 NotifyMaskResourceChange = 64 + NotifyMaskLease = 128 ) type Output uint32 @@ -2067,6 +2377,119 @@ func configureProviderPropertyRequest(c *xgb.Conn, Provider Provider, Property x return buf } +// CreateLeaseCookie is a cookie used only for CreateLease requests. +type CreateLeaseCookie struct { + *xgb.Cookie +} + +// CreateLease sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateLeaseCookie.Reply() +func CreateLease(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs uint16, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) CreateLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createLeaseRequest(c, Window, Lid, NumCrtcs, NumOutputs, Crtcs, Outputs), cookie) + return CreateLeaseCookie{cookie} +} + +// CreateLeaseUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateLeaseUnchecked(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs uint16, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) CreateLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createLeaseRequest(c, Window, Lid, NumCrtcs, NumOutputs, Crtcs, Outputs), cookie) + return CreateLeaseCookie{cookie} +} + +// CreateLeaseReply represents the data returned from a CreateLease request. +type CreateLeaseReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Nfd byte + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a CreateLease request. +func (cook CreateLeaseCookie) Reply() (*CreateLeaseReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createLeaseReply(buf), nil +} + +// createLeaseReply reads a byte slice into a CreateLeaseReply value. +func createLeaseReply(buf []byte) *CreateLeaseReply { + v := new(CreateLeaseReply) + b := 1 // skip reply determinant + + v.Nfd = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// Write request to wire for CreateLease +// createLeaseRequest writes a CreateLease request to a byte slice. +func createLeaseRequest(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs uint16, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) []byte { + size := xgb.Pad(((16 + xgb.Pad((int(NumCrtcs) * 4))) + xgb.Pad((int(NumOutputs) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 45 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Lid)) + b += 4 + + xgb.Put16(buf[b:], NumCrtcs) + b += 2 + + xgb.Put16(buf[b:], NumOutputs) + b += 2 + + for i := 0; i < int(NumCrtcs); i++ { + xgb.Put32(buf[b:], uint32(Crtcs[i])) + b += 4 + } + + for i := 0; i < int(NumOutputs); i++ { + xgb.Put32(buf[b:], uint32(Outputs[i])) + b += 4 + } + + return buf +} + // CreateModeCookie is a cookie used only for CreateMode requests. type CreateModeCookie struct { *xgb.Cookie @@ -2173,6 +2596,70 @@ func createModeRequest(c *xgb.Conn, Window xproto.Window, ModeInfo ModeInfo, Nam return buf } +// DeleteMonitorCookie is a cookie used only for DeleteMonitor requests. +type DeleteMonitorCookie struct { + *xgb.Cookie +} + +// DeleteMonitor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DeleteMonitor(c *xgb.Conn, Window xproto.Window, Name xproto.Atom) DeleteMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(deleteMonitorRequest(c, Window, Name), cookie) + return DeleteMonitorCookie{cookie} +} + +// DeleteMonitorChecked sends a checked request. +// If an error occurs, it can be retrieved using DeleteMonitorCookie.Check() +func DeleteMonitorChecked(c *xgb.Conn, Window xproto.Window, Name xproto.Atom) DeleteMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'DeleteMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(deleteMonitorRequest(c, Window, Name), cookie) + return DeleteMonitorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook DeleteMonitorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DeleteMonitor +// deleteMonitorRequest writes a DeleteMonitor request to a byte slice. +func deleteMonitorRequest(c *xgb.Conn, Window xproto.Window, Name xproto.Atom) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 44 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(Name)) + b += 4 + + return buf +} + // DeleteOutputModeCookie is a cookie used only for DeleteOutputMode requests. type DeleteOutputModeCookie struct { *xgb.Cookie @@ -2426,6 +2913,70 @@ func destroyModeRequest(c *xgb.Conn, Mode Mode) []byte { return buf } +// FreeLeaseCookie is a cookie used only for FreeLease requests. +type FreeLeaseCookie struct { + *xgb.Cookie +} + +// FreeLease sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeLease(c *xgb.Conn, Lid Lease, Terminate byte) FreeLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'FreeLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(freeLeaseRequest(c, Lid, Terminate), cookie) + return FreeLeaseCookie{cookie} +} + +// FreeLeaseChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeLeaseCookie.Check() +func FreeLeaseChecked(c *xgb.Conn, Lid Lease, Terminate byte) FreeLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'FreeLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(freeLeaseRequest(c, Lid, Terminate), cookie) + return FreeLeaseCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook FreeLeaseCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for FreeLease +// freeLeaseRequest writes a FreeLease request to a byte slice. +func freeLeaseRequest(c *xgb.Conn, Lid Lease, Terminate byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 46 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Lid)) + b += 4 + + buf[b] = Terminate + b += 1 + + return buf +} + // GetCrtcGammaCookie is a cookie used only for GetCrtcGamma requests. type GetCrtcGammaCookie struct { *xgb.Cookie @@ -2464,11 +3015,9 @@ type GetCrtcGammaReply struct { // padding: 1 bytes Size uint16 // padding: 22 bytes - Red []uint16 // size: xgb.Pad((int(Size) * 2)) - // alignment gap to multiple of 2 + Red []uint16 // size: xgb.Pad((int(Size) * 2)) Green []uint16 // size: xgb.Pad((int(Size) * 2)) - // alignment gap to multiple of 2 - Blue []uint16 // size: xgb.Pad((int(Size) * 2)) + Blue []uint16 // size: xgb.Pad((int(Size) * 2)) } // Reply blocks and returns the reply data for a GetCrtcGamma request. @@ -2507,16 +3056,12 @@ func getCrtcGammaReply(buf []byte) *GetCrtcGammaReply { b += 2 } - b = (b + 1) & ^1 // alignment gap - v.Green = make([]uint16, v.Size) for i := 0; i < int(v.Size); i++ { v.Green[i] = xgb.Get16(buf[b:]) b += 2 } - b = (b + 1) & ^1 // alignment gap - v.Blue = make([]uint16, v.Size) for i := 0; i < int(v.Size); i++ { v.Blue[i] = xgb.Get16(buf[b:]) @@ -2694,8 +3239,7 @@ type GetCrtcInfoReply struct { NumOutputs uint16 NumPossibleOutputs uint16 Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) - // alignment gap to multiple of 4 - Possible []Output // size: xgb.Pad((int(NumPossibleOutputs) * 4)) + Possible []Output // size: xgb.Pad((int(NumPossibleOutputs) * 4)) } // Reply blocks and returns the reply data for a GetCrtcInfo request. @@ -2760,8 +3304,6 @@ func getCrtcInfoReply(buf []byte) *GetCrtcInfoReply { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Possible = make([]Output, v.NumPossibleOutputs) for i := 0; i < int(v.NumPossibleOutputs); i++ { v.Possible[i] = Output(xgb.Get32(buf[b:])) @@ -2962,6 +3504,122 @@ func getCrtcTransformRequest(c *xgb.Conn, Crtc Crtc) []byte { return buf } +// GetMonitorsCookie is a cookie used only for GetMonitors requests. +type GetMonitorsCookie struct { + *xgb.Cookie +} + +// GetMonitors sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMonitorsCookie.Reply() +func GetMonitors(c *xgb.Conn, Window xproto.Window, GetActive bool) GetMonitorsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetMonitors' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMonitorsRequest(c, Window, GetActive), cookie) + return GetMonitorsCookie{cookie} +} + +// GetMonitorsUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMonitorsUnchecked(c *xgb.Conn, Window xproto.Window, GetActive bool) GetMonitorsCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'GetMonitors' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMonitorsRequest(c, Window, GetActive), cookie) + return GetMonitorsCookie{cookie} +} + +// GetMonitorsReply represents the data returned from a GetMonitors request. +type GetMonitorsReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Timestamp xproto.Timestamp + NMonitors uint32 + NOutputs uint32 + // padding: 12 bytes + Monitors []MonitorInfo // size: MonitorInfoListSize(Monitors) +} + +// Reply blocks and returns the reply data for a GetMonitors request. +func (cook GetMonitorsCookie) Reply() (*GetMonitorsReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMonitorsReply(buf), nil +} + +// getMonitorsReply reads a byte slice into a GetMonitorsReply value. +func getMonitorsReply(buf []byte) *GetMonitorsReply { + v := new(GetMonitorsReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.NMonitors = xgb.Get32(buf[b:]) + b += 4 + + v.NOutputs = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Monitors = make([]MonitorInfo, v.NMonitors) + b += MonitorInfoReadList(buf[b:], v.Monitors) + + return v +} + +// Write request to wire for GetMonitors +// getMonitorsRequest writes a GetMonitors request to a byte slice. +func getMonitorsRequest(c *xgb.Conn, Window xproto.Window, GetActive bool) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 42 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + if GetActive { + buf[b] = 1 + } else { + buf[b] = 0 + } + b += 1 + + return buf +} + // GetOutputInfoCookie is a cookie used only for GetOutputInfo requests. type GetOutputInfoCookie struct { *xgb.Cookie @@ -3009,12 +3667,10 @@ type GetOutputInfoReply struct { NumPreferred uint16 NumClones uint16 NameLen uint16 - Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) - // alignment gap to multiple of 4 - Modes []Mode // size: xgb.Pad((int(NumModes) * 4)) - // alignment gap to multiple of 4 - Clones []Output // size: xgb.Pad((int(NumClones) * 4)) - Name []byte // size: xgb.Pad((int(NameLen) * 1)) + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Modes []Mode // size: xgb.Pad((int(NumModes) * 4)) + Clones []Output // size: xgb.Pad((int(NumClones) * 4)) + Name []byte // size: xgb.Pad((int(NameLen) * 1)) } // Reply blocks and returns the reply data for a GetOutputInfo request. @@ -3082,16 +3738,12 @@ func getOutputInfoReply(buf []byte) *GetOutputInfoReply { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Modes = make([]Mode, v.NumModes) for i := 0; i < int(v.NumModes); i++ { v.Modes[i] = Mode(xgb.Get32(buf[b:])) b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Clones = make([]Output, v.NumClones) for i := 0; i < int(v.NumClones); i++ { v.Clones[i] = Output(xgb.Get32(buf[b:])) @@ -3551,14 +4203,11 @@ type GetProviderInfoReply struct { NumAssociatedProviders uint16 NameLen uint16 // padding: 8 bytes - Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) - // alignment gap to multiple of 4 - Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) - // alignment gap to multiple of 4 - AssociatedProviders []Provider // size: xgb.Pad((int(NumAssociatedProviders) * 4)) - // alignment gap to multiple of 4 - AssociatedCapability []uint32 // size: xgb.Pad((int(NumAssociatedProviders) * 4)) - Name string // size: xgb.Pad((int(NameLen) * 1)) + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) + AssociatedProviders []Provider // size: xgb.Pad((int(NumAssociatedProviders) * 4)) + AssociatedCapability []uint32 // size: xgb.Pad((int(NumAssociatedProviders) * 4)) + Name string // size: xgb.Pad((int(NameLen) * 1)) } // Reply blocks and returns the reply data for a GetProviderInfo request. @@ -3613,24 +4262,18 @@ func getProviderInfoReply(buf []byte) *GetProviderInfoReply { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Outputs = make([]Output, v.NumOutputs) for i := 0; i < int(v.NumOutputs); i++ { v.Outputs[i] = Output(xgb.Get32(buf[b:])) b += 4 } - b = (b + 3) & ^3 // alignment gap - v.AssociatedProviders = make([]Provider, v.NumAssociatedProviders) for i := 0; i < int(v.NumAssociatedProviders); i++ { v.AssociatedProviders[i] = Provider(xgb.Get32(buf[b:])) b += 4 } - b = (b + 3) & ^3 // alignment gap - v.AssociatedCapability = make([]uint32, v.NumAssociatedProviders) for i := 0; i < int(v.NumAssociatedProviders); i++ { v.AssociatedCapability[i] = xgb.Get32(buf[b:]) @@ -3966,8 +4609,7 @@ type GetScreenInfoReply struct { Rate uint16 NInfo uint16 // padding: 2 bytes - Sizes []ScreenSize // size: xgb.Pad((int(NSizes) * 8)) - // alignment gap to multiple of 2 + Sizes []ScreenSize // size: xgb.Pad((int(NSizes) * 8)) Rates []RefreshRates // size: RefreshRatesListSize(Rates) } @@ -4026,8 +4668,6 @@ func getScreenInfoReply(buf []byte) *GetScreenInfoReply { v.Sizes = make([]ScreenSize, v.NSizes) b += ScreenSizeReadList(buf[b:], v.Sizes) - b = (b + 1) & ^1 // alignment gap - v.Rates = make([]RefreshRates, (int(v.NInfo) - int(v.NSizes))) b += RefreshRatesReadList(buf[b:], v.Rates) @@ -4101,12 +4741,10 @@ type GetScreenResourcesReply struct { NumModes uint16 NamesLen uint16 // padding: 8 bytes - Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) - // alignment gap to multiple of 4 - Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) - // alignment gap to multiple of 4 - Modes []ModeInfo // size: xgb.Pad((int(NumModes) * 32)) - Names []byte // size: xgb.Pad((int(NamesLen) * 1)) + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) + Modes []ModeInfo // size: xgb.Pad((int(NumModes) * 32)) + Names []byte // size: xgb.Pad((int(NamesLen) * 1)) } // Reply blocks and returns the reply data for a GetScreenResources request. @@ -4160,16 +4798,12 @@ func getScreenResourcesReply(buf []byte) *GetScreenResourcesReply { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Outputs = make([]Output, v.NumOutputs) for i := 0; i < int(v.NumOutputs); i++ { v.Outputs[i] = Output(xgb.Get32(buf[b:])) b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Modes = make([]ModeInfo, v.NumModes) b += ModeInfoReadList(buf[b:], v.Modes) @@ -4247,12 +4881,10 @@ type GetScreenResourcesCurrentReply struct { NumModes uint16 NamesLen uint16 // padding: 8 bytes - Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) - // alignment gap to multiple of 4 - Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) - // alignment gap to multiple of 4 - Modes []ModeInfo // size: xgb.Pad((int(NumModes) * 32)) - Names []byte // size: xgb.Pad((int(NamesLen) * 1)) + Crtcs []Crtc // size: xgb.Pad((int(NumCrtcs) * 4)) + Outputs []Output // size: xgb.Pad((int(NumOutputs) * 4)) + Modes []ModeInfo // size: xgb.Pad((int(NumModes) * 32)) + Names []byte // size: xgb.Pad((int(NamesLen) * 1)) } // Reply blocks and returns the reply data for a GetScreenResourcesCurrent request. @@ -4306,16 +4938,12 @@ func getScreenResourcesCurrentReply(buf []byte) *GetScreenResourcesCurrentReply b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Outputs = make([]Output, v.NumOutputs) for i := 0; i < int(v.NumOutputs); i++ { v.Outputs[i] = Output(xgb.Get32(buf[b:])) b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Modes = make([]ModeInfo, v.NumModes) b += ModeInfoReadList(buf[b:], v.Modes) @@ -5254,7 +5882,7 @@ func (cook SetCrtcGammaCookie) Check() error { // Write request to wire for SetCrtcGamma // setCrtcGammaRequest writes a SetCrtcGamma request to a byte slice. func setCrtcGammaRequest(c *xgb.Conn, Crtc Crtc, Size uint16, Red []uint16, Green []uint16, Blue []uint16) []byte { - size := xgb.Pad((((((12 + xgb.Pad((int(Size) * 2))) + 2) + xgb.Pad((int(Size) * 2))) + 2) + xgb.Pad((int(Size) * 2)))) + size := xgb.Pad((((12 + xgb.Pad((int(Size) * 2))) + xgb.Pad((int(Size) * 2))) + xgb.Pad((int(Size) * 2)))) b := 0 buf := make([]byte, size) @@ -5266,7 +5894,7 @@ func setCrtcGammaRequest(c *xgb.Conn, Crtc Crtc, Size uint16, Red []uint16, Gree buf[b] = 24 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put32(buf[b:], uint32(Crtc)) @@ -5282,23 +5910,17 @@ func setCrtcGammaRequest(c *xgb.Conn, Crtc Crtc, Size uint16, Red []uint16, Gree b += 2 } - b = (b + 1) & ^1 // alignment gap - for i := 0; i < int(Size); i++ { xgb.Put16(buf[b:], Green[i]) b += 2 } - b = (b + 1) & ^1 // alignment gap - for i := 0; i < int(Size); i++ { xgb.Put16(buf[b:], Blue[i]) b += 2 } - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // SetCrtcTransformCookie is a cookie used only for SetCrtcTransform requests. @@ -5385,6 +6007,73 @@ func setCrtcTransformRequest(c *xgb.Conn, Crtc Crtc, Transform render.Transform, return buf[:b] } +// SetMonitorCookie is a cookie used only for SetMonitor requests. +type SetMonitorCookie struct { + *xgb.Cookie +} + +// SetMonitor sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetMonitor(c *xgb.Conn, Window xproto.Window, Monitorinfo MonitorInfo) SetMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setMonitorRequest(c, Window, Monitorinfo), cookie) + return SetMonitorCookie{cookie} +} + +// SetMonitorChecked sends a checked request. +// If an error occurs, it can be retrieved using SetMonitorCookie.Check() +func SetMonitorChecked(c *xgb.Conn, Window xproto.Window, Monitorinfo MonitorInfo) SetMonitorCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'SetMonitor' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setMonitorRequest(c, Window, Monitorinfo), cookie) + return SetMonitorCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetMonitorCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetMonitor +// setMonitorRequest writes a SetMonitor request to a byte slice. +func setMonitorRequest(c *xgb.Conn, Window xproto.Window, Monitorinfo MonitorInfo) []byte { + size := xgb.Pad((8 + (24 + xgb.Pad((int(Monitorinfo.NOutput) * 4))))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 43 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], uint32(Window)) + b += 4 + + { + structBytes := Monitorinfo.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + return buf +} + // SetOutputPrimaryCookie is a cookie used only for SetOutputPrimary requests. type SetOutputPrimaryCookie struct { *xgb.Cookie diff --git a/record/record.go b/record/record.go index 419587f..bf7c0ec 100644 --- a/record/record.go +++ b/record/record.go @@ -554,7 +554,7 @@ func (cook CreateContextCookie) Check() error { // Write request to wire for CreateContext // createContextRequest writes a CreateContext request to a byte slice. func createContextRequest(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) []byte { - size := xgb.Pad((((20 + xgb.Pad((int(NumClientSpecs) * 4))) + 4) + xgb.Pad((int(NumRanges) * 24)))) + size := xgb.Pad(((20 + xgb.Pad((int(NumClientSpecs) * 4))) + xgb.Pad((int(NumRanges) * 24)))) b := 0 buf := make([]byte, size) @@ -566,7 +566,7 @@ func createContextRequest(c *xgb.Conn, Context Context, ElementHeader ElementHea buf[b] = 1 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put32(buf[b:], uint32(Context)) @@ -588,13 +588,9 @@ func createContextRequest(c *xgb.Conn, Context Context, ElementHeader ElementHea b += 4 } - b = (b + 3) & ^3 // alignment gap - b += RangeListBytes(buf[b:], Ranges) - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // DisableContextCookie is a cookie used only for DisableContext requests. @@ -1099,7 +1095,7 @@ func (cook RegisterClientsCookie) Check() error { // Write request to wire for RegisterClients // registerClientsRequest writes a RegisterClients request to a byte slice. func registerClientsRequest(c *xgb.Conn, Context Context, ElementHeader ElementHeader, NumClientSpecs uint32, NumRanges uint32, ClientSpecs []ClientSpec, Ranges []Range) []byte { - size := xgb.Pad((((20 + xgb.Pad((int(NumClientSpecs) * 4))) + 4) + xgb.Pad((int(NumRanges) * 24)))) + size := xgb.Pad(((20 + xgb.Pad((int(NumClientSpecs) * 4))) + xgb.Pad((int(NumRanges) * 24)))) b := 0 buf := make([]byte, size) @@ -1111,7 +1107,7 @@ func registerClientsRequest(c *xgb.Conn, Context Context, ElementHeader ElementH buf[b] = 2 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put32(buf[b:], uint32(Context)) @@ -1133,13 +1129,9 @@ func registerClientsRequest(c *xgb.Conn, Context Context, ElementHeader ElementH b += 4 } - b = (b + 3) & ^3 // alignment gap - b += RangeListBytes(buf[b:], Ranges) - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // UnregisterClientsCookie is a cookie used only for UnregisterClients requests. diff --git a/render/render.go b/render/render.go index 223162a..839a05d 100644 --- a/render/render.go +++ b/render/render.go @@ -639,52 +639,6 @@ func init() { xgb.NewExtErrorFuncs["RENDER"][0] = PictFormatErrorNew } -// BadPictOp is the error number for a BadPictOp. -const BadPictOp = 2 - -type PictOpError struct { - Sequence uint16 - NiceName string -} - -// PictOpErrorNew constructs a PictOpError value that implements xgb.Error from a byte slice. -func PictOpErrorNew(buf []byte) xgb.Error { - v := PictOpError{} - v.NiceName = "PictOp" - - b := 1 // skip error determinant - b += 1 // don't read error number - - v.Sequence = xgb.Get16(buf[b:]) - b += 2 - - return v -} - -// SequenceId returns the sequence id attached to the BadPictOp error. -// This is mostly used internally. -func (err PictOpError) SequenceId() uint16 { - return err.Sequence -} - -// BadId returns the 'BadValue' number if one exists for the BadPictOp error. If no bad value exists, 0 is returned. -func (err PictOpError) BadId() uint32 { - return 0 -} - -// Error returns a rudimentary string representation of the BadPictOp error. - -func (err PictOpError) Error() string { - fieldVals := make([]string, 0, 0) - fieldVals = append(fieldVals, "NiceName: "+err.NiceName) - fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) - return "BadPictOp {" + xgb.StringsJoin(fieldVals, ", ") + "}" -} - -func init() { - xgb.NewExtErrorFuncs["RENDER"][2] = PictOpErrorNew -} - const ( PictOpClear = 0 PictOpSrc = 1 @@ -741,6 +695,52 @@ const ( PictOpHSLLuminosity = 62 ) +// BadPictOp is the error number for a BadPictOp. +const BadPictOp = 2 + +type PictOpError struct { + Sequence uint16 + NiceName string +} + +// PictOpErrorNew constructs a PictOpError value that implements xgb.Error from a byte slice. +func PictOpErrorNew(buf []byte) xgb.Error { + v := PictOpError{} + v.NiceName = "PictOp" + + b := 1 // skip error determinant + b += 1 // don't read error number + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + return v +} + +// SequenceId returns the sequence id attached to the BadPictOp error. +// This is mostly used internally. +func (err PictOpError) SequenceId() uint16 { + return err.Sequence +} + +// BadId returns the 'BadValue' number if one exists for the BadPictOp error. If no bad value exists, 0 is returned. +func (err PictOpError) BadId() uint32 { + return 0 +} + +// Error returns a rudimentary string representation of the BadPictOp error. + +func (err PictOpError) Error() string { + fieldVals := make([]string, 0, 0) + fieldVals = append(fieldVals, "NiceName: "+err.NiceName) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence)) + return "BadPictOp {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtErrorFuncs["RENDER"][2] = PictOpErrorNew +} + const ( PictTypeIndexed = 0 PictTypeDirect = 1 @@ -1613,7 +1613,7 @@ func (cook AddGlyphsCookie) Check() error { // Write request to wire for AddGlyphs // addGlyphsRequest writes a AddGlyphs request to a byte slice. func addGlyphsRequest(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids []uint32, Glyphs []Glyphinfo, Data []byte) []byte { - size := xgb.Pad(((((12 + xgb.Pad((int(GlyphsLen) * 4))) + 4) + xgb.Pad((int(GlyphsLen) * 12))) + xgb.Pad((len(Data) * 1)))) + size := xgb.Pad((((12 + xgb.Pad((int(GlyphsLen) * 4))) + xgb.Pad((int(GlyphsLen) * 12))) + xgb.Pad((len(Data) * 1)))) b := 0 buf := make([]byte, size) @@ -1625,7 +1625,7 @@ func addGlyphsRequest(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids buf[b] = 20 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put32(buf[b:], uint32(Glyphset)) @@ -1639,16 +1639,12 @@ func addGlyphsRequest(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids b += 4 } - b = (b + 3) & ^3 // alignment gap - b += GlyphinfoListBytes(buf[b:], Glyphs) copy(buf[b:], Data[:len(Data)]) b += int(len(Data)) - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // AddTrapsCookie is a cookie used only for AddTraps requests. @@ -1760,7 +1756,7 @@ func (cook ChangePictureCookie) Check() error { // Write request to wire for ChangePicture // changePictureRequest writes a ChangePicture request to a byte slice. func changePictureRequest(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((8 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -1780,6 +1776,7 @@ func changePictureRequest(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueL xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -2240,7 +2237,7 @@ func (cook CreateConicalGradientCookie) Check() error { // Write request to wire for CreateConicalGradient // createConicalGradientRequest writes a CreateConicalGradient request to a byte slice. func createConicalGradientRequest(c *xgb.Conn, Picture Picture, Center Pointfix, Angle Fixed, NumStops uint32, Stops []Fixed, Colors []Color) []byte { - size := xgb.Pad((((24 + xgb.Pad((int(NumStops) * 4))) + 4) + xgb.Pad((int(NumStops) * 8)))) + size := xgb.Pad(((24 + xgb.Pad((int(NumStops) * 4))) + xgb.Pad((int(NumStops) * 8)))) b := 0 buf := make([]byte, size) @@ -2252,7 +2249,7 @@ func createConicalGradientRequest(c *xgb.Conn, Picture Picture, Center Pointfix, buf[b] = 36 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put32(buf[b:], uint32(Picture)) @@ -2275,13 +2272,9 @@ func createConicalGradientRequest(c *xgb.Conn, Picture Picture, Center Pointfix, b += 4 } - b = (b + 3) & ^3 // alignment gap - b += ColorListBytes(buf[b:], Colors) - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // CreateCursorCookie is a cookie used only for CreateCursor requests. @@ -2458,7 +2451,7 @@ func (cook CreateLinearGradientCookie) Check() error { // Write request to wire for CreateLinearGradient // createLinearGradientRequest writes a CreateLinearGradient request to a byte slice. func createLinearGradientRequest(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 Pointfix, NumStops uint32, Stops []Fixed, Colors []Color) []byte { - size := xgb.Pad((((28 + xgb.Pad((int(NumStops) * 4))) + 4) + xgb.Pad((int(NumStops) * 8)))) + size := xgb.Pad(((28 + xgb.Pad((int(NumStops) * 4))) + xgb.Pad((int(NumStops) * 8)))) b := 0 buf := make([]byte, size) @@ -2470,7 +2463,7 @@ func createLinearGradientRequest(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 P buf[b] = 34 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put32(buf[b:], uint32(Picture)) @@ -2496,13 +2489,9 @@ func createLinearGradientRequest(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 P b += 4 } - b = (b + 3) & ^3 // alignment gap - b += ColorListBytes(buf[b:], Colors) - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // CreatePictureCookie is a cookie used only for CreatePicture requests. @@ -2545,7 +2534,7 @@ func (cook CreatePictureCookie) Check() error { // Write request to wire for CreatePicture // createPictureRequest writes a CreatePicture request to a byte slice. func createPictureRequest(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Format Pictformat, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((16 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((20 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -2571,6 +2560,7 @@ func createPictureRequest(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Fo xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -2620,7 +2610,7 @@ func (cook CreateRadialGradientCookie) Check() error { // Write request to wire for CreateRadialGradient // createRadialGradientRequest writes a CreateRadialGradient request to a byte slice. func createRadialGradientRequest(c *xgb.Conn, Picture Picture, Inner Pointfix, Outer Pointfix, InnerRadius Fixed, OuterRadius Fixed, NumStops uint32, Stops []Fixed, Colors []Color) []byte { - size := xgb.Pad((((36 + xgb.Pad((int(NumStops) * 4))) + 4) + xgb.Pad((int(NumStops) * 8)))) + size := xgb.Pad(((36 + xgb.Pad((int(NumStops) * 4))) + xgb.Pad((int(NumStops) * 8)))) b := 0 buf := make([]byte, size) @@ -2632,7 +2622,7 @@ func createRadialGradientRequest(c *xgb.Conn, Picture Picture, Inner Pointfix, O buf[b] = 35 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put32(buf[b:], uint32(Picture)) @@ -2664,13 +2654,9 @@ func createRadialGradientRequest(c *xgb.Conn, Picture Picture, Inner Pointfix, O b += 4 } - b = (b + 3) & ^3 // alignment gap - b += ColorListBytes(buf[b:], Colors) - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // CreateSolidFillCookie is a cookie used only for CreateSolidFill requests. @@ -3156,11 +3142,9 @@ type QueryPictFormatsReply struct { NumVisuals uint32 NumSubpixel uint32 // padding: 4 bytes - Formats []Pictforminfo // size: xgb.Pad((int(NumFormats) * 28)) - // alignment gap to multiple of 4 - Screens []Pictscreen // size: PictscreenListSize(Screens) - // alignment gap to multiple of 4 - Subpixels []uint32 // size: xgb.Pad((int(NumSubpixel) * 4)) + Formats []Pictforminfo // size: xgb.Pad((int(NumFormats) * 28)) + Screens []Pictscreen // size: PictscreenListSize(Screens) + Subpixels []uint32 // size: xgb.Pad((int(NumSubpixel) * 4)) } // Reply blocks and returns the reply data for a QueryPictFormats request. @@ -3208,13 +3192,9 @@ func queryPictFormatsReply(buf []byte) *QueryPictFormatsReply { v.Formats = make([]Pictforminfo, v.NumFormats) b += PictforminfoReadList(buf[b:], v.Formats) - b = (b + 3) & ^3 // alignment gap - v.Screens = make([]Pictscreen, v.NumScreens) b += PictscreenReadList(buf[b:], v.Screens) - b = (b + 3) & ^3 // alignment gap - v.Subpixels = make([]uint32, v.NumSubpixel) for i := 0; i < int(v.NumSubpixel); i++ { v.Subpixels[i] = xgb.Get32(buf[b:]) @@ -152,7 +152,7 @@ func ClientIdSpecListBytes(buf []byte, list []ClientIdSpec) int { type ClientIdValue struct { Spec ClientIdSpec Length uint32 - Value []uint32 // size: xgb.Pad((int(Length) * 4)) + Value []uint32 // size: xgb.Pad(((int(Length) / 4) * 4)) } // ClientIdValueRead reads a byte slice into a ClientIdValue value. @@ -165,8 +165,8 @@ func ClientIdValueRead(buf []byte, v *ClientIdValue) int { v.Length = xgb.Get32(buf[b:]) b += 4 - v.Value = make([]uint32, v.Length) - for i := 0; i < int(v.Length); i++ { + v.Value = make([]uint32, (int(v.Length) / 4)) + for i := 0; i < int((int(v.Length) / 4)); i++ { v.Value[i] = xgb.Get32(buf[b:]) b += 4 } @@ -186,7 +186,7 @@ func ClientIdValueReadList(buf []byte, dest []ClientIdValue) int { // Bytes writes a ClientIdValue value to a byte slice. func (v ClientIdValue) Bytes() []byte { - buf := make([]byte, (12 + xgb.Pad((int(v.Length) * 4)))) + buf := make([]byte, (12 + xgb.Pad(((int(v.Length) / 4) * 4)))) b := 0 { @@ -198,7 +198,7 @@ func (v ClientIdValue) Bytes() []byte { xgb.Put32(buf[b:], v.Length) b += 4 - for i := 0; i < int(v.Length); i++ { + for i := 0; i < int((int(v.Length) / 4)); i++ { xgb.Put32(buf[b:], v.Value[i]) b += 4 } @@ -222,7 +222,7 @@ func ClientIdValueListBytes(buf []byte, list []ClientIdValue) int { func ClientIdValueListSize(list []ClientIdValue) int { size := 0 for _, item := range list { - size += (12 + xgb.Pad((int(item.Length) * 4))) + size += (12 + xgb.Pad(((int(item.Length) / 4) * 4))) } return size } diff --git a/screensaver/screensaver.go b/screensaver/screensaver.go index 6854505..1112c49 100644 --- a/screensaver/screensaver.go +++ b/screensaver/screensaver.go @@ -513,7 +513,7 @@ func (cook SetAttributesCookie) Check() error { // Write request to wire for SetAttributes // setAttributesRequest writes a SetAttributes request to a byte slice. func setAttributesRequest(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class byte, Depth byte, Visual xproto.Visualid, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((24 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((28 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -557,6 +557,7 @@ func setAttributesRequest(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int1 xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -573,7 +574,7 @@ type SuspendCookie struct { // Suspend sends an unchecked request. // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. -func Suspend(c *xgb.Conn, Suspend bool) SuspendCookie { +func Suspend(c *xgb.Conn, Suspend uint32) SuspendCookie { c.ExtLock.RLock() defer c.ExtLock.RUnlock() if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { @@ -586,7 +587,7 @@ func Suspend(c *xgb.Conn, Suspend bool) SuspendCookie { // SuspendChecked sends a checked request. // If an error occurs, it can be retrieved using SuspendCookie.Check() -func SuspendChecked(c *xgb.Conn, Suspend bool) SuspendCookie { +func SuspendChecked(c *xgb.Conn, Suspend uint32) SuspendCookie { c.ExtLock.RLock() defer c.ExtLock.RUnlock() if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok { @@ -605,7 +606,7 @@ func (cook SuspendCookie) Check() error { // Write request to wire for Suspend // suspendRequest writes a Suspend request to a byte slice. -func suspendRequest(c *xgb.Conn, Suspend bool) []byte { +func suspendRequest(c *xgb.Conn, Suspend uint32) []byte { size := 8 b := 0 buf := make([]byte, size) @@ -621,14 +622,8 @@ func suspendRequest(c *xgb.Conn, Suspend bool) []byte { xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 - if Suspend { - buf[b] = 1 - } else { - buf[b] = 0 - } - b += 1 - - b += 3 // padding + xgb.Put32(buf[b:], Suspend) + b += 4 return buf } diff --git a/xf86dri/xf86dri.go b/xf86dri/xf86dri.go index bc67e9b..c8fec53 100644 --- a/xf86dri/xf86dri.go +++ b/xf86dri/xf86dri.go @@ -896,8 +896,7 @@ type GetDrawableInfoReply struct { BackY int16 NumBackClipRects uint32 ClipRects []DrmClipRect // size: xgb.Pad((int(NumClipRects) * 8)) - // alignment gap to multiple of 4 - BackClipRects []DrmClipRect // size: xgb.Pad((int(NumBackClipRects) * 8)) + BackClipRects []DrmClipRect // size: xgb.Pad((int(NumBackClipRects) * 8)) } // Reply blocks and returns the reply data for a GetDrawableInfo request. @@ -958,8 +957,6 @@ func getDrawableInfoReply(buf []byte) *GetDrawableInfoReply { v.ClipRects = make([]DrmClipRect, v.NumClipRects) b += DrmClipRectReadList(buf[b:], v.ClipRects) - b = (b + 3) & ^3 // alignment gap - v.BackClipRects = make([]DrmClipRect, v.NumBackClipRects) b += DrmClipRectReadList(buf[b:], v.BackClipRects) diff --git a/xf86vidmode/xf86vidmode.go b/xf86vidmode/xf86vidmode.go index 6bd3232..8b605e2 100644 --- a/xf86vidmode/xf86vidmode.go +++ b/xf86vidmode/xf86vidmode.go @@ -1152,11 +1152,9 @@ type GetGammaRampReply struct { // padding: 1 bytes Size uint16 // padding: 22 bytes - Red []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) - // alignment gap to multiple of 2 + Red []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) Green []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) - // alignment gap to multiple of 2 - Blue []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) + Blue []uint16 // size: xgb.Pad((((int(Size) + 1) & -2) * 2)) } // Reply blocks and returns the reply data for a GetGammaRamp request. @@ -1195,16 +1193,12 @@ func getGammaRampReply(buf []byte) *GetGammaRampReply { b += 2 } - b = (b + 1) & ^1 // alignment gap - v.Green = make([]uint16, ((int(v.Size) + 1) & -2)) for i := 0; i < int(((int(v.Size) + 1) & -2)); i++ { v.Green[i] = xgb.Get16(buf[b:]) b += 2 } - b = (b + 1) & ^1 // alignment gap - v.Blue = make([]uint16, ((int(v.Size) + 1) & -2)) for i := 0; i < int(((int(v.Size) + 1) & -2)); i++ { v.Blue[i] = xgb.Get16(buf[b:]) @@ -1532,8 +1526,7 @@ type GetMonitorReply struct { NumHsync byte NumVsync byte // padding: 20 bytes - Hsync []Syncrange // size: xgb.Pad((int(NumHsync) * 4)) - // alignment gap to multiple of 4 + Hsync []Syncrange // size: xgb.Pad((int(NumHsync) * 4)) Vsync []Syncrange // size: xgb.Pad((int(NumVsync) * 4)) Vendor string // size: xgb.Pad((int(VendorLength) * 1)) AlignmentPad []byte // size: xgb.Pad(((((int(VendorLength) + 3) & -4) - int(VendorLength)) * 1)) @@ -1585,8 +1578,6 @@ func getMonitorReply(buf []byte) *GetMonitorReply { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Vsync = make([]Syncrange, v.NumVsync) for i := 0; i < int(v.NumVsync); i++ { v.Vsync[i] = Syncrange(xgb.Get32(buf[b:])) @@ -2280,7 +2271,7 @@ func (cook SetGammaRampCookie) Check() error { // Write request to wire for SetGammaRamp // setGammaRampRequest writes a SetGammaRamp request to a byte slice. func setGammaRampRequest(c *xgb.Conn, Screen uint16, Size uint16, Red []uint16, Green []uint16, Blue []uint16) []byte { - size := xgb.Pad((((((8 + xgb.Pad((((int(Size) + 1) & -2) * 2))) + 2) + xgb.Pad((((int(Size) + 1) & -2) * 2))) + 2) + xgb.Pad((((int(Size) + 1) & -2) * 2)))) + size := xgb.Pad((((8 + xgb.Pad((((int(Size) + 1) & -2) * 2))) + xgb.Pad((((int(Size) + 1) & -2) * 2))) + xgb.Pad((((int(Size) + 1) & -2) * 2)))) b := 0 buf := make([]byte, size) @@ -2292,7 +2283,7 @@ func setGammaRampRequest(c *xgb.Conn, Screen uint16, Size uint16, Red []uint16, buf[b] = 18 // request opcode b += 1 - blen := b + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units b += 2 xgb.Put16(buf[b:], Screen) @@ -2306,23 +2297,17 @@ func setGammaRampRequest(c *xgb.Conn, Screen uint16, Size uint16, Red []uint16, b += 2 } - b = (b + 1) & ^1 // alignment gap - for i := 0; i < int(((int(Size) + 1) & -2)); i++ { xgb.Put16(buf[b:], Green[i]) b += 2 } - b = (b + 1) & ^1 // alignment gap - for i := 0; i < int(((int(Size) + 1) & -2)); i++ { xgb.Put16(buf[b:], Blue[i]) b += 2 } - b = xgb.Pad(b) - xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units - return buf[:b] + return buf } // SetViewPortCookie is a cookie used only for SetViewPort requests. diff --git a/xfixes/xfixes.go b/xfixes/xfixes.go index 5751527..42d802d 100644 --- a/xfixes/xfixes.go +++ b/xfixes/xfixes.go @@ -101,6 +101,11 @@ const ( BarrierDirectionsNegativeY = 8 ) +const ( + ClientDisconnectFlagsDefault = 0 + ClientDisconnectFlagsTerminate = 1 +) + // CursorNotify is the event number for a CursorNotifyEvent. const CursorNotify = 1 @@ -1353,6 +1358,100 @@ func fetchRegionRequest(c *xgb.Conn, Region Region) []byte { return buf } +// GetClientDisconnectModeCookie is a cookie used only for GetClientDisconnectMode requests. +type GetClientDisconnectModeCookie struct { + *xgb.Cookie +} + +// GetClientDisconnectMode sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetClientDisconnectModeCookie.Reply() +func GetClientDisconnectMode(c *xgb.Conn) GetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getClientDisconnectModeRequest(c), cookie) + return GetClientDisconnectModeCookie{cookie} +} + +// GetClientDisconnectModeUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetClientDisconnectModeUnchecked(c *xgb.Conn) GetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'GetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getClientDisconnectModeRequest(c), cookie) + return GetClientDisconnectModeCookie{cookie} +} + +// GetClientDisconnectModeReply represents the data returned from a GetClientDisconnectMode request. +type GetClientDisconnectModeReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + DisconnectMode uint32 + // padding: 20 bytes +} + +// Reply blocks and returns the reply data for a GetClientDisconnectMode request. +func (cook GetClientDisconnectModeCookie) Reply() (*GetClientDisconnectModeReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getClientDisconnectModeReply(buf), nil +} + +// getClientDisconnectModeReply reads a byte slice into a GetClientDisconnectModeReply value. +func getClientDisconnectModeReply(buf []byte) *GetClientDisconnectModeReply { + v := new(GetClientDisconnectModeReply) + b := 1 // skip reply determinant + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.DisconnectMode = xgb.Get32(buf[b:]) + b += 4 + + b += 20 // padding + + return v +} + +// Write request to wire for GetClientDisconnectMode +// getClientDisconnectModeRequest writes a GetClientDisconnectMode request to a byte slice. +func getClientDisconnectModeRequest(c *xgb.Conn) []byte { + size := 4 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 34 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + return buf +} + // GetCursorImageCookie is a cookie used only for GetCursorImage requests. type GetCursorImageCookie struct { *xgb.Cookie @@ -1524,9 +1623,8 @@ type GetCursorImageAndNameReply struct { CursorAtom xproto.Atom Nbytes uint16 // padding: 2 bytes - Name string // size: xgb.Pad((int(Nbytes) * 1)) - // alignment gap to multiple of 4 CursorImage []uint32 // size: xgb.Pad(((int(Width) * int(Height)) * 4)) + Name string // size: xgb.Pad((int(Nbytes) * 1)) } // Reply blocks and returns the reply data for a GetCursorImageAndName request. @@ -1583,6 +1681,12 @@ func getCursorImageAndNameReply(buf []byte) *GetCursorImageAndNameReply { b += 2 // padding + v.CursorImage = make([]uint32, (int(v.Width) * int(v.Height))) + for i := 0; i < int((int(v.Width) * int(v.Height))); i++ { + v.CursorImage[i] = xgb.Get32(buf[b:]) + b += 4 + } + { byteString := make([]byte, v.Nbytes) copy(byteString[:v.Nbytes], buf[b:]) @@ -1590,14 +1694,6 @@ func getCursorImageAndNameReply(buf []byte) *GetCursorImageAndNameReply { b += int(v.Nbytes) } - b = (b + 3) & ^3 // alignment gap - - v.CursorImage = make([]uint32, (int(v.Width) * int(v.Height))) - for i := 0; i < int((int(v.Width) * int(v.Height))); i++ { - v.CursorImage[i] = xgb.Get32(buf[b:]) - b += 4 - } - return v } @@ -2228,6 +2324,67 @@ func selectSelectionInputRequest(c *xgb.Conn, Window xproto.Window, Selection xp return buf } +// SetClientDisconnectModeCookie is a cookie used only for SetClientDisconnectMode requests. +type SetClientDisconnectModeCookie struct { + *xgb.Cookie +} + +// SetClientDisconnectMode sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SetClientDisconnectMode(c *xgb.Conn, DisconnectMode uint32) SetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(setClientDisconnectModeRequest(c, DisconnectMode), cookie) + return SetClientDisconnectModeCookie{cookie} +} + +// SetClientDisconnectModeChecked sends a checked request. +// If an error occurs, it can be retrieved using SetClientDisconnectModeCookie.Check() +func SetClientDisconnectModeChecked(c *xgb.Conn, DisconnectMode uint32) SetClientDisconnectModeCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["XFIXES"]; !ok { + panic("Cannot issue request 'SetClientDisconnectMode' using the uninitialized extension 'XFIXES'. xfixes.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(setClientDisconnectModeRequest(c, DisconnectMode), cookie) + return SetClientDisconnectModeCookie{cookie} +} + +// Check returns an error if one occurred for checked requests that are not expecting a reply. +// This cannot be called for requests expecting a reply, nor for unchecked requests. +func (cook SetClientDisconnectModeCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SetClientDisconnectMode +// setClientDisconnectModeRequest writes a SetClientDisconnectMode request to a byte slice. +func setClientDisconnectModeRequest(c *xgb.Conn, DisconnectMode uint32) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["XFIXES"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 33 // request opcode + b += 1 + + xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + b += 2 + + xgb.Put32(buf[b:], DisconnectMode) + b += 4 + + return buf +} + // SetCursorNameCookie is a cookie used only for SetCursorName requests. type SetCursorNameCookie struct { *xgb.Cookie diff --git a/xgbgen/aligngap.go b/xgbgen/aligngap.go deleted file mode 100644 index 0cd7ac4..0000000 --- a/xgbgen/aligngap.go +++ /dev/null @@ -1,120 +0,0 @@ -package main - -import ( - "fmt" - "os" -) - -func (p *Protocol) AddAlignGaps() { - for i := range p.Imports { - p.Imports[i].AddAlignGaps() - } - for i := range p.Types { - switch t := p.Types[i].(type) { - case *Struct: - t.Fields = addAlignGapsToFields(t.xmlName, t.Fields) - case *Event: - t.Fields = addAlignGapsToFields(t.xmlName, t.Fields) - case *Error: - t.Fields = addAlignGapsToFields(t.xmlName, t.Fields) - } - } - for i := range p.Requests { - p.Requests[i].Fields = addAlignGapsToFields( - p.Requests[i].xmlName, p.Requests[i].Fields) - if p.Requests[i].Reply != nil { - p.Requests[i].Reply.Fields = addAlignGapsToFields( - p.Requests[i].xmlName, p.Requests[i].Reply.Fields) - } - } -} - -func addAlignGapsToFields(name string, fields []Field) []Field { - var i int - for i = 0; i < len(fields); i++ { - if _, ok := fields[i].(*ListField); ok { - break - } - } - if i >= len(fields) { - return fields - } - - r := make([]Field, 0, len(fields)+2) - r = append(r, fields[:i]...) - - r = append(r, fields[i]) - for i = i + 1; i < len(fields); i++ { - switch f := fields[i].(type) { - case *ListField: - // ok, add padding - sz := xcbSizeOfType(f.Type) - switch { - case sz == 1: - // nothing - case sz == 2: - r = append(r, &PadField{0, 2}) - case sz == 3: - panic(fmt.Errorf("Alignment is not a power of 2")) - case sz >= 4: - r = append(r, &PadField{0, 4}) - } - case *LocalField: - // nothing - default: - fmt.Fprintf(os.Stderr, - "Can't add alignment gaps, mix of list and non-list "+ - "fields: %s\n", name) - return fields - } - r = append(r, fields[i]) - } - return r -} - -func xcbSizeOfField(fld Field) int { - switch f := fld.(type) { - case *PadField: - return int(f.Bytes) - case *SingleField: - return xcbSizeOfType(f.Type) - case *ListField: - return 0 - case *ExprField: - return xcbSizeOfType(f.Type) - case *ValueField: - return xcbSizeOfType(f.MaskType) - case *SwitchField: - return 0 - default: - return 0 - } -} - -func xcbSizeOfType(typ Type) int { - switch t := typ.(type) { - case *Resource: - return 4 - case *TypeDef: - return t.Size().Eval() - case *Base: - return t.Size().Eval() - case *Struct: - sz := 0 - for i := range t.Fields { - sz += xcbSizeOfField(t.Fields[i]) - } - return sz - case *Union: - sz := 0 - for i := range t.Fields { - csz := xcbSizeOfField(t.Fields[i]) - if csz > sz { - sz = csz - } - } - return sz - default: - return 0 - } -} diff --git a/xgbgen/context.go b/xgbgen/context.go index 755cf6e..2e31598 100644 --- a/xgbgen/context.go +++ b/xgbgen/context.go @@ -49,8 +49,23 @@ func (c *Context) Morph(xmlBytes []byte) { // Translate XML types to nice types c.protocol = parsedXml.Translate(nil) - - c.protocol.AddAlignGaps() + + // For backwards compatibility we patch the type of the send_event field of + // PutImage to be byte + if c.protocol.Name == "shm" { + for _, req := range c.protocol.Requests { + if req.xmlName != "PutImage" { + continue + } + for _, ifield := range req.Fields { + field, ok := ifield.(*SingleField) + if !ok || field.xmlName != "send_event" { + continue + } + field.Type = &Base{ srcName: "byte", xmlName: "CARD8", size: newFixedSize(1, true) } + } + } + } // Start with Go header. c.Putln("// Package %s is the X client API for the %s extension.", diff --git a/xgbgen/expression.go b/xgbgen/expression.go index f88232c..3e2235d 100644 --- a/xgbgen/expression.go +++ b/xgbgen/expression.go @@ -32,6 +32,9 @@ type Expression interface { // Initialize makes sure all names in this expression and any subexpressions // have been translated to Go source names. Initialize(p *Protocol) + + // Makes all field references relative to path + Specialize(path string) Expression } // Function is a custom expression not found in the XML. It's simply used @@ -62,6 +65,12 @@ func (e *Function) Initialize(p *Protocol) { e.Expr.Initialize(p) } +func (e *Function) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + // BinaryOp is an expression that performs some operation (defined in the XML // file) with Expr1 and Expr2 as operands. type BinaryOp struct { @@ -150,6 +159,13 @@ func (e *BinaryOp) Initialize(p *Protocol) { e.Expr2.Initialize(p) } +func (e *BinaryOp) Specialize(path string) Expression { + r := *e + r.Expr1 = r.Expr1.Specialize(path) + r.Expr2 = r.Expr2.Specialize(path) + return &r +} + // UnaryOp is the same as BinaryOp, except it's a unary operator with only // one sub-expression. type UnaryOp struct { @@ -186,6 +202,12 @@ func (e *UnaryOp) Initialize(p *Protocol) { e.Expr.Initialize(p) } +func (e *UnaryOp) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + // Padding represents the application of the 'pad' function to some // sub-expression. type Padding struct { @@ -215,6 +237,12 @@ func (e *Padding) Initialize(p *Protocol) { e.Expr.Initialize(p) } +func (e *Padding) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + // PopCount represents the application of the 'PopCount' function to // some sub-expression. type PopCount struct { @@ -244,6 +272,12 @@ func (e *PopCount) Initialize(p *Protocol) { e.Expr.Initialize(p) } +func (e *PopCount) Specialize(path string) Expression { + r := *e + r.Expr = r.Expr.Specialize(path) + return &r +} + // Value represents some constant integer. type Value struct { v int @@ -267,6 +301,10 @@ func (e *Value) String() string { func (e *Value) Initialize(p *Protocol) {} +func (e *Value) Specialize(path string) Expression { + return e +} + // Bit represents some bit whose value is computed by '1 << bit'. type Bit struct { b int @@ -290,6 +328,10 @@ func (e *Bit) String() string { func (e *Bit) Initialize(p *Protocol) {} +func (e *Bit) Specialize(path string) Expression { + return e +} + // FieldRef represents a reference to some variable in the generated code // with name Name. type FieldRef struct { @@ -321,6 +363,10 @@ func (e *FieldRef) Initialize(p *Protocol) { e.Name = SrcName(p, e.Name) } +func (e *FieldRef) Specialize(path string) Expression { + return &FieldRef{Name: path + "." + e.Name} +} + // EnumRef represents a reference to some enumeration field. // EnumKind is the "group" an EnumItem is the name of the specific enumeration // value inside that group. @@ -351,6 +397,10 @@ func (e *EnumRef) Initialize(p *Protocol) { e.EnumItem = SrcName(p, e.EnumItem) } +func (e *EnumRef) Specialize(path string) Expression { + return e +} + // SumOf represents a summation of the variable in the generated code named by // Name. It is not currently used. (It's XKB voodoo.) type SumOf struct { @@ -380,3 +430,7 @@ func (e *SumOf) String() string { func (e *SumOf) Initialize(p *Protocol) { e.Name = SrcName(p, e.Name) } + +func (e *SumOf) Specialize(path string) Expression { + return e +} diff --git a/xgbgen/field.go b/xgbgen/field.go index 2522a06..58f54c8 100644 --- a/xgbgen/field.go +++ b/xgbgen/field.go @@ -73,6 +73,32 @@ func (p *PadField) Size() Size { } } +type RequiredStartAlign struct { +} + +func (f *RequiredStartAlign) Initialize(p *Protocol) { } + +func (f *RequiredStartAlign) SrcName() string { + panic("illegal to take source name of a required_start_align field") +} + +func (f *RequiredStartAlign) XmlName() string { + panic("illegal to take XML name of a required_start_align field") +} + +func (f *RequiredStartAlign) SrcType() string { + panic("it is illegal to call SrcType on a required_start_align field") +} + +func (f *RequiredStartAlign) Size() Size { + return newFixedSize(0, true) +} + +func (f *RequiredStartAlign) Define(c *Context) { } + +func (f *RequiredStartAlign) Read(c *Context, prefix string) { } +func (f *RequiredStartAlign) Write(c *Context, prefix string) { } + // SingleField represents most of the fields in an XML protocol description. // It corresponds to any single value. type SingleField struct { @@ -289,35 +315,72 @@ func (f *ValueField) Initialize(p *Protocol) { } // SwitchField represents a 'switch' element in the XML protocol description -// file. It is not currently used. (i.e., it is XKB voodoo.) +// file. +// Currently we translate this to a slice of uint32 and let the user sort +// through it. type SwitchField struct { + xmlName string Name string + MaskName string Expr Expression Bitcases []*Bitcase } func (f *SwitchField) SrcName() string { - panic("it is illegal to call SrcName on a SwitchField field") + return f.Name } func (f *SwitchField) XmlName() string { - panic("it is illegal to call XmlName on a SwitchField field") + return f.xmlName } func (f *SwitchField) SrcType() string { - panic("it is illegal to call SrcType on a SwitchField field") + return "[]uint32" } -// XXX: This is a bit tricky. The size has to be represented as a non-concrete -// expression that finds *which* bitcase fields are included, and sums the -// sizes of those fields. func (f *SwitchField) Size() Size { - return newFixedSize(0, true) + // TODO: size expression used here is not correct unless every element of + // the switch is 32 bit long. This assumption holds for xproto but may not + // hold for other protocols (xkb?) + listSize := newExpressionSize(&Function{ + Name: "xgb.Pad", + Expr: &BinaryOp{ + Op: "*", + Expr1: &Value{v: 4}, + Expr2: &PopCount{ + Expr: &Function{ + Name: "int", + Expr: &FieldRef{ + Name: f.MaskName, + }, + }, + }, + }, + }, true) + + return listSize +} + +func (f *SwitchField) ListLength() Size { + return newExpressionSize(&PopCount{ + Expr: &Function{ + Name: "int", + Expr: &FieldRef{ + Name: f.MaskName, + }, + }, + }, true) } func (f *SwitchField) Initialize(p *Protocol) { + f.xmlName = f.Name f.Name = SrcName(p, f.Name) f.Expr.Initialize(p) + fieldref, ok := f.Expr.(*FieldRef) + if !ok { + panic("switch field's expression not a fieldref") + } + f.MaskName = SrcName(p, fieldref.Name) for _, bitcase := range f.Bitcases { bitcase.Expr.Initialize(p) for _, field := range bitcase.Fields { diff --git a/xgbgen/go.go b/xgbgen/go.go index ace4e00..87b5028 100644 --- a/xgbgen/go.go +++ b/xgbgen/go.go @@ -186,11 +186,8 @@ func (f *ValueField) Read(c *Context, prefix string) { } func (f *ValueField) Write(c *Context, prefix string) { - // big time mofos - if rq, ok := f.Parent.(*Request); !ok || rq.SrcName() != "ConfigureWindow" { - WriteSimpleSingleField(c, - fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType) - } + WriteSimpleSingleField(c, + fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType) c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) c.Putln("xgb.Put32(buf[b:], %s%s[i])", prefix, f.ListName) c.Putln("b += 4") @@ -200,16 +197,24 @@ func (f *ValueField) Write(c *Context, prefix string) { // Switch field func (f *SwitchField) Define(c *Context) { - c.Putln("// switch field: %s (%s)", f.Name, f.Expr) - panic("todo") + c.Putln("%s []uint32", f.Name) } func (f *SwitchField) Read(c *Context, prefix string) { - c.Putln("// reading switch field: %s (%s)", f.Name, f.Expr) - panic("todo") + c.Putln("") + c.Putln("%s%s = make([]uint32, %s)", + prefix, f.Name, f.ListLength().Reduce(prefix)) + c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) + c.Putln("%s%s[i] = xgb.Get32(buf[b:])", prefix, f.Name) + c.Putln("b += 4") + c.Putln("}") + c.Putln("b = xgb.Pad(b)") } func (f *SwitchField) Write(c *Context, prefix string) { - c.Putln("// writing switch field: %s (%s)", f.Name, f.Expr) - panic("todo") + c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) + c.Putln("xgb.Put32(buf[b:], %s%s[i])", prefix, f.Name) + c.Putln("b += 4") + c.Putln("}") + c.Putln("b = xgb.Pad(b)") } diff --git a/xgbgen/go_request_reply.go b/xgbgen/go_request_reply.go index 396305e..9cadc33 100644 --- a/xgbgen/go_request_reply.go +++ b/xgbgen/go_request_reply.go @@ -205,10 +205,7 @@ func (r *Request) ParamNames() string { for _, field := range r.Fields { switch f := field.(type) { case *ValueField: - // mofos... - if r.SrcName() != "ConfigureWindow" { - names = append(names, f.MaskName) - } + names = append(names, f.MaskName) names = append(names, f.ListName) case *PadField: continue @@ -226,17 +223,16 @@ func (r *Request) ParamNameTypes() string { for _, field := range r.Fields { switch f := field.(type) { case *ValueField: - // mofos... - if r.SrcName() != "ConfigureWindow" { - nameTypes = append(nameTypes, - fmt.Sprintf("%s %s", f.MaskName, f.MaskType.SrcName())) - } + nameTypes = append(nameTypes, + fmt.Sprintf("%s %s", f.MaskName, f.MaskType.SrcName())) nameTypes = append(nameTypes, fmt.Sprintf("%s []uint32", f.ListName)) case *PadField: continue case *ExprField: continue + case *RequiredStartAlign: + continue default: nameTypes = append(nameTypes, fmt.Sprintf("%s %s", field.SrcName(), field.SrcType())) diff --git a/xgbgen/request_reply.go b/xgbgen/request_reply.go index ae4eccb..5032e31 100644 --- a/xgbgen/request_reply.go +++ b/xgbgen/request_reply.go @@ -105,17 +105,15 @@ func (r *Request) Size(c *Context) Size { } for _, field := range r.Fields { - switch field.(type) { + switch field := field.(type) { case *LocalField: // local fields don't go over the wire continue case *SingleField: - // mofos!!! - if r.SrcName() == "ConfigureWindow" && - field.SrcName() == "ValueMask" { - - continue + fsz := field.Size() + if _, isstruct := field.Type.(*Struct); isstruct { + fsz.Expression = fsz.Expression.Specialize(field.SrcName()) } - size = size.Add(field.Size()) + size = size.Add(fsz) default: size = size.Add(field.Size()) } diff --git a/xgbgen/translation.go b/xgbgen/translation.go index f595e5f..d35fa88 100644 --- a/xgbgen/translation.go +++ b/xgbgen/translation.go @@ -325,12 +325,14 @@ func (x *XMLField) Translate(parent interface{}) Field { case "pad": return &PadField{ Bytes: x.Bytes, + Align: x.Align, } case "field": - return &SingleField{ + s := &SingleField{ xmlName: x.Name, Type: newTranslation(x.Type), } + return s case "list": return &ListField{ xmlName: x.Name, @@ -365,6 +367,8 @@ func (x *XMLField) Translate(parent interface{}) Field { swtch.Bitcases[i] = bitcase.Translate() } return swtch + case "required_start_align": + return &RequiredStartAlign{} } log.Panicf("Unrecognized field element: %s", x.XMLName.Local) diff --git a/xgbgen/xml_fields.go b/xgbgen/xml_fields.go index fe6c5d5..8b7b5c7 100644 --- a/xgbgen/xml_fields.go +++ b/xgbgen/xml_fields.go @@ -10,6 +10,7 @@ type XMLField struct { // For 'pad' element Bytes uint `xml:"bytes,attr"` + Align uint16 `xml:"align,attr"` // For 'field', 'list', 'localfield', 'exprfield' and 'switch' elements. Name string `xml:"name,attr"` diff --git a/xprint/xprint.go b/xprint/xprint.go index 97e06e1..ee9702d 100644 --- a/xprint/xprint.go +++ b/xprint/xprint.go @@ -317,10 +317,12 @@ func NewPcontextId(c *xgb.Conn) (Pcontext, error) { } type Printer struct { - NameLen uint32 - Name []String8 // size: xgb.Pad((int(NameLen) * 1)) + NameLen uint32 + Name []String8 // size: xgb.Pad((int(NameLen) * 1)) + // alignment gap to multiple of 4 DescLen uint32 Description []String8 // size: xgb.Pad((int(DescLen) * 1)) + // alignment gap to multiple of 4 } // PrinterRead reads a byte slice into a Printer value. @@ -336,6 +338,8 @@ func PrinterRead(buf []byte, v *Printer) int { b += 1 } + b = (b + 3) & ^3 // alignment gap + v.DescLen = xgb.Get32(buf[b:]) b += 4 @@ -345,6 +349,8 @@ func PrinterRead(buf []byte, v *Printer) int { b += 1 } + b = (b + 3) & ^3 // alignment gap + return b } @@ -360,7 +366,7 @@ func PrinterReadList(buf []byte, dest []Printer) int { // Bytes writes a Printer value to a byte slice. func (v Printer) Bytes() []byte { - buf := make([]byte, (((4 + xgb.Pad((int(v.NameLen) * 1))) + 4) + xgb.Pad((int(v.DescLen) * 1)))) + buf := make([]byte, (((((4 + xgb.Pad((int(v.NameLen) * 1))) + 4) + 4) + xgb.Pad((int(v.DescLen) * 1))) + 4)) b := 0 xgb.Put32(buf[b:], v.NameLen) @@ -371,6 +377,8 @@ func (v Printer) Bytes() []byte { b += 1 } + b = (b + 3) & ^3 // alignment gap + xgb.Put32(buf[b:], v.DescLen) b += 4 @@ -379,6 +387,8 @@ func (v Printer) Bytes() []byte { b += 1 } + b = (b + 3) & ^3 // alignment gap + return buf[:b] } @@ -398,7 +408,7 @@ func PrinterListBytes(buf []byte, list []Printer) int { func PrinterListSize(list []Printer) int { size := 0 for _, item := range list { - size += (((4 + xgb.Pad((int(item.NameLen) * 1))) + 4) + xgb.Pad((int(item.DescLen) * 1))) + size += (((((4 + xgb.Pad((int(item.NameLen) * 1))) + 4) + 4) + xgb.Pad((int(item.DescLen) * 1))) + 4) } return size } @@ -469,7 +479,7 @@ func (cook CreateContextCookie) Check() error { // Write request to wire for CreateContext // createContextRequest writes a CreateContext request to a byte slice. func createContextRequest(c *xgb.Conn, ContextId uint32, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) []byte { - size := xgb.Pad(((16 + xgb.Pad((int(PrinterNameLen) * 1))) + xgb.Pad((int(LocaleLen) * 1)))) + size := xgb.Pad((((16 + xgb.Pad((int(PrinterNameLen) * 1))) + 4) + xgb.Pad((int(LocaleLen) * 1)))) b := 0 buf := make([]byte, size) @@ -481,7 +491,7 @@ func createContextRequest(c *xgb.Conn, ContextId uint32, PrinterNameLen uint32, buf[b] = 2 // request opcode b += 1 - xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + blen := b b += 2 xgb.Put32(buf[b:], ContextId) @@ -498,12 +508,16 @@ func createContextRequest(c *xgb.Conn, ContextId uint32, PrinterNameLen uint32, b += 1 } + b = (b + 3) & ^3 // alignment gap + for i := 0; i < int(LocaleLen); i++ { buf[b] = byte(Locale[i]) b += 1 } - return buf + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] } // PrintDestroyContextCookie is a cookie used only for PrintDestroyContext requests. @@ -1482,7 +1496,7 @@ func printGetPrinterListReply(buf []byte) *PrintGetPrinterListReply { // Write request to wire for PrintGetPrinterList // printGetPrinterListRequest writes a PrintGetPrinterList request to a byte slice. func printGetPrinterListRequest(c *xgb.Conn, PrinterNameLen uint32, LocaleLen uint32, PrinterName []String8, Locale []String8) []byte { - size := xgb.Pad(((12 + xgb.Pad((int(PrinterNameLen) * 1))) + xgb.Pad((int(LocaleLen) * 1)))) + size := xgb.Pad((((12 + xgb.Pad((int(PrinterNameLen) * 1))) + 4) + xgb.Pad((int(LocaleLen) * 1)))) b := 0 buf := make([]byte, size) @@ -1494,7 +1508,7 @@ func printGetPrinterListRequest(c *xgb.Conn, PrinterNameLen uint32, LocaleLen ui buf[b] = 1 // request opcode b += 1 - xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + blen := b b += 2 xgb.Put32(buf[b:], PrinterNameLen) @@ -1508,12 +1522,16 @@ func printGetPrinterListRequest(c *xgb.Conn, PrinterNameLen uint32, LocaleLen ui b += 1 } + b = (b + 3) & ^3 // alignment gap + for i := 0; i < int(LocaleLen); i++ { buf[b] = byte(Locale[i]) b += 1 } - return buf + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] } // PrintGetScreenOfContextCookie is a cookie used only for PrintGetScreenOfContext requests. @@ -1644,9 +1662,7 @@ type PrintInputSelectedReply struct { Length uint32 // number of bytes in this reply // padding: 1 bytes EventMask uint32 - EventList []uint32 AllEventsMask uint32 - AllEventsList []uint32 } // Reply blocks and returns the reply data for a PrintInputSelected request. @@ -1677,23 +1693,9 @@ func printInputSelectedReply(buf []byte) *PrintInputSelectedReply { v.EventMask = xgb.Get32(buf[b:]) b += 4 - v.EventList = make([]uint32, xgb.PopCount(int(v.EventMask))) - for i := 0; i < xgb.PopCount(int(v.EventMask)); i++ { - v.EventList[i] = xgb.Get32(buf[b:]) - b += 4 - } - b = xgb.Pad(b) - v.AllEventsMask = xgb.Get32(buf[b:]) b += 4 - v.AllEventsList = make([]uint32, xgb.PopCount(int(v.AllEventsMask))) - for i := 0; i < xgb.PopCount(int(v.AllEventsMask)); i++ { - v.AllEventsList[i] = xgb.Get32(buf[b:]) - b += 4 - } - b = xgb.Pad(b) - return v } @@ -1761,7 +1763,7 @@ func (cook PrintPutDocumentDataCookie) Check() error { // Write request to wire for PrintPutDocumentData // printPutDocumentDataRequest writes a PrintPutDocumentData request to a byte slice. func printPutDocumentDataRequest(c *xgb.Conn, Drawable xproto.Drawable, LenData uint32, LenFmt uint16, LenOptions uint16, Data []byte, DocFormat []String8, Options []String8) []byte { - size := xgb.Pad((((16 + xgb.Pad((int(LenData) * 1))) + xgb.Pad((len(DocFormat) * 1))) + xgb.Pad((len(Options) * 1)))) + size := xgb.Pad((((((16 + xgb.Pad((int(LenData) * 1))) + 4) + xgb.Pad((int(LenFmt) * 1))) + 4) + xgb.Pad((int(LenOptions) * 1)))) b := 0 buf := make([]byte, size) @@ -1773,7 +1775,7 @@ func printPutDocumentDataRequest(c *xgb.Conn, Drawable xproto.Drawable, LenData buf[b] = 11 // request opcode b += 1 - xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units + blen := b b += 2 xgb.Put32(buf[b:], uint32(Drawable)) @@ -1791,17 +1793,23 @@ func printPutDocumentDataRequest(c *xgb.Conn, Drawable xproto.Drawable, LenData copy(buf[b:], Data[:LenData]) b += int(LenData) - for i := 0; i < int(len(DocFormat)); i++ { + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(LenFmt); i++ { buf[b] = byte(DocFormat[i]) b += 1 } - for i := 0; i < int(len(Options)); i++ { + b = (b + 3) & ^3 // alignment gap + + for i := 0; i < int(LenOptions); i++ { buf[b] = byte(Options[i]) b += 1 } - return buf + b = xgb.Pad(b) + xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units + return buf[:b] } // PrintQueryScreensCookie is a cookie used only for PrintQueryScreens requests. @@ -2065,27 +2073,27 @@ type PrintSelectInputCookie struct { // PrintSelectInput sends an unchecked request. // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. -func PrintSelectInput(c *xgb.Conn, Context Pcontext, EventMask uint32, EventList []uint32) PrintSelectInputCookie { +func PrintSelectInput(c *xgb.Conn, Context Pcontext, EventMask uint32) PrintSelectInputCookie { c.ExtLock.RLock() defer c.ExtLock.RUnlock() if _, ok := c.Extensions["XpExtension"]; !ok { panic("Cannot issue request 'PrintSelectInput' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") } cookie := c.NewCookie(false, false) - c.NewRequest(printSelectInputRequest(c, Context, EventMask, EventList), cookie) + c.NewRequest(printSelectInputRequest(c, Context, EventMask), cookie) return PrintSelectInputCookie{cookie} } // PrintSelectInputChecked sends a checked request. // If an error occurs, it can be retrieved using PrintSelectInputCookie.Check() -func PrintSelectInputChecked(c *xgb.Conn, Context Pcontext, EventMask uint32, EventList []uint32) PrintSelectInputCookie { +func PrintSelectInputChecked(c *xgb.Conn, Context Pcontext, EventMask uint32) PrintSelectInputCookie { c.ExtLock.RLock() defer c.ExtLock.RUnlock() if _, ok := c.Extensions["XpExtension"]; !ok { panic("Cannot issue request 'PrintSelectInput' using the uninitialized extension 'XpExtension'. xprint.Init(connObj) must be called first.") } cookie := c.NewCookie(true, false) - c.NewRequest(printSelectInputRequest(c, Context, EventMask, EventList), cookie) + c.NewRequest(printSelectInputRequest(c, Context, EventMask), cookie) return PrintSelectInputCookie{cookie} } @@ -2097,8 +2105,8 @@ func (cook PrintSelectInputCookie) Check() error { // Write request to wire for PrintSelectInput // printSelectInputRequest writes a PrintSelectInput request to a byte slice. -func printSelectInputRequest(c *xgb.Conn, Context Pcontext, EventMask uint32, EventList []uint32) []byte { - size := xgb.Pad((8 + (4 + xgb.Pad((4 * xgb.PopCount(int(EventMask))))))) +func printSelectInputRequest(c *xgb.Conn, Context Pcontext, EventMask uint32) []byte { + size := 12 b := 0 buf := make([]byte, size) @@ -2118,11 +2126,6 @@ func printSelectInputRequest(c *xgb.Conn, Context Pcontext, EventMask uint32, Ev xgb.Put32(buf[b:], EventMask) b += 4 - for i := 0; i < xgb.PopCount(int(EventMask)); i++ { - xgb.Put32(buf[b:], EventList[i]) - b += 4 - } - b = xgb.Pad(b) return buf } diff --git a/xproto/xproto.go b/xproto/xproto.go index e6b2c6b..ddd3ca9 100644 --- a/xproto/xproto.go +++ b/xproto/xproto.go @@ -343,6 +343,8 @@ const ( BlankingDefault = 2 ) +type Bool32 uint32 + type Button byte const ( @@ -921,9 +923,10 @@ func init() { // Note that to *create* a Union, you should *never* create // this struct directly (unless you know what you're doing). // Instead use one of the following constructors for 'ClientMessageDataUnion': -// ClientMessageDataUnionData8New(Data8 []byte) ClientMessageDataUnion -// ClientMessageDataUnionData16New(Data16 []uint16) ClientMessageDataUnion -// ClientMessageDataUnionData32New(Data32 []uint32) ClientMessageDataUnion +// +// ClientMessageDataUnionData8New(Data8 []byte) ClientMessageDataUnion +// ClientMessageDataUnionData16New(Data16 []uint16) ClientMessageDataUnion +// ClientMessageDataUnionData32New(Data32 []uint32) ClientMessageDataUnion type ClientMessageDataUnion struct { Data8 []byte // size: 20 Data16 []uint16 // size: 20 @@ -1208,6 +1211,10 @@ func NewColormapId(c *xgb.Conn) (Colormap, error) { return Colormap(id), nil } +const ( + ColormapNone = 0 +) + // BadColormap is the error number for a BadColormap. const BadColormap = 12 @@ -1247,10 +1254,6 @@ func init() { } const ( - ColormapNone = 0 -) - -const ( ColormapAllocNone = 0 ColormapAllocAll = 1 ) @@ -1787,6 +1790,10 @@ func NewCursorId(c *xgb.Conn) (Cursor, error) { return Cursor(id), nil } +const ( + CursorNone = 0 +) + // BadCursor is the error number for a BadCursor. const BadCursor = 6 @@ -1826,10 +1833,6 @@ func init() { } const ( - CursorNone = 0 -) - -const ( CwBackPixmap = 1 CwBackPixel = 2 CwBorderPixmap = 4 @@ -3052,6 +3055,7 @@ type Host struct { // padding: 1 bytes AddressLen uint16 Address []byte // size: xgb.Pad((int(AddressLen) * 1)) + // alignment gap to multiple of 4 } // HostRead reads a byte slice into a Host value. @@ -3070,6 +3074,8 @@ func HostRead(buf []byte, v *Host) int { copy(v.Address[:v.AddressLen], buf[b:]) b += int(v.AddressLen) + b = (b + 3) & ^3 // alignment gap + return b } @@ -3085,7 +3091,7 @@ func HostReadList(buf []byte, dest []Host) int { // Bytes writes a Host value to a byte slice. func (v Host) Bytes() []byte { - buf := make([]byte, (4 + xgb.Pad((int(v.AddressLen) * 1)))) + buf := make([]byte, ((4 + xgb.Pad((int(v.AddressLen) * 1))) + 4)) b := 0 buf[b] = v.Family @@ -3099,6 +3105,8 @@ func (v Host) Bytes() []byte { copy(buf[b:], v.Address[:v.AddressLen]) b += int(v.AddressLen) + b = (b + 3) & ^3 // alignment gap + return buf[:b] } @@ -3118,7 +3126,7 @@ func HostListBytes(buf []byte, list []Host) int { func HostListSize(list []Host) int { size := 0 for _, item := range list { - size += (4 + xgb.Pad((int(item.AddressLen) * 1))) + size += ((4 + xgb.Pad((int(item.AddressLen) * 1))) + 4) } return size } @@ -3453,6 +3461,8 @@ func init() { type Keycode byte +type Keycode32 uint32 + // KeymapNotify is the event number for a KeymapNotifyEvent. const KeymapNotify = 11 @@ -4237,10 +4247,6 @@ func NewPixmapId(c *xgb.Conn) (Pixmap, error) { return Pixmap(id), nil } -const ( - PixmapNone = 0 -) - // BadPixmap is the error number for a BadPixmap. const BadPixmap = 4 @@ -4280,6 +4286,10 @@ func init() { } const ( + PixmapNone = 0 +) + +const ( PlaceOnTop = 0 PlaceOnBottom = 1 ) @@ -5578,9 +5588,8 @@ type SetupInfo struct { // padding: 4 bytes Vendor string // size: xgb.Pad((int(VendorLen) * 1)) // alignment gap to multiple of 4 - PixmapFormats []Format // size: xgb.Pad((int(PixmapFormatsLen) * 8)) - // alignment gap to multiple of 4 - Roots []ScreenInfo // size: ScreenInfoListSize(Roots) + PixmapFormats []Format // size: xgb.Pad((int(PixmapFormatsLen) * 8)) + Roots []ScreenInfo // size: ScreenInfoListSize(Roots) } // SetupInfoRead reads a byte slice into a SetupInfo value. @@ -5657,8 +5666,6 @@ func SetupInfoRead(buf []byte, v *SetupInfo) int { v.PixmapFormats = make([]Format, v.PixmapFormatsLen) b += FormatReadList(buf[b:], v.PixmapFormats) - b = (b + 3) & ^3 // alignment gap - v.Roots = make([]ScreenInfo, v.RootsLen) b += ScreenInfoReadList(buf[b:], v.Roots) @@ -5677,7 +5684,7 @@ func SetupInfoReadList(buf []byte, dest []SetupInfo) int { // Bytes writes a SetupInfo value to a byte slice. func (v SetupInfo) Bytes() []byte { - buf := make([]byte, (((((40 + xgb.Pad((int(v.VendorLen) * 1))) + 4) + xgb.Pad((int(v.PixmapFormatsLen) * 8))) + 4) + ScreenInfoListSize(v.Roots))) + buf := make([]byte, ((((40 + xgb.Pad((int(v.VendorLen) * 1))) + 4) + xgb.Pad((int(v.PixmapFormatsLen) * 8))) + ScreenInfoListSize(v.Roots))) b := 0 buf[b] = v.Status @@ -5745,8 +5752,6 @@ func (v SetupInfo) Bytes() []byte { b += FormatListBytes(buf[b:], v.PixmapFormats) - b = (b + 3) & ^3 // alignment gap - b += ScreenInfoListBytes(buf[b:], v.Roots) return buf[:b] @@ -5768,7 +5773,7 @@ func SetupInfoListBytes(buf []byte, list []SetupInfo) int { func SetupInfoListSize(list []SetupInfo) int { size := 0 for _, item := range list { - size += (((((40 + xgb.Pad((int(item.VendorLen) * 1))) + 4) + xgb.Pad((int(item.PixmapFormatsLen) * 8))) + 4) + ScreenInfoListSize(item.Roots)) + size += ((((40 + xgb.Pad((int(item.VendorLen) * 1))) + 4) + xgb.Pad((int(item.PixmapFormatsLen) * 8))) + ScreenInfoListSize(item.Roots)) } return size } @@ -5782,7 +5787,9 @@ type SetupRequest struct { AuthorizationProtocolDataLen uint16 // padding: 2 bytes AuthorizationProtocolName string // size: xgb.Pad((int(AuthorizationProtocolNameLen) * 1)) + // alignment gap to multiple of 4 AuthorizationProtocolData string // size: xgb.Pad((int(AuthorizationProtocolDataLen) * 1)) + // alignment gap to multiple of 4 } // SetupRequestRead reads a byte slice into a SetupRequest value. @@ -5815,6 +5822,8 @@ func SetupRequestRead(buf []byte, v *SetupRequest) int { b += int(v.AuthorizationProtocolNameLen) } + b = (b + 3) & ^3 // alignment gap + { byteString := make([]byte, v.AuthorizationProtocolDataLen) copy(byteString[:v.AuthorizationProtocolDataLen], buf[b:]) @@ -5822,6 +5831,8 @@ func SetupRequestRead(buf []byte, v *SetupRequest) int { b += int(v.AuthorizationProtocolDataLen) } + b = (b + 3) & ^3 // alignment gap + return b } @@ -5837,7 +5848,7 @@ func SetupRequestReadList(buf []byte, dest []SetupRequest) int { // Bytes writes a SetupRequest value to a byte slice. func (v SetupRequest) Bytes() []byte { - buf := make([]byte, ((12 + xgb.Pad((int(v.AuthorizationProtocolNameLen) * 1))) + xgb.Pad((int(v.AuthorizationProtocolDataLen) * 1)))) + buf := make([]byte, ((((12 + xgb.Pad((int(v.AuthorizationProtocolNameLen) * 1))) + 4) + xgb.Pad((int(v.AuthorizationProtocolDataLen) * 1))) + 4)) b := 0 buf[b] = v.ByteOrder @@ -5862,9 +5873,13 @@ func (v SetupRequest) Bytes() []byte { copy(buf[b:], v.AuthorizationProtocolName[:v.AuthorizationProtocolNameLen]) b += int(v.AuthorizationProtocolNameLen) + b = (b + 3) & ^3 // alignment gap + copy(buf[b:], v.AuthorizationProtocolData[:v.AuthorizationProtocolDataLen]) b += int(v.AuthorizationProtocolDataLen) + b = (b + 3) & ^3 // alignment gap + return buf[:b] } @@ -5884,7 +5899,7 @@ func SetupRequestListBytes(buf []byte, list []SetupRequest) int { func SetupRequestListSize(list []SetupRequest) int { size := 0 for _, item := range list { - size += ((12 + xgb.Pad((int(item.AuthorizationProtocolNameLen) * 1))) + xgb.Pad((int(item.AuthorizationProtocolDataLen) * 1))) + size += ((((12 + xgb.Pad((int(item.AuthorizationProtocolNameLen) * 1))) + 4) + xgb.Pad((int(item.AuthorizationProtocolDataLen) * 1))) + 4) } return size } @@ -6389,6 +6404,10 @@ func NewWindowId(c *xgb.Conn) (Window, error) { return Window(id), nil } +const ( + WindowNone = 0 +) + // BadWindow is the error number for a BadWindow. const BadWindow = 3 @@ -6428,10 +6447,6 @@ func init() { } const ( - WindowNone = 0 -) - -const ( WindowClassCopyFromParent = 0 WindowClassInputOutput = 1 WindowClassInputOnly = 2 @@ -6598,8 +6613,7 @@ type AllocColorCellsReply struct { MasksLen uint16 // padding: 20 bytes Pixels []uint32 // size: xgb.Pad((int(PixelsLen) * 4)) - // alignment gap to multiple of 4 - Masks []uint32 // size: xgb.Pad((int(MasksLen) * 4)) + Masks []uint32 // size: xgb.Pad((int(MasksLen) * 4)) } // Reply blocks and returns the reply data for a AllocColorCells request. @@ -6641,8 +6655,6 @@ func allocColorCellsReply(buf []byte) *AllocColorCellsReply { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Masks = make([]uint32, v.MasksLen) for i := 0; i < int(v.MasksLen); i++ { v.Masks[i] = xgb.Get32(buf[b:]) @@ -7101,7 +7113,7 @@ func (cook ChangeGCCookie) Check() error { // Write request to wire for ChangeGC // changeGCRequest writes a ChangeGC request to a byte slice. func changeGCRequest(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((8 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -7118,6 +7130,7 @@ func changeGCRequest(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uin xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -7214,7 +7227,7 @@ func (cook ChangeKeyboardControlCookie) Check() error { // Write request to wire for ChangeKeyboardControl // changeKeyboardControlRequest writes a ChangeKeyboardControl request to a byte slice. func changeKeyboardControlRequest(c *xgb.Conn, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((4 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((8 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -7228,6 +7241,7 @@ func changeKeyboardControlRequest(c *xgb.Conn, ValueMask uint32, ValueList []uin xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -7509,7 +7523,7 @@ func (cook ChangeWindowAttributesCookie) Check() error { // Write request to wire for ChangeWindowAttributes // changeWindowAttributesRequest writes a ChangeWindowAttributes request to a byte slice. func changeWindowAttributesRequest(c *xgb.Conn, Window Window, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((8 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -7526,6 +7540,7 @@ func changeWindowAttributesRequest(c *xgb.Conn, Window Window, ValueMask uint32, xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -7727,7 +7742,7 @@ func (cook ConfigureWindowCookie) Check() error { // Write request to wire for ConfigureWindow // configureWindowRequest writes a ConfigureWindow request to a byte slice. func configureWindowRequest(c *xgb.Conn, Window Window, ValueMask uint16, ValueList []uint32) []byte { - size := xgb.Pad((10 + (2 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((12 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -8231,7 +8246,7 @@ func (cook CreateGCCookie) Check() error { // Write request to wire for CreateGC // createGCRequest writes a CreateGC request to a byte slice. func createGCRequest(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((12 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((16 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -8251,6 +8266,7 @@ func createGCRequest(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uin xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -8426,7 +8442,7 @@ func (cook CreateWindowCookie) Check() error { // Write request to wire for CreateWindow // createWindowRequest writes a CreateWindow request to a byte slice. func createWindowRequest(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class uint16, Visual Visualid, ValueMask uint32, ValueList []uint32) []byte { - size := xgb.Pad((28 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask))))))) + size := xgb.Pad((32 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))) b := 0 buf := make([]byte, size) @@ -8468,6 +8484,7 @@ func createWindowRequest(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X i xgb.Put32(buf[b:], ValueMask) b += 4 + for i := 0; i < xgb.PopCount(int(ValueMask)); i++ { xgb.Put32(buf[b:], ValueList[i]) b += 4 @@ -12914,8 +12931,7 @@ type QueryFontReply struct { FontDescent int16 CharInfosLen uint32 Properties []Fontprop // size: xgb.Pad((int(PropertiesLen) * 8)) - // alignment gap to multiple of 4 - CharInfos []Charinfo // size: xgb.Pad((int(CharInfosLen) * 12)) + CharInfos []Charinfo // size: xgb.Pad((int(CharInfosLen) * 12)) } // Reply blocks and returns the reply data for a QueryFont request. @@ -12993,8 +13009,6 @@ func queryFontReply(buf []byte) *QueryFontReply { v.Properties = make([]Fontprop, v.PropertiesLen) b += FontpropReadList(buf[b:], v.Properties) - b = (b + 3) & ^3 // alignment gap - v.CharInfos = make([]Charinfo, v.CharInfosLen) b += CharinfoReadList(buf[b:], v.CharInfos) diff --git a/xselinux/xselinux.go b/xselinux/xselinux.go index 68d55ea..5b383cc 100644 --- a/xselinux/xselinux.go +++ b/xselinux/xselinux.go @@ -41,7 +41,9 @@ type ListItem struct { ObjectContextLen uint32 DataContextLen uint32 ObjectContext string // size: xgb.Pad((int(ObjectContextLen) * 1)) - DataContext string // size: xgb.Pad((int(DataContextLen) * 1)) + // alignment gap to multiple of 4 + DataContext string // size: xgb.Pad((int(DataContextLen) * 1)) + // alignment gap to multiple of 4 } // ListItemRead reads a byte slice into a ListItem value. @@ -64,6 +66,8 @@ func ListItemRead(buf []byte, v *ListItem) int { b += int(v.ObjectContextLen) } + b = (b + 3) & ^3 // alignment gap + { byteString := make([]byte, v.DataContextLen) copy(byteString[:v.DataContextLen], buf[b:]) @@ -71,6 +75,8 @@ func ListItemRead(buf []byte, v *ListItem) int { b += int(v.DataContextLen) } + b = (b + 3) & ^3 // alignment gap + return b } @@ -86,7 +92,7 @@ func ListItemReadList(buf []byte, dest []ListItem) int { // Bytes writes a ListItem value to a byte slice. func (v ListItem) Bytes() []byte { - buf := make([]byte, ((12 + xgb.Pad((int(v.ObjectContextLen) * 1))) + xgb.Pad((int(v.DataContextLen) * 1)))) + buf := make([]byte, ((((12 + xgb.Pad((int(v.ObjectContextLen) * 1))) + 4) + xgb.Pad((int(v.DataContextLen) * 1))) + 4)) b := 0 xgb.Put32(buf[b:], uint32(v.Name)) @@ -101,9 +107,13 @@ func (v ListItem) Bytes() []byte { copy(buf[b:], v.ObjectContext[:v.ObjectContextLen]) b += int(v.ObjectContextLen) + b = (b + 3) & ^3 // alignment gap + copy(buf[b:], v.DataContext[:v.DataContextLen]) b += int(v.DataContextLen) + b = (b + 3) & ^3 // alignment gap + return buf[:b] } @@ -123,7 +133,7 @@ func ListItemListBytes(buf []byte, list []ListItem) int { func ListItemListSize(list []ListItem) int { size := 0 for _, item := range list { - size += ((12 + xgb.Pad((int(item.ObjectContextLen) * 1))) + xgb.Pad((int(item.DataContextLen) * 1))) + size += ((((12 + xgb.Pad((int(item.ObjectContextLen) * 1))) + 4) + xgb.Pad((int(item.DataContextLen) * 1))) + 4) } return size } @@ -45,7 +45,7 @@ type AdaptorInfo struct { Type byte // padding: 1 bytes Name string // size: xgb.Pad((int(NameSize) * 1)) - // padding: 0 bytes + // alignment gap to multiple of 4 Formats []Format // size: xgb.Pad((int(NumFormats) * 8)) } @@ -77,7 +77,7 @@ func AdaptorInfoRead(buf []byte, v *AdaptorInfo) int { b += int(v.NameSize) } - b += 0 // padding + b = (b + 3) & ^3 // alignment gap v.Formats = make([]Format, v.NumFormats) b += FormatReadList(buf[b:], v.Formats) @@ -97,7 +97,7 @@ func AdaptorInfoReadList(buf []byte, dest []AdaptorInfo) int { // Bytes writes a AdaptorInfo value to a byte slice. func (v AdaptorInfo) Bytes() []byte { - buf := make([]byte, (((12 + xgb.Pad((int(v.NameSize) * 1))) + 0) + xgb.Pad((int(v.NumFormats) * 8)))) + buf := make([]byte, (((12 + xgb.Pad((int(v.NameSize) * 1))) + 4) + xgb.Pad((int(v.NumFormats) * 8)))) b := 0 xgb.Put32(buf[b:], uint32(v.BaseId)) @@ -120,7 +120,7 @@ func (v AdaptorInfo) Bytes() []byte { copy(buf[b:], v.Name[:v.NameSize]) b += int(v.NameSize) - b += 0 // padding + b = (b + 3) & ^3 // alignment gap b += FormatListBytes(buf[b:], v.Formats) @@ -143,7 +143,7 @@ func AdaptorInfoListBytes(buf []byte, list []AdaptorInfo) int { func AdaptorInfoListSize(list []AdaptorInfo) int { size := 0 for _, item := range list { - size += (((12 + xgb.Pad((int(item.NameSize) * 1))) + 0) + xgb.Pad((int(item.NumFormats) * 8))) + size += (((12 + xgb.Pad((int(item.NameSize) * 1))) + 4) + xgb.Pad((int(item.NumFormats) * 8))) } return size } @@ -159,6 +159,7 @@ type AttributeInfo struct { Max int32 Size uint32 Name string // size: xgb.Pad((int(Size) * 1)) + // alignment gap to multiple of 4 } // AttributeInfoRead reads a byte slice into a AttributeInfo value. @@ -184,6 +185,8 @@ func AttributeInfoRead(buf []byte, v *AttributeInfo) int { b += int(v.Size) } + b = (b + 3) & ^3 // alignment gap + return b } @@ -199,7 +202,7 @@ func AttributeInfoReadList(buf []byte, dest []AttributeInfo) int { // Bytes writes a AttributeInfo value to a byte slice. func (v AttributeInfo) Bytes() []byte { - buf := make([]byte, (16 + xgb.Pad((int(v.Size) * 1)))) + buf := make([]byte, ((16 + xgb.Pad((int(v.Size) * 1))) + 4)) b := 0 xgb.Put32(buf[b:], v.Flags) @@ -217,6 +220,8 @@ func (v AttributeInfo) Bytes() []byte { copy(buf[b:], v.Name[:v.Size]) b += int(v.Size) + b = (b + 3) & ^3 // alignment gap + return buf[:b] } @@ -236,7 +241,7 @@ func AttributeInfoListBytes(buf []byte, list []AttributeInfo) int { func AttributeInfoListSize(list []AttributeInfo) int { size := 0 for _, item := range list { - size += (16 + xgb.Pad((int(item.Size) * 1))) + size += ((16 + xgb.Pad((int(item.Size) * 1))) + 4) } return size } @@ -397,6 +402,7 @@ type EncodingInfo struct { // padding: 2 bytes Rate Rational Name string // size: xgb.Pad((int(NameSize) * 1)) + // alignment gap to multiple of 4 } // EncodingInfoRead reads a byte slice into a EncodingInfo value. @@ -427,6 +433,8 @@ func EncodingInfoRead(buf []byte, v *EncodingInfo) int { b += int(v.NameSize) } + b = (b + 3) & ^3 // alignment gap + return b } @@ -442,7 +450,7 @@ func EncodingInfoReadList(buf []byte, dest []EncodingInfo) int { // Bytes writes a EncodingInfo value to a byte slice. func (v EncodingInfo) Bytes() []byte { - buf := make([]byte, (20 + xgb.Pad((int(v.NameSize) * 1)))) + buf := make([]byte, ((20 + xgb.Pad((int(v.NameSize) * 1))) + 4)) b := 0 xgb.Put32(buf[b:], uint32(v.Encoding)) @@ -468,6 +476,8 @@ func (v EncodingInfo) Bytes() []byte { copy(buf[b:], v.Name[:v.NameSize]) b += int(v.NameSize) + b = (b + 3) & ^3 // alignment gap + return buf[:b] } @@ -487,7 +497,7 @@ func EncodingInfoListBytes(buf []byte, list []EncodingInfo) int { func EncodingInfoListSize(list []EncodingInfo) int { size := 0 for _, item := range list { - size += (20 + xgb.Pad((int(item.NameSize) * 1))) + size += ((20 + xgb.Pad((int(item.NameSize) * 1))) + 4) } return size } @@ -567,9 +577,8 @@ type Image struct { DataSize uint32 NumPlanes uint32 Pitches []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) - // alignment gap to multiple of 4 - Offsets []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) - Data []byte // size: xgb.Pad((int(DataSize) * 1)) + Offsets []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) + Data []byte // size: xgb.Pad((int(DataSize) * 1)) } // ImageRead reads a byte slice into a Image value. @@ -597,8 +606,6 @@ func ImageRead(buf []byte, v *Image) int { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Offsets = make([]uint32, v.NumPlanes) for i := 0; i < int(v.NumPlanes); i++ { v.Offsets[i] = xgb.Get32(buf[b:]) @@ -624,7 +631,7 @@ func ImageReadList(buf []byte, dest []Image) int { // Bytes writes a Image value to a byte slice. func (v Image) Bytes() []byte { - buf := make([]byte, ((((16 + xgb.Pad((int(v.NumPlanes) * 4))) + 4) + xgb.Pad((int(v.NumPlanes) * 4))) + xgb.Pad((int(v.DataSize) * 1)))) + buf := make([]byte, (((16 + xgb.Pad((int(v.NumPlanes) * 4))) + xgb.Pad((int(v.NumPlanes) * 4))) + xgb.Pad((int(v.DataSize) * 1)))) b := 0 xgb.Put32(buf[b:], v.Id) @@ -647,8 +654,6 @@ func (v Image) Bytes() []byte { b += 4 } - b = (b + 3) & ^3 // alignment gap - for i := 0; i < int(v.NumPlanes); i++ { xgb.Put32(buf[b:], v.Offsets[i]) b += 4 @@ -676,7 +681,7 @@ func ImageListBytes(buf []byte, list []Image) int { func ImageListSize(list []Image) int { size := 0 for _, item := range list { - size += ((((16 + xgb.Pad((int(item.NumPlanes) * 4))) + 4) + xgb.Pad((int(item.NumPlanes) * 4))) + xgb.Pad((int(item.DataSize) * 1))) + size += (((16 + xgb.Pad((int(item.NumPlanes) * 4))) + xgb.Pad((int(item.NumPlanes) * 4))) + xgb.Pad((int(item.DataSize) * 1))) } return size } @@ -2416,7 +2421,6 @@ type QueryImageAttributesReply struct { Height uint16 // padding: 12 bytes Pitches []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) - // alignment gap to multiple of 4 Offsets []uint32 // size: xgb.Pad((int(NumPlanes) * 4)) } @@ -2465,8 +2469,6 @@ func queryImageAttributesReply(buf []byte) *QueryImageAttributesReply { b += 4 } - b = (b + 3) & ^3 // alignment gap - v.Offsets = make([]uint32, v.NumPlanes) for i := 0; i < int(v.NumPlanes); i++ { v.Offsets[i] = xgb.Get32(buf[b:]) |
