github.com/robotn/xgb@v0.0.0-20190912153532-2cb92d044934/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/robotn/xgb" 8 9 "github.com/robotn/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 }