diff options
Diffstat (limited to 'nexgb/shm')
| -rw-r--r-- | nexgb/shm/shm.go | 164 | 
1 files changed, 164 insertions, 0 deletions
| diff --git a/nexgb/shm/shm.go b/nexgb/shm/shm.go index 3e086c4..e5841ca 100644 --- a/nexgb/shm/shm.go +++ b/nexgb/shm/shm.go @@ -276,6 +276,70 @@ func attachRequest(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) []byte  	return buf  } +// AttachFdCookie is a cookie used only for AttachFd requests. +type AttachFdCookie struct { +	*xgb.Cookie +} + +// AttachFd sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AttachFd(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie { +	if _, ok := c.Extensions["MIT-SHM"]; !ok { +		panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") +	} +	cookie := c.NewCookie(false, false) +	c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie) +	return AttachFdCookie{cookie} +} + +// AttachFdChecked sends a checked request. +// If an error occurs, it can be retrieved using AttachFdCookie.Check() +func AttachFdChecked(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie { +	if _, ok := c.Extensions["MIT-SHM"]; !ok { +		panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") +	} +	cookie := c.NewCookie(true, false) +	c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie) +	return AttachFdCookie{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 AttachFdCookie) Check() error { +	return cook.Cookie.Check() +} + +// Write request to wire for AttachFd +// attachFdRequest writes a AttachFd request to a byte slice. +func attachFdRequest(c *xgb.Conn, Shmseg Seg, ReadOnly bool) []byte { +	size := 12 +	b := 0 +	buf := make([]byte, size) + +	buf[b] = c.Extensions["MIT-SHM"] +	b += 1 + +	buf[b] = 6 // 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(Shmseg)) +	b += 4 + +	if ReadOnly { +		buf[b] = 1 +	} else { +		buf[b] = 0 +	} +	b += 1 + +	b += 3 // padding + +	return buf +} +  // CreatePixmapCookie is a cookie used only for CreatePixmap requests.  type CreatePixmapCookie struct {  	*xgb.Cookie @@ -351,6 +415,106 @@ func createPixmapRequest(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawabl  	return buf  } +// CreateSegmentCookie is a cookie used only for CreateSegment requests. +type CreateSegmentCookie struct { +	*xgb.Cookie +} + +// CreateSegment sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateSegmentCookie.Reply() +func CreateSegment(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie { +	if _, ok := c.Extensions["MIT-SHM"]; !ok { +		panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") +	} +	cookie := c.NewCookie(true, true) +	c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie) +	return CreateSegmentCookie{cookie} +} + +// CreateSegmentUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateSegmentUnchecked(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie { +	if _, ok := c.Extensions["MIT-SHM"]; !ok { +		panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.") +	} +	cookie := c.NewCookie(false, true) +	c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie) +	return CreateSegmentCookie{cookie} +} + +// CreateSegmentReply represents the data returned from a CreateSegment request. +type CreateSegmentReply 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 CreateSegment request. +func (cook CreateSegmentCookie) Reply() (*CreateSegmentReply, error) { +	buf, err := cook.Cookie.Reply() +	if err != nil { +		return nil, err +	} +	if buf == nil { +		return nil, nil +	} +	return createSegmentReply(buf), nil +} + +// createSegmentReply reads a byte slice into a CreateSegmentReply value. +func createSegmentReply(buf []byte) *CreateSegmentReply { +	v := new(CreateSegmentReply) +	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 CreateSegment +// createSegmentRequest writes a CreateSegment request to a byte slice. +func createSegmentRequest(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) []byte { +	size := 16 +	b := 0 +	buf := make([]byte, size) + +	buf[b] = c.Extensions["MIT-SHM"] +	b += 1 + +	buf[b] = 7 // 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(Shmseg)) +	b += 4 + +	xgb.Put32(buf[b:], Size) +	b += 4 + +	if ReadOnly { +		buf[b] = 1 +	} else { +		buf[b] = 0 +	} +	b += 1 + +	b += 3 // padding + +	return buf +} +  // DetachCookie is a cookie used only for Detach requests.  type DetachCookie struct {  	*xgb.Cookie | 
