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