github.com/BurntSushi/xgb@v0.0.0-20210121224620-deaf085860bc/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/BurntSushi/xgb" 8 9 "github.com/BurntSushi/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 }