github.com/robotn/xgb@v0.0.0-20190912153532-2cb92d044934/shm/shm.go (about)

     1  // Package shm is the X client API for the MIT-SHM extension.
     2  package shm
     3  
     4  // This file is automatically generated from shm.xml. Edit at your peril!
     5  
     6  import (
     7  	"github.com/robotn/xgb"
     8  
     9  	"github.com/robotn/xgb/xproto"
    10  )
    11  
    12  // Init must be called before using the MIT-SHM extension.
    13  func Init(c *xgb.Conn) error {
    14  	reply, err := xproto.QueryExtension(c, 7, "MIT-SHM").Reply()
    15  	switch {
    16  	case err != nil:
    17  		return err
    18  	case !reply.Present:
    19  		return xgb.Errorf("No extension named MIT-SHM could be found on on the server.")
    20  	}
    21  
    22  	c.ExtLock.Lock()
    23  	c.Extensions["MIT-SHM"] = reply.MajorOpcode
    24  	c.ExtLock.Unlock()
    25  	for evNum, fun := range xgb.NewExtEventFuncs["MIT-SHM"] {
    26  		xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun
    27  	}
    28  	for errNum, fun := range xgb.NewExtErrorFuncs["MIT-SHM"] {
    29  		xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun
    30  	}
    31  	return nil
    32  }
    33  
    34  func init() {
    35  	xgb.NewExtEventFuncs["MIT-SHM"] = make(map[int]xgb.NewEventFun)
    36  	xgb.NewExtErrorFuncs["MIT-SHM"] = make(map[int]xgb.NewErrorFun)
    37  }
    38  
    39  // BadBadSeg is the error number for a BadBadSeg.
    40  const BadBadSeg = 0
    41  
    42  type BadSegError xproto.ValueError
    43  
    44  // BadSegErrorNew constructs a BadSegError value that implements xgb.Error from a byte slice.
    45  func BadSegErrorNew(buf []byte) xgb.Error {
    46  	v := BadSegError(xproto.ValueErrorNew(buf).(xproto.ValueError))
    47  	v.NiceName = "BadSeg"
    48  	return v
    49  }
    50  
    51  // SequenceId returns the sequence id attached to the BadBadSeg error.
    52  // This is mostly used internally.
    53  func (err BadSegError) SequenceId() uint16 {
    54  	return err.Sequence
    55  }
    56  
    57  // BadId returns the 'BadValue' number if one exists for the BadBadSeg error. If no bad value exists, 0 is returned.
    58  func (err BadSegError) BadId() uint32 {
    59  	return 0
    60  }
    61  
    62  // Error returns a rudimentary string representation of the BadBadSeg error.
    63  func (err BadSegError) Error() string {
    64  	fieldVals := make([]string, 0, 4)
    65  	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
    66  	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
    67  	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
    68  	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
    69  	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
    70  	return "BadBadSeg {" + xgb.StringsJoin(fieldVals, ", ") + "}"
    71  }
    72  
    73  func init() {
    74  	xgb.NewExtErrorFuncs["MIT-SHM"][0] = BadSegErrorNew
    75  }
    76  
    77  // Completion is the event number for a CompletionEvent.
    78  const Completion = 0
    79  
    80  type CompletionEvent struct {
    81  	Sequence uint16
    82  	// padding: 1 bytes
    83  	Drawable   xproto.Drawable
    84  	MinorEvent uint16
    85  	MajorEvent byte
    86  	// padding: 1 bytes
    87  	Shmseg Seg
    88  	Offset uint32
    89  }
    90  
    91  // CompletionEventNew constructs a CompletionEvent value that implements xgb.Event from a byte slice.
    92  func CompletionEventNew(buf []byte) xgb.Event {
    93  	v := CompletionEvent{}
    94  	b := 1 // don't read event number
    95  
    96  	b += 1 // padding
    97  
    98  	v.Sequence = xgb.Get16(buf[b:])
    99  	b += 2
   100  
   101  	v.Drawable = xproto.Drawable(xgb.Get32(buf[b:]))
   102  	b += 4
   103  
   104  	v.MinorEvent = xgb.Get16(buf[b:])
   105  	b += 2
   106  
   107  	v.MajorEvent = buf[b]
   108  	b += 1
   109  
   110  	b += 1 // padding
   111  
   112  	v.Shmseg = Seg(xgb.Get32(buf[b:]))
   113  	b += 4
   114  
   115  	v.Offset = xgb.Get32(buf[b:])
   116  	b += 4
   117  
   118  	return v
   119  }
   120  
   121  // Bytes writes a CompletionEvent value to a byte slice.
   122  func (v CompletionEvent) Bytes() []byte {
   123  	buf := make([]byte, 32)
   124  	b := 0
   125  
   126  	// write event number
   127  	buf[b] = 0
   128  	b += 1
   129  
   130  	b += 1 // padding
   131  
   132  	b += 2 // skip sequence number
   133  
   134  	xgb.Put32(buf[b:], uint32(v.Drawable))
   135  	b += 4
   136  
   137  	xgb.Put16(buf[b:], v.MinorEvent)
   138  	b += 2
   139  
   140  	buf[b] = v.MajorEvent
   141  	b += 1
   142  
   143  	b += 1 // padding
   144  
   145  	xgb.Put32(buf[b:], uint32(v.Shmseg))
   146  	b += 4
   147  
   148  	xgb.Put32(buf[b:], v.Offset)
   149  	b += 4
   150  
   151  	return buf
   152  }
   153  
   154  // SequenceId returns the sequence id attached to the Completion event.
   155  // Events without a sequence number (KeymapNotify) return 0.
   156  // This is mostly used internally.
   157  func (v CompletionEvent) SequenceId() uint16 {
   158  	return v.Sequence
   159  }
   160  
   161  // String is a rudimentary string representation of CompletionEvent.
   162  func (v CompletionEvent) String() string {
   163  	fieldVals := make([]string, 0, 7)
   164  	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
   165  	fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable))
   166  	fieldVals = append(fieldVals, xgb.Sprintf("MinorEvent: %d", v.MinorEvent))
   167  	fieldVals = append(fieldVals, xgb.Sprintf("MajorEvent: %d", v.MajorEvent))
   168  	fieldVals = append(fieldVals, xgb.Sprintf("Shmseg: %d", v.Shmseg))
   169  	fieldVals = append(fieldVals, xgb.Sprintf("Offset: %d", v.Offset))
   170  	return "Completion {" + xgb.StringsJoin(fieldVals, ", ") + "}"
   171  }
   172  
   173  func init() {
   174  	xgb.NewExtEventFuncs["MIT-SHM"][0] = CompletionEventNew
   175  }
   176  
   177  type Seg uint32
   178  
   179  func NewSegId(c *xgb.Conn) (Seg, error) {
   180  	id, err := c.NewId()
   181  	if err != nil {
   182  		return 0, err
   183  	}
   184  	return Seg(id), nil
   185  }
   186  
   187  // Skipping definition for base type 'Bool'
   188  
   189  // Skipping definition for base type 'Byte'
   190  
   191  // Skipping definition for base type 'Card8'
   192  
   193  // Skipping definition for base type 'Char'
   194  
   195  // Skipping definition for base type 'Void'
   196  
   197  // Skipping definition for base type 'Double'
   198  
   199  // Skipping definition for base type 'Float'
   200  
   201  // Skipping definition for base type 'Int16'
   202  
   203  // Skipping definition for base type 'Int32'
   204  
   205  // Skipping definition for base type 'Int8'
   206  
   207  // Skipping definition for base type 'Card16'
   208  
   209  // Skipping definition for base type 'Card32'
   210  
   211  // AttachCookie is a cookie used only for Attach requests.
   212  type AttachCookie struct {
   213  	*xgb.Cookie
   214  }
   215  
   216  // Attach sends an unchecked request.
   217  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   218  func Attach(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) AttachCookie {
   219  	c.ExtLock.RLock()
   220  	defer c.ExtLock.RUnlock()
   221  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   222  		panic("Cannot issue request 'Attach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   223  	}
   224  	cookie := c.NewCookie(false, false)
   225  	c.NewRequest(attachRequest(c, Shmseg, Shmid, ReadOnly), cookie)
   226  	return AttachCookie{cookie}
   227  }
   228  
   229  // AttachChecked sends a checked request.
   230  // If an error occurs, it can be retrieved using AttachCookie.Check()
   231  func AttachChecked(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) AttachCookie {
   232  	c.ExtLock.RLock()
   233  	defer c.ExtLock.RUnlock()
   234  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   235  		panic("Cannot issue request 'Attach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   236  	}
   237  	cookie := c.NewCookie(true, false)
   238  	c.NewRequest(attachRequest(c, Shmseg, Shmid, ReadOnly), cookie)
   239  	return AttachCookie{cookie}
   240  }
   241  
   242  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   243  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   244  func (cook AttachCookie) Check() error {
   245  	return cook.Cookie.Check()
   246  }
   247  
   248  // Write request to wire for Attach
   249  // attachRequest writes a Attach request to a byte slice.
   250  func attachRequest(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) []byte {
   251  	size := 16
   252  	b := 0
   253  	buf := make([]byte, size)
   254  
   255  	c.ExtLock.RLock()
   256  	buf[b] = c.Extensions["MIT-SHM"]
   257  	c.ExtLock.RUnlock()
   258  	b += 1
   259  
   260  	buf[b] = 1 // request opcode
   261  	b += 1
   262  
   263  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   264  	b += 2
   265  
   266  	xgb.Put32(buf[b:], uint32(Shmseg))
   267  	b += 4
   268  
   269  	xgb.Put32(buf[b:], Shmid)
   270  	b += 4
   271  
   272  	if ReadOnly {
   273  		buf[b] = 1
   274  	} else {
   275  		buf[b] = 0
   276  	}
   277  	b += 1
   278  
   279  	b += 3 // padding
   280  
   281  	return buf
   282  }
   283  
   284  // AttachFdCookie is a cookie used only for AttachFd requests.
   285  type AttachFdCookie struct {
   286  	*xgb.Cookie
   287  }
   288  
   289  // AttachFd sends an unchecked request.
   290  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   291  func AttachFd(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie {
   292  	c.ExtLock.RLock()
   293  	defer c.ExtLock.RUnlock()
   294  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   295  		panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   296  	}
   297  	cookie := c.NewCookie(false, false)
   298  	c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie)
   299  	return AttachFdCookie{cookie}
   300  }
   301  
   302  // AttachFdChecked sends a checked request.
   303  // If an error occurs, it can be retrieved using AttachFdCookie.Check()
   304  func AttachFdChecked(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie {
   305  	c.ExtLock.RLock()
   306  	defer c.ExtLock.RUnlock()
   307  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   308  		panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   309  	}
   310  	cookie := c.NewCookie(true, false)
   311  	c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie)
   312  	return AttachFdCookie{cookie}
   313  }
   314  
   315  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   316  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   317  func (cook AttachFdCookie) Check() error {
   318  	return cook.Cookie.Check()
   319  }
   320  
   321  // Write request to wire for AttachFd
   322  // attachFdRequest writes a AttachFd request to a byte slice.
   323  func attachFdRequest(c *xgb.Conn, Shmseg Seg, ReadOnly bool) []byte {
   324  	size := 12
   325  	b := 0
   326  	buf := make([]byte, size)
   327  
   328  	c.ExtLock.RLock()
   329  	buf[b] = c.Extensions["MIT-SHM"]
   330  	c.ExtLock.RUnlock()
   331  	b += 1
   332  
   333  	buf[b] = 6 // request opcode
   334  	b += 1
   335  
   336  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   337  	b += 2
   338  
   339  	xgb.Put32(buf[b:], uint32(Shmseg))
   340  	b += 4
   341  
   342  	if ReadOnly {
   343  		buf[b] = 1
   344  	} else {
   345  		buf[b] = 0
   346  	}
   347  	b += 1
   348  
   349  	b += 3 // padding
   350  
   351  	return buf
   352  }
   353  
   354  // CreatePixmapCookie is a cookie used only for CreatePixmap requests.
   355  type CreatePixmapCookie struct {
   356  	*xgb.Cookie
   357  }
   358  
   359  // CreatePixmap sends an unchecked request.
   360  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   361  func CreatePixmap(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) CreatePixmapCookie {
   362  	c.ExtLock.RLock()
   363  	defer c.ExtLock.RUnlock()
   364  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   365  		panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   366  	}
   367  	cookie := c.NewCookie(false, false)
   368  	c.NewRequest(createPixmapRequest(c, Pid, Drawable, Width, Height, Depth, Shmseg, Offset), cookie)
   369  	return CreatePixmapCookie{cookie}
   370  }
   371  
   372  // CreatePixmapChecked sends a checked request.
   373  // If an error occurs, it can be retrieved using CreatePixmapCookie.Check()
   374  func CreatePixmapChecked(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) CreatePixmapCookie {
   375  	c.ExtLock.RLock()
   376  	defer c.ExtLock.RUnlock()
   377  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   378  		panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   379  	}
   380  	cookie := c.NewCookie(true, false)
   381  	c.NewRequest(createPixmapRequest(c, Pid, Drawable, Width, Height, Depth, Shmseg, Offset), cookie)
   382  	return CreatePixmapCookie{cookie}
   383  }
   384  
   385  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   386  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   387  func (cook CreatePixmapCookie) Check() error {
   388  	return cook.Cookie.Check()
   389  }
   390  
   391  // Write request to wire for CreatePixmap
   392  // createPixmapRequest writes a CreatePixmap request to a byte slice.
   393  func createPixmapRequest(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) []byte {
   394  	size := 28
   395  	b := 0
   396  	buf := make([]byte, size)
   397  
   398  	c.ExtLock.RLock()
   399  	buf[b] = c.Extensions["MIT-SHM"]
   400  	c.ExtLock.RUnlock()
   401  	b += 1
   402  
   403  	buf[b] = 5 // request opcode
   404  	b += 1
   405  
   406  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   407  	b += 2
   408  
   409  	xgb.Put32(buf[b:], uint32(Pid))
   410  	b += 4
   411  
   412  	xgb.Put32(buf[b:], uint32(Drawable))
   413  	b += 4
   414  
   415  	xgb.Put16(buf[b:], Width)
   416  	b += 2
   417  
   418  	xgb.Put16(buf[b:], Height)
   419  	b += 2
   420  
   421  	buf[b] = Depth
   422  	b += 1
   423  
   424  	b += 3 // padding
   425  
   426  	xgb.Put32(buf[b:], uint32(Shmseg))
   427  	b += 4
   428  
   429  	xgb.Put32(buf[b:], Offset)
   430  	b += 4
   431  
   432  	return buf
   433  }
   434  
   435  // CreateSegmentCookie is a cookie used only for CreateSegment requests.
   436  type CreateSegmentCookie struct {
   437  	*xgb.Cookie
   438  }
   439  
   440  // CreateSegment sends a checked request.
   441  // If an error occurs, it will be returned with the reply by calling CreateSegmentCookie.Reply()
   442  func CreateSegment(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie {
   443  	c.ExtLock.RLock()
   444  	defer c.ExtLock.RUnlock()
   445  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   446  		panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   447  	}
   448  	cookie := c.NewCookie(true, true)
   449  	c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie)
   450  	return CreateSegmentCookie{cookie}
   451  }
   452  
   453  // CreateSegmentUnchecked sends an unchecked request.
   454  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   455  func CreateSegmentUnchecked(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie {
   456  	c.ExtLock.RLock()
   457  	defer c.ExtLock.RUnlock()
   458  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   459  		panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   460  	}
   461  	cookie := c.NewCookie(false, true)
   462  	c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie)
   463  	return CreateSegmentCookie{cookie}
   464  }
   465  
   466  // CreateSegmentReply represents the data returned from a CreateSegment request.
   467  type CreateSegmentReply struct {
   468  	Sequence uint16 // sequence number of the request for this reply
   469  	Length   uint32 // number of bytes in this reply
   470  	Nfd      byte
   471  	// padding: 24 bytes
   472  }
   473  
   474  // Reply blocks and returns the reply data for a CreateSegment request.
   475  func (cook CreateSegmentCookie) Reply() (*CreateSegmentReply, error) {
   476  	buf, err := cook.Cookie.Reply()
   477  	if err != nil {
   478  		return nil, err
   479  	}
   480  	if buf == nil {
   481  		return nil, nil
   482  	}
   483  	return createSegmentReply(buf), nil
   484  }
   485  
   486  // createSegmentReply reads a byte slice into a CreateSegmentReply value.
   487  func createSegmentReply(buf []byte) *CreateSegmentReply {
   488  	v := new(CreateSegmentReply)
   489  	b := 1 // skip reply determinant
   490  
   491  	v.Nfd = buf[b]
   492  	b += 1
   493  
   494  	v.Sequence = xgb.Get16(buf[b:])
   495  	b += 2
   496  
   497  	v.Length = xgb.Get32(buf[b:]) // 4-byte units
   498  	b += 4
   499  
   500  	b += 24 // padding
   501  
   502  	return v
   503  }
   504  
   505  // Write request to wire for CreateSegment
   506  // createSegmentRequest writes a CreateSegment request to a byte slice.
   507  func createSegmentRequest(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) []byte {
   508  	size := 16
   509  	b := 0
   510  	buf := make([]byte, size)
   511  
   512  	c.ExtLock.RLock()
   513  	buf[b] = c.Extensions["MIT-SHM"]
   514  	c.ExtLock.RUnlock()
   515  	b += 1
   516  
   517  	buf[b] = 7 // request opcode
   518  	b += 1
   519  
   520  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   521  	b += 2
   522  
   523  	xgb.Put32(buf[b:], uint32(Shmseg))
   524  	b += 4
   525  
   526  	xgb.Put32(buf[b:], Size)
   527  	b += 4
   528  
   529  	if ReadOnly {
   530  		buf[b] = 1
   531  	} else {
   532  		buf[b] = 0
   533  	}
   534  	b += 1
   535  
   536  	b += 3 // padding
   537  
   538  	return buf
   539  }
   540  
   541  // DetachCookie is a cookie used only for Detach requests.
   542  type DetachCookie struct {
   543  	*xgb.Cookie
   544  }
   545  
   546  // Detach sends an unchecked request.
   547  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   548  func Detach(c *xgb.Conn, Shmseg Seg) DetachCookie {
   549  	c.ExtLock.RLock()
   550  	defer c.ExtLock.RUnlock()
   551  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   552  		panic("Cannot issue request 'Detach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   553  	}
   554  	cookie := c.NewCookie(false, false)
   555  	c.NewRequest(detachRequest(c, Shmseg), cookie)
   556  	return DetachCookie{cookie}
   557  }
   558  
   559  // DetachChecked sends a checked request.
   560  // If an error occurs, it can be retrieved using DetachCookie.Check()
   561  func DetachChecked(c *xgb.Conn, Shmseg Seg) DetachCookie {
   562  	c.ExtLock.RLock()
   563  	defer c.ExtLock.RUnlock()
   564  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   565  		panic("Cannot issue request 'Detach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   566  	}
   567  	cookie := c.NewCookie(true, false)
   568  	c.NewRequest(detachRequest(c, Shmseg), cookie)
   569  	return DetachCookie{cookie}
   570  }
   571  
   572  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   573  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   574  func (cook DetachCookie) Check() error {
   575  	return cook.Cookie.Check()
   576  }
   577  
   578  // Write request to wire for Detach
   579  // detachRequest writes a Detach request to a byte slice.
   580  func detachRequest(c *xgb.Conn, Shmseg Seg) []byte {
   581  	size := 8
   582  	b := 0
   583  	buf := make([]byte, size)
   584  
   585  	c.ExtLock.RLock()
   586  	buf[b] = c.Extensions["MIT-SHM"]
   587  	c.ExtLock.RUnlock()
   588  	b += 1
   589  
   590  	buf[b] = 2 // request opcode
   591  	b += 1
   592  
   593  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   594  	b += 2
   595  
   596  	xgb.Put32(buf[b:], uint32(Shmseg))
   597  	b += 4
   598  
   599  	return buf
   600  }
   601  
   602  // GetImageCookie is a cookie used only for GetImage requests.
   603  type GetImageCookie struct {
   604  	*xgb.Cookie
   605  }
   606  
   607  // GetImage sends a checked request.
   608  // If an error occurs, it will be returned with the reply by calling GetImageCookie.Reply()
   609  func GetImage(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32, Format byte, Shmseg Seg, Offset uint32) GetImageCookie {
   610  	c.ExtLock.RLock()
   611  	defer c.ExtLock.RUnlock()
   612  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   613  		panic("Cannot issue request 'GetImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   614  	}
   615  	cookie := c.NewCookie(true, true)
   616  	c.NewRequest(getImageRequest(c, Drawable, X, Y, Width, Height, PlaneMask, Format, Shmseg, Offset), cookie)
   617  	return GetImageCookie{cookie}
   618  }
   619  
   620  // GetImageUnchecked sends an unchecked request.
   621  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   622  func GetImageUnchecked(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32, Format byte, Shmseg Seg, Offset uint32) GetImageCookie {
   623  	c.ExtLock.RLock()
   624  	defer c.ExtLock.RUnlock()
   625  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   626  		panic("Cannot issue request 'GetImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   627  	}
   628  	cookie := c.NewCookie(false, true)
   629  	c.NewRequest(getImageRequest(c, Drawable, X, Y, Width, Height, PlaneMask, Format, Shmseg, Offset), cookie)
   630  	return GetImageCookie{cookie}
   631  }
   632  
   633  // GetImageReply represents the data returned from a GetImage request.
   634  type GetImageReply struct {
   635  	Sequence uint16 // sequence number of the request for this reply
   636  	Length   uint32 // number of bytes in this reply
   637  	Depth    byte
   638  	Visual   xproto.Visualid
   639  	Size     uint32
   640  }
   641  
   642  // Reply blocks and returns the reply data for a GetImage request.
   643  func (cook GetImageCookie) Reply() (*GetImageReply, error) {
   644  	buf, err := cook.Cookie.Reply()
   645  	if err != nil {
   646  		return nil, err
   647  	}
   648  	if buf == nil {
   649  		return nil, nil
   650  	}
   651  	return getImageReply(buf), nil
   652  }
   653  
   654  // getImageReply reads a byte slice into a GetImageReply value.
   655  func getImageReply(buf []byte) *GetImageReply {
   656  	v := new(GetImageReply)
   657  	b := 1 // skip reply determinant
   658  
   659  	v.Depth = buf[b]
   660  	b += 1
   661  
   662  	v.Sequence = xgb.Get16(buf[b:])
   663  	b += 2
   664  
   665  	v.Length = xgb.Get32(buf[b:]) // 4-byte units
   666  	b += 4
   667  
   668  	v.Visual = xproto.Visualid(xgb.Get32(buf[b:]))
   669  	b += 4
   670  
   671  	v.Size = xgb.Get32(buf[b:])
   672  	b += 4
   673  
   674  	return v
   675  }
   676  
   677  // Write request to wire for GetImage
   678  // getImageRequest writes a GetImage request to a byte slice.
   679  func getImageRequest(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32, Format byte, Shmseg Seg, Offset uint32) []byte {
   680  	size := 32
   681  	b := 0
   682  	buf := make([]byte, size)
   683  
   684  	c.ExtLock.RLock()
   685  	buf[b] = c.Extensions["MIT-SHM"]
   686  	c.ExtLock.RUnlock()
   687  	b += 1
   688  
   689  	buf[b] = 4 // request opcode
   690  	b += 1
   691  
   692  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   693  	b += 2
   694  
   695  	xgb.Put32(buf[b:], uint32(Drawable))
   696  	b += 4
   697  
   698  	xgb.Put16(buf[b:], uint16(X))
   699  	b += 2
   700  
   701  	xgb.Put16(buf[b:], uint16(Y))
   702  	b += 2
   703  
   704  	xgb.Put16(buf[b:], Width)
   705  	b += 2
   706  
   707  	xgb.Put16(buf[b:], Height)
   708  	b += 2
   709  
   710  	xgb.Put32(buf[b:], PlaneMask)
   711  	b += 4
   712  
   713  	buf[b] = Format
   714  	b += 1
   715  
   716  	b += 3 // padding
   717  
   718  	xgb.Put32(buf[b:], uint32(Shmseg))
   719  	b += 4
   720  
   721  	xgb.Put32(buf[b:], Offset)
   722  	b += 4
   723  
   724  	return buf
   725  }
   726  
   727  // PutImageCookie is a cookie used only for PutImage requests.
   728  type PutImageCookie struct {
   729  	*xgb.Cookie
   730  }
   731  
   732  // PutImage sends an unchecked request.
   733  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   734  func PutImage(c *xgb.Conn, Drawable xproto.Drawable, Gc xproto.Gcontext, TotalWidth uint16, TotalHeight uint16, SrcX uint16, SrcY uint16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16, Depth byte, Format byte, SendEvent byte, Shmseg Seg, Offset uint32) PutImageCookie {
   735  	c.ExtLock.RLock()
   736  	defer c.ExtLock.RUnlock()
   737  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   738  		panic("Cannot issue request 'PutImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   739  	}
   740  	cookie := c.NewCookie(false, false)
   741  	c.NewRequest(putImageRequest(c, Drawable, Gc, TotalWidth, TotalHeight, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY, Depth, Format, SendEvent, Shmseg, Offset), cookie)
   742  	return PutImageCookie{cookie}
   743  }
   744  
   745  // PutImageChecked sends a checked request.
   746  // If an error occurs, it can be retrieved using PutImageCookie.Check()
   747  func PutImageChecked(c *xgb.Conn, Drawable xproto.Drawable, Gc xproto.Gcontext, TotalWidth uint16, TotalHeight uint16, SrcX uint16, SrcY uint16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16, Depth byte, Format byte, SendEvent byte, Shmseg Seg, Offset uint32) PutImageCookie {
   748  	c.ExtLock.RLock()
   749  	defer c.ExtLock.RUnlock()
   750  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   751  		panic("Cannot issue request 'PutImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   752  	}
   753  	cookie := c.NewCookie(true, false)
   754  	c.NewRequest(putImageRequest(c, Drawable, Gc, TotalWidth, TotalHeight, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY, Depth, Format, SendEvent, Shmseg, Offset), cookie)
   755  	return PutImageCookie{cookie}
   756  }
   757  
   758  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   759  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   760  func (cook PutImageCookie) Check() error {
   761  	return cook.Cookie.Check()
   762  }
   763  
   764  // Write request to wire for PutImage
   765  // putImageRequest writes a PutImage request to a byte slice.
   766  func putImageRequest(c *xgb.Conn, Drawable xproto.Drawable, Gc xproto.Gcontext, TotalWidth uint16, TotalHeight uint16, SrcX uint16, SrcY uint16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16, Depth byte, Format byte, SendEvent byte, Shmseg Seg, Offset uint32) []byte {
   767  	size := 40
   768  	b := 0
   769  	buf := make([]byte, size)
   770  
   771  	c.ExtLock.RLock()
   772  	buf[b] = c.Extensions["MIT-SHM"]
   773  	c.ExtLock.RUnlock()
   774  	b += 1
   775  
   776  	buf[b] = 3 // request opcode
   777  	b += 1
   778  
   779  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   780  	b += 2
   781  
   782  	xgb.Put32(buf[b:], uint32(Drawable))
   783  	b += 4
   784  
   785  	xgb.Put32(buf[b:], uint32(Gc))
   786  	b += 4
   787  
   788  	xgb.Put16(buf[b:], TotalWidth)
   789  	b += 2
   790  
   791  	xgb.Put16(buf[b:], TotalHeight)
   792  	b += 2
   793  
   794  	xgb.Put16(buf[b:], SrcX)
   795  	b += 2
   796  
   797  	xgb.Put16(buf[b:], SrcY)
   798  	b += 2
   799  
   800  	xgb.Put16(buf[b:], SrcWidth)
   801  	b += 2
   802  
   803  	xgb.Put16(buf[b:], SrcHeight)
   804  	b += 2
   805  
   806  	xgb.Put16(buf[b:], uint16(DstX))
   807  	b += 2
   808  
   809  	xgb.Put16(buf[b:], uint16(DstY))
   810  	b += 2
   811  
   812  	buf[b] = Depth
   813  	b += 1
   814  
   815  	buf[b] = Format
   816  	b += 1
   817  
   818  	buf[b] = SendEvent
   819  	b += 1
   820  
   821  	b += 1 // padding
   822  
   823  	xgb.Put32(buf[b:], uint32(Shmseg))
   824  	b += 4
   825  
   826  	xgb.Put32(buf[b:], Offset)
   827  	b += 4
   828  
   829  	return buf
   830  }
   831  
   832  // QueryVersionCookie is a cookie used only for QueryVersion requests.
   833  type QueryVersionCookie struct {
   834  	*xgb.Cookie
   835  }
   836  
   837  // QueryVersion sends a checked request.
   838  // If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply()
   839  func QueryVersion(c *xgb.Conn) QueryVersionCookie {
   840  	c.ExtLock.RLock()
   841  	defer c.ExtLock.RUnlock()
   842  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   843  		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   844  	}
   845  	cookie := c.NewCookie(true, true)
   846  	c.NewRequest(queryVersionRequest(c), cookie)
   847  	return QueryVersionCookie{cookie}
   848  }
   849  
   850  // QueryVersionUnchecked sends an unchecked request.
   851  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   852  func QueryVersionUnchecked(c *xgb.Conn) QueryVersionCookie {
   853  	c.ExtLock.RLock()
   854  	defer c.ExtLock.RUnlock()
   855  	if _, ok := c.Extensions["MIT-SHM"]; !ok {
   856  		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
   857  	}
   858  	cookie := c.NewCookie(false, true)
   859  	c.NewRequest(queryVersionRequest(c), cookie)
   860  	return QueryVersionCookie{cookie}
   861  }
   862  
   863  // QueryVersionReply represents the data returned from a QueryVersion request.
   864  type QueryVersionReply struct {
   865  	Sequence      uint16 // sequence number of the request for this reply
   866  	Length        uint32 // number of bytes in this reply
   867  	SharedPixmaps bool
   868  	MajorVersion  uint16
   869  	MinorVersion  uint16
   870  	Uid           uint16
   871  	Gid           uint16
   872  	PixmapFormat  byte
   873  	// padding: 15 bytes
   874  }
   875  
   876  // Reply blocks and returns the reply data for a QueryVersion request.
   877  func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) {
   878  	buf, err := cook.Cookie.Reply()
   879  	if err != nil {
   880  		return nil, err
   881  	}
   882  	if buf == nil {
   883  		return nil, nil
   884  	}
   885  	return queryVersionReply(buf), nil
   886  }
   887  
   888  // queryVersionReply reads a byte slice into a QueryVersionReply value.
   889  func queryVersionReply(buf []byte) *QueryVersionReply {
   890  	v := new(QueryVersionReply)
   891  	b := 1 // skip reply determinant
   892  
   893  	if buf[b] == 1 {
   894  		v.SharedPixmaps = true
   895  	} else {
   896  		v.SharedPixmaps = false
   897  	}
   898  	b += 1
   899  
   900  	v.Sequence = xgb.Get16(buf[b:])
   901  	b += 2
   902  
   903  	v.Length = xgb.Get32(buf[b:]) // 4-byte units
   904  	b += 4
   905  
   906  	v.MajorVersion = xgb.Get16(buf[b:])
   907  	b += 2
   908  
   909  	v.MinorVersion = xgb.Get16(buf[b:])
   910  	b += 2
   911  
   912  	v.Uid = xgb.Get16(buf[b:])
   913  	b += 2
   914  
   915  	v.Gid = xgb.Get16(buf[b:])
   916  	b += 2
   917  
   918  	v.PixmapFormat = buf[b]
   919  	b += 1
   920  
   921  	b += 15 // padding
   922  
   923  	return v
   924  }
   925  
   926  // Write request to wire for QueryVersion
   927  // queryVersionRequest writes a QueryVersion request to a byte slice.
   928  func queryVersionRequest(c *xgb.Conn) []byte {
   929  	size := 4
   930  	b := 0
   931  	buf := make([]byte, size)
   932  
   933  	c.ExtLock.RLock()
   934  	buf[b] = c.Extensions["MIT-SHM"]
   935  	c.ExtLock.RUnlock()
   936  	b += 1
   937  
   938  	buf[b] = 0 // request opcode
   939  	b += 1
   940  
   941  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   942  	b += 2
   943  
   944  	return buf
   945  }