github.com/BurntSushi/xgb@v0.0.0-20210121224620-deaf085860bc/screensaver/screensaver.go (about)

     1  // Package screensaver is the X client API for the MIT-SCREEN-SAVER extension.
     2  package screensaver
     3  
     4  // This file is automatically generated from screensaver.xml. Edit at your peril!
     5  
     6  import (
     7  	"github.com/BurntSushi/xgb"
     8  
     9  	"github.com/BurntSushi/xgb/xproto"
    10  )
    11  
    12  // Init must be called before using the MIT-SCREEN-SAVER extension.
    13  func Init(c *xgb.Conn) error {
    14  	reply, err := xproto.QueryExtension(c, 16, "MIT-SCREEN-SAVER").Reply()
    15  	switch {
    16  	case err != nil:
    17  		return err
    18  	case !reply.Present:
    19  		return xgb.Errorf("No extension named MIT-SCREEN-SAVER could be found on on the server.")
    20  	}
    21  
    22  	c.ExtLock.Lock()
    23  	c.Extensions["MIT-SCREEN-SAVER"] = reply.MajorOpcode
    24  	c.ExtLock.Unlock()
    25  	for evNum, fun := range xgb.NewExtEventFuncs["MIT-SCREEN-SAVER"] {
    26  		xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun
    27  	}
    28  	for errNum, fun := range xgb.NewExtErrorFuncs["MIT-SCREEN-SAVER"] {
    29  		xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun
    30  	}
    31  	return nil
    32  }
    33  
    34  func init() {
    35  	xgb.NewExtEventFuncs["MIT-SCREEN-SAVER"] = make(map[int]xgb.NewEventFun)
    36  	xgb.NewExtErrorFuncs["MIT-SCREEN-SAVER"] = make(map[int]xgb.NewErrorFun)
    37  }
    38  
    39  const (
    40  	EventNotifyMask = 1
    41  	EventCycleMask  = 2
    42  )
    43  
    44  const (
    45  	KindBlanked  = 0
    46  	KindInternal = 1
    47  	KindExternal = 2
    48  )
    49  
    50  // Notify is the event number for a NotifyEvent.
    51  const Notify = 0
    52  
    53  type NotifyEvent struct {
    54  	Sequence uint16
    55  	State    byte
    56  	Time     xproto.Timestamp
    57  	Root     xproto.Window
    58  	Window   xproto.Window
    59  	Kind     byte
    60  	Forced   bool
    61  	// padding: 14 bytes
    62  }
    63  
    64  // NotifyEventNew constructs a NotifyEvent value that implements xgb.Event from a byte slice.
    65  func NotifyEventNew(buf []byte) xgb.Event {
    66  	v := NotifyEvent{}
    67  	b := 1 // don't read event number
    68  
    69  	v.State = buf[b]
    70  	b += 1
    71  
    72  	v.Sequence = xgb.Get16(buf[b:])
    73  	b += 2
    74  
    75  	v.Time = xproto.Timestamp(xgb.Get32(buf[b:]))
    76  	b += 4
    77  
    78  	v.Root = xproto.Window(xgb.Get32(buf[b:]))
    79  	b += 4
    80  
    81  	v.Window = xproto.Window(xgb.Get32(buf[b:]))
    82  	b += 4
    83  
    84  	v.Kind = buf[b]
    85  	b += 1
    86  
    87  	if buf[b] == 1 {
    88  		v.Forced = true
    89  	} else {
    90  		v.Forced = false
    91  	}
    92  	b += 1
    93  
    94  	b += 14 // padding
    95  
    96  	return v
    97  }
    98  
    99  // Bytes writes a NotifyEvent value to a byte slice.
   100  func (v NotifyEvent) Bytes() []byte {
   101  	buf := make([]byte, 32)
   102  	b := 0
   103  
   104  	// write event number
   105  	buf[b] = 0
   106  	b += 1
   107  
   108  	buf[b] = v.State
   109  	b += 1
   110  
   111  	b += 2 // skip sequence number
   112  
   113  	xgb.Put32(buf[b:], uint32(v.Time))
   114  	b += 4
   115  
   116  	xgb.Put32(buf[b:], uint32(v.Root))
   117  	b += 4
   118  
   119  	xgb.Put32(buf[b:], uint32(v.Window))
   120  	b += 4
   121  
   122  	buf[b] = v.Kind
   123  	b += 1
   124  
   125  	if v.Forced {
   126  		buf[b] = 1
   127  	} else {
   128  		buf[b] = 0
   129  	}
   130  	b += 1
   131  
   132  	b += 14 // padding
   133  
   134  	return buf
   135  }
   136  
   137  // SequenceId returns the sequence id attached to the Notify event.
   138  // Events without a sequence number (KeymapNotify) return 0.
   139  // This is mostly used internally.
   140  func (v NotifyEvent) SequenceId() uint16 {
   141  	return v.Sequence
   142  }
   143  
   144  // String is a rudimentary string representation of NotifyEvent.
   145  func (v NotifyEvent) String() string {
   146  	fieldVals := make([]string, 0, 7)
   147  	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
   148  	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
   149  	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
   150  	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
   151  	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
   152  	fieldVals = append(fieldVals, xgb.Sprintf("Kind: %d", v.Kind))
   153  	fieldVals = append(fieldVals, xgb.Sprintf("Forced: %t", v.Forced))
   154  	return "Notify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
   155  }
   156  
   157  func init() {
   158  	xgb.NewExtEventFuncs["MIT-SCREEN-SAVER"][0] = NotifyEventNew
   159  }
   160  
   161  const (
   162  	StateOff      = 0
   163  	StateOn       = 1
   164  	StateCycle    = 2
   165  	StateDisabled = 3
   166  )
   167  
   168  // Skipping definition for base type 'Bool'
   169  
   170  // Skipping definition for base type 'Byte'
   171  
   172  // Skipping definition for base type 'Card8'
   173  
   174  // Skipping definition for base type 'Char'
   175  
   176  // Skipping definition for base type 'Void'
   177  
   178  // Skipping definition for base type 'Double'
   179  
   180  // Skipping definition for base type 'Float'
   181  
   182  // Skipping definition for base type 'Int16'
   183  
   184  // Skipping definition for base type 'Int32'
   185  
   186  // Skipping definition for base type 'Int8'
   187  
   188  // Skipping definition for base type 'Card16'
   189  
   190  // Skipping definition for base type 'Card32'
   191  
   192  // QueryInfoCookie is a cookie used only for QueryInfo requests.
   193  type QueryInfoCookie struct {
   194  	*xgb.Cookie
   195  }
   196  
   197  // QueryInfo sends a checked request.
   198  // If an error occurs, it will be returned with the reply by calling QueryInfoCookie.Reply()
   199  func QueryInfo(c *xgb.Conn, Drawable xproto.Drawable) QueryInfoCookie {
   200  	c.ExtLock.RLock()
   201  	defer c.ExtLock.RUnlock()
   202  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   203  		panic("Cannot issue request 'QueryInfo' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   204  	}
   205  	cookie := c.NewCookie(true, true)
   206  	c.NewRequest(queryInfoRequest(c, Drawable), cookie)
   207  	return QueryInfoCookie{cookie}
   208  }
   209  
   210  // QueryInfoUnchecked sends an unchecked request.
   211  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   212  func QueryInfoUnchecked(c *xgb.Conn, Drawable xproto.Drawable) QueryInfoCookie {
   213  	c.ExtLock.RLock()
   214  	defer c.ExtLock.RUnlock()
   215  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   216  		panic("Cannot issue request 'QueryInfo' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   217  	}
   218  	cookie := c.NewCookie(false, true)
   219  	c.NewRequest(queryInfoRequest(c, Drawable), cookie)
   220  	return QueryInfoCookie{cookie}
   221  }
   222  
   223  // QueryInfoReply represents the data returned from a QueryInfo request.
   224  type QueryInfoReply struct {
   225  	Sequence         uint16 // sequence number of the request for this reply
   226  	Length           uint32 // number of bytes in this reply
   227  	State            byte
   228  	SaverWindow      xproto.Window
   229  	MsUntilServer    uint32
   230  	MsSinceUserInput uint32
   231  	EventMask        uint32
   232  	Kind             byte
   233  	// padding: 7 bytes
   234  }
   235  
   236  // Reply blocks and returns the reply data for a QueryInfo request.
   237  func (cook QueryInfoCookie) Reply() (*QueryInfoReply, error) {
   238  	buf, err := cook.Cookie.Reply()
   239  	if err != nil {
   240  		return nil, err
   241  	}
   242  	if buf == nil {
   243  		return nil, nil
   244  	}
   245  	return queryInfoReply(buf), nil
   246  }
   247  
   248  // queryInfoReply reads a byte slice into a QueryInfoReply value.
   249  func queryInfoReply(buf []byte) *QueryInfoReply {
   250  	v := new(QueryInfoReply)
   251  	b := 1 // skip reply determinant
   252  
   253  	v.State = buf[b]
   254  	b += 1
   255  
   256  	v.Sequence = xgb.Get16(buf[b:])
   257  	b += 2
   258  
   259  	v.Length = xgb.Get32(buf[b:]) // 4-byte units
   260  	b += 4
   261  
   262  	v.SaverWindow = xproto.Window(xgb.Get32(buf[b:]))
   263  	b += 4
   264  
   265  	v.MsUntilServer = xgb.Get32(buf[b:])
   266  	b += 4
   267  
   268  	v.MsSinceUserInput = xgb.Get32(buf[b:])
   269  	b += 4
   270  
   271  	v.EventMask = xgb.Get32(buf[b:])
   272  	b += 4
   273  
   274  	v.Kind = buf[b]
   275  	b += 1
   276  
   277  	b += 7 // padding
   278  
   279  	return v
   280  }
   281  
   282  // Write request to wire for QueryInfo
   283  // queryInfoRequest writes a QueryInfo request to a byte slice.
   284  func queryInfoRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte {
   285  	size := 8
   286  	b := 0
   287  	buf := make([]byte, size)
   288  
   289  	c.ExtLock.RLock()
   290  	buf[b] = c.Extensions["MIT-SCREEN-SAVER"]
   291  	c.ExtLock.RUnlock()
   292  	b += 1
   293  
   294  	buf[b] = 1 // request opcode
   295  	b += 1
   296  
   297  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   298  	b += 2
   299  
   300  	xgb.Put32(buf[b:], uint32(Drawable))
   301  	b += 4
   302  
   303  	return buf
   304  }
   305  
   306  // QueryVersionCookie is a cookie used only for QueryVersion requests.
   307  type QueryVersionCookie struct {
   308  	*xgb.Cookie
   309  }
   310  
   311  // QueryVersion sends a checked request.
   312  // If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply()
   313  func QueryVersion(c *xgb.Conn, ClientMajorVersion byte, ClientMinorVersion byte) QueryVersionCookie {
   314  	c.ExtLock.RLock()
   315  	defer c.ExtLock.RUnlock()
   316  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   317  		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   318  	}
   319  	cookie := c.NewCookie(true, true)
   320  	c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie)
   321  	return QueryVersionCookie{cookie}
   322  }
   323  
   324  // QueryVersionUnchecked sends an unchecked request.
   325  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   326  func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion byte, ClientMinorVersion byte) QueryVersionCookie {
   327  	c.ExtLock.RLock()
   328  	defer c.ExtLock.RUnlock()
   329  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   330  		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   331  	}
   332  	cookie := c.NewCookie(false, true)
   333  	c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie)
   334  	return QueryVersionCookie{cookie}
   335  }
   336  
   337  // QueryVersionReply represents the data returned from a QueryVersion request.
   338  type QueryVersionReply struct {
   339  	Sequence uint16 // sequence number of the request for this reply
   340  	Length   uint32 // number of bytes in this reply
   341  	// padding: 1 bytes
   342  	ServerMajorVersion uint16
   343  	ServerMinorVersion uint16
   344  	// padding: 20 bytes
   345  }
   346  
   347  // Reply blocks and returns the reply data for a QueryVersion request.
   348  func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) {
   349  	buf, err := cook.Cookie.Reply()
   350  	if err != nil {
   351  		return nil, err
   352  	}
   353  	if buf == nil {
   354  		return nil, nil
   355  	}
   356  	return queryVersionReply(buf), nil
   357  }
   358  
   359  // queryVersionReply reads a byte slice into a QueryVersionReply value.
   360  func queryVersionReply(buf []byte) *QueryVersionReply {
   361  	v := new(QueryVersionReply)
   362  	b := 1 // skip reply determinant
   363  
   364  	b += 1 // padding
   365  
   366  	v.Sequence = xgb.Get16(buf[b:])
   367  	b += 2
   368  
   369  	v.Length = xgb.Get32(buf[b:]) // 4-byte units
   370  	b += 4
   371  
   372  	v.ServerMajorVersion = xgb.Get16(buf[b:])
   373  	b += 2
   374  
   375  	v.ServerMinorVersion = xgb.Get16(buf[b:])
   376  	b += 2
   377  
   378  	b += 20 // padding
   379  
   380  	return v
   381  }
   382  
   383  // Write request to wire for QueryVersion
   384  // queryVersionRequest writes a QueryVersion request to a byte slice.
   385  func queryVersionRequest(c *xgb.Conn, ClientMajorVersion byte, ClientMinorVersion byte) []byte {
   386  	size := 8
   387  	b := 0
   388  	buf := make([]byte, size)
   389  
   390  	c.ExtLock.RLock()
   391  	buf[b] = c.Extensions["MIT-SCREEN-SAVER"]
   392  	c.ExtLock.RUnlock()
   393  	b += 1
   394  
   395  	buf[b] = 0 // request opcode
   396  	b += 1
   397  
   398  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   399  	b += 2
   400  
   401  	buf[b] = ClientMajorVersion
   402  	b += 1
   403  
   404  	buf[b] = ClientMinorVersion
   405  	b += 1
   406  
   407  	b += 2 // padding
   408  
   409  	return buf
   410  }
   411  
   412  // SelectInputCookie is a cookie used only for SelectInput requests.
   413  type SelectInputCookie struct {
   414  	*xgb.Cookie
   415  }
   416  
   417  // SelectInput sends an unchecked request.
   418  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   419  func SelectInput(c *xgb.Conn, Drawable xproto.Drawable, EventMask uint32) SelectInputCookie {
   420  	c.ExtLock.RLock()
   421  	defer c.ExtLock.RUnlock()
   422  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   423  		panic("Cannot issue request 'SelectInput' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   424  	}
   425  	cookie := c.NewCookie(false, false)
   426  	c.NewRequest(selectInputRequest(c, Drawable, EventMask), cookie)
   427  	return SelectInputCookie{cookie}
   428  }
   429  
   430  // SelectInputChecked sends a checked request.
   431  // If an error occurs, it can be retrieved using SelectInputCookie.Check()
   432  func SelectInputChecked(c *xgb.Conn, Drawable xproto.Drawable, EventMask uint32) SelectInputCookie {
   433  	c.ExtLock.RLock()
   434  	defer c.ExtLock.RUnlock()
   435  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   436  		panic("Cannot issue request 'SelectInput' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   437  	}
   438  	cookie := c.NewCookie(true, false)
   439  	c.NewRequest(selectInputRequest(c, Drawable, EventMask), cookie)
   440  	return SelectInputCookie{cookie}
   441  }
   442  
   443  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   444  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   445  func (cook SelectInputCookie) Check() error {
   446  	return cook.Cookie.Check()
   447  }
   448  
   449  // Write request to wire for SelectInput
   450  // selectInputRequest writes a SelectInput request to a byte slice.
   451  func selectInputRequest(c *xgb.Conn, Drawable xproto.Drawable, EventMask uint32) []byte {
   452  	size := 12
   453  	b := 0
   454  	buf := make([]byte, size)
   455  
   456  	c.ExtLock.RLock()
   457  	buf[b] = c.Extensions["MIT-SCREEN-SAVER"]
   458  	c.ExtLock.RUnlock()
   459  	b += 1
   460  
   461  	buf[b] = 2 // request opcode
   462  	b += 1
   463  
   464  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   465  	b += 2
   466  
   467  	xgb.Put32(buf[b:], uint32(Drawable))
   468  	b += 4
   469  
   470  	xgb.Put32(buf[b:], EventMask)
   471  	b += 4
   472  
   473  	return buf
   474  }
   475  
   476  // SetAttributesCookie is a cookie used only for SetAttributes requests.
   477  type SetAttributesCookie struct {
   478  	*xgb.Cookie
   479  }
   480  
   481  // SetAttributes sends an unchecked request.
   482  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   483  func SetAttributes(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) SetAttributesCookie {
   484  	c.ExtLock.RLock()
   485  	defer c.ExtLock.RUnlock()
   486  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   487  		panic("Cannot issue request 'SetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   488  	}
   489  	cookie := c.NewCookie(false, false)
   490  	c.NewRequest(setAttributesRequest(c, Drawable, X, Y, Width, Height, BorderWidth, Class, Depth, Visual, ValueMask, ValueList), cookie)
   491  	return SetAttributesCookie{cookie}
   492  }
   493  
   494  // SetAttributesChecked sends a checked request.
   495  // If an error occurs, it can be retrieved using SetAttributesCookie.Check()
   496  func SetAttributesChecked(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) SetAttributesCookie {
   497  	c.ExtLock.RLock()
   498  	defer c.ExtLock.RUnlock()
   499  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   500  		panic("Cannot issue request 'SetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   501  	}
   502  	cookie := c.NewCookie(true, false)
   503  	c.NewRequest(setAttributesRequest(c, Drawable, X, Y, Width, Height, BorderWidth, Class, Depth, Visual, ValueMask, ValueList), cookie)
   504  	return SetAttributesCookie{cookie}
   505  }
   506  
   507  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   508  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   509  func (cook SetAttributesCookie) Check() error {
   510  	return cook.Cookie.Check()
   511  }
   512  
   513  // Write request to wire for SetAttributes
   514  // setAttributesRequest writes a SetAttributes request to a byte slice.
   515  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 {
   516  	size := xgb.Pad((24 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
   517  	b := 0
   518  	buf := make([]byte, size)
   519  
   520  	c.ExtLock.RLock()
   521  	buf[b] = c.Extensions["MIT-SCREEN-SAVER"]
   522  	c.ExtLock.RUnlock()
   523  	b += 1
   524  
   525  	buf[b] = 3 // request opcode
   526  	b += 1
   527  
   528  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   529  	b += 2
   530  
   531  	xgb.Put32(buf[b:], uint32(Drawable))
   532  	b += 4
   533  
   534  	xgb.Put16(buf[b:], uint16(X))
   535  	b += 2
   536  
   537  	xgb.Put16(buf[b:], uint16(Y))
   538  	b += 2
   539  
   540  	xgb.Put16(buf[b:], Width)
   541  	b += 2
   542  
   543  	xgb.Put16(buf[b:], Height)
   544  	b += 2
   545  
   546  	xgb.Put16(buf[b:], BorderWidth)
   547  	b += 2
   548  
   549  	buf[b] = Class
   550  	b += 1
   551  
   552  	buf[b] = Depth
   553  	b += 1
   554  
   555  	xgb.Put32(buf[b:], uint32(Visual))
   556  	b += 4
   557  
   558  	xgb.Put32(buf[b:], ValueMask)
   559  	b += 4
   560  	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
   561  		xgb.Put32(buf[b:], ValueList[i])
   562  		b += 4
   563  	}
   564  	b = xgb.Pad(b)
   565  
   566  	return buf
   567  }
   568  
   569  // SuspendCookie is a cookie used only for Suspend requests.
   570  type SuspendCookie struct {
   571  	*xgb.Cookie
   572  }
   573  
   574  // Suspend sends an unchecked request.
   575  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   576  func Suspend(c *xgb.Conn, Suspend bool) SuspendCookie {
   577  	c.ExtLock.RLock()
   578  	defer c.ExtLock.RUnlock()
   579  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   580  		panic("Cannot issue request 'Suspend' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   581  	}
   582  	cookie := c.NewCookie(false, false)
   583  	c.NewRequest(suspendRequest(c, Suspend), cookie)
   584  	return SuspendCookie{cookie}
   585  }
   586  
   587  // SuspendChecked sends a checked request.
   588  // If an error occurs, it can be retrieved using SuspendCookie.Check()
   589  func SuspendChecked(c *xgb.Conn, Suspend bool) SuspendCookie {
   590  	c.ExtLock.RLock()
   591  	defer c.ExtLock.RUnlock()
   592  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   593  		panic("Cannot issue request 'Suspend' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   594  	}
   595  	cookie := c.NewCookie(true, false)
   596  	c.NewRequest(suspendRequest(c, Suspend), cookie)
   597  	return SuspendCookie{cookie}
   598  }
   599  
   600  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   601  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   602  func (cook SuspendCookie) Check() error {
   603  	return cook.Cookie.Check()
   604  }
   605  
   606  // Write request to wire for Suspend
   607  // suspendRequest writes a Suspend request to a byte slice.
   608  func suspendRequest(c *xgb.Conn, Suspend bool) []byte {
   609  	size := 8
   610  	b := 0
   611  	buf := make([]byte, size)
   612  
   613  	c.ExtLock.RLock()
   614  	buf[b] = c.Extensions["MIT-SCREEN-SAVER"]
   615  	c.ExtLock.RUnlock()
   616  	b += 1
   617  
   618  	buf[b] = 5 // request opcode
   619  	b += 1
   620  
   621  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   622  	b += 2
   623  
   624  	if Suspend {
   625  		buf[b] = 1
   626  	} else {
   627  		buf[b] = 0
   628  	}
   629  	b += 1
   630  
   631  	b += 3 // padding
   632  
   633  	return buf
   634  }
   635  
   636  // UnsetAttributesCookie is a cookie used only for UnsetAttributes requests.
   637  type UnsetAttributesCookie struct {
   638  	*xgb.Cookie
   639  }
   640  
   641  // UnsetAttributes sends an unchecked request.
   642  // If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
   643  func UnsetAttributes(c *xgb.Conn, Drawable xproto.Drawable) UnsetAttributesCookie {
   644  	c.ExtLock.RLock()
   645  	defer c.ExtLock.RUnlock()
   646  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   647  		panic("Cannot issue request 'UnsetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   648  	}
   649  	cookie := c.NewCookie(false, false)
   650  	c.NewRequest(unsetAttributesRequest(c, Drawable), cookie)
   651  	return UnsetAttributesCookie{cookie}
   652  }
   653  
   654  // UnsetAttributesChecked sends a checked request.
   655  // If an error occurs, it can be retrieved using UnsetAttributesCookie.Check()
   656  func UnsetAttributesChecked(c *xgb.Conn, Drawable xproto.Drawable) UnsetAttributesCookie {
   657  	c.ExtLock.RLock()
   658  	defer c.ExtLock.RUnlock()
   659  	if _, ok := c.Extensions["MIT-SCREEN-SAVER"]; !ok {
   660  		panic("Cannot issue request 'UnsetAttributes' using the uninitialized extension 'MIT-SCREEN-SAVER'. screensaver.Init(connObj) must be called first.")
   661  	}
   662  	cookie := c.NewCookie(true, false)
   663  	c.NewRequest(unsetAttributesRequest(c, Drawable), cookie)
   664  	return UnsetAttributesCookie{cookie}
   665  }
   666  
   667  // Check returns an error if one occurred for checked requests that are not expecting a reply.
   668  // This cannot be called for requests expecting a reply, nor for unchecked requests.
   669  func (cook UnsetAttributesCookie) Check() error {
   670  	return cook.Cookie.Check()
   671  }
   672  
   673  // Write request to wire for UnsetAttributes
   674  // unsetAttributesRequest writes a UnsetAttributes request to a byte slice.
   675  func unsetAttributesRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte {
   676  	size := 8
   677  	b := 0
   678  	buf := make([]byte, size)
   679  
   680  	c.ExtLock.RLock()
   681  	buf[b] = c.Extensions["MIT-SCREEN-SAVER"]
   682  	c.ExtLock.RUnlock()
   683  	b += 1
   684  
   685  	buf[b] = 4 // request opcode
   686  	b += 1
   687  
   688  	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
   689  	b += 2
   690  
   691  	xgb.Put32(buf[b:], uint32(Drawable))
   692  	b += 4
   693  
   694  	return buf
   695  }